Ë
    M/ÅeÌ6  ã                   ó²  — d 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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 G d„ dej@                  ejB                  ejD                  ¬«      Z# G d„ d«      Z$de%ddfd„Z&de%ddfd„Z'de%dee%   fd„Z(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                   ó¬  ‡ — e Zd ZdZdej
                  deddfˆ fd„Ze	 d$de	d   d	e
ddfd
„«       Zdeej                     defd„Zdedeeej&                        fd„Zd%d„Zdefd„Zdeej                     deej.                     fd„Zdeej                     ddfd„Zej6                  d%d„«       Zej6                  dedededdfd„«       Zej6                  dedededdfd„«       Zdededdfd„Z	 d&dedede e	egdf      ddfd„Z!	 	 d'dedede e"eef      de e	d gdf      dd f
d!„Z#e$dedefd"„«       Z%e$d&dede e	egdf      defd#„«       Z&ˆ xZ'S )(ÚDNSAuthenticatorz!Base class for DNS AuthenticatorsÚconfigÚnameÚreturnNc                 ó4   •— t         ‰| �  ||«       d| _        y )NF)ÚsuperÚ__init__Ú_attempt_cleanup)Úselfr   r   Ú	__class__s      €ú</usr/lib/python3/dist-packages/certbot/plugins/dns_common.pyr   zDNSAuthenticator.__init__   s   ø€ Ü‰Ñ˜ Ô&à %ˆÕó    Úadd).NÚdefault_propagation_secondsc                 ó$   —  |d|t         d¬«       y )Núpropagation-secondszjThe number of seconds to wait for DNS to propagate before asking the ACME server to verify the DNS record.)ÚdefaultÚtypeÚhelp)Úint)Úclsr!   r"   s      r   Úadd_parser_argumentsz%DNSAuthenticator.add_parser_arguments$   s   € ñ 	Ð!Ø/Üð-ö	.r    Úfailed_achallsc                 óx   — | j                  d«      }dj                  | j                  ||dk7  rd¬«      S d¬«      S )z,See certbot.plugins.common.Plugin.auth_hint.r$   zßThe 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Ú )r   ÚsecsÚsuffix)ÚconfÚformatr   )r   r+   Údelays      r   Ú	auth_hintzDNSAuthenticator.auth_hint-   sI   € à—	‘	Ð/Ó0ˆðN÷ ‰V˜Ÿ™¨¸eÀqºj°sˆVÓQð		
ð OQˆVÓQð		
r    Úunused_domainc                 ó$   — t         j                  gS ©N)r
   ÚDNS01)r   r6   s     r   Úget_chall_prefzDNSAuthenticator.get_chall_pref7   s   € Ü× Ñ Ð!Ð!r    c                  ó   — y r8   © ©r   s    r   ÚpreparezDNSAuthenticator.prepare:   s   € Ør    c                 ó   — t        «       ‚r8   ©ÚNotImplementedErrorr=   s    r   Ú	more_infozDNSAuthenticator.more_info=   s   € Ü!Ó#Ð#r    Úachallsc                 ó²  — | j                  «        d| _        g }|D ]w  }|j                  }|j                  |«      }|j	                  |j
                  «      }| j                  |||«       |j                  |j                  |j
                  «      «       Œy t        j                  d| j                  d«      z  «       t        | j                  d«      «       |S )NTz/Waiting %d seconds for DNS changes to propagater$   )Ú_setup_credentialsr   ÚdomainÚvalidation_domain_nameÚ
validationÚaccount_keyÚ_performÚappendÚresponseÚdisplay_utilÚnotifyr2   r   )r   rC   Ú	responsesÚachallrF   rG   rH   s          r   ÚperformzDNSAuthenticator.perform@   sÇ   € à×ÑÔ!à $ˆÔàˆ	Øò 	BˆFØ—]‘]ˆFØ%+×%BÑ%BÀ6Ó%JÐ"Ø×*Ñ*¨6×+=Ñ+=Ó>ˆJà�M‰M˜&Ð"8¸*ÔEØ×Ñ˜VŸ_™_¨V×-?Ñ-?Ó@ÕAð	Bô 	×ÑÐMØ—I‘IÐ3Ó4ñ5ô 	6äˆd�i‰iÐ-Ó.Ô/àÐr    c                 óÂ   — | j                   rS|D ]M  }|j                  }|j                  |«      }|j                  |j                  «      }| j                  |||«       ŒO y y r8   )r   rF   rG   rH   rI   Ú_cleanup)r   rC   rP   rF   rG   rH   s         r   ÚcleanupzDNSAuthenticator.cleanupX   sb   € Ø× Ò Ø!ò J�ØŸ™�Ø)/×)FÑ)FÀvÓ)NÐ&Ø#×.Ñ.¨v×/AÑ/AÓB�
à—‘˜fÐ&<¸jÕIñJð !r    c                 ó   — t        «       ‚)z@
        Establish credentials, prompting if necessary.
        r@   r=   s    r   rE   z#DNSAuthenticator._setup_credentialsa   s   € ô
 "Ó#Ð#r    rF   Úvalidation_namerH   c                 ó   — t        «       ‚)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
        r@   ©r   rF   rV   rH   s       r   rJ   zDNSAuthenticator._performh   s   € ô "Ó#Ð#r    c                 ó   — t        «       ‚)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.
        r@   rX   s       r   rS   zDNSAuthenticator._cleanupu   s   € ô "Ó#Ð#r    ÚkeyÚlabelc                 óš   — | j                  |«      }|s8| j                  |«      }t        | j                  | j	                  |«      |«       yy)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)r2   Ú_prompt_for_dataÚsetattrr   Údest)r   rZ   r[   Úconfigured_valueÚ	new_values        r   Ú
