a
    lJhu                     @   sV  d 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 z2ddlZejejejejdZeedoejZW n ey   dZdZY n0 d	d
lmZmZmZmZm Z m!Z!m"Z" dZ#dZ$dZ%dZ&e'e(dddZ)G dd deZ*G dd de*Z+G dd de+Z,G dd deZ-G dd de-Z.G dd de-Z/dS )zFModule implementing low-level socket communication with MySQL servers.    N)ABCabstractmethod)deque)AnyDequeListOptionalTupleUnion)TLSv1TLSv1.1TLSv1.2TLSv1.3HAS_TLSv1_3F   )ConnectionTimeoutErrorInterfaceErrorNotSupportedErrorOperationalErrorProgrammingErrorReadTimeoutErrorWriteTimeoutError2   i       )errreturnc                 C   s"   | j st| S d| j  d| j S )z`Reformat the IOError error message.

    This function reformats the IOError error message.
    zErrno z: )errnostrstrerror)r    r    I/var/www/shaz/venv/lib/python3.9/site-packages/mysql/connector/network.py_strioerrorI   s    r"   c                	   @   sP   e Zd ZdZed	ejeeee	 ee	 ddddZ
eejeedddZdS )
NetworkBrokeraP  Broker class interface.

    The network object is a broker used as a delegate by a socket object. Whenever the
    socket wants to deliver or get packets to or from the MySQL server it needs to rely
    on its network broker (netbroker).

    The netbroker sends `payloads` and receives `packets`.

    A packet is a bytes sequence, it has a header and body (referred to as payload).
    The first `PACKET_HEADER_LENGTH` or `COMPRESSED_PACKET_HEADER_LENGTH`
    (as appropriate) bytes correspond to the `header`, the remaining ones represent the
    `payload`.

    The maximum payload length allowed to be sent per packet to the server is
    `MAX_PAYLOAD_LENGTH`. When  `send` is called with a payload whose length is greater
    than `MAX_PAYLOAD_LENGTH` the netbroker breaks it down into packets, so the caller
    of `send` can provide payloads of arbitrary length.

    Finally, data received by the netbroker comes directly from the server, expect to
    get a packet for each call to `recv`. The received packet contains a header and
    payload, the latter respecting `MAX_PAYLOAD_LENGTH`.
    Nsockaddresspayloadpacket_numbercompressed_packet_numberr   c                 C   s   dS )a  Send `payload` to the MySQL server.

        If provided a payload whose length is greater than `MAX_PAYLOAD_LENGTH`, it is
        broken down into packets.

        Args:
            sock: Object holding the socket connection.
            address: Socket's location.
            payload: Packet's body to send.
            packet_number: Sequence id (packet ID) to attach to the header when sending
                           plain packets.
            compressed_packet_number: Same as `packet_number` but used when sending
                                      compressed packets.

        Raises:
            :class:`OperationalError`: If something goes wrong while sending packets to
                                       the MySQL server.
        Nr    )selfr%   r&   r'   r(   r)   r    r    r!   sendi   s    	zNetworkBroker.sendr%   r&   r   c                 C   s   dS )a)  Get the next available packet from the MySQL server.

        Args:
            sock: Object holding the socket connection.
            address: Socket's location.

        Returns:
            packet: A packet from the MySQL server.

        Raises:
            :class:`OperationalError`: If something goes wrong while receiving packets
                                       from the MySQL server.
            :class:`InterfaceError`: If something goes wrong while receiving packets
                                     from the MySQL server.
        Nr    )r*   r%   r&   r    r    r!   recv   s    zNetworkBroker.recv)NN)__name__
__module____qualname____doc__r   socketr   bytesr   intr+   	bytearrayr-   r    r    r    r!   r#   Q   s     r#   c                   @   s   e Zd ZdZddddZddddZejeeddd	d
Z	deje
edddZdejeeee
 ee
 ddddZejeedddZdS )NetworkBrokerPlain,Broker class for MySQL socket communication.Nr   c                 C   s
   d| _ d S N_pktnrr*   r    r    r!   __init__   s    zNetworkBrokerPlain.__init__c                 C   s   | j d d | _ dS zIncrement packet id.r      Nr;   r=   r    r    r!   _set_next_pktnr   s    z"NetworkBrokerPlain._set_next_pktnrr%   r&   pktr   c              
   C   s   z| | W n tjtfyD } ztdd|W Y d}~npd}~0  ty| } z"td|t|fd|W Y d}~n8d}~0  ty } ztdd|W Y d}~n
