
    aRV                         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	 Z G d
 de      Zd Z G d de      Z y)z
Packet handling
    N)HMAC)util)linefeed_bytecr_byte_valueasbytes	MSG_NAMESDEBUG	xffffffff	zero_byte)ubyte_ord)SSHExceptionProxyCommandFailure)Messagec                 8    t        | ||      j                         S N)r   digest)keymessagedigest_classs      /lib/python3.12/site-packages/paramiko/packet.pycompute_hmacr   .   s    Wl+2244    c                       e Zd ZdZy)NeedRekeyExceptionz1
    Exception indicating a rekey is needed.
    N)__name__
__module____qualname____doc__ r   r   r   r   2   s     	r   r   c                     d }t        | j                        t        u r't        | j                        dkD  r| j                  d   }|S )Nr   )typeargstuplelen)eargs     r   	first_argr(   :   s7    
CAFF|uQVVqffQiJr   c                      e Zd ZdZ edd      Z edd      Z edd      Z edd      Zd Z	e
d        Zd Z	 	 d!dZ	 d"dZd	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd"dZd Zd Zd Zd Z d Z!d Z"d Z#d Z$d Z%y )#
Packetizerz9
    Implementation of the base SSH packet protocol.
          c                    || _         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?        j@                         | _!        d| _"        tG        jF                         | _$        d | _%        d | _&        d| _'        d| _(        y )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sockets     r   __init__zPacketizer.__init__Q   s?   #! 7  !"#)*&+,( !" "&!%  $#"W!G%)"$(!%&"$%! &OO- %&! $		$(!$)!$r   c                     | j                   S r   )r1   rX   s    r   closedzPacketizer.closed   s    }}r   c                     || _         y)z?
        Set the Python log object to use for logging.
        N)r0   )rX   logs     r   set_logzPacketizer.set_log   s     r   c                     || _         || _        || _        || _        || _        || _        d| _        d| _        || _        | xj                  dz  c_	        | j                  dk(  rd| _	        d| _
        yy)zd
        Switch outbound data cipher.
        :param etm: Set encrypt-then-mac from OpenSSH
        r         FN)rA   rC   r=   rD   r?   rF   r7   r8   rL   r4   r3   )rX   block_engine
block_size
mac_enginemac_sizemac_keysdctretms           r   set_outbound_cipherzPacketizer.set_outbound_cipher   s     #/  * *&$ 	Q! !D %D "r   c                     || _         || _        || _        || _        || _        d| _        d| _        d| _        d| _        || _	        | xj                  dz  c_
        | j                  dk(  rd| _
        d| _        yy)zc
        Switch inbound data cipher.
        :param etm: Set encrypt-then-mac from OpenSSH
        r   r+   rc   FN)rB   r>   rE   r@   rG   r9   r:   r;   r<   rM   r4   r3   )rX   rd   re   rf   rg   rh   rj   s          r   set_inbound_cipherzPacketizer.set_inbound_cipher   s     ".))%# !"#)*&+,( 	Q! !D %D "r   c                     || _         y r   )rH   rX   
