o
    NK&h                     @  s   d dl mZ d dlZd dlZd dlmZ d dlmZmZm	Z	 d dl
mZ g dZdddejjfd6ddZd7ddZd8ddZd9ddZd:d!d"Zd;d'd(Zd<d,d-Zd=d/d0ZG d1d2 d2ejZG d3d4 d4eZG d5d dejZdS )>    )annotationsN)Iterable)AnyOptionalUnion)logger)zECDHE-ECDSA-CHACHA20-POLY1305zECDHE-ECDSA-AES256-GCM-SHA384zECDHE-ECDSA-AES128-GCM-SHA256zECDHE-RSA-CHACHA20-POLY1305zECDHE-RSA-AES256-GCM-SHA384zECDHE-RSA-AES128-GCM-SHA256certfileOptional[str]keyfilepasswordpurposessl.Purposereturnssl.SSLContextc                 C  s^   t j|d}t jj|_|dt |dg |t j	j
u r"t|_| r-|r-|| || |S )z>Create a context with secure crypto and HTTP/1.1 in protocols.)r   :zhttp/1.1)sslcreate_default_context
TLSVersionTLSv1_2minimum_versionset_ciphersjoinCIPHERS_TLS12set_alpn_protocolsPurposeCLIENT_AUTHserver_name_callbacksni_callbackload_cert_chain)r   r
   r   r   context r    I/var/www/html/venv/lib/python3.10/site-packages/sanic/http/tls/context.pycreate_context   s   
r"   ctxdef&Union[None, ssl.SSLContext, dict, str]Optional[ssl.SSLContext]c                 C  sV   | du s
t | tjr| S t | trt| S t | tr!tdi | S tdt|  d)z:Convert an ssl argument shorthand to an SSLContext object.NzInvalid ssl argument z8. Expecting a list of certdirs, a dict or an SSLContext.r    )	
isinstancer   
SSLContextstrload_cert_dirdict
CertSimple
ValueErrortype)r#   r    r    r!   shorthand_to_ctx*   s   

r.   ssldef3Union[None, ssl.SSLContext, dict, str, list, tuple]c                 C  s$   t | ttfrttt| S t| S )zBProcess app.run ssl argument from easy formats to full SSLContext.)r&   listtupleCertSelectormapr.   )r/   r    r    r!   process_to_context:   s
   r5   pr(   c                 C  sz   t j| rtd|  dt j| d}t j| d}t |t js*td| t |t js8td| t||S )Nz Certificate folder expected but z is a file.zprivkey.pemzfullchain.pemz+Certificate not found or permission denied )ospathisfiler,   r   accessR_OKr+   )r6   r
   r   r    r    r!   r)   E   s   
r)   selfr3   server_namec                 C  sP   |s| j r| j S td| jD ]}t||r|  S q| j r!| j S td|)zFind the first certificate that matches the given SNI.

    :raises ssl.CertificateError: No matching certificate found.
    :return: A matching ssl.SSLContext object if found.z4The client provided no SNI to match for certificate.z'No certificate found matching hostname )sanic_fallbackr,   sanic_selectmatch_hostname)r<   r=   ctxr    r    r!   	find_certU   s   

rB   rA   #Union[ssl.SSLContext, CertSelector]hostnameboolc                 C  sj   t t| di dg }| }|D ] }|dr+|ddd |dd kr* d	S q||kr2 d	S qd
S )z:Match names from CertSelector against a received hostname.sanicnamesz*..      NTF)r*   getattrgetlower
startswithsplit)rA   rD   rG   namer    r    r!   r@   h   s   
r@   sslobjssl.SSLObjectOptional[int]c              
   C  sZ   t | || z	t||| _W dS  ty, } ztd|  tjW  Y d}~S d}~ww )z&Select a certificate matching the SNI.zRejecting TLS connection: N)r   rB   r   r,   r   warningr   #ALERT_DESCRIPTION_UNRECOGNIZED_NAME)rR   r=   rA   er    r    r!   selector_sni_callbacky   s   rX   Nonec                 C  s
   || _ dS )z3Store the received SNI as sslobj.sanic_server_name.N)sanic_server_name)rR   r=   rA   r    r    r!   r      s   
r   c                   @  s$   e Zd ZU ded< edddZdS )	SanicSSLContextzdict[str, os.PathLike]rF   r   r   c                 C  s
   | |_ |S N	__class__)clsr   r    r    r!   create_from_ssl_context   s   z'SanicSSLContext.create_from_ssl_contextN)r   r   )__name__
__module____qualname____annotations__classmethodr`   r    r    r    r!   r[      s   
 r[   c                   @  s*   e Zd ZU dZded< dd Zdd ZdS )	r+   z9A wrapper for creating SSLContext with a sanic attribute.zdict[str, Any]rF   c           	      K  s   | dd p| }|d< | dd p| }|d< |dd }|r"|s&tdi }d|vrFtj|}dd	 |d
 D |d< dd |d D }t|||}| |_i |||_|S )Ncertificatecertr
   keyr   z*SSL dict needs filenames for cert and key.rG   c                 S  s   g | ]
\}}|d v r|qS ))DNSz
IP Addressr    ).0trQ   r    r    r!   
<listcomp>   s
    z&CertSimple.__new__.<locals>.<listcomp>subjectAltNamec                 S  s    i | ]}|D ]\}}||qqS r    r    )rj   itemkvr    r    r!   
<dictcomp>   s     z&CertSimple.__new__.<locals>.<dictcomp>subject)	poprM   r,   r   _ssl_test_decode_certr"   r^   rF   )	r_   rg   rh   kwr   r
   r   rr   r<   r    r    r!   __new__   s    
zCertSimple.__new__c                 K  s   d S r\   r    )r<   rg   rh   rv   r    r    r!   __init__   s   zCertSimple.__init__N)ra   rb   rc   __doc__rd   rw   rx   r    r    r    r!   r+      s
   
 r+   c                      s.   e Zd ZdZ fddZd fddZ  ZS )	r3   a$  Automatically select SSL certificate based on the hostname that the
    client is trying to access, via SSL SNI. Paths to certificate folders
    with privkey.pem and fullchain.pem in them should be provided, and
    will be matched in the order given whenever there is a new connection.
    c                   s   t  | S r\   )superrw   )r_   ctxsr]   r    r!   rw      s   zCertSelector.__new__r{   "Iterable[Optional[ssl.SSLContext]]c                   s   t    t| _g | _d | _g }t|D ]$\}}|sqtt|di 	dg }||7 }| j
| |dkr8|| _q|s?tdtdd|  d S )NrF   rG   r   z3No certificates with SubjectAlternativeNames found.zCertificate vhosts: z, )rz   rx   rX   r   r?   r>   	enumerater*   rL   rM   appendr,   r   infor   )r<   r{   	all_namesirA   rG   r]   r    r!   rx      s&   
zCertSelector.__init__)r{   r|   )ra   rb   rc   ry   rw   rx   __classcell__r    r    r]   r!   r3      s    )
r   r	   r
   r	   r   r	   r   r   r   r   )r#   r$   r   r%   )r/   r0   r   r%   )r6   r(   r   r   )r<   r3   r=   r(   )rA   rC   rD   r(   r   rE   )rR   rS   r=   r(   rA   r3   r   rT   )rR   rS   r=   r(   rA   r   r   rY   )
__future__r   r7   r   collections.abcr   typingr   r   r   	sanic.logr   r   r   r   r"   r.   r5   r)   rB   r@   rX   r   r'   r[   r+   r3   r    r    r    r!   <module>   s,    






	