
    M/eN&                        d 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 ddlmZ ddlmZ ddlmZ ddlmZ erddlmZ  ej4                  e      Z G d dej:                        Zy)z2A class that performs HTTP-01 challenges for Nginx    N)Any)List)Optional)TYPE_CHECKING)
challenges)!KeyAuthorizationChallengeResponse)errors)"KeyAuthorizationAnnotatedChallenge)os)common)nginxparser)Addr)NginxConfiguratorc                        e Zd ZdZd fdZdee   fdZddZdee	   fdZ
dedefdZdedee   fd	Zdedee   fd
Zdedeee      fdZ xZS )NginxHttp01a  HTTP-01 authenticator for Nginx

    :ivar configurator: NginxConfigurator object
    :type configurator: :class:`~nginx.configurator.NginxConfigurator`

    :ivar list achalls: Annotated
        class:`~certbot.achallenges.KeyAuthorizationAnnotatedChallenge`
        challenges

    :param list indices: Meant to hold indices of challenges in a
        larger array. NginxHttp01 is capable of solving many challenges
        at once which causes an indexing issue within NginxConfigurator
        who must return all responses in order. Imagine
        NginxConfigurator maintaining state about where all of the
        challenges, possibly of different types, belong in the response
        array. This is an optional utility.

    returnc                     t         |   |       |  t        j                  j	                  |j
                  j                  d      | _        y )Nzle_http_01_cert_challenge.conf)super__init__r   pathjoinconfig
config_dirchallenge_conf)selfconfigurator	__class__s     A/usr/lib/python3/dist-packages/certbot_nginx/_internal/http_01.pyr   zNginxHttp01.__init__-   s;    & ggll**,LN    c                     | j                   sg S | j                   D cg c]  }|j                  |j                         }}| j                          | j                  j                  dd       |S c c}w )zPerform a challenge on Nginx.

        :returns: list of :class:`acme.challenges.KeyAuthorizationChallengeResponse`
        :rtype: list

        zHTTP ChallengeT)achallsresponseaccount_key_mod_configr   save)r   x	responsess      r   performzNginxHttp01.perform3   sg     ||I8<E1QZZ.E	E 	 	/6 Fs   "A/c                    d}ddd| j                   g}| j                  j                  j                  }g d}| j                  j                  j                  |   }|D ]*  }|d   dgk(  s|d   }||vr|j                  d|       d	} n d}| j                  j                  j                  j                         D ]c  }	|	}|	D ]  }|d   dgk(  s|d   } n t        |      D ]6  \  }
}|d   |d   k(  st        |d         t        |d
         k  r|||
<   d	} n |sc n |s)|D ]$  }|d   dgk(  s|d   }|j                  d|        n |st        j                  d|z        | j                  D cg c]  }| j                  |       }}|D cg c]  }||	 }}t        j                  |      }t        j!                  dt#        |             | j                  j$                  j'                  d	| j                          t)        j*                  | j                   dd      5 }t        j,                  ||       ddd       yc c}w c c}w # 1 sw Y   yxY w)a  Modifies Nginx config to include server_names_hash_bucket_size directive
           and server challenge blocks.

        :raises .MisconfigurationError:
            Unable to find a suitable HTTP block in which to include
            authenticator hosts.
        F
include )r*   server_names_hash_bucket_sizer,   128r   http   T   z;Certbot could not find a block to include challenges in %s.NzGenerated server block:
%swzutf-8)encoding)r   r   parserconfig_rootparsedinsertvalues	enumerateintr	   MisconfigurationErrorr!   _make_or_mod_server_blockr   UnspacedListloggerdebugstrreverterregister_file_creationioopendump)r   includedinclude_directiverootbucket_directivemainlinebodyfound_bucketfile_contentsposn
inner_lineachallr   r&   new_confs                   r   r$   zNginxHttp01._mod_configG   s    !9c43F3FG  ''33N  ''..t4 	DAw6("Aw$D0KK#45	$ !..55<<CCE 	M D% 7vh&7D
 %.dO  ja=$4Q$77:a=)C0@0C,DD%5T
