
    Df3                     t   d 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 	 ej	        Z
n# e$ r
 ej        Z
Y nw xY wn# e$ r dZY nw xY wddlmZ ddlmZmZ dd	lmZmZ  G d
 d          Z G d dee          Z G d dee          Z G d d          Z G d de          Z G d de          ZdS )a  
A library for integrating :doc:`pyOpenSSL <pyopenssl:index>` with Cheroot.

The :py:mod:`OpenSSL <pyopenssl:OpenSSL>` module must be importable
for SSL/TLS/HTTPS functionality.
You can obtain it from `here <https://github.com/pyca/pyopenssl>`_.

To use this module, set :py:attr:`HTTPServer.ssl_adapter
<cheroot.server.HTTPServer.ssl_adapter>` to an instance of
:py:class:`ssl.Adapter <cheroot.ssl.Adapter>`.
There are two ways to use :abbr:`TLS (Transport-Level Security)`:

Method One
----------

 * :py:attr:`ssl_adapter.context
   <cheroot.ssl.pyopenssl.pyOpenSSLAdapter.context>`: an instance of
   :py:class:`SSL.Context <pyopenssl:OpenSSL.SSL.Context>`.

If this is not None, it is assumed to be an :py:class:`SSL.Context
<pyopenssl:OpenSSL.SSL.Context>` instance, and will be passed to
:py:class:`SSL.Connection <pyopenssl:OpenSSL.SSL.Connection>` on bind().
The developer is responsible for forming a valid :py:class:`Context
<pyopenssl:OpenSSL.SSL.Context>` object. This
approach is to be preferred for more flexibility, e.g. if the cert and
key are streams instead of files, or need decryption, or
:py:data:`SSL.SSLv3_METHOD <pyopenssl:OpenSSL.SSL.SSLv3_METHOD>`
is desired instead of the default :py:data:`SSL.SSLv23_METHOD
<pyopenssl:OpenSSL.SSL.SSLv3_METHOD>`, etc. Consult
the :doc:`pyOpenSSL <pyopenssl:api/ssl>` documentation for
complete options.

Method Two (shortcut)
---------------------

 * :py:attr:`ssl_adapter.certificate
   <cheroot.ssl.pyopenssl.pyOpenSSLAdapter.certificate>`: the file name
   of the server's TLS certificate.
 * :py:attr:`ssl_adapter.private_key
   <cheroot.ssl.pyopenssl.pyOpenSSLAdapter.private_key>`: the file name
   of the server's private key file.

Both are :py:data:`None` by default. If :py:attr:`ssl_adapter.context
<cheroot.ssl.pyopenssl.pyOpenSSLAdapter.context>` is :py:data:`None`,
but ``.private_key`` and ``.certificate`` are both given and valid, they
will be read, and the context will be automatically created from them.

.. spelling::

   pyopenssl
    N)SSL)crypto   )Adapter   )errorsserver)StreamReaderStreamWriterc                   P     e Zd ZdZdZdZd Z fdZd
 fd	Z fdZ	 fd	Z
 xZS )SSLFileobjectMixinz#Base mixin for a TLS socket stream.   g{Gz?c                 
   t          j                     }	 	  ||i |S # t          j        $ r t          j        | j                   Y nt          j        $ r t          j        | j                   Y nt          j        $ rO}|r|j        dk    rY d}~dS |j        d         }|r|t          j	        v rY d}~dS t          j        |          d}~wt          j        $ rq}|r|j        dk    rY d}~dS d}	 |j        d         d         d         }n# t          $ r Y nw xY w|dk    rt          j                    t          j        |j         d}~ww xY wt          j                     |z
  | j        k    rt          j        d          p)	zWrap the given call with TLS error-trapping.

        is_reader: if False EOF errors will be raised. If True, EOF errors
        will return "" (to emulate normal sockets).
        T)zUnexpected EOFN    r   r   zhttp requestz	timed out)timer   WantReadErrorsleep	ssl_retryWantWriteErrorSysCallErrorargsr   socket_errors_to_ignoresocketerrorError
IndexError
NoSSLErrorFatalSSLAlertssl_timeouttimeout)	self	is_readercallr   kwargsstarteerrnumthirdargs	            D/var/www/media/lib/python3.11/site-packages/cheroot/ssl/pyopenssl.py
_safe_callzSSLFileobjectMixin._safe_callR   s    	%	2!4tT,V,,,$ + + + 
4>*****% + + +
4>*****# + + + +A!A!A33333 6+I!I!I33333l6***9 4 4 4 +A!A!A33333 vay|AHH!   D ~-- +---*AF334  y{{U"T%555n[111K%	2sc    (E	'E2E C
C
6C

