
    M/eI                        d 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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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j\                  dk\  rddl/m0Z1 nddl1Z1dZ2dZ3dZ4d Z5d!Z6 ejn                  e8      Z9 G d" d#e&jt                        Z;d$ee   d%ee   fd&Z<d'e=d%ee   fd(Z>d)e=d*e=d+e?d%dfd,Z@d%e=fd-ZAy).zNginx Configuration    N)	ExitStack)Any)Callable)Dict)Iterable)List)Mapping)Optional)Sequence)Set)Tuple)Type)Union)
challenges)crypto_util)achallenges)errors)util)os)common)	constants)display_ops)http_01)nginxparser)obj)parser)   	         r      c                       e Zd ZdZdZdZg dZeded   ddfd	       Z	e
defd
       Zdededdf fdZe
defd       Ze
defd       Ze
defd       ZdededdfdZdbdZdedededededdfdZdej,                  dededededdfdZ	 dcdeded ee   deej,                     fd!Zd"edeej,                     fd#Z	 ddd"ed$edeej,                     fd%Zd&edeeef   fd'Zded(ed&edej,                  fd)Z dej,                  deddfd*Z!ded(ed&edej,                  fd+Z"d"edee#eef      fd,Z$d-e%e&eef      deej,                     fd.Z'd/e(ej,                     d"edee#eef      fd0Z)d/e(ej,                     d"edee#eef      fd1Z*d"ed&edeej,                     fd2Z+d"edeeej,                     eej,                     f   fd3Z,d4ed5edefd6Z-dej,                  d&ed7edefd8Z.dej,                  d&edefd9Z/d"ed&edee#eef      fd:Z0de1e   fd;Z2deeef   fd<Z3dej,                  ddfd=Z4dee   fd>Z5	 dcded?ed@ee6eee   f      ddfdAZ7dej,                  dedefdBZ8dedCe6eee   df   ddfdDZ9dej,                  deddfdEZ:dcdej,                  dFeee      deej,                  ej,                  f   fdGZ;dedHee6eee   f      ddfdIZ<dedej,                  ddfdJZ=dedee6eee   f      ddfdKZ>dej,                  dee   ddfdLZ?dbdMZ@dbdNZAdefdOZBdeeCdPf   fdQZDdefdRZEdefdSZFdTe(eGj                     defdUZIdedVee   dWeddfdXZJdb fdYZKdbdZZLdfd[eCddf fd\ZMd]edeeNeOj                        fd^ZQd_eeGj                     deeOj                     fd`ZSd_eeGj                     ddfdaZT xZUS )gNginxConfiguratoraE  Nginx configurator.

    .. todo:: Add proper support for comments in the config. Currently,
        config files modified by the configurator will lose all their comments.

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

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

    :ivar str save_notes: Human-readable config change notes

    :ivar reverter: saves and reverts checkpoints
    :type reverter: :class:`certbot.reverter.Reverter`

    :ivar tup version: version of Nginx

    zNginx Web Server plugin80)ssl_certificatessl_certificate_keyssl_dhparamadd).NreturnNc                     t               } |dt        j                  d   d|z          |dt        j                  d   d        |dt        j                  d   t        d	
       y )Nserver-rootserver_rootz*Nginx server root directory. (default: %s))defaulthelpctlzVPath to the 'nginx' binary, used for 'configtest' and retrieving nginx version number.sleep-secondssleep_secondszRNumber of seconds to wait for nginx configuration changes to apply when reloading.)r-   typer.   )_determine_default_server_rootr   CLI_DEFAULTSint)clsr(   default_server_roots      F/usr/lib/python3/dist-packages/certbot_nginx/_internal/configurator.pyadd_parser_argumentsz&NginxConfigurator.add_parser_argumentsV   sj    <>M9#9#9-#H=@SS	UE911%8 @ 	 	OY%;%;O%LSV'	(    c                 `    t         j                  j                  | j                  d      d      S )zNginx config file path.r,   z
nginx.conf)r   pathjoinconfselfs    r8   
nginx_confzNginxConfigurator.nginx_confb   s"     ww||DIIm4lCCr:   argskwargsc                 X   |j                  dd      }|j                  dd      }t        |   |i | d| _        d| _        i | _        i | _        d| _        || _        || _	        | j                  | j                  | j                  d| _        | j                  j                          |  y)a  Initialize an Nginx Configurator.

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

        :param tup openssl_version: version of OpenSSL linked to Nginx as a tuple (1, 4, 7)
            (used mostly for unittesting)

        versionNopenssl_version r   redirectzensure-http-headerzstaple-ocsp)popsuper__init__
save_notes	new_vhost_wildcard_vhosts_wildcard_redirect_vhosts
_chall_outrE   rF   _enable_redirect_set_http_header_enable_ocsp_stapling_enhance_funcreverterrecovery_routine)r@   rB   rC   rE   rF   	__class__s        r8   rL   zNginxConfigurator.__init__g   s     **Y- **%6=$)&)  59 CEKM&  .*.*?*?484I4I-1-G-GI 	&&(r:   c                    | j                   dk\  }t        j                  d      }| j                   dk\  xr0 | j                  xr" t        j                  | j                        |k\  }|r|rd}n
d}n|rd}nd}t	               }t        j                  |j                         t        j                  d      j                  d	      j                  d
      j                  |      }t        |j                  t        j                  |                  S )z4Full absolute path to SSL configuration file source.)r      r   z1.0.2l)r      r   zoptions-ssl-nginx.confz+options-ssl-nginx-tls13-session-tix-on.confz!options-ssl-nginx-tls12-only.confzoptions-ssl-nginx-old.confcertbot_nginx	_internaltls_configs)rE   r   parse_loose_versionrF   r   atexitregistercloseimportlib_resourcesfilesjoinpathstrenter_contextas_file)r@   	use_tls13min_openssl_versionsession_tix_offconfig_filenamefile_managerrefs          r8   mod_ssl_conf_srcz"NginxConfigurator.mod_ssl_conf_src   s     LLJ.	"66x@,,)3 R8L8L R$$T%9%9:>QQ 	 ":"O"E"> {**+"((9BB;O'(A 	 <--.A.I.I#.NOPPr:   c                     t         j                  j                  | j                  j                  t
        j                        S )z-Full absolute path to SSL configuration file.)r   r<   r=   config
