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