#'L 	"  7vh&7DKK#34	 ..$&*+, , HL||TV$008TT#5q}!55))&12CK@""99$%%	' WWT((#@ 	/HVX.	/ 	/ U5	/ 	/s   2II	I	$IIc                 V   g }d| j                   j                  j                  z  }dj                  | j                   j                  j                        }| j                   j                  j                  }| j                   j	                  t        |            \  }}|rI|s|dz   }t        j                  |      t        j                  |      g}t        j                  d||       n,t        j                  |      g}t        j                  d|       |D cg c]  }|s|	 c}S c c}w )zFinds addresses for a challenge block to listen on.
        :returns: list of :class:`certbot_nginx._internal.obj.Addr` to apply
        :rtype: list
        z%sz[::]:{0}z ipv6only=onz5Using default addresses %s and %s for authentication.z,Using default address %s for authentication.)
r   r   http01_portformat	ipv6_infor@   r   
fromstringr>   r?   )r   	addressesdefault_addr	ipv6_addrportipv6ipv6onlyaddresss           r   _default_listen_addressesz%NginxHttp01._default_listen_addresses   s    
 +-	d//66BBB%%$$002	  ''33**44SY?h%6	635ILLQ$!# 67ILLG$& (1<GG<<<s   D&D&rQ   c                     t         j                  t         j                  j                  t        j
                  j                  |j                  j                  d            z   S )Ntoken)	r   sepr   r   r   HTTP01URI_ROOT_PATHchallencode)r   rQ   s     r   _get_validation_pathz NginxHttp01._get_validation_path   s<    vvZ%6%6%D%DfllFYFYZaFbcccr   c                 \   | j                         }|D cg c]  }dd|j                  d      g }}t        j                  j	                  | j
                  j                  j                  d      }|j                  dd|j                  gdd|g| j                  |      g       dg|gS c c}w )	a  Creates a server block for a challenge.

        :param achall: Annotated HTTP-01 challenge
        :type achall: :class:`certbot.achallenges.KeyAuthorizationAnnotatedChallenge`

        :returns: server block for the challenge host
        :rtype: list
        listenr,   F)include_defaulthttp_01_nonexistentserver_namerH   server)r_   	to_stringr   r   r   r   r   work_dirextenddomain_location_directive_for_achall)r   rQ   addrsaddrblockdocument_roots         r   _make_server_blockzNginxHttp01._make_server_block   s     ..0TYZD(C!FGZZ $$--/DF 	}c6==9sM299&A 	
 
E"" [s   B)c                     |j                  |j                        }| j                  |      }dddd|gg ddddd|ggg}|S )Nlocationr,   =)default_typer,   z
text/plainr   200)
validationr#   rg   )r   rQ   r}   validation_pathlocation_directives        r   rr   z*NginxHttp01._location_directive_for_achall   s^    &&v'9'9:
33F;)3S/JB (#uc:FHI "!r   c                 p   | j                   j                  |j                        \  }}d}|s| j                  |      }t	        ||z         D ]g  }| j                  |      g}| j                   j                  j                  ||       g dg}| j                   j                  j                  ||d       i |S )a|  Modifies server blocks to respond to a challenge. Returns a new HTTP server block
           to add to the configuration if an existing one can't be found.

        :param achall: Annotated HTTP-01 challenge
        :type achall: :class:`certbot.achallenges.KeyAuthorizationAnnotatedChallenge`

        :returns: new server block to be added, if any
        :rtype: list

        N)rewriter,   z!^(/.well-known/acme-challenge/.*)r,   z$1r,   breakT)insert_at_top)r   choose_auth_vhostsrq   rw   setrr   r4   add_server_directives)r   rQ   http_vhostshttps_vhosts	new_vhostvhostr   rewrite_directives           r   r<   z%NginxHttp01._make_or_mod_server_block   s     %)$5$5$H$H$W!\)-	 //7I |34 	>E"&"E"Ef"M!N$$::5BTU"; !<$$::( ; >	> r   )r   r   r   N)r   N)__name__
__module____qualname____doc__r   r   r   r(   r$   r   r_   r
   r@   rg   r   rw   rr   r   r<   __classcell__)r   s   @r   r   r      s    &N?@ (H/T=4: =<d+M dRU d#)K #PTUXPY #."5W ",0I"0R '/S	':r   r   )r   rC   loggingtypingr   r   r   r   acmer   acme.challengesr   certbotr	   certbot.achallengesr
   certbot.compatr   certbot.pluginsr   certbot_nginx._internalr   certbot_nginx._internal.objr   $certbot_nginx._internal.configuratorr   	getLoggerr   r>   ChallengePerformerr    r   r   <module>r      s^    8 	        =  B  " / ,F			8	$Y&++ Yr   