U ¨Ãq`Ü1ã@sNdZddlZddlZddlZddlZddlZddlZddlZddlZddl m Z ddl m Z m Z ddl mZddlmZmZddlmZddlmZdd lmZed ƒZd Zed ƒZd ZGdd„deƒZGdd„dejƒZGdd„deƒZ Gdd„deƒZ!Gdd„deƒZ"Gdd„deƒZ#Gdd„deƒZ$Gdd„deƒZ%Gdd„deƒZ&dS) z SSH Agent interface éN)Úselect)ÚasbytesÚio_sleep)Úbyte_chr)Ú SSHExceptionÚAuthenticationException)ÚMessage)ÚPKey)Úretry_on_signalé é é éc@s<eZdZdd„Zdd„Zdd„Zdd„Zd d „Zd d „Zd S)ÚAgentSSHcCsd|_d|_dS©N©)Ú_connÚ_keys©Úselfrrú5/tmp/pip-target-nv4zd3e_/lib/python/paramiko/agent.pyÚ__init__/szAgentSSH.__init__cCs|jS)a4 Return the list of keys available through the SSH agent, if any. If no SSH agent was running (or it couldn't be contacted), an empty list will be returned. :return: a tuple of `.AgentKey` objects representing keys available on the SSH agent )rrrrrÚget_keys3s zAgentSSH.get_keyscCsd||_| t¡\}}|tkr$tdƒ‚g}t| ¡ƒD] }| t||  ¡ƒ¡|  ¡q4t |ƒ|_ dS)Nz!could not get keys from ssh-agent) rÚ _send_messageÚcSSH2_AGENTC_REQUEST_IDENTITIESÚSSH2_AGENT_IDENTITIES_ANSWERrÚrangeZget_intÚappendÚAgentKeyÚ get_binaryZ get_stringÚtupler)rÚconnÚptypeÚresultÚkeysÚirrrÚ_connect?s zAgentSSH._connectcCs$|jdk r|j ¡d|_d|_dSr)rÚcloserrrrrÚ_closeJs  zAgentSSH._closecCsXt|ƒ}|j t dt|ƒ¡|¡| d¡}t| t d|¡d¡ƒ}t |  ¡ƒ|fS)Nz>Iér) rrÚsendÚstructÚpackÚlenÚ _read_allrÚunpackÚordZget_byte)rÚmsgÚdatarrrrPs  zAgentSSH._send_messagecCsb|j |¡}t|ƒ|kr^t|ƒdkr,tdƒ‚|j |t|ƒ¡}t|ƒdkrTtdƒ‚||7}q |S)Nrúlost ssh-agent)rÚrecvr-r)rÚwantedr#Úextrarrrr.Ws     zAgentSSH._read_allN) Ú__name__Ú __module__Ú __qualname__rrr&r(rr.rrrrr.s   rc@s0eZdZdZdd„Zdd„Zdd„Zdd „Zd S) ÚAgentProxyThreadz@ Class in charge of communication between two channels. cCs"tjj||jd||_d|_dS)N)ÚtargetF)Ú threadingÚThreadrÚrunÚ_agentÚ_exit©rÚagentrrrrhszAgentProxyThread.__init__cCspz\| ¡\}}||_||_|j ¡t|jtƒsR|jjdksJt|jjdƒsRt dƒ‚|  ¡Wn‚YnXdS)NÚfilenozUnable to connect to SSH agent) Úget_connectionÚ_AgentProxyThread__inrZ_AgentProxyThread__addrr?ÚconnectÚ isinstanceÚintrÚhasattrrÚ _communicate)rÚrÚaddrrrrr>ms    ÿ þ zAgentProxyThread.runcCsìddl}| |j|j¡}| |j|j|tjB¡|jsèt|jj |jgggdƒ}|dD]„}|jj |krœ|jj   d¡}t |ƒdkrŽ|j  |¡qÚ|  ¡qÜqV|j|krV|j  d¡}t |ƒdkrÎ|jj   |¡qV|  ¡qÜqVt t¡q0dS)Nrgà?i)ÚfcntlrEZF_GETFLZF_SETFLÚosÚ O_NONBLOCKr@rr?rr4r-r*r(ÚtimeÚsleepr)rrMZoldflagsÚeventsÚfdr2rrrrJ€s&      zAgentProxyThread._communicatecCs d|_|j ¡|jj ¡dS)NT)r@rEr'r?rrrrrr(˜s zAgentProxyThread._closeN)r7r8r9Ú__doc__rr>rJr(rrrrr:cs r:c@s eZdZdZdd„Zdd„ZdS)ÚAgentLocalProxyzˆ Class to be used when wanting to ask a local SSH Agent being asked from a remote fake agent (so use a unix socket for ex.) cCst ||¡dS©N)r:rrArrrr¤szAgentLocalProxy.__init__cCsTt tjtj¡}z0| |j ¡¡| d¡| ¡\}}||fWS‚YnXdS)zX Return a pair of socket object and string address. May block! éN)ÚsocketÚAF_UNIXÚ SOCK_STREAMÚbindr?Ú _get_filenameÚlistenÚaccept)rr!rKrLrrrrD§s   zAgentLocalProxy.get_connectionN©r7r8r9rTrrDrrrrrUžsrUc@s eZdZdZdd„Zdd„ZdS)ÚAgentRemoteProxyzA Class to be used when wanting to ask a remote SSH Agent cCst ||¡||_dSrV)r:rÚ_AgentRemoteProxy__chan)rrBZchanrrrr¼s zAgentRemoteProxy.__init__cCs |jdfSrV)rarrrrrDÀszAgentRemoteProxy.get_connectionNr_rrrrr`·sr`c@s0eZdZdZdd„Zdd„Zdd„Zdd „Zd S) ÚAgentClientProxya˜ Class proxying request as a client: #. client ask for a request_forward_agent() #. server creates a proxy and a fake SSH Agent #. server ask for establishing a connection when needed, calling the forward_agent_handler at client side. #. the forward_agent_handler launch a thread for connecting the remote fake agent and the local agent #. Communication occurs ... cCs&d|_||_t||ƒ|_|j ¡dSrV)rZ_AgentClientProxy__chanRr`ÚthreadÚstart©rZ chanRemoterrrrÑs zAgentClientProxy.__init__cCs | ¡dSrV©r'rrrrÚ__del__×szAgentClientProxy.__del__cs†dtjkrJtjdkrJt tjtj¡‰zt‡fdd„ƒWq|YdSXn2tjdkrxddlm }|  ¡rr|  ¡‰q|dSndSˆ|_ dS)zJ Method automatically called by ``AgentProxyThread.run``. Ú SSH_AUTH_SOCKÚwin32csˆ tjd¡S)Nrh)rFrNÚenvironr©r!rrÚâóz*AgentClientProxy.connect..Nr) rNrjÚsysÚplatformrXrYrZr Zparamiko.win_pageantÚ win_pageantÚcan_talk_to_agentÚPageantConnectionr)rrprrkrrFÚs ÿ    zAgentClientProxy.connectcCs6t|dƒrd|j_|j d¡|jdk r2|j ¡dS)zh Close the current connection and terminate the agent Should be called manually rcTéèN)rIrcr@Újoinrr'rrrrr'ós    zAgentClientProxy.closeN)r7r8r9rTrrgrFr'rrrrrbÄs  rbc@s@eZdZdZdd„Zdd„Zdd„Zdd „Zd d „Zd d „Z dS)ÚAgentServerProxyz‘ :param .Transport t: Transport used for SSH Agent communication forwarding :raises: `.SSHException` -- mostly if we lost the agent cCsPt |¡||_t d¡|_t |jtj ¡|jd|_ t |ƒ|_ |j   ¡dS)NZsshproxyz /sshproxy.ssh)rrÚ_AgentServerProxy__tÚtempfileÚmkdtempÚ_dirrNÚchmodÚstatÚS_IRWXUÚ_filerUrcrd)rÚtrrrrs    zAgentServerProxy.__init__cCs | ¡dSrVrfrrrrrgszAgentServerProxy.__del__cCs2|j ¡}|dkrtdƒ‚| d¡| |¡dS)Nr3z auth-agent)rvZopen_forward_agent_channelrÚset_namer&)rZ conn_sockrrrrFs   zAgentServerProxy.connectcCs8t |j¡t |j¡d|j_|j d¡| ¡dS)zk Terminate the agent, clean the files, close connections Should be called manually TrsN) rNÚremover}Úrmdirryrcr@rtr(rrrrr's    zAgentServerProxy.closecCs d| ¡iS)z— Helper for the environnement under unix :return: a dict containing the ``SSH_AUTH_SOCK`` environnement variables rh)r\rrrrÚget_env$szAgentServerProxy.get_envcCs|jSrV)r}rrrrr\-szAgentServerProxy._get_filenameN) r7r8r9rTrrgrFr'r‚r\rrrrruÿs   ruc@s0eZdZdZdd„Zdd„Zdd„Zdd „Zd S) ÚAgentRequestHandlera¥ Primary/default implementation of SSH agent forwarding functionality. Simply instantiate this class, handing it a live command-executing session object, and it will handle forwarding any local SSH agent processes it finds. For example:: # Connect client = SSHClient() client.connect(host, port, username) # Obtain session session = client.get_transport().open_session() # Forward local agent AgentRequestHandler(session) # Commands executed after this point will see the forwarded agent on # the remote end. session.exec_command("git clone https://my.git.repository/") cCs"d|_||_| |j¡g|_dSrV)rZ_AgentRequestHandler__chanCZrequest_forward_agentÚ_forward_agent_handlerÚ"_AgentRequestHandler__clientProxys)rZ chanClientrrrrGs zAgentRequestHandler.__init__cCs|j t|ƒ¡dSrV)r…rrbrerrrr„Msz*AgentRequestHandler._forward_agent_handlercCs | ¡dSrVrfrrrrrgPszAgentRequestHandler.__del__cCs|jD] }| ¡qdSrV)r…r')rÚprrrr'Ss zAgentRequestHandler.closeN)r7r8r9rTrr„rgr'rrrrrƒ1s rƒc@s eZdZdZdd„Zdd„ZdS)ÚAgentaL Client interface for using private keys from an SSH agent running on the local machine. If an SSH agent is running, this class can be used to connect to it and retrieve `.PKey` objects which can be used when attempting to authenticate to remote SSH servers. Upon initialization, a session with the local machine's SSH agent is opened, if one is running. If no agent is running, initialization will succeed, but `get_keys` will return an empty tuple. :raises: `.SSHException` -- if an SSH agent is found, but speaks an incompatible protocol cCs”t |¡dtjkrTtjdkrTt tjtj¡}z|  tjd¡Wq†YdSXn2tjdkr‚ddl m }|  ¡r||  ¡}q†dSndS| |¡dS)NrhrirW)rp)rrrNrjrnrorXrYrZrFÚrprqrrr&)rr!rprrrrgs     zAgent.__init__cCs | ¡dS)z1 Close the SSH agent connection. N)r(rrrrr'}sz Agent.closeN)r7r8r9rTrr'rrrrr‡Xsr‡c@s8eZdZdZdd„Zdd„Zdd„Zdd „Zd d „Zd S) rz´ Private key held in a local SSH agent. This type of key can be used for authenticating to a remote server (signing). Most other key operations work as expected. cCs$||_||_d|_t|ƒ ¡|_dSrV)rBÚblobZ public_blobrZget_textÚname)rrBr‰rrrr‹szAgentKey.__init__cCs|jSrV)r‰rrrrr‘szAgentKey.asbytescCs| ¡SrV)rrrrrÚ__str__”szAgentKey.__str__cCs|jSrV)rŠrrrrÚget_name—szAgentKey.get_namecCsXtƒ}| t¡| |j¡| |¡| d¡|j |¡\}}|tkrPt dƒ‚|  ¡S)Nrzkey cannot be used for signing) rZadd_byteÚcSSH2_AGENTC_SIGN_REQUESTZ add_stringr‰Zadd_intrBrÚSSH2_AGENT_SIGN_RESPONSErr)rr2r1r"r#rrrÚ sign_ssh_datašs    zAgentKey.sign_ssh_dataN) r7r8r9rTrrr‹rŒrrrrrr„s r)'rTrNrXr+rnr<rPrwr{rZparamiko.commonrrZparamiko.py3compatrZparamiko.ssh_exceptionrrZparamiko.messagerZ paramiko.pkeyr Z paramiko.utilr rrrrŽÚobjectrr=r:rUr`rbrurƒr‡rrrrrÚs8     5; ;2',