U
     T‚gG  ã                   @   sª  d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlmZm	Z	 d dl
mZmZ d dlmZ d dlmZ d dlmZmZmZmZmZ d dlmZmZmZ d dlmZmZ d d	lmZm Z  G d
d„ deƒZ!da"da#d a$da%d a&da'dd„ Z(dd„ Z)dd„ Z*dd„ Z+dd„ Z,dd„ Z-dd„ Z.dd„ Z/dd„ Z0G dd„ dƒZ1G d d!„ d!ej2ƒZ2G d"d#„ d#ej3ƒZ4G d$d%„ d%ej5ƒZ5G d&d'„ d'ej6ƒZ6d(d)„ Z7d*d+„ Z8e9d,k�r¦e(ƒ  dS )-é    N)ÚListÚTuple)ÚconnectÚdefault)ÚConchOptions)Ú
ConchError)ÚchannelÚcommonÚ
connectionÚ
forwardingÚsession)ÚreactorÚstdioÚtask)ÚlogÚusage)ÚioTypeÚnetworkStringc                	   @   s  e Zd ZU dZdZdddgdddd	gd
dddggZdddgdddgdddgdddgdddgdddggZejdgej	d d!�ej	d d!�d"œe 
¡ ej	d#d!�ej	d$d%d&�gd'�Zg Zeeeeeef f  ed(< g Zeeeeeef f  ed)< d*d+„ Zd,d-„ Zd.d/„ Zd0d1„ ZdS )2ÚClientOptionsz(Usage:   conch [options] host [command]
zYconch is a SSHv2 client that allows logging into a remote machine and executing commands.ÚescapeÚeú~ÚlocalforwardÚLNz<listen-port:host:port   Forward local port to remote addressÚremoteforwardÚRz<listen-port:host:port   Forward remote port to local addressÚnullÚnzRedirect input from /dev/null.ÚforkÚfz(Fork to background after authentication.ÚttyÚtz-Tty; allocate a tty even if command is given.ÚnottyÚTzDo not allocate a tty.ÚnoshellÚNz"Do not execute a shell or command.Ú	subsystemÚsz-Invoke command (mandatory) as SSH2 subsystem.)r    r"   zlisten-port:host:port)Údescr)r   r   ÚcommandÚargumentT)r(   Úrepeat)ZmutuallyExclusiveZ
optActionsZextraActionsÚlocalForwardsÚremoteForwardsc                 C   sp   |dkrd| d< nZ|d dkrDt |ƒdkrDtt|d ƒd ƒ| d< n(t |ƒdkrZ|| d< nt d	|› d
�¡ dS )z:
        Set escape character; ``none'' = disable
        ÚnoneNr   r   ú^é   é   é@   zBad escape character 'z'.)ÚlenÚchrÚordÚsysÚexit)ÚselfÚesc© r:   ú?/tmp/pip-unpacked-wheel-1_7di8ic/twisted/conch/scripts/conch.pyÚ
opt_escapeO   s    

zClientOptions.opt_escapec                 C   s8   |  d¡\}}}t|ƒ}t|ƒ}| j |||ff¡ dS )zH
        Forward local port to remote address (lport:host:port)
        ú:N)ÚsplitÚintr,   Úappend)r8   r   Ú	localPortZ
remoteHostÚ
remotePortr:   r:   r;   Úopt_localforward\   s    zClientOptions.opt_localforwardc                 C   s8   |  d¡\}}}t|ƒ}t|ƒ}| j |||ff¡ dS )zH
        Forward remote port to local address (rport:host:port)
        r=   N)r>   r?   r-   r@   )r8   r   rB   ZconnHostZconnPortr:   r:   r;   Úopt_remoteforwarde   s    zClientOptions.opt_remoteforwardc                 G   s   || d< d  |¡| d< d S )NÚhostú r)   )Újoin)r8   rE   r)   r:   r:   r;   Ú	parseArgsn   s    zClientOptions.parseArgs)Ú__name__Ú
__module__Ú__qualname__ZsynopsisZlongdescZoptParametersZoptFlagsr   ZCompletionsZ	CompleterZCompleteUserAtHostZcompDatar,   r   r   r?   Ú__annotations__r-   r<   rC   rD   rH   r:   r:   r:   r;   r      sL   
ÿüüøú	

þ
ýú  		r   c                  C   sv  t jdd … } d| krF|  d¡}| ||d … |  } | |d |d …= | d d … D ]\}zB|  |¡}|d d… dkr–| |d  d dkr–g | ||d …< W qR tk
r¬   Y qRX qRtƒ azt | ¡ W nF tjk
�r
 } z$t	d|› �ƒ t 
