Ë
    #ïàjiC  ã                   ó  — d 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	 ddlmZ ddlmZmZ dd	lmZ d
dlmZ d„ Zd„ Zddœd„Zddœd„Zd„ Z G d„ de«      Zy# e$ r dZY ŒKw xY w# e$ r 	 ddl
m	Z	 n# e$ r dZ	Y nw xY wY Œdw xY w)zñ
A library for integrating Python's builtin :py:mod:`ssl` library with Cheroot.

The :py:mod:`ssl` module must be importable for SSL functionality.

To use this module, set ``HTTPServer.ssl_adapter`` to an instance of
``BuiltinSSLAdapter``.
é    N)Úsuppress)ÚDEFAULT_BUFFER_SIZEéÿÿÿÿé   )Úerrors©ÚStreamReaderÚStreamWriter)Ú
HTTPServeré   )ÚAdapterc                 ó�   ‡— t        |«      dk  rt        d«      ‚t        | «      j                  «       Št	        ˆfd„|D «       «      S )zACheck whether SSL exception contains either of messages provided.r   zF_assert_ssl_exc_contains() requires at least one message to be passed.c              3   óB   •K  — | ]  }|j                  «       ‰v –— Œ y ­w)N)Úlower)Ú.0ÚmÚerr_msg_lowers     €úB/srv/dav/.venv/lib/python3.12/site-packages/cheroot/ssl/builtin.pyú	<genexpr>z+_assert_ssl_exc_contains.<locals>.<genexpr>+   s   øè ø€ Ò8¨aˆq�w‰w‹y˜MÔ)Ñ8ùs   ƒ)ÚlenÚ	TypeErrorÚstrr   Úany)ÚexcÚmsgsr   s     @r   Ú_assert_ssl_exc_containsr   #   sC   ø€ ä
ˆ4ƒy�1‚}Üð1ó
ð 	
ô ˜“H—N‘NÓ$€MÜÓ8°4Ô8Ó8Ð8ó    c                 óÞ   — t        t        j                  t        «      5  | j	                  |dd¬«      5 }|j                  d«       ddd«       ddd«       y# 1 sw Y   ŒxY w# 1 sw Y   yxY w)z;Wrap a socket in ssl and perform the server-side handshake.T©Údo_handshake_on_connectÚserver_sides   0000N)r   ÚsslÚSSLErrorÚOSErrorÚwrap_socketÚsend)ÚcontextÚserverÚssl_socks      r   Ú_loopback_for_cert_threadr*   .   sp   € ô 
”#—,‘,¤Ó	(ñ #Ø× Ñ ØØ$(Øð !ó 
ð 	#ð ð& �M‰M˜'Ô"÷/	#÷#ð #÷	#ð 	#ú÷#ð #ús"   ŸA#´AÁA#ÁA 	ÁA#Á#A,©Úprivate_key_passwordc                óì  — t        j                  |¬«      }|j                  | ||¬«       d|_        t         j                  |_        t        j                  «       \  }}	 t        j                  t        ||f¬«      }	 |j                  «        |j                  |dd¬«      5 }|j                  d«       |j                  «       cddd«       |j                  «        |j!                  «        |j!                  «        S # 1 sw Y   nxY w	 |j                  «        n# |j                  «        w xY w	 |j!                  «        |j!                  «        y# |j!                  «        |j!                  «        w xY w)	z@Create a loopback connection to parse a cert with a private key.)Úcafile©ÚpasswordF)ÚtargetÚargsTr   é   N)r"   Úcreate_default_contextÚload_cert_chainÚcheck_hostnameÚ	CERT_NONEÚverify_modeÚsocketÚ
socketpairÚ	threadingÚThreadr*   Ústartr%   ÚrecvÚgetpeercertÚjoinÚclose)	ÚcertificateÚprivate_keyÚcertificate_chainr,   r'   Úclientr(   Úthreadr)   s	            r   Ú_loopback_for_certrG   O   s?  € ô ×(Ñ(Ð0AÔB€GØ×ÑØØØ%ð ô ð
 #€GÔÜŸ-™-€GÔô ×&Ñ&Ó(�N€FˆFðô ×!Ñ!Ü,Ø˜6Ð"ô