config_dirr   MOD_SSL_CONF_DESTr?   s    r8   mod_ssl_confzNginxConfigurator.mod_ssl_conf   s)     ww||DKK22I4O4OPPr:   c                     t         j                  j                  | j                  j                  t
        j                        S )z?Full absolute path to digest of updated SSL configuration file.)r   r<   r=   rq   rr   r   UPDATED_MOD_SSL_CONF_DIGESTr?   s    r8   updated_mod_ssl_conf_digestz-NginxConfigurator.updated_mod_ssl_conf_digest   s)     ww||DKK22I4Y4YZZr:   options_ssloptions_ssl_digestc                 d    t        j                  ||| j                  t        j                         y)zICopy Certbot's SSL options file into the system's config dir if required.N)r   install_version_controlled_filero   r   ALL_SSL_OPTIONS_HASHES)r@   rx   ry   s      r8   install_ssl_options_confz*NginxConfigurator.install_ssl_options_conf   s(    ..+!!9#C#C	Er:   c                    t        j                  | j                  d            st        j                  d      | j                          t        j                  | j                  d            | _        | j                  | j                         | _        | j                  | j                         | _
        | j                  | j                  | j                         | j                          	 t        j                   | j                  d             y# t"        t        j$                  f$ rK t&        j)                  dd       t        j*                  dj-                  | j                  d                  w xY w)	zPrepare the authenticator/installer.

        :raises .errors.NoInstallationError: If Nginx ctl cannot be found
        :raises .errors.MisconfigurationError: If Nginx is misconfigured
        r/   zvCould not find a usable 'nginx' binary. Ensure nginx exists, the binary is executable, and your PATH is set correctly.r+   NzEncountered error:Texc_infozUnable to lock {0})r   
exe_existsr>   r   NoInstallationErrorconfig_testr   NginxParserrE   get_versionrF   _get_openssl_versionr}   rt   rw   install_ssl_dhparamslock_dir_until_exitOSError	LockErrorloggerdebugPluginErrorformatr?   s    r8   preparezNginxConfigurator.prepare   s.    tyy/0,,LM M
 	((=)AB <<++-DL'#'#<#<#>D %%d&7&79Y9YZ!!#	\$$TYY}%=>))* 	\LL-L=$$%9%@%@=AY%Z[[	\s   ,$D A$E5domain	cert_pathkey_path
chain_pathfullchain_pathc                     |st        j                  d      | j                  |d      }|D ]F  }| j                  |||||       t	        j
                  dj                  ||j                               H y)aU  Deploys certificate to specified virtual host.

        .. note:: Aborts if the vhost is missing ssl_certificate or
            ssl_certificate_key.

        .. note:: This doesn't save the config files!

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

        zNThe nginx plugin currently requires --fullchain-path to install a certificate.T)create_if_no_matchz.Successfully deployed certificate for {} to {}N)r   r   choose_vhosts_deploy_certdisplay_utilnotifyr   filep)r@   r   r   r   r   r   vhostsvhosts           r8   deploy_certzNginxConfigurator.deploy_cert   s|     $$)* * ##Ft#D 	>EeY*nU P!'!<>	>r:   r   
_cert_path_chain_pathc           	         ddd|gddd|gg}| j                   j                  ||       t        j                  d|j                         | xj
                  d|j                  ddj                  d	 |j                  D              d
z  c_        | xj
                  d|z  z  c_        | xj
                  d|z  z  c_        y)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
        
    r%    r&   z'Deploying Certificate to VirtualHost %szChanged vhost at z with addresses of z, c              3   2   K   | ]  }t        |        y wNrf   .0addrs     r8   	<genexpr>z1NginxConfigurator._deploy_cert.<locals>.<genexpr>  s     &ITs4y&I   
z	ssl_certificate %s
z	ssl_certificate_key %s
N)r   update_or_add_server_directivesr   infor   rM   r=   addrs)r@   r   r   r   r   r   cert_directivess          r8   r   zNginxConfigurator._deploy_cert   s     %&7nM$&;S(KM 	33E?K=u{{K"[[!YY&IU[[&IIK 	L 	3nDD7(BBr:   
prefer_sslno_ssl_filter_portc                 .   |r'| j                   }dt        j                  dt        fd}n&| j                  }dt        j                  dt        fd}||v r||   S | j
                  j                         }i }|D ]@  }|| j                  ||      s|j                  D ]  }	 ||      r|||	<   |	|vs|||	<    B t        |j                               }
t        j                  t        |
            }|D ]  }||vrg ||<   ||   j                  |       ! |S )zCPrompts user to choose vhosts to install a wildcard certificate forxr)   c                     | j                   S r   sslr   s    r8   preference_testzBNginxConfigurator._choose_vhosts_wildcard.<locals>.preference_test  s    uur:   c                     | j                    S r   r   r   s    r8   r   zBNginxConfigurator._choose_vhosts_wildcard.<locals>.preference_test  s    55y r:   )rO   r   VirtualHostboolrP   r   
get_vhosts_vhost_listening_on_port_no_sslnamessetvaluesr   select_vhost_multiplelistappend)r@   r   r   r   vhosts_cacher   r   filtered_vhostsr   namedialog_inputreturn_vhostss               r8   _choose_vhosts_wildcardz)NginxConfigurator._choose_vhosts_wildcard  sE    00L3?? t   99L!3?? !t ! \!'' '')  	2E!-;;ECUV 2"5),1OD)0,1OD)2	2 ?1134 $99$|:LM" 	/E\)')V$ ''.	/
 r:   target_namec                 v    | j                  |      }| j                  |      fD cg c]  }||	 }}|S c c}w r   )_get_ranked_matches_select_best_name_match)r@   r   matchesr   r   s        r8   _choose_vhost_singlez&NginxConfigurator._choose_vhost_singleH  sB    **;7"::7CDV!VV Ws   66r   c                 `   t        j                  |      r| j                  |d      }n| j                  |      }|sL|r2| j	                  |dt        | j                  j                              g}nt        j                  d|z        |D ]   }|j                  r| j                  |       " |S )a  Chooses a virtual host based on the given domain name.

        .. note:: This makes the vhost SSL-enabled if it isn't already. Follows
            Nginx's server block selection rules preferring blocks that are
            already SSL.

        .. todo:: This should maybe return list if no obvious answer
            is presented.

        :param str target_name: domain name
        :param bool create_if_no_match: If we should create a new vhost from default
            when there is no match found. If we can't choose a default, raise a
            MisconfigurationError.

        :returns: ssl vhosts associated with name
        :rtype: list of :class:`~certbot_nginx._internal.obj.VirtualHost`

        T)r   a	  Cannot find a VirtualHost matching domain %s. In order for Certbot to correctly perform the challenge please add a corresponding server_name directive to your nginx configuration for every domain on your certificate: https://nginx.org/en/docs/http/server_names.html)r   is_wildcard_domainr   r   _vhost_from_duplicated_defaultrf   rq   
