
    qi9                     h   S r SSKrSSKrSSKrSSKrSSKJr   SSKr	SSK	J
r
Jr   \
R                  rSSKrSSKJrJr  SSKJrJr  SS	KJr   " S
 S5      r " S S\\5      r " S S\\5      r " S S5      r " S S\S9r " S S\5      rg! \ a    \
R                  r Nof = f! \ a    Sr
 N}f = f)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                   b   ^  \ rS rSrSrSrSrS rU 4S jrSU 4S jjr	U 4S jr
U 4S	 jrS
rU =r$ )SSLFileobjectMixinQ   z#Base mixin for a TLS socket stream.   g{Gz?c                    [         R                   " 5       n  U" U0 UD6$ ! [        R                   a$    [         R                  " U R                  5         GOd[        R
                   a$    [         R                  " U R                  5         GO.[        R                   af  nU(       a  UR                  S:X  a   SnAgUR                  S   nU(       a  U[        R                  ;   a   SnAg[        R                  " U5      eSnAf[        R                   a  nU(       a  UR                  S:X  a   SnAgSn[        R                  " [        5         UR                  S   S   S   nSSS5        O! , (       d  f       O= fUS:X  a  [        R                   e[        R"                  " UR                  6 eSnAff = f[         R                   " 5       U-
  U R$                  :  a  [        R&                  " S5      eGM  )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).
)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	            J/home/kali/flask_env/lib/python3.13/site-packages/cheroot/ssl/pyopenssl.py
_safe_callSSLFileobjectMixin._safe_callX   sj    		4T,V,,$$ + 

4>>*%% +

4>>*## ++A!A6+I+I!Ill6**99 4+A!A((4 vvay|AH 544 ~- +++**AFF334 yy{U"T%5%55nn[11G sW     4F83F8F8 D<*D+DF8F34F3E/&	F3/
E=	9:F33F8c                 B   > U R                  S[        [        U ]  U5      $ )z*Receive message of a size from the socket.T)r/   superr   recvr&   size	__class__s     r.   r3   SSLFileobjectMixin.recv   s%    $d0
 	
r   c                 B   > U R                  S[        [        U ]  U5      $ )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/   r2   r   readliner4   s     r.   r9   SSLFileobjectMixin.readline   s'     $d4
 	
r   c                 J   > U R                   " S[        [        U ]  /UQ70 UD6$ )z!Send whole message to the socket.F)r/   r2   r   sendallr&   r   r)   r6   s      r.   r<   SSLFileobjectMixin.sendall   s6    $d3
 
 	
 	
r   c                 J   > U R                   " S[        [        U ]  /UQ70 UD6$ )z(Send some part of message to the socket.F)r/   r2   r   sendr=   s      r.   r@   SSLFileobjectMixin.send   s6    $d0
 
 	
 	
r    )r   )__name__
__module____qualname____firstlineno____doc__r$   r   r/   r3   r9   r<   r@   __static_attributes____classcell__r6   s   @r.   r   r   Q   s/    -KI*2X




 
r   r   c                       \ rS rSrSrSrg)SSLFileobjectStreamReader   ,SSL file object attached to a socket object.rB   NrC   rD   rE   rF   rG   rH   rB   r   r.   rL   rL          6r   rL   c                       \ rS rSrSrSrg)SSLFileobjectStreamWriter   rN   rB   NrO   rB   r   r.   rR   rR      rP   r   rR   c                       \ rS rSrSrS rSrg)SSLConnectionProxyMeta   z2Metaclass for generating a bunch of proxy methods.c                    ^
 SnSm
SnU
4S jnU H  nU" U5      X7'   XsU   l         M     S nU H  n	U" U	5      X9'   M     [        XU5      $ )z.Attach a list of proxy methods to a new class.)"get_contextpendingr@   writer3   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_exr<   
settimeout
gettimeoutshutdown)rv   )familyc                    >^  U U4S jnU$ )&Create a proxy method for a new class.c                    > U R                   R                  5          TT;  a  US S  O/ n[        U R                  T5      " U6 U R                   R	                  5         $ ! U R                   R	                  5         f = fN)_lockacquiregetattr	_ssl_connrelease)r&   r   new_argsmethodproxy_methods_no_argss      r.   proxy_wrapperMSSLConnectionProxyMeta.__new__.<locals>.lock_decorator.<locals>.proxy_wrapper   sd    

""$)#)1F#FQB  #4>>6:HEJJ&&(DJJ&&(s   %A A9rB   )r   r   r   s   ` r.   lock_decorator6SSLConnectionProxyMeta.__new__.<locals>.lock_decorator   s    ) ! r   c                 4   ^  U 4S jnT Ul         [        U5      $ )ry   c                 0   > [        U R                  T5      $ r{   )r~   r   )r&   	property_s    r.   proxy_prop_wrapperQSSLConnectionProxyMeta.__new__.<locals>.make_property.<locals>.proxy_prop_wrapper   s    t~~y99r   )rC   property)r   r   s   ` r.   make_property5SSLConnectionProxyMeta.__new__.<locals>.make_property   s    : +4'.//r   )rC   type)mclnamebasesnmspcproxy_methodsproxy_propsr   mr   pr   s             @r.   __new__SSLConnectionProxyMeta.__new__   sk    #
H !.!	! A%a(EH !!H 	0 A$Q'EH 
 D''r   rB   N)rC   rD   rE   rF   rG   r   rH   rB   r   r.   rU   rU      s    <K(r   rU   c                       \ rS rSrSrS rSrg)SSLConnectioni  zA 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                 h    [         R                  " U6 U l        [        R                  " 5       U l        g)z"Initialize SSLConnection instance.N)r   