¡  t  d¡ W 5 d }~X Y nX td	 �rdtd
 �rFtd
 dk�r6t j}nttd
 dƒ}nt j}t j}t |¡ |t _nt ¡  tƒ  t j ¡ }zt |¡aW n tk
�r¤   d aY nX zt tjdd„ ¡}W n tk
�rÖ   d }Y nX zt  ¡  W 5 t�rüt |tjt¡ |�rt tj|¡ td �r$td �s.td �s>t tjtj¡ X t j !¡ �rhtd �sht	d "td ¡ƒ t  t#¡ d S )Nr1   z-lr0   é   z-or   ú-zERROR: r   Úlogfileza+c                  W   s   t  dt¡S ©Nr   )r   Ú	callLaterÚ	reConnect)Úar:   r:   r;   Ú<lambda>¦   ó    zrun.<locals>.<lambda>r)   r    r"   zConnection to {} closed.rE   )$r6   ÚargvÚindexÚ
ValueErrorr   ÚoptionsZparseOptionsr   Z
UsageErrorÚprintZopt_helpr7   ÚstdoutÚopenÚstderrr   ZstartLoggingZdiscardLogsÚ	doConnectÚstdinÚfilenor    Ú	tcgetattrÚoldÚBaseExceptionÚsignalÚSIGUSR1Ú	tcsetattrÚTCSANOWÚSIGWINCHÚSIG_DFLr   ÚrunÚisattyÚformatÚ
exitStatus)ÚargsÚiÚargÚur   ZrealoutÚfdZoldUSR1r:   r:   r;   rj   |   sj    

$




 ÿ
rj   c                  C   s0   ddl m}  dat dt¡ t |  ¡ ¡ ‚ d S )Nr   ©Úfailurer0   g{®Gáz„?)	Útwisted.pythonrt   rm   r   rQ   Ú_stopReactorr   ÚerrZFailurers   r:   r:   r;   ÚhandleError¸   s
    rx   c                   C   s&   zt  ¡  W n tk
r    Y nX d S ©N)r   Ústoprc   r:   r:   r:   r;   rv   Â   s    rv   c                  C   sÔ   dt d kr(t d  dd¡\t d< t d< t js8ddgt _t d } t d sTt ¡ t d< t d sfdt d< ntt d ƒt d< t d } t d }tj}t d	 s¤t | t ¡t d	< t 	t d t t
ƒ ¡}t | |t ||¡ t¡ d S )
Nú@rE   r1   Úuserz~/.ssh/id_rsaz~/.ssh/id_dsaÚporté   zhost-key-algorithms)rY   r>   Z	identitysÚgetpassÚgetuserr?   r   ZverifyHostKeyZgetHostKeyAlgorithmsZSSHUserAuthClientÚSSHConnectionr   Ú
addErrbackÚ_ebExit)rE   r}   ZvhkZuaor:   r:   r;   r^   É   s"    

r^   c                 C   s   d| › �a t dt¡ d S )Nzconch: exiting with error çš™™™™™¹?)rm   r   rQ   rv   )r   r:   r:   r;   rƒ   Þ   s    
rƒ   c                  C   s0  t tjdƒrttƒ tjrLtjD ]*\} }t | t 	t|t
¡¡}tj |¡ q tjr’tjD ]*\}}t d|› d|› �¡ t ||¡ qXt ddt¡ td r¢td r®t tƒ ¡ td �r,t ¡ rÊt d	¡ t ¡  td
ƒD ]P}zt |¡ W qÚ tk
�r( } zd	d l}|j|jk�r‚ W 5 d }~X Y qÚX qÚd S )NZ
sendIgnorez!asking for remote forwarding for r=   ÚbeforeÚshutdownr$   Úagentr   r   é   )ÚhasattrÚconnÚ	transportÚ
_KeepAliverY   r,   r   Z	listenTCPr   ZSSHListenForwardingFactoryÚ SSHListenClientForwardingChannelr@   r-   r   ÚmsgÚrequestRemoteForwardingZaddSystemEventTriggerÚbeforeShutdownZopenChannelÚ
SSHSessionÚosr   Ú_exitÚsetsidÚrangeÚcloseÚOSErrorÚerrnoÚEBADF)rA   Úhostportr'   rB   ro   r   r˜   r:   r:   r;   Ú	onConnectä   s>      ÿþ

