U
    ˜­“]e‹ ã                   @   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m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mZmZmZ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' ddl%m(Z( ddl%m)Z) ddl%m*Z* ddl%m+Z+ e ,e-¡Z.ej/ 0ej1ej2¡ej/ 3ej4¡G dd„ de j5ƒƒƒZ6e$ 7e6¡ dS )zApache Configurator.é    N)Údefaultdict)Ú
challenges)ÚDefaultDictÚDictÚListÚSetÚUnion)Úerrors)Ú
interfaces)Úutil)Ú"KeyAuthorizationAnnotatedChallenge)Ú
filesystem)Úos)Úcommon)Úpath_surgery)ÚAutoHSTSEnhancement)Úapache_util)Ú	constants)Údisplay_ops)Úhttp_01)Úobj)Úparserc                       sž  e Zd ZdZdZej d¡dkr(ed7 Zedddd	d
d
dgd
dgd
dgdddddde	 
dd¡dZdd„ Zdd„ Zedd„ ƒZ‡ fdd„Zedd„ ƒZedd„ ƒZd d!„ Zd×d"d#„Z‡ fd$d%„Zd&d'„ ZdØ‡ fd)d*„	Zd+d,„ Zd-d.„ Zd/d0„ ZdÙd1d2„ZdÚd4d5„Zd6d7„ Zd8d9„ ZdÛd:d;„Z d<d=„ Z!dÜd>d?„Z"dÝd@dA„Z#dBdC„ Z$dÞdEdF„Z%dßdGdH„Z&dIdJ„ Z'dKdL„ Z(dMdN„ Z)dOdP„ Z*dQdR„ Z+dSdT„ Z,dUdV„ Z-dWdX„ Z.dYdZ„ Z/dàd[d\„Z0dád]d^„Z1d_d`„ Z2dadb„ Z3dcdd„ Z4dedf„ Z5dgdh„ Z6didj„ Z7dkdl„ Z8dmdn„ Z9dodp„ Z:dqdr„ Z;dsdt„ Z<dudv„ Z=dwdx„ Z>dydz„ Z?d{d|„ Z@d}d~„ ZAdd€„ ZBdd‚„ ZCdƒd„„ ZDd…d†„ ZEd‡dˆ„ ZFd‰dŠ„ ZGd‹dŒ„ ZHddŽ„ ZIdd„ ZJdâd‘d’„ZKd“d”„ ZLd•d–„ ZMd—d˜„ ZNd™dš„ ZOd›dœ„ ZPddž„ ZQdŸd „ ZRd¡d¢„ ZSd£d¤„ ZTd¥d¦„ ZUd§d¨„ ZVd©dª„ ZWd«d¬„ ZXd­d®„ ZYd¯d°„ ZZd±d²„ Z[d³d´„ Z\dãdµd¶„Z]d·d¸„ Z^däd¹dº„Z_d»d¼„ Z`d½d¾„ Zad¿dÀ„ ZbdÁdÂ„ ZcdÃdÄ„ ZddÅdÆ„ ZedÇdÈ„ ZfdÉdÊ„ ZgdËdÌ„ ZhdÍdÎ„ ZidÏdÐ„ ZjdÑdÒ„ ZkdÓdÔ„ ZldÕdÖ„ Zm‡  ZnS )åÚApacheConfiguratora·  Apache configurator.

    :ivar config: Configuration.
    :type config: :class:`~certbot.interfaces.IConfig`

    :ivar parser: Handles low level parsing
    :type parser: :class:`~certbot_apache.parser`

    :ivar tup version: version of Apache
    :ivar list vhosts: All vhosts found in the configuration
        (:class:`list` of :class:`~certbot_apache.obj.VirtualHost`)

    :ivar dict assoc: Mapping between domains and vhosts

    zApache Web Server pluginÚCERTBOT_DOCSÚ1z (Please note that the default values of the Apache plugin options change depending on the operating system Certbot is run on.)z/etc/apache2z/etc/apache2/sites-availableÚ*z/var/log/apache2Z
apache2ctlz-vZgracefulZ
configtestNz-le-ssl.confFÚcertbot_apachezoptions-ssl-apache.conf)Úserver_rootÚ
vhost_rootZvhost_filesÚ	logs_rootÚctlÚversion_cmdÚrestart_cmdÚconftest_cmdÚenmodÚdismodÚle_vhost_extÚhandle_modulesÚhandle_sitesÚchallenge_locationÚMOD_SSL_CONF_SRCc                 C   s   | j  |¡S )zGet a value from options)ÚoptionsÚget)ÚselfÚkey© r/   ú=/usr/lib/python3/dist-packages/certbot_apache/configurator.pyÚoptionu   s    zApacheConfigurator.optionc              
   C   s¢   ddddddddd	d
g
}|D ]D}|   | dd¡¡dk	rP|   | dd¡¡| j|< q| j| | j|< q|  d
¡| jd d< |  d
¡| jd d< |  d
¡| jd d< dS )zw
        Set the values possibly changed by command line parameters to
        OS_DEFAULTS constant dictionary
        r$   r%   r&   r   r   r   r)   r'   r(   r    Ú_ú-Nr!   r   r"   r#   )ÚconfÚreplacer+   ÚOS_DEFAULTSr1   )r-   ZoptsÚor/   r/   r0   Ú_prepare_optionsy   s    
   þz#ApacheConfigurator._prepare_optionsc                 C   sâ   t j d¡dkrtj}n| j}|d|d dd |d|d dd |d|d	 d
d |d|d dd |dd dd |d|d dd |d|d dd |d|d dd |d|d dd |d|d dd tj|ddd  d S )!Nr   r   r$   z#Path to the Apache 'a2enmod' binary)ÚdefaultÚhelpr%   z$Path to the Apache 'a2dismod' binaryzle-vhost-extr&   z!SSL vhost configuration extensionzserver-rootr   zApache server root directoryú
vhost-rootz,Apache server VirtualHost configuration rootz	logs-rootr   zApache server logs directoryzchallenge-locationr)   z*Directory path for challenge configurationzhandle-modulesr'   zULet installer handle enabling required modules for you (Only Ubuntu/Debian currently)zhandle-sitesr(   zJLet installer handle enabling sites for you (Only Ubuntu/Debian currently)r    z"Full path to Apache control scriptzinit-scripté   )Zargument_nameÚnargs)r   Úenvironr,   r   r6   r   Zadd_deprecated_argument)ÚclsÚaddZDEFAULTSr/   r/   r0   Úadd_parser_arguments   sN    
ÿ
ÿ
ÿ
ÿÿ
ÿþ
ÿ
ÿ
ÿ  ÿz'ApacheConfigurator.add_parser_argumentsc                    sŠ   |  dd¡}tt| ƒj||Ž tƒ | _tƒ | _tƒ | _t	tƒ| _
i | _d| _d| _d| _|| _d| _t | j¡| _| j| j| jdœ| _dS )zšInitialize an Apache Configurator.

        :param tup version: version of Apache as a tuple (2, 4, 7)
            (used mostly for unittesting)

        ÚversionNÚ F)Úredirectúensure-http-headerústaple-ocsp)ÚpopÚsuperr   Ú__init__ÚdictÚassocÚsetÚ
