/usr/lib/ruby/vendor_ruby/net/ssh/authentication/session.rb is in ruby-net-ssh 1:3.2.0-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | require 'net/ssh/loggable'
require 'net/ssh/transport/constants'
require 'net/ssh/authentication/constants'
require 'net/ssh/authentication/key_manager'
require 'net/ssh/authentication/methods/none'
require 'net/ssh/authentication/methods/publickey'
require 'net/ssh/authentication/methods/hostbased'
require 'net/ssh/authentication/methods/password'
require 'net/ssh/authentication/methods/keyboard_interactive'
module Net; module SSH; module Authentication
# Raised if the current authentication method is not allowed
class DisallowedMethod < Net::SSH::Exception
end
# Represents an authentication session. It manages the authentication of
# a user over an established connection (the "transport" object, see
# Net::SSH::Transport::Session).
#
# The use of an authentication session to manage user authentication is
# internal to Net::SSH (specifically Net::SSH.start). Consumers of the
# Net::SSH library will never need to access this class directly.
class Session
include Transport::Constants, Constants, Loggable
# transport layer abstraction
attr_reader :transport
# the list of authentication methods to try
attr_reader :auth_methods
# the list of authentication methods that are allowed
attr_reader :allowed_auth_methods
# a hash of options, given at construction time
attr_reader :options
# Instantiates a new Authentication::Session object over the given
# transport layer abstraction.
def initialize(transport, options={})
self.logger = transport.logger
@transport = transport
@auth_methods = options[:auth_methods] || Net::SSH::Config.default_auth_methods
@options = options
@allowed_auth_methods = @auth_methods
end
# Attempts to authenticate the given user, in preparation for the next
# service request. Returns true if an authentication method succeeds in
# authenticating the user, and false otherwise.
def authenticate(next_service, username, password=nil)
debug { "beginning authentication of `#{username}'" }
transport.send_message(transport.service_request("ssh-userauth"))
expect_message(SERVICE_ACCEPT)
key_manager = KeyManager.new(logger, options)
keys.each { |key| key_manager.add(key) } unless keys.empty?
key_data.each { |key2| key_manager.add_key_data(key2) } unless key_data.empty?
attempted = []
@auth_methods.each do |name|
begin
next unless @allowed_auth_methods.include?(name)
attempted << name
debug { "trying #{name}" }
begin
method = Methods.const_get(name.split(/\W+/).map { |p| p.capitalize }.join).new(self, :key_manager => key_manager)
rescue NameError
debug{"Mechanism #{name} was requested, but isn't a known type. Ignoring it."}
next
end
return true if method.authenticate(next_service, username, password)
rescue Net::SSH::Authentication::DisallowedMethod
end
end
error { "all authorization methods failed (tried #{attempted.join(', ')})" }
return false
ensure
key_manager.finish if key_manager
end
# Blocks until a packet is received. It silently handles USERAUTH_BANNER
# packets, and will raise an error if any packet is received that is not
# valid during user authentication.
def next_message
loop do
packet = transport.next_message
case packet.type
when USERAUTH_BANNER
info { packet[:message] }
# TODO add a hook for people to retrieve the banner when it is sent
when USERAUTH_FAILURE
@allowed_auth_methods = packet[:authentications].split(/,/)
debug { "allowed methods: #{packet[:authentications]}" }
return packet
when USERAUTH_METHOD_RANGE, SERVICE_ACCEPT
return packet
when USERAUTH_SUCCESS
transport.hint :authenticated
return packet
else
raise Net::SSH::Exception, "unexpected message #{packet.type} (#{packet})"
end
end
end
# Blocks until a packet is received, and returns it if it is of the given
# type. If it is not, an exception is raised.
def expect_message(type)
message = next_message
unless message.type == type
raise Net::SSH::Exception, "expected #{type}, got #{message.type} (#{message})"
end
message
end
private
# Returns an array of paths to the key files usually defined
# by system default.
def default_keys
if defined?(OpenSSL::PKey::EC)
%w(~/.ssh/id_ed25519 ~/.ssh/id_rsa ~/.ssh/id_dsa ~/.ssh/id_ecdsa
~/.ssh2/id_ed25519 ~/.ssh2/id_rsa ~/.ssh2/id_dsa ~/.ssh2/id_ecdsa)
else
%w(~/.ssh/id_dsa ~/.ssh/id_rsa ~/.ssh2/id_dsa ~/.ssh2/id_rsa)
end
end
# Returns an array of paths to the key files that should be used when
# attempting any key-based authentication mechanism.
def keys
Array(options[:keys] || default_keys)
end
# Returns an array of the key data that should be used when
# attempting any key-based authentication mechanism.
def key_data
Array(options[:key_data])
end
end
end; end; end
|