U
    ÓZjVV  ã                   @   sÐ   d 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 ddl	m
Z
 ddlmZmZmZmZmZmZmZ ddlmZmZ ddlmZmZ ddlmZ d	d
„ ZG dd„ deƒZdd„ ZG dd„ deƒZ dS )z
Packet handling
é    N)ÚHMAC)Úutil)Úlinefeed_byteÚcr_byte_valueÚasbytesÚ	MSG_NAMESÚDEBUGÚ	xffffffffÚ	zero_byte)ÚuÚbyte_ord)ÚSSHExceptionÚProxyCommandFailure)ÚMessagec                 C   s   t | ||ƒ ¡ S ©N)r   Údigest)ÚkeyÚmessageZdigest_class© r   úR/var/www/html/TRUCKING_PROJECT/venv/lib/python3.8/site-packages/paramiko/packet.pyÚcompute_hmac.   s    r   c                   @   s   e Zd ZdZdS )ÚNeedRekeyExceptionz1
    Exception indicating a rekey is needed.
    N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   2   s   r   c                 C   s.   d }t | jƒtkr*t| jƒdkr*| jd }|S )Nr   )ÚtypeÚargsÚtupleÚlen)ÚeÚargr   r   r   Ú	first_arg:   s    
r"   c                   @   s"  e Zd ZdZeddƒZeddƒZeddƒZeddƒZdd„ Z	e
dd„ ƒZdd	„ Zd>dd„Zd?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%d&„ Zd'd(„ Zd@d)d*„Zd+d,„ Zd-d.„ Zd/d0„ Zd1d2„ Z d3d4„ Z!d5d6„ Z"d7d8„ Z#d9d:„ Z$d;d<„ Z%d=S )AÚ
Packetizerz9
    Implementation of the base SSH packet protocol.
    é   é   c                 C   sð   || _ d | _d| _d| _d| _d| _tƒ | _d| _d| _	d| _
d| _d| _d| _d| _d| _d| _d| _d | _d | _d| _d | _d | _tƒ | _tƒ | _d | _d | _d| _d| _d| _d| _t  ¡ | _!d| _"t# #¡ | _$d | _%d | _&d| _'d| _(d S )NFr   é   ))Ú_Packetizer__socketÚ_Packetizer__loggerÚ_Packetizer__closedÚ_Packetizer__dump_packetsÚ_Packetizer__need_rekeyÚ_Packetizer__init_countÚbytesÚ_Packetizer__remainderÚ_Packetizer__sent_bytesÚ_Packetizer__sent_packetsÚ_Packetizer__received_bytesÚ_Packetizer__received_packetsÚ$_Packetizer__received_bytes_overflowÚ&_Packetizer__received_packets_overflowÚ_Packetizer__block_size_outÚ_Packetizer__block_size_inÚ_Packetizer__mac_size_outÚ_Packetizer__mac_size_inÚ_Packetizer__block_engine_outÚ_Packetizer__block_engine_inÚ_Packetizer__sdctr_outÚ_Packetizer__mac_engine_outÚ_Packetizer__mac_engine_inÚ_Packetizer__mac_key_outÚ_Packetizer__mac_key_inÚ _Packetizer__compress_engine_outÚ_Packetizer__compress_engine_inÚ _Packetizer__sequence_number_outÚ_Packetizer__sequence_number_inÚ_Packetizer__etm_outÚ_Packetizer__etm_inÚ	threadingÚRLockÚ_Packetizer__write_lockÚ_Packetizer__keepalive_intervalÚtimeÚ_Packetizer__keepalive_lastÚ_Packetizer__keepalive_callbackÚ_Packetizer__timerÚ_Packetizer__handshake_completeÚ_Packetizer__timer_expired)ÚselfÚsocketr   r   r   Ú__init__Q   sJ    

zPacketizer.__init__c                 C   s   | j S r   )r)   ©rP   r   r   r   Úclosed�   s    zPacketizer.closedc                 C   s
   || _ dS )z?
        Set the Python log object to use for logging.
        N)r(   )rP   Úlogr   r   r   Úset_log…   s    zPacketizer.set_logFc                 C   s^   || _ || _|| _|| _|| _|| _d| _d| _|| _|  j	dO  _	| j	dkrZd| _	d| _
dS )zd
        Switch outbound data cipher.
        :param etm: Set encrypt-then-mac from OpenSSH
        r   é   é   FN)r9   r;   r5   r<   r7   r>   r/   r0   rD   r,   r+   )rP   Úblock_engineÚ
