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