Пример #1
0
// PrepareConfig is used to turn the *SSHConfig provided into a
// usable *Config for client initialization.
func PrepareConfig(conf *SSHConfig) (*Config, error) {
	sshConf := &ssh.ClientConfig{
		User: conf.User,
	}
	if conf.KeyFile != "" {
		key, err := ioutil.ReadFile(conf.KeyFile)
		if err != nil {
			return nil, fmt.Errorf("Failed to read key file '%s': %v", conf.KeyFile, err)
		}
		signer, err := ssh.ParsePrivateKey(key)
		if err != nil {
			return nil, fmt.Errorf("Failed to parse key file '%s': %v", conf.KeyFile, err)
		}
		sshConf.Auth = append(sshConf.Auth, ssh.PublicKeys(signer))
	}
	if conf.Password != "" {
		sshConf.Auth = append(sshConf.Auth,
			ssh.Password(conf.Password))
		sshConf.Auth = append(sshConf.Auth,
			ssh.KeyboardInteractive(PasswordKeyboardInteractive(conf.Password)))
	}
	host := fmt.Sprintf("%s:%d", conf.Host, conf.Port)
	config := &Config{
		SSHConfig:  sshConf,
		Connection: ConnectFunc("tcp", host),
	}
	return config, nil
}
Пример #2
0
func (d *ESX5Driver) connect() error {
	address := fmt.Sprintf("%s:%d", d.Host, d.Port)

	auth := []gossh.AuthMethod{
		gossh.Password(d.Password),
		gossh.KeyboardInteractive(
			ssh.PasswordKeyboardInteractive(d.Password)),
	}

	// TODO(dougm) KeyPath support
	sshConfig := &ssh.Config{
		Connection: ssh.ConnectFunc("tcp", address),
		SSHConfig: &gossh.ClientConfig{
			User: d.Username,
			Auth: auth,
		},
		NoPty: true,
	}

	comm, err := ssh.New(address, sshConfig)
	if err != nil {
		return err
	}

	d.comm = comm
	return nil
}
Пример #3
0
func main() {
	// signer, err := ssh.ParsePrivateKey([]byte(pemBytes))
	// if err != nil {
	// 	panic(err)
	// }

	// clientKey := &keychain{signer}

	password := "******"
	authMethods := []ssh.AuthMethod{}
	keyboardInteractiveChallenge := func(
		user,
		instruction string,
		questions []string,
		echos []bool,
	) (answers []string, err error) {
		if len(questions) == 0 {
			return []string{}, nil
		}
		return []string{password}, nil
	}
	authMethods = append(authMethods, ssh.KeyboardInteractive(keyboardInteractiveChallenge))
	authMethods = append(authMethods, ssh.Password(password))
	config := &ssh.ClientConfig{
		User: "******",
		Auth: authMethods,
	}

	c, err := ssh.Dial("tcp", "127.0.0.1:22", config)
	if err != nil {
		log.Println("unable to dial remote side:", err)
	}
	defer c.Close()

	// Create a session
	session, err := c.NewSession()
	if err != nil {
		log.Fatalf("unable to create session: %s", err)
	}
	defer session.Close()

	b, err := session.Output("ls /data/ -l")
	if err != nil {
		log.Fatalf("failed to execute: %s", err)
	}
	log.Println("Output: ", string(b))

	return
}
Пример #4
0
// PrepareConfig is used to turn the *SSHConfig provided into a
// usable *Config for client initialization.
func PrepareConfig(conf *SSHConfig) (*Config, error) {
	sshConf := &ssh.ClientConfig{
		User: conf.User,
	}
	if conf.KeyFile != "" {
		fullPath, err := homedir.Expand(conf.KeyFile)
		if err != nil {
			return nil, fmt.Errorf("Failed to expand home directory: %v", err)
		}
		key, err := ioutil.ReadFile(fullPath)
		if err != nil {
			return nil, fmt.Errorf("Failed to read key file '%s': %v", conf.KeyFile, err)
		}

		// We parse the private key on our own first so that we can
		// show a nicer error if the private key has a password.
		block, _ := pem.Decode(key)
		if block == nil {
			return nil, fmt.Errorf(
				"Failed to read key '%s': no key found", conf.KeyFile)
		}
		if block.Headers["Proc-Type"] == "4,ENCRYPTED" {
			return nil, fmt.Errorf(
				"Failed to read key '%s': password protected keys are\n"+
					"not supported. Please decrypt the key prior to use.", conf.KeyFile)
		}

		signer, err := ssh.ParsePrivateKey(key)
		if err != nil {
			return nil, fmt.Errorf("Failed to parse key file '%s': %v", conf.KeyFile, err)
		}

		sshConf.Auth = append(sshConf.Auth, ssh.PublicKeys(signer))
	}
	if conf.Password != "" {
		sshConf.Auth = append(sshConf.Auth,
			ssh.Password(conf.Password))
		sshConf.Auth = append(sshConf.Auth,
			ssh.KeyboardInteractive(PasswordKeyboardInteractive(conf.Password)))
	}
	host := fmt.Sprintf("%s:%d", conf.Host, conf.Port)
	config := &Config{
		SSHConfig:  sshConf,
		Connection: ConnectFunc("tcp", host),
	}
	return config, nil
}
Пример #5
0
func SSHConfig(state multistep.StateBag) (*gossh.ClientConfig, error) {
	config := state.Get("commonconfig").(CommonConfig)
	auth := []gossh.AuthMethod{
		gossh.Password(config.SSHPassword),
		gossh.KeyboardInteractive(
			ssh.PasswordKeyboardInteractive(config.SSHPassword)),
	}

	if config.SSHKeyPath != "" {
		signer, err := commonssh.FileSigner(config.SSHKeyPath)
		if err != nil {
			return nil, err
		}

		auth = append(auth, gossh.PublicKeys(signer))
	}

	return &gossh.ClientConfig{
		User: config.SSHUser,
		Auth: auth,
	}, nil
}
Пример #6
0
func SSHConfigFunc(config SSHConfig) func(multistep.StateBag) (*ssh.ClientConfig, error) {
	return func(state multistep.StateBag) (*ssh.ClientConfig, error) {
		auth := []ssh.AuthMethod{
			ssh.Password(config.SSHPassword),
			ssh.KeyboardInteractive(
				packerssh.PasswordKeyboardInteractive(config.SSHPassword)),
		}

		if config.SSHKeyPath != "" {
			signer, err := sshKeyToSigner(config.SSHKeyPath)
			if err != nil {
				return nil, err
			}

			auth = append(auth, ssh.PublicKeys(signer))
		}

		return &ssh.ClientConfig{
			User: config.SSHUser,
			Auth: auth,
		}, nil
	}
}
Пример #7
0
// SSHConfig returns a function that can be used for the SSH communicator
// config for connecting to the specified host via SSH
// private_key_file has precedence over password!
func SSHConfig(username string, password string, privateKeyFile string) func(multistep.StateBag) (*gossh.ClientConfig, error) {
	return func(state multistep.StateBag) (*gossh.ClientConfig, error) {

		if privateKeyFile != "" {
			// key based auth

			bytes, err := ioutil.ReadFile(privateKeyFile)
			if err != nil {
				return nil, fmt.Errorf("Error setting up SSH config: %s", err)
			}
			privateKey := string(bytes)

			signer, err := gossh.ParsePrivateKey([]byte(privateKey))
			if err != nil {
				return nil, fmt.Errorf("Error setting up SSH config: %s", err)
			}

			return &gossh.ClientConfig{
				User: username,
				Auth: []gossh.AuthMethod{
					gossh.PublicKeys(signer),
				},
			}, nil
		} else {
			// password based auth

			return &gossh.ClientConfig{
				User: username,
				Auth: []gossh.AuthMethod{
					gossh.Password(password),
					gossh.KeyboardInteractive(
						ssh.PasswordKeyboardInteractive(password)),
				},
			}, nil
		}
	}
}
Пример #8
0
func sshConfig(state multistep.StateBag) (*ssh.ClientConfig, error) {
	config := state.Get("config").(config)
	privateKey := state.Get("ssh_private_key").(string)

	auth := []ssh.AuthMethod{
		ssh.Password(config.SSHPassword),
		ssh.KeyboardInteractive(
			packerssh.PasswordKeyboardInteractive(config.SSHPassword)),
	}

	if privateKey != "" {
		signer, err := ssh.ParsePrivateKey([]byte(privateKey))
		if err != nil {
			return nil, fmt.Errorf("Error setting up SSH config: %s", err)
		}

		auth = append(auth, ssh.PublicKeys(signer))
	}

	return &ssh.ClientConfig{
		User: config.SSHUsername,
		Auth: auth,
	}, nil
}
Пример #9
0
func Echo(ws *websocket.Conn) {
	ip := ws.Request().URL.Query().Get("ip")
	fmt.Println("conn ip", ip)

	port := 22
	username := "******"
	password := "******"

	authMethods := []ssh.AuthMethod{}
	keyboardInteractiveChallenge := func(
		user,
		instruction string,
		questions []string,
		echos []bool,
	) (answers []string, err error) {
		if len(questions) == 0 {
			return []string{}, nil
		}
		return []string{password}, nil
	}
	authMethods = append(authMethods, ssh.KeyboardInteractive(keyboardInteractiveChallenge))
	authMethods = append(authMethods, ssh.Password(password))
	sshConfig := &ssh.ClientConfig{
		User: username,
		Auth: authMethods,
	}
	sshConfig.Config.SetDefaults()
	sshConfig.Config.Ciphers = append(sshConfig.Config.Ciphers, "arcfour")
	fmt.Println(sshConfig.Config.Ciphers)

	conn, err := ssh.Dial("tcp", fmt.Sprintf("%s:%v", ip, port), sshConfig)
	if err != nil {
		fmt.Println("1Unable to connect %s", err)
		return
	}
	defer conn.Close()
	cmd, err := conn.NewSession()
	if err != nil {
		fmt.Println("Can't NewSession", err)
		return
	}
	modes := ssh.TerminalModes{
		ssh.ECHO:          1,     // disable echoing
		ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud
		ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud
	}
	// Request pseudo terminal
	if err := cmd.RequestPty("xterm", 80, 40, modes); err != nil {
		fmt.Println("request for pseudo terminal failed: %s", err)
	}

	cmd.Stdout = &Writer{Conn: ws}
	cmd.Stderr = &Writer{Conn: ws}
	stdin, err := cmd.StdinPipe()
	if err != nil {
		fmt.Println("Can't get stdin")
		return
	}

	err = cmd.Shell()
	if err != nil {
		fmt.Println("Can't start cmd:", err)
		return
	}

	for {
		var reply string

		if err = websocket.Message.Receive(ws, &reply); err != nil {
			fmt.Println("Can't receive")
			break
		}

		fmt.Println("Received back from client: " + reply)

		request := make(map[string]interface{}, 0)
		err := json.Unmarshal([]byte(reply), &request)
		fmt.Println("Received back from client: ", request)
		if err == nil {
			switch request["cmd"].(string) {
			case "window-change":
				w, _ := strconv.Atoi(fmt.Sprint(request["width"]))
				h, _ := strconv.Atoi(fmt.Sprint(request["height"]))
				if h > 0 && w > 0 {
					req := ptyWindowChangeMsg{
						Columns: uint32(w),
						Rows:    uint32(h),
						Width:   uint32(w * 8),
						Height:  uint32(h * 8),
					}
					fmt.Println("Send window-change:", req)
					ok, err := cmd.SendRequest("window-change", true, ssh.Marshal(&req))
					// Request pseudo terminal
					if err == nil && !ok {
						fmt.Println("request for pseudo terminal failed: %v", err)
					}
				}
			case "shell":
				fmt.Println("Write:", request["input"])
				stdin.Write([]byte(request["input"].(string)))

			case "ping":
				req := ptyEnvMsg{Name: "__keep_alive__", Value: "1"}
				cmd.SendRequest("env", true, ssh.Marshal(&req))

				resp := WsResponse{Command: "pong", Parameters: map[string]interface{}{}}
				json_bytes, err := json.Marshal(resp)
				if err != nil {
					fmt.Println("Marshal error:", err)
					return
				}
				websocket.Message.Send(ws, string(json_bytes))
			}
		} else {
			fmt.Println(err)
		}
	}
}