block_sizeÚ
mac_engineÚmac_sizeÚmac_keyZsdctrÚetmr   r   r   Úset_outbound_cipher‹   s    
zPacketizer.set_outbound_cipherc                 C   sd   || _ || _|| _|| _|| _d| _d| _d| _d| _|| _	|  j
dO  _
| j
dkr`d| _
d| _dS )zc
        Switch inbound data cipher.
        :param etm: Set encrypt-then-mac from OpenSSH
        r   r$   rX   FN)r:   r6   r=   r8   r?   r1   r2   r3   r4   rE   r,   r+   )rP   rY   rZ   r[   r\   r]   r^   r   r   r   Úset_inbound_cipher©   s    
zPacketizer.set_inbound_cipherc                 C   s
   || _ d S r   )r@   ©rP   Z
compressorr   r   r   Úset_outbound_compressorÇ   s    z"Packetizer.set_outbound_compressorc                 C   s
   || _ d S r   )rA   ra   r   r   r   Úset_inbound_compressorÊ   s    z!Packetizer.set_inbound_compressorc                 C   s   d| _ | j ¡  d S ©NT)r)   r'   ÚcloserS   r   r   r   re   Í   s    zPacketizer.closec                 C   s
   || _ d S r   ©r*   )rP   Úhexdumpr   r   r   Úset_hexdumpÑ   s    zPacketizer.set_hexdumpc                 C   s   | j S r   rf   rS   r   r   r   Úget_hexdumpÔ   s    zPacketizer.get_hexdumpc                 C   s   | j S r   )r8   rS   r   r   r   Úget_mac_size_in×   s    zPacketizer.get_mac_size_inc                 C   s   | j S r   )r7   rS   r   r   r   Úget_mac_size_outÚ   s    zPacketizer.get_mac_size_outc                 C   s   | j S )zæ
        Returns ``True`` if a new set of keys needs to be negotiated.  This
        will be triggered during a packet read or write, so it should be
        checked after every read or write, or at least after every few.
        ©r+   rS   r   r   r   Ú
need_rekeyÝ   s    zPacketizer.need_rekeyc                 C   s   || _ || _t ¡ | _dS )zÏ
        Turn on/off the callback keepalive.  If ``interval`` seconds pass with
        no data read from or written to the socket, the callback will be
        executed and the timer will be reset.
        N)rI   rL   rJ   rK   )rP   ÚintervalÚcallbackr   r   r   Úset_keepaliveå   s    zPacketizer.set_keepalivec                 C   s
   d| _ d S rd   )rO   rS   r   r   r   Ú
read_timerï   s    zPacketizer.read_timerc                 C   s(   | j s$t t|ƒ| j¡| _ | j  ¡  dS )zó
        Tells `Packetizer` that the handshake process started.
        Starts a book keeping timer that can signal a timeout in the
        handshake process.

        :param float timeout: amount of seconds to wait before timing out
        N)rM   rF   ÚTimerÚfloatrq   Ústart)rP   Útimeoutr   r   r   Ústart_handshakeò   s    zPacketizer.start_handshakec                 C   s   | j s
dS | jrdS | jS )aR  
        Checks if the handshake has timed out.

        If `start_handshake` wasn't called before the call to this function,
        the return value will always be `False`. If the handshake completed
        before a timeout was reached, the return value will be `False`

        :return: handshake time out status, as a `bool`
        F)rM   rN   rO   rS   r   r   r   Úhandshake_timed_outþ   s
    
zPacketizer.handshake_timed_outc                 C   s    | j r| j  ¡  d| _d| _dS )zF
        Tells `Packetizer` that the handshake has completed.
        FTN)rM   ÚcancelrO   rN   rS   r   r   r   Úcomplete_handshake  s    
zPacketizer.complete_handshakec              
   C   sF  t ƒ }t| jƒdkr>| jd|… }| j|d… | _|t|ƒ8 }|dk�rBd}|  ¡ rZtƒ ‚z6| j |¡}t|ƒdkrztƒ ‚||7 }|t|ƒ8 }W nr tjk
rª   d}Y nZ tj	k
�r } z8t
|ƒ}|tjkrÖd}n|tjkrân| jrðtƒ ‚n‚ W 5 d}~X Y nX |r>| j�rtƒ ‚|�r8t|ƒdk�r8| j�r8tƒ ‚|  ¡  q>|S )a&  
        Read as close to N bytes as possible, blocking as long as necessary.

        :param int n: number of bytes to read
        :return: the data read, as a `str`

        :raises:
            ``EOFError`` -- if the socket was closed before all the bytes could
            be read
        r   NFT)r-   r   r.   rw   ÚEOFErrorr'   ÚrecvrQ   ru   Úerrorr"   ÚerrnoÚEAGAINÚEINTRr)   r+   r   Ú_check_keepalive)rP   ÚnÚcheck_rekeyÚoutZgot_timeoutÚxr    r!   r   r   r   Úread_all  sB    



zPacketizer.read_allc              
   C   s(  t   ¡ | _d}t|ƒdk�r$d}z| j |¡}W n’ tjk
rJ   d}Y nz tjk
r˜ } z0t|ƒ}|t	j
krtd}n|t	jkr„d}nd}W 5 d }~X Y n, tk
r¬   ‚ Y n tk
rÂ   d}Y nX |rØd}| jrôd}n|dkrì|dkrìd}|d7 }|dk �rtƒ ‚|t|ƒk�r�q$||d … }qd S )Nr   FTéÿÿÿÿé
   rW   )rJ   rK   r   r'   ÚsendrQ   ru   r|   r"   r}   r~   r   r   Ú	Exceptionr)   rz   )rP   rƒ   Z#iteration_with_zero_as_return_valueZretry_writer�   r    r!   r   r   r   Ú	write_allJ  s@    




zPacketizer.write_allc                 C   sr   | j }t|kr||  |¡7 }q| t¡}||d d… | _ |d|… }t|ƒdkrj|d tkrj|dd… }t|ƒS )z‰
        Read a line from the socket.  We assume no data is pending after the
        line, so it's okay to attempt large reads.
        rW   Nr   r†   )r.   r   Ú_read_timeoutÚindexr   r   r   )rP   ru   Úbufr�   r   r   r   Úreadlineu  s    
zPacketizer.readlinec                 C   sÆ  t |ƒ}t|d ƒ}|tkr&t| }n
d |¡}t|ƒ}| j ¡  �zp| jdk	rZ|  |¡}|  	|¡}| j
r’|  td ||¡¡ |  tt |d¡¡ | jdk	rÒ| jrÄ|dd… | j |dd… ¡ }qÖ| j |¡}n|}| jdk	�r t d| j¡}|| jrü|n| }|t| j|| jƒd| j… 7 }| jd t@ | _|  |¡ |  jt|ƒ7  _|  jd7  _| j| jk�pr| j| jk}	|	�r²| j�s²d	}
|  t|
 | j| j¡¡ d| _ d| _!|  "¡  W 5 | j ¡  X dS )
zR
        Write a block of data using the current cipher, as an SSH block.
        r   ú${:x}NzWrite packet <{}>, length {}zOUT: é   ú>IrW   z(Rekeying (hit {} packets, {} bytes sent))#r   r   r   Úformatr   rH   ÚacquireÚreleaser@   Ú_build_packetr*   Ú_logr   r   Úformat_binaryr9   rD   ÚupdateÚstructÚpackrB   r   r>   r<   r7   r	   rŠ   r/   r0   ÚREKEY_PACKETSÚREKEY_BYTESr+   r3   r4   Ú_trigger_rekey)rP   ÚdataÚcmdÚcmd_nameZorig_lenÚpacketrƒ   ÚpackedÚpayloadZsent_too_muchÚmsgr   r   r   Úsend_message„  sj    






þ

ÿ  ÿþþ

þ ÿzPacketizer.send_messagec                 C   s–  | j | jdd�}| jr¬t d|dd… ¡d }|| j d }|dd… | j |dd� }| j | jdd�}t d| j|¡| }t| j	|| j
ƒd| j… }t ||¡s¨td	ƒ‚|}| jdk	rÂ| j |¡}| jrÜ|  tt |d
¡¡ | jrè|}n¤t d|dd… ¡d }|dd… }|t|ƒ | j dk�r,tdƒ‚|   || j t|ƒ ¡}	|	d|t|ƒ … }|	|t|ƒ d… }
| jdk	�r„| j |¡}|| }| j�r¨|  tt |d
¡¡ | jdk�r| j�s|
d| j… }t d| j|¡| }t| j	|| j
ƒd| j… }t ||¡�std	ƒ‚t|d ƒ}|d|| … }| j�rF|  td ||¡¡ | jdk	�r\|  |¡}t|dd… ƒ}| j|_| jd t@ | _|| j d }|  j|7  _|  jd7  _| j�rø|  j|7  _|  jd7  _| j| j k�sî| j| j!k�rDtdƒ‚nL| j| j"k�s| j| j#k�rDd}|  t| | j| j¡¡ d| _d| _|  $¡  t|d ƒ}|t%k�rdt%| }n
d |¡}| j�rŽ|  td |t|ƒ¡¡ ||fS )zë
        Only one thread should ever be in this function (no other locking is
        done).

        :raises: `.SSHException` -- if the packet is mangled
        :raises: `.NeedRekeyException` -- if the transport should rekey
        T)r‚   r‘   Nr�   r   Fz>IIzMismatched MACzIN: zInvalid packet blockingrW   z"Got payload ({} bytes, {} padding)z+Remote transport is ignoring rekey requestsz,Rekeying (hit {} packets, {} bytes received)r�   zRead packet <{}>, length {})&r…   r6   rE   r™   Úunpackr8   rš   rC   r   r?   r=   r   Zconstant_time_bytes_eqr   r:   r˜   r*   r–   r   r—   r   r   r’   rA   r   Zseqnor	   r1   r2   r+   r3   r4   ÚREKEY_PACKETS_OVERFLOW_MAXÚREKEY_BYTES_OVERFLOW_MAXr›   rœ   r�   r   )rP   ÚheaderZpacket_sizeÚ	remainingr¡   ÚmacZmac_payloadZmy_macÚleftoverr�   Zpost_packetÚpaddingr£   r¤   Zraw_packet_sizeÚerrrŸ   r    r   r   r   Úread_messageÃ  sÔ    ÿÿ  ÿþ
ÿÿÿ  ÿþ ÿþ
ÿÿ
üÿ
ÿþ


þzPacketizer.read_messagec                 C   sH   | j d krd S tt|ƒtƒr6|D ]}| j  ||¡ q n| j  ||¡ d S r   )r(   Ú
issubclassr   ÚlistrU   )rP   Úlevelr¤   Úmr   r   r   r–   E  s    
zPacketizer._logc                 C   s@   | j r| jr| jrd S t ¡ }|| j| j  kr<|  ¡  || _d S r   )rI   r9   r+   rJ   rK   rL   )rP   Únowr   r   r   r€   N  s    ÿþýzPacketizer._check_keepalivec              
   C   s¦   t   ¡ }z&| j d¡}t|ƒdkr(tƒ ‚W q¢W nH tjk
rD   Y n4 tk
rv } zt|ƒt	j
krdn‚ W 5 d }~X Y nX | jr„tƒ ‚t   ¡ }|| |krt ¡ ‚q|S )Né€   r   )rJ   r'   r{   r   rz   rQ   ru   ÚEnvironmentErrorr"   r}   r   r)   )rP   ru   rt   r„   r    r´   r   r   r   r‹   [  s$    
zPacketizer._read_timeoutc                 C   s~   | j }| jrdnd}d| t|ƒ| |  }t dt|ƒ| d |¡}||7 }| js^| jd krl|t| 7 }n|t 	|¡7 }|S )Nr�   r&   rX   z>IBrW   )
r5   rD   r   r™   rš   r;   r9   r
   ÚosÚurandom)rP   r£   ZbsizeZaddlenr­   r¡   r   r   r   r•   q  s    zPacketizer._build_packetc                 C   s
   d| _ d S rd   rl   rS   r   r   r   r�   ƒ  s    zPacketizer._trigger_rekeyN)FF)F)F)&r   r   r   r   Úpowr›   rœ   r§   r¨   rR   ÚpropertyrT   rV   r_   r`   rb   rc   re   rh   ri   rj   rk   rm   rp   rq   rv   rw   ry   r…   rŠ   rŽ   r¥   r¯   r–   r€   r‹   r•   r�   r   r   r   r   r#   A   sL   



0
  ø
% ù

	
3+? 	r#   )!r   r}   r·   rQ   r™   rF   rJ   Úhmacr   Zparamikor   Zparamiko.commonr   r   r   r   r   r	   r
   Zparamiko.py3compatr   r   Zparamiko.ssh_exceptionr   r   Zparamiko.messager   r   r‰   r   r"   Úobjectr#   r   r   r   r   Ú<module>   s    $	