ó
Á£ô_c           @   sM  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 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
   filesystem(   t   os(   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/site-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/site-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/site-packages/certbot/plugins/dns_common.pyt   get_chall_pref(   s    c         C   s   d  S(   N(    (   R   (    (    s>   /usr/lib/python2.7/site-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/site-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/site-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/site-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   t   validation_nameR!   (    (    s>   /usr/lib/python2.7/site-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   R0   R!   (    (    s>   /usr/lib/python2.7/site-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/site-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_fileR2   R   R3   R   t   patht   abspatht
   expanduser(   R   R4   R5   t	   validatorR6   R7   (    (    s>   /usr/lib/python2.7/site-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   CredentialsConfigurationR3   t   require(   t   filenamet   configuration(   t   required_variablesR   R=   (    s>   /usr/lib/python2.7/site-packages/certbot/plugins/dns_common.pyt   __validatorŸ   s
    (   R>   R?   R(   R3   R@   (   R   R4   R5   RC   R=   t   _DNSAuthenticator__validatort   credentials_configuration(    (   RC   R   R=   s>   /usr/lib/python2.7/site-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(   R5   (    s>   /usr/lib/python2.7/site-packages/certbot/plugins/dns_common.pyRD   ½   s    s   Input your {0}t   force_interactives   {0} required to proceed.N(   R   t   validated_inputRI   R   t   display_utilt   OKR   RH   (   R5   RE   t   codeR%   (    (   R5   s>   /usr/lib/python2.7/site-packages/certbot/plugins/dns_common.pyR1   ³   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   RH   RI   R   R:   R<   t   validate_file(   RA   (   R5   R=   (    s>   /usr/lib/python2.7/site-packages/certbot/plugins/dns_common.pyRD   ×   s    
s   Input the path to your {0}RK   s   {0} required to proceed.N(   R   t   validated_directoryRI   R   RM   RN   R   RH   (   R5   R=   RE   RO   R%   (    (   R5   R=   s>   /usr/lib/python2.7/site-packages/certbot/plugins/dns_common.pyR9   Ê   s    N(   t   __name__t
   __module__t   __doc__R   t   classmethodR   R   R   R,   R.   t   abct   abstractmethodR   R#   R-   R8   t   NoneR>   RG   t   staticmethodR1   R9   (    (    (    s>   /usr/lib/python2.7/site-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/site-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   RH   RI   t   mapper(   R   RA   Rc   t   e(    (    s>   /usr/lib/python2.7/site-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$   RI   Rc   t   _getR   RH   t   lenR`   RA   t   join(   R   RC   t   messagest   var(    (    s>   /usr/lib/python2.7/site-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
        (   Rh   (   R   Rl   (    (    s>   /usr/lib/python2.7/site-packages/certbot/plugins/dns_common.pyR(     s    c         C   s   |  j  | ƒ |  j k S(   N(   Rc   R`   (   R   Rl   (    (    s>   /usr/lib/python2.7/site-packages/certbot/plugins/dns_common.pyRg   "  s    c         C   s   |  j  j |  j | ƒ ƒ S(   N(   R`   t   getRc   (   R   Rl   (    (    s>   /usr/lib/python2.7/site-packages/certbot/plugins/dns_common.pyRh   %  s    (   RR   RS   RT   R   R@   R(   Rg   Rh   (    (    (    s>   /usr/lib/python2.7/site-packages/certbot/plugins/dns_common.pyR?   ì   s   		
	c         C   s^   t  j j |  ƒ s- t j d j |  ƒ ƒ ‚ n  t  j j |  ƒ rZ t j d j |  ƒ ƒ ‚ n  d S(   s&   Ensure that the specified file exists.s   File not found: {0}s   Path is a directory: {0}N(   R   R:   t   existsR   RH   RI   t   isdir(   RA   (    (    s>   /usr/lib/python2.7/site-packages/certbot/plugins/dns_common.pyRP   )  s    c         C   s0   t  |  ƒ t j |  ƒ r, 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(   RP   R   t   has_world_permissionsR&   t   warning(   RA   (    (    s>   /usr/lib/python2.7/site-packages/certbot/plugins/dns_common.pyR]   3  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   rangeRi   Rj   (   R   t	   fragmentsRJ   (    (    s>   /usr/lib/python2.7/site-packages/certbot/plugins/dns_common.pyt   base_domain_name_guesses<  s    (%   RT   RV   t   loggingt   timeR    R^   t   zope.interfacet   zopet   acmeR   t   certbotR   R   t   certbot.compatR   R   t   certbot.displayR   R   RM   t   certbot.pluginsR   t	   getLoggerRR   R&   t	   interfacet   implementert   IAuthenticatort   providert   IPluginFactoryt   PluginR	   t   objectR?   RP   R]   Rv   (    (    (    s>   /usr/lib/python2.7/site-packages/certbot/plugins/dns_common.pyt   <module>   s*   Ô=	
		