U
    ¹êW[Ù+  ã                   @   s>  d Z ddlmZmZ ddlZddlZddlZddlZddlm	Z	 ddl
mZmZ ddlmZ ddlmZmZ ddlmZ dd	lmZmZmZ G d
d„ dejƒZG dd„ dejƒZG dd„ dƒZdd„ Zdd„ Zddddddddddddd gZ e	ej!ƒG d!d"„ d"ejƒƒZ"G d#d$„ d$ej#ƒZ$d%d&„ Z%d'd(„ Z&d)d*„ Z'd+d,„ Z(dS )-z 
This module contains the implementation of SSHSession, which (by default)
allows access to a shell and a python interpreter over SSH.

Maintainer: Paul Swartz
é    )ÚdivisionÚabsolute_importN)Úimplementer)Ú
interfacesÚprotocol)Úlog)Ú	_bytesChrÚnetworkString)ÚISession)ÚcommonÚchannelÚ
connectionc                   @   sh   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S )Ú
SSHSessions   sessionc                 O   s*   t jj| f|ž|Ž d| _d | _d | _d S ©Nó    )r   Ú
SSHChannelÚ__init__ÚbufÚclientÚsession)ÚselfÚargsÚkw© r   ú;/usr/lib/python3/dist-packages/twisted/conch/ssh/session.pyr      s    zSSHSession.__init__c                 C   sr   t  |¡\}}t d| ¡ | j ||¡}|r`t| ƒ}t|ƒ}| |¡ | t	|ƒ¡ || _
dS t d¡ dS d S )Nzasking for subsystem "%s"é   zfailed to get subsystemr   )r   ÚgetNSr   ÚmsgÚavatarZlookupSubsystemÚSSHSessionProcessProtocolÚwrapProcessProtocolZmakeConnectionÚwrapProtocolr   )r   ÚdataZ	subsystemÚignoredr   ÚppÚprotor   r   r   Úrequest_subsystem%   s    

zSSHSession.request_subsystemc                 C   sZ   t  d¡ | jst| jƒ| _zt| ƒ}| j |¡ W n   t  ¡  Y dS X || _dS d S )Nzgetting shellr   r   )	r   r   r   r
   r   r   Z	openShellÚdeferrr   )r   r"   r$   r   r   r   Úrequest_shell4   s    
zSSHSession.request_shellc                 C   sn   | j st| jƒ| _ t |¡\}}t d| ¡ zt| ƒ}| j  ||¡ W n   t 	¡  Y dS X || _
dS d S )Nzexecuting command "%s"r   r   )r   r
   r   r   r   r   r   r   ZexecCommandr'   r   )r   r"   Úfr$   r   r   r   Úrequest_execB   s    zSSHSession.request_execc                 C   sf   | j st| jƒ| _ t|ƒ\}}}t d||f ¡ z| j  |||¡ W n   t ¡  Y dS X dS d S )Nzpty request: %r %rr   r   )r   r
   r   ÚparseRequest_pty_reqr   r   ZgetPtyÚerr)r   r"   ÚtermZ
windowSizeÚmodesr   r   r   Úrequest_pty_reqQ   s    zSSHSession.request_pty_reqc                 C   sT   | j st| jƒ| _ t|ƒ}z| j  |¡ W n    t d¡ t ¡  Y dS X dS d S )Nzerror changing window sizer   r   )r   r
   r   ÚparseRequest_window_changeZwindowChangedr   r   r,   )r   r"   ÚwinSizer   r   r   Úrequest_window_change^   s    
z SSHSession.request_window_changec                 C   s*   | j s|  j|7  _d S | j j |¡ d S ©N)r   r   Ú	transportÚwrite©r   r"   r   r   r   ÚdataReceivedk   s    zSSHSession.dataReceivedc                 C   s@   |t jkr.| jr<t| jjdƒr<| jj |¡ nt d| ¡ d S )NÚwriteErrzweird extended data: %s)r   ÚEXTENDED_DATA_STDERRr   Úhasattrr4   r8   r   r   )r   ZdataTyper"   r   r   r   ÚextReceivedr   s    
zSSHSession.extReceivedc                 C   s(   | j r| j  ¡  n| jr$| j | ¡ d S r3   )r   ÚeofReceivedr   ÚconnZ	sendClose©r   r   r   r   r<   y   s    zSSHSession.eofReceivedc                 C   s(   | j r| j  ¡  n| jr$| jj ¡  d S r3   )r   Úclosedr   r4   ÚloseConnectionr>   r   r   r   r?      s    zSSHSession.closedc                 C   s"   | j r| j j ¡  tj | ¡ d S r3   )r   r4   r@   r   r   r>   r   r   r   r@   ˆ   s    zSSHSession.loseConnectionN)Ú__name__Ú
__module__Ú__qualname__Únamer   r&   r(   r*   r/   r2   r7   r;   r<   r?   r@   r   r   r   r   r      s   	r   c                   @   s0   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
S )Ú_ProtocolWrapperzS
    This class wraps a L{Protocol} instance in a L{ProcessProtocol} instance.
    c                 C   s
   || _ d S r3   ©r%   ©r   r%   r   r   r   r   ‘   s    z_ProtocolWrapper.__init__c                 C   s   | j  ¡  d S r3   )r%   ÚconnectionMader>   r   r   r   rH   ”   r   z_ProtocolWrapper.connectionMadec                 C   s   | j  |¡ d S r3   ©r%   r7   r6   r   r   r   ÚoutReceived–   r   z_ProtocolWrapper.outReceivedc                 C   s   | j  |¡ d S r3   )r%   ÚconnectionLost©r   Úreasonr   r   r   ÚprocessEnded˜   r   z_ProtocolWrapper.processEndedN)rA   rB   rC   Ú__doc__r   rH   rJ   rN   r   r   r   r   rE      s
   rE   c                   @   s4   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ ZdS )Ú_DummyTransportc                 C   s
   || _ d S r3   rF   rG   r   r   r   r   œ   s    z_DummyTransport.__init__c                 C   s   | j j |¡ d S r3   )r%   r4   r5   r6   r   r   r   r7   Ÿ   s    z_DummyTransport.dataReceivedc                 C   s   | j  |¡ d S r3   rI   r6   r   r   r   r5   ¢   s    z_DummyTransport.writec                 C   s   |   d |¡¡ d S r   )r5   Újoin©r   Úseqr   r   r   ÚwriteSequence¥   s    z_DummyTransport.writeSequencec                 C   s   | j  tj¡ d S r3   )r%   rK   r   ZconnectionDoner>   r   r   r   r@   ¨   s    z_DummyTransport.loseConnectionN)rA   rB   rC   r   r7   r5   rT   r@   r   r   r   r   rP   š   s
   rP   c                 C   s   t | tjƒrt| ƒS | S d S r3   )Ú
isinstancer   ÚProtocolrE   )Úinstr   r   r   r    «   s    r    c                 C   s   t | ƒS r3   )rP   rF   r   r   r   r!   ±   s    r!   ZABRTZALRMZFPEZHUPZILLZINTZKILLÚPIPEZQUITZSEGVZTERMZUSR1ZUSR2c                   @   sˆ   e Zd 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d„Zdd„ Zd dd„Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZdS )!r   z›I am both an L{IProcessProtocol} and an L{ITransport}.

    I am a transport to the remote endpoint and a process protocol to the
    local subsystem.
    Nc                 C   s   || _ d| _d S )NF)r   ÚlostOutOrErrFlag)r   r   r   r   r   r   É   s    z"SSHSessionProcessProtocol.__init__c                 C   s$   | j jr | j | j j¡ d | j _d S r3   )r   r   r4   r5   r>   r   r   r   rH   Í   s    z(SSHSessionProcessProtocol.connectionMadec                 C   s   | j  |¡ d S r3   ©r   r5   r6   r   r   r   rJ   Ò   s    z%SSHSessionProcessProtocol.outReceivedc                 C   s   | j  tj|¡ d S r3   )r   ZwriteExtendedr   r9   )r   r,   r   r   r   ÚerrReceivedÕ   s    z%SSHSessionProcessProtocol.errReceivedc                 C   s"   | j r| jj | j¡ nd| _ dS )zW
        EOF should only be sent when both STDOUT and STDERR have been closed.
        TN)rY   r   r=   ZsendEOFr>   r   r   r   ÚoutConnectionLostØ   s    z+SSHSessionProcessProtocol.outConnectionLostc                 C   s   |   ¡  dS )z*
        See outConnectionLost().
        N)r\   r>   r   r   r   ÚerrConnectionLostá   s    z+SSHSessionProcessProtocol.errConnectionLostc                 C   s   | j  ¡  d S r3   ©r   r@   rL   r   r   r   rK   ç   s    z(SSHSessionProcessProtocol.connectionLostc                 C   s   | j dkr†i | _ tD ]*}d| }tt|dƒ}|dk	r|| j |< qtj ¡ D ]:\}}| d¡rJ| d¡sJ|| j krJ|d tj | j |< qJ| j | S )z:
        Get a signal name given a signal number.
        NZSIGZSIG_ú@)	Ú_signalValuesToNamesÚSUPPORTED_SIGNALSÚgetattrÚsignalÚ__dict__ÚitemsÚ
startswithÚsysÚplatform)r   ZsignumÚsignameZsigvalueÚkÚvr   r   r   Ú_getSignalNameë   s    

z(SSHSessionProcessProtocol._getSignalNamec              
   C   sö   |dk	rè|j }|jdk	r®|  |j¡}ttddƒdk	rVt |j¡rVt d|f ¡ d}nt d|f ¡ d}| j	j
 | j	dt t|dd… ƒ¡t|ƒ t d	¡ t d	¡ ¡ n:|jdk	rèt d
|jf ¡ | j	j
 | j	dt d|j¡¡ | j	 ¡  dS )zÆ
        When we are told the process ended, try to notify the other side about
        how the process ended using the exit-signal or exit-status requests.
        Also, close the channel.
        NÚ	WCOREDUMPzexitSignal: %s (core dumped)r   zexitSignal: %sr   s   exit-signalé   r   zexitCode: %rs   exit-statusú>L)Úvaluerc   rl   rb   Úosrm   Zstatusr   r   r   r=   ZsendRequestr   ÚNSr	   ÚchrZexitCodeÚstructÚpackr@   )r   rM   r,   ri   Z
coreDumpedr   r   r   rN      s4    

ÿ ÿÿþ
ÿz&SSHSessionProcessProtocol.processEndedc                 C   s   | j jj ¡ S )z>
        Return the host from my session's transport.
        )r   r=   r4   ÚgetHostr>   r   r   r   rv     s    z!SSHSessionProcessProtocol.getHostc                 C   s   | j jj ¡ S )z>
        Return the peer from my session's transport.
        )r   r=   r4   ÚgetPeerr>   r   r   r   rw   #  s    z!SSHSessionProcessProtocol.getPeerc                 C   s   | j  |¡ d S r3   rZ   r6   r   r   r   r5   *  s    zSSHSessionProcessProtocol.writec                 C   s   | j  d |¡¡ d S r   )r   r5   rQ   rR   r   r   r   rT   .  s    z'SSHSessionProcessProtocol.writeSequencec                 C   s   | j  ¡  d S r3   r^   r>   r   r   r   r@   2  s    z(SSHSessionProcessProtocol.loseConnection)N)N)rA   rB   rC   rO   r`   r   rH   rJ   r[   r\   r]   rK   rl   rN   rv   rw   r5   rT   r@   r   r   r   r   r   ½   s    	