ˆð
	Ø�L‰LŒNØ×$Ñ$ØØ(,Ø!ð %ó ð .ð Ø—‘˜aÔ Ø×+Ñ+Ó-÷.ð .ð �K‰KŒMà�‰ŒØ�‰�÷.ð .úð .ð �K‰K�MøˆF�K‰K�MúˆMà�‰ŒØ�‰�øð 	�‰ŒØ�‰�úsB   ÁE Á=$D Â!!C<Ã	D ÃE Ã<DÄD Ä	E ÄD,Ä,E Å"E3c                ó  — t        t        t        j                  t        «      5  t        | |||¬«      cddd«       S # 1 sw Y   nxY wt        t        «      5  t        j                  j                  | «      cddd«       S # 1 sw Y   i S xY w)zParse a certificate.r+   N)	r   ÚAttributeErrorr"   r#   r$   rG   Ú	ExceptionÚ_sslÚ_test_decode_cert)rB   rC   rD   r,   s       r   Ú_parse_certrM   }   su   € ô 
”.¤#§,¡,´Ó	8ñ 
Ü!ØØØØ!5ô	
÷
÷ 
ò 
úô 
”)Ó	ñ 7Ü�x‰x×)Ñ)¨+Ó6÷7÷ 7ñ 7ð €Iús   ¤=½AÁBÂBc                 ó   — || _         y)z7Handle the SNI callback to tag the socket with the SNI.N)Úsni)ÚsockrO   r'   s      r   Ú_sni_callbackrQ   œ   s	   € à€D…Hr   c                   óè   ‡ — e Zd ZdZdZ	 dZ	 dZ	 dZ	 dZ	 ddddddd	d
œZ	ddddddddddddddœZ
	 	 d%ddœˆ fd„Zed„ «       Zej                  d„ «       Zˆ fd„Zd„ Zd„ Zd „ Zd!„ Zd"„ Zd#efd$„Zˆ xZS )&ÚBuiltinSSLAdapterzDWrapper for integrating Python's builtin :py:mod:`ssl` with Cheroot.NÚ	M_VERSIONÚM_SERIALÚV_STARTÚV_ENDÚS_DNÚI_DNÚSAN)ÚversionÚserialNumberÚ	notBeforeÚnotAfterÚsubjectÚissuerÚsubjectAltNameÚCÚSTÚLÚOÚOUÚCNÚTÚIÚGÚSÚDÚUIDÚEmail)ÚcountryNameÚstateOrProvinceNameÚlocalityNameÚorganizationNameÚorganizationalUnitNameÚ
commonNameÚtitleÚinitialsÚ	givenNameÚsurnameÚdescriptionÚuseridÚemailAddressr+   c          	      ó  •— t         €t        d«      ‚t        t        | �  |||||¬«       t        j
                  t         j                  j                  |¬«      | _        | j                  j                  |||¬«       | j                  �| j                  j                  |«       | j                  dt        ||| j                  |¬«      «      | _        | j                  syd}t!        |«      5 }|j#                  «       }ddd«       |j%                  t         j&                  «      }|dk(  ry|j%                  t         j(                  |«      }	|	dk(  ry|	t+        t         j(                  «      z  }	|||	 | j                  d<   y# 1 sw Y   ŒƒxY w)	zASet up context in addition to base class properties if available.Nz-You must install the ssl module to use HTTPS.r+   )Úpurposer.   r/   Ú
SSL_SERVERr   ÚSSL_SERVER_CERT)r"   ÚImportErrorÚsuperrS   Ú__init__r4   ÚPurposeÚCLIENT_AUTHr'   r5   ÚciphersÚset_ciphersÚ_make_env_cert_dictrM   rD   Ú_server_envÚopenÚreadÚfindÚ
PEM_HEADERÚ
PEM_FOOTERr   )ÚselfrB   rC   rD   r…   r,   ÚcertÚfÚ
cert_startÚcert_endÚ	__class__s             €r   r‚   zBuiltinSSLAdapter.__init__å   ss  ø€ ô ˆ;ÜÐMÓNÐNäÔ Ñ/ØØØØØ!5ð 	0ô 	
ô ×1Ñ1Ü—K‘K×+Ñ+Ø$ô
ˆŒð 	�‰×$Ñ$ØØØ)ð 	%ô 	
ð
 �<‰<Ð#Ø�L‰L×$Ñ$ WÔ-à×3Ñ3ØÜØØØ×&Ñ&Ø%9ô	ó
