B
    ɢ](                 @   s.  d 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
 y0ddlmZ ddlmZmZ dd	lmZ d
ZW n ek
r   dZY nX ddlmZ ddlZddlZddlZddlZdZdZeejdZdd Zdd ZdZ G dd de!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
   )	text_typePY2)CLIENT)OperationalError)byte2intint2byte    )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messageZstage1Zstage2sresult r   NC:\Users\jaco\AppData\Local\Temp\pip-install-vjvq8kq0\pymysql\pymysql\_auth.pyscramble_native_password"   s    
r   c             C   sF   t | }trt |}x(tt|D ]}||  || N  < q"W t|S )N)	bytearrayr   rangelenbytes)Zmessage1Zmessage2r   ir   r   r   r   0   s    r      c               @   s   e Zd Zdd Zdd ZdS )RandStruct_323c             C   s"   d| _ || j  | _|| j  | _d S )Ni?)	max_valueseed1seed2)selfr%   r&   r   r   r   __init__C   s    zRandStruct_323.__init__c             C   sD   | j d | j | j | _ | j | j d | j | _t| j t| j S )N   !   )r%   r&   r$   float)r'   r   r   r   my_rndH   s    zRandStruct_323.my_rndN)__name__
__module____qualname__r(   r,   r   r   r   r   r#   A   s   r#   c             C   s   t d t| }t|dt }td|}td|}t|d |d A |d |d A }t }x8t	t
tt|D ]"}|tt| d d  qxW tt| d }	| }
t }x&|
D ]}|tt|t|	A  qW | S )zScramble for old_passwordzold password (for MySQL <4.1) is used.  Upgrade your password with newer auth method.
old password support will be removed in future PyMySQL versionNz>LLr   r      @   )warningswarn_hash_password_323SCRAMBLE_LENGTH_323structunpackr#   ioBytesIOr   minr   writer   intr,   getvaluer   )r   r   Z	hash_passZhash_messageZhash_pass_nZhash_message_nZrand_stZoutbuf_extraoutcr   r   r   scramble_old_passwordN   s     
 "
rB   c             C   s   d}d}d}xVdd | D D ]D}||d@ | | |d>  d@ N }||d> |A  d@ }|| d@ }qW |d	@ }|d	@ }t d
||S )Ni5W0P   iqV4c             S   s   g | ]}|d krt |qS )) 	    	   )r   ).0xr   r   r   
<listcomp>k   s    z&_hash_password_323.<locals>.<listcomp>?   r"   l    iz>LL)r6   pack)r   nraddZnr2rA   Zr1Zr2r   r   r   r4   e   s     r4   c             C   s   |  | |  }|  |S )N)Zwrite_packet_read_packetcheck_error)connZ	send_datapktr   r   r   
_roundtripx   s    
rS   c             C   sN   t | }t |}t|}x,tt|D ]}||  |||  N  < q&W t|S )N)r   r   r   r    )r   saltZpassword_bytesZsalt_lenr!   r   r   r   _xor_password   s    rU   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.
    zEcryptography is required for sha256_password or caching_sha2_password    )	algorithmN)ZmgfrW   label)_have_cryptographyRuntimeErrorrU   r
   Zload_pem_public_keyr	   Zencryptr   ZOAEPZMGF1r   SHA1)r   rT   Z
public_keyr   Zrsa_keyr   r   r   sha2_rsa_encrypt   s    r\   c             C   s   | j r&trtd | jd }t| |S | rZ| | _| jsZ| jrZtrPtd t| d}|	 r|j
dd  | _trtd| jd | jr| jstdt| j| j| j}nd	}t| |S )
Nzsha256: Sending plain passwordrV   z$sha256: Requesting server public key   r   zReceived public key:
asciiz$Couldn't receive server's public keyr   )_secureDEBUGprintr   rS   is_auth_switch_requestread_allrT   server_public_keyis_extra_auth_data_datadecoder   r\   )rQ   rR   datar   r   r   sha256_password_auth   s*    



ri   c             C   s|   | sdS t |  }t | }t ||  }t|}trJt|}x(tt|D ]}||  || N  < qXW t|S )zScramble algorithm used in cached_sha2_password fast path.

    XOR(SHA256(password), SHA256(SHA256(SHA256(password)), nonce))
    r   )hashlibsha256r   r   r   r   r   r    )r   noncep1p2Zp3resr!   r   r   r   scramble_caching_sha2   s    rp   c             C   sX  | j st| dS | rFtr$td | | _t| j | j}t| |}| sdt	d|j
d d  |d | }|dkrtrtd |  }|  |S |dkrt	d| trtd	 | jrtrtd
 t| | j d S | js8t| d}| st	d|j
d d  |j
dd  | _tr8t| jd t| j | j| j}t| |}d S )Nr   zcaching sha2: Trying fast pathz.caching sha2: Unknown packet for fast auth: %sr   r)   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 connectionrV      z/caching sha2: Unknown packet for public key: %sr^   )r   rS   rb   r`   ra   rc   rT   rp   re   r   rf   ZadvanceZ
read_uint8rO   rP   r_   rd   rg   r\   )rQ   rR   Z	scramblednrh   r   r   r   caching_sha2_password_auth   sJ    





rt   )+__doc___compatr   r   	constantsr   errr   utilr   r   Zcryptography.hazmat.backendsr	   Zcryptography.hazmat.primitivesr
   r   Z)cryptography.hazmat.primitives.asymmetricr   rY   ImportError	functoolsr   rj   r8   r6   r2   r`   r   newr   r   r   r5   objectr#   rB   r4   rS   rU   r\   ri   rp   rt   r   r   r   r   <module>   s>   
	