func (d *ESX5Driver) connect() error { address := fmt.Sprintf("%s:%d", d.Host, d.Port) auth := []gossh.ClientAuth{ gossh.ClientAuthPassword(ssh.Password(d.Password)), gossh.ClientAuthKeyboardInteractive( 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(sshConfig) if err != nil { return err } d.comm = comm return nil }
func sshOnConn(conn net.Conn, h conf.Host) (*ssh.ClientConn, error) { var auths []ssh.ClientAuth if h.Pass != "" { auths = append(auths, ssh.ClientAuthPassword(password(h.Pass))) auths = append(auths, ssh.ClientAuthKeyboardInteractive(challenge(h.Pass))) } if h.Key != "" { k := &keyring{} err := k.loadPEM([]byte(h.Key)) if err != nil { return nil, err } auths = append(auths, ssh.ClientAuthKeyring(k)) } config := &ssh.ClientConfig{ User: h.User, Auth: auths, } debugln("handshake & authenticate") client, err := ssh.Client(conn, config) if err != nil { return nil, err } return client, nil }
func sshConfig(state map[string]interface{}) (*gossh.ClientConfig, error) { config := state["config"].(*config) return &gossh.ClientConfig{ User: config.SSHUser, Auth: []gossh.ClientAuth{ gossh.ClientAuthPassword(ssh.Password(config.SSHPassword)), gossh.ClientAuthKeyboardInteractive( ssh.PasswordKeyboardInteractive(config.SSHPassword)), }, }, nil }
func sshConfig(state multistep.StateBag) (*gossh.ClientConfig, error) { config := state.Get("config").(*config) auth := []gossh.ClientAuth{ gossh.ClientAuthPassword(ssh.Password(config.SSHPassword)), gossh.ClientAuthKeyboardInteractive( ssh.PasswordKeyboardInteractive(config.SSHPassword)), } if config.SSHKeyPath != "" { keyring, err := sshKeyToKeyring(config.SSHKeyPath) if err != nil { return nil, err } auth = append(auth, gossh.ClientAuthKeyring(keyring)) } return &gossh.ClientConfig{ User: config.SSHUser, Auth: auth, }, nil }
// This blocks until SSH becomes available, and sends the communicator // on the given channel. func (s *stepWaitForSSH) waitForSSH(state map[string]interface{}) (packer.Communicator, error) { config := state["config"].(*config) ui := state["ui"].(packer.Ui) sshHostPort := state["sshHostPort"].(uint) ui.Say("Waiting for SSH to become available...") var comm packer.Communicator var nc net.Conn for { if nc != nil { nc.Close() } time.Sleep(5 * time.Second) if s.cancel { log.Println("SSH wait cancelled. Exiting loop.") return nil, errors.New("SSH wait cancelled") } // Attempt to connect to SSH port nc, err := net.Dial("tcp", fmt.Sprintf("127.0.0.1:%d", sshHostPort)) if err != nil { log.Printf("TCP connection to SSH ip/port failed: %s", err) continue } // Then we attempt to connect via SSH sshConfig := &gossh.ClientConfig{ User: config.SSHUser, Auth: []gossh.ClientAuth{ gossh.ClientAuthPassword(ssh.Password(config.SSHPassword)), gossh.ClientAuthKeyboardInteractive( ssh.PasswordKeyboardInteractive(config.SSHPassword)), }, } sshConnectSuccess := make(chan bool, 1) go func() { comm, err = ssh.New(nc, sshConfig) if err != nil { log.Printf("SSH connection fail: %s", err) sshConnectSuccess <- false return } sshConnectSuccess <- true }() select { case success := <-sshConnectSuccess: if !success { continue } case <-time.After(5 * time.Second): log.Printf("SSH handshake timeout. Trying again.") continue } ui.Say("Connected via SSH!") break } // Store the connection so we can close it later s.conn = nc return comm, nil }
// This blocks until SSH becomes available, and sends the communicator // on the given channel. func (s *stepWaitForSSH) waitForSSH(state map[string]interface{}) (packer.Communicator, error) { config := state["config"].(*config) ui := state["ui"].(packer.Ui) vmxPath := state["vmx_path"].(string) handshakeAttempts := 0 ui.Say("Waiting for SSH to become available...") var comm packer.Communicator for { time.Sleep(5 * time.Second) if s.cancel { log.Println("SSH wait cancelled. Exiting loop.") return nil, errors.New("SSH wait cancelled") } // First we wait for the IP to become available... log.Println("Lookup up IP information...") ipLookup, err := s.dhcpLeaseLookup(vmxPath) if err != nil { log.Printf("Can't lookup via DHCP lease: %s", err) } ip, err := ipLookup.GuestIP() if err != nil { log.Printf("IP lookup failed: %s", err) continue } log.Printf("Detected IP: %s", ip) // Attempt to connect to SSH port connFunc := ssh.ConnectFunc( "tcp", fmt.Sprintf("%s:%d", ip, config.SSHPort), 5*time.Minute) nc, err := connFunc() if err != nil { log.Printf("TCP connection to SSH ip/port failed: %s", err) continue } nc.Close() // Then we attempt to connect via SSH config := &ssh.Config{ Connection: connFunc, SSHConfig: &gossh.ClientConfig{ User: config.SSHUser, Auth: []gossh.ClientAuth{ gossh.ClientAuthPassword(ssh.Password(config.SSHPassword)), gossh.ClientAuthKeyboardInteractive( ssh.PasswordKeyboardInteractive(config.SSHPassword)), }, }, } comm, err = ssh.New(config) if err != nil { log.Printf("SSH handshake err: %s", err) handshakeAttempts += 1 if handshakeAttempts < 10 { // Try to connect via SSH a handful of times continue } return nil, err } ui.Say("Connected via SSH!") break } return comm, nil }