_chall_outÚ_wildcard_vhostsr   Ú_enhanced_vhostsÚ	_autohstsÚ
save_notesÚ	_preparedr   rB   ÚvhostsÚcopyÚdeepcopyr6   r+   Ú_enable_redirectÚ_set_http_headerÚ_enable_ocsp_staplingÚ_enhance_func)r-   ÚargsÚkwargsrB   ©Ú	__class__r/   r0   rI   ´   s"    
þzApacheConfigurator.__init__c                 C   s   t j | jjtj¡S )z-Full absolute path to SSL configuration file.)r   ÚpathÚjoinÚconfigÚ
config_dirr   ZMOD_SSL_CONF_DEST©r-   r/   r/   r0   Úmod_ssl_confÖ   s    zApacheConfigurator.mod_ssl_confc                 C   s   t j | jjtj¡S )z?Full absolute path to digest of updated SSL configuration file.)r   r^   r_   r`   ra   r   ZUPDATED_MOD_SSL_CONF_DIGESTrb   r/   r/   r0   Úupdated_mod_ssl_conf_digestÛ   s    z.ApacheConfigurator.updated_mod_ssl_conf_digestc              
   C   s  |   ¡  |  |  d¡¡ |  ¡  | jdkrR|  ¡ | _t dd dd„ | jD ƒ¡¡ | jdk rrt	 
d t| jƒ¡¡‚|  ¡  |  ¡ | _| j d	¡ |  ¡ | _|  | j| j¡ zt |  d
¡¡ W n> tt	jfk
rü   tjddd t	 d |  d
¡¡¡‚Y nX d| _dS )aW  Prepare the authenticator/installer.

        :raises .errors.NoInstallationError: If Apache configs cannot be found
        :raises .errors.MisconfigurationError: If Apache is misconfigured
        :raises .errors.NotSupportedError: If Apache version is not supported
        :raises .errors.PluginError: If there is any other error

        r    NzApache version is %sÚ.c                 s   s   | ]}t |ƒV  qd S ©N©Ústr©Ú.0Úir/   r/   r0   Ú	<genexpr>õ   s     z-ApacheConfigurator.prepare.<locals>.<genexpr>)é   rm   z!Apache Version {0} not supported.z	httpd.augr   zEncountered error:T©Úexc_infoz|Unable to create a lock file in {0}. Are you running Certbot with sufficient privileges to modify your Apache configuration?)r8   Ú_verify_exe_availabilityr1   Úconfig_testrB   Úget_versionÚloggerÚdebugr_   r	   ZNotSupportedErrorÚformatrh   Úrecovery_routineÚ
get_parserr   Zcheck_parsing_errorsÚget_virtual_hostsrS   Úinstall_ssl_options_confrc   rd   r   Zlock_dir_until_exitÚOSErrorZ	LockErrorÚPluginErrorrR   rb   r/   r/   r0   Úprepareà   s:    	

ÿ
ÿ

ÿþÿ
zApacheConfigurator.preparec                 C   sB   | j  ¡ }|r | j|| j|d | j  |¡ |r>|s>|  |¡ dS )af  Saves all changes to the configuration files.

        This function first checks for save errors, if none are found,
        all configuration changes made will be saved. According to the
        function parameters. If an exception is raised, a new checkpoint
        was not created.

        :param str title: The title of the save. If a title is given, the
            configuration will be saved as a new checkpoint and put in a
            timestamped directory.

        :param bool temporary: Indicates whether the changes made will
            be quickly reversed in the future (ie. challenges)

        )Ú	temporaryN)r   Zunsaved_filesÚadd_to_checkpointrQ   ÚsaveZfinalize_checkpoint)r-   Útitler}   Z
save_filesr/   r/   r0   r     s    
 ÿzApacheConfigurator.savec                    s$   t t| ƒ ¡  | jr | jj ¡  dS )zÉRevert 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)rH   r   rv   r   ÚaugÚloadrb   r\   r/   r0   rv   -  s    z#ApacheConfigurator.recovery_routinec                 C   s   |   ¡  | jj ¡  dS )zƒUsed to cleanup challenge configurations.

        :raises .errors.PluginError: If unable to revert the challenge config.

        N)Zrevert_temporary_configr   r   r‚   rb   r/   r/   r0   Úrevert_challenge_config<  s    z*ApacheConfigurator.revert_challenge_configr<   c                    s    t t| ƒ |¡ | jj ¡  dS )zúRollback 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)rH   r   Úrollback_checkpointsr   r   r‚   )r-   Zrollbackr\   r/   r0   r„   E  s    	z'ApacheConfigurator.rollback_checkpointsc                 C   s&   t  |¡s"t|ƒs"t d |¡¡‚dS )z(Checks availability of Apache executablez!Cannot find Apache executable {0}N)r   Z
exe_existsr   r	   ZNoInstallationErrorru   )r-   Úexer/   r/   r0   rp   Q  s
    
ÿz+ApacheConfigurator._verify_exe_availabilityc                 C   s    t j|  d¡|  d¡| j| dS )zInitializes the ApacheParserr   r;   )Zconfigurator)r   ZApacheParserr1   r4   rB   rb   r/   r/   r0   rw   X  s      þzApacheConfigurator.get_parserc                 C   s    t |tjƒrd}nd}| |¡S )z¬
        Checks if domain is a wildcard domain

        :param str domain: Domain to check

        :returns: If the domain is wildcard domain
        :rtype: bool
        z*.s   *.)Ú
isinstanceÚsixZ	text_typeÚ
startswith)r-   ÚdomainZwildcard_markerr/   r/   r0   Ú_wildcard_domain_  s    	z#ApacheConfigurator._wildcard_domainc                 C   s*   |   |¡}|D ]}|  |||||¡ qdS )aê  Deploys certificate to specified virtual host.

        Currently tries to find the last directives to deploy the certificate
        in the VHost associated with the given domain. If it can't find the
        directives, it searches the "included" confs. The function verifies
        that it has located the three directives and finally modifies them
        to point to the correct destination. After the certificate is
        installed, the VirtualHost is enabled if it isn't already.

        .. todo:: Might be nice to remove chain directive if none exists
                  This shouldn't happen within certbot though

        :raises errors.PluginError: When unable to deploy certificate due to
            a lack of directives

        N)Úchoose_vhostsÚ_deploy_cert)r-   r‰   Ú	cert_pathÚkey_pathÚ
chain_pathÚfullchain_pathrS   Úvhostr/   r/   r0   Údeploy_certn  s    
zApacheConfigurator.deploy_certTc                 C   s<   |   |¡r*|| jkr| j| S |  ||¡S |  ||¡gS dS )a‚  
        Finds VirtualHosts that can be used with the provided domain

        :param str domain: Domain name to match VirtualHosts to
        :param bool create_if_no_ssl: If found VirtualHost doesn't have a HTTPS
            counterpart, should one get created

        :returns: List of VirtualHosts or None
        :rtype: `list` of :class:`~certbot_apache.obj.VirtualHost`
        N)rŠ   rN   Ú_choose_vhosts_wildcardÚchoose_vhost)r-   r‰   Úcreate_if_no_sslr/   r/   r0   r‹   „  s
    


z ApacheConfigurator.choose_vhostsc                 C   s>   t ƒ }| jD ](}| ¡ D ]}|  ||¡r| |¡ qqt|ƒS )z~
        Get VHost objects for every VirtualHost that the user wants to handle
        with the wildcard certificate.
        )rL   rS   Ú	get_namesÚ_in_wildcard_scoper@   Úlist)r-   r‰   Zmatchedr‘   Únamer/   r/   r0   Ú_vhosts_for_wildcardš  s    
z'ApacheConfigurator._vhosts_for_wildcardc                 C   s,   t | d¡ƒt | d¡ƒkr(t ||¡S dS )a  
        Helper method for _vhosts_for_wildcard() that makes sure that the domain
        is in the scope of wildcard domain.

        eg. in scope: domain = *.wild.card, name = 1.wild.card
        not in scope: domain = *.wild.card, name = 1.2.wild.card
        re   N)ÚlenÚsplitÚfnmatch)r-   r™   r‰   r/   r/   r0   r—   ©  s    z%ApacheConfigurator._in_wildcard_scopec           
      C   sÊ   |   |¡}tƒ }|D ]6}| ¡ D ](}|jr4|||< q ||kr |r |||< q qtdd„ | ¡ D ƒƒ}t t|ƒ¡}|sŠt	 
d|¡ t d¡‚tƒ }	|D ]&}|js°|	 |  |¡¡ q”|	 |¡ q”|	| j|< |	S )zCPrompts user to choose vhosts to install a wildcard certificate forc                 S   s   g | ]}|‘qS r/   r/   ©rj   r‘   r/   r/   r0   Ú
<listcomp>È  s     z>ApacheConfigurator._choose_vhosts_wildcard.<locals>.<listcomp>zNo vhost exists with servername or alias for domain %s. No vhost was selected. Please specify ServerName or ServerAlias in the Apache config.úNo vhost selected)rš   rJ   r–   ÚsslrL   Úvaluesr   Zselect_vhost_multipler˜   rs   Úerrorr	   r{   ÚappendÚmake_vhost_sslrN   )
r-   r‰   Z
create_sslrS   Úfiltered_vhostsr‘   r™   Zdialog_inputZdialog_outputZreturn_vhostsr/   r/   r0   r“   µ  s.    

ü

z*ApacheConfigurator._choose_vhosts_wildcardc                 C   sÌ  |   d¡ |  |j¡ |  |¡ | j dd|j¡| j dd|j¡dœ}|dk	rd| j dd|j¡|d< |d s†t d	|j¡ t 	d
¡‚n |d s¦t d|j¡ t 	d¡‚t 
d|j¡ | jdk sÊ|r(|s(|}| jj |d d |¡ | jj |d d |¡ |dk	r| j |jd|¡ n
t 	d¡‚nD|s8t 	d¡‚|}| jj |d d |¡ | jj |d d |¡ |js~|  |¡ |  jd|jd dd„ |jD ƒ¡||f 7  _|dk	rÈ|  jd| 7  _dS )a  
        Helper function for deploy_cert() that handles the actual deployment
        this exists because we might want to do multiple deployments per
        domain originally passed for deploy_cert(). This is especially true
        with wildcard certificates
        Ú443ÚSSLCertificateFileNÚSSLCertificateKeyFile)r   Úcert_keyÚSSLCertificateChainFiler   r   zOCannot find an SSLCertificateFile directive in %s. VirtualHost was not modifiedz.Unable to find an SSLCertificateFile directiverª   zbCannot find an SSLCertificateKeyFile directive for certificate in %s. VirtualHost was not modifiedzAUnable to find an SSLCertificateKeyFile directive for certificatez'Deploying Certificate to VirtualHost %s)rm   é   é   éÿÿÿÿz3--chain-path is required for your version of ApachezKPlease provide the --fullchain-path option pointing to your full chain filezZChanged vhost at %s with addresses of %s
	SSLCertificateFile %s
	SSLCertificateKeyFile %s
z, c                 s   s   | ]}t |ƒV  qd S rf   rg   ©rj   Úaddrr/   r/   r0   rl   (  s     z2ApacheConfigurator._deploy_cert.<locals>.<genexpr>z	SSLCertificateChainFile %s
)Úprepare_server_httpsÚ_add_dummy_ssl_directivesr^   Ú_clean_vhostr   Úfind_dirrs   Úwarningr	   r{   ÚinfoÚfileprB   r   rL   Úadd_dirÚenabledÚenable_siterQ   r_   Úaddrs)r-   r‘   r   rŽ   r   r   r^   Zset_cert_pathr/   r/   r0   rŒ   á  sz    	

 ÿ ÿþ  ÿþÿþÿ

 ÿ

 þý
zApacheConfigurator._deploy_certc                 C   sh   || j kr| j | S |  |¡}|dk	rX|s.|S |js>|  |¡}|  ||¡ || j |< |S | j|| dS )aÏ  Chooses a virtual host based on the given domain name.

        If there is no clear virtual host to be selected, the user is prompted
        with all available choices.

        The returned vhost is guaranteed to have TLS enabled unless
        create_if_no_ssl is set to False, in which case there is no such guarantee
        and the result is not cached.

        :param str target_name: domain name
        :param bool create_if_no_ssl: If found VirtualHost doesn't have a HTTPS
            counterpart, should one get created

        :returns: vhost associated with name
        :rtype: :class:`~certbot_apache.obj.VirtualHost`

        :raises .errors.PluginError: If no vhost is available or chosen

        N©Útemp)rK   Ú_find_best_vhostr¡   r¥   Ú_add_servername_aliasÚ_choose_vhost_from_list)r-   Útarget_namer•   r‘   r/   r/   r0   r”   -  s    




zApacheConfigurator.choose_vhostc                    sš   t  || j¡}|d kr.t d|¡ t d¡‚nR|r6|S |js€|  |d¡‰ t	‡ fdd„| jD ƒƒsl|  
|¡}nt d¡ t d¡‚|  ||¡ || j|< |S )Nz…No vhost exists with servername or alias of %s. No vhost was selected. Please specify ServerName or ServerAlias in the Apache config.r    r§   c                 3   s   | ]}|j o| ˆ ¡V  qd S rf   )r¹   Ú	conflictsrž   ©r»   r/   r0   rl   d  s   ÿz=ApacheConfigurator._choose_vhost_from_list.<locals>.<genexpr>z”The selected vhost would conflict with other HTTPS VirtualHosts within Apache. Please select another vhost or add ServerNames to your configuration.z$VirtualHost not able to be selected.)r   Zselect_vhostrS   rs   r£   r	   r{   r¡   Ú_get_proposed_addrsÚanyr¥   r¿   rK   )r-   rÁ   r½   r‘   r/   rÃ   r0   rÀ   U  s0    üÿÿÿ
z*ApacheConfigurator._choose_vhost_from_listc                 C   s8   |  ¡ }|D ]&}|  ¡ }d|krt ||¡r dS qdS )a¦  Checks if target domain is covered by one or more of the provided
        names. The target name is matched by wildcard as well as exact match.

        :param names: server aliases
        :type names: `collections.Iterable` of `str`
        :param str target_name: name to compare with wildcards

        :returns: True if target_name is covered by a wildcard,
            otherwise, False
        :rtype: bool

        ú[TF)Úlowerr   )r-   ÚnamesrÁ   r™   r/   r/   r0   Údomain_in_namess  s    z"ApacheConfigurator.domain_in_namesÚ80c                    sF   g }| j D ],}t‡ fdd„|jD ƒƒr
|js
| |¡ q
|  |||¡S )a¹  Returns non-HTTPS vhost objects found from the Apache config

        :param str target: Domain name of the desired VirtualHost
        :param bool filter_defaults: whether _default_ vhosts should be
            included if it is the best match
        :param str port: port number the vhost should be listening on

        :returns: VirtualHost object that's the best match for target name
        :rtype: `obj.VirtualHost` or None
        c                 3   s"   | ]}|  ¡ p| ¡ ˆ kV  qd S rf   )Zis_wildcardÚget_port©rj   Úa©Úportr/   r0   rl   —  s     z:ApacheConfigurator.find_best_http_vhost.<locals>.<genexpr>)rS   rÅ   r»   r¡   r¤   r¾   )r-   ÚtargetÚfilter_defaultsrÏ   r¦   r‘   r/   rÎ   r0   Úfind_best_http_vhostŠ  s
    
z'ApacheConfigurator.find_best_http_vhostc           
         sÎ   d}d}|dkr| j }|D ]v}|jdkr*q| ¡ }ˆ |kr@d}n2|  |ˆ ¡rRd}n t‡ fdd„|jD ƒƒrd}nq|jr€|d7 }||kr|}|}q|dkrÊ|r¨|  |¡}d	d
„ |D ƒ}	t|	ƒdkrÊ|	d }|S )aþ  Finds the best vhost for a target_name.

        This does not upgrade a vhost to HTTPS... it only finds the most
        appropriate vhost for the given target_name.

        :param str target_name: domain handled by the desired vhost
        :param vhosts: vhosts to consider
        :type vhosts: `collections.Iterable` of :class:`~certbot_apache.obj.VirtualHost`
        :param bool filter_defaults: whether a vhost with a _default_
            addr is acceptable

        :returns: VHost or None

        Nr   Té   rm   c                 3   s   | ]}|  ¡ ˆ kV  qd S rf   ©Úget_addrr¯   ©rÁ   r/   r0   rl   ¾  s     z6ApacheConfigurator._find_best_vhost.<locals>.<genexpr>r<   c                 S   s   g | ]}|j d kr|‘qS )F©Úmodmacro©rj   Úvhr/   r/   r0   rŸ   Ñ  s    
ÿz7ApacheConfigurator._find_best_vhost.<locals>.<listcomp>)	rS   rØ   r–   rÉ   rÅ   r»   r¡   Ú_non_default_vhostsr›   )
r-   rÁ   rS   rÑ   Zbest_candidateZbest_pointsr‘   rÈ   ZpointsZreasonable_vhostsr/   rÖ   r0   r¾   ›  s:    

ÿz#ApacheConfigurator._find_best_vhostc                 C   s   dd„ |D ƒS )z%Return all non _default_ only vhosts.c                 S   s$   g | ]}t d d„ |jD ƒƒs|‘qS )c                 s   s   | ]}|  ¡ d kV  qdS )Ú	_default_NrÔ   r¯   r/   r/   r0   rl   Ú  s    zDApacheConfigurator._non_default_vhosts.<locals>.<listcomp>.<genexpr>)Úallr»   rÙ   r/   r/   r0   rŸ   Ú  s
     ÿ z:ApacheConfigurator._non_default_vhosts.<locals>.<listcomp>r/   )r-   rS   r/   r/   r0   rÛ   Ø  s    z&ApacheConfigurator._non_default_vhostsc                 C   s¬   t ƒ }g }| jD ]h}| | ¡ ¡ |jr4| |j¡ |jD ]<}tj	 
| ¡ ¡r^| | ¡ ¡ q:|  |¡}|r:| |¡ q:q|r¢tj tj¡jd d |¡¡dd t |¡S )zÊReturns all names found in the Apache Configuration.

        :returns: All ServerNames, ServerAliases, and reverse DNS entries for
                  virtual host addresses
        :rtype: set

        zaApache mod_macro seems to be in use in file(s):
{0}

Unfortunately mod_macro is not yet supportedz
  T)Zforce_interactive)rL   rS   Úupdater–   rØ   r¤   r·   r»   r   Zhostname_regexÚmatchrÕ   r@   Úget_name_from_ipÚzopeÚ	componentÚ
getUtilityr
   ZIDisplayZnotificationru   r_   r   Zget_filtered_names)r-   Z	all_namesZvhost_macror‘   r°   r™   r/   r/   r0   Úget_all_namesÞ  s(    


þýz ApacheConfigurator.get_all_namesc              
   C   sX   t j | ¡ ¡sTz"t | ¡ ¡ t | ¡ ¡d W S  tjtjtj	fk
rR   Y nX dS )zÎReturns a reverse dns name if available.

        :param addr: IP Address
        :type addr: ~.common.Addr

        :returns: name or empty string if name cannot be determined
        :rtype: str

        r   rC   )
r   Zprivate_ips_regexrß   rÕ   ÚsocketZ	inet_atonZgethostbyaddrr£   ZherrorZtimeout)r-   r°   r/   r/   r0   rà   ÿ  s    z#ApacheConfigurator.get_name_from_ipc                 C   sl   | j jdd|dd}| j jdd|dd}g }|D ]}| j  |¡}| |¡ q0d}|rd| j  |d ¡}||fS )zøHelper method for getting the ServerName and
        ServerAlias values from vhost in path

        :param path: Path to read ServerName and ServerAliases from

        :returns: Tuple including ServerName and `list` of ServerAlias strings
        Ú
ServerNameNF©ÚstartZexcludeÚServerAliasr®   )r   r´   Úget_argr¤   )r-   r^   Zservername_matchZserveralias_matchÚserveraliasesÚaliasÚserveraliasÚ
servernamer/   r/   r0   Ú_get_vhost_names  s(    	   ÿ   ÿz#ApacheConfigurator._get_vhost_namesc                 C   s<   |   |j¡\}}|D ]}|js|j |¡ q|js8||_dS )z±Helper function for get_virtual_hosts().

        :param host: In progress vhost whose names will be added
        :type host: :class:`~certbot_apache.obj.VirtualHost`

        N)rï   r^   rØ   Úaliasesr@   r™   )r-   Zhostrî   rë   rì   r/   r/   r0   Ú_add_servernames-  s    z#ApacheConfigurator._add_servernamesc                 C   s  t ƒ }z| jj |d ¡}W n" tk
r>   t d|¡ Y dS X |D ]}| tj	 
| j |¡¡¡ qDd}| jjdd|ddr€d}|D ]}| ¡ d	kr„d}q„t | jj d
t |¡ ¡¡}|dkrÄdS d}d| ¡ krØd}| j |¡}	tj|||||	|d}
|  |
¡ |
S )zÑUsed by get_virtual_hosts to create vhost objects

        :param str path: Augeas path to virtual host

        :returns: newly created vhost
        :rtype: :class:`~certbot_apache.obj.VirtualHost`

        ú/argz6Encountered a problem while parsing file: %s, skippingNFZ	SSLEngineÚonrç   Tr§   z/augeas/files%s/pathz/macro/r×   )rL   r   r   rß   ÚRuntimeErrorrs   rµ   r@   r   ÚAddrÚ
fromstringrê   r´   rË   r   Zget_file_pathr,   rÇ   Úparsed_in_originalÚVirtualHostrñ   )r-   r^   r»   rZ   ÚargZis_sslr°   ÚfilenameZmacroZvhost_enabledr‘   r/   r/   r0   Ú_create_vhost>  s:    	ÿ ÿ
z ApacheConfigurator._create_vhostc                 C   sR  i }t tƒ}g }t| jjƒD ].}| jj d|t d¡f ¡}dd„ |D ƒ}|D ]ú}|  |¡}|sdqPt	 
|j¡}t |j¡}	|	|kr¨|j||	< ||	  |¡ | |¡ qP|	|jkr&|	||	 kr&g }
|D ]4}|j||	 krô||	  t	 
|j¡¡ qÊ|
 |¡ qÊ|
}|	||	< ||	  |¡ | |¡ qP|||	 krP||	  |¡ | |¡ qPq|S )zÎReturns list of virtual hosts found in the Apache configuration.

        :returns: List of :class:`~certbot_apache.obj.VirtualHost`
            objects found in configuration
        :rtype: list

        z"/files%s//*[label()=~regexp('%s')]rø   c                 S   s$   g | ]}d t j |¡ ¡ kr|‘qS )Úvirtualhost)r   r^   ÚbasenamerÇ   )rj   r^   r/   r/   r0   rŸ   |  s    ÿz8ApacheConfigurator.get_virtual_hosts.<locals>.<listcomp>)r   rL   r˜   r   Zparser_pathsr   rß   Úcase_irû   r   Zget_internal_aug_pathr^   r   Úrealpathr·   r@   r¤   Úremove)r-   Z
file_pathsZinternal_pathsZvhsZ
vhost_pathÚpathsr^   Ú	new_vhostZinternal_pathrÿ   Znew_vhsÚvr/   r/   r0   rx   j  sL    	ÿÿ


ÿ
ÿz$ApacheConfigurator.get_virtual_hostsc                 C   s   | j dkp| j dt|ƒ¡S )az  Returns if vhost is a name based vhost

        NameVirtualHost was deprecated in Apache 2.4 as all VirtualHosts are
        now NameVirtualHosts. If version is earlier than 2.4, check if addr
        has a NameVirtualHost directive in the Apache config

        :param certbot_apache.obj.Addr target_addr: vhost address

        :returns: Success
        :rtype: bool

        ©rm   r¬   ÚNameVirtualHost)rB   r   r´   rh   )r-   Ztarget_addrr/   r/   r0   Úis_name_vhostŸ  s    
ÿz ApacheConfigurator.is_name_vhostc                 C   st   t  | j jd ¡}| ¡ dkr6| j  |dt|ƒg¡}n| j  |dt|ƒg¡}d||f }t |¡ |  j	|7  _	dS )z¿Adds NameVirtualHost directive for given address.

        :param addr: Address that will be added as NameVirtualHost directive
        :type addr: :class:`~certbot_apache.obj.Addr`

        r™   r§   r  z=Setting %s to be NameBasedVirtualHost
	Directive added to %s
N)
r   Úget_aug_pathÚlocrË   Úadd_dir_to_ifmodsslrh   r¸   rs   rt   rQ   )r-   r°   r  r^   Úmsgr/   r/   r0   Úadd_name_vhost´  s      ÿÿ
z!ApacheConfigurator.add_name_vhostc                 C   s   |   |¡ | j|dd dS )zÄPrepare the server for HTTPS.

        Make sure that the ssl_module is loaded and that the server
        is appropriately listening on port.

        :param str port: Port to listen on

        T)ÚhttpsN)Úprepare_https_modulesÚensure_listen)r-   rÏ   r½   r/   r/   r0   r±   È  s    

z'ApacheConfigurator.prepare_server_httpsc           	         s  |r|dkrd|df }n|}‡ fdd„ˆ j  d¡D ƒ}ˆ  ||¡rHdS t|ƒ}|s^| |¡ |D ]Œ}t| d¡ƒd	kr”||krî||krî| |¡ qb|ddd
…  dd	¡\}}|ddd
… }d||f |krbd||f |krb| d||f ¡ qb|rˆ  |||¡ nˆ  |||¡ dS )aX  Make sure that Apache is listening on the port. Checks if the
        Listen statement for the port already exists, and adds it to the
        configuration if necessary.

        :param str port: Port number to check and add Listen for if not in
            place already
        :param bool https: If the port will be used for HTTPS

        r§   ú%s %sr  c                    s    g | ]}ˆ j  |¡ ¡ d  ‘qS )r   )r   rê   rœ   ©rj   Úxrb   r/   r0   rŸ   è  s   ÿz4ApacheConfigurator.ensure_listen.<locals>.<listcomp>ÚListenNú:r<   r®   z%s:%s)	r   r´   Ú_has_port_alreadyrL   r@   r›   rœ   Ú_add_listens_httpsÚ_add_listens_http)	r-   rÏ   r  Úport_serviceÚlistensZlisten_dirsÚlistenr2   Zipr/   rb   r0   r  Õ  s0    

ÿ
ÿz ApacheConfigurator.ensure_listenc                 C   s    |  |¡}||krP| j t | jjd ¡d|¡ |  jd|| jjd f 7  _nL|D ]F}| j t | jjd ¡d| d¡¡ |  jd|| jjd f 7  _qTdS )a<  Helper method for ensure_listen to figure out which new
        listen statements need adding for listening HTTP on port

        :param set listens: Set of all needed Listen statements
        :param list listens_orig: List of existing listen statements
        :param string port: Port number we're adding
        r  r  ú Added Listen %s directive to %s
ú N)Ú
differencer   r¸   r  r  rQ   rœ   )r-   r  Úlistens_origrÏ   Únew_listensr  r/   r/   r0   r    s,    	
 ÿ 
ÿ

ÿ ÿ
ÿÿz$ApacheConfigurator._add_listens_httpc                 C   sÈ   |dkrd|df }n|}|  |¡}||ks4||krx| j t | jjd ¡d| d¡¡ |  jd|| jjd f 7  _nL|D ]F}| j t | jjd ¡d| d¡¡ |  jd|| jjd f 7  _q|dS )	a=  Helper method for ensure_listen to figure out which new
        listen statements need adding for listening HTTPS on port

        :param set listens: Set of all needed Listen statements
        :param list listens_orig: List of existing listen statements
        :param string port: Port number we're adding
        r§   r  r  r  r  r  r  N)r  r   r	  r  r  rœ   rQ   )r-   r  r  rÏ   r  r  r  r/   r/   r0   r     s2    

 þ 
ÿ þ
ÿÿz%ApacheConfigurator._add_listens_httpsc                 C   sN   ||krdS |D ]8}t | d¡ƒdkr| d¡d  d¡d |kr dS qdS )zëHelper method for prepare_server_https to find out if user
        already has an active Listen statement for the port we need

        :param list listens: List of listen variables
        :param string port: Port in question
        Tr  r<   r®   r  r   N)r›   rœ   )r-   r  rÏ   r  r/   r/   r0   r  A  s    z$ApacheConfigurator._has_port_alreadyc                 C   sL   |   d¡rH| jdkr.d| jjkr.| jd|d d| jjkrH| jd|d dS )	z˜Helper method for prepare_server_https, taking care of enabling
        needed modules

        :param boolean temp: If the change is temporary
        r'   r  Úsocache_shmcb_moduleÚsocache_shmcbr¼   Z
ssl_moduler¡   N)r1   rB   r   ÚmodulesÚ
enable_mod)r-   r½   r/   r/   r0   r  S  s    
ÿz(ApacheConfigurator.prepare_https_modulesc                 C   s  |j }|  |¡}| jj d|  |¡t d¡f ¡}|  ||¡ | jj ¡  | jj d|  |¡t d¡f ¡}|  	||¡}|sÄ| j 
|¡ | jj d|  |¡t d¡f ¡}|  	||¡}|sÄt d¡‚|  |¡ t d|¡ |  jd| 7  _|  ¡  |  |¡}||_| j |¡ |  |¡ |S )ax  Makes an ssl_vhost version of a nonssl_vhost.

        Duplicates vhost and adds default ssl options
        New vhost will reside as (nonssl_vhost.path) +
        ``self.option("le_vhost_ext")``

        .. note:: This function saves the configuration

        :param nonssl_vhost: Valid VH that doesn't have SSLEngine on
        :type nonssl_vhost: :class:`~certbot_apache.obj.VirtualHost`

        :returns: SSL vhost
        :rtype: :class:`~certbot_apache.obj.VirtualHost`

        :raises .errors.PluginError: If more than one virtual host is in
            the file or if plugin is unable to write/read vhost files.

        z#/files%s//* [label()=~regexp('%s')]rø   z;Could not reverse map the HTTPS VirtualHost to the originalzCreated an SSL vhost at %szCreated ssl vhost at %s
)r·   Ú_get_ssl_vhost_pathr   r   rß   Ú_escaperþ   Ú_copy_create_ssl_vhost_skeletonr‚   Ú_get_new_vh_pathÚ
parse_filer	   r{   Ú_update_ssl_vhosts_addrsrs   r¶   rQ   r   rû   ÚancestorrS   r¤   Ú_add_name_vhost_if_necessary)r-   Znonssl_vhostZavail_fpÚssl_fpÚorig_matchesÚnew_matchesZvh_pÚ	ssl_vhostr/   r/   r0   r¥   a  sL    

ÿÿ
ÿÿÿÿÿÿ

	
z!ApacheConfigurator.make_vhost_sslc                 C   s4   dd„ |D ƒ}|D ]}|  dd¡|kr|  S qdS )a   Helper method for make_vhost_ssl for matching augeas paths. Returns
        VirtualHost path from new_matches that's not present in orig_matches.

        Paths are normalized, because augeas leaves indices out for paths
        with only single directive with a similar key c                 S   s   g | ]}|  d d¡‘qS )ú[1]rC   ©r5   ri   r/   r/   r0   rŸ   ¶  s     z7ApacheConfigurator._get_new_vh_path.<locals>.<listcomp>r/  rC   Nr0  )r-   r,  r-  rß   r/   r/   r0   r&  ¯  s
    
z#ApacheConfigurator._get_new_vh_pathc                 C   s~   |   d¡r@tj |   d¡¡r@tj t |  d¡¡tj |¡¡}n
t |¡}| 	d¡rp|dt
dƒ … |  d¡ S ||  d¡ S )a-   Get a file path for SSL vhost, uses user defined path as priority,
        but if the value is invalid or not defined, will fall back to non-ssl
        vhost filepath.

        :param str non_ssl_vh_fp: Filepath of non-SSL vhost

        :returns: Filepath for SSL vhost
        :rtype: str
        r;   r   z.confNr&   )r4   r   r^   Úexistsr_   r   rÿ   r1   rý   Úendswithr›   )r-   Znon_ssl_vh_fpÚfpr/   r/   r0   r#  ½  s    
ÿ

z&ApacheConfigurator._get_ssl_vhost_pathc                 C   sX   |  ¡  ¡  d¡sdS | ¡ d  ¡ }|d dkrN|d |d krN|dd… }| d¡S )	a`  Decides whether a line should be copied to a SSL vhost.

        A canonical example of when sifting a line is required:
        When the http vhost contains a RewriteRule that unconditionally
        redirects any request to the https version of the same site.
        e.g:
        RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [L,QSA,R=permanent]
        Copying the above line to the ssl vhost would cause a
        redirection loop.

        :param str line: a line extracted from the http vhost.

        :returns: True - don't copy line from http vhost to SSL vhost.
        :rtype: bool

        ÚrewriteruleFrm   r   )ú'ú"r®   r<   zhttps://)rÇ   Úlstriprˆ   rœ   Ústrip)r-   ÚlinerÐ   r/   r/   r0   Ú_sift_rewrite_ruleÓ  s    z%ApacheConfigurator._sift_rewrite_rulec           
   	   C   sR  t j |¡r4d| }tƒ }| |¡ | j ||¡ n| j d|¡ d}zx|  |¡}|  	|¡\}}t
