o
    Zh?                     @   s   d Z ddlZddlZddlmZmZmZmZmZm	Z	m
Z
mZ ddlZddlmZ ddlmZ ddlmZ dZd	ZG d
d dZddgZdS )z*Base implementation of 0MQ authentication.    N)Any	AwaitableDictListOptionalSetTupleUnion)_check_version)z85   )load_certificates*s   1.0c                   @   s  e Zd ZU dZded< eed< eed< eeef ed< ded< e	e ed	< e	e ed
< eeeeef f ed< eeee
ef f ed< eed< 			d@ded dedefddZdAddZdAddZdeddfddZdeddfddZ	dBdedeeeef  ddfddZ	 dCded!eeejf ddfd"d#Z	dBded$eddfd%d&Zd'e
defd(d)Z	dBded!ee ddfd*d+Zd,ee
 fd-d.Zded/ed0edeee
f fd1d2Zded3e
deee
f fd4d5Zded6e
deee
f fd7d8Z	9dDd:e
d;e
d<e
d=eddf
d>d?ZdS )EAuthenticatora  Implementation of ZAP authentication for zmq connections.

    This authenticator class does not register with an event loop. As a result,
    you will need to manually call `handle_zap_message`::

        auth = zmq.Authenticator()
        auth.allow("127.0.0.1")
        auth.start()
        while True:
            await auth.handle_zap_msg(auth.zap_socket.recv_multipart())

    Alternatively, you can register `auth.zap_socket` with a poller.

    Since many users will want to run ZAP in a way that does not block the
    main thread, other authentication classes (such as :mod:`zmq.auth.thread`)
    are provided.

    Note:

    - libzmq provides four levels of security: default NULL (which the Authenticator does
      not see), and authenticated NULL, PLAIN, CURVE, and GSSAPI, which the Authenticator can see.
    - until you add policies, all incoming NULL connections are allowed.
      (classic ZeroMQ behavior), and all PLAIN and CURVE connections are denied.
    - GSSAPI requires no configuration.
    zzmq.Contextcontextencoding	allow_anycredentials_providersz
zmq.Socket
zap_socket_allowed_denied	passwordscertslogNutf-8c                 C   sb   t dd |ptj | _|| _d| _i | _d | _t	 | _
t	 | _i | _i | _|p-td| _d S )N)   r   securityFzzmq.auth)r
   zmqContextinstancer   r   r   r   r   setr   r   r   r   logging	getLoggerr   )selfr   r   r    r$   D/var/www/html/lang_env/lib/python3.10/site-packages/zmq/auth/base.py__init__:   s   
zAuthenticator.__init__returnc                 C   s:   | j jtjtjd| _d| j_| jd | j	d dS )zCreate and bind the ZAP socket)Zsocket_classr   zinproc://zeromq.zap.01ZStartingN)
r   socketr   ZREPZSocketr   Zlingerbindr   debugr#   r$   r$   r%   startP   s   zAuthenticator.startc                 C   s   | j r| j   d| _ dS )zClose the ZAP socketN)r   closer+   r$   r$   r%   stopW   s   

zAuthenticator.stop	addressesc                 G   2   | j rtd| jdd| | j| dS )a6  Allow IP address(es).

        Connections from addresses not explicitly allowed will be rejected.

        - For NULL, all clients from this address will be accepted.
        - For real auth setups, they will be allowed to continue with authentication.

        allow is mutually exclusive with deny.
        z Only use allow or deny, not bothzAllowing %s,N)r   
ValueErrorr   r*   joinr   updater#   r/   r$   r$   r%   allow]   s   
zAuthenticator.allowc                 G   r0   )zDeny IP address(es).

        Addresses not explicitly denied will be allowed to continue with authentication.

        deny is mutually exclusive with allow.
        z"Only use a allow or deny, not bothz
