U
    ÓZjÁ.  ã                   @   sô   d Z ddlZddlZddlm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 e e¡Zej ej¡ej ej¡G dd„ dejƒƒƒZG dd„ de ƒZ!dd„ Z"dd„ Z#dd„ Z$dS )z*Common code for DNS Authenticator Plugins.é    N)Úsleep)Ú
challenges)Úerrors)Ú
interfaces)Ú
filesystem)Úos)Úops)Úutil)Úcommonc                       s®   e Zd ZdZ‡ fdd„Zed dd„ƒZdd„ Zd	d
„ Zdd„ Z	dd„ Z
ejdd„ ƒZejdd„ ƒZejdd„ ƒZdd„ Zd!dd„Zd"dd„Zedd„ ƒZed#dd„ƒZ‡  ZS )$ÚDNSAuthenticatorz"Base class for DNS  Authenticatorsc                    s   t t| ƒ ||¡ d| _d S )NF)Úsuperr   Ú__init__Ú_attempt_cleanup)ÚselfÚconfigÚname©Ú	__class__© ú]/var/www/html/TRUCKING_PROJECT/venv/lib/python3.8/site-packages/certbot/plugins/dns_common.pyr      s    zDNSAuthenticator.__init__é
   c                 C   s   |d|t dd� d S )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)ÚclsÚaddZdefault_propagation_secondsr   r   r   Úadd_parser_arguments!   s
    ýz%DNSAuthenticator.add_parser_argumentsc                 C   s   t jgS ©N)r   ZDNS01)r   Zunused_domainr   r   r   Úget_chall_pref)   s    zDNSAuthenticator.get_chall_prefc                 C   s   d S r   r   ©r   r   r   r   Úprepare,   s    zDNSAuthenticator.preparec                 C   s|   |   ¡  d| _g }|D ]@}|j}| |¡}| |j¡}|  |||¡ | | |j¡¡ qt	 
d|  d¡¡ t|  d¡ƒ |S )NTz/Waiting %d seconds for DNS changes to propagater   )Ú_setup_credentialsr   ÚdomainÚvalidation_domain_nameÚ
validationÚaccount_keyÚ_performÚappendÚresponseÚloggerÚinfoÚconfr   )r   ÚachallsÚ	responsesÚachallr$   r%   r&   r   r   r   Úperform/   s    
ÿzDNSAuthenticator.performc                 C   s>   | j r:|D ].}|j}| |¡}| |j¡}|  |||¡ q
d S r   )r   r$   r%   r&   r'   Ú_cleanup)r   r.   r0   r$   r%   r&   r   r   r   ÚcleanupF   s    
zDNSAuthenticator.cleanupc                 C   s
   t ƒ ‚dS )z@
        Establish credentials, prompting if necessary.
        N©ÚNotImplementedErrorr!   r   r   r   r#   O   s    z#DNSAuthenticator._setup_credentialsc                 C   s
   t ƒ ‚dS )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
        Nr4   ©r   r$   Zvalidation_namer&   r   r   r   r(   V   s    
zDNSAuthenticator._performc                 C   s
   t ƒ ‚dS )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.
        Nr4   r6   r   r   r   r2   b   s    zDNSAuthenticator._cleanupc                 C   s0   |   |¡}|s,|  |¡}t| j|  |¡|ƒ dS )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_dataÚsetattrr   Údest)r   ÚkeyÚlabelÚconfigured_valueÚ	new_valuer   r   r   Ú
_configureo   s    


zDNSAuthenticator._configureNc                 C   sB   |   |¡}|s>|  ||¡}t| j|  |¡tj tj |¡¡ƒ dS )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_filer8   r   r9   r   ÚpathÚabspathÚ
expanduser)r   r:   r;   Ú	validatorr<   r=   r   r   r   Ú_configure_file   s    

z DNSAuthenticator._configure_filec                    sN   ‡ ‡‡fdd„}ˆ  |||¡ tˆ |¡ˆjƒ}ˆ r>| ˆ ¡ ˆrJˆ|ƒ |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.
        c                    s*   t | ˆjƒ}ˆ r| ˆ ¡ ˆr&ˆ|ƒ d S r   )ÚCredentialsConfigurationr9   Úrequire)ÚfilenameÚconfiguration©Úrequired_variablesr   rC   r   r   Ú__validator    s
    
z<DNSAuthenticator._configure_credentials.<locals>.__validator)rD   rE   r-   r9   rF   )r   r:   r;   rJ   rC   Ú_DNSAuthenticator__validatorZcredentials_configurationr   rI   r   Ú_configure_credentials�   s    	
z'DNSAuthenticator._configure_credentialsc                    sH   ‡ fdd„}t j|d ˆ ¡dd�\}}|tjkr4|S t d ˆ ¡¡‚dS )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
        c                    s   | st  d ˆ ¡¡‚d S )NzPlease enter your {0}.)r   ÚPluginErrorÚformat)Úi©r;   r   r   rK   ¾   s    z6DNSAuthenticator._prompt_for_data.<locals>.__validatorzInput your {0}T©Úforce_interactiveú{0} required to proceed.N)r   Zvalidated_inputrO   Údisplay_utilÚOKr   rN   )r;   rL   Úcoder*   r   rQ   r   r7   ´   s    
