A wrapper around the transport layer that represents the functionality of user authentication.
| [W] | key_manager | The UserKeyManager instance used by the auth service. |
| [R] | order | The array of auth-method names (as strings), giving the order in which each auth-method will be tried. |
| [W] | session | The SSH (transport) session to use for communication. |
Create a new user-auth service on top of the given session.
[ show source ]
# File lib/net/ssh/userauth/driver.rb, line 44
44: def initialize( log, buffers, methods, order )
45: @log = log
46: @buffers = buffers
47: @methods = methods
48: @on_banner = proc { |msg,lang| puts msg }
49: @order = order.dup
50: @allowed_auth_methods = nil
51: end
Processes the authentication of the given username. The ‘next_service’ parameter should be set to the SSH service that will be requested once the authentication succeeds (usually ‘ssh-connection’).
This will return true if the user is accepted by the server, and false otherwise.
[ show source ]
# File lib/net/ssh/userauth/driver.rb, line 140
140: def authenticate( next_service, username, password=nil )
141: msg = @buffers.writer
142: msg.write_byte SERVICE_REQUEST
143: msg.write_string "ssh-userauth"
144: send_message msg
145:
146: message = wait_for_message
147: unless message.message_type == SERVICE_ACCEPT
148: raise Net::SSH::Exception,
149: "expected SERVICE_ACCEPT, got #{message.inspect}"
150: end
151:
152: data = { :password => password,
153: :key_manager => @key_manager }
154:
155: @order.each do |auth_method|
156: # if the server has reported a list of auth methods that are
157: # allowed to continue, only consider those auth methods.
158: next if @allowed_auth_methods &&
159: !@allowed_auth_methods.include?( auth_method )
160:
161: @log.debug "trying #{auth_method.inspect}" if @log.debug?
162:
163: impl = @methods[ auth_method.downcase.gsub(/-/,"_").intern ]
164: if impl.nil?
165: raise NotImplementedError,
166: "`#{auth_method}' authentication is not implemented"
167: end
168:
169: return true if impl.authenticate( next_service, username, data )
170: end
171:
172: @log.debug "all authorization methods failed" if @log.debug?
173: return false
174:
175: ensure
176: @key_manager.finish
177: end
Specify the callback to use when the server sends a banner message at login time.
[ show source ]
# File lib/net/ssh/userauth/driver.rb, line 78
78: def on_banner( &block )
79: @on_banner = block
80: end
Sends the message by delegating to the session’s send_message method. (This is a convenience method for the authentication implementations.)
[ show source ]
# File lib/net/ssh/userauth/driver.rb, line 85
85: def send_message( message )
86: @session.send_message message
87: end
Changes the set of authentication methods to try to the given array. Methods are tried in the order in which they are listed in the array.
[ show source ]
# File lib/net/ssh/userauth/driver.rb, line 72
72: def set_auth_method_order( *methods )
73: @order = methods.flatten
74: end
Causes the set of on-disk host key files to be used to be set to the given array. Any host key files that were specified previously are lost.
[ show source ]
# File lib/net/ssh/userauth/driver.rb, line 64
64: def set_host_key_files( files )
65: @key_manager.clear_host!
66: files.each { |file| @key_manager.add_host_key file }
67: end
Causes the set of on-disk key files to be used to be set to the given array. Any key files that were specified previously are lost.
[ show source ]
# File lib/net/ssh/userauth/driver.rb, line 56
56: def set_key_files( files )
57: @key_manager.clear!
58: files.each { |file| @key_manager << file }
59: end
Wraps the Net::SSH::Transport::Session#wait_for_message method, doing special checking for authentication-related messages.
[ show source ]
# File lib/net/ssh/userauth/driver.rb, line 91
91: def wait_for_message
92: loop do
93: type, buffer = @session.wait_for_message
94:
95: case type
96: when USERAUTH_BANNER
97: message = buffer.read_string
98: language = buffer.read_string
99:
100: if @log.debug?
101: @log.debug "got USERAUTH_BANNER (#{message}:#{language})"
102: end
103:
104: @on_banner.call( message, language )
105:
106: when USERAUTH_FAILURE
107: authentications = buffer.read_string
108: @allowed_auth_methods = authentications.split(/,/)
109: partial_success = buffer.read_bool
110: return OpenStruct.new( :message_type => type,
111: :authentications => authentications,
112: :partial_success => partial_success )
113:
114: when USERAUTH_SUCCESS
115: return OpenStruct.new( :message_type => type )
116:
117: when SERVICE_ACCEPT
118: return OpenStruct.new( :message_type => type,
119: :service_name => buffer.read_string )
120:
121: # authmethod-specific codes
122: when 60..79
123: return OpenStruct.new( :message_type => type,
124: :buffer => buffer )
125:
126: else
127: raise Net::SSH::Exception,
128: "unexpected message type '#{type}' (#{buffer.to_s})"
129: end
130: end
131: end