https_portr   MisconfigurationErrorr   _make_server_ssl)r@   r   r   r   r   s        r8   r   zNginxConfigurator.choose_vhostsM  s    ( "";/11+$1OF..{;F!==k4../1 2 22P U`	ab b  	-E99%%e,	- r:   portc                     | j                   j                         }d}d}|D ]D  }|j                  D ]3  }|j                  rd}|j                  s|j                         |k(  s2d}5 F ||fS )a,  Returns tuple of booleans (ipv6_active, ipv6only_present)
        ipv6_active is true if any server block listens ipv6 address in any port

        ipv6only_present is true if ipv6only=on option exists in any server
        block ipv6 listen directive for the specified port.

        :param str port: Port to check ipv6only=on directive for

        :returns: Tuple containing information if IPv6 is enabled in the global
            configuration, and existence of ipv6only directive for specified port
        :rtype: tuple of type (bool, bool)
        FT)r   r   r   ipv6ipv6onlyget_port)r@   r   r   ipv6_activeipv6only_presentvhr   s          r8   	ipv6_infozNginxConfigurator.ipv6_infoz  sw     '')  	,B ,99"&K==T]]_%<'+$	,	, ,,,r:   allow_port_mismatchc                 "   | j                   J | j                  N| j                  |||      }| j                   j                  |d      | _        t	               | j                  _        | j                  | j                  |       | j                  S )zif allow_port_mismatch is False, only server blocks with matching ports will be
           used as a default server block template.
        T)remove_singleton_listen_params)r   rN   _get_default_vhostduplicate_vhostr   r   _add_server_name_to_vhost)r@   r   r   r   default_vhosts        r8   r   z0NginxConfigurator._vhost_from_duplicated_default  s    
 {{&&&>>! 33F<OQUVM![[88/3 9 5DN#&5DNN &&t~~v>~~r:   c                     |j                   j                  |       ddgg}|j                   D ]*  }|d   j                  d       |d   j                  |       , | j                  j	                  ||       y )Nr   server_namer   r   )r   r(   r   r   r   )r@   r   r   
name_blockr   s        r8   r   z+NginxConfigurator._add_server_name_to_vhost  sl    /0
KK 	'DqM  %qM  &	' 	33E:Fr:   c                    | j                   j                         }g }g }|D ]c  }|j                  D ]R  }|j                  s|j	                  |       | j                  ||j                               r|j	                  |        c e t        |      dk(  r|d   S t        |      dk(  r|r|d   S t        j                  d| d      )zRHelper method for _vhost_from_duplicated_default; see argument documentation therer   r   z9Could not automatically find a matching server block for z=. Set the `server_name` directive to use the Nginx installer.)
r   r   r   r-   r   _port_matchesr   lenr   r   )	r@   r   r   r   
vhost_listall_default_vhostsport_matching_vhostsr   r   s	            r8   r   z$NginxConfigurator._get_default_vhost  s     [[++-
! 	E <<&--e4))$@,33E:	 #$)'**#$).A%a(( ** ,88>x @I,I J 	Jr:   c                 Z    | j                   j                         }| j                  ||      S )a)  Returns a ranked list of vhosts that match target_name.
        The ranking gives preference to SSL vhosts.

        :param str target_name: The name to match
        :returns: list of dicts containing the vhost, the matching name, and
            the numerical rank
        :rtype: list

        )r   r   _rank_matches_by_name_and_ssl)r@   r   r   s      r8   r   z%NginxConfigurator._get_ranked_matches  s)     [[++-
11*kJJr:   r   c                     |sy|d   d   t         t        t         t        z   t        t        z   fv r1|d   d   }|D cg c]  }|d   |k(  s| }}t        |d       d   S |d   d   S c c}w )a%  Returns the best name match of a ranked list of vhosts.

        :param list matches: list of dicts containing the vhost, the matching name,
            and the numerical rank
        :returns: the most matching vhost
        :rtype: :class:`~certbot_nginx._internal.obj.VirtualHost`

        Nr   rankc                     t        | d         S )Nr   )r   r   s    r8   <lambda>z;NginxConfigurator._select_best_name_match.<locals>.<lambda>  s    AfI r:   keyr   )START_WILDCARD_RANKEND_WILDCARD_RANKNO_SSL_MODIFIERmax)r@   r   r   r   	wildcardss        r8   r   z)NginxConfigurator._select_best_name_match  s     QZ$79J/13D3V$X X 1:f%D$+AqqyD/@AIAy&>?HHqz'"" Bs   A)
A)r   c                 n   g }|D ]  }t        j                  ||j                        \  }}|dk(  r|j                  ||t        d       E|dk(  r|j                  ||t
        d       d|dk(  r|j                  ||t        d       |dk(  s|j                  ||t        d        t        |d       S )a  Returns a ranked list of vhosts from vhost_list that match target_name.
        This method should always be followed by a call to _select_best_name_match.

        :param list vhost_list: list of vhosts to filter and rank
        :param str target_name: The name to match
        :returns: list of dicts containing the vhost, the matching name, and
            the numerical rank
        :rtype: list

        exact)r   r   r   wildcard_startwildcard_endregexc                     | d   S Nr    r   s    r8   r   z9NginxConfigurator._rank_matches_by_name.<locals>.<lambda>
  
    QvY r:   r   )	r   get_best_matchr   r   	NAME_RANKr   r   
REGEX_RANKsorted)r@   r   r   r   r   	name_typer   s          r8   _rank_matches_by_namez'NginxConfigurator._rank_matches_by_name  s    "  	5E$33KMOItG#(,(1 3 4 ..(,(; = > n,(,(9 ; < g%(,(2 4 5	5$ g#677r:   c                     | j                  ||      }|D ]#  }|d   j                  r|dxx   t        z  cc<   % t        |d       S )a  Returns a ranked list of vhosts from vhost_list that match target_name.
        The ranking gives preference to SSLishness before name match level.

        :param list vhost_list: list of vhosts to filter and rank
        :param str target_name: The name to match
        :returns: list of dicts containing the vhost, the matching name, and
            the numerical rank
        :rtype: list

        r   r   c                     | d   S r  r  r   s    r8   r   zANginxConfigurator._rank_matches_by_name_and_ssl.<locals>.<lambda>  r  r:   r   )r  r   r   r	  )r@   r   r   r   matchs        r8   r   z/NginxConfigurator._rank_matches_by_name_and_ssl  sP     ,,ZE 	1E>%%f0	1 g#677r:   c                     t        j                  |      r| j                  |d|      }|S | j                  ||      }| j	                  |      fD cg c]  }||	 }}|S c c}w )a`  Chooses a single virtual host for redirect enhancement.

        Chooses the vhost most closely matching target_name that is
        listening to port without using ssl.

        .. todo:: This should maybe return list if no obvious answer
            is presented.

        .. todo:: The special name "$hostname" corresponds to the machine's
            hostname. Currently we just ignore this.

        :param str target_name: domain name
        :param str port: port number

        :returns: vhosts associated with name
        :rtype: list of :class:`~certbot_nginx._internal.obj.VirtualHost`

        F)r   r   )r   r   r   _get_redirect_ranked_matchesr   )r@   r   r   r   r   r   s         r8   choose_redirect_vhostsz(NginxConfigurator.choose_redirect_vhosts  sy    & "";/11+%#' 2 )F
  77TJG"&">">w"G!HYA1=aYFY Zs   A"A"c           	      "   | j                  |      D cg c]  }|sd|v s|d    }}|D cg c]4  }| j                  |t        | j                  j                        d      r|6 }}|D cg c]4  }| j                  |t        | j                  j
                        d      r|6 }}|s6	 | j                  |dt        | j                  j                              g}||fS ||fS c c}w c c}w c c}w # t        j                  $ r g }Y ||fS w xY w)a  Returns a list of HTTP and HTTPS vhosts with a server_name matching target_name.

        If no HTTP vhost exists, one will be cloned from the default vhost. If that fails, no HTTP
        vhost will be returned.

        :param str target_name: non-wildcard domain name

        :returns: tuple of HTTP and HTTPS virtualhosts
        :rtype: tuple of :class:`~certbot_nginx._internal.obj.VirtualHost`

        r   FT)	r   _vhost_listeningrf   rq   http01_portr   r   r   r   )r@   r   mr   r   http_vhostshttps_vhostss          r8   choose_auth_vhostsz$NginxConfigurator.choose_auth_vhosts:  s9    '+&>&>{&KbqU\`aUa!G*bb$* Wb,,RT[[5L5L1MuU  W W%+ Vr--b#dkk6L6L2MtT  V V !#BB;PUCFt{{G^G^C_ a b
 L(({L(( cWV // ! L((!s,   C$C$C$9C)-9C.+1C3 3DD	test_portmatching_portc                 8    |dk(  s||| j                   k(  S ||k(  S )NrG   )DEFAULT_LISTEN_PORT)r@   r  r  s      r8   r   zNginxConfigurator._port_matchesW  s+    B-"7 8 888M))r:   r   c                      j                   J  j                   j                  |      dt        j                  dt        ffd|j
                  s j                  k(  xr k(  S t         fd|j
                  D              S )a  Tests whether a vhost has an address listening on a port with SSL enabled or disabled.

        :param `obj.VirtualHost` vhost: The vhost whose addresses will be tested
        :param port str: The port number as a string that the address should be bound to
        :param bool ssl: Whether SSL should be enabled or disabled on the address

        :returns: Whether the vhost has an address listening on the port and protocol.
        :rtype: bool

        r   r)   c                 L    r| j                   xs S | j                    xr  S r   r   )r   all_addrs_are_sslr   s    r8   _ssl_matchesz8NginxConfigurator._vhost_listening.<locals>._ssl_matchesp  s.    4748800 :xx<9(9$9:r:   c              3   r   K   | ].  }j                  |j                               xr  |       0 y wr   )r   r   )r   r   r   r   r@   s     r8   r   z5NginxConfigurator._vhost_listening.<locals>.<genexpr>y  s9      , %%dDMMO<SdASS ,s   47)r   has_ssl_on_directiver   Addrr   r   r  any)r@   r   r   r   r   r  s   ` ``@@r8   r  z"NginxConfigurator._vhost_listening^  s     {{&&& !KK<<UC	:sxx 	:D 	: {{4333P?P8PP ,${{, , 	,r:   c                 (    | j                  ||d      S NF)r  )r@   r   r   s      r8   r   z1NginxConfigurator._vhost_listening_on_port_no_ssl|  s    $$UD%88r:   c                       j                   j                         }dt        j                  dt        dt
        f fd}|D cg c]  } |||      s| }} j                  ||      S c c}w )a  Gets a ranked list of plaintextish port-listening vhosts matching target_name

        Filter all hosts for those listening on port without using ssl.
        Rank by how well these match target_name.

        :param str target_name: The name to match
        :param str port: port number as a string
        :returns: list of dicts containing the vhost, the matching name, and
            the numerical rank
        :rtype: list

        r   r   r)   c                 (    j                  | |      S r   )r   )r   r   r@   s     r8   _vhost_matcheszFNginxConfigurator._get_redirect_ranked_matches.<locals>._vhost_matches  s    77tDDr:   )r   r   r   r   rf   r   r  )r@   r   r   
all_vhostsr)  r   matching_vhostss   `      r8   r  z.NginxConfigurator._get_redirect_ranked_matches  sq     [[++-
	E#// 	E 	E 	E /9XUN5RV<W5XX))/;GG Ys   A)A)c                    t               }| j                  j                         D ]f  }	 |j                  j	                  d       |j                  j                  t        j                                |j                  |j                         |j                  D ]  }|j                         }t        j                  j                  |      r|j                  |       Dt        j                  j                  |      rd	 |j                   r5|j#                         }t        j$                  t        j&                  |       n$t        j$                  t        j(                  |       |j                  t        j*                  |      d           i t3        j4                  |      S # t        $ r Y >w xY w# t        j,                  t        j.                  t        j0                  f$ r Y Pw xY w)zReturns all names found in the Nginx Configuration.

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

        z	$hostnamer   )r   r   r   r   remover(   socketgethostnameKeyErrorupdater   get_addrr   hostname_regexr  private_ips_regexr   get_ipv6_exploded	inet_ptonAF_INET6AF_INETgethostbyaddrerrorherrortimeoutr   get_filtered_names)r@   	all_namesr   r   hosts        r8   get_all_nameszNginxConfigurator.get_all_names  sh    "e	[[++- 	!E"";/ 2 2 45 U[[) !}}((..t4MM$'1177=!99#'#9#9#;D",,V__dC",,V^^TB!f&:&:4&@&CD!	!4 &&y11-  & #LL&--H ! !s%   AF$>BF4$	F10F142G*)G*c                    t         j                  j                  | j                  j                  d      }t        j                  d|d| j                  j                        }|j                  J t        j                  j                  t        j                  j                  |j                        }t        j                  |t!        j"                         g      }t        j                  j%                  t        j                  j                  |      }t'        j(                  t         j                  j                  |d      d	      \  }}|5  |j+                  |       ddd       ||j                  fS # 1 sw Y   xY w)
