
    "iȭ                        d Z ddlmZmZ ddlmZ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mZ ddlmZ 	 ddlmZ ddlmZmZ dd	lmZ d
Zn# e$ r dZY nw xY w	 ddlZn# e$ r dZY nw xY w	 ddlZddlZddlZn# e$ r	 dZdZdZY nw xY wddlmZ ddlm Z!m"Z#  e	j$        e%          &                     e	j'                                e	j$        e%          Z( G d de)          Z* G d de*          Z+ G d de*          Z, G d de*          Z- G d de*          Z. G d de*          Z/ G d de*          Z0 G d de*          Z1 G d d e*          Z2e
j3        d!k    re2Z0d" Z4dS )#z5Implementing support for MySQL Authentication Plugins    )	b64encode	b64decode)sha1sha256N)quote)uuid4)UnsupportedAlgorithm)hashesserialization)paddingTF   )errors)normalize_unicode_string"validate_normalized_unicode_stringc                   2    e Zd ZdZdZdZ	 	 ddZd Zd ZdS )	BaseAuthPlugina  Base class for authentication plugins


    Classes inheriting from BaseAuthPlugin should implement the method
    prepare_password(). When instantiating, auth_data argument is
    required. The username, password and database are optional. The
    ssl_enabled argument can be used to tell the plugin whether SSL is
    active or not.

    The method auth_response() method is used to retrieve the password
    which was prepared by prepare_password().
    F Nc                 L    || _         || _        || _        || _        || _        dS )InitializationN)
_auth_data	_username	_password	_database_ssl_enabled)self	auth_datausernamepassworddatabasessl_enabledinstances          V/srv/django_bis/venv311/lib/python3.11/site-packages/mysql/connector/authentication.py__init__zBaseAuthPlugin.__init__[   s.     $!!!'    c                     t           )zPrepares and returns password to be send to MySQL

        This method needs to be implemented by classes inheriting from
        this class. It is used by the auth_response() method.

        Raises NotImplementedError.
        )NotImplementedErrorr   s    r"   prepare_passwordzBaseAuthPlugin.prepare_passwordd   s
     "!r$   c                     | j         r4| j        s-t          j        d                    | j                            |                                 S )zReturns the prepared password to send to MySQL

        Raises InterfaceError on errors. For example, when SSL is required
        by not enabled.

        Returns str
        {name} requires SSLname)requires_sslr   r   InterfaceErrorformatplugin_namer(   r'   s    r"   auth_responsezBaseAuthPlugin.auth_responsen   s_      	(T%6 	('(=(D(D% )E )' )' ( ( ($$&&&r$   )NNNFN)	__name__
__module____qualname____doc__r-   r0   r#   r(   r1    r$   r"   r   r   J   sb          LKIM-1( ( ( (" " "' ' ' ' 'r$   r   c                        e Zd ZdZdZdZd ZdS )MySQLNativePasswordAuthPluginzBClass implementing the MySQL Native Password authentication pluginFmysql_native_passwordc                    | j         st          j        d          | j        sdS | j        }t	          | j        t
                    r| j                            d          }n| j        }| j         }d}	 t          |                                          }t          |                                          }t          ||z                                             }d t          ||          D             }t          j        dg|R  }n9# t          $ r,}t          j        d                    |                    d}~ww xY w|S )z;Prepares and returns password as native MySQL 4.1+ password"Missing authentication data (seed)r$   utf-8Nc                     g | ]
\  }}||z  S r6   r6   ).0h1h3s      r"   
<listcomp>zBMySQLNativePasswordAuthPlugin.prepare_password.<locals>.<listcomp>   s     ???"bR"W???r$   20BzFailed scrambling password; {0})r   r   r.   r   
isinstancestrencoder   digestzipstructpack	Exceptionr/   )	r   r   r   hash4hash1hash2hash3xoredexcs	            r"   r(   z.MySQLNativePasswordAuthPlugin.prepare_password   sF    	N'(LMMM~ 	3>dnc** 	&~,,W55HH~HO		?NN))++EKK&&((EU*++2244E??S->->???EK....EE 	? 	? 	?'188==? ? ?	? s   2BD 
D;'D66D;Nr2   r3   r4   r5   r-   r0   r(   r6   r$   r"   r8   r8   |   s3        LLL)K    r$   r8   c                        e Zd ZdZdZdZd ZdS )MySQLClearPasswordAuthPluginzAClass implementing the MySQL Clear Password authentication pluginTmysql_clear_passwordc                     | j         sdS | j         }t          |t                    r|                    d          }|dz   S !Returns password as as clear text    utf8r   rC   rD   rE   r   r   s     r"   r(   z-MySQLClearPasswordAuthPlugin.prepare_password   F    ~ 	7>h$$ 	/v..H'!!r$   NrQ   r6   r$   r"   rS   rS      s3        KKL(K	" 	" 	" 	" 	"r$   rS   c                        e Zd ZdZdZdZd ZdS )MySQLSHA256PasswordAuthPluginzClass implementing the MySQL SHA256 authentication plugin

    Note that encrypting using RSA is not supported since the Python
    Standard Library does not provide this OpenSSL functionality.
    Tsha256_passwordc                     | j         sdS | j         }t          |t                    r|                    d          }|dz   S rV   rZ   r[   s     r"   r(   z.MySQLSHA256PasswordAuthPlugin.prepare_password   r\   r$   NrQ   r6   r$   r"   r^   r^      s9          L#K	" 	" 	" 	" 	"r$   r^   c                   4    e Zd ZdZdZdZdZdZd Zd Z	d Z
d	S )
"MySQLCachingSHA2PasswordAuthPluginzClass implementing the MySQL caching_sha2_password authentication plugin

    Note that encrypting using RSA is not supported since the Python
    Standard Library does not provide this OpenSSL functionality.
    Fcaching_sha2_password      c                 B   | j         st          j        d          | j        sdS t	          | j        t
                    r| j                            d          n| j        }| j         }t          |                                          }t                      }|	                    t          |                                                     |	                    |           |                                }d t          ||          D             }t          j        dg|R  }|S )z Returns a scramble of the password using a Nonce sent by the
        server.

        The scramble is of the form:
        XOR(SHA2(password), SHA2(SHA2(SHA2(password)), Nonce))
        r;   r$   r<   c                     g | ]
