o
    c_                     @   s   d Z ddlmZ zddlmZ ddlmZmZ ddlm	Z	 dZ
W n ey+   dZ
Y nw dd	lmZ dd
lZdZdZeejdZdd Zdd Zda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 )#z
Implements auth methods
   )OperationalError    )default_backend)serializationhashes)paddingTF)partialN   sha1c                 C   sT   | sdS t |  }t | }t  }||dt  || | }t||S )z'Scramble used for mysql_native_password    N)sha1_newdigestupdateSCRAMBLE_LENGTH	_my_crypt)passwordmessagestage1stage2sresult r   //usr/lib/python3/dist-packages/pymysql/_auth.pyscramble_native_password   s   

r   c                 C   s6   t | }tt|D ]}||  || N  < q
t|S N)	bytearrayrangelenbytes)message1message2r   ir   r   r   r   +   s   r   c                  C   s.   zddl m}  | aW d S  ty   tdw )Nr   bindingsz='pynacl' package is required for ed25519_password auth method)naclr#   _nacl_bindingsImportErrorRuntimeErrorr"   r   r   r   
_init_nacl:   s   
r(   c                 C   sP   t | }tt |d d@ g}tt |d d@ dB g}|t| dd  | S )Nr            @   r   )r   r   )s32baba0ba31r   r   r   _scalar_clampF   s   r1   c           
      C   s   t st  t|  }t|dd }t|dd |  }t |}t |}t |}t|| |  }t |}t ||}t 	||}	||	 S )znSign a random scramble with elliptic curve Ed25519.

    Secret and public key are derived from password.
    N    )
r%   r(   hashlibsha512r   r1   !crypto_core_ed25519_scalar_reduce&crypto_scalarmult_ed25519_base_noclampcrypto_core_ed25519_scalar_mulcrypto_core_ed25519_scalar_add)
r   scramblehr   rRAkksSr   r   r   ed25519_passwordM   s   



rA   c                 C   s   |  | |  }|  |S r   )write_packet_read_packetcheck_error)conn	send_datapktr   r   r   
_roundtripv   s   
rH   c                 C   sN   |d t  }t| }t|}tt|D ]}||  |||  N  < qt|S r   )r   r   r   r   r   )r   saltpassword_bytessalt_lenr!   r   r   r   _xor_password}   s   rL   c                 C   sP   t stdt| d |}t|t }||tjtj	t
 dt
 ddS )zhEncrypt password with salt and public_key.

    Used for sha256_password and caching_sha2_password.
    z\'cryptography' package is required for sha256_password or caching_sha2_password auth methods    )	algorithmN)mgfrN   label)_have_cryptographyr'   rL   r   load_pem_public_keyr   encryptr   OAEPMGF1r   SHA1)r   rI   
public_keyr   rsa_keyr   r   r   sha2_rsa_encrypt   s   rY   c                 C   s   | j rtr	td | jd }t| |S | r-| | _| js-| jr-tr(td t| d}|	 rD|j
dd  | _trDtd| jd | jrX| jsNtdt| j| j| j}nd	}t| |S )
Nzsha256: Sending plain passwordrM   z$sha256: Requesting server public key   r   zReceived public key:
asciiz$Couldn't receive server's public keyr   )_secureDEBUGprintr   rH   is_auth_switch_requestread_allrI   server_public_keyis_extra_auth_data_datadecoder   rY   )rE   rG   datar   r   r   sha256_password_auth   s*   




rf   c                 C   sl   | sdS t |  }t | }t ||  }t|}tt|D ]}||  || N  < q%t|S )zScramble algorithm used in cached_sha2_password fast path.

    XOR(SHA256(password), SHA256(SHA256(SHA256(password)), nonce))
    r   )r3   sha256r   r   r   r   r   )r   noncep1p2p3resr!   r   r   r   scramble_caching_sha2   s   rm   c                 C   sR  | j st| dS | r#trtd | | _t| j | j}t| |}| s2t	d|j
d d  |d | }|dkrOtrEtd |  }|  |S |dkrYt	d| tr_td	 | jrptrhtd
 t| | j d S | jst| d}| st	d|j
d d  |j
dd  | _trt| jd t| j | j| j}t| |}d S )Nr   zcaching sha2: Trying fast pathz.caching sha2: Unknown packet for fast auth: %sr      z%caching sha2: succeeded by fast path.   z.caching sha2: Unknwon result for fast auth: %sz!caching sha2: Trying full auth...z:caching sha2: Sending plain password via secure connectionrM      z/caching sha2: Unknown packet for public key: %sr[   )r   rH   r_   r]   r^   r`   rI   rm   rb   r   rc   advance
read_uint8rC   rD   r\   ra   rd   rY   )rE   rG   	scramblednre   r   r   r   caching_sha2_password_auth   sN   



	
ru   )__doc__errr   cryptography.hazmat.backendsr   cryptography.hazmat.primitivesr   r   )cryptography.hazmat.primitives.asymmetricr   rQ   r&   	functoolsr   r3   r]   r   newr   r   r   r%   r(   r1   rA   rH   rL   rY   rf   rm   ru   r   r   r   r   <module>   s6    )