o
    Uh)p                     @   s,  d Z ddlZddlZddlZdZdZdZz"ddlZeedr*ej	dkr*dZej
fZndZejjejjjfZW n- eefyc   zddlZddlZddlZd	ZejfZW n ey`   d
ZdZY nw Y nw ddlmZ ddlmZ dddZG dd dZG dd d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)SSHExceptionc                 C   sH   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)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!)_API_SSH_GSSAPI_OLD_SSH_GSSAPI_NEWosname	_SSH_SSPIImportError)auth_methodgss_deleg_credsr   r   C/var/www/html/venv/lib/python3.10/site-packages/paramiko/ssh_gss.pyGSSAuthM   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   sN   || _ || _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_statuscc_fileselfr   r   r   r   r   __init__s   s   
z_SSH_GSSAuth.__init__c                 C   s   | dr
|| _dS 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r(|| 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)pyasn1.type.univr,   pyasn1.codec.derr-   _make_uint32encoder   len)r$   moder,   r-   OIDskrb5_OID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)r1   r;   decode__str__r   )r$   desired_mechr;   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   r2      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)r2   r4   rB   rC   r   r3   )r$   
session_idr)   r'   r   micr   r   r   _ssh_build_mic   s   z_SSH_GSSAuth._ssh_build_micN)r+   )__name__
__module____qualname____doc__r%   r(   r*   r9   rA   r2   rH   r   r   r   r   r   m   s    
		r   c                   @   V   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   sD   t | || | jrtjtjtjtjf| _dS tjtjtjf| _dS r   N)	r   r%   r   gssapiC_PROT_READY_FLAGC_INTEG_FLAGC_MUTUAL_FLAG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u r*tj
| j}n||\}	}
|	 | jkr<tdtj
| j}d}z|du r[tj|||j	d| _| j|}n| j|}W n tjyz   dt d | j}t|w | 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   r:   host@NUnsupported mechanism OID.)	peer_name	mech_type	req_flagsz{} Target: {}r.   )r1   r;   r   r   rO   NameC_NT_HOSTBASED_SERVICEContextrT   flagsOIDmech_from_stringr   r<   r=   r   InitContextr   stepGSSExceptionformatsysexc_infoestablishedr   )r$   targetr>   r)   
recv_tokenr;   	targ_namectx	krb5_mechr?   r@   tokenmessager   r   r   ssh_init_sec_context  s>   

z$_SSH_GSSAPI_OLD.ssh_init_sec_contextFc                 C   D   || _ |s| | j | j| j| j}| j|}|S | 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   rH   r   r   r   r   get_micr    r$   rF   gss_kex	mic_field	mic_tokenr   r   r   ssh_get_mic@     z_SSH_GSSAPI_OLD.ssh_get_micc                 C   s:   || _ || _| jdu 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    rO   AcceptContextra   rf   r!   r$   hostnamerh   r)   rl   r   r   r   ssh_accept_sec_context[  s   


z&_SSH_GSSAPI_OLD.ssh_accept_sec_contextc                 C   T   || _ || _| jdur | | j | j| j| j}| j|| dS | 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   rH   r   r   r    
verify_micr   r$   rt   rF   r)   rs   r   r   r   ssh_check_mico     

z_SSH_GSSAPI_OLD.ssh_check_micc                 C      | j jdurdS dS )
        Checks if credentials are delegated (server mode).

        :return: ``True`` if credentials are delegated, otherwise ``False``
        NTF)r    delegated_credr$   r   r   r   credentials_delegated  s   z%_SSH_GSSAPI_OLD.credentials_delegatedc                 C      t )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
        NotImplementedErrorr$   client_tokenr   r   r   save_client_creds     z!_SSH_GSSAPI_OLD.save_client_credsNNNFNrI   rJ   rK   rL   r%   rn   ru   r{   r   propertyr   r   r   r   r   r   r      s    

4



r   c                   @   rM   )r   z
    Implementation of the GSS-API MIT Kerberos Authentication for SSH2,
    using the newer, currently maintained gssapi package.

    :see: `.GSSAuth`
    c                 C   sR   t | || | jrtjjtjjtjjtjjf| _	dS tjjtjjtjjf| _	dS rN   )
r   r%   r   rO   RequirementFlagprotection_ready	integritymutual_authenticationdelegate_to_peerrT   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ur.||\}}|	 | j
kr.tdtjj}	d}
|du rJt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   r:   rU   )	name_typeNrV   initiate)r   r]   r?   usage)r1   r;   r   r   rO   rZ   NameTypehostbased_servicer<   r=   r   r   MechTypekerberosSecurityContextrT   r   ra   completer   )r$   rg   r>   r)   rh   r;   ri   r?   r@   rk   rl   r   r   r   rn     s0   
z$_SSH_GSSAPI_NEW.ssh_init_sec_contextFc                 C   ro   )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   rH   r   r   r   r   get_signaturer    rq   r   r   r   ru     s   z_SSH_GSSAPI_NEW.ssh_get_micc                 C   s>   || _ || _| jdu rtjdd| _| j|}| jj| _|S )rw   Naccept)r   )r   r   r    rO   r   ra   r   r!   ry   r   r   r   r{   
  s   

z&_SSH_GSSAPI_NEW.ssh_accept_sec_contextc                 C   r|   )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   rH   r   r   r    verify_signaturer   r~   r   r   r   r     r   z_SSH_GSSAPI_NEW.ssh_check_micc                 C   r   )z
        Checks if credentials are delegated (server mode).

        :return: ``True`` if credentials are delegated, otherwise ``False``
        :rtype: bool
        NTF)r    delegated_credsr   r   r   r   r   8  s   z%_SSH_GSSAPI_NEW.credentials_delegatedc                 C   r   )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
        r   r   r   r   r   r   D  s   
z!_SSH_GSSAPI_NEW.save_client_credsr   r   r   r   r   r   r   r   r     s    

.


r   c                   @   sT   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 | _dS tjtjB | _dS rN   )r   r%   r   sspiconISC_REQ_INTEGRITYISC_REQ_MUTUAL_AUTHISC_REQ_DELEGATErT   r#   r   r   r   r%   X  s   
z_SSH_SSPI.__init__Nc              
   C   s   ddl m} || _|| _d}d| j }|dur)||\}}	| | jkr)tdz|du r8tj	d| j
|d| _| j|\}}
|
d j}
W n tjy_ } z| jd| j7  _ d}~ww |dkrk	 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   r:   host/NrV   Kerberos)scflags	targetspnz, Target: {}T)r1   r;   r   r   r<   r=   r   r   sspi
ClientAuthrT   r   	authorizeBuffer
pywintypeserrorstrerrorrc   r   )r$   rg   r>   r)   rh   r;   r   ri   r?   r@   rl   er   r   r   rn   k  s6   
z_SSH_SSPI.ssh_init_sec_contextFc                 C   ro   )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   rH   r   r   r   r   signr    rq   r   r   r   ru     rv   z_SSH_SSPI.ssh_get_micc                 C   sV   || _ || _d| j  }tjd|d| _| j|\}}|d j}|dkr)d| _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
        r   r   )spnr   TN)r   r   r   
ServerAuthr    r   r   r!   )r$   rz   r)   rh   ri   r   rl   r   r   r   r{     s   

z _SSH_SSPI.ssh_accept_sec_contextc                 C   sR   || _ || _|dur| | j | j| j| j}| j|| dS | 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   rH   r   r   r    verifyr   r~   r   r   r   r     s   
z_SSH_SSPI.ssh_check_micc                 C   s   | j tj@ o| jp| j S )r   )rT   r   r   r!   r   r   r   r   r     s   
z_SSH_SSPI.credentials_delegatedc                 C   r   )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 SSPI token received form the client
        :raises:
            ``NotImplementedError`` -- Credential delegation is currently not
            supported in server mode
        r   r   r   r   r   r     r   z_SSH_SSPI.save_client_credsr   r   r   r   r   r   r   r   r   Q  s    

4


r   )T)rL   rB   r   rd   GSS_AUTH_AVAILABLEGSS_EXCEPTIONSr
   rO   hasattrr   rb   
exceptionsGeneralErrorrawmiscGSSErrorr   OSErrorr   r   r   r   paramiko.commonr   paramiko.ssh_exceptionr   r   r   r   r   r   r   r   r   r   <module>   sP   


   5 0