Parent

Included Modules

Class Index [+]

Quicksearch

Net::SSH::Authentication::KeyManager

This class encapsulates all operations done by clients on a user’s private keys. In practice, the client should never need a reference to a private key; instead, they grab a list of “identities” (public keys) that are available from the KeyManager, and then use the KeyManager to do various private key operations using those identities.

The KeyManager also uses the Agent class to encapsulate the ssh-agent. Thus, from a client’s perspective it is completely hidden whether an identity comes from the ssh-agent or from a file on disk.

Attributes

key_files[R]

The list of user key files that will be examined

key_data[R]

The list of user key data that will be examined

known_identities[R]

The map of loaded identities

options[R]

The map of options that were passed to the key-manager

Public Class Methods

new(logger, options={}) click to toggle source

Create a new KeyManager. By default, the manager will use the ssh-agent (if it is running).

    # File lib/net/ssh/authentication/key_manager.rb, line 41
41:         def initialize(logger, options={})
42:           self.logger = logger
43:           @key_files = []
44:           @key_data = []
45:           @use_agent = true
46:           @known_identities = {}
47:           @agent = nil
48:           @options = options
49:         end

Public Instance Methods

add(key_file) click to toggle source

Add the given key_file to the list of key files that will be used.

    # File lib/net/ssh/authentication/key_manager.rb, line 63
63:         def add(key_file)
64:           key_files.push(File.expand_path(key_file)).uniq!
65:           self
66:         end
add_key_data(key_data_) click to toggle source

Add the given key_file to the list of keys that will be used.

    # File lib/net/ssh/authentication/key_manager.rb, line 69
69:         def add_key_data(key_data_)
70:           key_data.push(key_data_).uniq!
71:           self
72:         end
agent() click to toggle source

Returns an Agent instance to use for communicating with an SSH agent process. Returns nil if use of an SSH agent has been disabled, or if the agent is otherwise not available.

     # File lib/net/ssh/authentication/key_manager.rb, line 176
176:         def agent
177:           return unless use_agent?
178:           @agent ||= Agent.connect(logger)
179:         rescue AgentNotAvailable
180:           @use_agent = false
181:           nil
182:         end
clear!() click to toggle source

Clear all knowledge of any loaded user keys. This also clears the list of default identity files that are to be loaded, thus making it appropriate to use if a client wishes to NOT use the default identity files.

    # File lib/net/ssh/authentication/key_manager.rb, line 55
55:         def clear!
56:           key_files.clear
57:           key_data.clear
58:           known_identities.clear
59:           self
60:         end
each_identity() click to toggle source

Iterates over all available identities (public keys) known to this manager. As it finds one, it will then yield it to the caller. The origin of the identities may be from files on disk or from an ssh-agent. Note that identities from an ssh-agent are always listed first in the array, with other identities coming after.

If key manager was created with :keys_only option, any identity from ssh-agent will be ignored unless it present in key_files or key_data.

     # File lib/net/ssh/authentication/key_manager.rb, line 97
 97:         def each_identity
 98:           prepared_identities = prepare_identities_from_files + prepare_identities_from_data
 99: 
100:           user_identities = load_identities(prepared_identities, false)
101: 
102:           if agent
103:             agent.identities.each do |key|
104:               corresponding_user_identity = user_identities.detect { |identity|
105:                 identity[:public_key] && identity[:public_key].to_pem == key.to_pem
106:               }
107:               user_identities.delete(corresponding_user_identity) if corresponding_user_identity
108: 
109:               if !options[:keys_only] || corresponding_user_identity
110:                 known_identities[key] = { :from => :agent }
111:                 yield key
112:               end
113:             end
114:           end
115: 
116:           user_identities = load_identities(user_identities, true)
117: 
118:           user_identities.each do |identity|
119:             key = identity.delete(:public_key)
120:             known_identities[key] = identity
121:             yield key
122:           end
123: 
124:           self
125:         end
finish() click to toggle source

This is used as a hint to the KeyManager indicating that the agent connection is no longer needed. Any other open resources may be closed at this time.

Calling this does NOT indicate that the KeyManager will no longer be used. Identities may still be requested and operations done on loaded identities, in which case, the agent will be automatically reconnected. This method simply allows the client connection to be closed when it will not be used in the immediate future.

    # File lib/net/ssh/authentication/key_manager.rb, line 83
83:         def finish
84:           @agent.close if @agent
85:           @agent = nil
86:         end
sign(identity, data) click to toggle source

Sign the given data, using the corresponding private key of the given identity. If the identity was originally obtained from an ssh-agent, then the ssh-agent will be used to sign the data, otherwise the private key for the identity will be loaded from disk (if it hasn’t been loaded already) and will then be used to sign the data.

