o
    g_                     @   s   d Z ddlZddlmZ ddlmZmZmZmZm	Z	m
Z
 ddlmZ ddlmZ ddlmZ edd	\ZZZZZed
d\ZZdd edd	D \ZZZZZdd ed
dD \ZZG dd dZ G dd de Z!G dd dZ"G dd dZ#dS )a  
This module provides GSS-API / SSPI Key Exchange as defined in :rfc:`4462`.

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

.. note::
    `RFC 4462 Section 2.2
    <https://tools.ietf.org/html/rfc4462.html#section-2.2>`_ says we are not
    required to implement GSS-API error messages. Thus, in many methods within
    this module, if an error occurs an exception will be thrown and the
    connection will be terminated.

.. seealso:: :doc:`/api/ssh_gss`

.. versionadded:: 1.15
    N)sha1)DEBUGmax_byte	zero_bytebyte_chr	byte_maskbyte_ord)util)Message)SSHException   #   (   *   c                 C      g | ]}t |qS  r   .0cr   r   J/var/www/html/api-tag/env/lib/python3.10/site-packages/paramiko/kex_gss.py
<listcomp>F   s    r   c                 C   r   r   r   r   r   r   r   r   G   s    c                   @   s|   e Zd ZdZdZdZeded  Ze	d Z
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dS )KexGSSGroup1z
    GSS-API / SSPI Authenticated Diffie-Hellman Key Exchange as defined in `RFC
    4462 Section 2 <https://tools.ietf.org/html/rfc4462.html#section-2>`_
    lE   8{3If?E yZ3V58noPe?a-tBLy3W[<p6m5P&aF!33*w& ARM;L}.c|&A@h\&&#-Dvd             z(gss-group1-sha1-toWM5Slw5Ew8Mqkay+al2g==c                 C   s,   || _ | j j| _d | _d| _d| _d| _d S )Nr   )	transportkexgss_ctxtkexgssgss_hostxefselfr   r   r   r   __init__Y   s   

zKexGSSGroup1.__init__c                 C   s   |    | jjrt| j| j| j| _| jt	 dS t| j| j| j| _
| jj| _t }|t || jj| jd || j
 | j| | jtttt dS )zU
        Start the GSS-API / SSPI Authenticated Diffie-Hellman Key Exchange.
        Ntarget)_generate_xr   server_modepowGr!   Pr#   _expect_packetMSG_KEXGSS_INITr"   r    r
   add_bytec_MSG_KEXGSS_INIT
add_stringr   ssh_init_sec_context	add_mpint_send_messageMSG_KEXGSS_HOSTKEYMSG_KEXGSS_CONTINUEMSG_KEXGSS_COMPLETEMSG_KEXGSS_ERRORr%   mr   r   r   	start_kexa   s$   

zKexGSSGroup1.start_kexc                 C   s   | j jr|tkr| |S | j js|tkr| |S | j jr'|tkr'| |S | j js4|tkr4| 	|S |t
kr=| |S d}t||)
        Parse the next packet.

        :param ptype: The (string) type of the incoming packet
        :param `.Message` m: The packet content
        z.GSS KexGroup1 asked to handle packet type {:d})r   r*   r/   _parse_kexgss_initr6   _parse_kexgss_hostkeyr7   _parse_kexgss_continuer8   _parse_kexgss_completer9   _parse_kexgss_errorr   formatr%   ptyper;   msgr   r   r   
parse_next{   s   




zKexGSSGroup1.parse_nextc                 C   sV   	 t d}t|d d|dd  }|dd }|| j| jfvr"nqt|| _dS )ap  
        generate an "x" (1 < x < q), where q is (p-1)/2.
        p is a 128-byte (1024-bit) number, where the first 64 bits are 1.
        therefore q can be approximated as a 2^1023.  we drop the subset of
        potential x where the first 63 bits are 1, because some of those will
        be larger than q (but this is a tiny tiny subset of potential x).
              r   r   Nr   )osurandomr   b7fffffffffffffffb0000000000000000r	   inflate_longr!   )r%   x_bytesfirstr   r   r   r)      s   
zKexGSSGroup1._generate_xc                 C   8   |  }|| j_|  }| j|| | jtt dS )z
        Parse the SSH2_MSG_KEXGSS_HOSTKEY message (client mode).

        :param `.Message` m: The content of the SSH2_MSG_KEXGSS_HOSTKEY message
        N
