xref: /openbsd/usr.sbin/httpd/parse.y (revision d415bd75)
1 /*	$OpenBSD: parse.y,v 1.128 2022/02/27 20:30:30 bluhm Exp $	*/
2 
3 /*
4  * Copyright (c) 2020 Matthias Pressfreund <mpfr@fn.de>
5  * Copyright (c) 2007 - 2015 Reyk Floeter <reyk@openbsd.org>
6  * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
7  * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org>
8  * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
9  * Copyright (c) 2004 Ryan McBride <mcbride@openbsd.org>
10  * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
11  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
12  * Copyright (c) 2001 Daniel Hartmeier.  All rights reserved.
13  * Copyright (c) 2001 Theo de Raadt.  All rights reserved.
14  *
15  * Permission to use, copy, modify, and distribute this software for any
16  * purpose with or without fee is hereby granted, provided that the above
17  * copyright notice and this permission notice appear in all copies.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
20  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
21  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
22  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
23  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
24  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
25  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
26  */
27 
28 %{
29 #include <sys/types.h>
30 #include <sys/socket.h>
31 #include <sys/un.h>
32 #include <sys/stat.h>
33 #include <sys/queue.h>
34 #include <sys/tree.h>
35 #include <sys/ioctl.h>
36 #include <sys/sockio.h>
37 #include <sys/time.h>
38 
39 #include <net/if.h>
40 #include <netinet/in.h>
41 #include <arpa/inet.h>
42 
43 #include <ctype.h>
44 #include <unistd.h>
45 #include <err.h>
46 #include <errno.h>
47 #include <limits.h>
48 #include <stdint.h>
49 #include <stdarg.h>
50 #include <stdio.h>
51 #include <netdb.h>
52 #include <string.h>
53 #include <ifaddrs.h>
54 #include <syslog.h>
55 
56 #include "httpd.h"
57 #include "http.h"
58 
59 TAILQ_HEAD(files, file)		 files = TAILQ_HEAD_INITIALIZER(files);
60 static struct file {
61 	TAILQ_ENTRY(file)	 entry;
62 	FILE			*stream;
63 	char			*name;
64 	size_t			 ungetpos;
65 	size_t			 ungetsize;
66 	u_char			*ungetbuf;
67 	int			 eof_reached;
68 	int			 lineno;
69 	int			 errors;
70 } *file, *topfile;
71 struct file	*pushfile(const char *, int);
72 int		 popfile(void);
73 int		 check_file_secrecy(int, const char *);
74 int		 yyparse(void);
75 int		 yylex(void);
76 int		 yyerror(const char *, ...)
77     __attribute__((__format__ (printf, 1, 2)))
78     __attribute__((__nonnull__ (1)));
79 int		 kw_cmp(const void *, const void *);
80 int		 lookup(char *);
81 int		 igetc(void);
82 int		 lgetc(int);
83 void		 lungetc(int);
84 int		 findeol(void);
85 
86 TAILQ_HEAD(symhead, sym)	 symhead = TAILQ_HEAD_INITIALIZER(symhead);
87 struct sym {
88 	TAILQ_ENTRY(sym)	 entry;
89 	int			 used;
90 	int			 persist;
91 	char			*nam;
92 	char			*val;
93 };
94 int		 symset(const char *, const char *, int);
95 char		*symget(const char *);
96 
97 struct httpd		*conf = NULL;
98 static int		 errors = 0;
99 static int		 loadcfg = 0;
100 uint32_t		 last_server_id = 0;
101 uint32_t		 last_auth_id = 0;
102 
103 static struct server	*srv = NULL, *parentsrv = NULL;
104 static struct server_config *srv_conf = NULL;
105 struct serverlist	 servers;
106 struct media_type	 media;
107 
108 struct address	*host_v4(const char *);
109 struct address	*host_v6(const char *);
110 int		 host_dns(const char *, struct addresslist *,
111 		    int, struct portrange *, const char *, int);
112 int		 host_if(const char *, struct addresslist *,
113 		    int, struct portrange *, const char *, int);
114 int		 host(const char *, struct addresslist *,
115 		    int, struct portrange *, const char *, int);
116 struct server	*server_inherit(struct server *, struct server_config *,
117 		    struct server_config *);
118 int		 listen_on(const char *, int, struct portrange *);
119 int		 getservice(char *);
120 int		 is_if_in_group(const char *, const char *);
121 int		 get_fastcgi_dest(struct server_config *, const char *, char *);
122 void		 remove_locations(struct server_config *);
123 
124 typedef struct {
125 	union {
126 		int64_t			 number;
127 		char			*string;
128 		struct timeval		 tv;
129 		struct portrange	 port;
130 		struct auth		 auth;
131 	} v;
132 	int lineno;
133 } YYSTYPE;
134 
135 %}
136 
137 %token	ACCESS ALIAS AUTO BACKLOG BODY BUFFER CERTIFICATE CHROOT CIPHERS COMMON
138 %token	COMBINED CONNECTION DHE DIRECTORY ECDHE ERR FCGI INDEX IP KEY LIFETIME
139 %token	LISTEN LOCATION LOG LOGDIR MATCH MAXIMUM NO NODELAY OCSP ON PORT PREFORK
140 %token	PROTOCOLS REQUESTS ROOT SACK SERVER SOCKET STRIP STYLE SYSLOG TCP TICKET
141 %token	TIMEOUT TLS TYPE TYPES HSTS MAXAGE SUBDOMAINS DEFAULT PRELOAD REQUEST
142 %token	ERROR INCLUDE AUTHENTICATE WITH BLOCK DROP RETURN PASS REWRITE
143 %token	CA CLIENT CRL OPTIONAL PARAM FORWARDED FOUND NOT
144 %token	ERRDOCS GZIPSTATIC
145 %token	<v.string>	STRING
146 %token  <v.number>	NUMBER
147 %type	<v.port>	port
148 %type	<v.string>	fcgiport
149 %type	<v.number>	opttls optmatch optfound
150 %type	<v.tv>		timeout
151 %type	<v.string>	numberstring optstring
152 %type	<v.auth>	authopts
153 
154 %%
155 
156 grammar		: /* empty */
157 		| grammar include '\n'
158 		| grammar '\n'
159 		| grammar varset '\n'
160 		| grammar main '\n'
161 		| grammar server '\n'
162 		| grammar types '\n'
163 		| grammar error '\n'		{ file->errors++; }
164 		;
165 
166 include		: INCLUDE STRING		{
167 			struct file	*nfile;
168 
169 			if ((nfile = pushfile($2, 0)) == NULL) {
170 				yyerror("failed to include file %s", $2);
171 				free($2);
172 				YYERROR;
173 			}
174 			free($2);
175 
176 			file = nfile;
177 			lungetc('\n');
178 		}
179 		;
180 
181 varset		: STRING '=' STRING	{
182 			char *s = $1;
183 			while (*s++) {
184 				if (isspace((unsigned char)*s)) {
185 					yyerror("macro name cannot contain "
186 					    "whitespace");
187 					free($1);
188 					free($3);
189 					YYERROR;
190 				}
191 			}
192 			if (symset($1, $3, 0) == -1)
193 				fatal("cannot store variable");
194 			free($1);
195 			free($3);
196 		}
197 		;
198 
199 opttls		: /*empty*/	{ $$ = 0; }
200 		| TLS		{ $$ = 1; }
201 		;
202 
203 main		: PREFORK NUMBER	{
204 			if (loadcfg)
205 				break;
206 			if ($2 <= 0 || $2 > PROC_MAX_INSTANCES) {
207 				yyerror("invalid number of preforked "
208 				    "servers: %lld", $2);
209 				YYERROR;
210 			}
211 			conf->sc_prefork_server = $2;
212 		}
213 		| CHROOT STRING		{
214 			conf->sc_chroot = $2;
215 		}
216 		| ERRDOCS STRING	{
217 			if ($2 != NULL && strlcpy(conf->sc_errdocroot, $2,
218 			    sizeof(conf->sc_errdocroot)) >=
219 			    sizeof(conf->sc_errdocroot)) {
220 				yyerror("errdoc root path too long");
221 				free($2);
222 				YYERROR;
223 			}
224 			free($2);
225 			conf->sc_custom_errdocs = 1;
226 		}
227 		| LOGDIR STRING		{
228 			conf->sc_logdir = $2;
229 		}
230 		| DEFAULT TYPE mediastring	{
231 			memcpy(&conf->sc_default_type, &media,
232 			    sizeof(struct media_type));
233 		}
234 		;
235 
236 server		: SERVER optmatch STRING	{
237 			struct server		*s;
238 			struct sockaddr_un	*sun;
239 
240 			if (!loadcfg) {
241 				free($3);
242 				YYACCEPT;
243 			}
244 
245 			if ((s = calloc(1, sizeof (*s))) == NULL)
246 				fatal("out of memory");
247 
248 			if (strlcpy(s->srv_conf.name, $3,
249 			    sizeof(s->srv_conf.name)) >=
250 			    sizeof(s->srv_conf.name)) {
251 				yyerror("server name truncated");
252 				free($3);
253 				free(s);
254 				YYERROR;
255 			}
256 			free($3);
257 
258 			strlcpy(s->srv_conf.root, HTTPD_DOCROOT,
259 			    sizeof(s->srv_conf.root));
260 			strlcpy(s->srv_conf.index, HTTPD_INDEX,
261 			    sizeof(s->srv_conf.index));
262 			strlcpy(s->srv_conf.accesslog, HTTPD_ACCESS_LOG,
263 			    sizeof(s->srv_conf.accesslog));
264 			strlcpy(s->srv_conf.errorlog, HTTPD_ERROR_LOG,
265 			    sizeof(s->srv_conf.errorlog));
266 			s->srv_conf.id = ++last_server_id;
267 			s->srv_conf.parent_id = s->srv_conf.id;
268 			s->srv_s = -1;
269 			s->srv_conf.timeout.tv_sec = SERVER_TIMEOUT;
270 			s->srv_conf.requesttimeout.tv_sec =
271 			    SERVER_REQUESTTIMEOUT;
272 			s->srv_conf.maxrequests = SERVER_MAXREQUESTS;
273 			s->srv_conf.maxrequestbody = SERVER_MAXREQUESTBODY;
274 			s->srv_conf.flags = SRVFLAG_LOG;
275 			if ($2)
276 				s->srv_conf.flags |= SRVFLAG_SERVER_MATCH;
277 			s->srv_conf.logformat = LOG_FORMAT_COMMON;
278 			s->srv_conf.tls_protocols = TLS_PROTOCOLS_DEFAULT;
279 			if ((s->srv_conf.tls_cert_file =
280 			    strdup(HTTPD_TLS_CERT)) == NULL)
281 				fatal("out of memory");
282 			if ((s->srv_conf.tls_key_file =
283 			    strdup(HTTPD_TLS_KEY)) == NULL)
284 				fatal("out of memory");
285 			strlcpy(s->srv_conf.tls_ciphers,
286 			    HTTPD_TLS_CIPHERS,
287 			    sizeof(s->srv_conf.tls_ciphers));
288 			strlcpy(s->srv_conf.tls_dhe_params,
289 			    HTTPD_TLS_DHE_PARAMS,
290 			    sizeof(s->srv_conf.tls_dhe_params));
291 			strlcpy(s->srv_conf.tls_ecdhe_curves,
292 			    HTTPD_TLS_ECDHE_CURVES,
293 			    sizeof(s->srv_conf.tls_ecdhe_curves));
294 
295 			sun = (struct sockaddr_un *)&s->srv_conf.fastcgi_ss;
296 			sun->sun_family = AF_UNIX;
297 			(void)strlcpy(sun->sun_path, HTTPD_FCGI_SOCKET,
298 			    sizeof(sun->sun_path));
299 			sun->sun_len = sizeof(struct sockaddr_un);
300 
301 			s->srv_conf.hsts_max_age = SERVER_HSTS_DEFAULT_AGE;
302 
303 			(void)strlcpy(s->srv_conf.errdocroot,
304 			    conf->sc_errdocroot,
305 			    sizeof(s->srv_conf.errdocroot));
306 			if (conf->sc_custom_errdocs)
307 				s->srv_conf.flags |= SRVFLAG_ERRDOCS;
308 
309 			if (last_server_id == INT_MAX) {
310 				yyerror("too many servers defined");
311 				free(s);
312 				YYERROR;
313 			}
314 			srv = s;
315 			srv_conf = &srv->srv_conf;
316 
317 			SPLAY_INIT(&srv->srv_clients);
318 			TAILQ_INIT(&srv->srv_hosts);
319 			TAILQ_INIT(&srv_conf->fcgiparams);
320 
321 			TAILQ_INSERT_TAIL(&srv->srv_hosts, srv_conf, entry);
322 		} '{' optnl serveropts_l '}'	{
323 			struct server		*s, *sn;
324 			struct server_config	*a, *b;
325 
326 			srv_conf = &srv->srv_conf;
327 
328 			/* Check if the new server already exists. */
329 			if (server_match(srv, 1) != NULL) {
330 				yyerror("server \"%s\" defined twice",
331 				    srv->srv_conf.name);
332 				serverconfig_free(srv_conf);
333 				free(srv);
334 				YYABORT;
335 			}
336 
337 			if (srv->srv_conf.ss.ss_family == AF_UNSPEC) {
338 				yyerror("listen address not specified");
339 				serverconfig_free(srv_conf);
340 				free(srv);
341 				YYERROR;
342 			}
343 
344 			if ((s = server_match(srv, 0)) != NULL) {
345 				if ((s->srv_conf.flags & SRVFLAG_TLS) !=
346 				    (srv->srv_conf.flags & SRVFLAG_TLS)) {
347 					yyerror("server \"%s\": tls and "
348 					    "non-tls on same address/port",
349 					    srv->srv_conf.name);
350 					serverconfig_free(srv_conf);
351 					free(srv);
352 					YYERROR;
353 				}
354 				if (srv->srv_conf.flags & SRVFLAG_TLS &&
355 				    server_tls_cmp(s, srv) != 0) {
356 					yyerror("server \"%s\": tls "
357 					    "configuration mismatch on same "
358 					    "address/port",
359 					    srv->srv_conf.name);
360 					serverconfig_free(srv_conf);
361 					free(srv);
362 					YYERROR;
363 				}
364 			}
365 
366 			if ((srv->srv_conf.flags & SRVFLAG_TLS) &&
367 			    srv->srv_conf.tls_protocols == 0) {
368 				yyerror("server \"%s\": no tls protocols",
369 				    srv->srv_conf.name);
370 				serverconfig_free(srv_conf);
371 				free(srv);
372 				YYERROR;
373 			}
374 
375 			if (server_tls_load_keypair(srv) == -1) {
376 				/* Soft fail as there may be no certificate. */
377 				log_warnx("%s:%d: server \"%s\": failed to "
378 				    "load public/private keys", file->name,
379 				    yylval.lineno, srv->srv_conf.name);
380 
381 				remove_locations(srv_conf);
382 				serverconfig_free(srv_conf);
383 				srv_conf = NULL;
384 				free(srv);
385 				srv = NULL;
386 				break;
387 			}
388 
389 			if (server_tls_load_ca(srv) == -1) {
390 				yyerror("server \"%s\": failed to load "
391 				    "ca cert(s)", srv->srv_conf.name);
392 				serverconfig_free(srv_conf);
393 				free(srv);
394 				YYERROR;
395 			}
396 
397 			if (server_tls_load_crl(srv) == -1) {
398 				yyerror("server \"%s\": failed to load crl(s)",
399 				    srv->srv_conf.name);
400 				serverconfig_free(srv_conf);
401 				free(srv);
402 				YYERROR;
403 			}
404 
405 			if (server_tls_load_ocsp(srv) == -1) {
406 				yyerror("server \"%s\": failed to load "
407 				    "ocsp staple", srv->srv_conf.name);
408 				serverconfig_free(srv_conf);
409 				free(srv);
410 				YYERROR;
411 			}
412 
413 			DPRINTF("adding server \"%s[%u]\"",
414 			    srv->srv_conf.name, srv->srv_conf.id);
415 
416 			TAILQ_INSERT_TAIL(conf->sc_servers, srv, srv_entry);
417 
418 			/*
419 			 * Add aliases and additional listen addresses as
420 			 * individual servers.
421 			 */
422 			TAILQ_FOREACH(a, &srv->srv_hosts, entry) {
423 				/* listen address */
424 				if (a->ss.ss_family == AF_UNSPEC)
425 					continue;
426 				TAILQ_FOREACH(b, &srv->srv_hosts, entry) {
427 					/* alias name */
428 					if (*b->name == '\0' ||
429 					    (b == &srv->srv_conf && b == a))
430 						continue;
431 
432 					if ((sn = server_inherit(srv,
433 					    b, a)) == NULL) {
434 						serverconfig_free(srv_conf);
435 						free(srv);
436 						YYABORT;
437 					}
438 
439 					DPRINTF("adding server \"%s[%u]\"",
440 					    sn->srv_conf.name, sn->srv_conf.id);
441 
442 					TAILQ_INSERT_TAIL(conf->sc_servers,
443 					    sn, srv_entry);
444 				}
445 			}
446 
447 			/* Remove temporary aliases */
448 			TAILQ_FOREACH_SAFE(a, &srv->srv_hosts, entry, b) {
449 				TAILQ_REMOVE(&srv->srv_hosts, a, entry);
450 				if (a == &srv->srv_conf)
451 					continue;
452 				serverconfig_free(a);
453 				free(a);
454 			}
455 
456 			srv = NULL;
457 			srv_conf = NULL;
458 		}
459 		;
460 
461 serveropts_l	: serveropts_l serveroptsl nl
462 		| serveroptsl optnl
463 		;
464 
465 serveroptsl	: LISTEN ON STRING opttls port	{
466 			if (listen_on($3, $4, &$5) == -1) {
467 				free($3);
468 				YYERROR;
469 			}
470 			free($3);
471 		}
472 		| ALIAS optmatch STRING		{
473 			struct server_config	*alias;
474 
475 			if (parentsrv != NULL) {
476 				yyerror("alias inside location");
477 				free($3);
478 				YYERROR;
479 			}
480 
481 			if ((alias = calloc(1, sizeof(*alias))) == NULL)
482 				fatal("out of memory");
483 
484 			if (strlcpy(alias->name, $3, sizeof(alias->name)) >=
485 			    sizeof(alias->name)) {
486 				yyerror("server alias truncated");
487 				free($3);
488 				free(alias);
489 				YYERROR;
490 			}
491 			free($3);
492 
493 			if ($2)
494 				alias->flags |= SRVFLAG_SERVER_MATCH;
495 
496 			TAILQ_INSERT_TAIL(&srv->srv_hosts, alias, entry);
497 		}
498 		| ERRDOCS STRING	{
499 			if (parentsrv != NULL) {
500 				yyerror("errdocs inside location");
501 				YYERROR;
502 			}
503 			if ($2 != NULL && strlcpy(srv->srv_conf.errdocroot, $2,
504 			    sizeof(srv->srv_conf.errdocroot)) >=
505 			    sizeof(srv->srv_conf.errdocroot)) {
506 				yyerror("errdoc root path too long");
507 				free($2);
508 				YYERROR;
509 			}
510 			free($2);
511 			srv->srv_conf.flags |= SRVFLAG_ERRDOCS;
512 		}
513 		| NO ERRDOCS		{
514 			if (parentsrv != NULL) {
515 				yyerror("errdocs inside location");
516 				YYERROR;
517 			}
518 			srv->srv_conf.flags &= ~SRVFLAG_ERRDOCS;
519 		}
520 		| tcpip			{
521 			if (parentsrv != NULL) {
522 				yyerror("tcp flags inside location");
523 				YYERROR;
524 			}
525 		}
526 		| connection		{
527 			if (parentsrv != NULL) {
528 				yyerror("connection options inside location");
529 				YYERROR;
530 			}
531 		}
532 		| tls			{
533 			struct server_config	*sc;
534 			int			 tls_flag = 0;
535 
536 			if (parentsrv != NULL) {
537 				yyerror("tls configuration inside location");
538 				YYERROR;
539 			}
540 
541 			/* Ensure that at least one server has TLS enabled. */
542 			TAILQ_FOREACH(sc, &srv->srv_hosts, entry) {
543 				tls_flag |= (sc->flags & SRVFLAG_TLS);
544 			}
545 			if (tls_flag == 0) {
546 				yyerror("tls options without tls listener");
547 				YYERROR;
548 			}
549 		}
550 		| request
551 		| root
552 		| directory
553 		| logformat
554 		| fastcgi
555 		| authenticate
556 		| gzip_static
557 		| filter
558 		| LOCATION optfound optmatch STRING	{
559 			struct server		*s;
560 			struct sockaddr_un	*sun;
561 
562 			if (srv->srv_conf.ss.ss_family == AF_UNSPEC) {
563 				yyerror("listen address not specified");
564 				free($4);
565 				YYERROR;
566 			}
567 
568 			if (parentsrv != NULL) {
569 				yyerror("location %s inside location", $4);
570 				free($4);
571 				YYERROR;
572 			}
573 
574 			if (!loadcfg) {
575 				free($4);
576 				YYACCEPT;
577 			}
578 
579 			if ((s = calloc(1, sizeof (*s))) == NULL)
580 				fatal("out of memory");
581 
582 			if (strlcpy(s->srv_conf.location, $4,
583 			    sizeof(s->srv_conf.location)) >=
584 			    sizeof(s->srv_conf.location)) {
585 				yyerror("server location truncated");
586 				free($4);
587 				free(s);
588 				YYERROR;
589 			}
590 			free($4);
591 
592 			if (strlcpy(s->srv_conf.name, srv->srv_conf.name,
593 			    sizeof(s->srv_conf.name)) >=
594 			    sizeof(s->srv_conf.name)) {
595 				yyerror("server name truncated");
596 				free(s);
597 				YYERROR;
598 			}
599 
600 			sun = (struct sockaddr_un *)&s->srv_conf.fastcgi_ss;
601 			sun->sun_family = AF_UNIX;
602 			(void)strlcpy(sun->sun_path, HTTPD_FCGI_SOCKET,
603 			    sizeof(sun->sun_path));
604 			sun->sun_len = sizeof(struct sockaddr_un);
605 
606 			s->srv_conf.id = ++last_server_id;
607 			/* A location entry uses the parent id */
608 			s->srv_conf.parent_id = srv->srv_conf.id;
609 			s->srv_conf.flags = SRVFLAG_LOCATION;
610 			if ($2 == 1) {
611 				s->srv_conf.flags &=
612 				    ~SRVFLAG_LOCATION_NOT_FOUND;
613 				s->srv_conf.flags |=
614 				    SRVFLAG_LOCATION_FOUND;
615 			} else if ($2 == -1) {
616 				s->srv_conf.flags &=
617 				    ~SRVFLAG_LOCATION_FOUND;
618 				s->srv_conf.flags |=
619 				    SRVFLAG_LOCATION_NOT_FOUND;
620 			}
621 			if ($3)
622 				s->srv_conf.flags |= SRVFLAG_LOCATION_MATCH;
623 			s->srv_s = -1;
624 			memcpy(&s->srv_conf.ss, &srv->srv_conf.ss,
625 			    sizeof(s->srv_conf.ss));
626 			s->srv_conf.port = srv->srv_conf.port;
627 			s->srv_conf.prefixlen = srv->srv_conf.prefixlen;
628 			s->srv_conf.tls_flags = srv->srv_conf.tls_flags;
629 
630 			if (last_server_id == INT_MAX) {
631 				yyerror("too many servers/locations defined");
632 				free(s);
633 				YYERROR;
634 			}
635 			parentsrv = srv;
636 			srv = s;
637 			srv_conf = &srv->srv_conf;
638 			SPLAY_INIT(&srv->srv_clients);
639 		} '{' optnl serveropts_l '}'	{
640 			struct server	*s = NULL;
641 			uint32_t	 f;
642 
643 			f = SRVFLAG_LOCATION_FOUND |
644 			    SRVFLAG_LOCATION_NOT_FOUND;
645 
646 			TAILQ_FOREACH(s, conf->sc_servers, srv_entry) {
647 				/* Compare locations of same parent server */
648 				if ((s->srv_conf.flags & SRVFLAG_LOCATION) &&
649 				    s->srv_conf.parent_id ==
650 				    srv_conf->parent_id &&
651 				    (s->srv_conf.flags & f) ==
652 				    (srv_conf->flags & f) &&
653 				    strcmp(s->srv_conf.location,
654 				    srv_conf->location) == 0)
655 					break;
656 			}
657 			if (s != NULL) {
658 				yyerror("location \"%s\" defined twice",
659 				    srv->srv_conf.location);
660 				serverconfig_free(srv_conf);
661 				free(srv);
662 				YYABORT;
663 			}
664 
665 			DPRINTF("adding location \"%s\" for \"%s[%u]\"",
666 			    srv->srv_conf.location,
667 			    srv->srv_conf.name, srv->srv_conf.id);
668 
669 			TAILQ_INSERT_TAIL(conf->sc_servers, srv, srv_entry);
670 
671 			srv = parentsrv;
672 			srv_conf = &parentsrv->srv_conf;
673 			parentsrv = NULL;
674 		}
675 		| DEFAULT TYPE mediastring	{
676 			srv_conf->flags |= SRVFLAG_DEFAULT_TYPE;
677 			memcpy(&srv_conf->default_type, &media,
678 			    sizeof(struct media_type));
679 		}
680 		| include
681 		| hsts				{
682 			if (parentsrv != NULL) {
683 				yyerror("hsts inside location");
684 				YYERROR;
685 			}
686 			srv->srv_conf.flags |= SRVFLAG_SERVER_HSTS;
687 		}
688 		;
689 
690 optfound	: /* empty */	{ $$ = 0; }
691 		| FOUND		{ $$ = 1; }
692 		| NOT FOUND	{ $$ = -1; }
693 		;
694 
695 hsts		: HSTS '{' optnl hstsflags_l '}'
696 		| HSTS hstsflags
697 		| HSTS
698 		;
699 
700 hstsflags_l	: hstsflags optcommanl hstsflags_l
701 		| hstsflags optnl
702 		;
703 
704 hstsflags	: MAXAGE NUMBER		{
705 			if ($2 < 0 || $2 > INT_MAX) {
706 				yyerror("invalid number of seconds: %lld", $2);
707 				YYERROR;
708 			}
709 			srv_conf->hsts_max_age = $2;
710 		}
711 		| SUBDOMAINS		{
712 			srv->srv_conf.hsts_flags |= HSTSFLAG_SUBDOMAINS;
713 		}
714 		| PRELOAD		{
715 			srv->srv_conf.hsts_flags |= HSTSFLAG_PRELOAD;
716 		}
717 		;
718 
719 fastcgi		: NO FCGI		{
720 			srv_conf->flags &= ~SRVFLAG_FCGI;
721 			srv_conf->flags |= SRVFLAG_NO_FCGI;
722 		}
723 		| FCGI			{
724 			srv_conf->flags &= ~SRVFLAG_NO_FCGI;
725 			srv_conf->flags |= SRVFLAG_FCGI;
726 		}
727 		| FCGI			{
728 			srv_conf->flags &= ~SRVFLAG_NO_FCGI;
729 			srv_conf->flags |= SRVFLAG_FCGI;
730 		} '{' optnl fcgiflags_l '}'
731 		| FCGI			{
732 			srv_conf->flags &= ~SRVFLAG_NO_FCGI;
733 			srv_conf->flags |= SRVFLAG_FCGI;
734 		} fcgiflags
735 		;
736 
737 fcgiflags_l	: fcgiflags optcommanl fcgiflags_l
738 		| fcgiflags optnl
739 		;
740 
741 fcgiflags	: SOCKET STRING {
742 			struct sockaddr_un *sun;
743 			sun = (struct sockaddr_un *)&srv_conf->fastcgi_ss;
744 			memset(sun, 0, sizeof(*sun));
745 			sun->sun_family = AF_UNIX;
746 			if (strlcpy(sun->sun_path, $2, sizeof(sun->sun_path))
747 			    >= sizeof(sun->sun_path)) {
748 				yyerror("socket path too long");
749 				free($2);
750 				YYERROR;
751 			}
752 			srv_conf->fastcgi_ss.ss_len =
753 			    sizeof(struct sockaddr_un);
754 			free($2);
755 		}
756 		| SOCKET TCP STRING {
757 			if (get_fastcgi_dest(srv_conf, $3, FCGI_DEFAULT_PORT)
758 			    == -1) {
759 				free($3);
760 				YYERROR;
761 			}
762 			free($3);
763 		}
764 		| SOCKET TCP STRING fcgiport {
765 			if (get_fastcgi_dest(srv_conf, $3, $4) == -1) {
766 				free($3);
767 				free($4);
768 				YYERROR;
769 			}
770 			free($3);
771 			free($4);
772 		}
773 		| PARAM STRING STRING	{
774 			struct fastcgi_param	*param;
775 
776 			if ((param = calloc(1, sizeof(*param))) == NULL)
777 				fatal("out of memory");
778 
779 			if (strlcpy(param->name, $2, sizeof(param->name)) >=
780 			    sizeof(param->name)) {
781 				yyerror("fastcgi_param name truncated");
782 				free($2);
783 				free($3);
784 				free(param);
785 				YYERROR;
786 			}
787 			if (strlcpy(param->value, $3, sizeof(param->value)) >=
788 			    sizeof(param->value)) {
789 				yyerror("fastcgi_param value truncated");
790 				free($2);
791 				free($3);
792 				free(param);
793 				YYERROR;
794 			}
795 			free($2);
796 			free($3);
797 
798 			DPRINTF("[%s,%s,%d]: adding param \"%s\" value \"%s\"",
799 			    srv_conf->location, srv_conf->name, srv_conf->id,
800 			    param->name, param->value);
801 			TAILQ_INSERT_HEAD(&srv_conf->fcgiparams, param, entry);
802 		}
803 		| STRIP NUMBER			{
804 			if ($2 < 0 || $2 > INT_MAX) {
805 				yyerror("invalid fastcgi strip number");
806 				YYERROR;
807 			}
808 			srv_conf->fcgistrip = $2;
809 		}
810 		;
811 
812 connection	: CONNECTION '{' optnl conflags_l '}'
813 		| CONNECTION conflags
814 		;
815 
816 conflags_l	: conflags optcommanl conflags_l
817 		| conflags optnl
818 		;
819 
820 conflags	: TIMEOUT timeout		{
821 			memcpy(&srv_conf->timeout, &$2,
822 			    sizeof(struct timeval));
823 		}
824 		| REQUEST TIMEOUT timeout	{
825 			memcpy(&srv_conf->requesttimeout, &$3,
826 			    sizeof(struct timeval));
827 		}
828 		| MAXIMUM REQUESTS NUMBER	{
829 			srv_conf->maxrequests = $3;
830 		}
831 		| MAXIMUM REQUEST BODY NUMBER	{
832 			srv_conf->maxrequestbody = $4;
833 		}
834 		;
835 
836 tls		: TLS '{' optnl tlsopts_l '}'
837 		| TLS tlsopts
838 		;
839 
840 tlsopts_l	: tlsopts optcommanl tlsopts_l
841 		| tlsopts optnl
842 		;
843 
844 tlsopts		: CERTIFICATE STRING		{
845 			free(srv_conf->tls_cert_file);
846 			if ((srv_conf->tls_cert_file = strdup($2)) == NULL)
847 				fatal("out of memory");
848 			free($2);
849 		}
850 		| KEY STRING			{
851 			free(srv_conf->tls_key_file);
852 			if ((srv_conf->tls_key_file = strdup($2)) == NULL)
853 				fatal("out of memory");
854 			free($2);
855 		}
856 		| OCSP STRING			{
857 			free(srv_conf->tls_ocsp_staple_file);
858 			if ((srv_conf->tls_ocsp_staple_file = strdup($2))
859 			    == NULL)
860 				fatal("out of memory");
861 			free($2);
862 		}
863 		| CIPHERS STRING		{
864 			if (strlcpy(srv_conf->tls_ciphers, $2,
865 			    sizeof(srv_conf->tls_ciphers)) >=
866 			    sizeof(srv_conf->tls_ciphers)) {
867 				yyerror("ciphers too long");
868 				free($2);
869 				YYERROR;
870 			}
871 			free($2);
872 		}
873 		| CLIENT CA STRING tlsclientopt {
874 			srv_conf->tls_flags |= TLSFLAG_CA;
875 			free(srv_conf->tls_ca_file);
876 			if ((srv_conf->tls_ca_file = strdup($3)) == NULL)
877 				fatal("out of memory");
878 			free($3);
879 		}
880 		| DHE STRING			{
881 			if (strlcpy(srv_conf->tls_dhe_params, $2,
882 			    sizeof(srv_conf->tls_dhe_params)) >=
883 			    sizeof(srv_conf->tls_dhe_params)) {
884 				yyerror("dhe too long");
885 				free($2);
886 				YYERROR;
887 			}
888 			free($2);
889 		}
890 		| ECDHE STRING			{
891 			if (strlcpy(srv_conf->tls_ecdhe_curves, $2,
892 			    sizeof(srv_conf->tls_ecdhe_curves)) >=
893 			    sizeof(srv_conf->tls_ecdhe_curves)) {
894 				yyerror("ecdhe too long");
895 				free($2);
896 				YYERROR;
897 			}
898 			free($2);
899 		}
900 		| PROTOCOLS STRING		{
901 			if (tls_config_parse_protocols(
902 			    &srv_conf->tls_protocols, $2) != 0) {
903 				yyerror("invalid tls protocols");
904 				free($2);
905 				YYERROR;
906 			}
907 			free($2);
908 		}
909 		| TICKET LIFETIME DEFAULT	{
910 			srv_conf->tls_ticket_lifetime = SERVER_DEF_TLS_LIFETIME;
911 		}
912 		| TICKET LIFETIME NUMBER	{
913 			if ($3 != 0 && $3 < SERVER_MIN_TLS_LIFETIME) {
914 				yyerror("ticket lifetime too small");
915 				YYERROR;
916 			}
917 			if ($3 > SERVER_MAX_TLS_LIFETIME) {
918 				yyerror("ticket lifetime too large");
919 				YYERROR;
920 			}
921 			srv_conf->tls_ticket_lifetime = $3;
922 		}
923 		| NO TICKET			{
924 			srv_conf->tls_ticket_lifetime = 0;
925 		}
926 		;
927 
928 tlsclientopt	: /* empty */
929 		| tlsclientopt CRL STRING	{
930 			srv_conf->tls_flags = TLSFLAG_CRL;
931 			free(srv_conf->tls_crl_file);
932 			if ((srv_conf->tls_crl_file = strdup($3)) == NULL)
933 				fatal("out of memory");
934 			free($3);
935 		}
936 		| tlsclientopt OPTIONAL		{
937 			srv_conf->tls_flags |= TLSFLAG_OPTIONAL;
938 		}
939 		;
940 root		: ROOT rootflags
941 		| ROOT '{' optnl rootflags_l '}'
942 		;
943 
944 rootflags_l	: rootflags optcommanl rootflags_l
945 		| rootflags optnl
946 		;
947 
948 rootflags	: STRING		{
949 			if (strlcpy(srv->srv_conf.root, $1,
950 			    sizeof(srv->srv_conf.root)) >=
951 			    sizeof(srv->srv_conf.root)) {
952 				yyerror("document root too long");
953 				free($1);
954 				YYERROR;
955 			}
956 			free($1);
957 			srv->srv_conf.flags |= SRVFLAG_ROOT;
958 		}
959 		;
960 
961 request		: REQUEST requestflags
962 		| REQUEST '{' optnl requestflags_l '}'
963 		;
964 
965 requestflags_l	: requestflags optcommanl requestflags_l
966 		| requestflags optnl
967 		;
968 
969 requestflags	: REWRITE STRING		{
970 			if (strlcpy(srv->srv_conf.path, $2,
971 			    sizeof(srv->srv_conf.path)) >=
972 			    sizeof(srv->srv_conf.path)) {
973 				yyerror("request path too long");
974 				free($2);
975 				YYERROR;
976 			}
977 			free($2);
978 			srv->srv_conf.flags |= SRVFLAG_PATH_REWRITE;
979 			srv->srv_conf.flags &= ~SRVFLAG_NO_PATH_REWRITE;
980 		}
981 		| NO REWRITE			{
982 			srv->srv_conf.flags |= SRVFLAG_NO_PATH_REWRITE;
983 			srv->srv_conf.flags &= ~SRVFLAG_PATH_REWRITE;
984 		}
985 		| STRIP NUMBER			{
986 			if ($2 < 0 || $2 > INT_MAX) {
987 				yyerror("invalid strip number");
988 				YYERROR;
989 			}
990 			srv->srv_conf.strip = $2;
991 		}
992 		;
993 
994 authenticate	: NO AUTHENTICATE		{
995 			srv->srv_conf.flags |= SRVFLAG_NO_AUTH;
996 		}
997 		| AUTHENTICATE authopts		{
998 			struct auth	*auth;
999 
1000 			if ((auth = auth_add(conf->sc_auth, &$2)) == NULL) {
1001 				yyerror("failed to add auth");
1002 				YYERROR;
1003 			}
1004 
1005 			if (auth->auth_id == 0) {
1006 				/* New htpasswd, get new Id */
1007 				auth->auth_id = ++last_auth_id;
1008 				if (last_auth_id == INT_MAX) {
1009 					yyerror("too many auth ids defined");
1010 					auth_free(conf->sc_auth, auth);
1011 					YYERROR;
1012 				}
1013 			}
1014 
1015 			srv->srv_conf.auth_id = auth->auth_id;
1016 			srv->srv_conf.flags |= SRVFLAG_AUTH;
1017 		}
1018 		;
1019 
1020 authopts	: STRING WITH STRING	{
1021 			if (strlcpy(srv->srv_conf.auth_realm, $1,
1022 			    sizeof(srv->srv_conf.auth_realm)) >=
1023 			    sizeof(srv->srv_conf.auth_realm)) {
1024 				yyerror("basic auth realm name too long");
1025 				free($1);
1026 				YYERROR;
1027 			}
1028 			free($1);
1029 			if (strlcpy($$.auth_htpasswd, $3,
1030 			    sizeof($$.auth_htpasswd)) >=
1031 			    sizeof($$.auth_htpasswd)) {
1032 				yyerror("password file name too long");
1033 				free($3);
1034 				YYERROR;
1035 			}
1036 			free($3);
1037 
1038 		}
1039 		| WITH STRING		{
1040 			if (strlcpy($$.auth_htpasswd, $2,
1041 			    sizeof($$.auth_htpasswd)) >=
1042 			    sizeof($$.auth_htpasswd)) {
1043 				yyerror("password file name too long");
1044 				free($2);
1045 				YYERROR;
1046 			}
1047 			free($2);
1048 		};
1049 
1050 directory	: DIRECTORY dirflags
1051 		| DIRECTORY '{' optnl dirflags_l '}'
1052 		;
1053 
1054 dirflags_l	: dirflags optcommanl dirflags_l
1055 		| dirflags optnl
1056 		;
1057 
1058 dirflags	: INDEX STRING		{
1059 			if (strlcpy(srv_conf->index, $2,
1060 			    sizeof(srv_conf->index)) >=
1061 			    sizeof(srv_conf->index)) {
1062 				yyerror("index file too long");
1063 				free($2);
1064 				YYERROR;
1065 			}
1066 			srv_conf->flags &= ~SRVFLAG_NO_INDEX;
1067 			srv_conf->flags |= SRVFLAG_INDEX;
1068 			free($2);
1069 		}
1070 		| NO INDEX		{
1071 			srv_conf->flags &= ~SRVFLAG_INDEX;
1072 			srv_conf->flags |= SRVFLAG_NO_INDEX;
1073 		}
1074 		| AUTO INDEX		{
1075 			srv_conf->flags &= ~SRVFLAG_NO_AUTO_INDEX;
1076 			srv_conf->flags |= SRVFLAG_AUTO_INDEX;
1077 		}
1078 		| NO AUTO INDEX		{
1079 			srv_conf->flags &= ~SRVFLAG_AUTO_INDEX;
1080 			srv_conf->flags |= SRVFLAG_NO_AUTO_INDEX;
1081 		}
1082 		;
1083 
1084 
1085 logformat	: LOG logflags
1086 		| LOG '{' optnl logflags_l '}'
1087 		| NO LOG		{
1088 			srv_conf->flags &= ~SRVFLAG_LOG;
1089 			srv_conf->flags |= SRVFLAG_NO_LOG;
1090 		}
1091 		;
1092 
1093 logflags_l	: logflags optcommanl logflags_l
1094 		| logflags optnl
1095 		;
1096 
1097 logflags	: STYLE logstyle
1098 		| SYSLOG		{
1099 			srv_conf->flags &= ~SRVFLAG_NO_SYSLOG;
1100 			srv_conf->flags |= SRVFLAG_SYSLOG;
1101 		}
1102 		| NO SYSLOG		{
1103 			srv_conf->flags &= ~SRVFLAG_SYSLOG;
1104 			srv_conf->flags |= SRVFLAG_NO_SYSLOG;
1105 		}
1106 		| ACCESS STRING		{
1107 			if (strlcpy(srv_conf->accesslog, $2,
1108 			    sizeof(srv_conf->accesslog)) >=
1109 			    sizeof(srv_conf->accesslog)) {
1110 				yyerror("access log name too long");
1111 				free($2);
1112 				YYERROR;
1113 			}
1114 			free($2);
1115 			srv_conf->flags |= SRVFLAG_ACCESS_LOG;
1116 		}
1117 		| ERR STRING		{
1118 			if (strlcpy(srv_conf->errorlog, $2,
1119 			    sizeof(srv_conf->errorlog)) >=
1120 			    sizeof(srv_conf->errorlog)) {
1121 				yyerror("error log name too long");
1122 				free($2);
1123 				YYERROR;
1124 			}
1125 			free($2);
1126 			srv_conf->flags |= SRVFLAG_ERROR_LOG;
1127 		}
1128 		;
1129 
1130 logstyle	: COMMON		{
1131 			srv_conf->flags &= ~SRVFLAG_NO_LOG;
1132 			srv_conf->flags |= SRVFLAG_LOG;
1133 			srv_conf->logformat = LOG_FORMAT_COMMON;
1134 		}
1135 		| COMBINED		{
1136 			srv_conf->flags &= ~SRVFLAG_NO_LOG;
1137 			srv_conf->flags |= SRVFLAG_LOG;
1138 			srv_conf->logformat = LOG_FORMAT_COMBINED;
1139 		}
1140 		| CONNECTION		{
1141 			srv_conf->flags &= ~SRVFLAG_NO_LOG;
1142 			srv_conf->flags |= SRVFLAG_LOG;
1143 			srv_conf->logformat = LOG_FORMAT_CONNECTION;
1144 		}
1145 		| FORWARDED		{
1146 			srv_conf->flags &= ~SRVFLAG_NO_LOG;
1147 			srv_conf->flags |= SRVFLAG_LOG;
1148 			srv_conf->logformat = LOG_FORMAT_FORWARDED;
1149 		}
1150 		;
1151 
1152 filter		: block RETURN NUMBER optstring	{
1153 			if ($3 <= 0 || server_httperror_byid($3) == NULL) {
1154 				yyerror("invalid return code: %lld", $3);
1155 				free($4);
1156 				YYERROR;
1157 			}
1158 			srv_conf->return_code = $3;
1159 
1160 			if ($4 != NULL) {
1161 				/* Only for 3xx redirection headers */
1162 				if ($3 < 300 || $3 > 399) {
1163 					yyerror("invalid return code for "
1164 					    "location URI");
1165 					free($4);
1166 					YYERROR;
1167 				}
1168 				srv_conf->return_uri = $4;
1169 				srv_conf->return_uri_len = strlen($4) + 1;
1170 			}
1171 		}
1172 		| block DROP			{
1173 			/* No return code, silently drop the connection */
1174 			srv_conf->return_code = 0;
1175 		}
1176 		| block				{
1177 			/* Forbidden */
1178 			srv_conf->return_code = 403;
1179 		}
1180 		| PASS				{
1181 			srv_conf->flags &= ~SRVFLAG_BLOCK;
1182 			srv_conf->flags |= SRVFLAG_NO_BLOCK;
1183 		}
1184 		;
1185 
1186 block		: BLOCK				{
1187 			srv_conf->flags &= ~SRVFLAG_NO_BLOCK;
1188 			srv_conf->flags |= SRVFLAG_BLOCK;
1189 		}
1190 		;
1191 
1192 optmatch	: /* empty */		{ $$ = 0; }
1193 		| MATCH			{ $$ = 1; }
1194 		;
1195 
1196 optstring	: /* empty */		{ $$ = NULL; }
1197 		| STRING		{ $$ = $1; }
1198 		;
1199 
1200 fcgiport	: NUMBER		{
1201 			if ($1 <= 0 || $1 > (int)USHRT_MAX) {
1202 				yyerror("invalid port: %lld", $1);
1203 				YYERROR;
1204 			}
1205 			if (asprintf(&$$, "%lld", $1) == -1) {
1206 				yyerror("out of memory");
1207 				YYERROR;
1208 			}
1209 		}
1210 		| STRING		{
1211 			if (getservice($1) <= 0) {
1212 				yyerror("invalid port: %s", $1);
1213 				free($1);
1214 				YYERROR;
1215 			}
1216 
1217 			$$ = $1;
1218 		}
1219 		;
1220 
1221 gzip_static	: NO GZIPSTATIC		{
1222 			srv->srv_conf.flags &= ~SRVFLAG_GZIP_STATIC;
1223 		}
1224 		| GZIPSTATIC		{
1225 			srv->srv_conf.flags |= SRVFLAG_GZIP_STATIC;
1226 		}
1227 		;
1228 
1229 tcpip		: TCP '{' optnl tcpflags_l '}'
1230 		| TCP tcpflags
1231 		;
1232 
1233 tcpflags_l	: tcpflags optcommanl tcpflags_l
1234 		| tcpflags optnl
1235 		;
1236 
1237 tcpflags	: SACK			{ srv_conf->tcpflags |= TCPFLAG_SACK; }
1238 		| NO SACK		{ srv_conf->tcpflags |= TCPFLAG_NSACK; }
1239 		| NODELAY		{
1240 			srv_conf->tcpflags |= TCPFLAG_NODELAY;
1241 		}
1242 		| NO NODELAY		{
1243 			srv_conf->tcpflags |= TCPFLAG_NNODELAY;
1244 		}
1245 		| BACKLOG NUMBER	{
1246 			if ($2 < 0 || $2 > SERVER_MAX_CLIENTS) {
1247 				yyerror("invalid backlog: %lld", $2);
1248 				YYERROR;
1249 			}
1250 			srv_conf->tcpbacklog = $2;
1251 		}
1252 		| SOCKET BUFFER NUMBER	{
1253 			srv_conf->tcpflags |= TCPFLAG_BUFSIZ;
1254 			if ((srv_conf->tcpbufsiz = $3) < 0) {
1255 				yyerror("invalid socket buffer size: %lld", $3);
1256 				YYERROR;
1257 			}
1258 		}
1259 		| IP STRING NUMBER	{
1260 			if ($3 < 0) {
1261 				yyerror("invalid ttl: %lld", $3);
1262 				free($2);
1263 				YYERROR;
1264 			}
1265 			if (strcasecmp("ttl", $2) == 0) {
1266 				srv_conf->tcpflags |= TCPFLAG_IPTTL;
1267 				srv_conf->tcpipttl = $3;
1268 			} else if (strcasecmp("minttl", $2) == 0) {
1269 				srv_conf->tcpflags |= TCPFLAG_IPMINTTL;
1270 				srv_conf->tcpipminttl = $3;
1271 			} else {
1272 				yyerror("invalid TCP/IP flag: %s", $2);
1273 				free($2);
1274 				YYERROR;
1275 			}
1276 			free($2);
1277 		}
1278 		;
1279 
1280 types		: TYPES	'{' optnl mediaopts_l '}'
1281 		;
1282 
1283 mediaopts_l	: mediaopts_l mediaoptsl nl
1284 		| mediaoptsl nl
1285 		;
1286 
1287 mediaoptsl	: mediastring medianames_l optsemicolon
1288 		| include
1289 		;
1290 
1291 mediastring	: STRING '/' STRING	{
1292 			if (strlcpy(media.media_type, $1,
1293 			    sizeof(media.media_type)) >=
1294 			    sizeof(media.media_type) ||
1295 			    strlcpy(media.media_subtype, $3,
1296 			    sizeof(media.media_subtype)) >=
1297 			    sizeof(media.media_subtype)) {
1298 				yyerror("media type too long");
1299 				free($1);
1300 				free($3);
1301 				YYERROR;
1302 			}
1303 			free($1);
1304 			free($3);
1305 		}
1306 		;
1307 
1308 medianames_l	: medianames_l medianamesl
1309 		| medianamesl
1310 		;
1311 
1312 medianamesl	: numberstring				{
1313 			if (strlcpy(media.media_name, $1,
1314 			    sizeof(media.media_name)) >=
1315 			    sizeof(media.media_name)) {
1316 				yyerror("media name too long");
1317 				free($1);
1318 				YYERROR;
1319 			}
1320 			free($1);
1321 
1322 			if (!loadcfg)
1323 				break;
1324 
1325 			if (media_add(conf->sc_mediatypes, &media) == NULL) {
1326 				yyerror("failed to add media type");
1327 				YYERROR;
1328 			}
1329 		}
1330 		;
1331 
1332 port		: PORT NUMBER {
1333 			if ($2 <= 0 || $2 > (int)USHRT_MAX) {
1334 				yyerror("invalid port: %lld", $2);
1335 				YYERROR;
1336 			}
1337 			$$.val[0] = htons($2);
1338 			$$.op = 1;
1339 		}
1340 		| PORT STRING {
1341 			int	 val;
1342 
1343 			if ((val = getservice($2)) == -1) {
1344 				yyerror("invalid port: %s", $2);
1345 				free($2);
1346 				YYERROR;
1347 			}
1348 			free($2);
1349 
1350 			$$.val[0] = val;
1351 			$$.op = 1;
1352 		}
1353 		;
1354 
1355 timeout		: NUMBER
1356 		{
1357 			if ($1 < 0) {
1358 				yyerror("invalid timeout: %lld", $1);
1359 				YYERROR;
1360 			}
1361 			$$.tv_sec = $1;
1362 			$$.tv_usec = 0;
1363 		}
1364 		;
1365 
1366 numberstring	: NUMBER		{
1367 			char *s;
1368 			if (asprintf(&s, "%lld", $1) == -1) {
1369 				yyerror("asprintf: number");
1370 				YYERROR;
1371 			}
1372 			$$ = s;
1373 		}
1374 		| STRING
1375 		;
1376 
1377 optsemicolon	: ';'
1378 		|
1379 		;
1380 
1381 optnl		: '\n' optnl
1382 		|
1383 		;
1384 
1385 optcommanl	: ',' optnl
1386 		| nl
1387 		;
1388 
1389 nl		: '\n' optnl
1390 		;
1391 
1392 %%
1393 
1394 struct keywords {
1395 	const char	*k_name;
1396 	int		 k_val;
1397 };
1398 
1399 int
1400 yyerror(const char *fmt, ...)
1401 {
1402 	va_list		 ap;
1403 	char		*msg;
1404 
1405 	file->errors++;
1406 	va_start(ap, fmt);
1407 	if (vasprintf(&msg, fmt, ap) == -1)
1408 		fatalx("yyerror vasprintf");
1409 	va_end(ap);
1410 	logit(LOG_CRIT, "%s:%d: %s", file->name, yylval.lineno, msg);
1411 	free(msg);
1412 	return (0);
1413 }
1414 
1415 int
1416 kw_cmp(const void *k, const void *e)
1417 {
1418 	return (strcmp(k, ((const struct keywords *)e)->k_name));
1419 }
1420 
1421 int
1422 lookup(char *s)
1423 {
1424 	/* this has to be sorted always */
1425 	static const struct keywords keywords[] = {
1426 		{ "access",		ACCESS },
1427 		{ "alias",		ALIAS },
1428 		{ "authenticate",	AUTHENTICATE},
1429 		{ "auto",		AUTO },
1430 		{ "backlog",		BACKLOG },
1431 		{ "block",		BLOCK },
1432 		{ "body",		BODY },
1433 		{ "buffer",		BUFFER },
1434 		{ "ca",			CA },
1435 		{ "certificate",	CERTIFICATE },
1436 		{ "chroot",		CHROOT },
1437 		{ "ciphers",		CIPHERS },
1438 		{ "client",		CLIENT },
1439 		{ "combined",		COMBINED },
1440 		{ "common",		COMMON },
1441 		{ "connection",		CONNECTION },
1442 		{ "crl",		CRL },
1443 		{ "default",		DEFAULT },
1444 		{ "dhe",		DHE },
1445 		{ "directory",		DIRECTORY },
1446 		{ "drop",		DROP },
1447 		{ "ecdhe",		ECDHE },
1448 		{ "errdocs",		ERRDOCS },
1449 		{ "error",		ERR },
1450 		{ "fastcgi",		FCGI },
1451 		{ "forwarded",		FORWARDED },
1452 		{ "found",		FOUND },
1453 		{ "gzip-static",	GZIPSTATIC },
1454 		{ "hsts",		HSTS },
1455 		{ "include",		INCLUDE },
1456 		{ "index",		INDEX },
1457 		{ "ip",			IP },
1458 		{ "key",		KEY },
1459 		{ "lifetime",		LIFETIME },
1460 		{ "listen",		LISTEN },
1461 		{ "location",		LOCATION },
1462 		{ "log",		LOG },
1463 		{ "logdir",		LOGDIR },
1464 		{ "match",		MATCH },
1465 		{ "max",		MAXIMUM },
1466 		{ "max-age",		MAXAGE },
1467 		{ "no",			NO },
1468 		{ "nodelay",		NODELAY },
1469 		{ "not",		NOT },
1470 		{ "ocsp",		OCSP },
1471 		{ "on",			ON },
1472 		{ "optional",		OPTIONAL },
1473 		{ "param",		PARAM },
1474 		{ "pass",		PASS },
1475 		{ "port",		PORT },
1476 		{ "prefork",		PREFORK },
1477 		{ "preload",		PRELOAD },
1478 		{ "protocols",		PROTOCOLS },
1479 		{ "request",		REQUEST },
1480 		{ "requests",		REQUESTS },
1481 		{ "return",		RETURN },
1482 		{ "rewrite",		REWRITE },
1483 		{ "root",		ROOT },
1484 		{ "sack",		SACK },
1485 		{ "server",		SERVER },
1486 		{ "socket",		SOCKET },
1487 		{ "strip",		STRIP },
1488 		{ "style",		STYLE },
1489 		{ "subdomains",		SUBDOMAINS },
1490 		{ "syslog",		SYSLOG },
1491 		{ "tcp",		TCP },
1492 		{ "ticket",		TICKET },
1493 		{ "timeout",		TIMEOUT },
1494 		{ "tls",		TLS },
1495 		{ "type",		TYPE },
1496 		{ "types",		TYPES },
1497 		{ "with",		WITH }
1498 	};
1499 	const struct keywords	*p;
1500 
1501 	p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
1502 	    sizeof(keywords[0]), kw_cmp);
1503 
1504 	if (p)
1505 		return (p->k_val);
1506 	else
1507 		return (STRING);
1508 }
1509 
1510 #define START_EXPAND	1
1511 #define DONE_EXPAND	2
1512 
1513 static int	expanding;
1514 
1515 int
1516 igetc(void)
1517 {
1518 	int	c;
1519 
1520 	while (1) {
1521 		if (file->ungetpos > 0)
1522 			c = file->ungetbuf[--file->ungetpos];
1523 		else
1524 			c = getc(file->stream);
1525 
1526 		if (c == START_EXPAND)
1527 			expanding = 1;
1528 		else if (c == DONE_EXPAND)
1529 			expanding = 0;
1530 		else
1531 			break;
1532 	}
1533 	return (c);
1534 }
1535 
1536 int
1537 lgetc(int quotec)
1538 {
1539 	int		c, next;
1540 
1541 	if (quotec) {
1542 		if ((c = igetc()) == EOF) {
1543 			yyerror("reached end of file while parsing "
1544 			    "quoted string");
1545 			if (file == topfile || popfile() == EOF)
1546 				return (EOF);
1547 			return (quotec);
1548 		}
1549 		return (c);
1550 	}
1551 
1552 	while ((c = igetc()) == '\\') {
1553 		next = igetc();
1554 		if (next != '\n') {
1555 			c = next;
1556 			break;
1557 		}
1558 		yylval.lineno = file->lineno;
1559 		file->lineno++;
1560 	}
1561 
1562 	if (c == EOF) {
1563 		/*
1564 		 * Fake EOL when hit EOF for the first time. This gets line
1565 		 * count right if last line in included file is syntactically
1566 		 * invalid and has no newline.
1567 		 */
1568 		if (file->eof_reached == 0) {
1569 			file->eof_reached = 1;
1570 			return ('\n');
1571 		}
1572 		while (c == EOF) {
1573 			if (file == topfile || popfile() == EOF)
1574 				return (EOF);
1575 			c = igetc();
1576 		}
1577 	}
1578 	return (c);
1579 }
1580 
1581 void
1582 lungetc(int c)
1583 {
1584 	if (c == EOF)
1585 		return;
1586 
1587 	if (file->ungetpos >= file->ungetsize) {
1588 		void *p = reallocarray(file->ungetbuf, file->ungetsize, 2);
1589 		if (p == NULL)
1590 			err(1, "%s", __func__);
1591 		file->ungetbuf = p;
1592 		file->ungetsize *= 2;
1593 	}
1594 	file->ungetbuf[file->ungetpos++] = c;
1595 }
1596 
1597 int
1598 findeol(void)
1599 {
1600 	int	c;
1601 
1602 	/* skip to either EOF or the first real EOL */
1603 	while (1) {
1604 		c = lgetc(0);
1605 		if (c == '\n') {
1606 			file->lineno++;
1607 			break;
1608 		}
1609 		if (c == EOF)
1610 			break;
1611 	}
1612 	return (ERROR);
1613 }
1614 
1615 int
1616 yylex(void)
1617 {
1618 	char	 buf[8096];
1619 	char	*p, *val;
1620 	int	 quotec, next, c;
1621 	int	 token;
1622 
1623 top:
1624 	p = buf;
1625 	while ((c = lgetc(0)) == ' ' || c == '\t')
1626 		; /* nothing */
1627 
1628 	yylval.lineno = file->lineno;
1629 	if (c == '#')
1630 		while ((c = lgetc(0)) != '\n' && c != EOF)
1631 			; /* nothing */
1632 	if (c == '$' && !expanding) {
1633 		while (1) {
1634 			if ((c = lgetc(0)) == EOF)
1635 				return (0);
1636 
1637 			if (p + 1 >= buf + sizeof(buf) - 1) {
1638 				yyerror("string too long");
1639 				return (findeol());
1640 			}
1641 			if (isalnum(c) || c == '_') {
1642 				*p++ = c;
1643 				continue;
1644 			}
1645 			*p = '\0';
1646 			lungetc(c);
1647 			break;
1648 		}
1649 		val = symget(buf);
1650 		if (val == NULL) {
1651 			yyerror("macro '%s' not defined", buf);
1652 			return (findeol());
1653 		}
1654 		p = val + strlen(val) - 1;
1655 		lungetc(DONE_EXPAND);
1656 		while (p >= val) {
1657 			lungetc((unsigned char)*p);
1658 			p--;
1659 		}
1660 		lungetc(START_EXPAND);
1661 		goto top;
1662 	}
1663 
1664 	switch (c) {
1665 	case '\'':
1666 	case '"':
1667 		quotec = c;
1668 		while (1) {
1669 			if ((c = lgetc(quotec)) == EOF)
1670 				return (0);
1671 			if (c == '\n') {
1672 				file->lineno++;
1673 				continue;
1674 			} else if (c == '\\') {
1675 				if ((next = lgetc(quotec)) == EOF)
1676 					return (0);
1677 				if (next == quotec || next == ' ' ||
1678 				    next == '\t')
1679 					c = next;
1680 				else if (next == '\n') {
1681 					file->lineno++;
1682 					continue;
1683 				} else
1684 					lungetc(next);
1685 			} else if (c == quotec) {
1686 				*p = '\0';
1687 				break;
1688 			} else if (c == '\0') {
1689 				yyerror("syntax error");
1690 				return (findeol());
1691 			}
1692 			if (p + 1 >= buf + sizeof(buf) - 1) {
1693 				yyerror("string too long");
1694 				return (findeol());
1695 			}
1696 			*p++ = c;
1697 		}
1698 		yylval.v.string = strdup(buf);
1699 		if (yylval.v.string == NULL)
1700 			err(1, "%s", __func__);
1701 		return (STRING);
1702 	}
1703 
1704 #define allowed_to_end_number(x) \
1705 	(isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=')
1706 
1707 	if (c == '-' || isdigit(c)) {
1708 		do {
1709 			*p++ = c;
1710 			if ((size_t)(p-buf) >= sizeof(buf)) {
1711 				yyerror("string too long");
1712 				return (findeol());
1713 			}
1714 		} while ((c = lgetc(0)) != EOF && isdigit(c));
1715 		lungetc(c);
1716 		if (p == buf + 1 && buf[0] == '-')
1717 			goto nodigits;
1718 		if (c == EOF || allowed_to_end_number(c)) {
1719 			const char *errstr = NULL;
1720 
1721 			*p = '\0';
1722 			yylval.v.number = strtonum(buf, LLONG_MIN,
1723 			    LLONG_MAX, &errstr);
1724 			if (errstr) {
1725 				yyerror("\"%s\" invalid number: %s",
1726 				    buf, errstr);
1727 				return (findeol());
1728 			}
1729 			return (NUMBER);
1730 		} else {
1731 nodigits:
1732 			while (p > buf + 1)
1733 				lungetc((unsigned char)*--p);
1734 			c = (unsigned char)*--p;
1735 			if (c == '-')
1736 				return (c);
1737 		}
1738 	}
1739 
1740 #define allowed_in_string(x) \
1741 	(isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
1742 	x != '{' && x != '}' && x != '<' && x != '>' && \
1743 	x != '!' && x != '=' && x != '#' && \
1744 	x != ',' && x != ';' && x != '/'))
1745 
1746 	if (isalnum(c) || c == ':' || c == '_' || c == '*') {
1747 		do {
1748 			*p++ = c;
1749 			if ((size_t)(p-buf) >= sizeof(buf)) {
1750 				yyerror("string too long");
1751 				return (findeol());
1752 			}
1753 		} while ((c = lgetc(0)) != EOF && (allowed_in_string(c)));
1754 		lungetc(c);
1755 		*p = '\0';
1756 		if ((token = lookup(buf)) == STRING)
1757 			if ((yylval.v.string = strdup(buf)) == NULL)
1758 				err(1, "%s", __func__);
1759 		return (token);
1760 	}
1761 	if (c == '\n') {
1762 		yylval.lineno = file->lineno;
1763 		file->lineno++;
1764 	}
1765 	if (c == EOF)
1766 		return (0);
1767 	return (c);
1768 }
1769 
1770 int
1771 check_file_secrecy(int fd, const char *fname)
1772 {
1773 	struct stat	st;
1774 
1775 	if (fstat(fd, &st)) {
1776 		log_warn("cannot stat %s", fname);
1777 		return (-1);
1778 	}
1779 	if (st.st_uid != 0 && st.st_uid != getuid()) {
1780 		log_warnx("%s: owner not root or current user", fname);
1781 		return (-1);
1782 	}
1783 	if (st.st_mode & (S_IWGRP | S_IXGRP | S_IRWXO)) {
1784 		log_warnx("%s: group writable or world read/writable", fname);
1785 		return (-1);
1786 	}
1787 	return (0);
1788 }
1789 
1790 struct file *
1791 pushfile(const char *name, int secret)
1792 {
1793 	struct file	*nfile;
1794 
1795 	if ((nfile = calloc(1, sizeof(struct file))) == NULL) {
1796 		log_warn("%s", __func__);
1797 		return (NULL);
1798 	}
1799 	if ((nfile->name = strdup(name)) == NULL) {
1800 		log_warn("%s", __func__);
1801 		free(nfile);
1802 		return (NULL);
1803 	}
1804 	if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
1805 		log_warn("%s: %s", __func__, nfile->name);
1806 		free(nfile->name);
1807 		free(nfile);
1808 		return (NULL);
1809 	} else if (secret &&
1810 	    check_file_secrecy(fileno(nfile->stream), nfile->name)) {
1811 		fclose(nfile->stream);
1812 		free(nfile->name);
1813 		free(nfile);
1814 		return (NULL);
1815 	}
1816 	nfile->lineno = TAILQ_EMPTY(&files) ? 1 : 0;
1817 	nfile->ungetsize = 16;
1818 	nfile->ungetbuf = malloc(nfile->ungetsize);
1819 	if (nfile->ungetbuf == NULL) {
1820 		log_warn("%s", __func__);
1821 		fclose(nfile->stream);
1822 		free(nfile->name);
1823 		free(nfile);
1824 		return (NULL);
1825 	}
1826 	TAILQ_INSERT_TAIL(&files, nfile, entry);
1827 	return (nfile);
1828 }
1829 
1830 int
1831 popfile(void)
1832 {
1833 	struct file	*prev;
1834 
1835 	if ((prev = TAILQ_PREV(file, files, entry)) != NULL)
1836 		prev->errors += file->errors;
1837 
1838 	TAILQ_REMOVE(&files, file, entry);
1839 	fclose(file->stream);
1840 	free(file->name);
1841 	free(file->ungetbuf);
1842 	free(file);
1843 	file = prev;
1844 	return (file ? 0 : EOF);
1845 }
1846 
1847 int
1848 parse_config(const char *filename, struct httpd *x_conf)
1849 {
1850 	struct sym		*sym, *next;
1851 	struct media_type	 dflt = HTTPD_DEFAULT_TYPE;
1852 
1853 	conf = x_conf;
1854 	if (config_init(conf) == -1) {
1855 		log_warn("%s: cannot initialize configuration", __func__);
1856 		return (-1);
1857 	}
1858 
1859 	/* Set default media type */
1860 	memcpy(&conf->sc_default_type, &dflt, sizeof(struct media_type));
1861 
1862 	errors = 0;
1863 
1864 	if ((file = pushfile(filename, 0)) == NULL)
1865 		return (-1);
1866 
1867 	topfile = file;
1868 	setservent(1);
1869 
1870 	yyparse();
1871 	errors = file->errors;
1872 	while (popfile() != EOF)
1873 		;
1874 
1875 	endservent();
1876 	endprotoent();
1877 
1878 	/* Free macros */
1879 	TAILQ_FOREACH_SAFE(sym, &symhead, entry, next) {
1880 		if (!sym->persist) {
1881 			free(sym->nam);
1882 			free(sym->val);
1883 			TAILQ_REMOVE(&symhead, sym, entry);
1884 			free(sym);
1885 		}
1886 	}
1887 
1888 	return (errors ? -1 : 0);
1889 }
1890 
1891 int
1892 load_config(const char *filename, struct httpd *x_conf)
1893 {
1894 	struct sym		*sym, *next;
1895 	struct http_mediatype	 mediatypes[] = MEDIA_TYPES;
1896 	struct media_type	 m;
1897 	int			 i;
1898 
1899 	conf = x_conf;
1900 	conf->sc_flags = 0;
1901 
1902 	loadcfg = 1;
1903 	errors = 0;
1904 	last_server_id = 0;
1905 	last_auth_id = 0;
1906 
1907 	srv = NULL;
1908 
1909 	if ((file = pushfile(filename, 0)) == NULL)
1910 		return (-1);
1911 
1912 	topfile = file;
1913 	setservent(1);
1914 
1915 	yyparse();
1916 	errors = file->errors;
1917 	popfile();
1918 
1919 	endservent();
1920 	endprotoent();
1921 
1922 	/* Free macros and check which have not been used. */
1923 	for (sym = TAILQ_FIRST(&symhead); sym != NULL; sym = next) {
1924 		next = TAILQ_NEXT(sym, entry);
1925 		if ((conf->sc_opts & HTTPD_OPT_VERBOSE) && !sym->used)
1926 			fprintf(stderr, "warning: macro '%s' not "
1927 			    "used\n", sym->nam);
1928 		if (!sym->persist) {
1929 			free(sym->nam);
1930 			free(sym->val);
1931 			TAILQ_REMOVE(&symhead, sym, entry);
1932 			free(sym);
1933 		}
1934 	}
1935 
1936 	if (TAILQ_EMPTY(conf->sc_servers)) {
1937 		log_warnx("no actions, nothing to do");
1938 		errors++;
1939 	}
1940 
1941 	if (RB_EMPTY(conf->sc_mediatypes)) {
1942 		/* Add default media types */
1943 		for (i = 0; mediatypes[i].media_name != NULL; i++) {
1944 			(void)strlcpy(m.media_name, mediatypes[i].media_name,
1945 			    sizeof(m.media_name));
1946 			(void)strlcpy(m.media_type, mediatypes[i].media_type,
1947 			    sizeof(m.media_type));
1948 			(void)strlcpy(m.media_subtype,
1949 			    mediatypes[i].media_subtype,
1950 			    sizeof(m.media_subtype));
1951 			m.media_encoding = NULL;
1952 
1953 			if (media_add(conf->sc_mediatypes, &m) == NULL) {
1954 				log_warnx("failed to add default media \"%s\"",
1955 				    m.media_name);
1956 				errors++;
1957 			}
1958 		}
1959 	}
1960 
1961 	return (errors ? -1 : 0);
1962 }
1963 
1964 int
1965 symset(const char *nam, const char *val, int persist)
1966 {
1967 	struct sym	*sym;
1968 
1969 	TAILQ_FOREACH(sym, &symhead, entry) {
1970 		if (strcmp(nam, sym->nam) == 0)
1971 			break;
1972 	}
1973 
1974 	if (sym != NULL) {
1975 		if (sym->persist == 1)
1976 			return (0);
1977 		else {
1978 			free(sym->nam);
1979 			free(sym->val);
1980 			TAILQ_REMOVE(&symhead, sym, entry);
1981 			free(sym);
1982 		}
1983 	}
1984 	if ((sym = calloc(1, sizeof(*sym))) == NULL)
1985 		return (-1);
1986 
1987 	sym->nam = strdup(nam);
1988 	if (sym->nam == NULL) {
1989 		free(sym);
1990 		return (-1);
1991 	}
1992 	sym->val = strdup(val);
1993 	if (sym->val == NULL) {
1994 		free(sym->nam);
1995 		free(sym);
1996 		return (-1);
1997 	}
1998 	sym->used = 0;
1999 	sym->persist = persist;
2000 	TAILQ_INSERT_TAIL(&symhead, sym, entry);
2001 	return (0);
2002 }
2003 
2004 int
2005 cmdline_symset(char *s)
2006 {
2007 	char	*sym, *val;
2008 	int	ret;
2009 
2010 	if ((val = strrchr(s, '=')) == NULL)
2011 		return (-1);
2012 	sym = strndup(s, val - s);
2013 	if (sym == NULL)
2014 		errx(1, "%s: strndup", __func__);
2015 	ret = symset(sym, val + 1, 1);
2016 	free(sym);
2017 
2018 	return (ret);
2019 }
2020 
2021 char *
2022 symget(const char *nam)
2023 {
2024 	struct sym	*sym;
2025 
2026 	TAILQ_FOREACH(sym, &symhead, entry) {
2027 		if (strcmp(nam, sym->nam) == 0) {
2028 			sym->used = 1;
2029 			return (sym->val);
2030 		}
2031 	}
2032 	return (NULL);
2033 }
2034 
2035 struct address *
2036 host_v4(const char *s)
2037 {
2038 	struct in_addr		 ina;
2039 	struct sockaddr_in	*sain;
2040 	struct address		*h;
2041 
2042 	memset(&ina, 0, sizeof(ina));
2043 	if (inet_pton(AF_INET, s, &ina) != 1)
2044 		return (NULL);
2045 
2046 	if ((h = calloc(1, sizeof(*h))) == NULL)
2047 		fatal(__func__);
2048 	sain = (struct sockaddr_in *)&h->ss;
2049 	sain->sin_len = sizeof(struct sockaddr_in);
2050 	sain->sin_family = AF_INET;
2051 	sain->sin_addr.s_addr = ina.s_addr;
2052 	if (sain->sin_addr.s_addr == INADDR_ANY)
2053 		h->prefixlen = 0; /* 0.0.0.0 address */
2054 	else
2055 		h->prefixlen = -1; /* host address */
2056 	return (h);
2057 }
2058 
2059 struct address *
2060 host_v6(const char *s)
2061 {
2062 	struct addrinfo		 hints, *res;
2063 	struct sockaddr_in6	*sa_in6;
2064 	struct address		*h = NULL;
2065 
2066 	memset(&hints, 0, sizeof(hints));
2067 	hints.ai_family = AF_INET6;
2068 	hints.ai_socktype = SOCK_DGRAM; /* dummy */
2069 	hints.ai_flags = AI_NUMERICHOST;
2070 	if (getaddrinfo(s, "0", &hints, &res) == 0) {
2071 		if ((h = calloc(1, sizeof(*h))) == NULL)
2072 			fatal(__func__);
2073 		sa_in6 = (struct sockaddr_in6 *)&h->ss;
2074 		sa_in6->sin6_len = sizeof(struct sockaddr_in6);
2075 		sa_in6->sin6_family = AF_INET6;
2076 		memcpy(&sa_in6->sin6_addr,
2077 		    &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr,
2078 		    sizeof(sa_in6->sin6_addr));
2079 		sa_in6->sin6_scope_id =
2080 		    ((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id;
2081 		if (memcmp(&sa_in6->sin6_addr, &in6addr_any,
2082 		    sizeof(sa_in6->sin6_addr)) == 0)
2083 			h->prefixlen = 0; /* any address */
2084 		else
2085 			h->prefixlen = -1; /* host address */
2086 		freeaddrinfo(res);
2087 	}
2088 
2089 	return (h);
2090 }
2091 
2092 int
2093 host_dns(const char *s, struct addresslist *al, int max,
2094     struct portrange *port, const char *ifname, int ipproto)
2095 {
2096 	struct addrinfo		 hints, *res0, *res;
2097 	int			 error, cnt = 0;
2098 	struct sockaddr_in	*sain;
2099 	struct sockaddr_in6	*sin6;
2100 	struct address		*h;
2101 
2102 	if ((cnt = host_if(s, al, max, port, ifname, ipproto)) != 0)
2103 		return (cnt);
2104 
2105 	memset(&hints, 0, sizeof(hints));
2106 	hints.ai_family = PF_UNSPEC;
2107 	hints.ai_socktype = SOCK_DGRAM; /* DUMMY */
2108 	hints.ai_flags = AI_ADDRCONFIG;
2109 	error = getaddrinfo(s, NULL, &hints, &res0);
2110 	if (error == EAI_AGAIN || error == EAI_NODATA || error == EAI_NONAME)
2111 		return (0);
2112 	if (error) {
2113 		log_warnx("%s: could not parse \"%s\": %s", __func__, s,
2114 		    gai_strerror(error));
2115 		return (-1);
2116 	}
2117 
2118 	for (res = res0; res && cnt < max; res = res->ai_next) {
2119 		if (res->ai_family != AF_INET &&
2120 		    res->ai_family != AF_INET6)
2121 			continue;
2122 		if ((h = calloc(1, sizeof(*h))) == NULL)
2123 			fatal(__func__);
2124 
2125 		if (port != NULL)
2126 			memcpy(&h->port, port, sizeof(h->port));
2127 		if (ifname != NULL) {
2128 			if (strlcpy(h->ifname, ifname, sizeof(h->ifname)) >=
2129 			    sizeof(h->ifname))
2130 				log_warnx("%s: interface name truncated",
2131 				    __func__);
2132 			freeaddrinfo(res0);
2133 			free(h);
2134 			return (-1);
2135 		}
2136 		if (ipproto != -1)
2137 			h->ipproto = ipproto;
2138 		h->ss.ss_family = res->ai_family;
2139 		h->prefixlen = -1; /* host address */
2140 
2141 		if (res->ai_family == AF_INET) {
2142 			sain = (struct sockaddr_in *)&h->ss;
2143 			sain->sin_len = sizeof(struct sockaddr_in);
2144 			sain->sin_addr.s_addr = ((struct sockaddr_in *)
2145 			    res->ai_addr)->sin_addr.s_addr;
2146 		} else {
2147 			sin6 = (struct sockaddr_in6 *)&h->ss;
2148 			sin6->sin6_len = sizeof(struct sockaddr_in6);
2149 			memcpy(&sin6->sin6_addr, &((struct sockaddr_in6 *)
2150 			    res->ai_addr)->sin6_addr, sizeof(struct in6_addr));
2151 		}
2152 
2153 		TAILQ_INSERT_HEAD(al, h, entry);
2154 		cnt++;
2155 	}
2156 	if (cnt == max && res) {
2157 		log_warnx("%s: %s resolves to more than %d hosts", __func__,
2158 		    s, max);
2159 	}
2160 	freeaddrinfo(res0);
2161 	return (cnt);
2162 }
2163 
2164 int
2165 host_if(const char *s, struct addresslist *al, int max,
2166     struct portrange *port, const char *ifname, int ipproto)
2167 {
2168 	struct ifaddrs		*ifap, *p;
2169 	struct sockaddr_in	*sain;
2170 	struct sockaddr_in6	*sin6;
2171 	struct address		*h;
2172 	int			 cnt = 0, af;
2173 
2174 	if (getifaddrs(&ifap) == -1)
2175 		fatal("getifaddrs");
2176 
2177 	/* First search for IPv4 addresses */
2178 	af = AF_INET;
2179 
2180  nextaf:
2181 	for (p = ifap; p != NULL && cnt < max; p = p->ifa_next) {
2182 		if (p->ifa_addr == NULL ||
2183 		    p->ifa_addr->sa_family != af ||
2184 		    (strcmp(s, p->ifa_name) != 0 &&
2185 		    !is_if_in_group(p->ifa_name, s)))
2186 			continue;
2187 		if ((h = calloc(1, sizeof(*h))) == NULL)
2188 			fatal("calloc");
2189 
2190 		if (port != NULL)
2191 			memcpy(&h->port, port, sizeof(h->port));
2192 		if (ifname != NULL) {
2193 			if (strlcpy(h->ifname, ifname, sizeof(h->ifname)) >=
2194 			    sizeof(h->ifname))
2195 				log_warnx("%s: interface name truncated",
2196 				    __func__);
2197 			freeifaddrs(ifap);
2198 			free(h);
2199 			return (-1);
2200 		}
2201 		if (ipproto != -1)
2202 			h->ipproto = ipproto;
2203 		h->ss.ss_family = af;
2204 		h->prefixlen = -1; /* host address */
2205 
2206 		if (af == AF_INET) {
2207 			sain = (struct sockaddr_in *)&h->ss;
2208 			sain->sin_len = sizeof(struct sockaddr_in);
2209 			sain->sin_addr.s_addr = ((struct sockaddr_in *)
2210 			    p->ifa_addr)->sin_addr.s_addr;
2211 		} else {
2212 			sin6 = (struct sockaddr_in6 *)&h->ss;
2213 			sin6->sin6_len = sizeof(struct sockaddr_in6);
2214 			memcpy(&sin6->sin6_addr, &((struct sockaddr_in6 *)
2215 			    p->ifa_addr)->sin6_addr, sizeof(struct in6_addr));
2216 			sin6->sin6_scope_id = ((struct sockaddr_in6 *)
2217 			    p->ifa_addr)->sin6_scope_id;
2218 		}
2219 
2220 		TAILQ_INSERT_HEAD(al, h, entry);
2221 		cnt++;
2222 	}
2223 	if (af == AF_INET) {
2224 		/* Next search for IPv6 addresses */
2225 		af = AF_INET6;
2226 		goto nextaf;
2227 	}
2228 
2229 	if (cnt > max) {
2230 		log_warnx("%s: %s resolves to more than %d hosts", __func__,
2231 		    s, max);
2232 	}
2233 	freeifaddrs(ifap);
2234 	return (cnt);
2235 }
2236 
2237 int
2238 host(const char *s, struct addresslist *al, int max,
2239     struct portrange *port, const char *ifname, int ipproto)
2240 {
2241 	struct address *h;
2242 
2243 	h = host_v4(s);
2244 
2245 	/* IPv6 address? */
2246 	if (h == NULL)
2247 		h = host_v6(s);
2248 
2249 	if (h != NULL) {
2250 		if (port != NULL)
2251 			memcpy(&h->port, port, sizeof(h->port));
2252 		if (ifname != NULL) {
2253 			if (strlcpy(h->ifname, ifname, sizeof(h->ifname)) >=
2254 			    sizeof(h->ifname)) {
2255 				log_warnx("%s: interface name truncated",
2256 				    __func__);
2257 				free(h);
2258 				return (-1);
2259 			}
2260 		}
2261 		if (ipproto != -1)
2262 			h->ipproto = ipproto;
2263 
2264 		TAILQ_INSERT_HEAD(al, h, entry);
2265 		return (1);
2266 	}
2267 
2268 	return (host_dns(s, al, max, port, ifname, ipproto));
2269 }
2270 
2271 struct server *
2272 server_inherit(struct server *src, struct server_config *alias,
2273     struct server_config *addr)
2274 {
2275 	struct server	*dst, *s, *dstl;
2276 
2277 	if ((dst = calloc(1, sizeof(*dst))) == NULL)
2278 		fatal("out of memory");
2279 
2280 	/* Copy the source server and assign a new Id */
2281 	memcpy(&dst->srv_conf, &src->srv_conf, sizeof(dst->srv_conf));
2282 	if ((dst->srv_conf.tls_cert_file =
2283 	    strdup(src->srv_conf.tls_cert_file)) == NULL)
2284 		fatal("out of memory");
2285 	if ((dst->srv_conf.tls_key_file =
2286 	    strdup(src->srv_conf.tls_key_file)) == NULL)
2287 		fatal("out of memory");
2288 	if (src->srv_conf.tls_ocsp_staple_file != NULL) {
2289 		if ((dst->srv_conf.tls_ocsp_staple_file =
2290 		    strdup(src->srv_conf.tls_ocsp_staple_file)) == NULL)
2291 			fatal("out of memory");
2292 	}
2293 
2294 	if (src->srv_conf.return_uri != NULL &&
2295 	    (dst->srv_conf.return_uri =
2296 	    strdup(src->srv_conf.return_uri)) == NULL)
2297 		fatal("out of memory");
2298 
2299 	dst->srv_conf.id = ++last_server_id;
2300 	dst->srv_conf.parent_id = dst->srv_conf.id;
2301 	dst->srv_s = -1;
2302 
2303 	if (last_server_id == INT_MAX) {
2304 		yyerror("too many servers defined");
2305 		serverconfig_free(&dst->srv_conf);
2306 		free(dst);
2307 		return (NULL);
2308 	}
2309 
2310 	/* Now set alias and listen address */
2311 	strlcpy(dst->srv_conf.name, alias->name, sizeof(dst->srv_conf.name));
2312 	memcpy(&dst->srv_conf.ss, &addr->ss, sizeof(dst->srv_conf.ss));
2313 	dst->srv_conf.port = addr->port;
2314 	dst->srv_conf.prefixlen = addr->prefixlen;
2315 	if (addr->flags & SRVFLAG_TLS)
2316 		dst->srv_conf.flags |= SRVFLAG_TLS;
2317 	else
2318 		dst->srv_conf.flags &= ~SRVFLAG_TLS;
2319 
2320 	/* Don't inherit the "match" option, use it from the alias */
2321 	dst->srv_conf.flags &= ~SRVFLAG_SERVER_MATCH;
2322 	dst->srv_conf.flags |= (alias->flags & SRVFLAG_SERVER_MATCH);
2323 
2324 	if (server_tls_load_keypair(dst) == -1)
2325 		log_warnx("%s:%d: server \"%s\": failed to "
2326 		    "load public/private keys", file->name,
2327 		    yylval.lineno, dst->srv_conf.name);
2328 
2329 	if (server_tls_load_ca(dst) == -1) {
2330 		yyerror("failed to load ca cert(s) for server %s",
2331 		    dst->srv_conf.name);
2332 		serverconfig_free(&dst->srv_conf);
2333 		return NULL;
2334 	}
2335 
2336 	if (server_tls_load_crl(dst) == -1) {
2337 		yyerror("failed to load crl(s) for server %s",
2338 		    dst->srv_conf.name);
2339 		serverconfig_free(&dst->srv_conf);
2340 		free(dst);
2341 		return NULL;
2342 	}
2343 
2344 	if (server_tls_load_ocsp(dst) == -1) {
2345 		yyerror("failed to load ocsp staple "
2346 		    "for server %s", dst->srv_conf.name);
2347 		serverconfig_free(&dst->srv_conf);
2348 		free(dst);
2349 		return (NULL);
2350 	}
2351 
2352 	/* Check if the new server already exists */
2353 	if (server_match(dst, 1) != NULL) {
2354 		yyerror("server \"%s\" defined twice",
2355 		    dst->srv_conf.name);
2356 		serverconfig_free(&dst->srv_conf);
2357 		free(dst);
2358 		return (NULL);
2359 	}
2360 
2361 	/* Copy all the locations of the source server */
2362 	TAILQ_FOREACH(s, conf->sc_servers, srv_entry) {
2363 		if (!(s->srv_conf.flags & SRVFLAG_LOCATION &&
2364 		    s->srv_conf.parent_id == src->srv_conf.parent_id))
2365 			continue;
2366 
2367 		if ((dstl = calloc(1, sizeof(*dstl))) == NULL)
2368 			fatal("out of memory");
2369 
2370 		memcpy(&dstl->srv_conf, &s->srv_conf, sizeof(dstl->srv_conf));
2371 		strlcpy(dstl->srv_conf.name, alias->name,
2372 		    sizeof(dstl->srv_conf.name));
2373 
2374 		/* Copy the new Id and listen address */
2375 		dstl->srv_conf.id = ++last_server_id;
2376 		dstl->srv_conf.parent_id = dst->srv_conf.id;
2377 		memcpy(&dstl->srv_conf.ss, &addr->ss,
2378 		    sizeof(dstl->srv_conf.ss));
2379 		dstl->srv_conf.port = addr->port;
2380 		dstl->srv_conf.prefixlen = addr->prefixlen;
2381 		dstl->srv_s = -1;
2382 
2383 		DPRINTF("adding location \"%s\" for \"%s[%u]\"",
2384 		    dstl->srv_conf.location,
2385 		    dstl->srv_conf.name, dstl->srv_conf.id);
2386 
2387 		TAILQ_INSERT_TAIL(conf->sc_servers, dstl, srv_entry);
2388 	}
2389 
2390 	return (dst);
2391 }
2392 
2393 int
2394 listen_on(const char *addr, int tls, struct portrange *port)
2395 {
2396 	struct addresslist	 al;
2397 	struct address		*h;
2398 	struct server_config	*s_conf, *alias = NULL;
2399 
2400 	if (parentsrv != NULL) {
2401 		yyerror("listen %s inside location", addr);
2402 		return (-1);
2403 	}
2404 
2405 	TAILQ_INIT(&al);
2406 	if (strcmp("*", addr) == 0) {
2407 		if (host("0.0.0.0", &al, 1, port, NULL, -1) <= 0) {
2408 			yyerror("invalid listen ip: %s",
2409 			    "0.0.0.0");
2410 			return (-1);
2411 		}
2412 		if (host("::", &al, 1, port, NULL, -1) <= 0) {
2413 			yyerror("invalid listen ip: %s", "::");
2414 			return (-1);
2415 		}
2416 	} else {
2417 		if (host(addr, &al, HTTPD_MAX_ALIAS_IP, port, NULL,
2418 		    -1) <= 0) {
2419 			yyerror("invalid listen ip: %s", addr);
2420 			return (-1);
2421 		}
2422 	}
2423 
2424 	while ((h = TAILQ_FIRST(&al)) != NULL) {
2425 		if (srv->srv_conf.ss.ss_family != AF_UNSPEC) {
2426 			if ((alias = calloc(1,
2427 			    sizeof(*alias))) == NULL)
2428 				fatal("out of memory");
2429 				/* Add as an IP-based alias. */
2430 			s_conf = alias;
2431 		} else
2432 			s_conf = &srv->srv_conf;
2433 		memcpy(&s_conf->ss, &h->ss, sizeof(s_conf->ss));
2434 		s_conf->prefixlen = h->prefixlen;
2435 		/* Set the default port to 80 or 443 */
2436 		if (!h->port.op)
2437 			s_conf->port = htons(tls ?
2438 			    HTTPS_PORT : HTTP_PORT);
2439 		else
2440 			s_conf->port = h->port.val[0];
2441 
2442 		if (tls)
2443 			s_conf->flags |= SRVFLAG_TLS;
2444 
2445 		if (alias != NULL) {
2446 			/*
2447 			 * IP-based; use name match flags from
2448 			 * parent
2449 			 */
2450 			alias->flags &= ~SRVFLAG_SERVER_MATCH;
2451 			alias->flags |= srv->srv_conf.flags &
2452 			    SRVFLAG_SERVER_MATCH;
2453 			TAILQ_INSERT_TAIL(&srv->srv_hosts,
2454 			    alias, entry);
2455 		}
2456 		TAILQ_REMOVE(&al, h, entry);
2457 		free(h);
2458 	}
2459 
2460 	return (0);
2461 }
2462 
2463 int
2464 getservice(char *n)
2465 {
2466 	struct servent	*s;
2467 	const char	*errstr;
2468 	long long	 llval;
2469 
2470 	llval = strtonum(n, 0, UINT16_MAX, &errstr);
2471 	if (errstr) {
2472 		s = getservbyname(n, "tcp");
2473 		if (s == NULL)
2474 			s = getservbyname(n, "udp");
2475 		if (s == NULL)
2476 			return (-1);
2477 		return (s->s_port);
2478 	}
2479 
2480 	return (htons((unsigned short)llval));
2481 }
2482 
2483 int
2484 is_if_in_group(const char *ifname, const char *groupname)
2485 {
2486 	unsigned int		 len;
2487 	struct ifgroupreq	 ifgr;
2488 	struct ifg_req		*ifg;
2489 	int			 s;
2490 	int			 ret = 0;
2491 
2492 	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
2493 		err(1, "socket");
2494 
2495 	memset(&ifgr, 0, sizeof(ifgr));
2496 	if (strlcpy(ifgr.ifgr_name, ifname, IFNAMSIZ) >= IFNAMSIZ)
2497 		err(1, "IFNAMSIZ");
2498 	if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1) {
2499 		if (errno == EINVAL || errno == ENOTTY)
2500 			goto end;
2501 		err(1, "SIOCGIFGROUP");
2502 	}
2503 
2504 	len = ifgr.ifgr_len;
2505 	ifgr.ifgr_groups = calloc(len / sizeof(struct ifg_req),
2506 	    sizeof(struct ifg_req));
2507 	if (ifgr.ifgr_groups == NULL)
2508 		err(1, "getifgroups");
2509 	if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1)
2510 		err(1, "SIOCGIFGROUP");
2511 
2512 	ifg = ifgr.ifgr_groups;
2513 	for (; ifg && len >= sizeof(struct ifg_req); ifg++) {
2514 		len -= sizeof(struct ifg_req);
2515 		if (strcmp(ifg->ifgrq_group, groupname) == 0) {
2516 			ret = 1;
2517 			break;
2518 		}
2519 	}
2520 	free(ifgr.ifgr_groups);
2521 
2522 end:
2523 	close(s);
2524 	return (ret);
2525 }
2526 
2527 int
2528 get_fastcgi_dest(struct server_config *xsrv_conf, const char *node, char *port)
2529 {
2530 	struct addrinfo		 hints, *res;
2531 	int			 s;
2532 
2533 	memset(&hints, 0, sizeof(hints));
2534 	hints.ai_family = AF_UNSPEC;
2535 	hints.ai_socktype = SOCK_STREAM;
2536 
2537 	if ((s = getaddrinfo(node, port, &hints, &res)) != 0) {
2538 		yyerror("getaddrinfo: %s\n", gai_strerror(s));
2539 		return -1;
2540 	}
2541 
2542 	memset(&(xsrv_conf)->fastcgi_ss, 0, sizeof(xsrv_conf->fastcgi_ss));
2543 	memcpy(&(xsrv_conf)->fastcgi_ss, res->ai_addr, res->ai_addrlen);
2544 
2545 	freeaddrinfo(res);
2546 
2547 	return (0);
2548 }
2549 
2550 void
2551 remove_locations(struct server_config *xsrv_conf)
2552 {
2553 	struct server *s, *next;
2554 
2555 	TAILQ_FOREACH_SAFE(s, conf->sc_servers, srv_entry, next) {
2556 		if (!(s->srv_conf.flags & SRVFLAG_LOCATION &&
2557 		    s->srv_conf.parent_id == xsrv_conf->parent_id))
2558 			continue;
2559 		TAILQ_REMOVE(conf->sc_servers, s, srv_entry);
2560 		serverconfig_free(&s->srv_conf);
2561 		free(s);
2562 	}
2563 }
2564