GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/httpd/parse.y Lines: 162 547 29.6 %
Date: 2017-11-07 Branches: 94 361 26.0 %

Line Branch Exec Source
1
/*	$OpenBSD: parse.y,v 1.92 2017/08/28 06:00:05 florian Exp $	*/
2
3
/*
4
 * Copyright (c) 2007 - 2015 Reyk Floeter <reyk@openbsd.org>
5
 * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
6
 * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org>
7
 * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
8
 * Copyright (c) 2004 Ryan McBride <mcbride@openbsd.org>
9
 * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
10
 * Copyright (c) 2001 Markus Friedl.  All rights reserved.
11
 * Copyright (c) 2001 Daniel Hartmeier.  All rights reserved.
12
 * Copyright (c) 2001 Theo de Raadt.  All rights reserved.
13
 *
14
 * Permission to use, copy, modify, and distribute this software for any
15
 * purpose with or without fee is hereby granted, provided that the above
16
 * copyright notice and this permission notice appear in all copies.
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
19
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
20
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
21
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
22
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
23
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
24
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25
 */
26
27
%{
28
#include <sys/types.h>
29
#include <sys/socket.h>
30
#include <sys/stat.h>
31
#include <sys/queue.h>
32
#include <sys/tree.h>
33
#include <sys/ioctl.h>
34
#include <sys/sockio.h>
35
#include <sys/time.h>
36
37
#include <net/if.h>
38
#include <netinet/in.h>
39
#include <arpa/inet.h>
40
41
#include <ctype.h>
42
#include <unistd.h>
43
#include <err.h>
44
#include <errno.h>
45
#include <limits.h>
46
#include <stdint.h>
47
#include <stdarg.h>
48
#include <stdio.h>
49
#include <netdb.h>
50
#include <string.h>
51
#include <ifaddrs.h>
52
#include <syslog.h>
53
54
#include "httpd.h"
55
#include "http.h"
56
57
TAILQ_HEAD(files, file)		 files = TAILQ_HEAD_INITIALIZER(files);
58
static struct file {
59
	TAILQ_ENTRY(file)	 entry;
60
	FILE			*stream;
61
	char			*name;
62
	int			 lineno;
63
	int			 errors;
64
} *file, *topfile;
65
struct file	*pushfile(const char *, int);
66
int		 popfile(void);
67
int		 check_file_secrecy(int, const char *);
68
int		 yyparse(void);
69
int		 yylex(void);
70
int		 yyerror(const char *, ...)
71
    __attribute__((__format__ (printf, 1, 2)))
72
    __attribute__((__nonnull__ (1)));
73
int		 kw_cmp(const void *, const void *);
74
int		 lookup(char *);
75
int		 lgetc(int);
76
int		 lungetc(int);
77
int		 findeol(void);
78
79
TAILQ_HEAD(symhead, sym)	 symhead = TAILQ_HEAD_INITIALIZER(symhead);
80
struct sym {
81
	TAILQ_ENTRY(sym)	 entry;
82
	int			 used;
83
	int			 persist;
84
	char			*nam;
85
	char			*val;
86
};
87
int		 symset(const char *, const char *, int);
88
char		*symget(const char *);
89
90
struct httpd		*conf = NULL;
91
static int		 errors = 0;
92
static int		 loadcfg = 0;
93
uint32_t		 last_server_id = 0;
94
uint32_t		 last_auth_id = 0;
95
96
static struct server	*srv = NULL, *parentsrv = NULL;
97
static struct server_config *srv_conf = NULL;
98
struct serverlist	 servers;
99
struct media_type	 media;
100
101
struct address	*host_v4(const char *);
102
struct address	*host_v6(const char *);
103
int		 host_dns(const char *, struct addresslist *,
104
		    int, struct portrange *, const char *, int);
105
int		 host_if(const char *, struct addresslist *,
106
		    int, struct portrange *, const char *, int);
107
int		 host(const char *, struct addresslist *,
108
		    int, struct portrange *, const char *, int);
109
void		 host_free(struct addresslist *);
110
struct server	*server_inherit(struct server *, struct server_config *,
111
		    struct server_config *);
112
int		 getservice(char *);
113
int		 is_if_in_group(const char *, const char *);
114
115
typedef struct {
116
	union {
117
		int64_t			 number;
118
		char			*string;
119
		struct timeval		 tv;
120
		struct portrange	 port;
121
		struct auth		 auth;
122
		struct {
123
			struct sockaddr_storage	 ss;
124
			char			 name[HOST_NAME_MAX+1];
125
		}			 addr;
126
	} v;
127
	int lineno;
128
} YYSTYPE;
129
130
%}
131
132
%token	ACCESS ALIAS AUTO BACKLOG BODY BUFFER CERTIFICATE CHROOT CIPHERS COMMON
133
%token	COMBINED CONNECTION DHE DIRECTORY ECDHE ERR FCGI INDEX IP KEY LIFETIME
134
%token	LISTEN LOCATION LOG LOGDIR MATCH MAXIMUM NO NODELAY OCSP ON PORT PREFORK
135
%token	PROTOCOLS REQUESTS ROOT SACK SERVER SOCKET STRIP STYLE SYSLOG TCP TICKET
136
%token	TIMEOUT TLS TYPE TYPES HSTS MAXAGE SUBDOMAINS DEFAULT PRELOAD REQUEST
137
%token	ERROR INCLUDE AUTHENTICATE WITH BLOCK DROP RETURN PASS
138
%token	<v.string>	STRING
139
%token  <v.number>	NUMBER
140
%type	<v.port>	port
141
%type	<v.number>	opttls optmatch
142
%type	<v.tv>		timeout
143
%type	<v.string>	numberstring optstring
144
%type	<v.auth>	authopts
145
146
%%
147
148
grammar		: /* empty */
149
		| grammar include '\n'
150
		| grammar '\n'
151
		| grammar varset '\n'
152
		| grammar main '\n'
153
		| grammar server '\n'
154
		| grammar types '\n'
155
		| grammar error '\n'		{ file->errors++; }
156
		;
157
158
include		: INCLUDE STRING		{
159
			struct file	*nfile;
160
161
			if ((nfile = pushfile($2, 0)) == NULL) {
162
				yyerror("failed to include file %s", $2);
163
				free($2);
164
				YYERROR;
165
			}
166
			free($2);
167
168
			file = nfile;
169
			lungetc('\n');
170
		}
171
		;
172
173
varset		: STRING '=' STRING	{
174
			char *s = $1;
175
			while (*s++) {
176
				if (isspace((unsigned char)*s)) {
177
					yyerror("macro name cannot contain "
178
					    "whitespace");
179
					YYERROR;
180
				}
181
			}
182
			if (symset($1, $3, 0) == -1)
183
				fatal("cannot store variable");
184
			free($1);
185
			free($3);
186
		}
187
		;
188
189
opttls		: /*empty*/	{ $$ = 0; }
190
		| TLS		{ $$ = 1; }
191
		;
192
193
main		: PREFORK NUMBER	{
194
			if (loadcfg)
195
				break;
196
			if ($2 <= 0 || $2 > PROC_MAX_INSTANCES) {
197
				yyerror("invalid number of preforked "
198
				    "servers: %lld", $2);
199
				YYERROR;
200
			}
201
			conf->sc_prefork_server = $2;
202
		}
203
		| CHROOT STRING		{
204
			conf->sc_chroot = $2;
205
		}
206
		| LOGDIR STRING		{
207
			conf->sc_logdir = $2;
208
		}
209
		| DEFAULT TYPE mediastring	{
210
			memcpy(&conf->sc_default_type, &media,
211
			    sizeof(struct media_type));
212
		}
213
		;
