U
    ~fhB                     @  s  U d Z ddlmZ ddlZddlZddlZddlZddlmZm	Z	 ddl
mZmZ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 dd	lmZmZ dd
lmZmZmZm Z  ddl!m"Z"m#Z# ddl$m%Z% erddl&m'Z' ddl(m)Z) dZ*dZ+z4ddl,Z-e.e/e0e-j12ddd dkr(dZ+W n> e3k
rh   zddl-Z-W n e3k
rb   dZ*Y nX Y nX dZ4dddddddZ5ddddddZ6ddddddd Z7ddd!d"d#Z8dddd$d%d&Z9dddd$d'd(Z:dddd$d)d*Z;dddd$d+d,Z<dddd$d-d.Z=e9e<e;eee:ej>e5d/d0ej>e5d1d0e=d2	Z?d3e@d4< G d5d6 d6ZAG d7d8 d8eAZBG d9d: d:eAZCG d;d< d<eAZDeCej>eBd/d0ej>eBd1d0eDej>eBd1d0d=ZEd>e@d?< dDddd@ddAdBdCZFdS )EzAuthentication helpers.    )annotationsN)standard_b64decodestandard_b64encode)TYPE_CHECKINGAnyCallable	CoroutineMappingMutableMappingOptionalcast)quote)Binary)_authenticate_aws)_authenticate_oidc_get_authenticator)MongoCredential_authenticate_scram_start_parse_scram_response_xor)ConfigurationErrorOperationFailure)saslprep)AsyncConnection)HelloTF.   )r      r   r   strNone)credentialsconn	mechanismreturnc                    s  | j }|dkr*d}tj}t| jd}nd}tj}t|| jd}| j}| j	}t
j}	|j}
|
r|
 rt|
tsxt|
jdk	st|
j\}}|
j}n"t| |\}}}|||I dH }|dk	st|d }t|}t|d }|dk rtd	|d
 }|d }||stdd| }|jr6|j\}}}}nd\}}}}|r\||ks\||krt||t||}|	|d| }|	|d| }||||f|_|| }d|||f}|	||| }dtt|| }d||f}t|	||| }d|d t |d}|||I dH }t|d }t
!|d |sJtd|d sd|d t dd}|||I dH }|d stddS )zAuthenticate using SCRAM.SCRAM-SHA-256sha256utf-8sha1Npayload   ii   z+Server returned an invalid iteration count.   s   rz!Server returned an invalid nonce.s	   c=biws,r=)NNNNs
   Client Keys
   Server Key   ,s   p=   conversationIdZsaslContinuer.   r(      vz%Server returned an invalid signature.done    z%SASL conversation failed to complete.)"usernamehashlibr%   r   passwordencoder'   _password_digestsourcecachehmacHMACauth_ctxspeculate_succeeded
isinstance_ScramContextAssertionError
scram_dataspeculative_authenticater   commandr   intr   
startswithdatapbkdf2_hmacr   digestjoinr   r   r   compare_digest) r    r!   r"   r3   rH   	digestmodrF   r8   r9   Z_hmacctxnonce
first_barerescmdZserver_firstparsedZ
iterationsZsaltZrnonceZwithout_proofZ
client_keyZ
server_keyZcsaltZciterationsZsalted_passZ
stored_keyZauth_msgZ
client_sigZclient_proofZclient_finalZ
server_sig rR   =/tmp/pip-unpacked-wheel-36gvocj8/pymongo/asynchronous/auth.py_authenticate_scramG   sx    


rT   )r3   r5   r#   c                 C  sf   t |tstdt|dkr&tdt | ts8tdt }|  d| }||d |	 S )z0Get a password digest to use for authentication.z#password must be an instance of strr   zpassword can't be emptyz#username must be an instance of strz:mongo:r&   )
r>   r   	TypeErrorlen
ValueErrorr4   md5updater6   	hexdigest)r3   r5   md5hashrF   rR   rR   rS   r7      s    

