U
    ]J                     @   s  d 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Zddl	Z
ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZ eeZdd Zdd Z e!dZ"e!dej#Z$e
j%&ej'G dd de(Z)G dd de)Z*G dd de(Z+G dd de(Z,G dd de,Z-dd Z.d d! Z/G d"d# d#e(Z0e0ej1e ej1e< dS )$zPlugin common functions.    N)util)List)achallenges)	constants)crypto_util)errors)
interfaces)reverter)os)
filesystem)PluginStoragec                 C   s   | d S )9ArgumentParser options namespace (prefix of all options).- namer   r   8/usr/lib/python3/dist-packages/certbot/plugins/common.pyoption_namespace   s    r   c                 C   s   |  ddd S );ArgumentParser dest namespace (prefix of all destinations).r   _)replacer   r   r   r   dest_namespace$   s    r   zX(^127\.0\.0\.1)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^192\.168\.)z3^(([a-z0-9]|[a-z0-9][a-z0-9\-]*[a-z0-9])\.)*[a-z]+$c                   @   sb   e Zd ZdZdd Zejdd Zedd Z	e
dd	 Zd
d Ze
dd Zdd Zdd ZdS )PluginzGeneric plugin.c                 C   s   || _ || _d S N)configr   )selfr   r   r   r   r   __init__5   s    zPlugin.__init__c                 C   s   dS )a  Add plugin arguments to the CLI argument parser.

        NOTE: If some of your flags interact with others, you can
        use cli.report_config_interaction to register this to ensure
        values are correctly saved/overridable during renewal.

        :param callable add: Function that proxies calls to
            `argparse.ArgumentParser.add_argument` prepending options
            with unique plugin name prefix.

        Nr   )clsaddr   r   r   add_parser_arguments9   s    zPlugin.add_parser_argumentsc                    s    fdd}|  |S )zYInject parser options.

        See `~.IPlugin.inject_parser_options` for docs.

        c                    s   j dt | f||S )Nz--{0}{1})add_argumentformatr   )Zarg_name_no_prefixargskwargsr   parserr   r   r   O   s    z)Plugin.inject_parser_options.<locals>.add)r   )r   r%   r   r   r   r$   r   inject_parser_optionsG   s    zPlugin.inject_parser_optionsc                 C   s
   t | jS )r   )r   r   r   r   r   r   r   V   s    zPlugin.option_namespacec                 C   s
   | j | S )z'Option name (include plugin namespace).)r   )r   r   r   r   r   option_name[   s    zPlugin.option_namec                 C   s
   t | jS )r   )r   r   r'   r   r   r   r   _   s    zPlugin.dest_namespacec                 C   s   | j |dd S )z.Find a destination for given variable ``var``.r   r   )r   r   r   varr   r   r   destd   s    zPlugin.destc                 C   s   t | j| |S )z0Find a configuration value for variable ``var``.)getattrr   r+   r)   r   r   r   confj   s    zPlugin.confN)__name__
__module____qualname____doc__r   	jose_utilabstractclassmethodr   classmethodr&   propertyr   r(   r   r+   r-   r   r   r   r   r   /   s   



r   c                       st   e Zd ZdZ fddZdddZdd Zd	d
 Zdd ZdddZ	dd Z
edd Zedd Zdd Z  ZS )	InstallerzAn installer base class with reverter and ssl_dhparam methods defined.

    Installer plugins do not have to inherit from this class.

    c                    s4   t t| j|| t| j| j| _t| j| _d S r   )	superr6   r   r   r   r   Zstorager	   ZReverter)r   r"   r#   	__class__r   r   r   u   s    zInstaller.__init__Fc              
   C   s\   |r| j j}n| j j}z||| W n2 tjk
rV } ztt|W 5 d}~X Y nX dS )a  Add files to a checkpoint.

        :param set save_files: set of filepaths to save
        :param str save_notes: notes about changes during the save
        :param bool temporary: True if the files should be added to a
            temporary checkpoint rather than a permanent one. This is
            usually used for changes that will soon be reverted.

        :raises .errors.PluginError: when unable to add to checkpoint

        N)r	   Zadd_to_temp_checkpointadd_to_checkpointr   ReverterErrorPluginErrorstr)r   Z
save_filesZ
save_notesZ	temporaryZcheckpoint_funcerrr   r   r   r:   z   s    
zInstaller.add_to_checkpointc              
   C   sH   z| j | W n2 tjk
