U
    ~fhA                     @  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 ddlmZ ddl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 ddl m!Z! ddl"m#Z#m$Z$ erddl%m&Z& ddl'm(Z( dZ)dZ*z4ddl+Z,e-e.e/e,j01ddd dkr$dZ*W n> e2k
rd   zddl,Z,W n e2k
r^   dZ)Y nX Y nX dZ3dddddddZ4ddddddZ5ddddddd Z6ddd!d"d#Z7dd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<e8e;e:e!e#e9ej=e4d/d0ej=e4d1d0e<d2	Z>d3e?d4< G d5d6 d6Z@G d7d8 d8e@ZAG d9d: d:e@ZBG d;d< d<e@ZCeBej=eAd/d0ej=eAd1d0eCej=eAd1d0d=ZDd>e?d?< dDddd@ddAdBdCZEdS )EzAuthentication helpers.    )annotationsN)standard_b64decodestandard_b64encode)TYPE_CHECKINGAnyCallableMappingMutableMappingOptionalcast)quote)Binary)MongoCredential_authenticate_scram_start_parse_scram_response_xor)ConfigurationErrorOperationFailure)saslprep)_authenticate_aws)_authenticate_oidc_get_authenticator)Hello)
ConnectionTF.   )r      r   r   strNone)credentialsconn	mechanismreturnc                  C  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| |\}}}|||}|dk	st|d }t|}t|d }|dk rtd	|d
 }|d }||stdd| }|jr0|j\}}}}nd\}}}}|rV||ksV||krt||t||}|	|d| }|	|d| }||||f|_|| }d|||f}|	||| }dtt|| }d||f}t|	||| }d|d t |d}|||}t|d }t
!|d |s>td|d szd|d t dd}|||}|d szt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!   r2   rG   	digestmodrE   r7   r8   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 rQ   </tmp/pip-unpacked-wheel-36gvocj8/pymongo/synchronous/auth.py_authenticate_scramF   sx    


rS   )r2   r4   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
ValueErrorr3   md5updater5   	hexdigest)r2   r4   md5hashrE   rQ   rQ   rR   r6      s    

r6   )rL   r2   r4   r"   c                 C  s:   t ||}t }|  | | }||d | S )z*Get an auth key to use for authentication.r%   )r6   r3   rW   rX   r5   rY   )rL   r2   r4   rG   rZ   rE   rQ   rQ   rR   	_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namerQ   rQ   rR   _canonicalize_hostname   s         rj   )r   r    r"   c              
   C  sv  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|}tdD ]j}t|	t|d }|dkrvtdt|	pd
}d|d |d}|d|}|tjkrL qqLtdt|	t|d dkrtdt|	t|	|dkrtdt|	}d|d |d}|d| W 5 t|	 X W n4 tjk
rp } 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,   )rm   userdomainr4   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   r2   r4   Zmechanism_propertiesaddressZcanonicalize_host_namerj   Zservice_nameZservice_realm_USE_PRINCIPALrH   r   kerberosZauthGSSClientInitZGSS_C_MUTUAL_FLAGsplitZAUTH_GSS_COMPLETEr   ZauthGSSClientCleanZauthGSSClientStepZauthGSSClientResponserB   ranger   ZauthGSSClientUnwrapZauthGSSClientWrapZKrbError)r   r    r2   r4   propshostZserviceZ	principalresultrK   rn   ro   r'   rO   response_excrQ   rQ   rR   _authenticate_gssapi   s    

  




