Class | Net::SSH::Authentication::Agent |
In: |
lib/net/ssh/authentication/agent.rb
lib/net/ssh/authentication/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_ANSWER1 | = | 2 |
SSH_AGENT_RSA_IDENTITIES_ANSWER2 | = | 5 |
SSH_AGENT_FAILURE | = | 5 |
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_ANSWER1 | = | 2 |
SSH_AGENT_RSA_IDENTITIES_ANSWER2 | = | 5 |
SSH_AGENT_FAILURE | = | 5 |
Instantiates a new agent object, connects to a running SSH agent, negotiates the agent protocol version, and returns the agent object.
# File lib/net/ssh/authentication/agent.rb, line 51 51: def self.connect(logger=nil) 52: agent = new(logger) 53: agent.connect! 54: agent.negotiate! 55: agent 56: end
Instantiates a new agent object, connects to a running SSH agent, negotiates the agent protocol version, and returns the agent object.
# File lib/net/ssh/authentication/agent.rb, line 51 51: def self.connect(logger=nil) 52: agent = new(logger) 53: agent.connect! 54: agent.negotiate! 55: agent 56: end
Closes this socket. This agent reference is no longer able to query the agent.
# File lib/net/ssh/authentication/agent.rb, line 112 112: def close 113: @socket.close 114: end
Closes this socket. This agent reference is no longer able to query the agent.
# File lib/net/ssh/authentication/agent.rb, line 112 112: def close 113: @socket.close 114: 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/authentication/agent.rb, line 68 68: def connect! 69: begin 70: debug { "connecting to ssh-agent" } 71: @socket = agent_socket_factory.open(ENV['SSH_AUTH_SOCK']) 72: rescue 73: error { "could not connect to ssh-agent" } 74: raise AgentNotAvailable, $!.message 75: end 76: 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/authentication/agent.rb, line 68 68: def connect! 69: begin 70: debug { "connecting to ssh-agent" } 71: @socket = agent_socket_factory.open(ENV['SSH_AUTH_SOCK']) 72: rescue 73: error { "could not connect to ssh-agent" } 74: raise AgentNotAvailable, $!.message 75: end 76: 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/authentication/agent.rb, line 94 94: def identities 95: type, body = send_and_wait(SSH2_AGENT_REQUEST_IDENTITIES) 96: raise AgentError, "could not get identity count" if agent_failed(type) 97: raise AgentError, "bad authentication reply: #{type}" if type != SSH2_AGENT_IDENTITIES_ANSWER 98: 99: identities = [] 100: body.read_long.times do 101: key = Buffer.new(body.read_string).read_key 102: key.extend(Comment) 103: key.comment = body.read_string 104: identities.push key 105: end 106: 107: return identities 108: 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/authentication/agent.rb, line 94 94: def identities 95: type, body = send_and_wait(SSH2_AGENT_REQUEST_IDENTITIES) 96: raise AgentError, "could not get identity count" if agent_failed(type) 97: raise AgentError, "bad authentication reply: #{type}" if type != SSH2_AGENT_IDENTITIES_ANSWER 98: 99: identities = [] 100: body.read_long.times do 101: key = Buffer.new(body.read_string).read_key 102: key.extend(Comment) 103: key.comment = body.read_string 104: identities.push key 105: end 106: 107: return identities 108: end
Attempts to negotiate the SSH agent protocol version. Raises an error if the version could not be negotiated successfully.
# File lib/net/ssh/authentication/agent.rb, line 80 80: def negotiate! 81: # determine what type of agent we're communicating with 82: type, body = send_and_wait(SSH2_AGENT_REQUEST_VERSION, :string, Transport::ServerVersion::PROTO_VERSION) 83: 84: if type == SSH2_AGENT_VERSION_RESPONSE 85: raise NotImplementedError, "SSH2 agents are not yet supported" 86: elsif type != SSH_AGENT_RSA_IDENTITIES_ANSWER1 && type != SSH_AGENT_RSA_IDENTITIES_ANSWER2 87: raise AgentError, "unknown response from agent: #{type}, #{body.to_s.inspect}" 88: end 89: end
Attempts to negotiate the SSH agent protocol version. Raises an error if the version could not be negotiated successfully.
# File lib/net/ssh/authentication/agent.rb, line 80 80: def negotiate! 81: # determine what type of agent we're communicating with 82: type, body = send_and_wait(SSH2_AGENT_REQUEST_VERSION, :string, Transport::ServerVersion::PROTO_VERSION) 83: 84: if type == SSH2_AGENT_VERSION_RESPONSE 85: raise NotImplementedError, "SSH2 agents are not yet supported" 86: elsif type != SSH_AGENT_RSA_IDENTITIES_ANSWER1 && type != SSH_AGENT_RSA_IDENTITIES_ANSWER2 87: raise AgentError, "unknown response from agent: #{type}, #{body.to_s.inspect}" 88: end 89: end
Using the agent and the given public key, sign the given data. The signature is returned in SSH2 format.
# File lib/net/ssh/authentication/agent.rb, line 118 118: def sign(key, data) 119: type, reply = send_and_wait(SSH2_AGENT_SIGN_REQUEST, :string, Buffer.from(:key, key), :string, data, :long, 0) 120: 121: if agent_failed(type) 122: raise AgentError, "agent could not sign data with requested identity" 123: elsif type != SSH2_AGENT_SIGN_RESPONSE 124: raise AgentError, "bad authentication response #{type}" 125: end 126: 127: return reply.read_string 128: end
Using the agent and the given public key, sign the given data. The signature is returned in SSH2 format.
# File lib/net/ssh/authentication/agent.rb, line 118 118: def sign(key, data) 119: type, reply = send_and_wait(SSH2_AGENT_SIGN_REQUEST, :string, Buffer.from(:key, key), :string, data, :long, 0) 120: 121: if agent_failed(type) 122: raise AgentError, "agent could not sign data with requested identity" 123: elsif type != SSH2_AGENT_SIGN_RESPONSE 124: raise AgentError, "bad authentication response #{type}" 125: end 126: 127: return reply.read_string 128: end