get_stringr   host_key_verify_keyr.   r7   r8   r%   r;   rT   sigr   r   r   r?      
   z"KexGSSGroup1._parse_kexgss_hostkeyc                 C   ^   | j js,| }t }|t || jj| j	|d | j 
| | j ttt dS 	 dS )z
        Parse the SSH2_MSG_KEXGSS_CONTINUE message.

        :param `.Message` m: The content of the SSH2_MSG_KEXGSS_CONTINUE
            message
        r(   
recv_tokenNr   r*   rS   r
   r0   c_MSG_KEXGSS_CONTINUEr2   r   r3   r    send_messager.   r7   r8   r9   r%   r;   	srv_tokenr   r   r   r@      s   
z#KexGSSGroup1._parse_kexgss_continuec                 C   s:  | j jdu rt | j _| | _| jdk s| j| jd kr!td| }| }d}|r1| }t	| j| j
| j}t }|| j j| j j| j j| j j || j j  || j || j || tt| }| j || |dur| jj| j|d | j|| n| j|| d| j _| j   dS )z
        Parse the SSH2_MSG_KEXGSS_COMPLETE message (client mode).

        :param `.Message` m: The content of the
            SSH2_MSG_KEXGSS_COMPLETE message
        NrH   Server kex "f" is out of rangerZ   T)r   rT   NullHostKey	get_mpintr#   r-   r   rS   get_booleanr+   r!   r
   addlocal_versionremote_versionlocal_kex_initremote_kex_initr2   __str__r4   r"   r   strdigest_set_K_Hr   r3   r    ssh_check_micgss_kex_used_activate_outboundr%   r;   	mic_tokenboolr`   KhmHr   r   r   rA      s@   


z#KexGSSGroup1._parse_kexgss_completec           	      C   s  |  }| | _| jdk s| j| jd krtdt| j| j| j}t | j_	| jj	
 }t }|| jj| jj| jj| jj || || j || j || t|  }| j|| | j| j|}t }| jjr| jj| jjdd}|t || j || |dur| d || n| d | j!| d| j_"| j#  dS |t$ || | j!| | j%t&t't( dS )z
        Parse the SSH2_MSG_KEXGSS_INIT message (server mode).

        :param `.Message` m: The content of the SSH2_MSG_KEXGSS_INIT message
        rH   Client kex "e" is out of rangeTgss_kexNF))rS   rc   r"   r-   r   r+   r!   rb   r   rT   rj   r
   re   rg   rf   ri   rh   r2   r4   r#   r   asbytesrl   rm   r   ssh_accept_sec_contextr    _gss_srv_ctxt_statusssh_get_mic
session_idr0   c_MSG_KEXGSS_COMPLETEadd_booleanr5   ro   rp   r]   r.   r7   r8   r9   	r%   r;   client_tokenrt   keyru   rv   r`   rr   r   r   r   r>      sX   









zKexGSSGroup1._parse_kexgss_initc                 C   2   |  }|  }| }|  td|||)a  
        Parse the SSH2_MSG_KEXGSS_ERROR message (client mode).
        The server may send a GSS-API error message. if it does, we display
        the error by throwing an exception (client mode).

        :param `.Message` m: The content of the SSH2_MSG_KEXGSS_ERROR message
        :raise SSHException: Contains GSS-API major and minor status as well as
                             the error message and the language tag of the
                             message
        CGSS-API Error:
Major Status: {}
Minor Status: {}
Error Message: {}
get_intrS   r   rC   r%   r;   
maj_status
min_statuserr_msgr   r   r   rB   *     z KexGSSGroup1._parse_kexgss_errorN)__name__
__module____qualname____doc__r-   r,   r   r   rL   r   rM   NAMEr&   r<   rG   r)   r?   r@   rA   r>   rB   r   r   r   r   r   L   s     -8r   c                   @   s   e Zd ZdZdZdZdZdS )KexGSSGroup14z
    GSS-API / SSPI Authenticated Diffie-Hellman Group14 Key Exchange as defined
    in `RFC 4462 Section 2
    <https://tools.ietf.org/html/rfc4462.html#section-2>`_
    l   &UG9