|dƒ4}| d¡ | d |¡¡ | d¡ | d¡ W 5 Q R X | j |¡s¼| j |¡ W n, tk
rê   tjdd	d
 t d¡‚Y nX |rtj tj¡}	|	 d |j|¡|	j¡ | jj d|  |¡ d¡ | jj d|  |j¡ d¡ dS )a  Copies over existing Vhost with IfModule mod_ssl.c> skeleton.

        :param obj.VirtualHost vhost: Original VirtualHost object
        :param str ssl_fp: Full path where the new ssl_vhost will reside.

        A new file is created on the filesystem.

        z-Appended new VirtualHost directive to file %sFrÍ   z<IfModule mod_ssl.c>
Ú
z</VirtualHost>
z</IfModule>
z/Error writing/reading to file in make_vhost_sslTrn   z&Unable to write/read in make_vhost_sslzSome rewrite rules copied from {0} were disabled in the vhost for your HTTPS site located at {1} because they have the potential to create redirection loops.z/augeas/files%s/mtimeÚ0N) r   r^   r1  rL   r@   Úreverterr~   Úregister_file_creationÚ_get_vhost_blockÚ_sift_rewrite_rulesÚopenÚwriter_   r   Úparsed_in_currentr'  ÚIOErrorrs   Úcriticalr	   r{   rá   râ   rã   r
   Z	IReporterZadd_messageru   r·   ZMEDIUM_PRIORITYr   r$  )
