
    M/e                         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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 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  ej<                  e      Z  G d d      Z!dee"   dee   fdZ#	 dHdee   de	ee   ge$f   de	ee   ee%   gdf   deee%      ddf
dZ&de"dee"   deee"   ee"   f   fd Z'de"d!e"de$fd"Z(de"d!e"d#e$de$fd$Z)de"d!e"de$fd%Z*dede$fd&Z+dede$fd'Z,d(ee   d)e$d*eddfd+Z-d(ee   d)e$d*eddfd,Z.d-Z/d.d/e/d0d1hZ0d2Z1d3d4e1gZ2d*ed5e%ddfd6Z3d*ed5e%d7e"ddfd8Z4	 dHd*ed9e"d:ee	ege$f      dee%   fd;Z5d<ee   de$fd=Z6d*ed<ee   d)e$ddfd>Z7d*ed<ee   d5e%ddfd?Z8d*ed<ee   d)e$ddfd@Z9d<ee   de$fdAZ:d9e"d:e	ege$f   d*eddfdBZ;dCeee"e"f   e$f   dDee"ef   ddfdEZ<dFedee"ef   fdGZ=y)Iz>NginxParser is a member object of the NginxConfigurator class.    N)Any)Callable)cast)Dict)Iterable)List)Mapping)Optional)Sequence)Set)Tuple)Union)errors)os)nginxparser)obj)UnspacedListc            
          e Zd ZdZdeddfdZd+dZdeddfdZd	edefd
Zde	e
eef   ef   fdZde	eeee   ef   f   fdZdeej&                     fdZdeej&                     ddfdZdedefdZd,dededee   fdZdefdZd-dededdfdZdede	eef   fdZdej&                  defdZ	 d,dej&                  dee   deddfdZ	 d,dej&                  dee   deddfdZ	 d.dej&                  d ed!ee egef      ddfd"Z!dej&                  d#eddfd$Z"dej&                  d%e ee   gdf   ddfd&Z#	 	 d/d'ej&                  d(ed)eee      dej&                  fd*Z$y)0NginxParserzClass handles the fine details of parsing the Nginx Configuration.

    :ivar str root: Normalized absolute path to the server root
        directory. Without trailing slash.
    :ivar dict parsed: Mapping of file paths to parsed trees

    rootreturnNc                     i | _         t        j                  j                  |      | _        | j                         | _        | j                          y N)parsedr   pathabspathr   _find_config_rootconfig_rootload)selfr   s     @/usr/lib/python3/dist-packages/certbot_nginx/_internal/parser.py__init__zNginxParser.__init__)   s9    /1GGOOD)	113
 			    c                 H    i | _         | j                  | j                         y)z/Loads Nginx files into a parsed tree.

        N)r   _parse_recursivelyr   )r    s    r!   r   zNginxParser.load3   s      0 01r#   filepathc                    | j                  |      }| j                  |      }|D ]  }|D ]  }t        |      r| j                  |d          #|d   dgk(  s
