M/e6dZddlZddlZddlmZddlmZddlmZddlmZddlm Z ddlm Z dd lm Z ddl Z dd l mZdd lmZdd lmZdd lmZddlmZddlmZddlmZddlmZddlmZddlmZej:eZGddej@ejBejDZ#GddZ$de%ddfdZ&de%ddfdZ'de%dee%fdZ(y)z*Common code for DNS Authenticator Plugins.N)sleep)Callable)Iterable)List)Mapping)Optional)Type) challenges) achallenges) configuration)errors) interfaces) filesystem)os)ops)util)commonc eZdZdZdej deddffd Ze d$de dd e ddfd Z d e e jdefd Zd edeeej&fdZd%dZdefdZde e jde ej.fdZde e jddfdZej6d%dZej6dedededdfdZej6dedededdfdZdededdfdZ d&dedede e egdfddfdZ! d'dedede e"eefde e d gdfdd f d!Z#e$dedefd"Z%e$d&dede e egdfdefd#Z&xZ'S)(DNSAuthenticatorz!Base class for DNS AuthenticatorsconfignamereturnNc4t|||d|_y)NF)super__init___attempt_cleanup)selfrr __class__s J MM&"8* E   V__V-?-?@ A  B MII345 6 dii-./r c|jrS|D]M}|j}|j|}|j|j}|j |||Oyyr8)rrFrGrHrI_cleanup)rrCrPrFrGrHs rcleanupzDNSAuthenticator.cleanupXsb  ! J)/)F)Fv)N&#..v/A/AB  f&--e4I DKK3 ; r validatorc |j|}|ss|j||}t|j|j |t j jt j j|yy)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) r2_prompt_for_filer^rr_rpathabspath expanduser)rrZr[rcr`ras r_configure_filez DNSAuthenticator._configure_filesa 99S>--eY?I DKK3ASAST]A^1_ ` r required_variablesCredentialsConfigurationcdtddffd }j|||tj|j}r|j r||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. filenamerNcnt|j}r|jr |yyr8)rkr_require)rmapplied_configurationrjrrcs r __validatorz.__validators7$.__validators((()A)H)H)OPPr zInput your {0}Tforce_interactive{0} required to proceed.)rrrvalidated_inputr3rMOKr ry)r[rscoderLs` rr]z!DNSAuthenticator._prompt_for_datass Q3 Q4 Q,,   # #E *"$h .__validatorsP(()Q)X)XY^)_``ww))(3H ( #(#r zInput the path to your {0}Trzr|)rrrvalidated_directoryr3rMr~r ry)r[rcrsrrLs`` rrez!DNSAuthenticator._prompt_for_filesp $# $$ $00  ( / / 6"$h rBChallengeResponserQrTabcabstractmethodrErJrSrbrrirru staticmethodr]re __classcell__)rs@rrrs+&}<<&C&D& @B.x ':.:=.GK.. [-K-K(L QT "C"HT*BVBV=W4X" $3$tK$B$BC*6670JtK$B$BCJJ $$   $s $S $  $%) $ $  $s $S $  $%) $ $Represents a user-supplied filed which stores API credentials.c|Sr8r<)xs rz!CredentialsConfiguration.sqr rmmapperrNct| tj||_||_ y#tj$rC}t j d||dtjdj||d}~wwxYw)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 configobj ConfigObjconfobjConfigObjErrorloggerdebugr ryr3r)rrmres rrz!CredentialsConfiguration.__init__s "(+ $..x8DL ''  LLB   $$BII  s/B>BBrjc g}|D]}|j|s4|jdj|j|||H|j |rZ|jdj|j||||rYt j djt|dk(rdnd|jjdj|y) 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-property propertiesz * N) _hasrKr3r_getr rylenrrmjoin)rrjmessagesvars rroz CredentialsConfiguration.require"s % TC99S> K!' C(8:LS:Q!RTYYs^ I!' C(8:LS:Q!RT  T $$LSS&)(mq&8 l -- X.  r rc$|j|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 )rrrs rr2zCredentialsConfiguration.conf;syy~r c<|j||jvSr8)rrrs rrzCredentialsConfiguration._hasEs{{34<<//r cV|jj|j|Sr8)rgetrrs rrzCredentialsConfiguration._getHs || C 011r )rrrrrrrrrrorr2boolrrr<r rrkrksHEPhucz.BUY4'#s(*;2 00022 2r rkrmrctjj|s$tjdj |tjj |r$tjdj |y)z&Ensure that the specified file exists.zFile not found: {0}zPath is a directory: {0}N)rrfexistsr ryr3isdirrms rrrLsc 77>>( #  !6!=!=h!GHH ww}}X  !;!B!B8!LMMr crt|tj|rtj d|yy)zHEnsure that the specified file exists and warn about unsafe permissions.z8Unsafe permissions on credentials configuration file: %sN)rrhas_world_permissionsrwarningrs rrrVs/(''1QS[\2r rFc|jd}tdt|Dcgc]}dj||dc}Scc}w)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 .rN)splitrangerr)rF fragmentsrws rbase_domain_name_guessesr_s@ S!I-21c)n-E FCHHYqr] # FF FsA))rrloggingtimertypingrrrrrr racmer certbotr r r rcertbot.compatrrcertbot.displayrrrMcertbot.pluginsr getLoggerrrPlugin AuthenticatorABCMetarrkrrrrrr<r rrs0 !%0"   8 $fKv}}j&>&>#++fKRD2D2NNCNDN]]]GSGT#YGr