U
    ¹êW[H  ã                   @   s¬  d dl mZ d dlmZmZma d dlmZ d dlm	Z	m
Z
 d dl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m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ZG d
d„ dtj ƒ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„ Z/G dd„ dƒZ0G d d!„ d!e	j1ƒZ1G d"d#„ d#ej2ƒZ3G d$d%„ d%ej4ƒZ4G d&d'„ d'ej5ƒZ5d(d)„ Z6d*d+„ Z7e8d,kr¨e'ƒ  d	S )-é    )Úprint_function)ÚconnectÚdefaultÚoptions)Ú
ConchError)Ú
connectionÚcommon)ÚsessionÚ
forwardingÚchannel)ÚreactorÚstdioÚtask)ÚlogÚusage)ÚioTypeÚnetworkStringÚunicodeNc                	   @   sÔ   e Zd Z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g Zd(d)„ Zd*d+„ Zd,d-„ Zd.d/„ ZdS )0Ú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 addressZ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   ÚcommandZargumentT)r'   Úrepeat)ZmutuallyExclusiveZ
optActionsZextraActionsc                 C   sn   |dkrd| d< nX|d dkrDt |ƒdkrDtt|d ƒd ƒ| d< n&t |ƒdkrZ|| d< nt d	 |¡¡ dS )
z:
        Set escape character; ``none'' = disable
        ZnoneNr   r   ú^é   é   é@   zBad escape character '{}'.)ÚlenÚchrÚordÚsysÚexitÚformat)ÚselfZesc© r5   ú=/usr/lib/python3/dist-packages/twisted/conch/scripts/conch.pyÚ
opt_escape@   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ÚintÚlocalForwardsÚappend)r4   r   Ú	localPortZ
remoteHostÚ
remotePortr5   r5   r6   Úopt_localforwardN   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)
        r8   N)r9   r:   ÚremoteForwardsr<   )r4   r   r>   ZconnHostZconnPortr5   r5   r6   Úopt_remoteforwardX   s    zClientOptions.opt_remoteforwardc                 G   s   || d< d  |¡| d< d S )NÚhostú r(   )Újoin)r4   rB   r(   r5   r5   r6   Ú	parseArgsb   s    zClientOptions.parseArgs)Ú__name__Ú
__module__Ú__qualname__ZsynopsisZlongdescZoptParametersZoptFlagsr   ZCompletionsZ	CompleterZCompleteUserAtHostZcompDatar;   r@   r7   r?   rA   rE   r5   r5   r5   r6   r      s:   

þû

þ
þû


r   c                  C   sb  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   d aY nX zt tjdd„ ¡}W n   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 !¡ rTtd sTt	d 
td ¡ƒ t  t"¡ d S )Nr,   z-lr+   é   z-or   ú-z	ERROR: {}r   Zlogfileza+c                  W   s   t  dt¡S ©Nr   )r   Ú	callLaterÚ	reConnect)Úar5   r5   r6   Ú<lambda>›   ó    zrun.<locals>.<lambda>r(   r   r!   zConnection to {} closed.rB   )#r1   ÚargvÚindexÚ
ValueErrorr   r   ZparseOptionsr   Z
UsageErrorÚprintr3   Zopt_helpr2   ÚstdoutÚopenÚstderrr   ZstartLoggingZdiscardLogsÚ	doConnectÚstdinÚfilenor   Ú	tcgetattrÚoldÚsignalÚSIGUSR1Ú	tcsetattrÚTCSANOWÚSIGWINCHÚSIG_DFLr   ÚrunÚisattyÚ
exitStatus)ÚargsÚiÚargÚur   ZrealoutÚfdZoldUSR1r5   r5   r6   rc   r   sd    

$