r-   r‘   r+  ZnotesÚfilesÚsiftZorig_contentsZssl_vh_contentsZnew_fileZreporterr/   r/   r0   r%  ô  s>    



 ýüz2ApacheConfigurator._copy_create_ssl_vhost_skeletonc           	      C   sD  g }d}t |ƒ}d}|D ] }| ¡  ¡  d¡}| ¡  ¡  d¡}|sV|sV| |¡ q|rp|  |¡sp| |¡ q|r |  |¡r |s| |¡ d}| d| ¡ qg }|r| |¡ t|ƒ}| ¡  ¡  d¡sà| |¡ t|ƒ}qº| |¡ |  |¡r(|s
| |¡ d}| d dd	„ |D ƒ¡¡ qq| d |¡¡ qq||fS )
z Helper function for _copy_create_ssl_vhost_skeleton to prepare the
        new HTTPS VirtualHost contents. Currently disabling the rewrites Fzƒ# Some rewrite rules in this file were disabled on your HTTPS site,
# because they have the potential to create redirection loops.
Zrewritecondr4  Tú# r;  c                 S   s   g | ]}d | ‘qS )rH  r/   )rj   Úlr/   r/   r0   rŸ   ]  s     z:ApacheConfigurator._sift_rewrite_rules.<locals>.<listcomp>)ÚiterrÇ   r7  rˆ   r¤   r:  Únextr_   )	r-   ÚcontentsÚresultrG  Úcommentr9  ÚAÚBÚchunkr/   r/   r0   r@  $  sL    








