// 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 }
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 }
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 }
// 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 }
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 }
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 } }
// 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 } } }
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 }
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) } } }