zBGenerate invalid certs that let us create ssl directives for Nginxsnakeoili   zkey.pem)key_sizekey_dirkeynamestrict_permissionsN)domainszcert.pemwb)mode)r   r<   r=   rq   work_dirr   generate_keyrF  fileOpenSSLcryptoload_privatekeyFILETYPE_PEMpemacme_crypto_utilgen_ss_certr.  r/  dump_certificater   unique_filewrite)r@   tmp_dirle_keyr   certcert_pem	cert_filer   s           r8   _get_snakeoil_pathsz%NginxConfigurator._get_snakeoil_paths  s    '',,t{{33Z@))7I#{{==? {{&&&nn,,NN''5++C&:L:L:N9OP>>22NN''/#//GGLL*-D :	9 	&OOH%	&&++%%	& 	&s   E66E?c           	         | j                   j                  }| j                  t        |            }dg}dg}|j                  s-ddd| j
                  gg}| j                  j                  ||       |j                         r>ddddj                  |      ddg}|d   s"|j                  d       |j                  d       |j                         rdddd	j                  |      ddg}| j                         \  }}||dd
d|gddd|gddd| j                  gddd| j                  gg}	| j                  j                  ||	       y)zMake a server SSL.

        Make a server SSL by adding new listen and SSL directives.

        :param vhost: The vhost to add SSL to.
        :type vhost: :class:`~certbot_nginx._internal.obj.VirtualHost`

        rG   r   listenr   z[::]:{0}r   r   zipv6only=onz{0}r%   r&   includer'   N)rq   r   r   rf   r   r  r   add_server_directivesipv6_enabledr   r   ipv4_enabledr\  rt   ssl_dhparams)
