GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/relayd/relayd.c Lines: 270 772 35.0 %
Date: 2017-11-13 Branches: 135 722 18.7 %

Line Branch Exec Source
1
/*	$OpenBSD: relayd.c,v 1.169 2017/05/31 04:14:34 jsg Exp $	*/
2
3
/*
4
 * Copyright (c) 2007 - 2016 Reyk Floeter <reyk@openbsd.org>
5
 * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org>
6
 *
7
 * Permission to use, copy, modify, and distribute this software for any
8
 * purpose with or without fee is hereby granted, provided that the above
9
 * copyright notice and this permission notice appear in all copies.
10
 *
11
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
 */
19
20
#include <sys/types.h>
21
#include <sys/queue.h>
22
#include <sys/socket.h>
23
#include <sys/wait.h>
24
#include <sys/resource.h>
25
26
#include <netinet/in.h>
27
#include <arpa/inet.h>
28
29
#include <signal.h>
30
#include <string.h>
31
#include <stdio.h>
32
#include <stdlib.h>
33
#include <fcntl.h>
34
#include <getopt.h>
35
#include <fnmatch.h>
36
#include <syslog.h>
37
#include <err.h>
38
#include <errno.h>
39
#include <event.h>
40
#include <unistd.h>
41
#include <ctype.h>
42
#include <pwd.h>
43
#include <sha1.h>
44
#include <md5.h>
45
46
#include <tls.h>
47
48
#include "relayd.h"
49
50
#define MAXIMUM(a, b)	(((a) > (b)) ? (a) : (b))
51
52
__dead void	 usage(void);
53
54
int		 parent_configure(struct relayd *);
55
void		 parent_configure_done(struct relayd *);
56
void		 parent_reload(struct relayd *, u_int, const char *);
57
void		 parent_sig_handler(int, short, void *);
58
void		 parent_shutdown(struct relayd *);
59
int		 parent_dispatch_pfe(int, struct privsep_proc *, struct imsg *);
60
int		 parent_dispatch_hce(int, struct privsep_proc *, struct imsg *);
61
int		 parent_dispatch_relay(int, struct privsep_proc *,
62
		    struct imsg *);
63
int		 parent_dispatch_ca(int, struct privsep_proc *,
64
		    struct imsg *);
