U
    dJY                     @  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ZddlZddl	m
Z
m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 dd
lmZ ddl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.e/e,j01ddd dkr4dZ*W n> e2k
rt   zddl,Z,W n e2k
rn   dZ)Y nX Y nX e3dddddddddg	Z4G dd dZ5ed d!d"d#d$d%d&gZ6ed'd(d)d*gZ7ed+d,gZ8d-d.d-d-d/d.d d0d1d2Z9d3d3d3d4d5d6Z:d3d7d8d9d:Z;d d-d;d<d=d>Z<d d?d-d@dAdBdCZ=d-d-d-dDdEdFZ>d-d-d-d-dGdHdIZ?d-d-dJdKdLZ@d d?d@dMdNdOZAd d?d@dMdPdQZBd d?d@dMdRdSZCd d?d@dMdTdUZDd d?d@dMdVdWZEeAeDeCeeBejFe=ddXejFe=ddXeEdYZGdZeHd[< G d\d] d]ZIG d^d_ d_eIZJG d`da daeIZKG dbdc dceIZLeKejFeJddXejFeJddXeLejFeJddXddZMdZeHde< djd d?dfd@dgdhdiZNdS )kzAuthentication helpers.    )annotationsN)standard_b64decodestandard_b64encode)
namedtuple)TYPE_CHECKINGAnyCallableMappingMutableMappingOptional)quote)Binary)SON)_authenticate_aws)_authenticate_oidc_get_authenticator_OIDCProperties)ConfigurationErrorOperationFailure)saslprep)Hello)
ConnectionTF.   )r      GSSAPI
MONGODB-CRMONGODB-OIDCMONGODB-X509MONGODB-AWSPLAINSCRAM-SHA-1SCRAM-SHA-256DEFAULTc                   @  sT   e Zd ZdZed ZddddZdddd	d
ZdddddZddddZ	dS )_CachedataNonereturnc                 C  s
   d | _ d S Nr%   self r-   0/tmp/pip-unpacked-wheel-oblwsawz/pymongo/auth.py__init__K   s    z_Cache.__init__objectbool)otherr)   c                 C  s   t |trdS tS )NT
isinstancer$   NotImplementedr,   r2   r-   r-   r.   __eq__N   s    
z_Cache.__eq__c                 C  s   t |trdS tS )NFr3   r6   r-   r-   r.   __ne__T   s    
z_Cache.__ne__intc                 C  s   | j S r*   )	_hash_valr+   r-   r-   r.   __hash__Y   s    z_Cache.__hash__N)
__name__
__module____qualname__	__slots__hashr:   r/   r7   r8   r;   r-   r-   r-   r.   r$   F   s   r$   MongoCredential	mechanismsourceusernamepasswordmechanism_propertiescacheGSSAPIPropertiesservice_namecanonicalize_host_nameservice_realm_AWSPropertiesaws_session_tokenstrzOptional[str]zMapping[str, Any])mechrC   userpasswdextradatabaser)   c                 C  s2  | dkr|dkrt |  d| dkr|dk	r>|dkr>td|di }|dd	}|d
d}|d}	t|||	d}
t| d|||
dS | dkr|dk	rt d|dk	r|dkrtdt| d|dddS | dkr>|dk	r|dkrt d|dk	r|dkrt d|di }|d}t|d}t| d|||dS | dkr|di }|d}|dd}|dd}dddddd g}|d!|}|s|d"krt d#t||||d$}t| d|||dS | d%kr|p|pd}t| |||ddS |p|pd&}|dkrt d't| |||dt S dS )(z8Build and return a mechanism specific credentials tuple.)r   r   r   Nz requires a username.r   	$externalz:authentication source must be $external or None for GSSAPIZauthmechanismpropertiesZSERVICE_NAMEZmongodbZCANONICALIZE_HOST_NAMEFZSERVICE_REALM)rI   rJ   rK   r   z+Passwords are not supported by MONGODB-X509z@authentication source must be $external or None for MONGODB-X509r   z;username without a password is not supported by MONGODB-AWSz?authentication source must be $external or None for MONGODB-AWSZAWS_SESSION_TOKEN)rM   r   request_token_callbackrefresh_token_callbackZPROVIDER_NAME z*.mongodb.netz*.mongodb-dev.netz*.mongodbgov.net	localhostz	127.0.0.1z::1allowed_hostsZawsziauthentication with MONGODB-OIDC requires providing an request_token_callback or a provider_name of 'aws')rU   rV   provider_namerY   r    ZadminzA password is required.)r   
ValueErrorgetrH   rA   rL   r   r$   )rO   rC   rP   rQ   rR   rS   Z
propertiesrI   canonicalizerK   propsrM   Z	aws_propsrU   rV   rZ   Zdefault_allowedrY   Z
oidc_propsZsource_databaser-   r-   r.   _build_credentials_tuplen   s~    	







