o
    c                    @   s,  d 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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 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- ddl*m.Z. ddl*m/Z/ dd l*m0Z0 dd!l*m1Z1 dd"l*m2Z2 dd#l3m4Z4 zddl5Z5d$Z6W n e7y   d%Z6Y nw e8e9Z:G d&d' d'Z;G d(d) d)e%j<Z=e'>e= dS )*zApache Configurator.    )defaultdictN)Any)Callable)cast)DefaultDict)Dict)Iterable)List)Optional)Sequence)Set)Tuple)Type)Union)
challenges)achallenges)errors)util)
filesystem)os)RenewableCert)common)AutoHSTSEnhancement)path_surgery)apache_util)
assertions)	constants)display_ops)
dualparser)http_01)obj)parser)ApacheBlockNodeTFc                #   @   s   e Zd ZdZ																		dd
edededededeee  deee  deee  deee  dee dee dededededee ddf"ddZdS )	OsOptionsz
    Dedicated class to describe the OS specificities (eg. paths, binary names)
    that the Apache configurator needs to be aware to operate properly.
    /etc/apache2/etc/apache2/sites-available*/var/log/apache2
apache2ctlN-le-ssl.confFserver_root
vhost_rootvhost_files	logs_rootctlversion_cmdrestart_cmdrestart_cmd_altconftest_cmdenmoddismodle_vhost_exthandle_moduleshandle_siteschallenge_location
apache_binreturnc                 C   s   || _ || _|| _|| _|| _|sddgn|| _|sddgn|| _|| _|	s*ddgn|	| _|ddg}|dg | _	|dg | _
|d	g | _|
| _|| _|| _|| _|| _|| _|| _d S )
Nr(   z-vgraceful
configtestz-tz-DDUMP_RUN_CFGDUMP_INCLUDESDUMP_MODULES)r*   r+   r,   r-   r.   r/   r0   r1   r2   get_defines_cmdget_includes_cmdget_modules_cmdr3   r4   r5   r6   r7   r8   bin)selfr*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r4   r5   r6   r7   r8   r9   syntax_tests_cmd_base rF   R/opt/certbot/lib/python3.10/site-packages/certbot_apache/_internal/configurator.py__init__<   s(   

zOsOptions.__init__)r$   r%   r&   r'   r(   NNNNNNr)   FFr$   N)	__name__
__module____qualname____doc__strr
   r	   boolrH   rF   rF   rF   rG   r#   7   sj    



	
r#   c                       s2
  e Zd ZU dZdZeed< ej	ddkred7 Ze
 Ze
ed< dd	ed
efddZdddZdddZeded d
dfddZdeded
df fddZed
efddZed
efddZded
ee fdd Zdd	ed
ee fd!d"Zdd#d$Zd d&ee d'ed
dfd(d)Zd fd*d+Zdd,d-Zd!d/e d
df fd0d1Z!d2ed
dfd3d4Z"d
e#j$fd5d6Z%d7e&eef d
e'j(fd8d9Z)	d"d:ed;ed<ed=ee d>ee d
dfd?d@Z*dd:edAed
e+e,j- fdBdCZ.d:ed
e+e,j- fdDdEZ/dFed
e0j1fdGdHZ2dIed:ed
ee fdJdKZ3dd:edLed
e+e,j- fdMdNZ4	d"dOe,j-d;ed<ed=ee d>ee d
dfdPdQZ5ddFedAed
e,j-fdRdSZ6	%d#dFedTed
e,j-fdUdVZ7dWe8e dFed
efdXdYZ9	Zd$d[ed\ed]ed
ee,j- fd^d_Z:		d%dFed`ee+e,j-  d\ed
ee,j- fdadbZ;d`e+e,j- d
e+e,j- fdcddZ<d
e=e fdedfZ>dge,j?d
efdhdiZ@djee d
eAee e+ee  f fdkdlZBdme,j-d
dfdndoZCdjed
ee,j- fdpdqZDd
e+e,j- fdrdsZEd
e+e,j- fdtduZFd
e+e,j- fdvdwZGdxeHd
e,j-fdydzZIdOe,j-d
dfd{d|ZJd#d]edTed
dfd}d~ZKd#d]eded
dfddZLde=e de+e d]ed
dfddZMde=e de+e d]ed
dfddZNde+e d]ed
ee fddZOdTed
dfddZPde,j-d
e,j-fddZQde+e de+e d
ee fddZRded
efddZSded
efddZTdOe,j-ded
dfddZUde8e d
eAe+e ef fddZVdOe,j-d
e+e fddZWde+e d
dfddZXded
e=e,j? fddZYdOe,j-d
dfddZZdee de+e d
dfddZ[dee de+e d
dfddZ\ded
dfddZ]dFedOe,j-d
dfddZ^dedFed
efddZ_ded
e,j-fddZ`dOe,j-d
ee fddZadOe,j-d
ee fddZbded
efddZcd
e+e fddZd	d&d:ededeeee+e ef  d
dfddÄZfdOe,j-dede d
dfddƄZgdOe,j-dehd
dfddɄZiddd˄Zjddd̈́ZkdOe,j-deld
efddЄZmde,j-ded
dfddԄZnde,j-ded
dfddׄZode,j-ded
dfddلZpde,j-ded
dfddۄZqdOe,j-d
dfdd݄ZrdOe,j-d
dfdd߄ZsdOe,j-d
efddZtdOe,j-d
eeeeef  fddZude,j-d
dfddZvde,j-d
efddZwde,j-ded
efddZxde,j-d
ee,j- fddZyd$dOe,j-d]ed
e8e,j? fddZzdOe,j-d
dfddZ{d#dedTed
dfddZ|dddZ}dddZ~dddZd
eAe df fddZd
efddZde8ej d
efd dZded
eeej  fddZde+ej d
e+ej fddZde+eej  d	e+ej d
ejd
dfddZde+ej d
dfddZ	ddeded	ed
dfddZdelde+e d
dfddZde,j-d
dfddZded
dfddZdeld
dfddZ  ZS ('  ApacheConfiguratora  Apache configurator.

    :ivar config: Configuration.
    :type config: certbot.configuration.NamespaceConfig

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

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

    :ivar dict assoc: Mapping between domains and vhosts

    zApache Web Server plugindescriptionCERTBOT_DOCS1z (Please note that the default values of the Apache plugin options change depending on the operating system Certbot is run on.)OS_DEFAULTSTwarn_on_no_mod_sslr:   c                 C   sD   t d}| |}| jdk s|rt ||k rtdS tdS )a  
        Pick the appropriate TLS Apache configuration file for current version of Apache and OS.

        :param bool warn_on_no_mod_ssl: True if we should warn if mod_ssl is not found.

        :return: the path to the TLS Apache configuration file to use
        :rtype: str
        z1.0.2l)         oldcurrent)r   parse_loose_versionopenssl_versionversionr   find_ssl_apache_conf)rD   rT   min_openssl_versionr[   rF   rF   rG   pick_apache_config   s   



z%ApacheConfigurator.pick_apache_configNc                 C   sd   | j j| j jd< | j j| j jd< | j j| j jd< | j j| j jd< | j j| j jd< | j j| j jd< dS )zd
        Set our various command binaries to whatever the user has overridden for apachectl
        r   N)optionsr.   r/   r0   r2   rB   rA   r@   rD   rF   rF   rG   _override_cmds   s   z!ApacheConfigurator._override_cmdsc              
   C   sh   g d}|D ]'}|  |dddur"t| j||  |dd qt| j|t| j| q|   dS )zw
        Set the values possibly changed by command line parameters to
        OS_DEFAULTS constant dictionary
        )r3   r4   r5   r*   r+   r-   r8   r6   r7   r.   rC   _-N)confreplacesetattrr`   getattrrS   rb   )rD   optsorF   rF   rG   _prepare_options   s   z#ApacheConfigurator._prepare_optionsadd).Nc                 C   s   t jddkrtj}n| j}|d|jdd |d|jdd |d|jd	d |d