65
int		 bindany(struct ctl_bindany *);
66
void		 parent_tls_ticket_rekey(int, short, void *);
67
68
struct relayd			*relayd_env;
69
70
static struct privsep_proc procs[] = {
71
	{ "pfe",	PROC_PFE, parent_dispatch_pfe, pfe },
72
	{ "hce",	PROC_HCE, parent_dispatch_hce, hce },
73
	{ "relay",	PROC_RELAY, parent_dispatch_relay, relay },
74
	{ "ca",		PROC_CA, parent_dispatch_ca, ca }
75
};
76
77
void
78
parent_sig_handler(int sig, short event, void *arg)
79
{
80
1096
	struct privsep	*ps = arg;
81
82

548
	switch (sig) {
83
	case SIGTERM:
84
	case SIGINT:
85
548
		parent_shutdown(ps->ps_env);
86
548
		break;
87
	case SIGHUP:
88
		log_info("%s: reload requested with SIGHUP", __func__);
89
90
		/*
91
		 * This is safe because libevent uses async signal handlers
92
		 * that run in the event loop and not in signal context.
93
		 */
94
		parent_reload(ps->ps_env, CONFIG_RELOAD, NULL);
95
		break;
96
	case SIGPIPE:
97
	case SIGUSR1:
98
		/* ignore */
99
		break;
100
	default:
101
		fatalx("unexpected signal");
102
	}
103
}
104
105
__dead void
106
usage(void)
107
{
108
	extern char	*__progname;
109
110
	fprintf(stderr, "usage: %s [-dnv] [-D macro=value] [-f file]\n",
111
	    __progname);
112
	exit(1);
113
}
114
115
int
116
main(int argc, char *argv[])
117
{
118
	int			 c;
119
	int			 debug = 0, verbose = 0;
120
	u_int32_t		 opts = 0;
121
	struct relayd		*env;
122
	struct privsep		*ps;
123
	const char		*conffile = CONF_FILE;
124
	enum privsep_procid	 proc_id = PROC_PARENT;
125
	int			 proc_instance = 0;
126
1112
	const char		*errp, *title = NULL;
127
	int			 argc0 = argc;
128
129
5560
	while ((c = getopt(argc, argv, "dD:nI:P:f:v")) != -1) {
130


2224
		switch (c) {
131
		case 'd':
132
			debug = 2;
133
556
			break;
134
		case 'D':
135
			if (cmdline_symset(optarg) < 0)
136
				log_warnx("could not parse macro definition %s",
137
				    optarg);
138
			break;
139
		case 'n':
140
			debug = 2;
141
			opts |= RELAYD_OPT_NOACTION;
142
			break;
143
		case 'f':
144
556
			conffile = optarg;
145
556
			break;
146
		case 'v':
147
1112
			verbose++;
148
1112
			opts |= RELAYD_OPT_VERBOSE;
149
1112
			break;
150
		case 'P':
151
			title = optarg;
152
			proc_id = proc_getid(procs, nitems(procs), title);
153
			if (proc_id == PROC_MAX)
154
				fatalx("invalid process name");
155
			break;
156
		case 'I':
157
			proc_instance = strtonum(optarg, 0,
158
			    PROC_MAX_INSTANCES, &errp);
159
			if (errp)
160
				fatalx("invalid process instance");
161
			break;
162
		default:
163
			usage();
164
		}
165
	}
166
167
	/* log to stderr until daemonized */
168
556
	log_init(debug ? debug : 1, LOG_DAEMON);
169
170
556
	argc -= optind;
171
556
	if (argc > 0)
172
		usage();
173
174

1112
	if ((env = calloc(1, sizeof(*env))) == NULL ||
175
556
	    (ps = calloc(1, sizeof(*ps))) == NULL)
176
		exit(1);
177
178
556
	relayd_env = env;
179
556
	env->sc_ps = ps;
180
556
	ps->ps_env = env;
181
556
	TAILQ_INIT(&ps->ps_rcsocks);
182
556
	env->sc_conffile = conffile;
183
556
	env->sc_conf.opts = opts;
184
556
	TAILQ_INIT(&env->sc_hosts);
185
556
	TAILQ_INIT(&env->sc_sessions);
186
556
	env->sc_rtable = getrtable();
187
	/* initialize the TLS session id to a random key for all relay procs */
188
556
	arc4random_buf(env->sc_conf.tls_sid, sizeof(env->sc_conf.tls_sid));
189
190
556
	if (parse_config(env->sc_conffile, env) == -1)
191
		exit(1);
192
193
548
	if (debug)
194
548
		env->sc_conf.opts |= RELAYD_OPT_LOGUPDATE;
195
196
548
	if (geteuid())
197
		errx(1, "need root privileges");
198
199
548
	if ((ps->ps_pw =  getpwnam(RELAYD_USER)) == NULL)
200
		errx(1, "unknown user %s", RELAYD_USER);
201
202
	/* Configure the control socket */
203
548
	ps->ps_csock.cs_name = RELAYD_SOCKET;
204
205
548
	log_init(debug, LOG_DAEMON);
206
548
	log_setverbose(verbose);
207
208
548
	if (env->sc_conf.opts & RELAYD_OPT_NOACTION)
209
		ps->ps_noaction = 1;
210
211
548
	ps->ps_instances[PROC_RELAY] = env->sc_conf.prefork_relay;
212
548
	ps->ps_instances[PROC_CA] = env->sc_conf.prefork_relay;
213
548
	ps->ps_instance = proc_instance;
214
548
	if (title != NULL)
215
		ps->ps_title[proc_id] = title;
216
217
	/* only the parent returns */
218
548
	proc_init(ps, procs, nitems(procs), argc0, argv, proc_id);
219
220
548
	log_procinit("parent");
221

548
	if (!debug && daemon(1, 0) == -1)
222
		err(1, "failed to daemonize");
223
224
548
	if (ps->ps_noaction == 0)
225
548
		log_info("startup");
226
227
548
	event_init();
228
229
548
	signal_set(&ps->ps_evsigint, SIGINT, parent_sig_handler, ps);
230
548
	signal_set(&ps->ps_evsigterm, SIGTERM, parent_sig_handler, ps);
231
548
	signal_set(&ps->ps_evsighup, SIGHUP, parent_sig_handler, ps);
232
548
	signal_set(&ps->ps_evsigpipe, SIGPIPE, parent_sig_handler, ps);
233
548
	signal_set(&ps->ps_evsigusr1, SIGUSR1, parent_sig_handler, ps);
234
235
548
	signal_add(&ps->ps_evsigint, NULL);
236
548
	signal_add(&ps->ps_evsigterm, NULL);
237
548
	signal_add(&ps->ps_evsighup, NULL);
238
548
	signal_add(&ps->ps_evsigpipe, NULL);
239
548
	signal_add(&ps->ps_evsigusr1, NULL);
240
241
548
	proc_connect(ps);
242
243
548
	relay_http(NULL);
244
548
	if (load_config(env->sc_conffile, env) == -1) {
245
		proc_kill(env->sc_ps);
246
		exit(1);
247
	}
248
249
548
	if (env->sc_conf.opts & RELAYD_OPT_NOACTION) {
250
		fprintf(stderr, "configuration OK\n");
251
		proc_kill(env->sc_ps);
252
		exit(0);
253
	}
254
255
548
	if (env->sc_conf.flags & (F_TLS|F_TLSCLIENT))
256
140
		ssl_init(env);
257
258
	/* rekey the TLS tickets before pushing the config */
259
548
	parent_tls_ticket_rekey(0, 0, env);
260
548
	if (parent_configure(env) == -1)
261
		fatalx("configuration failed");
262
263
548
	init_routes(env);
264
265
548
	event_dispatch();
266
267
548
	parent_shutdown(env);
268
	/* NOTREACHED */
269
270
548
	return (0);
271
548
}
272
273
int
274
parent_configure(struct relayd *env)
275
{
276
	struct table		*tb;
277
	struct rdr		*rdr;
278
	struct router		*rt;
279
	struct protocol		*proto;
280
	struct relay		*rlay;
281
	int			 id;
282
	int			 ret = -1;
283
284
1660
	TAILQ_FOREACH(tb, env->sc_tables, entry)
285
8
		config_settable(env, tb);
286
1096
	TAILQ_FOREACH(rdr, env->sc_rdrs, entry)
287
		config_setrdr(env, rdr);
288
1096
	TAILQ_FOREACH(rt, env->sc_rts, rt_entry)
289
		config_setrt(env, rt);
290
2192
	TAILQ_FOREACH(proto, env->sc_protos, entry)
291
548
		config_setproto(env, proto);
292
2192
	TAILQ_FOREACH(proto, env->sc_protos, entry)
293
548
		config_setrule(env, proto);
294
2192
	TAILQ_FOREACH(rlay, env->sc_relays, rl_entry) {
295
		/* Check for TLS Inspection */
296
564
		if ((rlay->rl_conf.flags & (F_TLS|F_TLSCLIENT)) ==
297
548
		    (F_TLS|F_TLSCLIENT) &&
298
124
		    rlay->rl_conf.tls_cacert_len &&
299
16
		    rlay->rl_conf.tls_cakey_len)
300
16
			rlay->rl_conf.flags |= F_TLSINSPECT;
301
302
548
		config_setrelay(env, rlay);
303
	}
304
305
	/* HCE, PFE, CA and the relays need to reload their config. */
306
548
	env->sc_reload = 2 + (2 * env->sc_conf.prefork_relay);
307
308
6576
	for (id = 0; id < PROC_MAX; id++) {
309
2740
		if (id == privsep_process)
310
			continue;
311
4384
		proc_compose_imsg(env->sc_ps, id, -1, IMSG_CFG_DONE, -1,
312
2192
		    -1, &env->sc_conf, sizeof(env->sc_conf));
313
2192
	}
314
315
	ret = 0;
316
317
548
	config_purge(env, CONFIG_ALL & ~CONFIG_RELAYS);
318
548
	return (ret);
319
}
320
321
void
322
parent_reload(struct relayd *env, u_int reset, const char *filename)
323
{
324
	if (env->sc_reload) {
325
		log_debug("%s: already in progress: %d pending",
326
		    __func__, env->sc_reload);
327
		return;
328
	}
329
330
	/* Switch back to the default config file */
331
	if (filename == NULL || *filename == '\0')
332
		filename = env->sc_conffile;
333
334
	log_debug("%s: level %d config file %s", __func__, reset, filename);
335
336
	config_purge(env, CONFIG_ALL);
337
338
	if (reset == CONFIG_RELOAD) {
339
		if (load_config(filename, env) == -1) {
340
			log_debug("%s: failed to load config file %s",
341
			    __func__, filename);
342
		}
343
344
		config_setreset(env, CONFIG_ALL);
345
346
		if (parent_configure(env) == -1) {
347
			log_debug("%s: failed to commit config from %s",
348
			    __func__, filename);
349
		}
350
	} else
351
		config_setreset(env, reset);
352
}
353
354
void
355
parent_configure_done(struct relayd *env)
356
{
357
	int	 id;
358
359
4384
	if (env->sc_reload == 0) {
360
		log_warnx("%s: configuration already finished", __func__);
361
		return;
362
	}
363
364
2192
	env->sc_reload--;
365
2192
	if (env->sc_reload == 0) {
366
6576
		for (id = 0; id < PROC_MAX; id++) {
367
2740
			if (id == privsep_process)
368
				continue;
369
370
2192
			proc_compose(env->sc_ps, id, IMSG_CTL_START, NULL, 0);
371
2192
		}
372
	}
373
4384
}
374
375
void
376
parent_shutdown(struct relayd *env)
377
{
378
548
	config_purge(env, CONFIG_ALL);
379
380
	proc_kill(env->sc_ps);
381
	control_cleanup(&env->sc_ps->ps_csock);
382
	(void)unlink(env->sc_ps->ps_csock.cs_name);
383
	carp_demote_shutdown();
384
385
	free(env->sc_ps);
386
	free(env);
387
388
	log_info("parent terminating, pid %d", getpid());
389
390
	exit(0);
391
}
392
393
int
394
parent_dispatch_pfe(int fd, struct privsep_proc *p, struct imsg *imsg)
395
{
396
1096
	struct privsep		*ps = p->p_ps;
397
548
	struct relayd		*env = ps->ps_env;
398
548
	struct ctl_demote	 demote;
399
548
	struct ctl_netroute	 crt;
400
	u_int			 v;
401
	char			*str = NULL;
402
403


548
	switch (imsg->hdr.type) {
404
	case IMSG_DEMOTE:
405
		IMSG_SIZE_CHECK(imsg, &demote);
406
		memcpy(&demote, imsg->data, sizeof(demote));
407
		carp_demote_set(demote.group, demote.level);
408
		break;
409
	case IMSG_RTMSG:
410
		IMSG_SIZE_CHECK(imsg, &crt);
411
		memcpy(&crt, imsg->data, sizeof(crt));
412
		pfe_route(env, &crt);
413
		break;
414
	case IMSG_CTL_RESET:
415
		IMSG_SIZE_CHECK(imsg, &v);
416
		memcpy(&v, imsg->data, sizeof(v));
417
		parent_reload(env, v, NULL);
418
		break;
419
	case IMSG_CTL_RELOAD:
420
		if (IMSG_DATA_SIZE(imsg) > 0)
421
			str = get_string(imsg->data, IMSG_DATA_SIZE(imsg));
422
		parent_reload(env, CONFIG_RELOAD, str);
423
		free(str);
424
		break;
425
	case IMSG_CTL_SHUTDOWN:
426
		parent_shutdown(env);
427
		break;
428
	case IMSG_CFG_DONE:
429
548
		parent_configure_done(env);
430
548
		break;
431
	case IMSG_SNMPSOCK:
432
		(void)snmp_setsock(env, p->p_id);
433
		break;
434
	default:
435
		return (-1);
436
	}
437
438
548
	return (0);
439
548
}
440
441
int
442
parent_dispatch_hce(int fd, struct privsep_proc *p, struct imsg *imsg)
443
{
444
1096
	struct privsep		*ps = p->p_ps;
445
548
	struct relayd		*env = ps->ps_env;
446
548
	struct ctl_script	 scr;
447
448
548
	switch (imsg->hdr.type) {
449
	case IMSG_SCRIPT:
450
		IMSG_SIZE_CHECK(imsg, &scr);
451
		bcopy(imsg->data, &scr, sizeof(scr));
452
		scr.retval = script_exec(env, &scr);
453
		proc_compose(ps, PROC_HCE, IMSG_SCRIPT, &scr, sizeof(scr));
454
		break;
455
	case IMSG_CFG_DONE:
456
548
		parent_configure_done(env);
457
548
		break;
458
	default:
459
		return (-1);
460
	}
461
462
548
	return (0);
463
548
}
464
465
int
466
parent_dispatch_relay(int fd, struct privsep_proc *p, struct imsg *imsg)
467
{
468
1096
	struct privsep		*ps = p->p_ps;
469
548
	struct relayd		*env = ps->ps_env;
470
548
	struct ctl_bindany	 bnd;
471
	int			 s;
472
473
548
	switch (imsg->hdr.type) {
474
	case IMSG_BINDANY:
475
		IMSG_SIZE_CHECK(imsg, &bnd);
476
		bcopy(imsg->data, &bnd, sizeof(bnd));
477
		if (bnd.bnd_proc > env->sc_conf.prefork_relay)
478
			fatalx("%s: invalid relay proc", __func__);
479
		switch (bnd.bnd_proto) {
480
		case IPPROTO_TCP:
481
		case IPPROTO_UDP:
482
			break;
483
		default:
484
			fatalx("%s: requested socket "
485
			    "for invalid protocol", __func__);
486
			/* NOTREACHED */
487
		}
488
		s = bindany(&bnd);
489
		proc_compose_imsg(ps, PROC_RELAY, bnd.bnd_proc,
490
		    IMSG_BINDANY, -1, s, &bnd.bnd_id, sizeof(bnd.bnd_id));
491
		break;
492
	case IMSG_CFG_DONE:
493
548
		parent_configure_done(env);
494
548
		break;
495
	default:
496
		return (-1);
497
	}
498
499
548
	return (0);
500
548
}
501
502
int
503
parent_dispatch_ca(int fd, struct privsep_proc *p, struct imsg *imsg)
504
{
505
1096
	struct privsep		*ps = p->p_ps;
506
548
	struct relayd		*env = ps->ps_env;
507
508
548
	switch (imsg->hdr.type) {
509
	case IMSG_CFG_DONE:
510
548
		parent_configure_done(env);
511
		break;
512
	default:
513
		return (-1);
514
	}
515
516
548
	return (0);
517
548
}
518
519
void
520
purge_table(struct relayd *env, struct tablelist *head, struct table *table)
521
{
522
	struct host		*host;
523
524
40
	while ((host = TAILQ_FIRST(&table->hosts)) != NULL) {
525
24
		TAILQ_REMOVE(&table->hosts, host, entry);
526
24
		TAILQ_REMOVE(&env->sc_hosts, host, globalentry);
527
8
		if (event_initialized(&host->cte.ev)) {
528
			event_del(&host->cte.ev);
529
			close(host->cte.s);
530
		}
531
8
		ibuf_free(host->cte.buf);
532
8
		tls_free(host->cte.tls);
533
8
		free(host);
534
	}
535
8
	free(table->sendbuf);
536
8
	tls_config_free(table->tls_cfg);
537
538
8
	if (head != NULL)
539
24
		TAILQ_REMOVE(head, table, entry);
540
8
	free(table);
541
8
}
542
543
void
544
purge_key(char **key, off_t len)
545
{
546
4384
	freezero(*key, len);
547
548
2192
	*key = NULL;
549
2192
}
550
551
void
552
purge_relay(struct relayd *env, struct relay *rlay)
553
{
554
	struct rsession		*con;
555
	struct relay_table	*rlt;
556
557
	/* shutdown and remove relay */
558
1096
	if (event_initialized(&rlay->rl_ev))
559
		event_del(&rlay->rl_ev);
560
548
	close(rlay->rl_s);
561
1644
	TAILQ_REMOVE(env->sc_relays, rlay, rl_entry);
562
563
	/* cleanup sessions */
564
1096
	while ((con =
565
548
	    SPLAY_ROOT(&rlay->rl_sessions)) != NULL)
566
		relay_close(con, NULL);
567
568
	/* cleanup relay */
569
548
	if (rlay->rl_bev != NULL)
570
		bufferevent_free(rlay->rl_bev);
571
548
	if (rlay->rl_dstbev != NULL)
572
		bufferevent_free(rlay->rl_dstbev);
573
574
548
	purge_key(&rlay->rl_tls_cert, rlay->rl_conf.tls_cert_len);
575
548
	purge_key(&rlay->rl_tls_key, rlay->rl_conf.tls_key_len);
576
548
	purge_key(&rlay->rl_tls_ca, rlay->rl_conf.tls_ca_len);
577
548
	purge_key(&rlay->rl_tls_cakey, rlay->rl_conf.tls_cakey_len);
578
579
548
	if (rlay->rl_tls_pkey != NULL) {
580
		EVP_PKEY_free(rlay->rl_tls_pkey);
581
		rlay->rl_tls_pkey = NULL;
582
	}
583
548
	if (rlay->rl_tls_cacertx509 != NULL) {
584
		X509_free(rlay->rl_tls_cacertx509);
585
		rlay->rl_tls_cacertx509 = NULL;
586
	}
587
548
	if (rlay->rl_tls_capkey != NULL) {
588
		EVP_PKEY_free(rlay->rl_tls_capkey);
589
		rlay->rl_tls_capkey = NULL;
590
	}
591
592
548
	tls_free(rlay->rl_tls_ctx);
593
548
	tls_config_free(rlay->rl_tls_cfg);
594
548
	tls_config_free(rlay->rl_tls_client_cfg);
595
596
1112
	while ((rlt = TAILQ_FIRST(&rlay->rl_tables))) {
597
24
		TAILQ_REMOVE(&rlay->rl_tables, rlt, rlt_entry);
598
8
		free(rlt);
599
	}
600
601
548
	free(rlay);
602
548
}
603
604
struct kv *
605
kv_add(struct kvtree *keys, char *key, char *value, int unique)
606
{
607
	struct kv	*kv, *oldkv;
608
609
	if (key == NULL)
610
		return (NULL);
611
	if ((kv = calloc(1, sizeof(*kv))) == NULL)
612
		return (NULL);
613
	if ((kv->kv_key = strdup(key)) == NULL)
614
		goto fail;
615
	if (value != NULL &&
616
	    (kv->kv_value = strdup(value)) == NULL)
617
		goto fail;
618
	TAILQ_INIT(&kv->kv_children);
619
620
	if ((oldkv = RB_INSERT(kvtree, keys, kv)) != NULL) {
621
		/*
622
		 * return error if the key should occur only once,
623
		 * or add it to a list attached to the key's node.
624
		 */
625
		if (unique)
626
			goto fail;
627
		TAILQ_INSERT_TAIL(&oldkv->kv_children, kv, kv_entry);
628
		kv->kv_parent = oldkv;
629
	}
630
631
	return (kv);
632
 fail:
633
	free(kv->kv_key);
634
	free(kv->kv_value);
635
	free(kv);
636
	return (NULL);
637
}
638
639
int
640
kv_set(struct kv *kv, char *fmt, ...)
641
{
642
	va_list		  ap;
643
	char		*value = NULL;
644
	struct kv	*ckv;
645
646
	va_start(ap, fmt);
647
	if (vasprintf(&value, fmt, ap) == -1)
648
		return (-1);
649
	va_end(ap);
650
651
	/* Remove all children */
652
	while ((ckv = TAILQ_FIRST(&kv->kv_children)) != NULL) {
653
		TAILQ_REMOVE(&kv->kv_children, ckv, kv_entry);
654
		kv_free(ckv);
655
		free(ckv);
656
	}
657
658
	/* Set the new value */
659
	free(kv->kv_value);
660
	kv->kv_value = value;
661
662
	return (0);
663
}
664
665
int
666
kv_setkey(struct kv *kv, char *fmt, ...)
667
{
668
	va_list  ap;
669
	char	*key = NULL;
670
671
	va_start(ap, fmt);
672
	if (vasprintf(&key, fmt, ap) == -1)
673
		return (-1);
674
	va_end(ap);
675
676
	free(kv->kv_key);
677
	kv->kv_key = key;
678
679
	return (0);
680
}
681
682
void
683
kv_delete(struct kvtree *keys, struct kv *kv)
684
{
685
	struct kv	*ckv;
686
687
	RB_REMOVE(kvtree, keys, kv);
688
689
	/* Remove all children */
690
	while ((ckv = TAILQ_FIRST(&kv->kv_children)) != NULL) {
691
		TAILQ_REMOVE(&kv->kv_children, ckv, kv_entry);
692
		kv_free(ckv);
693
		free(ckv);
694
	}
695
696
	kv_free(kv);
697
	free(kv);
698
}
699
700
struct kv *
701
kv_extend(struct kvtree *keys, struct kv *kv, char *value)
702
{
703
	char		*newvalue;
704
705
	if (kv == NULL) {
706
		return (NULL);
707
	} else if (kv->kv_value != NULL) {
708
		if (asprintf(&newvalue, "%s%s", kv->kv_value, value) == -1)
709
			return (NULL);
710
711
		free(kv->kv_value);
712
		kv->kv_value = newvalue;
713
	} else if ((kv->kv_value = strdup(value)) == NULL)
714
		return (NULL);
715
716
	return (kv);
717
}
718
719
void
720
kv_purge(struct kvtree *keys)
721
{
722
	struct kv	*kv;
723
724
	while ((kv = RB_MIN(kvtree, keys)) != NULL)
725
		kv_delete(keys, kv);
726
}
727
728
void
729
kv_free(struct kv *kv)
730
{
731
	/*
732
	 * This function does not clear memory referenced by
733
	 * kv_children or stuff on the tailqs. Use kv_delete() instead.
734
	 */
735
736
9840
	free(kv->kv_key);
737
4920
	free(kv->kv_value);
738
4920
	memset(kv, 0, sizeof(*kv));
739
4920
}
740
741
struct kv *
742
kv_inherit(struct kv *dst, struct kv *src)
743
{
744
64
	memset(dst, 0, sizeof(*dst));
745
32
	memcpy(dst, src, sizeof(*dst));
746
32
	TAILQ_INIT(&dst->kv_children);
747
748
32
	if (src->kv_key != NULL) {
749
		if ((dst->kv_key = strdup(src->kv_key)) == NULL) {
750
			kv_free(dst);
751
			return (NULL);
752
		}
753
	}
754
32
	if (src->kv_value != NULL) {
755
16
		if ((dst->kv_value = strdup(src->kv_value)) == NULL) {
756
			kv_free(dst);
757
			return (NULL);
758
		}
759
	}
760
761
32
	if (src->kv_match != NULL)
762
		dst->kv_match = src->kv_match;
763
32
	if (src->kv_matchtree != NULL)
764
		dst->kv_matchtree = src->kv_matchtree;
765
766
32
	return (dst);
767
32
}
768
769
int
770
kv_log(struct rsession *con, struct kv *kv, u_int16_t labelid,
771
    enum direction dir)
