a }|g 8@sTdZddlZddlZddlmZddlmZddlmZddlmZddlm Z ddlm Z dd lm Z ddl Z dd l mZdd lmZdd lmZdd lmZddlmZddlmZddlmZddlmZddlmZddlmZeeZGdddej ej!ej"dZ#GdddZ$e%ddddZ&e%ddddZ'e%ee%ddd Z(dS)!z*Common code for DNS Authenticator Plugins.N)sleep)Callable)Iterable)List)Mapping)Optional)Type) challenges) achallenges) configuration)errors) interfaces) filesystem)os)ops)util)commoncseZdZdZejeddfdd Zed2e de ddd d Z e e jed d d ZeeeejdddZddddZedddZe e je ejdddZe e jddddZejddddZejeeeddddZejeeeddd d!Zeedd"d#d$Zd3eee e egdfdd%d&d'Z!d4eee e"eefe e d(gdfd(d)d*d+Z#e$eed,d-d.Z%e$d5ee e egdfed/d0d1Z&Z'S)6DNSAuthenticatorz!Base class for DNS AuthenticatorsN)confignamereturncst||d|_dS)NF)super__init___attempt_cleanup)selfrr __class__>/usr/lib/python3.9/site-packages/certbot/plugins/dns_common.pyr#szDNSAuthenticator.__init__ ).N)adddefault_propagation_secondsrcCs|d|tdddS)Npropagation-secondszjThe number of seconds to wait for DNS to propagate before asking the ACME server to verify the DNS record.)defaulttypehelp)int)clsr r!rrradd_parser_arguments(s z%DNSAuthenticator.add_parser_arguments)failed_achallsrcCs(|d}dj|j||dkr dnddS)z,See certbot.plugins.common.Plugin.auth_hint.r"zThe Certificate Authority failed to verify the DNS TXT records created by --{name}. Ensure the above domains are hosted by this DNS provider, or try increasing --{name}-propagation-seconds (currently {secs} second{suffix}).s)rZsecssuffix)confformatr)rr)Zdelayrrr auth_hint1s  zDNSAuthenticator.auth_hint) unused_domainrcCstjgSN)r ZDNS01)rr1rrrget_chall_pref;szDNSAuthenticator.get_chall_pref)rcCsdSr2rrrrrprepare>szDNSAuthenticator.preparecCs tdSr2NotImplementedErrorr4rrr more_infoAszDNSAuthenticator.more_info)achallsrcCs~|d|_g}|D]@}|j}||}||j}|||||||jqt d| dt | d|S)NTz/Waiting %d seconds for DNS changes to propagater") _setup_credentialsrdomainvalidation_domain_name validation account_key_performappendresponse display_utilnotifyr.r)rr9Z responsesachallr;r<r=rrrperformDs  zDNSAuthenticator.performcCs>|jr:|D].}|j}||}||j}||||q dSr2)rr;r<r=r>_cleanup)rr9rDr;r<r=rrrcleanup\s   zDNSAuthenticator.cleanupcCs tdS)z@ Establish credentials, prompting if necessary. Nr6r4rrrr:esz#DNSAuthenticator._setup_credentials)r;validation_namer=rcCs tdS)aX Performs a dns-01 challenge by creating a DNS TXT record. :param str domain: The domain being validated. :param str validation_domain_name: The validation record domain name. :param str validation: The validation record content. :raises errors.PluginError: If the challenge cannot be performed Nr6rr;rHr=rrrr?ls zDNSAuthenticator._performcCs tdS)aX Deletes the DNS TXT record which would have been created by `_perform_achall`. Fails gracefully if no such record exists. :param str domain: The domain being validated. :param str validation_domain_name: The validation record domain name. :param str validation: The validation record content. Nr6rIrrrrFys zDNSAuthenticator._cleanup)keylabelrcCs0||}|s,||}t|j|||dS)a Ensure that a configuration value is available. If necessary, prompts the user and stores the result. :param str key: The configuration key. :param str label: The user-friendly label for this piece of information. N)r._prompt_for_datasetattrrdest)rrJrKconfigured_value new_valuerrr _configures  zDNSAuthenticator._configure)rJrK validatorrcCsB||}|s>|||}t|j||tjtj|dS)a  Ensure that a configuration value is available for a path. If necessary, prompts the user and stores the result. :param str key: The configuration key. :param str label: The user-friendly label for this piece of information. N) r._prompt_for_filerMrrNrpathabspath expanduser)rrJrKrRrOrPrrr_configure_files  z DNSAuthenticator._configure_fileCredentialsConfiguration)rJrKrequired_variablesrRrcsVtddfdd }|||t|j}rF|rR||S)a As `_configure_file`, but for a credential configuration file. If necessary, prompts the user and stores the result. Always stores absolute paths to avoid issues during renewal. :param str key: The configuration key. :param str label: The user-friendly label for this piece of information. :param dict required_variables: Map of variable which must be present to error to display. :param callable validator: A method which will be called to validate the `CredentialsConfiguration` resulting from the supplied input after it has been validated to contain the `required_variables`. Should throw a `~certbot.errors.PluginError` to indicate any issue. Nfilenamercs*t|j}r|r&|dSr2)rXrNrequire)r[Zapplied_configurationrYrrRrr __validators   z.__validator)strrWrXr.rNr\)rrJrKrYrR_DNSAuthenticator__validatorZcredentials_configurationrr]r_configure_credentialss  z'DNSAuthenticator._configure_credentials)rKrcsPtddfdd }tj|ddd\}}|tjkr<|StddS) z Prompt the user for a piece of information. :param str label: The user-friendly label for this piece of information. :returns: The user's response (guaranteed non-empty). :rtype: str N)ircs|stddS)NzPlease enter your {0}.)r PluginErrorr/)rbrKrrr^sz6DNSAuthenticator._prompt_for_data..__validatorzInput your {0}TZforce_interactive{0} required to proceed.)r_rZvalidated_inputr/rBOKr rc)rKr`coderArrdrrLs   z!DNSAuthenticator._prompt_for_data)rKrRrcsRtddfdd }tj|ddd\}}|tjkr>|StddS) a Prompt the user for a path. :param str label: The user-friendly label for the file. :param callable validator: A method which will be called to validate the supplied input after it has been validated to be a non-empty path to an existing file. Should throw a `~certbot.errors.PluginError` to indicate any issue. :returns: The user's response (guaranteed to exist). :rtype: str NrZcs8|stdtj|}t|r4|dS)Nz&Please enter a valid path to your {0}.)r rcr/rrTrV validate_filer[rKrRrrr^s  z6DNSAuthenticator._prompt_for_file..__validatorzInput the path to your {0}Trerf)r_rZvalidated_directoryr/rBrgr rc)rKrRr`rhrArrkrrSs    z!DNSAuthenticator._prompt_for_file)r)N)NN)N)(__name__ __module__ __qualname____doc__r ZNamespaceConfigr_r classmethodrr&r(rr ZAnnotatedChallenger0rrr Z Challenger3r5r8ZChallengeResponserErGabcabstractmethodr:r?rFrQrrWrra staticmethodrLrS __classcell__rrrrr sR       (r) metaclassc@seZdZdZddfeeegefddddZeeefddd d Zee ed d d Z ee d ddZ ee ed ddZ dS)rXz>Represents a user-supplied filed which stores API credentials.cCs|Sr2r)xrrr z!CredentialsConfiguration.N)r[mapperrc Csnt|zt||_WnJtjyb}z0tjd||ddtd ||WYd}~n d}~00||_ dS)z :param str filename: A path to the configuration file. :param callable mapper: A transformation to apply to configuration key names :raises errors.PluginError: If the file does not exist or is not a valid format. z0Error parsing credentials configuration '%s': %sT)exc_infoz0Error parsing credentials configuration '{}': {}N) validate_file_permissions configobjZ ConfigObjconfobjZConfigObjErrorloggerdebugr rcr/ry)rr[ryerrrr s"z!CredentialsConfiguration.__init__)rYrc Csg}|D]R}||s4|d||||q||s|d||||q|rtdt|dkrxdnd|jj d |dS) zEnsures that the supplied set of variables are all present in the file. :param dict required_variables: Map of variable which must be present to error to display. :raises errors.PluginError: If one or more are missing. z)Property "{0}" not found (should be {1}).z'Property "{0}" not set (should be {1}).z9Missing {0} in credentials configuration file {1}: * {2}r*propertyZ propertiesz * N) _hasr@r/ry_getr rclenr}r[join)rrYmessagesvarrrrr\&s$  z CredentialsConfiguration.require)rrcCs ||S)zFind a configuration value for variable `var`, as transformed by `mapper`. :param str var: The variable to get. :returns: The value of the variable, if it exists. :rtype: str or None )rrrrrrr.?szCredentialsConfiguration.confcCs|||jvSr2)ryr}rrrrrIszCredentialsConfiguration._hascCs|j||Sr2)r}getryrrrrrLszCredentialsConfiguration._get)rlrmrnror_rrrr\rr.boolrrrrrrrX s $ rXrZcCs<tj|std|tj|r8td|dS)z&Ensure that the specified file exists.zFile not found: {0}zPath is a directory: {0}N)rrTexistsr rcr/isdirrjrrrriPs  ricCs"t|t|rtd|dS)zHEnsure that the specified file exists and warn about unsafe permissions.z8Unsafe permissions on credentials configuration file: %sN)rirZhas_world_permissionsr~Zwarningrjrrrr{Zs r{)r;rcs&|dfddtdtDS)aReturn a list of progressively less-specific domain names. One of these will probably be the domain name known to the DNS provider. :Example: >>> base_domain_name_guesses('foo.bar.baz.example.com') ['foo.bar.baz.example.com', 'bar.baz.example.com', 'baz.example.com', 'example.com', 'com'] :param str domain: The domain for which to return guesses. :returns: The a list of less specific domain names. :rtype: list .csg|]}d|dqS)rN)r).0rbZ fragmentsrr srxz,base_domain_name_guesses..r)splitranger)r;rrrbase_domain_name_guessescs r))rorqZloggingtimertypingrrrrrrr|Zacmer Zcertbotr r r r Zcertbot.compatrrZcertbot.displayrrrBZcertbot.pluginsrZ getLoggerrlr~ZPluginZ AuthenticatorABCMetarrXr_rir{rrrrrs6                  jG