U
    ccr!                     @   sp  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 d3dd	ZerendZerend
Zd4ddZd5d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#e$ a%da&e' a(d#d$ Z)e
fd%d&Z*G d'd( d(e+Z,e, Z-d)d* Z.d+d, Z/d-d. Z0G d/d0 d0e+Z1d1d2 Z2dS )6z0
Useful functions used by the rest of paramiko.
    )
generatorsN)DEBUG	zero_byte	xffffffffmax_byte)PY2longbyte_chrbyte_ordb)	SSHConfigFc              	   C   s   t d}d}|s0t| dkr0t| d dkr0d}t| d r`t}|rHt}|dt| d   |  } tdt| dD ](}|d> td| ||d  d  }qp|r|t ddt|  > 8 }|S )zTturns a normalized byte string into a long-int
    (adapted from Crypto.Util.number)r                >I   )r   lenr
   r   r   rangestructunpack)sZalways_positiveoutnegativeZfilleri r   1/tmp/pip-unpacked-wheel-rglolp_m/paramiko/util.pyinflate_long%   s     &r      Tc                 C   s   t  }t| } | dkr<| dkr<td| t@ | }| dL } qt|D ]4}| dkr`|d tkr` q| dkrD|d tkrD qqDd}| dkrt}nt	}||d d }|r| dkrt
|d dkrt| }| dkrt
|d dk rt	| }|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
   )nZadd_sign_paddingr   r   r   r   r   deflate_long>   s*    
r&    c                    sp   d}g }t | |d kr<|t| ||d   |d7 }q|t | k r^|t| |d    fdd|D S )Nr      c                    s   g | ]} | qS r   r   ).0lineprefixr   r   
<listcomp>e   s     z!format_binary.<locals>.<listcomp>)r   appendformat_binary_line)datar,   xr   r   r+   r   format_binary]   s    
r2   c                 C   s4   d dd | D }d dd | D }d||S )N c                 S   s   g | ]}d  t|qS )z{:02X}formatr
   r)   cr   r   r   r-   i   s     z&format_binary_line.<locals>.<listcomp>r'   c                 S   s*   g | ]"}d  t|t|d d  qS )z.{:c}..?   _   r4   r6   r   r   r   r-   k   s     z	{:50s} {})joinr5   )r0   leftrightr   r   r   r/   h   s
    r/   c                 C   sR   d}| D ]D}t |}d|  kr(dkr:n n|t|7 }q|td|7 }q|S )N    r      z%{:02X})r
   r	   r   r5   )r   r   r7   r   r   r   r   safe_stringp   s    r?   c                 C   sr   z
|   W S  tk
rl   t| d}t|d }|dkr>Y dS t|d }|d@ sd|dK }|d8 }qJ| Y S X d S )NFr   r   r   r   )
bit_lengthAttributeErrorr&   r
   r   )r%   ZnormZhbyteZbitlenr   r   r   r@   {   s    


r@   c                   C   s   d tjt  dS )Nr'   
)r:   	tracebackformat_exceptionsysexc_infosplitr   r   r   r   
tb_strings   s    rH   c                 C   s   t  }t  }t|dkr$|dd }|dkr|  }t|dkrH|| |t| || | }t|t|}||d| 7 }||8 }q$|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)Zhash_algZsaltkeynbytesZkeydatarJ   Zhash_objsizer   r   r   generate_key_bytes   s    


rO   c                 C   s   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)Zparamiko.hostkeysrP   )filenamerP   r   r   r   load_host_keys   s    rR   c                 C   s   t  }||  |S )z
    Provided only as a backward-compatible wrapper around `.SSHConfig`.

    .. deprecated:: 2.7
        Use `SSHConfig.from_file` instead.
    )r   parse)Zfile_objconfigr   r   r   parse_ssh_config   s    
rU   c                 C   s
   | | S )zM
    Provided only as a backward-compatible wrapper around `.SSHConfig`.
    )lookup)hostnamerT   r   r   r   lookup_ssh_host_config   s    rX   c           	      C   s|   dd|  }}}dd|   }}}|dkrh|| }||||   }}||||   }}||||   }}q |dk rx||7 }|S )Nr   r   r   )	r1   mu1u2u3Zv1Zv2Zv3qr   r   r   mod_inverse   s    r^   c                   C   sF   zt jW S  tk
r@   t td7 att _W 5 Q R X t j Y S X d S )Nr   )_g_thread_dataidrA   _g_thread_lock_g_thread_counterr   r   r   r   get_thread_id   s    rc   c                 C   sf   t d}t|jdkrdS || t| d}t |}d}|d7 }|t |d |	| dS )zKsend paramiko logs to a logfile,
    if they're not already going somewhereZ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)rQ   levelloggerfhandlerfrmr   r   r   log_to_file   s    



rs   c                   @   s   e Zd Zdd ZdS )PFilterc                 C   s   t  |_dS )NT)rc   Z	_threadid)selfrecordr   r   r   filter  s    zPFilter.filterN)__name__
__module____qualname__rw   r   r   r   r   rt     s   rt   c                 C   s   t | }|t |S N)re   rf   	addFilter_pfilter)namero   r   r   r   
get_logger  s    

r   c              
   C   s@   z|  W S  t k
r8 } z|jtjkr( W 5 d}~X Y q X q dS )z6Retries function until it doesn't raise an EINTR errorN)EnvironmentErrorerrnoZEINTR)functioner   r   r   retry_on_signal  s
    r   c                 C   sV   t | t |krdS d}tr tntt | D ] }|t| | t|| A O }q,|dkS )NFr   )r   r   xranger   r
   )rd   r   resr   r   r   r   constant_time_bytes_eq  s    r   c                   @   s   e Zd Zdd Zdd ZdS )ClosingContextManagerc                 C   s   | S r{   r   )ru   r   r   r   	__enter__(  s    zClosingContextManager.__enter__c                 C   s   |    d S r{   )close)ru   typevaluerC   r   r   r   __exit__+  s    zClosingContextManager.__exit__N)rx   ry   rz   r   r   r   r   r   r   r   '  s   r   c                 C   s   t | t||S r{   )maxrK   )Zminimumvalmaximumr   r   r   clamp_value/  s    r   )F)T)r'   )3__doc__
__future__r   r   rE   r   rC   	threadingre   Zparamiko.commonr   r   r   r   Zparamiko.py3compatr   r   r	   r
   r   Zparamiko.configr   r   r#   r$   r&   r2   r/   r?   r@   rH   rO   rR   rU   rX   r^   localr_   rb   Lockra   rc   rs   objectrt   r}   r   r   r   r   r   r   r   r   r   <module>   sH   




