U
    /e6                     @  s   d dl mZ d dlZd dl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Zejdkshejdkrddd	d
ddZddd	d
ddZn$ddd	d
ddZddd	d
ddZG dd dZdS )    )annotationsN)get_template)Security)   
   )   r   r      zssl.SSLContextzssl.TLSVersionNone)ctxversionreturnc                 C  s
   || _ d S N)minimum_versionr
   r    r   8/tmp/pip-unpacked-wheel-g426oqom/distributed/security.py_set_minimum_version   s    r   c                 C  s
   || _ d S r   )maximum_versionr   r   r   r   _set_maximum_version   s    r   c                 C  s@   |t jjk	rtd||  jt jt jB t jB t jB O  _d S NzUnsupported TLS/SSL version: )	ssl
TLSVersionTLSv1_2
ValueErroroptionsOP_NO_SSLv2OP_NO_SSLv3OP_NO_TLSv1OP_NO_TLSv1_1r   r   r   r   r   $   s
    c                 C  s   |t jjk	rtd|d S r   )r   r   r   r   r   r   r   r   r   /   s    c                   @  st   e Zd ZdZdZdddZedd Zdd	 Zdd
dZ	dd Z
dd Zdd Zdd Zdd Zdd Zdd ZdS )r   a4  Security configuration for a Dask cluster.

    Default values are loaded from Dask's configuration files, and can be
    overridden in the constructor.

    Parameters
    ----------
    require_encryption : bool, optional
        Whether TLS encryption is required for all connections.
    tls_ca_file : str, optional
        Path to a CA certificate file encoded in PEM format.
    tls_ciphers : str, optional
        An OpenSSL cipher string of allowed ciphers. If not provided, the
        system defaults will be used.
    tls_min_version : ssl.TLSVersion, optional
        The minimum TLS version to support. Defaults to TLS 1.2.
    tls_max_version : ssl.TLSVersion, optional
        The maximum TLS version to support. Defaults to the maximum version
        supported.
    tls_client_cert : str, optional
        Path to a certificate file for the client, encoded in PEM format.
    tls_client_key : str, optional
        Path to a key file for the client, encoded in PEM format.
        Alternatively, the key may be appended to the cert file, and this
        parameter be omitted.
    tls_scheduler_cert : str, optional
        Path to a certificate file for the scheduler, encoded in PEM format.
    tls_scheduler_key : str, optional
        Path to a key file for the scheduler, encoded in PEM format.
        Alternatively, the key may be appended to the cert file, and this
        parameter be omitted.
    tls_worker_cert : str, optional
        Path to a certificate file for a worker, encoded in PEM format.
    tls_worker_key : str, optional
        Path to a key file for a worker, encoded in PEM format.
        Alternatively, the key may be appended to the cert file, and this
        parameter be omitted.
    extra_conn_args : mapping, optional
        Mapping with keyword arguments to pass down to connections.
    )require_encryptiontls_ca_filetls_cipherstls_min_versiontls_max_versiontls_client_keytls_client_certtls_scheduler_keytls_scheduler_certtls_worker_keytls_worker_certextra_conn_argsNc                 K  s  t jdk r tdt j dt t|| j}|rDt	dt