|jdd |dd dd |d|j	dd |d|j
dd |d|jdd |d|jdd |d|jdd |d|jdd d S )NrQ   rR   r3   z#Path to the Apache 'a2enmod' binary)defaulthelpr4   z$Path to the Apache 'a2dismod' binaryzle-vhost-extz!SSL vhost configuration extensionzserver-rootzApache server root directory
vhost-rootz,Apache server VirtualHost configuration rootz	logs-rootzApache server logs directoryzchallenge-locationz*Directory path for challenge configurationzhandle-moduleszULet installer handle enabling required modules for you (Only Ubuntu/Debian currently)zhandle-siteszJLet installer handle enabling sites for you (Only Ubuntu/Debian currently)r.   z"Full path to Apache control scriptrC   z!Full path to apache2/httpd binary)r   environgetrO   rS   r3   r4   r5   r*   r-   r8   r6   r7   r.   rC   )clsrl   DEFAULTSrF   rF   rG   add_parser_arguments   sJ   
z'ApacheConfigurator.add_parser_argumentsargskwargsc                    s   | dd}| dd}| dd}t j|i | i | _t | _i | _tt| _i | _	d| _
|| _g | _d| _|  d| _|| _|| _|  t| j| _| j| j| jd| _dS )zInitialize an Apache Configurator.

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

        r\   Nuse_parsernodeFr[    redirectzensure-http-headerzstaple-ocsp)popsuperrH   assocset
_chall_out_wildcard_vhostsr   _enhanced_vhosts	_autohsts
save_notesUSE_PARSERNODEparsed_paths	_preparedparser_rootr\   _openssl_versioncopydeepcopyrS   r`   _enable_redirect_set_http_header_enable_ocsp_stapling_enhance_func)rD   ru   rv   r\   rw   r[   	__class__rF   rG   rH      s.   
zApacheConfigurator.__init__c                 C      t j| jjtjS )z-Full absolute path to SSL configuration file.)r   pathjoinconfig
config_dirr   MOD_SSL_CONF_DESTra   rF   rF   rG   mod_ssl_conf     zApacheConfigurator.mod_ssl_confc                 C   r   )z?Full absolute path to digest of updated SSL configuration file.)r   r   r   r   r   r   UPDATED_MOD_SSL_CONF_DIGESTra   rF   rF   rG   updated_mod_ssl_conf_digest   r   z.ApacheConfigurator.updated_mod_ssl_conf_digestssl_module_locationc              
   C   sx   zt |dd}| }W d   W |S 1 sw   Y  W |S  ty; } ztjt|dd W Y d}~dS d}~ww )z>Extract the open lines of openssl_version for testing purposesrb)modeNTexc_info)openreadIOErrorloggerdebugrM   )rD   r   fcontentserrorrF   rF   rG   _open_module_file%  s   
z$ApacheConfigurator._open_module_filec                 C   s   | j r| j S z| jjd }W n ty   |rtd Y dS w |r)| j|}n| jjr2| jj}ntd dS | 	|}|sGtd dS t
d|}|sVtd dS |d d	| _ | j S )
ao  Lazily retrieve openssl version

        :param bool warn_on_no_mod_ssl: `True` if we should warn if mod_ssl is not found. Set to
            `False` when we know we'll try to enable mod_ssl later. This is currently debian/ubuntu,
            when called from `prepare`.

        :return: the OpenSSL version as a string, or None.
        :rtype: str or None
        
ssl_modulez9Could not find ssl_module; not disabling session tickets.Nz[ssl_module is statically linked but --apache-bin is missing; not disabling session tickets.z>Unable to read ssl_module file; not disabling session tickets.s   OpenSSL ([0-9]\.[^ ]+) z>Could not find OpenSSL version; not disabling session tickets.r   zUTF-8)r   r!   modulesKeyErrorr   warningstandard_path_from_server_rootr`   rC   r   refindalldecode)rD   rT   r   r   matchesrF   rF   rG   r[   /  s2   






z"ApacheConfigurator.openssl_versionc              	   C   s<  |    | | jj |   | jdu r(|  | _tdd	dd | jD  | jdk r8t
dt| j|   |  | _| j| j dd}| jr[| |}|| _| | _| jd	 |  | _| jj }| | j| j| z	t| jj W n t t
j!fy   tjd
dd t
"d| jjw 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

        NzApache version is %s.c                 s       | ]}t |V  qd S NrM   .0irF   rF   rG   	<genexpr>o      z-ApacheConfigurator.prepare.<locals>.<genexpr>)rU   rV   z!Apache Version {0} not supported.)augeasparser
augeaspathac_astz	httpd.augzEncountered error:Tr   z|Unable to create a lock file in {0}. Are you running Certbot with sufficient privileges to modify your Apache configuration?)$rk   _verify_exe_availabilityr`   r.   config_testr\   get_versionr   r   r   r   NotSupportedErrorformatrM   recovery_routine
get_parserr!   get_root_augpathr   get_parsernode_rootr   r   check_parsing_errorsget_virtual_hostsvhostsr6   install_ssl_options_confr   r   r   lock_dir_until_exitr*   OSError	LockErrorPluginErrorr   )rD   pn_metar   rT   rF   rF   rG   prepareZ  sN   	









zApacheConfigurator.prepareFtitle	temporaryc                 C   sJ   | j  }|r| j|| j|d | j | |r!|s#| | dS d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)

        )r   N)r!   unsaved_filesadd_to_checkpointr   savefinalize_checkpoint)rD   r   r   
save_filesrF   rF   rG   r     s   
zApacheConfigurator.savec                    s(   t    t| dr| jj  dS 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

        r!   N)r|   r   hasattrr!   augloadra   r   rF   rG   r     s   

z#ApacheConfigurator.recovery_routinec                 C   s   |    | jj  dS )zUsed to cleanup challenge configurations.

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

        N)revert_temporary_configr!   r   r   ra   rF   rF   rG   revert_challenge_config  s   z*ApacheConfigurator.revert_challenge_config   rollbackc                    s   t  | | jj  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   )rD   r   r   rF   rG   r     s   	z'ApacheConfigurator.rollback_checkpointsexec                 C   s*   t |st|std|dS dS )z(Checks availability of Apache executablez!Cannot find Apache executable {0}N)r   
exe_existsr   r   NoInstallationErrorr   )rD   r   rF   rF   rG   r     s   
z+ApacheConfigurator._verify_exe_availabilityc                 C   s   t j| jj| | d| jdS )zInitializes the ApacheParserro   )r\   )r!   ApacheParserr`   r*   re   r\   ra   rF   rF   rG   r     s   zApacheConfigurator.get_parsermetadatac              	   C   s   t rXt| jjt| jjt| jjd}||d< t	| j
jd -}tjd	dditjj}|| |d< W d   n1 sDw   Y  W d   n1 sSw   Y  tjtjd| j
jd |dS )
z0Initializes the ParserNode parser root instance.)definesincludesr   apache_varsrootwritableTr   N)nameancestorfilepathr   rF   )HAS_APACHECONFIGr   parse_definesr`   r@   parse_includesrA   parse_modulesrB   r   r!   locapacheconfigmake_loaderflavorsNATIVE_APACHEloadsr   r   DualBlockNoder   PASS)rD   r   r   r   loaderrF   rF   rG   r     s*   
z&ApacheConfigurator.get_parsernode_rootdomain	cert_pathkey_path
chain_pathfullchain_pathc                 C   s>   |  |}|D ]}| ||||| td||j 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

        z.Successfully deployed certificate for {} to {}N)choose_vhosts_deploy_certdisplay_utilnotifyr   filep)rD   r   r   r   r   r   r   vhostrF   rF   rG   deploy_cert  s   

zApacheConfigurator.deploy_certcreate_if_no_sslc                 C   s8   t |r|| jv r| j| S | ||S | ||g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._internal.obj.VirtualHost`
        )r   is_wildcard_domainr   _choose_vhosts_wildcardchoose_vhost)rD   r   r  rF   rF   rG   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.
        )r~   r   	get_names_in_wildcard_scoperl   list)rD   r   matchedr  r   rF   rF   rG   _vhosts_for_wildcard,  s   