EE/E2DE
DED/EEc                 b    |                      dt          t          |           j        |          S )z*Receive message of a size from the socket.T)r+   superr   recvr"   size	__class__s     r*   r.   zSSLFileobjectMixin.recv   s0    $d++0
 
 	
r   r   c                 b    |                      dt          t          |           j        |          S )zReceive message of a size from the socket.

        Matches the following interface:
        https://docs.python.org/3/library/io.html#io.IOBase.readline
        T)r+   r-   r   readliner/   s     r*   r3   zSSLFileobjectMixin.readline   s2     $d++4
 
 	
r   c                 X     | j         dt          t          |           j        g|R i |S )z!Send whole message to the socket.F)r+   r-   r   sendallr"   r   r%   r1   s      r*   r5   zSSLFileobjectMixin.sendall   sK    t$d++3
 
 
 
 
 
 	
r   c                 X     | j         dt          t          |           j        g|R i |S )z(Send some part of message to the socket.F)r+   r-   r   sendr6   s      r*   r8   zSSLFileobjectMixin.send   sK    t$d++0
 
 
 
 
 
 	
r   )r   )__name__
__module____qualname____doc__r    r   r+   r.   r3   r5   r8   __classcell__r1   s   @r*   r   r   K   s        --KI,2 ,2 ,2\
 
 
 
 


 

 

 

 

 


 
 
 
 

 
 
 
 
 
 
 
 
r   r   c                       e Zd ZdZdS )SSLFileobjectStreamReader,SSL file object attached to a socket object.Nr9   r:   r;   r<    r   r*   r@   r@              6666r   r@   c                       e Zd ZdZdS )SSLFileobjectStreamWriterrA   NrB   rC   r   r*   rF   rF      rD   r   rF   c                       e Zd ZdZd ZdS )SSLConnectionProxyMetaz2Metaclass for generating a bunch of proxy methods.c                    
 d}d
d}
fd}|D ]} ||          ||<   |||         _         d }|D ]}	 ||	          ||	<   t          |||          S )z.Attach a list of proxy methods to a new class.)"get_contextpendingr8   writer.   readrenegotiatebindlistenconnectacceptsetblockingfilenocloseget_cipher_listgetpeernamegetsockname
getsockopt
setsockoptmakefileget_app_dataset_app_datastate_stringsock_shutdownget_peer_certificate	want_read
want_writeset_connect_stateset_accept_state
connect_exr5   
settimeout
gettimeoutshutdown)rh   )familyc                       fd}|S )&Create a proxy method for a new class.c                     | j                                          	 vr
|d d          ng } t          | j                  | | j                                          S # | j                                          w xY wN)_lockacquiregetattr	_ssl_connrelease)r"   r   new_argsmethodproxy_methods_no_argss      r*   proxy_wrapperzMSSLConnectionProxyMeta.__new__.<locals>.lock_decorator.<locals>.proxy_wrapper   s    
""$$$)#)1F#F#FQQQB  ;74>6::HEJ&&((((DJ&&((((s   'A A8rC   )rt   rv   ru   s   ` r*   lock_decoratorz6SSLConnectionProxyMeta.__new__.<locals>.lock_decorator   s*    ) ) ) ) ) ) ! r   c                 :      fd} |_         t          |          S )rk   c                 .    t          | j                  S rm   )rp   rq   )r"   	property_s    r*   proxy_prop_wrapperzQSSLConnectionProxyMeta.__new__.<locals>.make_property.<locals>.proxy_prop_wrapper   s    t~y999r   )r9   property)rz   r{   s   ` r*   make_propertyz5SSLConnectionProxyMeta.__new__.<locals>.make_property   s4    : : : : :*3'.///r   )r9   type)mclnamebasesnmspcproxy_methodsproxy_propsrw   mr}   pru   s             @r*   __new__zSSLConnectionProxyMeta.__new__   s    