r›   c                   C   s   t ƒ  tjj ¡  d S ry   )r�   rŠ   r‹   ÚloseConnectionr:   r:   r:   r;   rR     s    rR   c                  C   s8   t j} | D ](\}}t d|› d|› �¡ t |¡ q
d S )Nzcancelling r=   )rY   r-   r   rŽ   rŠ   ÚcancelRemoteForwarding)r-   rB   rš   r:   r:   r;   r�     s    r�   c                   C   s   t d st dt¡ d S )NZ	reconnectr„   )rY   r   rQ   rv   r:   r:   r:   r;   ÚstopConnection  s    rž   c                   @   s,   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	S )
rŒ   c                 C   s*   || _ d | _t | j¡| _| j d¡ d S )Ni,  )rŠ   ÚglobalTimeoutr   ZLoopingCallÚ
sendGlobalÚlcÚstart)r8   rŠ   r:   r:   r;   Ú__init__  s    z_KeepAlive.__init__c                 C   s2   | j jdddd�}| | j¡ t d| j¡| _d S )Ns"   conch-keep-alive@twistedmatrix.comrU   r1   ©Z	wantReplyé   )rŠ   ÚsendGlobalRequestÚaddBothÚ	_cbGlobalr   rQ   Ú	_ebGlobalrŸ   )r8   Údr:   r:   r;   r       s      ÿz_KeepAlive.sendGlobalc                 C   s   | j r| j  ¡  d | _ d S ry   )rŸ   Úcancel)r8   Úresr:   r:   r;   r¨   '  s    
z_KeepAlive._cbGlobalc                 C   s   | j rd | _ | jj ¡  d S ry   )rŸ   rŠ   r‹   rœ   ©r8   r:   r:   r;   r©   ,  s    z_KeepAlive._ebGlobalN)rI   rJ   rK   r£   r    r¨   r©   r:   r:   r:   r;   rŒ     s   rŒ   c                   @   sL   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
dS )r�   c                 C   s   | a g | _i | _tƒ  d S ry   )rŠ   r,   r-   r›   r­   r:   r:   r;   ÚserviceStarted3  s    zSSHConnection.serviceStartedc                 C   s(   | j }g | _ |D ]}| ¡  qtƒ  d S ry   )r,   rœ   rž   )r8   Úlfr'   r:   r:   r;   ÚserviceStopped:  s
    
zSSHConnection.serviceStoppedc                 C   sX   t  d|f¡}| jd|dd�}t d|› d|› �¡ | | j||¡ | | j||¡ d S )Nú0.0.0.0s   tcpip-forwardr1   r¤   zrequesting remote forwarding r=   )	r   ÚpackGlobal_tcpip_forwardr¦   r   rŽ   ZaddCallbackÚ_cbRemoteForwardingr‚   Ú_ebRemoteForwarding)r8   rB   rš   Údatarª   r:   r:   r;   r�   A  s
    z%SSHConnection.requestRemoteForwardingc                 C   s4   t  d|› d|› �¡ || j|< t  t| jƒ¡ d S )Nzaccepted remote forwarding r=   )r   rŽ   r-   Úrepr)r8   ÚresultrB   rš   r:   r:   r;   r³   H  s    