\  }}||z  S r6   r6   )r>   r?   h2s      r"   rA   z@MySQLCachingSHA2PasswordAuthPlugin._scramble.<locals>.<listcomp>   s     ;;;Xb"b;;;r$   32B)r   r   r.   r   rC   rD   rE   r   rF   updaterG   rH   rI   )r   r   r   rL   rM   rO   rN   s          r"   	_scramblez,MySQLCachingSHA2PasswordAuthPlugin._scramble   s     	N'(LMMM~ 	3 $.#..C4>((11148N 	O	x  ''))VE]]))++,,,Y;;UE):):;;;E*E***r$   c                     t          | j                  dk    r|                                 S | j        d         | j        k    r|                                 S d S )Nr   r   )lenr   rk   perform_full_authentication_full_authenticationr'   s    r"   r(   z3MySQLCachingSHA2PasswordAuthPlugin.prepare_password   sS    t!##>>###_Q4#CCC,,...tr$   c                     | j         s-t          j        d                    | j                            | j        sdS | j        }t          |t                    r|                    d          }|dz   S )rW   r*   r+   rX   rY   )	r   r   r.   r/   r0   r   rC   rD   rE   r[   s     r"   ro   z7MySQLCachingSHA2PasswordAuthPlugin._full_authentication   s      	('(=(D(D% )E )' )' ( ( ( ~ 	7>h$$ 	/v..H'!!r$   N)r2   r3   r4   r5   r-   r0   rn   fast_auth_successrk   r(   ro   r6   r$   r"   rb   rb      sc         
 L)K"#  6  " " " " "r$   rb   c                       e Zd ZdZg dZdZdZeZdZ	dZ
dZdZdZdZd Zd Zd	 Zd
 Zd Zd Zd Zd ZddZd Zd Zd Zd Zd ZdS )MySQLLdapSaslPasswordAuthPlugina5  Class implementing the MySQL ldap sasl authentication plugin.

    The MySQL's ldap sasl authentication plugin support two authentication
    methods SCRAM-SHA-1 and GSSAPI (using Kerberos). This implementation only
    support SCRAM-SHA-1 and SCRAM-SHA-256.

    SCRAM-SHA-1 amd SCRAM-SHA-256
        This method requires 2 messages from client and 2 responses from
        server.

        The first message from client will be generated by prepare_password(),
        after receive the response from the server, it is required that this
        response is passed back to auth_continue() which will return the
        second message from the client. After send this second message to the
        server, the second server respond needs to be passed to auth_finalize()
        to finish the authentication process.
    )zSCRAM-SHA-1zSCRAM-SHA-256GSSAPIFauthentication_ldap_sasl_clientNr   c                 P    t          d t          ||          D                       S )Nc                     g | ]
