Class | Net::SSH::UserAuth::Agent |
In: |
lib/net/ssh/userauth/agent.rb
|
Parent: | Object |
This class implements a simple client for the ssh-agent protocol. It does not implement any specific protocol, but instead copies the behavior of the ssh-agent functions in the OpenSSH library (3.8).
This means that although it behaves like a SSH1 client, it also has some SSH2 functionality (like signing data).
SSH2_AGENT_REQUEST_VERSION | = | 1 |
SSH2_AGENT_REQUEST_IDENTITIES | = | 11 |
SSH2_AGENT_IDENTITIES_ANSWER | = | 12 |
SSH2_AGENT_SIGN_REQUEST | = | 13 |
SSH2_AGENT_SIGN_RESPONSE | = | 14 |
SSH2_AGENT_FAILURE | = | 30 |
SSH2_AGENT_VERSION_RESPONSE | = | 103 |
SSH_COM_AGENT2_FAILURE | = | 102 |
SSH_AGENT_REQUEST_RSA_IDENTITIES | = | 1 |
SSH_AGENT_RSA_IDENTITIES_ANSWER | = | 2 |
SSH_AGENT_FAILURE | = | 5 |
buffers | [W] | The buffer factory to use to obtain buffer instances. |
keys | [W] | The key factory to use to obtain key instances. |
socket_factory | [W] | The socket factory used to connect to the agent process. It must respond to open, and accept a single parameter (the name of the socket to open). |
socket_name | [W] | The name of the socket to open. |
version | [W] | The version of the SSH protocol version to report. |
Closes this socket. This agent reference is no longer able to query the agent.
# File lib/net/ssh/userauth/agent.rb, line 145 145: def close 146: @socket.close 147: end
Connect to the agent process using the socket factory and socket name given by the attribute writers. If the agent on the other end of the socket reports that it is an SSH2-compatible agent, this will fail (it only supports the ssh-agent distributed by OpenSSH).
# File lib/net/ssh/userauth/agent.rb, line 69 69: def connect! 70: @socket = @socket_factory.open( @socket_name ) 71: 72: # determine what type of agent we're communicating with 73: buffer = @buffers.writer 74: buffer.write_string Net::SSH::Transport::Session.version 75: type, body = send_with_reply SSH2_AGENT_REQUEST_VERSION, buffer 76: 77: if type == SSH2_AGENT_VERSION_RESPONSE 78: raise NotImplementedError, "SSH2 agents are not yet supported" 79: elsif type != SSH_AGENT_RSA_IDENTITIES_ANSWER 80: raise AgentError, 81: "unknown response from agent: #{type}, #{body.to_s.inspect}" 82: end 83: end
Return an array of all identities (public keys) known to the agent. Each key returned is augmented with a comment property which is set to the comment returned by the agent for that key.
# File lib/net/ssh/userauth/agent.rb, line 88 88: def identities 89: case @version 90: when 1 91: code1 = SSH_AGENT_REQUEST_RSA_IDENTITIES 92: code2 = SSH_AGENT_RSA_IDENTITIES_ANSWER 93: when 2 94: code1 = SSH2_AGENT_REQUEST_IDENTITIES 95: code2 = SSH2_AGENT_IDENTITIES_ANSWER 96: else 97: raise NotImplementedError, "SSH version #{@version}" 98: end 99: 100: type, body = send_with_reply code1 101: raise AgentError, 102: "could not get identity count" if agent_failed( type ) 103: raise AgentError, "bad authentication reply: #{type}" if type != code2 104: 105: identities = [] 106: body.read_long.times do 107: case @version 108: when 1 109: key = @keys.get( "rsa" ) 110: bits = body.read_long 111: key.e = body.read_bignum 112: key.n = body.read_bignum 113: when 2 114: blob = @buffers.reader( body.read_string ) 115: key = blob.read_key 116: end 117: 118: unless key.respond_to?( :comment= ) 119: key.instance_eval "def comment=(cmt)\n@comment = cmt\nend\n" 120: end 121: 122: unless key.respond_to?( :comment ) 123: key.instance_eval "def comment\n@comment\nend\n" 124: end 125: 126: key.comment = body.read_string 127: identities.push key 128: end 129: 130: return identities 131: end
Using the agent and the given public key, sign the given data. The signature is returned in SSH2 format.
# File lib/net/ssh/userauth/agent.rb, line 151 151: def sign( key, data ) 152: blob = @buffers.writer 153: blob.write_key key 154: 155: packet_data = @buffers.writer 156: packet_data.write_string blob.to_s 157: packet_data.write_string data.to_s 158: packet_data.write_long 0 159: 160: type, reply = send_with_reply SSH2_AGENT_SIGN_REQUEST, packet_data 161: if agent_failed( type ) 162: raise AgentError, 163: "agent could not sign data with requested identity" 164: elsif type != SSH2_AGENT_SIGN_RESPONSE 165: raise AgentError, "bad authentication response #{type}" 166: end 167: 168: return reply.read_string 169: end