connection_strategy (Capistrano::SSH)

    # File lib/capistrano/ssh.rb, line 54
        def self.connection_strategy(server, options={}, &block)
          methods = [ %w(publickey hostbased), %w(password keyboard-interactive) ]
          password_value = nil

          # construct the hash of ssh options that should be passed more-or-less
          # directly to Net::SSH. This will be the general ssh options, merged with
          # the server-specific ssh-options.
          ssh_options = (options[:ssh_options] || {}).merge(server.options[:ssh_options] || {})

          # load any SSH configuration files that were specified in the SSH options. This
          # will load from ~/.ssh/config and /etc/ssh_config by default (see Net::SSH
          # for details). Merge the explicitly given ssh_options over the top of the info
          # from the config file.
          ssh_options = Net::SSH.configuration_for(server.host, ssh_options.fetch(:config, true)).merge(ssh_options)

          # Once we've loaded the config, we don't need Net::SSH to do it again.
          ssh_options[:config] = false

          ssh_options[:verbose] = :debug if options[:verbose] && options[:verbose] > 0

          user = server.user || options[:user] || ssh_options[:username] ||
                 ssh_options[:user] || ServerDefinition.default_user
          port = server.port || options[:port] || ssh_options[:port]

          # the .ssh/config file might have changed the host-name on us
          host = ssh_options.fetch(:host_name, server.host)

          ssh_options[:port] = port if port

          # delete these, since we've determined which username to use by this point
          ssh_options.delete(:username)
          ssh_options.delete(:user)

          begin
            connection_options = ssh_options.merge(
              :password => password_value,
              :auth_methods => ssh_options[:auth_methods] || methods.shift
            )

            yield host, user, connection_options
          rescue Net::SSH::AuthenticationFailed
            raise if methods.empty? || ssh_options[:auth_methods]
            password_value = options[:password]
            retry
          end
        end