\  }}||z  S r6   r6   )r>   b1b2s      r"   rA   z8MySQLLdapSaslPasswordAuthPlugin._xor.<locals>.<listcomp>#  s     @@@&"bb2g@@@r$   )bytesrG   )r   bytes1bytes2s      r"   _xorz$MySQLLdapSaslPasswordAuthPlugin._xor"  s)    @@C,?,?@@@AAAr$   c                 `    t          j        ||| j                  }|                                S N)hmacnewdef_digest_moderF   )r   r   saltdigest_makers       r"   _hmacz%MySQLLdapSaslPasswordAuthPlugin._hmac%  s*    x$0DEE""$$$r$   c                     |                                 }|                     ||dz             }|}t          |dz
            D ].}|                     ||          }|                     ||          }/|S )zPrepares Hi
        Hi(password, salt, iterations) where Hi(p,s,i) is defined as
        PBKDF2 (HMAC, p, s, i, output length of H).

        s      r   )rE   r   ranger}   )r   r   r   countpwhiaux_s           r"   _hiz#MySQLLdapSaslPasswordAuthPlugin._hi)  sy     __ZZD#6677uqy!! 	$ 	$A**R%%C2s##BB	r$   c                     t          |          }t          |          }|'t          j        d                    |                    |S )Nzbroken_rule: {})	norm_ustr
valid_normr   r.   r/   )r   stringnorm_strbroken_rulecharrules         r"   
_normalizez*MySQLLdapSaslPasswordAuthPlugin._normalize7  sI    V$$ **"'(9(@(@(M(MNNN
 r$   c                 .   d}t          t                                                    dd          | _        |                    |                     | j                  | j                  }t          |t                     r|                    d          }|S )aq  This method generates the first message to the server to start the

        The client-first message consists of a gs2-header,
        the desired username, and a randomly generated client nonce cnonce.

        The first message from the server has the form:
            b'n,a=<user_name>,n=<user_name>,r=<client_nonce>

        Returns client's first message
        z.n,a={user_name},n={user_name},r={client_nonce}-r   )	user_nameclient_noncerY   )	rD   r   replacer   r/   r   r   rC   rE   )r   
cfm_fprnatcfms      r"   _first_messagez.MySQLLdapSaslPasswordAuthPlugin._first_messageB  s     F
LL00b99$//$.*I*I-1->   @ @ c3 	%**V$$C
r$   c                 >   t                               d| j                   t          j        j                            | j                            d          t          j        j	                  }	 t          j
                    }t                               d           	 |j         nx# t          j        j        j        $ r\}t                               d|           |                    |           t!          j        d                    |                    d}~ww xY wn1# t          j        j        j        $ r}| j        sBt                               d|           t!          j        d	                    |                    	 t                               d
           t          j                            || j                            d          d          }|d         }nc# t          j        j        j        $ rG}t                               d|           t!          j        d                    |                    d}~ww xY wY d}~nd}~ww xY wt          j        j        t          j        j        t          j        j        f}| j        r| j        }nd}t                               d|           t          j        |t          j        j                  }|| _         t          j!        ||tE          |          d          | _#        	 | j#        $                                }nc# t          j        j        j        $ rG}t                               d|           t!          j        d                    |                    d}~ww xY wt                               d|           |S )zGet a TGT Authentication request and initiates security context.

        This method will contact the Kerberos KDC in order of obtain a TGT.
        z# user name: %srY   	name_typezE# Stored credentials found, if password was given it will be ignored.z Credentials has expired: %szCredentials has expired: {}Nz* Unable to retrieve stored credentials: %sz/Unable to retrieve stored credentials error: {}z5# Attempt to retrieve credentials with given passwordinitiateusager   z; Unable to retrieve credentials with the given password: %sz:Unable to retrieve credentials with the given password: {}zldap/ldapauthz# service principal: %sr,   credsflagsr   z'Unable to initiate security context: %sz'Unable to initiate security context: {}z# initial client token: %s)%_LOGGERdebugr   gssapirawnamesimport_namerE   NameTypeuserCredentialslifetime
exceptionsExpiredCredentialsErrorwarningacquirer   r.   r/   miscGSSErrorr   erroracquire_cred_with_passwordProgrammingErrorRequirementFlagmutual_authenticationextended_errordelegate_to_peerkrb_service_principalNamekerberos_principaltarget_nameSecurityContextsumctxstep)	r   r   crederracquire_cred_resultflags_lservice_principalservkinitial_client_tokens	            r"   _first_message_krbz2MySQLLdapSaslPasswordAuthPlugin._first_message_krbV  s   
 	'888J$001F1Fv1N1N;A?;O 1 Q Q	
	*%''DMM . / / /W:(@ W W W >DDDY'''+,I,P,PQT,U,UVVVW 
 z' 	* 	* 	*> *JCPPP+ELLSQQS S S*MM #3 4 4 4*0**O*O!4>#8#8#@#@
 +P +T +T'.q1DDz/ * * *MM #1257 7 7 1#VC[[* * ** DDDD	*& )?)8):

 % 	0 $ : //1BCCC-9[\\\ )u0403G0:< < <
	_#'8==??  z' 	_ 	_ 	_MMCSIII'(Q(X(XY\(](]^^^	_ 	24HIII##s}   /-D B% $D %D>ADDD I9A	IAG I I 9AH;;I  IIL M?8AM::M?c                    t                               d|           | j                            |          }t                               d|           t                               d| j        j                   || j        j        fS )a   Continue with the Kerberos TGT service request.

        With the TGT authentication service given response generate a TGT
        service request. This method must be invoked sequentially (in a loop)
        until the security context is completed and an empty response needs to
        be send to acknowledge the server.

        Args:
            tgt_auth_challenge the challenge for the negotiation.

        Returns: tuple (bytearray TGS service request,
                        bool True if context is completed otherwise False).
        tgt_auth challenge: %sz# context step response: %sz# context completed?: %s)r   r   r   r   completer   tgt_auth_challengeresps      r"   auth_continue_krbz1MySQLLdapSaslPasswordAuthPlugin.auth_continue_krb  sm     	.0BCCCx}}/003T:::0$(2CDDDTX&&&r$   c                 0   | j         j        st          j        d          t                              d|           t                              d| j         j                   	 | j                             |          }t                              d|           nc# t          j	        j
        j        $ rG}t                              d|           t          j        d                    |                    d}~ww xY wt                              d|           t          d	          }t                              d
|           | j                             |d          }t                              d|d         t!          |d                              |j        S )aP  Accept handshake and generate closing handshake message for server.

        This method verifies the server authenticity from the given message
        and included signature and generates the closing handshake for the
        server.

        When this method is invoked the security context is already established
        and the client and server can send GSSAPI formated secure messages.

        To finish the authentication handshake the server sends a message
        with the security layer availability and the maximum buffer size.

        Since the connector only uses the GSSAPI authentication mechanism to
        authenticate the user with the server, the server will verify clients
        message signature and terminate the GSSAPI authentication and send two
        messages; an authentication acceptance b'  ' and a
        OK packet (that must be received after sent the returned message from
        this method).

        Args:
            message a wrapped hssapi message from the server.

        Returns: bytearray closing handshake message to be send to the server.
        z"Security context is not completed.z# servers message: %sz# GSSAPI flags in use: %sz# unwraped: %s#Unable to unwrap server message: %s#Unable to unwrap server message: {}Nz# unwrapped server message: %s      z# message response: %sFencryptz*# wrapped message response: %s, length: %dr   )r   r   r   r   r   r   actual_flagsunwrapr   r   r   BadMICErrorr.   r/   	bytearraywraprm   messager   r   unwrapedr   responsewrapeds         r"   auth_accept_close_handshakez;MySQLLdapSaslPasswordAuthPlugin.auth_accept_close_handshake  sm   2 x  	P)*NOOO-w7771483HIII	1xw//HMM*H5555z$0 	1 	1 	1MM?EEE' )$$*F3KK1 1 1	1
 	6AAA
 /00.999x77BQiVAY	1 	1 	1 ~   "5B C81AC33C8c           
         | j                                         }|| _        t                              d|           || j        vrTt          j        d                    |d	                    | j        dd                   | j        d                             d| j         v r/t          st          j        d          |                                 S | j         dk    rt          | _        |                                 S )	zThis method will prepare the fist message to the server.

        Returns bytes to send to the server as the first message.
        z read_method_name_from_server: %szpThe sasl authentication method "{}" requested from the server is not supported. Only "{}" and "{}" are supportedz", "Ns   GSSAPIzwModule gssapi is required for GSSAPI authentication mechanism but was not found. Unable to authenticate with the servers   SCRAM-SHA-256)r   decoder   r   r   sasl_mechanismsr   r.   r/   joinr   r   r   r   r   r   )r   r   auth_mechanisms      r"   r1   z-MySQLLdapSaslPasswordAuthPlugin.auth_response  s   
 //11%:"8.III!555'EEKV"FKK0DSbS0I$J$J(,F. F./ / / '' '-&' ' ' **,,,?...#)D ""$$$r$   c                 	   | j         st          j        d          |                     | j                  }|                     |t          | j                  | j                  }t          
                    dt          |                                                     |                     |d          }t          
                    dt          |                                                     |                     |                                          }t          
                    dt          |                                                     |                     |d          }t          
                    dt          |                                                     d                    d	                    |                     | j                            d
                    | j                  g          }t          
                    d|           d                    || j        d                    t          d                    |                     | j                                                                                                                d
                    | j                  g          }t          
                    d|           |                     ||                                          }t          
                    dt          |                                                     |                     ||          }	t          
                    dt          |	                                                     t          |                     ||                                                                                    | _        t          
                    d| j                   t          d                    |                     | j                                                                                                      }
d                    d                    |
          d
                    | j                  d                    t          |	                                                    g          }t          
                    d|           |                                S )a  This method generates the second message to the server

        Second message consist on the concatenation of the client and the
        server nonce, and cproof.

        c=<n,a=<user_name>>,r=<server_nonce>,p=<client_proof>
        where:
            <client_proof>: xor(<client_key>, <client_signature>)

            <client_key>: hmac(salted_password, b"Client Key")
            <client_signature>: hmac(<stored_key>, <auth_msg>)
            <stored_key>: h(<client_key>)
            <auth_msg>: <client_first_no_header>,<servers_first>,
                        c=<client_header>,r=<server_nonce>
            <client_first_no_header>: n=<username>r=<client_nonce>
        r;   zsalted_password: %ss
   Client Keyzclient_key: %szstored_key: %ss
   Server Keyzserver_key: %s,zn={}zr={}zclient_first_no_header: %szc={}zn,a={},zauth_msg: %szclient_signature: %szclient_proof: %szserver_auth_var: %szp={}zsecond_message: %s)r   r   r.   r   r   r   r   server_salt
iterationsr   r   r   r   r   r   rF   r   r/   r   r   servers_firstrE   server_noncer}   server_auth_var)r   passwsalted_password
client_key
stored_key
server_keyclient_first_no_headerauth_msgclient_signatureclient_proofclient_headermsgs               r"   _second_messagez/MySQLLdapSaslPasswordAuthPlugin._second_message  s   "  	N'(LMMM//((5#,T-=#>#>#'?4 4 	+007799	; 	; 	; ZZ??
&	*(=(=(D(D(F(FGGG))*55<<>>
&	*(=(=(D(D(F(FGGGZZ??
&	*(=(=(D(D(F(FGGG!$MM$//$.99::MM$+,,+. "/ "/ 	24JKKK88"MM)I$4$4//%1 %117; ;;A688E EMM$+,,. / / 	nh///::j(//2C2CDD, 01188::	< 	< 	< yy-=>>()L*A*A*H*H*J*JKKK(JJz8??#4#455 7  77=vxx 	+T-ABBB!T__T^<<==DDFFH HHN 	hhm44d&788i&=&=&D&D&F&FGGI J J 	*C000zz||r$   c                 f   |rt          |t          t          f          s't          j        d                    |                    	 |                                }|| _        |                    d          \  }}}n5# t          $ r( t          j        d                    |                    w xY w|
                    d          r*|
                    d          r|
                    d          s't          j        d                    |                    | j        |v r0|dd         | _        t                              d	| j                   n't          j        d
                    |                    |dd         | _        t                              d| j        t!          | j                             	 |dd         }t                              d                    |                     t#          |          | _        dS #  t          j        d                    |                    xY w)zValidates first message from the server.

        Extracts the server's salt and iterations from the servers 1st response.
        First message from the server is in the form:
            <server_salt>,i=<iterations>
        zUnexpected server message: {}r   zr=zs=zi=z&Incomplete reponse from the server: {}   Nzserver_nonce: %sz<Unable to authenticate response: response not well formed {}zserver_salt: %s length: %sziterations: {}z/Unable to authenticate: iterations not found {})rC   r   rz   r   r.   r/   r   r   split
ValueError
startswithr   r   r   r   r   rm   intr   )r   r   r_server_nonces_salt	i_counters        r"   _validate_first_reponsez7MySQLLdapSaslPasswordAuthPlugin._validate_first_reponseC  s`     	BJ}y%>P$Q$Q 	B' )++16-+@+@B B B	B)0022M!.D0=0C0CC0H0H-NFII 	B 	B 	B' )++16-+@+@B B B	B ((.. 	B  &&	B##D))	B ' )++16-+@+@B B B.. .qrr 2DMM,d.?@@@@' )++16-+@+@B B B "!"":2D4D4+,,	. 	. 	.	N!!""IMM*11)<<===!)nnDOOO	N' )77=vm7L7LN N Ns   4A< <2B.:AH )H0c                 T    |                      |           |                                 S )zwreturn the second message from the client.

        Returns bytes to send to the server as the second message.
        )r
  r   )r   servers_first_responses     r"   auth_continuez-MySQLLdapSaslPasswordAuthPlugin.auth_continuek  s+    
 	$$%;<<<##%%%r$   c                 ,   |r=t          |t                    r(t          |          dk    s|                    d          st	          j        d          |dd                                         }t                              d|           | j	        |k    S )aX  Validates second message from the server.

        The client and the server prove to each other they have the same Auth
        variable.

        The second message from the server consist of the server's proof:
            server_proof = HMAC(<server_key>, <auth_msg>)
            where:
                <server_key>: hmac(<salted_password>, b"Server Key")
                <auth_msg>: <client_first_no_header>,<servers_first>,
                            c=<client_header>,r=<server_nonce>

        Our server_proof must be equal to the Auth variable send on this second
        response.
        r  s   v=z(The server's proof is not well formated.Nzserver auth variable: %s)
rC   r   rm   r  r   r.   r   r   r   r   )r   servers_second
server_vars      r"   _validate_second_reponsez8MySQLLdapSaslPasswordAuthPlugin._validate_second_reponses  s       	TZ	%J%J 	T~!!)B)B5)I)I!'(RSSS#ABB'..00
0*===#z11r$   c                 X    |                      |          st          j        d          dS )zfinalize the authentication process.

        Raises errors.InterfaceError if the ervers_second_response is invalid.

        Returns True in succesfull authentication False otherwise.
        z7Authentication failed: Unable to proof server identity.T)r  r   r.   )r   servers_second_responses     r"   auth_finalizez-MySQLLdapSaslPasswordAuthPlugin.auth_finalize  s?     ,,-DEE 	B' )A B B Btr$   r   )r2   r3   r4   r5   r   r-   r0   r   r   r   client_saltr   r   r   r   r}   r   r   r   r   r   r   r   r1   r   r
  r  r  r  r6   r$   r"   rs   rs     sA        " A@@OL3KOLKK JOB B B% % %  	 	 	  (A$ A$ A$H' ' ',1 1 1f% % % %8B B BH&N &N &NP& & &2 2 2.
 
 
 
 
r$   rs   c                   Z    e Zd ZdZdZdZdZed             Zd Z	d Z
d Zdd	Zd
 Zd ZdS )MySQLKerberosAuthPluginz3Implement the MySQL Kerberos authentication plugin.authentication_kerberos_clientFNc                  0   	 t          j        d          } t          | j                  }|                    d          dk    r|                    dd          \  }}|S # t           j        j        j        $ r}t          j
                    cY d}~S d}~ww xY w)z(Get user from credentials without realm.r   r   @r   r   N)r   r   rD   r,   findr  r   r   r   getpassgetuser)r   r   r   r   s       r"   get_user_from_credentialsz1MySQLKerberosAuthPlugin.get_user_from_credentials  s    	%&Z888Euz??Dyy~~##**S!,,aKz' 	% 	% 	%?$$$$$$$$	%s   AA B8B