214
215
server		: SERVER optmatch STRING	{
216
			struct server	*s;
217
218
			if (!loadcfg) {
219
				free($3);
220
				YYACCEPT;
221
			}
222
223
			if ((s = calloc(1, sizeof (*s))) == NULL)
224
				fatal("out of memory");
225
226
			if (strlcpy(s->srv_conf.name, $3,
227
			    sizeof(s->srv_conf.name)) >=
228
			    sizeof(s->srv_conf.name)) {
229
				yyerror("server name truncated");
230
				free($3);
231
				free(s);
232
				YYERROR;
233
			}
234
			free($3);
235
236
			strlcpy(s->srv_conf.root, HTTPD_DOCROOT,
237
			    sizeof(s->srv_conf.root));
238
			strlcpy(s->srv_conf.index, HTTPD_INDEX,
239
			    sizeof(s->srv_conf.index));
240
			strlcpy(s->srv_conf.accesslog, HTTPD_ACCESS_LOG,
241
			    sizeof(s->srv_conf.accesslog));
242
			strlcpy(s->srv_conf.errorlog, HTTPD_ERROR_LOG,
243
			    sizeof(s->srv_conf.errorlog));
244
			s->srv_conf.id = ++last_server_id;
245
			s->srv_conf.parent_id = s->srv_conf.id;
246
			s->srv_s = -1;
247
			s->srv_conf.timeout.tv_sec = SERVER_TIMEOUT;
248
			s->srv_conf.requesttimeout.tv_sec =
249
			    SERVER_REQUESTTIMEOUT;
250
			s->srv_conf.maxrequests = SERVER_MAXREQUESTS;
251
			s->srv_conf.maxrequestbody = SERVER_MAXREQUESTBODY;
252
			s->srv_conf.flags = SRVFLAG_LOG;
253
			if ($2)
254
				s->srv_conf.flags |= SRVFLAG_SERVER_MATCH;
255
			s->srv_conf.logformat = LOG_FORMAT_COMMON;
256
			s->srv_conf.tls_protocols = TLS_PROTOCOLS_DEFAULT;
257
			if ((s->srv_conf.tls_cert_file =
258
			    strdup(HTTPD_TLS_CERT)) == NULL)
259
				fatal("out of memory");
260
			if ((s->srv_conf.tls_key_file =
261
			    strdup(HTTPD_TLS_KEY)) == NULL)
262
				fatal("out of memory");
263
			strlcpy(s->srv_conf.tls_ciphers,
264
			    HTTPD_TLS_CIPHERS,
265
			    sizeof(s->srv_conf.tls_ciphers));
266
			strlcpy(s->srv_conf.tls_dhe_params,
267
			    HTTPD_TLS_DHE_PARAMS,
268
			    sizeof(s->srv_conf.tls_dhe_params));
269
			strlcpy(s->srv_conf.tls_ecdhe_curves,
270
			    HTTPD_TLS_ECDHE_CURVES,
271
			    sizeof(s->srv_conf.tls_ecdhe_curves));
272
273
			s->srv_conf.hsts_max_age = SERVER_HSTS_DEFAULT_AGE;
274
275
			if (last_server_id == INT_MAX) {
276
				yyerror("too many servers defined");
277
				free(s);
278
				YYERROR;
279
			}
280
			srv = s;
281
			srv_conf = &srv->srv_conf;
282
283
			SPLAY_INIT(&srv->srv_clients);
284
			TAILQ_INIT(&srv->srv_hosts);
285
286
			TAILQ_INSERT_TAIL(&srv->srv_hosts, srv_conf, entry);
287
		} '{' optnl serveropts_l '}'	{
288
			struct server		*s, *sn;
289
			struct server_config	*a, *b;
290
291
			srv_conf = &srv->srv_conf;
292
293
			/* Check if the new server already exists. */
294
			if (server_match(srv, 1) != NULL) {
295
				yyerror("server \"%s\" defined twice",
296
				    srv->srv_conf.name);
297
				serverconfig_free(srv_conf);
298
				free(srv);
299
				YYABORT;
300
			}
301
302
			if (srv->srv_conf.ss.ss_family == AF_UNSPEC) {
303
				yyerror("listen address not specified");
304
				serverconfig_free(srv_conf);
305
				free(srv);
306
				YYERROR;
307
			}
308
309
			if ((s = server_match(srv, 0)) != NULL) {
310
				if ((s->srv_conf.flags & SRVFLAG_TLS) !=
311
				    (srv->srv_conf.flags & SRVFLAG_TLS)) {
312
					yyerror("server \"%s\": tls and "
313
					    "non-tls on same address/port",
314
					    srv->srv_conf.name);
315
					serverconfig_free(srv_conf);
316
					free(srv);
317
					YYERROR;
318
				}
319
				if (server_tls_cmp(s, srv, 0) != 0) {
320
					yyerror("server \"%s\": tls "
321
					    "configuration mismatch on same "
322
					    "address/port",
323
					    srv->srv_conf.name);
324
					serverconfig_free(srv_conf);
325
					free(srv);
326
					YYERROR;
327
				}
328
			}
329
330
			if ((srv->srv_conf.flags & SRVFLAG_TLS) &&
331
			    srv->srv_conf.tls_protocols == 0) {
332
				yyerror("server \"%s\": no tls protocols",
333
				    srv->srv_conf.name);
334
				serverconfig_free(srv_conf);
335
				free(srv);
336
				YYERROR;
337
			}
338
339
			if (server_tls_load_keypair(srv) == -1) {
340
				yyerror("server \"%s\": failed to load "
341
				    "public/private keys", srv->srv_conf.name);
342
				serverconfig_free(srv_conf);
343
				free(srv);
344
				YYERROR;
345
			}
346
347
			if (server_tls_load_ocsp(srv) == -1) {
348
				yyerror("server \"%s\": failed to load "
349
				    "ocsp staple", srv->srv_conf.name);
350
				serverconfig_free(srv_conf);
351
				free(srv);
352
				YYERROR;
353
			}
354
355
			DPRINTF("adding server \"%s[%u]\"",
356
			    srv->srv_conf.name, srv->srv_conf.id);
357
358
			TAILQ_INSERT_TAIL(conf->sc_servers, srv, srv_entry);
359
360
			/*
361
			 * Add aliases and additional listen addresses as
362
			 * individual servers.
363
			 */
364
			TAILQ_FOREACH(a, &srv->srv_hosts, entry) {
365
				/* listen address */
366
				if (a->ss.ss_family == AF_UNSPEC)
367
					continue;
368
				TAILQ_FOREACH(b, &srv->srv_hosts, entry) {
369
					/* alias name */
370
					if (*b->name == '\0' ||
371
					    (b == &srv->srv_conf && b == a))
372
						continue;
373
374
					if ((sn = server_inherit(srv,
375
					    b, a)) == NULL) {
376
						serverconfig_free(srv_conf);
377
						free(srv);
378
						YYABORT;
379
					}
380
381
					DPRINTF("adding server \"%s[%u]\"",
382
					    sn->srv_conf.name, sn->srv_conf.id);
383
384
					TAILQ_INSERT_TAIL(conf->sc_servers,
385
					    sn, srv_entry);
386
				}
387
			}
388
389
			/* Remove temporary aliases */
390
			TAILQ_FOREACH_SAFE(a, &srv->srv_hosts, entry, b) {
391
				TAILQ_REMOVE(&srv->srv_hosts, a, entry);
392
				if (a == &srv->srv_conf)
393
					continue;
394
				serverconfig_free(a);
395
				free(a);
396
			}
397
398
			srv = NULL;
399
			srv_conf = NULL;
400
		}
401
		;
402
403
serveropts_l	: serveropts_l serveroptsl nl
404
		| serveroptsl optnl
405
		;