d}~0 0 dS )z!Write packet to the comm channel.  r   N  r   valuesi  )	sendallr2   timeoutTimeoutErrorr   IOErrorr   r"   AttributeError)r*   r%   r&   rC   r   r    r    r!   	_send_pkt   s     zNetworkBrokerPlain._send_pktr   )r%   sizer   c                 C   sT   t |}t|}|rP|||}|dkr:|dkr:tdd||d }||8 }q|S )z(Read `size` bytes from the comm channel.r   i  rE   N)r5   
memoryview	recv_intor   )r*   r%   rO   rC   Zpkt_viewreadr    r    r!   _recv_chunk   s    

zNetworkBrokerPlain._recv_chunkr$   c              
   C   s   |du r|    n|| _t|tkrd}tt|t D ]@}| ||dtd| j |||t    |    |t7 }q8||d }| ||tdt|dd td| j |  dS )zSend payload to the MySQL server.

        If provided a payload whose length is greater than `MAX_PAYLOAD_LENGTH`, it is
        broken down into packets.
        Nr      <B<I   )rA   r<   lenMAX_PAYLOAD_LENGTHrangerN   structpack)r*   r%   r&   r'   r(   r)   offset_r    r    r!   r+      s6    

zNetworkBrokerPlain.sendr,   c              
   C   s   zJ| j |td}td|dd d d |d  }| _|| j ||d W S  tjtfy } ztd|j	d|W Y d}~nBd}~0  t
y } z"td	|t|fd
|W Y d}~n
d}~0 0 dS )z+Receive `one` packet from the MySQL server.rO   rV   r   rW       rD   )r   msgNrF   rG   )rS   PACKET_HEADER_LENGTHr[   unpackr<   r2   rJ   rK   r   r   rL   r   r"   )r*   r%   r&   headerZpayload_lenr   r    r    r!   r-      s    $zNetworkBrokerPlain.recv)r   )NN)r.   r/   r0   r1   r>   rA   r2   r   r3   rN   r4   r5   rS   r   r+   r-   r    r    r    r!   r6      s      ,r6   c                       s   e Zd ZdZdd fddZeeeee dddZ	ddd	d
Z
ejeedd fddZdejeeee ee dd fddZejeedd fddZejeed fddZ  ZS )NetworkBrokerCompressedr7   Nr8   c                    s   t    d| _t | _d S r9   )superr>   _compressed_pktnrr   _queue_readr=   	__class__r    r!   r>      s    
z NetworkBrokerCompressed.__init__)r'   pktnrr   c                 C   s   g }t | tkrpd}tt | t D ]>}|dtd| | ||t    |d d }|t7 }q$| |d } |tdt | dd td| |   |S )	z2Prepare a payload for sending to the MySQL server.r   rT   rU   r   r@   NrV   rW   )rX   rY   rZ   appendr[   r\   )r'   rk   Zpktsr]   r^   r    r    r!   _prepare_packets  s$    

&z(NetworkBrokerCompressed._prepare_packetsc                 C   s   | j d d | _ dS r?   )rg   r=   r    r    r!   _set_next_compressed_pktnr  s    z2NetworkBrokerCompressed._set_next_compressed_pktnrrB   c                    s\   t |}tdt|dd td| j tdt|dd  | }t |||S )z1Compress packet and write it to the comm channel.rV   r   rW   rU   )zlibcompressr[   r\   rX   rg   rf   rN   )r*   r%   r&   rC   compressed_pktri   r    r!   rN   #  s    
z!NetworkBrokerCompressed._send_pktr$   c           	   	      s  |du r|    n|| _|du r*|   n|| _td| || j}t|tt	 krd}t
t|t D ].}| |||||t   |   |t7 }ql| ||||d  nft|tkr| ||| nJt ||tdt|dd td| j tdddd  |  dS )zSend `payload` as compressed packets to the MySQL server.

        If provided a payload whose length is greater than `MAX_PAYLOAD_LENGTH`, it is
        broken down into packets.
        N    r   rV   rW   rU   )rA   r<   rn   rg   r5   joinrm   rX   rY   rb   rZ   rN   MIN_COMPRESS_LENGTHrf   r[   r\   )	r*   r%   r&   r'   r(   r)   Zpayload_prepr]   r^   ri   r    r!   r+   .  s:    