rB } ztt|W 5 d}~X Y nX dS )zTimestamp and save changes made through the reverter.

        :param str title: Title describing checkpoint

        :raises .errors.PluginError: when an error occurs

        N)r	   finalize_checkpointr   r;   r<   r=   )r   titler>   r   r   r   r?      s    zInstaller.finalize_checkpointc              
   C   sF   z| j   W n2 tjk
r@ } ztt|W 5 d}~X Y nX dS )zRevert all previously modified files.

        Reverts all modified files that have not been saved as a checkpoint

        :raises .errors.PluginError: If unable to recover the configuration

        N)r	   recovery_routiner   r;   r<   r=   r   r>   r   r   r   rA      s    zInstaller.recovery_routinec              
   C   sF   z| j   W n2 tjk
r@ } ztt|W 5 d}~X Y nX dS )zkRollback temporary checkpoint.

        :raises .errors.PluginError: when unable to revert config

        N)r	   revert_temporary_configr   r;   r<   r=   rB   r   r   r   rC      s    z!Installer.revert_temporary_config   c              
   C   sH   z| j | W n2 tjk
rB } ztt|W 5 d}~X Y nX dS )zRollback saved checkpoints.

        :param int rollback: Number of checkpoints to revert

        :raises .errors.PluginError: If there is a problem with the input or
            the function is unable to correctly revert the configuration

        N)r	   rollback_checkpointsr   r;   r<   r=   )r   Zrollbackr>   r   r   r   rE      s    	zInstaller.rollback_checkpointsc                 C   sx   t jdtdd t  V t ddt z| j  W n2 tjk
rh } zt	t
|W 5 d}~X Y nX W 5 Q R X dS )zShow all of the configuration changes that have taken place.

        :raises .errors.PluginError: If there is a problem while processing
            the checkpoints directories.

        zThe view_config_changes method is no longer part of Certbot's plugin interface, has been deprecated, and will be removed in a future release.   
stacklevelignorez.*view_config_changesN)warningswarnDeprecationWarningcatch_warningsfilterwarningsr	   view_config_changesr   r;   r<   r=   rB   r   r   r   rO      s     
zInstaller.view_config_changesc                 C   s   t j| jjtjS )z(Full absolute path to ssl_dhparams file.)r
   pathjoinr   
config_dirr   ZSSL_DHPARAMS_DESTr'   r   r   r   ssl_dhparams   s    zInstaller.ssl_dhparamsc                 C   s   t j| jjtjS )z:Full absolute path to digest of updated ssl_dhparams file.)r
   rP   rQ   r   rR   r   ZUPDATED_SSL_DHPARAMS_DIGESTr'   r   r   r   updated_ssl_dhparams_digest   s    z%Installer.updated_ssl_dhparams_digestc                 C   s   t | j| jtjtjS )zJCopy Certbot's ssl_dhparams file into the system's config dir if required.)install_version_controlled_filerS   rT   r   ZSSL_DHPARAMS_SRCZALL_SSL_DHPARAMS_HASHESr'   r   r   r   install_ssl_dhparams   s    zInstaller.install_ssl_dhparams)F)rD   )r.   r/   r0   r1   r   r:   r?   rA   rC   rE   rO   r5   rS   rT   rV   __classcell__r   r   r8   r   r6   o   s   



r6   c                   @   sv   e Zd ZdZdddZe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d Zdd Zdd ZdS )AddrzRepresents an virtual host address.

    :param str addr: addr part of vhost address
    :param str port: port number or \*, or ""

    Fc                 C   s   || _ || _d S r   )tupipv6)r   rY   rZ   r   r   r   r      s    zAddr.__init__c                 C   s   | drh|d}|d|d  }d}t||d krX||d  dkrX||d d }| ||fdd	S |d}| |d
 |d fS dS )zInitialize Addr from string.[]NrD    rF   :T)rZ   r   )
startswithrfindlen	partition)r   Zstr_addrZendIndexZhostportrY   r   r   r   
fromstring   s    

 
zAddr.fromstringc                 C   s   | j d rd| j  S | j d S )NrD   z%s:%sr   rY   r'   r   r   r   __str__  s    

zAddr.__str__c                 C   s   | j r|  | jd fS | jS )z5Normalized representation of addr/port tuple
        rD   )rZ   get_ipv6_explodedrY   r'   r   r   r   normalized_tuple	  s    zAddr.normalized_tuplec                 C   s    t || jr|  | kS dS )NF)