rc   c                  C   s0   ddl m}  dat dt¡ t |  ¡ ¡ ‚ d S )Nr   ©Úfailurer+   g{®Gáz„?)	Útwisted.pythonrl   re   r   rL   Ú_stopReactorr   ÚerrZFailurerk   r5   r5   r6   ÚhandleError­   s
    rp   c                   C   s   zt  ¡  W n   Y nX d S ©N)r   Ústopr5   r5   r5   r6   rn   ·   s     rn   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ú@rB   r,   Úuserz~/.ssh/id_rsaz~/.ssh/id_dsaÚporté   zhost-key-algorithms)r   r9   Z	identitysÚgetpassZgetuserr:   r   ZverifyHostKeyZgetHostKeyAlgorithmsZSSHUserAuthClientÚSSHConnectionr   Ú
addErrbackÚ_ebExit)rB   ru   ZvhkZuaor5   r5   r6   rX   ¾   s(    

 ÿrX   c                 C   s   d  | ¡at dt¡ d S )Nzconch: exiting with error {}çš™™™™™¹?)r3   re   r   rL   rn   )r   r5   r5   r6   rz   Õ   s    
rz   c                  C   s,  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 ||¡¡ 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 {}:{}ZbeforeZshutdownr#   Úagentr   r   é   )ÚhasattrÚconnÚ	transportÚ
_KeepAliver   r;   r   Z	listenTCPr
   ZSSHListenForwardingFactoryÚ SSHListenClientForwardingChannelr<   r@   r   Úmsgr3   ÚrequestRemoteForwardingZaddSystemEventTriggerÚbeforeShutdownZopenChannelÚ
SSHSessionÚosr   Ú_exitÚsetsidÚrangeÚcloseÚOSErrorÚerrnoZEBADF)r=   Úhostportr&   r>   rg   r   r   r5   r5   r6   Ú	onConnectÜ   s@    þÿ ÿ

r   c                   C   s   t ƒ  tjj ¡  d S rq   )r…   r   r€   ÚloseConnectionr5   r5   r5   r6   rM   ÿ   s    rM   c                  C   s4   t j} | D ]$\}}t d ||¡¡ t |¡ q
d S )Nzcancelling {}:{})r   r@   r   rƒ   r3   r   ÚcancelRemoteForwarding)r@   r>   rŽ   r5   r5   r6   r…     s    r…   c                   C   s   t d st dt¡ d S )NZ	reconnectr{   )r   r   rL   rn   r5   r5   r5   r6   Ú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Ú
sendGlobalZlcÚstart)r4   r   r5   r5   r6   Ú__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.comrP   r,   ©Z	wantReplyé   )r   ÚsendGlobalRequestÚaddBothÚ	_cbGlobalr   rL   Ú	_ebGlobalr“   )r4   Údr5   r5   r6   r”     s     ÿz_KeepAlive.sendGlobalc                 C   s   | j r| j  ¡  d | _ d S rq   )r“   Zcancel)r4   Úresr5   r5   r6   r›   #  s    
z_KeepAlive._cbGlobalc                 C   s   | j rd | _ | jj ¡  d S rq   )r“   r   r€   r   ©r4   r5   r5   r6   rœ   )  s    z_KeepAlive._ebGlobalN)rF   rG   rH   r–   r”   r›   rœ   r5   r5   r5   r6   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 )rx   c                 C   s2   | a g | _i | _t| tjƒs(| j`| j`t	ƒ  d S rq   )
r   r;   r@   Ú
isinstancer   rx   Ú	__class__r„   r‘   r   rŸ   r5   r5   r6   ÚserviceStarted1  s    zSSHConnection.serviceStartedc                 C   s(   | j }g | _ |D ]}| ¡  qtƒ  d S rq   )r;   r   r’   )r4   Zlfr&   r5   r5   r6   ÚserviceStopped=  s
    