ÿz&ApacheConfigurator._sift_rewrite_rulesc              	   C   s¤   z| j j |j¡}W n4 tk
rH   tjd|j|jdd t	 
d¡‚Y nX |d }|d }|d }t|dƒ$}| |¡ | || ¡ d	¡}W 5 Q R X |  |¡ |S )
a   Helper method to get VirtualHost contents from the original file.
        This is done with help of augeas span, which returns the span start and
        end positions

        :returns: `list` of VirtualHost block content lines without closing tag
        z3Error while reading the VirtualHost %s from file %sTrn   z$Unable to read VirtualHost from filer   é   é   Úrr;  )r   r   Úspanr^   Ú
ValueErrorrs   rE  r™   r·   r	   r{   rA  ÚseekÚreadrœ   Ú_remove_closing_vhost_tag)r-   r‘   Zspan_valZ
span_filepZ
span_startZspan_endZfhÚvh_contentsr/   r/   r0   r?  d  s"      ÿ

z#ApacheConfigurator._get_vhost_blockc                 C   sX   t t|ƒƒD ]F\}}|r| ¡  d¡}|dkrNt|ƒ| d }|d|… ||<  qTqdS )a”  Removes the closing VirtualHost tag if it exists.

        This method modifies vh_contents directly to remove the closing
        tag. If the closing vhost tag is found, everything on the line
        after it is also removed. Whether or not this tag is included
        in the result of span depends on the Augeas version.

        :param list vh_contents: VirtualHost block contents to check

        z</virtualhost>r®   r<   N)Ú	enumerateÚreversedrÇ   Úfindr›   )r-   rZ  Úoffsetr9  Z
line_indexZcontent_indexr/   r/   r0   rY  {  s    z,ApacheConfigurator._remove_closing_vhost_tagc                 C   sf   t ƒ }| jj |d ¡}|D ]D}tj t| j |¡ƒ¡}| 	d¡}| jj  |t|ƒ¡ | 
|¡ q|S )Nrò   r§   )rL   r   r   rß   r   rõ   rö   rh   rê   Úget_addr_objr@   )r-   Úvh_pathZ	ssl_addrsZ
ssl_addr_pr°   Zold_addrZssl_addrr/   r/   r0   r(  Ž  s    ÿ
z+ApacheConfigurator._update_ssl_vhosts_addrsc                 C   s&   |   |jddg¡ |  |jdg¡ d S )Nr¨   r©   r«   )Ú_deduplicate_directivesr^   Ú_remove_directives©r-   r‘   r/   r/   r0   r³   ›  s    ÿÿzApacheConfigurator._clean_vhostc              	   C   sX   |D ]N}t | j |d |d¡ƒdkr| j |d |d¡}| jj t dd|d ¡¡ qqd S )NFr<   ú/\w*$rC   r   )r›   r   r´   r   r   ÚreÚsub©r-   r`  Z
directivesZ	directiveZdirective_pathr/   r/   r0   ra  £  s     ÿÿ
 ÿz*ApacheConfigurator._deduplicate_directivesc              	   C   sP   |D ]F}| j  |d |d¡r| j  |d |d¡}| j j t dd|d ¡¡ qqd S )NFrd  rC   r   )r   r´   r   r   re  rf  rg  r/   r/   r0   rb  «  s    
 ÿz%ApacheConfigurator._remove_directivesc                 C   sL   | j  |dd¡ | j  |dd¡ | j  d| j|¡}|sH| j  |d| j¡ d S )Nr¨   Zinsert_cert_file_pathr©   Zinsert_key_file_pathZInclude)r   r¸   r´   rc   )r-   r`  Zexisting_incr/   r/   r0   r²   ²  s    
ÿ
ÿz,ApacheConfigurator._add_dummy_ssl_directivesc                 C   s|   |j }|  |¡\}}||ks$||kr(d S |  ||¡r8d S | jjdd |dds^| j |d|¡ n| j |d|¡ |  |¡ d S )Nræ   Frç   ré   )r^   rï   Ú_has_matching_wildcardr   r´   r¸   rñ   )r-   rÁ   r‘   r`  ZsnameZsaliasesr/   r/   r0   r¿   ¼  s    
 ÿz(ApacheConfigurator._add_servername_aliasc                    s0   ˆ j jd|dd}‡ fdd„|D ƒ}ˆ  ||¡S )aL  Is target_name already included in a wildcard in the vhost?

        :param str vh_path: Augeas path to the vhost
        :param str target_name: name to compare with wildcards

        :returns: True if there is a wildcard covering target_name in
            the vhost in vhost_path, otherwise, False
        :rtype: bool

        ré   Frç   c                 3   s   | ]}ˆ j j |¡V  qd S rf   ©r   r   r,   )rj   rß   rb   r/   r0   rl   ×  s     z<ApacheConfigurator._has_matching_wildcard.<locals>.<genexpr>)r   r´   rÉ   )r-   r`  rÁ   Úmatchesrð   r/   rb   r0   rh  Ê  s      ÿz)ApacheConfigurator._has_matching_wildcardc                    s¦   d}|j D ]Š‰ tˆ fƒ‰ˆ  ¡ dkr<ˆ ‡ fdd„dD ƒ¡ | jD ]P}|j|jkrBt‡fdd„|j D ƒƒrB|  ˆ ¡sB|  ˆ ¡ t	 
dˆ ¡ d} q
qBq
|r¢|  ¡  dS )	aG  Add NameVirtualHost Directives if necessary for new vhost.

        NameVirtualHosts was a directive in Apache < 2.4
        https://httpd.apache.org/docs/2.2/mod/core.html#namevirtualhost

        :param vhost: New virtual host that was recently created.
        :type vhost: :class:`~certbot_apache.obj.VirtualHost`

        F)r   rÜ   c                 3   s    | ]}t  |ˆ  ¡ f¡V  qd S rf   )r   rõ   rË   rÌ   )r°   r/   r0   rl   í  s   ÿzBApacheConfigurator._add_name_vhost_if_necessary.<locals>.<genexpr>c                 3   s   | ]}|ˆ kV  qd S rf   r/   )rj   Z	test_addrrÃ   r/   r0   rl   ò  s   ÿzEnabling NameVirtualHosts on %sTN)r»   rL   rÕ   rÞ   rS   r·   rÅ   r  r  rs   r¶   r   )r-   r‘   Zneed_to_saveZtest_vhr/   )r°   r»   r0   r*  Ú  s*    


ÿ
ÿÿý
z/ApacheConfigurator._add_name_vhost_if_necessaryc                 C   sD   | j D ]}|  |¡|kr|  S qd |¡}t |¡ t |¡‚dS )a>  
        Searches through VirtualHosts and tries to match the id in a comment

        :param str id_str: Id string for matching

        :returns: The matched VirtualHost or None
        :rtype: :class:`~certbot_apache.obj.VirtualHost` or None

        :raises .errors.PluginError: If no VirtualHost is found
        z$No VirtualHost with ID {} was found.N)rS   Ú_find_vhost_idru   rs   rµ   r	   r{   )r-   Úid_strrÚ   r
  r/   r/   r0   Úfind_vhost_by_idý  s    



z#ApacheConfigurator.find_vhost_by_idc                 C   sB   t j d¡}| j ||j¡}|r>| j |d ¡}| d¡d S dS )aC  Tries to find the unique ID from the VirtualHost comments. This is
        used for keeping track of VirtualHost directive over time.

        :param vhost: Virtual host to add the id
        :type vhost: :class:`~certbot_apache.obj.VirtualHost`

        :returns: The unique ID or None
        :rtype: str or None
        rC   r   r  r®   N)r   ÚMANAGED_COMMENT_IDru   r   Zfind_commentsr^   rê   rœ   )r-   r‘   Zsearch_commentZ
id_commentrN  r/   r/   r0   rk    s    z!ApacheConfigurator._find_vhost_idc                 C   s:   |   |¡}|r|S t ¡ }tj |¡}| j |j|¡ |S )a  Adds an unique ID to the VirtualHost as a comment for mapping back
        to it on later invocations, as the config file order might have changed.
        If ID already exists, returns that instead.

        :param vhost: Virtual host to add or find the id
        :type vhost: :class:`~certbot_apache.obj.VirtualHost`

        :returns: The unique ID for vhost
        :rtype: str or None
        )	rk  r   Z	unique_idr   rn  ru   r   Zadd_commentr^   )r-   r‘   Zvh_idZ	id_stringrN  r/   r/   r0   Úadd_vhost_id%  s    
zApacheConfigurator.add_vhost_idc                 C   sd   |  dd¡}|  dd¡}|  dd¡}|  dd¡}|  d	d
¡}|  dd¡}|  dd¡}|  dd¡}|S )Nú,z\,rÆ   z\[ú]z\]ú|z\|ú=z\=ú(z\(ú)z\)ú!z\!r0  )r-   r3  r/   r/   r0   r$  :  s    zApacheConfigurator._escapec                 C   s
   dddgS )z)Returns currently supported enhancements.rD   rE   rF   r/   rb   r/   r/   r0   Úsupported_enhancementsH  s    z)ApacheConfigurator.supported_enhancementsc                 C   sÐ   z| j | }W n$ tk