r   c                   @   s   e Zd Zdd„ ZdS )ÚSSHSessionClientc                 C   s   | j r| j  |¡ d S r3   )r4   r5   r6   r   r   r   r7   9  s    zSSHSessionClient.dataReceivedN)rA   rB   rC   r7   r   r   r   r   rx   7  s   rx   c           	         sx   t  | ¡\}}t d|dd… ¡\}}}}t  |dd… ¡\‰ }||||f}‡ fdd„tdtˆ ƒd dƒD ƒ‰ ||ˆ fS )	z‹Parse the data from a pty-req request into usable data.

    @returns: a tuple of (terminal type, (rows, cols, xpixel, ypixel), modes)
    ú>4LNé   c              
      s@   g | ]8}t ˆ ||d  … ƒt dˆ |d  |d … ¡d f‘qS )r   ro   é   r   )Úordrt   Úunpack)Ú.0Úi©r.   r   r   Ú
<listcomp>G  s   ÿz(parseRequest_pty_req.<locals>.<listcomp>r   r   r{   )r   r   rt   r}   ÚrangeÚlen)	r"   r-   ÚrestÚcolsÚrowsÚxpixelÚypixelr#   r1   r   r€   r   r+   >  s    
ÿr+   c           
      C   s>   |\}}}}t  | ¡}t d||||¡}t  |¡}	|| |	 S )zÚ
    Pack a pty-req request so that it is suitable for sending.

    NOTE: modes must be packed before being sent here.

    @type geometry: L{tuple}
    @param geometry: A tuple of (rows, columns, xpixel, ypixel)
    ry   )r   rr   rt   ru   )
