a
    `~8                     @   sL  d 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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 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*dd Z+dd Z,dS ) zPlugin common functions.    N)util)List)achallenges)crypto_util)errors)
interfaces)reverter)	constants)
filesystem)os)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__0   s    zPlugin.__init__c                 C   s   dS )zAdd plugin arguments to the CLI argument parser.

        :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_arguments4   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 | g|R i |S )Nz--{0}{1})add_argumentformatr   )Zarg_name_no_prefixargskwargsr   parserr   r   r   F   s    z)Plugin.inject_parser_options.<locals>.add)r   )r   r%   r   r   r   r$   r   inject_parser_options>   s    zPlugin.inject_parser_optionsc                 C   s
   t | jS )r   )r   r   r   r   r   r   r   L   s    zPlugin.option_namespacec                 C   s
   | j | S )z'Option name (include plugin namespace).)r   )r   r   r   r   r   option_nameQ   s    zPlugin.option_namec                 C   s
   t | jS )r   )r   r   r'   r   r   r   r   U   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   destZ   s    zPlugin.destc                 C   s   t | j| |S )z0Find a configuration value for variable ``var``.)getattrr   r+   r)   r   r   r   conf`   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                       sl   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	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                    s8   t t| j|i | t| j| j| _t| j| _d S r   )	superr6   r   r   r   r   Zstorager   ZReverter)r   r"   r#   	__class__r   r   r   k   s    zInstaller.__init__Fc              
   C   s^   |r| j j}n| j j}z||| W n4 tjyX } ztt|W Y d}~n
d}~0 0 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:   p   s    
zInstaller.add_to_checkpointc              
   C   sJ   z| j | W n4 tjyD } ztt|W Y d}~n
d}~0 0 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   sH   z| j   W n4 tjyB } ztt|W Y d}~n
d}~0 0 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   sH   z| j   W n4 tjyB } ztt|W Y d}~n
d}~0 0 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   sJ   z| j | W n4 tjyD } ztt|W Y d}~n
d}~0 0 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   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   rF   rG   r   rH   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_filerI   rJ   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   r5   rI   rJ   rL   __classcell__r   r   r8   r   r6   e   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   rO   rP   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       :T)rP   r   )
startswithrfindlen	partition)r   Zstr_addrZendIndexZhostportrO   r   r   r   
fromstring   s    

 
zAddr.fromstringc                 C   s   | j d rd| j  S | j d S )NrD   z%s:%sr   rO   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   )rP   get_ipv6_explodedrO   r'   r   r   r   normalized_tuple   s    zAddr.normalized_tuplec                 C   s    t || jr|  | kS dS )NF)
isinstancer9   r_   )r   otherr   r   r   __eq__   s    zAddr.__eq__c                 C   s
   t | jS r   )hashrO   r'   r   r   r   __hash__   s    zAddr.__hash__c                 C   s
   | j d S )z Return addr part of Addr object.r   r\   r'   r   r   r   get_addr   s    zAddr.get_addrc                 C   s
   | j d S )zReturn port.rD   r\   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   rO   rP   )r   rZ   r   r   r   get_addr_obj  s    zAddr.get_addr_objc                 C   s   | d}|d}| |S )z7Return IPv6 address in normalized form, helper functionrQ   rR   )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 formrU   r   rS   )rP   rG   rl   rO   r'   r   r   r   r^     s    zAddr.get_ipv6_explodedc                 C   s   g d}| d}t|t|kr2|dt| }d}t|D ]N\}}|sPd}q>t|dkrf|d}|sxt|||< q>t|||t| < q>|S )z#Explode IPv6 address for comparison)0rm   rm   rm   rm   rm   rm   rm   rU   r   FTrD   rm   )splitrX   	enumeraterh   r=   )r   rk   resultZ	addr_listZappend_to_endiblockr   r   r   rj     s    

zAddr._explode_ipv6N)F)r.   r/   r0   r1   r   r4   r[   r]   r_   rb   rd   re   rf   rg   rl   r^   rj   r   r   r   r   rN      s   

rN   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   rt   r   r   r   r   :  s    zChallengePerformer.__init__Nc                 C   s$   | j | |du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)ru   appendrv   )r   Z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   performK  s    zChallengePerformer.perform)N)r.   r/   r0   r1   r   ry   r{   r   r   r   r   rs   .  s   
rs   c                    s   t fdd  fdd}tjs>|  dS t }|krTdS ||v rd|  n`tjrtd}| }W d   n1 s0    Y  |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                     s8   t d} |   W d    n1 s*0    Y  d S )Nw)openwrite)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_filed  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   rF   isfiler}   readloggerZwarning)r   r   r   Z
all_hashesr   Zactive_file_digestr   Zsaved_digestr   )r   r   r   r   r   r   rK   V  s(    

&rK   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
   chmodr	   ZCONFIG_DIRS_MODEpkg_resourcesZresource_filenamer   rF   rG   r   Zcopytree)Ztest_dirpkgr   Ztemp_dirrH   Zwork_dirZtest_configsr   r   r   	dir_setup  s    r   )-r1   Zloggingrer   r   Zjosepyr   r2   r   Zzope.interfacezopeZacme.magic_typingr   Zcertbotr   r   r   r   r   Zcertbot._internalr	   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   rN   rs   rK   r   r   r   r   r   <module>   sB   
:gb(2