772
{
773
	char	*msg;
774
775
	if (con->se_log == NULL)
776
		return (0);
777
	if (asprintf(&msg, " %s%s%s%s%s%s%s",
778
	    dir == RELAY_DIR_REQUEST ? "[" : "{",
779
	    labelid == 0 ? "" : label_id2name(labelid),
780
	    labelid == 0 ? "" : ", ",
781
	    kv->kv_key == NULL ? "(unknown)" : kv->kv_key,
782
	    kv->kv_value == NULL ? "" : ": ",
783
	    kv->kv_value == NULL ? "" : kv->kv_value,
784
	    dir == RELAY_DIR_REQUEST ? "]" : "}") == -1)
785
		return (-1);
786
	if (evbuffer_add(con->se_log, msg, strlen(msg)) == -1) {
787
		free(msg);
788
		return (-1);
789
	}
790
	free(msg);
791
	con->se_haslog = 1;
792
	return (0);
793
}
794
795
struct kv *
796
kv_find(struct kvtree *keys, struct kv *kv)
797
{
798
	struct kv	*match;
799
	const char	*key;
800
801
	if (kv->kv_flags & KV_FLAG_GLOBBING) {
802
		/* Test header key using shell globbing rules */
803
		key = kv->kv_key == NULL ? "" : kv->kv_key;
804
		RB_FOREACH(match, kvtree, keys) {
805
			if (fnmatch(key, match->kv_key, FNM_CASEFOLD) == 0)
806
				break;
807
		}
808
	} else {
809
		/* Fast tree-based lookup only works without globbing */
810
		match = RB_FIND(kvtree, keys, kv);
811
	}
812
813
	return (match);
814
}
815
816
int
817
kv_cmp(struct kv *a, struct kv *b)
818
{
819
	return (strcasecmp(a->kv_key, b->kv_key));
820
}
821
822
RB_GENERATE(kvtree, kv, kv_node, kv_cmp);
823
824
int
825
rule_add(struct protocol *proto, struct relay_rule *rule, const char *rulefile)
826
{
827
	struct relay_rule	*r = NULL;
828
	struct kv		*kv = NULL;
829
	FILE			*fp = NULL;
830
1608
	char			 buf[BUFSIZ];
831
	int			 ret = -1;
832
	u_int			 i;
833
834
11256
	for (i = 0; i < KEY_TYPE_MAX; i++) {
835
4824
		kv = &rule->rule_kv[i];
836
4824
		if (kv->kv_type != i)
837
			continue;
838
839
1544
		switch (kv->kv_option) {
840
		case KEY_OPTION_LOG:
841
			/* log action needs a key or a file to be specified */
842

556
			if (kv->kv_key == NULL && rulefile == NULL &&
843
24
			    (kv->kv_key = strdup("*")) == NULL)
844
				goto fail;
845
			break;
846
		default:
847
			break;
848
		}
849
850
1544
		switch (kv->kv_type) {
851
		case KEY_TYPE_QUERY:
852
		case KEY_TYPE_PATH:
853
		case KEY_TYPE_URL:
854
208
			if (rule->rule_dir != RELAY_DIR_REQUEST)
855
				goto fail;
856
			break;
857
		default:
858
			break;
859
		}
860
861

2260
		if (kv->kv_value != NULL && strchr(kv->kv_value, '$') != NULL)
862
16
			kv->kv_flags |= KV_FLAG_MACRO;
863

2276
		if (kv->kv_key != NULL && strpbrk(kv->kv_key, "*?[") != NULL)
864
96
			kv->kv_flags |= KV_FLAG_GLOBBING;
865
	}
866
867
804
	if (rulefile == NULL) {
868
796
		TAILQ_INSERT_TAIL(&proto->rules, rule, rule_entry);
869
796
		return (0);
870
	}
871
872
8
	if ((fp = fopen(rulefile, "r")) == NULL)
873
		goto fail;
874
875
48
	while (fgets(buf, sizeof(buf), fp) != NULL) {
876
		/* strip whitespace and newline characters */
877
16
		buf[strcspn(buf, "\r\n\t ")] = '\0';
878

32
		if (!strlen(buf) || buf[0] == '#')
879
			continue;
880
881
16
		if ((r = rule_inherit(rule)) == NULL)
882
			goto fail;
883
884
224
		for (i = 0; i < KEY_TYPE_MAX; i++) {
885
96
			kv = &r->rule_kv[i];
886
96
			if (kv->kv_type != i)
887
				continue;
888
32
			free(kv->kv_key);
889
32
			if ((kv->kv_key = strdup(buf)) == NULL) {
890
				rule_free(r);
891
				free(r);
892
				goto fail;
893
			}
894
		}
895
896
16
		TAILQ_INSERT_TAIL(&proto->rules, r, rule_entry);
897
	}
898
899
	ret = 0;
900
8
	rule_free(rule);
901
8
	free(rule);
902
903
 fail:
904
8
	if (fp != NULL)
905
8
		fclose(fp);
906
8
	return (ret);
907
804
}
908
909
struct relay_rule *
910
rule_inherit(struct relay_rule *rule)
911
{
912
	struct relay_rule	*r;
913
	u_int			 i;
914
	struct kv		*kv;
915
916
32
	if ((r = calloc(1, sizeof(*r))) == NULL)
917
		return (NULL);
918
16
	memcpy(r, rule, sizeof(*r));
919
920
224
	for (i = 0; i < KEY_TYPE_MAX; i++) {
921
96
		kv = &rule->rule_kv[i];
922
96
		if (kv->kv_type != i)
923
			continue;
924
32
		if (kv_inherit(&r->rule_kv[i], kv) == NULL) {
925
			free(r);
926
			return (NULL);
927
		}
928
	}
929
930
16
	if (r->rule_label > 0)
931
16
		label_ref(r->rule_label);
932
16
	if (r->rule_tag > 0)
933
		tag_ref(r->rule_tag);
934
16
	if (r->rule_tagged > 0)
935
		tag_ref(r->rule_tagged);
936
937
16
	return (r);
938
16
}
939
940
void
941
rule_free(struct relay_rule *rule)
942
{
943
	u_int	i;
944
945
12300
	for (i = 0; i < KEY_TYPE_MAX; i++)
946
4920
		kv_free(&rule->rule_kv[i]);
947
820
	if (rule->rule_label > 0)
948
40
		label_unref(rule->rule_label);
949
820
	if (rule->rule_tag > 0)
950
48
		tag_unref(rule->rule_tag);
951
820
	if (rule->rule_tagged > 0)
952
40
		tag_unref(rule->rule_tagged);
953
820
}
954
955
void
956
rule_delete(struct relay_rules *rules, struct relay_rule *rule)
957
{
958
3248
	TAILQ_REMOVE(rules, rule, rule_entry);
959
812
	rule_free(rule);
960
812
	free(rule);
961
812
}
962
963
void
964
rule_settable(struct relay_rules *rules, struct relay_table *rlt)
965
{
966
	struct relay_rule	*r;
967
	char			 pname[TABLE_NAME_SIZE];
968
969
	if (rlt->rlt_table == NULL || strlcpy(pname, rlt->rlt_table->conf.name,
970
	    sizeof(pname)) >= sizeof(pname))
971
		return;
972
973
	pname[strcspn(pname, ":")] = '\0';
974
975
	TAILQ_FOREACH(r, rules, rule_entry) {
976
		if (r->rule_tablename[0] &&
977
		    strcmp(pname, r->rule_tablename) == 0)
978
			r->rule_table = rlt;
979
	}
980
}
981
982
/*
983
 * Utility functions
984
 */