z'ApacheConfigurator._vhosts_for_wildcardtarget_namec                 C   s   t d|S )a  
        Prepare an error to notify the user that Certbot could not find a vhost
        to secure.
        :param str target_name: The server name that could not be mapped
        :return: An instance of PluginError
        :rtype: errors.PluginError
        zCertbot could not find a VirtualHost for {0} in the Apache configuration. Please create a VirtualHost with a ServerName matching {0} and try again.)r   r   r   )rD   r  rF   rF   rG   !_generate_no_suitable_vhost_error;  s   z4ApacheConfigurator._generate_no_suitable_vhost_errorr   c                 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
        r   N)lensplitfnmatch)rD   r   r   rF   rF   rG   r  I  s   z%ApacheConfigurator._in_wildcard_scope
create_sslc           
      C   s   |  |}i }|D ]}| D ]}|jr|||< q||vr#|r#|||< qq	t| }tt|}|s9| |g }	|D ]}|jsK|		| 
| q=|		| q=|	| j|< |	S )zCPrompts user to choose vhosts to install a wildcard certificate for)r  r
  sslr~   valuesr   select_vhost_multipler  r  appendmake_vhost_sslr   )
rD   r   r  r   filtered_vhostsr  r   dialog_inputdialog_outputreturn_vhostsrF   rF   rG   r  U  s*   

	

z*ApacheConfigurator._choose_vhosts_wildcardr  c                 C   s  |  d d| jjvrtd| |j | | | jdd|j| jdd|jd}|dur=| jdd|j|d	< t	
d
|j | jdk sM|rz|sz|}| jj|d d | | jj|d d | |duru| j|jd| n&td|std|}| jj|d d | | jj|d d | |js| | |  jd|jddd |jD ||f 7  _|dur|  jd| 7  _dS 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
        443r   z6Could not find ssl_module; not installing certificate.SSLCertificateFileNSSLCertificateKeyFile)r   cert_keySSLCertificateChainFiler   z'Deploying Certificate to VirtualHost %s)rU   rV      r   r!  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   r   r   r   r   addrrF   rF   rG   r     r   z2ApacheConfigurator._deploy_cert.<locals>.<genexpr>z	SSLCertificateChainFile %s
)prepare_server_httpsr!   r   r   MisconfigurationError_add_dummy_ssl_directivesr   _clean_vhostfind_dirr   infor  r\   r   r~   add_dirr   enabledenable_siter   r   addrs)rD   r  r   r   r   r   r   set_cert_pathrF   rF   rG   r   }  sL   






zApacheConfigurator._deploy_certc                 C   sh   || j v r
| j | S | |}|dur,|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._internal.obj.VirtualHost`

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

        Ntemp)r}   _find_best_vhostr  r  _add_servername_alias_choose_vhost_from_list)rD   r  r  r  rF   rF   rG   r	    s   




zApacheConfigurator.choose_vhostr3  c                    s   t || j}|d u r| ||r|S |js9| |d t fdd| jD s/| |}n
t	d t
d| || || j|< |S )Nr  c                 3   s     | ]}|j o| V  qd S r   )r.  	conflicts)r   	one_vhostr0  rF   rG   r     s    z=ApacheConfigurator._choose_vhost_from_list.<locals>.<genexpr>zThe 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   select_vhostr   r  r  _get_proposed_addrsanyr  r   r   r   r   r5  r}   )rD   r  r3  r  rF   r9  rG   r6    s$   


z*ApacheConfigurator._choose_vhost_from_listnamesc                 C   s8   |  }|D ]}|  }d|v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  )rD   r=  r  r   rF   rF   rG   domain_in_names  s   z"ApacheConfigurator.domain_in_names80targetfilter_defaultsportc                    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 r   )is_wildcardget_port)r   arD  rF   rG   r   )  s   " z:ApacheConfigurator.find_best_http_vhost.<locals>.<genexpr>)r   r<  r0  r  r  r4  )rD   rB  rC  rD  r  r  rF   rH  rG   find_best_http_vhost  s   

z'ApacheConfigurator.find_best_http_vhostr   c           
         s   d}d}|du r| j }|D ];}|jdu rq| } |v r d}n| | r)d}nt fdd|jD r8d}nq|jr@|d7 }||krH|}|}q|du re|rT| |}d	d
 |D }	t|	dkre|	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._internal.obj.VirtualHost`
        :param bool filter_defaults: whether a vhost with a _default_
            addr is acceptable

        :returns: VHost or None

        Nr   T   rU   c                 3   s    | ]	}|   kV  qd S r   get_addrr%  r  rF   rG   r   S  s    z6ApacheConfigurator._find_best_vhost.<locals>.<genexpr>r   c                 S   s   g | ]	}|j d u r|qS Fmodmacror   vhrF   rF   rG   
<listcomp>f  s    
z7ApacheConfigurator._find_best_vhost.<locals>.<listcomp>)	r   rP  r
  r@  r<  r0  r  _non_default_vhostsr  )
rD   r  r   rC  best_candidatebest_pointsr  r=  pointsreasonable_vhostsrF   rM  rG   r4  -  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_NrK  r%  rF   rF   rG   r   o  s    
zDApacheConfigurator._non_default_vhosts.<locals>.<listcomp>.<genexpr>)allr0  rQ  rF   rF   rG   rS  o  s    z:ApacheConfigurator._non_default_vhosts.<locals>.<listcomp>rF   )rD   r   rF   rF   rG   rT  m  s   z&ApacheConfigurator._non_default_vhostsc                 C   s   t  }g }| jD ]4}||  |jr||j |jD ]}tj	
| r/||  q| |}|r;|| qq|rLtjdd|dd t|S )zReturns 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)force_interactive)r~   r   updater
  rP  r  r  r0  r   hostname_regexmatchrL  rl   get_name_from_ipr  notificationr   r   r   get_filtered_names)rD   	all_namesvhost_macror  r&  r   rF   rF   rG   get_all_namess  s.   