ˆÔð ×ÒØØˆÜ�+Óð 	 !Ø—6‘6“8ˆD÷	ð —Y‘YœsŸ~™~Ó.ˆ
Ø˜ÒØØ—9‘9œSŸ^™^¨ZÓ8ˆØ�rŠ>ØØ”CœŸ™Ó'Ñ'ˆØ.2°:¸hÐ.Gˆ×ÑÐ*Ò+÷	ð 	ús   Ã,E?Å?Fc                 ó   — | j                   S )z>:py:class:`~ssl.SSLContext` that will be used to wrap sockets.)Ú_context)rŽ   s    r   r'   zBuiltinSSLAdapter.context  s   € ð �}‰}Ðr   c                 ó¨   — || _         t        t        «      5  t        j                  r|j
                  €t        |_        ddd«       y# 1 sw Y   yxY w)zSet the ssl ``context`` to use.N)r•   r   rI   r"   ÚHAS_SNIÚsni_callbackrQ   )rŽ   r'   s     r   r'   zBuiltinSSLAdapter.context$  sD   € ð  ˆŒô ”nÓ%ñ 	5Ü�{Š{˜w×3Ñ3Ð;Ü'4�Ô$÷	5÷ 	5ñ 	5ús   —(AÁAc                 ó*   •— t         t        | �  |«      S )z!Wrap and return the given socket.)r�   rS   Úbind)rŽ   rP   r“   s     €r   rš   zBuiltinSSLAdapter.bind2  s   ø€ äÔ&¨Ñ2°4Ó8Ð8r   c                 ó0  — 	 | j                   j                  |dd¬«      }|| j                  |«      fS # t        j                  t        j                  f$ r"}t        j                  |j                  Ž |‚d}~wt        j                  $ rc}|j                  t        j                  k(  xr t        |d«      }|rt
        j                  }nt
        j                  } ||j                  Ž |‚d}~wt        $ r"}t        j                  |j                  Ž |‚d}~ww xY w)z<Wrap and return the given socket, plus WSGI environ entries.Tr   Nzhttp request)r'   r%   r"   ÚSSLEOFErrorÚSSLZeroReturnErrorr   ÚFatalSSLAlertr2   r#   ÚerrnoÚSSL_ERROR_SSLr   Ú
NoSSLErrorr$   Úget_environ)rŽ   rP   ÚsÚtls_connection_drop_errorÚgeneric_tls_errorÚ!peer_speaks_plain_http_over_httpsÚ reraised_connection_drop_exc_clsÚtcp_connection_drop_errors           r   ÚwrapzBuiltinSSLAdapter.wrap6  s  € ð	-Ø—‘×(Ñ(ØØ(,Ø ð )ó ˆAð< �$×"Ñ" 1Ó%Ð%Ð%øô1 �O‰OÜ×"Ñ"ð
ò 	-ô ×&Ñ&Ø*×/Ñ/ðà,ð-ûô �|‰|ò 	%à!×'Ñ'¬3×+<Ñ+<Ñ<ò PÜ,Ð->ÀÓOð .ñ 1Ü39×3DÑ3DÑ0ä39×3GÑ3GÐ0á2Ø"×'Ñ'ðà$ð%ûô ò 	-Ü×&Ñ&Ø*×/Ñ/ðà,ð-ûð	-ús.   ‚3 ³#DÁA3Á3DÂ	AC'Ã'DÃ3DÄDc           
      ó\  — |j                  «       }dd|d   |d   d|d   t        j                  ›dt        j                  ›�t        j
                  dd	œ	}t        t        «      5  |j                  «       }|�||d<   d
d
d
«       t        t        «      5  |j                  j                  j                  «       |d<   d
d
d
«       t        t        «      5  |d
d }|j                  j                  «       D ]  }||d   |d   fk(  sŒ|d   |d<    n d
d
d
«       t        t        «      5  |j                  |d<   d
d
d
«       | j                  r•| j                  j                  t        j                   k7  rn|j#                  «       }|r\d|d<   |j%                  | j'                  d|«      «       t	        j(                  |j#                  d¬«      «      j+                  «       |d<   |j%                  | j,                  «       |S # 1 sw Y   �Œ�xY w# 1 sw Y   �ŒOxY w# 1 sw Y   �Œ	xY w# 1 sw Y   ŒîxY w)z;Create WSGI environ entries to be merged into each request.ÚhttpsÚonr   r   Ú r   z Python/ÚNONE)	zwsgi.url_schemeÚHTTPSÚSSL_PROTOCOLÚ
SSL_CIPHERÚSSL_CIPHER_EXPORTÚSSL_CIPHER_USEKEYSIZEÚSSL_VERSION_INTERFACEÚSSL_VERSION_LIBRARYÚSSL_CLIENT_VERIFYNÚSSL_COMPRESS_METHODÚSSL_SESSION_IDÚnameÚprotocolÚalg_bitsÚSSL_CIPHER_ALGKEYSIZEÚSSL_TLS_SNIÚSUCCESSr¶   Ú
SSL_CLIENTT)Úbinary_formÚSSL_CLIENT_CERT)Úcipherr   r[   Úsysr"   ÚOPENSSL_VERSIONr   rI   ÚcompressionÚsessionÚidÚhexr'   Úget_ciphersrO   r8   r7   r?   Úupdater‡   ÚDER_cert_to_PEM_certÚstriprˆ   )rŽ   rP   rÂ   Ússl_environrÅ   Útarget_cipherÚcipÚclient_certs           r   r¢   zBuiltinSSLAdapter.get_environY  s  € à—‘“ˆà&ØØ" 1™IØ  ™)Ø!#Ø%+¨A¡Yô ×"Ó"Ü—’ð&ô
 $'×#6Ñ#6Ø!'ñ
