
    a!                     v   d Z ddlm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
mZmZmZ ddlmZmZmZmZmZ ddlmZ ddZerendZeren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#i a$da% ejL                         a'd Z(e
fdZ) G d de*      Z+ e+       Z,d Z-d Z.d Z/ G d de*      Z0d Z1y)!z0
Useful functions used by the rest of paramiko.
    )
generatorsN)DEBUG	zero_byte	xffffffffmax_byte)PY2longbyte_chrbyte_ordb)	SSHConfigc           	         t        d      }d}|s!t        |       dkD  rt        | d         dk\  rd}t        |       dz  r%t        }|rt        }|dt        |       dz  z
  z  | z   } t        dt        |       d      D ]'  }|dz  t        j                  d| ||dz          d   z   }) |r|t        d      dt        |       z  z  z  }|S )zTturns a normalized byte string into a long-int
    (adapted from Crypto.Util.number)r                >I   )r	   lenr   r   r   rangestructunpack)salways_positiveoutnegativefilleris         -lib/python3.12/site-packages/paramiko/util.pyinflate_longr    %   s     q'CHA
!A$41G
1vzF a#a&1*n%)1c!fa  AbyFMM$!a!e=a@@AtAw1s1v:&&J       c                    t               }t        |       } | dk7  r5| dk7  r0t        j                  d| t        z        |z   }| dz  } | dk7  r| dk7  r0t        |      D ])  }| dk(  r|d   t        k7  r n*| dk(  s|d   t        k7  s) n d}| dk(  rt        }nt        }||d   d }|r>| dk(  rt        |d         dk\  r	t        |z   }| dk(  rt        |d         dk  r	t        |z   }|S )	zTturns a long-int into a normalized byte string
    (adapted from Crypto.Util.number)r   r   r   r   )r   Nr   )bytesr	   r   packr   	enumeratedeflate_zero
deflate_ffr   r   r   )nadd_sign_paddingr   r   s       r   deflate_longr,   >   s     	AQA6RKKa)m,q0	b 6R q\ F1-G!A$*,	 6AA	!A$&	AF!A$4/AAG(1Q4.4/1AHr!   c                     d}g }t        |       |dz   kD  r7|j                  t        | ||dz                 |dz  }t        |       |dz   kD  r7|t        |       k  r|j                  t        | |d               |D cg c]  }||z   	 c}S c c}w )Nr      )r   appendformat_binary_line)dataprefixxr   lines        r   format_binaryr5   ]   s    	A
C
d)a"f


%d1q2v&678	R d)a"f
 	3t9}

%d12h/0&)*dFTM***s   <Bc           
      :   dj                  | D cg c]  }dj                  t        |             c}      }dj                  | D cg c].  }dj                  t        |            t        |      dz   dz     0 c}      }dj                  ||      S c c}w c c}w )N z{:02X} z.{:c}..?   _   z	{:50s} {})joinformatr   )r1   cleftrights       r   r0   r0   h   s    884@aX__Xa[1@ADGGJNOQ		(1+	&b(8R'?	@OE dE**	 AOs   !B3Bc                     d}| D ]G  }t        |      }d|cxk  rdk  rn n|t        |      z  }+|t        dj                  |            z  }I |S )Nr!   r      z%{:02X})r   r
   r   r<   )r   r   r=   r   s       r   safe_stringrB   p   sY    
C *QK>c>8A;C1Y%%a())C* Jr!   c                     	 | j                         S # t        $ rI t        | d      }t        |d         }|dk(  rY yt	        |      dz  }|dz  s|dz  }|dz  }|dz  s|cY S w xY w)NFr   r   r   r   )
bit_lengthAttributeErrorr,   r   r   )r*   normhbytebitlens       r   rD   rD   {   s|    ||~ 	Au%a!A:TQ4<aKEaKF 4< 	s    (A$"A$A$#A$c                      dj                  t        j                  t        j                                j                  d      S )Nr8   
)r;   	tracebackformat_exceptionsysexc_infosplit r!   r   
tb_stringsrQ      s-    779--s||~>?EEdKKr!   c                 p   t               }t               }t        |      dkD  r|dd }|dkD  r |        }t        |      dkD  r|j                  |       |j                  t        |             |j                  |       |j	                         }t        |t        |            }||d| z  }||z  }|dkD  r|S )a  
    Given a password, passphrase, or other human-source key, scramble it
    through a secure hash into some keyworthy bytes.  This specific algorithm
    is used for encrypting/decrypting private key files.

    :param function hash_alg: A function which creates a new hash object, such
        as ``hashlib.sha256``.
    :param salt: data to salt the hash with.
    :type salt: byte string
    :param str key: human-entered password or passphrase.
    :param int nbytes: number of bytes to generate.
    :return: Key data `str`
    r   Nr   )r%   r   updater   digestmin)hash_algsaltkeynbyteskeydatarT   hash_objsizes           r   generate_key_bytesr]      s     gGWF