zSSHConnection.serviceStoppedc                 C   sT   t  d|f¡}| jd|dd}t d ||¡¡ | | j||¡ | | j	||¡ d S )Nú0.0.0.0s   tcpip-forwardr,   r—   z"requesting remote forwarding {}:{})
r
   ÚpackGlobal_tcpip_forwardr™   r   rƒ   r3   ZaddCallbackÚ_cbRemoteForwardingry   Ú_ebRemoteForwarding)r4   r>   rŽ   Údatar   r5   r5   r6   r„   E  s    ÿ ÿz%SSHConnection.requestRemoteForwardingc                 C   s0   t  d ||¡¡ || j|< t  t| jƒ¡ d S )Nz accepted remote forwarding {}:{})r   rƒ   r3   r@   Úrepr)r4   Úresultr>   rŽ   r5   r5   r6   r¦   O  s     ÿ
z!SSHConnection._cbRemoteForwardingc                 C   s    t  d ||¡¡ t  |¡ d S )Nzremote forwarding {}:{} failed)r   rƒ   r3   )r4   r   r>   rŽ   r5   r5   r6   r§   V  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ƒ   r3   r@   Ú	Exceptionr©   )r4   r>   r¨   r5   r5   r6   r‘   \  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 {!r}r,   zconnect forwarding {})ZremoteWindowZremoteMaxPacketr   zdon't know about that port)
r   rƒ   r3   r
   ZunpackOpen_forwarded_tcpipr@   ÚSSHConnectForwardingChannelr   r   ZOPEN_CONNECT_FAILED)r4   Z