Connectionr   	threadingRLockr|   )r&   r   s     r.   __init__SSLConnection.__init__  s     .__&
r   )r|   r   N)rC   rD   rE   rF   rG   r   rH   rB   r   r.   r   r     s    'r   r   )	metaclassc                      ^  \ rS rSrSrSr Sr Sr Sr Sr	 Sr
   SSS.U 4S jjjrS rS rS rS	 rS
 rSS jrSrU =r$ )pyOpenSSLAdapteri  z=A wrapper for integrating :doc:`pyOpenSSL <pyopenssl:index>`.Nprivate_key_passwordc                b   > [         c  [        S5      e[        [        U ]  UUUUUS9  SU l        g)z$Initialize OpenSSL Adapter instance.Nz(You must install pyOpenSSL to use HTTPS.r   )r   ImportErrorr2   r   r   _environ)r&   certificateprivate_keycertificate_chainciphersr   r6   s         r.   r   pyOpenSSLAdapter.__init__,  sC     ;HII.!5 	/ 	
 r   c                     U R                   c  U R                  5       U l         [        U R                   U5      nU R                  5       U l        U$ )z!Wrap and return the given socket.)contextrX   r   get_environr   )r&   sockconns      r.   r]   pyOpenSSLAdapter.bindC  sA    <<++-DLT\\40((*r   c                 8    XR                   R                  5       4$ )z<Wrap and return the given socket, plus WSGI environ entries.)r   copy)r&   r   s     r.   wrappyOpenSSLAdapter.wrapK  s    
 ]]'')))r   c                    Sn[        U[        5      (       a  UR                  S5      nO[        U[        5      (       a  Un[	        U5      nXQ:  a  [        SU SU S3[        SS9  U$ )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_callback#pyOpenSSLAdapter._password_callbackR  sx     
h$$!1J%((!Jj/0,_,= >@@S?TTUW	 r   c                 ^   [         R                  " [         R                  5      nUR                  U R                  U R
                  5        UR                  U R                  5        U R                  (       a  UR                  U R                  5        UR                  U R                  5        U$ )znReturn 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.   rX   pyOpenSSLAdapter.get_contextk  s|     KK))*	//1J1JK	d../!!##D$:$:;	t//0r   c           	         SS[         R                  R                  < S[        R                  R                  < S[        R                  R
                  < S[        R                  < 3[        R                  " [        R                  5      R                  5       S.nU R                  (       Ga,  [        U R                  S5       n[        R                  " [        R                  UR!                  5       5      nSSS5        UR#                  WR%                  5       UR'                  5       S	.5        S
UR)                  5       4SUR+                  5       44 H  u  pE[-        U5      SS nSU-  nXaU'   U(       d  M%  UR/                  S5      nUSU XhS-   S pUR/                  S5      nUSU XhS-   S pU
(       a  U	(       a  SU< SU
< 3nXU'   U(       a  M]  M     U$ ! , (       d  f       N= f)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_PEMr[   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   pyOpenSSLAdapter.get_environy  s     ' ))11))++& $'#5#5""$fh
 d&&-..''NN$ . ,0,<,<,>+/+A+A+C	 doo'(d&&()
 B2,v5',G$ e++c*C#(#;Agi0@5++c*C!&te!GI.>3u;A3"G/4G, e. Q .-s   4G
G+c                     SU;   a  [         O[        n[        (       a5  [        U[        5      (       a   U" XU5      nUR                  5       Ul        U$ [        R                  " XU5      $ )zReturn socket file object.r)	rL   rR   r   r   ssl_conn_typeru   r$   r   CP_fileobject)r&   r   modebufsizeclswrapped_sockets         r.   ri   pyOpenSSLAdapter.makefile  sa     d{ &* 	
 3:dM22 W5N)-):N&!! ++D@@r   )r   r   )NN)r  r   )rC   rD   rE   rF   rG   r   r   r   r   r   r   r   r]   r   r   rX   r   ri   rH   rI   rJ   s   @r.   r   r     s    GK8K9>
 G G"A  " .*2;zA Ar   r   ) rG   r   r   r   r   warningsr   r   OpenSSL.versionr   r   r   r   r  AttributeErrorConnectionTyper   r    r   r   r   ri   r	   r
   r   r   rL   rR   rU   r   r   rB   r   r.   <module>r     s   2h  
   "	#+  2 W
 W
t7 2L 77 2L 7N( N(b'4 'qAw qAa  +**+ 
Cs.   B& B B# B& "B##B& &B10B1