zNetworkBrokerCompressed.send)r%   compressed_plluncompressed_pllr   c           	         s"  t  j||d}|dkr|ntt|}d}|t|k rtd|||t d  d d }t| t|| krt  j|t	d}td|dd d d |d td|dd d d   }| _
}t  j||d}||dkr|nt|7 }| j|||t |   |t| 7 }q.d	S )
z&Handle reading of a compressed packet.r_   r   rV   r   r`   rW   r   r   N)rf   rS   r5   ro   
decompressrX   r[   rc   rb   COMPRESSED_PACKET_HEADER_LENGTHrg   rh   rl   )	r*   r%   ru   rv   rq   rC   r]   Zpllrd   ri   r    r!   _recv_compressed_pktk  s<    z,NetworkBrokerCompressed._recv_compressed_pktr,   c              
      s   | j szht j|td}td|dd d d |d td|dd d d   }| _}| ||| W nn tj	t
fy } ztdd	|W Y d
}~nBd
}~0  ty } z"td|t|fd|W Y d
}~n
d
}~0 0 | j sd
S | j  }|d | _|S )z{Receive `one` or `several` packets from the MySQL server, enqueue them, and
        return the packet at the head.
        r_   rV   r   rW   r`   r   r   rD   rE   NrF   rG   )rh   rf   rS   rx   r[   rc   rg   ry   r2   rJ   rK   r   rL   r   r"   popleftr<   )r*   r%   r&   rd   ru   rv   r   rC   ri   r    r!   r-     s2     

zNetworkBrokerCompressed.recv)NN)r.   r/   r0   r1   r>   staticmethodr3   r4   r   rm   rn   r2   r   rN   r   r+   ry   r5   r-   __classcell__r    r    ri   r!   re      s(     >0re   c                
   @   s   e Zd ZdZddddZddddZdddd	Zddd
dZddddZe	e
 ddddZeeddddZd"e	e e	e e	e e	e e	e e	ee  e	ee  edddZd#ee	e
 e	e
 e	e
 ddddZd$e	e
 edddZeddddZeeedd d!ZdS )%MySQLSocketzMySQL socket communication interface.

    Examples:
        Subclasses: network.MySQLTCPSocket and network.MySQLUnixSocket.
    Nr8   c                 C   s   d| _ d| _d| _t | _dS )zsNetwork layer where transactions are made with plain (uncompressed) packets
        is enabled by default.
        N)r%   _connection_timeoutserver_hostr6   
_netbrokerr=   r    r    r!   r>     s    zMySQLSocket.__init__c                 C   s   t  | _dS )zIEnable network layer where transactions are made with compressed packets.N)re   r   r=   r    r    r!   switch_to_compressed_mode  s    z%MySQLSocket.switch_to_compressed_modec              	   C   s8   z| j tj | j   W n ttfy2   Y n0 dS )z'Shut down the socket before closing it.N)r%   shutdownr2   	SHUT_RDWRcloserM   OSErrorr=   r    r    r!   r     s
    zMySQLSocket.shutdownc              	   C   s*   z| j   W n ttfy$   Y n0 dS )zClose the socket.N)r%   r   rM   r   r=   r    r    r!   close_connection  s    zMySQLSocket.close_connectionc                 C   s   |    d S N)r   r=   r    r    r!   __del__  s    zMySQLSocket.__del__)rJ   r   c                 C   s   || _ | jr| j| dS )zSet the connection timeout.N)r~   r%   
settimeout)r*   rJ   r    r    r!   set_connection_timeout  s    z"MySQLSocket.set_connection_timeout)ssl_contexthostr   c              
   C   s   | j dusJ | j jdkr"tdtdu r2tdz|j| j |d| _ W n tyv } ztd|W Y d}~nd}~0  tjtfy } z$t	d| j
