o
    
i$                     @   s"  U d 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	 zddl
Z
W n ey.   dZY nw ddlZeeZi ZdZ	 dZdZejdgZd	d
 Zdd ZdefdefdefdefdefdefdZeee	eef f ed< dd Zdd Z dd Z!d!ddZ"								d"dd Z#dS )#aq  Implements I/O streams over SSH.

Examples
--------

>>> with open('/proc/version_signature', host='1.2.3.4') as conn:
...     print(conn.read())
b'Ubuntu 4.4.0-1061.70-aws 4.4.131'

Similarly, from a command line::

    $ python -c "from smart_open import ssh;print(ssh.open('/proc/version_signature', host='1.2.3.4').read())"
    b'Ubuntu 4.4.0-1061.70-aws 4.4.131'

    N)DictCallableTupleT)sshscpsftp   )zssh://username@host/path/filezssh://username@host//path/filezscp://username@host/path/filezsftp://username@host/path/filez~/.ssh/configc                 C   s   | ot j| S N)urllibparseunquote)text r   B/home/ubuntu/.local/lib/python3.10/site-packages/smart_open/ssh.py_unquoteD   s   r   c                 C   s(   | dkrdS | dkrdS t d|  d)NnoFyesTzExpected 'yes' / 'no', got .)
ValueError)stringr   r   r   	_str2boolH   s
   r   connecttimeoutcompressiongssapiauthenticationgssapikeyexchangegssapidelegatecredentialsgssapitrustdns)timeoutcompressgss_authgss_kexgss_deleg_credsgss_trust_dns_PARAMIKO_CONFIG_MAPc                 C   sT   t j| }|jtv sJ t|jt|jt|j|j	|j
r"t|j
nd t|jdS )N)schemeuri_pathuserhostportpassword)r
   r   urlsplitr$   SCHEMESdictr   pathusernamehostnamer(   intr)   )uri_as_string	split_urir   r   r   	parse_urid   s   r3   c                 C   sH   t jt|}t| }|d}|d i ||}t||fi |S )Nr%   r$   )
smart_openutilscheck_kwargsopenr3   pop)urimodetransport_paramskwargs
parsed_urir%   final_paramsr   r   r   open_uriq   s   

r?   c                 C   sb   t  }|  |t   |pi  }d|vr|d| |d| |j| |fi | |S )Nkey_filenamer)   r.   )paramiko	SSHClientload_system_host_keysset_missing_host_key_policyAutoAddPolicycopy
setdefaultconnect)r/   r.   r(   r)   connect_kwargsr   r<   r   r   r   _connect_sshz   s   rJ   c              
   C   s~  t dd | ||||fD s| ||||fS | std|pi  }dd tD }d}|D ]{}ztj|}	W n	 ty?   Y q,w | |	 vrGq,|		| }	|d u rV|	
dd }|s\|	d }|d u rtzt|	d	 }W n ttfys   Y nw |
d
d u r|	
dg }
t|
r|
|d
< t D ]\}\}}|
|d u r||	v r||	| ||< qq,|d u rt}|st }|r|} | ||||fS )Nc                 s   s    | ]}|d u V  qd S r	   r   ).0argr   r   r   	<genexpr>   s    z&_maybe_fetch_config.<locals>.<genexpr>z'you must specify the host to connect toc                 S   s   g | ]
}t j|r|qS r   )osr-   exists)rK   fr   r   r   
<listcomp>   s    z'_maybe_fetch_config.<locals>.<listcomp> r&   r/   r(   r@   identityfile)anyr   rF   _SSH_CONFIG_FILESrA   	SSHConfig	from_pathPermissionErrorget_hostnameslookupgetr0   KeyErrorlenr#   itemsDEFAULT_PORTgetpassgetuser)r'   r.   r)   r(   rI   connect_paramsconfig_filesactual_hostnameconfig_filenamecfgrS   
param_namesshcfg_namefrom_strr   r   r   _maybe_fetch_config   sT   
	rj   rc	                 C   s0  t |||||\}}}}}||f}	d}
t|
D ]g}zt|	 }| js3|  t||||| }t|	< W n tyI   t||||| }t|	< Y nw z| }| }W  n) t	j
y~ } z|jog|jd dk}||
d ksp|sq t|	= W Y d}~qd}~ww |j| ||d}| |_|dur|jdi | |S )a  Open a file on a remote machine over SSH.

    Expects authentication to be already set up via existing keys on the local machine.

    Parameters
    ----------
    path: str
        The path to the file to open on the remote machine.
    mode: str, optional
        The mode to use for opening the file.
    host: str, optional
        The hostname of the remote machine. May not be None.
    user: str, optional
        The username to use to login to the remote machine.
        If None, defaults to the name of the current user.
    password: str, optional
        The password to use to login to the remote machine.
    port: int, optional
        The port to connect to.
    connect_kwargs: dict, optional
        Any additional settings to be passed to paramiko.SSHClient.connect.
    prefetch_kwargs: dict, optional
        Any additional settings to be passed to paramiko.SFTPFile.prefetch.
        The presence of this dict (even if empty) triggers prefetching.
    buffer_size: int, optional
        Passed to the bufsize argument of paramiko.SFTPClient.open.

    Returns
    -------
    A file-like object.

    Important
    ---------
    If you specify a previously unseen host, then its host key will be added to
    the local ~/.ssh/known_hosts *automatically*.

    If ``username`` or ``password`` are specified in *both* the uri and
    ``transport_params``, ``transport_params`` will take precedence
       r   zSSH session not active   N)r:   bufsizer   )rj   range_SSHget_transportactivecloserJ   r\   open_sftp_clientrA   SSHExceptionargsr7   nameprefetch)r-   r:   r'   r&   r)   r(   rI   prefetch_kwargsbuffer_sizekeyattemptsattemptr   	transportsftp_clientexconnection_timed_outfobjr   r   r   r7      s>   2

r7   )NNNN)rk   NNNNNNrl   )$__doc__r`   rN   loggingurllib.parser
   typingr   r   r   rA   ImportErrorMISSING_DEPSsmart_open.utilsr4   	getLogger__name__loggerrq   r+   r_   URI_EXAMPLESr-   
expanduserrU   r   r   floatr#   str__annotations__r3   r?   rJ   rj   r7   r   r   r   r   <module>   sR   


	
Y