1 /* $OpenBSD: config.c,v 1.51 2019/12/18 10:00:39 gilles 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 table_add(t, ss_to_text(&ss), NULL); 218 table_add(localnames, ss_to_text(&ss), NULL); 219 (void)snprintf(buf, sizeof buf, "[%s]", ss_to_text(&ss)); 220 table_add(localnames, buf, NULL); 221 (void)snprintf(buf, sizeof buf, "[ipv6:%s]", ss_to_text(&ss)); 222 table_add(localnames, buf, NULL); 223 break; 224 } 225 } 226 227 freeifaddrs(ifap); 228 } 229 230 void 231 purge_config(uint8_t what) 232 { 233 struct dispatcher *d; 234 struct listener *l; 235 struct table *t; 236 struct rule *r; 237 struct pki *p; 238 const char *k; 239 void *iter_dict; 240 241 if (what & PURGE_LISTENERS) { 242 while ((l = TAILQ_FIRST(env->sc_listeners)) != NULL) { 243 TAILQ_REMOVE(env->sc_listeners, l, entry); 244 free(l); 245 } 246 free(env->sc_listeners); 247 env->sc_listeners = NULL; 248 } 249 if (what & PURGE_TABLES) { 250 while (dict_root(env->sc_tables_dict, NULL, (void **)&t)) 251 table_destroy(env, t); 252 free(env->sc_tables_dict); 253 env->sc_tables_dict = NULL; 254 } 255 if (what & PURGE_RULES) { 256 while ((r = TAILQ_FIRST(env->sc_rules)) != NULL) { 257 TAILQ_REMOVE(env->sc_rules, r, r_entry); 258 free(r); 259 } 260 free(env->sc_rules); 261 env->sc_rules = NULL; 262 } 263 if (what & PURGE_DISPATCHERS) { 264 while (dict_poproot(env->sc_dispatchers, (void **)&d)) { 265 free(d); 266 } 267 free(env->sc_dispatchers); 268 env->sc_dispatchers = NULL; 269 } 270 if (what & PURGE_PKI) { 271 while (dict_poproot(env->sc_pki_dict, (void **)&p)) { 272 freezero(p->pki_cert, p->pki_cert_len); 273 freezero(p->pki_key, p->pki_key_len); 274 EVP_PKEY_free(p->pki_pkey); 275 free(p); 276 } 277 free(env->sc_pki_dict); 278 env->sc_pki_dict = NULL; 279 } else if (what & PURGE_PKI_KEYS) { 280 iter_dict = NULL; 281 while (dict_iter(env->sc_pki_dict, &iter_dict, &k, 282 (void **)&p)) { 283 freezero(p->pki_cert, p->pki_cert_len); 284 p->pki_cert = NULL; 285 freezero(p->pki_key, p->pki_key_len); 286 p->pki_key = NULL; 287 EVP_PKEY_free(p->pki_pkey); 288 p->pki_pkey = NULL; 289 } 290 } 291 } 292 293 #ifndef CONFIG_MINIMUM 294 295 void 296 config_process(enum smtp_proc_type proc) 297 { 298 struct rlimit rl; 299 300 smtpd_process = proc; 301 setproctitle("%s", proc_title(proc)); 302 303 if (getrlimit(RLIMIT_NOFILE, &rl) == -1) 304 fatal("fdlimit: getrlimit"); 305 rl.rlim_cur = rl.rlim_max; 306 if (setrlimit(RLIMIT_NOFILE, &rl) == -1) 307 fatal("fdlimit: setrlimit"); 308 } 309 310 void 311 config_peer(enum smtp_proc_type proc) 312 { 313 struct mproc *p; 314 315 if (proc == smtpd_process) 316 fatal("config_peers: cannot peer with oneself"); 317 318 if (proc == PROC_CONTROL) 319 p = p_control; 320 else if (proc == PROC_LKA) 321 p = p_lka; 322 else if (proc == PROC_PARENT) 323 p = p_parent; 324 else if (proc == PROC_QUEUE) 325 p = p_queue; 326 else if (proc == PROC_SCHEDULER) 327 p = p_scheduler; 328 else if (proc == PROC_PONY) 329 p = p_pony; 330 else if (proc == PROC_CA) 331 p = p_ca; 332 else 333 fatalx("bad peer"); 334 335 mproc_enable(p); 336 } 337 338 #else 339 340 void config_process(enum smtp_proc_type proc) {} 341 void config_peer(enum smtp_proc_type proc) {} 342 343 #endif 344