!

	! 	! 	! 	! 	!  	" 	"A%~a((E!H !E!H	0 	0 	0  	( 	(A$}Q''E!HH D%'''r   N)r9   r:   r;   r<   r   rC   r   r*   rH   rH      s)        <<2( 2( 2( 2( 2(r   rH   c                       e Zd ZdZd ZdS )SSLConnectionzA thread-safe wrapper for an ``SSL.Connection``.

    :param tuple args: the arguments to create the wrapped \
                        :py:class:`SSL.Connection(*args) \
                        <pyopenssl:OpenSSL.SSL.Connection>`
    c                 \    t          j        | | _        t          j                    | _        dS )z"Initialize SSLConnection instance.N)r   
Connectionrq   	threadingRLockrn   )r"   r   s     r*   __init__zSSLConnection.__init__   s#    ._&&


r   N)r9   r:   r;   r<   r   rC   r   r*   r   r      s-         ' ' ' ' 'r   r   )	metaclassc                   f     e Zd ZdZdZ	 dZ	 dZ	 dZ	 dZ	 	 	 d fd	Z	d Z
d Zd Zd Zdd
Z xZS )pyOpenSSLAdapterz1A wrapper for integrating pyOpenSSL with Cheroot.Nc                     t           t          d          t          t          |                               ||||           d| _        dS )z$Initialize OpenSSL Adapter instance.Nz(You must install pyOpenSSL to use HTTPS.)r   ImportErrorr-   r   r   _environ)r"   certificateprivate_keycertificate_chainciphersr1   s        r*   r   zpyOpenSSLAdapter.__init__
  sS    
 ;HIII%%..&7	
 	
 	
 r   c                     | j         |                                 | _         t          | j         |          }|                                 | _        |S )z!Wrap and return the given socket.)contextrJ   r   get_environr   )r"   sockconns      r*   rO   zpyOpenSSLAdapter.bind  sF    <++--DLT\400((**r   c                 8    || j                                         fS )z<Wrap and return the given socket, plus WSGI environ entries.)r   copy)r"   r   s     r*   wrapzpyOpenSSLAdapter.wrap   s    
 T]''))))r   c                     t          j        t           j                  }|                    | j                   | j        r|                    | j                   |                    | j                   |S )z~Return an ``SSL.Context`` from self attributes.

        Ref: :py:class:`SSL.Context <pyopenssl:OpenSSL.SSL.Context>`
        )	r   ContextSSLv23_METHODuse_privatekey_filer   r   load_verify_locationsuse_certificate_filer   )r"   cs     r*   rJ   zpyOpenSSLAdapter.get_context'  sk     K)**	d.///! 	<##D$:;;;	t/000r   c           	         ddt           j        j        dt          j        j        dt          j        j        dt          j        t          j        t          j	                  
                                d}| j        rZt          | j        d          5 }t          j        t          j        |                                          }ddd           n# 1 swxY w Y   |                    |                                |                                d	           d
|                                fd|                                ffD ]\  }}t-          |          dd         }d|z  }|||<   |rk|                    d          }|d|         ||dz   d         }	}|                    d          }|d|         ||dz   d         }
}|
r|	rd|d|
}|	||<   |k|S )z;Return WSGI environ entries to be merged into each request.httpson /z Python/)zwsgi.url_schemeHTTPSSSL_VERSION_INTERFACESSL_VERSION_LIBRARYrbN)SSL_SERVER_M_VERSIONSSL_SERVER_M_SERIALIS   zSSL_SERVER_%s_DN=r   SSL_SERVER__DN_)cheroot_server
HTTPServerversionOpenSSL	__title____version__sysr   SSLeay_versionSSLEAY_VERSIONdecoder   openr   load_certificateFILETYPE_PEMrM   updateget_versionget_serial_number
get_issuerget_subjectstrrfind)r"   ssl_environ	cert_filecertprefixdndnstrwsgikeyposvaluekeys              r*   r   zpyOpenSSLAdapter.get_environ4  sR     ')111)))7?+F+F+F&
 $'#5"$ $fhh
 
  %	5d&-- .')9)9               
 (,(8(8(:(:'+'='='?'?       doo''(d&&(() 5 5
 B2,v5',G$  5++c**C#(#;cAghh5E++c**C!&tteC!GHHo3E 5u 5 5;A6633"G/4G,  5 s   2CCCrr   c                     d|v rt           nt          }t          r=t          |t                    r( ||||          }|                                |_        |S t          j        |||          S )zReturn socket file object.r   )	r@   rF   r   
isinstancessl_conn_typerg   r    r   CP_fileobject)r"   r   modebufsizeclswrapped_sockets         r*   r[   zpyOpenSSLAdapter.makefilel  s|     d{{ &%% 	
  	E:dM22 	E StW55N)-):):N&!! "/dGDDDr   )NN)r   r   )r9   r:   r;   r<   r   r   r   r   r   r   rO   r   rJ   r   r[   r=   r>   s   @r*   r   r      s        ;;K8K9>
 G G" ?C       * * *  6 6 6pE E E E E E E Er   r   )r<   r   r   r   r   OpenSSL.versionr   r   r   r   r   AttributeErrorConnectionTyper    r   r   r	   r   r[   r
   r   r   r@   rF   rH   r   r   rC   r   r*   <module>r      s8  2 2h  



     
+ + + +*+   
CCC       / / / / / / / / 1 1 1 1 1 1 1 1W
 W
 W
 W
 W
 W
 W
 W
t7 7 7 7 7 2L 7 7 77 7 7 7 7 2L 7 7 75( 5( 5( 5( 5( 5( 5( 5(p' ' ' ' '4 ' ' ' 'GE GE GE GE GEw GE GE GE GE GEs,   A  - A  <A  <A   A
	A
