From: Martijn van Duren Subject: smtpd: create startup.c To: tech@openbsd.org Date: Wed, 1 Jul 2026 15:23:46 +0200 Hello tech@, Here's a followup to the shuffling of the deckchairs diff. This diff is basically more of the same, but creates a new startup.c for functions and variables that would cause issues for smtpctl when added to util.c. I realize that startup.c isn't an ideal name, but since it's needed give each libexec binary their own main() function it's the best I could come up with. This diff moves the env, p_*, profiling, backend_*, smtpd_process variables, and imsg_callback, and setup_peer(), setup_proc(), imsg_wait(), load_pki_tree(), load_pki_keys(), fork_proc_backend(), and imsg_dispatch() functions into startup.c. The debug variable appears to be a dead store, so can be removed. The next step is giving each binary their own main(). OK? martijn@ diff d010102fe4efde3ee95164581695909c7c6b672a 7c135bf813cf25880851c83cbd4734bfe1ac67c3 commit - d010102fe4efde3ee95164581695909c7c6b672a commit + 7c135bf813cf25880851c83cbd4734bfe1ac67c3 blob - a6337c2bb329e27300a21ffa517a5a84d0f773c5 blob + 37b6919a9da103b0f3ce6bccfcb98f6dd5a47d6e --- usr.sbin/smtpd/smtpd/Makefile +++ usr.sbin/smtpd/smtpd/Makefile @@ -14,7 +14,7 @@ SRCS= aliases.c bounce.c ca.c compress_backend.c confi dispatcher.c proxy.c queue.c queue_backend.c report_smtp.c \ resolver.c rfc5322.c ruleset.c runq.c scheduler.c \ scheduler_backend.c smtp.c smtp_session.c smtpd.c srs.c ssl.c \ - stat_backend.c table.c to.c tree.c util.c waitq.c \ + startup.c stat_backend.c table.c to.c tree.c util.c waitq.c \ compress_gzip.c table_db.c table_getpwnam.c table_proc.c \ table_static.c queue_fs.c queue_null.c queue_proc.c \ queue_ram.c scheduler_ramqueue.c scheduler_null.c \ blob - 206cd414a29ac4acbb22b6a540c5ca2751098e90 blob + a00f8c6d79b8fea6b9071776ced8a909654aefd4 --- usr.sbin/smtpd/smtpd-ca/Makefile +++ usr.sbin/smtpd/smtpd-ca/Makefile @@ -15,7 +15,7 @@ SRCS= aliases.c bounce.c ca.c compress_backend.c confi dispatcher.c proxy.c queue.c queue_backend.c report_smtp.c \ resolver.c rfc5322.c ruleset.c runq.c scheduler.c \ scheduler_backend.c smtp.c smtp_session.c smtpd.c srs.c ssl.c \ - stat_backend.c table.c to.c tree.c util.c waitq.c \ + startup.c stat_backend.c table.c to.c tree.c util.c waitq.c \ compress_gzip.c table_db.c table_getpwnam.c table_proc.c \ table_static.c queue_fs.c queue_null.c queue_proc.c \ queue_ram.c scheduler_ramqueue.c scheduler_null.c \ blob - 22d7abdc025cccaec993ecec8f4ab7c4377fd8b3 blob + d289b421744c03b32a2296c421e9f3734cd44089 --- usr.sbin/smtpd/smtpd-control/Makefile +++ usr.sbin/smtpd/smtpd-control/Makefile @@ -15,7 +15,7 @@ SRCS= aliases.c bounce.c ca.c compress_backend.c confi dispatcher.c proxy.c queue.c queue_backend.c report_smtp.c \ resolver.c rfc5322.c ruleset.c runq.c scheduler.c \ scheduler_backend.c smtp.c smtp_session.c smtpd.c srs.c ssl.c \ - stat_backend.c table.c to.c tree.c util.c waitq.c \ + startup.c stat_backend.c table.c to.c tree.c util.c waitq.c \ compress_gzip.c table_db.c table_getpwnam.c table_proc.c \ table_static.c queue_fs.c queue_null.c queue_proc.c \ queue_ram.c scheduler_ramqueue.c scheduler_null.c \ blob - 9aa8e1c7ceb3112f7aaba17352f5b5aa3b242bf7 blob + f4c47fd8387e2bf7ee7c22a395f5e74b099be30d --- usr.sbin/smtpd/smtpd-dispatcher/Makefile +++ usr.sbin/smtpd/smtpd-dispatcher/Makefile @@ -15,7 +15,7 @@ SRCS= aliases.c bounce.c ca.c compress_backend.c confi dispatcher.c proxy.c queue.c queue_backend.c report_smtp.c \ resolver.c rfc5322.c ruleset.c runq.c scheduler.c \ scheduler_backend.c smtp.c smtp_session.c smtpd.c srs.c ssl.c \ - stat_backend.c table.c to.c tree.c util.c waitq.c \ + startup.c stat_backend.c table.c to.c tree.c util.c waitq.c \ compress_gzip.c table_db.c table_getpwnam.c table_proc.c \ table_static.c queue_fs.c queue_null.c queue_proc.c \ queue_ram.c scheduler_ramqueue.c scheduler_null.c \ blob - 03476d16571fc4fb85105215a79543bfb9882166 blob + 0b82bec27876d79e60fa80a4a65436fe3633142e --- usr.sbin/smtpd/smtpd-lka/Makefile +++ usr.sbin/smtpd/smtpd-lka/Makefile @@ -15,7 +15,7 @@ SRCS= aliases.c bounce.c ca.c compress_backend.c confi dispatcher.c proxy.c queue.c queue_backend.c report_smtp.c \ resolver.c rfc5322.c ruleset.c runq.c scheduler.c \ scheduler_backend.c smtp.c smtp_session.c smtpd.c srs.c ssl.c \ - stat_backend.c table.c to.c tree.c util.c waitq.c \ + startup.c stat_backend.c table.c to.c tree.c util.c waitq.c \ compress_gzip.c table_db.c table_getpwnam.c table_proc.c \ table_static.c queue_fs.c queue_null.c queue_proc.c \ queue_ram.c scheduler_ramqueue.c scheduler_null.c \ blob - 6fce8a91f1035dffdd28a98bb546d0ed5c62b977 blob + 7b6651dbeda248bc110f0b655118e59e23dfd9b2 --- usr.sbin/smtpd/smtpd-queue/Makefile +++ usr.sbin/smtpd/smtpd-queue/Makefile @@ -15,7 +15,7 @@ SRCS= aliases.c bounce.c ca.c compress_backend.c confi dispatcher.c proxy.c queue.c queue_backend.c report_smtp.c \ resolver.c rfc5322.c ruleset.c runq.c scheduler.c \ scheduler_backend.c smtp.c smtp_session.c smtpd.c srs.c ssl.c \ - stat_backend.c table.c to.c tree.c util.c waitq.c \ + startup.c stat_backend.c table.c to.c tree.c util.c waitq.c \ compress_gzip.c table_db.c table_getpwnam.c table_proc.c \ table_static.c queue_fs.c queue_null.c queue_proc.c \ queue_ram.c scheduler_ramqueue.c scheduler_null.c \ blob - 93076c8a5241d7202b0810b4d3d723377dbaba1d blob + d26854ca8cd02f506b2c4ebaf93fc204f0130a2c --- usr.sbin/smtpd/smtpd-scheduler/Makefile +++ usr.sbin/smtpd/smtpd-scheduler/Makefile @@ -15,7 +15,7 @@ SRCS= aliases.c bounce.c ca.c compress_backend.c confi dispatcher.c proxy.c queue.c queue_backend.c report_smtp.c \ resolver.c rfc5322.c ruleset.c runq.c scheduler.c \ scheduler_backend.c smtp.c smtp_session.c smtpd.c srs.c ssl.c \ - stat_backend.c table.c to.c tree.c util.c waitq.c \ + startup.c stat_backend.c table.c to.c tree.c util.c waitq.c \ compress_gzip.c table_db.c table_getpwnam.c table_proc.c \ table_static.c queue_fs.c queue_null.c queue_proc.c \ queue_ram.c scheduler_ramqueue.c scheduler_null.c \ blob - 7292b6810caaa49358b7b92ef3f26ade95d2ea42 blob + de95861f48bf015b5cc1cce1857a8318d266111b --- usr.sbin/smtpd/smtpd.c +++ usr.sbin/smtpd/smtpd.c @@ -59,12 +59,8 @@ static void forkmda(struct mproc *, uint64_t, struct d static int parent_forward_open(char *, char *, uid_t, gid_t); static struct child *child_add(pid_t, int, const char *); static struct mproc *start_child(int, char **, char *); -static struct mproc *setup_peer(enum smtp_proc_type, pid_t, int); static void setup_peers(struct mproc *, struct mproc *); static void setup_done(struct mproc *); -static void setup_proc(void); -static struct mproc *setup_peer(enum smtp_proc_type, pid_t, int); -static int imsg_wait(struct imsgbuf *, struct imsg *, int); static void offline_scan(int, short, void *); static int offline_add(char *, uid_t, gid_t); @@ -73,8 +69,6 @@ static int offline_enqueue(char *, uid_t, gid_t); static void purge_task(void); static int parent_auth_user(const char *, const char *); -static void load_pki_tree(void); -static void load_pki_keys(void); static void fork_filter_processes(void); static void fork_filter_process(const char *, struct filter_proc *); @@ -115,26 +109,11 @@ static struct timeval offline_timeout; static pid_t purge_pid = -1; extern char **environ; -void (*imsg_callback)(struct mproc *, struct imsg *); -enum smtp_proc_type smtpd_process; +extern const char *backend_queue; +extern const char *backend_scheduler; +extern const char *backend_stat; -struct smtpd *env = NULL; - -struct mproc *p_control = NULL; -struct mproc *p_lka = NULL; -struct mproc *p_parent = NULL; -struct mproc *p_queue = NULL; -struct mproc *p_scheduler = NULL; -struct mproc *p_dispatcher = NULL; -struct mproc *p_ca = NULL; - -const char *backend_queue = "fs"; -const char *backend_scheduler = "ramqueue"; -const char *backend_stat = "ram"; - -int profiling = 0; -int debug = 0; int foreground = 0; int control_socket = -1; @@ -483,7 +462,6 @@ main(int argc, char *argv[]) flags = 0; opts = 0; - debug = 0; tracing = 0; log_init(1, LOG_MAIL); @@ -523,7 +501,6 @@ main(int argc, char *argv[]) usage(); break; case 'n': - debug = 2; opts |= SMTPD_OPT_NOACTION; break; case 'f': @@ -902,136 +879,6 @@ setup_done(struct mproc *p) imsg_free(&imsg); } -static void -setup_proc(void) -{ - struct imsgbuf *ibuf; - struct imsg imsg; - int setup = 1; - - log_procinit(proc_title(smtpd_process)); - - p_parent = calloc(1, sizeof(*p_parent)); - if (p_parent == NULL) - fatal("calloc"); - if((p_parent->name = strdup("parent")) == NULL) - fatal("strdup"); - p_parent->proc = PROC_PARENT; - p_parent->handler = imsg_dispatch; - mproc_init(p_parent, 3); - - ibuf = &p_parent->imsgbuf; - - while (setup) { - if (imsg_wait(ibuf, &imsg, 10000) == -1) - fatal("imsg_wait"); - - switch (imsg.hdr.type) { - case IMSG_SETUP_KEY: - env->sc_queue_key = strdup(imsg.data); - break; - case IMSG_SETUP_PEER: - setup_peer(imsg.hdr.peerid, imsg.hdr.pid, - imsg_get_fd(&imsg)); - break; - case IMSG_SETUP_DONE: - setup = 0; - break; - default: - fatal("bad imsg %d", imsg.hdr.type); - } - imsg_free(&imsg); - } - - if (imsg_compose(ibuf, IMSG_SETUP_DONE, 0, 0, -1, NULL, 0) == -1) - fatal("imsg_compose"); - - if (imsgbuf_flush(ibuf) == -1) - fatal("imsgbuf_flush"); - - log_debug("setup_proc: %s done", proc_title(smtpd_process)); -} - -static struct mproc * -setup_peer(enum smtp_proc_type proc, pid_t pid, int sock) -{ - struct mproc *p, **pp; - - log_debug("setup_peer: %s -> %s[%u] fd=%d", proc_title(smtpd_process), - proc_title(proc), pid, sock); - - if (sock == -1) - fatalx("peer socket not received"); - - switch (proc) { - case PROC_LKA: - pp = &p_lka; - break; - case PROC_QUEUE: - pp = &p_queue; - break; - case PROC_CONTROL: - pp = &p_control; - break; - case PROC_SCHEDULER: - pp = &p_scheduler; - break; - case PROC_DISPATCHER: - pp = &p_dispatcher; - break; - case PROC_CA: - pp = &p_ca; - break; - default: - fatalx("unknown peer"); - } - - if (*pp) - fatalx("peer already set"); - - p = calloc(1, sizeof(*p)); - if (p == NULL) - fatal("calloc"); - if((p->name = strdup(proc_title(proc))) == NULL) - fatal("strdup"); - mproc_init(p, sock); - p->pid = pid; - p->proc = proc; - p->handler = imsg_dispatch; - - *pp = p; - - return p; -} - -static int -imsg_wait(struct imsgbuf *ibuf, struct imsg *imsg, int timeout) -{ - struct pollfd pfd[1]; - ssize_t n; - - pfd[0].fd = ibuf->fd; - pfd[0].events = POLLIN; - - while (1) { - if ((n = imsg_get(ibuf, imsg)) == -1) - return -1; - if (n) - return 1; - - n = poll(pfd, 1, timeout); - if (n == -1) - return -1; - if (n == 0) { - errno = ETIMEDOUT; - return -1; - } - - if (imsgbuf_read(ibuf) != 1) - return -1; - } -} - int smtpd(void) { struct event ev_sigint; @@ -1093,111 +940,6 @@ smtpd(void) { return (0); } -static void -load_pki_tree(void) -{ - struct pki *pki; - struct ca *sca; - const char *k; - void *iter_dict; - - log_debug("debug: init ssl-tree"); - iter_dict = NULL; - while (dict_iter(env->sc_pki_dict, &iter_dict, &k, (void **)&pki)) { - log_debug("info: loading pki information for %s", k); - if (pki->pki_cert_file == NULL) - fatalx("load_pki_tree: missing certificate file"); - if (pki->pki_key_file == NULL) - fatalx("load_pki_tree: missing key file"); - - if (!ssl_load_certificate(pki, pki->pki_cert_file)) - fatalx("load_pki_tree: failed to load certificate file"); - } - - log_debug("debug: init ca-tree"); - iter_dict = NULL; - while (dict_iter(env->sc_ca_dict, &iter_dict, &k, (void **)&sca)) { - log_debug("info: loading CA information for %s", k); - if (!ssl_load_cafile(sca, sca->ca_cert_file)) - fatalx("load_pki_tree: failed to load CA file"); - } -} - -void -load_pki_keys(void) -{ - struct pki *pki; - const char *k; - void *iter_dict; - - log_debug("debug: init ssl-tree"); - iter_dict = NULL; - while (dict_iter(env->sc_pki_dict, &iter_dict, &k, (void **)&pki)) { - log_debug("info: loading pki keys for %s", k); - - if (!ssl_load_keyfile(pki, pki->pki_key_file, k)) - fatalx("load_pki_keys: failed to load key file"); - } -} - -int -fork_proc_backend(const char *key, const char *conf, const char *procname, - int do_stdout) -{ - pid_t pid; - int sp[2]; - char path[PATH_MAX]; - char name[PATH_MAX]; - char *arg; - - if (strlcpy(name, conf, sizeof(name)) >= sizeof(name)) { - log_warnx("warn: %s-proc: conf too long", key); - return (-1); - } - - arg = strchr(name, ':'); - if (arg) - *arg++ = '\0'; - - if (snprintf(path, sizeof(path), PATH_LIBEXEC "/%s-%s", key, name) >= - (ssize_t)sizeof(path)) { - log_warn("warn: %s-proc: exec path too long", key); - return (-1); - } - - if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) == -1) { - log_warn("warn: %s-proc: socketpair", key); - return (-1); - } - - if ((pid = fork()) == -1) { - log_warn("warn: %s-proc: fork", key); - close(sp[0]); - close(sp[1]); - return (-1); - } - - if (pid == 0) { - /* child process */ - dup2(sp[0], STDIN_FILENO); - if (do_stdout) - dup2(sp[0], STDOUT_FILENO); - if (closefrom(STDERR_FILENO + 1) == -1) - exit(1); - - if (procname == NULL) - procname = name; - - execl(path, procname, arg, (char *)NULL); - fatal("execl: %s", path); - } - - /* parent process */ - close(sp[0]); - - return (sp[1]); -} - struct child * child_add(pid_t pid, int type, const char *title) { @@ -1835,54 +1577,6 @@ parent_forward_open(char *username, char *directory, u return fd; } -void -imsg_dispatch(struct mproc *p, struct imsg *imsg) -{ - struct timespec t0, t1, dt; - int msg; - - if (imsg == NULL) { - imsg_callback(p, imsg); - return; - } - - log_imsg(smtpd_process, p->proc, imsg); - - if (profiling & PROFILE_IMSG) - clock_gettime(CLOCK_MONOTONIC, &t0); - - msg = imsg->hdr.type; - imsg_callback(p, imsg); - - if (profiling & PROFILE_IMSG) { - clock_gettime(CLOCK_MONOTONIC, &t1); - timespecsub(&t1, &t0, &dt); - - log_debug("profile-imsg: %s %s %s %d %lld.%09ld", - proc_name(smtpd_process), - proc_name(p->proc), - imsg_to_str(msg), - (int)imsg->hdr.len, - (long long)dt.tv_sec, - dt.tv_nsec); - - if (profiling & PROFILE_TOSTAT) { - char key[STAT_KEY_SIZE]; - /* can't profstat control process yet */ - if (smtpd_process == PROC_CONTROL) - return; - - if (!bsnprintf(key, sizeof key, - "profiling.imsg.%s.%s.%s", - proc_name(smtpd_process), - proc_name(p->proc), - imsg_to_str(msg))) - return; - stat_set(key, stat_timespec(&dt)); - } - } -} - int parent_auth_user(const char *username, const char *password) { blob - b8268d69c6985d4d42234b550c8cfe6086d465b3 blob + fe8bcb8204fbf40110bcecfdf4ee634876b35013 --- usr.sbin/smtpd/smtpd.h +++ usr.sbin/smtpd/smtpd.h @@ -1614,6 +1614,12 @@ const char *srs_encode(const char *, const char *); const char *srs_decode(const char *); +/* startup.c */ +void setup_proc(void); +int imsg_wait(struct imsgbuf *, struct imsg *, int); +void load_pki_tree(void); +void load_pki_keys(void); + /* stat_backend.c */ struct stat_backend *stat_backend_lookup(const char *); void stat_increment(const char *, size_t); blob - /dev/null blob + 8195f93b98fd0b9a8bd5993d675cc69cc2ce4287 (mode 644) --- /dev/null +++ usr.sbin/smtpd/startup.c @@ -0,0 +1,332 @@ +/* $OpenBSD$ */ + +/* + * Copyright (c) 2008 Gilles Chehade + * Copyright (c) 2008 Pierre-Yves Ritschard + * Copyright (c) 2009 Jacek Masiulaniec + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include + +#include "smtpd.h" +#include "log.h" +#include "ssl.h" + +struct smtpd *env = NULL; + +struct mproc *p_control = NULL; +struct mproc *p_lka = NULL; +struct mproc *p_parent = NULL; +struct mproc *p_queue = NULL; +struct mproc *p_scheduler = NULL; +struct mproc *p_dispatcher = NULL; +struct mproc *p_ca = NULL; + +int profiling = 0; + +enum smtp_proc_type smtpd_process; + +const char *backend_queue = "fs"; +const char *backend_scheduler = "ramqueue"; +const char *backend_stat = "ram"; + +void (*imsg_callback)(struct mproc *, struct imsg *); + +static struct mproc * +setup_peer(enum smtp_proc_type proc, pid_t pid, int sock) +{ + struct mproc *p, **pp; + + log_debug("setup_peer: %s -> %s[%u] fd=%d", proc_title(smtpd_process), + proc_title(proc), pid, sock); + + if (sock == -1) + fatalx("peer socket not received"); + + switch (proc) { + case PROC_LKA: + pp = &p_lka; + break; + case PROC_QUEUE: + pp = &p_queue; + break; + case PROC_CONTROL: + pp = &p_control; + break; + case PROC_SCHEDULER: + pp = &p_scheduler; + break; + case PROC_DISPATCHER: + pp = &p_dispatcher; + break; + case PROC_CA: + pp = &p_ca; + break; + default: + fatalx("unknown peer"); + } + + if (*pp) + fatalx("peer already set"); + + p = calloc(1, sizeof(*p)); + if (p == NULL) + fatal("calloc"); + if((p->name = strdup(proc_title(proc))) == NULL) + fatal("strdup"); + mproc_init(p, sock); + p->pid = pid; + p->proc = proc; + p->handler = imsg_dispatch; + + *pp = p; + + return p; +} + +void +setup_proc(void) +{ + struct imsgbuf *ibuf; + struct imsg imsg; + int setup = 1; + + log_procinit(proc_title(smtpd_process)); + + p_parent = calloc(1, sizeof(*p_parent)); + if (p_parent == NULL) + fatal("calloc"); + if((p_parent->name = strdup("parent")) == NULL) + fatal("strdup"); + p_parent->proc = PROC_PARENT; + p_parent->handler = imsg_dispatch; + mproc_init(p_parent, 3); + + ibuf = &p_parent->imsgbuf; + + while (setup) { + if (imsg_wait(ibuf, &imsg, 10000) == -1) + fatal("imsg_wait"); + + switch (imsg.hdr.type) { + case IMSG_SETUP_KEY: + env->sc_queue_key = strdup(imsg.data); + break; + case IMSG_SETUP_PEER: + setup_peer(imsg.hdr.peerid, imsg.hdr.pid, + imsg_get_fd(&imsg)); + break; + case IMSG_SETUP_DONE: + setup = 0; + break; + default: + fatal("bad imsg %d", imsg.hdr.type); + } + imsg_free(&imsg); + } + + if (imsg_compose(ibuf, IMSG_SETUP_DONE, 0, 0, -1, NULL, 0) == -1) + fatal("imsg_compose"); + + if (imsgbuf_flush(ibuf) == -1) + fatal("imsgbuf_flush"); + + log_debug("setup_proc: %s done", proc_title(smtpd_process)); +} + +int +imsg_wait(struct imsgbuf *ibuf, struct imsg *imsg, int timeout) +{ + struct pollfd pfd[1]; + ssize_t n; + + pfd[0].fd = ibuf->fd; + pfd[0].events = POLLIN; + + while (1) { + if ((n = imsg_get(ibuf, imsg)) == -1) + return -1; + if (n) + return 1; + + n = poll(pfd, 1, timeout); + if (n == -1) + return -1; + if (n == 0) { + errno = ETIMEDOUT; + return -1; + } + + if (imsgbuf_read(ibuf) != 1) + return -1; + } +} + +void +load_pki_tree(void) +{ + struct pki *pki; + struct ca *sca; + const char *k; + void *iter_dict; + + log_debug("debug: init ssl-tree"); + iter_dict = NULL; + while (dict_iter(env->sc_pki_dict, &iter_dict, &k, (void **)&pki)) { + log_debug("info: loading pki information for %s", k); + if (pki->pki_cert_file == NULL) + fatalx("load_pki_tree: missing certificate file"); + if (pki->pki_key_file == NULL) + fatalx("load_pki_tree: missing key file"); + + if (!ssl_load_certificate(pki, pki->pki_cert_file)) + fatalx("load_pki_tree: failed to load certificate file"); + } + + log_debug("debug: init ca-tree"); + iter_dict = NULL; + while (dict_iter(env->sc_ca_dict, &iter_dict, &k, (void **)&sca)) { + log_debug("info: loading CA information for %s", k); + if (!ssl_load_cafile(sca, sca->ca_cert_file)) + fatalx("load_pki_tree: failed to load CA file"); + } +} + +void +load_pki_keys(void) +{ + struct pki *pki; + const char *k; + void *iter_dict; + + log_debug("debug: init ssl-tree"); + iter_dict = NULL; + while (dict_iter(env->sc_pki_dict, &iter_dict, &k, (void **)&pki)) { + log_debug("info: loading pki keys for %s", k); + + if (!ssl_load_keyfile(pki, pki->pki_key_file, k)) + fatalx("load_pki_keys: failed to load key file"); + } +} + +int +fork_proc_backend(const char *key, const char *conf, const char *procname, + int do_stdout) +{ + pid_t pid; + int sp[2]; + char path[PATH_MAX]; + char name[PATH_MAX]; + char *arg; + + if (strlcpy(name, conf, sizeof(name)) >= sizeof(name)) { + log_warnx("warn: %s-proc: conf too long", key); + return (-1); + } + + arg = strchr(name, ':'); + if (arg) + *arg++ = '\0'; + + if (snprintf(path, sizeof(path), PATH_LIBEXEC "/%s-%s", key, name) >= + (ssize_t)sizeof(path)) { + log_warn("warn: %s-proc: exec path too long", key); + return (-1); + } + + if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) == -1) { + log_warn("warn: %s-proc: socketpair", key); + return (-1); + } + + if ((pid = fork()) == -1) { + log_warn("warn: %s-proc: fork", key); + close(sp[0]); + close(sp[1]); + return (-1); + } + + if (pid == 0) { + /* child process */ + dup2(sp[0], STDIN_FILENO); + if (do_stdout) + dup2(sp[0], STDOUT_FILENO); + if (closefrom(STDERR_FILENO + 1) == -1) + exit(1); + + if (procname == NULL) + procname = name; + + execl(path, procname, arg, (char *)NULL); + fatal("execl: %s", path); + } + + /* parent process */ + close(sp[0]); + + return (sp[1]); +} + +void +imsg_dispatch(struct mproc *p, struct imsg *imsg) +{ + struct timespec t0, t1, dt; + int msg; + + if (imsg == NULL) { + imsg_callback(p, imsg); + return; + } + + log_imsg(smtpd_process, p->proc, imsg); + + if (profiling & PROFILE_IMSG) + clock_gettime(CLOCK_MONOTONIC, &t0); + + msg = imsg->hdr.type; + imsg_callback(p, imsg); + + if (profiling & PROFILE_IMSG) { + clock_gettime(CLOCK_MONOTONIC, &t1); + timespecsub(&t1, &t0, &dt); + + log_debug("profile-imsg: %s %s %s %d %lld.%09ld", + proc_name(smtpd_process), + proc_name(p->proc), + imsg_to_str(msg), + (int)imsg->hdr.len, + (long long)dt.tv_sec, + dt.tv_nsec); + + if (profiling & PROFILE_TOSTAT) { + char key[STAT_KEY_SIZE]; + /* can't profstat control process yet */ + if (smtpd_process == PROC_CONTROL) + return; + + if (!bsnprintf(key, sizeof key, + "profiling.imsg.%s.%s.%s", + proc_name(smtpd_process), + proc_name(p->proc), + imsg_to_str(msg))) + return; + stat_set(key, stat_timespec(&dt)); + } + } +}