1 b9e76932 2026-05-19 rsadowski /* $OpenBSD: config.c,v 1.51 2026/05/19 05:04:11 rsadowski Exp $ */
4 c525adb9 2014-04-18 reyk * Copyright (c) 2011 - 2014 Reyk Floeter <reyk@openbsd.org>
6 591e6ab5 2011-05-19 reyk * Permission to use, copy, modify, and distribute this software for any
7 591e6ab5 2011-05-19 reyk * purpose with or without fee is hereby granted, provided that the above
8 591e6ab5 2011-05-19 reyk * copyright notice and this permission notice appear in all copies.
10 591e6ab5 2011-05-19 reyk * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 591e6ab5 2011-05-19 reyk * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 591e6ab5 2011-05-19 reyk * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 591e6ab5 2011-05-19 reyk * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 591e6ab5 2011-05-19 reyk * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 591e6ab5 2011-05-19 reyk * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 591e6ab5 2011-05-19 reyk * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 591e6ab5 2011-05-19 reyk #include <sys/types.h>
20 591e6ab5 2011-05-19 reyk #include <sys/queue.h>
21 d93c36af 2015-01-22 reyk #include <sys/time.h>
22 591e6ab5 2011-05-19 reyk #include <sys/uio.h>
24 d93c36af 2015-01-22 reyk #include <stdio.h>
25 d93c36af 2015-01-22 reyk #include <stdlib.h>
26 591e6ab5 2011-05-19 reyk #include <unistd.h>
27 591e6ab5 2011-05-19 reyk #include <limits.h>
28 591e6ab5 2011-05-19 reyk #include <string.h>
29 d93c36af 2015-01-22 reyk #include <imsg.h>
31 591e6ab5 2011-05-19 reyk #include "relayd.h"
32 6b5c4000 2026-03-02 rsadowski #include "log.h"
35 591e6ab5 2011-05-19 reyk config_init(struct relayd *env)
37 591e6ab5 2011-05-19 reyk struct privsep *ps = env->sc_ps;
40 591e6ab5 2011-05-19 reyk /* Global configuration */
41 591e6ab5 2011-05-19 reyk if (privsep_process == PROC_PARENT) {
42 58fc320c 2016-09-02 reyk env->sc_conf.timeout.tv_sec = CHECK_TIMEOUT / 1000;
43 58fc320c 2016-09-02 reyk env->sc_conf.timeout.tv_usec = (CHECK_TIMEOUT % 1000) * 1000;
44 58fc320c 2016-09-02 reyk env->sc_conf.interval.tv_sec = CHECK_INTERVAL;
45 58fc320c 2016-09-02 reyk env->sc_conf.interval.tv_usec = 0;
46 58fc320c 2016-09-02 reyk env->sc_conf.prefork_relay = RELAY_NUMPROC;
47 58fc320c 2016-09-02 reyk env->sc_conf.statinterval.tv_sec = RELAY_STATINTERVAL;
48 a98b5322 2017-11-29 benno env->sc_ps->ps_csock.cs_name = RELAYD_SOCKET;
51 6878f871 2016-09-02 reyk ps->ps_what[PROC_PARENT] = CONFIG_ALL;
52 ce78c3f2 2017-11-27 claudio ps->ps_what[PROC_PFE] = CONFIG_ALL & ~(CONFIG_PROTOS|CONFIG_CERTS);
53 6878f871 2016-09-02 reyk ps->ps_what[PROC_HCE] = CONFIG_TABLES;
54 ce78c3f2 2017-11-27 claudio ps->ps_what[PROC_CA] = CONFIG_RELAYS|CONFIG_CERTS;
55 ce78c3f2 2017-11-27 claudio ps->ps_what[PROC_RELAY] = CONFIG_RELAYS|CONFIG_CERTS|
56 6878f871 2016-09-02 reyk CONFIG_TABLES|CONFIG_PROTOS|CONFIG_CA_ENGINE;
58 591e6ab5 2011-05-19 reyk /* Other configuration */
59 591e6ab5 2011-05-19 reyk what = ps->ps_what[privsep_process];
60 591e6ab5 2011-05-19 reyk if (what & CONFIG_TABLES) {
61 591e6ab5 2011-05-19 reyk if ((env->sc_tables =
62 591e6ab5 2011-05-19 reyk calloc(1, sizeof(*env->sc_tables))) == NULL)
63 591e6ab5 2011-05-19 reyk return (-1);
64 591e6ab5 2011-05-19 reyk TAILQ_INIT(env->sc_tables);
66 591e6ab5 2011-05-19 reyk memset(&env->sc_empty_table, 0, sizeof(env->sc_empty_table));
67 591e6ab5 2011-05-19 reyk env->sc_empty_table.conf.id = EMPTY_TABLE;
68 591e6ab5 2011-05-19 reyk env->sc_empty_table.conf.flags |= F_DISABLE;
69 591e6ab5 2011-05-19 reyk (void)strlcpy(env->sc_empty_table.conf.name, "empty",
70 591e6ab5 2011-05-19 reyk sizeof(env->sc_empty_table.conf.name));
73 591e6ab5 2011-05-19 reyk if (what & CONFIG_RDRS) {
74 591e6ab5 2011-05-19 reyk if ((env->sc_rdrs =
75 591e6ab5 2011-05-19 reyk calloc(1, sizeof(*env->sc_rdrs))) == NULL)
76 591e6ab5 2011-05-19 reyk return (-1);
77 591e6ab5 2011-05-19 reyk TAILQ_INIT(env->sc_rdrs);
80 591e6ab5 2011-05-19 reyk if (what & CONFIG_RELAYS) {
81 591e6ab5 2011-05-19 reyk if ((env->sc_relays =
82 591e6ab5 2011-05-19 reyk calloc(1, sizeof(*env->sc_relays))) == NULL)
83 591e6ab5 2011-05-19 reyk return (-1);
84 591e6ab5 2011-05-19 reyk TAILQ_INIT(env->sc_relays);
86 fe4913ec 2019-05-31 reyk if ((env->sc_certs =
87 fe4913ec 2019-05-31 reyk calloc(1, sizeof(*env->sc_certs))) == NULL)
88 fe4913ec 2019-05-31 reyk return (-1);
89 fe4913ec 2019-05-31 reyk TAILQ_INIT(env->sc_certs);
91 fae05986 2014-04-22 reyk if ((env->sc_pkeys =
92 fae05986 2014-04-22 reyk calloc(1, sizeof(*env->sc_pkeys))) == NULL)
93 fae05986 2014-04-22 reyk return (-1);
94 fae05986 2014-04-22 reyk TAILQ_INIT(env->sc_pkeys);
96 591e6ab5 2011-05-19 reyk if (what & CONFIG_PROTOS) {
97 591e6ab5 2011-05-19 reyk if ((env->sc_protos =
98 591e6ab5 2011-05-19 reyk calloc(1, sizeof(*env->sc_protos))) == NULL)
99 591e6ab5 2011-05-19 reyk return (-1);
100 591e6ab5 2011-05-19 reyk TAILQ_INIT(env->sc_protos);
102 591e6ab5 2011-05-19 reyk bzero(&env->sc_proto_default, sizeof(env->sc_proto_default));
103 591e6ab5 2011-05-19 reyk env->sc_proto_default.id = EMPTY_ID;
104 591e6ab5 2011-05-19 reyk env->sc_proto_default.flags = F_USED;
105 591e6ab5 2011-05-19 reyk env->sc_proto_default.tcpflags = TCPFLAG_DEFAULT;
106 591e6ab5 2011-05-19 reyk env->sc_proto_default.tcpbacklog = RELAY_BACKLOG;
107 096ff28b 2014-12-12 reyk env->sc_proto_default.tlsflags = TLSFLAG_DEFAULT;
108 9261e0d8 2019-05-31 reyk TAILQ_INIT(&env->sc_proto_default.tlscerts);
109 096ff28b 2014-12-12 reyk (void)strlcpy(env->sc_proto_default.tlsciphers,
110 096ff28b 2014-12-12 reyk TLSCIPHERS_DEFAULT,
111 096ff28b 2014-12-12 reyk sizeof(env->sc_proto_default.tlsciphers));
112 3fe6d92f 2017-11-27 claudio (void)strlcpy(env->sc_proto_default.tlsecdhecurves,
113 3fe6d92f 2017-11-27 claudio TLSECDHECURVES_DEFAULT,
114 3fe6d92f 2017-11-27 claudio sizeof(env->sc_proto_default.tlsecdhecurves));
115 f4a6eef3 2017-05-27 claudio (void)strlcpy(env->sc_proto_default.tlsdhparams,
116 f4a6eef3 2017-05-27 claudio TLSDHPARAM_DEFAULT,
117 f4a6eef3 2017-05-27 claudio sizeof(env->sc_proto_default.tlsdhparams));
118 591e6ab5 2011-05-19 reyk env->sc_proto_default.type = RELAY_PROTO_TCP;
119 591e6ab5 2011-05-19 reyk (void)strlcpy(env->sc_proto_default.name, "default",
120 591e6ab5 2011-05-19 reyk sizeof(env->sc_proto_default.name));
122 591e6ab5 2011-05-19 reyk if (what & CONFIG_RTS) {
123 591e6ab5 2011-05-19 reyk if ((env->sc_rts =
124 591e6ab5 2011-05-19 reyk calloc(1, sizeof(*env->sc_rts))) == NULL)
125 591e6ab5 2011-05-19 reyk return (-1);
126 591e6ab5 2011-05-19 reyk TAILQ_INIT(env->sc_rts);
128 591e6ab5 2011-05-19 reyk if (what & CONFIG_ROUTES) {
129 591e6ab5 2011-05-19 reyk if ((env->sc_routes =
130 591e6ab5 2011-05-19 reyk calloc(1, sizeof(*env->sc_routes))) == NULL)
131 591e6ab5 2011-05-19 reyk return (-1);
132 591e6ab5 2011-05-19 reyk TAILQ_INIT(env->sc_routes);
135 591e6ab5 2011-05-19 reyk return (0);
139 591e6ab5 2011-05-19 reyk config_purge(struct relayd *env, u_int reset)
141 591e6ab5 2011-05-19 reyk struct privsep *ps = env->sc_ps;
142 591e6ab5 2011-05-19 reyk struct table *table;
143 591e6ab5 2011-05-19 reyk struct rdr *rdr;
144 591e6ab5 2011-05-19 reyk struct address *virt;
145 591e6ab5 2011-05-19 reyk struct protocol *proto;
146 69fde657 2014-07-09 reyk struct relay_rule *rule;
147 591e6ab5 2011-05-19 reyk struct relay *rlay;
148 591e6ab5 2011-05-19 reyk struct netroute *nr;
149 591e6ab5 2011-05-19 reyk struct router *rt;
150 fae05986 2014-04-22 reyk struct ca_pkey *pkey;
151 9261e0d8 2019-05-31 reyk struct keyname *keyname;
152 591e6ab5 2011-05-19 reyk u_int what;
154 591e6ab5 2011-05-19 reyk what = ps->ps_what[privsep_process] & reset;
156 591e6ab5 2011-05-19 reyk if (what & CONFIG_TABLES && env->sc_tables != NULL) {
157 591e6ab5 2011-05-19 reyk while ((table = TAILQ_FIRST(env->sc_tables)) != NULL)
158 2f479274 2015-05-02 claudio purge_table(env, env->sc_tables, table);
159 591e6ab5 2011-05-19 reyk env->sc_tablecount = 0;
161 591e6ab5 2011-05-19 reyk if (what & CONFIG_RDRS && env->sc_rdrs != NULL) {
162 591e6ab5 2011-05-19 reyk while ((rdr = TAILQ_FIRST(env->sc_rdrs)) != NULL) {
163 591e6ab5 2011-05-19 reyk TAILQ_REMOVE(env->sc_rdrs, rdr, entry);
164 591e6ab5 2011-05-19 reyk while ((virt = TAILQ_FIRST(&rdr->virts)) != NULL) {
165 591e6ab5 2011-05-19 reyk TAILQ_REMOVE(&rdr->virts, virt, entry);
166 591e6ab5 2011-05-19 reyk free(virt);
170 591e6ab5 2011-05-19 reyk env->sc_rdrcount = 0;
172 fae05986 2014-04-22 reyk if (what & CONFIG_RELAYS && env->sc_pkeys != NULL) {
173 fae05986 2014-04-22 reyk while ((pkey = TAILQ_FIRST(env->sc_pkeys)) != NULL) {
174 fae05986 2014-04-22 reyk TAILQ_REMOVE(env->sc_pkeys, pkey, pkey_entry);
175 fae05986 2014-04-22 reyk free(pkey);
178 591e6ab5 2011-05-19 reyk if (what & CONFIG_RELAYS && env->sc_relays != NULL) {
179 591e6ab5 2011-05-19 reyk while ((rlay = TAILQ_FIRST(env->sc_relays)) != NULL)
180 591e6ab5 2011-05-19 reyk purge_relay(env, rlay);
181 591e6ab5 2011-05-19 reyk env->sc_relaycount = 0;
183 591e6ab5 2011-05-19 reyk if (what & CONFIG_PROTOS && env->sc_protos != NULL) {
184 591e6ab5 2011-05-19 reyk while ((proto = TAILQ_FIRST(env->sc_protos)) != NULL) {
185 591e6ab5 2011-05-19 reyk TAILQ_REMOVE(env->sc_protos, proto, entry);
186 69fde657 2014-07-09 reyk while ((rule = TAILQ_FIRST(&proto->rules)) != NULL)
187 69fde657 2014-07-09 reyk rule_delete(&proto->rules, rule);
188 69fde657 2014-07-09 reyk proto->rulecount = 0;
189 ba24b6a0 2015-12-07 mmcc free(proto->style);
190 ba24b6a0 2015-12-07 mmcc free(proto->tlscapass);
191 9261e0d8 2019-05-31 reyk while ((keyname =
192 9261e0d8 2019-05-31 reyk TAILQ_FIRST(&proto->tlscerts)) != NULL) {
193 9261e0d8 2019-05-31 reyk TAILQ_REMOVE(&proto->tlscerts, keyname, entry);
194 9261e0d8 2019-05-31 reyk free(keyname->name);
195 9261e0d8 2019-05-31 reyk free(keyname);
197 b04f28f2 2021-12-05 jsg free(proto);
199 591e6ab5 2011-05-19 reyk env->sc_protocount = 0;
201 591e6ab5 2011-05-19 reyk if (what & CONFIG_RTS && env->sc_rts != NULL) {
202 591e6ab5 2011-05-19 reyk while ((rt = TAILQ_FIRST(env->sc_rts)) != NULL) {
203 591e6ab5 2011-05-19 reyk TAILQ_REMOVE(env->sc_rts, rt, rt_entry);
204 591e6ab5 2011-05-19 reyk while ((nr = TAILQ_FIRST(&rt->rt_netroutes)) != NULL) {
205 591e6ab5 2011-05-19 reyk TAILQ_REMOVE(&rt->rt_netroutes, nr, nr_entry);
206 591e6ab5 2011-05-19 reyk TAILQ_REMOVE(env->sc_routes, nr, nr_route);
208 591e6ab5 2011-05-19 reyk env->sc_routecount--;
212 591e6ab5 2011-05-19 reyk env->sc_routercount = 0;
214 591e6ab5 2011-05-19 reyk if (what & CONFIG_ROUTES && env->sc_routes != NULL) {
215 591e6ab5 2011-05-19 reyk while ((nr = TAILQ_FIRST(env->sc_routes)) != NULL) {
216 591e6ab5 2011-05-19 reyk if ((rt = nr->nr_router) != NULL)
217 591e6ab5 2011-05-19 reyk TAILQ_REMOVE(&rt->rt_netroutes, nr, nr_entry);
218 591e6ab5 2011-05-19 reyk TAILQ_REMOVE(env->sc_routes, nr, nr_route);
221 591e6ab5 2011-05-19 reyk env->sc_routecount = 0;
226 591e6ab5 2011-05-19 reyk config_setreset(struct relayd *env, u_int reset)
228 591e6ab5 2011-05-19 reyk struct privsep *ps = env->sc_ps;
231 591e6ab5 2011-05-19 reyk for (id = 0; id < PROC_MAX; id++) {
232 591e6ab5 2011-05-19 reyk if ((reset & ps->ps_what[id]) == 0 ||
233 591e6ab5 2011-05-19 reyk id == privsep_process)
235 141b9058 2015-12-02 reyk proc_compose(ps, id, IMSG_CTL_RESET, &reset, sizeof(reset));
238 cf7bc080 2019-06-01 reyk * XXX Make sure that the reset message is sent
239 cf7bc080 2019-06-01 reyk * immediately by flushing the imsg output buffer, before
240 cf7bc080 2019-06-01 reyk * sending any other imsg that potentially include an fd.
241 cf7bc080 2019-06-01 reyk * This should better be fixed in the imsg API itself.
243 cf7bc080 2019-06-01 reyk proc_flush_imsg(ps, id, -1);
246 591e6ab5 2011-05-19 reyk return (0);
250 591e6ab5 2011-05-19 reyk config_getreset(struct relayd *env, struct imsg *imsg)
252 591e6ab5 2011-05-19 reyk u_int mode;
254 591e6ab5 2011-05-19 reyk IMSG_SIZE_CHECK(imsg, &mode);
255 591e6ab5 2011-05-19 reyk memcpy(&mode, imsg->data, sizeof(mode));
257 591e6ab5 2011-05-19 reyk config_purge(env, mode);
259 591e6ab5 2011-05-19 reyk return (0);
263 591e6ab5 2011-05-19 reyk config_getcfg(struct relayd *env, struct imsg *imsg)
265 591e6ab5 2011-05-19 reyk struct privsep *ps = env->sc_ps;
266 591e6ab5 2011-05-19 reyk struct table *tb;
267 591e6ab5 2011-05-19 reyk struct host *h, *ph;
268 c525adb9 2014-04-18 reyk u_int what;
270 58fc320c 2016-09-02 reyk if (IMSG_DATA_SIZE(imsg) != sizeof(struct relayd_config))
271 591e6ab5 2011-05-19 reyk return (0); /* ignore */
273 591e6ab5 2011-05-19 reyk /* Update runtime flags */
274 58fc320c 2016-09-02 reyk memcpy(&env->sc_conf, imsg->data, sizeof(env->sc_conf));
276 c525adb9 2014-04-18 reyk what = ps->ps_what[privsep_process];
278 c525adb9 2014-04-18 reyk if (what & CONFIG_TABLES) {
279 591e6ab5 2011-05-19 reyk /* Update the tables */
280 591e6ab5 2011-05-19 reyk TAILQ_FOREACH(tb, env->sc_tables, entry) {
281 591e6ab5 2011-05-19 reyk TAILQ_FOREACH(h, &tb->hosts, entry) {
282 591e6ab5 2011-05-19 reyk if (h->conf.parentid && (ph = host_find(env,
283 591e6ab5 2011-05-19 reyk h->conf.parentid)) != NULL) {
284 591e6ab5 2011-05-19 reyk SLIST_INSERT_HEAD(&ph->children,
291 58fc320c 2016-09-02 reyk if (env->sc_conf.flags & (F_TLS|F_TLSCLIENT)) {
292 03ee1221 2014-05-04 reyk if (what & CONFIG_CA_ENGINE)
293 03ee1221 2014-05-04 reyk ca_engine_init(env);
296 591e6ab5 2011-05-19 reyk if (privsep_process != PROC_PARENT)
297 141b9058 2015-12-02 reyk proc_compose(env->sc_ps, PROC_PARENT, IMSG_CFG_DONE, NULL, 0);
299 591e6ab5 2011-05-19 reyk return (0);
303 591e6ab5 2011-05-19 reyk config_settable(struct relayd *env, struct table *tb)
305 591e6ab5 2011-05-19 reyk struct privsep *ps = env->sc_ps;
306 591e6ab5 2011-05-19 reyk struct host *host;
308 591e6ab5 2011-05-19 reyk struct iovec iov[2];
310 591e6ab5 2011-05-19 reyk for (id = 0; id < PROC_MAX; id++) {
311 591e6ab5 2011-05-19 reyk if ((ps->ps_what[id] & CONFIG_TABLES) == 0 ||
312 591e6ab5 2011-05-19 reyk id == privsep_process)
315 591e6ab5 2011-05-19 reyk /* XXX need to send table to pfe for control socket */
316 591e6ab5 2011-05-19 reyk if (id == PROC_HCE && tb->conf.check == CHECK_NOCHECK)
319 591e6ab5 2011-05-19 reyk DPRINTF("%s: sending table %s %d to %s", __func__,
320 591e6ab5 2011-05-19 reyk tb->conf.name, tb->conf.id, env->sc_ps->ps_title[id]);
323 591e6ab5 2011-05-19 reyk iov[c].iov_base = &tb->conf;
324 591e6ab5 2011-05-19 reyk iov[c++].iov_len = sizeof(tb->conf);
325 591e6ab5 2011-05-19 reyk if (tb->sendbuf != NULL) {
326 591e6ab5 2011-05-19 reyk iov[c].iov_base = tb->sendbuf;
327 591e6ab5 2011-05-19 reyk iov[c++].iov_len = strlen(tb->sendbuf);
330 141b9058 2015-12-02 reyk proc_composev(ps, id, IMSG_CFG_TABLE, iov, c);
332 591e6ab5 2011-05-19 reyk TAILQ_FOREACH(host, &tb->hosts, entry) {
333 141b9058 2015-12-02 reyk proc_compose(ps, id, IMSG_CFG_HOST,
334 591e6ab5 2011-05-19 reyk &host->conf, sizeof(host->conf));
338 591e6ab5 2011-05-19 reyk return (0);
342 591e6ab5 2011-05-19 reyk config_gettable(struct relayd *env, struct imsg *imsg)
344 591e6ab5 2011-05-19 reyk struct table *tb;
346 591e6ab5 2011-05-19 reyk u_int8_t *p = imsg->data;
349 591e6ab5 2011-05-19 reyk if ((tb = calloc(1, sizeof(*tb))) == NULL)
350 591e6ab5 2011-05-19 reyk return (-1);
352 591e6ab5 2011-05-19 reyk IMSG_SIZE_CHECK(imsg, &tb->conf);
353 591e6ab5 2011-05-19 reyk memcpy(&tb->conf, p, sizeof(tb->conf));
354 591e6ab5 2011-05-19 reyk s = sizeof(tb->conf);
356 591e6ab5 2011-05-19 reyk sb = IMSG_DATA_SIZE(imsg) - s;
357 21a3e757 2011-05-19 reyk if (sb > 0) {
358 21a3e757 2011-05-19 reyk if ((tb->sendbuf = get_string(p + s, sb)) == NULL) {
360 21a3e757 2011-05-19 reyk return (-1);
363 738b3cc9 2019-09-15 rob if (tb->conf.check == CHECK_BINSEND_EXPECT) {
364 738b3cc9 2019-09-15 rob tb->sendbinbuf = string2binary(tb->sendbuf);
365 738b3cc9 2019-09-15 rob if (tb->sendbinbuf == NULL) {
367 738b3cc9 2019-09-15 rob return (-1);
371 591e6ab5 2011-05-19 reyk TAILQ_INIT(&tb->hosts);
372 591e6ab5 2011-05-19 reyk TAILQ_INSERT_TAIL(env->sc_tables, tb, entry);
374 591e6ab5 2011-05-19 reyk env->sc_tablecount++;
376 591e6ab5 2011-05-19 reyk DPRINTF("%s: %s %d received table %d (%s)", __func__,
377 591e6ab5 2011-05-19 reyk env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance,
378 591e6ab5 2011-05-19 reyk tb->conf.id, tb->conf.name);
380 591e6ab5 2011-05-19 reyk return (0);
384 591e6ab5 2011-05-19 reyk config_gethost(struct relayd *env, struct imsg *imsg)
386 591e6ab5 2011-05-19 reyk struct table *tb;
387 591e6ab5 2011-05-19 reyk struct host *host;
389 591e6ab5 2011-05-19 reyk if ((host = calloc(1, sizeof(*host))) == NULL)
390 591e6ab5 2011-05-19 reyk return (-1);
392 591e6ab5 2011-05-19 reyk IMSG_SIZE_CHECK(imsg, &host->conf);
393 591e6ab5 2011-05-19 reyk memcpy(&host->conf, imsg->data, sizeof(host->conf));
395 591e6ab5 2011-05-19 reyk if (host_find(env, host->conf.id) != NULL) {
396 591e6ab5 2011-05-19 reyk log_debug("%s: host %d already exists",
397 591e6ab5 2011-05-19 reyk __func__, host->conf.id);
398 591e6ab5 2011-05-19 reyk free(host);
399 591e6ab5 2011-05-19 reyk return (-1);
402 591e6ab5 2011-05-19 reyk if ((tb = table_find(env, host->conf.tableid)) == NULL) {
403 591e6ab5 2011-05-19 reyk log_debug("%s: "
404 591e6ab5 2011-05-19 reyk "received host for unknown table %d", __func__,
405 591e6ab5 2011-05-19 reyk host->conf.tableid);
406 591e6ab5 2011-05-19 reyk free(host);
407 591e6ab5 2011-05-19 reyk return (-1);
410 591e6ab5 2011-05-19 reyk host->tablename = tb->conf.name;
411 591e6ab5 2011-05-19 reyk host->cte.s = -1;
413 591e6ab5 2011-05-19 reyk SLIST_INIT(&host->children);
414 591e6ab5 2011-05-19 reyk TAILQ_INSERT_TAIL(&tb->hosts, host, entry);
415 28bd28ce 2014-11-19 blambert TAILQ_INSERT_TAIL(&env->sc_hosts, host, globalentry);
417 591e6ab5 2011-05-19 reyk DPRINTF("%s: %s %d received host %s for table %s", __func__,
418 591e6ab5 2011-05-19 reyk env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance,
419 591e6ab5 2011-05-19 reyk host->conf.name, tb->conf.name);
421 591e6ab5 2011-05-19 reyk return (0);
425 591e6ab5 2011-05-19 reyk config_setrdr(struct relayd *env, struct rdr *rdr)
427 591e6ab5 2011-05-19 reyk struct privsep *ps = env->sc_ps;
428 591e6ab5 2011-05-19 reyk struct address *virt;
431 591e6ab5 2011-05-19 reyk for (id = 0; id < PROC_MAX; id++) {
432 591e6ab5 2011-05-19 reyk if ((ps->ps_what[id] & CONFIG_RDRS) == 0 ||
433 591e6ab5 2011-05-19 reyk id == privsep_process)
436 591e6ab5 2011-05-19 reyk DPRINTF("%s: sending rdr %s to %s", __func__,
437 591e6ab5 2011-05-19 reyk rdr->conf.name, ps->ps_title[id]);
439 141b9058 2015-12-02 reyk proc_compose(ps, id, IMSG_CFG_RDR,
440 591e6ab5 2011-05-19 reyk &rdr->conf, sizeof(rdr->conf));
442 591e6ab5 2011-05-19 reyk TAILQ_FOREACH(virt, &rdr->virts, entry) {
443 591e6ab5 2011-05-19 reyk virt->rdrid = rdr->conf.id;
444 141b9058 2015-12-02 reyk proc_compose(ps, id, IMSG_CFG_VIRT,
445 591e6ab5 2011-05-19 reyk virt, sizeof(*virt));
449 591e6ab5 2011-05-19 reyk return (0);
453 591e6ab5 2011-05-19 reyk config_getrdr(struct relayd *env, struct imsg *imsg)
455 591e6ab5 2011-05-19 reyk struct rdr *rdr;
457 591e6ab5 2011-05-19 reyk if ((rdr = calloc(1, sizeof(*rdr))) == NULL)
458 591e6ab5 2011-05-19 reyk return (-1);
460 591e6ab5 2011-05-19 reyk IMSG_SIZE_CHECK(imsg, &rdr->conf);
461 591e6ab5 2011-05-19 reyk memcpy(&rdr->conf, imsg->data, sizeof(rdr->conf));
463 591e6ab5 2011-05-19 reyk if ((rdr->table = table_find(env, rdr->conf.table_id)) == NULL) {
464 591e6ab5 2011-05-19 reyk log_debug("%s: table not found", __func__);
466 591e6ab5 2011-05-19 reyk return (-1);
468 591e6ab5 2011-05-19 reyk if ((rdr->backup = table_find(env, rdr->conf.backup_id)) == NULL) {
469 591e6ab5 2011-05-19 reyk rdr->conf.backup_id = EMPTY_TABLE;
470 591e6ab5 2011-05-19 reyk rdr->backup = &env->sc_empty_table;
473 591e6ab5 2011-05-19 reyk TAILQ_INIT(&rdr->virts);
474 591e6ab5 2011-05-19 reyk TAILQ_INSERT_TAIL(env->sc_rdrs, rdr, entry);
476 591e6ab5 2011-05-19 reyk env->sc_rdrcount++;
478 591e6ab5 2011-05-19 reyk DPRINTF("%s: %s %d received rdr %s", __func__,
479 591e6ab5 2011-05-19 reyk env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance,
480 591e6ab5 2011-05-19 reyk rdr->conf.name);
482 591e6ab5 2011-05-19 reyk return (0);
486 591e6ab5 2011-05-19 reyk config_getvirt(struct relayd *env, struct imsg *imsg)
488 591e6ab5 2011-05-19 reyk struct rdr *rdr;
489 591e6ab5 2011-05-19 reyk struct address *virt;
491 591e6ab5 2011-05-19 reyk IMSG_SIZE_CHECK(imsg, virt);
493 591e6ab5 2011-05-19 reyk if ((virt = calloc(1, sizeof(*virt))) == NULL)
494 591e6ab5 2011-05-19 reyk return (-1);
495 591e6ab5 2011-05-19 reyk memcpy(virt, imsg->data, sizeof(*virt));
497 591e6ab5 2011-05-19 reyk if ((rdr = rdr_find(env, virt->rdrid)) == NULL) {
498 591e6ab5 2011-05-19 reyk log_debug("%s: rdr not found", __func__);
499 591e6ab5 2011-05-19 reyk free(virt);
500 591e6ab5 2011-05-19 reyk return (-1);
503 591e6ab5 2011-05-19 reyk TAILQ_INSERT_TAIL(&rdr->virts, virt, entry);
505 591e6ab5 2011-05-19 reyk DPRINTF("%s: %s %d received address for rdr %s", __func__,
506 591e6ab5 2011-05-19 reyk env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance,
507 591e6ab5 2011-05-19 reyk rdr->conf.name);
509 591e6ab5 2011-05-19 reyk return (0);
513 591e6ab5 2011-05-19 reyk config_setrt(struct relayd *env, struct router *rt)
515 591e6ab5 2011-05-19 reyk struct privsep *ps = env->sc_ps;
516 591e6ab5 2011-05-19 reyk struct netroute *nr;
519 591e6ab5 2011-05-19 reyk for (id = 0; id < PROC_MAX; id++) {
520 591e6ab5 2011-05-19 reyk if ((ps->ps_what[id] & CONFIG_RTS) == 0 ||
521 591e6ab5 2011-05-19 reyk id == privsep_process)
524 591e6ab5 2011-05-19 reyk DPRINTF("%s: sending router %s to %s tbl %d", __func__,
525 591e6ab5 2011-05-19 reyk rt->rt_conf.name, ps->ps_title[id], rt->rt_conf.gwtable);
527 141b9058 2015-12-02 reyk proc_compose(ps, id, IMSG_CFG_ROUTER,
528 591e6ab5 2011-05-19 reyk &rt->rt_conf, sizeof(rt->rt_conf));
530 591e6ab5 2011-05-19 reyk TAILQ_FOREACH(nr, &rt->rt_netroutes, nr_entry) {
531 141b9058 2015-12-02 reyk proc_compose(ps, id, IMSG_CFG_ROUTE,
532 591e6ab5 2011-05-19 reyk &nr->nr_conf, sizeof(nr->nr_conf));
536 591e6ab5 2011-05-19 reyk return (0);
540 591e6ab5 2011-05-19 reyk config_getrt(struct relayd *env, struct imsg *imsg)
542 591e6ab5 2011-05-19 reyk struct router *rt;
544 591e6ab5 2011-05-19 reyk if ((rt = calloc(1, sizeof(*rt))) == NULL)
545 591e6ab5 2011-05-19 reyk return (-1);
547 591e6ab5 2011-05-19 reyk IMSG_SIZE_CHECK(imsg, &rt->rt_conf);
548 591e6ab5 2011-05-19 reyk memcpy(&rt->rt_conf, imsg->data, sizeof(rt->rt_conf));
550 591e6ab5 2011-05-19 reyk if ((rt->rt_gwtable = table_find(env, rt->rt_conf.gwtable)) == NULL) {
551 591e6ab5 2011-05-19 reyk log_debug("%s: table not found", __func__);
553 591e6ab5 2011-05-19 reyk return (-1);
556 591e6ab5 2011-05-19 reyk TAILQ_INIT(&rt->rt_netroutes);
557 591e6ab5 2011-05-19 reyk TAILQ_INSERT_TAIL(env->sc_rts, rt, rt_entry);
559 591e6ab5 2011-05-19 reyk env->sc_routercount++;
561 591e6ab5 2011-05-19 reyk DPRINTF("%s: %s %d received router %s", __func__,
562 591e6ab5 2011-05-19 reyk env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance,
563 591e6ab5 2011-05-19 reyk rt->rt_conf.name);
565 591e6ab5 2011-05-19 reyk return (0);
569 591e6ab5 2011-05-19 reyk config_getroute(struct relayd *env, struct imsg *imsg)
571 591e6ab5 2011-05-19 reyk struct router *rt;
572 591e6ab5 2011-05-19 reyk struct netroute *nr;
574 591e6ab5 2011-05-19 reyk if ((nr = calloc(1, sizeof(*nr))) == NULL)
575 591e6ab5 2011-05-19 reyk return (-1);
577 591e6ab5 2011-05-19 reyk IMSG_SIZE_CHECK(imsg, &nr->nr_conf);
578 591e6ab5 2011-05-19 reyk memcpy(&nr->nr_conf, imsg->data, sizeof(nr->nr_conf));
580 591e6ab5 2011-05-19 reyk if (route_find(env, nr->nr_conf.id) != NULL) {
581 591e6ab5 2011-05-19 reyk log_debug("%s: route %d already exists",
582 591e6ab5 2011-05-19 reyk __func__, nr->nr_conf.id);
584 591e6ab5 2011-05-19 reyk return (-1);
587 591e6ab5 2011-05-19 reyk if ((rt = router_find(env, nr->nr_conf.routerid)) == NULL) {
588 591e6ab5 2011-05-19 reyk log_debug("%s: received route for unknown router", __func__);
590 591e6ab5 2011-05-19 reyk return (-1);
593 591e6ab5 2011-05-19 reyk nr->nr_router = rt;
595 591e6ab5 2011-05-19 reyk TAILQ_INSERT_TAIL(env->sc_routes, nr, nr_route);
596 591e6ab5 2011-05-19 reyk TAILQ_INSERT_TAIL(&rt->rt_netroutes, nr, nr_entry);
598 591e6ab5 2011-05-19 reyk env->sc_routecount++;
600 591e6ab5 2011-05-19 reyk DPRINTF("%s: %s %d received route %d for router %s", __func__,
601 591e6ab5 2011-05-19 reyk env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance,
602 591e6ab5 2011-05-19 reyk nr->nr_conf.id, rt->rt_conf.name);
604 591e6ab5 2011-05-19 reyk return (0);
608 591e6ab5 2011-05-19 reyk config_setproto(struct relayd *env, struct protocol *proto)
610 591e6ab5 2011-05-19 reyk struct privsep *ps = env->sc_ps;
612 69fde657 2014-07-09 reyk struct iovec iov[IOV_MAX];
615 591e6ab5 2011-05-19 reyk for (id = 0; id < PROC_MAX; id++) {
616 591e6ab5 2011-05-19 reyk if ((ps->ps_what[id] & CONFIG_PROTOS) == 0 ||
617 591e6ab5 2011-05-19 reyk id == privsep_process)
620 591e6ab5 2011-05-19 reyk DPRINTF("%s: sending protocol %s to %s", __func__,
621 591e6ab5 2011-05-19 reyk proto->name, ps->ps_title[id]);
624 591e6ab5 2011-05-19 reyk iov[c].iov_base = proto;
625 591e6ab5 2011-05-19 reyk iov[c++].iov_len = sizeof(*proto);
627 591e6ab5 2011-05-19 reyk if (proto->style != NULL) {
628 591e6ab5 2011-05-19 reyk iov[c].iov_base = proto->style;
629 0481e102 2017-09-14 jsg iov[c++].iov_len = strlen(proto->style) + 1;
632 141b9058 2015-12-02 reyk proc_composev(ps, id, IMSG_CFG_PROTO, iov, c);
635 69fde657 2014-07-09 reyk return (0);
639 69fde657 2014-07-09 reyk config_setrule(struct relayd *env, struct protocol *proto)
641 69fde657 2014-07-09 reyk struct privsep *ps = env->sc_ps;
642 69fde657 2014-07-09 reyk struct relay_rule *rule;
643 69fde657 2014-07-09 reyk struct iovec iov[IOV_MAX];
645 69fde657 2014-07-09 reyk size_t c, i;
647 69fde657 2014-07-09 reyk for (id = 0; id < PROC_MAX; id++) {
648 69fde657 2014-07-09 reyk if ((ps->ps_what[id] & CONFIG_PROTOS) == 0 ||
649 69fde657 2014-07-09 reyk id == privsep_process)
652 69fde657 2014-07-09 reyk DPRINTF("%s: sending rules %s to %s", __func__,
653 69fde657 2014-07-09 reyk proto->name, ps->ps_title[id]);
655 69fde657 2014-07-09 reyk /* Now send all the rules */
656 69fde657 2014-07-09 reyk TAILQ_FOREACH(rule, &proto->rules, rule_entry) {
657 69fde657 2014-07-09 reyk rule->rule_protoid = proto->id;
658 69fde657 2014-07-09 reyk bzero(&rule->rule_ctl, sizeof(rule->rule_ctl));
660 69fde657 2014-07-09 reyk iov[c].iov_base = rule;
661 69fde657 2014-07-09 reyk iov[c++].iov_len = sizeof(*rule);
662 69fde657 2014-07-09 reyk for (i = 1; i < KEY_TYPE_MAX; i++) {
663 69fde657 2014-07-09 reyk if (rule->rule_kv[i].kv_key != NULL) {
664 69fde657 2014-07-09 reyk rule->rule_ctl.kvlen[i].key =
665 69fde657 2014-07-09 reyk strlen(rule->rule_kv[i].kv_key);
666 69fde657 2014-07-09 reyk iov[c].iov_base =
667 69fde657 2014-07-09 reyk rule->rule_kv[i].kv_key;
668 69fde657 2014-07-09 reyk iov[c++].iov_len =
669 69fde657 2014-07-09 reyk rule->rule_ctl.kvlen[i].key;
671 69fde657 2014-07-09 reyk rule->rule_ctl.kvlen[i].key = -1;
672 69fde657 2014-07-09 reyk if (rule->rule_kv[i].kv_value != NULL) {
673 69fde657 2014-07-09 reyk rule->rule_ctl.kvlen[i].value =
674 69fde657 2014-07-09 reyk strlen(rule->rule_kv[i].kv_value);
675 69fde657 2014-07-09 reyk iov[c].iov_base =
676 69fde657 2014-07-09 reyk rule->rule_kv[i].kv_value;
677 69fde657 2014-07-09 reyk iov[c++].iov_len =
678 69fde657 2014-07-09 reyk rule->rule_ctl.kvlen[i].value;
680 69fde657 2014-07-09 reyk rule->rule_ctl.kvlen[i].value = -1;
683 141b9058 2015-12-02 reyk proc_composev(ps, id, IMSG_CFG_RULE, iov, c);
687 591e6ab5 2011-05-19 reyk return (0);
691 591e6ab5 2011-05-19 reyk config_getproto(struct relayd *env, struct imsg *imsg)
693 591e6ab5 2011-05-19 reyk struct protocol *proto;
694 591e6ab5 2011-05-19 reyk size_t styl;
696 21a3e757 2011-05-19 reyk u_int8_t *p = imsg->data;
698 591e6ab5 2011-05-19 reyk if ((proto = calloc(1, sizeof(*proto))) == NULL)
699 591e6ab5 2011-05-19 reyk return (-1);
701 591e6ab5 2011-05-19 reyk IMSG_SIZE_CHECK(imsg, proto);
702 21a3e757 2011-05-19 reyk memcpy(proto, p, sizeof(*proto));
703 21a3e757 2011-05-19 reyk s = sizeof(*proto);
705 21a3e757 2011-05-19 reyk styl = IMSG_DATA_SIZE(imsg) - s;
706 0481e102 2017-09-14 jsg proto->style = NULL;
707 21a3e757 2011-05-19 reyk if (styl > 0) {
708 0481e102 2017-09-14 jsg if ((proto->style = get_string(p + s, styl - 1)) == NULL) {
709 21a3e757 2011-05-19 reyk free(proto);
710 21a3e757 2011-05-19 reyk return (-1);
714 69fde657 2014-07-09 reyk TAILQ_INIT(&proto->rules);
715 9261e0d8 2019-05-31 reyk TAILQ_INIT(&proto->tlscerts);
716 096ff28b 2014-12-12 reyk proto->tlscapass = NULL;
718 591e6ab5 2011-05-19 reyk TAILQ_INSERT_TAIL(env->sc_protos, proto, entry);
720 591e6ab5 2011-05-19 reyk env->sc_protocount++;
722 591e6ab5 2011-05-19 reyk DPRINTF("%s: %s %d received protocol %s", __func__,
723 591e6ab5 2011-05-19 reyk env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance,
724 591e6ab5 2011-05-19 reyk proto->name);
726 591e6ab5 2011-05-19 reyk return (0);
730 69fde657 2014-07-09 reyk config_getrule(struct relayd *env, struct imsg *imsg)
732 69fde657 2014-07-09 reyk struct protocol *proto;
733 69fde657 2014-07-09 reyk struct relay_rule *rule;
734 69fde657 2014-07-09 reyk size_t s, i;
735 591e6ab5 2011-05-19 reyk u_int8_t *p = imsg->data;
736 69fde657 2014-07-09 reyk ssize_t len;
738 69fde657 2014-07-09 reyk if ((rule = calloc(1, sizeof(*rule))) == NULL)
739 69fde657 2014-07-09 reyk return (-1);
741 69fde657 2014-07-09 reyk IMSG_SIZE_CHECK(imsg, rule);
742 69fde657 2014-07-09 reyk memcpy(rule, p, sizeof(*rule));
743 69fde657 2014-07-09 reyk s = sizeof(*rule);
744 69fde657 2014-07-09 reyk len = IMSG_DATA_SIZE(imsg) - s;
746 69fde657 2014-07-09 reyk if ((proto = proto_find(env, rule->rule_protoid)) == NULL) {
747 69fde657 2014-07-09 reyk free(rule);
748 69fde657 2014-07-09 reyk return (-1);
751 69fde657 2014-07-09 reyk #define GETKV(_n, _f) { \
752 69fde657 2014-07-09 reyk if (rule->rule_ctl.kvlen[_n]._f >= 0) { \
753 69fde657 2014-07-09 reyk /* Also accept "empty" 0-length strings */ \
754 69fde657 2014-07-09 reyk if ((len < rule->rule_ctl.kvlen[_n]._f) || \
755 69fde657 2014-07-09 reyk (rule->rule_kv[_n].kv_##_f = \
756 69fde657 2014-07-09 reyk get_string(p + s, \
757 69fde657 2014-07-09 reyk rule->rule_ctl.kvlen[_n]._f)) == NULL) { \
758 69fde657 2014-07-09 reyk free(rule); \
759 69fde657 2014-07-09 reyk return (-1); \
761 69fde657 2014-07-09 reyk s += rule->rule_ctl.kvlen[_n]._f; \
762 69fde657 2014-07-09 reyk len -= rule->rule_ctl.kvlen[_n]._f; \
764 69fde657 2014-07-09 reyk DPRINTF("%s: %s %s (len %ld, option %d): %s", __func__, \
765 69fde657 2014-07-09 reyk #_n, #_f, rule->rule_ctl.kvlen[_n]._f, \
766 69fde657 2014-07-09 reyk rule->rule_kv[_n].kv_option, \
767 69fde657 2014-07-09 reyk rule->rule_kv[_n].kv_##_f); \
771 005cea93 2014-07-09 reyk memset(&rule->rule_kv[0], 0, sizeof(struct kv));
772 69fde657 2014-07-09 reyk for (i = 1; i < KEY_TYPE_MAX; i++) {
773 2d9632ee 2014-07-11 reyk TAILQ_INIT(&rule->rule_kv[i].kv_children);
774 69fde657 2014-07-09 reyk GETKV(i, key);
775 69fde657 2014-07-09 reyk GETKV(i, value);
778 69fde657 2014-07-09 reyk if (rule->rule_labelname[0])
779 69fde657 2014-07-09 reyk rule->rule_label = label_name2id(rule->rule_labelname);
781 69fde657 2014-07-09 reyk if (rule->rule_tagname[0])
782 69fde657 2014-07-09 reyk rule->rule_tag = tag_name2id(rule->rule_tagname);
784 69fde657 2014-07-09 reyk if (rule->rule_taggedname[0])
785 69fde657 2014-07-09 reyk rule->rule_tagged = tag_name2id(rule->rule_taggedname);
787 69fde657 2014-07-09 reyk rule->rule_id = proto->rulecount++;
789 69fde657 2014-07-09 reyk TAILQ_INSERT_TAIL(&proto->rules, rule, rule_entry);
791 69fde657 2014-07-09 reyk DPRINTF("%s: %s %d received rule %u for protocol %s", __func__,
792 591e6ab5 2011-05-19 reyk env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance,
793 69fde657 2014-07-09 reyk rule->rule_id, proto->name);
795 591e6ab5 2011-05-19 reyk return (0);
798 ce78c3f2 2017-11-27 claudio static int
799 fe4913ec 2019-05-31 reyk config_setrelayfd(struct privsep *ps, int id, int n,
800 fe4913ec 2019-05-31 reyk objid_t obj_id, objid_t rlay_id, enum fd_type type, int ofd)
802 ce78c3f2 2017-11-27 claudio struct ctl_relayfd rfd;
805 fe4913ec 2019-05-31 reyk rfd.id = obj_id;
806 ce78c3f2 2017-11-27 claudio rfd.relayid = rlay_id;
807 ce78c3f2 2017-11-27 claudio rfd.type = type;
809 ce78c3f2 2017-11-27 claudio if ((fd = dup(ofd)) == -1)
810 ce78c3f2 2017-11-27 claudio return (-1);
811 ce78c3f2 2017-11-27 claudio if (proc_compose_imsg(ps, id, n, IMSG_CFG_RELAY_FD, -1, fd,
812 ce78c3f2 2017-11-27 claudio &rfd, sizeof(rfd)) != 0)
813 ce78c3f2 2017-11-27 claudio return (-1);
815 ce78c3f2 2017-11-27 claudio return (0);
819 591e6ab5 2011-05-19 reyk config_setrelay(struct relayd *env, struct relay *rlay)
821 0f7a5e2e 2012-10-03 reyk struct privsep *ps = env->sc_ps;
822 0f7a5e2e 2012-10-03 reyk struct ctl_relaytable crt;
823 0f7a5e2e 2012-10-03 reyk struct relay_table *rlt;
824 c525adb9 2014-04-18 reyk struct relay_config rl;
825 fe4913ec 2019-05-31 reyk struct relay_cert *cert;
827 0f7a5e2e 2012-10-03 reyk int fd, n, m;
828 3bb18274 2014-02-24 jsg struct iovec iov[6];
830 c525adb9 2014-04-18 reyk u_int what;
832 591e6ab5 2011-05-19 reyk /* opens listening sockets etc. */
833 591e6ab5 2011-05-19 reyk if (relay_privinit(rlay) == -1)
834 591e6ab5 2011-05-19 reyk return (-1);
836 591e6ab5 2011-05-19 reyk for (id = 0; id < PROC_MAX; id++) {
837 c525adb9 2014-04-18 reyk what = ps->ps_what[id];
839 c525adb9 2014-04-18 reyk if ((what & CONFIG_RELAYS) == 0 || id == privsep_process)
842 591e6ab5 2011-05-19 reyk DPRINTF("%s: sending relay %s to %s fd %d", __func__,
843 591e6ab5 2011-05-19 reyk rlay->rl_conf.name, ps->ps_title[id], rlay->rl_s);
845 c525adb9 2014-04-18 reyk memcpy(&rl, &rlay->rl_conf, sizeof(rl));
848 c525adb9 2014-04-18 reyk iov[c].iov_base = &rl;
849 c525adb9 2014-04-18 reyk iov[c++].iov_len = sizeof(rl);
851 c525adb9 2014-04-18 reyk if ((what & CONFIG_CA_ENGINE) == 0 &&
852 096ff28b 2014-12-12 reyk rl.tls_cakey_len) {
853 096ff28b 2014-12-12 reyk iov[c].iov_base = rlay->rl_tls_cakey;
854 096ff28b 2014-12-12 reyk iov[c++].iov_len = rl.tls_cakey_len;
856 096ff28b 2014-12-12 reyk rl.tls_cakey_len = 0;
858 591e6ab5 2011-05-19 reyk if (id == PROC_RELAY) {
859 591e6ab5 2011-05-19 reyk /* XXX imsg code will close the fd after 1st call */
861 591e6ab5 2011-05-19 reyk proc_range(ps, id, &n, &m);
862 591e6ab5 2011-05-19 reyk for (n = 0; n < m; n++) {
863 591e6ab5 2011-05-19 reyk if ((fd = dup(rlay->rl_s)) == -1)
864 591e6ab5 2011-05-19 reyk return (-1);
865 4b93801a 2016-11-24 reyk if (proc_composev_imsg(ps, id, n,
866 4b93801a 2016-11-24 reyk IMSG_CFG_RELAY, -1, fd, iov, c) != 0) {
867 4b93801a 2016-11-24 reyk log_warn("%s: failed to compose "
868 4b93801a 2016-11-24 reyk "IMSG_CFG_RELAY imsg for `%s'",
869 4b93801a 2016-11-24 reyk __func__, rlay->rl_conf.name);
870 4b93801a 2016-11-24 reyk return (-1);
872 4b93801a 2016-11-24 reyk /* Prevent fd exhaustion in the parent. */
873 4b93801a 2016-11-24 reyk if (proc_flush_imsg(ps, id, n) == -1) {
874 4b93801a 2016-11-24 reyk log_warn("%s: failed to flush "
875 4b93801a 2016-11-24 reyk "IMSG_CFG_RELAY imsg for `%s'",
876 4b93801a 2016-11-24 reyk __func__, rlay->rl_conf.name);
877 4b93801a 2016-11-24 reyk return (-1);
881 4b93801a 2016-11-24 reyk if (proc_composev(ps, id,
882 4b93801a 2016-11-24 reyk IMSG_CFG_RELAY, iov, c) != 0) {
883 4b93801a 2016-11-24 reyk log_warn("%s: failed to compose "
884 4b93801a 2016-11-24 reyk "IMSG_CFG_RELAY imsg for `%s'",
885 4b93801a 2016-11-24 reyk __func__, rlay->rl_conf.name);
886 4b93801a 2016-11-24 reyk return (-1);
890 fe4913ec 2019-05-31 reyk /* cert keypairs */
891 fe4913ec 2019-05-31 reyk TAILQ_FOREACH(cert, env->sc_certs, cert_entry) {
892 fe4913ec 2019-05-31 reyk if (cert->cert_relayid != rlay->rl_conf.id)
895 fe4913ec 2019-05-31 reyk proc_range(ps, id, &n, &m);
896 fe4913ec 2019-05-31 reyk for (n = 0; (what & CONFIG_CERTS) && n < m; n++) {
897 fe4913ec 2019-05-31 reyk if (cert->cert_fd != -1 &&
898 fe4913ec 2019-05-31 reyk config_setrelayfd(ps, id, n,
899 fe4913ec 2019-05-31 reyk cert->cert_id, cert->cert_relayid,
900 fe4913ec 2019-05-31 reyk RELAY_FD_CERT, cert->cert_fd) == -1) {
901 fe4913ec 2019-05-31 reyk log_warn("%s: fd passing failed for "
902 fe4913ec 2019-05-31 reyk "`%s'", __func__,
903 fe4913ec 2019-05-31 reyk rlay->rl_conf.name);
904 fe4913ec 2019-05-31 reyk return (-1);
906 0c91187d 2019-06-26 reyk if (id == PROC_RELAY &&
907 0c91187d 2019-06-26 reyk cert->cert_ocsp_fd != -1 &&
908 0c91187d 2019-06-26 reyk config_setrelayfd(ps, id, n,
909 0c91187d 2019-06-26 reyk cert->cert_id, cert->cert_relayid,
910 0c91187d 2019-06-26 reyk RELAY_FD_OCSP, cert->cert_ocsp_fd) == -1) {
911 0c91187d 2019-06-26 reyk log_warn("%s: fd passing failed for "
912 0c91187d 2019-06-26 reyk "`%s'", __func__,
913 0c91187d 2019-06-26 reyk rlay->rl_conf.name);
914 0c91187d 2019-06-26 reyk return (-1);
916 fe4913ec 2019-05-31 reyk if (id == PROC_CA &&
917 fe4913ec 2019-05-31 reyk cert->cert_key_fd != -1 &&
918 fe4913ec 2019-05-31 reyk config_setrelayfd(ps, id, n,
919 fe4913ec 2019-05-31 reyk cert->cert_id, cert->cert_relayid,
920 fe4913ec 2019-05-31 reyk RELAY_FD_KEY, cert->cert_key_fd) == -1) {
921 fe4913ec 2019-05-31 reyk log_warn("%s: fd passing failed for "
922 fe4913ec 2019-05-31 reyk "`%s'", __func__,
923 fe4913ec 2019-05-31 reyk rlay->rl_conf.name);
924 fe4913ec 2019-05-31 reyk return (-1);
929 fe4913ec 2019-05-31 reyk /* CA certs */
930 ce78c3f2 2017-11-27 claudio if (what & CONFIG_CERTS) {
932 ce78c3f2 2017-11-27 claudio proc_range(ps, id, &n, &m);
933 ce78c3f2 2017-11-27 claudio for (n = 0; n < m; n++) {
934 ce78c3f2 2017-11-27 claudio if (rlay->rl_tls_ca_fd != -1 &&
935 fe4913ec 2019-05-31 reyk config_setrelayfd(ps, id, n, 0,
936 ce78c3f2 2017-11-27 claudio rlay->rl_conf.id, RELAY_FD_CACERT,
937 ce78c3f2 2017-11-27 claudio rlay->rl_tls_ca_fd) == -1) {
938 ce78c3f2 2017-11-27 claudio log_warn("%s: fd passing failed for "
939 ce78c3f2 2017-11-27 claudio "`%s'", __func__,
940 ce78c3f2 2017-11-27 claudio rlay->rl_conf.name);
941 ce78c3f2 2017-11-27 claudio return (-1);
943 ce78c3f2 2017-11-27 claudio if (rlay->rl_tls_cacert_fd != -1 &&
944 fe4913ec 2019-05-31 reyk config_setrelayfd(ps, id, n, 0,
945 ce78c3f2 2017-11-27 claudio rlay->rl_conf.id, RELAY_FD_CAFILE,
946 ce78c3f2 2017-11-27 claudio rlay->rl_tls_cacert_fd) == -1) {
947 ce78c3f2 2017-11-27 claudio log_warn("%s: fd passing failed for "
948 ce78c3f2 2017-11-27 claudio "`%s'", __func__,
949 ce78c3f2 2017-11-27 claudio rlay->rl_conf.name);
950 ce78c3f2 2017-11-27 claudio return (-1);
952 c4efe747 2024-10-28 tb if (rlay->rl_tls_client_ca_fd != -1 &&
953 c4efe747 2024-10-28 tb config_setrelayfd(ps, id, n, 0,
954 c4efe747 2024-10-28 tb rlay->rl_conf.id, RELAY_FD_CLIENTCACERT,
955 c4efe747 2024-10-28 tb rlay->rl_tls_client_ca_fd) == -1) {
956 c4efe747 2024-10-28 tb log_warn("%s: fd passing failed for "
957 c4efe747 2024-10-28 tb "`%s'", __func__,
958 c4efe747 2024-10-28 tb rlay->rl_conf.name);
961 ce78c3f2 2017-11-27 claudio /* Prevent fd exhaustion in the parent. */
962 ce78c3f2 2017-11-27 claudio if (proc_flush_imsg(ps, id, n) == -1) {
963 ce78c3f2 2017-11-27 claudio log_warn("%s: failed to flush "
964 ce78c3f2 2017-11-27 claudio "IMSG_CFG_RELAY imsg for `%s'",
965 ce78c3f2 2017-11-27 claudio __func__, rlay->rl_conf.name);
966 ce78c3f2 2017-11-27 claudio return (-1);
971 c525adb9 2014-04-18 reyk if ((what & CONFIG_TABLES) == 0)
974 0f7a5e2e 2012-10-03 reyk /* Now send the tables associated to this relay */
975 0f7a5e2e 2012-10-03 reyk TAILQ_FOREACH(rlt, &rlay->rl_tables, rlt_entry) {
976 0f7a5e2e 2012-10-03 reyk crt.id = rlt->rlt_table->conf.id;
977 0f7a5e2e 2012-10-03 reyk crt.relayid = rlay->rl_conf.id;
978 0f7a5e2e 2012-10-03 reyk crt.mode = rlt->rlt_mode;
979 016b3271 2012-10-03 reyk crt.flags = rlt->rlt_flags;
982 0f7a5e2e 2012-10-03 reyk iov[c].iov_base = &crt;
983 0f7a5e2e 2012-10-03 reyk iov[c++].iov_len = sizeof(crt);
985 141b9058 2015-12-02 reyk proc_composev(ps, id, IMSG_CFG_RELAY_TABLE, iov, c);
989 4b93801a 2016-11-24 reyk /* Close server socket early to prevent fd exhaustion in the parent. */
990 4b93801a 2016-11-24 reyk if (rlay->rl_s != -1) {
991 4b93801a 2016-11-24 reyk close(rlay->rl_s);
992 4b93801a 2016-11-24 reyk rlay->rl_s = -1;
994 c4efe747 2024-10-28 tb if (rlay->rl_tls_client_ca_fd != -1) {
995 c4efe747 2024-10-28 tb close(rlay->rl_tls_client_ca_fd);
996 c4efe747 2024-10-28 tb rlay->rl_tls_client_ca_fd = -1;
998 ce78c3f2 2017-11-27 claudio if (rlay->rl_tls_cacert_fd != -1) {
999 ce78c3f2 2017-11-27 claudio close(rlay->rl_tls_cacert_fd);
1000 ce78c3f2 2017-11-27 claudio rlay->rl_tls_cacert_fd = -1;
1002 ce78c3f2 2017-11-27 claudio if (rlay->rl_tls_ca_fd != -1) {
1003 ce78c3f2 2017-11-27 claudio close(rlay->rl_tls_ca_fd);
1004 ce78c3f2 2017-11-27 claudio rlay->rl_tls_ca_fd = -1;
1006 fe4913ec 2019-05-31 reyk TAILQ_FOREACH(cert, env->sc_certs, cert_entry) {
1007 fe4913ec 2019-05-31 reyk if (cert->cert_relayid != rlay->rl_conf.id)
1010 fe4913ec 2019-05-31 reyk if (cert->cert_fd != -1) {
1011 fe4913ec 2019-05-31 reyk close(cert->cert_fd);
1012 fe4913ec 2019-05-31 reyk cert->cert_fd = -1;
1014 fe4913ec 2019-05-31 reyk if (cert->cert_key_fd != -1) {
1015 fe4913ec 2019-05-31 reyk close(cert->cert_key_fd);
1016 fe4913ec 2019-05-31 reyk cert->cert_key_fd = -1;
1018 0c91187d 2019-06-26 reyk if (cert->cert_ocsp_fd != -1) {
1019 0c91187d 2019-06-26 reyk close(cert->cert_ocsp_fd);
1020 0c91187d 2019-06-26 reyk cert->cert_ocsp_fd = -1;
1024 591e6ab5 2011-05-19 reyk return (0);
1028 591e6ab5 2011-05-19 reyk config_getrelay(struct relayd *env, struct imsg *imsg)
1030 591e6ab5 2011-05-19 reyk struct privsep *ps = env->sc_ps;
1031 591e6ab5 2011-05-19 reyk struct relay *rlay;
1032 591e6ab5 2011-05-19 reyk u_int8_t *p = imsg->data;
1035 591e6ab5 2011-05-19 reyk if ((rlay = calloc(1, sizeof(*rlay))) == NULL)
1036 591e6ab5 2011-05-19 reyk return (-1);
1038 591e6ab5 2011-05-19 reyk IMSG_SIZE_CHECK(imsg, &rlay->rl_conf);
1039 591e6ab5 2011-05-19 reyk memcpy(&rlay->rl_conf, p, sizeof(rlay->rl_conf));
1040 591e6ab5 2011-05-19 reyk s = sizeof(rlay->rl_conf);
1042 754759d6 2024-01-17 claudio rlay->rl_s = imsg_get_fd(imsg);
1043 ce78c3f2 2017-11-27 claudio rlay->rl_tls_ca_fd = -1;
1044 ce78c3f2 2017-11-27 claudio rlay->rl_tls_cacert_fd = -1;
1045 c4efe747 2024-10-28 tb rlay->rl_tls_client_ca_fd = -1;
1047 591e6ab5 2011-05-19 reyk if (ps->ps_what[privsep_process] & CONFIG_PROTOS) {
1048 591e6ab5 2011-05-19 reyk if (rlay->rl_conf.proto == EMPTY_ID)
1049 591e6ab5 2011-05-19 reyk rlay->rl_proto = &env->sc_proto_default;
1050 591e6ab5 2011-05-19 reyk else if ((rlay->rl_proto =
1051 591e6ab5 2011-05-19 reyk proto_find(env, rlay->rl_conf.proto)) == NULL) {
1052 591e6ab5 2011-05-19 reyk log_debug("%s: unknown protocol", __func__);
1053 591e6ab5 2011-05-19 reyk goto fail;
1057 09b69d98 2014-11-22 tedu if ((off_t)(IMSG_DATA_SIZE(imsg) - s) <
1058 fe4913ec 2019-05-31 reyk (rlay->rl_conf.tls_cakey_len)) {
1059 591e6ab5 2011-05-19 reyk log_debug("%s: invalid message length", __func__);
1060 591e6ab5 2011-05-19 reyk goto fail;
1063 096ff28b 2014-12-12 reyk if (rlay->rl_conf.tls_cakey_len) {
1064 096ff28b 2014-12-12 reyk if ((rlay->rl_tls_cakey = get_data(p + s,
1065 096ff28b 2014-12-12 reyk rlay->rl_conf.tls_cakey_len)) == NULL)
1066 03668b6b 2013-05-30 reyk goto fail;
1067 096ff28b 2014-12-12 reyk s += rlay->rl_conf.tls_cakey_len;
1070 0f7a5e2e 2012-10-03 reyk TAILQ_INIT(&rlay->rl_tables);
1071 591e6ab5 2011-05-19 reyk TAILQ_INSERT_TAIL(env->sc_relays, rlay, rl_entry);
1073 591e6ab5 2011-05-19 reyk env->sc_relaycount++;
1075 591e6ab5 2011-05-19 reyk DPRINTF("%s: %s %d received relay %s", __func__,
1076 591e6ab5 2011-05-19 reyk ps->ps_title[privsep_process], ps->ps_instance,
1077 591e6ab5 2011-05-19 reyk rlay->rl_conf.name);
1079 591e6ab5 2011-05-19 reyk return (0);
1082 ce78c3f2 2017-11-27 claudio free(rlay->rl_tls_cakey);
1083 591e6ab5 2011-05-19 reyk close(rlay->rl_s);
1084 591e6ab5 2011-05-19 reyk free(rlay);
1085 591e6ab5 2011-05-19 reyk return (-1);
1089 0f7a5e2e 2012-10-03 reyk config_getrelaytable(struct relayd *env, struct imsg *imsg)
1091 0f7a5e2e 2012-10-03 reyk struct relay_table *rlt = NULL;
1092 0f7a5e2e 2012-10-03 reyk struct ctl_relaytable crt;
1093 0f7a5e2e 2012-10-03 reyk struct relay *rlay;
1094 0f7a5e2e 2012-10-03 reyk struct table *table;
1095 0f7a5e2e 2012-10-03 reyk u_int8_t *p = imsg->data;
1097 0f7a5e2e 2012-10-03 reyk IMSG_SIZE_CHECK(imsg, &crt);
1098 0f7a5e2e 2012-10-03 reyk memcpy(&crt, p, sizeof(crt));
1100 0f7a5e2e 2012-10-03 reyk if ((rlay = relay_find(env, crt.relayid)) == NULL) {
1101 0f7a5e2e 2012-10-03 reyk log_debug("%s: unknown relay", __func__);
1102 0f7a5e2e 2012-10-03 reyk goto fail;
1105 0f7a5e2e 2012-10-03 reyk if ((table = table_find(env, crt.id)) == NULL) {
1106 0f7a5e2e 2012-10-03 reyk log_debug("%s: unknown table", __func__);
1107 0f7a5e2e 2012-10-03 reyk goto fail;
1110 0f7a5e2e 2012-10-03 reyk if ((rlt = calloc(1, sizeof(*rlt))) == NULL)
1111 0f7a5e2e 2012-10-03 reyk goto fail;
1113 0f7a5e2e 2012-10-03 reyk rlt->rlt_table = table;
1114 0f7a5e2e 2012-10-03 reyk rlt->rlt_mode = crt.mode;
1115 016b3271 2012-10-03 reyk rlt->rlt_flags = crt.flags;
1117 0f7a5e2e 2012-10-03 reyk TAILQ_INSERT_TAIL(&rlay->rl_tables, rlt, rlt_entry);
1119 0f7a5e2e 2012-10-03 reyk DPRINTF("%s: %s %d received relay table %s for relay %s", __func__,
1120 0f7a5e2e 2012-10-03 reyk env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance,
1121 0f7a5e2e 2012-10-03 reyk table->conf.name, rlay->rl_conf.name);
1123 0f7a5e2e 2012-10-03 reyk return (0);
1126 ba24b6a0 2015-12-07 mmcc free(rlt);
1127 0f7a5e2e 2012-10-03 reyk return (-1);
1131 ce78c3f2 2017-11-27 claudio config_getrelayfd(struct relayd *env, struct imsg *imsg)
1133 ce78c3f2 2017-11-27 claudio struct ctl_relayfd crfd;
1134 fe4913ec 2019-05-31 reyk struct relay *rlay = NULL;
1135 fe4913ec 2019-05-31 reyk struct relay_cert *cert;
1136 ce78c3f2 2017-11-27 claudio u_int8_t *p = imsg->data;
1138 ce78c3f2 2017-11-27 claudio IMSG_SIZE_CHECK(imsg, &crfd);
1139 ce78c3f2 2017-11-27 claudio memcpy(&crfd, p, sizeof(crfd));
1141 fe4913ec 2019-05-31 reyk switch (crfd.type) {
1142 fe4913ec 2019-05-31 reyk case RELAY_FD_CERT:
1143 fe4913ec 2019-05-31 reyk case RELAY_FD_KEY:
1144 0c91187d 2019-06-26 reyk case RELAY_FD_OCSP:
1145 fe4913ec 2019-05-31 reyk if ((cert = cert_find(env, crfd.id)) == NULL) {
1146 fe4913ec 2019-05-31 reyk if ((cert = cert_add(env, crfd.id)) == NULL)
1147 fe4913ec 2019-05-31 reyk return (-1);
1148 fe4913ec 2019-05-31 reyk cert->cert_relayid = crfd.relayid;
1150 fe4913ec 2019-05-31 reyk /* FALLTHROUGH */
1152 fe4913ec 2019-05-31 reyk if ((rlay = relay_find(env, crfd.relayid)) == NULL) {
1153 fe4913ec 2019-05-31 reyk log_debug("%s: unknown relay", __func__);
1154 fe4913ec 2019-05-31 reyk return (-1);
1159 ce78c3f2 2017-11-27 claudio switch (crfd.type) {
1160 ce78c3f2 2017-11-27 claudio case RELAY_FD_CERT:
1161 754759d6 2024-01-17 claudio cert->cert_fd = imsg_get_fd(imsg);
1163 fe4913ec 2019-05-31 reyk case RELAY_FD_KEY:
1164 754759d6 2024-01-17 claudio cert->cert_key_fd = imsg_get_fd(imsg);
1166 0c91187d 2019-06-26 reyk case RELAY_FD_OCSP:
1167 754759d6 2024-01-17 claudio cert->cert_ocsp_fd = imsg_get_fd(imsg);
1169 ce78c3f2 2017-11-27 claudio case RELAY_FD_CACERT:
1170 754759d6 2024-01-17 claudio rlay->rl_tls_ca_fd = imsg_get_fd(imsg);
1172 ce78c3f2 2017-11-27 claudio case RELAY_FD_CAFILE:
1173 754759d6 2024-01-17 claudio rlay->rl_tls_cacert_fd = imsg_get_fd(imsg);
1175 c4efe747 2024-10-28 tb case RELAY_FD_CLIENTCACERT:
1176 a6cad40b 2024-10-31 claudio rlay->rl_tls_client_ca_fd = imsg_get_fd(imsg);
1180 b9e76932 2026-05-19 rsadowski DPRINTF("%s: %s %d received relay type %d for relay %s", __func__,
1181 ce78c3f2 2017-11-27 claudio env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance,
1182 b9e76932 2026-05-19 rsadowski crfd.type, rlay->rl_conf.name);
1184 ce78c3f2 2017-11-27 claudio return (0);