Denying %sr1   N)r   r2   r   r*   r3   r   r4   r5   r$   r$   r%   denyl   s   zAuthenticator.denyr   domainc                 C   s    |r|| j |< | jd| dS )zConfigure PLAIN authentication for a given domain.

        PLAIN authentication uses a plain-text password file.
        To cover all domains, use "*".
        You can modify the password file at any time; it is reloaded automatically.
        zConfigure plain: %sNr   r   r*   )r#   r8   r   r$   r$   r%   configure_plainx   s   	
zAuthenticator.configure_plain.locationc              
   C   st   | j d|| |tkrd| _dS d| _z
t|| j|< W dS  ty9 } z| j d|| W Y d}~dS d}~ww )a	  Configure CURVE authentication for a given domain.

        CURVE authentication uses a directory that holds all public client certificates,
        i.e. their public keys.

        To cover all domains, use "*".

        You can add and remove certificates in that directory at any time. configure_curve must be called
        every time certificates are added or removed, in order to update the Authenticator's state

        To allow all client keys without checking, specify CURVE_ALLOW_ANY for the location.
        zConfigure curve: %s[%s]TFz&Failed to load CURVE certs from %s: %sN)r   r*   CURVE_ALLOW_ANYr   r   r   	Exceptionerror)r#   r8   r<   er$   r$   r%   configure_curve   s   
zAuthenticator.configure_curvecredentials_providerc                 C   s.   d| _ |dur|| j|< dS | jd| dS )a  Configure CURVE authentication for a given domain.

        CURVE authentication using a callback function validating
        the client public key according to a custom mechanism, e.g. checking the
        key against records in a db. credentials_provider is an object of a class which
        implements a callback method accepting two parameters (domain and key), e.g.::

            class CredentialsProvider(object):

                def __init__(self):
                    ...e.g. db connection

                def callback(self, domain, key):
                    valid = ...lookup key and/or domain in db
                    if valid:
                        logging.info('Authorizing: {0}, {1}'.format(domain, key))
                        return True
                    else:
                        logging.warning('NOT Authorizing: {0}, {1}'.format(domain, key))
                        return False

        To cover all domains, use "*".
        FNz0None credentials_provider provided for domain:%s)r   r   r   r?   )r#   r8   rB   r$   r$   r%   configure_curve_callback   s   z&Authenticator.configure_curve_callbackclient_public_keyc                 C   s   t |dS )a  Return the User-Id corresponding to a CURVE client's public key

        Default implementation uses the z85-encoding of the public key.

        Override to define a custom mapping of public key : user-id

        This is only called on successful authentication.

        Parameters
        ----------
        client_public_key: bytes
            The client public key used for the given message

        Returns
        -------
        user_id: unicode
            The user ID as text
        ascii)r   encodedecode)r#   rD   r$   r$   r%   curve_user_id   s   zAuthenticator.curve_user_idc                 C   s   dS )z~Configure GSSAPI authentication

        Currently this is a no-op because there is nothing to configure with GSSAPI.
        Nr$   )r#   r8   r<   r$   r$   r%   configure_gssapi   s    zAuthenticator.configure_gssapimsgc              	      s  t |dk r' jd| t |dk r jd dS  |d dd dS |dd \}}}}}}|dd }| jd	}| jd	}|tkr[ jd