985
986
struct host *
987
host_find(struct relayd *env, objid_t id)
988
{
989
	struct table	*table;
990
	struct host	*host;
991
992
	TAILQ_FOREACH(table, env->sc_tables, entry)
993
		TAILQ_FOREACH(host, &table->hosts, entry)
994
			if (host->conf.id == id)
995
				return (host);
996
	return (NULL);
997
}
998
999
struct table *
1000
table_find(struct relayd *env, objid_t id)
1001
{
1002
	struct table	*table;
1003
1004
	TAILQ_FOREACH(table, env->sc_tables, entry)
1005
		if (table->conf.id == id)
1006
			return (table);
1007
	return (NULL);
1008
}
1009
1010
struct rdr *
1011
rdr_find(struct relayd *env, objid_t id)
1012
{
1013
	struct rdr	*rdr;
1014
1015
	TAILQ_FOREACH(rdr, env->sc_rdrs, entry)
1016
		if (rdr->conf.id == id)
1017
			return (rdr);
1018
	return (NULL);
1019
}
1020
1021
struct relay *
1022
relay_find(struct relayd *env, objid_t id)
1023
{
1024
	struct relay	*rlay;
1025
1026
	TAILQ_FOREACH(rlay, env->sc_relays, rl_entry)
1027
		if (rlay->rl_conf.id == id)
1028
			return (rlay);
1029
	return (NULL);
1030
}
1031
1032
struct protocol *
1033
proto_find(struct relayd *env, objid_t id)
1034
{
1035
	struct protocol	*p;
1036
1037
	TAILQ_FOREACH(p, env->sc_protos, entry)
1038
		if (p->id == id)
1039
			return (p);
1040
	return (NULL);
1041
}
1042
1043
struct rsession *
1044
session_find(struct relayd *env, objid_t id)
1045
{
1046
	struct relay		*rlay;
1047
	struct rsession		*con;
1048
1049
	TAILQ_FOREACH(rlay, env->sc_relays, rl_entry)
1050
		SPLAY_FOREACH(con, session_tree, &rlay->rl_sessions)
1051
			if (con->se_id == id)
1052
				return (con);
1053
	return (NULL);
1054
}
1055
1056
struct netroute *
1057
route_find(struct relayd *env, objid_t id)
1058
{
1059
	struct netroute	*nr;
1060
1061
	TAILQ_FOREACH(nr, env->sc_routes, nr_route)
1062
		if (nr->nr_conf.id == id)
1063
			return (nr);
1064
	return (NULL);
1065
}
1066
1067
struct router *
1068
router_find(struct relayd *env, objid_t id)
1069
{
1070
	struct router	*rt;
1071
1072
	TAILQ_FOREACH(rt, env->sc_rts, rt_entry)
1073
		if (rt->rt_conf.id == id)
1074
			return (rt);
1075
	return (NULL);
1076
}
1077
1078
struct host *
1079
host_findbyname(struct relayd *env, const char *name)
1080
{
1081
	struct table	*table;
1082
	struct host	*host;
1083
1084
	TAILQ_FOREACH(table, env->sc_tables, entry)
1085
		TAILQ_FOREACH(host, &table->hosts, entry)
1086
			if (strcmp(host->conf.name, name) == 0)
1087
				return (host);
1088
	return (NULL);
1089
}
1090
1091
struct table *
1092
table_findbyname(struct relayd *env, const char *name)
1093
{
1094
	struct table	*table;
1095
1096
24
	TAILQ_FOREACH(table, env->sc_tables, entry)
1097
8
		if (strcmp(table->conf.name, name) == 0)
1098
8
			return (table);
1099
	return (NULL);
1100
8
}
1101
1102
struct table *
1103
table_findbyconf(struct relayd *env, struct table *tb)
1104
{
1105
	struct table		*table;
1106
16
	struct table_config	 a, b;
1107
1108
8
	bcopy(&tb->conf, &a, sizeof(a));
1109
8
	a.id = a.rdrid = 0;
1110
8
	a.flags &= ~(F_USED|F_BACKUP);
1111
1112
32
	TAILQ_FOREACH(table, env->sc_tables, entry) {
1113
8
		bcopy(&table->conf, &b, sizeof(b));
1114
8
		b.id = b.rdrid = 0;
1115
8
		b.flags &= ~(F_USED|F_BACKUP);
1116
1117
		/*
1118
		 * Compare two tables and return the existing table if
1119
		 * the configuration seems to be the same.
1120
		 */
1121

8
		if (bcmp(&a, &b, sizeof(b)) == 0 &&
1122
		    ((tb->sendbuf == NULL && table->sendbuf == NULL) ||
1123
		    (tb->sendbuf != NULL && table->sendbuf != NULL &&
1124
		    strcmp(tb->sendbuf, table->sendbuf) == 0)))
1125
			return (table);
1126
	}
1127
8
	return (NULL);
1128
8
}
1129
1130
struct rdr *
1131
rdr_findbyname(struct relayd *env, const char *name)
1132
{
1133
	struct rdr	*rdr;
1134
1135
	TAILQ_FOREACH(rdr, env->sc_rdrs, entry)
1136
		if (strcmp(rdr->conf.name, name) == 0)
1137
			return (rdr);
1138
	return (NULL);
1139
}
1140
1141
struct relay *
1142
relay_findbyname(struct relayd *env, const char *name)
1143
{
1144
	struct relay	*rlay;
1145
1146
	TAILQ_FOREACH(rlay, env->sc_relays, rl_entry)
1147
		if (strcmp(rlay->rl_conf.name, name) == 0)
1148
			return (rlay);
1149
	return (NULL);
1150
}
1151
1152
struct relay *
1153
relay_findbyaddr(struct relayd *env, struct relay_config *rc)
1154
{
1155
	struct relay	*rlay;
1156
1157
	TAILQ_FOREACH(rlay, env->sc_relays, rl_entry)
1158
		if (bcmp(&rlay->rl_conf.ss, &rc->ss, sizeof(rc->ss)) == 0 &&
1159
		    rlay->rl_conf.port == rc->port)
1160
			return (rlay);
1161
	return (NULL);
1162
}
1163
1164
EVP_PKEY *
1165
pkey_find(struct relayd *env, char * hash)
1166
{
1167
	struct ca_pkey	*pkey;
1168
1169
	TAILQ_FOREACH(pkey, env->sc_pkeys, pkey_entry)
1170
		if (strcmp(hash, pkey->pkey_hash) == 0)
1171
			return (pkey->pkey);
1172
	return (NULL);
1173
}
1174
1175
struct ca_pkey *
1176
pkey_add(struct relayd *env, EVP_PKEY *pkey, char *hash)
1177
{
1178
	struct ca_pkey	*ca_pkey;
1179
1180
	if (env->sc_pkeys == NULL)
1181
		fatalx("pkeys");
1182
1183
	if ((ca_pkey = calloc(1, sizeof(*ca_pkey))) == NULL)
1184
		return (NULL);
1185
1186
	ca_pkey->pkey = pkey;
1187
	if (strlcpy(ca_pkey->pkey_hash, hash, sizeof(ca_pkey->pkey_hash)) >=
1188
	    sizeof(ca_pkey->pkey_hash)) {
1189
		free(ca_pkey);
1190
		return (NULL);
1191
	}
1192
1193
	TAILQ_INSERT_TAIL(env->sc_pkeys, ca_pkey, pkey_entry);
1194
1195
	return (ca_pkey);
1196
}
1197
1198
void
1199
event_again(struct event *ev, int fd, short event,
1200
    void (*fn)(int, short, void *),
1201
    struct timeval *start, struct timeval *end, void *arg)
