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
656: retried = 0
657: @rye_opts[:keys].compact!
658: begin
659: if @rye_via
660:
661:
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
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
679: retried += 1
680:
681: @rye_opts[:auth_methods] ||= []
682:
683:
684:
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:
698:
699:
700:
701: @rye_opts.delete :auth_methods if @rye_opts.has_key?(:auth_methods)
702:
703: self
704: end