|d   dgk(  s6|d   D ]`  }t        |      r| j                  |d          #|d   dgk(  s-|d   dgk(  s7|d   D ]"  }t        |      s| j                  |d          $ b   y)a  Parses nginx config files recursively by looking at 'include'
        directives inside 'http' and 'server' blocks. Note that this only
        reads Nginx files that potentially declare a virtual host.

        :param str filepath: The path to the files to parse, as a glob

           r   httpserverN)abs_path_parse_files_is_include_directiver%   )r    r&   treestreeentrysubentryserver_entrys          r!   r%   zNginxParser._parse_recursively:   s     ==*!!(+ 	MD M(/++E!H51X&)U1X(-C$)!H M0: 33HQK@"1X&1hqkhZ6O 19 M#8#F$($;$;LO$LMMM	Mr#   r   c                    t         j                  j                  |      sGt         j                  j                  t         j                  j	                  | j
                  |            S t         j                  j                  |      S )zConverts a relative path to an absolute path relative to the root.
        Does nothing for paths that are already absolute.

        :param str path: The path
        :returns: The absolute path
        :rtype: str

        )r   r   isabsnormpathjoinr   )r    r   s     r!   r+   zNginxParser.abs_pathV   sQ     ww}}T"77##BGGLLD$ABBww%%r#   c                    | j                         }i }|j                         D ]Z  }|D ]S  \  }}t        |      }|d   D ];  }|j                         }||vr|j                  ||<   |j                  xs ||   ||<   = U \ |S )zSBuilds a map from address to whether it listens on ssl in any server block
        addrs)_get_raw_serversvalues_parse_server_rawnormalized_tuplessl)	r    serversaddr_to_sslserver_listr*   _parsed_serveraddr
addr_tuples	            r!   _build_addr_to_sslzNginxParser._build_addr_to_sslc   s     '')35">>+ 	RK( R	 1& 9)'2 RD!%!6!6!8J!426((J/.2hh.Q+j:QK
+	RR	R r#   c                     i }| j                   j                         D ]T  \  }}g ||<   ||   t        |d fd       t        ||         D ]#  \  }\  }}| j	                  |      }||f||   |<   % V |S )z0Get a map of unparsed all server blocks
        c                 4    t        |       dk\  xr	 | d   dgk(  S )N   r   r*   len)xs    r!   <lambda>z.NginxParser._get_raw_servers.<locals>.<lambda>~   s    SVq[-OQqThZ=O r#   c                 0    j                  | d   |f      S )Nr(   )append)rK   ysrvs     r!   rL   z.NginxParser._get_raw_servers.<locals>.<lambda>   s    #**adAY*? r#   )r   items_do_for_subarray	enumerate_get_included_directives)	r    r>   filenamer/   ir*   r   
new_serverrP   s	           @r!   r9   zNginxParser._get_raw_serverst   s     JL"kk//1 	:NHd "GH(#C T#O?A &/wx/@%A :!>FD!::6B
(2D'9!!$:	: r#   c                    d}| j                         }g }|j                         D ]O  \  }}|D ]E  \  }}t        |      }t        j                  ||d   |d   ||d   ||      }	|j                  |	       G Q | j                  |       |S )aG  Gets list of all 'virtual hosts' found in Nginx configuration.
        Technically this is a misnomer because Nginx does not have virtual
        hosts, it has 'server blocks'.

        :returns: List of :class:`~certbot_nginx._internal.obj.VirtualHost`
            objects found in configuration
        :rtype: list

        Tr8   r=   names)r9   rQ   r;   r   VirtualHostrN   _update_vhosts_addrs_ssl)
r    enabledr>   vhostsrU   r@   r*   r   rB   vhosts
             r!   
get_vhostszNginxParser.get_vhosts   s     '')%,]]_ 	%!Hk + % !2& 9(5g(>(5e(<(/(5g(>(.(,. e$%	% 	%%f-r#   r]   c                     | j                         }|D ]?  }|j                  D ].  }||j                            |_        |j                  s(d|_        0 A y)zPUpdate a list of raw parsed vhosts to include global address sslishness
        TN)rE   r8   r<   r=   )r    r]   r?   r^   rC   s        r!   r[   z$NginxParser._update_vhosts_addrs_ssl   sW     --/ 	%E %&t'<'<'>?88 $EI%	%r#   blockc                    t        j                  |      }|D ][  }t        |      st        j                  | j	                  |d               }|D ]!  }	 |j                  | j                  |          # ] |S # t        $ r Y 3w xY w)zReturns array with the "include" directives expanded out by
        concatenating the contents of the included file to the block.

        :param list block:
        :rtype: list

        r(   )copydeepcopyr-   globr+   extendr   KeyError)r    ra   result	directiveincluded_filesincls         r!   rT   z$NginxParser._get_included_directives   s     u% 	I$Y/!%MM)A,/"1* Ddkk$&78		  $ s   A88	BBoverridec                    t        j                   |      }g }|D ]j  }|| j                  v r|s	 t        j                  |dd      5 }t	        j
                  |      }|| j                  |<   |j                  |       ddd       l |S # 1 sw Y   xY w# t        $ r t        j                  d|       Y t        $ r t        j                  d|       Y t        j                  $ r!}t        j                  d||       Y d}~d}~ww xY w)zParse files from a glob

        :param str filepath: Nginx config file path
        :param bool override: Whether to parse a file that has been parsed
        :returns: list of parsed tree structures
        :rtype: list

        rutf-8encodingNzCould not open file: %sSCould not read file: %s due to invalid character. Only UTF-8 encoding is supported."Could not parse file: %s due to %s)re   r   ioopenr   r   rN   IOErrorloggerwarningUnicodeDecodeError	pyparsingParseException)	r    r&   rl   filesr.   item_filer   errs	            r!   r,   zNginxParser._parse_files   s     		(#  	PDt{{"8PWWT39 )U(--e4F(.DKK%LL()		P  ) )  @8$?% 3  ,-13 ++ PCT3OOPs;   B6B	=B	B	BD	6D	D	(DD	c                 &   dg}|D ]u  }t         j                  j                  t         j                  j                  | j                  |            sKt         j                  j                  | j                  |      c S  t        j                  d      )z)Return the Nginx Configuration Root file.z
nginx.confz9Could not find Nginx root configuration file (nginx.conf))r   r   isfiler6   r   r   NoInstallationError)r    locationnames      r!   r   zNginxParser._find_config_root   sn     > 	5Dww~~bggll499d;<ww||DIIt44	5 ((GI 	Ir#   extlazyc                    | j                   j                         D ]  \  }}|r |t        j                  j                  z   |z   }t        |t              st        d| d      	 |r|j                         s[t        j                  |      }t        j                  d||       t        j                  |dd      5 }|j                  |       ddd        y# 1 sw Y   xY w# t         $ r t        j#                  d|       Y w xY w)	zDumps parsed configurations into files.

        :param str ext: The file extension to use for the dumped files. If
            empty, this overrides the existing conf files.
        :param bool lazy: Only write files that have been modified

        zError tree z is not an UnspacedListz!Writing nginx conf tree to %s:
%swro   rp   Nz#Could not open file for writing: %s)r   rQ   r   r   extsep
isinstancer   
ValueErroris_dirtyr   dumpsrw   debugrt   ru   writerv   error)r    r   r   rU   r/   outr~   s          r!   filedumpzNginxParser.filedump   s     #kk//1 	NNHd#bggnn4s:dL1 ;tf4K!LMM	N!''-A8SQWWXsW= %KK$%	N% %  NBHMNs1   #C#6AC#:CC#C 	C##DDr*   c                 T    | j                         }t        |      }t        ||       |S )zParses a list of server directives, accounting for global address sslishness.

        :param list server: list of directives in a server block
        :rtype: dict
        )rE   r;   _apply_global_addr_ssl)r    r*   r?   rB   s       r!   parse_serverzNginxParser.parse_server  s,     --/)&1{M:r#   r^   c                 J    |j                   }|D ]  }|st        |      s y y)zDoes vhost have ssl on for all ports?

        :param :class:`~certbot_nginx._internal.obj.VirtualHost` vhost: The vhost in question

        :returns: True if 'ssl on' directive is included
        :rtype: bool

        TF)raw_is_ssl_on_directive)r    r^   r*   ri   s       r!   has_ssl_on_directivez NginxParser.has_ssl_on_directive  s2      	I#I.		 r#   
directivesinsert_at_topc                 Z    | j                  |t        j                  t        ||             y)a  Add directives to the server block identified by vhost.

        This method modifies vhost to be fully consistent with the new directives.

        ..note :: It's an error to try and add a nonrepeatable directive that already
            exists in the config block with a conflicting value.

        ..todo :: Doesn't match server blocks whose server_name directives are
            split across multiple conf files.

        :param :class:`~certbot_nginx._internal.obj.VirtualHost` vhost: The vhost
            whose information we use to match on
        :param list directives: The directives to add
        :param bool insert_at_top: True if the directives need to be inserted at the top
            of the server block instead of the bottom

        N)_modify_server_directives	functoolspartial_add_directivesr    r^   r   r   s       r!   add_server_directivesz!NginxParser.add_server_directives%  s'    & 	&&uoz=I	Kr#   c                 Z    | j                  |t        j                  t        ||             y)a\  Add or replace directives in the server block identified by vhost.

        This method modifies vhost to be fully consistent with the new directives.

        ..note :: When a directive with the same name already exists in the
        config block, the first instance will be replaced. Otherwise, the directive
        will be appended/prepended to the config block as in add_server_directives.

        ..todo :: Doesn't match server blocks whose server_name directives are
            split across multiple conf files.

        :param :class:`~certbot_nginx._internal.obj.VirtualHost` vhost: The vhost
            whose information we use to match on
        :param list directives: The directives to add
        :param bool insert_at_top: True if the directives need to be inserted at the top
            of the server block instead of the bottom

        N)r   r   r   _update_or_add_directivesr   s       r!   update_or_add_server_directivesz+NginxParser.update_or_add_server_directives;  s(    ( 	&&u7]S	Ur#   directive_name
match_funcc                 Z    | j                  |t        j                  t        ||             y)al  Remove all directives of type directive_name.

        :param :class:`~certbot_nginx._internal.obj.VirtualHost` vhost: The vhost
            to remove directives from
        :param string directive_name: The directive type to remove
        :param callable match_func: Function of the directive that returns true for directives
            to be deleted.
        N)r   r   r   _remove_directives)r    r^   r   r   s       r!   remove_server_directivesz$NginxParser.remove_server_directivesR  s(     	&&u0.*M	Or#   directives_listc                     | j                  |      }| j                  |      }|d   |_        |d   |_        |d   |_        ||_        y )Nr8   r=   rY   )rT   r   r8   r=   rY   r   )r    r^   r   rW   rB   s        r!   %_update_vhost_based_on_new_directivesz1NginxParser._update_vhost_based_on_new_directives_  sM    22?C
))*5#G,!%(	#G,	r#   
block_funcc           	         |j                   }	 | j                  |   }|j                  D ]  }||   }	 t        |t              rt        |      dk7  rt        j                  d      |d   } ||       | j                  ||       y # t        j                  $ r)}t        j                  d|dt        |            d }~ww xY w)NrH   zNot a server block.r(   zProblem in z: )
filepr   r   r   listrJ   r   MisconfigurationErrorr   str)r    r^   r   rU   rh   indexr   s          r!   r   z%NginxParser._modify_server_directivesh  s    ;;	[[[*F ''fd+s6{a/?223HIIAYFv66ufE++ 	[..hPSTWPX/YZZ	[s   A7B C$B==Cvhost_templateremove_singleton_listen_paramsonly_directivesc                    t        j                  |      }| j                  |j                     }|j                  dd D ]  }||   }	 t        j                  ||j                  d            }|Rt        j                  g       }|d   D ]  }	|	s|	d   |v s|j                  |	         ||d<   | j                  ||       |j                  |       t        |      dz
  |j                  d<   |r|j                  D ]  }
d|
_        d|
_         ||j                  d      d   D ]Q  }	|	s|	d   dk(  sh d}|D ]:  }|	D cg c]  }|j                  d      d    }}||v s)|	|j                  |      = < S |S c c}w )	a  Duplicate the vhost in the configuration files.

        :param :class:`~certbot_nginx._internal.obj.VirtualHost` vhost_template: The vhost
            whose information we copy
        :param bool remove_singleton_listen_params: If we should remove parameters
            from listen directives in the block that can only be used once per address
        :param list only_directives: If it exists, only duplicate the named directives. Only
            looks at first level of depth; does not expand includes.

        :returns: A vhost object for the newly created vhost
        :rtype: :class:`~certbot_nginx._internal.obj.VirtualHost`
        Nr(   r   Flisten>   bindrcvbufsetfibsndbufbacklogdefaultdeferredfastopenipv6only	reuseportso_keepaliveaccept_filterdefault_server=)rc   rd   r   r   r   r   r   rN   r   rJ   r8   r   r   splitr   )r    r   r   r   	new_vhostenclosing_blockr   raw_in_parsednew_directivesri   rC   excludeparamrK   keyss                  r!   duplicate_vhostzNginxParser.duplicate_vhostx  s   " MM.1	++n&:&:;#(("- 	5E-e4O	5on6I6I"6M&NO&(55b9N*1- 5	1!@")))45  .M!66y.Q}- 1A5	r)! &$ %& -Y^^B-?@C =	1!9LG ") =9BCAQCC D= )$**U*; <	==   Ds   ?E9)r   N)F)tmpTr   )FN)%__name__
__module____qualname____doc__r   r"   r   r%   r+   r   r   boolrE   r   r   r   r   r9   r   rZ   r_   r   r[   rT   r,   r   r   r   r   r   r   r
   r   r   r   r   r    r#   r!   r   r       s   S T 2M3 M4 M8&S &S &DsCx$)>$? "$sE$s)\2I,J'J"K &D1 @%x/H %T %l | (S D T,EW >	I3 	INC Nt Nt N2	< 	DcN 	#// d & 5:K3?? KS	 K-1K>BK. ?DUS__ URVWZR[ U7;UHLU0 PTOcoo Os O-5hud{6K-LOX\O3?? ?KPT[s [.6S	{D7H.I[NR[" @E?C4coo 48<4)1$s))<4HK4r#   r   ssl_optionsr   c                    | 8	 t        j                  | dd      5 }t        j                  |      cd d d        S t        g       S # 1 sw Y   nxY w	 t        g       S # t        $ r# t
        j                  d|        Y t        g       S t        $ r# t
        j                  d|        Y t        g       S t        j                  $ r+}t
        j                  d| |       Y d }~t        g       S d }~ww xY w)Nrn   ro   rp   z"Missing NGINX TLS options file: %srr   rs   )rt   ru   r   r   rv   rw   rx   ry   rz   ParseBaseExceptionr   )r   r~   r   s      r!   _parse_ssl_optionsr     s    		ScG< /"''./ / / / /   	NNN?M  " 	MNN ?@KM  ++ 	SNN?cRR	Ss9   A A	A AA C0	C03C0C++C0r0   	conditionfuncr   c                     |g }t        | t              r8 ||       r
 || |       yt        |       D ]  \  }}t        |||||gz           yy)a(  Executes a function for a subarray of a nested array if it matches
    the given condition.

    :param list entry: The list to iterate over
    :param function condition: Returns true iff func should be executed on item
    :param function func: The function to call for each matching item

    N)r   r   rS   rR   )r0   r   r   r   r   r}   s         r!   rR   rR     s]     |%U(/ Ht y$wGH	 r#   target_namerY   c                    g }g }g }g }|D ]|  }t        | |      r|j                  |       !t        | |d      r|j                  |       @t        | |d      r|j                  |       _t        | |      sl|j                  |       ~ |rt	        |t
              }d|fS |rt        |t
              }d|fS |rt        |t
              }d|fS |r	|d   }d|fS y	)
ah  Finds the best match for target_name out of names using the Nginx
    name-matching rules (exact > longest wildcard starting with * >
    longest wildcard ending with * > regex).

    :param str target_name: The name to match
    :param set names: The candidate server names
    :returns: Tuple of (type of match, the name that matched)
    :rtype: tuple

    TF)keyexactwildcard_startwildcard_endr   regex)NN)_exact_matchrN   _wildcard_match_regex_matchminrJ   max)r   rY   r   r   r   r   r   matchs           r!   get_best_matchr     s     ENLE T*LL[$5!!$'[$6%+t,LL Es#~N,&&Lc*u$$a~r#   r   c                 P    | j                         }|j                         |d|z   fv S )N.)lower)r   r   target_lowers      r!   r   r     s+    $$&L::<L#*<===r#   startc                 f   |dk(  ry| j                  d      }|j                  d      }|s |j                          |j                          |j                  d      }|dvrydj                  |      j	                         }dj                  |      j	                         }|j                  d|z         S )N*Tr   r   )r    F)r   reversepopr6   r   endswith)r   r   r   partsmatch_partsfirsttarget_name_lower
name_lowers           r!   r   r     s    s{c"E**S/K  OOAEI--/+&,,.J %%cJ&677r#   c                     t        |      dk  s|d   dk7  ry	 t        j                  |dd        }t        t        j                  ||             S # t        j
                  $ r Y yw xY w)NrH   r   ~Fr(   )rJ   recompiler   r   r   )r   r   r   s      r!   r   r     s_    
4y1}Q3

48$BHHUK01188 s   6A A&%A&c                     t        | t              xr- t        |       dk(  xr | d   dk(  xr t        | d   t              S )zChecks if an nginx parsed entry is an 'include' directive.

    :param list entry: the parsed entry
    :returns: Whether it's an 'include' directive
    :rtype: bool

    rH   r   includer(   )r   r   rJ   r   r0   s    r!   r-   r-   -  sG     ud# &J!O& %aI 5&uQx%'r#   c                 j    t        | t              xr" t        |       dk(  xr | d   dk(  xr | d   dk(  S )zChecks if an nginx parsed entry is an 'ssl on' directive.

    :param list entry: the parsed entry
    :returns: Whether it's an 'ssl on' directive
    :rtype: bool

    rH   r   r=   r(   on)r   r   rJ   r  s    r!   r   r   :  sE     ud# J!O %aE 1!Hr#   r   r   ra   c                     | D ]  }t        |||        |r-d|d   vr%|j                  t        j                  d             yyy)z"Adds directives to a config block.
r   N)_add_directiverN   r   r   r   r   ra   ri   s       r!   r   r   G  sK       8	ui78U2Y&[--d34 'ur#   c                     | D ]  }t        |||        |r-d|d   vr%|j                  t        j                  d             yyy)z.Adds or replaces directives in a config block.r  r   N)_update_or_add_directiverN   r   r   r
  s       r!   r   r   P  sM       B	 	=ABU2Y&[--d34 'ur#   r  server_namer   rewrite
add_headerz managed by Certbot #r   c                 r   |dz   t        |       k  r| |dz      nd}t        |t              rS|rQt        |      dk\  r|d   dk(  rt        |d   v ryt        |t        j
                        r|j                  d   }n|d   }| j                  |dz   t        dd        |d|vr| j                  |dz   d       yyy)	zAdd a ``#managed by Certbot`` comment to the end of the line at location.

    :param list block: The block containing the directive to be commented
    :param int location: The location within ``block`` of the directive to be commented
    r(   NrH   r  r   r   r  )	rJ   r   r   COMMENTr   r   spacedinsertCOMMENT_BLOCK)ra   r   
next_entrys      r!   comment_directiver  _  s     )11s5z(Ax!|$tJ*d#
z?aJrNc$9gTV>Wj+":":;#**1-J#AJ	LLA}Q/0$j"8X\4( #9r#   include_locationc                    dj                  |      }| |   }t        j                  g       }|j                  |       t        j                  |      }|dz   |z   }t        j
                  |      }d}	|d   j                  d   |d   d   k7  rd}	|d   j                  j                  |	d       |d   j                  j                  d       t        j                  |      }t        j
                  |      }|d   | |<   y)z=Comment out the line at location, with a note of explanation.z duplicated in {0}z #r   r(   z# ;N)formatr   r   rN   r   loadsr  r  )
ra   r   r  comment_messageri   new_dir_blockdumped	commentednew_dirinsert_locations
             r!   _comment_out_directiver%  s  s    *112BCO hI,,R0M#}-F/I	*G Oqzwqz!},AJ_d3AJS!w'F'GajE(Or#   r   r   c                 D    t        fdt        |       D        d      S )zeFinds the index of the first instance of directive_name in block.
       If no line exists, use None.c              3   P   K   | ]  \  }}|r|d    k(  r |      r|  yw)r   Nr   ).0r   liner   r   s      r!   	<genexpr>z!_find_location.<locals>.<genexpr>  s9      Z;5$aN*
0BjQUFV  Zs   #&N)nextrS   )ra   r   r   s    ``r!   _find_locationr,    s*      Z)E*: Z[_a ar#   ri   c                 2    t        |       dk(  xs | d   dk(  S )z;Is this directive either a whitespace or comment directive?r   r  rI   ri   s    r!   _is_whitespace_or_commentr/    s    y>Q5)A,#"55r#   c                    t        |t        j                        st        j                  |      }t        |      r| j	                  |       y t        | |d         }|d   }dt        t           dt        dt        fd}d}|t        k(  rt        |d         }|D ]|  }t        | |d         }	|d   }
t        |      r# ||	|
      r-t        t        |	      }| |   |k7  r(t        j                  |j                  || |               t!        | ||d          ~  |||      rp|rD| j#                  dt        j                  d             | j#                  d|       t%        | d       y | j	                  |       t%        | t'        |       dz
         y t        t        |      }| |   |k7  r(t        j                  |j                  || |               y )	Nr   locdir_namer   c                 B    | du xs t        |t              xr |t        v S )z, Can we append this directive to the block? N)r   r   REPEATABLE_DIRECTIVES)r1  r2  s     r!   
can_appendz"_add_directive.<locals>.can_append  s-    d{ Fz(C8  E#+/D#D	Fr#   z<tried to insert directive "{0}" but found conflicting "{1}".r(   r  )r   r   r   r/  rN   r,  r
   intr   r   INCLUDEr   r   r   r   r  r%  r  r  rJ   )ra   ri   r   r   r   r5  err_fmtincluded_directivesincluded_directiveincluded_dir_locincluded_dir_nameresolved_included_dir_locresolved_locations                r!   r	  r	    s   i!9!9:,,Y7	 +YeYq\2H q\NF F F F
 MG   11>"5 	W-e5G5JK 21 5-.@A&'79JK -16F,G)237II 66w~~*E2K,L8N O O&u.GSTV	W (N+ LLK44T:;LLI&eQ' 	 LL#eSZ!^4 S(+9,**7>>)UK\E]+^__ -r#   c                 &    || |<   t        | |       y r   )r  )ra   ri   r   s      r!   _update_directiver@    s    E(OeX&r#   c                     t        |t        j                        st        j                  |      }t        |      r| j	                  |       y t        | |d         }|t        | ||       y t        | ||       y )Nr   )r   r   r   r/  rN   r,  r@  r	  )ra   ri   r   r   s       r!   r  r    sl    i!9!9:,,Y7	 +YeYq\2H %H55)]3r#   c                     d| v xr t         | v S )Nr  )r  r.  s    r!   _is_certbot_commentrC    s    )49 44r#   c                 ~    	 t        || |      }|y|dz   t        |      k  rt        ||dz            r||dz   = ||= =)zYRemoves directives of name directive_name from a config block if match_func matches.
    )r   Nr(   )r,  rJ   rC  )r   r   ra   r   s       r!   r   r     sW     !%JOa<#e*$)<U8a<=P)Qhl#(O r#   r?   rB   c                 l    |d   D ],  }| |j                            |_        |j                  s(d|d<   . y)zCApply global sslishness information to the parsed server block
    r8   Tr=   N)r<   r=   )r?   rB   rC   s      r!   r   r     s>     g& (t446788#'M% (r#   r*   c                    t               }d}t               }d}| D ]  }|s|d   dk(  rUt        j                  j                  dj	                  |dd             }|sB|j                  |       |j                  s`d}c|d   dk(  r|j                  d	 |dd D               t        |      sd}d} |r|D ]	  }d|_         |||d