windowSizeZ	maxPacketr¨   ZremoteHPZorigHPZ	connectHPr5   r5   r6   Úchannel_forwarded_tcpipg  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 {}r,   zstopping connectionr   )	r   rƒ   r3   Úchannelsr.   r’   r¡   Ú	__bases__ÚchannelClosed)r4   r   r5   r5   r6   r°   x  s    
zSSHConnection.channelClosedN)rF   rG   rH   r¢   r£   r„   r¦   r§   r‘   r­   r°   r5   r5   r5   r6   rx   0  s   
rx   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¡¡ td r<ˆ jjˆ dddd}| dd„ ¡ td	 rHd S td
 rXtd s`td sftƒ  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 r@t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 {} openr|   s   auth-agent-req@openssh.comrP   r,   r—   c                 S   s
   t  | ¡S rq   )r   rƒ   ©Úxr5   r5   r6   rO     rP   z(SSHSession.channelOpen.<locals>.<lambda>r#   r(   r   r!   r   c                    s   ˆ   ¡ S rq   )ÚsendEOFr±   rŸ   r5   r6   rO   ˜  rP   r   r%   s	   subsystemZTERMÚ12345678Ú4HÚ s   pty-reqs   execs   shell) r   rƒ   r3   Úidr   r   ÚsendRequestrš   Ú_enterRawModer	   ZSSHSessionClientÚ
escapeModeÚhandleInputÚdataReceivedÚwriteZconnectionLostr   Z
StandardIOr   ZNSr‡   ÚenvironÚfcntlÚioctlr   Ú
TIOCGWINSZÚstructÚunpackZpackRequest_pty_reqr]   ra   Ú_windowResized)	r4   Zfoor   Úcrj   ZtermÚwinszÚwinSizeZ
ptyReqDatar5   rŸ   r6   ÚchannelOpenˆ  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)ó   
ó   r,   r   r+   ó   .zdisconnecting from escapeó   c                   S   s6   t ƒ  tj ¡  tj ¡  t t ¡ tj	¡ t
ƒ  d S rq   )Ú_leaveRawModer1   rU   ÚflushrY   r‡   ÚkillÚgetpidr]   ÚSIGTSTPr¹   r5   r5   r5   r6   Ú_Á  s
    

z!SSHSession.handleInput.<locals>._r   ó   Rzrekeying connectionó   #s'   
The following connections are open:
z
  #{} {}
ó   ~)rº   r½   r   r   rƒ   r’   r   rL   r   r€   ZsendKexInitr   r®   ÚkeysÚsortr   r3   )r4   ÚcharrÒ   r®   Z	channelIdr5   r5   r6   r»   ´  sD    


ÿ
þ
zSSHSession.handleInputc                 C   s   | j  |¡ d S rq   )r   r½   ©r4   r¨   r5   r5   r6   r¼   Ý  s    zSSHSession.dataReceivedc                 C   sL   |t jkrHt d t|ƒ¡¡ ttjƒt	kr<tjj
 |¡ ntj |¡ d S )Nzgot {} stderr data)r   ZEXTENDED_DATA_STDERRr   rƒ   r3   r.   r   r1   rW   r   Úbufferr½   )r4   r    r¨   r5   r5   r6   ÚextReceivedá  s
    
zSSHSession.extReceivedc                 C   s   t  d¡ | j ¡  d S )Nzgot eof)r   rƒ   r   ZloseWriteConnectionrŸ   r5   r5   r6   ÚeofReceivedê  s    
zSSHSession.eofReceivedc                 C   s    t  d | ¡¡ | j | ¡ d S )Nzremote side closed {})r   rƒ   r3   r   Z	sendCloserŸ   r5   r5   r6   ÚcloseReceivedï  s    zSSHSession.closeReceivedc                 C   s&   t  d | ¡¡ t  t| jjƒ¡ d S )Nz	closed {})r   rƒ   r3   r©   r   r®   rŸ   r5   r5   r6   Ú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Ã   re   r   rƒ   r3   rÙ   r5   r5   r6   Úrequest_exit_statusú  s    zSSHSession.request_exit_statusc                 C   s   | j  | ¡ d S rq   )r   r³   rŸ   r5   r5   r6   r³      s    zSSHSession.sendEOFc                 C   s   | j  ¡  d S rq   )r   ZpauseProducingrŸ   r5   r5   r6   ÚstopWriting  s    zSSHSession.stopWritingc                 C   s   | j  ¡  d S rq   )r   ZresumeProducingrŸ   r5   r5   r6   Ú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µ   r,   r+   r}   s   window-changeú!4L)râ   )	r¿   rÀ   r   rÁ   rÂ   rÃ   r   r¸   Zpack)r4   rf   rÆ   rÇ   ZnewSizer5   r5   r6   rÄ     s    zSSHSession._windowResizedN)rF   rG   rH   ÚnamerÈ   r»   r¼   rÛ   rÜ   rÝ   rÞ   rß   r³   rà   rá   rÄ   r5   r5   r5   r6   r†   „  s   ,)	r†   c                   @   s   e Zd ZdS )r‚   N©rF   rG   rH   r5   r5   r5   r6   r‚     s    r‚   c                   @   s   e Zd ZdS )r¬   Nrä   r5   r5   r5   r6   r¬     s    r¬   c                  C   s*   t sd S tj ¡ } t | tjt¡ da d S rK   )Ú
_inRawModer1   rY   rZ   r   r_   r`   Ú_savedRawMode)rj   r5   r5   r6   rÍ     s
    
rÍ   c                  C   sR  t rd S tj ¡ } zt | ¡}|d d … }W n   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}   ÚIEXTENr,   é   )rå   r1   rY   rZ   r   r[   r   rƒ   ZIGNPARZISTRIPZINLCRZIGNCRZICRNLZIXONZIXANYZIXOFFr~   rç   ZISIGZICANONZECHOZECHOEZECHOKZECHONLrè   ZOPOSTZVMINZVTIMEræ   r_   r`   )rj   r\   Únewr5   r5   r6   r¹   #  sB    

ÿÿÿ
ÿÿÿr¹   Ú__main__)9Z
__future__r   Ztwisted.conch.clientr   r   r   Ztwisted.conch.errorr   Ztwisted.conch.sshr   r   r	   r
   r   Ztwisted.internetr   r   r   rm   r   r   Ztwisted.python.compatr   r   r   r‡   r1   rw   rÂ   r   r¿   r]   ZConchOptionsr   r   re   r\   rå   ræ   rc   rp   rn   rX   rz   r   rM   r…   r’   r   rx   Z
SSHChannelr†   r‚   r¬   rÍ   r¹   rF   r5   r5   r5   r6   Ú<module>   sP   J;
#T 
%