r7   )rM   r3   r5   r#   c                 C  s:   t ||}t }|  | | }||d | S )z*Get an auth key to use for authentication.r&   )r7   r4   rX   rY   r6   rZ   )rM   r3   r5   rH   r[   rF   rR   rR   rS   	_auth_key   s
    
r\   )hostnamer#   c                 C  sd   t | dddt jt jd \}}}}}zt |t j}W n t jk
rV   |  Y S X |d  S )z2Canonicalize hostname following MIT-krb5 behavior.Nr   )socketgetaddrinfoIPPROTO_TCPAI_CANONNAMEgetnameinfoNI_NAMEREQDgaierrorlower)r]   afsocktypeproto	canonnameZsockaddrnamerR   rR   rS   _canonicalize_hostname   s         rk   )r    r!   r#   c              
     s  t stdz@| j}| j}| j}|jd }|jr:t|}|jd | }|j	dk	r`|d |j	 }|dk	rt
rdt|t|f}tj||tjd\}}	qd|kr|dd\}
}n
|d }
}tj|tj|
||d\}}	ntj|tjd\}}	|tjkrtd	z:t|	d
dkr tdt|	}dd|dd}|d|I dH }tdD ]p}t|	t|d }|dkr|tdt|	pd
}d|d |d}|d|I dH }|tjkrR q̐qRtdt|	t|d dkrtdt|	t|	|dkrtdt|	}d|d |d}|d|I dH  W 5 t|	 X W n4 tjk
r } ztt|dW 5 d}~X Y nX dS )zAuthenticate using GSSAPI.zEThe "kerberos" module must be installed to use GSSAPI authentication.r   @N:)gssflagsr-   )rn   userdomainr5   z&Kerberos context failed to initialize. z*Unknown kerberos failure in step function.GSSAPIZ	saslStartr"   r(   ZautoAuthorize	$external
   r(   r.   r/   z+Kerberos authentication failed to complete.z0Unknown kerberos failure during GSS_Unwrap step.z.Unknown kerberos failure during GSS_Wrap step.)HAVE_KERBEROSr   r3   r5   Zmechanism_propertiesaddressZcanonicalize_host_namerk   Zservice_nameZservice_realm_USE_PRINCIPALrI   r   kerberosZauthGSSClientInitZGSS_C_MUTUAL_FLAGsplitZAUTH_GSS_COMPLETEr   ZauthGSSClientCleanZauthGSSClientStepZauthGSSClientResponserC   ranger   ZauthGSSClientUnwrapZauthGSSClientWrapZKrbError)r    r!   r3   r5   propshostZserviceZ	principalresultrL   ro   rp   r(   rP   response_excrR   rR   rS   _authenticate_gssapi   s    

  




r   c                   sN   | j }| j}| j}d| d|  }ddt|dd}|||I dH  dS )z(Authenticate using SASL PLAIN (RFC 4616) r-   PLAINrs   N)r8   r3   r5   r6   r   rC   )r    r!   r8   r3   r5   r(   rP   rR   rR   rS   _authenticate_plain2  s    r   c                   s<   |j }|r| rdS t| |j }|d|I dH  dS )z Authenticate using MONGODB-X509.Nrt   )r<   r=   _X509Contextrx   speculate_commandrC   )r    r!   rL   rP   rR   rR   rS   _authenticate_x509A  s
    r   c           	        s`   | j }| j}| j}||ddiI dH }|d }t|||}d|||d}|||I dH  dS )zAuthenticate using MONGODB-CR.Zgetnoncer-   NrM   )authenticatero   rM   key)r8   r3   r5   rC   r\   )	r    r!   r8   r3   r5   r   rM   r   queryrR   rR   rS   _authenticate_mongo_crL  s    r   c                   s   |j dkr|jr|j}n>| j}| }|d | j |d< |j||ddI d H dg }d|krpt| |dI d H S t| |dI d H S nt| |dI d H S d S )N   r   ZsaslSupportedMechsF)Zpublish_eventsr$   SCRAM-SHA-1)Zmax_wire_versionZnegotiated_mechsr8   Z	hello_cmdr3   rC   getrT   )r    r!   Zmechsr8   rP   rR   rR   rS   _authenticate_default[  s    
 r   r   )r"   r$   )	rr   z