BBc                    t                               d           t          j        j                            |                    d          t          j        j                  }	 t          j        	                    || j
                            d          d          }n8# t          j        j        j        $ r}t          j        d|           d}~ww xY w|d         }|S )	z.Acquire credentials through provided password.z8Attempt to acquire credentials through provided passwordr<   r   r   r   z7Unable to acquire credentials with the given password: Nr   )r   r   r   r   r   r   rE   r   r   r   r   r   r   r   r   )r   upnr   r   r   r   s         r"   _acquire_cred_with_passwordz3MySQLKerberosAuthPlugin._acquire_cred_with_password  s    F	
 	
 	
 :#//JJwo* 0 
 

	
55N))'22$ 6     z' 	 	 	)O#OO  	 $A&s   $:B C8CCc                    t          j        d|dd                   d         }|dd         }t          j        d| d|d|                   d         }||d         }t          j        d|dd                   d         }t          j        d| d|dd                   d         }|                                |                                fS aY  Parse authentication data.

        Get the SPN and REALM from the authentication data packet.

        Format:
            SPN string length two bytes <B1> <B2> +
            SPN string +
            UPN realm string length two bytes <B1> <B2> +
            UPN realm string

        Returns:
            tuple: With 'spn' and 'realm'.
        z<HNr  r   <srH   unpackr   r   packetspn_lenspn	realm_lenrealms         r"   _parse_auth_dataz(MySQLKerberosAuthPlugin._parse_auth_data       -fRaRj11!4mNNNNF8G8,<==a@!M$rr