z ApacheConfigurator.get_all_namesr&  c              
   C   sX   t j| s*zt|  t| d W S  tjtjtj	fy)   Y dS w dS )zReturns 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   rx   )
r   private_ips_regexr^  rL  socket	inet_atongethostbyaddrr   herrortimeout)rD   r&  rF   rF   rG   r_    s   z#ApacheConfigurator.get_name_from_ipr   c                 C   sl   | j jdd|dd}| j jdd|dd}g }|D ]}| j |}|| qd}|r2| j |d }||fS )zHelper 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startexcludeServerAliasr$  )r!   r+  get_argr  )rD   r   servername_matchserveralias_matchserveraliasesaliasserveralias
servernamerF   rF   rG   _get_vhost_names  s   	z#ApacheConfigurator._get_vhost_nameshostc                 C   sH   |  |j\}}|D ]}|js|dur|j| q
|js"||_dS dS )zHelper function for get_virtual_hosts().

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

        N)rw  r   rP  aliasesrl   r   )rD   rx  rv  rs  rt  rF   rF   rG   _add_servernames  s   
z#ApacheConfigurator._add_servernamesc                 C   s"  t  }z| jj|d }W n ty   td| Y dS w |D ]}| j|}|dur<tj	
|}|dur<|| q!d}| jjdd|ddrKd}|D ]
}| d	krWd}qMt| jjd
t| d}|du rodS d}	d| v ryd}	| j|}
tj|||||
|	d}| | |S )zUsed by get_virtual_hosts to create vhost objects

        :param str path: Augeas path to virtual host

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

        /argz6Encountered a problem while parsing file: %s, skippingNF	SSLEngineonrl  Tr  z/augeas/filesz/pathz/macro/rO  )r~   r!   r   r^  RuntimeErrorr   r   rp  r    Addr
fromstringrl   r+  rF  r   get_file_pathrq   r?  parsed_in_originalVirtualHostrz  )rD   r   r0  ru   arg	arg_valuer&  is_sslfilenamemacrovhost_enabledr  rF   rF   rG   _create_vhost  sF   	

z ApacheConfigurator._create_vhostc                 C   sb   |   }| jr/tr/|  }|D ]}d}|D ]}t||r!d} nq|s,td|jq|S |S )z
        Temporary wrapper for legacy and ParserNode version for
        get_virtual_hosts. This should be replaced with the ParserNode
        implementation when ready.
        FTzEquivalent for {} was not found)	get_virtual_hosts_v1r   r   get_virtual_hosts_v2r   isEqualVirtualHostAssertionErrorr   r   )rD   	v1_vhosts	v2_vhostsv1_vhfoundv2_vhrF   rF   rG   r     s   
z$ApacheConfigurator.get_virtual_hostsc                 C   sL  i }t t}g }t| jjD ]}| jjd|tdf }dd |D }|D ]{}| |}|s1q't	
|j}t|j}	|	|vrS|j||	< ||	 | || q'|	|jkr|	||	 krg }
|D ]}|j||	 krw||	 t	
|j qb|
| qb|
}|	||	< ||	 | || q'|||	 vr||	 | || q'q|S )zReturns list of virtual hosts found in the Apache configuration.

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

        z"/files%s//*[label()=~regexp('%s')]r  c                 S   s$   g | ]}d t j| v r|qS )virtualhost)r   r   basenamer?  )r   r   rF   rF   rG   rS  ,  s    
z;ApacheConfigurator.get_virtual_hosts_v1.<locals>.<listcomp>)r   r~   r  r!   parser_pathsr   r^  case_ir  r   get_internal_aug_pathr   r   realpathr  rl   r  remove)rD   
file_pathsinternal_pathsvhs
vhost_pathpathsr   	new_vhostinternal_pathr  new_vhsvrF   rF   rG   r    sP   	





z'ApacheConfigurator.get_virtual_hosts_v1c                 C   sH   | j stdg }| j jddd}|D ]}|| tt| q|S )zReturns list of virtual hosts found in the Apache configuration using
        ParserNode interface.
        :returns: List of :class:`~certbot_apache.obj.VirtualHost`
            objects found in configuration
        :rtype: list
        zHThis ApacheConfigurator instance is not configured to use a node parser.r  Frn  )r   r   Errorfind_blocksr  _create_vhost_v2r   r"   )rD   r  r   vhblockrF   rF   rG   r  O  s   
z'ApacheConfigurator.get_virtual_hosts_v2nodec              	   C   s   t  }|jD ]}tj|}|r|| qd}|jddd}|r3|D ]}|jd  dkr2d} nq#|D ]
}| dkr?d}q5|j	du rJt
d	t|j	| j}d}	|d
r[d}	tj|j	d||||	|d}
| |
 |
S )a  Used by get_virtual_hosts_v2 to create vhost objects using ParserNode
        interfaces.
        :param ApacheBlockNode node: The BlockNode object of VirtualHost block
        :returns: newly created vhost
        :rtype: :class:`~certbot_apache.obj.VirtualHost`
        Fr|  r  r   r}  Tr  NzNode filepath cannot be None.Macrorx   )rP  r  )r~   