ˆô$ ”nÓ%ñ 	AØ×*Ñ*Ó,ˆKØÐ&Ø5@�Ð1Ñ2÷	Aô ”nÓ%ñ 	BØ,0¯L©L¯O©O×,?Ñ,?Ó,AˆKÐ(Ñ)÷	Bä”nÓ%ñ 	Ø" 2 A˜JˆMØ—|‘|×/Ñ/Ó1ò �Ø  S¨¡[°#°j±/Ð$BÓBØ;>¸z¹?�KÐ 7Ñ8Ùð÷	ô ”nÓ%ñ 	2Ø)-¯©ˆK˜Ñ&÷	2ð �<Š<˜DŸL™L×4Ñ4¼¿¹ÒEØ×*Ñ*Ó,ˆKÙð 4=�Ð/Ñ0Ø×"Ñ"Ø×,Ñ,¨\¸;ÓGôô 25×1IÑ1IØ×$Ñ$°Ð$Ó6ó2ç‘%“'ð Ð-Ñ.ð 	×Ñ˜4×+Ñ+Ô,ð Ð÷S	Añ 	Aú÷	Bñ 	Bú÷	ñ 	ú÷	2ð 	2ús6   Á$G;Â(HÃ0HÄHÄ%H"Ç;HÈHÈHÈ"H+c                 ó  — |si S i }| j                   j                  «       D ]…  \  }}|›d|›�}|j                  |«      }|dk(  r"|j                  | j	                  ||«      «       ŒE|j                  d«      r"|j                  | j                  ||«      «       Œxt        |«      ||<   Œ‡ d|v rRt        j                  |d   «      }|t        j                  |d   «      z  }|dz  }t        t        |«      «      ||›d�<   |S )zÍReturn a dict of WSGI environment variables for a certificate.

        E.g. SSL_CLIENT_M_VERSION, SSL_CLIENT_M_SERIAL, etc.
        See https://httpd.apache.org/docs/2.4/mod/mod_ssl.html#envvars.
        Ú_rZ   Ú_DNr]   r^   i€Q Ú	_V_REMAIN)ÚCERT_KEY_TO_ENVÚitemsÚgetrÊ   Ú_make_env_san_dictÚendswithÚ_make_env_dn_dictr   r"   Úcert_time_to_secondsÚint)	rŽ   Ú
env_prefixÚparsed_certÚenvÚcert_keyÚenv_varÚkeyÚvalueÚremains	            r   r‡   z%BuiltinSSLAdapter._make_env_cert_dict™  sÿ   € ñ ØˆIàˆØ!%×!5Ñ!5×!;Ñ!;Ó!=ò 	&ÑˆH�gÚ'©Ð1ˆCØ—O‘O HÓ-ˆEØ˜%ÒØ—
‘
˜4×2Ñ2°3¸Ó>Õ?Ø×!Ñ! %Ô(Ø—
‘
˜4×1Ñ1°#°uÓ=Õ>ä˜u›:��C’ð	&ð ˜+Ñ%Ü×-Ñ-¨k¸*Ñ.EÓFˆFØ”c×.Ñ.¨{¸;Ñ/GÓHÑHˆFØ�lÑ"ˆFÜ14´S¸³[Ó1AˆC¢Ð-Ñ.àˆ
r   c                 ó‚   — |si S i }d}d}|D ]/  \  }}|dk(  r||d||fz  <   |dz  }Œ|dk(  sŒ!||d||fz  <   |dz  }Œ1 |S )zïReturn a dict of WSGI environment variables for a certificate DN.

        E.g. SSL_CLIENT_SAN_Email_0, SSL_CLIENT_SAN_DNS_0, etc.
        See SSL_CLIENT_SAN_* at
        https://httpd.apache.org/docs/2.4/mod/mod_ssl.html#envvars.
        r   ÚDNSz	%s_DNS_%ir   rn   z%s_Email_%i© )rŽ   rÝ   Ú