z!SSHConnection._cbRemoteForwardingc                 C   s&   t  d|› d|› d�¡ t  |¡ d S )Nzremote forwarding r=   z failed©r   rŽ   )r8   r   rB   rš   r:   r:   r;   r´   M  s    z!SSHConnection._ebRemoteForwardingc                 C   s`   t  d|f¡}|  d|¡ t d|› �¡ z| j|= W n tk
rJ   Y nX t t| jƒ¡ d S )Nr±   s   cancel-tcpip-forwardzcancelling remote forwarding )r   r²   r¦   r   rŽ   r-   Ú	Exceptionr¶   )r8   rB   rµ   r:   r:   r;   r�   Q  s    z$SSHConnection.cancelRemoteForwardingc                 C   s€   t  d|›�¡ t |¡\}}t  | j¡ t  |¡ |d | jkrp| j|d  }t  d|› �¡ t|||| d�S ttjdƒ‚d S )NzFTCP r1   zconnect forwarding )ZremoteWindowZremoteMaxPacketrŠ   zdon't know about that port)	r   rŽ   r   ZunpackOpen_forwarded_tcpipr-   ÚSSHConnectForwardingChannelr   r
   ZOPEN_CONNECT_FAILED)r8   Z
windowSizeZ	maxPacketrµ   ZremoteHPZorigHPZ	connectHPr:   r:   r;   Úchannel_forwarded_tcpip[  s"    
   ÿ ÿz%SSHConnection.channel_forwarded_tcpipc                 C   sT   t  d|› �¡ t  | j¡ t| jƒdkr<t  d¡ tƒ  n| jjd  | |¡ d S )Nzconnection closing r1   zstopping connectionr   )r   rŽ   Úchannelsr3   rž   Ú	__class__Ú	__bases__ÚchannelClosed)r8   r   r:   r:   r;   r¿   k  s    
zSSHConnection.channelClosedN)rI   rJ   rK   r®   r°   r�   r³   r´   r�   r»   r¿   r:   r:   r:   r;   r�   2  s   
r�   c                   @   sp   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ ZdS )r‘   s   sessionc           	         sÐ  t  dˆ j› d�¡ td r>ˆ jjˆ dddd�}| dd	„ ¡ td
 rJd S td rZtd sbtd shtƒ  t 	¡ }td r�td s�dˆ _
ˆ j|_nˆ j|_‡ fdd	„|_t |¡ˆ _d}td rÚˆ j ˆ dt td ¡¡ nòtd �r^td �rBtjd }t |tjd¡}t d|¡}t ||d¡}ˆ j ˆ d|¡ t tjˆ j¡ ˆ j ˆ dt td ¡¡ nntd �s¼tjd }t |tjd¡}t d|¡}t ||d¡}ˆ j ˆ d|¡ t tjˆ j¡ ˆ j ˆ dd¡ d S )Nzsession z openr‡   s   auth-agent-req@openssh.comrU   r1   r¤   c                 S   s
   t  | ¡S ry   r¸   ©Úxr:   r:   r;   rT     rU   z(SSHSession.channelOpen.<locals>.<lambda>r$   r)   r    r"   r   c                    s   ˆ   ¡ S ry   )ÚsendEOFrÀ   r­   r:   r;   rT   Š  rU   r   r&   s	   subsystemÚTERMÚ12345678Ú4HÚ s   pty-reqs   execs   shell)r   rŽ   ÚidrY   rŠ   ÚsendRequestr§   Ú_enterRawModer   ZSSHSessionClientÚ
escapeModeÚhandleInputÚdataReceivedÚwriteZconnectionLostr   Z
StandardIOr	   ZNSr’   ÚenvironÚfcntlÚioctlr    Ú
TIOCGWINSZÚstructÚunpackZpackRequest_pty_reqrd   rh   Ú_windowResized)	r8   Zfoorª   Úcrr   ZtermÚwinszÚwinSizeZ
ptyReqDatar:   r­   r;   ÚchannelOpeny  sP       ÿ





zSSHSession.channelOpenc              	   C   s&  |dkrd| _ |  |¡ �n| j dkr:|td kr:d| _ nè| j dk�rd| _ |dkrht d¡ tƒ  d S |dkrˆdd	„ }t d
|¡ d S |dkrªt d¡ | jj	 
¡  d S |dk�r| j d¡ | jj ¡ }| ¡  |D ]$}| j td || jj| ¡ƒ¡ qØd S |  d| ¡ nd
| _ |  |¡ d S )N)ó   
ó   r1   r   r0   ó   .zdisconnecting from escapeó   c                   S   s6   t ƒ  tj ¡  tj ¡  t t ¡ tj	¡ t
ƒ  d S ry   )Ú_leaveRawModer6   r[   Úflushr_   r’   ÚkillÚgetpidrd   ÚSIGTSTPrÉ   r:   r:   r:   r;   Ú_²  s
    

z!SSHSession.handleInput.<locals>._r   ó   Rzrekeying connectionó   #s'   
The following connections are open:
z
  #{} {}
ó   ~)rÊ   rÍ   rY   r   rŽ   rž   r   rQ   rŠ   r‹   ZsendKexInitr   r¼   ÚkeysÚsortr   rl   )r8   Úcharrâ   r¼   Z	channelIdr:   r:   r;   rË   ¤  sH    


 
ÿÿÿzSSHSession.handleInputc                 C   s   | j  |¡ d S ry   )r   rÍ   ©r8   rµ   r:   r:   r;   rÌ   Ñ  s    zSSHSession.dataReceivedc                 C   sN   |t jkrJt dt|ƒ› d�¡ ttjƒtkr>tjj	 
|¡ ntj 
|¡ d S )Nzgot z stderr data)r
   ZEXTENDED_DATA_STDERRr   rŽ   r3   r   r6   r]   ÚstrÚbufferrÍ   )r8   r!   rµ   r:   r:   r;   ÚextReceivedÔ  s
    
zSSHSession.extReceivedc                 C   s   t  d¡ | j ¡  d S )Nzgot eof)r   rŽ   r   ZloseWriteConnectionr­   r:   r:   r;   ÚeofReceivedÜ  s    
zSSHSession.eofReceivedc                 C   s    t  d| › �¡ | j | ¡ d S )Nzremote side closed )r   rŽ   rŠ   Z	sendCloser­   r:   r:   r;   ÚcloseReceivedà  s    zSSHSession.closeReceivedc                 C   s&   t  d| › �¡ t  t| jjƒ¡ d S )Nzclosed )r   rŽ   r¶   rŠ   r¼   r­   r:   r:   r;   Úclosedä  s    zSSHSession.closedc                 C   s(   t t d|¡d ƒat dt› �¡ d S )Nz>Lr   zexit status: )r?   rÒ   rÓ   rm   r   rŽ   ré   r:   r:   r;   Úrequest_exit_statusé  s    zSSHSession.request_exit_statusc                 C   s   | j  | ¡ d S ry   )rŠ   rÂ   r­   r:   r:   r;   rÂ   î  s    zSSHSession.sendEOFc                 C   s   | j  ¡  d S ry   )r   ZpauseProducingr­   r:   r:   r;   ÚstopWritingñ  s    zSSHSession.stopWritingc                 C   s   | j  ¡  d S ry   )r   ZresumeProducingr­   r:   r:   r;   ÚstartWritingô  s    zSSHSession.startWritingc                 G   sV   t  dtjd¡}t d|¡}|d |d |d |d f}| j | dtjd	|žŽ ¡ d S )
Nr   rÄ   rÅ   r1   r0   rˆ   s   window-changeú!4L)ró   )	rÏ   rÐ   r    rÑ   rÒ   rÓ   rŠ   rÈ   Úpack)r8   rn   rÖ   r×   ZnewSizer:   r:   r;   rÔ   ÷  s    zSSHSession._windowResizedN)rI   rJ   rK   ÚnamerØ   rË   rÌ   rì   rí   rî   rï   rð   rÂ   rñ   rò   rÔ   r:   r:   r:   r;   r‘   v  s   +-r‘   c                   @   s   e Zd ZdS )r�   N©rI   rJ   rK   r:   r:   r:   r;   r�   þ  s   r�   c                   @   s   e Zd ZdS )rº   Nrö   r:   r:   r:   r;   rº     s   rº   c                  C   s*   t sd S tj ¡ } t | tjt¡ da d S rP   )Ú
_inRawModer6   r_   r`   r    rf   rg   Ú_savedRawMode)rr   r:   r:   r;   rÝ     s
    