parametersr    r  r  rl   find_directivesr?  rF  r   r   r  r   included_in_pathsr   find_ancestorsr  _populate_vhost_names_v2)rD   r  r0  paramr&  r  	sslengine	directiver.  r  r  rF   rF   rG   r  `  s:   





z#ApacheConfigurator._create_vhost_v2c                 C   s|   |j std|j jddd}|j jddd}d}|r#|d jd }|js<|D ]}|jD ]}|j| q-q(||_dS dS )zHelper function that populates the VirtualHost names.
        :param host: In progress vhost whose names will be added
        :type host: :class:`~certbot_apache.obj.VirtualHost`
        z Current VirtualHost has no node.rk  Fr  ro  Nr$  )	r  r   r   r  r  rP  ry  rl   r   )rD   r  rq  rr  rv  rt  ru  rF   rF   rG   r    s   


z+ApacheConfigurator._populate_vhost_names_v2c                 C   s   |  | | j|dd dS )zPrepare 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
        :param bool temp: If this is just temporary
        T)httpsN)prepare_https_modulesensure_listen)rD   rD  r3  rF   rF   rG   r'    s   

z'ApacheConfigurator.prepare_server_httpsr  c           
         s$  |r|dkr| d}n|} fdd j dD }dd |D } ||r*dS t|}|s5|| |D ]F}t|dd	krP||vrO||vrO|| q7|ddd
 dd	\}}	|	ddd
 }	d|	|f |vr}d|	|f |vr}|d|	|f  q7|r ||| dS  ||| 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   httpsc                    s   g | ]} j |qS rF   )r!   rp  r   xra   rF   rG   rS        z4ApacheConfigurator.ensure_listen.<locals>.<listcomp>Listenc                 S   s   g | ]
}|r|  d  qS )r   )r  )r   r  rF   rF   rG   rS    s    N:r   r$  z%s:%s)	r!   r+  _has_port_alreadyr~   rl   r  r  _add_listens_https_add_listens_http)
rD   rD  r  port_service
directiveslistenslisten_dirslistenrc   iprF   ra   rG   r    s2   

z ApacheConfigurator.ensure_listenr  listens_origc                 C   s   | |}||v r,| jt| jjd d| |  jd| d| jjd  d7  _dS |D ]&}| jt| jjd d|d |  jd| d| jjd  d7  _q.d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  directive to 
 N)
differencer!   r-  get_aug_pathr   r   r  )rD   r  r  rD  new_listensr  rF   rF   rG   r    s$   
	




z$ApacheConfigurator._add_listens_httpc                 C   s   |dkr
| d}n|}| |}||v s||v r?| jt| jjd d|d |  jd| d| jjd  d7  _d	S |D ]&}| jt| jjd d|d |  jd| d| jjd  d7  _qAd	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  r  N)r  r!   add_dir_to_ifmodsslr  r   r  r   )rD   r  r  rD  r  r  r  rF   rF   rG   r    s*   





z%ApacheConfigurator._add_listens_httpsc                 C   sN   ||v rdS |D ]}t |ddkr$|dd dd |kr$ dS qdS )zHelper 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  )rD   r  rD  r  rF   rF   rG   r    s   z$ApacheConfigurator._has_port_alreadyc                 C   s|   | j jr:d| jjvr| jd|d d| jjvr<| jd|d | j  | jj  | j  | j	| j
| jdd dS dS dS )	zHelper method for prepare_server_https, taking care of enabling
        needed modules

        :param boolean temp: If the change is temporary
        socache_shmcb_modulesocache_shmcbr2  r   r  T)rT   N)r`   r6   r!   r   
enable_modensure_augeas_stater   r   reset_modulesr   r   r   )rD   r3  rF   rF   rG   r  .  s   


z(ApacheConfigurator.prepare_https_modulesnonssl_vhostc           	      C   s&  |j }| |}| jjd| |tdf }| || | jj  | jjd| |tdf }| 	||}|sb| j
| | jjd| |tdf }| 	||}|sbtd| | td| |  jd| 7  _|   | |}|std|}||_| j| |S )a  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.options.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._internal.obj.VirtualHost`

        :returns: SSL vhost
        :rtype: :class:`~certbot_apache._internal.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
zCould not create a vhost)r  _get_ssl_vhost_pathr!   r   r^  _escaper  _copy_create_ssl_vhost_skeletonr   _get_new_vh_path
parse_filer   r   _update_ssl_vhosts_addrsr   r,  r   r   r  r  r   r   r  )	rD   r  avail_fpssl_fporig_matchesnew_matchesvh_pr  	ssl_vhostrF   rF   rG   r  C  sP   





z!ApacheConfigurator.make_vhost_sslr  r  c                 C   s4   dd |D }|D ]}| dd|v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]rx   rf   r   rF   rF   rG   rS    r  z7ApacheConfigurator._get_new_vh_path.<locals>.<listcomp>r  rx   Nr  )rD   r  r  r^  rF   rF   rG   r    s   z#ApacheConfigurator._get_new_vh_pathnon_ssl_vh_fpc                 C   sx   |  drtj|  drtjt| jjtj	|}nt|}|
dr6|dtd  | jj S || jj 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
        ro   z.confN)re   r   r   existsr   r   r  r`   r+   r  endswithr  r5   )rD   r  fprF   rF   rG   r    s   


z&ApacheConfigurator._get_ssl_vhost_pathlinec                 C   sX   |   dsdS | d  }|d dv r'|d |d kr'|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

        rewriteruleFrU   r   )'"r$  r   zhttps://)r?  lstrip
startswithr  strip)rD   r  rB  rF   rF   rG   _sift_rewrite_rule  s   
z%ApacheConfigurator._sift_rewrite_ruler  c           	      C   sN  t j|rd| }t }|| | j|| n| jd| zF| |}| 	|\}}t
|d}|d |d| |d |d W d   n1 sUw   Y  | j|sf| j| W n tyz   tjd	d
d tdw |rtd|j d| d | 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 %sFrG  z<IfModule mod_ssl.c>
r  z</VirtualHost>
z</IfModule>
Nz/Error writing/reading to file in make_vhost_sslTr   z&Unable to write/read in make_vhost_sslzSome rewrite rules copied from z; were disabled in the vhost for your HTTPS site located at z= because they have the potential to create redirection loops.z/augeas/files%s/mtime0)r   r   r  r~   rl   reverterr   register_file_creation_get_vhost_block_sift_rewrite_rulesr   writer   r!   parsed_in_currentr  r   r   criticalr   r   r  r  r  r   r  )	rD   r  r  notesfilesorig_contentsssl_vh_contentssiftnew_filerF   rF   rG   r    s<   





 z2ApacheConfigurator._copy_create_ssl_vhost_skeletonr   c           	      C   sJ  g }d}t |}d}|D ]}|  d}|  d}|s*|s*|| q|r7| |s7|| q|rO| |rO|sG|| d}|d|  qg }|r|| t|}|  dsw|| t|}|  dre|| | |r|s|| d}|ddd	 |D  q|d| 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.
rewritecondr  T# r  c                 s   s    | ]}d | V  qdS )r  NrF   )r   lrF   rF   rG   r   ;  r   z9ApacheConfigurator._sift_rewrite_rules.<locals>.<genexpr>)iterr?  r  r  r  r  nextr   )	rD   r   resultr  commentr  ABchunkrF   rF   rG   r    sH   







z&ApacheConfigurator._sift_rewrite_rulesc              	   C   s   z
| j j|j}W n ty!   tjd|j|jdd t	
dw |d }|d }|d }t|d}|| ||| d	}W d
   n1 sMw   Y  | | |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 %sTr   z$Unable to read VirtualHost from filer         rr  N)r!   r   spanr   
ValueErrorr   r  r   r  r   r   r   seekr   r  _remove_closing_vhost_tag)rD   r  span_val
span_filep
span_startspan_endfhvh_contentsrF   rF   rG   r  @  s"   



z#ApacheConfigurator._get_vhost_blockr  c                 C   sZ   t t|D ]$\}}|r*| d}|dkr't|| d }|d| ||<  dS q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  )rD   r  offsetr  
line_indexcontent_indexrF   rF   rG   r  W  s   z,ApacheConfigurator._remove_closing_vhost_tagvh_pathc                 C   sj   t  }| jj|d }|D ]$}tjt| j|}|r2|	d}| jj |t| |
| q|S )Nr{  r  )r~   r!   r   r^  r    r  r  rM   rp  get_addr_objrl   )rD   r  	ssl_addrs
ssl_addr_pr&  old_addrssl_addrrF   rF   rG   r  j  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rD   r  rF   rF   rG   r*  x  s   zApacheConfigurator._clean_vhostr  c              	   C   sp   |D ]3}t | j|d |ddkr5| j|d |d}| jjtdd|d  t | j|d |ddksqd S )NFr   /\w*$rx   r   )r  r!   r+  r   r  r   subrD   r  r  r  directive_pathrF   rF   rG   r    s"   
z*ApacheConfigurator._deduplicate_directivesc              	   C   s`   |D ]+}| j |d |dr-| j |d |d}| j jtdd|d  | j |d |dsqd S )NFr"  rx   r   )r!   r+  r   r  r   r#  r$  rF   rF   rG   r     s   
z%ApacheConfigurator._remove_directivesc                 C   sP   | j |dd | j |dd | j d| j|}|s&| j |d| j d S d S )Nr  insert_cert_file_pathr   insert_key_file_pathInclude)r!   r-  r+  r   )rD   r  existing_incrF   rF   rG   r)    s   