ý

z!DNSAuthenticator._prompt_for_datac                    sJ   ‡ ‡fdd„}t j|d ˆ ¡dd�\}}|tjkr6|S t d ˆ ¡¡‚dS )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
        c                    s8   | st  d ˆ ¡¡‚tj | ¡} t| ƒ ˆr4ˆ| ƒ d S )Nz&Please enter a valid path to your {0}.)r   rN   rO   r   r@   rB   Úvalidate_file©rG   ©r;   rC   r   r   rK   Ù   s    z6DNSAuthenticator._prompt_for_file.<locals>.__validatorzInput the path to your {0}TrR   rT   N)r   Zvalidated_directoryrO   rU   rV   r   rN   )r;   rC   rL   rW   r*   r   rZ   r   r?   Ì   s    ý

z!DNSAuthenticator._prompt_for_file)r   )N)NN)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Úclassmethodr   r    r"   r1   r3   ÚabcÚabstractmethodr#   r(   r2   r>   rD   rM   Ústaticmethodr7   r?   Ú__classcell__r   r   r   r   r      s*   	




%
r   c                   @   s@   e Zd ZdZdd„ fdd„Zdd„ Zdd	„ Zd
d„ Zdd„ ZdS )rE   z>Represents a user-supplied filed which stores API credentials.c                 C   s   | S r   r   )Úxr   r   r   Ú<lambda>ò   ó    z!CredentialsConfiguration.<lambda>c              
   C   sh   t |ƒ zt |¡| _W nD tjk
r\ } z$tjd|dd� t d 	|¡¡‚W 5 d}~X Y nX || _
dS )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.
        z+Error parsing credentials configuration: %sT)Úexc_infoz,Error parsing credentials configuration: {0}N)Úvalidate_file_permissionsÚ	configobjZ	ConfigObjÚconfobjZConfigObjErrorr+   Údebugr   rN   rO   Úmapper)r   rG   rl   Úer   r   r   r   ò   s    "z!CredentialsConfiguration.__init__c              	   C   s’   g }|D ]R}|   |¡s4| d |  |¡|| ¡¡ q|  |¡s| d |  |¡|| ¡¡ q|rŽt d t|ƒdkrxdnd| jj	d 
|¡¡¡‚dS )	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}é   ÚpropertyÚ
propertiesz
 * N)Ú_hasr)   rO   rl   Ú_getr   rN   Úlenrj   rG   Újoin)r   rJ   ÚmessagesÚvarr   r   r   rF     s(    
 ÿ
 ÿýÿz CredentialsConfiguration.requirec                 C   s
   |   |¡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.
        :rtype: str
        )rr   ©r   rv   r   r   r   r-     s    zCredentialsConfiguration.confc                 C   s   |   |¡| jkS r   )rl   rj   rw   r   r   r   rq   %  s    zCredentialsConfiguration._hasc                 C   s   | j  |  |¡¡S r   )rj   Úgetrl   rw   r   r   r   rr   (  s    zCredentialsConfiguration._getN)	r[   r\   r]   r^   r   rF   r-   rq   rr   r   r   r   r   rE   ï   s   
rE   c                 C   s<   t j | ¡st d | ¡¡‚t j | ¡r8t d | ¡¡‚dS )z&Ensure that the specified file exists.zFile not found: {0}zPath is a directory: {0}N)r   r@   Úexistsr   rN   rO   ÚisdirrY   r   r   r   rX   ,  s    rX   c                 C   s"   t | ƒ t | ¡rt d| ¡ dS )zHEnsure that the specified file exists and warn about unsafe permissions.z8Unsafe permissions on credentials configuration file: %sN)rX   r   Zhas_world_permissionsr+   ÚwarningrY   r   r   r   rh   6  s    
rh   c                    s&   |   d¡‰ ‡ fdd„tdtˆ ƒƒD ƒS )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
    Ú.c                    s   g | ]}d   ˆ |d… ¡‘qS )r|   N)rt   )Ú.0rP   ©Ú	fragmentsr   r   Ú
<listcomp>O  s     z,base_domain_name_guesses.<locals>.<listcomp>r   )ÚsplitÚrangers   )r$   r   r~   r   Úbase_domain_name_guesses?  s    
rƒ   )%r^   r`   ÚloggingÚtimer   ri   Zzope.interfaceZzopeZacmer   Zcertbotr   r   Zcertbot.compatr   r   Zcertbot.displayr   r	   rU   Zcertbot.pluginsr
   Ú	getLoggerr[   r+   Z	interfaceZimplementerZIAuthenticatorÚproviderZIPluginFactoryZPluginr   ÚobjectrE   rX   rh   rƒ   r   r   r   r   Ú<module>   s,   
 W=
	