r_   bytes)firsecr)   c                 C  s   d dd t| |D S )zXOR two byte strings together.    c                 S  s   g | ]\}}t ||A gqS r-   )r`   ).0xyr-   r-   r.   
<listcomp>   s     z_xor.<locals>.<listcomp>)joinzip)ra   rb   r-   r-   r.   _xor   s    rj   dict)responser)   c                 C  s   t dd | dD S )z-Split a scram response into key, value pairs.c                 s  s,   | ]$}t t jttf |d dV  qdS )   =   N)typingcastTuplerN   split)rd   itemr-   r-   r.   	<genexpr>   s    z(_parse_scram_response.<locals>.<genexpr>   ,)rk   rr   )rl   r-   r-   r.   _parse_scram_response   s    rv   z-tuple[bytes, bytes, MutableMapping[str, Any]])credentialsrB   r)   c                 C  sr   | j }|ddddd}ttd}d| d | }td	d
|fdtd| fddddifg}|||fS )Nutf-8rm   s   =3Dru   s   =2C    s   n=s   ,r=Z	saslStartrn   rB   payloads   n,,ZautoAuthorizern   optionsZskipEmptyExchangeT)rD   encodereplacer   osurandomr   r   )rw   rB   rD   rP   nonce
first_barecmdr-   r-   r.   _authenticate_scram_start   s    
	r   r   r'   )rw   connrB   r)   c                  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|	||| }t dd|d fdt!|fg}|||}t|d }t
"|d |sHtd|d st dd|d fdt!dfg}|||}|d stddS )zAuthenticate using SCRAM.r"   sha256rx   sha1Nr{      ii   z+Server returned an invalid iteration count.   s   rz!Server returned an invalid nonce.s	   c=biws,r=)NNNNs
   Client Keys
   Server Keyru   s   p=ZsaslContinuern   conversationId   vz%Server returned an invalid signature.donerc   z%SASL conversation failed to complete.)#rD   hashlibr   r   rE   r~   r   _password_digestrC   rG   hmacHMACauth_ctxspeculate_succeededr4   _ScramContextAssertionError
scram_dataspeculative_authenticater   commandrv   r9   r   
startswithr&   pbkdf2_hmacr   digestrh   r   rj   r   r   compare_digest) rw   r   rB   rD   r   	digestmodr&   rC   rG   Z_hmacctxr   r   resr   Z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_sigr-   r-   r.   _authenticate_scram   s    






r   )rD   rE   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:rx   )
r4   rN   	TypeErrorlenr[   r   md5updater~   	hexdigest)rD   rE   md5hashr&   r-   r-   r.   r   6  s    

r   )r   rD   rE   r)   c                 C  s:   t ||}t }|  | | }||d | S )z*Get an auth key to use for authentication.rx   )r   r   r   r   r~   r   )r   rD   rE   r   r   r&   r-   r-   r.   	_auth_keyE  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namer-   r-   r.   _canonicalize_hostnameN  s         r   )rw   r   r)   c              
   C  s  t stdzH| 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	zBt|	d
dkr tdt|	}tddd|fdg}|d|}tdD ]t}t|	t|d }|dkr|tdt|	pd
}tdd|d fd|fg}|d|}|tjkrR qАqRtdt|	t|d dkrtdt|	t|	|dkrtdt|	}tdd|d fd|fg}|d| W 5 t|	 X W n2 tjk
r } ztt|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:)gssflagsrn   )r   rP   domainrE   z&Kerberos context failed to initialize.rW   z*Unknown kerberos failure in step function.rz   )rB   r   r{   r|   rT   
   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   rD   rE   rF   addressrJ   r   rI   rK   _USE_PRINCIPALrh   r   kerberosZauthGSSClientInitZGSS_C_MUTUAL_FLAGrr   ZAUTH_GSS_COMPLETEr   ZauthGSSClientCleanZauthGSSClientStepZauthGSSClientResponser   r   rangerN   ZauthGSSClientUnwrapZauthGSSClientWrapZKrbError)rw   r   rD   rE   r^   hostZserviceZ	principalresultr   rP   r   r{   r   rl   _excr-   r-   r.   _authenticate_gssapi]  s    

  






r   c                 C  sN   | j }| j}| j}d| d|  }tdddt|fdg}||| dS )z(Authenticate using SASL PLAIN (RFC 4616) rz   )rB   r    r{   r|   N)rC   rD   rE   r~   r   r   r   )rw   r   rC   rD   rE   r{   r   r-   r-   r.   _authenticate_plain  s    
r   c                 C  s6   |j }|r| rdS t| |j }|d| dS )z Authenticate using MONGODB-X509.NrT   )r   r   _X509Contextr   speculate_commandr   )rw   r   r   r   r-   r-   r.   _authenticate_x509  s
    r   c           	      C  sb   | j }| j}| j}||ddi}|d }t|||}tdd|fd|fd|fg}||| dS )zAuthenticate using MONGODB-CR.Zgetnoncern   r   authenticatern   rP   keyN)rC   rD   rE   r   r   r   )	rw   r   rC   rD   rE   rl   r   r   queryr-   r-   r.   _authenticate_mongo_cr  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"   r!   )Zmax_wire_versionZnegotiated_mechsrC   Z	hello_cmdrD   r   r\   r   )rw   r   ZmechsrC   r   r-   r-   r.   _authenticate_default  s    
r   )rB   )r   r   r   r   r    r!   r"   r#   zMapping[str, Callable]	_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 )_AuthContextrA   tuple[str, int]r'   )rw   r   r)   c                 C  s   || _ d | _|| _d S r*   )rw   r   r   )r,   rw   r   r-   r-   r.   r/     s    z_AuthContext.__init__zOptional[_AuthContext])credsr   r)   c                 C  s   t | j}|r|| |S d S r*   )_SPECULATIVE_AUTH_MAPr\   rB   )r   r   Zspec_clsr-   r-   r.   from_credentials   s    
z_AuthContext.from_credentials"Optional[MutableMapping[str, Any]]r(   c                 C  s   t d S r*   )NotImplementedErrorr+   r-   r-   r.   r   )  s    z_AuthContext.speculate_commandr   )hellor)   c                 C  s   |j | _ d S r*   )r   )r,   r   r-   r-   r.   parse_response,  s    z_AuthContext.parse_responser1   c                 C  s
   t | jS r*   )r1   r   r+   r-   r-   r.   r   /  s    z _AuthContext.speculate_succeededN)	r<   r=   r>   r/   staticmethodr   r   r   r   r-   r-   r-   r.   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   rA   r   rN   r'   )rw   r   rB   r)   c                   s   t  || d | _|| _d S r*   )superr/   r   rB   )r,   rw   r   rB   	__class__r-   r.   r/   4  s    z_ScramContext.__init__r   r(   c                 C  s.   t | j| j\}}}| jj|d< ||f| _|S )Ndb)r   rw   rB   rC   r   )r,   r   r   r   r-   r-   r.   r   ;  s    
z_ScramContext.speculate_command)r<   r=   r>   r/   r   __classcell__r-   r-   r   r.   r   3  s   r   c                   @  s   e Zd ZddddZdS )r   zMutableMapping[str, Any]r(   c                 C  s(   t ddg}| jjd k	r$| jj|d< |S )Nr   )rB   r   rP   )r   rw   rD   )r,   r   r-   r-   r.   r   E  s    z_X509Context.speculate_commandNr<   r=   r>   r   r-   r-   r-   r.   r   D  s   r   c                   @  s   e Zd ZddddZdS )_OIDCContextr   r(   c                 C  s4   t | j| j}|d}|d kr$d S | jj|d< |S )NFr   )r   rw   r   Zauth_start_cmdrC   )r,   Zauthenticatorr   r-   r-   r.   r   M  s    
z_OIDCContext.speculate_commandNr   r-   r-   r-   r.   r   L  s   r   )r   r!   r"   r   r#   r   r1   )rw   r   reauthenticater)   c                 C  s2   | j }t| }|dkr$t| || n
|| | dS )zAuthenticate connection.r   N)rB   r   r   )rw   r   r   rB   Z	auth_funcr-   r-   r.   r   _  s
    r   )F)O__doc__
__future__r   	functoolsr   r   r   r   ro   base64r   r   collectionsr   r   r   r   r	   r
   r   urllib.parser   Zbson.binaryr   Zbson.sonr   Zpymongo.auth_awsr   Zpymongo.auth_oidcr   r   r   Zpymongo.errorsr   r   Zpymongo.saslprepr   Zpymongo.hellor   Zpymongo.poolr   r   r   Zwinkerberosr   tuplemapr9   __version__rr   ImportError	frozensetZ
MECHANISMSr$   rA   rH   rL   r_   rj   rv   r   r   r   r   r   r   r   r   r   r   partialr   __annotations__r   r   r   r   r   r   r-   r-   r-   r.   <module>   s    $ QW	u
 