r2   t d |¡¡‚Y nX | j|dd}dd„ |D ƒ}|sŒd}|}|rl|d| 7 }| ||¡}	t |	¡ t |	¡‚z|D ]}
||
|ƒ q’W n& tjk
rÊ   t d||¡ ‚ Y nX d	S )
aë  Enhance configuration.

        :param str domain: domain to enhance
        :param str enhancement: enhancement type defined in
            :const:`~certbot.constants.ENHANCEMENTS`
        :param options: options for the enhancement
            See :const:`~certbot.constants.ENHANCEMENTS`
            documentation for appropriate parameter.

        :raises .errors.PluginError: If Enhancement is not supported, or if
            there is any other problem with the enhancement.

        zUnsupported enhancement: {0}F©r•   c                 S   s   g | ]}|j r|‘qS r/   ©r¡   rž   r/   r/   r0   rŸ   b  s      z.ApacheConfigurator.enhance.<locals>.<listcomp>z‹Certbot was not able to find SSL VirtualHost for a domain {0} for enabling enhancement "{1}". The requested enhancement was not configured.z: zFailed %s for %sN)rY   ÚKeyErrorr	   r{   ru   r‹   rs   rµ   )r-   r‰   Zenhancementr+   ÚfuncÚmatched_vhostsrS   Úmsg_tmplZmsg_enhancementr
  r‘   r/   r/   r0   ÚenhanceL  s,    ÿ


zApacheConfigurator.enhancec                 C   s.   t j| }|  ||¡ |t ¡ dœ| j|< dS )a   Increase the AutoHSTS max-age value

        :param vhost: Virtual host object to modify
        :type vhost: :class:`~certbot_apache.obj.VirtualHost`

        :param str id_str: The unique ID string of VirtualHost

        :param int nextstep: Next AutoHSTS max-age value index

        ©ÚlaststepÚ	timestampN)r   ÚAUTOHSTS_STEPSÚ_autohsts_writeÚtimerP   )r-   r‘   rl  ÚnextstepÚnextstep_valuer/   r/   r0   Ú_autohsts_increaseu  s    
z%ApacheConfigurator._autohsts_increasec           
      C   sº   d}| j  dd|j¡}|rFd}|D ]"}t || j j |¡ ¡ ¡r"|}q"|s`d |j	¡}t
 |¡‚d |¡}| dd¡}| j j ||¡ d ||j	¡}	t |	¡ |  j|	7  _|  |	¡ dS )	zJ
        Write the new HSTS max-age value to the VirtualHost file
        NÚHeaderz/(?:[ "]|^)(strict-transport-security)(?:[ "]|$)zUCertbot was unable to find the existing HSTS header from the VirtualHost at path {0}.ú"max-age={0}"zarg[3]zarg[4]z<Increasing HSTS max-age value to {0} for VirtualHost in {1}
)r   r´   r^   re  Úsearchr   r,   rÇ   ru   r·   r	   r{   r5   rL   rs   rt   rQ   r   )
r-   r‘   r†  Zhsts_dirpathÚheader_pathÚpatrß   Úerr_msgZhsts_maxageÚnote_msgr/   r/   r0   rƒ  „  s,    ÿ

 ÿ
z"ApacheConfigurator._autohsts_writec                 C   s4   z| j  d¡| _W n tk
r.   tƒ | _Y nX dS )zE
        Populates the AutoHSTS state from the pluginstorage
        ÚautohstsN)ÚstorageZfetchrP   rz  rJ   rb   r/   r/   r0   Ú_autohsts_fetch_state£  s    z(ApacheConfigurator._autohsts_fetch_statec                 C   s   | j  d| j¡ | j  ¡  dS )zE
        Saves the state of AutoHSTS object to pluginstorage
        r  N)r  ZputrP   r   rb   r/   r/   r0   Ú_autohsts_save_state¬  s    z'ApacheConfigurator._autohsts_save_statec                 C   s   t | j d|j|j¡ƒS )zz
        Searches AutoHSTS managed VirtualHosts that belong to the lineage.
        Matches the private key path.
        r©   )Úboolr   r´   rŽ   r^   )r-   r‘   Úlineager/   r/   r0   Ú_autohsts_vhost_in_lineage³  s     ÿÿz-ApacheConfigurator._autohsts_vhost_in_lineagec                 C   sÜ   d}|   ¡ |k rt d¡‚d| jjkr0|  d¡ | jjdd|jd}|sZ| j |jdd¡ |  	t 
|j¡¡}| j dd	|¡}|rœ| jj t d
d|d ¡¡ | j |ddg¡ d|j }|  j|7  _|  ¡  t |¡ d	S )a¨  Enables OCSP Stapling

        In OCSP, each client (e.g. browser) would have to query the
        OCSP Responder to validate that the site certificate was not revoked.

        Enabling OCSP Stapling, would allow the web-server to query the OCSP
        Responder, and staple its response to the offered certificate during
        TLS. i.e. clients would not have to query the OCSP responder.

        OCSP Stapling enablement on Apache implicitly depends on
        SSLCertificateChainFile being set by other code.

        .. note:: This function saves the configuration

        :param ssl_vhost: Destination of traffic, an ssl enabled vhost
        :type ssl_vhost: :class:`~certbot_apache.obj.VirtualHost`

        :param unused_options: Not currently used
        :type unused_options: Not Available

        :returns: Success, general_vhost (HTTP vhost)
        :rtype: (bool, :class:`~certbot_apache.obj.VirtualHost`)

        )rm   rÓ   rÓ   z=Unable to set OCSP directives.
Apache version is below 2.3.3.r  r   ZSSLUseStaplingró   ©rè   ZSSLStaplingCacheNrd  rC   r   z-shmcb:/var/run/apache2/stapling_cache(128000)z,OCSP Stapling was enabled on SSL Vhost: %s.
)rr   r	   r{   r   r!  r"  r´   r^   r¸   r$  r  r·   r   r   re  rf  r	  rQ   r   rs   r¶   )r-   r.  Úunused_optionsZmin_apache_verZuse_stapling_aug_pathZssl_vhost_aug_pathZstapling_cache_aug_pathr
  r/   r/   r0   rX   ½  s@    ÿ
 ÿ ÿÿþÿz(ApacheConfigurator._enable_ocsp_staplingc                 C   sn   d| j jkr|  d¡ |  ||¡ | j  |jdtj| ¡ |  jd||j	f 7  _|  
¡  t d||j	¡ dS )aƒ  Enables header that is identified by header_substring on ssl_vhost.

        If the header identified by header_substring is not already set,
        a new Header directive is placed in ssl_vhost's configuration with
        arguments from: constants.HTTP_HEADER[header_substring]

        .. note:: This function saves the configuration

        :param ssl_vhost: Destination of traffic, an ssl enabled vhost
        :type ssl_vhost: :class:`~certbot_apache.obj.VirtualHost`

        :param header_substring: string that uniquely identifies a header.
                e.g: Strict-Transport-Security, Upgrade-Insecure-Requests.
        :type str

        :returns: Success, general_vhost (HTTP vhost)
        :rtype: (bool, :class:`~certbot_apache.obj.VirtualHost`)

        :raises .errors.PluginError: If no viable HTTP host can be created or
            set with header header_substring.

        Úheaders_moduleÚheadersrˆ  z$Adding %s header to ssl vhost in %s
z#Adding %s header to ssl vhost in %sN)r   r!  r"  Ú_verify_no_matching_http_headerr¸   r^   r   ÚHEADER_ARGSrQ   r·   r   rs   r¶   )r-   r.  Úheader_substringr/   r/   r0   rW   û  s    
ÿÿÿz#ApacheConfigurator._set_http_headerc                 C   sZ   | j jdd|jd}|rVd| ¡  }|D ],}t || j j |¡ ¡ ¡r(t 	d| ¡‚q(dS )a%  Checks to see if an there is an existing Header directive that
        contains the string header_substring.

        :param ssl_vhost: vhost to check
        :type vhost: :class:`~certbot_apache.obj.VirtualHost`

        :param header_substring: string that uniquely identifies a header.
                e.g: Strict-Transport-Security, Upgrade-Insecure-Requests.
        :type str

        :returns: boolean
        :rtype: (bool)

        :raises errors.PluginEnhancementAlreadyPresent When header
                header_substring exists

        rˆ  Nr–  z(?:[ "]|^)(%s)(?:[ "]|$)zExisting %s header)
r   r´   r^   rÇ   re  rŠ  r   r,   r	   ÚPluginEnhancementAlreadyPresent)r-   r.  rœ  r‹  rŒ  rß   r/   r/   r0   rš  #  s    
ÿÿz2ApacheConfigurator._verify_no_matching_http_headerc           
      C   sl  d| j jkr|  d¡ |  |¡}|dkrnt d¡ |  |¡}| jD ]}|jrB| 	|¡rBt
 d¡‚qB|  |¡ nú|| jd krŠt d¡ dS |  |¡ |  |¡r¨t d¡ |  |¡sÄ| j  |jd	d
¡ | ¡ }t|ƒD ]D\}}dd |¡dg}	|t|ƒd kr|	 ¡  | j  |jd|	¡ qÔ|  |¡ |  jd|j|jf 7  _|  ¡  | jd  |¡ t d|j|j¡ dS )a:  Redirect all equivalent HTTP traffic to ssl_vhost.

        .. todo:: This enhancement should be rewritten and will
           unfortunately require lots of debugging by hand.

        Adds Redirect directive to the port 80 equivalent of ssl_vhost
        First the function attempts to find the vhost with equivalent
        ip addresses that serves on non-ssl ports
        The function then adds the directive

        .. note:: This function saves the configuration

        :param ssl_vhost: Destination of traffic, an ssl enabled vhost
        :type ssl_vhost: :class:`~certbot_apache.obj.VirtualHost`

        :param unused_options: Not currently used
        :type unused_options: Not Available

        :raises .errors.PluginError: If no viable HTTP host can be created or
            used for the redirect.

        Zrewrite_moduleZrewriteNzBDid not find http version of ssl virtual host attempting to createzšUnable to find corresponding HTTP vhost; Unable to create one as intended addresses conflict; Current configuration does not support automated redirectionrD   z'Already enabled redirect for this vhostznAdded an HTTP->HTTPS rewrite in addition to other RewriteRules; you may wish to check for overall consistency.ÚRewriteEngineró   z%{SERVER_NAME}z={0}z[OR]r<   ZRewriteCondz*Redirecting host in %s to ssl vhost in %s