r@   r   r   ipv6info
ipv6_block
ipv4_blocklisten_blocksnakeoil_certsnakeoil_key	ssl_blocks
             r8   r   z"NginxConfigurator._make_server_ssl  se    [[++
>>#j/2T
T
 {{%xd6N6NOPLKK--e\B""$++J7!J A;!!#&!!-0"",,z2!J '+&>&>&@#| (#}=,c<@y#t'8'89}c4+<+<=
	 	))9	r:   c                 
    g dS )z)Returns currently supported enhancements.rH   r  r?   s    r8   supported_enhancementsz(NginxConfigurator.supported_enhancements  s    @@r:   enhancementoptionsc                     	  | j                   |   ||       y# t        t        f$ r% t        j                  dj                  |            w xY w)aw  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.

        zUnsupported enhancement: {0}N)rU   r0  
ValueErrorr   r   r   )r@   r   rm  rn  s       r8   enhancezNginxConfigurator.enhance  sX    	D+D{+FG<*% 	D$$.55kBD D	Ds	    4Ac                 L    t        t        |            }|j                  |      S r   )_test_block_from_block_redirect_block_for_domaincontains_list)r@   r   r   test_redirect_blocks       r8   _has_certbot_redirectz'NginxConfigurator._has_certbot_redirect  s&    45OPV5WX""#677r:   header_substringc                 X   t        |t              s"t        j                  dt	        |       d      |t
        j                  vrt        j                  | d      | j                  |      }|st        j                  d      |D ]  }|j                  |      rt        j                  d|z        |j                  r0t        d |j                  D              r| j                  |      \  }}ddd	|d	gt
        j                  |   z   d
gg}| j                  j!                  ||        y)ab  Enables header identified by header_substring on domain.

        If the vhost is listening plaintextishly, separates out the relevant
        directives into a new server block, and only add header directive to
        HTTPS block.

        :param str domain: the domain to enable header for.
        :param str header_substring: String to uniquely identify a header.
                        e.g. Strict-Transport-Security, Upgrade-Insecure-Requests
        :returns: Success
        :raises .errors.PluginError: If no viable HTTPS host can be created or
            set with header header_substring.
        zInvalid header_substring type z, expected a str.z& is not supported by the nginx plugin.z8Unable to find corresponding HTTPS host for enhancement.zExisting %s headerc              3   6   K   | ]  }|j                      y wr   r   r   s     r8   r   z5NginxConfigurator._set_http_header.<locals>.<genexpr>A  s      F$TXX Fs   r   
add_headerr   r   N)
isinstancerf   r   NotSupportedErrorr2   r   HEADER_ARGSr   r   
has_headerPluginEnhancementAlreadyPresentr   r$  r   _split_blockr   r`  )r@   r   rx  r   r   _header_directivess          r8   rS   z"NginxConfigurator._set_http_header!  sK    *C0**+K.23C.D-EEV,X Y Y9#8#88**#$$JKM M ##F+$$JL L 	HE 01<<(,<=? ?
 yyS F%++ FF,,U35 <.>D))*:;<! KK--e5FG	Hr:   c                 V    t        |      }| j                  j                  ||d       y)z(Add redirect directive to vhost
        T)insert_at_topN)rt  r   r`  )r@   r   r   redirect_blocks       r8   _add_redirect_blockz%NginxConfigurator._add_redirect_blockJ  s,     4F;))> 	* 	7r:   only_directivesc                      j                   j                  ||      }dt        dt        fd}dt        dt        f fd}dt        dt        fd} j                  D ]  } j                   j                  ||          j                   j                  |d|        j                   j                  |d	|        j                   j                  |d|       ||fS )