33A6	.)...qrr
;;A>zz||U\\^^++r$   c                     | j         sdS | j         }t          |t                    r|                    d          }|dz   S )z!Return password as as clear text.rX   rY   rZ   r[   s     r"   r(   z(MySQLKerberosAuthPlugin.prepare_password  r\   r$   c                 V   d}d}|rC	 |                      |          \  }}n)# t          j        $ r}t          d|           d}~ww xY w||                                 S | j        r| j         d| nd}t                              d|           t                              d|           t                              d| j                   	 t          j	        d          }t          |j                  }t                              d	           t                              d
|           |                    d          dk    r|                    dd          \  }}	n|}d}	| j        r| j         d| n|}| j        rA| j        |k    r6t                              d           | j        |                     |          }|	r"|	|k    r| j        |                     |          }n# t          j        j        j        $ r@}|r| j        |                     |          }nt'          j        d|           Y d}~n_d}~wt          j        j        j        $ r@}|r| j        |                     |          }nt'          j        d|           Y d}~nd}~ww xY wt          j        j        t          j        j        t          j        j        f}
t          j        |t          j        j                  }|                    t          j        j                   }t          j!        ||tE          |
          d          | _#        	 | j#        $                                }n8# t          j        j        j        $ r}t'          j        d|           d}~ww xY wt                              d|           |S )z'Prepare the fist message to the server.NInvalid authentication data: r  Service Principal: %s	Realm: %sUsername: %sr   r   zCached credentials foundzCached credentials UPN: %sr   r   zBThe user from cached credentials doesn't match with the given userzCredentials has expired: z-Unable to retrieve cached credentials error: r   r   %Unable to initiate security context: Initial client token: %s)%r.  rH   r   InterruptedErrorr(   r   r   r   r   r   rD   r,   r  r  r   r!  r   r   r   r   r.   r   r   r   r   r   r   r   r   r   canonicalizeMechTypekerberosr   r   contextr   )r   r   r+  r-  r   r   r   	creds_upn
