
    M/e)                        U d Z ddlZddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlm	Z	 dd	lm
Z
 dd
lmZ ddlmZ ddlmZ ddlmZ dd	lm
Z  ej(                  e      Zdej.                  ddfdZdedee   fdZdededdfdZdej.                  ddfdZ e       Zee   ed<   deddfdZ dej.                  dee   ddfdZ!g Z"ee   ed<   deddfdZ#dee   dee   ddfdZ$dej.                  dee   d eddfd!Z%dej.                  dee   d eddfd"Z&dedee   d ed#e'd$e'ddfd%Z(d+d&eded'eeeef      defd(Z)d)edee   fd*Z*y),z;Facilities for implementing hooks that call shell commands.    N)Dict)List)Optional)Set)configuration)errors)util)
filesystem)misc)os)opsconfigreturnc                     t        | j                  d       t        | j                  d       t        | j                  d       t        | j                  d       y)z#Check hook commands are executable.prepostdeployrenewN)validate_hookpre_hook	post_hookdeploy_hook
renew_hook)r   s    9/usr/lib/python3/dist-packages/certbot/_internal/hooks.pyvalidate_hooksr      s@    &//5)&""F+&$$h/&##W-    	shell_cmdc                     t        j                  |       s+t        j                  |        t        j                  |       syt        j
                  j                  |       S )zExtract the program run by a shell command.

    :param str shell_cmd: command to be executed

    :returns: basename of command or None if the command isn't found
    :rtype: str or None

    N)r	   
exe_exists	plug_utilpath_surgeryr   pathbasename)r   s    r   _progr$      sB     ??9%y)y)77I&&r   	hook_namec                    | r}| j                  dd      d   }t        |      s\t        j                  d   }t        j                  j                  |      r	| d| d}nd| d| d| d	}t        j                  |      yy)
zCheck that a command provided as a hook is plausibly executable.

    :raises .errors.HookCommandNotFound: if the command is not found
    N   r   PATHz-hook command z exists, but is not executable.zUnable to find z in the PATH.
(PATH is z0)
See also the --disable-hook-validation option.)splitr$   r   environr"   existsr   HookCommandNotFound)r   r%   cmdr"   msgs        r   r   r   .   s    
 oodA&q)Sz::f%Dww~~c"^I;6UV &i[seC[fMO 
 ,,S11  r   c                     | j                   dk(  r1| j                  r%t        | j                        D ]  }t	        |        | j
                  }|rt	        |       yy)a  Run pre-hooks if they exist and haven't already been run.

    When Certbot is running with the renew subcommand, this function
    runs any hooks found in the config.renewal_pre_hooks_dir (if they
    have not already been run) followed by any pre-hook in the config.
    If hooks in config.renewal_pre_hooks_dir are run and the pre-hook in
    the config is a path to one of these scripts, it is not run twice.

    :param configuration.NamespaceConfig config: Certbot settings

    r   N)verbdirectory_hooks
list_hooksrenewal_pre_hooks_dir_run_pre_hook_if_necessaryr   )r   hookr-   s      r   r   r   B   sU     {{g&"8"8v;;< 	-D&t,	- //C
"3' r   executed_pre_hookscommandc                     | t         v rt        j                  d|        yt        d|        t         j	                  |        y)zRun the specified pre-hook if we haven't already.

    If we've already run this exact command before, a message is logged
    saying the pre-hook was skipped.

    :param str command: pre-hook to be run

    z*Pre-hook command already run, skipping: %szpre-hookN)r6   loggerinfo	_run_hookaddr7   s    r   r4   r4   Z   s4     $$@'J*g&w'r   renewed_domainsc                 R   | j                   }| j                  dk(  r@| j                  r%t        | j                        D ]  }t        |        |rt        |       yy|rJdj                  |      }t        |      dkD  rt        j                  d       |dd }t        d||dd       yy)	a  Run post-hooks if defined.

    This function also registers any executables found in
    config.renewal_post_hooks_dir to be run when Certbot is used with
    the renew subcommand.

    If the verb is renew, we delay executing any post-hooks until
    :func:`run_saved_post_hooks` is called. In this case, this function
    registers all hooks found in config.renewal_post_hooks_dir to be
    called followed by any post-hook in the config. If the post-hook in
    the config is a path to an executable in the post-hook directory, it
    is not scheduled to be run twice.

    :param configuration.NamespaceConfig config: Certbot settings

    r    i }  z?Limiting RENEWED_DOMAINS environment variable to 32k charactersN	post-hook RENEWED_DOMAINSFAILED_DOMAINS)r   r0   r1   r2   renewal_post_hooks_dir_run_eventuallyjoinlenr9   warningr;   )r   r>   r-   r5   renewed_domains_strs        r   r   r   j   s    , 

C{{g!!"6#@#@A &%&C   
!hh7"#f,NN\]"5gv">#6 #%			
 
r   
post_hooksc                 @    | t         vrt         j                  |        yy)zRegisters a post-hook to be run eventually.

    All commands given to this function will be run exactly once in the
    order they were given when :func:`run_saved_post_hooks` is called.

    :param str command: post-hook to register to be run

    N)rL   appendr=   s    r   rG   rG      s     j '" !r   failed_domainsc                    dj                  |       }dj                  |      }t        |      dkD  rt        j                  d       |dd }t        |      dkD  rt        j                  d       |dd }t        D ]  }t        d|||d        y)zGRun any post hooks that were saved up in the course of the 'renew' verbr@   i>  z?Limiting RENEWED_DOMAINS environment variable to 16k charactersNz>Limiting FAILED_DOMAINS environment variable to 16k charactersrA   rC   )rH   rI   r9   rJ   rL   r;   )r>   rO   rK   failed_domains_strr-   s        r   run_saved_post_hooksrR      s     ((?3.1 &(XY1'6:
