1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15   
 16   
 17   
 18   
 19  """ 
 20  SSH Agent interface for Unix clients. 
 21  """ 
 22   
 23  import os 
 24  import socket 
 25  import struct 
 26  import sys 
 27   
 28  from paramiko.ssh_exception import SSHException 
 29  from paramiko.message import Message 
 30  from paramiko.pkey import PKey 
 31   
 32   
 33  SSH2_AGENTC_REQUEST_IDENTITIES, SSH2_AGENT_IDENTITIES_ANSWER, \ 
 34      SSH2_AGENTC_SIGN_REQUEST, SSH2_AGENT_SIGN_RESPONSE = range(11, 15) 
 35   
 36   
 38      """ 
 39      Client interface for using private keys from an SSH agent running on the 
 40      local machine.  If an SSH agent is running, this class can be used to 
 41      connect to it and retreive L{PKey} objects which can be used when 
 42      attempting to authenticate to remote SSH servers. 
 43       
 44      Because the SSH agent protocol uses environment variables and unix-domain 
 45      sockets, this probably doesn't work on Windows.  It does work on most 
 46      posix platforms though (Linux and MacOS X, for example). 
 47      """ 
 48       
 50          """ 
 51          Open a session with the local machine's SSH agent, if one is running. 
 52          If no agent is running, initialization will succeed, but L{get_keys} 
 53          will return an empty tuple. 
 54           
 55          @raise SSHException: if an SSH agent is found, but speaks an 
 56              incompatible protocol 
 57          """ 
 58          self.keys = () 
 59          if ('SSH_AUTH_SOCK' in os.environ) and (sys.platform != 'win32'): 
 60              conn = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) 
 61              try: 
 62                  conn.connect(os.environ['SSH_AUTH_SOCK']) 
 63              except: 
 64                   
 65                  return 
 66              self.conn = conn 
 67          elif sys.platform == 'win32': 
 68              import win_pageant 
 69              if win_pageant.can_talk_to_agent(): 
 70                  self.conn = win_pageant.PageantConnection() 
 71              else: 
 72                  return 
 73          else: 
 74               
 75              return 
 76               
 77          ptype, result = self._send_message(chr(SSH2_AGENTC_REQUEST_IDENTITIES)) 
 78          if ptype != SSH2_AGENT_IDENTITIES_ANSWER: 
 79              raise SSHException('could not get keys from ssh-agent') 
 80          keys = [] 
 81          for i in range(result.get_int()): 
 82              keys.append(AgentKey(self, result.get_string())) 
 83              result.get_string() 
 84          self.keys = tuple(keys) 
  85   
 87          """ 
 88          Close the SSH agent connection. 
 89          """ 
 90          self.conn.close() 
 91          self.conn = None 
 92          self.keys = () 
  93   
 95          """ 
 96          Return the list of keys available through the SSH agent, if any.  If 
 97          no SSH agent was running (or it couldn't be contacted), an empty list 
 98          will be returned. 
 99           
100          @return: a list of keys available on the SSH agent 
101          @rtype: tuple of L{AgentKey} 
102          """ 
103          return self.keys 
 104   
106          msg = str(msg) 
107          self.conn.send(struct.pack('>I', len(msg)) + msg) 
108          l = self._read_all(4) 
109          msg = Message(self._read_all(struct.unpack('>I', l)[0])) 
110          return ord(msg.get_byte()), msg 
 111   
113          result = self.conn.recv(wanted) 
114          while len(result) < wanted: 
115              if len(result) == 0: 
116                  raise SSHException('lost ssh-agent') 
117              extra = self.conn.recv(wanted - len(result)) 
118              if len(extra) == 0: 
119                  raise SSHException('lost ssh-agent') 
120              result += extra 
121          return result 
  122   
123   
125      """ 
126      Private key held in a local SSH agent.  This type of key can be used for 
127      authenticating to a remote server (signing).  Most other key operations 
128      work as expected. 
129      """ 
130       
135   
138   
141   
 152