# File lib/rye/box.rb, line 646
646:     def connect(reconnect=true)
647:       raise Rye::NoHost unless @rye_host
648:       return if @rye_ssh && !reconnect
649:       disconnect if @rye_ssh 
650:       if @rye_via
651:         debug "Opening connection to #{@rye_host} as #{@rye_user}, via #{@rye_via.host}"
652:       else
653:         debug "Opening connection to #{@rye_host} as #{@rye_user}"
654:       end
655:       highline = HighLine.new # Used for password prompt
656:       retried = 0
657:       @rye_opts[:keys].compact!  # A quick fix in Windows. TODO: Why is there a nil?
658:       begin
659:         if @rye_via
660:           # tell the +Rye::Hop+ what and where to setup,
661:           # it returns the local port used
662:           @rye_localport = @rye_via.fetch_port(@rye_host, @rye_opts[:port].nil? ? 22 : @rye_opts[:port] )
663:           debug "fetched localport #{@rye_localport}"
664:           @rye_ssh = Net::SSH.start("localhost", @rye_user, @rye_opts.merge(:port => @rye_localport) || {}) 
665:         else
666:           @rye_ssh = Net::SSH.start(@rye_host, @rye_user, @rye_opts || {}) 
667:         end
668:       rescue Net::SSH::HostKeyMismatch => ex
669:         STDERR.puts ex.message
670:         print "\a" if @rye_info # Ring the bell
671:         if highline.ask("Continue? ").strip.match(/\Ay|yes|sure|ya\z/i)
672:           @rye_opts[:paranoid] = false
673:           retry
674:         else
675:           raise Net::SSH::HostKeyMismatch
676:         end
677:       rescue Net::SSH::AuthenticationFailed => ex
678:         print "\a" if retried == 0 && @rye_info # Ring the bell once
679:         retried += 1
680: 
681:         @rye_opts[:auth_methods] ||= []
682: 
683:         # Raise Net::SSH::AuthenticationFailed if publickey is the 
684:         # only auth method
685:         if @rye_opts[:auth_methods] == ["publickey"]
686:           raise Net::SSH::AuthenticationFailed
687:         elsif STDIN.tty? && retried <= 3
688:           STDERR.puts "Passwordless login failed for #{@rye_user}"
689:           @rye_opts[:password] = highline.ask("Password: ") { |q| q.echo = '' }.strip
690:           @rye_opts[:auth_methods].push *['keyboard-interactive', 'password']
691:           retry
692:         else
693:           raise Net::SSH::AuthenticationFailed
694:         end
695:       end
696:       
697:       # We add :auth_methods (a Net::SSH joint) to force asking for a
698:       # password if the initial (key-based) authentication fails. We
699:       # need to delete the key from @rye_opts otherwise it lingers until
700:       # the next connection (if we switch_user is called for example).
701:       @rye_opts.delete :auth_methods if @rye_opts.has_key?(:auth_methods)
702:       
703:       self
704:     end