
    M/eH                        d Z ddlZddlZddlZddlZddlmZ ddl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  ej6                  e      Zdej<                  ddfdZdej<                  ddfdZ dej<                  ddfdZ!dej<                  ddfdZ"dej<                  de#de
ejH                     fdZ%dej<                  de#de
e	e#      fdZ&dej<                  de	e#   dee
ejH                     e
ejH                     f   fdZ'dejH                  de#de
e	e#      fd Z(de	eeejH                  ge#f   eejH                  ge
e	e#      f   f      fd!Z)dej<                  de#fd"Z*dej<                  d#eeeejH                  ge#f   eejH                  ge
e	e#      f   f      d$eejH                  ge#f   d%eejH                  ge#f   de	e#   f
d&Z+	 d:dej<                  d'ejH                  d(e,de
e#   fd)Z-	 	 d;dej<                  d*e#d+e,d,e
e#   de	e#   f
d-Z.d.ee#   de#fd/Z/dej<                  d0eejH                     de#fd1Z0dej<                  d0eejH                     d2ee#   ddfd3Z1 ed4      Z2dej<                  d5ed6e2f   d7e2d8ede2f
d9Z3y)<z Tools for managing certificates.    N)Any)Callable)Iterable)List)Optional)Tuple)TypeVar)Union)configuration)crypto_util)errors)ocsp)util)storage)osconfigreturnc                 h    t        j                  |       D ]  }t        j                  || d        y)aj  Update the certificate file family symlinks to use archive_dir.

    Use the information in the config file to make symlinks point to
    the correct archive directory.

    .. note:: This assumes that the installation is using a Reverter object.

    :param config: Configuration.
    :type config: :class:`certbot._internal.configuration.NamespaceConfig`

    T)update_symlinksN)r   renewal_conf_filesRenewableCert)r   renewal_files     @/usr/lib/python3/dist-packages/certbot/_internal/cert_manager.pyupdate_live_symlinksr   !   s2      226: JlFDIJ    c                    t        | d      d   }| j                  }|sSt        j                  dj	                  |      d      \  }}|t        j
                  k7  s|st        j                  d      t        | |      }|s$t        j                  dj	                  |            t        j                  |||        t        j                  dj	                  ||      d	
       y)zRename the specified lineage to the new name.

    :param config: Configuration.
    :type config: :class:`certbot._internal.configuration.NamespaceConfig`

    renamer   z&Enter the new name for certificate {0}T)force_interactiveUser ended interaction.z,No existing certificate with name {0} found.z Successfully renamed {0} to {1}.F)pauseN)get_certnamesnew_certnamedisplay_util
input_textformatOKr   Errorlineage_for_certnameConfigurationErrorr   rename_renewal_confignotification)r   certnamer"   codelineages        r   rename_lineager/   1   s     VX.q1H&&L)444;;HE"$l <??",,,899"684G'' ))+ 	+!!(L&A@"(&<"@Or   c                    g }g }t        j                  |       D ]?  }	 t        j                  ||       }t        j                  |       |j                  |       A t        | ||       y# t        $ rZ}t        j                  d||       t        j                  dt        j                                |j                  |       Y d}~d}~ww xY w)zDisplay information about certs configured with Certbot

    :param config: Configuration.
    :type config: :class:`certbot._internal.configuration.NamespaceConfig`
    zIRenewal configuration file %s produced an unexpected error: %s. Skipping.Traceback was:
%sN)r   r   r   r   verify_renewable_certappend	Exceptionloggerwarningdebug	traceback
format_exc_describe_certs)r   parsed_certsparse_failuresr   renewal_candidatees         r   certificatesr?   K   s     LN226: 	0	0 ' 5 5lF K--.?@ 12		0 FL.9  	0NN =>JAOLL-y/C/C/EF!!,//		0s   <A**	C3ACCc                    t        | dd      }dg}|D ]  }|j                  d|z           |j                  d       |j                  d       t        j                  dj	                  |      d	      st
        j                  d
       y|D ]<  }t        j                  | |       t        j                  dj                  |             > y)z;Delete Certbot files associated with a certificate lineage.deleteT)allow_multiplez8The following certificate(s) are selected for deletion:
z  * aP  
WARNING: Before continuing, ensure that the listed certificates are not being used by any installed server software (e.g. Apache, nginx, mail servers). Deleting a certificate that is still being used will cause the server software to stop working. See https://certbot.org/deleting-certs for information on deleting certificates safely.z:
Are you sure you want to delete the above certificate(s)?
)defaultz$Deletion of certificate(s) canceled.Nz.Deleted all files relating to certificate {0}.)r!   r3   r#   yesnojoinr5   infor   delete_filesnotifyr%   )r   	certnamesmsgr,   s       r   rA   rA   b   s    fhtDIF
GC &

