ó
Y[c           @   sE  d  Z  d d l Z d d l 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 e j e ƒ Z e	 j j e j ƒ e	 j j e j ƒ d
 e j f d „  ƒ  Yƒ ƒ Z d e f d „  ƒ  YZ  d „  Z! d „  Z" d „  Z# d S(   s*   Common code for DNS Authenticator Plugins.iÿÿÿÿN(   t   sleep(   t
   challenges(   t   errors(   t
   interfaces(   t   ops(   t   util(   t   commont   DNSAuthenticatorc           B   sÈ   e  Z d  Z d „  Z e d d „ ƒ Z d „  Z d „  Z d „  Z d „  Z	 e
 j d „  ƒ Z e
 j d	 „  ƒ Z e
 j d
 „  ƒ Z d „  Z d d „ Z d d d „ Z e d „  ƒ Z e d d „ ƒ Z RS(   s"   Base class for DNS  Authenticatorsc         C   s&   t  t |  ƒ j | | ƒ t |  _ d  S(   N(   t   superR   t   __init__t   Falset   _attempt_cleanup(   t   selft   configt   name(    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/dns_common.pyR	      s    i
   c         C   s    | d d | d t  d d ƒd  S(   Ns   propagation-secondst   defaultt   typet   helpsj   The number of seconds to wait for DNS to propagate before asking the ACME server to verify the DNS record.(   t   int(   t   clst   addt   default_propagation_seconds(    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/dns_common.pyt   add_parser_arguments    s    	c         C   s
   t  j g S(   N(   R   t   DNS01(   R   t   unused_domain(    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/dns_common.pyt   get_chall_pref(   s    c         C   s   d  S(   N(    (   R   (    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/dns_common.pyt   prepare+   s    c         C   s°   |  j  ƒ  t |  _ g  } xd | D]\ } | j } | j | ƒ } | j | j ƒ } |  j | | | ƒ | j | j	 | j ƒ ƒ q  Wt
 j d |  j d ƒ ƒ t |  j d ƒ ƒ | S(   Ns/   Waiting %d seconds for DNS changes to propagates   propagation-seconds(   t   _setup_credentialst   TrueR   t   domaint   validation_domain_namet
   validationt   account_keyt   _performt   appendt   responset   loggert   infot   confR    (   R   t   achallst	   responsest   achallR   R   R   (    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/dns_common.pyt   perform.   s    
			c         C   s^   |  j  rZ xN | D]C } | j } | j | ƒ } | j | j ƒ } |  j | | | ƒ q Wn  d  S(   N(   R   R   R   R   R    t   _cleanup(   R   R'   R)   R   R   R   (    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/dns_common.pyt   cleanupE   s    		c         C   s   t  ƒ  ‚ d S(   s@   
        Establish credentials, prompting if necessary.
        N(   t   NotImplementedError(   R   (    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/dns_common.pyR   N   s    c         C   s   t  ƒ  ‚ d S(   sX  
        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
        N(   R-   (   R   R   R   R   (    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/dns_common.pyR!   U   s    
c         C   s   t  ƒ  ‚ d S(   sX  
        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.
        N(   R-   (   R   R   R   R   (    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/dns_common.pyR+   a   s    c         C   sG   |  j  | ƒ } | sC |  j | ƒ } t |  j |  j | ƒ | ƒ n  d S(   s  
        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&   t   _prompt_for_datat   setattrR   t   dest(   R   t   keyt   labelt   configured_valuet	   new_value(    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/dns_common.pyt
   _configuren   s    
c         C   sb   |  j  | ƒ } | s^ |  j | | ƒ } t |  j |  j | ƒ t j j t j j | ƒ ƒ ƒ n  d S(   s  
        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&   t   _prompt_for_fileR/   R   R0   t   ost   patht   abspatht
   expanduser(   R   R1   R2   t	   validatorR3   R4   (    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/dns_common.pyt   _configure_file~   s    
c            sp   ‡  ‡ ‡ f d †  } ˆ j  | | | ƒ t ˆ j | ƒ ˆ j ƒ } ˆ  rY | j ˆ  ƒ n  ˆ rl ˆ | ƒ n  | S(   sð  
        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( | j ˆ  ƒ n  ˆ r; ˆ | ƒ n  d  S(   N(   t   CredentialsConfigurationR0   t   require(   t   filenamet   configuration(   t   required_variablesR   R;   (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/dns_common.pyt   __validatorŸ   s
    (   R<   R=   R&   R0   R>   (   R   R1   R2   RA   R;   t   _DNSAuthenticator__validatort   credentials_configuration(    (   RA   R   R;   s>   /usr/lib/python2.7/dist-packages/certbot/plugins/dns_common.pyt   _configure_credentialsŽ   s    	c            se   ‡  f d †  } t  j | d j ˆ  ƒ d t ƒ\ } } | t j k rI | St j d j ˆ  ƒ ƒ ‚ d S(   sá   
        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  j d j ˆ  ƒ ƒ ‚ n  d  S(   Ns   Please enter your {0}.(   R   t   PluginErrort   format(   t   i(   R2   (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/dns_common.pyRB   ½   s    s   Input your {0}t   force_interactives   {0} required to proceed.N(   R   t   validated_inputRG   R   t   display_utilt   OKR   RF   (   R2   RC   t   codeR#   (    (   R2   s>   /usr/lib/python2.7/dist-packages/certbot/plugins/dns_common.pyR.   ³   s    
c            sh   ‡  ‡ f d †  } t  j | d j ˆ  ƒ d t ƒ\ } } | t j k rL | St j d j ˆ  ƒ ƒ ‚ d S(   sÃ  
        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            sT   |  s! t  j d j ˆ  ƒ ƒ ‚ n  t j j |  ƒ }  t |  ƒ ˆ rP ˆ |  ƒ n  d  S(   Ns&   Please enter a valid path to your {0}.(   R   RF   RG   R7   R8   R:   t   validate_file(   R?   (   R2   R;   (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/dns_common.pyRB   Ø   s    
s   Input the path to your {0}RI   s   {0} required to proceed.N(   R   t   validated_directoryRG   R   RK   RL   R   RF   (   R2   R;   RC   RM   R#   (    (   R2   R;   s>   /usr/lib/python2.7/dist-packages/certbot/plugins/dns_common.pyR6   Ë   s    N(   t   __name__t
   __module__t   __doc__R	   t   classmethodR   R   R   R*   R,   t   abct   abstractmethodR   R!   R+   R5   t   NoneR<   RE   t   staticmethodR.   R6   (    (    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/dns_common.pyR      s"   							%R=   c           B   sA   e  Z d  Z d „  d „ Z d „  Z d „  Z d „  Z d „  Z RS(   s>   Represents a user-supplied filed which stores API credentials.c         C   s   |  S(   N(    (   t   x(    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/dns_common.pyt   <lambda>ñ   s    c         C   st   t  | ƒ y t j | ƒ |  _ WnD t j k
 rf } t j d | d t ƒt j	 d j
 | ƒ ƒ ‚ n X| |  _ d S(   sö   
        :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.
        s+   Error parsing credentials configuration: %st   exc_infos,   Error parsing credentials configuration: {0}N(   t   validate_file_permissionst	   configobjt	   ConfigObjt   confobjt   ConfigObjErrorR$   t   debugR   R   RF   RG   t   mapper(   R   R?   Ra   t   e(    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/dns_common.pyR	   ñ   s    
c         C   sÙ   g  } x~ | D]v } |  j  | ƒ sK | j d j |  j | ƒ | | ƒ ƒ q |  j | ƒ s | j d j |  j | ƒ | | ƒ ƒ q q W| rÕ t j d j t | ƒ d k r± d n d |  j j	 d j
 | ƒ ƒ ƒ ‚ n  d S(	   sô   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.
        s)   Property "{0}" not found (should be {1}).s'   Property "{0}" not set (should be {1}).s9   Missing {0} in credentials configuration file {1}:
 * {2}i   t   propertyt
   propertiess   
 * N(   t   _hasR"   RG   Ra   t   _getR   RF   t   lenR^   R?   t   join(   R   RA   t   messagest   var(    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/dns_common.pyR>     s    !	c         C   s   |  j  | ƒ S(   sÂ   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
        (   Rf   (   R   Rj   (    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/dns_common.pyR&     s    c         C   s   |  j  | ƒ |  j k S(   N(   Ra   R^   (   R   Rj   (    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/dns_common.pyRe   $  s    c         C   s   |  j  j |  j | ƒ ƒ S(   N(   R^   t   getRa   (   R   Rj   (    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/dns_common.pyRf   '  s    (   RP   RQ   RR   R	   R>   R&   Re   Rf   (    (    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/dns_common.pyR=   î   s   		
	c         C   s^   t  j j |  ƒ s- t j d j |  ƒ ƒ ‚ n  t  j j |  ƒ sZ t j d j |  ƒ ƒ ‚ n  d S(   s&   Ensure that the specified file exists.s   File not found: {0}s   Path is not a file: {0}N(   R7   R8   t   existsR   RF   RG   t   isfile(   R?   (    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/dns_common.pyRN   +  s    c         C   sI   t  |  ƒ t j t j |  ƒ j ƒ } | t j @rE t j d |  ƒ n  d S(   sH   Ensure that the specified file exists and warn about unsafe permissions.s8   Unsafe permissions on credentials configuration file: %sN(   RN   t   statt   S_IMODER7   t   st_modet   S_IRWXOR$   t   warning(   R?   t   permissions(    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/dns_common.pyR[   5  s    
c         C   sB   |  j  d ƒ } g  t d t | ƒ ƒ D] } d j | | ƒ ^ q% S(   sÂ  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
    t   .i    (   t   splitt   rangeRg   Rh   (   R   t	   fragmentsRH   (    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/dns_common.pyt   base_domain_name_guesses?  s    ($   RR   RT   t   loggingR7   Rn   t   timeR    R\   t   zope.interfacet   zopet   acmeR   t   certbotR   R   t   certbot.displayR   R   RK   t   certbot.pluginsR   t	   getLoggerRP   R$   t	   interfacet   implementert   IAuthenticatort   providert   IPluginFactoryt   PluginR   t   objectR=   RN   R[   Rx   (    (    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/dns_common.pyt   <module>   s*   Ö=	
	