r   c                 C  sH   | j }| j}| j}d| d|  }ddt|dd}||| dS )z(Authenticate using SASL PLAIN (RFC 4616) r,   PLAINrr   N)r7   r2   r4   r5   r   rB   )r   r    r7   r2   r4   r'   rO   rQ   rQ   rR   _authenticate_plain/  s    r   c                 C  s6   |j }|r| rdS t| |j }|d| dS )z Authenticate using MONGODB-X509.Nrs   )r;   r<   _X509Contextrw   speculate_commandrB   )r   r    rK   rO   rQ   rQ   rR   _authenticate_x509>  s
    r   c           	      C  sT   | j }| j}| j}||ddi}|d }t|||}d|||d}||| dS )zAuthenticate using MONGODB-CR.Zgetnoncer,   rL   )authenticatern   rL   keyN)r7   r2   r4   rB   r[   )	r   r    r7   r2   r4   r   rL   r   queryrQ   rQ   rR   _authenticate_mongo_crI  s    r   c                 C  s   |j dkrr|jr|j}n8| j}| }|d | j |d< |j||dddg }d|krdt| |dS t| |dS nt| |dS d S )N   r   ZsaslSupportedMechsF)Zpublish_eventsr#   SCRAM-SHA-1)Zmax_wire_versionZnegotiated_mechsr7   Z	hello_cmdr2   rB   getrS   )r   r    Zmechsr7   rO   rQ   rQ   rR   _authenticate_defaultX  s    
r   r   )r!   r#   )	rq   z
MONGODB-CRMONGODB-X509zMONGODB-AWSMONGODB-OIDCr   r   r#   DEFAULTz(Mapping[str, Callable[(Ellipsis, 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   rw   r"   c                 C  s   || _ d | _|| _d S N)r   rA   rw   )selfr   rw   rQ   rQ   rR   __init__w  s    z_AuthContext.__init__zOptional[_AuthContext])credsrw   r"   c                 C  s$   t | j}|r tt|| |S d S r   )_SPECULATIVE_AUTH_MAPr   r!   r   r   )r   rw   Zspec_clsrQ   rQ   rR   from_credentials|  s    z_AuthContext.from_credentials"Optional[MutableMapping[str, Any]]r"   c                 C  s   t d S r   )NotImplementedErrorr   rQ   rQ   rR   r     s    z_AuthContext.speculate_commandzHello[Mapping[str, Any]])hellor"   c                 C  s   |j | _ d S r   )rA   )r   r   rQ   rQ   rR   parse_response  s    z_AuthContext.parse_responseboolc                 C  s
   t | jS r   )r   rA   r   rQ   rQ   rR   r<     s    z _AuthContext.speculate_succeededN)	__name__
__module____qualname__r   staticmethodr   r   r   r<   rQ   rQ   rQ   rR   r   v  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   rw   r!   r"   c                   s   t  || d | _|| _d S r   )superr   r@   r!   )r   r   rw   r!   	__class__rQ   rR   r     s    z_ScramContext.__init__r   r   c                 C  s.   t | j| j\}}}| jj|d< ||f| _|S Ndb)r   r   r!   r7   r@   )r   rL   rM   rO   rQ   rQ   rR   r     s    
z_ScramContext.speculate_command)r   r   r   r   r   __classcell__rQ   rQ   r   rR   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!   rn   )r   r2   )r   rO   rQ   rQ   rR   r     s    
z_X509Context.speculate_commandNr   r   r   r   rQ   rQ   rQ   rR   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   rw   Zget_spec_auth_cmdr7   )r   ZauthenticatorrO   rQ   rQ   rR   r     s    z_OIDCContext.speculate_commandNr   rQ   rQ   rQ   rR   r     s   r   )r   r   r#   r   r   zMapping[str, Any]r   r   )r   r    reauthenticater"   c                 C  s2   | j }t| }|dkr$t| || n
|| | dS )zAuthenticate connection.r   N)r!   r   r   )r   r    r   r!   Z	auth_funcrQ   rQ   rR   r     s
    r   )F)F__doc__
__future__r   	functoolsr3   r9   r]   base64r   r   typingr   r   r   r   r	   r
   r   urllib.parser   Zbson.binaryr   Zpymongo.auth_sharedr   r   r   r   Zpymongo.errorsr   r   Zpymongo.saslprepr   Zpymongo.synchronous.auth_awsr   Zpymongo.synchronous.auth_oidcr   r   Zpymongo.hellor   Zpymongo.synchronous.poolr   rv   rx   Zwinkerberosry   tuplemaprC   __version__rz   ImportErrorZ_IS_SYNCrS   r6   r[   rj   r   r   r   r   r   partialr   __annotations__r   r>   r   r   r   r   rQ   rQ   rQ   rR   <module>   sx   $	$S	o
 