6H$%&JJ	b JJLMdiind;:; /VX.L#VH-	//r   
cli_configr,   c                    | j                   }t        j                  |d       	 t        j                  | |      }	 t        j                  ||       S # t
        j                  $ r Y yw xY w# t
        j                  t        f$ rA t        j                  d|       t        j                  dt        j                                Y yw xY w)z)Find a lineage object with name certname.  modeNzRenewal conf file %s is broken.r1   )renewal_configs_dirr   make_or_verify_dirr   renewal_file_for_certnamer   CertStorageErrorr   IOErrorr5   r7   r8   r9   )rL   r,   configs_dirr   s       r   r(   r(   |   s     00KKe488XN$$\:>> ""  ##W- 6E)9+?+?+ABs#   A A+ A('A(+ACCc                 B    t        | |      }|r|j                         S dS )z0Find the domains in the cert with name certname.N)r(   names)r   r,   r.   s      r   domains_for_certnamerY      s#     #684G%7==?/4/r   domainsc           	      "   dt         j                  dt        t        t         j                     t        t         j                     f   dt        t        t         j                     t        t         j                     f   ffd}d}t	        | ||      S )a  Find existing certs that match the given domain names.

    This function searches for certificates whose domains are equal to
    the `domains` parameter and certificates whose domains are a subset
    of the domains in the `domains` parameter. If multiple certificates
    are found whose names are a subset of `domains`, the one whose names
    are the largest subset of `domains` is returned.

    If multiple certificates' domains are an exact match or equally
    sized subsets, which matching certificates are returned is
    undefined.

    :param config: Configuration.
    :type config: :class:`certbot._internal.configuration.NamespaceConfig`
    :param domains: List of domain names
    :type domains: `list` of `str`

    :returns: lineages representing the identically matching cert and the
        largest subset if they exist
    :rtype: `tuple` of `storage.RenewableCert` or `None`

    candidate_lineagervr   c                    |\  }}t        | j                               }|t              k(  r| }||fS |j                  t                    r/|| }||fS t        |      t        |j                               kD  r| }||fS )zsReturn cert as identical_names_cert if it matches,
           or subset_names_cert if it matches as subset
        )setrX   issubsetlen)r\   r]   identical_names_certsubset_names_certcandidate_namesrZ   s        r   update_certs_for_domain_matchesz?find_duplicative_certs.<locals>.update_certs_for_domain_matches   s     35///5578c'l*#4  %&788 %%c'l3 !($5! %&788 _%,=,C,C,E(FF$5!$&788r   )NN)r   r   r   r   _search_lineages)r   rZ   re   inits    `  r   find_duplicative_certsrh      s    297;P;P 9,1(7;P;P2Q2:7;P;P2Q3R -S9 .38G<Q<Q3R3;G<Q<Q3R4S .T9. UaDF$CTJJr   r\   filetypec                     | j                   }t        j                  |      D cg c]G  }t        j                  dj                  |      |      r t        j                  j                  ||      I }}|r|S yc c}w )aJ   In order to match things like:
        /etc/letsencrypt/archive/example.com/chain1.pem.

        Anonymous functions which call this function are eventually passed (in a list) to
        `match_and_check_overlaps` to help specify the acceptable_matches.

        :param `.storage.RenewableCert` candidate_lineage: Lineage whose archive dir is to
            be searched.
        :param str filetype: main file name prefix e.g. "fullchain" or "chain".

        :returns: Files in candidate_lineage's archive dir that match the provided filetype.
        :rtype: list of str or None
    z{0}[0-9]*.pemN)archive_dirr   listdirrematchr%   pathrF   )r\   ri   rk   fpatterns        r   _archive_filesrr      sp     $//K57ZZ5L Fxx 6 6x @!D ww||K+ FG F	Fs   AA7c                      d d d d gS )z Generates the list that's passed to match_and_check_overlaps. Is its own function to
    make unit testing easier.

    :returns: list of functions
    :rtype: list
    c                     | j                   S N)fullchain_pathxs    r   <lambda>z%_acceptable_matches.<locals>.<lambda>   s    a&& r   c                     | j                   S ru   	cert_pathrw   s    r   ry   z%_acceptable_matches.<locals>.<lambda>   s
    !++ r   c                     t        | d      S )Ncertrr   rw   s    r   ry   z%_acceptable_matches.<locals>.<lambda>   s    nQ/ r   c                     t        | d      S )N	fullchainr   rw   s    r   ry   z%_acceptable_matches.<locals>.<lambda>   s    >![;Y r    r   r   r   _acceptable_matchesr      s     '(=/1Y[ [r   c                 F     t               }t         | fdd       }|d   S )a   If config.cert_path is defined, try to find an appropriate value for config.certname.

    :param `configuration.NamespaceConfig` cli_config: parsed command line arguments

    :returns: a lineage name
    :rtype: str

    :raises `errors.Error`: If the specified cert path can't be matched to a lineage name.
    :raises `errors.OverlappingMatchFound`: If the matched lineage's archive is shared.
    c                     j                   S ru   r{   )rx   rL   s    r   ry   z&cert_path_to_lineage.<locals>.<lambda>   s    z/C/C r   c                     | j                   S ru   )lineagenamerw   s    r   ry   z&cert_path_to_lineage.<locals>.<lambda>   s
    q}} r   r   )r   match_and_check_overlaps)rL   acceptable_matchesrn   s   `  r   cert_path_to_lineager      s-     -.$Z1C%CE\^E8Or   r   
match_funcrv_funcc                    dt         j                  dt        t           dt        t
        t        t         j                  gt        f   t        t         j                  gt        t        t              f   f      dt        t           ffd}t        | |g |      }|s#t        j                  d| j                   d      t        |      dkD  rt        j                         |S )	a   Searches through all lineages for a match, and checks for duplicates.
    If a duplicate is found, an error is raised, as performing operations on lineages
    that have their properties incorrectly duplicated elsewhere is probably a bad idea.

    :param `configuration.NamespaceConfig` cli_config: parsed command line arguments
    :param list acceptable_matches: a list of functions that specify acceptable matches
    :param function match_func: specifies what to match
    :param function rv_func: specifies what to return

    r\   return_valuer   r   c                     |D cg c]
  } ||        }}g }|D ],  }t        |t              r||z  }|s|j                  |       .  |       }||v r|j                   	|              |S c c}w )z1Returns a list of matches using _search_lineages.)
isinstancelistr3   )
r\   r   r   funcacceptable_matches_resolvedacceptable_matches_rvitemrn   r   r   s
           r   find_matchesz.match_and_check_overlaps.<locals>.find_matches  s    
 L^&^4t,='>&^#&^+-/ 	3D$%%-%%,,T2		3
 ,-))(9 :; '_s   A/zNo match found for cert-path !   )r   r   r   strr   r
   r   r   rf   r   r'   r|   ra   OverlappingMatchFound)rL   r   r   r   r   matcheds     ``  r   r   r      s     (=(= TRUY )1%!7#8#8"93">?!7#8#8"98DI;N"NOP3Q *R W[[^V_" **lBHZ[Gll::;O;O:PPQRSS	W	**,,Nr   r~   skip_filter_checksc                 r   g }t        j                         }| j                  r|j                  | j                  k7  r|sy| j                  r3t        | j                        j                  |j                               syt        j                  j                  t        j                        }g }|j                  r|j                  d       |j                  |k  r|j                  d       n"|j                  |      r|j                  d       |rddj!                  |      z   }nT|j                  |z
  }|j"                  dk(  rd}n3|j"                  dk  rd	|j$                  d
z   d}nd	|j"                   d}dj'                  |j                  |      }	t'        t)        j*                  |j,                        d      }
|j                  d|j                   d|
 d|j.                   ddj!                  |j                                d|	 d|j0                   d|j2                          dj!                  |      S )zJ Returns a human readable description of info about a RenewableCert objectN	TEST_CERTEXPIREDREVOKEDz	INVALID: z, r   zVALID: 1 dayzVALID: i  z hour(s)z daysz	{0} ({1})rx   z  Certificate Name: z
    Serial Number: z
    Key Type: z
    Domains:  z
    Expiry Date: z
    Certificate Path: z
    Private Key Path:  )r   RevocationCheckerr,   r   rZ   r_   r`   rX   datetimenowpytzUTCis_test_certr3   target_expiryocsp_revokedrF   dayssecondsr%   r   get_serial_from_certr|   private_key_typer   privkey)r   r~   r   certinfocheckerr   reasonsstatusdiffvalid_stringserials              r   human_readable_cert_infor   &  s    H$$&G4++v>GY~~c&..1::4::<H





)CG{#S y!			d	#y!tyy11!!C'99>#FYY]t||t34H=Ftyyk/F%%d&8&8&ALK44T^^DcJFOO*4+;+;*< =**0 2%%)%:%:$; <$$'HHTZZ\$:#; <((4~ 6--1^^,< =--1\\N< = 778r   verbrB   custom_promptc                 |   | j                   }|r|g}|S t        j                  |       }|D cg c]  }t        j                  |       }}|st	        j
                  d      |r\|sdj                  |      }	n|}	t        j                  |	|dd      \  }
}|
t        j                  k7  rt	        j
                  d      |S |sdj                  |      }	n|}	t        j                  |	|dd      \  }
}|
t        j                  k7  s|t        dt        |            vrt	        j
                  d      ||   g}|S c c}w )	z4Get certname from flag, interactively, or error out.zNo existing certificates found.z+Which certificate(s) would you like to {0}?z--cert-nameT)cli_flagr   r   z(Which certificate would you like to {0}?r   )r,   r   r   lineagename_for_filenamer   r'   r%   r#   	checklistr&   menurangera   )r   r   rB   r   r,   rJ   	filenamesnamechoicespromptr-   indexs               r   r!   r!   Q  s?    HJ	6 3 ..v6	FOPd733D9PP,,@AA FMMdS&*44-4QOD)|&ll#<==  !CJJ4P&&++-4QKD% |&%uQG7M*Mll#<== (I1 Qs   D9msgsc                 8    ddj                  d | D              z   S )zFFormat a results report for a category of single-line renewal outcomesz  z
  c              3   2   K   | ]  }t        |        y wru   )r   ).0rK   s     r   	<genexpr>z _report_lines.<locals>.<genexpr>z  s     73c#h7s   )rF   )r   s    r   _report_linesr   x  s    &++7$7777r   r;   c                 v    g }|D ]"  }t        | |      }||j                  |       $ dj                  |      S )z)Format a results report for a parsed certrC   )r   r3   rF   )r   r;   r   r~   	cert_infos        r   _report_human_readabler   }  sG     H ',VT:	 OOI&' 99Xr   r<   c                 L   g }|j                   }|s|s	 |d       nb|rE| j                  s| j                  rdnd} |dj                  |              |t	        | |             |r |d        |t        |             t        j                  dj                  |      dd       y	)
