U
    dd/                     @   s  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m	Z	m
Z
mZmZmZmZmZmZ ddlmZmZmZmZ ddlmZmZ ddlmZmZmZmZ ed	Zeeeef d
f Z ee d
f Z!G dd deZ"eddG dd deZ#eddG dd dee# Z$dS )    N)	dataclass)wraps)	AnyCallableDictListMappingOptionalTupleTypeVarUnion   )BrokenResourceErrorEndOfStreamaclose_forcefullyget_cancelled_exc_class)TypedAttributeSettyped_attribute)AnyByteStream
ByteStreamListener	TaskGroupT_Retval.c                   @   s   e Zd ZU dZe Zee ed< e Z	e
ed< e Zeeeef ed< e Zeeeeeeef f  ed< e Zee
 ed< e Zeed< e Zeeeeef  ed< e Zejed	< e Zeed
< e Zeed< dS )TLSAttributez5Contains Transport Layer Security related attributes.alpn_protocolchannel_binding_tls_uniquecipherpeer_certificatepeer_certificate_binaryserver_sideshared_ciphers
ssl_objectstandard_compatibletls_versionN)__name__
__module____qualname____doc__r   r   r	   str__annotations__r   bytesr   r
   intr   r   r   _PCTRTTT_PCTRTTr   r   boolr    r   r!   ssl	SSLObjectr"   r#    r1   r1   5/tmp/pip-unpacked-wheel-yaxr6kle/anyio/streams/tls.pyr      s   
r   F)eqc                	   @   s  e Zd ZU dZeed< eed< ejed< ej	ed< ej	ed< e
ddddd	eee ee eej ed d
ddZedef eedddZeeef dddZddddZd!eedddZeddddZddddZeeeeg ef f ddd ZdS )"	TLSStreama  
    A stream wrapper that encrypts all sent data and decrypts received data.

    This class has no public initializer; use :meth:`wrap` instead.
    All extra attributes from :class:`~TLSAttribute` are supported.

    :var AnyByteStream transport_stream: the wrapped stream

    transport_streamr"   _ssl_object	_read_bio
_write_bioNT)r   hostnamessl_contextr"   )r5   r   r9   r:   r"   returnc                   s   |dkr| }|sJ|rt jjnt jj}t |}tt drJ| jt jN  _t  }t  }|j	||||d}	| |||	||d}
|

|	jI dH  |
S )a  
        Wrap an existing stream with Transport Layer Security.

        This performs a TLS handshake with the peer.

        :param transport_stream: a bytes-transporting stream to wrap
        :param server_side: ``True`` if this is the server side of the connection, ``False`` if
            this is the client side (if omitted, will be set to ``False`` if ``hostname`` has been
            provided, ``False`` otherwise). Used only to create a default context when an explicit
            context has not been provided.
        :param hostname: host name of the peer (if host name checking is desired)
        :param ssl_context: the SSLContext object to use (if not provided, a secure default will be
            created)
        :param standard_compatible: if ``False``, skip the closing handshake when closing the
            connection, and don't raise an exception if the peer does the same
        :raises ~ssl.SSLError: if the TLS handshake fails

        NOP_IGNORE_UNEXPECTED_EOF)r   server_hostname)r5   r"   r6   r7   r8   )r/   PurposeCLIENT_AUTHSERVER_AUTHcreate_default_contexthasattroptionsr<   	MemoryBIOwrap_bio_call_sslobject_methoddo_handshake)clsr5   r   r9   r:   r"   purposeZbio_inZbio_outr!   wrapperr1   r1   r2   wrapE   s2    

   zTLSStream.wrap.)funcargsr;   c                    s  z|| }W n t jk
r   z4| jjrB| j| j I d H  | j I d H }W nX tk
rr   | j	
  Y nH tk
r } z| j	
  | j
  t|W 5 d }~X Y nX | j	| Y q  t jk
r   | j| j I d H  Y q  t jk
r( } z| j	
  | j
  t|W 5 d }~X Y q  t jk
r } zJ| j	
  | j
  t|t jsjd|jkr| jrzt|ntd  W 5 d }~X Y q X | jjr| j| j I d H  |S q d S )NZUNEXPECTED_EOF_WHILE_READING)r/   SSLWantReadErrorr8   pendingr5   sendreadreceiver   r7   	write_eofOSErrorr   writeSSLWantWriteErrorSSLSyscallErrorSSLError
isinstanceSSLEOFErrorstrerrorr"   )selfrL   rM   resultdataexcr1   r1   r2   rF   }   sD    







z TLSStream._call_sslobject_methodr;   c                    s8   |  | jjI dH  | j  | j  | j| j fS )z
        Does the TLS closing handshake.

        :return: a tuple of (wrapped byte stream, bytes left in the read buffer)

        N)rF   r6   unwrapr7   rS   r8   r5   rQ   r\   r1   r1   r2   ra      s    

