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   ú;/usr/local/lib/python3.10/dist-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 yéZô3¢Vý58nÛoP·eõ?a-ûÓtBLèûy3W[�<‘p¨6m5ÂÝPøß&aÌF!Í33*¾w& ãAR‘M;L}. c|&A“@”h\Š&&#-D¨v‡dÿÿÿÿ é   é   é   é   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<Gï8¶qbdR_ÊØhÅÀd«d©ÃY6K–pRT{ÜUÄj¼K­#¹Gt|õL¤ê‹4šS«8Ø ÒFYpw,(.> Â=¶H³G2C’düc_Ÿ.K?&jÚ_†c½}­z[\Vµ_1M.D‰^±/1v5I	ŽjÖV&|ÓŠ/òmVÀlRÓ<6#å{n4ó(EY91ÇTï:Ìg8	H	ÍAp¢cb4BÑBˆj~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