a  Splits this "virtual host" (i.e. this nginx server block) into
        separate HTTP and HTTPS blocks.

        :param vhost: The server block to break up into two.
        :param list only_directives: If this exists, only duplicate these directives
            when splitting the block.
        :type vhost: :class:`~certbot_nginx._internal.obj.VirtualHost`
        :returns: tuple (http_vhost, https_vhost)
        :rtype: tuple of type :class:`~certbot_nginx._internal.obj.VirtualHost`
        )r  	directiver)   c                 
    d| v S Nr   r  r  s    r8   _ssl_match_funcz7NginxConfigurator._split_block.<locals>._ssl_match_func`  s    I%%r:   c                      j                   | v S r   )rt   )r  r@   s    r8   _ssl_config_match_funcz>NginxConfigurator._split_block.<locals>._ssl_config_match_funcc  s    $$	11r:   c                 
    d| vS r  r  r  s    r8   _no_ssl_match_funcz:NginxConfigurator._split_block.<locals>._no_ssl_match_funcf  s    	))r:   r^  )
match_funcr_  )r   r   rf   r   SSL_DIRECTIVESremove_server_directives)r@   r   r  
http_vhostr  r  r  r  s   `       r8   r  zNginxConfigurator._split_blockR  s     [[000X
	&s 	&t 	&	2c 	2d 	2	*# 	*$ 	* ,, 	HIKK00YG	H,,Zo,^,,Z8N 	- 	P 	,,UHI[,\5  r:   unused_optionsc                     | j                   }| j                  ||      }|s!t        j                  d| j                          y|D ]  }| j	                  ||        y)a  Redirect all equivalent HTTP traffic to ssl_vhost.

        If the vhost is listening plaintextishly, separate out the
        relevant directives into a new server block and add a rewrite directive.

        .. note:: This function saves the configuration

        :param str domain: domain to enable redirect for
        :param unused_options: Not currently used
        :type unused_options: Not Available
        z>No matching insecure server blocks listening on port %s found.N)r  r  r   r   _enable_redirect_single)r@   r   r  r   r   r   s         r8   rR   z"NginxConfigurator._enable_redirectt  s`     '' ,,VT:KKX((* 	8E((7	8r:   c                    |j                   r:| j                  |ddg      \  }}g dg}| j                  j                  ||       |}| j	                  ||      r,t
        j                  d| j                  |j                         y| j                  ||       t
        j                  d| j                  |j                         y)a  Redirect all equivalent HTTP traffic to ssl_vhost.

        If the vhost is listening plaintextishly, separate out the
        relevant directives into a new server block and add a rewrite directive.

        .. note:: This function saves the configuration

        :param str domain: domain to enable redirect for
        :param `~obj.Vhost` vhost: vhost to enable redirect for
        r^  r   )r   r)   r   404z3Traffic on port %s already redirecting to ssl in %sz/Redirecting all traffic on port %s to ssl in %sN)
r   r  r   r`  rw  r   r   r  r   r  )r@   r   r   r  r  return_404_directives         r8   r  z)NginxConfigurator._enable_redirect_single  s     99 --eh5NOMJ %E#E KK--j:NOE%%eV4KKM((%++7 $$UF3KKI((%++7r:   c                     t        |t              s$|"t        j                  dt	        |       d      | j                  |      }|D ]  }| j                  ||        y)zInclude OCSP response in TLS handshake

        :param str domain: domain to enable OCSP response for
        :param chain_path: chain file path
        :type chain_path: `str` or `None`

        NzInvalid chain_path type z, expected a str or None.)r|  rf   r   r}  r2   r   _enable_ocsp_stapling_single)r@   r   r   r   r   s        r8   rT   z'NginxConfigurator._enable_ocsp_stapling  ss     *c*z/E**-Ed:FVEW XE ,E F F##F+ 	AE--eZ@	Ar:   c                    | j                   dk  rt        j                  d      |t        j                  d      ddd|gg dg d	d
gg}	 | j                  j	                  ||       | xj                  dj                  |j                        z  c_        | xj                  dj                  |      z  c_        | xj                  dz  c_        | xj                  dz  c_        y# t        j
                  $ rQ}t        j                  t        |             t        j                  dj                  |j                              d}~ww xY w)zInclude OCSP response in TLS handshake

        :param str vhost: vhost to enable OCSP response for
        :param chain_path: chain file path
        :type chain_path: `str` or `None`

        )r   r      zCVersion 1.3.7 or greater of nginx is needed to enable OCSP staplingNzh--chain-path is required to enable Online Certificate Status Protocol (OCSP) stapling on nginx >= 1.3.7.r   ssl_trusted_certificater   )r   ssl_staplingr   on)r   ssl_stapling_verifyr   r  r   z7An error occurred while enabling OCSP stapling for {0}.z-OCSP Stapling was enabled on SSL Vhost: {0}.
z	ssl_trusted_certificate {0}
z	ssl_stapling on
z	ssl_stapling_verify on
)rE   r   r   r   r`  r   r   r   rf   r   r   rM   r   )r@   r   r   stapling_directivesr:  s        r8   r  z.NginxConfigurator._enable_ocsp_stapling_single  s9    <<)#$$ &I J J $$%& & 0#zB184&B
	NKK--e.AC 	 3396%++3F	H<CCJOO0077 ++ 	NLLU$$$ &99?9LN N	Ns   C% %E	8AEE	c                 n    t        | j                  d      | j                  | j                  d             y)zlRestarts nginx server.

        :raises .errors.MisconfigurationError: If either the reload fails.

        r/   r0   N)nginx_restartr>   rA   r?   s    r8   restartzNginxConfigurator.restart  s&     	dii&?9STr:   c                     	 t        j                  | j                  d      d| j                  dg       y# t        j
                  $ r#}t	        j                  t        |            d}~ww xY w)z{Check the configuration of Nginx for errors.

        :raises .errors.MisconfigurationError: If config_test fails

        r/   -cz-tN)r   