compressors     r   set_outbound_compressorz"Packetizer.set_outbound_compressor   s
    %/"r   c                     || _         y r   )rI   ro   s     r   set_inbound_compressorz!Packetizer.set_inbound_compressor   s
    $.!r   c                 F    d| _         | j                  j                          y NT)r1   r/   closer\   s    r   rv   zPacketizer.close   s    r   c                     || _         y r   r2   )rX   hexdumps     r   set_hexdumpzPacketizer.set_hexdump   s
    %r   c                     | j                   S r   rx   r\   s    r   get_hexdumpzPacketizer.get_hexdump       """r   c                     | j                   S r   )r@   r\   s    r   get_mac_size_inzPacketizer.get_mac_size_in   s    !!!r   c                     | j                   S r   )r?   r\   s    r   get_mac_size_outzPacketizer.get_mac_size_out   r}   r   c                     | 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.
        r3   r\   s    r   
need_rekeyzPacketizer.need_rekey   s        r   c                 R    || _         || _        t        j                         | _        y)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)rQ   rT   rR   rS   )rX   intervalcallbacks      r   set_keepalivezPacketizer.set_keepalive   s"     %-!$,! $		r   c                     d| _         y ru   )rW   r\   s    r   
read_timerzPacketizer.read_timer   s
    #r   c                     | j                   sIt        j                  t        |      | j                        | _         | j                   j                          yy)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)rU   rN   Timerfloatr   start)rX   timeouts     r   start_handshakezPacketizer.start_handshake   s:     ||$??5>4??KDLLL  r   c                 N    | j                   sy| j                  ry| 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)rU   rV   rW   r\   s    r   handshake_timed_outzPacketizer.handshake_timed_out   s&     ||$$###r   c                 n    | j                   r)| j                   j                          d| _        d| _        yy)zF
        Tells `Packetizer` that the handshake has completed.
        FTN)rU   cancelrW   rV   r\   s    r   complete_handshakezPacketizer.complete_handshake  s0     <<LL!#(D (,D% r   c                 (   t               }t        | j                        dkD  r1| j                  d| }| j                  |d | _        |t        |      z  }|dkD  rd}| j                         r
t	               	 | j
                  j                  |      }t        |      dk(  r
t	               ||z  }|t        |      z  }|rL| j                  r
t	               |r$t        |      dk(  r| j                  r
t!               | j#                          |dkD  r|S # t        j                  $ r d}Y mt        j                  $ rV}t        |      }|t        j                  k(  rd}n+|t        j                  k(  rn| j                  r
t	                Y d}~d}~ww xY w)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)r5   r%   r6   r   EOFErrorr/   recvrY   r   errorr(   errnoEAGAINEINTRr1   r3   r   _check_keepalive)rX   ncheck_rekeyoutgot_timeoutxr&   r'   s           r   read_allzPacketizer.read_all  sh    gt 1$""2A&C#//3DSMA!eK'')j MM&&q)q6Q;"*$qSV" =="*$CHMt7H7H,..%%'? !e@ 
- >> #"<<   l%,,&"&KEKK']]"*$s    6AD F)F;AFFc                 H   t        j                          | _        d}t        |      dkD  rud}	 | j                  j	                  |      }|rd}| j                  rd}ndk(  r|dkD  rd}|dz  }|dk  r
t               |t        |      k(  r	 y ||d  }t        |      dkD  ruy # t
        j                  $ r d}Y ot
        j                  $ rC}t        |      }|t        j                  k(  rd}n|t        j                  k(  rd}nd}Y d }~d }~wt        $ r  t        $ r d}Y w xY w)Nr   FT
   rb   )rR   rS   r%   r/   sendrY   r   r   r(   r   r   r   r   	Exceptionr1   r   )rX   r   #iteration_with_zero_as_return_valueretry_writer   r&   r'   s          r   	write_allzPacketizer.write_allJ  s(    $		./+#hlKMM&&s+" ==A6ABF A3q831uj CH} ab'CK #hlL 	E >> #"<< l%,,&"&KEKK'"&KA&  s#   B   D!7D!	9DD! D!c                    | j                   }t        |vr|| j                  |      z  }t        |vr|j                  t              }||dz   d | _         |d| }t	        |      dkD  r|d   t
        k(  r|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   )r6   r   _read_timeoutindexr%   r   r   )rX   r   bufr   s       r   readlinezPacketizer.readlineu  s    
 3&4%%g..C 3&IIm$q1uw<"1gHqLs2w-7cr(Cvr   c                    t        |      }t        |d         }|t        v r
t        |   }ndj                  |      }t	        |      }| j
                  j                          	 | j                  | j                  |      }| j                  |      }| j                  rP| j                  t        dj                  ||             | j                  t        t        j                  |d             | j                  M| j                  r%|dd | j                  j!                  |dd       z   }n| j                  j!                  |      }n|}| j                  dt#        j$                  d| j&                        }|| j                  r|n|z   }|t)        | j*                  || j,                        d| j.                   z  }| j&                  dz   t0        z  | _        | j3                  |       | xj4                  t	        |      z  c_        | xj6                  dz  c_        | j6                  | j8                  k\  xs | j4                  | j:                  k\  }	|	rf| j<                  sZd	}
| j                  t        |
j                  | j6                  | j4                               d| _        d| _         | jC                          | j
                  jE                          y# | j
                  jE                          w xY w)
zR
        Write a block of data using the current cipher, as an SSH block.
        r   ${:x}NzWrite packet <{}>, length {}zOUT:    >Irb   z(Rekeying (hit {} packets, {} bytes sent))#r   r   r   formatr%   rP   acquirerH   _build_packetr2   _logr	   r   format_binaryrA   rL   updatestructpackrJ   r   rF   rD   r?   r
   r   r7   r8   REKEY_PACKETSREKEY_BYTESr3   r;   r<   _trigger_rekeyrelease)rX   datacmdcmd_nameorig_lenpacketr   packedpayloadsent_too_muchmsgs              r   send_messagezPacketizer.send_message  s   
 t}tAw) ~H~~c*Ht9!!#0	())511$7''-F""		299(HM 		%!3!3FG!DE&&2>> 1+(?(?(F(Fqr
) C 1188@C&&2T4+E+EF 4>>CvF|&&1F1F'D'') ) **Q.*D& NN3S)1$##t'9'99 9$$(8(88  T%6%6@		3::d&9&94;L;LM 23.340##%%%'D%%'s   #IK K*c           	      
   | j                  | j                  d      }| j                  rt        j                  d|dd       d   }|| j                  z
  dz   }|dd | j                  |d      z   }| j                  | j
                  d      }t        j                  d| j                  |      |z   }t        | j                  || j                        d| j
                   }t        j                  ||      st        d	      |}| j                  | j                  j                  |      }| j                   r*| j#                  t$        t        j&                  |d
             | j                  r|}nt        j                  d|dd       d   }|dd }|t)        |      z
  | j                  z  dk7  rt        d      | j                  || j
                  z   t)        |      z
        }	|	d|t)        |      z
   }|	|t)        |      z
  d }
| j                  | j                  j                  |      }||z   }| j                   r*| j#                  t$        t        j&                  |d
             | j
                  dkD  r| j                  s
d| j
                   }t        j                  d| j                        |z   }t        | j                  || j                        d| j
                   }t        j                  ||      st        d	      t+        |d         }|d|z
   }| j                   r&| j#                  t$        dj-                  ||             | j.                  | j/                  |      }t1        |dd       }| j                  |_        | j                  dz   t4        z  | _        || j
                  z   dz   }| xj6                  |z  c_        | xj8                  dz  c_        | j:                  rg| xj<                  |z  c_        | xj>                  dz  c_        | j>                  | j@                  k\  s| j<                  | jB                  k\  rt        d      | j8                  | jD                  k\  s| j6                  | jF                  k\  rZd}| j#                  t$        |j-                  | j8                  | j6                               d| _        d| _        | jI                          t+        |d         }|tJ        v r
tJ        |   }ndj-                  |      }| j                   r/| j#                  t$        dj-                  |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)z+Remote transport is ignoring rekey requestsz,Rekeying (hit {} packets, {} bytes received)r   zRead packet <{}>, length {})&r   r>   rM   r   unpackr@   r   rK   r   rG   rE   r   constant_time_bytes_eqr   rB   r   r2   r   r	   r   r%   r   r   rI   r   seqnor
   r9   r:   r3   r;   r<   REKEY_PACKETS_OVERFLOW_MAXREKEY_BYTES_OVERFLOW_MAXr   r   r   r   )rX   headerpacket_size	remainingr   macmac_payloadmy_macleftoverr   post_packetpaddingr   r   raw_packet_sizeerrr   r   s                     r   read_messagezPacketizer.read_message  s    t33F== --fRaj9!<K#d&:&::Q>IABZ$--	u-"MMF-- 2 2-FCE4#<#<kJ  "!!;0D0D"""$F ..vs;"#344F!!-++226:FIIeT//?@ ==F !--fRaj9!<K abzHc(m+t/C/CCqH"#<==--d0003x=@C 6;X67FkCM9;<K%%1//66v>&FIIeT//?@!$--2 2 23CE4#<#<kJ  "!!;0D0D"""$F ..vs;"#3446!9%[723II4;; $$0//8Ggabk"--	%)%>%>%Bi$O! &(:(::Q>01$ **o=*,,1,00223 ..$2O2OO"A  %%););;!!T%5%55 ACII