isinstancer9   rh   )r   otherr   r   r   __eq__  s    zAddr.__eq__c                 C   s
   t | jS r   )hashrY   r'   r   r   r   __hash__  s    zAddr.__hash__c                 C   s
   | j d S )z Return addr part of Addr object.r   re   r'   r   r   r   get_addr  s    zAddr.get_addrc                 C   s
   | j d S )zReturn port.rD   re   r'   r   r   r   get_port  s    zAddr.get_portc                 C   s   |  | jd |f| jS )z6Return new address object with same addr and new port.r   )r9   rY   rZ   )r   rc   r   r   r   get_addr_obj#  s    zAddr.get_addr_objc                 C   s   | d}|d}| |S )z7Return IPv6 address in normalized form, helper functionr[   r\   )lstriprstrip_explode_ipv6)r   addrr   r   r   _normalize_ipv6'  s    

zAddr._normalize_ipv6c                 C   s    | j rd| | jd S dS )zReturn IPv6 in normalized formr^   r   r]   )rZ   rQ   ru   rY   r'   r   r   r   rg   -  s    zAddr.get_ipv6_explodedc                 C   s   ddddddddg}| d}t|t|kr>|dt| }d}t|D ]P\}}|s^d}qJnt|dkrt|d}|st|||< qJt|||t| < qJ|S )z#Explode IPv6 address for comparison0r^   r   FTrD   )splitra   	enumeraterq   r=   )r   rt   resultZ	addr_listZappend_to_endiblockr   r   r   rs   3  s    

zAddr._explode_ipv6N)F)r.   r/   r0   r1   r   r4   rd   rf   rh   rk   rm   rn   ro   rp   ru   rg   rs   r   r   r   r   rX      s   

rX   c                   @   s*   e Zd ZdZdd Zd	ddZdd ZdS )
ChallengePerformerav  Abstract base for challenge performers.

    :ivar configurator: Authenticator and installer plugin
    :ivar achalls: Annotated challenges
    :vartype achalls: `list` of `.KeyAuthorizationAnnotatedChallenge`
    :ivar indices: Holds the indices of challenges from a larger array
        so the user of the class doesn't have to.
    :vartype indices: `list` of `int`

    c                 C   s   || _ g | _g | _d S r   )configuratorachallsindicesr   r}   r   r   r   r   X  s    zChallengePerformer.__init__Nc                 C   s$   | j | |dk	r | j| dS )zStore challenge to be performed when perform() is called.

        :param .KeyAuthorizationAnnotatedChallenge achall: Annotated
            challenge.
        :param int idx: index to challenge in a larger array

        N)r~   appendr   )r   achallidxr   r   r   	add_chall]  s    zChallengePerformer.add_challc                 C   s
   t  dS )zPerform all added challenges.

        :returns: challenge responses
        :rtype: `list` of `acme.challenges.KeyAuthorizationChallengeResponse`


        N)NotImplementedErrorr'   r   r   r   performi  s    zChallengePerformer.perform)N)r.   r/   r0   r1   r   r   r   r   r   r   r   r|   L  s   
r|   c                       sB   e Zd ZdZ fddZdd Zdd Zdd	 ZdddZ  Z	S )TLSSNI01z1Abstract base for TLS-SNI-01 challenge performersc                    s(   t t| | tj|jjd| _d S )Nz!le_tls_sni_01_cert_challenge.conf)	r7   r   r   r
   rP   rQ   r   rR   Zchallenge_confr   r8   r   r   r   x  s
     zTLSSNI01.__init__c                 C   s    t j| jjj|jdd S )zReturns standardized name for challenge certificate.

        :param .KeyAuthorizationAnnotatedChallenge achall: Annotated
            tls-sni-01 challenge.

        :returns: certificate file name
        :rtype: str

        tokenz.crtr
   rP   rQ   r}   r   work_dirZchallencoder   r   r   r   r   get_cert_path~  s    
zTLSSNI01.get_cert_pathc                 C   s    t j| jjj|jdd S )z'Get standardized path to challenge key.r   z.pemr   r   r   r   r   get_key_path  s    zTLSSNI01.get_key_pathc                 C   s   | |jjdS )z.Returns z_domain (SNI) name for the challenge.zutf-8)responseZaccount_keyZz_domaindecoder   r   r   r   get_z_domain  s    zTLSSNI01.get_z_domainNc              	   C   s   |  |}| |}| jjd| | jjd| |j|d\}\}}tjtjj	|}tj
tjj	|}	t|d}
|
| W 5 Q R X tj|ddd}||	 W 5 Q R X |S )z-Generate and write out challenge certificate.T)cert_keywb   )chmod)r   r   r}   r	   Zregister_file_creationZresponse_and_validationOpenSSLZcryptoZdump_certificateZFILETYPE_PEMZdump_privatekeyopenwriter   Z	safe_open)r   r   r   Z	cert_pathZkey_pathr   ZcertkeyZcert_pemZkey_pemZcert_chall_fdZkey_filer   r   r   _setup_challenge_cert  s(    

  zTLSSNI01._setup_challenge_cert)N)