z*Redirecting vhost in %s to ssl vhost in %s)r   r!  r"  Ú_get_http_vhostrs   rt   rÄ   rS   r¹   rÂ   r	   r{   Ú_create_redirect_vhostrO   Ú_verify_no_certbot_redirectÚ_is_rewrite_existsrµ   Ú_is_rewrite_engine_onr¸   r^   r–   r[  ru   r›   rG   Ú#_set_https_redirection_rewrite_rulerQ   r·   r   r@   r¶   )
r-   r.  r—  Z
general_vhZredirect_addrsr‘   rÈ   Úidxr™   rZ   r/   r/   r0   rV   ?  sH    




ÿ






ÿ ÿz#ApacheConfigurator._enable_redirectc                 C   s:   |   ¡ dkr"| j |jdtj¡ n| j |jdtj¡ d S )N©rm   rÓ   é	   ÚRewriteRule)rr   r   r¸   r^   r   ÚREWRITE_HTTPS_ARGS_WITH_ENDÚREWRITE_HTTPS_ARGSrc  r/   r/   r0   r¤    s    ÿÿz6ApacheConfigurator._set_https_redirection_rewrite_rulec                    sÐ   ˆ j jdd|jd}ttƒ}d}|D ],}t ||¡}|r$| d¡}||  |¡ q$|rÌt	j
t	jg}| ¡ D ]`\}}	‡ fdd„|	D ƒ}
|
t	jkr¸ˆ j j |¡ ˆ  |¡ ˆ  ¡  t d¡‚|
|krjt d¡‚qjdS )	aV  Checks to see if a redirect was already installed by certbot.

        Checks to see if virtualhost already contains a rewrite rule that is
        identical to Certbot's redirection rewrite rule.

        For graceful transition to new rewrite rules for HTTPS redireciton we
        delete certbot's old rewrite rules and set the new one instead.

        :param vhost: vhost to check
        :type vhost: :class:`~certbot_apache.obj.VirtualHost`

        :raises errors.PluginEnhancementAlreadyPresent: When the exact
                certbot redirection WriteRule exists in virtual host.
        r¨  Nr–  z(.*directive\[\d+\]).*r<   c                    s   g | ]}ˆ j j |¡‘qS r/   ri  r  rb   r/   r0   rŸ   º  s     zBApacheConfigurator._verify_no_certbot_redirect.<locals>.<listcomp>z'Certbot has already enabled redirection)r   r´   r^   r   r˜   re  rß   Úgroupr¤   r   rª  r©  ÚitemsZOLD_REWRITE_HTTPS_ARGSr   r   r¤  r   r	   r  )r-   r‘   Úrewrite_pathZrewrite_args_dictrŒ  rß   ÚmZdir_pathZredirect_argsZ
args_pathsZarg_valsr/   rb   r0   r¡  ˜  s:      ÿ
ÿ

ÿÿz.ApacheConfigurator._verify_no_certbot_redirectc                 C   s   | j jdd|jd}t|ƒS )zõChecks if there exists a RewriteRule directive in vhost

        :param vhost: vhost to check
        :type vhost: :class:`~certbot_apache.obj.VirtualHost`

        :returns: True if a RewriteRule directive exists.
        :rtype: bool

        r¨  Nr–  )r   r´   r^   r“  )r-   r‘   r­  r/   r/   r0   r¢  È  s    
  ÿz%ApacheConfigurator._is_rewrite_existsc                 C   sB   | j jdd|jd}|r>|D ] }d| ¡ kr| j  |¡  S qdS )z—Checks if a RewriteEngine directive is on

        :param vhost: vhost to check
        :type vhost: :class:`~certbot_apache.obj.VirtualHost`

        rž  ró   r–  rü   F)r   r´   r^   rÇ   rê   )r-   r‘   Zrewrite_engine_path_listZre_pathr/   r/   r0   r£  Ö  s    
ÿz(ApacheConfigurator._is_rewrite_engine_onc                 C   sr   |   |¡}|  ||¡}| jj ¡  |  t |  |¡¡¡}| j 	|¡ | j
d  |¡ |  jd|j|jf 7  _dS )a/  Creates an http_vhost specifically to redirect for the ssl_vhost.

        :param ssl_vhost: ssl vhost
        :type ssl_vhost: :class:`~certbot_apache.obj.VirtualHost`

        :returns: tuple of the form
            (`success`, :class:`~certbot_apache.obj.VirtualHost`)
        :rtype: tuple

        rD   z=Created a port 80 vhost, %s, for redirection to ssl vhost %s
N)Ú_get_redirect_config_strÚ_write_out_redirectr   r   r‚   rû   r  r$  rS   r¤   rO   r@   rQ   r·   )r-   r.  ÚtextÚredirect_filepathr  r/   r/   r0   r   ç  s    

þz)ApacheConfigurator._create_redirect_vhostc                 C   s„   d}d}|j d k	rd|j  }|jr2dd |j¡ }g }|  ¡ dkrJtj}ntj}dd dd„ |  |¡D ƒ¡||d |¡|  d	¡f S )
NrC   zServerName zServerAlias r  r¦  z‹<VirtualHost %s>
%s 
%s 
ServerSignature Off

RewriteEngine On
RewriteRule %s

ErrorLog %s/redirect.error.log
LogLevel warn
</VirtualHost>
c                 s   s   | ]}t |ƒV  qd S rf   rg   r¯   r/   r/   r0   rl     s   ÿz>ApacheConfigurator._get_redirect_config_str.<locals>.<genexpr>r   )	r™   rð   r_   rr   r   r©  rª  rÄ   r1   )r-   r.  rí   rî   Zrewrite_rule_argsr/   r/   r0   r¯    s(    


ÿ üõz+ApacheConfigurator._get_redirect_config_strc              	   C   sœ   d}|j d k	r2t|j ƒdt|ƒd  k r2d|j  }tj |  d¡|¡}| j d|¡ t|dƒ}| 	|¡ W 5 Q R X | j
 |¡sŒ| j
 |¡ t d|¡ |S )	Nzle-redirect.conféÿ   r<   zle-redirect-%s.confr   FÚwzCreated redirect file: %s)r™   r›   r   r^   r_   r1   r=  r>  rA  rB  r   rC  r'  rs   r¶   )r-   r.  r±  Zredirect_filenamer²  Zredirect_filer/   r/   r0   r°  "  s    

ÿz&ApacheConfigurator._write_out_redirectc                 C   s\   |j r|j S dd„ | jD ƒ}|D ]}| |¡r |  S q |D ]}|j|ddr<|  S q<dS )z*Find appropriate HTTP vhost for ssl_vhost.c                 S   s   g | ]}|j s|‘qS r/   ry  rž   r/   r/   r0   rŸ   E  s     z6ApacheConfigurator._get_http_vhost.<locals>.<listcomp>T)ZgenericN)r)  rS   Zsame_server)r-   r.  Zcandidate_http_vhsZhttp_vhr/   r/   r0   rŸ  @  s    ÿ


z"ApacheConfigurator._get_http_vhostc                 C   s&   t ƒ }|jD ]}| | |¡¡ q|S )zïReturn all addrs of vhost with the port replaced with the specified.

        :param obj.VirtualHost ssl_vhost: Original Vhost
        :param str port: Desired port for new addresses

        :returns: `set` of :class:`~obj.Addr`

        )rL   r»   r@   r_  )r-   r‘   rÏ   Z	redirectsr°   r/   r/   r0   rÄ   T  s    	
z&ApacheConfigurator._get_proposed_addrsc                 C   s\   |j r
dS | j |j¡sXt d|j¡ |  jd|j 7  _| j | jjd |j¡ d|_ dS )a  Enables an available site, Apache reload required.

        .. note:: Does not make sure that the site correctly works or that all
                  modules are enabled appropriately.
        .. note:: The distribution specific override replaces functionality
                  of this method where available.

        :param vhost: vhost to enable
        :type vhost: :class:`~certbot_apache.obj.VirtualHost`

        :raises .errors.NotSupportedError: If filesystem layout is not
            supported.

        Nz8Enabling site %s by adding Include to root configurationzEnabled site %s
r9   T)	r¹   r   r÷   r·   rs   r¶   rQ   Zadd_includer  rc  r/   r/   r0   rº   c  s    ÿzApacheConfigurator.enable_sitec                 C   s   d}t  | |¡¡‚dS )a×  Enables module in Apache.

        Both enables and reloads Apache so module is active.

        :param str mod_name: Name of the module to enable. (e.g. 'ssl')
        :param bool temp: Whether or not this is a temporary action.

        .. note:: The distribution specific override replaces functionality
                  of this method where available.

        :raises .errors.MisconfigurationError: We cannot enable modules in
            generic fashion.

        zÄApache needs to have module  "{0}" active for the requested installation options. Unfortunately Certbot is unable to install or enable it for you. Please install the module, and run Certbot again.N)r	   ÚMisconfigurationErrorru   )r-   Úmod_namer½   Zmod_messager/   r/   r0   r"  ~  s    zApacheConfigurator.enable_modc                 C   s   |   ¡  |  ¡  dS )z¢Runs a config test and reloads the Apache server.

        :raises .errors.MisconfigurationError: If either the config test
            or reload fails.

        N)rq   Ú_reloadrb   r/   r/   r0   Úrestart“  s    zApacheConfigurator.restartc                 C   sÈ   zt  |  d¡¡ W n® tjk
rÂ } zŽt d|  d¡¡ |  d¡}|r t d|¡ zt  |  d¡¡ W W Y ¢HdS  tjk
rœ } zt|ƒ}W 5 d}~X Y q¨X nt|ƒ}t 	|¡‚W 5 d}~X Y nX dS )zdReloads the Apache server.

        :raises .errors.MisconfigurationError: If reload fails

        r"   z!Unable to restart apache using %sZrestart_cmd_altz&Trying alternative restart command: %sN)
r   Ú
run_scriptr1   r	   ÚSubprocessErrorrs   r¶   rt   rh   rµ  )r-   ÚerrZalt_restartZsecerrr£   r/   r/   r0   r·    s(    ÿ
ÿÿzApacheConfigurator._reloadc              
   C   sL   zt  |  d¡¡ W n2 tjk
rF } zt t|ƒ¡‚W 5 d}~X Y nX dS )z|Check the configuration of Apache for errors.

        :raises .errors.MisconfigurationError: If config_test fails

        r#   N)r   r¹  r1   r	   rº  rµ  rh   )r-   r»  r/   r/   r0   rq   ¸  s    zApacheConfigurator.config_testc              	   C   sŽ   zt  |  d¡¡\}}W n* tjk
rB   t d|  d¡ ¡‚Y nX t dtj¡}| 	|¡}t
|ƒdkrrt d¡‚tdd„ |d  d	¡D ƒƒS )
zÚReturn version of Apache Server.

        Version is returned as tuple. (ie. 2.4.7 = (2, 4, 7))

        :returns: version
        :rtype: tuple

        :raises .PluginError: if unable to find Apache version

        r!   zUnable to run %s -vzApache/([0-9\.]*)r<   zUnable to find Apache versionc                 S   s   g | ]}t |ƒ‘qS r/   )Úintri   r/   r/   r0   rŸ   Û  s     z2ApacheConfigurator.get_version.<locals>.<listcomp>r   re   )r   r¹  r1   r	   rº  r{   re  ÚcompileÚ
IGNORECASEÚfindallr›   Útuplerœ   )r-   Ústdoutr2   Zregexrj  r/   r/   r0   rr   Ã  s    ÿÿ


zApacheConfigurator.get_versionc                 C   s,   dj tj| jjd d dd„ | jD ƒ¡dS )z3Human-readable string to help understand the modulez_Configures Apache to authenticate and install HTTPS.{0}Server root: {root}{0}Version: {version}Úrootre   c                 s   s   | ]}t |ƒV  qd S rf   rg   ri   r/   r/   r0   rl   ä  s     z/ApacheConfigurator.more_info.<locals>.<genexpr>)rÂ  rB   )ru   r   Úlinesepr   r  r_   rB   rb   r/   r/   r0   Ú	more_infoÝ  s     
üÿzApacheConfigurator.more_infoc                 C   s   t jgS )z%Return list of challenge preferences.)r   ZHTTP01)r-   Zunused_domainr/   r/   r0   Úget_chall_prefê  s    z!ApacheConfigurator.get_chall_prefc                 C   sr   | j  |¡ dgt|ƒ }t | ¡}t|ƒD ]\}}| ||¡ q,| ¡ }|rn|  ¡  t	 
d¡ |  |||¡ |S )a	  Perform the configuration related challenge.

        This function currently assumes all challenges will be fulfilled.
        If this turns out not to be the case in the future. Cleanup and
        outstanding challenges will have to be designed better.

        NrÓ   )rM   rÞ   r›   r   ZApacheHttp01r[  Z	add_challÚperformr¸  r„  ÚsleepÚ_update_responses)r-   ÚachallsÚ	responsesZ	http_doerrk   ZachallZhttp_responser/   r/   r0   rÆ  î  s    

zApacheConfigurator.performc                 C   s$   t |ƒD ]\}}|||j| < qd S rf   )r[  Úindices)r-   rÊ  Zchall_responseZ
chall_doerrk   Zrespr/   r/   r0   rÈ  	  s    z$ApacheConfigurator._update_responsesc                 C   s0   | j  |¡ | j s,|  ¡  |  ¡  | j ¡  dS )zRevert all challenges.N)rM   Údifference_updaterƒ   r¸  r   Zreset_modules)r-   rÉ  r/   r/   r0   Úcleanup	  s
    zApacheConfigurator.cleanupc                 C   s   t  |||  d¡tj¡S )zICopy Certbot's SSL options file into the system's config dir if required.r*   )r   Zinstall_version_controlled_filer1   r   ZALL_SSL_OPTIONS_HASHES)r-   Zoptions_sslZoptions_ssl_digestr/   r/   r0   ry    	  s     ÿz+ApacheConfigurator.install_ssl_options_confc                 C   sæ   |   ¡  g }|D ]¤}| j|dd}dd„ |D ƒ}|sVd}| |¡}t |¡ t |¡‚|D ]X}	z|  |	¡ | |	¡ W qZ tj	k
r°   |	|kr”Y qZd}t 	| ||	j
¡¡‚Y qZX qZq|rÚd}
|  |
¡ t |
¡ |  ¡  |  ¡  dS )	a$  
        Enable the AutoHSTS enhancement for defined domains

        :param _unused_lineage: Certificate lineage object, unused
        :type _unused_lineage: certbot.storage.RenewableCert

        :param domains: List of domains in certificate to enhance
        :type domains: str
        Frx  c                 S   s   g | ]}|j r|‘qS r/   ry  rž   r/   r/   r0   rŸ   9	  s      z6ApacheConfigurator.enable_autohsts.<locals>.<listcomp>z`Certbot was not able to find SSL VirtualHost for a domain {0} for enabling AutoHSTS enhancement.z_VirtualHost for domain {0} in file {1} has a String-Transport-Security header present, exiting.zEnabling AutoHSTSN)r‘  r‹   ru   rs   rµ   r	   r{   Ú_enable_autohsts_domainr¤   r  r·   r   r¶   r¸  r’  )r-   Z_unused_lineageZdomainsrO   Údr|  rS   r}  r
  rÚ   rŽ  r/   r/   r0   Úenable_autohsts)	  s6    



