3 گaI @s"dZddlZddlZddlZddlZddlmZddlmZddlmZddlm Z ddlm Z ddlm Z dd lm Z dd lm Z ddlZdd lmZdd lmZdd lmZddlmZddlmZddlmZddlmZddlmZejeZejddddZejddddZ ejddddZ!ejddddZ"eje#e ej$dddZ%eje#e e e#ddd Z&eje e#e e ej$e ej$fd!d"d#Z'ej$e#e e e#d$d%d&Z(e e eej$ge#feej$ge e e#ffd'd(d)Z)eje#d*d+d,Z*ejee eej$ge#feej$ge e e#ffeej$ge#feej$ge#fe e#d-d.d/Z+dEejej$e,e e#d1d2d3Z-dFeje#e,e e#e e#d4d5d6Z.ee#e#d7d8d9Z/ejeej$e#d:d;d<Z0ejeej$ee#dd=d>d?Z1e d@Z2ejedAe2fe2ee2dBdCdDZ3dS)Gz Tools for managing certificates.N)Any)Callable)Iterable)List)Optional)Tuple)TypeVar)Union) configuration) crypto_util)errors)ocsp)util)storage)os)configreturncCs(x"tj|D]}tj||ddq WdS)ajUpdate 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)Zupdate_symlinksN)rrenewal_conf_files RenewableCert)r renewal_filer"/usr/lib/python3.6/cert_manager.pyupdate_live_symlinks!s rcCst|dd}|j}|sJtjdj|dd\}}|tjks@| rJtjdt||}|shtj dj|t j |||tj dj||d d d S) zRename the specified lineage to the new name. :param config: Configuration. :type config: :class:`certbot._internal.configuration.NamespaceConfig` renamerz&Enter the new name for certificate {0}T)force_interactivezUser ended interaction.z,No existing certificate with name {0} found.z Successfully renamed {0} to {1}.F)pauseN) get_certnames new_certname display_utilZ input_textformatOKr Errorlineage_for_certnameZConfigurationErrorrZrename_renewal_config notification)rcertnamercodelineagerrrrename_lineage1s   r'cCsg}g}xtj|D]t}y$tj||}tj||j|Wqtk r}z.tjd||tj dt j |j|WYdd}~XqXqWt |||dS)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.zTraceback was: %sN) rrrr Zverify_renewable_certappend ExceptionloggerZwarningdebug traceback format_exc_describe_certs)r parsed_certsparse_failuresrZrenewal_candidateerrr certificatesKs   r2cCst|ddd}dg}x|D]}|jd|qW|jd|jdtjdj|dd sftjd d Sx(|D] }tj||tj d j |qlWd S) 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}.) rr(rZyesnojoinr*inforZ delete_filesnotifyr)r certnamesmsgr$rrrr3bs     r3) cli_configr$rcCs|j}tj|ddytj||}Wntjk r:dSXy tj||Stjtfk r~t j d|t j dt j dSXdS)z)Find a lineage object with name certname.i)modeNzRenewal conf file %s is broken.zTraceback was: %s) renewal_configs_dirrmake_or_verify_dirrZrenewal_file_for_certnamer CertStorageErrorrIOErrorr*r+r,r-)r<r$ configs_dirrrrrr"|s  r")rr$rcCst||}|r|jSdS)z0Find the domains in the cert with name certname.N)r"names)rr$r&rrrdomains_for_certnames rD)rdomainsrcsPtjtttjttjftttjttjfdfdd }d}t|||S)aFind 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_lineagervrcsb|\}}t|j}|tkr&|}n4|jtrZ|dkrB|}nt|t|jkrZ|}||fS)zsReturn cert as identical_names_cert if it matches, or subset_names_cert if it matches as subset N)setrCissubsetlen)rFrGZidentical_names_certZsubset_names_certZcandidate_names)rErrupdate_certs_for_domain_matchess   z?find_duplicative_certs..update_certs_for_domain_matchesN)NN)rrrr_search_lineages)rrErKZinitr)rErfind_duplicative_certss   rM)rFfiletypercs,|jfddtjD}|r(|SdS)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 cs,g|]$}tjdj|rtjj|qS)z {0}[0-9]*.pem)rematchrrpathr7).0f) archive_dirrNrr sz"_archive_files..N)rTrlistdir)rFrNpatternr)rTrNr_archive_filess rX)rcCsddddddddgS)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 cSs|jS)N)Zfullchain_path)xrrrsz%_acceptable_matches..cSs|jS)N) cert_path)rYrrrrZscSs t|dS)Ncert)rX)rYrrrrZscSs t|dS)N fullchain)rX)rYrrrrZsrrrrr_acceptable_matchess r^)r<rcs(t}t|fdddd}|dS)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. csjS)N)r[)rY)r<rrrZsz&cert_path_to_lineage..cSs|jS)N) lineagename)rYrrrrZsr)r^match_and_check_overlaps)r<acceptable_matchesrPr)r<rcert_path_to_lineages rb)r<ra match_funcrv_funcrc stjttttttjgtfttjgtttffttdfdd }t||g|}|svt j dj |j nt |dkrt 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 )rF return_valuerarcshfdd|D}g}x.|D]&}t|tr4||7}q|r|j|qW}||krd|j|S)z1Returns a list of matches using _search_lineages.csg|] }|qSrr)rRfunc)rFrrrUszBmatch_and_check_overlaps..find_matches..) isinstancelistr()rFreraZacceptable_matches_resolvedZacceptable_matches_rvitemrP)rcrd)rFr find_matches s   z.match_and_check_overlaps..find_matchesz!No match found for cert-path {0}!)rrrstrrr rrrLr r!rr[rJZOverlappingMatchFound)r<rarcrdrjZmatchedr)rcrdrr`s 4 r`F)rr\skip_filter_checksrc CsFg}tj}|jr(|j|jkr(| r(dS|jrHt|jj|j rHdStj j t j j }g}|j rn|jd|j|kr|jdn|j|r|jd|rddj|}nB|j|}|jdkrd}n(|jdkrd j|jd }n d j|j}d j|j|} ttj|jd } |jdj|j| |jdj|j| |j|jdj|S)zJ Returns a human readable description of info about a RenewableCert objectNZ TEST_CERTZEXPIREDZREVOKEDz INVALID: z, rkz VALID: 1 dayzVALID: {0} hour(s)izVALID: {0} daysz {0} ({1})rYz Certificate Name: {} Serial Number: {} Key Type: {} Domains: {} Expiry Date: {} Certificate Path: {} Private Key Path: {} )r ZRevocationCheckerr$r_rErHrIrCpytzZUTCZfromutcdatetimeZutcnowZ is_test_certr(Z target_expiryZ ocsp_revokedr7ZdaysrZsecondsr Zget_serial_from_certr[Zprivate_key_typer]Zprivkey) rr\rmcertinfoZcheckerZnowZreasonsZstatusZdiffZ valid_stringserialrrrhuman_readable_cert_info&sB           rt)rverbr4 custom_promptrc Cs|j}|r|g}ntj|}dd|D}|s8tjd|r||sLdj|}n|}tj||ddd\} }| tjkrtjdnZ|sd j|}n|}tj ||ddd\} } | tjks| t d t |krtjd|| g}|S) z4Get certname from flag, interactively, or error out.cSsg|]}tj|qSr)rZlineagename_for_filename)rRnamerrrrU`sz!get_certnames..zNo existing certificates found.z+Which certificate(s) would you like to {0}?z --cert-nameT)Zcli_flagrzUser ended interaction.z(Which certificate would you like to {0}?r) r$rrr r!rrZ checklistr ZmenurangerJ) rrur4rvr$r: filenameschoicespromptr%indexrrrrXs0        r)msgsrcCsddjdd|DS)zFFormat a results report for a category of single-line renewal outcomesz z css|]}t|VqdS)N)rl)rRr;rrr sz _report_lines..)r7)r}rrr _report_linessr)rr/rcCs8g}x(|D] }t||}|dk r |j|q Wdj|S)z)Format a results report for a parsed certNr5)rtr(r7)rr/rrr\Z cert_inforrr_report_human_readables   r)rr/r0rcCsg}|j}| r | r |dnL|rT|js0|jr4dnd}|dj||t|||rl|d|t|tjdj|dddd S) z/Print information about the certs we know aboutzNo certificates found.z matching rozFound the following {0}certs:z3 The following renewal configurations were invalid:r5F)rZwrapN) r(r$rErrrrr#r7)rr/r0outr9rPrrrr.s   r.T.)r<rf initial_rvargsrc Gs|j}tj|dd|}xltj|D]^}ytj||}Wn8tjtfk rpt j d|t j dt j w$YnX|||f|}q$W|S)aIterate 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. i)r=z)Renewal conf file %s is broken. Skipping.zTraceback was: %s) r>rr?rrrr r@rAr*r+r,r-)r<rfrrrBrGrrFrrrrLs  rL)F)FN)4__doc__rqZloggingrOr,Ztypingrrrrrrrr rpZcertbotr r r r rZcertbot._internalrZcertbot.compatrZcertbot.displayrZ getLogger__name__r*ZNamespaceConfigrr'r2r3rlrr"rDrMrXr^rbr`boolrtrrrr.rrLrrrrsn                 3(  %1"&