U
    ÓZjßp  ã                   @   sL  d Z ddlZddlZddlZdZdZdZzDddlZeedƒrTej	dkrTdZej
fZndZejjejjjfZW n^ eefk
rÊ   z(ddlZddlZddlZd	ZejfZW n ek
rÄ   d
ZdZY nX Y nX ddlmZ ddlmZ ddlmZ ddd„ZG dd„ deƒZG dd„ deƒZedk �r(eZ G dd„ deƒZ!G dd„ deƒZ"dS )zÌ
This module provides GSS-API / SSPI  authentication as defined in :rfc:`4462`.

.. note:: Credential delegation is not supported in server mode.

.. seealso:: :doc:`/api/kex_gss`

.. versionadded:: 1.15
é    NT© Ú	__title__zpython-gssapiÚMITúPYTHON-GSSAPI-NEWÚSSPIF)ÚMSG_USERAUTH_REQUEST)ÚSSHException)Ú__version_info__c                 C   sL   t dkrt| |ƒS t dkr$t| |ƒS t dkr@tjdkr@t| |ƒS tdƒ‚dS )aÀ  
    Provide SSH2 GSS-API / SSPI authentication.

    :param str auth_method: The name of the SSH authentication mechanism
                            (gssapi-with-mic or gss-keyex)
    :param bool gss_deleg_creds: Delegate client credentials or not.
                                 We delegate credentials by default.
    :return: Either an `._SSH_GSSAPI_OLD` or `._SSH_GSSAPI_NEW` (Unix)
             object or an `_SSH_SSPI` (Windows) object
    :rtype: object

    :raises: ``ImportError`` -- If no GSS-API / SSPI module could be imported.

    :see: `RFC 4462 <http://www.ietf.org/rfc/rfc4462.txt>`_
    :note: Check for the available API and return either an `._SSH_GSSAPI_OLD`
           (MIT GSSAPI using python-gssapi package) object, an
           `._SSH_GSSAPI_NEW` (MIT GSSAPI using gssapi package) object
           or an `._SSH_SSPI` (MS SSPI) object.
           If there is no supported API available,
           ``None`` will be returned.
    r   r   r   Úntz)Unable to import a GSS-API / SSPI module!N)Ú_APIÚ_SSH_GSSAPI_OLDÚ_SSH_GSSAPI_NEWÚosÚnameÚ	_SSH_SSPIÚImportError)Úauth_methodÚgss_deleg_credsr   r   úS/var/www/html/TRUCKING_PROJECT/venv/lib/python3.8/site-packages/paramiko/ssh_gss.pyÚGSSAuthN   s    


r   c                   @   sJ   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	d
„Zdd„ Zdd„ Z	dd„ Z
dS )Ú_SSH_GSSAuthzs
    Contains the shared variables and methods of `._SSH_GSSAPI_OLD`,
    `._SSH_GSSAPI_NEW` and `._SSH_SSPI`.
    c                 C   sL   || _ || _d| _d| _d| _d| _d| _d| _d| _d| _	d| _
d| _dS )úÝ
        :param str auth_method: The name of the SSH authentication mechanism
                                (gssapi-with-mic or gss-keyex)
        :param bool gss_deleg_creds: Delegate client credentials or not
        Nzssh-connectionz1.2.840.113554.1.2.2F)Ú_auth_methodÚ_gss_deleg_credsÚ	_gss_hostÚ	_usernameÚ_session_idÚ_serviceÚ
_krb5_mechÚ	_gss_ctxtÚ_gss_ctxt_statusÚ_gss_srv_ctxtÚ_gss_srv_ctxt_statusZcc_file©Úselfr   r   r   r   r   Ú__init__t   s    z_SSH_GSSAuth.__init__c                 C   s   |  d¡r|| _dS )zì
        This is just a setter to use a non default service.
        I added this method, because RFC 4462 doesn't specify "ssh-connection"
        as the only service value.

        :param str service: The desired SSH service
        zssh-N)Úfindr   )r$   Úservicer   r   r   Úset_service�   s    