|  |dd dS  jd|||||| d}	d}
d} jr| jv rd}	 jd| n)d}
d} jd| n j	r| j	v rd}
d} jd| n	d}	 jd| d}|
sL|dkr|	s jd d}	n|dkrt |dkrֈ jd|  |dd dS  fdd|D \}} 
|||\}	}na|dkrt |dkr jd|  |dd dS |d  } ||I dH \}	}|	r |}n-|d!krLt |dkr; jd"|  |dd dS |d  }|d#} ||\}	}|	rY |d$d%| dS  |d| dS )&zPerform ZAP authentication   z*Invalid ZAP message, not enough frames: %r   zNot enough information to replyr   s   400s   Not enough framesNreplacezInvalid ZAP version: %rs   Invalid versionzQversion: %r, request_id: %r, domain: %r, address: %r, identity: %r, mechanism: %rFs	   NO ACCESSTzPASSED (allowed) address=%ss   Address not allowedzDENIED (not allowed) address=%ss   Address deniedzDENIED (denied) address=%szPASSED (not denied) address=%s	anonymouss   NULLzALLOWED (NULL)s   PLAINzInvalid PLAIN credentials: %rs   Invalid credentialsc                 3   s    | ]
}|  jd V  qdS )rM   N)rG   r   ).0cr+   r$   r%   	<genexpr>$  s    
z3Authenticator.handle_zap_message.<locals>.<genexpr>s   CURVEzInvalid CURVE credentials: %rr   s   GSSAPIzInvalid GSSAPI credentials: %rutf8   200   OK)lenr   r?   _send_zap_replyrG   r   VERSIONr*   r   r   _authenticate_plain_authenticate_curverH   _authenticate_gssapi)r#   rJ   version
request_idr8   addressidentityZ	mechanismcredentialsallowedZdeniedreasonusernamepasswordkey	principalr$   r+   r%   handle_zap_message   s   







z Authenticator.handle_zap_messagerb   rc   c                 C   s   d}d}| j rE|sd}|| j v r)|| j | v r&|| j | | kr#d}nd}nd}nd}|r:| jd||| ||fS | jd	| ||fS d
}| jd| ||fS )zPLAIN ZAP authenticationF    r   Ts   Invalid passwords   Invalid usernames   Invalid domainz1ALLOWED (PLAIN) domain=%s username=%s password=%sz	DENIED %ss   No passwords definedzDENIED (PLAIN) %sr9   )r#   r8   rb   rc   r`   ra   r$   r$   r%   rX   C  s2   
z!Authenticator._authenticate_plain
client_keyc                    s(  d}d}| j rd}d}| jd ||fS | ji kr^|sd}|| jv rXt|}| j| ||}t|tr<|I dH }|rCd}d}nd}|rId	nd
}| jd||| ||fS d}||fS |sbd}|| j	v rt|}| j	| 
|ryd}d}nd}|rd	nd
}| jd||| ||fS d}||fS )zCURVE ZAP authenticationFrg   TrT   z ALLOWED (CURVE allow any client)r   Ns   Unknown keyZALLOWEDZDENIEDz0%s (CURVE auth_callback) domain=%s client_key=%ss   Unknown domainz"%s (CURVE) domain=%s client_key=%s)r   r   r*   r   r   rF   callback
isinstancer   r   get)r#   r8   rh   r`   ra   Zz85_client_keyrstatusr$   r$   r%   rY   i  s`   3




 

	z!Authenticator._authenticate_curvere   c                 C   s   | j d|| dS )zPNothing to do for GSSAPI, which has already been handled by an external service.z'ALLOWED (GSSAPI) domain=%s principal=%s)TrT   )r   r*   )r#   r8   re   r$   r$   r%   rZ     s   z"Authenticator._authenticate_gssapirN   r\   status_codestatus_textuser_idc                 C   s\   |dkr|nd}t |tr|| jd}d}| jd|| t|||||g}| j| dS )z.Send a ZAP reply to finish the authentication.rS   rg   rM   zZAP reply code=%s text=%sN)	rj   strrF   r   r   r*   rW   r   Zsend_multipart)r#   r\   rn   ro   rp   metadataZreplyr$   r$   r%   rV     s   
zAuthenticator._send_zap_reply)Nr   N)r'   N)r   N)r   r;   )rN   ) __name__
__module____qualname____doc____annotations__rq   boolr   r   r   bytesr   r&   r,   r.   r6   r7   r:   r	   osPathLikerA   rC   rH   rI   r   rf   r   rX   rY   rZ   rV   r$   r$   r$   r%   r      s   
 





"
d

&

>
r   r=   )rv   r!   rz   typingr   r   r   r   r   r   r   r	   r   Z	zmq.errorr
   Z	zmq.utilsr   r   r   r=   rW   r   __all__r$   r$   r$   r%   <module>   s    (   ,