ó
Y[c           @   sÁ  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	 Z
 d d l m Z d d l m Z d d l m Z m Z m Z 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 e j e ƒ Z e r0e e j  e e j! f Z" n  d e# f d „  ƒ  YZ$ e j% e j& g Z' d e j( f d „  ƒ  YZ) e
 j* j+ e j, ƒ e
 j* j- e j. ƒ d e j/ f d „  ƒ  Yƒ ƒ Z0 d „  Z1 d S(   s   Standalone Authenticator.iÿÿÿÿN(   t   errno(   t
   challenges(   t
   standalone(   t   DefaultDictt   Dictt   Sett   Tuplet   Listt   Typet   TYPE_CHECKING(   t   achallenges(   t   errors(   t
   interfaces(   t   commont   ServerManagerc           B   s5   e  Z d  Z d „  Z d d „ Z d „  Z d „  Z RS(   s§  Standalone servers manager.

    Manager for `ACMEServer` and `ACMETLSServer` instances.

    `certs` and `http_01_resources` correspond to
    `acme.crypto_util.SSLSocket.certs` and
    `acme.crypto_util.SSLSocket.http_01_resources` respectively. All
    created servers share the same certificates and resources, so if
    you're running both TLS and non-TLS instances, HTTP01 handlers
    will serve the same URLs!

    c         C   s   i  |  _  | |  _ | |  _ d  S(   N(   t
   _instancest   certst   http_01_resources(   t   selfR   R   (    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/standalone.pyt   __init__-   s    		t    c         C   sÞ   | t  j t  j f k s t ‚ | |  j k r8 |  j | S| | f } y@ | t  j k rn t j | |  j ƒ } n t j | |  j	 ƒ } Wn( t
 j k
 r® } t j | | ƒ ‚ n X| j ƒ  | j ƒ  d d } | |  j | <| S(   s,  Run ACME server on specified ``port``.

        This method is idempotent, i.e. all calls with the same pair of
        ``(port, challenge_type)`` will reuse the same server.

        :param int port: Port to run the server on.
        :param challenge_type: Subclass of `acme.challenges.Challenge`,
            either `acme.challenge.HTTP01` or `acme.challenges.TLSSNI01`.
        :param str listenaddr: (optional) The address to listen on. Defaults to all addrs.

        :returns: DualNetworkedServers instance.
        :rtype: ACMEServerMixin

        i    i   (   R   t   TLSSNI01t   HTTP01t   AssertionErrorR   t   acme_standalonet   TLSSNI01DualNetworkedServersR   t   HTTP01DualNetworkedServersR   t   sockett   errorR   t   StandaloneBindErrort   serve_forevert   getsocknames(   R   t   portt   challenge_typet
   listenaddrt   addresst   serversR   t	   real_port(    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/standalone.pyt   run2   s     
c         C   sP   |  j  | } x( | j ƒ  D] } t j d | d  Œ q W| j ƒ  |  j  | =d S(   sW   Stop ACME server running on the specified ``port``.

        :param int port:

        s   Stopping server at %s:%d...i   N(   R   R   t   loggert   debugt   shutdown_and_server_close(   R   R    t   instancet   sockname(    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/standalone.pyt   stopY   s    	
c         C   s   |  j  j ƒ  S(   sÉ   Return all running instances.

        Once the server is stopped using `stop`, it will not be
        returned.

        :returns: Mapping from ``port`` to ``servers``.
        :rtype: tuple

        (   R   t   copy(   R   (    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/standalone.pyt   runningh   s    
(   t   __name__t
   __module__t   __doc__R   R&   R,   R.   (    (    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/standalone.pyR       s
   	'	t   SupportedChallengesActionc           B   s#   e  Z d  Z d d „ Z d „  Z RS(   s9   Action class for parsing standalone_supported_challenges.c         C   s)   t  j d ƒ |  j | ƒ } | | _ d  S(   Nst   The standalone specific supported challenges flag is deprecated. Please use the --preferred-challenges flag instead.(   R'   t   warningt   _convert_and_validatet   standalone_supported_challenges(   R   t   parsert	   namespacet   valuest   option_stringt   converted_values(    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/standalone.pyt   __call__|   s    c         C   s#  | j  d ƒ } d | k rk t j d ƒ g  | D]$ } | d k rM t j j n | ^ q/ } d j | ƒ } n  g  | D] } | t j j k rr | ^ qr } | rÃ t	 j
 |  d j d j | ƒ ƒ ƒ ‚ n  t d „  t Dƒ ƒ } t | ƒ j | ƒ st	 j
 |  d j d j t | ƒ | ƒ ƒ ƒ ‚ n  | S(   s/  Validate the value of supported challenges provided by the user.

        References to "dvsni" are automatically converted to "tls-sni-01".

        :param str data: comma delimited list of challenge types

        :returns: validated and converted list of challenge types
        :rtype: str

        t   ,t   dvsnis5   Updating legacy standalone_supported_challenges values   Unrecognized challenges: {0}s   , c         s   s   |  ] } | j  Vq d  S(   N(   t   typ(   t   .0t   chall(    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/standalone.pys	   <genexpr>¤   s    s=   Plugin does not support the following (valid) challenges: {0}(   t   splitR'   t   infoR   R   R>   t   joint	   Challenget   TYPESt   argparset   ArgumentErrort   formatt   sett   SUPPORTED_CHALLENGESt   issubset(   R   t   datat   challsR@   t   namet   unrecognizedt   choices(    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/standalone.pyR4   „   s(    ."N(   R/   R0   R1   t   NoneR;   R4   (    (    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/standalone.pyR2   y   s   t   Authenticatorc           B   sŒ   e  Z d  Z d Z d „  Z e d „  ƒ Z e d „  ƒ Z d „  Z	 d „  Z
 d „  Z d „  Z d	 „  Z d
 „  Z d „  Z d „  Z d „  Z RS(   s  Standalone Authenticator.

    This authenticator creates its own ephemeral TCP listener on the
    necessary port in order to respond to incoming tls-sni-01 and http-01
    challenges from the certificate authority. Therefore, it does not
    rely on any existing server program.
    s   Spin up a temporary webserverc         O   s‡   t  t |  ƒ j | | Ž  t j j ƒ  |  _ |  j j t j j d ƒ t	 j
 t ƒ |  _ i  |  _ t ƒ  |  _ t |  j |  j ƒ |  _ d  S(   Ni   (   t   superRR   R   t   OpenSSLt   cryptot   PKeyt   keyt   generate_keyt   TYPE_RSAt   collectionst   defaultdictRI   t   servedR   R   R   R$   (   R   t   argst   kwargs(    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/standalone.pyR   »   s    	c      
   C   s6   | d d t  j d t d d j d „  t Dƒ ƒ ƒd  S(   Ns   supported-challengest   helpt   actiont   defaultR<   c         s   s   |  ] } | j  Vq d  S(   N(   R>   (   R?   R@   (    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/standalone.pys	   <genexpr>Ó   s    (   RF   t   SUPPRESSR2   RC   RJ   (   t   clst   add(    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/standalone.pyt   add_parser_argumentsÎ   s    		c         C   s3   g  |  j  d ƒ j d ƒ D] } t j j | ^ q S(   s$   Challenges supported by this plugin.s   supported-challengesR<   (   t   confRA   R   RD   RE   (   R   RN   (    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/standalone.pyt   supported_challengesÕ   s    c         C   s   d S(   Nsí   This authenticator creates its own ephemeral TCP listener on the necessary port in order to respond to incoming tls-sni-01 and http-01 challenges from the certificate authority. Therefore, it does not rely on any existing server program.(    (   R   (    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/standalone.pyt	   more_infoÛ   s    c         C   s   d  S(   N(    (   R   (    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/standalone.pyt   prepareâ   s    c         C   s   |  j  S(   N(   Rg   (   R   t   domain(    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/standalone.pyt   get_chall_prefå   s    c         C   s    g  | D] } |  j  | ƒ ^ q S(   N(   t   _try_perform_single(   R   t   achallst   achall(    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/standalone.pyt   performé   s    c         C   sE   x> t  r@ y |  j | ƒ SWq t j k
 r< } t | ƒ q Xq Wd  S(   N(   t   Truet   _perform_singleR   R   t   _handle_perform_error(   R   Rn   R   (    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/standalone.pyRl   ì   s
    	c         C   sZ   t  | j t j ƒ r- |  j | ƒ \ } } n |  j | ƒ \ } } |  j | j | ƒ | S(   N(   t
   isinstanceR@   R   R   t   _perform_http_01t   _perform_tls_sni_01R\   Rd   (   R   Rn   R$   t   response(    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/standalone.pyRq   ó   s
    c         C   s†   |  j  j } |  j  j } |  j j | t j d | ƒ} | j ƒ  \ } } t j	 j
 d | j d | d | ƒ } |  j j | ƒ | | f S(   NR"   R@   Rv   t
   validation(   t   configt   http01_portt   http01_addressR$   R&   R   R   t   response_and_validationR   t   HTTP01RequestHandlert   HTTP01ResourceR@   R   Rd   (   R   Rn   R    t   addrR$   Rv   Rw   t   resource(    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/standalone.pyRt   û   s    c         C   sz   |  j  j } |  j  j } |  j j | t j d | ƒ} | j d |  j ƒ \ } \ } } |  j | f |  j	 | j
 <| | f S(   NR"   t   cert_key(   Rx   t   tls_sni_01_portt   tls_sni_01_addressR$   R&   R   R   R{   RW   R   t   z_domain(   R   Rn   R    R~   R$   Rv   t   certt   _(    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/standalone.pyRu     s    !c         C   sš   xJ |  j  j ƒ  D]9 \ } } x* | D]" } | | k r# | j | ƒ q# q# Wq WxF t j |  j j ƒ  ƒ D], \ } } |  j  | sf |  j j | ƒ qf qf Wd  S(   N(   R\   t   itemst   removet   sixt	   iteritemsR$   R.   R,   (   R   Rm   t   unused_serverst   server_achallsRn   R    R$   (    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/standalone.pyt   cleanup  s    %(   R/   R0   R1   t   descriptionR   t   classmethodRe   t   propertyRg   Rh   Ri   Rk   Ro   Rl   Rq   Rt   Ru   RŒ   (    (    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/standalone.pyRR   ®   s   									
	c         C   s¬   |  j  j t j k r3 t j d j |  j ƒ ƒ ‚ nu |  j  j t j k r¥ t	 j
 j t j ƒ } d j |  j ƒ } | j | d d d t ƒ} | s¨ t j | ƒ ‚ q¨ n ‚  d  S(   Ns†   Could not bind TCP port {0} because you don't have the appropriate permissions (for example, you aren't running this program as root).sª   Could not bind TCP port {0} because it is already in use by another process on this system (such as a web server). Please stop the program in question and then try again.t   Retryt   CancelRa   (   t   socket_errorR    t   socket_errorst   EACCESR   t   PluginErrorRH   R    t
   EADDRINUSEt   zopet	   componentt
   getUtilityR   t   IDisplayt   yesnot   False(   R   t   displayt   msgt   should_retry(    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/standalone.pyRr     s    (2   R1   RF   RZ   t   loggingR   R    R“   RT   Rˆ   t   zope.interfaceR—   t   acmeR   R   R   t   acme.magic_typingR   R   R   R   R   R   R	   t   certbotR
   R   R   t   certbot.pluginsR   t	   getLoggerR/   R'   t   BaseDualNetworkedServerst"   KeyAuthorizationAnnotatedChallenget
   ServedTypet   objectR   R   R   RJ   t   ActionR2   t	   interfacet   implementert   IAuthenticatort   providert   IPluginFactoryt   PluginRR   Rr   (    (    (    s>   /usr/lib/python2.7/dist-packages/certbot/plugins/standalone.pyt   <module>   s6   4U5h