
\\/                 @   s  d  Z  d d l Z d d l Z d d l Z d d l Z d d l 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 m Z m Z m Z 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 e	 j  j! e j"  e	 j  j# e j$  Gd d   d e j%    Z& Gd d   d e j'  Z( Gd d   d e j'  Z) d d   Z* d S)zWebroot plugin.    N)
challenges)DictSetDefaultDictList)achallenges)cli)errors)
interfaces)util)ops)commonc                   s   e  Z d  Z d Z d Z d Z d d   Z e d d    Z d d	   Z	   f d
 d   Z
 d d   Z d d   Z d d   Z d d   Z d d   Z d d d  Z d d   Z d d   Z d d   Z d d    Z   S)!AuthenticatorzWebroot Authenticator.z Place files in webroot directoryzAuthenticator plugin that performs http-01 challenge by saving
necessary validation resources to appropriate paths on the file
system. It expects that there is some other HTTP server configured
to serve all files under specified web root ({0}).c             C   s   |  j  j |  j d   S)Npath)	MORE_INFOformatconf)self r   9/usr/lib/python3/dist-packages/certbot/plugins/webroot.py	more_info,   s    zAuthenticator.more_infoc          	   C   s?   | d d d g  d t  d d | d d i  d t d d d  S)	Nr   z-wdefaultactionhelpa  public_html / webroot path. This can be specified multiple times to handle different domains; each domain will have the webroot path that preceded it.  For instance: `-w /var/www/example -d example.com -d www.example.com -w /var/www/thing -d thing.net -d m.thing.net` (default: Ask)mapa  JSON dictionary mapping domains to webroot paths; this implies -d for each entry. You may need to escape this from your shell. E.g.: --webroot-map '{"eg1.is,m.eg1.is":"/www/eg1/", "eg2.is":"/www/eg2"}' This option is merged with, but takes precedence over, -w / -d entries. At present, if you put webroot-map in a config file, it needs to be on a single line, like: webroot-map = {"example.com":"/var/www"}.)_WebrootPathAction_WebrootMapAction)clsaddr   r   r   add_parser_arguments/   s    z"Authenticator.add_parser_argumentsc             C   s
   t  j g S)N)r   HTTP01)r   domainr   r   r   get_chall_prefA   s    zAuthenticator.get_chall_prefc                sA   t  t |   j | |   i  |  _ t j t  |  _ g  |  _ d  S)N)	superr   __init__
full_rootscollectionsdefaultdictset	performed_created_dirs)r   argskwargs)	__class__r   r   r$   E   s    	zAuthenticator.__init__c             C   s   d  S)Nr   )r   r   r   r   prepareM   s    zAuthenticator.preparec                s.     j  |    j     f d d   | D S)Nc                s   g  |  ] }   j  |   q Sr   )_perform_single).0achall)r   r   r   
<listcomp>U   s   	 z)Authenticator.perform.<locals>.<listcomp>)_set_webroots_create_challenge_dirs)r   achallsr   )r   r   performP   s    
zAuthenticator.performc             C   s  |  j  d  rb |  j  d  d } t j d |  x | D]" } |  j  d  j | j |  q9 Wn t t t j |  j  d     } x | D] } | j |  j  d  k r |  j	 | j |  } y | j
 |  Wn t k
 r Yn X| j d |  | |  j  d  | j <q Wd  S)Nr      z4Using the webroot path %s for all unmatched domains.r   r   )r   loggerinfo
setdefaultr!   listr(   sixZ
itervalues_prompt_for_webrootremove
ValueErrorinsert)r   r5   webroot_pathr1   known_webrootsZnew_webrootr   r   r   r3   W   s"    	#$	zAuthenticator._set_webrootsc             C   se   d  } xX | d  k r` | rK |  j  | |  } | d  k r] |  j |  } q	 |  j | d  } q	 W| S)NT)_prompt_with_webroot_list_prompt_for_new_webroot)r   r!   rC   webrootr   r   r   r>   m   s    z!Authenticator._prompt_for_webrootc             C   s   t  j j t j  } d |  j d  } xu | j d j |  d g | d | d d \ } } | t j	 k r t
 j d   q+ | d	 k r d  S| | d
 Sq+ Wd  S)Nz--r   zSelect the webroot for {0}:zEnter a new webrootZcli_flagforce_interactiveTzIEvery requested domain must have a webroot when using the webroot plugin.r   r7   )zopeZ	componentZ
getUtilityr
   ZIDisplayZoption_nameZmenur   display_utilCANCELr	   PluginError)r   r!   rC   ZdisplayZ	path_flagcodeindexr   r   r   rD   |   s    z'Authenticator._prompt_with_webroot_listFc             C   s`   t  j t d j |  d d \ } } | t j k rR | s@ d  St j d   n
 t |  Sd  S)NzInput the webroot for {0}:rG   TzIEvery requested domain must have a webroot when using the webroot plugin.)r   Zvalidated_directory_validate_webrootr   rI   rJ   r	   rK   )r   r!   Z