r.   r/   r0   r1   r   r   r   r   r   rW   r   r   r8   r   r   t  s   r   c              	      s   t fdd  fdd}tjs>|  dS t }|krTdS ||krd|  nLtjrtd}| }W 5 Q R X |krdS    td dS )a  Copy a file into an active location (likely the system's config dir) if required.

       :param str dest_path: destination path for version controlled file
       :param str digest_path: path to save a digest of the file in
       :param str src_path: path to version controlled file found in distribution
       :param list all_hashes: hashes of every released version of the file
    c               	      s$   t d} |   W 5 Q R X d S )Nw)r   r   )f)current_hashdigest_pathr   r   _write_current_hash  s    z<install_version_controlled_file.<locals>._write_current_hashc                      s   t     d S r   )shutilZcopyfiler   )r   	dest_pathsrc_pathr   r   _install_current_file  s    z>install_version_controlled_file.<locals>._install_current_fileNrzh%s has been manually modified; updated file saved to %s. We recommend updating %s for security purposes.)	r   Z	sha256sumr
   rP   isfiler   readloggerZwarning)r   r   r   Z
all_hashesr   Zactive_file_digestr   Zsaved_digestr   )r   r   r   r   r   r   rU     s,    

  rU   c                 C   s   dd }|d}|d}|d}t |tj t |tj t |tj t|tjd| }t	j
|tj|| dd |||fS )	z5Setup the directories necessary for the configurator.c                 S   s   t t| S )a  Return the real path of a temp directory with the specified prefix

        Some plugins rely on real paths of symlinks for working correctly. For
        example, certbot-apache uses real paths of configuration files to tell
        a virtual host from another. On systems where TMP itself is a symbolic
        link, (ex: OS X) such plugins will be confused. This function prevents
        such a case.
        )r   realpathtempfileZmkdtemp)prefixr   r   r   expanded_tempdir  s    	z#dir_setup.<locals>.expanded_tempdirZtempr   ZworkZtestdataT)Zsymlinks)r   r   r   ZCONFIG_DIRS_MODEpkg_resourcesZresource_filenamer
   rP   rQ   r   Zcopytree)Ztest_dirpkgr   Ztemp_dirrR   r   Ztest_configsr   r   r   	dir_setup  s"       r   c                   @   s8   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZdS )_TLSSNI01DeprecationModulez
    Internal class delegating to a module, and displaying warnings when
    attributes related to TLS-SNI-01 are accessed.
    c                 C   s   || j d< d S N_module)__dict__)r   moduler   r   r   r     s    z#_TLSSNI01DeprecationModule.__init__c                 C   s$   |dkrt jdtdd t| j|S )Nr   z0TLSSNI01 is deprecated and will be removed soon.rF   rG   )rJ   rK   rL   r,   r   r   attrr   r   r   __getattr__  s     z&_TLSSNI01DeprecationModule.__getattr__c                 C   s   t | j|| d S r   )setattrr   )r   r   valuer   r   r   __setattr__  s    z&_TLSSNI01DeprecationModule.__setattr__c                 C   s   t | j| d S r   )delattrr   r   r   r   r   __delattr__  s    z&_TLSSNI01DeprecationModule.__delattr__c                 C   s   dgt | j S r   )dirr   r'   r   r   r   __dir__  s    z"_TLSSNI01DeprecationModule.__dir__N)	r.   r/   r0   r1   r   r   r   r   r   r   r   r   r   r      s   r   )2r1   Zloggingrer   sysr   rJ   r   r   Zzope.interfacezopeZjosepyr   r2   Zacme.magic_typingr   Zcertbotr   r   r   r   r   r	   Zcertbot.compatr
   r   Zcertbot.plugins.storager   Z	getLoggerr.   r   r   r   compileZprivate_ips_regex
IGNORECASEZhostname_regexZ	interfaceZimplementerZIPluginobjectr   r6   rX   r|   r   rU   r   r   modulesr   r   r   r   <module>   sR   
 ?{b(92!