t|fd|W Y d}~nnd}~0  tjy } zt	t||W Y d}~n<d}~0  ty } zt	t||W Y d}~n
d}~0 0 dS )a  Upgrade an existing connection to TLS.

        Args:
            ssl_context (ssl.SSLContext): The SSL Context to be used.
            host (str): Server host name.

        Returns:
            None.

        Raises:
            ProgrammingError: If the transport does not expose the socket instance.
            NotSupportedError: If Python installation has no SSL support.
        Nr   z,SSL is not supported when using Unix sockets&Python installation has no SSL support)server_hostnamerF   rG   )r%   familyr   sslr   wrap_socket	NameErrorSSLErrorrL   r   r&   r"   CertificateErrorr   NotImplementedError)r*   r   r   r   r    r    r!   switch_to_ssl  s&    "zMySQLSocket.switch_to_sslF)ssl_cassl_certssl_keyssl_verify_certssl_verify_identitytls_versionstls_cipher_suitesr   c                 C   s4  d}| j stddtdu r$td|du r0g }|du r<g }z|r|jdd |d }t| }	t|	}
|dkrd	|vr|
 jtjO  _d
|vr|
 jtj	O  _d|vr|
 jtj
O  _nt }
||
_|rtj|
_n|rtj|
_ntj|
_|
  |rHz|
| W n< ttjfyF } ztd| |W Y d}~n
d}~0 0 |rz|
|| W n< ttjfy } ztd| |W Y d}~n
d}~0 0 |r|d	kr|
d| |
W S  ty } ztd|W Y d}~nHd}~0  tttjtjfy. } ztt||W Y d}~n
d}~0 0 dS )a  Build a SSLContext.

        Args:
            ssl_ca: Certificate authority, opptional.
            ssl_cert: SSL certificate, optional.
            ssl_key: Private key, optional.
            ssl_verify_cert: Verify the SSL certificate if `True`.
            ssl_verify_identity: Verify host identity if `True`.
            tls_versions: TLS protocol versions, optional.
            tls_cipher_suites: Set of steps that helps to establish a secure connection.

        Returns:
            ssl_context (ssl.SSLContext): An SSL Context ready be used.

        Raises:
            NotSupportedError: Python installation has no SSL support.
            InterfaceError: Socket undefined or invalid ssl data.
        Ni   rE   r   T)reverser   r   r   r   r   zInvalid CA Certificate: zInvalid Certificate/Key: :)r%   r   r   r   sortTLS_VERSIONS
SSLContextoptionsOP_NO_TLSv1_2OP_NO_TLSv1_1OP_NO_TLSv1create_default_contextcheck_hostnameCERT_REQUIREDverify_modeCERT_OPTIONAL	CERT_NONEload_default_certsload_verify_locationsrL   r   load_cert_chainset_ciphersrs   r   r   r   r   )r*   r   r   r   r   r   r   r   Ztls_versionZssl_protocolcontextr   r    r    r!   build_ssl_context  sh    



&&zMySQLSocket.build_ssl_context)r'   r(   r)   write_timeoutr   c              
   C   sp   z,| j s*| jdur*| j|r$t|nd W n$ tyP } zW Y d}~n
d}~0 0 | jj| j| j|||d dS )at  Send `payload` to the MySQL server.

        NOTE: if `payload` is an instance of `bytearray`, then `payload` might be
        changed by this method - `bytearray` is similar to passing a variable by
        reference.

        If you're sure you won't read `payload` after invoking `send()`,
        then you can use `bytearray.` Otherwise, you must use `bytes`.
        N)r(   r)   )r~   r%   r   floatr   r   r+   r&   )r*   r'   r(   r)   r   r^   r    r    r!   r+   r  s    zMySQLSocket.send)read_timeoutr   c              
   C   sd   z,| j s*| jdur*| j|r$t|nd W n$ tyP } zW Y d}~n
d}~0 0 | j| j| jS )z.Get packet from the MySQL server comm channel.N)r~   r%   r   r   r   r   r-   r&   )r*   r   r^   r    r    r!   r-     s    zMySQLSocket.recvc                 C   s   dS )zOpen the socket.Nr    r=   r    r    r!   open_connection  s    zMySQLSocket.open_connectionc                 C   s   dS )zGet the location of the socket.Nr    r=   r    r    r!   r&     s    zMySQLSocket.address)NNNFFNN)NNN)N)r.   r/   r0   r1   r>   r   r   r   r   r   r4   r   r   r   r   boolr   r   r3   r+   r5   r-   r   r   propertyr&   r    r    r    r!   r}     sR   
&       