run_scriptr>   rA   r   SubprocessErrorr   rf   )r@   errs     r8   r   zNginxConfigurator.config_test  sT    	9OOTYYu-tT__dKL%% 	9..s3x88	9s   25 A+A&&A+c           	         	 t        j                  | j                  d      d| j                  dgt         j                  t         j                  ddt        j                               }|j                  }|S # t        t        f$ rL}t        j                  t        |      d       t        j                  d| j                  d      z        d	}~ww xY w)
zReturn results of nginx -V

        :returns: version text
        :rtype: str

        :raises .PluginError:
            Unable to run Nginx version command
        r/   r  z-VTF)stdoutstderruniversal_newlinescheckenvr   zUnable to run %s -VN)
subprocessrunr>   rA   PIPEr   env_no_snap_for_external_callsr  r   rp  r   r   rf   r   r   )r@   proctextr:  s       r8   _nginx_versionz NginxConfigurator._nginx_version  s    	:>>5!4$?!!#'779;D ;;D
 	 $ 	:LLUdL3$$%		%(88: :	:s   A2A6 6CACC.c                    | j                         }t        j                  dt        j                        }|j	                  |      }t        j                  dt        j                        }|j	                  |      }t        j                  d      }|j	                  |      }|st        j                  d      |st        j                  d      |st        j                  d      |d   \  }}	|dk7  rt        j                  d	|       t        d
 |	j                  d      D              }
|
dk  rt        j                  d      |
S )zReturn version of Nginx Server.

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

        :returns: version
        :rtype: tuple

        :raises .PluginError:
            Unable to find Nginx version or version is unsupported

        z!nginx version: ([^/]+)/([0-9\.]*)zTLS SNI support enabledz --with-http_ssl_modulezUnable to find Nginx versionz;Nginx build is missing SSL module (--with-http_ssl_module).zNginx build doesn't support SNIr   nginxz:NGINX derivative %s is not officially supported by certbotc              3   2   K   | ]  }t        |        y wr   )r5   r   is     r8   r   z0NginxConfigurator.get_version.<locals>.<genexpr>5  s     Ic!fIr   .)r      0   zNginx version must be 0.8.48+)r  recompile
IGNORECASEfindallr   r   r   warningtuplesplitr}  )r@   r  version_regexversion_matches	sni_regexsni_matches	ssl_regexssl_matchesproduct_nameproduct_versionnginx_versions              r8   r   zNginxConfigurator.get_version  s*    ""$

#GW'//5JJ92==I	''-JJ9:	''-$$%CDD$$MO O$$%FGG(7(:%o7"NN &'35 Io.C.CC.HII :%**+JKKr:   c                     | j                         }t        j                  d|      }|s.t        j                  d|      }|st        j	                  d       y|d   S )a  Return version of OpenSSL linked to Nginx.

        Version is returned as string. If no version can be found, empty string is returned.

        :returns: openssl_version
        :rtype: str

        :raises .PluginError:
            Unable to run Nginx version command
        zrunning with OpenSSL ([^ ]+) zbuilt with OpenSSL ([^ ]+) zRNGINX configured with OpenSSL alternatives is not officially supported by Certbot.rG   r   )r  r  r  r   r  )r@   r  r   s      r8   r   z&NginxConfigurator._get_openssl_version>  sX     ""$**=tDjj!?FG  - .qzr:   c                     dj                  t        j                  | j                  j                  dj                  d | j                  D                    S )z3Human-readable string to help understand the modulez^Configures Nginx to authenticate and install HTTPS.{0}Server root: {root}{0}Version: {version}r  c              3   2   K   | ]  }t        |        y wr   r   r  s     r8   r   z.NginxConfigurator.more_info.<locals>.<genexpr>[  s      >AQ >r   )rootrE   )r   r   linesepr   config_rootr=   rE   r?   s    r8   	more_infozNginxConfigurator.more_infoT  sE    !!'

!8!8 > >> "( "@	
r:   failed_achallsc                      	 y)NzThe Certificate Authority failed to verify the temporary nginx configuration changes made by Certbot. Ensure the listed domains point to this nginx server and that it is accessible from the internet.r  )r@   r  s     r8   	auth_hintzNginxConfigurator.auth_hint^  s    ,	
r:   title	temporaryc                    t        | j                  j                  j                               }| j	                  || j
                  |       d| _        | j                  j                  d       |r|s| j                  |       yyy)a  Saves all changes to the configuration files.

        :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)

        :raises .errors.PluginError: If there was an error in
            an attempt to save the configuration, or an error creating a
            checkpoint

        rG   )extN)r   r   parsedkeysadd_to_checkpointrM   filedumpfinalize_checkpoint)r@   r  r  
save_filess       r8   savezNginxConfigurator.savei  so     ++0023
z4??IF 	$$$U+ #5r:   c                 d    t         |           d| _        | j                  j	                          y)zRevert all previously modified files.

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

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

        N)rK   rW   rN   r   load)r@   rX   s    r8   rW   z"NginxConfigurator.recovery_routine  s'     	 "r:   c                 f    | j                          d| _        | j                  j                          y)zUsed to cleanup challenge configurations.

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

        N)revert_temporary_configrN   r   r  r?   s    r8   revert_challenge_configz)NginxConfigurator.revert_challenge_config  s'     	$$&r:   rollbackc                 f    t         |   |       d| _        | j                  j	                          y)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)rK   rollback_checkpointsrN   r   r  )r@   r  rX   s     r8   r  z&NginxConfigurator.rollback_checkpoints  s)     	$X.r:   unused_domainc                 $    t         j                  gS )z%Return list of challenge preferences.)r   HTTP01)r@   r  s     r8   get_chall_prefz NginxConfigurator.get_chall_pref  s    !!""r:   achallsc                    | xj                   t        |      z  c_         dgt        |      z  }t        j                  |       }t	        |      D ]F  \  }}t        |t        j                        st        j                  d      |j                  ||       H |j                         }| j                          t	        |      D ]  \  }}|||j                  |   <    |D cg c]  }|s|	 c}S c c}w )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 KeyAuthorizationAnnotatedChallenge)rQ   r   r   NginxHttp01	enumerater|  r   "KeyAuthorizationAnnotatedChallenger   Error	add_challperformr  indices)	r@   r  	responses	http_doerr  achallhttp_responserespresponses	            r8   r  zNginxConfigurator.perform  s     	3w<'CG&3w<BW	''-	"7+ 	+IAv fk&T&TUll $K L L*	+ "))+ 	
 !/ 	3GAt.2Ii''*+	3 *3?Xh???s    C/(C/c                     | xj                   t        |      z  c_         | j                   dk  r!| j                          | j                          yy)zRevert all challenges.r   N)rQ   r   r  r  )r@   r  s     r8   cleanupzNginxConfigurator.cleanup  s<    3w<' ??a((*LLN  r:   )r)   Nr   )Fr&  )r   )V__name__
