Blame


1 15902770 2021-01-15 op %{
2 15902770 2021-01-15 op
3 15902770 2021-01-15 op /*
4 e2f167af 2022-01-02 op * Copyright (c) 2021, 2022 Omar Polo <op@omarpolo.com>
5 c39be742 2021-07-09 op * Copyright (c) 2018 Florian Obser <florian@openbsd.org>
6 c39be742 2021-07-09 op * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
7 c39be742 2021-07-09 op * Copyright (c) 2004 Ryan McBride <mcbride@openbsd.org>
8 c39be742 2021-07-09 op * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
9 c39be742 2021-07-09 op * Copyright (c) 2001 Markus Friedl. All rights reserved.
10 c39be742 2021-07-09 op * Copyright (c) 2001 Daniel Hartmeier. All rights reserved.
11 c39be742 2021-07-09 op * Copyright (c) 2001 Theo de Raadt. All rights reserved.
12 15902770 2021-01-15 op *
13 15902770 2021-01-15 op * Permission to use, copy, modify, and distribute this software for any
14 15902770 2021-01-15 op * purpose with or without fee is hereby granted, provided that the above
15 15902770 2021-01-15 op * copyright notice and this permission notice appear in all copies.
16 15902770 2021-01-15 op *
17 15902770 2021-01-15 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
18 15902770 2021-01-15 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
19 15902770 2021-01-15 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
20 15902770 2021-01-15 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
21 15902770 2021-01-15 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
22 15902770 2021-01-15 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
23 15902770 2021-01-15 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24 15902770 2021-01-15 op */
25 1f1f3810 2022-02-03 op
26 1f1f3810 2022-02-03 op #include "gmid.h"
27 15902770 2021-01-15 op
28 74f0778b 2021-06-16 op #include <ctype.h>
29 002a84a1 2021-02-10 op #include <errno.h>
30 534afd0d 2022-10-05 op #include <netdb.h>
31 6abda252 2021-02-06 op #include <stdarg.h>
32 15902770 2021-01-15 op #include <stdio.h>
33 74f0778b 2021-06-16 op #include <stdlib.h>
34 32693ee6 2021-01-28 op #include <string.h>
35 df5058c9 2023-06-05 op
36 df5058c9 2023-06-05 op #include "log.h"
37 15902770 2021-01-15 op
38 af1dab18 2023-06-09 op struct conf *conf;
39 af1dab18 2023-06-09 op
40 c39be742 2021-07-09 op TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files);
41 c39be742 2021-07-09 op static struct file {
42 c39be742 2021-07-09 op TAILQ_ENTRY(file) entry;
43 c39be742 2021-07-09 op FILE *stream;
44 c39be742 2021-07-09 op char *name;
45 c39be742 2021-07-09 op size_t ungetpos;
46 c39be742 2021-07-09 op size_t ungetsize;
47 c39be742 2021-07-09 op u_char *ungetbuf;
48 c39be742 2021-07-09 op int eof_reached;
49 c39be742 2021-07-09 op int lineno;
50 c39be742 2021-07-09 op int errors;
51 c39be742 2021-07-09 op } *file, *topfile;
52 74f0778b 2021-06-16 op
53 c39be742 2021-07-09 op struct file *pushfile(const char *, int);
54 c39be742 2021-07-09 op int popfile(void);
55 c39be742 2021-07-09 op int yyparse(void);
56 c39be742 2021-07-09 op int yylex(void);
57 c39be742 2021-07-09 op void yyerror(const char *, ...)
58 c39be742 2021-07-09 op __attribute__((__format__ (printf, 1, 2)))
59 c39be742 2021-07-09 op __attribute__((__nonnull__ (1)));
60 f3966209 2021-07-13 op void yywarn(const char *, ...)
61 f3966209 2021-07-13 op __attribute__((__format__ (printf, 1, 2)))
62 f3966209 2021-07-13 op __attribute__((__nonnull__ (1)));
63 c39be742 2021-07-09 op int kw_cmp(const void *, const void *);
64 c39be742 2021-07-09 op int lookup(char *);
65 c39be742 2021-07-09 op int igetc(void);
66 c39be742 2021-07-09 op int lgetc(int);
67 c39be742 2021-07-09 op void lungetc(int);
68 c39be742 2021-07-09 op int findeol(void);
69 ef129b08 2021-06-16 op
70 15902770 2021-01-15 op /*
71 15902770 2021-01-15 op * #define YYDEBUG 1
72 15902770 2021-01-15 op * int yydebug = 1;
73 15902770 2021-01-15 op */
74 15902770 2021-01-15 op
75 3b21cca3 2021-06-29 op TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead);
76 3b21cca3 2021-06-29 op struct sym {
77 3b21cca3 2021-06-29 op TAILQ_ENTRY(sym) entry;
78 3b21cca3 2021-06-29 op int used;
79 3b21cca3 2021-06-29 op int persist;
80 3b21cca3 2021-06-29 op char *name;
81 3b21cca3 2021-06-29 op char *val;
82 3b21cca3 2021-06-29 op };
83 3b21cca3 2021-06-29 op
84 c39be742 2021-07-09 op int symset(const char *, const char *, int);
85 c39be742 2021-07-09 op char *symget(const char *);
86 15902770 2021-01-15 op
87 c39be742 2021-07-09 op struct vhost *new_vhost(void);
88 c39be742 2021-07-09 op struct location *new_location(void);
89 b7967bc1 2022-01-02 op struct proxy *new_proxy(void);
90 e17642a7 2021-02-01 op char *ensure_absolute_path(char*);
91 6abda252 2021-02-06 op int check_block_code(int);
92 6abda252 2021-02-06 op char *check_block_fmt(char*);
93 6abda252 2021-02-06 op int check_strip_no(int);
94 391825e3 2021-07-09 op int check_port_num(int);
95 a709ddf5 2021-02-07 op int check_prefork_num(int);
96 49b73ba1 2021-02-10 op void advance_loc(void);
97 b7967bc1 2022-01-02 op void advance_proxy(void);
98 b7967bc1 2022-01-02 op void parsehp(char *, char **, const char **, const char *);
99 7b00c890 2022-10-05 op int fastcgi_conf(const char *, const char *);
100 2025e96d 2022-09-10 op void add_param(char *, char *);
101 534afd0d 2022-10-05 op int getservice(const char *);
102 13ed2fb6 2021-01-27 op
103 c39be742 2021-07-09 op static struct vhost *host;
104 c39be742 2021-07-09 op static struct location *loc;
105 b7967bc1 2022-01-02 op static struct proxy *proxy;
106 ee219d70 2022-02-26 op static char *current_media;
107 c39be742 2021-07-09 op static int errors;
108 c39be742 2021-07-09 op
109 c39be742 2021-07-09 op typedef struct {
110 c39be742 2021-07-09 op union {
111 c39be742 2021-07-09 op char *string;
112 c39be742 2021-07-09 op int number;
113 c39be742 2021-07-09 op } v;
114 c39be742 2021-07-09 op int lineno;
115 c39be742 2021-07-09 op } YYSTYPE;
116 c39be742 2021-07-09 op
117 15902770 2021-01-15 op %}
118 15902770 2021-01-15 op
119 15902770 2021-01-15 op /* for bison: */
120 15902770 2021-01-15 op /* %define parse.error verbose */
121 15902770 2021-01-15 op
122 c74c7030 2021-07-19 op %token ALIAS AUTO
123 c74c7030 2021-07-19 op %token BLOCK
124 d29a2ee2 2022-09-06 op %token CA CERT CHROOT CLIENT
125 c74c7030 2021-07-19 op %token DEFAULT
126 b7967bc1 2022-01-02 op %token FASTCGI FOR_HOST
127 c74c7030 2021-07-19 op %token INCLUDE INDEX IPV6
128 c74c7030 2021-07-19 op %token KEY
129 c74c7030 2021-07-19 op %token LANG LOCATION LOG
130 ff05125e 2021-10-15 op %token OCSP OFF ON
131 b7967bc1 2022-01-02 op %token PARAM PORT PREFORK PROTO PROTOCOLS PROXY
132 72b033ef 2021-12-29 op %token RELAY_TO REQUIRE RETURN ROOT
133 7b00c890 2022-10-05 op %token SERVER SNI STRIP
134 ee219d70 2022-02-26 op %token TCP TOEXT TYPE TYPES
135 593e412b 2022-01-01 op %token USE_TLS USER
136 5128c0b0 2022-01-01 op %token VERIFYNAME
137 d06d6f4b 2021-04-29 op
138 c39be742 2021-07-09 op %token ERROR
139 7252049d 2021-06-29 op
140 c39be742 2021-07-09 op %token <v.string> STRING
141 c39be742 2021-07-09 op %token <v.number> NUM
142 15902770 2021-01-15 op
143 534afd0d 2022-10-05 op %type <v.number> bool proxy_port
144 ee219d70 2022-02-26 op %type <v.string> string numberstring
145 98f52178 2021-06-29 op
146 15902770 2021-01-15 op %%
147 15902770 2021-01-15 op
148 6b86655a 2021-06-29 op conf : /* empty */
149 c39be742 2021-07-09 op | conf include '\n'
150 c39be742 2021-07-09 op | conf '\n'
151 c39be742 2021-07-09 op | conf varset '\n'
152 c39be742 2021-07-09 op | conf option '\n'
153 c39be742 2021-07-09 op | conf vhost '\n'
154 ee219d70 2022-02-26 op | conf types '\n'
155 c39be742 2021-07-09 op | conf error '\n' { file->errors++; }
156 3b21cca3 2021-06-29 op ;
157 3b21cca3 2021-06-29 op
158 c39be742 2021-07-09 op include : INCLUDE STRING {
159 c39be742 2021-07-09 op struct file *nfile;
160 c39be742 2021-07-09 op
161 c39be742 2021-07-09 op if ((nfile = pushfile($2, 0)) == NULL) {
162 c39be742 2021-07-09 op yyerror("failed to include file %s", $2);
163 c39be742 2021-07-09 op free($2);
164 c39be742 2021-07-09 op YYERROR;
165 c39be742 2021-07-09 op }
166 c39be742 2021-07-09 op free($2);
167 c39be742 2021-07-09 op
168 c39be742 2021-07-09 op file = nfile;
169 c39be742 2021-07-09 op lungetc('\n');
170 c39be742 2021-07-09 op }
171 c39be742 2021-07-09 op ;
172 c39be742 2021-07-09 op
173 c74c7030 2021-07-19 op bool : ON { $$ = 1; }
174 c74c7030 2021-07-19 op | OFF { $$ = 0; }
175 c39be742 2021-07-09 op ;
176 c39be742 2021-07-09 op
177 c39be742 2021-07-09 op string : string STRING {
178 98f52178 2021-06-29 op if (asprintf(&$$, "%s%s", $1, $2) == -1) {
179 98f52178 2021-06-29 op free($1);
180 98f52178 2021-06-29 op free($2);
181 98f52178 2021-06-29 op yyerror("string: asprintf: %s", strerror(errno));
182 98f52178 2021-06-29 op YYERROR;
183 98f52178 2021-06-29 op }
184 98f52178 2021-06-29 op free($1);
185 98f52178 2021-06-29 op free($2);
186 98f52178 2021-06-29 op }
187 c39be742 2021-07-09 op | STRING
188 98f52178 2021-06-29 op ;
189 98f52178 2021-06-29 op
190 ee219d70 2022-02-26 op numberstring : NUM {
191 ee219d70 2022-02-26 op char *s;
192 ee219d70 2022-02-26 op if (asprintf(&s, "%d", $1) == -1) {
193 ee219d70 2022-02-26 op yyerror("asprintf: number");
194 ee219d70 2022-02-26 op YYERROR;
195 ee219d70 2022-02-26 op }
196 ee219d70 2022-02-26 op $$ = s;
197 ee219d70 2022-02-26 op }
198 ee219d70 2022-02-26 op | STRING
199 ee219d70 2022-02-26 op ;
200 ee219d70 2022-02-26 op
201 c39be742 2021-07-09 op varset : STRING '=' string {
202 3b21cca3 2021-06-29 op char *s = $1;
203 3b21cca3 2021-06-29 op while (*s++) {
204 c39be742 2021-07-09 op if (isspace((unsigned char)*s)) {
205 3b21cca3 2021-06-29 op yyerror("macro name cannot contain "
206 3b21cca3 2021-06-29 op "whitespaces");
207 3b21cca3 2021-06-29 op free($1);
208 3b21cca3 2021-06-29 op free($3);
209 3b21cca3 2021-06-29 op YYERROR;
210 3b21cca3 2021-06-29 op }
211 3b21cca3 2021-06-29 op }
212 3b21cca3 2021-06-29 op symset($1, $3, 0);
213 3b21cca3 2021-06-29 op free($1);
214 3b21cca3 2021-06-29 op free($3);
215 3b21cca3 2021-06-29 op }
216 15902770 2021-01-15 op ;
217 15902770 2021-01-15 op
218 7277bb7d 2022-09-10 op option : CHROOT string {
219 af1dab18 2023-06-09 op if (strlcpy(conf->chroot, $2, sizeof(conf->chroot)) >=
220 af1dab18 2023-06-09 op sizeof(conf->chroot))
221 7277bb7d 2022-09-10 op yyerror("chroot path too long");
222 7277bb7d 2022-09-10 op free($2);
223 7277bb7d 2022-09-10 op }
224 af1dab18 2023-06-09 op | IPV6 bool { conf->ipv6 = $2; }
225 af1dab18 2023-06-09 op | PORT NUM { conf->port = check_port_num($2); }
226 af1dab18 2023-06-09 op | PREFORK NUM { conf->prefork = check_prefork_num($2); }
227 c74c7030 2021-07-19 op | PROTOCOLS string {
228 af1dab18 2023-06-09 op if (tls_config_parse_protocols(&conf->protos, $2) == -1)
229 002a84a1 2021-02-10 op yyerror("invalid protocols string \"%s\"", $2);
230 3c4b712b 2022-01-01 op free($2);
231 5bc3c98e 2021-01-15 op }
232 7277bb7d 2022-09-10 op | USER string {
233 af1dab18 2023-06-09 op if (strlcpy(conf->user, $2, sizeof(conf->user)) >=
234 af1dab18 2023-06-09 op sizeof(conf->user))
235 7277bb7d 2022-09-10 op yyerror("user name too long");
236 7277bb7d 2022-09-10 op free($2);
237 7277bb7d 2022-09-10 op }
238 15902770 2021-01-15 op ;
239 15902770 2021-01-15 op
240 c74c7030 2021-07-19 op vhost : SERVER string {
241 b8e64ccd 2021-03-31 op host = new_vhost();
242 af1dab18 2023-06-09 op TAILQ_INSERT_HEAD(&conf->hosts, host, vhosts);
243 b8e64ccd 2021-03-31 op
244 b8e64ccd 2021-03-31 op loc = new_location();
245 b8e64ccd 2021-03-31 op TAILQ_INSERT_HEAD(&host->locations, loc, locations);
246 b8e64ccd 2021-03-31 op
247 b7967bc1 2022-01-02 op TAILQ_INIT(&host->proxies);
248 b7967bc1 2022-01-02 op
249 534afd0d 2022-10-05 op (void) strlcpy(loc->match, "*", sizeof(loc->match));
250 534afd0d 2022-10-05 op (void) strlcpy(host->domain, $2, sizeof(host->domain));
251 15902770 2021-01-15 op
252 cbeee4ca 2021-01-28 op if (strstr($2, "xn--") != NULL) {
253 f3966209 2021-07-13 op yywarn("\"%s\" looks like punycode: you "
254 f3966209 2021-07-13 op "should use the decoded hostname", $2);
255 cbeee4ca 2021-01-28 op }
256 534afd0d 2022-10-05 op
257 534afd0d 2022-10-05 op free($2);
258 b7967bc1 2022-01-02 op } '{' optnl servbody '}' {
259 1c6967b3 2023-06-08 op if (host->cert_path == NULL ||
260 1c6967b3 2023-06-08 op host->key_path == NULL)
261 002a84a1 2021-02-10 op yyerror("invalid vhost definition: %s", $2);
262 15902770 2021-01-15 op }
263 f3966209 2021-07-13 op | error '}' { yyerror("bad server directive"); }
264 15902770 2021-01-15 op ;
265 15902770 2021-01-15 op
266 b7967bc1 2022-01-02 op servbody : /* empty */
267 b7967bc1 2022-01-02 op | servbody servopt optnl
268 b7967bc1 2022-01-02 op | servbody location optnl
269 b7967bc1 2022-01-02 op | servbody proxy optnl
270 15902770 2021-01-15 op ;
271 15902770 2021-01-15 op
272 c74c7030 2021-07-19 op servopt : ALIAS string {
273 cc8c2901 2021-04-29 op struct alist *a;
274 cc8c2901 2021-04-29 op
275 cc8c2901 2021-04-29 op a = xcalloc(1, sizeof(*a));
276 534afd0d 2022-10-05 op (void) strlcpy(a->alias, $2, sizeof(a->alias));
277 534afd0d 2022-10-05 op free($2);
278 edc5ca66 2022-09-10 op TAILQ_INSERT_TAIL(&host->aliases, a, aliases);
279 cc8c2901 2021-04-29 op }
280 c74c7030 2021-07-19 op | CERT string {
281 534afd0d 2022-10-05 op ensure_absolute_path($2);
282 1c6967b3 2023-06-08 op free(host->cert_path);
283 1c6967b3 2023-06-08 op host->cert_path = $2;
284 9cc630aa 2021-04-28 op }
285 c74c7030 2021-07-19 op | KEY string {
286 534afd0d 2022-10-05 op ensure_absolute_path($2);
287 1c6967b3 2023-06-08 op free(host->key_path);
288 1c6967b3 2023-06-08 op host->key_path = $2;
289 c92b802b 2021-06-11 op }
290 ff05125e 2021-10-15 op | OCSP string {
291 534afd0d 2022-10-05 op ensure_absolute_path($2);
292 1c6967b3 2023-06-08 op free(host->ocsp_path);
293 1c6967b3 2023-06-08 op host->ocsp_path = $2;
294 ff05125e 2021-10-15 op }
295 c74c7030 2021-07-19 op | PARAM string '=' string {
296 2025e96d 2022-09-10 op add_param($2, $4);
297 c705ecb1 2021-05-03 op }
298 c8b74339 2021-01-24 op | locopt
299 c8b74339 2021-01-24 op ;
300 7bdcc91e 2022-01-01 op
301 b7967bc1 2022-01-02 op proxy : PROXY { advance_proxy(); }
302 b7967bc1 2022-01-02 op proxy_matches '{' optnl proxy_opts '}' {
303 534afd0d 2022-10-05 op if (*proxy->host == '\0')
304 b7967bc1 2022-01-02 op yyerror("invalid proxy block: missing `relay-to' option");
305 b7967bc1 2022-01-02 op
306 deadd9e1 2023-06-09 op if ((proxy->cert_path == NULL && proxy->key_path != NULL) ||
307 deadd9e1 2023-06-09 op (proxy->cert_path != NULL && proxy->key_path == NULL))
308 b7967bc1 2022-01-02 op yyerror("invalid proxy block: missing cert or key");
309 b7967bc1 2022-01-02 op }
310 b7967bc1 2022-01-02 op ;
311 b7967bc1 2022-01-02 op
312 b7967bc1 2022-01-02 op proxy_matches : /* empty */
313 b7967bc1 2022-01-02 op | proxy_matches proxy_match
314 b7967bc1 2022-01-02 op ;
315 b7967bc1 2022-01-02 op
316 534afd0d 2022-10-05 op proxy_port : /* empty */ { $$ = 1965; }
317 534afd0d 2022-10-05 op | PORT STRING {
318 534afd0d 2022-10-05 op if (($$ = getservice($2)) == -1)
319 534afd0d 2022-10-05 op yyerror("invalid port number %s", $2);
320 534afd0d 2022-10-05 op free($2);
321 534afd0d 2022-10-05 op }
322 534afd0d 2022-10-05 op | PORT NUM { $$ = $2; }
323 534afd0d 2022-10-05 op ;
324 534afd0d 2022-10-05 op
325 b7967bc1 2022-01-02 op proxy_match : PROTO string {
326 534afd0d 2022-10-05 op (void) strlcpy(proxy->match_proto, $2, sizeof(proxy->match_proto));
327 534afd0d 2022-10-05 op free($2);
328 b7967bc1 2022-01-02 op }
329 534afd0d 2022-10-05 op | FOR_HOST string proxy_port {
330 534afd0d 2022-10-05 op (void) strlcpy(proxy->match_host, $2, sizeof(proxy->match_host));
331 534afd0d 2022-10-05 op (void) snprintf(proxy->match_port, sizeof(proxy->match_port),
332 534afd0d 2022-10-05 op "%d", $3);
333 534afd0d 2022-10-05 op free($2);
334 b7967bc1 2022-01-02 op }
335 7bdcc91e 2022-01-01 op ;
336 7bdcc91e 2022-01-01 op
337 7bdcc91e 2022-01-01 op proxy_opts : /* empty */
338 7bdcc91e 2022-01-01 op | proxy_opts proxy_opt optnl
339 7bdcc91e 2022-01-01 op ;
340 7bdcc91e 2022-01-01 op
341 7bdcc91e 2022-01-01 op proxy_opt : CERT string {
342 deadd9e1 2023-06-09 op free(proxy->cert);
343 7bdcc91e 2022-01-01 op ensure_absolute_path($2);
344 deadd9e1 2023-06-09 op proxy->cert_path = $2;
345 7bdcc91e 2022-01-01 op }
346 7bdcc91e 2022-01-01 op | KEY string {
347 deadd9e1 2023-06-09 op free(proxy->key);
348 7bdcc91e 2022-01-01 op ensure_absolute_path($2);
349 deadd9e1 2023-06-09 op proxy->key_path = $2;
350 c7c8ef44 2022-01-01 op }
351 c7c8ef44 2022-01-01 op | PROTOCOLS string {
352 b7967bc1 2022-01-02 op if (tls_config_parse_protocols(&proxy->protocols, $2) == -1)
353 c7c8ef44 2022-01-01 op yyerror("invalid protocols string \"%s\"", $2);
354 3c4b712b 2022-01-01 op free($2);
355 7bdcc91e 2022-01-01 op }
356 534afd0d 2022-10-05 op | RELAY_TO string proxy_port {
357 534afd0d 2022-10-05 op (void) strlcpy(proxy->host, $2, sizeof(proxy->host));
358 534afd0d 2022-10-05 op (void) snprintf(proxy->port, sizeof(proxy->port),
359 534afd0d 2022-10-05 op "%d", $3);
360 534afd0d 2022-10-05 op free($2);
361 593e412b 2022-01-01 op }
362 ba94a608 2022-01-04 op | REQUIRE CLIENT CA string {
363 ba94a608 2022-01-04 op ensure_absolute_path($4);
364 deadd9e1 2023-06-09 op proxy->reqca_path = $4;
365 1cdea97b 2022-01-30 op }
366 1cdea97b 2022-01-30 op | SNI string {
367 534afd0d 2022-10-05 op (void) strlcpy(proxy->sni, $2, sizeof(proxy->sni));
368 534afd0d 2022-10-05 op free($2);
369 ba94a608 2022-01-04 op }
370 593e412b 2022-01-01 op | USE_TLS bool {
371 b7967bc1 2022-01-02 op proxy->notls = !$2;
372 7bdcc91e 2022-01-01 op }
373 5128c0b0 2022-01-01 op | VERIFYNAME bool {
374 b7967bc1 2022-01-02 op proxy->noverifyname = !$2;
375 5128c0b0 2022-01-01 op }
376 7bdcc91e 2022-01-01 op ;
377 7bdcc91e 2022-01-01 op
378 c74c7030 2021-07-19 op location : LOCATION { advance_loc(); } string '{' optnl locopts '}' {
379 49b73ba1 2021-02-10 op /* drop the starting '/' if any */
380 49b73ba1 2021-02-10 op if (*$3 == '/')
381 49b73ba1 2021-02-10 op memmove($3, $3+1, strlen($3));
382 534afd0d 2022-10-05 op (void) strlcpy(loc->match, $3, sizeof(loc->match));
383 534afd0d 2022-10-05 op free($3);
384 6119e13e 2021-01-19 op }
385 c8b74339 2021-01-24 op | error '}'
386 c8b74339 2021-01-24 op ;
387 c8b74339 2021-01-24 op
388 c8b74339 2021-01-24 op locopts : /* empty */
389 c39be742 2021-07-09 op | locopts locopt optnl
390 c8b74339 2021-01-24 op ;
391 c8b74339 2021-01-24 op
392 c74c7030 2021-07-19 op locopt : AUTO INDEX bool { loc->auto_index = $3 ? 1 : -1; }
393 c74c7030 2021-07-19 op | BLOCK RETURN NUM string {
394 534afd0d 2022-10-05 op check_block_fmt($4);
395 534afd0d 2022-10-05 op (void) strlcpy(loc->block_fmt, $4, sizeof(loc->block_fmt));
396 6abda252 2021-02-06 op loc->block_code = check_block_code($3);
397 534afd0d 2022-10-05 op free($4);
398 6abda252 2021-02-06 op }
399 c74c7030 2021-07-19 op | BLOCK RETURN NUM {
400 534afd0d 2022-10-05 op (void) strlcpy(loc->block_fmt, "temporary failure",
401 534afd0d 2022-10-05 op sizeof(loc->block_fmt));
402 6abda252 2021-02-06 op loc->block_code = check_block_code($3);
403 6abda252 2021-02-06 op if ($3 >= 30 && $3 < 40)
404 6abda252 2021-02-06 op yyerror("missing `meta' for block return %d", $3);
405 6abda252 2021-02-06 op }
406 c74c7030 2021-07-19 op | BLOCK {
407 534afd0d 2022-10-05 op (void) strlcpy(loc->block_fmt, "temporary failure",
408 534afd0d 2022-10-05 op sizeof(loc->block_fmt));
409 6abda252 2021-02-06 op loc->block_code = 40;
410 6abda252 2021-02-06 op }
411 c74c7030 2021-07-19 op | DEFAULT TYPE string {
412 534afd0d 2022-10-05 op (void) strlcpy(loc->default_mime, $3,
413 534afd0d 2022-10-05 op sizeof(loc->default_mime));
414 534afd0d 2022-10-05 op free($3);
415 eb59f87e 2021-02-09 op }
416 abc8801d 2021-07-19 op | FASTCGI fastcgi
417 c74c7030 2021-07-19 op | INDEX string {
418 534afd0d 2022-10-05 op (void) strlcpy(loc->index, $2, sizeof(loc->index));
419 534afd0d 2022-10-05 op free($2);
420 eb59f87e 2021-02-09 op }
421 c74c7030 2021-07-19 op | LANG string {
422 534afd0d 2022-10-05 op (void) strlcpy(loc->lang, $2,
423 534afd0d 2022-10-05 op sizeof(loc->lang));
424 534afd0d 2022-10-05 op free($2);
425 eb59f87e 2021-02-09 op }
426 c74c7030 2021-07-19 op | LOG bool { loc->disable_log = !$2; }
427 da2185f3 2022-01-01 op | REQUIRE CLIENT CA string {
428 da2185f3 2022-01-01 op ensure_absolute_path($4);
429 deadd9e1 2023-06-09 op loc->reqca_path = $4;
430 da2185f3 2022-01-01 op }
431 da2185f3 2022-01-01 op | ROOT string {
432 534afd0d 2022-10-05 op (void) strlcpy(loc->dir, $2, sizeof(loc->dir));
433 534afd0d 2022-10-05 op free($2);
434 da2185f3 2022-01-01 op }
435 da2185f3 2022-01-01 op | STRIP NUM { loc->strip = check_strip_no($2); }
436 da2185f3 2022-01-01 op ;
437 da2185f3 2022-01-01 op
438 7b00c890 2022-10-05 op fastcgi : string {
439 7b00c890 2022-10-05 op loc->fcgi = fastcgi_conf($1, NULL);
440 534afd0d 2022-10-05 op free($1);
441 0d047efc 2021-05-24 op }
442 c74c7030 2021-07-19 op | TCP string PORT NUM {
443 0d047efc 2021-05-24 op char *c;
444 762b9b99 2021-07-09 op if (asprintf(&c, "%d", $4) == -1)
445 792f302a 2023-06-09 op fatal("asprintf");
446 7b00c890 2022-10-05 op loc->fcgi = fastcgi_conf($2, c);
447 534afd0d 2022-10-05 op free($2);
448 0d047efc 2021-05-24 op }
449 c74c7030 2021-07-19 op | TCP string {
450 7b00c890 2022-10-05 op loc->fcgi = fastcgi_conf($2, "9000");
451 534afd0d 2022-10-05 op free($2);
452 0d047efc 2021-05-24 op }
453 c74c7030 2021-07-19 op | TCP string PORT string {
454 7b00c890 2022-10-05 op loc->fcgi = fastcgi_conf($2, $4);
455 534afd0d 2022-10-05 op free($2);
456 534afd0d 2022-10-05 op free($4);
457 0d047efc 2021-05-24 op }
458 ee219d70 2022-02-26 op ;
459 ee219d70 2022-02-26 op
460 cd5826b8 2022-09-10 op types : TYPES '{' optnl mediaopts_l '}' ;
461 0d047efc 2021-05-24 op
462 ee219d70 2022-02-26 op mediaopts_l : mediaopts_l mediaoptsl nl
463 ee219d70 2022-02-26 op | mediaoptsl nl
464 ee219d70 2022-02-26 op ;
465 ee219d70 2022-02-26 op
466 aa9543b9 2022-09-10 op mediaoptsl : STRING {
467 aa9543b9 2022-09-10 op free(current_media);
468 aa9543b9 2022-09-10 op current_media = $1;
469 aa9543b9 2022-09-10 op } medianames_l optsemicolon
470 ee219d70 2022-02-26 op | include
471 ee219d70 2022-02-26 op ;
472 ee219d70 2022-02-26 op
473 ee219d70 2022-02-26 op medianames_l : medianames_l medianamesl
474 ee219d70 2022-02-26 op | medianamesl
475 ee219d70 2022-02-26 op ;
476 ee219d70 2022-02-26 op
477 d8d170aa 2022-04-08 op medianamesl : numberstring {
478 af1dab18 2023-06-09 op if (add_mime(&conf->mime, current_media, $1) == -1)
479 792f302a 2023-06-09 op fatal("add_mime");
480 aa9543b9 2022-09-10 op free($1);
481 d8d170aa 2022-04-08 op }
482 ee219d70 2022-02-26 op ;
483 ee219d70 2022-02-26 op
484 ee219d70 2022-02-26 op nl : '\n' optnl
485 ee219d70 2022-02-26 op ;
486 ee219d70 2022-02-26 op
487 c39be742 2021-07-09 op optnl : '\n' optnl /* zero or more newlines */
488 67f49405 2021-07-09 op | ';' optnl /* semicolons too */
489 c39be742 2021-07-09 op | /*empty*/
490 c39be742 2021-07-09 op ;
491 fdea6aa0 2021-04-30 op
492 ee219d70 2022-02-26 op optsemicolon : ';'
493 ee219d70 2022-02-26 op |
494 ee219d70 2022-02-26 op ;
495 ee219d70 2022-02-26 op
496 c39be742 2021-07-09 op %%
497 b8e64ccd 2021-03-31 op
498 e5d82d94 2022-03-19 op static const struct keyword {
499 74f0778b 2021-06-16 op const char *word;
500 74f0778b 2021-06-16 op int token;
501 74f0778b 2021-06-16 op } keywords[] = {
502 d93c8191 2021-07-09 op /* these MUST be sorted */
503 c74c7030 2021-07-19 op {"alias", ALIAS},
504 c74c7030 2021-07-19 op {"auto", AUTO},
505 c74c7030 2021-07-19 op {"block", BLOCK},
506 c74c7030 2021-07-19 op {"ca", CA},
507 c74c7030 2021-07-19 op {"cert", CERT},
508 c74c7030 2021-07-19 op {"chroot", CHROOT},
509 c74c7030 2021-07-19 op {"client", CLIENT},
510 c74c7030 2021-07-19 op {"default", DEFAULT},
511 abc8801d 2021-07-19 op {"fastcgi", FASTCGI},
512 b7967bc1 2022-01-02 op {"for-host", FOR_HOST},
513 88971f9a 2022-02-26 op {"include", INCLUDE},
514 c74c7030 2021-07-19 op {"index", INDEX},
515 c74c7030 2021-07-19 op {"ipv6", IPV6},
516 c74c7030 2021-07-19 op {"key", KEY},
517 c74c7030 2021-07-19 op {"lang", LANG},
518 c74c7030 2021-07-19 op {"location", LOCATION},
519 c74c7030 2021-07-19 op {"log", LOG},
520 ff05125e 2021-10-15 op {"ocsp", OCSP},
521 c74c7030 2021-07-19 op {"off", OFF},
522 c74c7030 2021-07-19 op {"on", ON},
523 c74c7030 2021-07-19 op {"param", PARAM},
524 c74c7030 2021-07-19 op {"port", PORT},
525 c74c7030 2021-07-19 op {"prefork", PREFORK},
526 b7967bc1 2022-01-02 op {"proto", PROTO},
527 c74c7030 2021-07-19 op {"protocols", PROTOCOLS},
528 72b033ef 2021-12-29 op {"proxy", PROXY},
529 72b033ef 2021-12-29 op {"relay-to", RELAY_TO},
530 c74c7030 2021-07-19 op {"require", REQUIRE},
531 c74c7030 2021-07-19 op {"return", RETURN},
532 c74c7030 2021-07-19 op {"root", ROOT},
533 c74c7030 2021-07-19 op {"server", SERVER},
534 1cdea97b 2022-01-30 op {"sni", SNI},
535 c74c7030 2021-07-19 op {"strip", STRIP},
536 c74c7030 2021-07-19 op {"tcp", TCP},
537 c74c7030 2021-07-19 op {"to-ext", TOEXT},
538 c74c7030 2021-07-19 op {"type", TYPE},
539 ee219d70 2022-02-26 op {"types", TYPES},
540 593e412b 2022-01-01 op {"use-tls", USE_TLS},
541 c74c7030 2021-07-19 op {"user", USER},
542 5128c0b0 2022-01-01 op {"verifyname", VERIFYNAME},
543 74f0778b 2021-06-16 op };
544 74f0778b 2021-06-16 op
545 c39be742 2021-07-09 op void
546 c39be742 2021-07-09 op yyerror(const char *msg, ...)
547 c39be742 2021-07-09 op {
548 c39be742 2021-07-09 op va_list ap;
549 c39be742 2021-07-09 op
550 c39be742 2021-07-09 op file->errors++;
551 c39be742 2021-07-09 op
552 c39be742 2021-07-09 op va_start(ap, msg);
553 f3966209 2021-07-13 op fprintf(stderr, "%s:%d error: ", config_path, yylval.lineno);
554 f3966209 2021-07-13 op vfprintf(stderr, msg, ap);
555 f3966209 2021-07-13 op fprintf(stderr, "\n");
556 f3966209 2021-07-13 op va_end(ap);
557 f3966209 2021-07-13 op }
558 f3966209 2021-07-13 op
559 f3966209 2021-07-13 op void
560 f3966209 2021-07-13 op yywarn(const char *msg, ...)
561 f3966209 2021-07-13 op {
562 f3966209 2021-07-13 op va_list ap;
563 f3966209 2021-07-13 op
564 f3966209 2021-07-13 op va_start(ap, msg);
565 f3966209 2021-07-13 op fprintf(stderr, "%s:%d warning: ", config_path, yylval.lineno);
566 c39be742 2021-07-09 op vfprintf(stderr, msg, ap);
567 c39be742 2021-07-09 op fprintf(stderr, "\n");
568 c39be742 2021-07-09 op va_end(ap);
569 c39be742 2021-07-09 op }
570 c39be742 2021-07-09 op
571 d93c8191 2021-07-09 op int
572 d93c8191 2021-07-09 op kw_cmp(const void *k, const void *e)
573 d93c8191 2021-07-09 op {
574 d93c8191 2021-07-09 op return strcmp(k, ((struct keyword *)e)->word);
575 d93c8191 2021-07-09 op }
576 d93c8191 2021-07-09 op
577 c39be742 2021-07-09 op int
578 c39be742 2021-07-09 op lookup(char *s)
579 74f0778b 2021-06-16 op {
580 c39be742 2021-07-09 op const struct keyword *p;
581 74f0778b 2021-06-16 op
582 c39be742 2021-07-09 op p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
583 c39be742 2021-07-09 op sizeof(keywords[0]), kw_cmp);
584 74f0778b 2021-06-16 op
585 c39be742 2021-07-09 op if (p)
586 c39be742 2021-07-09 op return p->token;
587 c39be742 2021-07-09 op else
588 c39be742 2021-07-09 op return STRING;
589 c39be742 2021-07-09 op }
590 c39be742 2021-07-09 op
591 c39be742 2021-07-09 op #define START_EXPAND 1
592 c39be742 2021-07-09 op #define DONE_EXPAND 2
593 c39be742 2021-07-09 op
594 c39be742 2021-07-09 op static int expanding;
595 c39be742 2021-07-09 op
596 c39be742 2021-07-09 op int
597 c39be742 2021-07-09 op igetc(void)
598 c39be742 2021-07-09 op {
599 c39be742 2021-07-09 op int c;
600 c39be742 2021-07-09 op
601 c39be742 2021-07-09 op while (1) {
602 c39be742 2021-07-09 op if (file->ungetpos > 0)
603 c39be742 2021-07-09 op c = file->ungetbuf[--file->ungetpos];
604 c39be742 2021-07-09 op else
605 c39be742 2021-07-09 op c = getc(file->stream);
606 c39be742 2021-07-09 op
607 c39be742 2021-07-09 op if (c == START_EXPAND)
608 c39be742 2021-07-09 op expanding = 1;
609 c39be742 2021-07-09 op else if (c == DONE_EXPAND)
610 c39be742 2021-07-09 op expanding = 0;
611 c39be742 2021-07-09 op else
612 c39be742 2021-07-09 op break;
613 74f0778b 2021-06-16 op }
614 c39be742 2021-07-09 op return c;
615 c39be742 2021-07-09 op }
616 74f0778b 2021-06-16 op
617 c39be742 2021-07-09 op int
618 c39be742 2021-07-09 op lgetc(int quotec)
619 c39be742 2021-07-09 op {
620 c39be742 2021-07-09 op int c, next;
621 c39be742 2021-07-09 op
622 c39be742 2021-07-09 op if (quotec) {
623 c39be742 2021-07-09 op if ((c = igetc()) == EOF) {
624 c39be742 2021-07-09 op yyerror("reached end of file while parsing "
625 c39be742 2021-07-09 op "quoted string");
626 c39be742 2021-07-09 op if (file == topfile || popfile() == EOF)
627 c39be742 2021-07-09 op return EOF;
628 c39be742 2021-07-09 op return quotec;
629 c39be742 2021-07-09 op }
630 74f0778b 2021-06-16 op return c;
631 74f0778b 2021-06-16 op }
632 74f0778b 2021-06-16 op
633 c39be742 2021-07-09 op while ((c = igetc()) == '\\') {
634 c39be742 2021-07-09 op next = igetc();
635 c39be742 2021-07-09 op if (next != '\n') {
636 c39be742 2021-07-09 op c = next;
637 74f0778b 2021-06-16 op break;
638 c39be742 2021-07-09 op }
639 c39be742 2021-07-09 op yylval.lineno = file->lineno;
640 c39be742 2021-07-09 op file->lineno++;
641 c39be742 2021-07-09 op }
642 3b21cca3 2021-06-29 op
643 c39be742 2021-07-09 op if (c == EOF) {
644 c39be742 2021-07-09 op /*
645 c39be742 2021-07-09 op * Fake EOL when hit EOF for the first time. This gets line
646 c39be742 2021-07-09 op * count right if last line in included file is syntactically
647 c39be742 2021-07-09 op * invalid and has no newline.
648 c39be742 2021-07-09 op */
649 c39be742 2021-07-09 op if (file->eof_reached == 0) {
650 c39be742 2021-07-09 op file->eof_reached = 1;
651 c39be742 2021-07-09 op return '\n';
652 c39be742 2021-07-09 op }
653 c39be742 2021-07-09 op while (c == EOF) {
654 c39be742 2021-07-09 op if (file == topfile || popfile() == EOF)
655 c39be742 2021-07-09 op return EOF;
656 c39be742 2021-07-09 op c = igetc();
657 c39be742 2021-07-09 op }
658 c39be742 2021-07-09 op }
659 c39be742 2021-07-09 op return c;
660 c39be742 2021-07-09 op }
661 c39be742 2021-07-09 op
662 c39be742 2021-07-09 op void
663 c39be742 2021-07-09 op lungetc(int c)
664 c39be742 2021-07-09 op {
665 c39be742 2021-07-09 op if (c == EOF)
666 c39be742 2021-07-09 op return;
667 c39be742 2021-07-09 op
668 c39be742 2021-07-09 op if (file->ungetpos >= file->ungetsize) {
669 c39be742 2021-07-09 op void *p = reallocarray(file->ungetbuf, file->ungetsize, 2);
670 c39be742 2021-07-09 op if (p == NULL)
671 2dd5994a 2023-06-06 op fatal("lungetc");
672 c39be742 2021-07-09 op file->ungetbuf = p;
673 c39be742 2021-07-09 op file->ungetsize *= 2;
674 c39be742 2021-07-09 op }
675 c39be742 2021-07-09 op file->ungetbuf[file->ungetpos++] = c;
676 c39be742 2021-07-09 op }
677 c39be742 2021-07-09 op
678 c39be742 2021-07-09 op int
679 c39be742 2021-07-09 op findeol(void)
680 c39be742 2021-07-09 op {
681 c39be742 2021-07-09 op int c;
682 c39be742 2021-07-09 op
683 c39be742 2021-07-09 op /* Skip to either EOF or the first real EOL. */
684 c39be742 2021-07-09 op while (1) {
685 c39be742 2021-07-09 op c = lgetc(0);
686 c39be742 2021-07-09 op if (c == '\n') {
687 c39be742 2021-07-09 op file->lineno++;
688 3b21cca3 2021-06-29 op break;
689 c39be742 2021-07-09 op }
690 c39be742 2021-07-09 op if (c == EOF)
691 74f0778b 2021-06-16 op break;
692 c39be742 2021-07-09 op }
693 c39be742 2021-07-09 op return ERROR;
694 c39be742 2021-07-09 op }
695 c39be742 2021-07-09 op
696 c39be742 2021-07-09 op int
697 c39be742 2021-07-09 op yylex(void)
698 c39be742 2021-07-09 op {
699 1bd706dc 2021-07-09 op char buf[8096];
700 1bd706dc 2021-07-09 op char *p, *val;
701 1bd706dc 2021-07-09 op int quotec, next, c;
702 1bd706dc 2021-07-09 op int token;
703 c39be742 2021-07-09 op
704 c39be742 2021-07-09 op top:
705 c39be742 2021-07-09 op p = buf;
706 c39be742 2021-07-09 op while ((c = lgetc(0)) == ' ' || c == '\t')
707 c39be742 2021-07-09 op ; /* nothing */
708 c39be742 2021-07-09 op
709 c39be742 2021-07-09 op yylval.lineno = file->lineno;
710 c39be742 2021-07-09 op if (c == '#')
711 c39be742 2021-07-09 op while ((c = lgetc(0)) != '\n' && c != EOF)
712 c39be742 2021-07-09 op ; /* nothing */
713 c39be742 2021-07-09 op if (c == '$' && !expanding) {
714 c39be742 2021-07-09 op while (1) {
715 c39be742 2021-07-09 op if ((c = lgetc(0)) == EOF)
716 c39be742 2021-07-09 op return 0;
717 67f49405 2021-07-09 op if (p + 1 >= buf + sizeof(buf) -1) {
718 67f49405 2021-07-09 op yyerror("string too long");
719 67f49405 2021-07-09 op return findeol();
720 67f49405 2021-07-09 op }
721 67f49405 2021-07-09 op if (isalnum(c) || c == '_') {
722 67f49405 2021-07-09 op *p++ = c;
723 67f49405 2021-07-09 op continue;
724 67f49405 2021-07-09 op }
725 67f49405 2021-07-09 op *p = '\0';
726 67f49405 2021-07-09 op lungetc(c);
727 67f49405 2021-07-09 op break;
728 67f49405 2021-07-09 op }
729 67f49405 2021-07-09 op val = symget(buf);
730 67f49405 2021-07-09 op if (val == NULL) {
731 67f49405 2021-07-09 op yyerror("macro `%s' not defined", buf);
732 67f49405 2021-07-09 op return findeol();
733 67f49405 2021-07-09 op }
734 67f49405 2021-07-09 op yylval.v.string = xstrdup(val);
735 67f49405 2021-07-09 op return STRING;
736 67f49405 2021-07-09 op }
737 67f49405 2021-07-09 op if (c == '@' && !expanding) {
738 67f49405 2021-07-09 op while (1) {
739 67f49405 2021-07-09 op if ((c = lgetc(0)) == EOF)
740 67f49405 2021-07-09 op return 0;
741 c39be742 2021-07-09 op
742 c39be742 2021-07-09 op if (p + 1 >= buf + sizeof(buf) - 1) {
743 c39be742 2021-07-09 op yyerror("string too long");
744 c39be742 2021-07-09 op return findeol();
745 c39be742 2021-07-09 op }
746 c39be742 2021-07-09 op if (isalnum(c) || c == '_') {
747 c39be742 2021-07-09 op *p++ = c;
748 74f0778b 2021-06-16 op continue;
749 74f0778b 2021-06-16 op }
750 c39be742 2021-07-09 op *p = '\0';
751 c39be742 2021-07-09 op lungetc(c);
752 c39be742 2021-07-09 op break;
753 74f0778b 2021-06-16 op }
754 c39be742 2021-07-09 op val = symget(buf);
755 c39be742 2021-07-09 op if (val == NULL) {
756 c39be742 2021-07-09 op yyerror("macro '%s' not defined", buf);
757 c39be742 2021-07-09 op return findeol();
758 74f0778b 2021-06-16 op }
759 c39be742 2021-07-09 op p = val + strlen(val) - 1;
760 c39be742 2021-07-09 op lungetc(DONE_EXPAND);
761 c39be742 2021-07-09 op while (p >= val) {
762 c39be742 2021-07-09 op lungetc(*p);
763 c39be742 2021-07-09 op p--;
764 c39be742 2021-07-09 op }
765 c39be742 2021-07-09 op lungetc(START_EXPAND);
766 c39be742 2021-07-09 op goto top;
767 74f0778b 2021-06-16 op }
768 74f0778b 2021-06-16 op
769 c39be742 2021-07-09 op switch (c) {
770 c39be742 2021-07-09 op case '\'':
771 c39be742 2021-07-09 op case '"':
772 c39be742 2021-07-09 op quotec = c;
773 c39be742 2021-07-09 op while (1) {
774 c39be742 2021-07-09 op if ((c = lgetc(quotec)) == EOF)
775 c39be742 2021-07-09 op return 0;
776 c39be742 2021-07-09 op if (c == '\n') {
777 c39be742 2021-07-09 op file->lineno++;
778 c39be742 2021-07-09 op continue;
779 c39be742 2021-07-09 op } else if (c == '\\') {
780 c39be742 2021-07-09 op if ((next = lgetc(quotec)) == EOF)
781 c39be742 2021-07-09 op return (0);
782 c39be742 2021-07-09 op if (next == quotec || next == ' ' ||
783 c39be742 2021-07-09 op next == '\t')
784 c39be742 2021-07-09 op c = next;
785 c39be742 2021-07-09 op else if (next == '\n') {
786 c39be742 2021-07-09 op file->lineno++;
787 c39be742 2021-07-09 op continue;
788 c39be742 2021-07-09 op } else
789 c39be742 2021-07-09 op lungetc(next);
790 c39be742 2021-07-09 op } else if (c == quotec) {
791 c39be742 2021-07-09 op *p = '\0';
792 c39be742 2021-07-09 op break;
793 c39be742 2021-07-09 op } else if (c == '\0') {
794 f3966209 2021-07-13 op yyerror("invalid syntax");
795 c39be742 2021-07-09 op return findeol();
796 c39be742 2021-07-09 op }
797 c39be742 2021-07-09 op if (p + 1 >= buf + sizeof(buf) - 1) {
798 c39be742 2021-07-09 op yyerror("string too long");
799 c39be742 2021-07-09 op return findeol();
800 c39be742 2021-07-09 op }
801 c39be742 2021-07-09 op *p++ = c;
802 c39be742 2021-07-09 op }
803 c39be742 2021-07-09 op yylval.v.string = strdup(buf);
804 c39be742 2021-07-09 op if (yylval.v.string == NULL)
805 2dd5994a 2023-06-06 op fatal("yylex: strdup");
806 c39be742 2021-07-09 op return STRING;
807 74f0778b 2021-06-16 op }
808 c39be742 2021-07-09 op
809 c39be742 2021-07-09 op #define allowed_to_end_number(x) \
810 c39be742 2021-07-09 op (isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=')
811 c39be742 2021-07-09 op
812 c39be742 2021-07-09 op if (c == '-' || isdigit(c)) {
813 c39be742 2021-07-09 op do {
814 c39be742 2021-07-09 op *p++ = c;
815 c39be742 2021-07-09 op if ((size_t)(p-buf) >= sizeof(buf)) {
816 c39be742 2021-07-09 op yyerror("string too long");
817 c39be742 2021-07-09 op return findeol();
818 c39be742 2021-07-09 op }
819 c39be742 2021-07-09 op } while ((c = lgetc(0)) != EOF && isdigit(c));
820 c39be742 2021-07-09 op lungetc(c);
821 c39be742 2021-07-09 op if (p == buf + 1 && buf[0] == '-')
822 c39be742 2021-07-09 op goto nodigits;
823 c39be742 2021-07-09 op if (c == EOF || allowed_to_end_number(c)) {
824 c39be742 2021-07-09 op const char *errstr = NULL;
825 c39be742 2021-07-09 op
826 c39be742 2021-07-09 op *p = '\0';
827 c39be742 2021-07-09 op yylval.v.number = strtonum(buf, LLONG_MIN,
828 c39be742 2021-07-09 op LLONG_MAX, &errstr);
829 c39be742 2021-07-09 op if (errstr) {
830 c39be742 2021-07-09 op yyerror("\"%s\" invalid number: %s",
831 c39be742 2021-07-09 op buf, errstr);
832 c39be742 2021-07-09 op return findeol();
833 c39be742 2021-07-09 op }
834 c39be742 2021-07-09 op return NUM;
835 c39be742 2021-07-09 op } else {
836 c39be742 2021-07-09 op nodigits:
837 c39be742 2021-07-09 op while (p > buf + 1)
838 c39be742 2021-07-09 op lungetc(*--p);
839 c39be742 2021-07-09 op c = *--p;
840 c39be742 2021-07-09 op if (c == '-')
841 c39be742 2021-07-09 op return c;
842 c39be742 2021-07-09 op }
843 74f0778b 2021-06-16 op }
844 c39be742 2021-07-09 op
845 c39be742 2021-07-09 op #define allowed_in_string(x) \
846 c39be742 2021-07-09 op (isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
847 c39be742 2021-07-09 op x != '{' && x != '}' && \
848 c39be742 2021-07-09 op x != '!' && x != '=' && x != '#' && \
849 67f49405 2021-07-09 op x != ',' && x != ';'))
850 c39be742 2021-07-09 op
851 67f49405 2021-07-09 op if (isalnum(c) || c == ':' || c == '_') {
852 c39be742 2021-07-09 op do {
853 c39be742 2021-07-09 op *p++ = c;
854 c39be742 2021-07-09 op if ((size_t)(p-buf) >= sizeof(buf)) {
855 c39be742 2021-07-09 op yyerror("string too long");
856 c39be742 2021-07-09 op return findeol();
857 c39be742 2021-07-09 op }
858 c39be742 2021-07-09 op } while ((c = lgetc(0)) != EOF && (allowed_in_string(c)));
859 c39be742 2021-07-09 op lungetc(c);
860 c39be742 2021-07-09 op *p = '\0';
861 c39be742 2021-07-09 op if ((token = lookup(buf)) == STRING)
862 c39be742 2021-07-09 op yylval.v.string = xstrdup(buf);
863 c39be742 2021-07-09 op return token;
864 74f0778b 2021-06-16 op }
865 c39be742 2021-07-09 op if (c == '\n') {
866 c39be742 2021-07-09 op yylval.lineno = file->lineno;
867 c39be742 2021-07-09 op file->lineno++;
868 74f0778b 2021-06-16 op }
869 c39be742 2021-07-09 op if (c == EOF)
870 c39be742 2021-07-09 op return 0;
871 c39be742 2021-07-09 op return c;
872 c39be742 2021-07-09 op }
873 c39be742 2021-07-09 op
874 c39be742 2021-07-09 op struct file *
875 c39be742 2021-07-09 op pushfile(const char *name, int secret)
876 c39be742 2021-07-09 op {
877 c39be742 2021-07-09 op struct file *nfile;
878 c39be742 2021-07-09 op
879 c39be742 2021-07-09 op nfile = xcalloc(1, sizeof(*nfile));
880 c39be742 2021-07-09 op nfile->name = xstrdup(name);
881 c39be742 2021-07-09 op if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
882 eae52ad4 2023-06-06 op log_warn("can't open %s", nfile->name);
883 c39be742 2021-07-09 op free(nfile->name);
884 c39be742 2021-07-09 op free(nfile);
885 c39be742 2021-07-09 op return NULL;
886 74f0778b 2021-06-16 op }
887 c39be742 2021-07-09 op nfile->lineno = TAILQ_EMPTY(&files) ? 1 : 0;
888 c39be742 2021-07-09 op nfile->ungetsize = 16;
889 c39be742 2021-07-09 op nfile->ungetbuf = xcalloc(1, nfile->ungetsize);
890 c39be742 2021-07-09 op TAILQ_INSERT_TAIL(&files, nfile, entry);
891 c39be742 2021-07-09 op return nfile;
892 c39be742 2021-07-09 op }
893 74f0778b 2021-06-16 op
894 c39be742 2021-07-09 op int
895 c39be742 2021-07-09 op popfile(void)
896 c39be742 2021-07-09 op {
897 c39be742 2021-07-09 op struct file *prev;
898 13ed2fb6 2021-01-27 op
899 c39be742 2021-07-09 op if ((prev = TAILQ_PREV(file, files, entry)) != NULL)
900 c39be742 2021-07-09 op prev->errors += file->errors;
901 13ed2fb6 2021-01-27 op
902 c39be742 2021-07-09 op TAILQ_REMOVE(&files, file, entry);
903 c39be742 2021-07-09 op fclose(file->stream);
904 c39be742 2021-07-09 op free(file->name);
905 c39be742 2021-07-09 op free(file->ungetbuf);
906 c39be742 2021-07-09 op free(file);
907 c39be742 2021-07-09 op file = prev;
908 c39be742 2021-07-09 op return file ? 0 : EOF;
909 13ed2fb6 2021-01-27 op }
910 13ed2fb6 2021-01-27 op
911 68368f4c 2023-06-09 op int
912 af1dab18 2023-06-09 op parse_conf(struct conf *c, const char *filename)
913 13ed2fb6 2021-01-27 op {
914 c39be742 2021-07-09 op struct sym *sym, *next;
915 af1dab18 2023-06-09 op
916 af1dab18 2023-06-09 op conf = c;
917 3b21cca3 2021-06-29 op
918 c39be742 2021-07-09 op file = pushfile(filename, 0);
919 c39be742 2021-07-09 op if (file == NULL)
920 68368f4c 2023-06-09 op return -1;
921 c39be742 2021-07-09 op topfile = file;
922 c39be742 2021-07-09 op
923 13ed2fb6 2021-01-27 op yyparse();
924 c39be742 2021-07-09 op errors = file->errors;
925 c39be742 2021-07-09 op popfile();
926 13ed2fb6 2021-01-27 op
927 c39be742 2021-07-09 op /* Free macros and check which have not been used. */
928 3b21cca3 2021-06-29 op TAILQ_FOREACH_SAFE(sym, &symhead, entry, next) {
929 3b21cca3 2021-06-29 op /* TODO: warn if !sym->used */
930 3b21cca3 2021-06-29 op if (!sym->persist) {
931 3b21cca3 2021-06-29 op free(sym->name);
932 3b21cca3 2021-06-29 op free(sym->val);
933 3b21cca3 2021-06-29 op TAILQ_REMOVE(&symhead, sym, entry);
934 3b21cca3 2021-06-29 op free(sym);
935 3b21cca3 2021-06-29 op }
936 3b21cca3 2021-06-29 op }
937 c39be742 2021-07-09 op
938 c39be742 2021-07-09 op if (errors)
939 68368f4c 2023-06-09 op return -1;
940 68368f4c 2023-06-09 op return 0;
941 13ed2fb6 2021-01-27 op }
942 e17642a7 2021-02-01 op
943 c39be742 2021-07-09 op int
944 c39be742 2021-07-09 op symset(const char *name, const char *val, int persist)
945 c39be742 2021-07-09 op {
946 c39be742 2021-07-09 op struct sym *sym;
947 c39be742 2021-07-09 op
948 c39be742 2021-07-09 op TAILQ_FOREACH(sym, &symhead, entry) {
949 c39be742 2021-07-09 op if (!strcmp(name, sym->name))
950 c39be742 2021-07-09 op break;
951 c39be742 2021-07-09 op }
952 c39be742 2021-07-09 op
953 c39be742 2021-07-09 op if (sym != NULL) {
954 c39be742 2021-07-09 op if (sym->persist)
955 c39be742 2021-07-09 op return 0;
956 c39be742 2021-07-09 op else {
957 c39be742 2021-07-09 op free(sym->name);
958 c39be742 2021-07-09 op free(sym->val);
959 c39be742 2021-07-09 op TAILQ_REMOVE(&symhead, sym, entry);
960 c39be742 2021-07-09 op free(sym);
961 c39be742 2021-07-09 op }
962 c39be742 2021-07-09 op }
963 c39be742 2021-07-09 op
964 c39be742 2021-07-09 op sym = xcalloc(1, sizeof(*sym));
965 c39be742 2021-07-09 op sym->name = xstrdup(name);
966 c39be742 2021-07-09 op sym->val = xstrdup(val);
967 c39be742 2021-07-09 op sym->used = 0;
968 c39be742 2021-07-09 op sym->persist = persist;
969 c39be742 2021-07-09 op
970 c39be742 2021-07-09 op TAILQ_INSERT_TAIL(&symhead, sym, entry);
971 c39be742 2021-07-09 op return 0;
972 c39be742 2021-07-09 op }
973 c39be742 2021-07-09 op
974 c39be742 2021-07-09 op int
975 c39be742 2021-07-09 op cmdline_symset(char *s)
976 c39be742 2021-07-09 op {
977 c39be742 2021-07-09 op char *sym, *val;
978 c39be742 2021-07-09 op int ret;
979 c39be742 2021-07-09 op
980 c39be742 2021-07-09 op if ((val = strrchr(s, '=')) == NULL)
981 c39be742 2021-07-09 op return -1;
982 c39be742 2021-07-09 op sym = xcalloc(1, val - s + 1);
983 c39be742 2021-07-09 op memcpy(sym, s, val - s);
984 c39be742 2021-07-09 op ret = symset(sym, val + 1, 1);
985 c39be742 2021-07-09 op free(sym);
986 c39be742 2021-07-09 op return ret;
987 c39be742 2021-07-09 op }
988 c39be742 2021-07-09 op
989 e17642a7 2021-02-01 op char *
990 c39be742 2021-07-09 op symget(const char *nam)
991 c39be742 2021-07-09 op {
992 c39be742 2021-07-09 op struct sym *sym;
993 c39be742 2021-07-09 op
994 c39be742 2021-07-09 op TAILQ_FOREACH(sym, &symhead, entry) {
995 c39be742 2021-07-09 op if (strcmp(nam, sym->name) == 0) {
996 c39be742 2021-07-09 op sym->used = 1;
997 c39be742 2021-07-09 op return sym->val;
998 c39be742 2021-07-09 op }
999 c39be742 2021-07-09 op }
1000 c39be742 2021-07-09 op return NULL;
1001 c39be742 2021-07-09 op }
1002 c39be742 2021-07-09 op
1003 c39be742 2021-07-09 op char *
1004 e17642a7 2021-02-01 op ensure_absolute_path(char *path)
1005 e17642a7 2021-02-01 op {
1006 e17642a7 2021-02-01 op if (path == NULL || *path != '/')
1007 adbe6a64 2021-04-30 op yyerror("not an absolute path: %s", path);
1008 e17642a7 2021-02-01 op return path;
1009 e17642a7 2021-02-01 op }
1010 6abda252 2021-02-06 op
1011 6abda252 2021-02-06 op int
1012 6abda252 2021-02-06 op check_block_code(int n)
1013 6abda252 2021-02-06 op {
1014 6abda252 2021-02-06 op if (n < 10 || n >= 70 || (n >= 20 && n <= 29))
1015 6abda252 2021-02-06 op yyerror("invalid block code %d", n);
1016 6abda252 2021-02-06 op return n;
1017 6abda252 2021-02-06 op }
1018 6abda252 2021-02-06 op
1019 6abda252 2021-02-06 op char *
1020 6abda252 2021-02-06 op check_block_fmt(char *fmt)
1021 6abda252 2021-02-06 op {
1022 6abda252 2021-02-06 op char *s;
1023 6abda252 2021-02-06 op
1024 6abda252 2021-02-06 op for (s = fmt; *s; ++s) {
1025 6abda252 2021-02-06 op if (*s != '%')
1026 6abda252 2021-02-06 op continue;
1027 6abda252 2021-02-06 op switch (*++s) {
1028 6abda252 2021-02-06 op case '%':
1029 6abda252 2021-02-06 op case 'p':
1030 6abda252 2021-02-06 op case 'q':
1031 6abda252 2021-02-06 op case 'P':
1032 6abda252 2021-02-06 op case 'N':
1033 6abda252 2021-02-06 op break;
1034 6abda252 2021-02-06 op default:
1035 6abda252 2021-02-06 op yyerror("invalid format specifier %%%c", *s);
1036 6abda252 2021-02-06 op }
1037 6abda252 2021-02-06 op }
1038 6abda252 2021-02-06 op
1039 6abda252 2021-02-06 op return fmt;
1040 6abda252 2021-02-06 op }
1041 6abda252 2021-02-06 op
1042 6abda252 2021-02-06 op int
1043 6abda252 2021-02-06 op check_strip_no(int n)
1044 6abda252 2021-02-06 op {
1045 6abda252 2021-02-06 op if (n <= 0)
1046 6abda252 2021-02-06 op yyerror("invalid strip number %d", n);
1047 a709ddf5 2021-02-07 op return n;
1048 a709ddf5 2021-02-07 op }
1049 a709ddf5 2021-02-07 op
1050 a709ddf5 2021-02-07 op int
1051 391825e3 2021-07-09 op check_port_num(int n)
1052 391825e3 2021-07-09 op {
1053 391825e3 2021-07-09 op if (n <= 0 || n >= UINT16_MAX)
1054 391825e3 2021-07-09 op yyerror("port number is %s: %d",
1055 391825e3 2021-07-09 op n <= 0 ? "too small" : "too large",
1056 391825e3 2021-07-09 op n);
1057 391825e3 2021-07-09 op return n;
1058 391825e3 2021-07-09 op }
1059 391825e3 2021-07-09 op
1060 391825e3 2021-07-09 op int
1061 a709ddf5 2021-02-07 op check_prefork_num(int n)
1062 a709ddf5 2021-02-07 op {
1063 c26f2460 2023-06-08 op if (n <= 0 || n >= PROC_MAX_INSTANCES)
1064 a709ddf5 2021-02-07 op yyerror("invalid prefork number %d", n);
1065 6abda252 2021-02-06 op return n;
1066 6abda252 2021-02-06 op }
1067 49b73ba1 2021-02-10 op
1068 49b73ba1 2021-02-10 op void
1069 49b73ba1 2021-02-10 op advance_loc(void)
1070 49b73ba1 2021-02-10 op {
1071 b8e64ccd 2021-03-31 op loc = new_location();
1072 b8e64ccd 2021-03-31 op TAILQ_INSERT_TAIL(&host->locations, loc, locations);
1073 49b73ba1 2021-02-10 op }
1074 c705ecb1 2021-05-03 op
1075 c705ecb1 2021-05-03 op void
1076 b7967bc1 2022-01-02 op advance_proxy(void)
1077 b7967bc1 2022-01-02 op {
1078 b7967bc1 2022-01-02 op proxy = new_proxy();
1079 b7967bc1 2022-01-02 op TAILQ_INSERT_TAIL(&host->proxies, proxy, proxies);
1080 b7967bc1 2022-01-02 op }
1081 b7967bc1 2022-01-02 op
1082 b7967bc1 2022-01-02 op void
1083 b7967bc1 2022-01-02 op parsehp(char *str, char **host, const char **port, const char *def)
1084 b7967bc1 2022-01-02 op {
1085 b7967bc1 2022-01-02 op char *at;
1086 b7967bc1 2022-01-02 op const char *errstr;
1087 b7967bc1 2022-01-02 op
1088 b7967bc1 2022-01-02 op *host = str;
1089 b7967bc1 2022-01-02 op
1090 b7967bc1 2022-01-02 op if ((at = strchr(str, ':')) != NULL) {
1091 b7967bc1 2022-01-02 op *at++ = '\0';
1092 b7967bc1 2022-01-02 op *port = at;
1093 b7967bc1 2022-01-02 op } else
1094 b7967bc1 2022-01-02 op *port = def;
1095 b7967bc1 2022-01-02 op
1096 b7967bc1 2022-01-02 op strtonum(*port, 1, UINT16_MAX, &errstr);
1097 b7967bc1 2022-01-02 op if (errstr != NULL)
1098 b7967bc1 2022-01-02 op yyerror("port is %s: %s", errstr, *port);
1099 8ad1c570 2021-05-09 op }
1100 8ad1c570 2021-05-09 op
1101 8ad1c570 2021-05-09 op int
1102 7b00c890 2022-10-05 op fastcgi_conf(const char *path, const char *port)
1103 8ad1c570 2021-05-09 op {
1104 8ad1c570 2021-05-09 op struct fcgi *f;
1105 5d22294a 2023-06-09 op int i = 0;
1106 fafc6849 2021-06-29 op
1107 af1dab18 2023-06-09 op TAILQ_FOREACH(f, &conf->fcgi, fcgi) {
1108 8ad1c570 2021-05-09 op if (!strcmp(f->path, path) &&
1109 534afd0d 2022-10-05 op ((port == NULL && *f->port == '\0') ||
1110 534afd0d 2022-10-05 op !strcmp(f->port, port)))
1111 8ad1c570 2021-05-09 op return i;
1112 5d22294a 2023-06-09 op ++i;
1113 8ad1c570 2021-05-09 op }
1114 8ad1c570 2021-05-09 op
1115 5d22294a 2023-06-09 op f = xcalloc(1, sizeof(*f));
1116 5d22294a 2023-06-09 op f->id = i;
1117 5d22294a 2023-06-09 op (void)strlcpy(f->path, path, sizeof(f->path));
1118 5d22294a 2023-06-09 op if (port != NULL)
1119 5d22294a 2023-06-09 op (void)strlcpy(f->port, port, sizeof(f->port));
1120 af1dab18 2023-06-09 op TAILQ_INSERT_TAIL(&conf->fcgi, f, fcgi);
1121 5d22294a 2023-06-09 op
1122 5d22294a 2023-06-09 op return f->id;
1123 c92b802b 2021-06-11 op }
1124 c92b802b 2021-06-11 op
1125 c92b802b 2021-06-11 op void
1126 2025e96d 2022-09-10 op add_param(char *name, char *val)
1127 c92b802b 2021-06-11 op {
1128 c92b802b 2021-06-11 op struct envlist *e;
1129 2025e96d 2022-09-10 op struct envhead *h = &host->params;
1130 c92b802b 2021-06-11 op
1131 c92b802b 2021-06-11 op e = xcalloc(1, sizeof(*e));
1132 534afd0d 2022-10-05 op (void) strlcpy(e->name, name, sizeof(e->name));
1133 534afd0d 2022-10-05 op (void) strlcpy(e->value, val, sizeof(e->value));
1134 edc5ca66 2022-09-10 op TAILQ_INSERT_TAIL(h, e, envs);
1135 3b21cca3 2021-06-29 op }
1136 534afd0d 2022-10-05 op
1137 534afd0d 2022-10-05 op int
1138 534afd0d 2022-10-05 op getservice(const char *n)
1139 534afd0d 2022-10-05 op {
1140 534afd0d 2022-10-05 op struct servent *s;
1141 534afd0d 2022-10-05 op const char *errstr;
1142 534afd0d 2022-10-05 op long long llval;
1143 534afd0d 2022-10-05 op
1144 534afd0d 2022-10-05 op llval = strtonum(n, 0, UINT16_MAX, &errstr);
1145 534afd0d 2022-10-05 op if (errstr) {
1146 534afd0d 2022-10-05 op s = getservbyname(n, "tcp");
1147 534afd0d 2022-10-05 op if (s == NULL)
1148 534afd0d 2022-10-05 op s = getservbyname(n, "udp");
1149 534afd0d 2022-10-05 op if (s == NULL)
1150 534afd0d 2022-10-05 op return (-1);
1151 534afd0d 2022-10-05 op return (ntohs(s->s_port));
1152 534afd0d 2022-10-05 op }
1153 534afd0d 2022-10-05 op
1154 534afd0d 2022-10-05 op return ((unsigned short)llval);
1155 534afd0d 2022-10-05 op }