Regardless of the identity’s origin or who does the signing, this will always return the signature in an SSH2-specified “signature blob” format.

     # File lib/net/ssh/authentication/key_manager.rb, line 136
136:         def sign(identity, data)
137:           info = known_identities[identity] or raise KeyManagerError, "the given identity is unknown to the key manager"
138: 
139:           if info[:key].nil? && info[:from] == :file
140:             begin
141:               info[:key] = KeyFactory.load_private_key(info[:file], options[:passphrase], true)
142:             rescue Exception, OpenSSL::OpenSSLError => e 
143:               raise KeyManagerError, "the given identity is known, but the private key could not be loaded: #{e.class} (#{e.message})"
144:             end
145:           end
146: 
147:           if info[:key]
148:             return Net::SSH::Buffer.from(:string, identity.ssh_type,
149:               :string, info[:key].ssh_do_sign(data.to_s)).to_s
150:           end
151: 
152:           if info[:from] == :agent
153:             raise KeyManagerError, "the agent is no longer available" unless agent
154:             return agent.sign(identity, data.to_s)
155:           end
156: 
157:           raise KeyManagerError, "[BUG] can't determine identity origin (#{info.inspect})"
158:         end
use_agent=(use_agent) click to toggle source

Toggles whether the ssh-agent will be used or not. If true, an attempt will be made to use the ssh-agent. If false, any existing connection to an agent is closed and the agent will not be used.

     # File lib/net/ssh/authentication/key_manager.rb, line 168
168:         def use_agent=(use_agent)
169:           finish if !use_agent
170:           @use_agent = use_agent
171:         end
use_agent?() click to toggle source

Identifies whether the ssh-agent will be used or not.

     # File lib/net/ssh/authentication/key_manager.rb, line 161
161:         def use_agent?
162:           @use_agent
163:         end

Private Instance Methods

load_identities(identities, ask_passphrase) click to toggle source

Load prepared identities. Private key decryption errors ignored if passphrase was not prompted.

     # File lib/net/ssh/authentication/key_manager.rb, line 206
206:         def load_identities(identities, ask_passphrase)
207:           identities.map do |identity|
208:             begin
209:               case identity[:load_from]
210:               when :pubkey_file
211:                 key = KeyFactory.load_public_key(identity[:file] + ".pub")
212:                 { :public_key => key, :from => :file, :file => identity[:file] }
213:               when :privkey_file
214:                 private_key = KeyFactory.load_private_key(identity[:file], options[:passphrase], ask_passphrase)
215:                 key = private_key.send(:public_key)
216:                 { :public_key => key, :from => :file, :file => identity[:file], :key => private_key }
217:               when :data
218:                 private_key = KeyFactory.load_data_private_key(identity[:data], options[:passphrase], ask_passphrase)
219:                 key = private_key.send(:public_key)
220:                 { :public_key => key, :from => :key_data, :data => identity[:data], :key => private_key }
221:               else
222:                 identity
223:               end
224: 
225:             rescue OpenSSL::PKey::RSAError, OpenSSL::PKey::DSAError, OpenSSL::PKey::ECError => e
226:               if ask_passphrase
227:                 process_identity_loading_error(identity, e)
228:                 nil
229:               else
230:                 identity
231:               end
232:             rescue Exception => e
233:               process_identity_loading_error(identity, e)
234:               nil
235:             end
236:           end.compact
237:         end
prepare_identities_from_data() click to toggle source

Prepared identities from user key_data, preserving their order and sources.

     # File lib/net/ssh/authentication/key_manager.rb, line 199
199:         def prepare_identities_from_data
200:           key_data.map do |data|
201:             { :load_from => :data, :data => data }
202:           end
203:         end
prepare_identities_from_files() click to toggle source

Prepares identities from user key_files for loading, preserving their order and sources.

     # File lib/net/ssh/authentication/key_manager.rb, line 187
187:         def prepare_identities_from_files
188:           key_files.map do |file|
189:             public_key_file = file + ".pub"
190:             if File.readable?(public_key_file)
191:               { :load_from => :pubkey_file, :file => file }
192:             elsif File.readable?(file)
193:               { :load_from => :privkey_file, :file => file }
194:             end
195:           end.compact
196:         end
process_identity_loading_error(identity, e) click to toggle source
     # File lib/net/ssh/authentication/key_manager.rb, line 239
239:         def process_identity_loading_error(identity, e)
240:           case identity[:load_from]
241:           when :pubkey_file
242:             error { "could not load public key file `#{identity[:file]}': #{e.class} (#{e.message})" }
243:           when :privkey_file
244:             error { "could not load private key file `#{identity[:file]}': #{e.class} (#{e.message})" }
245:           else
246:             raise e
247:           end
248:         end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.