xref: /openbsd/usr.sbin/httpd/parse.y (revision d89ec533)
1 /*	$OpenBSD: parse.y,v 1.127 2021/10/24 16:01:04 ian 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
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 		| filter
557 		| LOCATION optfound optmatch STRING	{
558 			struct server		*s;
559 			struct sockaddr_un	*sun;
560 
561 			if (srv->srv_conf.ss.ss_family == AF_UNSPEC) {
562 				yyerror("listen address not specified");
563 				free($4);
564 				YYERROR;
565 			}
566 
567 			if (parentsrv != NULL) {
568 				yyerror("location %s inside location", $4);
569 				free($4);
570 				YYERROR;
571 			}
572 
573 			if (!loadcfg) {
574 				free($4);
575 				YYACCEPT;
576 			}
577 
578 			if ((s = calloc(1, sizeof (*s))) == NULL)
579 				fatal("out of memory");
580 
581 			if (strlcpy(s->srv_conf.location, $4,
582 			    sizeof(s->srv_conf.location)) >=
583 			    sizeof(s->srv_conf.location)) {
584 				yyerror("server location truncated");
585 				free($4);
586 				free(s);
587 				YYERROR;
588 			}
589 			free($4);
590 
591 			if (strlcpy(s->srv_conf.name, srv->srv_conf.name,
592 			    sizeof(s->srv_conf.name)) >=
593 			    sizeof(s->srv_conf.name)) {
594 				yyerror("server name truncated");
595 				free(s);
596 				YYERROR;
597 			}
598 
599 			sun = (struct sockaddr_un *)&s->srv_conf.fastcgi_ss;
600 			sun->sun_family = AF_UNIX;
601 			(void)strlcpy(sun->sun_path, HTTPD_FCGI_SOCKET,
602 			    sizeof(sun->sun_path));
603 			sun->sun_len = sizeof(struct sockaddr_un);
604 
605 			s->srv_conf.id = ++last_server_id;
606 			/* A location entry uses the parent id */
607 			s->srv_conf.parent_id = srv->srv_conf.id;
608 			s->srv_conf.flags = SRVFLAG_LOCATION;
609 			if ($2 == 1) {
610 				s->srv_conf.flags &=
611 				    ~SRVFLAG_LOCATION_NOT_FOUND;
612 				s->srv_conf.flags |=
613 				    SRVFLAG_LOCATION_FOUND;
614 			} else if ($2 == -1) {
615 				s->srv_conf.flags &=
616 				    ~SRVFLAG_LOCATION_FOUND;
617 				s->srv_conf.flags |=
618 				    SRVFLAG_LOCATION_NOT_FOUND;
619 			}
620 			if ($3)
621 				s->srv_conf.flags |= SRVFLAG_LOCATION_MATCH;
622 			s->srv_s = -1;
623 			memcpy(&s->srv_conf.ss, &srv->srv_conf.ss,
624 			    sizeof(s->srv_conf.ss));
625 			s->srv_conf.port = srv->srv_conf.port;
626 			s->srv_conf.prefixlen = srv->srv_conf.prefixlen;
627 			s->srv_conf.tls_flags = srv->srv_conf.tls_flags;
628 
629 			if (last_server_id == INT_MAX) {
630 				yyerror("too many servers/locations defined");
631 				free(s);
632 				YYERROR;
633 			}
634 			parentsrv = srv;
635 			srv = s;
636 			srv_conf = &srv->srv_conf;
637 			SPLAY_INIT(&srv->srv_clients);
638 		} '{' optnl serveropts_l '}'	{
639 			struct server	*s = NULL;
640 			uint32_t	 f;
641 
642 			f = SRVFLAG_LOCATION_FOUND |
643 			    SRVFLAG_LOCATION_NOT_FOUND;
644 
645 			TAILQ_FOREACH(s, conf->sc_servers, srv_entry) {
646 				/* Compare locations of same parent server */
647 				if ((s->srv_conf.flags & SRVFLAG_LOCATION) &&
648 				    s->srv_conf.parent_id ==
649 				    srv_conf->parent_id &&
650 				    (s->srv_conf.flags & f) ==
651 				    (srv_conf->flags & f) &&
652 				    strcmp(s->srv_conf.location,
653 				    srv_conf->location) == 0)
654 					break;
655 			}
656 			if (s != NULL) {
657 				yyerror("location \"%s\" defined twice",
658 				    srv->srv_conf.location);
659 				serverconfig_free(srv_conf);
660 				free(srv);
661 				YYABORT;
662 			}
663 
664 			DPRINTF("adding location \"%s\" for \"%s[%u]\"",
665 			    srv->srv_conf.location,
666 			    srv->srv_conf.name, srv->srv_conf.id);
667 
668 			TAILQ_INSERT_TAIL(conf->sc_servers, srv, srv_entry);
669 
670 			srv = parentsrv;
671 			srv_conf = &parentsrv->srv_conf;
672 			parentsrv = NULL;
673 		}
674 		| DEFAULT TYPE mediastring	{
675 			srv_conf->flags |= SRVFLAG_DEFAULT_TYPE;
676 			memcpy(&srv_conf->default_type, &media,
677 			    sizeof(struct media_type));
678 		}
679 		| include
680 		| hsts				{
681 			if (parentsrv != NULL) {
682 				yyerror("hsts inside location");
683 				YYERROR;
684 			}
685 			srv->srv_conf.flags |= SRVFLAG_SERVER_HSTS;
686 		}
687 		;
688 
689 optfound	: /* empty */	{ $$ = 0; }
690 		| FOUND		{ $$ = 1; }
691 		| NOT FOUND	{ $$ = -1; }
692 		;
693 
694 hsts		: HSTS '{' optnl hstsflags_l '}'
695 		| HSTS hstsflags
696 		| HSTS
697 		;
698 
699 hstsflags_l	: hstsflags optcommanl hstsflags_l
700 		| hstsflags optnl
701 		;
702 
703 hstsflags	: MAXAGE NUMBER		{
704 			if ($2 < 0 || $2 > INT_MAX) {
705 				yyerror("invalid number of seconds: %lld", $2);
706 				YYERROR;
707 			}
708 			srv_conf->hsts_max_age = $2;
709 		}
710 		| SUBDOMAINS		{
711 			srv->srv_conf.hsts_flags |= HSTSFLAG_SUBDOMAINS;
712 		}
713 		| PRELOAD		{
714 			srv->srv_conf.hsts_flags |= HSTSFLAG_PRELOAD;
715 		}
716 		;
717 
718 fastcgi		: NO FCGI		{
719 			srv_conf->flags &= ~SRVFLAG_FCGI;
720 			srv_conf->flags |= SRVFLAG_NO_FCGI;
721 		}
722 		| FCGI			{
723 			srv_conf->flags &= ~SRVFLAG_NO_FCGI;
724 			srv_conf->flags |= SRVFLAG_FCGI;
725 		}
726 		| FCGI			{
727 			srv_conf->flags &= ~SRVFLAG_NO_FCGI;
728 			srv_conf->flags |= SRVFLAG_FCGI;
729 		} '{' optnl fcgiflags_l '}'
730 		| FCGI			{
731 			srv_conf->flags &= ~SRVFLAG_NO_FCGI;
732 			srv_conf->flags |= SRVFLAG_FCGI;
733 		} fcgiflags
734 		;
735 
736 fcgiflags_l	: fcgiflags optcommanl fcgiflags_l
737 		| fcgiflags optnl
738 		;
739 
740 fcgiflags	: SOCKET STRING {
741 			struct sockaddr_un *sun;
742 			sun = (struct sockaddr_un *)&srv_conf->fastcgi_ss;
743 			memset(sun, 0, sizeof(*sun));
744 			sun->sun_family = AF_UNIX;
745 			if (strlcpy(sun->sun_path, $2, sizeof(sun->sun_path))
746 			    >= sizeof(sun->sun_path)) {
747 				yyerror("socket path too long");
748 				free($2);
749 				YYERROR;
750 			}
751 			srv_conf->fastcgi_ss.ss_len =
752 			    sizeof(struct sockaddr_un);
753 			free($2);
754 		}
755 		| SOCKET TCP STRING {
756 			if (get_fastcgi_dest(srv_conf, $3, FCGI_DEFAULT_PORT)
757 			    == -1) {
758 				free($3);
759 				YYERROR;
760 			}
761 			free($3);
762 		}
763 		| SOCKET TCP STRING fcgiport {
764 			if (get_fastcgi_dest(srv_conf, $3, $4) == -1) {
765 				free($3);
766 				free($4);
767 				YYERROR;
768 			}
769 			free($3);
770 			free($4);
771 		}
772 		| PARAM STRING STRING	{
773 			struct fastcgi_param	*param;
774 
775 			if ((param = calloc(1, sizeof(*param))) == NULL)
776 				fatal("out of memory");
777 
778 			if (strlcpy(param->name, $2, sizeof(param->name)) >=
779 			    sizeof(param->name)) {
780 				yyerror("fastcgi_param name truncated");
781 				free($2);
782 				free($3);
783 				free(param);
784 				YYERROR;
785 			}
786 			if (strlcpy(param->value, $3, sizeof(param->value)) >=
787 			    sizeof(param->value)) {
788 				yyerror("fastcgi_param value truncated");
789 				free($2);
790 				free($3);
791 				free(param);
792 				YYERROR;
793 			}
794 			free($2);
795 			free($3);
796 
797 			DPRINTF("[%s,%s,%d]: adding param \"%s\" value \"%s\"",
798 			    srv_conf->location, srv_conf->name, srv_conf->id,
799 			    param->name, param->value);
800 			TAILQ_INSERT_HEAD(&srv_conf->fcgiparams, param, entry);
801 		}
802 		| STRIP NUMBER			{
803 			if ($2 < 0 || $2 > INT_MAX) {
804 				yyerror("invalid fastcgi strip number");
805 				YYERROR;
806 			}
807 			srv_conf->fcgistrip = $2;
808 		}
809 		;
810 
811 connection	: CONNECTION '{' optnl conflags_l '}'
812 		| CONNECTION conflags
813 		;
814 
815 conflags_l	: conflags optcommanl conflags_l
816 		| conflags optnl
817 		;
818 
819 conflags	: TIMEOUT timeout		{
820 			memcpy(&srv_conf->timeout, &$2,
821 			    sizeof(struct timeval));
822 		}
823 		| REQUEST TIMEOUT timeout	{
824 			memcpy(&srv_conf->requesttimeout, &$3,
825 			    sizeof(struct timeval));
826 		}
827 		| MAXIMUM REQUESTS NUMBER	{
828 			srv_conf->maxrequests = $3;
829 		}
830 		| MAXIMUM REQUEST BODY NUMBER	{
831 			srv_conf->maxrequestbody = $4;
832 		}
833 		;
834 
835 tls		: TLS '{' optnl tlsopts_l '}'
836 		| TLS tlsopts
837 		;
838 
839 tlsopts_l	: tlsopts optcommanl tlsopts_l
840 		| tlsopts optnl
841 		;
842 
843 tlsopts		: CERTIFICATE STRING		{
844 			free(srv_conf->tls_cert_file);
845 			if ((srv_conf->tls_cert_file = strdup($2)) == NULL)
846 				fatal("out of memory");
847 			free($2);
848 		}
849 		| KEY STRING			{
850 			free(srv_conf->tls_key_file);
851 			if ((srv_conf->tls_key_file = strdup($2)) == NULL)
852 				fatal("out of memory");
853 			free($2);
854 		}
855 		| OCSP STRING			{
856 			free(srv_conf->tls_ocsp_staple_file);
857 			if ((srv_conf->tls_ocsp_staple_file = strdup($2))
858 			    == NULL)
859 				fatal("out of memory");
860 			free($2);
861 		}
862 		| CIPHERS STRING		{
863 			if (strlcpy(srv_conf->tls_ciphers, $2,
864 			    sizeof(srv_conf->tls_ciphers)) >=
865 			    sizeof(srv_conf->tls_ciphers)) {
866 				yyerror("ciphers too long");
867 				free($2);
868 				YYERROR;
869 			}
870 			free($2);
871 		}
872 		| CLIENT CA STRING tlsclientopt {
873 			srv_conf->tls_flags |= TLSFLAG_CA;
874 			free(srv_conf->tls_ca_file);
875 			if ((srv_conf->tls_ca_file = strdup($3)) == NULL)
876 				fatal("out of memory");
877 			free($3);
878 		}
879 		| DHE STRING			{
880 			if (strlcpy(srv_conf->tls_dhe_params, $2,
881 			    sizeof(srv_conf->tls_dhe_params)) >=
882 			    sizeof(srv_conf->tls_dhe_params)) {
883 				yyerror("dhe too long");
884 				free($2);
885 				YYERROR;
886 			}
887 			free($2);
888 		}
889 		| ECDHE STRING			{
890 			if (strlcpy(srv_conf->tls_ecdhe_curves, $2,
891 			    sizeof(srv_conf->tls_ecdhe_curves)) >=
892 			    sizeof(srv_conf->tls_ecdhe_curves)) {
893 				yyerror("ecdhe too long");
894 				free($2);
895 				YYERROR;
896 			}
897 			free($2);
898 		}
899 		| PROTOCOLS STRING		{
900 			if (tls_config_parse_protocols(
901 			    &srv_conf->tls_protocols, $2) != 0) {
902 				yyerror("invalid tls protocols");
903 				free($2);
904 				YYERROR;
905 			}
906 			free($2);
907 		}
908 		| TICKET LIFETIME DEFAULT	{
909 			srv_conf->tls_ticket_lifetime = SERVER_DEF_TLS_LIFETIME;
910 		}
911 		| TICKET LIFETIME NUMBER	{
912 			if ($3 != 0 && $3 < SERVER_MIN_TLS_LIFETIME) {
913 				yyerror("ticket lifetime too small");
914 				YYERROR;
915 			}
916 			if ($3 > SERVER_MAX_TLS_LIFETIME) {
917 				yyerror("ticket lifetime too large");
918 				YYERROR;
919 			}
920 			srv_conf->tls_ticket_lifetime = $3;
921 		}
922 		| NO TICKET			{
923 			srv_conf->tls_ticket_lifetime = 0;
924 		}
925 		;
926 
927 tlsclientopt	: /* empty */
928 		| tlsclientopt CRL STRING	{
929 			srv_conf->tls_flags = TLSFLAG_CRL;
930 			free(srv_conf->tls_crl_file);
931 			if ((srv_conf->tls_crl_file = strdup($3)) == NULL)
932 				fatal("out of memory");
933 			free($3);
934 		}
935 		| tlsclientopt OPTIONAL		{
936 			srv_conf->tls_flags |= TLSFLAG_OPTIONAL;
937 		}
938 		;
939 root		: ROOT rootflags
940 		| ROOT '{' optnl rootflags_l '}'
941 		;
942 
943 rootflags_l	: rootflags optcommanl rootflags_l
944 		| rootflags optnl
945 		;
946 
947 rootflags	: STRING		{
948 			if (strlcpy(srv->srv_conf.root, $1,
949 			    sizeof(srv->srv_conf.root)) >=
950 			    sizeof(srv->srv_conf.root)) {
951 				yyerror("document root too long");
952 				free($1);
953 				YYERROR;
954 			}
955 			free($1);
956 			srv->srv_conf.flags |= SRVFLAG_ROOT;
957 		}
958 		;
959 
960 request		: REQUEST requestflags
961 		| REQUEST '{' optnl requestflags_l '}'
962 		;
963 
964 requestflags_l	: requestflags optcommanl requestflags_l
965 		| requestflags optnl
966 		;
967 
968 requestflags	: REWRITE STRING		{
969 			if (strlcpy(srv->srv_conf.path, $2,
970 			    sizeof(srv->srv_conf.path)) >=
971 			    sizeof(srv->srv_conf.path)) {
972 				yyerror("request path too long");
973 				free($2);
974 				YYERROR;
975 			}
976 			free($2);
977 			srv->srv_conf.flags |= SRVFLAG_PATH_REWRITE;
978 			srv->srv_conf.flags &= ~SRVFLAG_NO_PATH_REWRITE;
979 		}
980 		| NO REWRITE			{
981 			srv->srv_conf.flags |= SRVFLAG_NO_PATH_REWRITE;
982 			srv->srv_conf.flags &= ~SRVFLAG_PATH_REWRITE;
983 		}
984 		| STRIP NUMBER			{
985 			if ($2 < 0 || $2 > INT_MAX) {
986 				yyerror("invalid strip number");
987 				YYERROR;
988 			}
989 			srv->srv_conf.strip = $2;
990 		}
991 		;
992 
993 authenticate	: NO AUTHENTICATE		{
994 			srv->srv_conf.flags |= SRVFLAG_NO_AUTH;
995 		}
996 		| AUTHENTICATE authopts		{
997 			struct auth	*auth;
998 
999 			if ((auth = auth_add(conf->sc_auth, &$2)) == NULL) {
1000 				yyerror("failed to add auth");
1001 				YYERROR;
1002 			}
1003 
1004 			if (auth->auth_id == 0) {
1005 				/* New htpasswd, get new Id */
1006 				auth->auth_id = ++last_auth_id;
1007 				if (last_auth_id == INT_MAX) {
1008 					yyerror("too many auth ids defined");
1009 					auth_free(conf->sc_auth, auth);
1010 					YYERROR;
1011 				}
1012 			}
1013 
1014 			srv->srv_conf.auth_id = auth->auth_id;
1015 			srv->srv_conf.flags |= SRVFLAG_AUTH;
1016 		}
1017 		;
1018 
1019 authopts	: STRING WITH STRING	{
1020 			if (strlcpy(srv->srv_conf.auth_realm, $1,
1021 			    sizeof(srv->srv_conf.auth_realm)) >=
1022 			    sizeof(srv->srv_conf.auth_realm)) {
1023 				yyerror("basic auth realm name too long");
1024 				free($1);
1025 				YYERROR;
1026 			}
1027 			free($1);
1028 			if (strlcpy($$.auth_htpasswd, $3,
1029 			    sizeof($$.auth_htpasswd)) >=
1030 			    sizeof($$.auth_htpasswd)) {
1031 				yyerror("password file name too long");
1032 				free($3);
1033 				YYERROR;
1034 			}
1035 			free($3);
1036 
1037 		}
1038 		| WITH STRING		{
1039 			if (strlcpy($$.auth_htpasswd, $2,
1040 			    sizeof($$.auth_htpasswd)) >=
1041 			    sizeof($$.auth_htpasswd)) {
1042 				yyerror("password file name too long");
1043 				free($2);
1044 				YYERROR;
1045 			}
1046 			free($2);
1047 		};
1048 
1049 directory	: DIRECTORY dirflags
1050 		| DIRECTORY '{' optnl dirflags_l '}'
1051 		;
1052 
1053 dirflags_l	: dirflags optcommanl dirflags_l
1054 		| dirflags optnl
1055 		;
1056 
1057 dirflags	: INDEX STRING		{
1058 			if (strlcpy(srv_conf->index, $2,
1059 			    sizeof(srv_conf->index)) >=
1060 			    sizeof(srv_conf->index)) {
1061 				yyerror("index file too long");
1062 				free($2);
1063 				YYERROR;
1064 			}
1065 			srv_conf->flags &= ~SRVFLAG_NO_INDEX;
1066 			srv_conf->flags |= SRVFLAG_INDEX;
1067 			free($2);
1068 		}
1069 		| NO INDEX		{
1070 			srv_conf->flags &= ~SRVFLAG_INDEX;
1071 			srv_conf->flags |= SRVFLAG_NO_INDEX;
1072 		}
1073 		| AUTO INDEX		{
1074 			srv_conf->flags &= ~SRVFLAG_NO_AUTO_INDEX;
1075 			srv_conf->flags |= SRVFLAG_AUTO_INDEX;
1076 		}
1077 		| NO AUTO INDEX		{
1078 			srv_conf->flags &= ~SRVFLAG_AUTO_INDEX;
1079 			srv_conf->flags |= SRVFLAG_NO_AUTO_INDEX;
1080 		}
1081 		;
1082 
1083 
1084 logformat	: LOG logflags
1085 		| LOG '{' optnl logflags_l '}'
1086 		| NO LOG		{
1087 			srv_conf->flags &= ~SRVFLAG_LOG;
1088 			srv_conf->flags |= SRVFLAG_NO_LOG;
1089 		}
1090 		;
1091 
1092 logflags_l	: logflags optcommanl logflags_l
1093 		| logflags optnl
1094 		;
1095 
1096 logflags	: STYLE logstyle
1097 		| SYSLOG		{
1098 			srv_conf->flags &= ~SRVFLAG_NO_SYSLOG;
1099 			srv_conf->flags |= SRVFLAG_SYSLOG;
1100 		}
1101 		| NO SYSLOG		{
1102 			srv_conf->flags &= ~SRVFLAG_SYSLOG;
1103 			srv_conf->flags |= SRVFLAG_NO_SYSLOG;
1104 		}
1105 		| ACCESS STRING		{
1106 			if (strlcpy(srv_conf->accesslog, $2,
1107 			    sizeof(srv_conf->accesslog)) >=
1108 			    sizeof(srv_conf->accesslog)) {
1109 				yyerror("access log name too long");
1110 				free($2);
1111 				YYERROR;
1112 			}
1113 			free($2);
1114 			srv_conf->flags |= SRVFLAG_ACCESS_LOG;
1115 		}
1116 		| ERR STRING		{
1117 			if (strlcpy(srv_conf->errorlog, $2,
1118 			    sizeof(srv_conf->errorlog)) >=
1119 			    sizeof(srv_conf->errorlog)) {
1120 				yyerror("error log name too long");
1121 				free($2);
1122 				YYERROR;
1123 			}
1124 			free($2);
1125 			srv_conf->flags |= SRVFLAG_ERROR_LOG;
1126 		}
1127 		;
1128 
1129 logstyle	: COMMON		{
1130 			srv_conf->flags &= ~SRVFLAG_NO_LOG;
1131 			srv_conf->flags |= SRVFLAG_LOG;
1132 			srv_conf->logformat = LOG_FORMAT_COMMON;
1133 		}
1134 		| COMBINED		{
1135 			srv_conf->flags &= ~SRVFLAG_NO_LOG;
1136 			srv_conf->flags |= SRVFLAG_LOG;
1137 			srv_conf->logformat = LOG_FORMAT_COMBINED;
1138 		}
1139 		| CONNECTION		{
1140 			srv_conf->flags &= ~SRVFLAG_NO_LOG;
1141 			srv_conf->flags |= SRVFLAG_LOG;
1142 			srv_conf->logformat = LOG_FORMAT_CONNECTION;
1143 		}
1144 		| FORWARDED		{
1145 			srv_conf->flags &= ~SRVFLAG_NO_LOG;
1146 			srv_conf->flags |= SRVFLAG_LOG;
1147 			srv_conf->logformat = LOG_FORMAT_FORWARDED;
1148 		}
1149 		;
1150 
1151 filter		: block RETURN NUMBER optstring	{
1152 			if ($3 <= 0 || server_httperror_byid($3) == NULL) {
1153 				yyerror("invalid return code: %lld", $3);
1154 				free($4);
1155 				YYERROR;
1156 			}
1157 			srv_conf->return_code = $3;
1158 
1159 			if ($4 != NULL) {
1160 				/* Only for 3xx redirection headers */
1161 				if ($3 < 300 || $3 > 399) {
1162 					yyerror("invalid return code for "
1163 					    "location URI");
1164 					free($4);
1165 					YYERROR;
1166 				}
1167 				srv_conf->return_uri = $4;
1168 				srv_conf->return_uri_len = strlen($4) + 1;
1169 			}
1170 		}
1171 		| block DROP			{
1172 			/* No return code, silently drop the connection */
1173 			srv_conf->return_code = 0;
1174 		}
1175 		| block				{
1176 			/* Forbidden */
1177 			srv_conf->return_code = 403;
1178 		}
1179 		| PASS				{
1180 			srv_conf->flags &= ~SRVFLAG_BLOCK;
1181 			srv_conf->flags |= SRVFLAG_NO_BLOCK;
1182 		}
1183 		;
1184 
1185 block		: BLOCK				{
1186 			srv_conf->flags &= ~SRVFLAG_NO_BLOCK;
1187 			srv_conf->flags |= SRVFLAG_BLOCK;
1188 		}
1189 		;
1190 
1191 optmatch	: /* empty */		{ $$ = 0; }
1192 		| MATCH			{ $$ = 1; }
1193 		;
1194 
1195 optstring	: /* empty */		{ $$ = NULL; }
1196 		| STRING		{ $$ = $1; }
1197 		;
1198 
1199 fcgiport	: NUMBER		{
1200 			if ($1 <= 0 || $1 > (int)USHRT_MAX) {
1201 				yyerror("invalid port: %lld", $1);
1202 				YYERROR;
1203 			}
1204 			if (asprintf(&$$, "%lld", $1) == -1) {
1205 				yyerror("out of memory");
1206 				YYERROR;
1207 			}
1208 		}
1209 		| STRING		{
1210 			if (getservice($1) <= 0) {
1211 				yyerror("invalid port: %s", $1);
1212 				free($1);
1213 				YYERROR;
1214 			}
1215 
1216 			$$ = $1;
1217 		}
1218 		;
1219 
1220 tcpip		: TCP '{' optnl tcpflags_l '}'
1221 		| TCP tcpflags
1222 		;
1223 
1224 tcpflags_l	: tcpflags optcommanl tcpflags_l
1225 		| tcpflags optnl
1226 		;
1227 
1228 tcpflags	: SACK			{ srv_conf->tcpflags |= TCPFLAG_SACK; }
1229 		| NO SACK		{ srv_conf->tcpflags |= TCPFLAG_NSACK; }
1230 		| NODELAY		{
1231 			srv_conf->tcpflags |= TCPFLAG_NODELAY;
1232 		}
1233 		| NO NODELAY		{
1234 			srv_conf->tcpflags |= TCPFLAG_NNODELAY;
1235 		}
1236 		| BACKLOG NUMBER	{
1237 			if ($2 < 0 || $2 > SERVER_MAX_CLIENTS) {
1238 				yyerror("invalid backlog: %lld", $2);
1239 				YYERROR;
1240 			}
1241 			srv_conf->tcpbacklog = $2;
1242 		}
1243 		| SOCKET BUFFER NUMBER	{
1244 			srv_conf->tcpflags |= TCPFLAG_BUFSIZ;
1245 			if ((srv_conf->tcpbufsiz = $3) < 0) {
1246 				yyerror("invalid socket buffer size: %lld", $3);
1247 				YYERROR;
1248 			}
1249 		}
1250 		| IP STRING NUMBER	{
1251 			if ($3 < 0) {
1252 				yyerror("invalid ttl: %lld", $3);
1253 				free($2);
1254 				YYERROR;
1255 			}
1256 			if (strcasecmp("ttl", $2) == 0) {
1257 				srv_conf->tcpflags |= TCPFLAG_IPTTL;
1258 				srv_conf->tcpipttl = $3;
1259 			} else if (strcasecmp("minttl", $2) == 0) {
1260 				srv_conf->tcpflags |= TCPFLAG_IPMINTTL;
1261 				srv_conf->tcpipminttl = $3;
1262 			} else {
1263 				yyerror("invalid TCP/IP flag: %s", $2);
1264 				free($2);
1265 				YYERROR;
1266 			}
1267 			free($2);
1268 		}
1269 		;
1270 
1271 types		: TYPES	'{' optnl mediaopts_l '}'
1272 		;
1273 
1274 mediaopts_l	: mediaopts_l mediaoptsl nl
1275 		| mediaoptsl nl
1276 		;
1277 
1278 mediaoptsl	: mediastring medianames_l optsemicolon
1279 		| include
1280 		;
1281 
1282 mediastring	: STRING '/' STRING	{
1283 			if (strlcpy(media.media_type, $1,
1284 			    sizeof(media.media_type)) >=
1285 			    sizeof(media.media_type) ||
1286 			    strlcpy(media.media_subtype, $3,
1287 			    sizeof(media.media_subtype)) >=
1288 			    sizeof(media.media_subtype)) {
1289 				yyerror("media type too long");
1290 				free($1);
1291 				free($3);
1292 				YYERROR;
1293 			}
1294 			free($1);
1295 			free($3);
1296 		}
1297 		;
1298 
1299 medianames_l	: medianames_l medianamesl
1300 		| medianamesl
1301 		;
1302 
1303 medianamesl	: numberstring				{
1304 			if (strlcpy(media.media_name, $1,
1305 			    sizeof(media.media_name)) >=
1306 			    sizeof(media.media_name)) {
1307 				yyerror("media name too long");
1308 				free($1);
1309 				YYERROR;
1310 			}
1311 			free($1);
1312 
1313 			if (!loadcfg)
1314 				break;
1315 
1316 			if (media_add(conf->sc_mediatypes, &media) == NULL) {
1317 				yyerror("failed to add media type");
1318 				YYERROR;
1319 			}
1320 		}
1321 		;
1322 
1323 port		: PORT NUMBER {
1324 			if ($2 <= 0 || $2 > (int)USHRT_MAX) {
1325 				yyerror("invalid port: %lld", $2);
1326 				YYERROR;
1327 			}
1328 			$$.val[0] = htons($2);
1329 			$$.op = 1;
1330 		}
1331 		| PORT STRING {
1332 			int	 val;
1333 
1334 			if ((val = getservice($2)) == -1) {
1335 				yyerror("invalid port: %s", $2);
1336 				free($2);
1337 				YYERROR;
1338 			}
1339 			free($2);
1340 
1341 			$$.val[0] = val;
1342 			$$.op = 1;
1343 		}
1344 		;
1345 
1346 timeout		: NUMBER
1347 		{
1348 			if ($1 < 0) {
1349 				yyerror("invalid timeout: %lld", $1);
1350 				YYERROR;
1351 			}
1352 			$$.tv_sec = $1;
1353 			$$.tv_usec = 0;
1354 		}
1355 		;
1356 
1357 numberstring	: NUMBER		{
1358 			char *s;
1359 			if (asprintf(&s, "%lld", $1) == -1) {
1360 				yyerror("asprintf: number");
1361 				YYERROR;
1362 			}
1363 			$$ = s;
1364 		}
1365 		| STRING
1366 		;
1367 
1368 optsemicolon	: ';'
1369 		|
1370 		;
1371 
1372 optnl		: '\n' optnl
1373 		|
1374 		;
1375 
1376 optcommanl	: ',' optnl
1377 		| nl
1378 		;
1379 
1380 nl		: '\n' optnl
1381 		;
1382 
1383 %%
1384 
1385 struct keywords {
1386 	const char	*k_name;
1387 	int		 k_val;
1388 };
1389 
1390 int
1391 yyerror(const char *fmt, ...)
1392 {
1393 	va_list		 ap;
1394 	char		*msg;
1395 
1396 	file->errors++;
1397 	va_start(ap, fmt);
1398 	if (vasprintf(&msg, fmt, ap) == -1)
1399 		fatalx("yyerror vasprintf");
1400 	va_end(ap);
1401 	logit(LOG_CRIT, "%s:%d: %s", file->name, yylval.lineno, msg);
1402 	free(msg);
1403 	return (0);
1404 }
1405 
1406 int
1407 kw_cmp(const void *k, const void *e)
1408 {
1409 	return (strcmp(k, ((const struct keywords *)e)->k_name));
1410 }
1411 
1412 int
1413 lookup(char *s)
1414 {
1415 	/* this has to be sorted always */
1416 	static const struct keywords keywords[] = {
1417 		{ "access",		ACCESS },
1418 		{ "alias",		ALIAS },
1419 		{ "authenticate",	AUTHENTICATE},
1420 		{ "auto",		AUTO },
1421 		{ "backlog",		BACKLOG },
1422 		{ "block",		BLOCK },
1423 		{ "body",		BODY },
1424 		{ "buffer",		BUFFER },
1425 		{ "ca",			CA },
1426 		{ "certificate",	CERTIFICATE },
1427 		{ "chroot",		CHROOT },
1428 		{ "ciphers",		CIPHERS },
1429 		{ "client",		CLIENT },
1430 		{ "combined",		COMBINED },
1431 		{ "common",		COMMON },
1432 		{ "connection",		CONNECTION },
1433 		{ "crl",		CRL },
1434 		{ "default",		DEFAULT },
1435 		{ "dhe",		DHE },
1436 		{ "directory",		DIRECTORY },
1437 		{ "drop",		DROP },
1438 		{ "ecdhe",		ECDHE },
1439 		{ "errdocs",		ERRDOCS },
1440 		{ "error",		ERR },
1441 		{ "fastcgi",		FCGI },
1442 		{ "forwarded",		FORWARDED },
1443 		{ "found",		FOUND },
1444 		{ "hsts",		HSTS },
1445 		{ "include",		INCLUDE },
1446 		{ "index",		INDEX },
1447 		{ "ip",			IP },
1448 		{ "key",		KEY },
1449 		{ "lifetime",		LIFETIME },
1450 		{ "listen",		LISTEN },
1451 		{ "location",		LOCATION },
1452 		{ "log",		LOG },
1453 		{ "logdir",		LOGDIR },
1454 		{ "match",		MATCH },
1455 		{ "max",		MAXIMUM },
1456 		{ "max-age",		MAXAGE },
1457 		{ "no",			NO },
1458 		{ "nodelay",		NODELAY },
1459 		{ "not",		NOT },
1460 		{ "ocsp",		OCSP },
1461 		{ "on",			ON },
1462 		{ "optional",		OPTIONAL },
1463 		{ "param",		PARAM },
1464 		{ "pass",		PASS },
1465 		{ "port",		PORT },
1466 		{ "prefork",		PREFORK },
1467 		{ "preload",		PRELOAD },
1468 		{ "protocols",		PROTOCOLS },
1469 		{ "request",		REQUEST },
1470 		{ "requests",		REQUESTS },
1471 		{ "return",		RETURN },
1472 		{ "rewrite",		REWRITE },
1473 		{ "root",		ROOT },
1474 		{ "sack",		SACK },
1475 		{ "server",		SERVER },
1476 		{ "socket",		SOCKET },
1477 		{ "strip",		STRIP },
1478 		{ "style",		STYLE },
1479 		{ "subdomains",		SUBDOMAINS },
1480 		{ "syslog",		SYSLOG },
1481 		{ "tcp",		TCP },
1482 		{ "ticket",		TICKET },
1483 		{ "timeout",		TIMEOUT },
1484 		{ "tls",		TLS },
1485 		{ "type",		TYPE },
1486 		{ "types",		TYPES },
1487 		{ "with",		WITH }
1488 	};
1489 	const struct keywords	*p;
1490 
1491 	p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
1492 	    sizeof(keywords[0]), kw_cmp);
1493 
1494 	if (p)
1495 		return (p->k_val);
1496 	else
1497 		return (STRING);
1498 }
1499 
1500 #define START_EXPAND	1
1501 #define DONE_EXPAND	2
1502 
1503 static int	expanding;
1504 
1505 int
1506 igetc(void)
1507 {
1508 	int	c;
1509 
1510 	while (1) {
1511 		if (file->ungetpos > 0)
1512 			c = file->ungetbuf[--file->ungetpos];
1513 		else
1514 			c = getc(file->stream);
1515 
1516 		if (c == START_EXPAND)
1517 			expanding = 1;
1518 		else if (c == DONE_EXPAND)
1519 			expanding = 0;
1520 		else
1521 			break;
1522 	}
1523 	return (c);
1524 }
1525 
1526 int
1527 lgetc(int quotec)
1528 {
1529 	int		c, next;
1530 
1531 	if (quotec) {
1532 		if ((c = igetc()) == EOF) {
1533 			yyerror("reached end of file while parsing "
1534 			    "quoted string");
1535 			if (file == topfile || popfile() == EOF)
1536 				return (EOF);
1537 			return (quotec);
1538 		}
1539 		return (c);
1540 	}
1541 
1542 	while ((c = igetc()) == '\\') {
1543 		next = igetc();
1544 		if (next != '\n') {
1545 			c = next;
1546 			break;
1547 		}
1548 		yylval.lineno = file->lineno;
1549 		file->lineno++;
1550 	}
1551 
1552 	if (c == EOF) {
1553 		/*
1554 		 * Fake EOL when hit EOF for the first time. This gets line
1555 		 * count right if last line in included file is syntactically
1556 		 * invalid and has no newline.
1557 		 */
1558 		if (file->eof_reached == 0) {
1559 			file->eof_reached = 1;
1560 			return ('\n');
1561 		}
1562 		while (c == EOF) {
1563 			if (file == topfile || popfile() == EOF)
1564 				return (EOF);
1565 			c = igetc();
1566 		}
1567 	}
1568 	return (c);
1569 }
1570 
1571 void
1572 lungetc(int c)
1573 {
1574 	if (c == EOF)
1575 		return;
1576 
1577 	if (file->ungetpos >= file->ungetsize) {
1578 		void *p = reallocarray(file->ungetbuf, file->ungetsize, 2);
1579 		if (p == NULL)
1580 			err(1, "%s", __func__);
1581 		file->ungetbuf = p;
1582 		file->ungetsize *= 2;
1583 	}
1584 	file->ungetbuf[file->ungetpos++] = c;
1585 }
1586 
1587 int
1588 findeol(void)
1589 {
1590 	int	c;
1591 
1592 	/* skip to either EOF or the first real EOL */
1593 	while (1) {
1594 		c = lgetc(0);
1595 		if (c == '\n') {
1596 			file->lineno++;
1597 			break;
1598 		}
1599 		if (c == EOF)
1600 			break;
1601 	}
1602 	return (ERROR);
1603 }
1604 
1605 int
1606 yylex(void)
1607 {
1608 	char	 buf[8096];
1609 	char	*p, *val;
1610 	int	 quotec, next, c;
1611 	int	 token;
1612 
1613 top:
1614 	p = buf;
1615 	while ((c = lgetc(0)) == ' ' || c == '\t')
1616 		; /* nothing */
1617 
1618 	yylval.lineno = file->lineno;
1619 	if (c == '#')
1620 		while ((c = lgetc(0)) != '\n' && c != EOF)
1621 			; /* nothing */
1622 	if (c == '$' && !expanding) {
1623 		while (1) {
1624 			if ((c = lgetc(0)) == EOF)
1625 				return (0);
1626 
1627 			if (p + 1 >= buf + sizeof(buf) - 1) {
1628 				yyerror("string too long");
1629 				return (findeol());
1630 			}
1631 			if (isalnum(c) || c == '_') {
1632 				*p++ = c;
1633 				continue;
1634 			}
1635 			*p = '\0';
1636 			lungetc(c);
1637 			break;
1638 		}
1639 		val = symget(buf);
1640 		if (val == NULL) {
1641 			yyerror("macro '%s' not defined", buf);
1642 			return (findeol());
1643 		}
1644 		p = val + strlen(val) - 1;
1645 		lungetc(DONE_EXPAND);
1646 		while (p >= val) {
1647 			lungetc((unsigned char)*p);
1648 			p--;
1649 		}
1650 		lungetc(START_EXPAND);
1651 		goto top;
1652 	}
1653 
1654 	switch (c) {
1655 	case '\'':
1656 	case '"':
1657 		quotec = c;
1658 		while (1) {
1659 			if ((c = lgetc(quotec)) == EOF)
1660 				return (0);
1661 			if (c == '\n') {
1662 				file->lineno++;
1663 				continue;
1664 			} else if (c == '\\') {
1665 				if ((next = lgetc(quotec)) == EOF)
1666 					return (0);
1667 				if (next == quotec || next == ' ' ||
1668 				    next == '\t')
1669 					c = next;
1670 				else if (next == '\n') {
1671 					file->lineno++;
1672 					continue;
1673 				} else
1674 					lungetc(next);
1675 			} else if (c == quotec) {
1676 				*p = '\0';
1677 				break;
1678 			} else if (c == '\0') {
1679 				yyerror("syntax error");
1680 				return (findeol());
1681 			}
1682 			if (p + 1 >= buf + sizeof(buf) - 1) {
1683 				yyerror("string too long");
1684 				return (findeol());
1685 			}
1686 			*p++ = c;
1687 		}
1688 		yylval.v.string = strdup(buf);
1689 		if (yylval.v.string == NULL)
1690 			err(1, "%s", __func__);
1691 		return (STRING);
1692 	}
1693 
1694 #define allowed_to_end_number(x) \
1695 	(isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=')
1696 
1697 	if (c == '-' || isdigit(c)) {
1698 		do {
1699 			*p++ = c;
1700 			if ((size_t)(p-buf) >= sizeof(buf)) {
1701 				yyerror("string too long");
1702 				return (findeol());
1703 			}
1704 		} while ((c = lgetc(0)) != EOF && isdigit(c));
1705 		lungetc(c);
1706 		if (p == buf + 1 && buf[0] == '-')
1707 			goto nodigits;
1708 		if (c == EOF || allowed_to_end_number(c)) {
1709 			const char *errstr = NULL;
1710 
1711 			*p = '\0';
1712 			yylval.v.number = strtonum(buf, LLONG_MIN,
1713 			    LLONG_MAX, &errstr);
1714 			if (errstr) {
1715 				yyerror("\"%s\" invalid number: %s",
1716 				    buf, errstr);
1717 				return (findeol());
1718 			}
1719 			return (NUMBER);
1720 		} else {
1721 nodigits:
1722 			while (p > buf + 1)
1723 				lungetc((unsigned char)*--p);
1724 			c = (unsigned char)*--p;
1725 			if (c == '-')
1726 				return (c);
1727 		}
1728 	}
1729 
1730 #define allowed_in_string(x) \
1731 	(isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
1732 	x != '{' && x != '}' && x != '<' && x != '>' && \
1733 	x != '!' && x != '=' && x != '#' && \
1734 	x != ',' && x != ';' && x != '/'))
1735 
1736 	if (isalnum(c) || c == ':' || c == '_' || c == '*') {
1737 		do {
1738 			*p++ = c;
1739 			if ((size_t)(p-buf) >= sizeof(buf)) {
1740 				yyerror("string too long");
1741 				return (findeol());
1742 			}
1743 		} while ((c = lgetc(0)) != EOF && (allowed_in_string(c)));
1744 		lungetc(c);
1745 		*p = '\0';
1746 		if ((token = lookup(buf)) == STRING)
1747 			if ((yylval.v.string = strdup(buf)) == NULL)
1748 				err(1, "%s", __func__);
1749 		return (token);
1750 	}
1751 	if (c == '\n') {
1752 		yylval.lineno = file->lineno;
1753 		file->lineno++;
1754 	}
1755 	if (c == EOF)
1756 		return (0);
1757 	return (c);
1758 }
1759 
1760 int
1761 check_file_secrecy(int fd, const char *fname)
1762 {
1763 	struct stat	st;
1764 
1765 	if (fstat(fd, &st)) {
1766 		log_warn("cannot stat %s", fname);
1767 		return (-1);
1768 	}
1769 	if (st.st_uid != 0 && st.st_uid != getuid()) {
1770 		log_warnx("%s: owner not root or current user", fname);
1771 		return (-1);
1772 	}
1773 	if (st.st_mode & (S_IWGRP | S_IXGRP | S_IRWXO)) {
1774 		log_warnx("%s: group writable or world read/writable", fname);
1775 		return (-1);
1776 	}
1777 	return (0);
1778 }
1779 
1780 struct file *
1781 pushfile(const char *name, int secret)
1782 {
1783 	struct file	*nfile;
1784 
1785 	if ((nfile = calloc(1, sizeof(struct file))) == NULL) {
1786 		log_warn("%s", __func__);
1787 		return (NULL);
1788 	}
1789 	if ((nfile->name = strdup(name)) == NULL) {
1790 		log_warn("%s", __func__);
1791 		free(nfile);
1792 		return (NULL);
1793 	}
1794 	if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
1795 		log_warn("%s: %s", __func__, nfile->name);
1796 		free(nfile->name);
1797 		free(nfile);
1798 		return (NULL);
1799 	} else if (secret &&
1800 	    check_file_secrecy(fileno(nfile->stream), nfile->name)) {
1801 		fclose(nfile->stream);
1802 		free(nfile->name);
1803 		free(nfile);
1804 		return (NULL);
1805 	}
1806 	nfile->lineno = TAILQ_EMPTY(&files) ? 1 : 0;
1807 	nfile->ungetsize = 16;
1808 	nfile->ungetbuf = malloc(nfile->ungetsize);
1809 	if (nfile->ungetbuf == NULL) {
1810 		log_warn("%s", __func__);
1811 		fclose(nfile->stream);
1812 		free(nfile->name);
1813 		free(nfile);
1814 		return (NULL);
1815 	}
1816 	TAILQ_INSERT_TAIL(&files, nfile, entry);
1817 	return (nfile);
1818 }
1819 
1820 int
1821 popfile(void)
1822 {
1823 	struct file	*prev;
1824 
1825 	if ((prev = TAILQ_PREV(file, files, entry)) != NULL)
1826 		prev->errors += file->errors;
1827 
1828 	TAILQ_REMOVE(&files, file, entry);
1829 	fclose(file->stream);
1830 	free(file->name);
1831 	free(file->ungetbuf);
1832 	free(file);
1833 	file = prev;
1834 	return (file ? 0 : EOF);
1835 }
1836 
1837 int
1838 parse_config(const char *filename, struct httpd *x_conf)
1839 {
1840 	struct sym		*sym, *next;
1841 	struct media_type	 dflt = HTTPD_DEFAULT_TYPE;
1842 
1843 	conf = x_conf;
1844 	if (config_init(conf) == -1) {
1845 		log_warn("%s: cannot initialize configuration", __func__);
1846 		return (-1);
1847 	}
1848 
1849 	/* Set default media type */
1850 	memcpy(&conf->sc_default_type, &dflt, sizeof(struct media_type));
1851 
1852 	errors = 0;
1853 
1854 	if ((file = pushfile(filename, 0)) == NULL)
1855 		return (-1);
1856 
1857 	topfile = file;
1858 	setservent(1);
1859 
1860 	yyparse();
1861 	errors = file->errors;
1862 	while (popfile() != EOF)
1863 		;
1864 
1865 	endservent();
1866 	endprotoent();
1867 
1868 	/* Free macros */
1869 	TAILQ_FOREACH_SAFE(sym, &symhead, entry, next) {
1870 		if (!sym->persist) {
1871 			free(sym->nam);
1872 			free(sym->val);
1873 			TAILQ_REMOVE(&symhead, sym, entry);
1874 			free(sym);
1875 		}
1876 	}
1877 
1878 	return (errors ? -1 : 0);
1879 }
1880 
1881 int
1882 load_config(const char *filename, struct httpd *x_conf)
1883 {
1884 	struct sym		*sym, *next;
1885 	struct http_mediatype	 mediatypes[] = MEDIA_TYPES;
1886 	struct media_type	 m;
1887 	int			 i;
1888 
1889 	conf = x_conf;
1890 	conf->sc_flags = 0;
1891 
1892 	loadcfg = 1;
1893 	errors = 0;
1894 	last_server_id = 0;
1895 	last_auth_id = 0;
1896 
1897 	srv = NULL;
1898 
1899 	if ((file = pushfile(filename, 0)) == NULL)
1900 		return (-1);
1901 
1902 	topfile = file;
1903 	setservent(1);
1904 
1905 	yyparse();
1906 	errors = file->errors;
1907 	popfile();
1908 
1909 	endservent();
1910 	endprotoent();
1911 
1912 	/* Free macros and check which have not been used. */
1913 	for (sym = TAILQ_FIRST(&symhead); sym != NULL; sym = next) {
1914 		next = TAILQ_NEXT(sym, entry);
1915 		if ((conf->sc_opts & HTTPD_OPT_VERBOSE) && !sym->used)
1916 			fprintf(stderr, "warning: macro '%s' not "
1917 			    "used\n", sym->nam);
1918 		if (!sym->persist) {
1919 			free(sym->nam);
1920 			free(sym->val);
1921 			TAILQ_REMOVE(&symhead, sym, entry);
1922 			free(sym);
1923 		}
1924 	}
1925 
1926 	if (TAILQ_EMPTY(conf->sc_servers)) {
1927 		log_warnx("no actions, nothing to do");
1928 		errors++;
1929 	}
1930 
1931 	if (RB_EMPTY(conf->sc_mediatypes)) {
1932 		/* Add default media types */
1933 		for (i = 0; mediatypes[i].media_name != NULL; i++) {
1934 			(void)strlcpy(m.media_name, mediatypes[i].media_name,
1935 			    sizeof(m.media_name));
1936 			(void)strlcpy(m.media_type, mediatypes[i].media_type,
1937 			    sizeof(m.media_type));
1938 			(void)strlcpy(m.media_subtype,
1939 			    mediatypes[i].media_subtype,
1940 			    sizeof(m.media_subtype));
1941 			m.media_encoding = NULL;
1942 
1943 			if (media_add(conf->sc_mediatypes, &m) == NULL) {
1944 				log_warnx("failed to add default media \"%s\"",
1945 				    m.media_name);
1946 				errors++;
1947 			}
1948 		}
1949 	}
1950 
1951 	return (errors ? -1 : 0);
1952 }
1953 
1954 int
1955 symset(const char *nam, const char *val, int persist)
1956 {
1957 	struct sym	*sym;
1958 
1959 	TAILQ_FOREACH(sym, &symhead, entry) {
1960 		if (strcmp(nam, sym->nam) == 0)
1961 			break;
1962 	}
1963 
1964 	if (sym != NULL) {
1965 		if (sym->persist == 1)
1966 			return (0);
1967 		else {
1968 			free(sym->nam);
1969 			free(sym->val);
1970 			TAILQ_REMOVE(&symhead, sym, entry);
1971 			free(sym);
1972 		}
1973 	}
1974 	if ((sym = calloc(1, sizeof(*sym))) == NULL)
1975 		return (-1);
1976 
1977 	sym->nam = strdup(nam);
1978 	if (sym->nam == NULL) {
1979 		free(sym);
1980 		return (-1);
1981 	}
1982 	sym->val = strdup(val);
1983 	if (sym->val == NULL) {
1984 		free(sym->nam);
1985 		free(sym);
1986 		return (-1);
1987 	}
1988 	sym->used = 0;
1989 	sym->persist = persist;
1990 	TAILQ_INSERT_TAIL(&symhead, sym, entry);
1991 	return (0);
1992 }
1993 
1994 int
1995 cmdline_symset(char *s)
1996 {
1997 	char	*sym, *val;
1998 	int	ret;
1999 
2000 	if ((val = strrchr(s, '=')) == NULL)
2001 		return (-1);
2002 	sym = strndup(s, val - s);
2003 	if (sym == NULL)
2004 		errx(1, "%s: strndup", __func__);
2005 	ret = symset(sym, val + 1, 1);
2006 	free(sym);
2007 
2008 	return (ret);
2009 }
2010 
2011 char *
2012 symget(const char *nam)
2013 {
2014 	struct sym	*sym;
2015 
2016 	TAILQ_FOREACH(sym, &symhead, entry) {
2017 		if (strcmp(nam, sym->nam) == 0) {
2018 			sym->used = 1;
2019 			return (sym->val);
2020 		}
2021 	}
2022 	return (NULL);
2023 }
2024 
2025 struct address *
2026 host_v4(const char *s)
2027 {
2028 	struct in_addr		 ina;
2029 	struct sockaddr_in	*sain;
2030 	struct address		*h;
2031 
2032 	memset(&ina, 0, sizeof(ina));
2033 	if (inet_pton(AF_INET, s, &ina) != 1)
2034 		return (NULL);
2035 
2036 	if ((h = calloc(1, sizeof(*h))) == NULL)
2037 		fatal(__func__);
2038 	sain = (struct sockaddr_in *)&h->ss;
2039 	sain->sin_len = sizeof(struct sockaddr_in);
2040 	sain->sin_family = AF_INET;
2041 	sain->sin_addr.s_addr = ina.s_addr;
2042 	if (sain->sin_addr.s_addr == INADDR_ANY)
2043 		h->prefixlen = 0; /* 0.0.0.0 address */
2044 	else
2045 		h->prefixlen = -1; /* host address */
2046 	return (h);
2047 }
2048 
2049 struct address *
2050 host_v6(const char *s)
2051 {
2052 	struct addrinfo		 hints, *res;
2053 	struct sockaddr_in6	*sa_in6;
2054 	struct address		*h = NULL;
2055 
2056 	memset(&hints, 0, sizeof(hints));
2057 	hints.ai_family = AF_INET6;
2058 	hints.ai_socktype = SOCK_DGRAM; /* dummy */
2059 	hints.ai_flags = AI_NUMERICHOST;
2060 	if (getaddrinfo(s, "0", &hints, &res) == 0) {
2061 		if ((h = calloc(1, sizeof(*h))) == NULL)
2062 			fatal(__func__);
2063 		sa_in6 = (struct sockaddr_in6 *)&h->ss;
2064 		sa_in6->sin6_len = sizeof(struct sockaddr_in6);
2065 		sa_in6->sin6_family = AF_INET6;
2066 		memcpy(&sa_in6->sin6_addr,
2067 		    &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr,
2068 		    sizeof(sa_in6->sin6_addr));
2069 		sa_in6->sin6_scope_id =
2070 		    ((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id;
2071 		if (memcmp(&sa_in6->sin6_addr, &in6addr_any,
2072 		    sizeof(sa_in6->sin6_addr)) == 0)
2073 			h->prefixlen = 0; /* any address */
2074 		else
2075 			h->prefixlen = -1; /* host address */
2076 		freeaddrinfo(res);
2077 	}
2078 
2079 	return (h);
2080 }
2081 
2082 int
2083 host_dns(const char *s, struct addresslist *al, int max,
2084     struct portrange *port, const char *ifname, int ipproto)
2085 {
2086 	struct addrinfo		 hints, *res0, *res;
2087 	int			 error, cnt = 0;
2088 	struct sockaddr_in	*sain;
2089 	struct sockaddr_in6	*sin6;
2090 	struct address		*h;
2091 
2092 	if ((cnt = host_if(s, al, max, port, ifname, ipproto)) != 0)
2093 		return (cnt);
2094 
2095 	memset(&hints, 0, sizeof(hints));
2096 	hints.ai_family = PF_UNSPEC;
2097 	hints.ai_socktype = SOCK_DGRAM; /* DUMMY */
2098 	hints.ai_flags = AI_ADDRCONFIG;
2099 	error = getaddrinfo(s, NULL, &hints, &res0);
2100 	if (error == EAI_AGAIN || error == EAI_NODATA || error == EAI_NONAME)
2101 		return (0);
2102 	if (error) {
2103 		log_warnx("%s: could not parse \"%s\": %s", __func__, s,
2104 		    gai_strerror(error));
2105 		return (-1);
2106 	}
2107 
2108 	for (res = res0; res && cnt < max; res = res->ai_next) {
2109 		if (res->ai_family != AF_INET &&
2110 		    res->ai_family != AF_INET6)
2111 			continue;
2112 		if ((h = calloc(1, sizeof(*h))) == NULL)
2113 			fatal(__func__);
2114 
2115 		if (port != NULL)
2116 			memcpy(&h->port, port, sizeof(h->port));
2117 		if (ifname != NULL) {
2118 			if (strlcpy(h->ifname, ifname, sizeof(h->ifname)) >=
2119 			    sizeof(h->ifname))
2120 				log_warnx("%s: interface name truncated",
2121 				    __func__);
2122 			freeaddrinfo(res0);
2123 			free(h);
2124 			return (-1);
2125 		}
2126 		if (ipproto != -1)
2127 			h->ipproto = ipproto;
2128 		h->ss.ss_family = res->ai_family;
2129 		h->prefixlen = -1; /* host address */
2130 
2131 		if (res->ai_family == AF_INET) {
2132 			sain = (struct sockaddr_in *)&h->ss;
2133 			sain->sin_len = sizeof(struct sockaddr_in);
2134 			sain->sin_addr.s_addr = ((struct sockaddr_in *)
2135 			    res->ai_addr)->sin_addr.s_addr;
2136 		} else {
2137 			sin6 = (struct sockaddr_in6 *)&h->ss;
2138 			sin6->sin6_len = sizeof(struct sockaddr_in6);
2139 			memcpy(&sin6->sin6_addr, &((struct sockaddr_in6 *)
2140 			    res->ai_addr)->sin6_addr, sizeof(struct in6_addr));
2141 		}
2142 
2143 		TAILQ_INSERT_HEAD(al, h, entry);
2144 		cnt++;
2145 	}
2146 	if (cnt == max && res) {
2147 		log_warnx("%s: %s resolves to more than %d hosts", __func__,
2148 		    s, max);
2149 	}
2150 	freeaddrinfo(res0);
2151 	return (cnt);
2152 }
2153 
2154 int
2155 host_if(const char *s, struct addresslist *al, int max,
2156     struct portrange *port, const char *ifname, int ipproto)
2157 {
2158 	struct ifaddrs		*ifap, *p;
2159 	struct sockaddr_in	*sain;
2160 	struct sockaddr_in6	*sin6;
2161 	struct address		*h;
2162 	int			 cnt = 0, af;
2163 
2164 	if (getifaddrs(&ifap) == -1)
2165 		fatal("getifaddrs");
2166 
2167 	/* First search for IPv4 addresses */
2168 	af = AF_INET;
2169 
2170  nextaf:
2171 	for (p = ifap; p != NULL && cnt < max; p = p->ifa_next) {
2172 		if (p->ifa_addr == NULL ||
2173 		    p->ifa_addr->sa_family != af ||
2174 		    (strcmp(s, p->ifa_name) != 0 &&
2175 		    !is_if_in_group(p->ifa_name, s)))
2176 			continue;
2177 		if ((h = calloc(1, sizeof(*h))) == NULL)
2178 			fatal("calloc");
2179 
2180 		if (port != NULL)
2181 			memcpy(&h->port, port, sizeof(h->port));
2182 		if (ifname != NULL) {
2183 			if (strlcpy(h->ifname, ifname, sizeof(h->ifname)) >=
2184 			    sizeof(h->ifname))
2185 				log_warnx("%s: interface name truncated",
2186 				    __func__);
2187 			freeifaddrs(ifap);
2188 			free(h);
2189 			return (-1);
2190 		}
2191 		if (ipproto != -1)
2192 			h->ipproto = ipproto;
2193 		h->ss.ss_family = af;
2194 		h->prefixlen = -1; /* host address */
2195 
2196 		if (af == AF_INET) {
2197 			sain = (struct sockaddr_in *)&h->ss;
2198 			sain->sin_len = sizeof(struct sockaddr_in);
2199 			sain->sin_addr.s_addr = ((struct sockaddr_in *)
2200 			    p->ifa_addr)->sin_addr.s_addr;
2201 		} else {
2202 			sin6 = (struct sockaddr_in6 *)&h->ss;
2203 			sin6->sin6_len = sizeof(struct sockaddr_in6);
2204 			memcpy(&sin6->sin6_addr, &((struct sockaddr_in6 *)
2205 			    p->ifa_addr)->sin6_addr, sizeof(struct in6_addr));
2206 			sin6->sin6_scope_id = ((struct sockaddr_in6 *)
2207 			    p->ifa_addr)->sin6_scope_id;
2208 		}
2209 
2210 		TAILQ_INSERT_HEAD(al, h, entry);
2211 		cnt++;
2212 	}
2213 	if (af == AF_INET) {
2214 		/* Next search for IPv6 addresses */
2215 		af = AF_INET6;
2216 		goto nextaf;
2217 	}
2218 
2219 	if (cnt > max) {
2220 		log_warnx("%s: %s resolves to more than %d hosts", __func__,
2221 		    s, max);
2222 	}
2223 	freeifaddrs(ifap);
2224 	return (cnt);
2225 }
2226 
2227 int
2228 host(const char *s, struct addresslist *al, int max,
2229     struct portrange *port, const char *ifname, int ipproto)
2230 {
2231 	struct address *h;
2232 
2233 	h = host_v4(s);
2234 
2235 	/* IPv6 address? */
2236 	if (h == NULL)
2237 		h = host_v6(s);
2238 
2239 	if (h != NULL) {
2240 		if (port != NULL)
2241 			memcpy(&h->port, port, sizeof(h->port));
2242 		if (ifname != NULL) {
2243 			if (strlcpy(h->ifname, ifname, sizeof(h->ifname)) >=
2244 			    sizeof(h->ifname)) {
2245 				log_warnx("%s: interface name truncated",
2246 				    __func__);
2247 				free(h);
2248 				return (-1);
2249 			}
2250 		}
2251 		if (ipproto != -1)
2252 			h->ipproto = ipproto;
2253 
2254 		TAILQ_INSERT_HEAD(al, h, entry);
2255 		return (1);
2256 	}
2257 
2258 	return (host_dns(s, al, max, port, ifname, ipproto));
2259 }
2260 
2261 struct server *
2262 server_inherit(struct server *src, struct server_config *alias,
2263     struct server_config *addr)
2264 {
2265 	struct server	*dst, *s, *dstl;
2266 
2267 	if ((dst = calloc(1, sizeof(*dst))) == NULL)
2268 		fatal("out of memory");
2269 
2270 	/* Copy the source server and assign a new Id */
2271 	memcpy(&dst->srv_conf, &src->srv_conf, sizeof(dst->srv_conf));
2272 	if ((dst->srv_conf.tls_cert_file =
2273 	    strdup(src->srv_conf.tls_cert_file)) == NULL)
2274 		fatal("out of memory");
2275 	if ((dst->srv_conf.tls_key_file =
2276 	    strdup(src->srv_conf.tls_key_file)) == NULL)
2277 		fatal("out of memory");
2278 	if (src->srv_conf.tls_ocsp_staple_file != NULL) {
2279 		if ((dst->srv_conf.tls_ocsp_staple_file =
2280 		    strdup(src->srv_conf.tls_ocsp_staple_file)) == NULL)
2281 			fatal("out of memory");
2282 	}
2283 
2284 	if (src->srv_conf.return_uri != NULL &&
2285 	    (dst->srv_conf.return_uri =
2286 	    strdup(src->srv_conf.return_uri)) == NULL)
2287 		fatal("out of memory");
2288 
2289 	dst->srv_conf.id = ++last_server_id;
2290 	dst->srv_conf.parent_id = dst->srv_conf.id;
2291 	dst->srv_s = -1;
2292 
2293 	if (last_server_id == INT_MAX) {
2294 		yyerror("too many servers defined");
2295 		serverconfig_free(&dst->srv_conf);
2296 		free(dst);
2297 		return (NULL);
2298 	}
2299 
2300 	/* Now set alias and listen address */
2301 	strlcpy(dst->srv_conf.name, alias->name, sizeof(dst->srv_conf.name));
2302 	memcpy(&dst->srv_conf.ss, &addr->ss, sizeof(dst->srv_conf.ss));
2303 	dst->srv_conf.port = addr->port;
2304 	dst->srv_conf.prefixlen = addr->prefixlen;
2305 	if (addr->flags & SRVFLAG_TLS)
2306 		dst->srv_conf.flags |= SRVFLAG_TLS;
2307 	else
2308 		dst->srv_conf.flags &= ~SRVFLAG_TLS;
2309 
2310 	/* Don't inherit the "match" option, use it from the alias */
2311 	dst->srv_conf.flags &= ~SRVFLAG_SERVER_MATCH;
2312 	dst->srv_conf.flags |= (alias->flags & SRVFLAG_SERVER_MATCH);
2313 
2314 	if (server_tls_load_keypair(dst) == -1)
2315 		log_warnx("%s:%d: server \"%s\": failed to "
2316 		    "load public/private keys", file->name,
2317 		    yylval.lineno, dst->srv_conf.name);
2318 
2319 	if (server_tls_load_ca(dst) == -1) {
2320 		yyerror("failed to load ca cert(s) for server %s",
2321 		    dst->srv_conf.name);
2322 		serverconfig_free(&dst->srv_conf);
2323 		return NULL;
2324 	}
2325 
2326 	if (server_tls_load_crl(dst) == -1) {
2327 		yyerror("failed to load crl(s) for server %s",
2328 		    dst->srv_conf.name);
2329 		serverconfig_free(&dst->srv_conf);
2330 		free(dst);
2331 		return NULL;
2332 	}
2333 
2334 	if (server_tls_load_ocsp(dst) == -1) {
2335 		yyerror("failed to load ocsp staple "
2336 		    "for server %s", dst->srv_conf.name);
2337 		serverconfig_free(&dst->srv_conf);
2338 		free(dst);
2339 		return (NULL);
2340 	}
2341 
2342 	/* Check if the new server already exists */
2343 	if (server_match(dst, 1) != NULL) {
2344 		yyerror("server \"%s\" defined twice",
2345 		    dst->srv_conf.name);
2346 		serverconfig_free(&dst->srv_conf);
2347 		free(dst);
2348 		return (NULL);
2349 	}
2350 
2351 	/* Copy all the locations of the source server */
2352 	TAILQ_FOREACH(s, conf->sc_servers, srv_entry) {
2353 		if (!(s->srv_conf.flags & SRVFLAG_LOCATION &&
2354 		    s->srv_conf.parent_id == src->srv_conf.parent_id))
2355 			continue;
2356 
2357 		if ((dstl = calloc(1, sizeof(*dstl))) == NULL)
2358 			fatal("out of memory");
2359 
2360 		memcpy(&dstl->srv_conf, &s->srv_conf, sizeof(dstl->srv_conf));
2361 		strlcpy(dstl->srv_conf.name, alias->name,
2362 		    sizeof(dstl->srv_conf.name));
2363 
2364 		/* Copy the new Id and listen address */
2365 		dstl->srv_conf.id = ++last_server_id;
2366 		dstl->srv_conf.parent_id = dst->srv_conf.id;
2367 		memcpy(&dstl->srv_conf.ss, &addr->ss,
2368 		    sizeof(dstl->srv_conf.ss));
2369 		dstl->srv_conf.port = addr->port;
2370 		dstl->srv_conf.prefixlen = addr->prefixlen;
2371 		dstl->srv_s = -1;
2372 
2373 		DPRINTF("adding location \"%s\" for \"%s[%u]\"",
2374 		    dstl->srv_conf.location,
2375 		    dstl->srv_conf.name, dstl->srv_conf.id);
2376 
2377 		TAILQ_INSERT_TAIL(conf->sc_servers, dstl, srv_entry);
2378 	}
2379 
2380 	return (dst);
2381 }
2382 
2383 int
2384 listen_on(const char *addr, int tls, struct portrange *port)
2385 {
2386 	struct addresslist	 al;
2387 	struct address		*h;
2388 	struct server_config	*s_conf, *alias = NULL;
2389 
2390 	if (parentsrv != NULL) {
2391 		yyerror("listen %s inside location", addr);
2392 		return (-1);
2393 	}
2394 
2395 	TAILQ_INIT(&al);
2396 	if (strcmp("*", addr) == 0) {
2397 		if (host("0.0.0.0", &al, 1, port, NULL, -1) <= 0) {
2398 			yyerror("invalid listen ip: %s",
2399 			    "0.0.0.0");
2400 			return (-1);
2401 		}
2402 		if (host("::", &al, 1, port, NULL, -1) <= 0) {
2403 			yyerror("invalid listen ip: %s", "::");
2404 			return (-1);
2405 		}
2406 	} else {
2407 		if (host(addr, &al, HTTPD_MAX_ALIAS_IP, port, NULL,
2408 		    -1) <= 0) {
2409 			yyerror("invalid listen ip: %s", addr);
2410 			return (-1);
2411 		}
2412 	}
2413 
2414 	while ((h = TAILQ_FIRST(&al)) != NULL) {
2415 		if (srv->srv_conf.ss.ss_family != AF_UNSPEC) {
2416 			if ((alias = calloc(1,
2417 			    sizeof(*alias))) == NULL)
2418 				fatal("out of memory");
2419 				/* Add as an IP-based alias. */
2420 			s_conf = alias;
2421 		} else
2422 			s_conf = &srv->srv_conf;
2423 		memcpy(&s_conf->ss, &h->ss, sizeof(s_conf->ss));
2424 		s_conf->prefixlen = h->prefixlen;
2425 		/* Set the default port to 80 or 443 */
2426 		if (!h->port.op)
2427 			s_conf->port = htons(tls ?
2428 			    HTTPS_PORT : HTTP_PORT);
2429 		else
2430 			s_conf->port = h->port.val[0];
2431 
2432 		if (tls)
2433 			s_conf->flags |= SRVFLAG_TLS;
2434 
2435 		if (alias != NULL) {
2436 			/*
2437 			 * IP-based; use name match flags from
2438 			 * parent
2439 			 */
2440 			alias->flags &= ~SRVFLAG_SERVER_MATCH;
2441 			alias->flags |= srv->srv_conf.flags &
2442 			    SRVFLAG_SERVER_MATCH;
2443 			TAILQ_INSERT_TAIL(&srv->srv_hosts,
2444 			    alias, entry);
2445 		}
2446 		TAILQ_REMOVE(&al, h, entry);
2447 		free(h);
2448 	}
2449 
2450 	return (0);
2451 }
2452 
2453 int
2454 getservice(char *n)
2455 {
2456 	struct servent	*s;
2457 	const char	*errstr;
2458 	long long	 llval;
2459 
2460 	llval = strtonum(n, 0, UINT16_MAX, &errstr);
2461 	if (errstr) {
2462 		s = getservbyname(n, "tcp");
2463 		if (s == NULL)
2464 			s = getservbyname(n, "udp");
2465 		if (s == NULL)
2466 			return (-1);
2467 		return (s->s_port);
2468 	}
2469 
2470 	return (htons((unsigned short)llval));
2471 }
2472 
2473 int
2474 is_if_in_group(const char *ifname, const char *groupname)
2475 {
2476 	unsigned int		 len;
2477 	struct ifgroupreq	 ifgr;
2478 	struct ifg_req		*ifg;
2479 	int			 s;
2480 	int			 ret = 0;
2481 
2482 	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
2483 		err(1, "socket");
2484 
2485 	memset(&ifgr, 0, sizeof(ifgr));
2486 	if (strlcpy(ifgr.ifgr_name, ifname, IFNAMSIZ) >= IFNAMSIZ)
2487 		err(1, "IFNAMSIZ");
2488 	if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1) {
2489 		if (errno == EINVAL || errno == ENOTTY)
2490 			goto end;
2491 		err(1, "SIOCGIFGROUP");
2492 	}
2493 
2494 	len = ifgr.ifgr_len;
2495 	ifgr.ifgr_groups = calloc(len / sizeof(struct ifg_req),
2496 	    sizeof(struct ifg_req));
2497 	if (ifgr.ifgr_groups == NULL)
2498 		err(1, "getifgroups");
2499 	if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1)
2500 		err(1, "SIOCGIFGROUP");
2501 
2502 	ifg = ifgr.ifgr_groups;
2503 	for (; ifg && len >= sizeof(struct ifg_req); ifg++) {
2504 		len -= sizeof(struct ifg_req);
2505 		if (strcmp(ifg->ifgrq_group, groupname) == 0) {
2506 			ret = 1;
2507 			break;
2508 		}
2509 	}
2510 	free(ifgr.ifgr_groups);
2511 
2512 end:
2513 	close(s);
2514 	return (ret);
2515 }
2516 
2517 int
2518 get_fastcgi_dest(struct server_config *xsrv_conf, const char *node, char *port)
2519 {
2520 	struct addrinfo		 hints, *res;
2521 	int			 s;
2522 
2523 	memset(&hints, 0, sizeof(hints));
2524 	hints.ai_family = AF_UNSPEC;
2525 	hints.ai_socktype = SOCK_STREAM;
2526 
2527 	if ((s = getaddrinfo(node, port, &hints, &res)) != 0) {
2528 		yyerror("getaddrinfo: %s\n", gai_strerror(s));
2529 		return -1;
2530 	}
2531 
2532 	memset(&(xsrv_conf)->fastcgi_ss, 0, sizeof(xsrv_conf->fastcgi_ss));
2533 	memcpy(&(xsrv_conf)->fastcgi_ss, res->ai_addr, res->ai_addrlen);
2534 
2535 	freeaddrinfo(res);
2536 
2537 	return (0);
2538 }
2539 
2540 void
2541 remove_locations(struct server_config *xsrv_conf)
2542 {
2543 	struct server *s, *next;
2544 
2545 	TAILQ_FOREACH_SAFE(s, conf->sc_servers, srv_entry, next) {
2546 		if (!(s->srv_conf.flags & SRVFLAG_LOCATION &&
2547 		    s->srv_conf.parent_id == xsrv_conf->parent_id))
2548 			continue;
2549 		TAILQ_REMOVE(conf->sc_servers, s, srv_entry);
2550 		serverconfig_free(&s->srv_conf);
2551 		free(s);
2552 	}
2553 }
2554