4y1}BQx
1*:v;?OOF##"63v;'6%4= $ 1* Nr!   c                     ddl m}  ||       S )a  
    Read a file of known SSH host keys, in the format used by openssh, and
    return a compound dict of ``hostname -> keytype ->`` `PKey
    <paramiko.pkey.PKey>`. The hostname may be an IP address or DNS name.  The
    keytype will be either ``"ssh-rsa"`` or ``"ssh-dss"``.

    This type of file unfortunately doesn't exist on Windows, but on posix,
    it will usually be stored in ``os.path.expanduser("~/.ssh/known_hosts")``.

    Since 1.5.3, this is just a wrapper around `.HostKeys`.

    :param str filename: name of the file to read host keys from
    :return:
        nested dict of `.PKey` objects, indexed by hostname and then keytype
    r   )HostKeys)paramiko.hostkeysr_   )filenamer_   s     r   load_host_keysrb      s      +Hr!   c                 <    t               }|j                  |        |S )z
    Provided only as a backward-compatible wrapper around `.SSHConfig`.

    .. deprecated:: 2.7
        Use `SSHConfig.from_file` instead.
    )r   parse)file_objconfigs     r   parse_ssh_configrg      s     [F
LLMr!   c                 $    |j                  |       S )zM
    Provided only as a backward-compatible wrapper around `.SSHConfig`.
    )lookup)hostnamerf   s     r   lookup_ssh_host_configrk      s     ==""r!   c                     dd|}}}dd| }}}|dkD  r)||z  }||||z  z
  }}||||z  z
  }}||||z  z
  }}|dkD  r)|dk  r||z  }|S )Nr   r   rP   )	r3   mu1u2u3v1v2v3qs	            r   mod_inverseru      s    AqBBAqBB
q&"HR"q&[BR"q&[BR"q&[B	 q&
 
Av
aIr!   c                  (   t        t        j                               } 	 t        |    S # t        $ r` t
        j                          	 t        dz  at        x}t        | <   t
        j                          n# t
        j                          w xY w|cY S w xY w)Nr   )	id	threadingcurrentThread_g_thread_idsKeyError_g_thread_lockacquire_g_thread_counterrelease)tidrets     r   get_thread_idr      s}    
Y$$&
'C	S!!  	%"'88C-$""$N""$
s'   ( BA3B3B		BBc                 >   t        j                  d      }t        |j                        dkD  ry|j	                  |       t        | d      }t        j                  |      }d}|dz  }|j                  t        j                  |d             |j                  |       y)zKsend paramiko logs to a logfile,
    if they're not already going somewhereparamikor   Naz>%(levelname)-.3s [%(asctime)s.%(msecs)03d] thr=%(_threadid)-3dz %(name)s: %(message)sz%Y%m%d-%H:%M:%S)
logging	getLoggerr   handlerssetLevelopenStreamHandlersetFormatter	Formatter
addHandler)ra   levelloggerfhandlerfrms         r   log_to_filer      s     z*F
6??a
OOEXsA##A&G
JC##C**30ABC
gr!   c                       e Zd Zd Zy)PFilterc                 "    t               |_        y)NT)r   	_threadid)selfrecords     r   filterzPFilter.filter	  s    (?r!   N)__name__
__module____qualname__r   rP   r!   r   r   r     s    r!   r   c                 Z    t        j                  |       }|j                  t               |S N)r   r   	addFilter_pfilter)namer   s     r   
get_loggerr     s%    t$F
XMr!   c                 ~    	 	  |        S # t         $ r(}|j                  t        j                  k7  r Y d}~nd}~ww xY w=)z6Retries function until it doesn't raise an EINTR errorN)EnvironmentErrorerrnoEINTR)functiones     r   retry_on_signalr     s?    
	: 	ww%++% &	 s   
 	;6;c                     t        |       t        |      k7  ryd}t        rt        nt        t        |             D ]"  }|t	        | |         t	        ||         z  z  }$ |dk(  S )NFr   )r   r   xranger   r   )r   r   resr   s       r   constant_time_bytes_eqr   !  s^    
1vQ
CfA/ /x!~1../!8Or!   c                       e Zd Zd Zd Zy)ClosingContextManagerc                     | S r   rP   )r   s    r   	__enter__zClosingContextManager.__enter__,  s    r!   c                 $    | j                          y r   )close)r   typevaluerK   s       r   __exit__zClosingContextManager.__exit__/  s    

r!   N)r   r   r   r   r   rP   r!   r   r   r   +  s    r!   r   c                 .    t        | t        ||            S r   )maxrU   )minimumvalmaximums      r   clamp_valuer   3  s    wC)**r!   )F)T)r8   )2__doc__
__future__r   r   rM   r   rK   rx   r   paramiko.commonr   r   r   r   paramiko.py3compatr   r	   r
   r   r   paramiko.configr   r    r(   r)   r,   r5   r0   rB   rD   rQ   r]   rb   rg   rk   ru   rz   r~   Lockr|   r   r   objectr   r   r   r   r   r   r   rP   r!   r   <module>r      s   & "  
     A A ? ? %*  yQX$
>++L>*	#  ! !&  f  9F +r!   