creds_usercreds_realmr   r,   cnamer   s                 r"   r1   z%MySQLKerberosAuthPlugin.auth_response  s    	NN!229==
UU< N N N&'Ls'L'LMMMN ;((***-1^E))%)))-s333k5)))ndn555)	&Z888EEJIMM4555MM6	BBB ~~c""b((*3//#q*A*A'
KK&
"15NT^--e---YC ~ B$.J">">!   >- <<SAAE> +u 4 4*88==z$< 	O 	O 	O Ot~188==+,M,M,MNNN  z' 	 	 	 t~188==+ICII   	 "8"1"3

 {o8
 
 
 !!&/":;;-e**	
 
 
	#'<#4#4#6#6  z' 	 	 	'===  	
 	02FGGG##sQ   ! AAADG# #J<6H77J6JJ<M N/NNc                    t                               d|           | j                            |          }t                               d|           t                               d| j        j                   || j        j        fS )!  Continue with the Kerberos TGT service request.

        With the TGT authentication service given response generate a TGT
        service request. This method must be invoked sequentially (in a loop)
        until the security context is completed and an empty response needs to
        be send to acknowledge the server.

        Args:
            tgt_auth_challenge: the challenge for the negotiation.

        Returns:
            tuple (bytearray TGS service request,
            bool True if context is completed otherwise False).
        r   zContext step response: %sContext completed?: %s)r   r   r<  r   r   r   s      r"   r  z%MySQLKerberosAuthPlugin.auth_continueB  so     	.0BCCC|  !34414888.0EFFFT\***r$   c                 0   | j         j        st          j        d          t                              d|           t                              d| j         j                   	 | j                             |          }t                              d|           nc# t          j	        j
        j        $ rG}t                              d|           t          j        d                    |                    d}~ww xY wt                              d|           t          d	          }t                              d
