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) } 57: 58: attempted = [] 59: 60: @auth_methods.each do |name| 61: next unless @allowed_auth_methods.include?(name) 62: attempted << name 63: 64: debug { "trying #{name}" } 65: method = Methods.const_get(name.split(/\W+/).map { |p| p.capitalize }.join).new(self, :key_manager => key_manager) 66: 67: return true if method.authenticate(next_service, username, password) 68: end 69: 70: error { "all authorization methods failed (tried #{attempted.join(', ')})" } 71: return false 72: ensure 73: key_manager.finish if key_manager 74: 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) } 57: 58: attempted = [] 59: 60: @auth_methods.each do |name| 61: next unless @allowed_auth_methods.include?(name) 62: attempted << name 63: 64: debug { "trying #{name}" } 65: method = Methods.const_get(name.split(/\W+/).map { |p| p.capitalize }.join).new(self, :key_manager => key_manager) 66: 67: return true if method.authenticate(next_service, username, password) 68: end 69: 70: error { "all authorization methods failed (tried #{attempted.join(', ')})" } 71: return false 72: ensure 73: key_manager.finish if key_manager 74: 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 108 108: def expect_message(type) 109: message = next_message 110: unless message.type == type 111: raise Net::SSH::Exception, "expected #{type}, got #{message.type} (#{message})" 112: end 113: message 114: 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 108 108: def expect_message(type) 109: message = next_message 110: unless message.type == type 111: raise Net::SSH::Exception, "expected #{type}, got #{message.type} (#{message})" 112: end 113: message 114: 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 79 79: def next_message 80: loop do 81: packet = transport.next_message 82: 83: case packet.type 84: when USERAUTH_BANNER 85: info { packet[:message] } 86: # TODO add a hook for people to retrieve the banner when it is sent 87: 88: when USERAUTH_FAILURE 89: @allowed_auth_methods = packet[:authentications].split(/,/) 90: debug { "allowed methods: #{packet[:authentications]}" } 91: return packet 92: 93: when USERAUTH_METHOD_RANGE, SERVICE_ACCEPT 94: return packet 95: 96: when USERAUTH_SUCCESS 97: transport.hint :authenticated 98: return packet 99: 100: else 101: raise Net::SSH::Exception, "unexpected message #{packet.type} (#{packet})" 102: end 103: end 104: 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 79 79: def next_message 80: loop do 81: packet = transport.next_message 82: 83: case packet.type 84: when USERAUTH_BANNER 85: info { packet[:message] } 86: # TODO add a hook for people to retrieve the banner when it is sent 87: 88: when USERAUTH_FAILURE 89: @allowed_auth_methods = packet[:authentications].split(/,/) 90: debug { "allowed methods: #{packet[:authentications]}" } 91: return packet 92: 93: when USERAUTH_METHOD_RANGE, SERVICE_ACCEPT 94: return packet 95: 96: when USERAUTH_SUCCESS 97: transport.hint :authenticated 98: return packet 99: 100: else 101: raise Net::SSH::Exception, "unexpected message #{packet.type} (#{packet})" 102: end 103: end 104: end