ÿ

z"ApacheConfigurator.enable_autohstsc                 C   s¶   |   |d¡ d| jjkr"|  d¡ tjd dd… }tjd }| d |¡¡ |  	|¡}|  j
d ||j¡7  _
| j |jd	|¡ d
 ||j¡}|  j
|7  _
dt ¡ dœ| j|< dS )a  Do the initial AutoHSTS deployment to a vhost

        :param ssl_vhost: The VirtualHost object to deploy the AutoHSTS
        :type ssl_vhost: :class:`~certbot_apache.obj.VirtualHost` or None

        :raises errors.PluginEnhancementAlreadyPresent: When already enhanced

        zStrict-Transport-Securityr˜  r™  Nr®   r   r‰  z+Adding unique ID {0} to VirtualHost in {1}
rˆ  zXAdding gradually increasing HSTS header with initial value of {0} to VirtualHost in {1}
r  )rš  r   r!  r"  r   r›  r‚  r¤   ru   ro  rQ   r·   r¸   r^   r„  rP   )r-   r.  Zhsts_headerZinitial_maxageZuniq_idrŽ  r/   r/   r0   rÎ  U	  s(    
ÿ



 ÿ þz*ApacheConfigurator._enable_autohsts_domainc           	   	   C   s  |   ¡  | jsdS t ¡ }d}t| j ¡ ƒD ]¸\}}|d tj |krHq,|d d }|ttjƒk r,| j	sp|  
¡  z|  |¡}W n: tjk
r¸   d |¡}t |¡ | j |¡ Y q,Y nX |  |||¡ d |¡}|  j|7  _d}q,|rü|  d	¡ |  ¡  |  ¡  dS )
zÖ
        Increase the AutoHSTS values of VirtualHosts that the user has enabled
        this enhancement for.

        :param _unused_domain: Not currently used
        :type _unused_domain: Not Available

        NFr  r€  r<   zOCould not find VirtualHost with ID {0}, disabling AutoHSTS for this VirtualHostz9Increasing HSTS max-age value for VirtualHost with id {0}TzIncreased HSTS max-age values)r‘  rP   r„  r˜   r¬  r   ZAUTOHSTS_FREQr›   r‚  rR   r|   rm  r	   r{   ru   rs   rµ   rG   r‡  rQ   r   r¸  r’  )	r-   Z_unused_domainZcurtimeÚsave_and_restartrl  r`   r…  r‘   r
  r/   r/   r0   Úupdate_autohstsw	  s>    	ÿ

ÿ
z"ApacheConfigurator.update_autohstsc           	   	   C   s6  |   ¡  | jsdS g }g }t| j ¡ ƒD ]ˆ\}}|d d ttjƒkr(z|  |¡}W n: tj	k
rŽ   d 
|¡}t |¡ | j |¡ Y q(Y nX |  ||¡r(| |¡ | |¡ q(d}|D ]>}|  |tj¡ d 
|j¡}t |¡ |  j|d 7  _d}qº|r|  d	¡ |  ¡  |D ]}| j |¡ q|  ¡  dS )
zò
        Checks if autohsts vhost has reached maximum auto-increased value
        and changes the HSTS max-age to a high value.

        :param lineage: Certificate lineage object
        :type lineage: certbot.storage.RenewableCert
        Nr€  r<   zLVirtualHost with id {} was not found, unable to make HSTS max-age permanent.FzRStrict-Transport-Security max-age value for VirtualHost in {0} was made permanent.r;  TzMade HSTS max-age permanent)r‘  rP   r˜   r¬  r›   r   r‚  rm  r	   r{   ru   rs   rµ   rG   r•  r¤   rƒ  ZAUTOHSTS_PERMANENTr·   rt   rQ   r   r¸  r’  )	r-   r”  rS   Zaffected_idsrl  r`   r‘   r
  rÑ  r/   r/   r0   Údeploy_autohsts¥	  sD    ÿ


ÿ

z"ApacheConfigurator.deploy_autohsts)NF)r<   )NN)T)T)T)F)rÊ   )NT)F)F)N)rÊ   )F)oÚ__name__Ú
__module__Ú__qualname__Ú__doc__Zdescriptionr   r>   r,   rJ   Úpkg_resourcesZresource_filenamer6   r1   r8   ÚclassmethodrA   rI   Úpropertyrc   rd   r|   r   rv   rƒ   r„   rp   rw   rŠ   r’   r‹   rš   r—   r“   rŒ   r”   rÀ   rÉ   rÒ   r¾   rÛ   rä   rà   rï   rñ   rû   rx   r  r  r±   r  r  r  r  r  r¥   r&  r#  r:  r%  r@  r?  rY  r(  r³   ra  rb  r²   r¿   rh  r*  rm  rk  ro  r$  rw  r~  r‡  rƒ  r‘  r’  r•  rX   rW   rš  rV   r¤  r¡  r¢  r£  r   r¯  r°  rŸ  rÄ   rº   r"  r¸  r·  rq   rr   rÄ  rÅ  rÆ  rÈ  rÍ  ry   rÐ  rÎ  rÒ  rÓ  Ú__classcell__r/   r/   r\   r0   r   G   sþ   ÿ ÿñ
&"

4
	   ÿ


,L
(


=!,5

2!N!0@
#
)	
>(Q0!


!
	,".r   )8r×  rT   r   Zloggingre  rå   r„  Úcollectionsr   rØ  r‡   Zzope.componentrá   Zzope.interfaceZacmer   Zacme.magic_typingr   r   r   r   r   Zcertbotr	   r
   r   Zcertbot.achallengesr   Zcertbot.compatr   r   Zcertbot.pluginsr   Zcertbot.plugins.utilr   Zcertbot.plugins.enhancementsr   r   r   r   r   r   r   r   Z	getLoggerrÔ  rs   Z	interfaceZimplementerZIAuthenticatorZ
IInstallerZproviderZIPluginFactoryZ	Installerr   Úregisterr/   r/   r/   r0   Ú<module>   sh   
                    "