z,ApacheConfigurator._add_dummy_ssl_directivesc                 C   s|   |j }| |\}}||ks||v rd S | ||rd S | jjdd |dds/| j|d| n| j|d| | | d S )Nrk  Frl  ro  )r   rw  _has_matching_wildcardr!   r+  r-  rz  )rD   r  r  r  snamesaliasesrF   rF   rG   r5    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

        ro  Frl  c                 3   s    | ]
} j j|V  qd S r   r!   r   rq   )r   r^  ra   rF   rG   r     s    z<ApacheConfigurator._has_matching_wildcard.<locals>.<genexpr>)r!   r+  r@  )rD   r  r  r   ry  rF   ra   rG   r*    s
   z)ApacheConfigurator._has_matching_wildcardid_strc                 C   s@   | j D ]}| ||kr|  S qd|}t| t|)a8  
        Searches through VirtualHosts and tries to match the id in a comment

        :param str id_str: Id string for matching

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

        :raises .errors.PluginError: If no VirtualHost is found
        z$No VirtualHost with ID {} was found.)r   _find_vhost_idr   r   r   r   r   )rD   r.  rR  msgrF   rF   rG   find_vhost_by_id  s   



z#ApacheConfigurator.find_vhost_by_idc                 C   sJ   t jd}| j||j}|r#| j|d }|r!|dd S dS dS )aM  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._internal.obj.VirtualHost`

        :returns: The unique ID or None
        :rtype: str or None
        rx   r   r  r$  N)r   MANAGED_COMMENT_IDr   r!   find_commentsr   rp  r  )rD   r  search_comment
id_commentr  rF   rF   rG   r/    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._internal.obj.VirtualHost`

        :returns: The unique ID for vhost
        :rtype: str or None
        )	r/  r   	unique_idr   r2  r   r!   add_commentr   )rD   r  vh_id	id_stringr  rF   rF   rG   add_vhost_id  s   
zApacheConfigurator.add_vhost_idr  c                 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\!r  )rD   r  rF   rF   rG   r    s   zApacheConfigurator._escapec                 C   s   g dS )z)Returns currently supported enhancements.ry   rF   ra   rF   rF   rG   supported_enhancements     z)ApacheConfigurator.supported_enhancementsenhancementr`   c                 C   s   z| j | }W n ty   td|w | j|dd}dd |D }|sEd}|}|r5|dt| 7 }|||}	t|	 t|	z|D ]}
||
| qHW d	S  tjyb   td||  w )
a  Enhance configuration.

        :param str domain: domain to enhance
        :param str enhancement: enhancement type defined in
            :const:`~certbot.plugins.enhancements.ENHANCEMENTS`
        :param options: options for the enhancement
            See :const:`~certbot.plugins.enhancements.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      g | ]}|j r|qS rF   r  r   r  rF   rF   rG   rS        z.ApacheConfigurator.enhance.<locals>.<listcomp>zCertbot 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)	r   r   r   r   r   r   rM   r   r   )rD   r   rD  r`   funcmatched_vhostsr   msg_tmplmsg_enhancementr0  r  rF   rF   rG   enhance  s2   

zApacheConfigurator.enhancenextstepc                 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._internal.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timer   )rD   r  r.  rO  nextstep_valuerF   rF   rG   _autohsts_increase0  s   
z%ApacheConfigurator._autohsts_increaserV  c           
      C   s   d}| j dd|j}|r#d}|D ]}t|| j j| r"|}q|s0d|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   r   searchr   rq   r?  r   r  r   r   rf   r~   r   r   r   r   )
rD   r  rV  hsts_dirpathheader_pathpatr^  err_msghsts_maxagenote_msgrF   rF   rG   rT  A  s,   



z"ApacheConfigurator._autohsts_writec                 C   s0   z
| j d| _W dS  ty   i | _Y dS w )zE
        Populates the AutoHSTS state from the pluginstorage
        autohstsN)storagefetchr   r   ra   rF   rF   rG   _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
        ra  N)rb  putr   r   ra   rF   rF   rG   _autohsts_save_statei  s   z'ApacheConfigurator._autohsts_save_statelineagec                 C   s   t | jd|j|jS )zz
        Searches AutoHSTS managed VirtualHosts that belong to the lineage.
        Matches the private key path.
        r   )rN   r!   r+  r   r   )rD   r  rg  rF   rF   rG   _autohsts_vhost_in_lineagep  s   z-ApacheConfigurator._autohsts_vhost_in_lineager  unused_optionsc                 C   s   d| j jvr| d | j jdd|jd}|s | j |jdd | t |j}| j dd|}|rA| j j	
tdd	|d
  | j |ddg d|j }|  j|7  _|   t| dS )a9  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._internal.obj.VirtualHost`

        :param unused_options: Not currently used
        :type unused_options: Not Available
        r  r  SSLUseStaplingr}  rm  SSLStaplingCacheNr"  rx   r   z-shmcb:/var/run/apache2/stapling_cache(128000)z,OCSP Stapling was enabled on SSL Vhost: %s.
)r!   r   r  r+  r   r-  r  r  r  r   r  r   r#  r  r   r   r   r,  )rD   r  ri  use_stapling_aug_pathssl_vhost_aug_pathstapling_cache_aug_pathr0  rF   rF   rG   r   y  s2   
z(ApacheConfigurator._enable_ocsp_staplingheader_substringc                 C   sn   d| j jv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._internal.obj.VirtualHost`

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

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

        headers_moduleheadersrX  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_ARGSr   r  r   r   r,  )rD   r  rp  rF   rF   rG   r     s   