|           | j                             |d          }t                              d|d         t!          |d                              |j        S )a_  Accept handshake and generate closing handshake message for server.

        This method verifies the server authenticity from the given message
        and included signature and generates the closing handshake for the
        server.

        When this method is invoked the security context is already established
        and the client and server can send GSSAPI formated secure messages.

        To finish the authentication handshake the server sends a message
        with the security layer availability and the maximum buffer size.

        Since the connector only uses the GSSAPI authentication mechanism to
        authenticate the user with the server, the server will verify clients
        message signature and terminate the GSSAPI authentication and send two
        messages; an authentication acceptance b'  ' and a
        OK packet (that must be received after sent the returned message from
        this method).

        Args:
            message: a wrapped gssapi message from the server.

        Returns:
            bytearray (closing handshake message to be send to the server).
        z!Security context is not completedzServer message: %szGSSAPI flags in use: %szUnwraped: %sr   r   NzUnwrapped server message: %sr   zMessage response: %sFr   z(Wrapped message response: %s, length: %dr   )r<  r   r   r   r   r   r   r   r   r   r   r   r.   r/   r   r   rm   r   r   s         r"   r   z3MySQLKerberosAuthPlugin.auth_accept_close_handshakeZ  ss   4 |$ 	O)*MNNN*G444/1JKKK	|**733HMM.(3333z$0 	 	 	MM?EEE'5<<SAA  	 	4h???
 /00,h777""8U";;61Iq	NN	
 	
 	
 ~r   r   )r2   r3   r4   r5   r0   r-   r<  staticmethodr  r!  r.  r(   r1   r  r   r6   r$   r"   r  r    s        ==2KLG	% 	% \	%  4, , ,2	" 	" 	"X$ X$ X$ X$t+ + +06 6 6 6 6r$   r  c                   :    e Zd ZdZdZdZdZd Zd Zd
dZ	dd	Z
dS )MySQL_OCI_AuthPluginz2Implement the MySQL OCI IAM authentication plugin.authentication_oci_clientFNc                     t          |          }|d         |                                d}t          |                              dd                              dd          S )aI  Prepare client's authentication response

        Prepares client's authentication response in JSON format
        Args:
            signature:  server's nonce to be signed by client.
            oci_config: OCI configuration object.

        Returns:
            JSON_STRING {"fingerprint": string, "signature": string}
        fingerprint)rJ  	signature r   '")r   r   reprr   )r   rK  
oci_configsignature_64r1   s        r"   _prepare_auth_responsez+MySQL_OCI_AuthPlugin._prepare_auth_response  sd     !++%m4%,,..
 
 M""**333;;CEEEr$   c                    t           st          j        d          	 t          t          j                            |          d          5 }t          j        |	                                d          }ddd           n# 1 swxY w Y   n?# t          t          t          t          f$ r}t          j        d| d|           d}~ww xY w|S )z+Get the private_key form the given location'Package 'cryptography' is not installedrbN)r   z2An error occurred while reading the API_KEY from "z": )CRYPTOGRAPHY_AVAILABLEr   r   openospath
expanduserr   load_pem_private_keyread	TypeErrorOSErrorr  r	   )r   key_pathkey_fileprivate_keyr   s        r"   _get_private_keyz%MySQL_OCI_AuthPlugin._get_private_key  s%   % 	)9  		bg((22D99 X+@MMOO!                
 7J0DE 	 	 	)X     	
 s;   -B 
)A?3B ?BB BB C(CCDEFAULTc                 z   	 ddl m}m} n"# t          $ r t	          j        d          w xY w|s|j        }g }d d d}	 |                    ||          }|D ]j}	 ||         r0 ||         ||                   s|                    d| d           <# t          $ r"}	|                    d	|            Y d
}	~	cd
}	~	ww xY wnX# |j
        |j        |j        |j        |j        |j        f$ r,}	|                    t!          |	                     Y d
}	~	nd
}	~	ww xY w|rt	          j        d| d| d|           |S )z=Get a valid OCI config from the given configuration file pathr   )configr   zHPackage "oci" (Oracle Cloud Infrastructure Python SDK) is not installed.c                 (    t          |           dk    S )N    )rm   xs    r"   <lambda>z<MySQL_OCI_AuthPlugin._get_valid_oci_config.<locals>.<lambda>  s    c!ffrk r$   c                 z    t           j                            t           j                            |                     S r   )rX  rY  existsrZ  rh  s    r"   rj  z<MySQL_OCI_AuthPlugin._get_valid_oci_config.<locals>.<lambda>  s$    27>>"'2D2DQ2G2G#H#H r$   )rJ  r`  zParameter "z" is invalidzDoes not contain parameter NzInvalid profile z in: "z".  Errors found: )ocire  r   ImportErrorr   r   DEFAULT_LOCATION	from_fileappendKeyErrorConfigFileNotFoundInvalidConfigInvalidKeyFilePathInvalidPrivateKeyMissingPrivateKeyPassphraseProfileNotFoundrD   )
r   oci_pathprofile_namere  r   
error_listreq_keysrP  req_keyr   s
             r"   _get_valid_oci_configz*MySQL_OCI_AuthPlugin._get_valid_oci_config  s   	&......... 	& 	& 	&)%& & &	&  	/.H