_configurezDNSAuthenticator._configureƒ   sB   € ð  Ÿ9™9 S›>ÐÙØ×-Ñ-¨eÓ4ˆIä�D—K‘K §¡¨3£°Õ;ð  r    Ú	validatorc           	      ó  — | j                  |«      }|ss| j                  ||«      }t        | j                  | j	                  |«      t
        j                  j                  t
        j                  j                  |«      «      «       yy)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^   r   r_   r   ÚpathÚabspathÚ
expanduser)r   rZ   r[   rc   r`   ra   s         r   Ú_configure_filez DNSAuthenticator._configure_file“   sa   € ð  Ÿ9™9 S›>ÐÙØ×-Ñ-¨e°YÓ?ˆIä�D—K‘K §¡¨3£´·±·±ÄÇÁ×ASÑASÐT]ÓA^Ó1_Õ`ð  r    Úrequired_variablesÚCredentialsConfigurationc                 óÖ   ‡ ‡‡— dt         ddfˆˆ ˆfd„}‰ j                  |||«       t        ‰ j                  |«      ‰ 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.
        Úfilenamer   Nc                 ón   •— t        | ‰j                  «      }‰r|j                  ‰«       ‰r	 ‰|«       y y r8   )rk   r_   Úrequire)rm   Úapplied_configurationrj   r   rc   s     €€€r   Ú__validatorz<DNSAuthenticator._configure_credentials.<locals>.__validator¸   s7   ø€ Ü$<¸XÀtÇyÁyÓ$QÐ!á!Ø%×-Ñ-Ð.@ÔAáÙÐ/Õ0ð r    )Ústrri   rk   r2   r_   ro   )r   rZ   r[   rj   rc   Ú_DNSAuthenticator__validatorÚcredentials_configurations   `  ``  r   Ú_configure_credentialsz'DNSAuthenticator._configure_credentials¤   sg   ú€ ð(	1¤#ð 	1¨$÷ 	1ð 	×Ñ˜S %¨Ô5ä$<¸T¿Y¹YÀs»^ÈTÏYÉYÓ$WÐ!ÙØ%×-Ñ-Ð.@ÔAáÙÐ/Ô0à(Ð(r    c                 óæ   ‡ — dt         ddfˆ fd„}t        j                  |dj                  ‰ «      d¬«      \  }}|t        j
                  k(  r|S t        j                  dj                  ‰ «      «      ‚)	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
        Úir   Nc                 óR   •— | s$t        j                  dj                  ‰«      «      ‚y )NzPlease enter your {0}.)r   ÚPluginErrorr3   )rw   r[   s    €r   rq   z6DNSAuthenticator._prompt_for_data.<locals>.__validatorÖ   s(   ø€ ÙÜ×(Ñ(Ð)A×)HÑ)HÈÓ)OÓPÐPð r    zInput your {0}T©Úforce_interactiveú{0} required to proceed.)rr   r   Úvalidated_inputr3   rM   ÚOKr   ry   )r[   rs   ÚcoderL   s   `   r   r]   z!DNSAuthenticator._prompt_for_dataÌ   ss   ø€ ð	Qœ3ð 	Q 4õ 	Qô ×,Ñ,ØØ×#Ñ# EÓ*Ø"ô$‰ˆˆhð
 ”<—?‘?Ò"ØˆOÜ× Ñ Ð!;×!BÑ!BÀ5Ó!IÓJÐJr    c                 óê   ‡ ‡— dt         ddfˆ ˆfd„}t        j                  |dj                  ‰ «      d¬«      \  }}|t        j
                  k(  r|S t        j                  dj                  ‰ «      «      ‚)	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
        rm   r   Nc                 ó¼   •— | s$t        j                  dj                  ‰«      «      ‚t        j                  j                  | «      } t        | «       ‰r	 ‰| «       y y )Nz&Please enter a valid path to your {0}.)r   ry   r3   r   rf   rh   Úvalidate_file)rm   r[   rc   s    €€r   rq   z6DNSAuthenticator._prompt_for_file.<locals>.__validatorð   sP   ø€ ÙÜ×(Ñ(Ð)Q×)XÑ)XÐY^Ó)_Ó`Ð`ä—w‘w×)Ñ)¨(Ó3ˆHä˜(Ô#áÙ˜(Õ#ð r    zInput the path to your {0}Trz   r|   )rr   r   Úvalidated_directoryr3   rM   r~   r   ry   )r[   rc   rs   r   rL   s   ``   r   re   z!DNSAuthenticator._prompt_for_fileã   sp   ù€ ð		$¤#ð 		$¨$ö 		$ô ×0Ñ0ØØ(×/Ñ/°Ó6Ø"ô$‰ˆˆhð
 ”<—?‘?Ò"ØˆOÜ× Ñ Ð!;×!BÑ!BÀ5Ó!IÓJÐJr    )é
   )r   Nr8   )NN)(Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   ÚNamespaceConfigrr   r   Úclassmethodr   r(   r*   r   r   ÚAnnotatedChallenger5   r   r	   r
   Ú	Challenger:   r>   rB   ÚChallengeResponserQ   rT   ÚabcÚabstractmethodrE   rJ   rS   rb   r   ri   r   ru   Ústaticmethodr]   re   Ú__classcell__)r   s   @r   r   r      sš  ø„ Ù+ð&˜}×<Ñ<ð &ÀCð &ÈDõ &ð
 à@Bñ. x°	Ñ':ð .Ø:=ð.ØGKò.ó ð.ð