rÝ   c                  C   sZ  t rd S tj ¡ } zt | ¡}|d d … }W n  tk
rL   t d¡ Y �n
X |d tj	B |d< |d tj
tjB tjB tjB tjB tjB tjB  @ |d< ttdƒr¶|d tj @ |d< |d tjtjB tjB tjB tjB tjB tjB  @ |d< ttdƒ�r|d tj @ |d< |d tj @ |d< d|d tj< d|d tj< |at | tj|¡ da d S )Nznot a typewriter!r   ÚIUCLCrˆ   ÚIEXTENr1   é   ) r÷   r6   r_   r`   r    ra   rc   r   rŽ   ÚIGNPARÚISTRIPÚINLCRÚIGNCRÚICRNLÚIXONÚIXANYÚIXOFFr‰   rù   ÚISIGÚICANONÚECHOÚECHOEÚECHOKÚECHONLrú   ÚOPOSTÚVMINÚVTIMErø   rf   rg   )rr   rb   Únewr:   r:   r;   rÉ     sb    

ÿþýüûúÿ
	
ÿþýüûúÿ
	rÉ   Ú__main__):rÏ   r   r’   rd   rÒ   r6   r    Útypingr   r   Ztwisted.conch.clientr   r   Ztwisted.conch.client.optionsr   Ztwisted.conch.errorr   Ztwisted.conch.sshr   r	   r
   r   r   Ztwisted.internetr   r   r   ru   r   r   Ztwisted.python.compatr   r   r   rY   rŠ   rm   rb   r÷   rø   rj   rx   rv   r^   rƒ   r›   rR   r�   rž   rŒ   r�   Z
SSHChannelr‘   r�   rº   rÝ   rÉ   rI   r:   r:   r:   r;   Ú<module>   sP   V<
$D 		2
