o
    g^                     @   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 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ZdS )z
Packet handling
    N)HMAC)util)linefeed_bytecr_byte_value	MSG_NAMESDEBUG	xffffffff	zero_bytebyte_ord)u)SSHExceptionProxyCommandFailure)Messagec                 C   s   t | || S N)r   digest)keymessagedigest_class r   I/var/www/html/api-tag/env/lib/python3.10/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u rt| jdkr| jd }|S Nr   )typeargstuplelen)eargr   r   r   	first_arg:   s   
r#   c                   @   sH  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 Zdd Z				dDddZ			dEd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dFd.d/Zd0d1 Zd2d3 Z d4d5 Z!d6d7 Z"d8d9 Z#d:d; Z$d<d= Z%d>d? Z&d@dA Z'dBdC Z(dS )G
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 | _d | _t | _t | _d | _d | _d| _d| _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_initial_kex_done_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_Packetizer__aead_out_Packetizer__aead_in_Packetizer__iv_out_Packetizer__iv_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   sT   


zPacketizer.__init__c                 C      | j S r   )r*   rV   r   r   r   closed   s   zPacketizer.closedc                 C   
   d| _ d S r   )rD   rZ   r   r   r   reset_seqno_out      
zPacketizer.reset_seqno_outc                 C   r\   r   )rE   rZ   r   r   r   reset_seqno_in   r^   zPacketizer.reset_seqno_inc                 C   s
   || _ dS )z?
        Set the Python log object to use for logging.
        N)r)   )rV   logr   r   r   set_log   s   
zPacketizer.set_logFNc
           
      C   sn   || _ || _|| _|| _|| _|| _d| _d| _|| _|| _	|	| _
|  jdO  _| jdkr5d| _d| _dS dS )zd
        Switch outbound data cipher.
        :param etm: Set encrypt-then-mac from OpenSSH
        r         FN)r;   r=   r7   r>   r9   r@   r1   r2   rF   rH   rJ   r-   r,   )
rV   block_engine
block_size
mac_enginemac_sizemac_keysdctretmaeadiv_outr   r   r   set_outbound_cipher   s    

zPacketizer.set_outbound_cipherc	           	      C   st   || _ || _|| _|| _|| _d| _d| _d| _d| _|| _	|| _
|| _|  jdO  _| jdkr8d| _d| _dS dS )zc
        Switch inbound data cipher.
        :param etm: Set encrypt-then-mac from OpenSSH
        r   r%   rc   FN)r<   r8   r?   r:   rA   r3   r4   r5   r6   rG   rI   rK   r-   r,   )	rV   rd   re   rf   rg   rh   rj   rk   iv_inr   r   r   set_inbound_cipher   s"   

zPacketizer.set_inbound_cipherc                 C   
   || _ d S r   )rB   rV   
compressorr   r   r   set_outbound_compressor   r^   z"Packetizer.set_outbound_compressorc                 C   rp   r   )rC   rq   r   r   r   set_inbound_compressor   r^   z!Packetizer.set_inbound_compressorc                 C   s   d| _ | j  d S NT)r*   r(   closerZ   r   r   r   rv      s   zPacketizer.closec                 C   rp   r   r+   )rV   hexdumpr   r   r   set_hexdump   r^   zPacketizer.set_hexdumpc                 C   rY   r   rw   rZ   r   r   r   get_hexdump      zPacketizer.get_hexdumpc                 C   rY   r   )r:   rZ   r   r   r   get_mac_size_in   r{   zPacketizer.get_mac_size_inc                 C   rY   r   )r9   rZ   r   r   r   get_mac_size_out   r{   zPacketizer.get_mac_size_outc                 C   rY   )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,   rZ   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)rO   rR   rP   rQ   )rV   intervalcallbackr   r   r   set_keepalive   s   zPacketizer.set_keepalivec                 C   r\   ru   )rU   rZ   r   r   r   
read_timer  r^   zPacketizer.read_timerc                 C   s,   | j stt|| j| _ | j   dS 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)rS   rL   Timerfloatr   start)rV   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)rS   rT   rU   rZ   r   r   r   handshake_timed_out  s
   
zPacketizer.handshake_timed_outc                 C   s$   | j r| j   d| _d| _dS dS )zF
        Tells `Packetizer` that the handshake has completed.
        FTN)rS   cancelrU   rT   rZ   r   r   r   complete_handshake#  s
   

zPacketizer.complete_handshakec              
   C   s2  t  }t| jdkr| jd| }| j|d | _|t|8 }|dkrd}|  r,t z| j|}t|dkr<t ||7 }|t|8 }W n1 tjyS   d}Y n& tj	yx } zt
|}|tjkrgd}n| jrmt  W Y d}~nd}~ww |r| jrt |rt|dkr| jrt |   |dks#|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/   r   EOFErrorr(   recvrW   r   errorr#   errnoEAGAINr*   r,   r   _check_keepalive)rV   ncheck_rekeyoutgot_timeoutxr!   r"   r   r   r   read_all,  sF   
zPacketizer.read_allc              
   C   s  t   | _d}t|dkrd}z| j|}W n= tjy#   d}Y n2 tjyC } zt|}|t	j
kr7d}nd}W Y d }~nd }~w tyJ     tyT   d}Y nw |r_d}| jr^d}n|dkri|dkrid}|d7 }|dk rtt |t|kr}	 d S ||d  }t|dksd S )Nr   FT
   rb   )rP   rQ   r    r(   sendrW   r   r   r#   r   r   r   	Exceptionr*   r   )rV   r   #iteration_with_zero_as_return_valueretry_writer   r!   r"   r   r   r   	write_all\  sF   

#zPacketizer.write_allc                 C   sx   | j }t|vr|| |7 }t|vs|t}||d d | _ |d| }t|dkr8|d tkr8|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.
        rb   Nr   r   )r/   r   _read_timeoutindexr    r   r   )rV   r   bufr   r   r   r   readline  s   