z_SSH_GSSAuth.set_servicec                 C   s
   || _ dS )zÔ
        Setter for C{username}. If GSS-API Key Exchange is performed, the
        username is not set by C{ssh_init_sec_context}.

        :param str username: The name of the user who attempts to login
        N)r   )r$   Úusernamer   r   r   Úset_usernameš   s    z_SSH_GSSAuth.set_usernameÚclientc                 C   s\   ddl m} ddlm} |  d¡}| || jƒ¡}|  t|ƒ¡}|dkrP|| S || | S )aÄ  
        This method returns a single OID, because we only support the
        Kerberos V5 mechanism.

        :param str mode: Client for client mode and server for server mode
        :return: A byte sequence containing the number of supported
                 OIDs, the length of the OID and the actual OID encoded with
                 DER
        :note: In server mode we just return the OID length and the DER encoded
               OID.
        r   )ÚObjectIdentifier)Úencoderé   Úserver)Zpyasn1.type.univr,   Úpyasn1.codec.derr-   Ú_make_uint32Úencoder   Úlen)r$   Úmoder,   r-   ZOIDsZkrb5_OIDZOID_lenr   r   r   Ússh_gss_oids£   s    
z_SSH_GSSAuth.ssh_gss_oidsc                 C   s0   ddl m} | |¡\}}| ¡ | jkr,dS dS )zè
        Check if the given OID is the Kerberos V5 OID (server mode).

        :param str desired_mech: The desired GSS-API mechanism of the client
        :return: ``True`` if the given OID is supported, otherwise C{False}
        r   ©ÚdecoderFT)r0   r7   ÚdecodeÚ__str__r   )r$   Údesired_mechr7   ÚmechÚ__r   r   r   Ússh_check_mech¹   s
    z_SSH_GSSAuth.ssh_check_mechc                 C   s   t  d|¡S )zÇ
        Create a 32 bit unsigned integer (The byte sequence of an integer).

        :param int integer: The integer value to convert
        :return: The byte sequence of an 32 bit integer
        z!I)ÚstructÚpack)r$   Úintegerr   r   r   r1   É   s    z_SSH_GSSAuth._make_uint32c                 C   s„   |   t|ƒ¡}||7 }|t dt¡7 }||   t|ƒ¡7 }|| ¡ 7 }||   t|ƒ¡7 }|| ¡ 7 }||   t|ƒ¡7 }|| ¡ 7 }|S )aÎ  
        Create the SSH2 MIC filed for gssapi-with-mic.

        :param str session_id: The SSH session ID
        :param str username: The name of the user who attempts to login
        :param str service: The requested SSH service
        :param str auth_method: The requested SSH authentication mechanism
        :return: The MIC as defined in RFC 4462. The contents of the
                 MIC field are:
                 string    session_identifier,
                 byte      SSH_MSG_USERAUTH_REQUEST,
                 string    user-name,
                 string    service (ssh-connection),
                 string    authentication-method
                           (gssapi-with-mic or gssapi-keyex)
        ÚB)r1   r3   r>   r?   r   r2   )r$   Ú
session_idr)   r'   r   Zmicr   r   r   Ú_ssh_build_micÒ   s    z_SSH_GSSAuth._ssh_build_micN)r+   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r%   r(   r*   r5   r=   r1   rC   r   r   r   r   r   n   s   	
	r   c                   @   sT   e Zd ZdZdd„ Zddd„Zddd	„Zdd
d„Zddd„Ze	dd„ ƒZ
dd„ ZdS )r   z�
    Implementation of the GSS-API MIT Kerberos Authentication for SSH2,
    using the older (unmaintained) python-gssapi package.

    :see: `.GSSAuth`
    c                 C   sB   t  | ||¡ | jr,tjtjtjtjf| _ntjtjtjf| _dS ©r   N)	r   r%   r   ÚgssapiZC_PROT_READY_FLAGZC_INTEG_FLAGZC_MUTUAL_FLAGZC_DELEG_FLAGÚ
_gss_flagsr#   r   r   r   r%   ÷   s    üýz_SSH_GSSAPI_OLD.__init__Nc                 C   s  ddl m} || _|| _t d| j tj¡}t ¡ }| j|_	|dkrTtj
 | j¡}n4| |¡\}	}
|	 ¡ | jkrztdƒ‚ntj
 | j¡}d}z:|dkr¸tj|||j	d�| _| j |¡}n| j |¡}W n6 tjk
rü   d t ¡ d | j¡}t |¡‚Y nX | jj| _|S )	aË  
        Initialize a GSS-API context.

        :param str username: The name of the user who attempts to login
        :param str target: The hostname of the target to connect to
        :param str desired_mech: The negotiated GSS-API mechanism
                                 ("pseudo negotiated" mechanism, because we
                                 support just the krb5 mechanism :-))
        :param str recv_token: The GSS-API token received from the Server
        :raises:
            `.SSHException` -- Is raised if the desired mechanism of the client
            is not supported
        :return: A ``String`` if the GSS-API has returned a token or
            ``None`` if no token was returned
        r   r6   úhost@NúUnsupported mechanism OID.)Z	peer_nameZ	mech_typeZ	req_flagsz{} Target: {}r.   )r0   r7   r   r   rI   ÚNameZC_NT_HOSTBASED_SERVICEÚContextrJ   ÚflagsZOIDZmech_from_stringr   r8   r9   r   ZInitContextr   ÚstepÚGSSExceptionÚformatÚsysÚexc_infoÚestablishedr    )r$   Útargetr:   r)   Ú