z#ApacheConfigurator._set_http_headerc                 C   s^   | j jdd|jd}|r+d|  }|D ]}t|| j j| r*t	d| qdS dS )a,  Checks to see if there is an existing Header directive that
        contains the string header_substring.

        :param ssl_vhost: vhost to check
        :type vhost: :class:`~certbot_apache._internal.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

        rX  Nrk  z(?:[ "]|^)(%s)(?:[ "]|$)zExisting %s header)
r!   r+  r   r?  r   rZ  r   rq   r   PluginEnhancementAlreadyPresent)rD   r  rp  r\  r]  r^  rF   rF   rG   rs    s   
z2ApacheConfigurator._verify_no_matching_http_headerc           
      C   sl  d| j jvr| d | |}|du r8td | |}| jD ]}|jr0|	|r0t
dq!| | dS || jd v rFtd dS | | | |rUtd | |sc| j |jd	d
 | }t|D ]!\}}dd|dg}	|t|d kr|	  | j |jd|	 qk| | |  jd|j|jf 7  _|   | jd | td|j|j dS )aD  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._internal.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.

        rewrite_modulerewriteNzBDid not find http version of ssl virtual host attempting to createzUnable to find corresponding HTTP vhost; Unable to create one as intended addresses conflict; Current configuration does not support automated redirectionrz   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   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_vhostr   r   r;  r   r.  r7  r   r   _create_redirect_vhostr   _verify_no_certbot_redirect_is_rewrite_existsr   _is_rewrite_engine_onr-  r   r
  r  r   r  r{   #_set_https_redirection_rewrite_ruler   r  r   rl   r,  )
rD   r  ri  
general_vhredirect_addrsr  r=  idxr   ru   rF   rF   rG   r     sH   











z#ApacheConfigurator._enable_redirectc                 C   s   | j |jdtj d S )NRewriteRule)r!   r-  r   r   REWRITE_HTTPS_ARGSr!  rF   rF   rG   r  A  s   z6ApacheConfigurator._set_https_redirection_rewrite_rulec           
         s    j jdd|jd}tt}d}|D ]}t||}|r(|d}|| | q|ra|	 D ]3\}} fdd|D }	|	t
jv rV j j|  |    td|	t
jkr`tdq/dS dS )	a`  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._internal.obj.VirtualHost`

        :raises errors.PluginEnhancementAlreadyPresent: When the exact
                certbot redirection WriteRule exists in virtual host.
        r  Nrk  z(.*directive\[\d+\]).*r   c                    s   g | ]	} j j|qS rF   r-  r  ra   rF   rG   rS  c  s    zBApacheConfigurator._verify_no_certbot_redirect.<locals>.<listcomp>z'Certbot has already enabled redirection)r!   r+  r   r   r  r   r^  groupr  itemsr   OLD_REWRITE_HTTPS_ARGSr   r  r  r   r   ru  r  )
rD   r  rewrite_pathrewrite_args_dictr]  r^  mdir_path
args_pathsarg_valsrF   ra   rG   r|  D  s8   



z.ApacheConfigurator._verify_no_certbot_redirectc                 C   s   | j jdd|jd}t|S )zChecks if there exists a RewriteRule directive in vhost

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

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

        r  Nrk  )r!   r+  r   rN   )rD   r  r  rF   rF   rG   r}  q  s   
z%ApacheConfigurator._is_rewrite_existsc                 C   sB   | j jdd|jd}|r|D ]}d| v r| j |  S qdS )zChecks if a RewriteEngine directive is on

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

        rx  r}  rk  r  F)r!   r+  r   r?  rp  )rD   r  rewrite_engine_path_listre_pathrF   rF   rG   r~    s   z(ApacheConfigurator._is_rewrite_engine_onc                 C   s   |  |}| ||}| jj  | t| |}|du r%t	d| j
| | jd | |  jd|j|jf 7  _dS )zCreates an http_vhost specifically to redirect for the ssl_vhost.

        :param ssl_vhost: ssl vhost
        :type ssl_vhost: :class:`~certbot_apache._internal.obj.VirtualHost`
        NzCould not create a new vhostrz   z=Created a port 80 vhost, %s, for redirection to ssl vhost %s
)_get_redirect_config_str_write_out_redirectr!   r   r   r  r  r  r   r  r   r  r   rl   r   r  )rD   r  textredirect_filepathr  rF   rF   rG   r{    s   


z)ApacheConfigurator._create_redirect_vhostc                 C   sx   d}d}|j d urd|j  }|jrdd|j }dddd | |D  d| d	| d
dtj d| jj dS )Nrx   zServerName zServerAlias r  z<VirtualHost c                 s   r   r   r   r%  rF   rF   rG   r     r   z>ApacheConfigurator._get_redirect_config_str.<locals>.<genexpr>z>
z 
z4 
ServerSignature Off

RewriteEngine On
RewriteRule z

ErrorLog z1/redirect.error.log
LogLevel warn
</VirtualHost>
)r   ry  r   r;  r   r  r`   r-   )rD   r  ru  rv  rF   rF   rG   r    s    


z+ApacheConfigurator._get_redirect_config_strr  c                 C   s   d}|j d urt|j dt|d  k rd|j  }tj| jj|}| jd| t	|d}|
| W d    n1 s>w   Y  | j|sO| j| td| |S )Nzle-redirect.conf   r   zle-redirect-%s.confFwzCreated redirect file: %s)r   r  r   r   r   r`   r+   r  r  r   r  r!   r  r  r   r,  )rD   r  r  redirect_filenamer  redirect_filerF   rF   rG   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 rF   rG  rH  rF   rF   rG   rS    s
    z6ApacheConfigurator._get_http_vhost.<locals>.<listcomp>T)genericN)r   r   same_server)rD   r  candidate_http_vhshttp_vhrF   rF   rG   rz    s   
z"ApacheConfigurator._get_http_vhostc                 C   s&   t  }|jD ]
}||| q|S )zReturn 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`

        )r~   r0  rl   r  )rD   r  rD  	redirectsr&  rF   rF   rG   r;    s   	
z&ApacheConfigurator._get_proposed_addrsc                 C   s\   |j rdS | j|js,t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._internal.obj.VirtualHost`

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

        Nz8Enabling site %s by adding Include to root configurationzEnabled site %s
rm   T)	r.  r!   r  r  r   r,  r   add_includer   r!  rF   rF   rG   r/  	  s   zApacheConfigurator.enable_sitemod_namec                 C   s   d| d}t |)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  "z" 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.)r   r(  )rD   r  r3  mod_messagerF   rF   rG   r  	  s   

zApacheConfigurator.enable_modc                 C   s   |    |   dS )zRuns a config test and reloads the Apache server.

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

        N)r   _reloadra   rF   rF   rG   restart4	  s   zApacheConfigurator.restartc                 C   s   z
t | jj W dS  tjy[ } zDtd| jj | jjrNt	d| jj zt | jj W W Y d}~dS  tjyM } z
t
|}W Y d}~n	d}~ww t
|}t|d}~ww )zdReloads the Apache server.

        :raises .errors.MisconfigurationError: If reload fails

        z!Unable to restart apache using %sz&Trying alternative restart command: %sN)r   
run_scriptr`   r0   r   SubprocessErrorr   r   r1   r   rM   r(  )rD   errsecerrr   rF   rF   rG   r  >	  s*   
zApacheConfigurator._reloadc              
   C   s>   z
t | jj W dS  tjy } ztt|d}~ww )z|Check the configuration of Apache for errors.

        :raises .errors.MisconfigurationError: If config_test fails

        N)r   r  r`   r2   r   r  r(  rM   )rD   r  rF   rF   rG   r   W	  s   zApacheConfigurator.config_test.c                 C   s   zt | jj\}}W n tjy   td| jj w tdtj	}|