zTLSStream.unwrapc                    sT   | j r@z|  I d H  W n& tk
r>   t| jI d H   Y nX | j I d H  d S N)r"   ra   BaseExceptionr   r5   acloserb   r1   r1   r2   re      s    zTLSStream.aclose   )	max_bytesr;   c                    s"   |  | jj|I d H }|st|S rc   )rF   r6   rQ   r   )r\   rg   r^   r1   r1   r2   rR      s    zTLSStream.receive)itemr;   c                    s   |  | jj|I d H  d S rc   )rF   r6   rU   )r\   rh   r1   r1   r2   rP      s    zTLSStream.sendc                    sd   |  tj}td|}|rXt|dt|dp6d }}||fdk rXtd| tdd S )NzTLSv(\d+)(?:\.(\d+))?   r   r   )ri      z;send_eof() requires at least TLSv1.3; current session uses z7send_eof() has not yet been implemented for TLS streams)extrar   r#   rematchr+   groupNotImplementedError)r\   r#   rm   majorminorr1   r1   r2   send_eof   s    "zTLSStream.send_eofc                    s    j jtj jjtj jjtj jjtj	 fddtj
 fddtj fddtj fddtj fddtj fddtj jji
S )Nc                      s    j dS )NFr6   getpeercertr1   rb   r1   r2   <lambda>       z,TLSStream.extra_attributes.<locals>.<lambda>c                      s    j dS )NTrs   r1   rb   r1   r2   ru      s   c                      s    j jS rc   )r6   r   r1   rb   r1   r2   ru      rv   c                      s
    j  S rc   )r6   r    r1   rb   r1   r2   ru      rv   c                      s    j S rc   r"   r1   rb   r1   r2   ru      rv   c                      s    j S rc   )r6   r1   rb   r1   r2   ru      rv   )r5   extra_attributesr   r   r6   selected_alpn_protocolr   get_channel_bindingr   r   r   r   r    r"   r!   r#   versionrb   r1   rb   r2   rx      s,        
 
 
 
 
 
 zTLSStream.extra_attributes)rf   )r$   r%   r&   r'   r   r)   r.   r/   r0   rD   classmethodr	   r(   
SSLContextrK   r   r   objectrF   r
   r*   ra   re   r+   rR   rP   rr   propertyr   r   rx   r1   r1   r1   r2   r4   3   s<   




8
 /
r4   c                   @   s   e Zd ZU dZee ed< ejed< dZ	e
ed< dZeed< eeedd	d
dZdeegef ee ddddZddddZeeeeg ef f dddZdS )TLSListenera  
    A convenience listener that wraps another listener and auto-negotiates a TLS session on every
    accepted connection.

    If the TLS handshake times out or raises an exception, :meth:`handle_handshake_error` is
    called to do whatever post-mortem processing is deemed necessary.

    Supports only the :attr:`~TLSAttribute.standard_compatible` extra attribute.

    :param Listener listener: the listener to wrap
    :param ssl_context: the SSL context object
    :param standard_compatible: a flag passed through to :meth:`TLSStream.wrap`
    :param handshake_timeout: time limit for the TLS handshake
        (passed to :func:`~anyio.fail_after`)
    listenerr:   Tr"      handshake_timeoutN)r_   streamr;   c                    sR   dt  d t|I d H  t| t s6tt d t| trLt| t rN d S )Nz
        Handle an exception raised during the TLS handshake.

        This method does 3 things:

        #. Forcefully closes the original stream
        #. Logs the exception (unless it was a cancellation exception) using the ``z``
           logger
        #. Reraises the exception if it was a base exception or a cancellation exception

        :param exc: the exception
        :param stream: the original stream

        zError during TLS handshake)r$   r   rY   r   logging	getLogger	exception	Exception)r_   r   r1   r1   r2   handle_handshake_error  s    z"TLSListener.handle_handshake_error)handler
task_groupr;   c                    s6   t  td d fdd}j||I d H  d S )N)r   r;   c              
      s   ddl m} z4|j  tj| jjdI d H }W 5 Q R X W n4 tk
rt } z|| I d H  W 5 d }~X Y nX  |I d H  d S )Nr   )
fail_after)r:   r"   )	 r   r   r4   rK   r:   r"   rd   r   )r   r   Zwrapped_streamr_   r   r\   r1   r2   handler_wrapper$  s    $z*TLSListener.serve.<locals>.handler_wrapper)r   r   r   serve)r\   r   r   r   r1   r   r2   r     s    zTLSListener.server`   c                    s   | j  I d H  d S rc   )r   re   rb   r1   r1   r2   re   6  s    zTLSListener.aclosec                    s   t j fddiS )Nc                      s    j S rc   rw   r1   rb   r1   r2   ru   <  rv   z.TLSListener.extra_attributes.<locals>.<lambda>)r   r"   rb   r1   rb   r2   rx   9  s     
zTLSListener.extra_attributes)N)r$   r%   r&   r'   r   r   r)   r/   r}   r"   r.   r   floatstaticmethodrd   r   r   r   r4   r	   r   r   re   r   r   rx   r1   r1   r1   r2   r      s    

 r   )%r   rl   r/   Zdataclassesr   	functoolsr   typingr   r   r   r   r   r	   r
   r   r   r   r   r   r   r   Z_core._typedattrr   r   abcr   r   r   r   r   r(   r-   r,   r   r4   r   r1   r1   r1   r2   <module>   s"   , ;