xref: /openbsd-src/usr.sbin/smtpd/config.c (revision 58fbf5d6aa35e3d66f2c32c61d2f38824a990e85)
1 /*	$OpenBSD: config.c,v 1.53 2021/01/19 09:16:20 claudio 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 <ifaddrs.h>
27 #include <imsg.h>
28 #include <netdb.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <limits.h>
32 #include <string.h>
33 #include <unistd.h>
34 
35 #include <openssl/ssl.h>
36 
37 #include "smtpd.h"
38 #include "log.h"
39 #include "ssl.h"
40 
41 void		 set_local(struct smtpd *, const char *);
42 void		 set_localaddrs(struct smtpd *, struct table *);
43 
44 struct smtpd *
45 config_default(void)
46 {
47 	struct smtpd	       *conf = NULL;
48 	struct mta_limits      *limits = NULL;
49 	struct table	       *t = NULL;
50 	char			hostname[HOST_NAME_MAX+1];
51 
52 	if (getmailname(hostname, sizeof hostname) == -1)
53 		return NULL;
54 
55 	if ((conf = calloc(1, sizeof(*conf))) == NULL)
56 		return conf;
57 
58 	(void)strlcpy(conf->sc_hostname, hostname, sizeof(conf->sc_hostname));
59 
60 	conf->sc_maxsize = DEFAULT_MAX_BODY_SIZE;
61 	conf->sc_subaddressing_delim = SUBADDRESSING_DELIMITER;
62 	conf->sc_ttl = SMTPD_QUEUE_EXPIRY;
63 	conf->sc_srs_ttl = SMTPD_QUEUE_EXPIRY / 86400;
64 
65 	conf->sc_mta_max_deferred = 100;
66 	conf->sc_scheduler_max_inflight = 5000;
67 	conf->sc_scheduler_max_schedule = 10;
68 	conf->sc_scheduler_max_evp_batch_size = 256;
69 	conf->sc_scheduler_max_msg_batch_size = 1024;
70 
71 	conf->sc_session_max_rcpt = 1000;
72 	conf->sc_session_max_mails = 100;
73 
74 	conf->sc_mda_max_session = 50;
75 	conf->sc_mda_max_user_session = 7;
76 	conf->sc_mda_task_hiwat = 50;
77 	conf->sc_mda_task_lowat = 30;
78 	conf->sc_mda_task_release = 10;
79 
80 	/* Report mails delayed for more than 4 hours */
81 	conf->sc_bounce_warn[0] = 3600 * 4;
82 
83 	conf->sc_tables_dict = calloc(1, sizeof(*conf->sc_tables_dict));
84 	conf->sc_rules = calloc(1, sizeof(*conf->sc_rules));
85 	conf->sc_dispatchers = calloc(1, sizeof(*conf->sc_dispatchers));
86 	conf->sc_listeners = calloc(1, sizeof(*conf->sc_listeners));
87 	conf->sc_ca_dict = calloc(1, sizeof(*conf->sc_ca_dict));
88 	conf->sc_pki_dict = calloc(1, sizeof(*conf->sc_pki_dict));
89 	conf->sc_ssl_dict = calloc(1, sizeof(*conf->sc_ssl_dict));
90 	conf->sc_limits_dict = calloc(1, sizeof(*conf->sc_limits_dict));
91 	conf->sc_mda_wrappers = calloc(1, sizeof(*conf->sc_mda_wrappers));
92 	conf->sc_filter_processes_dict = calloc(1, sizeof(*conf->sc_filter_processes_dict));
93 	conf->sc_dispatcher_bounce = calloc(1, sizeof(*conf->sc_dispatcher_bounce));
94 	conf->sc_filters_dict = calloc(1, sizeof(*conf->sc_filters_dict));
95 	limits = calloc(1, sizeof(*limits));
96 
97 	if (conf->sc_tables_dict == NULL	||
98 	    conf->sc_rules == NULL		||
99 	    conf->sc_dispatchers == NULL	||
100 	    conf->sc_listeners == NULL		||
101 	    conf->sc_ca_dict == NULL		||
102 	    conf->sc_pki_dict == NULL		||
103 	    conf->sc_ssl_dict == NULL		||
104 	    conf->sc_limits_dict == NULL        ||
105 	    conf->sc_mda_wrappers == NULL	||
106 	    conf->sc_filter_processes_dict == NULL	||
107 	    conf->sc_dispatcher_bounce == NULL	||
108 	    conf->sc_filters_dict == NULL	||
109 	    limits == NULL)
110 		goto error;
111 
112 	dict_init(conf->sc_dispatchers);
113 	dict_init(conf->sc_mda_wrappers);
114 	dict_init(conf->sc_ca_dict);
115 	dict_init(conf->sc_pki_dict);
116 	dict_init(conf->sc_ssl_dict);
117 	dict_init(conf->sc_tables_dict);
118 	dict_init(conf->sc_limits_dict);
119 	dict_init(conf->sc_filter_processes_dict);
120 
121 	limit_mta_set_defaults(limits);
122 
123 	dict_xset(conf->sc_limits_dict, "default", limits);
124 
125 	TAILQ_INIT(conf->sc_listeners);
126 	TAILQ_INIT(conf->sc_rules);
127 
128 
129 	/* bounce dispatcher */
130 	conf->sc_dispatcher_bounce->type = DISPATCHER_BOUNCE;
131 
132 	/*
133 	 * declare special "localhost", "anyhost" and "localnames" tables
134 	 */
135 	set_local(conf, conf->sc_hostname);
136 
137 	t = table_create(conf, "static", "<anydestination>", NULL);
138 	table_add(t, "*", NULL);
139 
140 	hostname[strcspn(hostname, ".")] = '\0';
141 	if (strcmp(conf->sc_hostname, hostname) != 0)
142 		table_add(t, hostname, NULL);
143 
144 	table_create(conf, "getpwnam", "<getpwnam>", NULL);
145 
146 	return conf;
147 
148 error:
149 	free(conf->sc_tables_dict);
150 	free(conf->sc_rules);
151 	free(conf->sc_dispatchers);
152 	free(conf->sc_listeners);
153 	free(conf->sc_ca_dict);
154 	free(conf->sc_pki_dict);
155 	free(conf->sc_ssl_dict);
156 	free(conf->sc_limits_dict);
157 	free(conf->sc_mda_wrappers);
158 	free(conf->sc_filter_processes_dict);
159 	free(conf->sc_dispatcher_bounce);
160 	free(conf->sc_filters_dict);
161 	free(limits);
162 	free(conf);
163 	return NULL;
164 }
165 
166 void
167 set_local(struct smtpd *conf, const char *hostname)
168 {
169 	struct table	*t;
170 
171 	t = table_create(conf, "static", "<localnames>", NULL);
172 	table_add(t, "localhost", NULL);
173 	table_add(t, hostname, NULL);
174 
175 	set_localaddrs(conf, t);
176 }
177 
178 void
179 set_localaddrs(struct smtpd *conf, struct table *localnames)
180 {
181 	struct ifaddrs *ifap, *p;
182 	struct sockaddr_storage ss;
183 	struct sockaddr_in	*sain;
184 	struct sockaddr_in6	*sin6;
185 	struct table		*t;
186 	char buf[NI_MAXHOST + 5];
187 
188 	t = table_create(conf, "static", "<anyhost>", NULL);
189 	table_add(t, "local", NULL);
190 	table_add(t, "0.0.0.0/0", NULL);
191 	table_add(t, "::/0", NULL);
192 
193 	if (getifaddrs(&ifap) == -1)
194 		fatal("getifaddrs");
195 
196 	t = table_create(conf, "static", "<localhost>", NULL);
197 	table_add(t, "local", NULL);
198 
199 	for (p = ifap; p != NULL; p = p->ifa_next) {
200 		if (p->ifa_addr == NULL)
201 			continue;
202 		switch (p->ifa_addr->sa_family) {
203 		case AF_INET:
204 			sain = (struct sockaddr_in *)&ss;
205 			*sain = *(struct sockaddr_in *)p->ifa_addr;
206 			sain->sin_len = sizeof(struct sockaddr_in);
207 			table_add(t, ss_to_text(&ss), NULL);
208 			table_add(localnames, ss_to_text(&ss), NULL);
209 			(void)snprintf(buf, sizeof buf, "[%s]", ss_to_text(&ss));
210 			table_add(localnames, buf, NULL);
211 			break;
212 
213 		case AF_INET6:
214 			sin6 = (struct sockaddr_in6 *)&ss;
215 			*sin6 = *(struct sockaddr_in6 *)p->ifa_addr;
216 			sin6->sin6_len = sizeof(struct sockaddr_in6);
217 #ifdef __KAME__
218 			if ((IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) ||
219 			    IN6_IS_ADDR_MC_LINKLOCAL(&sin6->sin6_addr) ||
220 			    IN6_IS_ADDR_MC_INTFACELOCAL(&sin6->sin6_addr)) &&
221 			    sin6->sin6_scope_id == 0) {
222 				sin6->sin6_scope_id = ntohs(
223 				    *(u_int16_t *)&sin6->sin6_addr.s6_addr[2]);
224 				sin6->sin6_addr.s6_addr[2] = 0;
225 				sin6->sin6_addr.s6_addr[3] = 0;
226 			}
227 #endif
228 			table_add(t, ss_to_text(&ss), NULL);
229 			table_add(localnames, ss_to_text(&ss), NULL);
230 			(void)snprintf(buf, sizeof buf, "[%s]", ss_to_text(&ss));
231 			table_add(localnames, buf, NULL);
232 			(void)snprintf(buf, sizeof buf, "[ipv6:%s]", ss_to_text(&ss));
233 			table_add(localnames, buf, NULL);
234 			break;
235 		}
236 	}
237 
238 	freeifaddrs(ifap);
239 }
240 
241 void
242 purge_config(uint8_t what)
243 {
244 	struct dispatcher	*d;
245 	struct listener	*l;
246 	struct table	*t;
247 	struct rule	*r;
248 	struct pki	*p;
249 	const char	*k;
250 	void		*iter_dict;
251 
252 	if (what & PURGE_LISTENERS) {
253 		while ((l = TAILQ_FIRST(env->sc_listeners)) != NULL) {
254 			TAILQ_REMOVE(env->sc_listeners, l, entry);
255 			free(l);
256 		}
257 		free(env->sc_listeners);
258 		env->sc_listeners = NULL;
259 	}
260 	if (what & PURGE_TABLES) {
261 		while (dict_root(env->sc_tables_dict, NULL, (void **)&t))
262 			table_destroy(env, t);
263 		free(env->sc_tables_dict);
264 		env->sc_tables_dict = NULL;
265 	}
266 	if (what & PURGE_RULES) {
267 		while ((r = TAILQ_FIRST(env->sc_rules)) != NULL) {
268 			TAILQ_REMOVE(env->sc_rules, r, r_entry);
269 			free(r);
270 		}
271 		free(env->sc_rules);
272 		env->sc_rules = NULL;
273 	}
274 	if (what & PURGE_DISPATCHERS) {
275 		while (dict_poproot(env->sc_dispatchers, (void **)&d)) {
276 			free(d);
277 		}
278 		free(env->sc_dispatchers);
279 		env->sc_dispatchers = NULL;
280 	}
281 	if (what & PURGE_PKI) {
282 		while (dict_poproot(env->sc_pki_dict, (void **)&p)) {
283 			freezero(p->pki_cert, p->pki_cert_len);
284 			freezero(p->pki_key, p->pki_key_len);
285 			EVP_PKEY_free(p->pki_pkey);
286 			free(p);
287 		}
288 		free(env->sc_pki_dict);
289 		env->sc_pki_dict = NULL;
290 	} else if (what & PURGE_PKI_KEYS) {
291 		iter_dict = NULL;
292 		while (dict_iter(env->sc_pki_dict, &iter_dict, &k,
293 		    (void **)&p)) {
294 			freezero(p->pki_cert, p->pki_cert_len);
295 			p->pki_cert = NULL;
296 			freezero(p->pki_key, p->pki_key_len);
297 			p->pki_key = NULL;
298 			EVP_PKEY_free(p->pki_pkey);
299 			p->pki_pkey = NULL;
300 		}
301 	}
302 }
303 
304 #ifndef CONFIG_MINIMUM
305 
306 void
307 config_process(enum smtp_proc_type proc)
308 {
309 	struct rlimit rl;
310 
311 	smtpd_process = proc;
312 	setproctitle("%s", proc_title(proc));
313 
314 	if (getrlimit(RLIMIT_NOFILE, &rl) == -1)
315 		fatal("fdlimit: getrlimit");
316 	rl.rlim_cur = rl.rlim_max;
317 	if (setrlimit(RLIMIT_NOFILE, &rl) == -1)
318 		fatal("fdlimit: setrlimit");
319 }
320 
321 void
322 config_peer(enum smtp_proc_type proc)
323 {
324 	struct mproc	*p;
325 
326 	if (proc == smtpd_process)
327 		fatal("config_peers: cannot peer with oneself");
328 
329 	if (proc == PROC_CONTROL)
330 		p = p_control;
331 	else if (proc == PROC_LKA)
332 		p = p_lka;
333 	else if (proc == PROC_PARENT)
334 		p = p_parent;
335 	else if (proc == PROC_QUEUE)
336 		p = p_queue;
337 	else if (proc == PROC_SCHEDULER)
338 		p = p_scheduler;
339 	else if (proc == PROC_DISPATCHER)
340 		p = p_dispatcher;
341 	else if (proc == PROC_CA)
342 		p = p_ca;
343 	else
344 		fatalx("bad peer");
345 
346 	mproc_enable(p);
347 }
348 
349 #else
350 
351 void config_process(enum smtp_proc_type proc) {}
352 void config_peer(enum smtp_proc_type proc) {}
353 
354 #endif
355