allowraiserL   rF   r   r   r   rE      s    z%Authenticator._prompt_for_new_webrootc             C   s  |  j  d  } | s$ t j d   x| j   D]\ } } t j j | t j j	  |  j
 | <t j d |  j
 |  t j d  } z4t j |  } xt t j |  j
 |  d  d  d t D] } y t j | d  |  j j |  y t j | | j | j  WnH t t f k
 rT} z" t j d  t j d	 |  WYd  d  } ~ Xn XWq t k
 r} z; | j t j t j f k rt j d
 j | |    WYd  d  } ~ Xq Xq WWd  t j |  Xq1 Wd  S)Nr   zMissing parts of webroot configuration; please set either --webroot-path and --domains, or --webroot-map. Run with  --help webroot for examples.z-Creating root challenges validation dir at %s   r7   keyi  z3Unable to change owner and uid of webroot directoryzError was: %sz=Couldn't create root for {0} http-01 challenge responses: {1}r8   ) r   r	   rK   itemsosr   joinr   r    ZURI_ROOT_PATHr%   r9   debugumaskstatsortedr   Zget_prefixeslenmkdirr*   appendchownst_uidst_gidOSErrorAttributeErrorr:   errnoZEEXISTZEISDIRr   )r   Zpath_mapnamer   	old_umaskZ	stat_pathprefixZ	exceptionr   r   r   r4      s4    	"	3'*z$Authenticator._create_challenge_dirsc             C   s   t  j j | | j j d   S)Ntoken)rR   r   rS   Zchallencode)r   	root_pathr1   r   r   r   _get_validation_path   s    z"Authenticator._get_validation_pathc             C   s   | j    \ } } |  j | j } |  j | |  } t j d |  t j d  } z0 t | d   } | j	 | j
    Wd  QRXWd  t j |  X|  j | j |  | S)Nz#Attempting to save validation to %srO   wb)Zresponse_and_validationr%   r!   rg   r9   rT   rR   rU   openwritere   r)   r   )r   r1   ZresponseZ
validationrf   validation_pathrb   Zvalidation_filer   r   r   r/      s    zAuthenticator._perform_singlec             C   s,  xu | D]m } |  j  j | j d   } | d  k	 r |  j | |  } t j d |  t j |  |  j | j |  q Wg  } x t	 |  j
  d k r|  j
 j   } y t j |  Wq t k
 r} z5 | j d |  t j d |  t j d |  WYd  d  } ~ Xq Xq W| |  _
 t j d  d  S)NzRemoving %sr   z3Challenge directory %s was not empty, didn't removezError was: %szAll challenges cleaned up)r%   getr!   rg   r9   rT   rR   r?   r)   rX   r*   poprmdirr^   rA   r:   )r   r5   r1   rf   rk   Znot_removedr   excr   r   r   cleanup   s$    '	zAuthenticator.cleanup)__name__
__module____qualname____doc__Zdescriptionr   r   classmethodr   r"   r$   r.   r6   r3   r>   rD   rE   r4   rg   r/   rp   r   r   )r-   r   r      s"   )r   c               @   s%   e  Z d  Z d Z d d d  Z d S)r   z%Action class for parsing webroot_map.Nc                sh   xa t  j t j |   D]G \ }   t      | j j   f d d   t j | |  D  q Wd  S)Nc             3   s   |  ] } |   f Vq d  S)Nr   )r0   d)rB   r   r   	<genexpr>   s    z-_WebrootMapAction.__call__.<locals>.<genexpr>)	r=   Z	iteritemsjsonloadsrN   webroot_mapupdater   Zadd_domains)r   parser	namespacerz   option_stringdomainsr   )rB   r   __call__   s    %	z_WebrootMapAction.__call__)rq   rr   rs   rt   r   r   r   r   r   r      s   r   c                   s7   e  Z d  Z d Z   f d d   Z d d d  Z   S)r   z&Action class for parsing webroot_path.c                s&   t  t |   j | |   d |  _ d  S)NF)r#   r   r$   _domain_before_webroot)r   r+   r,   )r-   r   r   r$      s    z_WebrootPathAction.__init__Nc             C   s   |  j  r t j d   | j rX | j d } x9 | j D] } | j j | |  q8 Wn | j rj d |  _  | j j t |   d  S)NzPIf you specify multiple webroot paths, one of them must precede all domain flagsr7   Tr8   )	r   r	   rK   rB   r   rz   r;   rZ   rN   )r   r|   r}   rB   r~   Zprev_webrootr!   r   r   r   r     s    					z_WebrootPathAction.__call__)rq   rr   rs   rt   r$   r   r   r   )r-   r   r      s   r   c             C   s5   t  j j |   s% t j |  d   t  j j |   S)zValidates and returns the absolute path of webroot_path.

    :param str webroot_path: path to the webroot directory

    :returns: absolute path of webroot_path
    :rtype: str

    z% does not exist or is not a directory)rR   r   isdirr	   rK   abspath)rB   r   r   r   rN     s    	rN   )+rt   argparser&   r`   rx   ZloggingrR   r=   Zzope.componentrH   Zzope.interfaceZacmer   Zacme.magic_typingr   r   r   r   Zcertbotr   r   r	   r
   Zcertbot.displayr   rI   r   Zcertbot.pluginsr   Z	getLoggerrq   r9   Z	interfaceZimplementerZIAuthenticatorZproviderZIPluginFactoryZPluginr   ZActionr   r   rN   r   r   r   r   <module>   s4   "