r-   Úgeometryr.   r†   r…   r‡   rˆ   Z
termPackedZwinSizePackedZmodesPackedr   r   r   ÚpackRequest_pty_reqK  s
    	

rŠ   c                 C   s    t  d| ¡\}}}}||||fS )zzParse the data from a window-change request into usuable data.

    @returns: a tuple of (rows, cols, xpixel, ypixel)
    ry   )rt   r}   )r"   r…   r†   r‡   rˆ   r   r   r   r0   Z  s    r0   c                 C   s   | \}}}}t  d||||¡S )z¨
    Pack a window-change request so that it is suitable for sending.

    @type geometry: L{tuple}
    @param geometry: A tuple of (rows, columns, xpixel, ypixel)
    ry   )rt   ru   )r‰   r†   r…   r‡   rˆ   r   r   r   ÚpackRequest_window_changeb  s    r‹   ))rO   Z
__future__r   r   rt   rc   rg   rq   Zzope.interfacer   Ztwisted.internetr   r   Ztwisted.pythonr   Ztwisted.python.compatr   rs   r	   Ztwisted.conch.interfacesr
   Ztwisted.conch.sshr   r   r   r   r   ZProcessProtocolrE   rP   r    r!   ra   Z
ITransportr   rV   rx   r+   rŠ   r0   r‹   r   r   r   r   Ú<module>   s>   q     ÿy