1202
{
1203
	struct timeval tv_next, tv_now, tv;
1204
1205
	getmonotime(&tv_now);
1206
	bcopy(end, &tv_next, sizeof(tv_next));
1207
	timersub(&tv_now, start, &tv_now);
1208
	timersub(&tv_next, &tv_now, &tv_next);
1209
1210
	bzero(&tv, sizeof(tv));
1211
	if (timercmp(&tv_next, &tv, >))
1212
		bcopy(&tv_next, &tv, sizeof(tv));
1213
1214
	event_del(ev);
1215
	event_set(ev, fd, event, fn, arg);
1216
	event_add(ev, &tv);
1217
}
1218
1219
int
1220
expand_string(char *label, size_t len, const char *srch, const char *repl)
1221
{
1222
	char *tmp;
1223
	char *p, *q;
1224
1225
	if ((tmp = calloc(1, len)) == NULL) {
1226
		log_debug("%s: calloc", __func__);
1227
		return (-1);
1228
	}
1229
	p = q = label;
1230
	while ((q = strstr(p, srch)) != NULL) {
1231
		*q = '\0';
1232
		if ((strlcat(tmp, p, len) >= len) ||
1233
		    (strlcat(tmp, repl, len) >= len)) {
1234
			log_debug("%s: string too long", __func__);
1235
			free(tmp);
1236
			return (-1);
1237
		}
1238
		q += strlen(srch);
1239
		p = q;
1240
	}
1241
	if (strlcat(tmp, p, len) >= len) {
1242
		log_debug("%s: string too long", __func__);
1243
		free(tmp);
1244
		return (-1);
1245
	}
1246
	(void)strlcpy(label, tmp, len);	/* always fits */
1247
	free(tmp);
1248
1249
	return (0);
1250
}
1251
1252
void
1253
translate_string(char *str)
1254
{
1255
	char	*reader;
1256
	char	*writer;
1257
1258
	reader = writer = str;
1259
1260
	while (*reader) {
1261
		if (*reader == '\\') {
1262
			reader++;
1263
			switch (*reader) {
1264
			case 'n':
1265
				*writer++ = '\n';
1266
				break;
1267
			case 'r':
1268
				*writer++ = '\r';
1269
				break;
1270
			default:
1271
				*writer++ = *reader;
1272
			}
1273
		} else
1274
			*writer++ = *reader;
1275
		reader++;
1276
	}
1277
	*writer = '\0';
1278
}
1279
1280
char *
1281
digeststr(enum digest_type type, const u_int8_t *data, size_t len, char *buf)
1282
{
1283
	switch (type) {
1284
	case DIGEST_SHA1:
1285
		return (SHA1Data(data, len, buf));
1286
		break;
1287
	case DIGEST_MD5:
1288
		return (MD5Data(data, len, buf));
1289
		break;
1290
	default:
1291
		break;
1292
	}
1293
	return (NULL);
1294
}
1295
1296
const char *
1297
canonicalize_host(const char *host, char *name, size_t len)
1298
{
1299
	struct sockaddr_in	 sin4;
1300
	struct sockaddr_in6	 sin6;
1301
	size_t			 i, j;
1302
	size_t			 plen;
1303
	char			 c;
1304
1305
	if (len < 2)
1306
		goto fail;
1307
1308
	/*
1309
	 * Canonicalize an IPv4/6 address
1310
	 */
1311
	if (inet_pton(AF_INET, host, &sin4) == 1)
1312
		return (inet_ntop(AF_INET, &sin4, name, len));
1313
	if (inet_pton(AF_INET6, host, &sin6) == 1)
1314
		return (inet_ntop(AF_INET6, &sin6, name, len));
1315
1316
	/*
1317
	 * Canonicalize a hostname
1318
	 */
1319
1320
	/* 1. remove repeated dots and convert upper case to lower case */
1321
	plen = strlen(host);
1322
	bzero(name, len);
1323
	for (i = j = 0; i < plen; i++) {
1324
		if (j >= (len - 1))
1325
			goto fail;
1326
		c = tolower((unsigned char)host[i]);
1327
		if ((c == '.') && (j == 0 || name[j - 1] == '.'))
1328
			continue;
1329
		name[j++] = c;
1330
	}
1331
1332
	/* 2. remove trailing dots */
1333
	for (i = j; i > 0; i--) {
1334
		if (name[i - 1] != '.')
1335
			break;
1336
		name[i - 1] = '\0';
1337
		j--;
1338
	}
1339
	if (j <= 0)
1340
		goto fail;
1341
1342
	return (name);
1343
1344
 fail:
1345
	errno = EINVAL;
1346
	return (NULL);
1347
}
1348
1349
int
1350
parse_url(const char *url, char **protoptr, char **hostptr, char **pathptr)
1351
{
1352
	char	*p, *proto = NULL, *host = NULL, *path = NULL;
1353
1354
	/* return error if it is not a URL */
1355
	if ((p = strstr(url, ":/")) == NULL ||
1356
	    (strcspn(url, ":/") != (size_t)(p - url)))
1357
		return (-1);
1358
1359
	/* get protocol */
1360
	if ((proto = strdup(url)) == NULL)
1361
		goto fail;
1362
	p = proto + (p - url);
1363
1364
	/* get host */
1365
	p += strspn(p, ":/");
1366
	if (*p == '\0' || (host = strdup(p)) == NULL)
1367
		goto fail;
1368
	*p = '\0';
1369
1370
	/* find and copy path or default to "/" */
1371
	if ((p = strchr(host, '/')) == NULL)
1372
		p = "/";
1373
	if ((path = strdup(p)) == NULL)
1374
		goto fail;
1375
1376
	/* strip path after host */
1377
	host[strcspn(host, "/")] = '\0';
1378
1379
	DPRINTF("%s: %s proto %s, host %s, path %s", __func__,
1380
	    url, proto, host, path);
1381
1382
	*protoptr = proto;
1383
	*hostptr = host;
1384
	*pathptr = path;
1385
1386
	return (0);
1387
1388
 fail:
1389
	free(proto);
1390
	free(host);
1391
	free(path);
1392
	return (-1);
1393
}
1394
1395
int
1396
bindany(struct ctl_bindany *bnd)
1397
{
1398
	int	s, v;
1399
1400
	s = -1;
1401
	v = 1;
1402
1403
	if (relay_socket_af(&bnd->bnd_ss, bnd->bnd_port) == -1)
1404
		goto fail;
1405
	if ((s = socket(bnd->bnd_ss.ss_family,
1406
	    bnd->bnd_proto == IPPROTO_TCP ? SOCK_STREAM : SOCK_DGRAM,
1407
	    bnd->bnd_proto)) == -1)
1408
		goto fail;
1409
	if (setsockopt(s, SOL_SOCKET, SO_BINDANY,
1410
	    &v, sizeof(v)) == -1)
1411
		goto fail;
1412
	if (bind(s, (struct sockaddr *)&bnd->bnd_ss,
1413
	    bnd->bnd_ss.ss_len) == -1)
1414
		goto fail;
1415
1416
	return (s);
1417
1418
 fail:
1419
	if (s != -1)
1420
		close(s);
1421
	return (-1);
1422
}
1423
1424
int
1425
map6to4(struct sockaddr_storage *in6)
1426
{
1427
	struct sockaddr_storage	 out4;
1428
	struct sockaddr_in	*sin4 = (struct sockaddr_in *)&out4;
1429
	struct sockaddr_in6	*sin6 = (struct sockaddr_in6 *)in6;
1430
1431
	bzero(sin4, sizeof(*sin4));
1432
	sin4->sin_len = sizeof(*sin4);
1433
	sin4->sin_family = AF_INET;
1434
	sin4->sin_port = sin6->sin6_port;
1435
1436
	bcopy(&sin6->sin6_addr.s6_addr[12], &sin4->sin_addr.s_addr,
1437
	    sizeof(sin4->sin_addr));
1438
1439
	if (sin4->sin_addr.s_addr == INADDR_ANY ||
1440
	    sin4->sin_addr.s_addr == INADDR_BROADCAST ||
1441
	    IN_MULTICAST(ntohl(sin4->sin_addr.s_addr)))
1442
		return (-1);
1443
1444
	bcopy(&out4, in6, sizeof(*in6));
1445
1446
	return (0);
1447
}
1448
1449
int
1450
map4to6(struct sockaddr_storage *in4, struct sockaddr_storage *map)
1451
{
1452
	struct sockaddr_storage	 out6;
1453
	struct sockaddr_in	*sin4 = (struct sockaddr_in *)in4;
1454
	struct sockaddr_in6	*sin6 = (struct sockaddr_in6 *)&out6;
1455
	struct sockaddr_in6	*map6 = (struct sockaddr_in6 *)map;
1456
1457
	if (sin4->sin_addr.s_addr == INADDR_ANY ||
1458
	    sin4->sin_addr.s_addr == INADDR_BROADCAST ||
1459
	    IN_MULTICAST(ntohl(sin4->sin_addr.s_addr)))
1460
		return (-1);
1461
1462
	bcopy(map6, sin6, sizeof(*sin6));
1463
	sin6->sin6_len = sizeof(*sin6);
1464
	sin6->sin6_family = AF_INET6;
1465
	sin6->sin6_port = sin4->sin_port;
1466
1467
	bcopy(&sin4->sin_addr.s_addr, &sin6->sin6_addr.s6_addr[12],
1468
	    sizeof(sin4->sin_addr));
1469
1470
	bcopy(&out6, in4, sizeof(*in4));
1471
1472
	return (0);
1473
}
1474
1475
void
1476
socket_rlimit(int maxfd)
1477
{
1478
	struct rlimit	 rl;
1479
1480
	if (getrlimit(RLIMIT_NOFILE, &rl) == -1)
1481
		fatal("%s: failed to get resource limit", __func__);
1482
	log_debug("%s: max open files %llu", __func__, rl.rlim_max);
1483
1484
	/*
1485
	 * Allow the maximum number of open file descriptors for this
1486
	 * login class (which should be the class "daemon" by default).
1487
	 */
1488
	if (maxfd == -1)
1489
		rl.rlim_cur = rl.rlim_max;
1490
	else
1491
		rl.rlim_cur = MAXIMUM(rl.rlim_max, (rlim_t)maxfd);
1492
	if (setrlimit(RLIMIT_NOFILE, &rl) == -1)
1493
		fatal("%s: failed to set resource limit", __func__);
1494
}
1495
1496
char *
1497
get_string(u_int8_t *ptr, size_t len)
1498
{
1499
	size_t	 i;
1500
1501
	for (i = 0; i < len; i++)
1502
		if (!(isprint((unsigned char)ptr[i]) ||
1503
		    isspace((unsigned char)ptr[i])))
1504
			break;
1505
1506
	return strndup(ptr, i);
1507
}
1508
1509
void *
1510
get_data(u_int8_t *ptr, size_t len)
1511
{
1512
	u_int8_t	*data;
1513
1514
	if ((data = malloc(len)) == NULL)
1515
		return (NULL);
1516
	memcpy(data, ptr, len);
1517
1518
	return (data);
1519
}
1520
1521
int
1522
sockaddr_cmp(struct sockaddr *a, struct sockaddr *b, int prefixlen)
1523
{
1524
	struct sockaddr_in	*a4, *b4;
1525
	struct sockaddr_in6	*a6, *b6;
1526
	u_int32_t		 av[4], bv[4], mv[4];
1527
1528
	if (a->sa_family == AF_UNSPEC || b->sa_family == AF_UNSPEC)
1529
		return (0);
1530
	else if (a->sa_family > b->sa_family)
1531
		return (1);
1532
	else if (a->sa_family < b->sa_family)
1533
		return (-1);
1534
1535
	if (prefixlen == -1)
1536
		memset(&mv, 0xff, sizeof(mv));
1537
1538
	switch (a->sa_family) {
1539
	case AF_INET:
1540
		a4 = (struct sockaddr_in *)a;
1541
		b4 = (struct sockaddr_in *)b;
1542
1543
		av[0] = a4->sin_addr.s_addr;
1544
		bv[0] = b4->sin_addr.s_addr;
1545
		if (prefixlen != -1)
1546
			mv[0] = prefixlen2mask(prefixlen);
1547
1548
		if ((av[0] & mv[0]) > (bv[0] & mv[0]))
1549
			return (1);
1550
		if ((av[0] & mv[0]) < (bv[0] & mv[0]))
1551
			return (-1);
1552
		break;
1553
	case AF_INET6:
1554
		a6 = (struct sockaddr_in6 *)a;
1555
		b6 = (struct sockaddr_in6 *)b;
1556
1557
		memcpy(&av, &a6->sin6_addr.s6_addr, 16);
1558
		memcpy(&bv, &b6->sin6_addr.s6_addr, 16);
1559
		if (prefixlen != -1)
1560
			prefixlen2mask6(prefixlen, mv);
1561
1562
		if ((av[3] & mv[3]) > (bv[3] & mv[3]))
1563
			return (1);
1564
		if ((av[3] & mv[3]) < (bv[3] & mv[3]))
1565
			return (-1);
1566
		if ((av[2] & mv[2]) > (bv[2] & mv[2]))
1567
			return (1);
1568
		if ((av[2] & mv[2]) < (bv[2] & mv[2]))
1569
			return (-1);
1570
		if ((av[1] & mv[1]) > (bv[1] & mv[1]))
1571
			return (1);
1572
		if ((av[1] & mv[1]) < (bv[1] & mv[1]))
1573
			return (-1);
1574
		if ((av[0] & mv[0]) > (bv[0] & mv[0]))
1575
			return (1);
1576
		if ((av[0] & mv[0]) < (bv[0] & mv[0]))
1577
			return (-1);
1578
		break;
1579
	}
1580
1581
	return (0);
1582
}
1583
1584
u_int32_t
1585
prefixlen2mask(u_int8_t prefixlen)
1586
{
1587
	if (prefixlen == 0)
1588
		return (0);
1589
1590
	if (prefixlen > 32)
1591
		prefixlen = 32;
1592
1593
	return (htonl(0xffffffff << (32 - prefixlen)));
1594
}
1595
1596
struct in6_addr *
1597
prefixlen2mask6(u_int8_t prefixlen, u_int32_t *mask)
1598
{
1599
	static struct in6_addr  s6;
1600
	int			i;
1601
1602
	if (prefixlen > 128)
1603
		prefixlen = 128;
1604
1605
	bzero(&s6, sizeof(s6));
1606
	for (i = 0; i < prefixlen / 8; i++)
1607
		s6.s6_addr[i] = 0xff;
1608
	i = prefixlen % 8;
1609
	if (i)
1610
		s6.s6_addr[prefixlen / 8] = 0xff00 >> i;
1611
1612
	memcpy(mask, &s6, sizeof(s6));
1613
1614
	return (&s6);
1615
}
1616
1617
int
1618
accept_reserve(int sockfd, struct sockaddr *addr, socklen_t *addrlen,
1619
    int reserve, volatile int *counter)
