U vfV@sdZddlZddlZddlZddlZddlZddlZddlmZddl m Z ddl m Z m Z mZmZmZmZmZddlmZddlmZmZddlmZd d ZGd d d eZd dZGdddZdS)z Packet handling N)HMAC)util) linefeed_byte cr_byte_value MSG_NAMESDEBUG xffffffff zero_bytebyte_ord)u) SSHExceptionProxyCommandFailure)MessagecCst|||SN)rdigest)keymessageZ digest_classr@/opt/alt/python38/lib/python3.8/site-packages/paramiko/packet.py compute_hmac.src@seZdZdZdS)NeedRekeyExceptionz1 Exception indicating a rekey is needed. N)__name__ __module__ __qualname____doc__rrrrr2srcCs.d}t|jtkr*t|jdkr*|jd}|SNr)typeargstuplelen)eargrrr first_arg:s r"c@s2eZdZdZeddZeddZeddZeddZddZ e ddZ dd Z d d Z d d ZdBddZdCddZddZddZddZddZddZddZdd Zd!d"Zd#d$Zd%d&Zd'd(Zd)d*Zd+d,ZdDd-d.Zd/d0Zd1d2Z d3d4Z!d5d6Z"d7d8Z#d9d:Z$d;d<Z%d=d>Z&d?d@Z'dAS)E 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|_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_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 threadingRLock_Packetizer__write_lock_Packetizer__keepalive_intervaltime_Packetizer__keepalive_last_Packetizer__keepalive_callback_Packetizer__timer_Packetizer__handshake_complete_Packetizer__timer_expired)selfsocketrrr__init__QsL  zPacketizer.__init__cCs|jSr)r)rQrrrclosedszPacketizer.closedcCs d|_dSr)rCrTrrrreset_seqno_outszPacketizer.reset_seqno_outcCs d|_dSr)rDrTrrrreset_seqno_inszPacketizer.reset_seqno_incCs ||_dS)z? Set the Python log object to use for logging. N)r()rQlogrrrset_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) r:r<r6r=r8r?r0r1rEr,r+)rQ 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$r[FN) r;r7r>r9r@r2r3r4r5rFr,r+)rQr\r]r^r_r`rarrrset_inbound_ciphers  zPacketizer.set_inbound_ciphercCs ||_dSr)rArQZ compressorrrrset_outbound_compressorsz"Packetizer.set_outbound_compressorcCs ||_dSr)rBrdrrrset_inbound_compressorsz!Packetizer.set_inbound_compressorcCsd|_|jdSNT)r)r'closerTrrrrhszPacketizer.closecCs ||_dSrr*)rQhexdumprrr set_hexdumpszPacketizer.set_hexdumpcCs|jSrrirTrrr get_hexdumpszPacketizer.get_hexdumpcCs|jSr)r9rTrrrget_mac_size_inszPacketizer.get_mac_size_incCs|jSr)r8rTrrrget_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+rTrrr 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)rJrMrKrL)rQintervalcallbackrrr set_keepaliveszPacketizer.set_keepalivecCs d|_dSrg)rPrTrrr 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)rNrGTimerfloatrtstart)rQtimeoutrrrstart_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)rNrOrPrTrrrhandshake_timed_outs zPacketizer.handshake_timed_outcCs |jr|jd|_d|_dS)zF Tells `Packetizer` that the handshake has completed. FTN)rNcancelrPrOrTrrrcomplete_handshakes zPacketizer.complete_handshakec Cs8t}t|jdkr>|jd|}|j|d|_|t|8}|dkr4d}|rZtz6|j|}t|dkrzt||7}|t|8}Wndtjk rd}YnLtj k r}z,t |}|t j krd}n|j rtnW5d}~XYnX|r>|j rt|r*t|dkr*|jr*t|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.rzEOFErrorr'recvrRrxerrorr"errnoEAGAINr)r+r_check_keepalive)rQn check_rekeyoutZ got_timeoutxr r!rrrread_alls>       zPacketizer.read_allc Cst|_d}t|dkrd}z|j|}Wntjk rJd}Ynjtjk r}z t|}|t j krtd}nd}W5d}~XYn,t k rYnt k rd}YnX|rd}|j rd}n|dkr|dkrd}|d7}|dkrt|t|krq||d}qdS)NrFT rZ)rKrLrr'sendrRrxrr"rrr Exceptionr)r})rQrZ#iteration_with_zero_as_return_valueZ retry_writerr r!rrr write_allNs<   zPacketizer.write_allcCsr|j}t|kr|||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. rZNrr)r.r _read_timeoutindexrrr )rQrxbufrrrrreadlinevs   zPacketizer.readlinec Cs|}t|d}|tkr&t|}n d|}t|}|jz|jdk rZ||}| |}|j r| t d||| t t |d|jdk r|jr|dd|j|dd}q|j|}n|}|jdk r td|j}||jr|n|}|t|j||jd|j7}|jdt@} | dkrH|jsHtd | |_|||jt|7_|jd7_|j|jkp|j|j k} | r|j!sd } | t | |j|jd|_"d|_#|$W5|jXdS) zR Write a block of data using the current cipher, as an SSH block. r${:x}NzWrite packet <{}>, length {}zOUT: >IrZ/Sequence number rolled over during initial kex!z(Rekeying (hit {} packets, {} bytes sent))%Zasbytesr rformatrrIacquirereleaserA _build_packetr*_logrr format_binaryr:rEupdatestructpackrCrr?r=r8rr/r rr0r1 REKEY_PACKETS REKEY_BYTESr+r4r5_trigger_rekey) rQdatacmdcmd_nameZorig_lenpacketrpackedpayloadnext_seqZ sent_too_muchmsgrrr send_messagesp              zPacketizer.send_messagecCs|j|jdd}|jrtd|ddd}||jd}|dd|j|dd}|j|jdd}td|j||}t|j ||j d|j}t ||st d |}|jdk r|j|}|jr|tt |d |jr|}ntd|ddd}|dd}|t||jdkr,t d |||jt|} | d|t|}| |t|d} |jdk r|j|}||}|jr|tt |d |jdkr|js| d|j}td|j||}t|j ||j d|j}t ||st d t|d} |d || } |jrF|td || |jdk r\|| } t| d d} |j| _|jd t@}|dkr|jst d||_||jd}|j|7_|jd 7_|jr|j|7_|j d 7_ |j |j!ks |j|j"krbt dnL|j|j#ks2|j|j$krbd}|t||j|jd|_d|_ |%t| d}|t&krt&|}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 blockingrZz"Got payload ({} bytes, {} padding)rz+Remote transport is ignoring rekey requestsz,Rekeying (hit {} packets, {} bytes received)rzRead packet <{}>, length {})'rr7rFrunpackr9rrDrr@r>rZconstant_time_bytes_eqr r;rr*rrrrr rrBrZseqnorr/r2r3r+r4r5REKEY_PACKETS_OVERFLOW_MAXREKEY_BYTES_OVERFLOW_MAXrrrr)rQheaderZ packet_size remainingrmacZ mac_payloadZmy_macleftoverrZ post_packetpaddingrrrZraw_packet_sizeerrrrrrr read_messages               zPacketizer.read_messagecCsH|jdkrdStt|tr6|D]}|j||q n|j||dSr)r( issubclassrlistrX)rQlevelrmrrrrNs  zPacketizer._logcCs@|jr|jr|jrdSt}||j|jkr<|||_dSr)rJr:r+rKrLrM)rQnowrrrrWszPacketizer._check_keepalivecCstt}z&|jd}t|dkr(tWqpWntjk rDYnX|jrRtt}|||krtq|S)Nr)rKr'r~rr}rRrxr))rQrxrwrrrrrrds    zPacketizer._read_timeoutcCs~|j}|jrdnd}d|t|||}tdt||d|}||7}|js^|jdkrl|t|7}n|t |7}|S)Nrr&r[z>IBrZ) r6rErrrr<r:r osurandom)rQrZbsizeZaddlenrrrrrruszPacketizer._build_packetcCs d|_dSrgrorTrrrrszPacketizer._trigger_rekeyN)FF)F)F)(rrrrpowrrrrrSpropertyrUrVrWrYrbrcrerfrhrkrlrmrnrprsrtryrzr|rrrrrrrrrrrrrrr#AsP    1   %    0(B  r#)rrrrRrrGrKhmacrZparamikorZparamiko.commonrrrrrr r Z paramiko.utilr Zparamiko.ssh_exceptionr r Zparamiko.messagerrrrr"r#rrrrs   $