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