1 /* $OpenBSD: config.c,v 1.65 2024/01/17 08:22:40 claudio Exp $ */
2
3 /*
4 * Copyright (c) 2011 - 2015 Reyk Floeter <reyk@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #include <sys/types.h>
20 #include <sys/queue.h>
21 #include <sys/socket.h>
22 #include <sys/un.h>
23 #include <sys/tree.h>
24 #include <sys/time.h>
25 #include <sys/uio.h>
26
27 #include <unistd.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <string.h>
31 #include <imsg.h>
32
33 #include "httpd.h"
34
35 int config_getserver_config(struct httpd *, struct server *,
36 struct imsg *);
37 int config_getserver_auth(struct httpd *, struct server_config *);
38
39 int
config_init(struct httpd * env)40 config_init(struct httpd *env)
41 {
42 struct privsep *ps = env->sc_ps;
43 unsigned int what;
44
45 /* Global configuration */
46 if (privsep_process == PROC_PARENT)
47 env->sc_prefork_server = SERVER_NUMPROC;
48
49 ps->ps_what[PROC_PARENT] = CONFIG_ALL;
50 ps->ps_what[PROC_SERVER] =
51 CONFIG_SERVERS|CONFIG_MEDIA|CONFIG_AUTH;
52 ps->ps_what[PROC_LOGGER] = CONFIG_SERVERS;
53
54 (void)strlcpy(env->sc_errdocroot, "",
55 sizeof(env->sc_errdocroot));
56
57 /* Other configuration */
58 what = ps->ps_what[privsep_process];
59
60 if (what & CONFIG_SERVERS) {
61 if ((env->sc_servers =
62 calloc(1, sizeof(*env->sc_servers))) == NULL)
63 return (-1);
64 TAILQ_INIT(env->sc_servers);
65 }
66
67 if (what & CONFIG_MEDIA) {
68 if ((env->sc_mediatypes =
69 calloc(1, sizeof(*env->sc_mediatypes))) == NULL)
70 return (-1);
71 RB_INIT(env->sc_mediatypes);
72 }
73
74 if (what & CONFIG_AUTH) {
75 if ((env->sc_auth =
76 calloc(1, sizeof(*env->sc_auth))) == NULL)
77 return (-1);
78 TAILQ_INIT(env->sc_auth);
79 }
80
81 return (0);
82 }
83
84 void
config_purge(struct httpd * env,unsigned int reset)85 config_purge(struct httpd *env, unsigned int reset)
86 {
87 struct privsep *ps = env->sc_ps;
88 struct server *srv;
89 struct auth *auth;
90 unsigned int what;
91
92 what = ps->ps_what[privsep_process] & reset;
93
94 if (what & CONFIG_SERVERS && env->sc_servers != NULL) {
95 while ((srv = TAILQ_FIRST(env->sc_servers)) != NULL)
96 server_purge(srv);
97 }
98
99 if (what & CONFIG_MEDIA && env->sc_mediatypes != NULL)
100 media_purge(env->sc_mediatypes);
101
102 if (what & CONFIG_AUTH && env->sc_auth != NULL) {
103 while ((auth = TAILQ_FIRST(env->sc_auth)) != NULL) {
104 auth_free(env->sc_auth, auth);
105 free(auth);
106 }
107 }
108 }
109
110 int
config_setreset(struct httpd * env,unsigned int reset)111 config_setreset(struct httpd *env, unsigned int reset)
112 {
113 struct privsep *ps = env->sc_ps;
114 int id;
115
116 for (id = 0; id < PROC_MAX; id++) {
117 if ((reset & ps->ps_what[id]) == 0 ||
118 id == privsep_process)
119 continue;
120 proc_compose(ps, id, IMSG_CTL_RESET,
121 &reset, sizeof(reset));
122 }
123
124 return (0);
125 }
126
127 int
config_getreset(struct httpd * env,struct imsg * imsg)128 config_getreset(struct httpd *env, struct imsg *imsg)
129 {
130 unsigned int mode;
131
132 IMSG_SIZE_CHECK(imsg, &mode);
133 memcpy(&mode, imsg->data, sizeof(mode));
134
135 config_purge(env, mode);
136
137 return (0);
138 }
139
140 int
config_getcfg(struct httpd * env,struct imsg * imsg)141 config_getcfg(struct httpd *env, struct imsg *imsg)
142 {
143 struct ctl_flags cf;
144
145 if (IMSG_DATA_SIZE(imsg) != sizeof(cf))
146 return (0); /* ignore */
147
148 /* Update runtime flags */
149 memcpy(&cf, imsg->data, sizeof(cf));
150 env->sc_opts = cf.cf_opts;
151 env->sc_flags = cf.cf_flags;
152 memcpy(env->sc_tls_sid, cf.cf_tls_sid, sizeof(env->sc_tls_sid));
153
154 if (privsep_process != PROC_PARENT)
155 proc_compose(env->sc_ps, PROC_PARENT,
156 IMSG_CFG_DONE, NULL, 0);
157
158 return (0);
159 }
160
161 int
config_setserver(struct httpd * env,struct server * srv)162 config_setserver(struct httpd *env, struct server *srv)
163 {
164 struct privsep *ps = env->sc_ps;
165 struct server_config s;
166 int id;
167 int fd, n, m;
168 struct iovec iov[6];
169 size_t c;
170 unsigned int what;
171
172 /* opens listening sockets etc. */
173 if (server_privinit(srv) == -1)
174 return (-1);
175
176 for (id = 0; id < PROC_MAX; id++) {
177 what = ps->ps_what[id];
178
179 if ((what & CONFIG_SERVERS) == 0 || id == privsep_process)
180 continue;
181
182 DPRINTF("%s: sending %s \"%s[%u]\" to %s fd %d", __func__,
183 (srv->srv_conf.flags & SRVFLAG_LOCATION) ?
184 "location" : "server",
185 srv->srv_conf.name, srv->srv_conf.id,
186 ps->ps_title[id], srv->srv_s);
187
188 memcpy(&s, &srv->srv_conf, sizeof(s));
189
190 c = 0;
191 iov[c].iov_base = &s;
192 iov[c++].iov_len = sizeof(s);
193 if (srv->srv_conf.return_uri_len != 0) {
194 iov[c].iov_base = srv->srv_conf.return_uri;
195 iov[c++].iov_len = srv->srv_conf.return_uri_len;
196 }
197
198 if (id == PROC_SERVER &&
199 (srv->srv_conf.flags & SRVFLAG_LOCATION) == 0) {
200 /* XXX imsg code will close the fd after 1st call */
201 n = -1;
202 proc_range(ps, id, &n, &m);
203 for (n = 0; n < m; n++) {
204 if (srv->srv_s == -1)
205 fd = -1;
206 else if ((fd = dup(srv->srv_s)) == -1)
207 return (-1);
208 if (proc_composev_imsg(ps, id, n,
209 IMSG_CFG_SERVER, -1, fd, iov, c) != 0) {
210 log_warn("%s: failed to compose "
211 "IMSG_CFG_SERVER imsg for `%s'",
212 __func__, srv->srv_conf.name);
213 return (-1);
214 }
215
216 /* Prevent fd exhaustion in the parent. */
217 if (proc_flush_imsg(ps, id, n) == -1) {
218 log_warn("%s: failed to flush "
219 "IMSG_CFG_SERVER imsg for `%s'",
220 __func__, srv->srv_conf.name);
221 return (-1);
222 }
223 }
224
225 /* Configure TLS if necessary. */
226 config_setserver_tls(env, srv);
227 } else {
228 if (proc_composev(ps, id, IMSG_CFG_SERVER,
229 iov, c) != 0) {
230 log_warn("%s: failed to compose "
231 "IMSG_CFG_SERVER imsg for `%s'",
232 __func__, srv->srv_conf.name);
233 return (-1);
234 }
235
236 /* Configure FCGI parameters if necessary. */
237 config_setserver_fcgiparams(env, srv);
238 }
239 }
240
241 /* Close server socket early to prevent fd exhaustion in the parent. */
242 if (srv->srv_s != -1) {
243 close(srv->srv_s);
244 srv->srv_s = -1;
245 }
246
247 explicit_bzero(&srv->srv_conf.tls_ticket_key,
248 sizeof(srv->srv_conf.tls_ticket_key));
249
250 return (0);
251 }
252
253 static int
config_settls(struct httpd * env,struct server * srv,enum tls_config_type type,const char * label,uint8_t * data,size_t len)254 config_settls(struct httpd *env, struct server *srv, enum tls_config_type type,
255 const char *label, uint8_t *data, size_t len)
256 {
257 struct privsep *ps = env->sc_ps;
258 struct server_config *srv_conf = &srv->srv_conf;
259 struct tls_config tls;
260 struct iovec iov[2];
261 size_t c;
262
263 if (data == NULL || len == 0)
264 return (0);
265
266 DPRINTF("%s: sending tls %s for \"%s[%u]\" to %s fd %d", __func__,
267 label, srv_conf->name, srv_conf->id, ps->ps_title[PROC_SERVER],
268 srv->srv_s);
269
270 memset(&tls, 0, sizeof(tls));
271 tls.id = srv_conf->id;
272 tls.tls_type = type;
273 tls.tls_len = len;
274 tls.tls_chunk_offset = 0;
275
276 while (len > 0) {
277 tls.tls_chunk_len = len;
278 if (tls.tls_chunk_len > (MAX_IMSG_DATA_SIZE - sizeof(tls)))
279 tls.tls_chunk_len = MAX_IMSG_DATA_SIZE - sizeof(tls);
280
281 c = 0;
282 iov[c].iov_base = &tls;
283 iov[c++].iov_len = sizeof(tls);
284 iov[c].iov_base = data;
285 iov[c++].iov_len = tls.tls_chunk_len;
286
287 if (proc_composev(ps, PROC_SERVER, IMSG_CFG_TLS, iov, c) != 0) {
288 log_warn("%s: failed to compose IMSG_CFG_TLS imsg for "
289 "`%s'", __func__, srv_conf->name);
290 return (-1);
291 }
292
293 tls.tls_chunk_offset += tls.tls_chunk_len;
294 data += tls.tls_chunk_len;
295 len -= tls.tls_chunk_len;
296 }
297
298 return (0);
299 }
300
301 int
config_getserver_fcgiparams(struct httpd * env,struct imsg * imsg)302 config_getserver_fcgiparams(struct httpd *env, struct imsg *imsg)
303 {
304 struct server *srv;
305 struct server_config *srv_conf, *iconf;
306 struct fastcgi_param *fp;
307 uint32_t id;
308 size_t c, nc, len;
309 uint8_t *p = imsg->data;
310
311 len = sizeof(nc) + sizeof(id);
312 if (IMSG_DATA_SIZE(imsg) < len) {
313 log_debug("%s: invalid message length", __func__);
314 return (-1);
315 }
316
317 memcpy(&nc, p, sizeof(nc)); /* number of params */
318 p += sizeof(nc);
319
320 memcpy(&id, p, sizeof(id)); /* server conf id */
321 srv_conf = serverconfig_byid(id);
322 p += sizeof(id);
323
324 len += nc*sizeof(*fp);
325 if (IMSG_DATA_SIZE(imsg) < len) {
326 log_debug("%s: invalid message length", __func__);
327 return (-1);
328 }
329
330 /* Find associated server config */
331 TAILQ_FOREACH(srv, env->sc_servers, srv_entry) {
332 if (srv->srv_conf.id == id) {
333 srv_conf = &srv->srv_conf;
334 break;
335 }
336 TAILQ_FOREACH(iconf, &srv->srv_hosts, entry) {
337 if (iconf->id == id) {
338 srv_conf = iconf;
339 break;
340 }
341 }
342 }
343
344 /* Fetch FCGI parameters */
345 for (c = 0; c < nc; c++) {
346 if ((fp = calloc(1, sizeof(*fp))) == NULL)
347 fatalx("fcgiparams out of memory");
348 memcpy(fp, p, sizeof(*fp));
349 TAILQ_INSERT_HEAD(&srv_conf->fcgiparams, fp, entry);
350
351 p += sizeof(*fp);
352 }
353
354 return (0);
355 }
356
357 int
config_setserver_fcgiparams(struct httpd * env,struct server * srv)358 config_setserver_fcgiparams(struct httpd *env, struct server *srv)
359 {
360 struct privsep *ps = env->sc_ps;
361 struct server_config *srv_conf = &srv->srv_conf;
362 struct fastcgi_param *fp;
363 struct iovec *iov;
364 size_t c = 0, nc = 0;
365
366 DPRINTF("%s: sending fcgiparam for \"%s[%u]\" to %s fd %d", __func__,
367 srv_conf->name, srv_conf->id, ps->ps_title[PROC_SERVER],
368 srv->srv_s);
369
370 if (TAILQ_EMPTY(&srv_conf->fcgiparams)) /* nothing to do */
371 return (0);
372
373 TAILQ_FOREACH(fp, &srv_conf->fcgiparams, entry) {
374 nc++;
375 }
376 if ((iov = calloc(nc + 2, sizeof(*iov))) == NULL)
377 return (-1);
378
379 iov[c].iov_base = &nc; /* number of params */
380 iov[c++].iov_len = sizeof(nc);
381 iov[c].iov_base = &srv_conf->id; /* server config id */
382 iov[c++].iov_len = sizeof(srv_conf->id);
383
384 TAILQ_FOREACH(fp, &srv_conf->fcgiparams, entry) { /* push FCGI params */
385 iov[c].iov_base = fp;
386 iov[c++].iov_len = sizeof(*fp);
387 }
388 if (proc_composev(ps, PROC_SERVER, IMSG_CFG_FCGI, iov, c) != 0) {
389 log_warn("%s: failed to compose IMSG_CFG_FCGI imsg for "
390 "`%s'", __func__, srv_conf->name);
391 free(iov);
392 return (-1);
393 }
394 free(iov);
395
396 return (0);
397 }
398
399 int
config_setserver_tls(struct httpd * env,struct server * srv)400 config_setserver_tls(struct httpd *env, struct server *srv)
401 {
402 struct server_config *srv_conf = &srv->srv_conf;
403
404 if ((srv_conf->flags & SRVFLAG_TLS) == 0)
405 return (0);
406
407 log_debug("%s: configuring tls for %s", __func__, srv_conf->name);
408
409 if (config_settls(env, srv, TLS_CFG_CA, "ca", srv_conf->tls_ca,
410 srv_conf->tls_ca_len) != 0)
411 return (-1);
412
413 if (config_settls(env, srv, TLS_CFG_CERT, "cert", srv_conf->tls_cert,
414 srv_conf->tls_cert_len) != 0)
415 return (-1);
416
417 if (config_settls(env, srv, TLS_CFG_CRL, "crl", srv_conf->tls_crl,
418 srv_conf->tls_crl_len) != 0)
419 return (-1);
420
421 if (config_settls(env, srv, TLS_CFG_KEY, "key", srv_conf->tls_key,
422 srv_conf->tls_key_len) != 0)
423 return (-1);
424
425 if (config_settls(env, srv, TLS_CFG_OCSP_STAPLE, "ocsp staple",
426 srv_conf->tls_ocsp_staple, srv_conf->tls_ocsp_staple_len) != 0)
427 return (-1);
428
429 return (0);
430 }
431
432 int
config_getserver_auth(struct httpd * env,struct server_config * srv_conf)433 config_getserver_auth(struct httpd *env, struct server_config *srv_conf)
434 {
435 struct privsep *ps = env->sc_ps;
436
437 if ((ps->ps_what[privsep_process] & CONFIG_AUTH) == 0 ||
438 (srv_conf->flags & SRVFLAG_AUTH) == 0)
439 return (0);
440
441 if ((srv_conf->auth = auth_byid(env->sc_auth,
442 srv_conf->auth_id)) == NULL)
443 return (-1);
444
445 return (0);
446 }
447
448 int
config_getserver_config(struct httpd * env,struct server * srv,struct imsg * imsg)449 config_getserver_config(struct httpd *env, struct server *srv,
450 struct imsg *imsg)
451 {
452 #ifdef DEBUG
453 struct privsep *ps = env->sc_ps;
454 #endif
455 struct server_config *srv_conf, *parent;
456 uint8_t *p = imsg->data;
457 unsigned int f;
458 size_t s;
459
460 if ((srv_conf = calloc(1, sizeof(*srv_conf))) == NULL)
461 return (-1);
462
463 IMSG_SIZE_CHECK(imsg, srv_conf);
464 memcpy(srv_conf, p, sizeof(*srv_conf));
465 s = sizeof(*srv_conf);
466
467 /* Reset these variables to avoid free'ing invalid pointers */
468 serverconfig_reset(srv_conf);
469
470 TAILQ_FOREACH(parent, &srv->srv_hosts, entry) {
471 if (strcmp(parent->name, srv_conf->name) == 0)
472 break;
473 }
474 if (parent == NULL)
475 parent = &srv->srv_conf;
476
477 if (config_getserver_auth(env, srv_conf) != 0)
478 goto fail;
479
480 /*
481 * Get variable-length values for the virtual host. The tls_* ones
482 * aren't needed in the virtual hosts unless we implement SNI.
483 */
484 if (srv_conf->return_uri_len != 0) {
485 if ((srv_conf->return_uri = get_data(p + s,
486 srv_conf->return_uri_len)) == NULL)
487 goto fail;
488 s += srv_conf->return_uri_len;
489 }
490
491 if (srv_conf->flags & SRVFLAG_LOCATION) {
492 /* Inherit configuration from the parent */
493 f = SRVFLAG_INDEX|SRVFLAG_NO_INDEX;
494 if ((srv_conf->flags & f) == 0) {
495 srv_conf->flags |= parent->flags & f;
496 (void)strlcpy(srv_conf->index, parent->index,
497 sizeof(srv_conf->index));
498 }
499
500 f = SRVFLAG_AUTO_INDEX|SRVFLAG_NO_AUTO_INDEX;
501 if ((srv_conf->flags & f) == 0)
502 srv_conf->flags |= parent->flags & f;
503
504 f = SRVFLAG_ROOT;
505 if ((srv_conf->flags & f) == 0) {
506 srv_conf->flags |= parent->flags & f;
507 (void)strlcpy(srv_conf->root, parent->root,
508 sizeof(srv_conf->root));
509 }
510
511 f = SRVFLAG_FCGI|SRVFLAG_NO_FCGI;
512 if ((srv_conf->flags & f) == 0)
513 srv_conf->flags |= parent->flags & f;
514
515 f = SRVFLAG_LOG|SRVFLAG_NO_LOG;
516 if ((srv_conf->flags & f) == 0) {
517 srv_conf->flags |= parent->flags & f;
518 srv_conf->logformat = parent->logformat;
519 }
520
521 f = SRVFLAG_SYSLOG|SRVFLAG_NO_SYSLOG;
522 if ((srv_conf->flags & f) == 0)
523 srv_conf->flags |= parent->flags & f;
524
525 f = SRVFLAG_AUTH|SRVFLAG_NO_AUTH;
526 if ((srv_conf->flags & f) == 0) {
527 srv_conf->flags |= parent->flags & f;
528 srv_conf->auth = parent->auth;
529 srv_conf->auth_id = parent->auth_id;
530 (void)strlcpy(srv_conf->auth_realm,
531 parent->auth_realm,
532 sizeof(srv_conf->auth_realm));
533 }
534
535 f = SRVFLAG_TLS;
536 srv_conf->flags |= parent->flags & f;
537 srv_conf->tls_flags = parent->tls_flags;
538
539 f = SRVFLAG_ACCESS_LOG;
540 if ((srv_conf->flags & f) == 0) {
541 srv_conf->flags |= parent->flags & f;
542 (void)strlcpy(srv_conf->accesslog,
543 parent->accesslog,
544 sizeof(srv_conf->accesslog));
545 }
546
547 f = SRVFLAG_ERROR_LOG;
548 if ((srv_conf->flags & f) == 0) {
549 srv_conf->flags |= parent->flags & f;
550 (void)strlcpy(srv_conf->errorlog,
551 parent->errorlog,
552 sizeof(srv_conf->errorlog));
553 }
554
555 f = SRVFLAG_BLOCK|SRVFLAG_NO_BLOCK;
556 if ((srv_conf->flags & f) == 0) {
557 free(srv_conf->return_uri);
558 srv_conf->flags |= parent->flags & f;
559 srv_conf->return_code = parent->return_code;
560 srv_conf->return_uri_len = parent->return_uri_len;
561 if (srv_conf->return_uri_len &&
562 (srv_conf->return_uri =
563 strdup(parent->return_uri)) == NULL)
564 goto fail;
565 }
566
567 f = SRVFLAG_DEFAULT_TYPE;
568 if ((srv_conf->flags & f) == 0) {
569 srv_conf->flags |= parent->flags & f;
570 memcpy(&srv_conf->default_type,
571 &parent->default_type, sizeof(struct media_type));
572 }
573
574 f = SRVFLAG_PATH_REWRITE|SRVFLAG_NO_PATH_REWRITE;
575 if ((srv_conf->flags & f) == 0) {
576 srv_conf->flags |= parent->flags & f;
577 (void)strlcpy(srv_conf->path, parent->path,
578 sizeof(srv_conf->path));
579 }
580
581 f = SRVFLAG_SERVER_HSTS;
582 srv_conf->flags |= parent->flags & f;
583 srv_conf->hsts_max_age = parent->hsts_max_age;
584 srv_conf->hsts_flags = parent->hsts_flags;
585
586 memcpy(&srv_conf->timeout, &parent->timeout,
587 sizeof(srv_conf->timeout));
588 srv_conf->maxrequests = parent->maxrequests;
589 srv_conf->maxrequestbody = parent->maxrequestbody;
590
591 srv_conf->flags |= parent->flags & SRVFLAG_ERRDOCS;
592 (void)strlcpy(srv_conf->errdocroot, parent->errdocroot,
593 sizeof(srv_conf->errdocroot));
594
595 DPRINTF("%s: %s %d location \"%s\", "
596 "parent \"%s[%u]\", flags: %s",
597 __func__, ps->ps_title[privsep_process], ps->ps_instance,
598 srv_conf->location, parent->name, parent->id,
599 printb_flags(srv_conf->flags, SRVFLAG_BITS));
600 } else {
601 /* Add a new "virtual" server */
602 DPRINTF("%s: %s %d server \"%s[%u]\", parent \"%s[%u]\", "
603 "flags: %s", __func__,
604 ps->ps_title[privsep_process], ps->ps_instance,
605 srv_conf->name, srv_conf->id, parent->name, parent->id,
606 printb_flags(srv_conf->flags, SRVFLAG_BITS));
607 }
608
609 TAILQ_INSERT_TAIL(&srv->srv_hosts, srv_conf, entry);
610
611 return (0);
612
613 fail:
614 serverconfig_free(srv_conf);
615 free(srv_conf);
616 return (-1);
617 }
618
619 int
config_getserver(struct httpd * env,struct imsg * imsg)620 config_getserver(struct httpd *env, struct imsg *imsg)
621 {
622 #ifdef DEBUG
623 struct privsep *ps = env->sc_ps;
624 #endif
625 struct server *srv = NULL;
626 struct server_config srv_conf;
627 uint8_t *p = imsg->data;
628 size_t s;
629 int fd;
630
631 IMSG_SIZE_CHECK(imsg, &srv_conf);
632 memcpy(&srv_conf, p, sizeof(srv_conf));
633 s = sizeof(srv_conf);
634
635 /* Reset these variables to avoid free'ing invalid pointers */
636 serverconfig_reset(&srv_conf);
637
638 fd = imsg_get_fd(imsg);
639
640 if ((IMSG_DATA_SIZE(imsg) - s) < (size_t)srv_conf.return_uri_len) {
641 log_debug("%s: invalid message length", __func__);
642 goto fail;
643 }
644
645 /* Check if server with matching listening socket already exists */
646 if ((srv = server_byaddr((struct sockaddr *)
647 &srv_conf.ss, srv_conf.port)) != NULL) {
648 /* Add "host" to existing listening server */
649 if (fd != -1) {
650 if (srv->srv_s == -1)
651 srv->srv_s = fd;
652 else
653 close(fd);
654 }
655 return (config_getserver_config(env, srv, imsg));
656 }
657
658 if (srv_conf.flags & SRVFLAG_LOCATION)
659 fatalx("invalid location");
660
661 /* Otherwise create a new server */
662 if ((srv = calloc(1, sizeof(*srv))) == NULL)
663 goto fail;
664
665 memcpy(&srv->srv_conf, &srv_conf, sizeof(srv->srv_conf));
666 srv->srv_s = fd;
667
668 if (config_getserver_auth(env, &srv->srv_conf) != 0)
669 goto fail;
670
671 SPLAY_INIT(&srv->srv_clients);
672 TAILQ_INIT(&srv->srv_hosts);
673
674 /*
675 * Get all variable-length values for the parent server.
676 */
677 if (srv->srv_conf.return_uri_len != 0) {
678 if ((srv->srv_conf.return_uri = get_data(p + s,
679 srv->srv_conf.return_uri_len)) == NULL)
680 goto fail;
681 }
682
683 TAILQ_INSERT_TAIL(&srv->srv_hosts, &srv->srv_conf, entry);
684 TAILQ_INSERT_TAIL(env->sc_servers, srv, srv_entry);
685
686 DPRINTF("%s: %s %d configuration \"%s[%u]\", flags: %s", __func__,
687 ps->ps_title[privsep_process], ps->ps_instance,
688 srv->srv_conf.name, srv->srv_conf.id,
689 printb_flags(srv->srv_conf.flags, SRVFLAG_BITS));
690
691 return (0);
692
693 fail:
694 if (fd != -1)
695 close(fd);
696 if (srv != NULL)
697 serverconfig_free(&srv->srv_conf);
698 free(srv);
699
700 return (-1);
701 }
702
703 static int
config_gettls(struct httpd * env,struct server_config * srv_conf,struct tls_config * tls_conf,const char * label,uint8_t * data,size_t len,uint8_t ** outdata,size_t * outlen)704 config_gettls(struct httpd *env, struct server_config *srv_conf,
705 struct tls_config *tls_conf, const char *label, uint8_t *data, size_t len,
706 uint8_t **outdata, size_t *outlen)
707 {
708 #ifdef DEBUG
709 struct privsep *ps = env->sc_ps;
710 #endif
711
712 DPRINTF("%s: %s %d getting tls %s (%zu:%zu@%zu) for \"%s[%u]\"",
713 __func__, ps->ps_title[privsep_process], ps->ps_instance, label,
714 tls_conf->tls_len, len, tls_conf->tls_chunk_offset, srv_conf->name,
715 srv_conf->id);
716
717 if (tls_conf->tls_chunk_offset == 0) {
718 free(*outdata);
719 *outlen = 0;
720 if ((*outdata = calloc(1, tls_conf->tls_len)) == NULL)
721 goto fail;
722 *outlen = tls_conf->tls_len;
723 }
724
725 if (*outdata == NULL) {
726 log_debug("%s: tls config invalid chunk sequence", __func__);
727 goto fail;
728 }
729
730 if (*outlen != tls_conf->tls_len) {
731 log_debug("%s: tls config length mismatch (%zu != %zu)",
732 __func__, *outlen, tls_conf->tls_len);
733 goto fail;
734 }
735
736 if (len > (tls_conf->tls_len - tls_conf->tls_chunk_offset)) {
737 log_debug("%s: tls config invalid chunk length", __func__);
738 goto fail;
739 }
740
741 memcpy(*outdata + tls_conf->tls_chunk_offset, data, len);
742
743 return (0);
744
745 fail:
746 return (-1);
747 }
748
749 int
config_getserver_tls(struct httpd * env,struct imsg * imsg)750 config_getserver_tls(struct httpd *env, struct imsg *imsg)
751 {
752 struct server_config *srv_conf = NULL;
753 struct tls_config tls_conf;
754 uint8_t *p = imsg->data;
755 size_t len;
756
757 IMSG_SIZE_CHECK(imsg, &tls_conf);
758 memcpy(&tls_conf, p, sizeof(tls_conf));
759
760 len = tls_conf.tls_chunk_len;
761
762 if ((IMSG_DATA_SIZE(imsg) - sizeof(tls_conf)) < len) {
763 log_debug("%s: invalid message length", __func__);
764 goto fail;
765 }
766
767 p += sizeof(tls_conf);
768
769 if ((srv_conf = serverconfig_byid(tls_conf.id)) == NULL) {
770 log_debug("%s: server not found", __func__);
771 goto fail;
772 }
773
774 switch (tls_conf.tls_type) {
775 case TLS_CFG_CA:
776 if (config_gettls(env, srv_conf, &tls_conf, "ca", p, len,
777 &srv_conf->tls_ca, &srv_conf->tls_ca_len) != 0)
778 goto fail;
779 break;
780
781 case TLS_CFG_CERT:
782 if (config_gettls(env, srv_conf, &tls_conf, "cert", p, len,
783 &srv_conf->tls_cert, &srv_conf->tls_cert_len) != 0)
784 goto fail;
785 break;
786
787 case TLS_CFG_CRL:
788 if (config_gettls(env, srv_conf, &tls_conf, "crl", p, len,
789 &srv_conf->tls_crl, &srv_conf->tls_crl_len) != 0)
790 goto fail;
791 break;
792
793 case TLS_CFG_KEY:
794 if (config_gettls(env, srv_conf, &tls_conf, "key", p, len,
795 &srv_conf->tls_key, &srv_conf->tls_key_len) != 0)
796 goto fail;
797 break;
798
799 case TLS_CFG_OCSP_STAPLE:
800 if (config_gettls(env, srv_conf, &tls_conf, "ocsp staple",
801 p, len, &srv_conf->tls_ocsp_staple,
802 &srv_conf->tls_ocsp_staple_len) != 0)
803 goto fail;
804 break;
805
806 default:
807 log_debug("%s: unknown tls config type %i\n",
808 __func__, tls_conf.tls_type);
809 goto fail;
810 }
811
812 return (0);
813
814 fail:
815 return (-1);
816 }
817
818 int
config_setmedia(struct httpd * env,struct media_type * media)819 config_setmedia(struct httpd *env, struct media_type *media)
820 {
821 struct privsep *ps = env->sc_ps;
822 int id;
823 unsigned int what;
824
825 for (id = 0; id < PROC_MAX; id++) {
826 what = ps->ps_what[id];
827
828 if ((what & CONFIG_MEDIA) == 0 || id == privsep_process)
829 continue;
830
831 DPRINTF("%s: sending media \"%s\" to %s", __func__,
832 media->media_name, ps->ps_title[id]);
833
834 proc_compose(ps, id, IMSG_CFG_MEDIA, media, sizeof(*media));
835 }
836
837 return (0);
838 }
839
840 int
config_getmedia(struct httpd * env,struct imsg * imsg)841 config_getmedia(struct httpd *env, struct imsg *imsg)
842 {
843 #ifdef DEBUG
844 struct privsep *ps = env->sc_ps;
845 #endif
846 struct media_type media;
847 uint8_t *p = imsg->data;
848
849 IMSG_SIZE_CHECK(imsg, &media);
850 memcpy(&media, p, sizeof(media));
851
852 if (media_add(env->sc_mediatypes, &media) == NULL) {
853 log_debug("%s: failed to add media \"%s\"",
854 __func__, media.media_name);
855 return (-1);
856 }
857
858 DPRINTF("%s: %s %d received media \"%s\"", __func__,
859 ps->ps_title[privsep_process], ps->ps_instance,
860 media.media_name);
861
862 return (0);
863 }
864
865 int
config_setauth(struct httpd * env,struct auth * auth)866 config_setauth(struct httpd *env, struct auth *auth)
867 {
868 struct privsep *ps = env->sc_ps;
869 int id;
870 unsigned int what;
871
872 for (id = 0; id < PROC_MAX; id++) {
873 what = ps->ps_what[id];
874
875 if ((what & CONFIG_AUTH) == 0 || id == privsep_process)
876 continue;
877
878 DPRINTF("%s: sending auth \"%s[%u]\" to %s", __func__,
879 auth->auth_htpasswd, auth->auth_id, ps->ps_title[id]);
880
881 proc_compose(ps, id, IMSG_CFG_AUTH, auth, sizeof(*auth));
882 }
883
884 return (0);
885 }
886
887 int
config_getauth(struct httpd * env,struct imsg * imsg)888 config_getauth(struct httpd *env, struct imsg *imsg)
889 {
890 #ifdef DEBUG
891 struct privsep *ps = env->sc_ps;
892 #endif
893 struct auth auth;
894 uint8_t *p = imsg->data;
895
896 IMSG_SIZE_CHECK(imsg, &auth);
897 memcpy(&auth, p, sizeof(auth));
898
899 if (auth_add(env->sc_auth, &auth) == NULL) {
900 log_debug("%s: failed to add auth \"%s[%u]\"",
901 __func__, auth.auth_htpasswd, auth.auth_id);
902 return (-1);
903 }
904
905 DPRINTF("%s: %s %d received auth \"%s[%u]\"", __func__,
906 ps->ps_title[privsep_process], ps->ps_instance,
907 auth.auth_htpasswd, auth.auth_id);
908
909 return (0);
910 }
911