'WX0&9 
#6"4	

r   domainslineage_pathc                 x    | j                   r.t        | j                   ||| j                  | j                         yy)a  Run post-issuance hook if defined.

    :param configuration.NamespaceConfig config: Certbot settings
    :param domains: domains in the obtained certificate
    :type domains: `list` of `str`
    :param str lineage_path: live directory path for the new cert

    N)r   _run_deploy_hookdry_runrun_deploy_hooks)r   rS   rT   s      r   r   r      s6     ++W%v~~v7N7N	P r   c                    t               }| j                  rNt        | j                        D ]6  }t	        |||| j
                  | j                         |j                  |       8 | j                  r]| j                  |v r!t        j                  d| j                         yt	        | j                  ||| j
                  | j                         yy)a]  Run post-renewal hooks.

    This function runs any hooks found in
    config.renewal_deploy_hooks_dir followed by any renew-hook in the
    config. If the renew-hook in the config is a path to a script in
    config.renewal_deploy_hooks_dir, it is not run twice.

    If Certbot is doing a dry run, no hooks are run and messages are
    logged saying that they were skipped.

    :param configuration.NamespaceConfig config: Certbot settings
    :param domains: domains in the obtained certificate
    :type domains: `list` of `str`
    :param str lineage_path: live directory path for the new cert

    z0Skipping deploy-hook '%s' as it was already run.N)setr1   r2   renewal_deploy_hooks_dirrV   rW   rX   r<   r   r9   r:   )r   rS   rT   executed_dir_hooksr5   s        r   r   r      s    $ v>>? 	)DT7L&..&JaJab""4(	)  22KKJ))+ V..)6>>6;R;RT r   rW   rX   c                     |r|st         j                  d|        ydj                  |      t        j                  d<   |t        j                  d<   t        d|        y)at  Run the specified deploy-hook (if not doing a dry run).

    If dry_run is True, command is not run and a message is logged
    saying that it was skipped. If dry_run is False, the hook is run
    after setting the appropriate environment variables.

    :param str command: command to run as a deploy-hook
    :param domains: domains in the obtained certificate
    :type domains: `list` of `str`
    :param str lineage_path: live directory path for the new cert
    :param bool dry_run: True iff Certbot is doing a dry run
    :param bool run_deploy_hooks: True if deploy hooks should run despite Certbot doing a dry run

    z)Dry run: skipping deploy hook command: %sNr@   rD   RENEWED_LINEAGEzdeploy-hook)r9   r:   rH   r   r*   r;   )r7   rS   rT   rW   rX   s        r   rV   rV      sP      '?	 $'HHW$5BJJ !$0BJJ !mW%r   cmd_name	extra_envc                     t        j                         }|j                  |xs i        t        j                  | ||      \  }}}t        j                  d|  d|||       |S )aH  Run a hook command.

    :param str cmd_name: the user facing name of the hook being run
    :param shell_cmd: shell command to execute
    :type shell_cmd: `list` of `str` or `str`
    :param dict extra_env: extra environment variables to set
    :type extra_env: `dict` of `str` to `str`

    :returns: stderr if there was any)envzHook '')r	   env_no_snap_for_external_callsupdater   execute_command_statusdisplay_opsreport_executed_command)r_   r   r`   rb   
returncodeerrouts          r   r;   r;     sb     
-
-
/CJJyB66)&JS''&
!(<j#sSJr   dir_pathc                       fdt        j                         D        }|D cg c],  }t        j                  |      s|j	                  d      r+|. }}t        |      S c c}w )zList paths to all hooks found in dir_path in sorted order.

    :param str dir_path: directory to search

    :returns: `list` of `str`
    :rtype: sorted list of absolute paths to executables in dir_path

    c              3   ^   K   | ]$  }t         j                  j                  |       & y wN)r   r"   rH   ).0frl   s     r   	<genexpr>zlist_hooks.<locals>.<genexpr>+  s      HaXq)Hs   *-~)r   listdirr
   is_executableendswithsorted)rl   allpathsr"   hookss   `   r   r2   r2   "  sX     I2::h3GHH&dd**B*B4*HQUQ^Q^_bQcTdEd%= es   A"A"A"ro   )+__doc__loggingtypingr   r   r   r   certbotr   r   r	   certbot.compatr
   r   r   certbot.displayr   rg   certbot.pluginsr    	getLogger__name__r9   NamespaceConfigr   strr$   r   r   rZ   r6   __annotations__r4   r   rL   rG   rR   r   r   boolrV   r;   r2    r   r   <module>r      s   A      !   %   . -			8	$.=88 .T .'S 'Xc] '"2S 2S 2T 2((]22 (t (*  #u CH $( ( ( /
))/
#Y/
 
/
d 
DI 
#S 
#T 
#
$s) 
T#Y 
SW 
4P55 PS	 P!P&*PT}44 TtCy T T%)TB&c &DI &S &SW &'+&04&4  c3h8P \_ $ c r   