cert_valuerß   Ú	dns_countÚemail_countÚ	attr_nameÚvals           r   rØ   z$BuiltinSSLAdapter._make_env_san_dict·  s€   € ñ ØˆIàˆØˆ	ØˆØ(ò 	!‰NˆI�sØ˜EÒ!Ø=@��K :¨yÐ"9Ñ9Ñ:Ø˜Q‘‘	Ø˜gÓ%ØAD��M Z°Ð$=Ñ=Ñ>Ø˜qÑ ‘ð	!ð ˆ
r   c                 óÖ  — |si S g }i }|D ]j  }|D ]c  \  }}| j                   j                  |«      }|j                  |xs |›d|›�«       |sŒ>|j                  |g «       ||   j                  |«       Œe Œl |dj	                  |«      i}	|j                  «       D ]K  \  }}
dj	                  |
«      |	|›d|›�<   t        |
«      dk(  rŒ.t        |
«      D ]  \  }}||	d|||fz  <   Œ ŒM |	S )zìReturn a dict of WSGI environment variables for a certificate DN.

        E.g. SSL_CLIENT_S_DN_CN, SSL_CLIENT_S_DN_C, etc.
        See SSL_CLIENT_S_DN_x509 at
        https://httpd.apache.org/docs/2.4/mod/mod_ssl.html#envvars.
        ú=ú,rÒ   r   z%s_%s_%i)ÚCERT_KEY_TO_LDAP_CODEr×   ÚappendÚ
setdefaultr@   rÖ   r   Ú	enumerate)rŽ   rÝ   rè   ÚdnÚdn_attrsÚrdnrë   rì   Ú	attr_coderß   ÚvaluesÚis               r   rÚ   z#BuiltinSSLAdapter._make_env_dn_dictÐ  s#  € ñ ØˆIàˆØˆØò 	0ˆCØ"%ò 0‘�	˜3Ø ×6Ñ6×:Ñ:¸9ÓE�	Ø—	‘	 YÒ%;°)Ñ%;¹SÐAÔBÙ ØØ×#Ñ# I¨rÔ2Ø˜Ñ#×*Ñ*¨3Õ/ñ0ð	0ð ˜Ÿ™ ›ð
ˆð "*§¡Ó!1ò 	CÑˆI�vØ58·X±X¸fÓ5EˆCš:¡yÐ1Ñ2Ü�6‹{˜aÒØÜ# FÓ+ò C‘��3Ø?B��J *¨i¸Ð!;Ñ;Ò<ñCð		Cð ˆ
r   Úrc                 ó6   — d|v rt         nt        } ||||«      S )zReturn socket file object.rú   r   )rŽ   rP   ÚmodeÚbufsizeÚclss        r   ÚmakefilezBuiltinSSLAdapter.makefileð  s   € à! T™k�l¬|ˆÙ�4˜˜wÓ'Ð'r   )NN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rB   rC   rD   r…   r,   rÕ   rð   r‚   Úpropertyr'   Úsetterrš   r©   r¢   r‡   rØ   rÚ   r   rÿ   Ú__classcell__)r“   s   @r   rS   rS   ¢   sö   ø„ ÙNà€KØ6à€KØ9àÐØ6à€GØ"àÐØAð Ø"ØØØØØñ€Oð& Ø#ð ØØ"&ØØØØØØØØñÐðD Øð8Hð "ö8Hðt ñó ðð ‡^�^ñ5ó ð5ô9ò!&òF>ò@ò<ò2ð@ #&Ð/B÷ (r   rS   )r  r9   rÃ   r;   Ú
contextlibr   r"   r€   Ú_pyior   Úior­   r   rÿ   r	   r
   r(   r   r   r   r*   rG   rM   rQ   rS   rç   r   r   ú<module>r
     s­   ðñó Û 
Û Ý ðÛð!Ý)õ ß 1Ý Ý ò9ò#ðL ô+ðf ôò>ôQ(˜õ Q(øða ò Ø
‚Cðûð
 ò !ð!Þ*øØò !Ø Òð!üð!úsF   –A ›A) ÁA&Á%A&Á)BÁ/A6Á5BÁ6B Á=BÁ?B Â BÂB