|}t|dkr4tdtdd |d dD S )	zReturn 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

        zUnable to run %s -vzApache/([0-9\.]*)r   zUnable to find Apache versionc                 s   r   r   )intr   rF   rF   rG   r   z	  r   z1ApacheConfigurator.get_version.<locals>.<genexpr>r   r   )r   r  r`   r/   r   r  r   r   compile
IGNORECASEr   r  tupler  )rD   stdoutrc   regexr   rF   rF   rG   r   b	  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}r   r   c                 s   r   r   r   r   rF   rF   rG   r   	  r   z/ApacheConfigurator.more_info.<locals>.<genexpr>)r   r\   )r   r   linesepr!   r   r   r\   ra   rF   rF   rG   	more_info|	  s   zApacheConfigurator.more_infofailed_achallsc                 C   s   dS )NzThe Certificate Authority failed to verify the temporary Apache configuration changes made by Certbot. Ensure that the listed domains point to this Apache server and that it is accessible from the internet.rF   )rD   r  rF   rF   rG   	auth_hint	  s   zApacheConfigurator.auth_hintunused_domainc                 C   s   t jgS )z%Return list of challenge preferences.)r   HTTP01)rD   r  rF   rF   rG   get_chall_pref	  rC  z!ApacheConfigurator.get_chall_prefachallsc                 C   s   | j | dgt| }t| }t|D ]\}}t|tjs%t	
d||| q| }|rB|   td | ||| dd |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.

        NzEChallenge should be an instance of KeyAuthorizationAnnotatedChallengerJ  c                 S   s   g | ]}|r|qS rF   rF   )r   responserF   rF   rG   rS  	  s    z.ApacheConfigurator.perform.<locals>.<listcomp>)r   r\  r  r   ApacheHttp01r  
isinstancer   "KeyAuthorizationAnnotatedChallenger   r  	add_challperformr  rU  sleep_update_responses)rD   r  	responses	http_doerr   achallhttp_responserF   rF   rG   r  	  s   	


zApacheConfigurator.performr  chall_response
chall_doerc                 C   s$   t |D ]\}}|||j| < qd S r   )r  indices)rD   r  r  r  r   resprF   rF   rG   r  	  s   	z$ApacheConfigurator._update_responsesc                 C   s4   | j | | j s|   |   | j  dS dS )zRevert all challenges.N)r   difference_updater   r  r!   r  )rD   r  rF   rF   rG   cleanup	  s   zApacheConfigurator.cleanupoptions_ssloptions_ssl_digestc                 C   s   |  |}t|||tjS )zCopy Certbot's SSL options file into the system's config dir if required.

        :param bool warn_on_no_mod_ssl: True if we should warn if mod_ssl is not found.
        )r_   r   install_version_controlled_filer   ALL_SSL_OPTIONS_HASHES)rD   r  r  rT   apache_config_pathrF   rF   rG   r   	  s   

z+ApacheConfigurator.install_ssl_options_conf_unused_lineagedomainsc                 C   s   |    g }|D ]N}| j|dd}dd |D }|s+d}||}t| t||D ](}	z| |	 ||	 W q- tj	yU   |	|v rIY q-d}t	|||	j
w q|rid}
| |
 t|
 |   |   dS )	a:  
        Enable the AutoHSTS enhancement for defined domains

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

        :param domains: List of domains in certificate to enhance
        :type domains: `list` of `str`
        FrE  c                 S   rF  rF   rG  rH  rF   rF   rG   rS  	  rI  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)rd  r   r   r   r   r   r   _enable_autohsts_domainr  ru  r  r   r,  r  rf  )rD   r  r  r   drK  r   rL  r0  rR  r`  rF   rF   rG   enable_autohsts	  s:   





z"ApacheConfigurator.enable_autohstsc                 C   s   |  |d d| jjvr| d tjd dd }tjd }|d| | 	|}|du r5t
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._internal.obj.VirtualHost` or None

        :raises errors.PluginEnhancementAlreadyPresent: When already enhanced

        zStrict-Transport-Securityrq  rr  Nr$  r   rY  zCould not generate a unique idz+Adding unique ID {0} to VirtualHost in {1}
rX  zXAdding gradually increasing HSTS header with initial value of {0} to VirtualHost in {1}
rP  )rs  r!   r   r  r   rt  rS  r  r   r:  r   r  r   r  r-  r   rU  r   )rD   r  hsts_headerinitial_maxageuniq_idr`  rF   rF   rG   r  
  s(   





z*ApacheConfigurator._enable_autohsts_domain_unused_domainc           	   	   C   s  |    | js	dS t }d}t| j D ]\\}}|d tj |kr$qtt|d d }|t	tj
k rr| js;|   z| |}W n tjy\   d|}t| | j| Y qw | ||| 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

        NFrR  rQ  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)rd  r   rU  r  r  r   AUTOHSTS_FREQr   r  r  rS  r   r   r1  r   r   r   r   r   r{   rW  r   r   r  rf  )	rD   r  curtimesave_and_restartr.  r   rO  r  r0  rF   rF   rG   update_autohsts.
  sB   	

z"ApacheConfigurator.update_autohstsc           	   	   C   s,  |    | js	dS g }g }t| j D ]A\}}|d d ttjkrUz| |}W n tj	yD   d
|}t| | j| Y qw | ||rU|| || qd}|D ]}| |tj d
|j}t| |  j|d 7  _d}qZ|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._internal.storage.RenewableCert
        NrQ  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)rd  r   r  r  r  r   rS  r1  r   r   r   r   r   r{   rh  r  rT  AUTOHSTS_PERMANENTr  r   r   r   r  rf  )	rD   rg  r   affected_idsr.  r   r  r0  r  rF   rF   rG   deploy_autohsts\
  sH   




z"ApacheConfigurator.deploy_autohsts)T)r:   N)NF)r   )NNrN  )rA  )NTr   )rI   rJ   rK   rL   rP   rM   __annotations__r   rp   rq   r#   rS   rN   r_   rb   rk   classmethodr   rt   r   rH   propertyr   r   r
   bytesr   r[   r   r   r   r   r  r   r   r!   r   r   r   r   r   r   r  r	   r    r  r   r  r   r   r  r  r  r   r	  r6  r   r@  rI  r4  rT  r   rd  r  r_  r   rw  rz  r  r   r  r  r"   r  r  r'  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r*  r  r   r)  r5  r*  r1  r/  r:  r  rB  r   rN  rW  floatrT  rd  rf  r   rh  r   r   rs  r   r  r|  r}  r~  r{  r  r  rz  r;  r/  r  r  r  r   r   r  r   AnnotatedChallenger  r   r   r   r  r  ChallengeResponser  !KeyAuthorizationChallengeResponser   r  r  r  r   r  r  r  r  __classcell__rF   rF   r   rG   rO      s  
 &,
+A	
 
*
E)



@!*05."2"!"L!"/=

*
	
	4%
Q- "

"
%",#.rO   )?rL   collectionsr   r   r  loggingr   rf  rU  typingr   r   r   r   r   r   r	   r
   r   r   r   r   r   acmer   certbotr   r   r   certbot.compatr   r   certbot.displayr  certbot.interfacesr   certbot.pluginsr   certbot.plugins.enhancementsr   certbot.plugins.utilr   certbot_apache._internalr   r   r   r   r   r   r    r!   %certbot_apache._internal.apacheparserr"   r   r   ImportError	getLoggerrI   r   r#   ConfiguratorrO   registerrF   rF   rF   rG   <module>   s    
I                    #