recv_tokenr7   Ú	targ_nameÚctxÚ	krb5_mechr;   r<   ÚtokenÚmessager   r   r   Ússh_init_sec_context  s<     ÿ
ý
z$_SSH_GSSAPI_OLD.ssh_init_sec_contextFc                 C   sB   || _ |s0|  | j | j| j| j¡}| j |¡}n| j | j ¡}|S )aÞ  
        Create the MIC token for a SSH2 message.

        :param str session_id: The SSH session ID
        :param bool gss_kex: Generate the MIC for GSS-API Key Exchange or not
        :return: gssapi-with-mic:
                 Returns the MIC token from GSS-API for the message we created
                 with ``_ssh_build_mic``.
                 gssapi-keyex:
                 Returns the MIC token from GSS-API with the SSH session ID as
                 message.
        )r   rC   r   r   r   r   Zget_micr!   ©r$   rB   Zgss_kexÚ	mic_fieldÚ	mic_tokenr   r   r   Ússh_get_micA  s    üz_SSH_GSSAPI_OLD.ssh_get_micc                 C   s:   || _ || _| jdkr t ¡ | _| j |¡}| jj| _|S )á³  
        Accept a GSS-API context (server mode).

        :param str hostname: The servers hostname
        :param str username: The name of the user who attempts to login
        :param str recv_token: The GSS-API Token received from the server,
                               if it's not the initial call.
        :return: A ``String`` if the GSS-API has returned a token or ``None``
                if no token was returned
        N)r   r   r!   rI   ZAcceptContextrP   rU   r"   ©r$   ÚhostnamerW   r)   r[   r   r   r   Ússh_accept_sec_context\  s    


z&_SSH_GSSAPI_OLD.ssh_accept_sec_contextc                 C   sR   || _ || _| jdk	r>|  | j | j| j| j¡}| j ||¡ n| j | j |¡ dS )at  
        Verify the MIC token for a SSH2 message.

        :param str mic_token: The MIC token received from the client
        :param str session_id: The SSH session ID
        :param str username: The name of the user who attempts to login
        :return: None if the MIC check was successful
        :raises: ``gssapi.GSSException`` -- if the MIC check failed
        N)r   r   rC   r   r   r!   Z
