a bVV@sdZddlZddlZddlZddlZddlZddlZddlmZddl m Z ddl m Z m Z mZmZmZmZmZddlmZmZddlmZmZddlmZd d ZGd d d eZd dZGdddeZ dS)z Packet handling N)HMAC)util) linefeed_byte cr_byte_valueasbytes MSG_NAMESDEBUG xffffffff zero_byte)ubyte_ord) SSHExceptionProxyCommandFailure)MessagecCst|||SN)rdigest)keymessageZ digest_classr6/tmp/pip-target-98j97qn4/lib/python/paramiko/packet.py compute_hmac.src@seZdZdZdS)NeedRekeyExceptionz1 Exception indicating a rekey is needed. N)__name__ __module__ __qualname____doc__rrrrr2srcCs.d}t|jtur*t|jdkr*|jd}|S)Nr)typeargstuplelen)eargrrr first_arg:s r"c@s"eZdZdZeddZeddZeddZeddZddZ e ddZ dd Z d>d d Z d?d dZddZddZddZddZddZddZddZddZdd Zd!d"Zd#d$Zd%d&Zd'd(Zd@d)d*Zd+d,Zd-d.Zd/d0Zd1d2Z d3d4Z!d5d6Z"d7d8Z#d9d:Z$d;d<Z%d=S)A Packetizerz9 Implementation of the base SSH packet protocol. cCs||_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|_(dS)NFr))_Packetizer__socket_Packetizer__logger_Packetizer__closed_Packetizer__dump_packets_Packetizer__need_rekey_Packetizer__init_countbytes_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 threadingRLock_Packetizer__write_lock_Packetizer__keepalive_intervaltime_Packetizer__keepalive_last_Packetizer__keepalive_callback_Packetizer__timer_Packetizer__handshake_complete_Packetizer__timer_expired)selfsocketrrr__init__QsJ  zPacketizer.__init__cCs|jSr)r)rPrrrclosedszPacketizer.closedcCs ||_dS)z? Set the Python log object to use for logging. N)r()rPlogrrrset_logszPacketizer.set_logFcCs^||_||_||_||_||_||_d|_d|_||_|j dO_ |j dkrZd|_ d|_ dS)zd Switch outbound data cipher. :param etm: Set encrypt-then-mac from OpenSSH rFN) r9r;r5r<r7r>r/r0rDr,r+)rP block_engine block_size mac_enginemac_sizemac_keyZsdctretmrrrset_outbound_ciphers zPacketizer.set_outbound_ciphercCsd||_||_||_||_||_d|_d|_d|_d|_||_ |j dO_ |j dkr`d|_ d|_ dS)zc Switch inbound data cipher. :param etm: Set encrypt-then-mac from OpenSSH rr$rXFN) r:r6r=r8r?r1r2r3r4rEr,r+)rPrYrZr[r\r]r^rrrset_inbound_ciphers  zPacketizer.set_inbound_ciphercCs ||_dSr)r@rPZ compressorrrrset_outbound_compressorsz"Packetizer.set_outbound_compressorcCs ||_dSr)rArarrrset_inbound_compressorsz!Packetizer.set_inbound_compressorcCsd|_|jdSNT)r)r'closerSrrrreszPacketizer.closecCs ||_dSrr*)rPhexdumprrr set_hexdumpszPacketizer.set_hexdumpcCs|jSrrfrSrrr get_hexdumpszPacketizer.get_hexdumpcCs|jSr)r8rSrrrget_mac_size_inszPacketizer.get_mac_size_incCs|jSr)r7rSrrrget_mac_size_outszPacketizer.get_mac_size_outcCs|jS)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+rSrrr need_rekeyszPacketizer.need_rekeycCs||_||_t|_dS)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)rIrLrJrK)rPintervalcallbackrrr set_keepaliveszPacketizer.set_keepalivecCs d|_dSrd)rOrSrrr read_timerszPacketizer.read_timercCs(|js$tt||j|_|jdS)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)rMrFTimerfloatrqstart)rPtimeoutrrrstart_handshakeszPacketizer.start_handshakecCs|js dS|jrdS|jS)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)rMrNrOrSrrrhandshake_timed_outs zPacketizer.handshake_timed_outcCs |jr|jd|_d|_dS)zF Tells `Packetizer` that the handshake has completed. FTN)rMcancelrOrNrSrrrcomplete_handshakes zPacketizer.complete_handshakec CsFt}t|jdkr>|jd|}|j|d|_|t|8}|dkrBd}|rZtz6|j|}t|dkrzt||7}|t|8}Wnrtjyd}Yn\tj y}z@t |}|t j krd}n|t j krn|jrtnWYd}~n d}~00|r>|jrt|r8t|dkr8|jr8t|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 rNFT)r-rr.rwEOFErrorr'recvrQruerrorr"errnoEAGAINEINTRr)r+r_check_keepalive)rPn check_rekeyoutZ got_timeoutxr r!rrrread_allsB        zPacketizer.read_allc Cs"t|_d}t|dkrd}z|j|}WntjyHd}Ynxtjy}z8t|}|t j krpd}n|t j krd}nd}WYd}~n0d}~0t yYnt yd}Yn0|rd}|jrd}n|dkr|dkrd}|d7}|dkrt|t|krq||d}qdS)NrFT rW)rJrKrr'sendrQrur|r"r}r~rr Exceptionr)rz)rPrZ#iteration_with_zero_as_return_valueZ retry_writerr r!rrr write_allJs@      zPacketizer.write_allcCsr|j}t|vr|||7}q|t}||dd|_|d|}t|dkrj|dtkrj|dd}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. rWNrr)r.r _read_timeoutindexrrr )rPrubufrrrrreadlineus   zPacketizer.readlinec Cst|}t|d}|tvr&t|}n d|}t|}|jzz|jdurZ||}||}|j r| t d||| t t |d|jdur|jr|dd|j|dd}q|j|}n|}|jdur td|j}||jr|n|}|t|j||jd|j7}|jdt@|_|||jt|7_|jd7_|j|jkpr|j|jk} | r|jsd } | t | |j|jd|_d|_ |!W|j"n |j"0dS) zR Write a block of data using the current cipher, as an SSH block. r${:x}NzWrite packet <{}>, length {}zOUT: >IrWz(Rekeying (hit {} packets, {} bytes sent))#rr rformatrrHacquirer@ _build_packetr*_logrr format_binaryr9rDupdatestructpackrBrr>r<r7r rr/r0 REKEY_PACKETS REKEY_BYTESr+r3r4_trigger_rekeyrelease) rPdatacmdcmd_nameZorig_lenpacketrpackedpayloadZ sent_too_muchmsgrrr send_messagesd               zPacketizer.send_messagecCs|j|jdd}|jrtd|ddd}||jd}|dd|j|dd}|j|jdd}td|j||}t|j ||j d|j}t ||st d |}|jdur|j|}|jr|tt |d |jr|}ntd|ddd}|dd}|t||jdkr,t d |||jt|} | d|t|}| |t|d} |jdur|j|}||}|jr|tt |d |jdkr|js| d|j}td|j||}t|j ||j d|j}t ||st d t|d} |d || } |jrF|td || |jdur\|| } t| d d} |j| _|jd t@|_||jd}|j|7_|jd 7_|jr|j|7_|jd 7_|j|j ks|j|j!krDt dnL|j|j"ks|j|j#krDd}|t||j|jd|_d|_|$t| d}|t%vrdt%|}n d|}|jr|td|t| || fS)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)rrNrrFz>IIzMismatched MACzIN: zInvalid packet blockingrWz"Got payload ({} bytes, {} padding)z+Remote transport is ignoring rekey requestsz,Rekeying (hit {} packets, {} bytes received)rzRead packet <{}>, length {})&rr6rErunpackr8rrCrr?r=rZconstant_time_bytes_eqr r:rr*rrrrr rrArZseqnor r1r2r+r3r4REKEY_PACKETS_OVERFLOW_MAXREKEY_BYTES_OVERFLOW_MAXrrrr)rPheaderZ packet_size remainingrmacZ mac_payloadZmy_macleftoverrZ post_packetpaddingrrZraw_packet_sizeerrrrrrr read_messages                 zPacketizer.read_messagecCsH|jdurdStt|tr6|D]}|j||q n|j||dSr)r( issubclassrlistrU)rPlevelrmrrrrEs  zPacketizer._logcCs@|jr|jr|jrdSt}||j|jkr<|||_dSr)rIr9r+rJrKrL)rPnowrrrrNszPacketizer._check_keepalivec Cst}z&|jd}t|dkr(tWqWnHtjyBYn6tyv}zt|t j kr`nWYd}~n d}~00|j rtt}|||krtq|S)Nr) rJr'r{rrzrQruEnvironmentErrorr"r}rr))rPrurtrr rrrrr[s$    zPacketizer._read_timeoutcCs~|j}|jrdnd}d|t|||}tdt||d|}||7}|js^|jdurl|t|7}n|t |7}|S)Nrr&rXz>IBrW) r5rDrrrr;r9r osurandom)rPrZbsizeZaddlenrrrrrrqszPacketizer._build_packetcCs d|_dSrdrlrSrrrrszPacketizer._trigger_rekeyN)FF)F)F)&rrrrpowrrrrrRpropertyrTrVr_r`rbrcrerhrirjrkrmrprqrvrwryrrrrrrrrrrrrrrr#AsL    0   %    3+?  r#)!rr}rrQrrFrJhmacrZparamikorZparamiko.commonrrrrrr r Zparamiko.py3compatr r Zparamiko.ssh_exceptionr rZparamiko.messagerrrrr"objectr#rrrrs   $