| |di | _|d krftjd}|d krvt|}|| _| |dd | |d	d
t jj | |dd | |dd | |dd | |dd | |dd | |dd | |dd | |dd d S )N)r   r   r   zsupport for z7 is deprecated, and will be removed in a future releasezUnknown parameters: %rr*   z#distributed.comm.require-encryptionr!   zdistributed.comm.tls.ciphersr"   z distributed.comm.tls.min-versionr#   z distributed.comm.tls.max-versionr    zdistributed.comm.tls.ca-filer$   zdistributed.comm.tls.client.keyr%   z distributed.comm.tls.client.certr&   z"distributed.comm.tls.scheduler.keyr'   z#distributed.comm.tls.scheduler.certr(   zdistributed.comm.tls.worker.keyr)   z distributed.comm.tls.worker.cert)r   OPENSSL_VERSION_INFOwarningswarnOPENSSL_VERSIONDeprecationWarningset
difference	__slots__	TypeErrorsortedpopr*   daskconfiggetboolr   
_set_field_set_tls_version_fieldr   r   )selfr   kwargsextrar   r   r   __init__r   sR    
    zSecurity.__init__c                 K  sR  zDddl m} ddlm} ddlm}m} ddlm} ddl	m
} W n tk
r`   tdY nX |jdd	| d
}|j|jj|jj| d }	|||jdg}
||dg}tj }| |
|
j|dd|  |! "|#|tj$dd %||& | }|'|jj }| f d||	||	||	|d|S )aJ  Create a new temporary Security object.

        This creates a new self-signed key/cert pair suitable for securing
        communication for all roles in a Dask cluster. These keys/certs exist
        only in memory, and are stored in this object.

        This method requires the library ``cryptography`` be installed.
        r   )x509)default_backend)hashesserialization)rsa)NameOIDz_Using `Security.temporary` requires `cryptography`, please install it using either pip or condai  i   )Zpublic_exponentZkey_sizebackend)encodingformatZencryption_algorithmzdask-internalF)criticalim  )daysT)r   r    r$   r%   r&   r'   r(   r)   )(Zcryptographyr@   Zcryptography.hazmat.backendsrA   Zcryptography.hazmat.primitivesrB   rC   Z)cryptography.hazmat.primitives.asymmetricrD   Zcryptography.x509.oidrE   ImportErrorZgenerate_private_keyZprivate_bytesEncodingZPEMZPrivateFormatZPKCS8ZNoEncryptiondecodeNameZNameAttributeZCOMMON_NAMEZSubjectAlternativeNameZDNSNamedatetimeutcnowZCertificateBuilderZsubject_nameZissuer_nameadd_extensionZ
public_keyZserial_numberZrandom_serial_numberZnot_valid_beforeZnot_valid_after	timedeltasignSHA256Zpublic_bytes)clsr=   r@   rA   rB   rC   rD   rE   keyZkey_contentsZdask_internalZaltnamesnowcertZcert_contentsr   r   r   	temporary   sv    

  

   	zSecurity.temporaryc                 C  s.   ||kr|| }nt j|}t| || d S r   )r6   r7   r8   setattr)r<   r=   fieldconfig_namevalr   r   r   r:      s    
zSecurity._set_fieldc                 C  s   ||krT|| }d t jjt jjh}||krFt| d|dt| |d kr|}nN|t jjt jjd}tj|}||kr|| }nt| d|dt| t	| || d S )N=z# is not supported, expected one of )Ng333333?g?)
r   r   r   TLSv1_3r   listr6   r7   r8   rZ   )r<   r=   r[   r\   defaultr]   Zvalidr   r   r   r;      s(    
zSecurity._set_tls_version_fieldc                 C  s   t | j}|d i }|D ]^}t| |}|d k	rt|trNd|krNd||< qt|trrdtj| d||< q|||< q|S )Nr*   
zTemporary (In-memory)zLocal ())	r4   r2   removegetattr
isinstancestrospathabspath)r<   keysattrkr]   r   r   r   _attr_to_dict   s    





zSecurity._attr_to_dictc                 C  s(   |   }dddd | D  d S )Nz	Security(z, c                 s  s    | ]\}}| d | V  qdS )r^   Nr   ).0rV   valuer   r   r   	<genexpr>  s     z$Security.__repr__.<locals>.<genexpr>rc   )rn   joinitems)r<   rl   r   r   r   __repr__
  s    zSecurity.__repr__c                 C  s   t dj|  dS )Nzsecurity.html.j2)security)r   renderrn   )r<   r   r   r   _repr_html_  s    zSecurity._repr_html_c                 C  s<   |dkrt d|| j| jt| d| t| d| dS )zR
        Return the TLS configuration for the given role, as a flat dict.
        >   client	schedulerworkerzunknown role ztls_%s_certz
tls_%s_key)ca_fileciphersrX   rV   )r   r    r!   re   )r<   roler   r   r   get_tls_config_for_role  s    z Security.get_tls_config_for_rolec              
   C  sj  | drf| drf|d }|d  }}| d }}d|krRtj||d}ntj||d}t|| j | jd k	rt|| j d|k}	|d k	od|k}
|	s|
r,t x}|	rt	j
|d}t|d}|| W 5 Q R X |
rt	j
|d	}t|d}|| W 5 Q R X ||| W 5 Q R X n||| tj|_d
|_| drb|| d |S d S )Nr{   rX   rV   rb   )purposecadata)r   cafilezdask.crtwzdask.pemFr|   )r8   r   create_default_contextr   r"   r#   r   tempfileTemporaryDirectoryrh   ri   rr   openwriteload_cert_chainCERT_REQUIREDverify_modecheck_hostnameset_ciphers)r<   tlsr   caZ	cert_pathrX   Zkey_pathrV   r
   Zcert_in_memoryZkey_in_memorytempdirfr   r   r   _get_tls_context"  s:    


zSecurity._get_tls_contextc                 C  s&   |  |}| |tjj| j| jdS )zh
        Get the *connection_args* argument for a connect() call with
        the given *role*.
        )ssl_contextr   r*   )r~   r   r   PurposeSERVER_AUTHr   r*   r<   r}   r   r   r   r   get_connection_argsO  s
    
zSecurity.get_connection_argsc                 C  s"   |  |}| |tjj| jdS )zg
        Get the *connection_args* argument for a listen() call with
        the given *role*.
        )r   r   )r~   r   r   r   CLIENT_AUTHr   r   r   r   r   get_listen_args[  s    
zSecurity.get_listen_args)N)N)__name__
__module____qualname____doc__r2   r?   classmethodrY   r:   r;   rn   rt   rw   r~   r   r   r   r   r   r   r   r   9   s   )
(
<
-r   )
__future__r   rO   rh   r   sysr   r,   r6   Zdask.widgetsr   __all__version_infor+   r   r   r   r   r   r   r   <module>   s   