tcb0]Q\-:$90.`U_b;YS7x]Ek`:xds!,w<G8qbdR_hddY6KpRT{UjK#Gt|L4S8 FYpw,(.> =HG2Cdc_.K?&j_c}z[\V_1M.D^/1v5I	jV&|/mVlR<6#{n4(EY91T:g8	H	Apcb4BBj~H r   z)gss-group14-sha1-toWM5Slw5Ew8Mqkay+al2g==N)r   r   r   r   r-   r,   r   r   r   r   r   r   D  s
    r   c                   @   sx   e Zd ZdZdZdZdZ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dd Zdd ZdS )	KexGSSGexz
    GSS-API / SSPI Authenticated Diffie-Hellman Group Exchange as defined in
    `RFC 4462 Section 2 <https://tools.ietf.org/html/rfc4462.html#section-2>`_
    z%gss-gex-sha1-toWM5Slw5Ew8Mqkay+al2g==       i   c                 C   sD   || _ | j j| _d | _d | _d | _d | _d | _d | _d | _	d| _
d S )NF)r   r   r   r    pqgr!   r"   r#   	old_styler$   r   r   r   r&   [  s   

zKexGSSGex.__init__c                 C   sr   | j jr| j t dS | j j| _t }|t || j	 || j
 || j | j | | j t dS )zV
        Start the GSS-API / SSPI Authenticated Diffie-Hellman Group Exchange
        N)r   r*   r.   MSG_KEXGSS_GROUPREQr    r
   r0   c_MSG_KEXGSS_GROUPREQadd_intmin_bitspreferred_bitsmax_bitsr5   MSG_KEXGSS_GROUPr:   r   r   r   r<   g  s   

zKexGSSGex.start_kexc                 C   s   |t kr	| |S |tkr| |S |tkr| |S |tkr$| |S |tkr-| 	|S |t
kr6| |S |tkr?| |S d}t||)r=   z'KexGex asked to handle packet type {:d})r   _parse_kexgss_groupreqr   _parse_kexgss_groupr/   _parse_kexgss_gex_initr6   r?   r7   r@   r8   rA   r9   rB   r   rC   rD   r   r   r   rG   z  s    






zKexGSSGex.parse_nextc                 C   s   | j d d }t|d}t|d }t|}d}|d@ s)|dK }|dL }|d@ r	 t|}t|d ||dd   }t|d}|dkrK||k rKnq*|| _	d S )NrH   r   r      rI   )
r   r	   deflate_longr   lenrJ   rK   r   rN   r!   )r%   r   qnormqhbyte
byte_countqmaskrO   r!   r   r   r   r)     s"   

zKexGSSGex._generate_xc                 C   s   |  }|  }|  }|| jkr| j}|| jk r| j}||kr"|}||k r(|}|| _|| _|| _| j }|du r>td| jtd	||| |
|||\| _| _t }|t || j || j | j| | jt dS )z
        Parse the SSH2_MSG_KEXGSS_GROUPREQ message (server mode).

        :param `.Message` m: The content of the
            SSH2_MSG_KEXGSS_GROUPREQ message
        Nz-Can't do server-side gex with no modulus packzPicking p ({} <= {} <= {} bits))r   r   r   r   r   _get_modulus_packr   _logr   rC   get_modulusr   r   r
   r0   c_MSG_KEXGSS_GROUPr4   r5   r.   r/   )r%   r;   minbitspreferredbitsmaxbitspackr   r   r   r     s<   



z KexGSSGex._parse_kexgss_groupreqc                 C   s   |  | _|  | _t| j}|dk s|dkrtd|| jt	d| | 
  t| j| j| j| _t }|t || jj| jd || j | j| | jtttt dS )z
        Parse the SSH2_MSG_KEXGSS_GROUP message (client mode).

        :param `Message` m: The content of the SSH2_MSG_KEXGSS_GROUP message
        r   r   z<Server-generated gex p (don't ask) is out of range ({} bits)zGot server p ({} bits)r'   N)rc   r   r   r	   
bit_lengthr   rC   r   r   r   r)   r+   r!   r"   r
   r0   r1   r2   r   r3   r    r4   r5   r.   r6   r7   r8   r9   )r%   r;   bitlenr   r   r   r     s0   