1620
{
1621
	int ret;
1622
	if (getdtablecount() + reserve +
1623
	    *counter >= getdtablesize()) {
1624
		errno = EMFILE;
1625
		return (-1);
1626
	}
1627
1628
	if ((ret = accept4(sockfd, addr, addrlen, SOCK_NONBLOCK)) > -1) {
1629
		(*counter)++;
1630
		DPRINTF("%s: inflight incremented, now %d",__func__, *counter);
1631
	}
1632
	return (ret);
1633
}
1634
1635
void
1636
parent_tls_ticket_rekey(int fd, short events, void *arg)
1637
{
1638
	static struct event	 rekeyev;
1639
1096
	struct relayd		*env = arg;
1640
548
	struct timeval		 tv;
1641
548
	struct relay_ticket_key	 key;
1642
1643
548
	log_debug("%s: rekeying tickets", __func__);
1644
1645
548
	key.tt_keyrev = arc4random();
1646
548
	arc4random_buf(key.tt_key, sizeof(key.tt_key));
1647
1648
548
	proc_compose_imsg(env->sc_ps, PROC_RELAY, -1, IMSG_TLSTICKET_REKEY,
1649
	    -1, -1, &key, sizeof(key));
1650
1651
548
	evtimer_set(&rekeyev, parent_tls_ticket_rekey, env);
1652
548
	timerclear(&tv);
1653
548
	tv.tv_sec = TLS_SESSION_LIFETIME / 4;
1654
548
	evtimer_add(&rekeyev, &tv);
1655
548
}