
    5i9                        d 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Z	ddl	m
Z
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ZddlmZmZ ddlmZmZ dd	l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)warn)SSLcrypto   )errorsserver)StreamReaderStreamWriter   )Adapterc                   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        $ r}|r|j        dk    rY d}~dS d}t          j        t                    5  |j        d         d         d         }ddd           n# 1 swxY w Y   |dk    rt          j        t          j        |j         d}~ww xY wt          j                     |z
  | j        k    rt          j        d          )	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
contextlibsuppress
IndexError
NoSSLErrorFatalSSLAlertssl_timeouttimeout)	self	is_readercallr   kwargsstarteerrnumthirdargs	            K/home/kali/Ninja/venv/lib/python3.11/site-packages/cheroot/ssl/pyopenssl.py
_safe_callzSSLFileobjectMixin._safe_callX   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(44 / / vay|AH/ / / / / / / / / / / / / / / ~-- ++*AF334 y{{U"T%555n[111G#	2sc    (E%	'E%2E% C
C
6C

E%E /E 
D0$E 0D4	4E 7D4	8(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-   r1   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.   r0   r   readliner2   s     r-   r6   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.   r0   r   sendallr%   r   r(   r4   s      r-   r8   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.   r0   r   sendr9   s      r-   r;   zSSLFileobjectMixin.send   sK    t$d++0
 
 
 
 	
 
 	
r   )r   )__name__
__module____qualname____doc__r#   r   r.   r1   r6   r8   r;   __classcell__r4   s   @r-   r   r   Q   s        --KI*2 *2 *2X
 
 
 
 


 

 

 

 

 


 
 
 
 

 
 
 
 
 
 
 
 
r   r   c                       e Zd ZdZdS )SSLFileobjectStreamReader,SSL file object attached to a socket object.Nr<   r=   r>   r?    r   r-   rC   rC              6666r   rC   c                       e Zd ZdZdS )SSLFileobjectStreamWriterrD   NrE   rF   r   r-   rI   rI      rG   r   rI   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pendingr;   writer1   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_exr8   
settimeout
gettimeoutshutdown)rk   )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rF   )rw   ry   rx   s   ` r-   lock_decoratorz6SSLConnectionProxyMeta.__new__.<locals>.lock_decorator   s*    ) ) ) ) ) ) ! r   c                 :      fd} |_         t          |          S )rn   c                 .    t          | j                  S rp   )rs   rt   )r%   	property_s    r-   proxy_prop_wrapperzQSSLConnectionProxyMeta.__new__.<locals>.make_property.<locals>.proxy_prop_wrapper   s    t~y999r   )r<   property)r}   r~   s   ` r-   make_propertyz5SSLConnectionProxyMeta.__new__.<locals>.make_property   s6    : : : : : +4'.///r   )r<   type)mclnamebasesnmspcproxy_methodsproxy_propsrz   mr   prx   s             @r-   __new__zSSLConnectionProxyMeta.__new__   s    #
H !.!	! 	! 	! 	! 	!  	" 	"A%~a((E!H !E!H	0 	0 	0  	( 	(A$}Q''E!HH D%'''r   N)r<   r=   r>   r?   r   rF   r   r-   rK   rK      s.        <<K( K( K( K( K(r   rK   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   
Connectionrt   	threadingRLockrq   )r%   r   s     r-   __init__zSSLConnection.__init__  s#    ._&&


r   N)r<   r=   r>   r?   r   rF   r   r-   r   r     s-         ' ' ' ' 'r   r   )	metaclassc                   x     e Zd ZdZdZ	 dZ	 dZ	 dZ	 dZ	 dZ		 	 	 ddd fdZ
d Zd Zd Zd Zd	 ZddZ xZS )pyOpenSSLAdapterz=A wrapper for integrating :doc:`pyOpenSSL <pyopenssl:index>`.Nprivate_key_passwordc                    t           t          d          t          t          |                               |||||           d| _        dS )z$Initialize OpenSSL Adapter instance.Nz(You must install pyOpenSSL to use HTTPS.r   )r   ImportErrorr0   r   r   _environ)r%   certificateprivate_keycertificate_chainciphersr   r4   s         r-   r   zpyOpenSSLAdapter.__init__,  s]     ;HIII%%..!5 	/ 	
 	
 	
 r   c                     | j         |                                 | _         t          | j         |          }|                                 | _        |S )z!Wrap and return the given socket.)contextrM   r   get_environr   )r%   sockconns      r-   rR   zpyOpenSSLAdapter.bindC  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.wrapK  s    
 T]''))))r   c                    d}t          |t                    r|                    d          }nt          |t                    r|}t	          |          }||k    rt          d| d| dt          d           |S )z4Pass a passphrase to password protected private key.r   zutf-8zUser-provided password is zB bytes long and will be truncated since it exceeds the maximum of .r   )
stacklevel)
isinstancestrencodebyteslen_warnUserWarning)r%   password_max_length_verify_twicepassword
b_passwordpassword_lengths         r-   _password_callbackz#pyOpenSSLAdapter._password_callbackR  s     
h$$ 	"!11JJ%(( 	"!Jj//000W_ W W@SW W W	    r   c                 ,   t          j        t           j                  }|                    | j        | 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set_passwd_cbr   r   use_privatekey_filer   r   load_verify_locationsuse_certificate_filer   )r%   cs     r-   rM   zpyOpenSSLAdapter.get_contextk  s     K)**	/1JKK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_PEMrP   updateget_versionget_serial_number
get_issuerget_subjectr   rfind)r%   ssl_environ	cert_filecertprefixdndnstrwsgikeyposvaluekeys              r-   r   zpyOpenSSLAdapter.get_environy  sX     ' )111)))+++& $'#5"$ $fhh
 
  (	5d&-- .'NN$$                ,0,<,<,>,>+/+A+A+C+C 	 	 	 doo''(d&&(() 5 5
 B2,v5',G$  5++c**C#(#;cAgii0@5E++c**C!&tteC!GII.>3E 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   )	rC   rI   r   r   ssl_conn_typerj   r#   r   CP_fileobject)r%   r   modebufsizeclswrapped_sockets         r-   r^   zpyOpenSSLAdapter.makefile  sz     d{{ &%* 	
  	":dM22 	" StW55N)-):):N&!! +D$@@@r   )NN)r   r   )r<   r=   r>   r?   r   r   r   r   r   r   r   rR   r   r   rM   r   r^   r@   rA   s   @r-   r   r     s        GGK8K9>
 G G"A  "      .  * * *  2  ; ; ;zA A A A A A A Ar   r   ) r?   r   r   r   r   warningsr   r   OpenSSL.versionr   r   r   r   r   AttributeErrorConnectionTyper   r    r   r   r   r^   r	   r
   r   r   rC   rI   rK   r   r   rF   r   r-   <module>r      sd  2 2h  



      " " " " " "	########+ + + +*+   
CCC            2 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N( N( N( N( N( N( N( N(b' ' ' ' '4 ' ' ' 'qA qA qA qA qAw qA qA qA qA qAs,   A / A >A >A AA