Class | Net::SSH::Authentication::Session |
In: |
lib/net/ssh/authentication/session.rb
lib/net/ssh/authentication/session.rb |
Parent: | Object |
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.
allowed_auth_methods | [R] | the list of authentication methods that are allowed |
allowed_auth_methods | [R] | the list of authentication methods that are allowed |
auth_methods | [R] | the list of authentication methods to try |
auth_methods | [R] | the list of authentication methods to try |
options | [R] | a hash of options, given at construction time |
options | [R] | a hash of options, given at construction time |
transport | [R] | transport layer abstraction |
transport | [R] | transport layer abstraction |
Instantiates a new Authentication::Session object over the given transport layer abstraction.
# File lib/net/ssh/authentication/session.rb, line 36 36: def initialize(transport, options={}) 37: self.logger = transport.logger 38: @transport = transport 39: 40: @auth_methods = options[:auth_methods] || %w(publickey hostbased password keyboard-interactive) 41: @options = options 42: 43: @allowed_auth_methods = @auth_methods 44: end
Instantiates a new Authentication::Session object over the given transport layer abstraction.
# File lib/net/ssh/authentication/session.rb, line 36 36: def initialize(transport, options={}) 37: self.logger = transport.logger 38: @transport = transport 39: 40: @auth_methods = options[:auth_methods] || %w(publickey hostbased password keyboard-interactive) 41: @options = options 42: 43: @allowed_auth_methods = @auth_methods 44: 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.
# File lib/net/ssh/authentication/session.rb, line 49 49: def authenticate(next_service, username, password=nil) 50: debug { "beginning authentication of `#{username}'" } 51: 52: transport.send_message(transport.service_request("ssh-userauth")) 53: message = expect_message(SERVICE_ACCEPT) 54: 55: key_manager = KeyManager.new(logger, options) 56: keys.each { |key| key_manager.add(key) } unless keys.empty? 57: key_data.each { |key2| key_manager.add_key_data(key2) } unless key_data.empty? 58: 59: attempted = [] 60: 61: @auth_methods.each do |name| 62: next unless @allowed_auth_methods.include?(name) 63: attempted << name 64: 65: debug { "trying #{name}" } 66: method = Methods.const_get(name.split(/\W+/).map { |p| p.capitalize }.join).new(self, :key_manager => key_manager) 67: 68: return true if method.authenticate(next_service, username, password) 69: end 70: 71: error { "all authorization methods failed (tried #{attempted.join(', ')})" } 72: return false 73: ensure 74: key_manager.finish if key_manager 75: 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.
# File lib/net/ssh/authentication/session.rb, line 49 49: def authenticate(next_service, username, password=nil) 50: debug { "beginning authentication of `#{username}'" } 51: 52: transport.send_message(transport.service_request("ssh-userauth")) 53: message = expect_message(SERVICE_ACCEPT) 54: 55: key_manager = KeyManager.new(logger, options) 56: keys.each { |key| key_manager.add(key) } unless keys.empty? 57: key_data.each { |key2| key_manager.add_key_data(key2) } unless key_data.empty? 58: 59: attempted = [] 60: 61: @auth_methods.each do |name| 62: next unless @allowed_auth_methods.include?(name) 63: attempted << name 64: 65: debug { "trying #{name}" } 66: method = Methods.const_get(name.split(/\W+/).map { |p| p.capitalize }.join).new(self, :key_manager => key_manager) 67: 68: return true if method.authenticate(next_service, username, password) 69: end 70: 71: error { "all authorization methods failed (tried #{attempted.join(', ')})" } 72: return false 73: ensure 74: key_manager.finish if key_manager 75: 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.
# File lib/net/ssh/authentication/session.rb, line 109 109: def expect_message(type) 110: message = next_message 111: unless message.type == type 112: raise Net::SSH::Exception, "expected #{type}, got #{message.type} (#{message})" 113: end 114: message 115: 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.
# File lib/net/ssh/authentication/session.rb, line 109 109: def expect_message(type) 110: message = next_message 111: unless message.type == type 112: raise Net::SSH::Exception, "expected #{type}, got #{message.type} (#{message})" 113: end 114: message 115: 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.
# File lib/net/ssh/authentication/session.rb, line 80 80: def next_message 81: loop do 82: packet = transport.next_message 83: 84: case packet.type 85: when USERAUTH_BANNER 86: info { packet[:message] } 87: # TODO add a hook for people to retrieve the banner when it is sent 88: 89: when USERAUTH_FAILURE 90: @allowed_auth_methods = packet[:authentications].split(/,/) 91: debug { "allowed methods: #{packet[:authentications]}" } 92: return packet 93: 94: when USERAUTH_METHOD_RANGE, SERVICE_ACCEPT 95: return packet 96: 97: when USERAUTH_SUCCESS 98: transport.hint :authenticated 99: return packet 100: 101: else 102: raise Net::SSH::Exception, "unexpected message #{packet.type} (#{packet})" 103: end 104: end 105: 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.
# File lib/net/ssh/authentication/session.rb, line 80 80: def next_message 81: loop do 82: packet = transport.next_message 83: 84: case packet.type 85: when USERAUTH_BANNER 86: info { packet[:message] } 87: # TODO add a hook for people to retrieve the banner when it is sent 88: 89: when USERAUTH_FAILURE 90: @allowed_auth_methods = packet[:authentications].split(/,/) 91: debug { "allowed methods: #{packet[:authentications]}" } 92: return packet 93: 94: when USERAUTH_METHOD_RANGE, SERVICE_ACCEPT 95: return packet 96: 97: when USERAUTH_SUCCESS 98: transport.hint :authenticated 99: return packet 100: 101: else 102: raise Net::SSH::Exception, "unexpected message #{packet.type} (#{packet})" 103: end 104: end 105: end