verify_micr   ©r$   r`   rB   r)   r_   r   r   r   Ússh_check_micp  s    

üz_SSH_GSSAPI_OLD.ssh_check_micc                 C   s   | j jdk	rdS dS )ú‘
        Checks if credentials are delegated (server mode).

        :return: ``True`` if credentials are delegated, otherwise ``False``
        NTF)r!   Zdelegated_cred©r$   r   r   r   Úcredentials_delegatedŠ  s    z%_SSH_GSSAPI_OLD.credentials_delegatedc                 C   s   t ‚dS )a~  
        Save the Client token in a file. This is used by the SSH server
        to store the client credentials if credentials are delegated
        (server mode).

        :param str client_token: The GSS-API token received form the client
        :raises:
            ``NotImplementedError`` -- Credential delegation is currently not
            supported in server mode
        N©ÚNotImplementedError©r$   Zclient_tokenr   r   r   Úsave_client_creds•  s    z!_SSH_GSSAPI_OLD.save_client_creds)NNN)F)N)N©rD   rE   rF   rG   r%   r]   ra   re   rg   Úpropertyrj   rn   r   r   r   r   r   ï   s        ÿ
4




r   )é   é   c                   @   sT   e Zd ZdZdd„ Zddd„Zddd	„Zdd
d„Zddd„Ze	dd„ ƒZ
dd„ ZdS )r   z�
    Implementation of the GSS-API MIT Kerberos Authentication for SSH2,
    using the newer, currently maintained gssapi package.

    :see: `.GSSAuth`
    c                 C   sP   t  | ||¡ | jr4tjjtjjtjjtjjf| _	ntjjtjjtjjf| _	dS rH   )
r   r%   r   rI   ZRequirementFlagZprotection_readyZ	integrityZmutual_authenticationZdelegate_to_peerrJ   r#   r   r   r   r%   °  s    üýz_SSH_GSSAPI_NEW.__init__Nc                 C   s®   ddl m} || _|| _tjd| j tjjd�}|dk	r\| |¡\}}| 	¡ | j
kr\tdƒ‚tjj}	d}
|dkr”tj|| j|	dd�| _| j |
¡}
n| j |¡}
| jj| _|
S )	ae  
        Initialize a GSS-API context.

        :param str username: The name of the user who attempts to login
        :param str target: The hostname of the target to connect to
        :param str desired_mech: The negotiated GSS-API mechanism
                                 ("pseudo negotiated" mechanism, because we
                                 support just the krb5 mechanism :-))
        :param str recv_token: The GSS-API token received from the Server
        :raises: `.SSHException` -- Is raised if the desired mechanism of the
                 client is not supported
        :raises: ``gssapi.exceptions.GSSError`` if there is an error signaled
                                                by the GSS-API implementation
        :return: A ``String`` if the GSS-API has returned a token or ``None``
                 if no token was returned
        r   r6   rK   )Z	name_typeNrL   Zinitiate)r   rO   r;   Úusage)r0   r7   r   r   rI   rM   ZNameTypeZhostbased_servicer8   r9   r   r   ZMechTypeZkerberosÚSecurityContextrJ   r   rP   Úcompleter    )r$   rV   r:   r)   rW   r7   rX   r;   r<   rZ   r[   r   r   r   r]   Æ  s0    þü
z$_SSH_GSSAPI_NEW.ssh_init_sec_contextFc                 C   sB   || _ |s0|  | j | j| j| j¡}| j |¡}n| j | j ¡}|S )aò  
        Create the MIC token for a SSH2 message.

        :param str session_id: The SSH session ID
        :param bool gss_kex: Generate the MIC for GSS-API Key Exchange or not
        :return: gssapi-with-mic:
                 Returns the MIC token from GSS-API for the message we created
                 with ``_ssh_build_mic``.
                 gssapi-keyex:
                 Returns the MIC token from GSS-API with the SSH session ID as
                 message.
        :rtype: str
        )r   rC   r   r   r   r   Zget_signaturer!   r^   r   r   r   ra   ô  s    üz_SSH_GSSAPI_NEW.ssh_get_micc                 C   s>   || _ || _| jdkr$tjdd�| _| j |¡}| jj| _|S )rb   NÚaccept)rs   )r   r   r!   rI   rt   rP   ru   r"   rc   r   r   r   re     s    

z&_SSH_GSSAPI_NEW.ssh_accept_sec_contextc                 C   sR   || _ || _| jdk	r>|  | j | j| j| j¡}| j ||¡ n| j | j |¡ dS )a{  
        Verify the MIC token for a SSH2 message.

        :param str mic_token: The MIC token received from the client
        :param str session_id: The SSH session ID
        :param str username: The name of the user who attempts to login
        :return: None if the MIC check was successful
        :raises: ``gssapi.exceptions.GSSError`` -- if the MIC check failed
        N)r   r   rC   r   r   r!   Zverify_signaturer   rf   r   r   r   rg   $  s    

üz_SSH_GSSAPI_NEW.ssh_check_micc                 C   s   | j jdk	rdS dS )z¦
        Checks if credentials are delegated (server mode).

        :return: ``True`` if credentials are delegated, otherwise ``False``
        :rtype: bool
        NTF)r!   Zdelegated_credsri   r   r   r   rj   >  s    z%_SSH_GSSAPI_NEW.credentials_delegatedc                 C   s   t ‚dS )aw  
        Save the Client token in a file. This is used by the SSH server
        to store the client credentials if credentials are delegated
        (server mode).

        :param str client_token: The GSS-API token received form the client
        :raises: ``NotImplementedError`` -- Credential delegation is currently
                 not supported in server mode
        Nrk   rm   r   r   r   rn   J  s    
z!_SSH_GSSAPI_NEW.save_client_creds)NNN)F)N)Nro   r   r   r   r   r   ¨  s        ÿ
.



r   c                   @   sR   e Zd ZdZdd„ Zddd„Zddd	„Zd
d„ Zddd„Ze	dd„ ƒZ
dd„ ZdS )r   zf
    Implementation of the Microsoft SSPI Kerberos Authentication for SSH2.

    :see: `.GSSAuth`
    c                 C   s<   t  | ||¡ | jr*tjtjB tjB | _ntjtjB | _dS rH   )r   r%   r   ÚsspiconZISC_REQ_INTEGRITYZISC_REQ_MUTUAL_AUTHÚISC_REQ_DELEGATErJ   r#   r   r   r   r%   ^  s    ÿþÿ
ÿz_SSH_SSPI.__init__Nc              
   C   sà   ddl m} || _|| _d}d| j }|dk	rR| |¡\}}	| ¡ | jkrRtdƒ‚z:|dkrptj	d| j
|d�| _| j |¡\}}
|
d j}
W n< tjk
rÈ } z| jd | j¡7  _‚ W 5 d}~X Y nX |dkrÜd	| _d}
|
S )
a¼  
        Initialize a SSPI context.

        :param str username: The name of the user who attempts to login
        :param str target: The FQDN of the target to connect to
        :param str desired_mech: The negotiated SSPI mechanism
                                 ("pseudo negotiated" mechanism, because we
                                 support just the krb5 mechanism :-))
        :param recv_token: The SSPI token received from the Server
        :raises:
            `.SSHException` -- Is raised if the desired mechanism of the client
            is not supported
        :return: A ``String`` if the SSPI has returned a token or ``None`` if
                 no token was returned
        r   r6   úhost/NrL   ÚKerberos)ZscflagsZ	targetspnz, Target: {}T)r0   r7   r   r   r8   r9   r   r   ÚsspiZ
ClientAuthrJ   r   Ú	authorizeÚBufferÚ
pywintypesÚerrorÚstrerrorrR   r    )r$   rV   r:   r)   rW   r7   r   rX   r;   r<   r[   Úer   r   r   r]   q  s2    
  ÿz_SSH_SSPI.ssh_init_sec_contextFc                 C   sB   || _ |s0|  | j | j| j| j¡}| j |¡}n| j | j ¡}|S )aÚ  
        Create the MIC token for a SSH2 message.

        :param str session_id: The SSH session ID
        :param bool gss_kex: Generate the MIC for Key Exchange with SSPI or not
        :return: gssapi-with-mic:
                 Returns the MIC token from SSPI for the message we created
                 with ``_ssh_build_mic``.
                 gssapi-keyex:
                 Returns the MIC token from SSPI with the SSH session ID as
                 message.
        )r   rC   r   r   r   r   Úsignr!   r^   r   r   r   ra   ¥  s    üz_SSH_SSPI.ssh_get_micc                 C   sV   || _ || _d| j  }tjd|d�| _| j |¡\}}|d j}|dkrRd| _d}|S )a§  
        Accept a SSPI context (server mode).

        :param str hostname: The servers FQDN
        :param str username: The name of the user who attempts to login
        :param str recv_token: The SSPI Token received from the server,
                               if it's not the initial call.
        :return: A ``String`` if the SSPI has returned a token or ``None`` if
                 no token was returned
        ry   rz   )Zspnr   TN)r   r   r{   Z
ServerAuthr!   r|   r}   r"   )r$   rd   r)   rW   rX   r   r[   r   r   r   re   À  s    

z _SSH_SSPI.ssh_accept_sec_contextc                 C   sP   || _ || _|dk	r<|  | j | j| j| j¡}| j ||¡ n| j | j |¡ dS )ak  
        Verify the MIC token for a SSH2 message.

        :param str mic_token: The MIC token received from the client
        :param str session_id: The SSH session ID
        :param str username: The name of the user who attempts to login
        :return: None if the MIC check was successful
        :raises: ``sspi.error`` -- if the MIC check failed
        N)r   r   rC   r   r   r!   Úverifyr   rf   r   r   r   rg   Ö  s    
üz_SSH_SSPI.ssh_check_micc                 C   s   | j tj@ o| jp| j S )rh   )rJ   rw   rx   r"   ri   r   r   r   rj   ô  s    
ÿz_SSH_SSPI.credentials_delegatedc                 C   s   t ‚dS )a{  
        Save the Client token in a file. This is used by the SSH server
        to store the client credentails if credentials are delegated
        (server mode).

        :param str client_token: The SSPI token received form the client
        :raises:
            ``NotImplementedError`` -- Credential delegation is currently not
            supported in server mode
        Nrk   rm   r   r   r   rn   ÿ  s    z_SSH_SSPI.save_client_creds)NNN)F)Nro   r   r   r   r   r   W  s        ÿ
4



r   )T)#rG   r>   r   rS   ZGSS_AUTH_AVAILABLEZGSS_EXCEPTIONSr   rI   Úhasattrr   rQ   Ú
exceptionsZGeneralErrorÚrawÚmiscZGSSErrorr   ÚOSErrorr~   rw   r{   r   Zparamiko.commonr   Zparamiko.ssh_exceptionr   Zparamiko._versionr	   r   Úobjectr   r   Z_SSH_GSSAPIr   r   r   r   r   r   Ú<module>   sL   

þ
   5
 0