406
407
serveroptsl	: LISTEN ON STRING opttls port {
408
			struct addresslist	 al;
409
			struct address		*h;
410
			struct server_config	*s_conf, *alias = NULL;
411
412
			if (parentsrv != NULL) {
413
				yyerror("listen %s inside location", $3);
414
				free($3);
415
				YYERROR;
416
			}
417
418
			if (srv->srv_conf.ss.ss_family != AF_UNSPEC) {
419
				if ((alias = calloc(1,
420
				    sizeof(*alias))) == NULL)
421
					fatal("out of memory");
422
423
				/* Add as an IP-based alias. */
424
				s_conf = alias;
425
			} else
426
				s_conf = &srv->srv_conf;
427
428
			TAILQ_INIT(&al);
429
			if (host($3, &al, 1, &$5, NULL, -1) <= 0) {
430
				yyerror("invalid listen ip: %s", $3);
431
				free($3);
432
				YYERROR;
433
			}
434
			free($3);
435
			h = TAILQ_FIRST(&al);
436
			memcpy(&s_conf->ss, &h->ss, sizeof(s_conf->ss));
437
			s_conf->port = h->port.val[0];
438
			s_conf->prefixlen = h->prefixlen;
439
			host_free(&al);
440
441
			if ($4)
442
				s_conf->flags |= SRVFLAG_TLS;
443
444
			if (alias != NULL) {
445
				/* IP-based; use name match flags from parent */
446
				alias->flags &= ~SRVFLAG_SERVER_MATCH;
447
				alias->flags |= srv->srv_conf.flags &
448
				    SRVFLAG_SERVER_MATCH;
449
				TAILQ_INSERT_TAIL(&srv->srv_hosts,
450
				    alias, entry);
451
			}
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
		| root
510
		| directory
511
		| logformat
512
		| fastcgi
513
		| authenticate
514
		| filter
515
		| LOCATION optmatch STRING	{
516
			struct server	*s;
517
518
			if (srv->srv_conf.ss.ss_family == AF_UNSPEC) {
519
				yyerror("listen address not specified");
520
				free($3);
521
				YYERROR;
522
			}
523
524
			if (parentsrv != NULL) {
525
				yyerror("location %s inside location", $3);
526
				free($3);
527
				YYERROR;
528
			}
529
530
			if (!loadcfg) {
531
				free($3);
532
				YYACCEPT;
533
			}
534
535
			if ((s = calloc(1, sizeof (*s))) == NULL)
536
				fatal("out of memory");
537
538
			if (strlcpy(s->srv_conf.location, $3,
539
			    sizeof(s->srv_conf.location)) >=
540
			    sizeof(s->srv_conf.location)) {
541
				yyerror("server location truncated");
542
				free($3);
543
				free(s);
544
				YYERROR;
545
			}
546
			free($3);
547
548
			if (strlcpy(s->srv_conf.name, srv->srv_conf.name,
549
			    sizeof(s->srv_conf.name)) >=
550
			    sizeof(s->srv_conf.name)) {
551
				yyerror("server name truncated");
552
				free(s);
553
				YYERROR;
554
			}
555
556
			s->srv_conf.id = ++last_server_id;
557
			/* A location entry uses the parent id */
558
			s->srv_conf.parent_id = srv->srv_conf.id;
559
			s->srv_conf.flags = SRVFLAG_LOCATION;
560
			if ($2)
561
				s->srv_conf.flags |= SRVFLAG_LOCATION_MATCH;
562
			s->srv_s = -1;
563
			memcpy(&s->srv_conf.ss, &srv->srv_conf.ss,
564
			    sizeof(s->srv_conf.ss));
565
			s->srv_conf.port = srv->srv_conf.port;
566
			s->srv_conf.prefixlen = srv->srv_conf.prefixlen;
567
568
			if (last_server_id == INT_MAX) {
569
				yyerror("too many servers/locations defined");
570
				free(s);
571
				YYERROR;
572
			}
573
			parentsrv = srv;
574
			srv = s;
575
			srv_conf = &srv->srv_conf;
576
			SPLAY_INIT(&srv->srv_clients);
577
		} '{' optnl serveropts_l '}'	{
578
			struct server	*s = NULL;
579
580
			TAILQ_FOREACH(s, conf->sc_servers, srv_entry) {
581
				if ((s->srv_conf.flags & SRVFLAG_LOCATION) &&
582
				    s->srv_conf.id == srv_conf->id &&
583
				    strcmp(s->srv_conf.location,
584
				    srv_conf->location) == 0)
585
					break;
586
			}
587
			if (s != NULL) {
588
				yyerror("location \"%s\" defined twice",
589
				    srv->srv_conf.location);
590
				serverconfig_free(srv_conf);
591
				free(srv);
592
				YYABORT;
593
			}
594
595
			DPRINTF("adding location \"%s\" for \"%s[%u]\"",
596
			    srv->srv_conf.location,
597
			    srv->srv_conf.name, srv->srv_conf.id);
598
599
			TAILQ_INSERT_TAIL(conf->sc_servers, srv, srv_entry);
600
601
			srv = parentsrv;
602
			srv_conf = &parentsrv->srv_conf;
603
			parentsrv = NULL;
604
		}
605
		| DEFAULT TYPE mediastring	{
606
			srv_conf->flags |= SRVFLAG_DEFAULT_TYPE;
607
			memcpy(&srv_conf->default_type, &media,
608
			    sizeof(struct media_type));
609
		}
610
		| include
611
		| hsts				{
612
			if (parentsrv != NULL) {
613
				yyerror("hsts inside location");
614
				YYERROR;
615
			}
616
			srv->srv_conf.flags |= SRVFLAG_SERVER_HSTS;
617
		}
618
		;
619
620
hsts		: HSTS '{' optnl hstsflags_l '}'
621
		| HSTS hstsflags
622
		| HSTS
623
		;
624
625
hstsflags_l	: hstsflags optcommanl hstsflags_l
626
		| hstsflags optnl
627
		;
628
629
hstsflags	: MAXAGE NUMBER		{
630
			if ($2 < 0 || $2 > INT_MAX) {
631
				yyerror("invalid number of seconds: %lld", $2);
632
				YYERROR;
633
			}
634
			srv_conf->hsts_max_age = $2;
635
		}
636
		| SUBDOMAINS		{
637
			srv->srv_conf.hsts_flags |= HSTSFLAG_SUBDOMAINS;
638
		}
639
		| PRELOAD		{
640
			srv->srv_conf.hsts_flags |= HSTSFLAG_PRELOAD;
641
		}
642
		;
643
644
fastcgi		: NO FCGI		{
645
			srv_conf->flags &= ~SRVFLAG_FCGI;
646
			srv_conf->flags |= SRVFLAG_NO_FCGI;
647
		}
648
		| FCGI			{
649
			srv_conf->flags &= ~SRVFLAG_NO_FCGI;
650
			srv_conf->flags |= SRVFLAG_FCGI;
651
		}
652
		| FCGI			{
653
			srv_conf->flags &= ~SRVFLAG_NO_FCGI;
654
			srv_conf->flags |= SRVFLAG_FCGI;
655
		} '{' optnl fcgiflags_l '}'
656
		| FCGI			{
657
			srv_conf->flags &= ~SRVFLAG_NO_FCGI;
658
			srv_conf->flags |= SRVFLAG_FCGI;
659
		} fcgiflags
660
		;
661
662
fcgiflags_l	: fcgiflags optcommanl fcgiflags_l
663
		| fcgiflags optnl
664
		;
665
666
fcgiflags	: SOCKET STRING		{
667
			if (strlcpy(srv_conf->socket, $2,
668
			    sizeof(srv_conf->socket)) >=
669
			    sizeof(srv_conf->socket)) {
670
				yyerror("fastcgi socket too long");
671
				free($2);
672
				YYERROR;
673
			}
674
			free($2);
675
			srv_conf->flags |= SRVFLAG_SOCKET;
676
		}
677
		;
678
679
connection	: CONNECTION '{' optnl conflags_l '}'
680
		| CONNECTION conflags
681
		;
682
683
conflags_l	: conflags optcommanl conflags_l
684
		| conflags optnl
685
		;
686
687
conflags	: TIMEOUT timeout		{
688
			memcpy(&srv_conf->timeout, &$2,
689
			    sizeof(struct timeval));
690
		}
691
		| REQUEST TIMEOUT timeout	{
692
			memcpy(&srv_conf->requesttimeout, &$3,
693
			    sizeof(struct timeval));
694
		}
695
		| MAXIMUM REQUESTS NUMBER	{
696
			srv_conf->maxrequests = $3;
697
		}
698
		| MAXIMUM REQUEST BODY NUMBER	{
699
			srv_conf->maxrequestbody = $4;
700
		}
701
		;
702
703
tls		: TLS '{' optnl tlsopts_l '}'
704
		| TLS tlsopts
705
		;
706
707
tlsopts_l	: tlsopts optcommanl tlsopts_l
708
		| tlsopts optnl
709
		;
710
711
tlsopts		: CERTIFICATE STRING		{
712
			free(srv_conf->tls_cert_file);
713
			if ((srv_conf->tls_cert_file = strdup($2)) == NULL)
714
				fatal("out of memory");
715
			free($2);
716
		}
717
		| KEY STRING			{
718
			free(srv_conf->tls_key_file);
719
			if ((srv_conf->tls_key_file = strdup($2)) == NULL)
720
				fatal("out of memory");
721
			free($2);
722
		}
723
		| OCSP STRING			{
724
			free(srv_conf->tls_ocsp_staple_file);
725
			if ((srv_conf->tls_ocsp_staple_file = strdup($2))
726
			    == NULL)
727
				fatal("out of memory");
728
			free($2);
729
		}
730
		| CIPHERS STRING		{
731
			if (strlcpy(srv_conf->tls_ciphers, $2,
732
			    sizeof(srv_conf->tls_ciphers)) >=
733
			    sizeof(srv_conf->tls_ciphers)) {
734
				yyerror("ciphers too long");
735
				free($2);
736
				YYERROR;
737
			}
738
			free($2);
739
		}
740
		| DHE STRING			{
741
			if (strlcpy(srv_conf->tls_dhe_params, $2,
742
			    sizeof(srv_conf->tls_dhe_params)) >=
743
			    sizeof(srv_conf->tls_dhe_params)) {
744
				yyerror("dhe too long");
745
				free($2);
746
				YYERROR;
747
			}
748
			free($2);
749
		}
750
		| ECDHE STRING			{
751
			if (strlcpy(srv_conf->tls_ecdhe_curves, $2,
752
			    sizeof(srv_conf->tls_ecdhe_curves)) >=
753
			    sizeof(srv_conf->tls_ecdhe_curves)) {
754
				yyerror("ecdhe too long");
755
				free($2);
756
				YYERROR;
757
			}
758
			free($2);
759
		}
760
		| PROTOCOLS STRING		{
761
			if (tls_config_parse_protocols(
762
			    &srv_conf->tls_protocols, $2) != 0) {
763
				yyerror("invalid tls protocols");
764
				free($2);
765
				YYERROR;
766
			}
767
			free($2);
768
		}
769
		| TICKET LIFETIME DEFAULT	{
770
			srv_conf->tls_ticket_lifetime = SERVER_DEF_TLS_LIFETIME;
771
		}
772
		| TICKET LIFETIME NUMBER	{
773
			if ($3 != 0 && $3 < SERVER_MIN_TLS_LIFETIME) {
774
				yyerror("ticket lifetime too small");
775
				YYERROR;
776
			}
777
			if ($3 > SERVER_MAX_TLS_LIFETIME) {
778
				yyerror("ticket lifetime too large");
779
				YYERROR;
780
			}
781
			srv_conf->tls_ticket_lifetime = $3;
782
		}
783
		| NO TICKET			{
784
			srv_conf->tls_ticket_lifetime = 0;
785
		}
786
		;
787
788
root		: ROOT rootflags
789
		| ROOT '{' optnl rootflags_l '}'
790
		;
791
792
rootflags_l	: rootflags optcommanl rootflags_l
793
		| rootflags optnl
794
		;
795
796
rootflags	: STRING		{
797
			if (strlcpy(srv->srv_conf.root, $1,
798
			    sizeof(srv->srv_conf.root)) >=
799
			    sizeof(srv->srv_conf.root)) {
800
				yyerror("document root too long");
801
				free($1);
802
				YYERROR;
803
			}
804
			free($1);
805
			srv->srv_conf.flags |= SRVFLAG_ROOT;
806
		}
807
		| STRIP NUMBER		{
808
			if ($2 < 0 || $2 > INT_MAX) {
809
				yyerror("invalid strip number");
810
				YYERROR;
811
			}
812
			srv->srv_conf.strip = $2;
813
		}
814
		;
815
816
authenticate	: NO AUTHENTICATE		{
817
			srv->srv_conf.flags |= SRVFLAG_NO_AUTH;
818
		}
819
		| AUTHENTICATE authopts		{
820
			struct auth	*auth;
821
822
			if ((auth = auth_add(conf->sc_auth, &$2)) == NULL) {
823
				yyerror("failed to add auth");
824
				YYERROR;
825
			}
826
827
			if (auth->auth_id == 0) {
828
				/* New htpasswd, get new Id */
829
				auth->auth_id = ++last_auth_id;
830
				if (last_auth_id == INT_MAX) {
831
					yyerror("too many auth ids defined");
832
					auth_free(conf->sc_auth, auth);
833
					YYERROR;
834
				}
835
			}
836
837
			srv->srv_conf.auth_id = auth->auth_id;
838
			srv->srv_conf.flags |= SRVFLAG_AUTH;
839
		}
840
		;
841
842
authopts	: STRING WITH STRING	{
843
			if (strlcpy(srv->srv_conf.auth_realm, $1,
844
			    sizeof(srv->srv_conf.auth_realm)) >=
845
			    sizeof(srv->srv_conf.auth_realm)) {
846
				yyerror("basic auth realm name too long");
847
				free($1);
848
				YYERROR;
849
			}
850
			free($1);
851
			if (strlcpy($$.auth_htpasswd, $3,
852
			    sizeof($$.auth_htpasswd)) >=
853
			    sizeof($$.auth_htpasswd)) {
854
				yyerror("password file name too long");
855
				free($3);
856
				YYERROR;
857
			}
858
			free($3);
859
860
		}
861
		| WITH STRING		{
862
			if (strlcpy($$.auth_htpasswd, $2,
863
			    sizeof($$.auth_htpasswd)) >=
864
			    sizeof($$.auth_htpasswd)) {
865
				yyerror("password file name too long");
866
				free($2);
867
				YYERROR;
868
			}
869
			free($2);
870
		};
871
872
directory	: DIRECTORY dirflags
873
		| DIRECTORY '{' optnl dirflags_l '}'
874
		;
875
876
dirflags_l	: dirflags optcommanl dirflags_l
877
		| dirflags optnl
878
		;
879
880
dirflags	: INDEX STRING		{
881
			if (strlcpy(srv_conf->index, $2,
882
			    sizeof(srv_conf->index)) >=
883
			    sizeof(srv_conf->index)) {
884
				yyerror("index file too long");
885
				free($2);
886
				YYERROR;
887
			}
888
			srv_conf->flags &= ~SRVFLAG_NO_INDEX;
889
			srv_conf->flags |= SRVFLAG_INDEX;
890
			free($2);
891
		}
892
		| NO INDEX		{
893
			srv_conf->flags &= ~SRVFLAG_INDEX;
894
			srv_conf->flags |= SRVFLAG_NO_INDEX;
895
		}
896
		| AUTO INDEX		{
897
			srv_conf->flags &= ~SRVFLAG_NO_AUTO_INDEX;
898
			srv_conf->flags |= SRVFLAG_AUTO_INDEX;
899
		}
900
		| NO AUTO INDEX		{
901
			srv_conf->flags &= ~SRVFLAG_AUTO_INDEX;
902
			srv_conf->flags |= SRVFLAG_NO_AUTO_INDEX;
903
		}
904
		;
905
906
907
logformat	: LOG logflags
908
		| LOG '{' optnl logflags_l '}'
909
		| NO LOG		{
910
			srv_conf->flags &= ~SRVFLAG_LOG;
911
			srv_conf->flags |= SRVFLAG_NO_LOG;
912
		}
913
		;
914
915
logflags_l	: logflags optcommanl logflags_l
916
		| logflags optnl
917
		;
918
919
logflags	: STYLE logstyle
920
		| SYSLOG		{
921
			srv_conf->flags &= ~SRVFLAG_NO_SYSLOG;
922
			srv_conf->flags |= SRVFLAG_SYSLOG;
923
		}
924
		| NO SYSLOG		{
925
			srv_conf->flags &= ~SRVFLAG_SYSLOG;
926
			srv_conf->flags |= SRVFLAG_NO_SYSLOG;
927
		}
928
		| ACCESS STRING		{
929
			if (strlcpy(srv_conf->accesslog, $2,
930
			    sizeof(srv_conf->accesslog)) >=
931
			    sizeof(srv_conf->accesslog)) {
932
				yyerror("access log name too long");
933
				free($2);
934
				YYERROR;
935
			}
936
			free($2);
937
			srv_conf->flags |= SRVFLAG_ACCESS_LOG;
938
		}
939
		| ERR STRING		{
940
			if (strlcpy(srv_conf->errorlog, $2,
941
			    sizeof(srv_conf->errorlog)) >=
942
			    sizeof(srv_conf->errorlog)) {
943
				yyerror("error log name too long");
944
				free($2);
945
				YYERROR;
946
			}
947
			free($2);
948
			srv_conf->flags |= SRVFLAG_ERROR_LOG;
949
		}
950
		;
951
952
logstyle	: COMMON		{
953
			srv_conf->flags &= ~SRVFLAG_NO_LOG;
954
			srv_conf->flags |= SRVFLAG_LOG;
955
			srv_conf->logformat = LOG_FORMAT_COMMON;
956
		}
957
		| COMBINED		{
958
			srv_conf->flags &= ~SRVFLAG_NO_LOG;
959
			srv_conf->flags |= SRVFLAG_LOG;
960
			srv_conf->logformat = LOG_FORMAT_COMBINED;
961
		}
962
		| CONNECTION		{
963
			srv_conf->flags &= ~SRVFLAG_NO_LOG;
964
			srv_conf->flags |= SRVFLAG_LOG;
965
			srv_conf->logformat = LOG_FORMAT_CONNECTION;
966
		}
967
		;
968
969
filter		: block RETURN NUMBER optstring	{
970
			if ($3 <= 0 || server_httperror_byid($3) == NULL) {
971
				yyerror("invalid return code: %lld", $3);
972
				free($4);
973
				YYERROR;
974
			}
975
			srv_conf->return_code = $3;
976
977
			if ($4 != NULL) {
978
				/* Only for 3xx redirection headers */
979
				if ($3 < 300 || $3 > 399) {
980
					yyerror("invalid return code for "
981
					    "location URI");
982
					free($4);
983
					YYERROR;
984
				}
985
				srv_conf->return_uri = $4;
986
				srv_conf->return_uri_len = strlen($4) + 1;
987
			}
988
		}
989
		| block DROP			{
990
			/* No return code, silently drop the connection */
991
			srv_conf->return_code = 0;
992
		}
993
		| block				{
994
			/* Forbidden */
995
			srv_conf->return_code = 403;
996
		}
997
		| PASS				{
998
			srv_conf->flags &= ~SRVFLAG_BLOCK;
999
			srv_conf->flags |= SRVFLAG_NO_BLOCK;
1000
		}
1001
		;
1002
1003
block		: BLOCK				{
1004
			srv_conf->flags &= ~SRVFLAG_NO_BLOCK;
1005
			srv_conf->flags |= SRVFLAG_BLOCK;
1006
		}
1007
		;
1008
1009
optmatch	: /* empty */		{ $$ = 0; }
1010
		| MATCH			{ $$ = 1; }
1011
		;
1012
1013
optstring	: /* empty */		{ $$ = NULL; }
1014
		| STRING		{ $$ = $1; }
1015
		;
1016
1017
tcpip		: TCP '{' optnl tcpflags_l '}'
1018
		| TCP tcpflags
1019
		;
1020
1021
tcpflags_l	: tcpflags optcommanl tcpflags_l
1022
		| tcpflags optnl
1023
		;
1024
1025
tcpflags	: SACK			{ srv_conf->tcpflags |= TCPFLAG_SACK; }
1026
		| NO SACK		{ srv_conf->tcpflags |= TCPFLAG_NSACK; }
1027
		| NODELAY		{
1028
			srv_conf->tcpflags |= TCPFLAG_NODELAY;
1029
		}
1030
		| NO NODELAY		{
1031
			srv_conf->tcpflags |= TCPFLAG_NNODELAY;
1032
		}
1033
		| BACKLOG NUMBER	{
1034
			if ($2 < 0 || $2 > SERVER_MAX_CLIENTS) {
1035
				yyerror("invalid backlog: %lld", $2);
1036
				YYERROR;
1037
			}
1038
			srv_conf->tcpbacklog = $2;
1039
		}
1040
		| SOCKET BUFFER NUMBER	{
1041
			srv_conf->tcpflags |= TCPFLAG_BUFSIZ;
1042
			if ((srv_conf->tcpbufsiz = $3) < 0) {
1043
				yyerror("invalid socket buffer size: %lld", $3);
1044
				YYERROR;
1045
			}
1046
		}
1047
		| IP STRING NUMBER	{
1048
			if ($3 < 0) {
1049
				yyerror("invalid ttl: %lld", $3);
1050
				free($2);
1051
				YYERROR;
1052
			}
1053
			if (strcasecmp("ttl", $2) == 0) {
1054
				srv_conf->tcpflags |= TCPFLAG_IPTTL;
1055
				srv_conf->tcpipttl = $3;
1056
			} else if (strcasecmp("minttl", $2) == 0) {
1057
				srv_conf->tcpflags |= TCPFLAG_IPMINTTL;
1058
				srv_conf->tcpipminttl = $3;
1059
			} else {
1060
				yyerror("invalid TCP/IP flag: %s", $2);
1061
				free($2);
1062
				YYERROR;
1063
			}
1064
			free($2);
1065
		}
1066
		;
1067
1068
types		: TYPES	'{' optnl mediaopts_l '}'
1069
		;
1070
1071
mediaopts_l	: mediaopts_l mediaoptsl nl
1072
		| mediaoptsl nl
1073
		;
1074
1075
mediaoptsl	: mediastring medianames_l optsemicolon
1076
		| include
1077
		;
1078
1079
mediastring	: STRING '/' STRING	{
1080
			if (strlcpy(media.media_type, $1,
1081
			    sizeof(media.media_type)) >=
1082
			    sizeof(media.media_type) ||
1083
			    strlcpy(media.media_subtype, $3,
1084
			    sizeof(media.media_subtype)) >=
1085
			    sizeof(media.media_subtype)) {
1086
				yyerror("media type too long");
1087
				free($1);
1088
				free($3);
1089
				YYERROR;
1090
			}
1091
			free($1);
1092
			free($3);
1093
		}
1094
		;
1095
1096
medianames_l	: medianames_l medianamesl
1097
		| medianamesl
1098
		;
1099
1100
medianamesl	: numberstring				{
1101
			if (strlcpy(media.media_name, $1,
1102
			    sizeof(media.media_name)) >=
1103
			    sizeof(media.media_name)) {
1104
				yyerror("media name too long");
1105
				free($1);
1106
				YYERROR;
1107
			}
1108
			free($1);
1109
1110
			if (!loadcfg)
1111
				break;
1112
1113
			if (media_add(conf->sc_mediatypes, &media) == NULL) {
1114
				yyerror("failed to add media type");
1115
				YYERROR;
1116
			}
1117
		}
1118
		;
1119
1120
port		: PORT NUMBER {
1121
			if ($2 <= 0 || $2 > (int)USHRT_MAX) {
1122
				yyerror("invalid port: %lld", $2);
1123
				YYERROR;
1124
			}
1125
			$$.val[0] = htons($2);
1126
		}
1127
		| PORT STRING {
1128
			int	 val;
1129
1130
			if ((val = getservice($2)) == -1) {
1131
				yyerror("invalid port: %s", $2);
1132
				free($2);
1133
				YYERROR;
1134
			}
1135
			free($2);
1136
1137
			$$.val[0] = val;
1138
		}
1139
		;
1140
1141
timeout		: NUMBER
1142
		{
1143
			if ($1 < 0) {
1144
				yyerror("invalid timeout: %lld", $1);
1145
				YYERROR;
1146
			}
1147
			$$.tv_sec = $1;
1148
			$$.tv_usec = 0;
1149
		}
1150
		;
1151
1152
numberstring	: NUMBER		{
1153
			char *s;
1154
			if (asprintf(&s, "%lld", $1) == -1) {
1155
				yyerror("asprintf: number");
1156
				YYERROR;
1157
			}
1158
			$$ = s;
1159
		}
1160
		| STRING
1161
		;
1162
1163
optsemicolon	: ';'
1164
		|
1165
		;
1166
1167
optnl		: '\n' optnl
1168
		|
1169
		;
1170
1171
optcommanl	: ',' optnl
1172
		| nl
1173
		;
1174
1175
nl		: '\n' optnl
1176
		;
1177
1178
%%
1179
1180
struct keywords {
1181
	const char	*k_name;
1182
	int		 k_val;
1183
};
1184
1185
int
1186
yyerror(const char *fmt, ...)
1187
{
1188
	va_list		 ap;
1189
	char		*msg;
1190
1191
	file->errors++;
1192
	va_start(ap, fmt);
1193
	if (vasprintf(&msg, fmt, ap) == -1)
1194
		fatalx("yyerror vasprintf");
1195
	va_end(ap);
1196
	logit(LOG_CRIT, "%s:%d: %s", file->name, yylval.lineno, msg);
1197
	free(msg);
1198
	return (0);
1199
}
1200
1201
int
1202
kw_cmp(const void *k, const void *e)
1203
{
1204
11616
	return (strcmp(k, ((const struct keywords *)e)->k_name));
1205
}
1206
1207
int
1208
lookup(char *s)
1209
{
1210
	/* this has to be sorted always */
1211
	static const struct keywords keywords[] = {
1212
		{ "access",		ACCESS },
1213
		{ "alias",		ALIAS },
1214
		{ "authenticate",	AUTHENTICATE},
1215
		{ "auto",		AUTO },
1216
		{ "backlog",		BACKLOG },
1217
		{ "block",		BLOCK },
1218
		{ "body",		BODY },
1219
		{ "buffer",		BUFFER },
1220
		{ "certificate",	CERTIFICATE },
1221
		{ "chroot",		CHROOT },
1222
		{ "ciphers",		CIPHERS },
1223
		{ "combined",		COMBINED },
1224
		{ "common",		COMMON },
1225
		{ "connection",		CONNECTION },
1226
		{ "default",		DEFAULT },
1227
		{ "dhe",		DHE },
1228
		{ "directory",		DIRECTORY },
1229
		{ "drop",		DROP },
1230
		{ "ecdhe",		ECDHE },
1231
		{ "error",		ERR },
1232
		{ "fastcgi",		FCGI },
1233
		{ "hsts",		HSTS },
1234
		{ "include",		INCLUDE },
1235
		{ "index",		INDEX },
1236
		{ "ip",			IP },
1237
		{ "key",		KEY },
1238
		{ "lifetime",		LIFETIME },
1239
		{ "listen",		LISTEN },
1240
		{ "location",		LOCATION },
1241
		{ "log",		LOG },
1242
		{ "logdir",		LOGDIR },
1243
		{ "match",		MATCH },
1244
		{ "max",		MAXIMUM },
1245
		{ "max-age",		MAXAGE },
1246
		{ "no",			NO },
1247
		{ "nodelay",		NODELAY },
1248
		{ "ocsp",		OCSP },
1249
		{ "on",			ON },
1250
		{ "pass",		PASS },
1251
		{ "port",		PORT },
1252
		{ "prefork",		PREFORK },
1253
		{ "preload",		PRELOAD },
1254
		{ "protocols",		PROTOCOLS },
1255
		{ "request",		REQUEST },
1256
		{ "requests",		REQUESTS },
1257
		{ "return",		RETURN },
1258
		{ "root",		ROOT },
1259
		{ "sack",		SACK },
1260
		{ "server",		SERVER },
1261
		{ "socket",		SOCKET },
1262
		{ "strip",		STRIP },
1263
		{ "style",		STYLE },
1264
		{ "subdomains",		SUBDOMAINS },
1265
		{ "syslog",		SYSLOG },
1266
		{ "tcp",		TCP },
1267
		{ "ticket",		TICKET },
1268
		{ "timeout",		TIMEOUT },
1269
		{ "tls",		TLS },
1270
		{ "type",		TYPE },
1271
		{ "types",		TYPES },
1272
		{ "with",		WITH }
1273
	};
1274
	const struct keywords	*p;
1275
1276
2544
	p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
1277
	    sizeof(keywords[0]), kw_cmp);
1278
1279
1272
	if (p)
1280
1200
		return (p->k_val);
1281
	else
1282
72
		return (STRING);
1283
1272
}
1284
1285
#define MAXPUSHBACK	128
1286
1287
unsigned char	*parsebuf;
1288
int		 parseindex;
1289
unsigned char	 pushback_buffer[MAXPUSHBACK];
1290
int		 pushback_index = 0;
1291
1292
int
1293
lgetc(int quotec)
1294
{
1295
	int		c, next;
1296
1297
51802
	if (parsebuf) {
1298
		/* Read character from the parsebuffer instead of input. */
1299
		if (parseindex >= 0) {
1300
			c = parsebuf[parseindex++];
1301
			if (c != '\0')
1302
				return (c);
1303
			parsebuf = NULL;
1304
		} else
1305
			parseindex++;
1306
	}
1307
1308
25901
	if (pushback_index)
1309
1704
		return (pushback_buffer[--pushback_index]);
1310
1311
24197
	if (quotec) {
1312

53856
		if ((c = getc(file->stream)) == EOF) {
1313
			yyerror("reached end of file while parsing "
1314
			    "quoted string");
1315
			if (file == topfile || popfile() == EOF)
1316
				return (EOF);
1317
			return (quotec);
1318
		}
1319
13464
		return (c);
1320
	}
1321
1322

42932
	while ((c = getc(file->stream)) == '\\') {
1323
		next = getc(file->stream);
1324
		if (next != '\n') {
1325
			c = next;
1326
			break;
1327
		}
1328
		yylval.lineno = file->lineno;
1329
		file->lineno++;
1330
	}
1331
1332
10733
	while (c == EOF) {
1333

72
		if (file == topfile || popfile() == EOF)
1334
72
			return (EOF);
1335
		c = getc(file->stream);
1336
	}
1337
10661
	return (c);
1338
25901
}
1339
1340
int
1341
lungetc(int c)
1342
{
1343
3408
	if (c == EOF)
1344
		return (EOF);
1345
1704
	if (parsebuf) {
1346
		parseindex--;
1347
		if (parseindex >= 0)
1348
			return (c);
1349
	}
1350
1704
	if (pushback_index < MAXPUSHBACK-1)
1351
1704
		return (pushback_buffer[pushback_index++] = c);
1352
	else
1353
		return (EOF);
1354
1704
}
1355
1356
int
1357
findeol(void)
1358
{
1359
	int	c;
1360
1361
	parsebuf = NULL;
1362
1363
	/* skip to either EOF or the first real EOL */
1364
	while (1) {
1365
		if (pushback_index)
1366
			c = pushback_buffer[--pushback_index];
1367
		else
1368
			c = lgetc(0);
1369
		if (c == '\n') {
1370
			file->lineno++;
1371
			break;
1372
		}
1373
		if (c == EOF)
1374
			break;
1375
	}
1376
	return (ERROR);
1377
}
1378
1379
int
1380
yylex(void)
1381
{
1382
6192
	unsigned char	 buf[8096];
1383
	unsigned char	*p, *val;
1384
	int		 quotec, next, c;
1385
3096
	int		 token;
1386
1387
top:
1388
3096
	p = buf;
1389
7728
	while ((c = lgetc(0)) == ' ' || c == '\t')
1390
		; /* nothing */
1391
1392
3096
	yylval.lineno = file->lineno;
1393
3096
	if (c == '#')
1394
		while ((c = lgetc(0)) != '\n' && c != EOF)
1395
			; /* nothing */
1396
3096
	if (c == '$' && parsebuf == NULL) {
1397
		while (1) {
1398
			if ((c = lgetc(0)) == EOF)
1399
				return (0);
1400
1401
			if (p + 1 >= buf + sizeof(buf) - 1) {
1402
				yyerror("string too long");
1403
				return (findeol());
1404
			}
1405
			if (isalnum(c) || c == '_') {
1406
				*p++ = c;
1407
				continue;
1408
			}
1409
			*p = '\0';
1410
			lungetc(c);
1411
			break;
1412
		}
1413
		val = symget(buf);
1414
		if (val == NULL) {
1415
			yyerror("macro '%s' not defined", buf);
1416
			return (findeol());
1417
		}
1418
		parsebuf = val;
1419
		parseindex = 0;
1420
		goto top;
1421
	}
1422
1423
3096
	switch (c) {
1424
	case '\'':
1425
	case '"':
1426
		quotec = c;
1427
13464
		while (1) {
1428
13464
			if ((c = lgetc(quotec)) == EOF)
1429
				return (0);
1430
13464
			if (c == '\n') {
1431
				file->lineno++;
1432
				continue;
1433
13464
			} else if (c == '\\') {
1434
				if ((next = lgetc(quotec)) == EOF)
1435
					return (0);
1436
				if (next == quotec || c == ' ' || c == '\t')
1437
					c = next;
1438
				else if (next == '\n') {
1439
					file->lineno++;
1440
					continue;
1441
				} else
1442
					lungetc(next);
1443
13464
			} else if (c == quotec) {
1444
552
				*p = '\0';
1445
				break;
1446
12912
			} else if (c == '\0') {
1447
				yyerror("syntax error");
1448
				return (findeol());
1449
			}
1450
12912
			if (p + 1 >= buf + sizeof(buf) - 1) {
1451
				yyerror("string too long");
1452
				return (findeol());
1453
			}
1454
12912
			*p++ = c;
1455
		}
1456
552
		yylval.v.string = strdup(buf);
1457
552
		if (yylval.v.string == NULL)
1458
			err(1, "yylex: strdup");
1459
552
		return (STRING);
1460
	}
1461
1462
#define allowed_to_end_number(x) \
1463
	(isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=')
1464
1465

5088
	if (c == '-' || isdigit(c)) {
1466
		do {
1467
701
			*p++ = c;
1468
701
			if ((unsigned)(p-buf) >= sizeof(buf)) {
1469
				yyerror("string too long");
1470
				return (findeol());
1471
			}
1472

1402
		} while ((c = lgetc(0)) != EOF && isdigit(c));
1473
288
		lungetc(c);
1474

432
		if (p == buf + 1 && buf[0] == '-')
1475
			goto nodigits;
1476

576
		if (c == EOF || allowed_to_end_number(c)) {
1477
216
			const char *errstr = NULL;
1478
1479
216
			*p = '\0';
1480
216
			yylval.v.number = strtonum(buf, LLONG_MIN,
1481
			    LLONG_MAX, &errstr);
1482
216
			if (errstr) {
1483
				yyerror("\"%s\" invalid number: %s",
1484
				    buf, errstr);
1485
				return (findeol());
1486
			}
1487
216
			return (NUMBER);
1488
216
		} else {
1489
nodigits:
1490
360
			while (p > buf + 1)
1491
144
				lungetc(*--p);
1492
			c = *--p;
1493
72
			if (c == '-')
1494
				return (c);
1495
		}
1496
	}
1497
1498
#define allowed_in_string(x) \
1499
	(isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
1500
	x != '{' && x != '}' && x != '<' && x != '>' && \
1501
	x != '!' && x != '=' && x != '#' && \
1502
	x != ',' && x != ';' && x != '/'))
1503
1504
2328
	if (isalnum(c) || c == ':' || c == '_' || c == '*') {
1505
		do {
1506
7104
			*p++ = c;
1507
7104
			if ((unsigned)(p-buf) >= sizeof(buf)) {
1508
				yyerror("string too long");
1509
				return (findeol());
1510
			}
1511

15696
		} while ((c = lgetc(0)) != EOF && (allowed_in_string(c)));
1512
1272
		lungetc(c);
1513
1272
		*p = '\0';
1514
1272
		if ((token = lookup(buf)) == STRING)
1515
72
			if ((yylval.v.string = strdup(buf)) == NULL)
1516
				err(1, "yylex: strdup");
1517
1272
		return (token);
1518
	}
1519
1056
	if (c == '\n') {
1520
840
		yylval.lineno = file->lineno;
1521
840
		file->lineno++;
1522
840
	}
1523
1056
	if (c == EOF)
1524
72
		return (0);
1525
984
	return (c);
1526
3096
}
1527
1528
int
1529
check_file_secrecy(int fd, const char *fname)
1530
{
1531
	struct stat	st;
1532
1533
	if (fstat(fd, &st)) {
1534
		log_warn("cannot stat %s", fname);
1535
		return (-1);
1536
	}
1537
	if (st.st_uid != 0 && st.st_uid != getuid()) {
1538
		log_warnx("%s: owner not root or current user", fname);
1539
		return (-1);
1540
	}
1541
	if (st.st_mode & (S_IWGRP | S_IXGRP | S_IRWXO)) {
1542
		log_warnx("%s: group writable or world read/writable", fname);
1543
		return (-1);
1544
	}
1545
	return (0);
1546
}
1547
1548
struct file *
1549
pushfile(const char *name, int secret)
1550
{
1551
	struct file	*nfile;
1552
1553
288
	if ((nfile = calloc(1, sizeof(struct file))) == NULL) {
1554
		log_warn("%s: malloc", __func__);
1555
		return (NULL);
1556
	}
1557
144
	if ((nfile->name = strdup(name)) == NULL) {
1558
		log_warn("%s: malloc", __func__);
1559
		free(nfile);
1560
		return (NULL);
1561
	}
1562
144
	if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
1563
		log_warn("%s: %s", __func__, nfile->name);
1564
		free(nfile->name);
1565
		free(nfile);
1566
		return (NULL);
1567

144
	} else if (secret &&
1568
	    check_file_secrecy(fileno(nfile->stream), nfile->name)) {
1569
		fclose(nfile->stream);
1570
		free(nfile->name);
1571
		free(nfile);
1572
		return (NULL);
1573
	}