zPacketizer.readlinec                 C   s@   |dd  }t |d}|d }|dd}|dd | }|S )N   bigrb   r'   r   )int
from_bytesto_bytes)rV   iviv_counter_b
iv_counterinc_iv_counterinc_iv_counter_bnew_ivr   r   r   _inc_iv_counter  s   zPacketizer._inc_iv_counterc                 C   sL  |  }t|d }|tv rt| }nd|}t|}| j  z| jdur,| |}| |}| j	rH| 
td|| | 
tt|d | jdur| jra|dd | j|dd  }n+| jr|dd | j| j|dd |dd  }| | j| _n	| j|}n|}| jdur| jstd| j}|| jr|n| }|t| j|| jd| j 7 }| jd t@ }	|	dkr| jstd	|	| _| | |  j t|7  _ |  j!d7  _!| j!| j"kp| j | j#k}
|
r| j$sd
}| 
t|| j!| j  d| _%d| _&| '  W | j(  dS W | j(  dS W | j(  dS | j(  w )zR
        Write a block of data using the current cipher, as an SSH block.
        r   ${:x}NzWrite packet <{}>, length {}zOUT: r   >Irb   /Sequence number rolled over during initial kex!z(Rekeying (hit {} packets, {} bytes sent)))asbytesr
   r   formatr    rN   acquirerB   _build_packetr+   _logr   r   format_binaryr;   rF   updaterH   encryptrJ   r   structpackrD   r   r@   r>   r9   r   r0   r   r   r1   r2   REKEY_PACKETSREKEY_BYTESr,   r5   r6   _trigger_rekeyrelease)rV   datacmdcmd_nameorig_lenpacketr   packedpayloadnext_seqsent_too_muchmsgr   r   r   send_message  s|   














zPacketizer.send_messagec                 C   s>  | j | jdd}| jrVtd|dd d }|| j d }|dd | j |dd }| j | jdd}td| j|| }t| j	|| j
d| j }t||sTtd	|}| jrtd|dd d }|dd }|| j d | j }|dd | j |dd }| j| j||}| | j| _| jdur| js| j|}| jr| tt|d
 | js| jr|}nQtd|dd d }|dd }	|t|	 | j dkrtd|  || j t|	 }
|
d|t|	  }|
|t|	 d }| jdur| j|}|	| }| jr| tt|d
 | jdkrL| jsL| jsL|d| j }td| j|| }t| j	|| j
d| j }t||sLtd	t|d }|d||  }| jrh| td|| | jdurs| |}t|dd }| j|_| jd t@ }|dkr| jstd|| _|| j d }|  j |7  _ |  j!d7  _!| j"r|  j#|7  _#|  j$d7  _$| j$| j%ks| j#| j&krtdn&| j!| j'ks| j | j(krd}| t|| j!| j  d| _#d| _$| )  t|d }|t*v rt*| }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 blockingrb   z"Got payload ({} bytes, {} padding)r   z+Remote transport is ignoring rekey requestsz,Rekeying (hit {} packets, {} bytes received)r   zRead packet <{}>, length {})+r   r8   rG   r   unpackr:   r   rE   r   rA   r?   r   constant_time_bytes_eqr   rI   r<   decryptrK   r   r   r+   r   r   r   r    r
   r   rC   r   seqnor   r0   r3   r4   r,   r5   r6   REKEY_PACKETS_OVERFLOW_MAXREKEY_BYTES_OVERFLOW_MAXr   r   r   r   )rV   headerpacket_size	remainingr   macmac_payloadmy_macaadleftoverr   post_packetpaddingr   r   r   raw_packet_sizeerrr   r   r   r   r   read_message  s   





zPacketizer.read_messagec                 C   sJ   | j d u rd S tt|tr|D ]	}| j || qd S | j || d S r   )r)   
issubclassr   listr`   )rV   levelr   mr   r   r   r   }  s   
zPacketizer._logc                 C   sD   | j r	| jr	| jrd S t }|| j| j  kr |   || _d S d S r   )rO   r;   r,   rP   rQ   rR   )rV   nowr   r   r   r     s   
zPacketizer._check_keepalivec                 C   sn   t   }	 z| jd}t|dkrt W |S  tjy!   Y nw | jr(t t   }|| |kr6t q)NT   r   )rP   r(   r   r    r   rW   r   r*   )rV   r   r   r   r   r   r   r   r     s"   zPacketizer._read_timeoutc                 C   s   | j }| js	| jrdnd}d| t|| |  }tdt|| d |}||7 }| js2| jd u r:|t| 7 }|S |t	
|7 }|S )Nr   r'   rc   z>IBrb   )r7   rF   rH   r    r   r   r=   r;   r	   osurandom)rV   r   bsizeaddlenr   r   r   r   r   r     s   zPacketizer._build_packetc                 C   r\   ru   r~   rZ   r   r   r   r     s   
zPacketizer._trigger_rekey)FFFN)FFN)F))r   r   r   r   powr   r   r   r   rX   propertyr[   r]   r_   ra   rm   ro   rs   rt   rv   ry   rz   r|   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r$   A   s\    



7

)
"

	0(J 	r$   )r   r   r   rW   r   rL   rP   hmacr   paramikor   paramiko.commonr   r   r   r   r   r	   r
   paramiko.utilr   paramiko.ssh_exceptionr   r   paramiko.messager   r   r   r   r#   r$   r   r   r   r   <module>   s"   $	