S )zxParses a list of server directives.

    :param list server: list of directives in a server block
    :rtype: dict

    Fr   r   r  r(   NTr  c              3   >   K   | ]  }|j                  d         yw)z"'N)strip)r(  rK   s     r!   r*  z$_parse_server_raw.<locals>.<genexpr>$  s     ?A?s   )r8   r=   rY   )	setr   Addr
fromstringr6   addr=   updater   )r*   r8   r=   rY   apply_ssl_to_all_addrsri   rC   s          r!   r;   r;     s     5ECeE" *	Q<8#88&&sxx	!"'>?D		$88Cq\]*LL?12??!),C%)"*  	DDH	  r#   r   )>r   rc   r   re   rt   loggingr   typingr   r   r   r   r   r   r	   r
   r   r   r   r   rz   certbotr   certbot.compatr   certbot_nginx._internalr   r   #certbot_nginx._internal.nginxparserr   	getLoggerr   rw   r   r   r   r   r6  rR   r   r   r   r   r-   r   r   r   r7  r4  r  r  r  r%  r,  r/  r	  r@  r  rC  r   r   r;   r   r#   r!   <module>rV     s   D    	  	                / ' <			8	$L L^HSM d<6H " 26HDI H(DI;;L2M H#T#YS	$:D$@AH#DI.H:>H*+ +HSM +eHSMS[\_S`D`>a +\>c > > >
8 8C 8 8 82c   
' 
' 
'
 
 
5S	 5$ 5'5,055$s) 5D 5%156:5 &'9lS 
c7#)\ )S )T )(!, !# !QT !Y] !2 BFa, a a'#(=>aJRSV-a6# 64 6
>`, >`8C= >`QU >`Z^ >`B'\ 'hsm 's 'W[ '
4L 4Xc] 4,04594&58C= 5T 5s #8M */3(c3h0E(F (*.sCx.(=A($l $tCH~ $r#   