Blob


1 /* $OpenBSD: relayd.c,v 1.199 2026/06/03 19:26:56 rsadowski Exp $ */
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 */
20 #include <sys/types.h>
21 #include <sys/queue.h>
22 #include <sys/socket.h>
23 #include <sys/stat.h>
24 #include <sys/wait.h>
25 #include <sys/resource.h>
27 #include <netinet/in.h>
28 #include <arpa/inet.h>
30 #include <agentx.h>
31 #include <signal.h>
32 #include <string.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <fcntl.h>
36 #include <getopt.h>
37 #include <fnmatch.h>
38 #include <syslog.h>
39 #include <err.h>
40 #include <errno.h>
41 #include <event.h>
42 #include <unistd.h>
43 #include <ctype.h>
44 #include <pwd.h>
45 #include <sha1.h>
46 #include <md5.h>
48 #include <tls.h>
50 #include "relayd.h"
51 #include "log.h"
53 #define MAXIMUM(a, b) (((a) > (b)) ? (a) : (b))
55 __dead void usage(void);
57 int parent_configure(struct relayd *);
58 void parent_configure_done(struct relayd *);
59 void parent_reload(struct relayd *, u_int, const char *);
60 void parent_sig_handler(int, short, void *);
61 void parent_shutdown(struct relayd *);
62 int parent_dispatch_pfe(int, struct privsep_proc *, struct imsg *);
63 int parent_dispatch_hce(int, struct privsep_proc *, struct imsg *);
64 int parent_dispatch_relay(int, struct privsep_proc *,
65 struct imsg *);
66 int parent_dispatch_ca(int, struct privsep_proc *,
67 struct imsg *);
68 int bindany(struct ctl_bindany *);
69 void parent_tls_ticket_rekey(int, short, void *);
71 struct relayd *relayd_env;
73 static struct privsep_proc procs[] = {
74 { "pfe", PROC_PFE, parent_dispatch_pfe, pfe },
75 { "hce", PROC_HCE, parent_dispatch_hce, hce },
76 { "relay", PROC_RELAY, parent_dispatch_relay, relay },
77 { "ca", PROC_CA, parent_dispatch_ca, ca }
78 };
80 enum privsep_procid privsep_process;
82 void
83 parent_sig_handler(int sig, short event, void *arg)
84 {
85 struct privsep *ps = arg;
87 switch (sig) {
88 case SIGTERM:
89 case SIGINT:
90 parent_shutdown(ps->ps_env);
91 break;
92 case SIGHUP:
93 log_info("%s: reload requested with SIGHUP", __func__);
95 /*
96 * This is safe because libevent uses async signal handlers
97 * that run in the event loop and not in signal context.
98 */
99 parent_reload(ps->ps_env, CONFIG_RELOAD, NULL);
100 break;
101 case SIGPIPE:
102 case SIGUSR1:
103 /* ignore */
104 break;
105 default:
106 fatalx("unexpected signal");
110 __dead void
111 usage(void)
113 extern char *__progname;
115 fprintf(stderr, "usage: %s [-dnv] [-D macro=value] [-f file]\n",
116 __progname);
117 exit(1);
120 int
121 main(int argc, char *argv[])
123 int c;
124 int debug = 0, verbose = 0;
125 u_int32_t opts = 0;
126 struct relayd *env;
127 struct privsep *ps;
128 const char *conffile = CONF_FILE;
129 enum privsep_procid proc_id = PROC_PARENT;
130 int proc_instance = 0;
131 const char *errp, *title = NULL;
132 int argc0 = argc;
134 while ((c = getopt(argc, argv, "dD:nI:P:f:v")) != -1) {
135 switch (c) {
136 case 'd':
137 debug = 2;
138 break;
139 case 'D':
140 if (cmdline_symset(optarg) < 0)
141 log_warnx("could not parse macro definition %s",
142 optarg);
143 break;
144 case 'n':
145 debug = 2;
146 opts |= RELAYD_OPT_NOACTION;
147 break;
148 case 'f':
149 conffile = optarg;
150 break;
151 case 'v':
152 verbose++;
153 opts |= RELAYD_OPT_VERBOSE;
154 break;
155 case 'P':
156 title = optarg;
157 proc_id = proc_getid(procs, nitems(procs), title);
158 if (proc_id == PROC_MAX)
159 fatalx("invalid process name");
160 break;
161 case 'I':
162 proc_instance = strtonum(optarg, 0,
163 PROC_MAX_INSTANCES, &errp);
164 if (errp)
165 fatalx("invalid process instance");
166 break;
167 default:
168 usage();
172 /* log to stderr until daemonized */
173 log_init(debug ? debug : 1, LOG_DAEMON);
175 argc -= optind;
176 if (argc > 0)
177 usage();
179 if ((env = calloc(1, sizeof(*env))) == NULL ||
180 (ps = calloc(1, sizeof(*ps))) == NULL)
181 exit(1);
183 relayd_env = env;
184 env->sc_ps = ps;
185 ps->ps_env = env;
186 TAILQ_INIT(&ps->ps_rcsocks);
187 env->sc_conffile = conffile;
188 env->sc_conf.opts = opts;
189 TAILQ_INIT(&env->sc_hosts);
190 TAILQ_INIT(&env->sc_sessions);
191 env->sc_rtable = getrtable();
192 /* initialize the TLS session id to a random key for all relay procs */
193 arc4random_buf(env->sc_conf.tls_sid, sizeof(env->sc_conf.tls_sid));
195 if (parse_config(env->sc_conffile, env) == -1)
196 exit(1);
198 if (debug)
199 env->sc_conf.opts |= RELAYD_OPT_LOGUPDATE;
201 if (geteuid())
202 errx(1, "need root privileges");
204 if ((ps->ps_pw = getpwnam(RELAYD_USER)) == NULL)
205 errx(1, "unknown user %s", RELAYD_USER);
207 log_init(debug, LOG_DAEMON);
208 log_setverbose(verbose);
210 if (env->sc_conf.opts & RELAYD_OPT_NOACTION)
211 ps->ps_noaction = 1;
213 ps->ps_instances[PROC_RELAY] = env->sc_conf.prefork_relay;
214 ps->ps_instances[PROC_CA] = env->sc_conf.prefork_relay;
215 ps->ps_instance = proc_instance;
216 if (title != NULL)
217 ps->ps_title[proc_id] = title;
219 /* only the parent returns */
220 proc_init(ps, procs, nitems(procs), debug, argc0, argv, proc_id);
222 log_procinit("parent");
224 if (ps->ps_noaction == 0)
225 log_info("startup");
227 if (unveil("/", "rx") == -1)
228 err(1, "unveil /");
229 if (env->sc_conf.flags & F_AGENTX) {
230 if (unveil(env->sc_conf.agentx_path, "w") == -1)
231 err(1, "unveil %s", env->sc_conf.agentx_path);
232 } else {
233 if (unveil(AGENTX_MASTER_PATH, "w") == -1)
234 err(1, "unveil %s", env->sc_conf.agentx_path);
236 if (unveil(NULL, NULL) == -1)
237 err(1, "unveil");
239 event_init();
241 signal_set(&ps->ps_evsigint, SIGINT, parent_sig_handler, ps);
242 signal_set(&ps->ps_evsigterm, SIGTERM, parent_sig_handler, ps);
243 signal_set(&ps->ps_evsighup, SIGHUP, parent_sig_handler, ps);
244 signal_set(&ps->ps_evsigpipe, SIGPIPE, parent_sig_handler, ps);
245 signal_set(&ps->ps_evsigusr1, SIGUSR1, parent_sig_handler, ps);
247 signal_add(&ps->ps_evsigint, NULL);
248 signal_add(&ps->ps_evsigterm, NULL);
249 signal_add(&ps->ps_evsighup, NULL);
250 signal_add(&ps->ps_evsigpipe, NULL);
251 signal_add(&ps->ps_evsigusr1, NULL);
253 proc_connect(ps);
255 relay_http(NULL);
256 if (load_config(env->sc_conffile, env) == -1) {
257 proc_kill(env->sc_ps);
258 exit(1);
261 if (env->sc_conf.opts & RELAYD_OPT_NOACTION) {
262 fprintf(stderr, "configuration OK\n");
263 proc_kill(env->sc_ps);
264 exit(0);
267 /* rekey the TLS tickets before pushing the config */
268 parent_tls_ticket_rekey(0, 0, env);
269 if (parent_configure(env) == -1)
270 fatalx("configuration failed");
272 init_routes(env);
274 event_dispatch();
276 parent_shutdown(env);
277 /* NOTREACHED */
279 return (0);
282 int
283 parent_configure(struct relayd *env)
285 struct table *tb;
286 struct rdr *rdr;
287 struct router *rt;
288 struct protocol *proto;
289 struct relay *rlay;
290 int id;
291 int ret = -1;
293 TAILQ_FOREACH(tb, env->sc_tables, entry)
294 config_settable(env, tb);
295 TAILQ_FOREACH(rdr, env->sc_rdrs, entry)
296 config_setrdr(env, rdr);
297 TAILQ_FOREACH(rt, env->sc_rts, rt_entry)
298 config_setrt(env, rt);
299 TAILQ_FOREACH(proto, env->sc_protos, entry)
300 config_setproto(env, proto);
301 TAILQ_FOREACH(proto, env->sc_protos, entry)
302 config_setrule(env, proto);
303 TAILQ_FOREACH(rlay, env->sc_relays, rl_entry) {
304 /* Check for TLS Inspection */
305 if ((rlay->rl_conf.flags & (F_TLS|F_TLSCLIENT)) ==
306 (F_TLS|F_TLSCLIENT) && rlay->rl_tls_cacert_fd != -1)
307 rlay->rl_conf.flags |= F_TLSINSPECT;
309 config_setrelay(env, rlay);
312 /* HCE, PFE, CA and the relays need to reload their config. */
313 env->sc_reload = 2 + (2 * env->sc_conf.prefork_relay);
315 for (id = 0; id < PROC_MAX; id++) {
316 if (id == privsep_process)
317 continue;
318 proc_compose_imsg(env->sc_ps, id, -1, IMSG_CFG_DONE, -1,
319 -1, &env->sc_conf, sizeof(env->sc_conf));
322 ret = 0;
324 config_purge(env, CONFIG_ALL & ~CONFIG_RELAYS);
325 return (ret);
328 void
329 parent_reload(struct relayd *env, u_int reset, const char *filename)
331 if (env->sc_reload) {
332 log_debug("%s: already in progress: %d pending",
333 __func__, env->sc_reload);
334 return;
337 /* Switch back to the default config file */
338 if (filename == NULL || *filename == '\0')
339 filename = env->sc_conffile;
341 log_debug("%s: level %d config file %s", __func__, reset, filename);
343 config_purge(env, CONFIG_ALL);
345 if (reset == CONFIG_RELOAD) {
346 if (load_config(filename, env) == -1) {
347 log_debug("%s: failed to load config file %s",
348 __func__, filename);
351 config_setreset(env, CONFIG_ALL);
353 if (parent_configure(env) == -1) {
354 log_debug("%s: failed to commit config from %s",
355 __func__, filename);
357 } else
358 config_setreset(env, reset);
361 void
362 parent_configure_done(struct relayd *env)
364 int id;
366 if (env->sc_reload == 0) {
367 log_warnx("%s: configuration already finished", __func__);
368 return;
371 env->sc_reload--;
372 if (env->sc_reload == 0) {
373 for (id = 0; id < PROC_MAX; id++) {
374 if (id == privsep_process)
375 continue;
377 proc_compose(env->sc_ps, id, IMSG_CTL_START, NULL, 0);
382 void
383 parent_shutdown(struct relayd *env)
385 config_purge(env, CONFIG_ALL);
387 proc_kill(env->sc_ps);
388 control_cleanup(&env->sc_ps->ps_csock);
389 carp_demote_shutdown();
391 free(env->sc_ps);
392 free(env);
394 log_info("parent terminating, pid %d", getpid());
396 exit(0);
399 int
400 parent_dispatch_pfe(int fd, struct privsep_proc *p, struct imsg *imsg)
402 struct privsep *ps = p->p_ps;
403 struct relayd *env = ps->ps_env;
404 struct ctl_demote demote;
405 struct ctl_netroute crt;
406 u_int v;
407 char *str = NULL;
409 switch (imsg->hdr.type) {
410 case IMSG_DEMOTE:
411 IMSG_SIZE_CHECK(imsg, &demote);
412 memcpy(&demote, imsg->data, sizeof(demote));
413 demote.group[sizeof(demote.group) - 1] = '\0';
414 carp_demote_set(demote.group, demote.level);
415 break;
416 case IMSG_RTMSG:
417 IMSG_SIZE_CHECK(imsg, &crt);
418 memcpy(&crt, imsg->data, sizeof(crt));
419 crt.host.name[sizeof(crt.host.name) - 1] = '\0';
420 crt.rt.name[sizeof(crt.rt.name) - 1] = '\0';
421 crt.rt.label[sizeof(crt.rt.label) - 1] = '\0';
422 pfe_route(env, &crt);
423 break;
424 case IMSG_CTL_RESET:
425 IMSG_SIZE_CHECK(imsg, &v);
426 memcpy(&v, imsg->data, sizeof(v));
427 parent_reload(env, v, NULL);
428 break;
429 case IMSG_CTL_RELOAD:
430 if (IMSG_DATA_SIZE(imsg) > 0)
431 str = get_string(imsg->data, IMSG_DATA_SIZE(imsg));
432 parent_reload(env, CONFIG_RELOAD, str);
433 free(str);
434 break;
435 case IMSG_CTL_SHUTDOWN:
436 parent_shutdown(env);
437 break;
438 case IMSG_CFG_DONE:
439 parent_configure_done(env);
440 break;
441 case IMSG_AGENTXSOCK:
442 agentx_setsock(env, p->p_id);
443 break;
444 default:
445 return (-1);
448 return (0);
451 int
452 parent_dispatch_hce(int fd, struct privsep_proc *p, struct imsg *imsg)
454 struct privsep *ps = p->p_ps;
455 struct relayd *env = ps->ps_env;
456 struct ctl_script scr;
458 switch (imsg->hdr.type) {
459 case IMSG_SCRIPT:
460 IMSG_SIZE_CHECK(imsg, &scr);
461 bcopy(imsg->data, &scr, sizeof(scr));
462 scr.name[sizeof(scr.name) - 1] = '\0';
463 scr.path[sizeof(scr.path) - 1] = '\0';
464 scr.retval = script_exec(env, &scr);
465 proc_compose(ps, PROC_HCE, IMSG_SCRIPT, &scr, sizeof(scr));
466 break;
467 case IMSG_CFG_DONE:
468 parent_configure_done(env);
469 break;
470 default:
471 return (-1);
474 return (0);
477 int
478 parent_dispatch_relay(int fd, struct privsep_proc *p, struct imsg *imsg)
480 struct privsep *ps = p->p_ps;
481 struct relayd *env = ps->ps_env;
482 struct ctl_bindany bnd;
483 int s;
485 switch (imsg->hdr.type) {
486 case IMSG_BINDANY:
487 IMSG_SIZE_CHECK(imsg, &bnd);
488 bcopy(imsg->data, &bnd, sizeof(bnd));
489 if (bnd.bnd_proc < 0 || bnd.bnd_proc > env->sc_conf.prefork_relay)
490 fatalx("%s: invalid relay proc", __func__);
491 switch (bnd.bnd_proto) {
492 case IPPROTO_TCP:
493 case IPPROTO_UDP:
494 break;
495 default:
496 fatalx("%s: requested socket "
497 "for invalid protocol", __func__);
498 /* NOTREACHED */
500 s = bindany(&bnd);
501 proc_compose_imsg(ps, PROC_RELAY, bnd.bnd_proc,
502 IMSG_BINDANY, -1, s, &bnd.bnd_id, sizeof(bnd.bnd_id));
503 break;
504 case IMSG_CFG_DONE:
505 parent_configure_done(env);
506 break;
507 default:
508 return (-1);
511 return (0);
514 int
515 parent_dispatch_ca(int fd, struct privsep_proc *p, struct imsg *imsg)
517 struct privsep *ps = p->p_ps;
518 struct relayd *env = ps->ps_env;
520 switch (imsg->hdr.type) {
521 case IMSG_CFG_DONE:
522 parent_configure_done(env);
523 break;
524 default:
525 return (-1);
528 return (0);
531 void
532 purge_table(struct relayd *env, struct tablelist *head, struct table *table)
534 struct host *host;
536 while ((host = TAILQ_FIRST(&table->hosts)) != NULL) {
537 TAILQ_REMOVE(&table->hosts, host, entry);
538 TAILQ_REMOVE(&env->sc_hosts, host, globalentry);
539 if (event_initialized(&host->cte.ev)) {
540 event_del(&host->cte.ev);
541 close(host->cte.s);
543 ibuf_free(host->cte.buf);
544 tls_free(host->cte.tls);
545 free(host);
547 free(table->sendbuf);
548 ibuf_free(table->sendbinbuf);
549 tls_config_free(table->tls_cfg);
551 if (head != NULL)
552 TAILQ_REMOVE(head, table, entry);
553 free(table);
556 void
557 purge_key(char **key, off_t len)
559 freezero(*key, len);
561 *key = NULL;
564 void
565 purge_relay(struct relayd *env, struct relay *rlay)
567 struct rsession *con;
568 struct relay_table *rlt;
569 struct relay_cert *cert, *tmpcert;
571 /* shutdown and remove relay */
572 if (event_initialized(&rlay->rl_ev))
573 event_del(&rlay->rl_ev);
574 close(rlay->rl_s);
575 TAILQ_REMOVE(env->sc_relays, rlay, rl_entry);
577 /* cleanup sessions */
578 while ((con =
579 SPLAY_ROOT(&rlay->rl_sessions)) != NULL)
580 relay_close(con, NULL, 0);
582 /* cleanup relay */
583 if (rlay->rl_bev != NULL)
584 bufferevent_free(rlay->rl_bev);
585 if (rlay->rl_dstbev != NULL)
586 bufferevent_free(rlay->rl_dstbev);
588 purge_key(&rlay->rl_tls_cakey, rlay->rl_conf.tls_cakey_len);
590 if (rlay->rl_tls_pkey != NULL) {
591 EVP_PKEY_free(rlay->rl_tls_pkey);
592 rlay->rl_tls_pkey = NULL;
594 if (rlay->rl_tls_cacertx509 != NULL) {
595 X509_free(rlay->rl_tls_cacertx509);
596 rlay->rl_tls_cacertx509 = NULL;
598 if (rlay->rl_tls_capkey != NULL) {
599 EVP_PKEY_free(rlay->rl_tls_capkey);
600 rlay->rl_tls_capkey = NULL;
603 tls_free(rlay->rl_tls_ctx);
604 tls_config_free(rlay->rl_tls_cfg);
605 tls_config_free(rlay->rl_tls_client_cfg);
607 while ((rlt = TAILQ_FIRST(&rlay->rl_tables))) {
608 TAILQ_REMOVE(&rlay->rl_tables, rlt, rlt_entry);
609 free(rlt);
612 TAILQ_FOREACH_SAFE(cert, env->sc_certs, cert_entry, tmpcert) {
613 if (rlay->rl_conf.id != cert->cert_relayid)
614 continue;
615 if (cert->cert_fd != -1)
616 close(cert->cert_fd);
617 if (cert->cert_key_fd != -1)
618 close(cert->cert_key_fd);
619 if (cert->cert_ocsp_fd != -1)
620 close(cert->cert_ocsp_fd);
621 if (cert->cert_pkey != NULL)
622 EVP_PKEY_free(cert->cert_pkey);
623 TAILQ_REMOVE(env->sc_certs, cert, cert_entry);
624 free(cert);
627 free(rlay);
630 struct kv *
631 kv_add(struct kvtree *keys, char *key, char *value, int unique)
633 struct kv *kv, *oldkv;
635 if (key == NULL)
636 return (NULL);
637 if ((kv = calloc(1, sizeof(*kv))) == NULL)
638 return (NULL);
639 if ((kv->kv_key = strdup(key)) == NULL)
640 goto fail;
641 if (value != NULL &&
642 (kv->kv_value = strdup(value)) == NULL)
643 goto fail;
644 TAILQ_INIT(&kv->kv_children);
646 if ((oldkv = RB_INSERT(kvtree, keys, kv)) != NULL) {
647 /*
648 * return error if the key should occur only once,
649 * or add it to a list attached to the key's node.
650 */
651 if (unique)
652 goto fail;
653 TAILQ_INSERT_TAIL(&oldkv->kv_children, kv, kv_entry);
654 kv->kv_parent = oldkv;
657 return (kv);
658 fail:
659 free(kv->kv_key);
660 free(kv->kv_value);
661 free(kv);
662 return (NULL);
665 int
666 kv_set(struct kv *kv, char *fmt, ...)
668 va_list ap;
669 char *value = NULL;
670 struct kv *ckv;
671 int ret;
673 va_start(ap, fmt);
674 ret = vasprintf(&value, fmt, ap);
675 va_end(ap);
676 if (ret == -1)
677 return (-1);
679 /* Remove all children */
680 while ((ckv = TAILQ_FIRST(&kv->kv_children)) != NULL) {
681 TAILQ_REMOVE(&kv->kv_children, ckv, kv_entry);
682 kv_free(ckv);
683 free(ckv);
686 /* Set the new value */
687 free(kv->kv_value);
688 kv->kv_value = value;
690 return (0);
693 int
694 kv_setkey(struct kv *kv, char *fmt, ...)
696 va_list ap;
697 char *key = NULL;
698 int ret;
700 va_start(ap, fmt);
701 ret = vasprintf(&key, fmt, ap);
702 va_end(ap);
703 if (ret == -1)
704 return (-1);
706 free(kv->kv_key);
707 kv->kv_key = key;
709 return (0);
712 void
713 kv_delete(struct kvtree *keys, struct kv *kv)
715 struct kv *ckv;
717 RB_REMOVE(kvtree, keys, kv);
719 /* Remove all children */
720 while ((ckv = TAILQ_FIRST(&kv->kv_children)) != NULL) {
721 TAILQ_REMOVE(&kv->kv_children, ckv, kv_entry);
722 kv_free(ckv);
723 free(ckv);
726 kv_free(kv);
727 free(kv);
730 void
731 kv_purge(struct kvtree *keys)
733 struct kv *kv;
735 while ((kv = RB_MIN(kvtree, keys)) != NULL)
736 kv_delete(keys, kv);
739 void
740 kv_free(struct kv *kv)
742 /*
743 * This function does not clear memory referenced by
744 * kv_children or stuff on the tailqs. Use kv_delete() instead.
745 */
747 free(kv->kv_key);
748 free(kv->kv_value);
749 memset(kv, 0, sizeof(*kv));
752 struct kv *
753 kv_inherit(struct kv *dst, struct kv *src)
755 memset(dst, 0, sizeof(*dst));
756 memcpy(dst, src, sizeof(*dst));
757 TAILQ_INIT(&dst->kv_children);
759 if (src->kv_key != NULL) {
760 if ((dst->kv_key = strdup(src->kv_key)) == NULL) {
761 kv_free(dst);
762 return (NULL);
765 if (src->kv_value != NULL) {
766 if ((dst->kv_value = strdup(src->kv_value)) == NULL) {
767 kv_free(dst);
768 return (NULL);
772 if (src->kv_match != NULL)
773 dst->kv_match = src->kv_match;
774 if (src->kv_matchtree != NULL)
775 dst->kv_matchtree = src->kv_matchtree;
777 return (dst);
780 int
781 kv_log(struct rsession *con, struct kv *kv, u_int16_t labelid,
782 enum direction dir)
784 char *msg;
786 if (con->se_log == NULL)
787 return (0);
788 if (asprintf(&msg, " %s%s%s%s%s%s%s",
789 dir == RELAY_DIR_REQUEST ? "[" : "{",
790 labelid == 0 ? "" : label_id2name(labelid),
791 labelid == 0 ? "" : ", ",
792 kv->kv_key == NULL ? "(unknown)" : kv->kv_key,
793 kv->kv_value == NULL ? "" : ": ",
794 kv->kv_value == NULL ? "" : kv->kv_value,
795 dir == RELAY_DIR_REQUEST ? "]" : "}") == -1)
796 return (-1);
797 if (evbuffer_add(con->se_log, msg, strlen(msg)) == -1) {
798 free(msg);
799 return (-1);
801 free(msg);
802 con->se_haslog = 1;
803 return (0);
806 struct kv *
807 kv_find(struct kvtree *keys, struct kv *kv)
809 struct kv *match;
810 const char *key;
812 if (kv->kv_flags & KV_FLAG_GLOBBING) {
813 /* Test header key using shell globbing rules */
814 key = kv->kv_key == NULL ? "" : kv->kv_key;
815 RB_FOREACH(match, kvtree, keys) {
816 if (fnmatch(key, match->kv_key, FNM_CASEFOLD) == 0)
817 break;
819 } else {
820 /* Fast tree-based lookup only works without globbing */
821 match = RB_FIND(kvtree, keys, kv);
824 return (match);
827 struct kv *
828 kv_find_value(struct kvtree *keys, char *key, const char *value,
829 const char *delim)
831 struct kv *match, kv;
832 char *val = NULL, *next, *ptr;
833 size_t len;
835 kv.kv_key = key;
836 if ((match = RB_FIND(kvtree, keys, &kv)) == NULL)
837 return (NULL);
839 if (match->kv_value == NULL)
840 return (NULL);
842 if (delim == NULL) {
843 if (strcasecmp(match->kv_value, value) == 0)
844 goto done;
845 } else {
846 if ((val = strdup(match->kv_value)) == NULL)
847 return (NULL);
848 for (next = ptr = val; ptr != NULL;
849 ptr = strsep(&next, delim)) {
850 /* strip whitespace */
851 ptr += strspn(ptr, " \t");
852 len = strcspn(ptr, " \t");
853 if (strncasecmp(ptr, value, len) == 0)
854 goto done;
858 /* not matched */
859 match = NULL;
860 done:
861 #ifdef DEBUG
862 if (match != NULL)
863 DPRINTF("%s: matched %s: %s", __func__, key, value);
864 #endif
865 free(val);
866 return (match);
869 int
870 kv_cmp(struct kv *a, struct kv *b)
872 return (strcasecmp(a->kv_key, b->kv_key));
875 RB_GENERATE(kvtree, kv, kv_node, kv_cmp);
877 int
878 rule_add(struct protocol *proto, struct relay_rule *rule, const char *rulefile)
880 struct relay_rule *r = NULL;
881 struct kv *kv = NULL;
882 FILE *fp = NULL;
883 char buf[BUFSIZ];
884 int ret = -1;
885 u_int i;
887 for (i = 0; i < KEY_TYPE_MAX; i++) {
888 kv = &rule->rule_kv[i];
889 if (kv->kv_type != i)
890 continue;
892 switch (kv->kv_option) {
893 case KEY_OPTION_LOG:
894 /* log action needs a key or a file to be specified */
895 if (kv->kv_key == NULL && rulefile == NULL &&
896 (kv->kv_key = strdup("*")) == NULL)
897 goto fail;
898 break;
899 default:
900 break;
903 switch (kv->kv_type) {
904 case KEY_TYPE_QUERY:
905 case KEY_TYPE_PATH:
906 case KEY_TYPE_URL:
907 if (rule->rule_dir != RELAY_DIR_REQUEST)
908 goto fail;
909 break;
910 default:
911 break;
914 if (kv->kv_value != NULL && strchr(kv->kv_value, '$') != NULL)
915 kv->kv_flags |= KV_FLAG_MACRO;
916 if (kv->kv_key != NULL && strpbrk(kv->kv_key, "*?[") != NULL)
917 kv->kv_flags |= KV_FLAG_GLOBBING;
920 if (rulefile == NULL) {
921 TAILQ_INSERT_TAIL(&proto->rules, rule, rule_entry);
922 return (0);
925 if ((fp = fopen(rulefile, "r")) == NULL)
926 goto fail;
928 while (fgets(buf, sizeof(buf), fp) != NULL) {
929 /* strip whitespace and newline characters */
930 buf[strcspn(buf, "\r\n\t ")] = '\0';
931 if (!strlen(buf) || buf[0] == '#')
932 continue;
934 if ((r = rule_inherit(rule)) == NULL)
935 goto fail;
937 for (i = 0; i < KEY_TYPE_MAX; i++) {
938 kv = &r->rule_kv[i];
939 if (kv->kv_type != i)
940 continue;
941 free(kv->kv_key);
942 if ((kv->kv_key = strdup(buf)) == NULL) {
943 rule_free(r);
944 free(r);
945 goto fail;
949 TAILQ_INSERT_TAIL(&proto->rules, r, rule_entry);
952 ret = 0;
953 rule_free(rule);
954 free(rule);
956 fail:
957 if (fp != NULL)
958 fclose(fp);
959 return (ret);
962 struct relay_rule *
963 rule_inherit(struct relay_rule *rule)
965 struct relay_rule *r;
966 u_int i;
967 struct kv *kv;
969 if ((r = calloc(1, sizeof(*r))) == NULL)
970 return (NULL);
971 memcpy(r, rule, sizeof(*r));
973 for (i = 0; i < KEY_TYPE_MAX; i++) {
974 kv = &rule->rule_kv[i];
975 if (kv->kv_type != i)
976 continue;
977 if (kv_inherit(&r->rule_kv[i], kv) == NULL) {
978 free(r);
979 return (NULL);
983 if (r->rule_label > 0)
984 label_ref(r->rule_label);
985 if (r->rule_tag > 0)
986 tag_ref(r->rule_tag);
987 if (r->rule_tagged > 0)
988 tag_ref(r->rule_tagged);
990 return (r);
993 void
994 rule_free(struct relay_rule *rule)
996 u_int i;
998 for (i = 0; i < KEY_TYPE_MAX; i++)
999 kv_free(&rule->rule_kv[i]);
1000 if (rule->rule_label > 0)
1001 label_unref(rule->rule_label);
1002 if (rule->rule_tag > 0)
1003 tag_unref(rule->rule_tag);
1004 if (rule->rule_tagged > 0)
1005 tag_unref(rule->rule_tagged);
1008 void
1009 rule_delete(struct relay_rules *rules, struct relay_rule *rule)
1011 TAILQ_REMOVE(rules, rule, rule_entry);
1012 rule_free(rule);
1013 free(rule);
1016 void
1017 rule_settable(struct relay_rules *rules, struct relay_table *rlt)
1019 struct relay_rule *r;
1020 char pname[TABLE_NAME_SIZE];
1022 if (rlt->rlt_table == NULL || strlcpy(pname, rlt->rlt_table->conf.name,
1023 sizeof(pname)) >= sizeof(pname))
1024 return;
1026 pname[strcspn(pname, ":")] = '\0';
1028 TAILQ_FOREACH(r, rules, rule_entry) {
1029 if (r->rule_tablename[0] &&
1030 strcmp(pname, r->rule_tablename) == 0)
1031 r->rule_table = rlt;
1036 * Utility functions
1039 struct host *
1040 host_find(struct relayd *env, objid_t id)
1042 struct table *table;
1043 struct host *host;
1045 TAILQ_FOREACH(table, env->sc_tables, entry)
1046 TAILQ_FOREACH(host, &table->hosts, entry)
1047 if (host->conf.id == id)
1048 return (host);
1049 return (NULL);
1052 struct table *
1053 table_find(struct relayd *env, objid_t id)
1055 struct table *table;
1057 TAILQ_FOREACH(table, env->sc_tables, entry)
1058 if (table->conf.id == id)
1059 return (table);
1060 return (NULL);
1063 struct rdr *
1064 rdr_find(struct relayd *env, objid_t id)
1066 struct rdr *rdr;
1068 TAILQ_FOREACH(rdr, env->sc_rdrs, entry)
1069 if (rdr->conf.id == id)
1070 return (rdr);
1071 return (NULL);
1074 struct relay *
1075 relay_find(struct relayd *env, objid_t id)
1077 struct relay *rlay;
1079 TAILQ_FOREACH(rlay, env->sc_relays, rl_entry)
1080 if (rlay->rl_conf.id == id)
1081 return (rlay);
1082 return (NULL);
1085 struct protocol *
1086 proto_find(struct relayd *env, objid_t id)
1088 struct protocol *p;
1090 TAILQ_FOREACH(p, env->sc_protos, entry)
1091 if (p->id == id)
1092 return (p);
1093 return (NULL);
1096 struct rsession *
1097 session_find(struct relayd *env, objid_t id)
1099 struct relay *rlay;
1100 struct rsession *con;
1102 TAILQ_FOREACH(rlay, env->sc_relays, rl_entry)
1103 SPLAY_FOREACH(con, session_tree, &rlay->rl_sessions)
1104 if (con->se_id == id)
1105 return (con);
1106 return (NULL);
1109 struct netroute *
1110 route_find(struct relayd *env, objid_t id)
1112 struct netroute *nr;
1114 TAILQ_FOREACH(nr, env->sc_routes, nr_route)
1115 if (nr->nr_conf.id == id)
1116 return (nr);
1117 return (NULL);
1120 struct router *
1121 router_find(struct relayd *env, objid_t id)
1123 struct router *rt;
1125 TAILQ_FOREACH(rt, env->sc_rts, rt_entry)
1126 if (rt->rt_conf.id == id)
1127 return (rt);
1128 return (NULL);
1131 struct host *
1132 host_findbyname(struct relayd *env, const char *name)
1134 struct table *table;
1135 struct host *host;
1137 TAILQ_FOREACH(table, env->sc_tables, entry)
1138 TAILQ_FOREACH(host, &table->hosts, entry)
1139 if (strcmp(host->conf.name, name) == 0)
1140 return (host);
1141 return (NULL);
1144 struct table *
1145 table_findbyname(struct relayd *env, const char *name)
1147 struct table *table;
1149 TAILQ_FOREACH(table, env->sc_tables, entry)
1150 if (strcmp(table->conf.name, name) == 0)
1151 return (table);
1152 return (NULL);
1155 struct table *
1156 table_findbyconf(struct relayd *env, struct table *tb)
1158 struct table *table;
1159 struct table_config a, b;
1161 bcopy(&tb->conf, &a, sizeof(a));
1162 a.id = a.rdrid = 0;
1163 a.flags &= ~(F_USED|F_BACKUP);
1165 TAILQ_FOREACH(table, env->sc_tables, entry) {
1166 bcopy(&table->conf, &b, sizeof(b));
1167 b.id = b.rdrid = 0;
1168 b.flags &= ~(F_USED|F_BACKUP);
1171 * Compare two tables and return the existing table if
1172 * the configuration seems to be the same.
1174 if (bcmp(&a, &b, sizeof(b)) == 0 &&
1175 ((tb->sendbuf == NULL && table->sendbuf == NULL) ||
1176 (tb->sendbuf != NULL && table->sendbuf != NULL &&
1177 strcmp(tb->sendbuf, table->sendbuf) == 0)))
1178 return (table);
1180 return (NULL);
1183 struct rdr *
1184 rdr_findbyname(struct relayd *env, const char *name)
1186 struct rdr *rdr;
1188 TAILQ_FOREACH(rdr, env->sc_rdrs, entry)
1189 if (strcmp(rdr->conf.name, name) == 0)
1190 return (rdr);
1191 return (NULL);
1194 struct relay *
1195 relay_findbyname(struct relayd *env, const char *name)
1197 struct relay *rlay;
1199 TAILQ_FOREACH(rlay, env->sc_relays, rl_entry)
1200 if (strcmp(rlay->rl_conf.name, name) == 0)
1201 return (rlay);
1202 return (NULL);
1205 struct relay *
1206 relay_findbyaddr(struct relayd *env, struct relay_config *rc)
1208 struct relay *rlay;
1210 TAILQ_FOREACH(rlay, env->sc_relays, rl_entry)
1211 if (bcmp(&rlay->rl_conf.ss, &rc->ss, sizeof(rc->ss)) == 0 &&
1212 rlay->rl_conf.port == rc->port)
1213 return (rlay);
1214 return (NULL);
1217 EVP_PKEY *
1218 pkey_find(struct relayd *env, char * hash)
1220 struct ca_pkey *pkey;
1222 TAILQ_FOREACH(pkey, env->sc_pkeys, pkey_entry)
1223 if (strcmp(hash, pkey->pkey_hash) == 0)
1224 return (pkey->pkey);
1225 return (NULL);
1228 struct ca_pkey *
1229 pkey_add(struct relayd *env, EVP_PKEY *pkey, char *hash)
1231 struct ca_pkey *ca_pkey;
1233 if (env->sc_pkeys == NULL)
1234 fatalx("pkeys");
1236 if ((ca_pkey = calloc(1, sizeof(*ca_pkey))) == NULL)
1237 return (NULL);
1239 ca_pkey->pkey = pkey;
1240 if (strlcpy(ca_pkey->pkey_hash, hash, sizeof(ca_pkey->pkey_hash)) >=
1241 sizeof(ca_pkey->pkey_hash)) {
1242 free(ca_pkey);
1243 return (NULL);
1246 TAILQ_INSERT_TAIL(env->sc_pkeys, ca_pkey, pkey_entry);
1248 return (ca_pkey);
1251 struct relay_cert *
1252 cert_add(struct relayd *env, objid_t id)
1254 static objid_t last_cert_id = 0;
1255 struct relay_cert *cert;
1257 if ((cert = calloc(1, sizeof(*cert))) == NULL)
1258 return (NULL);
1260 if (id == 0)
1261 id = ++last_cert_id;
1262 if (id == INT_MAX) {
1263 log_warnx("too many tls keypairs defined");
1264 free(cert);
1265 return (NULL);
1268 cert->cert_id = id;
1269 cert->cert_fd = -1;
1270 cert->cert_key_fd = -1;
1271 cert->cert_ocsp_fd = -1;
1273 TAILQ_INSERT_TAIL(env->sc_certs, cert, cert_entry);
1275 return (cert);
1278 struct relay_cert *
1279 cert_find(struct relayd *env, objid_t id)
1281 struct relay_cert *cert;
1283 TAILQ_FOREACH(cert, env->sc_certs, cert_entry)
1284 if (cert->cert_id == id)
1285 return (cert);
1286 return (NULL);
1289 char *
1290 relay_load_fd(int fd, off_t *len)
1292 char *buf = NULL;
1293 struct stat st;
1294 off_t size;
1295 int err;
1297 if (fstat(fd, &st) != 0)
1298 goto fail;
1299 size = st.st_size;
1300 if ((buf = calloc(1, size + 1)) == NULL)
1301 goto fail;
1302 if (pread(fd, buf, size, 0) != size)
1303 goto fail;
1305 close(fd);
1307 *len = size;
1308 return (buf);
1310 fail:
1311 err = errno;
1312 free(buf);
1313 close(fd);
1314 errno = err;
1315 return (NULL);
1318 int
1319 relay_load_certfiles(struct relayd *env, struct relay *rlay, const struct keyname *name)
1321 char certfile[PATH_MAX];
1322 char hbuf[PATH_MAX];
1323 struct protocol *proto = rlay->rl_proto;
1324 struct relay_cert *cert;
1325 int useport = htons(rlay->rl_conf.port);
1326 int cert_fd = -1, key_fd = -1, ocsp_fd = -1, ret = 0;
1328 if (rlay->rl_conf.flags & F_TLSCLIENT) {
1329 if (strlen(proto->tlsca) && rlay->rl_tls_ca_fd == -1) {
1330 if ((rlay->rl_tls_ca_fd =
1331 open(proto->tlsca, O_RDONLY)) == -1)
1332 return (-1);
1333 log_debug("%s: using ca %s", __func__, proto->tlsca);
1335 if (strlen(proto->tlscacert) && rlay->rl_tls_cacert_fd == -1) {
1336 if ((rlay->rl_tls_cacert_fd =
1337 open(proto->tlscacert, O_RDONLY)) == -1)
1338 return (-1);
1339 log_debug("%s: using ca certificate %s", __func__,
1340 proto->tlscacert);
1342 if (strlen(proto->tlscakey) && !rlay->rl_conf.tls_cakey_len &&
1343 proto->tlscapass != NULL) {
1344 if ((rlay->rl_tls_cakey =
1345 ssl_load_key(env, proto->tlscakey,
1346 &rlay->rl_conf.tls_cakey_len,
1347 proto->tlscapass)) == NULL)
1348 return (-1);
1349 log_debug("%s: using ca key %s", __func__,
1350 proto->tlscakey);
1354 if ((rlay->rl_conf.flags & F_TLS) == 0)
1355 return (0);
1357 if (strlen(proto->tlsclientca) && rlay->rl_tls_client_ca_fd == -1) {
1358 if ((rlay->rl_tls_client_ca_fd =
1359 open(proto->tlsclientca, O_RDONLY)) == -1)
1360 return (-1);
1361 log_debug("%s: using client ca %s", __func__,
1362 proto->tlsclientca);
1365 if (name == NULL &&
1366 print_host(&rlay->rl_conf.ss, hbuf, sizeof(hbuf)) == NULL)
1367 goto fail;
1368 else if (name != NULL &&
1369 strlcpy(hbuf, name->name, sizeof(hbuf)) >= sizeof(hbuf))
1370 goto fail;
1372 if (name != NULL && strcmp(name->certificate, "") != 0) {
1373 if (strlcpy(certfile, name->certificate, sizeof(certfile))
1374 >= sizeof(certfile)) {
1375 log_warnx("certificate truncated");
1376 goto fail;
1379 else {
1380 ret = snprintf(certfile, sizeof(certfile),
1381 "/etc/ssl/%s:%u.crt", hbuf, useport);
1383 if (ret < 0 || (size_t)ret >= sizeof(certfile))
1384 goto fail;
1386 if ((cert_fd = open(certfile, O_RDONLY)) == -1) {
1388 ret = snprintf(certfile, sizeof(certfile),
1389 "/etc/ssl/%s.crt", hbuf);
1391 if (ret < 0 || (size_t)ret >= sizeof(certfile))
1392 goto fail;
1393 if ((cert_fd = open(certfile, O_RDONLY)) == -1)
1394 goto fail;
1395 useport = 0;
1397 log_debug("%s: using certificate %s", __func__, certfile);
1399 if (name != NULL && strcmp(name->key, "") != 0) {
1400 if (strlcpy(certfile, name->key, sizeof(certfile))
1401 >= sizeof(certfile)) {
1402 log_warnx("certificate key truncated");
1403 goto fail;
1406 else {
1407 if (useport) {
1408 ret = snprintf(certfile, sizeof(certfile),
1409 "/etc/ssl/private/%s:%u.key",
1410 hbuf, useport);
1412 if (ret < 0 || (size_t)ret >= sizeof(certfile))
1413 goto fail;
1414 } else {
1415 ret = snprintf(certfile, sizeof(certfile),
1416 "/etc/ssl/private/%s.key", hbuf);
1418 if (ret < 0 || (size_t)ret >= sizeof(certfile))
1419 goto fail;
1422 if ((key_fd = open(certfile, O_RDONLY)) == -1)
1423 goto fail;
1424 log_debug("%s: using private key %s", __func__, certfile);
1426 if (name != NULL && strcmp(name->ocsp, "") != 0) {
1427 if (strlcpy(certfile, name->ocsp, sizeof(certfile))
1428 >= sizeof(certfile)) {
1429 log_warnx("certificate ocsp truncated");
1430 goto fail;
1434 else {
1435 if (useport) {
1436 ret = snprintf(certfile, sizeof(certfile),
1437 "/etc/ssl/%s:%u.ocsp",
1438 hbuf, useport);
1440 if (ret < 0 || (size_t)ret >= sizeof(certfile))
1441 goto fail;
1442 } else {
1443 ret = snprintf(certfile, sizeof(certfile),
1444 "/etc/ssl/%s.ocsp", hbuf);
1446 if (ret < 0 || (size_t)ret >= sizeof(certfile))
1447 goto fail;
1450 if ((ocsp_fd = open(certfile, O_RDONLY)) != -1)
1451 log_debug("%s: using OCSP staple file %s", __func__, certfile);
1453 if ((cert = cert_add(env, 0)) == NULL)
1454 goto fail;
1456 cert->cert_relayid = rlay->rl_conf.id;
1457 cert->cert_fd = cert_fd;
1458 cert->cert_key_fd = key_fd;
1459 cert->cert_ocsp_fd = ocsp_fd;
1461 return (0);
1463 fail:
1464 if (cert_fd != -1)
1465 close(cert_fd);
1466 if (key_fd != -1)
1467 close(key_fd);
1468 if (ocsp_fd != -1)
1469 close(ocsp_fd);
1471 return (-1);
1474 void
1475 event_again(struct event *ev, int fd, short event,
1476 void (*fn)(int, short, void *),
1477 struct timeval *start, struct timeval *end, void *arg)
1479 struct timeval tv_next, tv_now, tv;
1481 getmonotime(&tv_now);
1482 bcopy(end, &tv_next, sizeof(tv_next));
1483 timersub(&tv_now, start, &tv_now);
1484 timersub(&tv_next, &tv_now, &tv_next);
1486 bzero(&tv, sizeof(tv));
1487 if (timercmp(&tv_next, &tv, >))
1488 bcopy(&tv_next, &tv, sizeof(tv));
1490 event_del(ev);
1491 event_set(ev, fd, event, fn, arg);
1492 event_add(ev, &tv);
1495 int
1496 expand_string(char *label, size_t len, const char *srch, const char *repl)
1498 char *tmp;
1499 char *p, *q;
1501 if ((tmp = calloc(1, len)) == NULL) {
1502 log_debug("%s: calloc", __func__);
1503 return (-1);
1505 p = label;
1506 while ((q = strstr(p, srch)) != NULL) {
1507 *q = '\0';
1508 if ((strlcat(tmp, p, len) >= len) ||
1509 (strlcat(tmp, repl, len) >= len)) {
1510 log_debug("%s: string too long", __func__);
1511 free(tmp);
1512 return (-1);
1514 q += strlen(srch);
1515 p = q;
1517 if (strlcat(tmp, p, len) >= len) {
1518 log_debug("%s: string too long", __func__);
1519 free(tmp);
1520 return (-1);
1522 (void)strlcpy(label, tmp, len); /* always fits */
1523 free(tmp);
1525 return (0);
1528 void
1529 translate_string(char *str)
1531 char *reader;
1532 char *writer;
1534 reader = writer = str;
1536 while (*reader) {
1537 if (*reader == '\\') {
1538 reader++;
1539 switch (*reader) {
1540 case 'n':
1541 *writer++ = '\n';
1542 break;
1543 case 'r':
1544 *writer++ = '\r';
1545 break;
1546 default:
1547 *writer++ = *reader;
1549 } else
1550 *writer++ = *reader;
1551 reader++;
1553 *writer = '\0';
1556 char *
1557 digeststr(enum digest_type type, const u_int8_t *data, size_t len, char *buf)
1559 switch (type) {
1560 case DIGEST_SHA1:
1561 return (SHA1Data(data, len, buf));
1562 break;
1563 case DIGEST_MD5:
1564 return (MD5Data(data, len, buf));
1565 break;
1566 default:
1567 break;
1569 return (NULL);
1572 const char *
1573 canonicalize_host(const char *host, char *name, size_t len)
1575 struct sockaddr_in sin4;
1576 struct sockaddr_in6 sin6;
1577 size_t i, j;
1578 size_t plen;
1579 char c;
1581 if (len < 2)
1582 goto fail;
1585 * Canonicalize an IPv4/6 address
1587 if (inet_pton(AF_INET, host, &sin4) == 1)
1588 return (inet_ntop(AF_INET, &sin4, name, len));
1589 if (inet_pton(AF_INET6, host, &sin6) == 1)
1590 return (inet_ntop(AF_INET6, &sin6, name, len));
1593 * Canonicalize a hostname
1596 /* 1. remove repeated dots and convert upper case to lower case */
1597 plen = strlen(host);
1598 bzero(name, len);
1599 for (i = j = 0; i < plen; i++) {
1600 if (j >= (len - 1))
1601 goto fail;
1602 c = tolower((unsigned char)host[i]);
1603 if ((c == '.') && (j == 0 || name[j - 1] == '.'))
1604 continue;
1605 name[j++] = c;
1608 /* 2. remove trailing dots */
1609 for (i = j; i > 0; i--) {
1610 if (name[i - 1] != '.')
1611 break;
1612 name[i - 1] = '\0';
1613 j--;
1615 if (j <= 0)
1616 goto fail;
1618 return (name);
1620 fail:
1621 errno = EINVAL;
1622 return (NULL);
1625 int
1626 parse_url(const char *url, char **protoptr, char **hostptr, char **pathptr)
1628 char *p, *proto = NULL, *host = NULL, *path = NULL;
1630 /* return error if it is not a URL */
1631 if ((p = strstr(url, ":/")) == NULL ||
1632 (strcspn(url, ":/") != (size_t)(p - url)))
1633 return (-1);
1635 /* get protocol */
1636 if ((proto = strdup(url)) == NULL)
1637 goto fail;
1638 p = proto + (p - url);
1640 /* get host */
1641 p += strspn(p, ":/");
1642 if (*p == '\0' || (host = strdup(p)) == NULL)
1643 goto fail;
1644 *p = '\0';
1646 /* find and copy path or default to "/" */
1647 if ((p = strchr(host, '/')) == NULL)
1648 p = "/";
1649 if ((path = strdup(p)) == NULL)
1650 goto fail;
1652 /* strip path after host */
1653 host[strcspn(host, "/")] = '\0';
1655 DPRINTF("%s: %s proto %s, host %s, path %s", __func__,
1656 url, proto, host, path);
1658 *protoptr = proto;
1659 *hostptr = host;
1660 *pathptr = path;
1662 return (0);
1664 fail:
1665 free(proto);
1666 free(host);
1667 free(path);
1668 return (-1);
1671 int
1672 bindany(struct ctl_bindany *bnd)
1674 int s, v;
1676 s = -1;
1677 v = 1;
1679 if (relay_socket_af(&bnd->bnd_ss, bnd->bnd_port) == -1)
1680 goto fail;
1681 if ((s = socket(bnd->bnd_ss.ss_family,
1682 bnd->bnd_proto == IPPROTO_TCP ? SOCK_STREAM : SOCK_DGRAM,
1683 bnd->bnd_proto)) == -1)
1684 goto fail;
1685 if (setsockopt(s, SOL_SOCKET, SO_BINDANY,
1686 &v, sizeof(v)) == -1)
1687 goto fail;
1688 if (bind(s, (struct sockaddr *)&bnd->bnd_ss,
1689 bnd->bnd_ss.ss_len) == -1)
1690 goto fail;
1692 return (s);
1694 fail:
1695 if (s != -1)
1696 close(s);
1697 return (-1);
1700 int
1701 map6to4(struct sockaddr_storage *in6)
1703 struct sockaddr_storage out4;
1704 struct sockaddr_in *sin4 = (struct sockaddr_in *)&out4;
1705 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)in6;
1707 bzero(sin4, sizeof(*sin4));
1708 sin4->sin_len = sizeof(*sin4);
1709 sin4->sin_family = AF_INET;
1710 sin4->sin_port = sin6->sin6_port;
1712 bcopy(&sin6->sin6_addr.s6_addr[12], &sin4->sin_addr.s_addr,
1713 sizeof(sin4->sin_addr));
1715 if (sin4->sin_addr.s_addr == INADDR_ANY ||
1716 sin4->sin_addr.s_addr == INADDR_BROADCAST ||
1717 IN_MULTICAST(ntohl(sin4->sin_addr.s_addr)))
1718 return (-1);
1720 bcopy(&out4, in6, sizeof(*in6));
1722 return (0);
1725 int
1726 map4to6(struct sockaddr_storage *in4, struct sockaddr_storage *map)
1728 struct sockaddr_storage out6;
1729 struct sockaddr_in *sin4 = (struct sockaddr_in *)in4;
1730 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&out6;
1731 struct sockaddr_in6 *map6 = (struct sockaddr_in6 *)map;
1733 if (sin4->sin_addr.s_addr == INADDR_ANY ||
1734 sin4->sin_addr.s_addr == INADDR_BROADCAST ||
1735 IN_MULTICAST(ntohl(sin4->sin_addr.s_addr)))
1736 return (-1);
1738 bcopy(map6, sin6, sizeof(*sin6));
1739 sin6->sin6_len = sizeof(*sin6);
1740 sin6->sin6_family = AF_INET6;
1741 sin6->sin6_port = sin4->sin_port;
1743 bcopy(&sin4->sin_addr.s_addr, &sin6->sin6_addr.s6_addr[12],
1744 sizeof(sin4->sin_addr));
1746 bcopy(&out6, in4, sizeof(*in4));
1748 return (0);
1751 void
1752 socket_rlimit(int maxfd)
1754 struct rlimit rl;
1756 if (getrlimit(RLIMIT_NOFILE, &rl) == -1)
1757 fatal("%s: failed to get resource limit", __func__);
1758 log_debug("%s: max open files %llu", __func__, rl.rlim_max);
1761 * Allow the maximum number of open file descriptors for this
1762 * login class (which should be the class "daemon" by default).
1764 if (maxfd == -1)
1765 rl.rlim_cur = rl.rlim_max;
1766 else
1767 rl.rlim_cur = MAXIMUM(rl.rlim_max, (rlim_t)maxfd);
1768 if (setrlimit(RLIMIT_NOFILE, &rl) == -1)
1769 fatal("%s: failed to set resource limit", __func__);
1772 char *
1773 get_string(u_int8_t *ptr, size_t len)
1775 size_t i;
1777 for (i = 0; i < len; i++)
1778 if (!(isprint((unsigned char)ptr[i]) ||
1779 isspace((unsigned char)ptr[i])))
1780 break;
1782 return strndup(ptr, i);
1785 void *
1786 get_data(u_int8_t *ptr, size_t len)
1788 u_int8_t *data;
1790 if ((data = malloc(len)) == NULL)
1791 return (NULL);
1792 memcpy(data, ptr, len);
1794 return (data);
1797 int
1798 sockaddr_cmp(struct sockaddr *a, struct sockaddr *b, int prefixlen)
1800 struct sockaddr_in *a4, *b4;
1801 struct sockaddr_in6 *a6, *b6;
1802 u_int32_t av[4], bv[4], mv[4];
1804 if (a->sa_family == AF_UNSPEC || b->sa_family == AF_UNSPEC)
1805 return (0);
1806 else if (a->sa_family > b->sa_family)
1807 return (1);
1808 else if (a->sa_family < b->sa_family)
1809 return (-1);
1811 if (prefixlen == -1)
1812 memset(&mv, 0xff, sizeof(mv));
1814 switch (a->sa_family) {
1815 case AF_INET:
1816 a4 = (struct sockaddr_in *)a;
1817 b4 = (struct sockaddr_in *)b;
1819 av[0] = a4->sin_addr.s_addr;
1820 bv[0] = b4->sin_addr.s_addr;
1821 if (prefixlen != -1)
1822 mv[0] = prefixlen2mask(prefixlen);
1824 if ((av[0] & mv[0]) > (bv[0] & mv[0]))
1825 return (1);
1826 if ((av[0] & mv[0]) < (bv[0] & mv[0]))
1827 return (-1);
1828 break;
1829 case AF_INET6:
1830 a6 = (struct sockaddr_in6 *)a;
1831 b6 = (struct sockaddr_in6 *)b;
1833 memcpy(&av, &a6->sin6_addr.s6_addr, 16);
1834 memcpy(&bv, &b6->sin6_addr.s6_addr, 16);
1835 if (prefixlen != -1)
1836 prefixlen2mask6(prefixlen, mv);
1838 if ((av[3] & mv[3]) > (bv[3] & mv[3]))
1839 return (1);
1840 if ((av[3] & mv[3]) < (bv[3] & mv[3]))
1841 return (-1);
1842 if ((av[2] & mv[2]) > (bv[2] & mv[2]))
1843 return (1);
1844 if ((av[2] & mv[2]) < (bv[2] & mv[2]))
1845 return (-1);
1846 if ((av[1] & mv[1]) > (bv[1] & mv[1]))
1847 return (1);
1848 if ((av[1] & mv[1]) < (bv[1] & mv[1]))
1849 return (-1);
1850 if ((av[0] & mv[0]) > (bv[0] & mv[0]))
1851 return (1);
1852 if ((av[0] & mv[0]) < (bv[0] & mv[0]))
1853 return (-1);
1854 break;
1857 return (0);
1860 u_int32_t
1861 prefixlen2mask(u_int8_t prefixlen)
1863 if (prefixlen == 0)
1864 return (0);
1866 if (prefixlen > 32)
1867 prefixlen = 32;
1869 return (htonl(0xffffffff << (32 - prefixlen)));
1872 struct in6_addr *
1873 prefixlen2mask6(u_int8_t prefixlen, u_int32_t *mask)
1875 static struct in6_addr s6;
1876 int i;
1878 if (prefixlen > 128)
1879 prefixlen = 128;
1881 bzero(&s6, sizeof(s6));
1882 for (i = 0; i < prefixlen / 8; i++)
1883 s6.s6_addr[i] = 0xff;
1884 i = prefixlen % 8;
1885 if (i)
1886 s6.s6_addr[prefixlen / 8] = 0xff00 >> i;
1888 memcpy(mask, &s6, sizeof(s6));
1890 return (&s6);
1893 int
1894 accept_reserve(int sockfd, struct sockaddr *addr, socklen_t *addrlen,
1895 int reserve, volatile int *counter)
1897 int ret;
1898 if (getdtablecount() + reserve +
1899 *counter >= getdtablesize()) {
1900 errno = EMFILE;
1901 return (-1);
1904 if ((ret = accept4(sockfd, addr, addrlen, SOCK_NONBLOCK)) > -1) {
1905 (*counter)++;
1906 DPRINTF("%s: inflight incremented, now %d",__func__, *counter);
1908 return (ret);
1911 void
1912 parent_tls_ticket_rekey(int fd, short events, void *arg)
1914 static struct event rekeyev;
1915 struct relayd *env = arg;
1916 struct timeval tv;
1917 struct relay_ticket_key key;
1919 log_debug("%s: rekeying tickets", __func__);
1921 key.tt_keyrev = arc4random();
1922 arc4random_buf(key.tt_key, sizeof(key.tt_key));
1924 proc_compose_imsg(env->sc_ps, PROC_RELAY, -1, IMSG_TLSTICKET_REKEY,
1925 -1, -1, &key, sizeof(key));
1927 evtimer_set(&rekeyev, parent_tls_ticket_rekey, env);
1928 timerclear(&tv);
1929 tv.tv_sec = TLS_SESSION_LIFETIME / 4;
1930 evtimer_add(&rekeyev, &tv);