__module____qualname____doc__descriptionr  r  classmethodr   r9   propertyrf   rA   r   rL   ro   rt   rw   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   r  r   r  r   r@  r\  r   rl  r   rq  rw  rS   r  r  rR   r  rT   r  r  r   r  r5   r   r   r  r   AnnotatedChallenger  r  rW   r  r  r   r   	Challenger  ChallengeResponser  r  __classcell__)rX   s   @r8   r#   r#   :   s   ( ,K ON	(x	': 	(t 	( 	( DC D D$(c $(S $(T $(L #Q# #Q #QJ Qc Q Q [S [ [EC ES EUY E!\H># ># > >RU >$'>,0>0C#// Cs Cc C"%C7:C?CC* EI/c /t /4<SM/MQRURaRaMb/h S__8M  27+ +*.+;?;P+Z-c -eD$J&7 -0S t -058__ Gs G GPT GJ J4 J!$J),J4Ks KtDcN7K K#)1'#s(2C)D#IQRURaRaIb#*$80I $8+.$837S#X3G$8L88Q 8368;?S#X;O8$# S T#//EZ 8)c )eD<Q<@<Q=R 7S ):*s *3 *4 *,coo ,S ,t ,PT ,<9S__ 9C 9TX 9H H3 H4PTUXZ]U]P^K_ H,$2s3x $2L&U38_ &&4coo 4$ 4rAS	 A
 <@Dc D D!%T#Y"78DDHD$83?? 8C 8D 8'Hs 'HeCcTXDX>Y 'H^b 'HR7 7# 7$ 7 !#//  !HTRUYDW  ! @A !D8s 8)1%T#Y2G)H8MQ887c 7#// 7d 7:AC A*25d3i3H*IANRA $8#// $819#$8CG$8RU	9 0+U38_ +Zc ,
3 

"*;+I+I"J
OR
,(3- ,4 ,D ,0
S   #C #Dj>R>R9S4T #
!@tK$B$BC !@*667!@HtK$B$BC  r:   r#   blockr)   c                 b    t        j                  |       }t        j                  |d       |d d S )Nr   )r   UnspacedListr   comment_directive)r  
test_blocks     r8   rs  rs    s.    ))%0J
Z+cr?r:   r   c           	          | }d}t        j                  |       r.d}|j                  dd      }|j                  dd      }d|z   dz   }d	d
ddd|dd|z  dg	g dd	ggdgg}|S )N=~r  z\.*z[^.]+^$r   ifr   z($hostz%s))z	
        r)   r   301r   zhttps://$host$request_urir   )r   r   replace)r   updated_domainmatch_symbolr  s       r8   rt  rt    s    NLv&'//U;'//W=~-3	4h\3@VX[\	O	 
	N
 r:   	nginx_ctlrA   sleep_durationc                 J   	 d}t        j                         5 }t        j                  | d|ddgt	        j
                         ||d      }|j                  d       |j                         j                  d      }d	d	d	       j                  dk7  rt        j                  d
|       t        j                         5 }t        j                  | d|g||t	        j
                         d      }|j                  dk7  rF|j                  d       t        j                  d|j                         j                  d      z        	 d	d	d	       |dkD  rt!        j"                  |       y	y	# 1 sw Y   xY w# 1 sw Y   1xY w# t        t        f$ r t        j                  d      w xY w)a  Restarts the Nginx Server.

    .. todo:: Nginx restart is fatal if the configuration references
        non-existent SSL cert/key files. Remove references to /etc/letsencrypt
        before restart.

    :param str nginx_ctl: Path to the Nginx binary.
    :param str nginx_conf: Path to the Nginx configuration file.
    :param int sleep_duration: How long to sleep after sending the reload signal.

    rG   r  z-sreloadF)r  r  r  r  r   zutf-8Nznginx reload failed:
%s)r  r  r  r  znginx restart failed:
%sznginx restart failed)tempfileTemporaryFiler  r  r   r  seekreaddecode
returncoder   r   r   r   r   rp  timesleep)r!  rA   r"  reload_outputoutr  
nginx_procs          r8   r  r    s   C##% 	7>>9dJh"O&*&I&I&K),SGD HHQKHHJ--g6M	7 ??aLL3]C '') RS'^^Yj,Is0S0S0U]bd
((A-HHQK 663chhj6G6G6PPR R .R 

>" 7	7 	7R R Z  C**+ABBCs=   E= A"E%:AE= ;BE1E= %E.*E= 1E:6E= =%F"c                      t         j                  j                  d      dk(  r%t        j                   dt        j
                   } | S t        j                  d   } | S )NCERTBOT_DOCS1z or r,   )r   environgetr   LINUX_SERVER_ROOTFREEBSD_DARWIN_SERVER_ROOTr4   )r7   s    r8   r3   r3     s^    	zz~~n%,"+"="=!> ?%%.%I%I$J L  (44]Cr:   )Br  r`   
contextlibr   loggingr  r.  r  sysr%  r+  typingr   r   r   r   r   r	   r
   r   r   r   r   r   rM  acmer   r   rR  certbotr   r   r   certbot.compatr   certbot.displayr   certbot.pluginsr   certbot_nginx._internalr   r   r   r   r   r   version_infoimportlib.resources	resourcesrc   r  r   r   r  r   	getLoggerr  r   Configuratorr#   rs  rf   rt  r5   r  r3   r  r:   r8   <module>rF     s/        	   
                 0      0 " - / + / ' *v5	  
 
		8	$]++ ]@%$s) S	 s tCy  *#S *#c *#3 *#4 *#Z r:   