422D4I4IJ ./D*/0D,!wqz") ~H~~c*HII-44Xs7|L Cxr   c                     | j                   y t        t        |      t              r$|D ]  }| j                   j	                  ||         y | j                   j	                  ||       y r   )r0   
issubclassr"   listr_   )rX   levelr   ms       r   r   zPacketizer._logE  sV    == d3i& ,!!%+, MMeS)r   c                     | j                   r| j                  r| j                  ry t        j                         }|| j                  | j                   z   kD  r| j                          || _        y y r   )rQ   rA   r3   rR   rS   rT   )rX   nows     r   r   zPacketizer._check_keepaliveN  s`    ))**   iik&&)B)BBB%%'$'D! Cr   c                    t        j                          }	 	 | j                  j                  d      }t        |      dk(  r
t	               	 |S # t
        j                  $ r Y n3t        $ r(}t        |      t        j                  k(  rn Y d }~nd }~ww xY w| j                  r
t	               t        j                          }||z
  |k\  rt        j                         )N   r   )rR   r/   r   r%   r   rY   r   EnvironmentErrorr(   r   r   r1   )rX   r   r   r   r&   r   s         r   r   zPacketizer._read_timeout[  s    		MM&&s+q6Q;"*$  >> # Q<5;;. 
 }}j ))+CU{g%nn&&# s   3A B"B*BBc                 >   | j                   }| j                  rdnd}d|z   t        |      |z   |z  z
  }t        j                  dt        |      |z   dz   |      }||z  }| j
                  s| j                  |t        |z  z  }|S |t        j                  |      z  }|S )Nr   r.   rc   z>IBrb   )
r=   rL   r%   r   r   rC   rA   r   osurandom)rX   r   bsizeaddlenr   r   s         r   r   zPacketizer._build_packetq  s    %% nn!e)Gv 5>?UCL7$:Q$>H't66> i'))F  bjj))Fr   c                     d| _         y ru   r   r\   s    r   r   zPacketizer._trigger_rekey  s
     r   N)FF)F)&r   r   r   r   powr   r   r   r   rZ   propertyr]   r`   rk   rm   rq   rs   rv   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     2JMa*K "%Q"1bz.%`   &J &<0/&#"#!,$
!$ -1f)V=(~~D*(,$!r   r*   )!r   r   r   rY   r   rN   rR   hmacr   paramikor   paramiko.commonr   r   r   r   r	   r
   r   paramiko.py3compatr   r   paramiko.ssh_exceptionr   r   paramiko.messager   r   r   r   r(   objectr*   r    r   r   <module>r      sb   &  	         + D $5	 	D	! D	!r   