z/Print information about the certs we know aboutzNo certificates found.z	matching r   zFound the following {0}certs:z3
The following renewal configurations were invalid:rC   F)r    wrapN)	r3   r,   rZ   r%   r   r   r#   r+   rF   )r   r;   r<   outrI   rn   s         r   r:   r:     s     CZZF'(#)??fnnK"E299%@A)&,?@   =01diinEFr   Tr   .
initial_rvargsc                    | j                   }t        j                  |d       |}t        j                  |       D ]#  }	 t        j
                  ||       } |||g| }% |S # t        j                  t        f$ rA t        j                  d|       t        j                  dt        j                                Y w xY w)a  Iterate func over unbroken lineages, allowing custom return conditions.

    Allows flexible customization of return values, including multiple
    return values and complex checks.

    :param `configuration.NamespaceConfig` cli_config: parsed command line arguments
    :param function func: function used while searching over lineages
    :param initial_rv: initial return value of the function (any type)

    :returns: Whatever was specified by `func` if a match is found.
    rN   rO   z)Renewal conf file %s is broken. Skipping.r1   )rQ   r   rR   r   r   r   r   rT   rU   r5   r7   r8   r9   )rL   r   r   r   rV   r]   r   r\   s           r   rf   rf     s     00KKe4	B22:> 0	 ' 5 5lJ O
 #R/$/0 I ''1 	LLDlSLL-y/C/C/EF	s   A##AB=<B=)F)FN)4__doc__r   loggingrm   r8   typingr   r   r   r   r   r   r	   r
   r   certbotr   r   r   r   r   certbot._internalr   certbot.compatr   certbot.displayr#   	getLogger__name__r5   NamespaceConfigr   r/   r?   rA   r   r   r(   rY   rh   rr   r   r   r   boolr   r!   r   r   r:   r   rf   r   r   r   <module>r      s   &   	           !     %  0			8	$J!>!> J4 J O=88 OT O4:66 :4 :./=00 /T /4]%B%B #&+3G4I4I+J$0!>!> 0#&0+3DI+>02K=#@#@ 2K$(I2K27AVAV8W8@AVAV8W9X 3Y2Kjg&;&; s xX\]`XaOb ,	[T%'2G2G1H#1M(N(0'2G2G1H(SWX[S\J]1](^)_ #` a 	[]%B%B s "&)F)F &19%!)7+@+@*A3*F!G!)7+@+@*A8DQTICV*V!W"X;Y 2Z& *273H3H2I32N)O	&
 '/0E0E/F/K&L&
 RVVYQZ&T 9>(]%B%B ('J_J_ (15(BJ3-(V \a15 -77  s  TX  !)# :>s) N8 8# 8
=#@#@ )1'2G2G)HMPGM99 G"*7+@+@"AG$,SMG6:G. CL!>!> hsTUvFV !"+.34r   