¨¨[×-KÑ-KÑ(Lð 
ÐQTó 
ð"¨Cð "°H¸TÀ*×BVÑBVÑ=WÑ4Xó "óð$˜3ó $ð˜t K×$BÑ$BÑCð Ø˜*×6Ñ6Ñ7óð0J˜t K×$BÑ$BÑCð JÈó Jð 	×Ñò$ó ð$ð 	×Ñð
$˜sð 
$°Sð 
$Ø ð
$Ø%)ò
$ó ð
$ð 	×Ñð$˜sð $°Sð $Ø ð$Ø%)ò$ó ð$ð<˜cð <¨#ð <°$ó <ð" FJña 3ð a¨sð aØ#+¨H°c°U¸D°[Ñ,AÑ#BðaØNRóað$ W[ØLPñ&)Øð&)Ø"ð&)Ø8@ÀÈÈcÈÑARÑ8Sð&)à˜HÐ&@Ð%AÀ4Ð%GÑHÑIð&)ð 
$ó&)ðP ðK ð K¨ò Kó ðKð, ñK ð K°¸À3À%ÈÀ+Ñ9NÑ0Oð KÐ[^ò Kó ôKr    r   )Ú	metaclassc                   óŒ   — e Zd ZdZd„ fdedeegef   ddfd„Zdeeef   ddfd	„Zd
ede	e   fd„Z
d
edefd„Zd
ede	e   fd„Zy)rk   z>Represents a user-supplied filed which stores API credentials.c                 ó   — | S r8   r<   )Úxs    r   ú<lambda>z!CredentialsConfiguration.<lambda>  s   € Èq€ r    rm   Úmapperr   Nc                 ó  — t        |«       	 t        j                  |«      | _        || _
        y# t        j                  $ rC}t
        j                  d||d¬«       t        j                  dj                  ||«      «      ‚d}~ww xY w)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Ú	ConfigObjÚconfobjÚConfigObjErrorÚloggerÚdebugr   ry   r3   r—   )r   rm   r—   Úes       r   r   z!CredentialsConfiguration.__init__  sŠ   € ô 	" (Ô+ð	Ü$×.Ñ.¨xÓ8ˆDŒLð ˆ�øô ×'Ñ'ò 	Ü�L‰LØBØØØð	 ô ô ×$Ñ$ØB×IÑIØØóóð ûð	ús   �/ ¯BÁ>B Â Brj   c           	      óà  — g }|D ]Œ  }| j                  |«      s4|j                  dj                  | j                  |«      ||   «      «       ŒH| j	                  |«      rŒZ|j                  dj                  | j                  |«      ||   «      «       ŒŽ |rYt        j                  dj                  t        |«      dk(  rdnd| j                  j                  dj                  |«      «      «      ‚y)	zôEnsures 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)Ú_hasrK   r3   r—   Ú_getr   ry   Úlenr�   rm   Újoin)r   rj   ÚmessagesÚvars       r   ro   z CredentialsConfiguration.require"  sÚ   € ð ˆà%ò 	TˆCØ—9‘9˜S”>Ø—‘Ð Kß!'¡¨¯©°CÓ(8Ð:LÈSÑ:QÓ!RõTà—Y‘Y˜s•^Ø—‘Ð Iß!'¡¨¯©°CÓ(8Ð:LÈSÑ:QÓ!RõTð	Tñ Ü×$Ñ$ØL×SÑSÜ&)¨(£m°qÒ&8™
¸lØŸ™×-Ñ-ØŸ™ XÓ.óóð ð r    rª   c                 ó$   — | j                  |«      S )zØFind 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
        )r¦   ©r   rª   s     r   r2   zCredentialsConfiguration.conf;  s   € ð �y‰y˜‹~Ðr    c                 ó<   — | j                  |«      | j                  v S r8   )r—   r�   r¬   s     r   r¥   zCredentialsConfiguration._hasE  s   € Ø�{‰{˜3Ó 4§<¡<Ð/Ð/r    c                 óV   — | j                   j                  | j                  |«      «      S r8   )r�   Úgetr—   r¬   s     r   r¦   zCredentialsConfiguration._getH  s    € Ø�|‰|×Ñ §¡¨CÓ 0Ó1Ð1r    )r…   r†   r‡   rˆ   rr   r   r   r   ro   r   r2   Úboolr¥   r¦   r<   r    r   rk   rk     s‹   „ ÙHáEPñ  ð ¨h¸°u¸c°zÑ.Bð ÐUYó ð4¨'°#°s°(Ñ*;ð Àó ð2˜ð  ¨¡ó ð0˜ð 0 ó 0ð2˜ð 2 ¨¡ô 2r    rk   rm   r   c                 ó  — t         j                  j                  | «      s$t        j                  dj                  | «      «      ‚t         j                  j                  | «      r$t        j                  dj                  | «      «      ‚y)z&Ensure that the specified file exists.zFile not found: {0}zPath is a directory: {0}N)r   rf   Úexistsr   ry   r3   Úisdir©rm   s    r   r‚   r‚   L  sc   € ô �7‰7�>‰>˜(Ô#Ü× Ñ Ð!6×!=Ñ!=¸hÓ!GÓHÐHä	‡w�w‡}�}�XÔÜ× Ñ Ð!;×!BÑ!BÀ8Ó!LÓMÐMð r    c                 ór   — t        | «       t        j                  | «      rt        j	                  d| «       yy)zHEnsure that the specified file exists and warn about unsafe permissions.z8Unsafe permissions on credentials configuration file: %sN)r‚   r   Úhas_world_permissionsrŸ   Úwarningr´   s    r   rš   rš   V  s/   € ô �(Ôä×'Ñ'¨Ô1Ü�‰ÐQÐS[Õ\ð 2r    rF   c                 ó˜   — | j                  d«      }t        dt        |«      «      D �cg c]  }dj                  ||d «      ‘Œ c}S c c}w )aÂ  Return 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
    ú.r   N)ÚsplitÚranger§   r¨   )rF   Ú	fragmentsrw   s      r   Úbase_domain_name_guessesr½   _  s@   € ð —‘˜SÓ!€IÜ-2°1´c¸)³nÓ-EÖF¨ˆC�H‰H�Y˜q˜r�]Õ#ÒFÐFùÒFs   ©A))rˆ   rŽ   ÚloggingÚtimer   Útypingr   r   r   r   r   r	   r›   Úacmer
   Úcertbotr   r   r   r   Úcertbot.compatr   r   Úcertbot.displayr   r   rM   Úcertbot.pluginsr   Ú	getLoggerr…   rŸ   ÚPluginÚAuthenticatorÚABCMetar   rk   rr   r‚   rš   r½   r<   r    r   ú<module>rÊ      sÌ   ðÙ 0Û 
Û Ý Ý Ý Ý Ý Ý Ý ã å Ý Ý !Ý Ý Ý %Ý Ý Ý 0Ý "à	ˆ×	Ñ	˜8Ó	$€ôfK�v—}‘} j×&>Ñ&>È#Ï+É+õ fK÷RD2ñ D2ðNN˜Cð N Dó Nð]¨ð ]°ó ]ðG Sð G¨T°#©Yô Gr    