xref: /openbsd-src/usr.sbin/smtpd/config.c (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /*	$OpenBSD: config.c,v 1.37 2016/09/01 10:54:25 eric Exp $	*/
2 
3 /*
4  * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@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/tree.h>
22 #include <sys/socket.h>
23 #include <sys/resource.h>
24 
25 #include <event.h>
26 #include <imsg.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <limits.h>
30 #include <string.h>
31 #include <unistd.h>
32 
33 #include <openssl/ssl.h>
34 
35 #include "smtpd.h"
36 #include "log.h"
37 #include "ssl.h"
38 
39 void
40 purge_config(uint8_t what)
41 {
42 	struct listener	*l;
43 	struct table	*t;
44 	struct rule	*r;
45 	struct pki	*p;
46 	const char	*k;
47 	void		*iter_dict;
48 
49 	if (what & PURGE_LISTENERS) {
50 		while ((l = TAILQ_FIRST(env->sc_listeners)) != NULL) {
51 			TAILQ_REMOVE(env->sc_listeners, l, entry);
52 			free(l);
53 		}
54 		free(env->sc_listeners);
55 		env->sc_listeners = NULL;
56 	}
57 	if (what & PURGE_TABLES) {
58 		while (dict_root(env->sc_tables_dict, NULL, (void **)&t))
59 			table_destroy(t);
60 		free(env->sc_tables_dict);
61 		env->sc_tables_dict = NULL;
62 	}
63 	if (what & PURGE_RULES) {
64 		while ((r = TAILQ_FIRST(env->sc_rules)) != NULL) {
65 			TAILQ_REMOVE(env->sc_rules, r, r_entry);
66 			free(r);
67 		}
68 		free(env->sc_rules);
69 		env->sc_rules = NULL;
70 	}
71 	if (what & PURGE_PKI) {
72 		while (dict_poproot(env->sc_pki_dict, (void **)&p)) {
73 			explicit_bzero(p->pki_cert, p->pki_cert_len);
74 			free(p->pki_cert);
75 			if (p->pki_key) {
76 				explicit_bzero(p->pki_key, p->pki_key_len);
77 				free(p->pki_key);
78 			}
79 			if (p->pki_pkey)
80 				EVP_PKEY_free(p->pki_pkey);
81 			free(p);
82 		}
83 		free(env->sc_pki_dict);
84 		env->sc_pki_dict = NULL;
85 	} else if (what & PURGE_PKI_KEYS) {
86 		iter_dict = NULL;
87 		while (dict_iter(env->sc_pki_dict, &iter_dict, &k,
88 		    (void **)&p)) {
89 			explicit_bzero(p->pki_cert, p->pki_cert_len);
90 			free(p->pki_cert);
91 			p->pki_cert = NULL;
92 			if (p->pki_key) {
93 				explicit_bzero(p->pki_key, p->pki_key_len);
94 				free(p->pki_key);
95 				p->pki_key = NULL;
96 			}
97 			if (p->pki_pkey)
98 				EVP_PKEY_free(p->pki_pkey);
99 			p->pki_pkey = NULL;
100 		}
101 	}
102 }
103 
104 void
105 config_process(enum smtp_proc_type proc)
106 {
107 	struct rlimit rl;
108 
109 	smtpd_process = proc;
110 	setproctitle("%s", proc_title(proc));
111 
112 	if (getrlimit(RLIMIT_NOFILE, &rl) == -1)
113 		fatal("fdlimit: getrlimit");
114 	rl.rlim_cur = rl.rlim_max;
115 	if (setrlimit(RLIMIT_NOFILE, &rl) == -1)
116 		fatal("fdlimit: setrlimit");
117 }
118 
119 void
120 config_peer(enum smtp_proc_type proc)
121 {
122 	struct mproc	*p;
123 
124 	if (proc == smtpd_process)
125 		fatal("config_peers: cannot peer with oneself");
126 
127 	if (proc == PROC_CONTROL)
128 		p = p_control;
129 	else if (proc == PROC_LKA)
130 		p = p_lka;
131 	else if (proc == PROC_PARENT)
132 		p = p_parent;
133 	else if (proc == PROC_QUEUE)
134 		p = p_queue;
135 	else if (proc == PROC_SCHEDULER)
136 		p = p_scheduler;
137 	else if (proc == PROC_PONY)
138 		p = p_pony;
139 	else if (proc == PROC_CA)
140 		p = p_ca;
141 	else
142 		fatalx("bad peer");
143 
144 	mproc_enable(p);
145 }
146