MONGODB-CRMONGODB-X509zMONGODB-AWSMONGODB-OIDCr   r   r$   DEFAULTz6Mapping[str, Callable[..., Coroutine[Any, Any, None]]]	_AUTH_MAPc                   @  s`   e Zd ZddddddZeddddd	d
ZddddZdddddZddddZdS )_AuthContextr   tuple[str, int]r   )r    rx   r#   c                 C  s   || _ d | _|| _d S N)r    rB   rx   )selfr    rx   rR   rR   rS   __init__|  s    z_AuthContext.__init__zOptional[_AuthContext])credsrx   r#   c                 C  s$   t | j}|r tt|| |S d S r   )_SPECULATIVE_AUTH_MAPr   r"   r   r   )r   rx   Zspec_clsrR   rR   rS   from_credentials  s    z_AuthContext.from_credentials"Optional[MutableMapping[str, Any]]r#   c                 C  s   t d S r   )NotImplementedErrorr   rR   rR   rS   r     s    z_AuthContext.speculate_commandzHello[Mapping[str, Any]])hellor#   c                 C  s   |j | _ d S r   )rB   )r   r   rR   rR   rS   parse_response  s    z_AuthContext.parse_responseboolc                 C  s
   t | jS r   )r   rB   r   rR   rR   rS   r=     s    z _AuthContext.speculate_succeededN)	__name__
__module____qualname__r   staticmethodr   r   r   r=   rR   rR   rR   rS   r   {  s   r   c                      s6   e Zd Zddddd fddZdd	d
dZ  ZS )r?   r   r   r   r   )r    rx   r"   r#   c                   s   t  || d | _|| _d S r   )superr   rA   r"   )r   r    rx   r"   	__class__rR   rS   r     s    z_ScramContext.__init__r   r   c                 C  s.   t | j| j\}}}| jj|d< ||f| _|S Ndb)r   r    r"   r8   rA   )r   rM   rN   rP   rR   rR   rS   r     s    
z_ScramContext.speculate_command)r   r   r   r   r   __classcell__rR   rR   r   rS   r?     s   r?   c                   @  s   e Zd ZddddZdS )r   zMutableMapping[str, Any]r   c                 C  s&   ddd}| j jd k	r"| j j|d< |S )Nr-   r   )r   r"   ro   )r    r3   )r   rP   rR   rR   rS   r     s    
z_X509Context.speculate_commandNr   r   r   r   rR   rR   rR   rS   r     s   r   c                   @  s   e Zd ZddddZdS )_OIDCContextr   r   c                 C  s2   t | j| j}| }|d kr"d S | jj|d< |S r   )r   r    rx   Zget_spec_auth_cmdr8   )r   ZauthenticatorrP   rR   rR   rS   r     s    z_OIDCContext.speculate_commandNr   rR   rR   rR   rS   r     s   r   )r   r   r$   r   r   zMapping[str, Any]r   r   )r    r!   reauthenticater#   c                   s>   | j }t| }|dkr*t| ||I dH  n|| |I dH  dS )zAuthenticate connection.r   N)r"   r   r   )r    r!   r   r"   Z	auth_funcrR   rR   rS   r     s
    r   )F)G__doc__
__future__r   	functoolsr4   r:   r^   base64r   r   typingr   r   r   r   r	   r
   r   r   urllib.parser   Zbson.binaryr   Zpymongo.asynchronous.auth_awsr   Zpymongo.asynchronous.auth_oidcr   r   Zpymongo.auth_sharedr   r   r   r   Zpymongo.errorsr   r   Zpymongo.saslprepr   Zpymongo.asynchronous.poolr   Zpymongo.hellor   rw   ry   Zwinkerberosrz   tuplemaprD   __version__r{   ImportErrorZ_IS_SYNCrT   r7   r\   rk   r   r   r   r   r   partialr   __annotations__r   r?   r   r   r   r   rR   rR   rR   rS   <module>   sx   (
$U	o
 