11HH
 

	())(LAAJ# O OO!'* O0x0G1DEEO"))*M*M*M*MNNN O O O%%&MG&M&MNNNNNNNNOO )$)(2&
 	( 	( 	( c#hh''''''''	(  	0)/< / /x / /",/ /0 0 0 sJ    * C 8BC 
C B;6C ;C  C )D-"DDc                 :   t           st          j        d          t                              d| j        t          | j                             t                              d|           |                     |          }|                     |d                   }|	                    | j        t          j                    t          j                              }|                     ||          }t                              d|           |                                S )z-Prepare authentication string for the server.rT  zserver nonce: %s, len %dz#OCI configuration file location: %sr`  zauthentication response: %s)rV  r   r   r   r   r   rm   r~  rb  signr   PKCS1v15r
   SHA256rR  rE   )r   ry  rP  ra  rK  r1   s         r"   r1   z"MySQL_OCI_AuthPlugin.auth_response  s    % 	)9   	0os4?';';	= 	= 	=;XFFF//99
++Jz,BCC$$OMOO
 
	 33IzJJ3]CCC##%%%r$   )Nrc  r   )r2   r3   r4   r5   r0   r-   r<  rR  rb  r~  r1   r6   r$   r"   rG  rG    ss        <<-KLGF F F$  &, , , ,\& & & & & &r$   rG  c                   2    e Zd ZdZdZdZdZd ZddZd Z	dS )	MySQLSSPIKerberosAuthPluginzDImplement the MySQL Kerberos authentication plugin with Windows SSPIr  FNc                    t          j        d|dd                   d         }|dd         }t          j        d| d|d|                   d         }||d         }t          j        d|dd                   d         }t          j        d| d|dd                   d         }|                                |                                fS r#  r&  r(  s         r"   r.  z,MySQLSSPIKerberosAuthPlugin._parse_auth_data  r/  r$   c                    t                               d           d}d}|rC	 |                     |          \  }}n)# t          j        $ r}t          d|           d}~ww xY wt                               d|           t                               d|           t                               d| j                   t          t          t          j
        d          t          j        t          j        f}| j        r| j        r| j        || j        f}nd}|}t                               d|           t                               d	|du            t          j        d
||t          |          t          j                  | _        	 d}| j                            |          \  }}	t                               d|           t                               d|	           t                               d| j        j                   |	d         j        }
t                               d| j        j                   n)# t,          $ r}t          j        d|           d}~ww xY wt                               d|
           |
S )z(Prepare the first message to the server.zauth_response for sspiNr2  r3  r4  r5  zKPackage "pywin32" (Python for Win32 (pywin32) extensions) is not installed.ztargetspn: %sz_auth_info is None: %sKerberos)	targetspn	auth_infoscflagsdatarepContext step err: %sContext step out_buf: %srC  r   zpkg_info: %sr6  r7  )r   r   r.  rH   r   r8  r   sspiconsspir   r   ISC_REQ_MUTUAL_AUTHISC_REQ_DELEGATEr   
ClientAuthr   SECURITY_NETWORK_DREP
clientauth	authorizeauthenticatedBufferpkg_inforJ   r.   )r   r   r+  r-  r   r   
_auth_infor  dataout_bufr   s              r"   r1   z)MySQLSSPIKerberosAuthPlugin.auth_response%  sx   ./// 	NN!229==
UU< N N N&'Ls'L'LMMMN 	-s333k5)))ndn555?dl)%& & &
 '$

 > 	dn 	.%@JJJ	oy111.
d0BCCC/)zJJ(EG G G	D?44T::LCMM0#666MM4g>>>MM2DO4QRRR#*1:#4 MM.$/*BCCCC 	 	 	'===  	
 	02FGGG##s.   ; A!
AA!B,H1 1
I;IIc                    t                               d|           | j                            |          \  }}t                               d|           t                               d|           |d         j        }t                               d|           t                               d| j        j                   || j        j        fS )rB  r   r  r  r   zContext step resp: %srC  )r   r   r  r  r  r  )r   r   r   r  r   s        r"   r  z)MySQLSSPIKerberosAuthPlugin.auth_continue\  s     	.0BCCC001CDDW,c2220':::qz -t444.0MNNNT_222r$   r   )
r2   r3   r4   r5   r0   r-   r<  r.  r1   r  r6   r$   r"   r  r    s\        NN2KLG, , ,25$ 5$ 5$ 5$n3 3 3 3 3r$   r  ntc                     t                                           D ]}|j        | k    r|c S t          j        d                    |                     )a.  Return authentication class based on plugin name

    This function returns the class for the authentication plugin plugin_name.
    The returned class is a subclass of BaseAuthPlugin.

    Raises errors.NotSupportedError when plugin_name is not supported.

    Returns subclass of BaseAuthPlugin.
    z,Authentication plugin '{0}' is not supported)r   __subclasses__r0   r   NotSupportedErrorr/   )r0   	authclasss     r"   get_auth_pluginr  |  si     $2244  	 K// 0 
"6==kJJL L Lr$   )5r5   base64r   r   hashlibr   r   r  r   loggingrX  rH   urllib.parser   uuidr   cryptography.exceptionsr	   cryptography.hazmat.primitivesr
   r   )cryptography.hazmat.primitives.asymmetricr   rV  rn  r   r  r  win32apir   r   utilsr   r   r   r   	getLoggerr2   
addHandlerNullHandlerr   objectr   r8   rS   r^   rb   rs   r  rG  r  r,   r  r6   r$   r"   <module>r     s  : < ; ' ' ' ' ' ' ' '                    				             #<<<<<<DDDDDDDDAAAAAA! # # #"#MMMM   FFFKKKNNNOOOO   DGHHH
      F F F F F F F F  (   & &':w':'<'< = = =
'
H
%
%/' /' /' /' /'V /' /' /'d! ! ! ! !N ! ! !H" " " " "> " " "$" " " " "N " " ",:" :" :" :" :" :" :" :"zO O O O On O O Ody y y y yn y y yxo& o& o& o& o&> o& o& o&dp3 p3 p3 p3 p3. p3 p3 p3f 7d??9L L L L Ls5   A AAA A('A(,A9 9BB