e    r}   c                       s\   e Zd ZdZdedd fddZeeddd	Zddd
dZe	e	ddddZ
  ZS )MySQLUnixSocketzpMySQL socket class using UNIX sockets.

    Opens a connection through the UNIX socket of the MySQL Server.
    /tmp/mysql.sockN)unix_socketr   c                    s   t    || _|| _d S r   )rf   r>   r   _address)r*   r   ri   r    r!   r>     s    
zMySQLUnixSocket.__init__r8   c                 C   s   | j S r   r   r=   r    r    r!   r&     s    zMySQLUnixSocket.addressc              
   C   s   z2t  t jt j| _| j| j | j| j W n t jt	fyt } z$t
d| jt|fd|W Y d }~ntd }~0  ty } z$td| jt|fd|W Y d }~n:d }~0  ty } ztt||W Y d }~n
d }~0 0 d S )Ni  rG   )r2   AF_UNIXSOCK_STREAMr%   r   r~   connectr   rJ   rK   r   r&   r"   rL   r   	Exceptionr   )r*   r   r    r    r!   r     s0    zMySQLUnixSocket.open_connection)argskwargsr   c                 O   s   t dt dS )zSwitch the socket to use SSL.z2SSL is disabled when using unix socket connectionsN)warningswarnWarning)r*   r   r   r    r    r!   r     s    zMySQLUnixSocket.switch_to_ssl)r   )r.   r/   r0   r1   r   r>   r   r&   r   r   r   r|   r    r    ri   r!   r     s   r   c                       sN   e Zd ZdZdeeedd fddZeed	d
dZ	dd	ddZ
  ZS )MySQLTCPSocketzYMySQL socket class using TCP/IP.

    Opens a TCP/IP connection to the MySQL Server.
    	127.0.0.1  FN)r   port
force_ipv6r   c                    s6   t    || _|| _|| _d| _| d| | _d S )Nr   r   )rf   r>   r   server_portr   _familyr   )r*   r   r   r   ri   r    r!   r>     s    
zMySQLTCPSocket.__init__r8   c                 C   s   | j S r   r   r=   r    r    r!   r&     s    zMySQLTCPSocket.addressc           	   
   C   s  d}zt | j| jdt jt j}|D ]6}| jrD|d t jkrD|} q\|d t jkr$|} q\q$| jr~|d du r~t	d| j |d du r|d }W n@ t
y } z(t	d| j| jt|fd|W Y d}~n
d}~0 0 |\| _}}}}z0t  | j||| _| j| j | j| W n t jtfy^ } z(td| j| jt|fd|W Y d}~n|d}~0  t
y } z(t	d| j| jt|fd|W Y d}~n<d}~0  ty } zt	t||W Y d}~n
d}~0 0 dS )z/Open the TCP/IP connection to the MySQL server.)NNNNNr   NzNo IPv6 address found for i  rG   )r2   getaddrinfor   r   r   SOL_TCPr   AF_INET6AF_INETr   rL   r"   r   r%   r   r~   r   rJ   rK   r   r   r   )	r*   ZaddrinfoZ	addrinfosinfor   socktypeprotor^   Zsockaddrr    r    r!   r     sh    
zMySQLTCPSocket.open_connection)r   r   F)r.   r/   r0   r1   r   r4   r   r>   r   r&   r   r|   r    r    ri   r!   r     s      r   )0r1   r2   r[   r   ro   abcr   r   collectionsr   typingr   r   r   r   r	   r
   r   PROTOCOL_TLSv1PROTOCOL_TLSv1_1PROTOCOL_TLSv1_2PROTOCOL_TLSr   hasattrr   ZTLS_V1_3_SUPPORTEDImportErrorerrorsr   r   r   r   r   r   r   rt   rY   rb   rx   rL   r   r"   r#   r6   re   r}   r   r   r    r    r    r!   <module>   s@    
$
Ge C j1