zKexGSSGex._parse_kexgss_groupc           	      C   s  |  }| | _| jdk s| j| jd krtd|   t| j| j| j| _	t| j| j| j}t
 | j_| jj }t }|| jj| jj| jj| jj| || j || j || j || j || j || j || j	 || t|  }| j|| | j| j|}t }| jj r| jj!| jj"dd}|#t$ || j	 |%| |dur|&d |%| n|&d | j'| d| j_(| j)  dS |#t* |%| | j'| | j+t,t-t. dS )z
        Parse the SSH2_MSG_KEXGSS_INIT message (server mode).

        :param `Message` m: The content of the SSH2_MSG_KEXGSS_INIT message
        rH   rw   Trx   NF)/rS   rc   r"   r   r   r)   r+   r   r!   r#   rb   r   rT   rj   r
   re   rg   rf   ri   rh   r   r   r   r   r4   r   rz   rl   rm   r   r{   r    r|   r}   r~   r0   r   r2   r   r5   ro   rp   r]   r.   r7   r8   r9   r   r   r   r   r     sf   








z KexGSSGex._parse_kexgss_gex_initc                 C   rQ   )z
        Parse the SSH2_MSG_KEXGSS_HOSTKEY message (client mode).

        :param `Message` m: The content of the SSH2_MSG_KEXGSS_HOSTKEY message
        NrR   rV   r   r   r   r?   1  rX   zKexGSSGex._parse_kexgss_hostkeyc                 C   rY   )z
        Parse the SSH2_MSG_KEXGSS_CONTINUE message.

        :param `Message` m: The content of the SSH2_MSG_KEXGSS_CONTINUE message
        rZ   Nr\   r_   r   r   r   r@   >  s   
z KexGSSGex._parse_kexgss_continuec                 C   sz  | j jdu rt | j _| | _| }| }d}|r | }| jdk s-| j| jd kr1tdt	| j| j
| j}t }|| j j| j j| j j| j j| j j  | js[|| j || j | jsj|| j || j || j || j || j || t|  }| j || |dur| jj| j |d | j!|| n| j!|| d| j _"| j #  dS )z
        Parse the SSH2_MSG_KEXGSS_COMPLETE message (client mode).

        :param `Message` m: The content of the SSH2_MSG_KEXGSS_COMPLETE message
        NrH   ra   rZ   T)$r   rT   rb   rc   r#   rS   rd   r   r   r+   r!   r
   re   rf   rg   rh   ri   rj   r   r   r   r   r   r4   r   r"   r   rz   rl   rm   r   r3   r    rn   ro   rp   rq   r   r   r   rA   T  sN   



z KexGSSGex._parse_kexgss_completec                 C   r   )a  
        Parse the SSH2_MSG_KEXGSS_ERROR message (client mode).
        The server may send a GSS-API error message. if it does, we display
        the error by throwing an exception (client mode).

        :param `Message` m:  The content of the SSH2_MSG_KEXGSS_ERROR message
        :raise SSHException: Contains GSS-API major and minor status as well as
                             the error message and the language tag of the
                             message
        r   r   r   r   r   r   rB     r   zKexGSSGex._parse_kexgss_errorN)r   r   r   r   r   r   r   r   r&   r<   rG   r)   r   r   r   r?   r@   rA   rB   r   r   r   r   r   P  s"    ,!>2r   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	rb   z
    This class represents the Null Host Key for GSS-API Key Exchange as defined
    in `RFC 4462 Section 5
    <https://tools.ietf.org/html/rfc4462.html#section-5>`_
    c                 C   s
   d| _ d S )N r   r%   r   r   r   r&     s   
zNullHostKey.__init__c                 C      | j S Nr   r   r   r   r   rj        zNullHostKey.__str__c                 C   r   r   r   r   r   r   r   get_name  r   zNullHostKey.get_nameN)r   r   r   r   r&   rj   r   r   r   r   r   rb     s
    rb   )$r   rJ   hashlibr   paramiko.commonr   r   r   r   r   r   paramikor	   paramiko.messager
   paramiko.ssh_exceptionr   ranger/   r7   r8   r6   r9   r   r   r1   r]   r   c_MSG_KEXGSS_HOSTKEYc_MSG_KEXGSS_ERRORr   r   r   r   r   rb   r   r   r   r   <module>   s@    	
 y  R