1574
144
	nfile->lineno = 1;
1575
144
	TAILQ_INSERT_TAIL(&files, nfile, entry);
1576
144
	return (nfile);
1577
144
}
1578
1579
int
1580
popfile(void)
1581
{
1582
	struct file	*prev;
1583
1584
288
	if ((prev = TAILQ_PREV(file, files, entry)) != NULL)
1585
		prev->errors += file->errors;
1586
1587
288
	TAILQ_REMOVE(&files, file, entry);
1588
144
	fclose(file->stream);
1589
144
	free(file->name);
1590
144
	free(file);
1591
144
	file = prev;
1592
144
	return (file ? 0 : EOF);
1593
}
1594
1595
int
1596
parse_config(const char *filename, struct httpd *x_conf)
1597
{
1598
	struct sym		*sym, *next;
1599
144
	struct media_type	 dflt = HTTPD_DEFAULT_TYPE;
1600
1601
72
	conf = x_conf;
1602
72
	if (config_init(conf) == -1) {
1603
		log_warn("%s: cannot initialize configuration", __func__);
1604
		return (-1);
1605
	}
1606
1607
	/* Set default media type */
1608
72
	memcpy(&conf->sc_default_type, &dflt, sizeof(struct media_type));
1609
1610
72
	errors = 0;
1611
1612
72
	if ((file = pushfile(filename, 0)) == NULL)
1613
		return (-1);
1614
1615
72
	topfile = file;
1616
72
	setservent(1);
1617
1618
72
	yyparse();
1619
72
	errors = file->errors;
1620
72
	popfile();
1621
1622
72
	endservent();
1623
72
	endprotoent();
1624
1625
	/* Free macros */
1626
144
	TAILQ_FOREACH_SAFE(sym, &symhead, entry, next) {
1627
		if (!sym->persist) {
1628
			free(sym->nam);
1629
			free(sym->val);
1630
			TAILQ_REMOVE(&symhead, sym, entry);
1631
			free(sym);
1632
		}
1633
	}
1634
1635
72
	return (errors ? -1 : 0);
1636
72
}
1637
1638
int
1639
load_config(const char *filename, struct httpd *x_conf)
1640
{
1641
	struct sym		*sym, *next;
1642
144
	struct http_mediatype	 mediatypes[] = MEDIA_TYPES;
1643
72
	struct media_type	 m;
1644
	int			 i;
1645
1646
72
	conf = x_conf;
1647
72
	conf->sc_flags = 0;
1648
1649
72
	loadcfg = 1;
1650
72
	errors = 0;
1651
72
	last_server_id = 0;
1652
72
	last_auth_id = 0;
1653
1654
72
	srv = NULL;
1655
1656
72
	if ((file = pushfile(filename, 0)) == NULL)
1657
		return (-1);
1658
1659
72
	topfile = file;
1660
72
	setservent(1);
1661
1662
72
	yyparse();
1663
72
	errors = file->errors;
1664
72
	popfile();
1665
1666
72
	endservent();
1667
72
	endprotoent();
1668
1669
	/* Free macros and check which have not been used. */
1670
144
	for (sym = TAILQ_FIRST(&symhead); sym != NULL; sym = next) {
1671
		next = TAILQ_NEXT(sym, entry);
1672
		if ((conf->sc_opts & HTTPD_OPT_VERBOSE) && !sym->used)
1673
			fprintf(stderr, "warning: macro '%s' not "
1674
			    "used\n", sym->nam);
1675
		if (!sym->persist) {
1676
			free(sym->nam);
1677
			free(sym->val);
1678
			TAILQ_REMOVE(&symhead, sym, entry);
1679
			free(sym);
1680
		}
1681
	}
1682
1683
72
	if (TAILQ_EMPTY(conf->sc_servers)) {
1684
		log_warnx("no actions, nothing to do");
1685
		errors++;
1686
	}
1687
1688
72
	if (RB_EMPTY(conf->sc_mediatypes)) {
1689
		/* Add default media types */
1690
1440
		for (i = 0; mediatypes[i].media_name != NULL; i++) {
1691
648
			(void)strlcpy(m.media_name, mediatypes[i].media_name,
1692
			    sizeof(m.media_name));
1693
648
			(void)strlcpy(m.media_type, mediatypes[i].media_type,
1694
			    sizeof(m.media_type));
1695
1296
			(void)strlcpy(m.media_subtype,
1696
648
			    mediatypes[i].media_subtype,
1697
			    sizeof(m.media_subtype));
1698
648
			m.media_encoding = NULL;
1699
1700
648
			if (media_add(conf->sc_mediatypes, &m) == NULL) {
1701
				log_warnx("failed to add default media \"%s\"",
1702
				    m.media_name);
1703
				errors++;
1704
			}
1705
		}
1706
	}
1707
1708
72
	return (errors ? -1 : 0);
1709
72
}
1710
1711
int
1712
symset(const char *nam, const char *val, int persist)
1713
{
1714
	struct sym	*sym;
1715
1716
	TAILQ_FOREACH(sym, &symhead, entry) {
1717
		if (strcmp(nam, sym->nam) == 0)
1718
			break;
1719
	}
1720
1721
	if (sym != NULL) {
1722
		if (sym->persist == 1)
1723
			return (0);
1724
		else {
1725
			free(sym->nam);
1726
			free(sym->val);
1727
			TAILQ_REMOVE(&symhead, sym, entry);
1728
			free(sym);
1729
		}
1730
	}
1731
	if ((sym = calloc(1, sizeof(*sym))) == NULL)
1732
		return (-1);
1733
1734
	sym->nam = strdup(nam);
1735
	if (sym->nam == NULL) {
1736
		free(sym);
1737
		return (-1);
1738
	}
1739
	sym->val = strdup(val);
1740
	if (sym->val == NULL) {
1741
		free(sym->nam);
1742
		free(sym);
1743
		return (-1);
1744
	}
1745
	sym->used = 0;
1746
	sym->persist = persist;
1747
	TAILQ_INSERT_TAIL(&symhead, sym, entry);
1748
	return (0);
1749
}
1750
1751
int
1752
cmdline_symset(char *s)
1753
{
1754
	char	*sym, *val;
1755
	int	ret;
1756
	size_t	len;
1757
1758
	if ((val = strrchr(s, '=')) == NULL)
1759
		return (-1);
1760
1761
	len = strlen(s) - strlen(val) + 1;
1762
	if ((sym = malloc(len)) == NULL)
1763
		errx(1, "cmdline_symset: malloc");
1764
1765
	(void)strlcpy(sym, s, len);
1766
1767
	ret = symset(sym, val + 1, 1);
1768
	free(sym);
1769
1770
	return (ret);
1771
}
1772
1773
char *
1774
symget(const char *nam)
1775
{
1776
	struct sym	*sym;
1777
1778
	TAILQ_FOREACH(sym, &symhead, entry) {
1779
		if (strcmp(nam, sym->nam) == 0) {
1780
			sym->used = 1;
1781
			return (sym->val);
1782
		}
1783
	}
1784
	return (NULL);
1785
}
1786
1787
struct address *
1788
host_v4(const char *s)
1789
{
1790
144
	struct in_addr		 ina;
1791
	struct sockaddr_in	*sain;
1792
	struct address		*h;
1793
1794
72
	memset(&ina, 0, sizeof(ina));
1795
72
	if (inet_pton(AF_INET, s, &ina) != 1)
1796
		return (NULL);
1797
1798
72
	if ((h = calloc(1, sizeof(*h))) == NULL)
1799
		fatal(__func__);
1800
72
	sain = (struct sockaddr_in *)&h->ss;
1801
72
	sain->sin_len = sizeof(struct sockaddr_in);
1802
72
	sain->sin_family = AF_INET;
1803
72
	sain->sin_addr.s_addr = ina.s_addr;
1804
72
	if (sain->sin_addr.s_addr == INADDR_ANY)
1805
		h->prefixlen = 0; /* 0.0.0.0 address */
1806
	else
1807
		h->prefixlen = -1; /* host address */
1808
72
	return (h);
1809
72
}
1810
1811
struct address *
1812
host_v6(const char *s)
1813
{
1814
	struct addrinfo		 hints, *res;
1815
	struct sockaddr_in6	*sa_in6;
1816
	struct address		*h = NULL;
1817
1818
	memset(&hints, 0, sizeof(hints));
1819
	hints.ai_family = AF_INET6;
1820
	hints.ai_socktype = SOCK_DGRAM; /* dummy */
1821
	hints.ai_flags = AI_NUMERICHOST;
1822
	if (getaddrinfo(s, "0", &hints, &res) == 0) {
1823
		if ((h = calloc(1, sizeof(*h))) == NULL)
1824
			fatal(__func__);
1825
		sa_in6 = (struct sockaddr_in6 *)&h->ss;
1826
		sa_in6->sin6_len = sizeof(struct sockaddr_in6);
1827
		sa_in6->sin6_family = AF_INET6;
1828
		memcpy(&sa_in6->sin6_addr,
1829
		    &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr,
1830
		    sizeof(sa_in6->sin6_addr));
1831
		sa_in6->sin6_scope_id =
1832
		    ((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id;
1833
		if (memcmp(&sa_in6->sin6_addr, &in6addr_any,
1834
		    sizeof(sa_in6->sin6_addr)) == 0)
1835
			h->prefixlen = 0; /* any address */
1836
		else
1837
			h->prefixlen = -1; /* host address */
1838
		freeaddrinfo(res);
1839
	}
1840
1841
	return (h);
1842
}
1843
1844
int
1845
host_dns(const char *s, struct addresslist *al, int max,
1846
    struct portrange *port, const char *ifname, int ipproto)
1847
{
1848
	struct addrinfo		 hints, *res0, *res;
1849
	int			 error, cnt = 0;
1850
	struct sockaddr_in	*sain;
1851
	struct sockaddr_in6	*sin6;
1852
	struct address		*h;
1853
1854
	if ((cnt = host_if(s, al, max, port, ifname, ipproto)) != 0)
1855
		return (cnt);
1856
1857
	memset(&hints, 0, sizeof(hints));
1858
	hints.ai_family = PF_UNSPEC;
1859
	hints.ai_socktype = SOCK_DGRAM; /* DUMMY */
1860
	hints.ai_flags = AI_ADDRCONFIG;
1861
	error = getaddrinfo(s, NULL, &hints, &res0);
1862
	if (error == EAI_AGAIN || error == EAI_NODATA || error == EAI_NONAME)
1863
		return (0);
1864
	if (error) {
1865
		log_warnx("%s: could not parse \"%s\": %s", __func__, s,
1866
		    gai_strerror(error));
1867
		return (-1);
1868
	}
1869
1870
	for (res = res0; res && cnt < max; res = res->ai_next) {
1871
		if (res->ai_family != AF_INET &&
1872
		    res->ai_family != AF_INET6)
1873
			continue;
1874
		if ((h = calloc(1, sizeof(*h))) == NULL)
1875
			fatal(__func__);
1876
1877
		if (port != NULL)
1878
			memcpy(&h->port, port, sizeof(h->port));
1879
		if (ifname != NULL) {
1880
			if (strlcpy(h->ifname, ifname, sizeof(h->ifname)) >=
1881
			    sizeof(h->ifname))
1882
				log_warnx("%s: interface name truncated",
1883
				    __func__);
1884
			freeaddrinfo(res0);
1885
			free(h);
1886
			return (-1);
1887
		}
1888
		if (ipproto != -1)
1889
			h->ipproto = ipproto;
1890
		h->ss.ss_family = res->ai_family;
1891
		h->prefixlen = -1; /* host address */
1892
1893
		if (res->ai_family == AF_INET) {
1894
			sain = (struct sockaddr_in *)&h->ss;
1895
			sain->sin_len = sizeof(struct sockaddr_in);
1896
			sain->sin_addr.s_addr = ((struct sockaddr_in *)
1897
			    res->ai_addr)->sin_addr.s_addr;
1898
		} else {
1899
			sin6 = (struct sockaddr_in6 *)&h->ss;
1900
			sin6->sin6_len = sizeof(struct sockaddr_in6);
1901
			memcpy(&sin6->sin6_addr, &((struct sockaddr_in6 *)
1902
			    res->ai_addr)->sin6_addr, sizeof(struct in6_addr));
1903
		}
1904
1905
		TAILQ_INSERT_HEAD(al, h, entry);
1906
		cnt++;
1907
	}
1908
	if (cnt == max && res) {
1909
		log_warnx("%s: %s resolves to more than %d hosts", __func__,
1910
		    s, max);
1911
	}
1912
	freeaddrinfo(res0);
1913
	return (cnt);
1914
}
1915
1916
int
1917
host_if(const char *s, struct addresslist *al, int max,
1918
    struct portrange *port, const char *ifname, int ipproto)
1919
{
1920
	struct ifaddrs		*ifap, *p;
1921
	struct sockaddr_in	*sain;
1922
	struct sockaddr_in6	*sin6;
1923
	struct address		*h;
1924
	int			 cnt = 0, af;
1925
1926
	if (getifaddrs(&ifap) == -1)
1927
		fatal("getifaddrs");
1928
1929
	/* First search for IPv4 addresses */
1930
	af = AF_INET;
1931
1932
 nextaf:
1933
	for (p = ifap; p != NULL && cnt < max; p = p->ifa_next) {
1934
		if (p->ifa_addr->sa_family != af ||
1935
		    (strcmp(s, p->ifa_name) != 0 &&
1936
		    !is_if_in_group(p->ifa_name, s)))
1937
			continue;
1938
		if ((h = calloc(1, sizeof(*h))) == NULL)
1939
			fatal("calloc");
1940
1941
		if (port != NULL)
1942
			memcpy(&h->port, port, sizeof(h->port));
1943
		if (ifname != NULL) {
1944
			if (strlcpy(h->ifname, ifname, sizeof(h->ifname)) >=
1945
			    sizeof(h->ifname))
1946
				log_warnx("%s: interface name truncated",
1947
				    __func__);
1948
			freeifaddrs(ifap);
1949
			return (-1);
1950
		}
1951
		if (ipproto != -1)
1952
			h->ipproto = ipproto;
1953
		h->ss.ss_family = af;
1954
		h->prefixlen = -1; /* host address */
1955
1956
		if (af == AF_INET) {
1957
			sain = (struct sockaddr_in *)&h->ss;
1958
			sain->sin_len = sizeof(struct sockaddr_in);
1959
			sain->sin_addr.s_addr = ((struct sockaddr_in *)
1960
			    p->ifa_addr)->sin_addr.s_addr;
1961
		} else {
1962
			sin6 = (struct sockaddr_in6 *)&h->ss;
1963
			sin6->sin6_len = sizeof(struct sockaddr_in6);
1964
			memcpy(&sin6->sin6_addr, &((struct sockaddr_in6 *)
1965
			    p->ifa_addr)->sin6_addr, sizeof(struct in6_addr));
1966
			sin6->sin6_scope_id = ((struct sockaddr_in6 *)
1967
			    p->ifa_addr)->sin6_scope_id;
1968
		}
1969
1970
		TAILQ_INSERT_HEAD(al, h, entry);
1971
		cnt++;
1972
	}
1973
	if (af == AF_INET) {
1974
		/* Next search for IPv6 addresses */
1975
		af = AF_INET6;
1976
		goto nextaf;
1977
	}
1978
1979
	if (cnt > max) {
1980
		log_warnx("%s: %s resolves to more than %d hosts", __func__,
1981
		    s, max);
1982
	}
1983
	freeifaddrs(ifap);
1984
	return (cnt);
1985
}
1986
1987
int
1988
host(const char *s, struct addresslist *al, int max,
1989
    struct portrange *port, const char *ifname, int ipproto)
1990
{
1991
	struct address *h;
1992
1993
144
	if (strcmp("*", s) == 0)
1994
		s = "0.0.0.0";
1995
1996
72
	h = host_v4(s);
1997
1998
	/* IPv6 address? */
1999
72
	if (h == NULL)
2000
		h = host_v6(s);
2001
2002
72
	if (h != NULL) {
2003
72
		if (port != NULL)
2004
72
			memcpy(&h->port, port, sizeof(h->port));
2005
72
		if (ifname != NULL) {
2006
			if (strlcpy(h->ifname, ifname, sizeof(h->ifname)) >=
2007
			    sizeof(h->ifname)) {
2008
				log_warnx("%s: interface name truncated",
2009
				    __func__);
2010
				free(h);
2011
				return (-1);
2012
			}
2013
		}
2014
72
		if (ipproto != -1)
2015
			h->ipproto = ipproto;
2016
2017
216
		TAILQ_INSERT_HEAD(al, h, entry);
2018
72
		return (1);
2019
	}
2020
2021
	return (host_dns(s, al, max, port, ifname, ipproto));
2022
72
}
2023
2024
void
2025
host_free(struct addresslist *al)
2026
{
2027
	struct address	 *h;
2028
2029
360
	while ((h = TAILQ_FIRST(al)) != NULL) {
2030
216
		TAILQ_REMOVE(al, h, entry);
2031
72
		free(h);
2032
	}
2033
72
}
2034
2035
struct server *
2036
server_inherit(struct server *src, struct server_config *alias,
2037
    struct server_config *addr)
2038
{
2039
	struct server	*dst, *s, *dstl;
2040
2041
	if ((dst = calloc(1, sizeof(*dst))) == NULL)
2042
		fatal("out of memory");
2043
2044
	/* Copy the source server and assign a new Id */
2045
	memcpy(&dst->srv_conf, &src->srv_conf, sizeof(dst->srv_conf));
2046
	if ((dst->srv_conf.tls_cert_file =
2047
	    strdup(src->srv_conf.tls_cert_file)) == NULL)
2048
		fatal("out of memory");
2049
	if ((dst->srv_conf.tls_key_file =
2050
	    strdup(src->srv_conf.tls_key_file)) == NULL)
2051
		fatal("out of memory");
2052
	if (src->srv_conf.tls_ocsp_staple_file != NULL) {
2053
		if ((dst->srv_conf.tls_ocsp_staple_file =
2054
		    strdup(src->srv_conf.tls_ocsp_staple_file)) == NULL)
2055
			fatal("out of memory");
2056
	}
2057
2058
	if (src->srv_conf.return_uri != NULL &&
2059
	    (dst->srv_conf.return_uri =
2060
	    strdup(src->srv_conf.return_uri)) == NULL)
2061
		fatal("out of memory");
2062
2063
	dst->srv_conf.id = ++last_server_id;
2064
	dst->srv_conf.parent_id = dst->srv_conf.id;
2065
	dst->srv_s = -1;
2066
2067
	if (last_server_id == INT_MAX) {
2068
		yyerror("too many servers defined");
2069
		serverconfig_free(&dst->srv_conf);
2070
		free(dst);
2071
		return (NULL);
2072
	}
2073
2074
	/* Now set alias and listen address */
2075
	strlcpy(dst->srv_conf.name, alias->name, sizeof(dst->srv_conf.name));
2076
	memcpy(&dst->srv_conf.ss, &addr->ss, sizeof(dst->srv_conf.ss));
2077
	dst->srv_conf.port = addr->port;
2078
	dst->srv_conf.prefixlen = addr->prefixlen;
2079
	if (addr->flags & SRVFLAG_TLS)
2080
		dst->srv_conf.flags |= SRVFLAG_TLS;
2081
	else
2082
		dst->srv_conf.flags &= ~SRVFLAG_TLS;
2083
2084
	/* Don't inherit the "match" option, use it from the alias */
2085
	dst->srv_conf.flags &= ~SRVFLAG_SERVER_MATCH;
2086
	dst->srv_conf.flags |= (alias->flags & SRVFLAG_SERVER_MATCH);
2087
2088
	if (server_tls_load_keypair(dst) == -1) {
2089
		yyerror("failed to load public/private keys "
2090
		    "for server %s", dst->srv_conf.name);
2091
		serverconfig_free(&dst->srv_conf);
2092
		free(dst);
2093
		return (NULL);
2094
	}
2095
2096
	if (server_tls_load_ocsp(dst) == -1) {
2097
		yyerror("failed to load ocsp staple "
2098
		    "for server %s", dst->srv_conf.name);
2099
		serverconfig_free(&dst->srv_conf);
2100
		free(dst);
2101
		return (NULL);
2102
	}
2103
2104
	/* Check if the new server already exists */
2105
	if (server_match(dst, 1) != NULL) {
2106
		yyerror("server \"%s\" defined twice",
2107
		    dst->srv_conf.name);
2108
		serverconfig_free(&dst->srv_conf);
2109
		free(dst);
2110
		return (NULL);
2111
	}
2112
2113
	/* Copy all the locations of the source server */
2114
	TAILQ_FOREACH(s, conf->sc_servers, srv_entry) {
2115
		if (!(s->srv_conf.flags & SRVFLAG_LOCATION &&
2116
		    s->srv_conf.parent_id == src->srv_conf.parent_id))
2117
			continue;
2118
2119
		if ((dstl = calloc(1, sizeof(*dstl))) == NULL)
2120
			fatal("out of memory");
2121
2122
		memcpy(&dstl->srv_conf, &s->srv_conf, sizeof(dstl->srv_conf));
2123
		strlcpy(dstl->srv_conf.name, alias->name,
2124
		    sizeof(dstl->srv_conf.name));
2125
2126
		/* Copy the new Id and listen address */
2127
		dstl->srv_conf.id = ++last_server_id;
2128
		dstl->srv_conf.parent_id = dst->srv_conf.id;
2129
		memcpy(&dstl->srv_conf.ss, &addr->ss,
2130
		    sizeof(dstl->srv_conf.ss));
2131
		dstl->srv_conf.port = addr->port;
2132
		dstl->srv_conf.prefixlen = addr->prefixlen;
2133
		dstl->srv_s = -1;
2134
2135
		DPRINTF("adding location \"%s\" for \"%s[%u]\"",
2136
		    dstl->srv_conf.location,
2137
		    dstl->srv_conf.name, dstl->srv_conf.id);
2138
2139
		TAILQ_INSERT_TAIL(conf->sc_servers, dstl, srv_entry);
2140
	}
2141
2142
	return (dst);
2143
}
2144
2145
int
2146
getservice(char *n)
2147
{
2148
	struct servent	*s;
2149
	const char	*errstr;
2150
	long long	 llval;
2151
2152
	llval = strtonum(n, 0, UINT16_MAX, &errstr);
2153
	if (errstr) {
2154
		s = getservbyname(n, "tcp");
2155
		if (s == NULL)
2156
			s = getservbyname(n, "udp");
2157
		if (s == NULL) {
2158
			yyerror("unknown port %s", n);
2159
			return (-1);
2160
		}
2161
		return (s->s_port);
2162
	}
2163
2164
	return (htons((unsigned short)llval));
2165
}
2166
2167
int
2168
is_if_in_group(const char *ifname, const char *groupname)
2169
{
2170
	unsigned int		 len;
2171
	struct ifgroupreq	 ifgr;
2172
	struct ifg_req		*ifg;
2173
	int			 s;
2174
	int			 ret = 0;
2175
2176
	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
2177
		err(1, "socket");
2178
2179
	memset(&ifgr, 0, sizeof(ifgr));
2180
	if (strlcpy(ifgr.ifgr_name, ifname, IFNAMSIZ) >= IFNAMSIZ)
2181
		err(1, "IFNAMSIZ");
2182
	if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1) {
2183
		if (errno == EINVAL || errno == ENOTTY)
2184
			goto end;
2185
		err(1, "SIOCGIFGROUP");
2186
	}
2187
2188
	len = ifgr.ifgr_len;
2189
	ifgr.ifgr_groups = calloc(len / sizeof(struct ifg_req),
2190
	    sizeof(struct ifg_req));
2191
	if (ifgr.ifgr_groups == NULL)
2192
		err(1, "getifgroups");
2193
	if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1)
2194
		err(1, "SIOCGIFGROUP");
2195
2196
	ifg = ifgr.ifgr_groups;
2197
	for (; ifg && len >= sizeof(struct ifg_req); ifg++) {
2198
		len -= sizeof(struct ifg_req);
2199
		if (strcmp(ifg->ifgrq_group, groupname) == 0) {
2200
			ret = 1;
2201
			break;
2202
		}
2203
	}
2204
	free(ifgr.ifgr_groups);
2205
2206
end:
2207
	close(s);
2208
	return (ret);
2209
}