U
    W+db                     @   s   d Z ddlZddlZddlmZ ddlmZ G dd dZG dd deZG d	d
 d
eZ	dd Z
e
 ZG dd deZG dd deZdS )z(SASL mechanisms for AMQP authentication.    N)BytesIO)_write_tablec                   @   s$   e Zd ZdZedd Zdd ZdS )SASLzThe base class for all amqp SASL authentication mechanisms.

    You should sub-class this if you're implementing your own authentication.
    c                 C   s   t dS )z2Return a bytes containing the SASL mechanism name.NNotImplementedErrorself r	   -/tmp/pip-unpacked-wheel-xhcdc304/amqp/sasl.py	mechanism   s    zSASL.mechanismc                 C   s   t dS )z@Return the first response to a SASL challenge as a bytes object.Nr   r   
connectionr	   r	   r
   start   s    z
SASL.startN)__name__
__module____qualname____doc__propertyr   r   r	   r	   r	   r
   r   
   s   
r   c                   @   s(   e Zd ZdZdZdd ZdZdd ZdS )	PLAINzbPLAIN SASL authentication mechanism.

    See https://tools.ietf.org/html/rfc4616 for details
    s   PLAINc                 C   s   || | _ | _d S Nusernamepasswordr   r   r   r	   r	   r
   __init__"   s    zPLAIN.__init__r   c                 C   s^   | j d ks| jd krtS t }|d || j d |d || jd | S )N    zutf-8)r   r   NotImplementedr   writeencodegetvaluer   r   Zlogin_responser	   r	   r
   r   *   s    

zPLAIN.startNr   r   r   r   r   r   	__slots__r   r	   r	   r	   r
   r      s
   r   c                   @   s(   e Zd ZdZdZdd ZdZdd ZdS )	AMQPLAINzhAMQPLAIN SASL authentication mechanism.

    This is a non-standard mechanism used by AMQP servers.
    s   AMQPLAINc                 C   s   || | _ | _d S r   r   r   r	   r	   r
   r   =   s    zAMQPLAIN.__init__r   c                 C   sF   | j d ks| jd krtS t }t| j | jd|jg  | dd  S )N)s   LOGINs   PASSWORD   )r   r   r   r   r   r   r   r    r	   r	   r
   r   E   s     zAMQPLAIN.startNr!   r	   r	   r	   r
   r#   5   s
   r#   c                     sZ   zdd l  dd l W n( tk
r<   G dd dt} |  Y S X G  fdddt}|S d S )Nr   c                   @   s&   e Zd ZdZdZd	ddZdd ZdS )
z)_get_gssapi_mechanism.<locals>.FakeGSSAPIz7A no-op SASL mechanism for when gssapi isn't available.N   amqpFc                 S   s   |st dd S )Nz?You need to install the `gssapi` module for GSSAPI SASL supportr   r   client_nameservicerdns	fail_softr	   r	   r
   r   Y   s    z2_get_gssapi_mechanism.<locals>.FakeGSSAPI.__init__c                 S   s   t S r   )r   r   r	   r	   r
   r   `   s    z/_get_gssapi_mechanism.<locals>.FakeGSSAPI.start)Nr%   FFr   r   r   r   r   r   r   r	   r	   r	   r
   
FakeGSSAPIT   s       
r,   c                       s6   e Zd ZdZdZdddZdZd	d
 Z fddZdS )z%_get_gssapi_mechanism.<locals>.GSSAPIzsGSSAPI SASL authentication mechanism.

            See https://tools.ietf.org/html/rfc4752 for details
            s   GSSAPINr%   Fc                 S   s4   |rt |ts|d}|| _|| _|| _|| _d S )Nascii)
isinstancebytesr   r'   r*   r(   r)   r&   r	   r	   r
   r   l   s    
z._get_gssapi_mechanism.<locals>.GSSAPI.__init__)r'   r*   r(   r)   c                 S   s^   |j j}| jr>|jtjtjfkr>| }t|d \}}}n|j j	}t
|tsZ|d}|S )Nr   r-   )	transportsockr)   familysocketAF_INETAF_INET6getpeernamegethostbyaddrhostr.   r/   r   )r   r   r1   Zpeerhostname_r	   r	   r
   get_hostname|   s    

z2_get_gssapi_mechanism.<locals>.GSSAPI.get_hostnamec                    s   z`| j r j | j d}nd }| |} d| j|g jj} j||d}|	d W S   j
jjk
r   | jrt Y S  Y nX d S )N)name   @)r<   creds)r'   ZCredentialsNamer;   joinr(   ZNameTypeZhostbased_serviceZSecurityContextsteprawmiscZGSSErrorr*   r   )r   r   r>   r9   r<   contextgssapir	   r
   r      s     

z+_get_gssapi_mechanism.<locals>.GSSAPI.start)Nr%   FF)	r   r   r   r   r   r   r"   r;   r   r	   rE   r	   r
   GSSAPId   s       
	rG   )rF   Zgssapi.raw.miscImportErrorr   )r,   rG   r	   rE   r
   _get_gssapi_mechanismO   s    
5rI   c                   @   s   e Zd ZdZdZdd ZdS )EXTERNALzEXTERNAL SASL mechanism.

    Enables external authentication, i.e. not handled through this protocol.
    Only passes 'EXTERNAL' as authentication mechanism, but no further
    authentication data.
    s   EXTERNALc                 C   s   dS )N    r	   r   r	   r	   r
   r      s    zEXTERNAL.startN)r   r   r   r   r   r   r	   r	   r	   r
   rJ      s   rJ   c                   @   s$   e Zd ZdZdZdd Zdd ZdS )RAWzA generic custom SASL mechanism.

    This mechanism takes a mechanism name and response to send to the server,
    so can be used for simple custom authentication schemes.
    Nc                 C   s:   t |tstt |tst|| | _| _tdt d S )NznPassing login_method and login_response to Connection is deprecated. Please implement a SASL subclass instead.)r.   r/   AssertionErrorr   responsewarningswarnDeprecationWarning)r   r   rN   r	   r	   r
   r      s    zRAW.__init__c                 C   s   | j S r   )rN   r   r	   r	   r
   r      s    z	RAW.startr+   r	   r	   r	   r
   rL      s   rL   )r   r3   rO   ior   Zamqp.serializationr   r   r   r#   rI   rG   rJ   rL   r	   r	   r	   r
   <module>   s   M