Blame


1 b9e76932 2026-05-19 rsadowski /* $OpenBSD: config.c,v 1.51 2026/05/19 05:04:11 rsadowski Exp $ */
2 591e6ab5 2011-05-19 reyk
3 591e6ab5 2011-05-19 reyk /*
4 c525adb9 2014-04-18 reyk * Copyright (c) 2011 - 2014 Reyk Floeter <reyk@openbsd.org>
5 591e6ab5 2011-05-19 reyk *
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.
9 591e6ab5 2011-05-19 reyk *
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.
17 591e6ab5 2011-05-19 reyk */
18 591e6ab5 2011-05-19 reyk
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>
23 591e6ab5 2011-05-19 reyk
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>
30 591e6ab5 2011-05-19 reyk
31 591e6ab5 2011-05-19 reyk #include "relayd.h"
32 6b5c4000 2026-03-02 rsadowski #include "log.h"
33 591e6ab5 2011-05-19 reyk
34 591e6ab5 2011-05-19 reyk int
35 591e6ab5 2011-05-19 reyk config_init(struct relayd *env)
36 591e6ab5 2011-05-19 reyk {
37 591e6ab5 2011-05-19 reyk struct privsep *ps = env->sc_ps;
38 591e6ab5 2011-05-19 reyk u_int what;
39 591e6ab5 2011-05-19 reyk
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;
49 591e6ab5 2011-05-19 reyk }
50 591e6ab5 2011-05-19 reyk
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;
57 6878f871 2016-09-02 reyk
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);
65 591e6ab5 2011-05-19 reyk
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));
71 591e6ab5 2011-05-19 reyk
72 591e6ab5 2011-05-19 reyk }
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);
78 591e6ab5 2011-05-19 reyk
79 591e6ab5 2011-05-19 reyk }
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);
85 fe4913ec 2019-05-31 reyk
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);
90 fe4913ec 2019-05-31 reyk
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);
95 591e6ab5 2011-05-19 reyk }
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);
101 591e6ab5 2011-05-19 reyk
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));
121 591e6ab5 2011-05-19 reyk }
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);
127 591e6ab5 2011-05-19 reyk }
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);
133 591e6ab5 2011-05-19 reyk }
134 591e6ab5 2011-05-19 reyk
135 591e6ab5 2011-05-19 reyk return (0);
136 591e6ab5 2011-05-19 reyk }
137 591e6ab5 2011-05-19 reyk
138 591e6ab5 2011-05-19 reyk void
139 591e6ab5 2011-05-19 reyk config_purge(struct relayd *env, u_int reset)
140 591e6ab5 2011-05-19 reyk {
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;
153 591e6ab5 2011-05-19 reyk
154 591e6ab5 2011-05-19 reyk what = ps->ps_what[privsep_process] & reset;
155 591e6ab5 2011-05-19 reyk
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;
160 591e6ab5 2011-05-19 reyk }
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);
167 591e6ab5 2011-05-19 reyk }
168 591e6ab5 2011-05-19 reyk free(rdr);
169 591e6ab5 2011-05-19 reyk }
170 591e6ab5 2011-05-19 reyk env->sc_rdrcount = 0;
171 591e6ab5 2011-05-19 reyk }
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);
176 fae05986 2014-04-22 reyk }
177 fae05986 2014-04-22 reyk }
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;
182 591e6ab5 2011-05-19 reyk }
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);
196 9261e0d8 2019-05-31 reyk }
197 b04f28f2 2021-12-05 jsg free(proto);
198 591e6ab5 2011-05-19 reyk }
199 591e6ab5 2011-05-19 reyk env->sc_protocount = 0;
200 591e6ab5 2011-05-19 reyk }
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);
207 591e6ab5 2011-05-19 reyk free(nr);
208 591e6ab5 2011-05-19 reyk env->sc_routecount--;
209 591e6ab5 2011-05-19 reyk }
210 591e6ab5 2011-05-19 reyk free(rt);
211 591e6ab5 2011-05-19 reyk }
212 591e6ab5 2011-05-19 reyk env->sc_routercount = 0;
213 591e6ab5 2011-05-19 reyk }
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);
219 591e6ab5 2011-05-19 reyk free(nr);
220 591e6ab5 2011-05-19 reyk }
221 591e6ab5 2011-05-19 reyk env->sc_routecount = 0;
222 591e6ab5 2011-05-19 reyk }
223 591e6ab5 2011-05-19 reyk }
224 591e6ab5 2011-05-19 reyk
225 591e6ab5 2011-05-19 reyk int
226 591e6ab5 2011-05-19 reyk config_setreset(struct relayd *env, u_int reset)
227 591e6ab5 2011-05-19 reyk {
228 591e6ab5 2011-05-19 reyk struct privsep *ps = env->sc_ps;
229 591e6ab5 2011-05-19 reyk int id;
230 591e6ab5 2011-05-19 reyk
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)
234 591e6ab5 2011-05-19 reyk continue;
235 141b9058 2015-12-02 reyk proc_compose(ps, id, IMSG_CTL_RESET, &reset, sizeof(reset));
236 cf7bc080 2019-06-01 reyk
237 cf7bc080 2019-06-01 reyk /*
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.
242 cf7bc080 2019-06-01 reyk */
243 cf7bc080 2019-06-01 reyk proc_flush_imsg(ps, id, -1);
244 591e6ab5 2011-05-19 reyk }
245 591e6ab5 2011-05-19 reyk
246 591e6ab5 2011-05-19 reyk return (0);
247 591e6ab5 2011-05-19 reyk }
248 591e6ab5 2011-05-19 reyk
249 591e6ab5 2011-05-19 reyk int
250 591e6ab5 2011-05-19 reyk config_getreset(struct relayd *env, struct imsg *imsg)
251 591e6ab5 2011-05-19 reyk {
252 591e6ab5 2011-05-19 reyk u_int mode;
253 591e6ab5 2011-05-19 reyk
254 591e6ab5 2011-05-19 reyk IMSG_SIZE_CHECK(imsg, &mode);
255 591e6ab5 2011-05-19 reyk memcpy(&mode, imsg->data, sizeof(mode));
256 591e6ab5 2011-05-19 reyk
257 591e6ab5 2011-05-19 reyk config_purge(env, mode);
258 591e6ab5 2011-05-19 reyk
259 591e6ab5 2011-05-19 reyk return (0);
260 591e6ab5 2011-05-19 reyk }
261 591e6ab5 2011-05-19 reyk
262 591e6ab5 2011-05-19 reyk int
263 591e6ab5 2011-05-19 reyk config_getcfg(struct relayd *env, struct imsg *imsg)
264 591e6ab5 2011-05-19 reyk {
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;
269 591e6ab5 2011-05-19 reyk
270 58fc320c 2016-09-02 reyk if (IMSG_DATA_SIZE(imsg) != sizeof(struct relayd_config))
271 591e6ab5 2011-05-19 reyk return (0); /* ignore */
272 591e6ab5 2011-05-19 reyk
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));
275 591e6ab5 2011-05-19 reyk
276 c525adb9 2014-04-18 reyk what = ps->ps_what[privsep_process];
277 c525adb9 2014-04-18 reyk
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,
285 591e6ab5 2011-05-19 reyk h, child);
286 591e6ab5 2011-05-19 reyk }
287 591e6ab5 2011-05-19 reyk }
288 591e6ab5 2011-05-19 reyk }
289 591e6ab5 2011-05-19 reyk }
290 591e6ab5 2011-05-19 reyk
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);
294 c525adb9 2014-04-18 reyk }
295 591e6ab5 2011-05-19 reyk
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);
298 591e6ab5 2011-05-19 reyk
299 591e6ab5 2011-05-19 reyk return (0);
300 591e6ab5 2011-05-19 reyk }
301 591e6ab5 2011-05-19 reyk
302 591e6ab5 2011-05-19 reyk int
303 591e6ab5 2011-05-19 reyk config_settable(struct relayd *env, struct table *tb)
304 591e6ab5 2011-05-19 reyk {
305 591e6ab5 2011-05-19 reyk struct privsep *ps = env->sc_ps;
306 591e6ab5 2011-05-19 reyk struct host *host;
307 591e6ab5 2011-05-19 reyk int id, c;
308 591e6ab5 2011-05-19 reyk struct iovec iov[2];
309 591e6ab5 2011-05-19 reyk
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)
313 591e6ab5 2011-05-19 reyk continue;
314 591e6ab5 2011-05-19 reyk
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)
317 591e6ab5 2011-05-19 reyk continue;
318 591e6ab5 2011-05-19 reyk
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]);
321 591e6ab5 2011-05-19 reyk
322 591e6ab5 2011-05-19 reyk c = 0;
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);
328 591e6ab5 2011-05-19 reyk }
329 591e6ab5 2011-05-19 reyk
330 141b9058 2015-12-02 reyk proc_composev(ps, id, IMSG_CFG_TABLE, iov, c);
331 591e6ab5 2011-05-19 reyk
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));
335 591e6ab5 2011-05-19 reyk }
336 591e6ab5 2011-05-19 reyk }
337 591e6ab5 2011-05-19 reyk
338 591e6ab5 2011-05-19 reyk return (0);
339 591e6ab5 2011-05-19 reyk }
340 591e6ab5 2011-05-19 reyk
341 591e6ab5 2011-05-19 reyk int
342 591e6ab5 2011-05-19 reyk config_gettable(struct relayd *env, struct imsg *imsg)
343 591e6ab5 2011-05-19 reyk {
344 591e6ab5 2011-05-19 reyk struct table *tb;
345 591e6ab5 2011-05-19 reyk size_t sb;
346 591e6ab5 2011-05-19 reyk u_int8_t *p = imsg->data;
347 591e6ab5 2011-05-19 reyk size_t s;
348 591e6ab5 2011-05-19 reyk
349 591e6ab5 2011-05-19 reyk if ((tb = calloc(1, sizeof(*tb))) == NULL)
350 591e6ab5 2011-05-19 reyk return (-1);
351 591e6ab5 2011-05-19 reyk
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);
355 591e6ab5 2011-05-19 reyk
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) {
359 21a3e757 2011-05-19 reyk free(tb);
360 21a3e757 2011-05-19 reyk return (-1);
361 21a3e757 2011-05-19 reyk }
362 21a3e757 2011-05-19 reyk }
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) {
366 738b3cc9 2019-09-15 rob free(tb);
367 738b3cc9 2019-09-15 rob return (-1);
368 738b3cc9 2019-09-15 rob }
369 738b3cc9 2019-09-15 rob }
370 591e6ab5 2011-05-19 reyk
371 591e6ab5 2011-05-19 reyk TAILQ_INIT(&tb->hosts);
372 591e6ab5 2011-05-19 reyk TAILQ_INSERT_TAIL(env->sc_tables, tb, entry);
373 591e6ab5 2011-05-19 reyk
374 591e6ab5 2011-05-19 reyk env->sc_tablecount++;
375 591e6ab5 2011-05-19 reyk
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);
379 591e6ab5 2011-05-19 reyk
380 591e6ab5 2011-05-19 reyk return (0);
381 591e6ab5 2011-05-19 reyk }
382 591e6ab5 2011-05-19 reyk
383 591e6ab5 2011-05-19 reyk int
384 591e6ab5 2011-05-19 reyk config_gethost(struct relayd *env, struct imsg *imsg)
385 591e6ab5 2011-05-19 reyk {
386 591e6ab5 2011-05-19 reyk struct table *tb;
387 591e6ab5 2011-05-19 reyk struct host *host;
388 591e6ab5 2011-05-19 reyk
389 591e6ab5 2011-05-19 reyk if ((host = calloc(1, sizeof(*host))) == NULL)
390 591e6ab5 2011-05-19 reyk return (-1);
391 591e6ab5 2011-05-19 reyk
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));
394 591e6ab5 2011-05-19 reyk
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);
400 591e6ab5 2011-05-19 reyk }
401 591e6ab5 2011-05-19 reyk
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);
408 591e6ab5 2011-05-19 reyk }
409 591e6ab5 2011-05-19 reyk
410 591e6ab5 2011-05-19 reyk host->tablename = tb->conf.name;
411 591e6ab5 2011-05-19 reyk host->cte.s = -1;
412 591e6ab5 2011-05-19 reyk
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);
416 591e6ab5 2011-05-19 reyk
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);
420 591e6ab5 2011-05-19 reyk
421 591e6ab5 2011-05-19 reyk return (0);
422 591e6ab5 2011-05-19 reyk }
423 591e6ab5 2011-05-19 reyk
424 591e6ab5 2011-05-19 reyk int
425 591e6ab5 2011-05-19 reyk config_setrdr(struct relayd *env, struct rdr *rdr)
426 591e6ab5 2011-05-19 reyk {
427 591e6ab5 2011-05-19 reyk struct privsep *ps = env->sc_ps;
428 591e6ab5 2011-05-19 reyk struct address *virt;
429 591e6ab5 2011-05-19 reyk int id;
430 591e6ab5 2011-05-19 reyk
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)
434 591e6ab5 2011-05-19 reyk continue;
435 591e6ab5 2011-05-19 reyk
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]);
438 591e6ab5 2011-05-19 reyk
439 141b9058 2015-12-02 reyk proc_compose(ps, id, IMSG_CFG_RDR,
440 591e6ab5 2011-05-19 reyk &rdr->conf, sizeof(rdr->conf));
441 591e6ab5 2011-05-19 reyk
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));
446 591e6ab5 2011-05-19 reyk }
447 591e6ab5 2011-05-19 reyk }
448 591e6ab5 2011-05-19 reyk
449 591e6ab5 2011-05-19 reyk return (0);
450 591e6ab5 2011-05-19 reyk }
451 591e6ab5 2011-05-19 reyk
452 591e6ab5 2011-05-19 reyk int
453 591e6ab5 2011-05-19 reyk config_getrdr(struct relayd *env, struct imsg *imsg)
454 591e6ab5 2011-05-19 reyk {
455 591e6ab5 2011-05-19 reyk struct rdr *rdr;
456 591e6ab5 2011-05-19 reyk
457 591e6ab5 2011-05-19 reyk if ((rdr = calloc(1, sizeof(*rdr))) == NULL)
458 591e6ab5 2011-05-19 reyk return (-1);
459 591e6ab5 2011-05-19 reyk
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));
462 591e6ab5 2011-05-19 reyk
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__);
465 591e6ab5 2011-05-19 reyk free(rdr);
466 591e6ab5 2011-05-19 reyk return (-1);
467 591e6ab5 2011-05-19 reyk }
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;
471 591e6ab5 2011-05-19 reyk }
472 591e6ab5 2011-05-19 reyk
473 591e6ab5 2011-05-19 reyk TAILQ_INIT(&rdr->virts);
474 591e6ab5 2011-05-19 reyk TAILQ_INSERT_TAIL(env->sc_rdrs, rdr, entry);
475 591e6ab5 2011-05-19 reyk
476 591e6ab5 2011-05-19 reyk env->sc_rdrcount++;
477 591e6ab5 2011-05-19 reyk
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);
481 591e6ab5 2011-05-19 reyk
482 591e6ab5 2011-05-19 reyk return (0);
483 591e6ab5 2011-05-19 reyk }
484 591e6ab5 2011-05-19 reyk
485 591e6ab5 2011-05-19 reyk int
486 591e6ab5 2011-05-19 reyk config_getvirt(struct relayd *env, struct imsg *imsg)
487 591e6ab5 2011-05-19 reyk {
488 591e6ab5 2011-05-19 reyk struct rdr *rdr;
489 591e6ab5 2011-05-19 reyk struct address *virt;
490 591e6ab5 2011-05-19 reyk
491 591e6ab5 2011-05-19 reyk IMSG_SIZE_CHECK(imsg, virt);
492 591e6ab5 2011-05-19 reyk
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));
496 591e6ab5 2011-05-19 reyk
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);
501 591e6ab5 2011-05-19 reyk }
502 591e6ab5 2011-05-19 reyk
503 591e6ab5 2011-05-19 reyk TAILQ_INSERT_TAIL(&rdr->virts, virt, entry);
504 591e6ab5 2011-05-19 reyk
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);
508 591e6ab5 2011-05-19 reyk
509 591e6ab5 2011-05-19 reyk return (0);
510 591e6ab5 2011-05-19 reyk }
511 591e6ab5 2011-05-19 reyk
512 591e6ab5 2011-05-19 reyk int
513 591e6ab5 2011-05-19 reyk config_setrt(struct relayd *env, struct router *rt)
514 591e6ab5 2011-05-19 reyk {
515 591e6ab5 2011-05-19 reyk struct privsep *ps = env->sc_ps;
516 591e6ab5 2011-05-19 reyk struct netroute *nr;
517 591e6ab5 2011-05-19 reyk int id;
518 591e6ab5 2011-05-19 reyk
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)
522 591e6ab5 2011-05-19 reyk continue;
523 591e6ab5 2011-05-19 reyk
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);
526 591e6ab5 2011-05-19 reyk
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));
529 591e6ab5 2011-05-19 reyk
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));
533 591e6ab5 2011-05-19 reyk }
534 591e6ab5 2011-05-19 reyk }
535 591e6ab5 2011-05-19 reyk
536 591e6ab5 2011-05-19 reyk return (0);
537 591e6ab5 2011-05-19 reyk }
538 591e6ab5 2011-05-19 reyk
539 591e6ab5 2011-05-19 reyk int
540 591e6ab5 2011-05-19 reyk config_getrt(struct relayd *env, struct imsg *imsg)
541 591e6ab5 2011-05-19 reyk {
542 591e6ab5 2011-05-19 reyk struct router *rt;
543 591e6ab5 2011-05-19 reyk
544 591e6ab5 2011-05-19 reyk if ((rt = calloc(1, sizeof(*rt))) == NULL)
545 591e6ab5 2011-05-19 reyk return (-1);
546 591e6ab5 2011-05-19 reyk
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));
549 591e6ab5 2011-05-19 reyk
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__);
552 591e6ab5 2011-05-19 reyk free(rt);
553 591e6ab5 2011-05-19 reyk return (-1);
554 591e6ab5 2011-05-19 reyk }
555 591e6ab5 2011-05-19 reyk
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);
558 591e6ab5 2011-05-19 reyk
559 591e6ab5 2011-05-19 reyk env->sc_routercount++;
560 591e6ab5 2011-05-19 reyk
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);
564 591e6ab5 2011-05-19 reyk
565 591e6ab5 2011-05-19 reyk return (0);
566 591e6ab5 2011-05-19 reyk }
567 591e6ab5 2011-05-19 reyk
568 591e6ab5 2011-05-19 reyk int
569 591e6ab5 2011-05-19 reyk config_getroute(struct relayd *env, struct imsg *imsg)
570 591e6ab5 2011-05-19 reyk {
571 591e6ab5 2011-05-19 reyk struct router *rt;
572 591e6ab5 2011-05-19 reyk struct netroute *nr;
573 591e6ab5 2011-05-19 reyk
574 591e6ab5 2011-05-19 reyk if ((nr = calloc(1, sizeof(*nr))) == NULL)
575 591e6ab5 2011-05-19 reyk return (-1);
576 591e6ab5 2011-05-19 reyk
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));
579 591e6ab5 2011-05-19 reyk
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);
583 591e6ab5 2011-05-19 reyk free(nr);
584 591e6ab5 2011-05-19 reyk return (-1);
585 591e6ab5 2011-05-19 reyk }
586 591e6ab5 2011-05-19 reyk
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__);
589 591e6ab5 2011-05-19 reyk free(nr);
590 591e6ab5 2011-05-19 reyk return (-1);
591 591e6ab5 2011-05-19 reyk }
592 591e6ab5 2011-05-19 reyk
593 591e6ab5 2011-05-19 reyk nr->nr_router = rt;
594 591e6ab5 2011-05-19 reyk
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);
597 591e6ab5 2011-05-19 reyk
598 591e6ab5 2011-05-19 reyk env->sc_routecount++;
599 591e6ab5 2011-05-19 reyk
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);
603 591e6ab5 2011-05-19 reyk
604 591e6ab5 2011-05-19 reyk return (0);
605 591e6ab5 2011-05-19 reyk }
606 591e6ab5 2011-05-19 reyk
607 591e6ab5 2011-05-19 reyk int
608 591e6ab5 2011-05-19 reyk config_setproto(struct relayd *env, struct protocol *proto)
609 591e6ab5 2011-05-19 reyk {
610 591e6ab5 2011-05-19 reyk struct privsep *ps = env->sc_ps;
611 591e6ab5 2011-05-19 reyk int id;
612 69fde657 2014-07-09 reyk struct iovec iov[IOV_MAX];
613 591e6ab5 2011-05-19 reyk size_t c;
614 591e6ab5 2011-05-19 reyk
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)
618 591e6ab5 2011-05-19 reyk continue;
619 591e6ab5 2011-05-19 reyk
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]);
622 591e6ab5 2011-05-19 reyk
623 591e6ab5 2011-05-19 reyk c = 0;
624 591e6ab5 2011-05-19 reyk iov[c].iov_base = proto;
625 591e6ab5 2011-05-19 reyk iov[c++].iov_len = sizeof(*proto);
626 591e6ab5 2011-05-19 reyk
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;
630 591e6ab5 2011-05-19 reyk }
631 591e6ab5 2011-05-19 reyk
632 141b9058 2015-12-02 reyk proc_composev(ps, id, IMSG_CFG_PROTO, iov, c);
633 69fde657 2014-07-09 reyk }
634 591e6ab5 2011-05-19 reyk
635 69fde657 2014-07-09 reyk return (0);
636 69fde657 2014-07-09 reyk }
637 69fde657 2014-07-09 reyk
638 69fde657 2014-07-09 reyk int
639 69fde657 2014-07-09 reyk config_setrule(struct relayd *env, struct protocol *proto)
640 69fde657 2014-07-09 reyk {
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];
644 69fde657 2014-07-09 reyk int id;
645 69fde657 2014-07-09 reyk size_t c, i;
646 69fde657 2014-07-09 reyk
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)
650 69fde657 2014-07-09 reyk continue;
651 69fde657 2014-07-09 reyk
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]);
654 69fde657 2014-07-09 reyk
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));
659 69fde657 2014-07-09 reyk c = 0;
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;
670 69fde657 2014-07-09 reyk } else
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;
679 69fde657 2014-07-09 reyk } else
680 69fde657 2014-07-09 reyk rule->rule_ctl.kvlen[i].value = -1;
681 69fde657 2014-07-09 reyk }
682 69fde657 2014-07-09 reyk
683 141b9058 2015-12-02 reyk proc_composev(ps, id, IMSG_CFG_RULE, iov, c);
684 69fde657 2014-07-09 reyk }
685 591e6ab5 2011-05-19 reyk }
686 591e6ab5 2011-05-19 reyk
687 591e6ab5 2011-05-19 reyk return (0);
688 591e6ab5 2011-05-19 reyk }
689 591e6ab5 2011-05-19 reyk
690 591e6ab5 2011-05-19 reyk int
691 591e6ab5 2011-05-19 reyk config_getproto(struct relayd *env, struct imsg *imsg)
692 591e6ab5 2011-05-19 reyk {
693 591e6ab5 2011-05-19 reyk struct protocol *proto;
694 591e6ab5 2011-05-19 reyk size_t styl;
695 21a3e757 2011-05-19 reyk size_t s;
696 21a3e757 2011-05-19 reyk u_int8_t *p = imsg->data;
697 591e6ab5 2011-05-19 reyk
698 591e6ab5 2011-05-19 reyk if ((proto = calloc(1, sizeof(*proto))) == NULL)
699 591e6ab5 2011-05-19 reyk return (-1);
700 591e6ab5 2011-05-19 reyk
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);
704 591e6ab5 2011-05-19 reyk
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);
711 21a3e757 2011-05-19 reyk }
712 21a3e757 2011-05-19 reyk }
713 591e6ab5 2011-05-19 reyk
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;
717 591e6ab5 2011-05-19 reyk
718 591e6ab5 2011-05-19 reyk TAILQ_INSERT_TAIL(env->sc_protos, proto, entry);
719 591e6ab5 2011-05-19 reyk
720 591e6ab5 2011-05-19 reyk env->sc_protocount++;
721 591e6ab5 2011-05-19 reyk
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);
725 591e6ab5 2011-05-19 reyk
726 591e6ab5 2011-05-19 reyk return (0);
727 591e6ab5 2011-05-19 reyk }
728 591e6ab5 2011-05-19 reyk
729 591e6ab5 2011-05-19 reyk int
730 69fde657 2014-07-09 reyk config_getrule(struct relayd *env, struct imsg *imsg)
731 591e6ab5 2011-05-19 reyk {
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;
737 591e6ab5 2011-05-19 reyk
738 69fde657 2014-07-09 reyk if ((rule = calloc(1, sizeof(*rule))) == NULL)
739 69fde657 2014-07-09 reyk return (-1);
740 591e6ab5 2011-05-19 reyk
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;
745 591e6ab5 2011-05-19 reyk
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);
749 69fde657 2014-07-09 reyk }
750 591e6ab5 2011-05-19 reyk
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); \
760 69fde657 2014-07-09 reyk } \
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; \
763 69fde657 2014-07-09 reyk \
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); \
768 69fde657 2014-07-09 reyk } \
769 69fde657 2014-07-09 reyk }
770 591e6ab5 2011-05-19 reyk
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);
776 591e6ab5 2011-05-19 reyk }
777 591e6ab5 2011-05-19 reyk
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);
780 591e6ab5 2011-05-19 reyk
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);
783 69fde657 2014-07-09 reyk
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);
786 69fde657 2014-07-09 reyk
787 69fde657 2014-07-09 reyk rule->rule_id = proto->rulecount++;
788 69fde657 2014-07-09 reyk
789 69fde657 2014-07-09 reyk TAILQ_INSERT_TAIL(&proto->rules, rule, rule_entry);
790 69fde657 2014-07-09 reyk
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);
794 591e6ab5 2011-05-19 reyk
795 591e6ab5 2011-05-19 reyk return (0);
796 591e6ab5 2011-05-19 reyk }
797 591e6ab5 2011-05-19 reyk
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)
801 ce78c3f2 2017-11-27 claudio {
802 ce78c3f2 2017-11-27 claudio struct ctl_relayfd rfd;
803 ce78c3f2 2017-11-27 claudio int fd;
804 ce78c3f2 2017-11-27 claudio
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;
808 ce78c3f2 2017-11-27 claudio
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);
814 ce78c3f2 2017-11-27 claudio
815 ce78c3f2 2017-11-27 claudio return (0);
816 ce78c3f2 2017-11-27 claudio }
817 ce78c3f2 2017-11-27 claudio
818 591e6ab5 2011-05-19 reyk int
819 591e6ab5 2011-05-19 reyk config_setrelay(struct relayd *env, struct relay *rlay)
820 591e6ab5 2011-05-19 reyk {
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;
826 0f7a5e2e 2012-10-03 reyk int id;
827 0f7a5e2e 2012-10-03 reyk int fd, n, m;
828 3bb18274 2014-02-24 jsg struct iovec iov[6];
829 0f7a5e2e 2012-10-03 reyk size_t c;
830 c525adb9 2014-04-18 reyk u_int what;
831 591e6ab5 2011-05-19 reyk
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);
835 591e6ab5 2011-05-19 reyk
836 591e6ab5 2011-05-19 reyk for (id = 0; id < PROC_MAX; id++) {
837 c525adb9 2014-04-18 reyk what = ps->ps_what[id];
838 c525adb9 2014-04-18 reyk
839 c525adb9 2014-04-18 reyk if ((what & CONFIG_RELAYS) == 0 || id == privsep_process)
840 591e6ab5 2011-05-19 reyk continue;
841 591e6ab5 2011-05-19 reyk
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);
844 591e6ab5 2011-05-19 reyk
845 c525adb9 2014-04-18 reyk memcpy(&rl, &rlay->rl_conf, sizeof(rl));
846 c525adb9 2014-04-18 reyk
847 591e6ab5 2011-05-19 reyk c = 0;
848 c525adb9 2014-04-18 reyk iov[c].iov_base = &rl;
849 c525adb9 2014-04-18 reyk iov[c++].iov_len = sizeof(rl);
850 ce78c3f2 2017-11-27 claudio
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;
855 fae05986 2014-04-22 reyk } else
856 096ff28b 2014-12-12 reyk rl.tls_cakey_len = 0;
857 591e6ab5 2011-05-19 reyk
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 */
860 591e6ab5 2011-05-19 reyk n = -1;
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);
871 4b93801a 2016-11-24 reyk }
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);
878 4b93801a 2016-11-24 reyk }
879 591e6ab5 2011-05-19 reyk }
880 591e6ab5 2011-05-19 reyk } else {
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);
887 4b93801a 2016-11-24 reyk }
888 591e6ab5 2011-05-19 reyk }
889 0f7a5e2e 2012-10-03 reyk
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)
893 fe4913ec 2019-05-31 reyk continue;
894 fe4913ec 2019-05-31 reyk n = -1;
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);
905 fe4913ec 2019-05-31 reyk }
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);
915 0c91187d 2019-06-26 reyk }
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);
925 fe4913ec 2019-05-31 reyk }
926 fe4913ec 2019-05-31 reyk }
927 fe4913ec 2019-05-31 reyk }
928 ce78c3f2 2017-11-27 claudio
929 fe4913ec 2019-05-31 reyk /* CA certs */
930 ce78c3f2 2017-11-27 claudio if (what & CONFIG_CERTS) {
931 ce78c3f2 2017-11-27 claudio n = -1;
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);
942 ce78c3f2 2017-11-27 claudio }
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);
951 ce78c3f2 2017-11-27 claudio }
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);
959 c4efe747 2024-10-28 tb return (-1);
960 c4efe747 2024-10-28 tb }
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);
967 ce78c3f2 2017-11-27 claudio }
968 ce78c3f2 2017-11-27 claudio }
969 ce78c3f2 2017-11-27 claudio }
970 ce78c3f2 2017-11-27 claudio
971 c525adb9 2014-04-18 reyk if ((what & CONFIG_TABLES) == 0)
972 c525adb9 2014-04-18 reyk continue;
973 c525adb9 2014-04-18 reyk
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;
980 0f7a5e2e 2012-10-03 reyk
981 0f7a5e2e 2012-10-03 reyk c = 0;
982 0f7a5e2e 2012-10-03 reyk iov[c].iov_base = &crt;
983 0f7a5e2e 2012-10-03 reyk iov[c++].iov_len = sizeof(crt);
984 0f7a5e2e 2012-10-03 reyk
985 141b9058 2015-12-02 reyk proc_composev(ps, id, IMSG_CFG_RELAY_TABLE, iov, c);
986 0f7a5e2e 2012-10-03 reyk }
987 591e6ab5 2011-05-19 reyk }
988 591e6ab5 2011-05-19 reyk
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;
993 4b93801a 2016-11-24 reyk }
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;
997 c4efe747 2024-10-28 tb }
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;
1001 ce78c3f2 2017-11-27 claudio }
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;
1005 ce78c3f2 2017-11-27 claudio }
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)
1008 fe4913ec 2019-05-31 reyk continue;
1009 591e6ab5 2011-05-19 reyk
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;
1013 fe4913ec 2019-05-31 reyk }
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;
1017 fe4913ec 2019-05-31 reyk }
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;
1021 0c91187d 2019-06-26 reyk }
1022 fe4913ec 2019-05-31 reyk }
1023 fe4913ec 2019-05-31 reyk
1024 591e6ab5 2011-05-19 reyk return (0);
1025 591e6ab5 2011-05-19 reyk }
1026 591e6ab5 2011-05-19 reyk
1027 591e6ab5 2011-05-19 reyk int
1028 591e6ab5 2011-05-19 reyk config_getrelay(struct relayd *env, struct imsg *imsg)
1029 591e6ab5 2011-05-19 reyk {
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;
1033 591e6ab5 2011-05-19 reyk size_t s;
1034 591e6ab5 2011-05-19 reyk
1035 591e6ab5 2011-05-19 reyk if ((rlay = calloc(1, sizeof(*rlay))) == NULL)
1036 591e6ab5 2011-05-19 reyk return (-1);
1037 591e6ab5 2011-05-19 reyk
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);
1041 591e6ab5 2011-05-19 reyk
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;
1046 591e6ab5 2011-05-19 reyk
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;
1054 591e6ab5 2011-05-19 reyk }
1055 591e6ab5 2011-05-19 reyk }
1056 591e6ab5 2011-05-19 reyk
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;
1061 591e6ab5 2011-05-19 reyk }
1062 591e6ab5 2011-05-19 reyk
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;
1068 03668b6b 2013-05-30 reyk }
1069 591e6ab5 2011-05-19 reyk
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);
1072 591e6ab5 2011-05-19 reyk
1073 591e6ab5 2011-05-19 reyk env->sc_relaycount++;
1074 591e6ab5 2011-05-19 reyk
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);
1078 591e6ab5 2011-05-19 reyk
1079 591e6ab5 2011-05-19 reyk return (0);
1080 591e6ab5 2011-05-19 reyk
1081 591e6ab5 2011-05-19 reyk fail:
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);
1086 591e6ab5 2011-05-19 reyk }
1087 0f7a5e2e 2012-10-03 reyk
1088 0f7a5e2e 2012-10-03 reyk int
1089 0f7a5e2e 2012-10-03 reyk config_getrelaytable(struct relayd *env, struct imsg *imsg)
1090 0f7a5e2e 2012-10-03 reyk {
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;
1096 0f7a5e2e 2012-10-03 reyk
1097 0f7a5e2e 2012-10-03 reyk IMSG_SIZE_CHECK(imsg, &crt);
1098 0f7a5e2e 2012-10-03 reyk memcpy(&crt, p, sizeof(crt));
1099 0f7a5e2e 2012-10-03 reyk
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;
1103 0f7a5e2e 2012-10-03 reyk }
1104 0f7a5e2e 2012-10-03 reyk
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;
1108 0f7a5e2e 2012-10-03 reyk }
1109 0f7a5e2e 2012-10-03 reyk
1110 0f7a5e2e 2012-10-03 reyk if ((rlt = calloc(1, sizeof(*rlt))) == NULL)
1111 0f7a5e2e 2012-10-03 reyk goto fail;
1112 0f7a5e2e 2012-10-03 reyk
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;
1116 0f7a5e2e 2012-10-03 reyk
1117 0f7a5e2e 2012-10-03 reyk TAILQ_INSERT_TAIL(&rlay->rl_tables, rlt, rlt_entry);
1118 0f7a5e2e 2012-10-03 reyk
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);
1122 0f7a5e2e 2012-10-03 reyk
1123 0f7a5e2e 2012-10-03 reyk return (0);
1124 0f7a5e2e 2012-10-03 reyk
1125 0f7a5e2e 2012-10-03 reyk fail:
1126 ba24b6a0 2015-12-07 mmcc free(rlt);
1127 0f7a5e2e 2012-10-03 reyk return (-1);
1128 0f7a5e2e 2012-10-03 reyk }
1129 ce78c3f2 2017-11-27 claudio
1130 ce78c3f2 2017-11-27 claudio int
1131 ce78c3f2 2017-11-27 claudio config_getrelayfd(struct relayd *env, struct imsg *imsg)
1132 ce78c3f2 2017-11-27 claudio {
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;
1137 ce78c3f2 2017-11-27 claudio
1138 ce78c3f2 2017-11-27 claudio IMSG_SIZE_CHECK(imsg, &crfd);
1139 ce78c3f2 2017-11-27 claudio memcpy(&crfd, p, sizeof(crfd));
1140 ce78c3f2 2017-11-27 claudio
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;
1149 fe4913ec 2019-05-31 reyk }
1150 fe4913ec 2019-05-31 reyk /* FALLTHROUGH */
1151 fe4913ec 2019-05-31 reyk default:
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);
1155 fe4913ec 2019-05-31 reyk }
1156 fe4913ec 2019-05-31 reyk break;
1157 ce78c3f2 2017-11-27 claudio }
1158 ce78c3f2 2017-11-27 claudio
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);
1162 ce78c3f2 2017-11-27 claudio break;
1163 fe4913ec 2019-05-31 reyk case RELAY_FD_KEY:
1164 754759d6 2024-01-17 claudio cert->cert_key_fd = imsg_get_fd(imsg);
1165 fe4913ec 2019-05-31 reyk break;
1166 0c91187d 2019-06-26 reyk case RELAY_FD_OCSP:
1167 754759d6 2024-01-17 claudio cert->cert_ocsp_fd = imsg_get_fd(imsg);
1168 0c91187d 2019-06-26 reyk break;
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);
1171 ce78c3f2 2017-11-27 claudio break;
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);
1174 ce78c3f2 2017-11-27 claudio break;
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);
1177 c4efe747 2024-10-28 tb break;
1178 ce78c3f2 2017-11-27 claudio }
1179 ce78c3f2 2017-11-27 claudio
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);
1183 ce78c3f2 2017-11-27 claudio
1184 ce78c3f2 2017-11-27 claudio return (0);
1185 ce78c3f2 2017-11-27 claudio }