1 /*++
2 /* NAME
3 /* tlsmgr 8
4 /* SUMMARY
5 /* Postfix TLS session cache and PRNG manager
6 /* SYNOPSIS
7 /* \fBtlsmgr\fR [generic Postfix daemon options]
8 /* DESCRIPTION
9 /* The \fBtlsmgr\fR(8) manages the Postfix TLS session caches.
10 /* It stores and retrieves cache entries on request by
11 /* \fBsmtpd\fR(8) and \fBsmtp\fR(8) processes, and periodically
12 /* removes entries that have expired.
13 /*
14 /* The \fBtlsmgr\fR(8) also manages the PRNG (pseudo random number
15 /* generator) pool. It answers queries by the \fBsmtpd\fR(8)
16 /* and \fBsmtp\fR(8)
17 /* processes to seed their internal PRNG pools.
18 /*
19 /* The \fBtlsmgr\fR(8)'s PRNG pool is initially seeded from
20 /* an external source (EGD, /dev/urandom, or regular file).
21 /* It is updated at configurable pseudo-random intervals with
22 /* data from the external source. It is updated periodically
23 /* with data from TLS session cache entries and with the time
24 /* of day, and is updated with the time of day whenever a
25 /* process requests \fBtlsmgr\fR(8) service.
26 /*
27 /* The \fBtlsmgr\fR(8) saves the PRNG state to an exchange file
28 /* periodically and when the process terminates, and reads
29 /* the exchange file when initializing its PRNG.
30 /* SECURITY
31 /* .ad
32 /* .fi
33 /* The \fBtlsmgr\fR(8) is not security-sensitive. The code that maintains
34 /* the external and internal PRNG pools does not "trust" the
35 /* data that it manipulates, and the code that maintains the
36 /* TLS session cache does not touch the contents of the cached
37 /* entries, except for seeding its internal PRNG pool.
38 /*
39 /* The \fBtlsmgr\fR(8) can be run chrooted and with reduced privileges.
40 /* At process startup it connects to the entropy source and
41 /* exchange file, and creates or truncates the optional TLS
42 /* session cache files.
43 /*
44 /* With Postfix version 2.5 and later, the \fBtlsmgr\fR(8) no
45 /* longer uses root privileges when opening cache files. These
46 /* files should now be stored under the Postfix-owned
47 /* \fBdata_directory\fR. As a migration aid, an attempt to
48 /* open a cache file under a non-Postfix directory is redirected
49 /* to the Postfix-owned \fBdata_directory\fR, and a warning
50 /* is logged.
51 /* DIAGNOSTICS
52 /* Problems and transactions are logged to \fBsyslogd\fR(8)
53 /* or \fBpostlogd\fR(8).
54 /* BUGS
55 /* There is no automatic means to limit the number of entries in the
56 /* TLS session caches and/or the size of the TLS cache files.
57 /* CONFIGURATION PARAMETERS
58 /* .ad
59 /* .fi
60 /* Changes to \fBmain.cf\fR are not picked up automatically,
61 /* because \fBtlsmgr\fR(8) is a persistent processes. Use the
62 /* command "\fBpostfix reload\fR" after a configuration change.
63 /*
64 /* The text below provides only a parameter summary. See
65 /* \fBpostconf\fR(5) for more details including examples.
66 /* TLS SESSION CACHE
67 /* .ad
68 /* .fi
69 /* .IP "\fBlmtp_tls_loglevel (0)\fR"
70 /* The LMTP-specific version of the smtp_tls_loglevel
71 /* configuration parameter.
72 /* .IP "\fBlmtp_tls_session_cache_database (empty)\fR"
73 /* The LMTP-specific version of the smtp_tls_session_cache_database
74 /* configuration parameter.
75 /* .IP "\fBlmtp_tls_session_cache_timeout (3600s)\fR"
76 /* The LMTP-specific version of the smtp_tls_session_cache_timeout
77 /* configuration parameter.
78 /* .IP "\fBsmtp_tls_loglevel (0)\fR"
79 /* Enable additional Postfix SMTP client logging of TLS activity.
80 /* .IP "\fBsmtp_tls_session_cache_database (empty)\fR"
81 /* Name of the file containing the optional Postfix SMTP client
82 /* TLS session cache.
83 /* .IP "\fBsmtp_tls_session_cache_timeout (3600s)\fR"
84 /* The expiration time of Postfix SMTP client TLS session cache
85 /* information.
86 /* .IP "\fBsmtpd_tls_loglevel (0)\fR"
87 /* Enable additional Postfix SMTP server logging of TLS activity.
88 /* .IP "\fBsmtpd_tls_session_cache_database (empty)\fR"
89 /* Name of the file containing the optional Postfix SMTP server
90 /* TLS session cache.
91 /* .IP "\fBsmtpd_tls_session_cache_timeout (3600s)\fR"
92 /* The expiration time of Postfix SMTP server TLS session cache
93 /* information.
94 /* PSEUDO RANDOM NUMBER GENERATOR
95 /* .ad
96 /* .fi
97 /* .IP "\fBtls_random_source (see 'postconf -d' output)\fR"
98 /* The external entropy source for the in-memory \fBtlsmgr\fR(8) pseudo
99 /* random number generator (PRNG) pool.
100 /* .IP "\fBtls_random_bytes (32)\fR"
101 /* The number of bytes that \fBtlsmgr\fR(8) reads from $tls_random_source
102 /* when (re)seeding the in-memory pseudo random number generator (PRNG)
103 /* pool.
104 /* .IP "\fBtls_random_exchange_name (see 'postconf -d' output)\fR"
105 /* Name of the pseudo random number generator (PRNG) state file
106 /* that is maintained by \fBtlsmgr\fR(8).
107 /* .IP "\fBtls_random_prng_update_period (3600s)\fR"
108 /* The time between attempts by \fBtlsmgr\fR(8) to save the state of
109 /* the pseudo random number generator (PRNG) to the file specified
110 /* with $tls_random_exchange_name.
111 /* .IP "\fBtls_random_reseed_period (3600s)\fR"
112 /* The maximal time between attempts by \fBtlsmgr\fR(8) to re-seed the
113 /* in-memory pseudo random number generator (PRNG) pool from external
114 /* sources.
115 /* MISCELLANEOUS CONTROLS
116 /* .ad
117 /* .fi
118 /* .IP "\fBconfig_directory (see 'postconf -d' output)\fR"
119 /* The default location of the Postfix main.cf and master.cf
120 /* configuration files.
121 /* .IP "\fBdata_directory (see 'postconf -d' output)\fR"
122 /* The directory with Postfix-writable data files (for example:
123 /* caches, pseudo-random numbers).
124 /* .IP "\fBdaemon_timeout (18000s)\fR"
125 /* How much time a Postfix daemon process may take to handle a
126 /* request before it is terminated by a built-in watchdog timer.
127 /* .IP "\fBprocess_id (read-only)\fR"
128 /* The process ID of a Postfix command or daemon process.
129 /* .IP "\fBprocess_name (read-only)\fR"
130 /* The process name of a Postfix command or daemon process.
131 /* .IP "\fBsyslog_facility (mail)\fR"
132 /* The syslog facility of Postfix logging.
133 /* .IP "\fBsyslog_name (see 'postconf -d' output)\fR"
134 /* A prefix that is prepended to the process name in syslog
135 /* records, so that, for example, "smtpd" becomes "prefix/smtpd".
136 /* .PP
137 /* Available in Postfix 3.3 and later:
138 /* .IP "\fBservice_name (read-only)\fR"
139 /* The master.cf service name of a Postfix daemon process.
140 /* SEE ALSO
141 /* smtp(8), Postfix SMTP client
142 /* smtpd(8), Postfix SMTP server
143 /* postconf(5), configuration parameters
144 /* master(5), generic daemon options
145 /* master(8), process manager
146 /* postlogd(8), Postfix logging
147 /* syslogd(8), system logging
148 /* README FILES
149 /* .ad
150 /* .fi
151 /* Use "\fBpostconf readme_directory\fR" or
152 /* "\fBpostconf html_directory\fR" to locate this information.
153 /* .na
154 /* .nf
155 /* TLS_README, Postfix TLS configuration and operation
156 /* LICENSE
157 /* .ad
158 /* .fi
159 /* The Secure Mailer license must be distributed with this software.
160 /* HISTORY
161 /* This service was introduced with Postfix version 2.2.
162 /* AUTHOR(S)
163 /* Lutz Jaenicke
164 /* BTU Cottbus
165 /* Allgemeine Elektrotechnik
166 /* Universitaetsplatz 3-4
167 /* D-03044 Cottbus, Germany
168 /*
169 /* Adapted by:
170 /* Wietse Venema
171 /* IBM T.J. Watson Research
172 /* P.O. Box 704
173 /* Yorktown Heights, NY 10598, USA
174 /*
175 /* Wietse Venema
176 /* Google, Inc.
177 /* 111 8th Avenue
178 /* New York, NY 10011, USA
179 /*--*/
180
181 /* System library. */
182
183 #include <sys_defs.h>
184 #include <sys/stat.h>
185 #include <stdlib.h>
186 #include <unistd.h>
187 #include <ctype.h>
188 #include <errno.h>
189 #include <string.h>
190 #include <sys/time.h> /* gettimeofday, not POSIX */
191 #include <limits.h>
192
193 #ifndef UCHAR_MAX
194 #define UCHAR_MAX 0xff
195 #endif
196
197 /* OpenSSL library. */
198
199 #ifdef USE_TLS
200 #include <openssl/rand.h> /* For the PRNG */
201 #endif
202
203 /* Utility library. */
204
205 #include <msg.h>
206 #include <events.h>
207 #include <stringops.h>
208 #include <mymalloc.h>
209 #include <iostuff.h>
210 #include <vstream.h>
211 #include <vstring.h>
212 #include <vstring_vstream.h>
213 #include <attr.h>
214 #include <set_eugid.h>
215 #include <htable.h>
216 #include <warn_stat.h>
217
218 /* Global library. */
219
220 #include <mail_conf.h>
221 #include <mail_params.h>
222 #include <mail_version.h>
223 #include <mail_proto.h>
224 #include <data_redirect.h>
225
226 /* Master process interface. */
227
228 #include <master_proto.h>
229 #include <mail_server.h>
230
231 /* TLS library. */
232
233 #ifdef USE_TLS
234 #include <tls_mgr.h>
235 #define TLS_INTERNAL
236 #include <tls.h> /* TLS_MGR_SCACHE_<type> */
237 #include <tls_prng.h>
238 #include <tls_scache.h>
239
240 /* Application-specific. */
241
242 /*
243 * Tunables.
244 */
245 char *var_tls_rand_source;
246 int var_tls_rand_bytes;
247 int var_tls_reseed_period;
248 int var_tls_prng_exch_period;
249 char *var_smtpd_tls_loglevel;
250 char *var_smtpd_tls_scache_db;
251 int var_smtpd_tls_scache_timeout;
252 char *var_smtp_tls_loglevel;
253 char *var_smtp_tls_scache_db;
254 int var_smtp_tls_scache_timeout;
255 char *var_lmtp_tls_loglevel;
256 char *var_lmtp_tls_scache_db;
257 int var_lmtp_tls_scache_timeout;
258 char *var_tls_rand_exch_name;
259
260 /*
261 * Bound the time that we are willing to wait for an I/O operation. This
262 * produces better error messages than waiting until the watchdog timer
263 * kills the process.
264 */
265 #define TLS_MGR_TIMEOUT 10
266
267 /*
268 * State for updating the PRNG exchange file.
269 */
270 static TLS_PRNG_SRC *rand_exch;
271
272 /*
273 * State for seeding the internal PRNG from external source.
274 */
275 static TLS_PRNG_SRC *rand_source_dev;
276 static TLS_PRNG_SRC *rand_source_egd;
277 static TLS_PRNG_SRC *rand_source_file;
278
279 /*
280 * The external entropy source type is encoded in the source name. The
281 * obvious alternative is to have separate configuration parameters per
282 * source type, so that one process can query multiple external sources.
283 */
284 #define DEV_PREF "dev:"
285 #define DEV_PREF_LEN (sizeof((DEV_PREF)) - 1)
286 #define DEV_PATH(dev) ((dev) + EGD_PREF_LEN)
287
288 #define EGD_PREF "egd:"
289 #define EGD_PREF_LEN (sizeof((EGD_PREF)) - 1)
290 #define EGD_PATH(egd) ((egd) + EGD_PREF_LEN)
291
292 /*
293 * State for TLS session caches.
294 */
295 typedef struct {
296 char *cache_label; /* cache short-hand name */
297 TLS_SCACHE *cache_info; /* cache handle */
298 int cache_active; /* cache status */
299 char **cache_db; /* main.cf parameter value */
300 const char *log_param; /* main.cf parameter name */
301 char **log_level; /* main.cf parameter value */
302 int *cache_timeout; /* main.cf parameter value */
303 } TLSMGR_SCACHE;
304
305 static TLSMGR_SCACHE cache_table[] = {
306 TLS_MGR_SCACHE_SMTPD, 0, 0, &var_smtpd_tls_scache_db,
307 VAR_SMTPD_TLS_LOGLEVEL,
308 &var_smtpd_tls_loglevel, &var_smtpd_tls_scache_timeout,
309 TLS_MGR_SCACHE_SMTP, 0, 0, &var_smtp_tls_scache_db,
310 VAR_SMTP_TLS_LOGLEVEL,
311 &var_smtp_tls_loglevel, &var_smtp_tls_scache_timeout,
312 TLS_MGR_SCACHE_LMTP, 0, 0, &var_lmtp_tls_scache_db,
313 VAR_LMTP_TLS_LOGLEVEL,
314 &var_lmtp_tls_loglevel, &var_lmtp_tls_scache_timeout,
315 0,
316 };
317
318 #define smtpd_cache (cache_table[0])
319
320 /*
321 * SLMs.
322 */
323 #define STR(x) vstring_str(x)
324 #define LEN(x) VSTRING_LEN(x)
325 #define STREQ(x, y) (strcmp((x), (y)) == 0)
326
327 /* tlsmgr_prng_exch_event - update PRNG exchange file */
328
tlsmgr_prng_exch_event(int unused_event,void * dummy)329 static void tlsmgr_prng_exch_event(int unused_event, void *dummy)
330 {
331 const char *myname = "tlsmgr_prng_exch_event";
332 unsigned char randbyte;
333 int next_period;
334 struct stat st;
335
336 if (msg_verbose)
337 msg_info("%s: update PRNG exchange file", myname);
338
339 /*
340 * Sanity check. If the PRNG exchange file was removed, there is no point
341 * updating it further. Restart the process and update the new file.
342 */
343 if (fstat(rand_exch->fd, &st) < 0)
344 msg_fatal("cannot fstat() the PRNG exchange file: %m");
345 if (st.st_nlink == 0) {
346 msg_warn("PRNG exchange file was removed -- exiting to reopen");
347 sleep(1);
348 exit(0);
349 }
350 tls_prng_exch_update(rand_exch);
351
352 /*
353 * Make prediction difficult for outsiders and calculate the time for the
354 * next execution randomly.
355 */
356 RAND_bytes(&randbyte, 1);
357 next_period = (var_tls_prng_exch_period * randbyte) / UCHAR_MAX;
358 event_request_timer(tlsmgr_prng_exch_event, dummy, next_period);
359 }
360
361 /* tlsmgr_reseed_event - re-seed the internal PRNG pool */
362
tlsmgr_reseed_event(int unused_event,void * dummy)363 static void tlsmgr_reseed_event(int unused_event, void *dummy)
364 {
365 int next_period;
366 unsigned char randbyte;
367 int must_exit = 0;
368
369 /*
370 * Reseed the internal PRNG from external source. Errors are recoverable.
371 * We simply restart and reconnect without making a fuss. This is OK
372 * because we do require that exchange file updates succeed. The exchange
373 * file is the only entropy source that really matters in the long term.
374 *
375 * If the administrator specifies an external randomness source that we
376 * could not open upon start-up, restart to see if we can open it now
377 * (and log a nagging warning if we can't).
378 */
379 if (*var_tls_rand_source) {
380
381 /*
382 * Source is a random device.
383 */
384 if (rand_source_dev) {
385 if (tls_prng_dev_read(rand_source_dev, var_tls_rand_bytes) <= 0) {
386 msg_info("cannot read from entropy device %s: %m -- "
387 "exiting to reopen", DEV_PATH(var_tls_rand_source));
388 must_exit = 1;
389 }
390 }
391
392 /*
393 * Source is an EGD compatible socket.
394 */
395 else if (rand_source_egd) {
396 if (tls_prng_egd_read(rand_source_egd, var_tls_rand_bytes) <= 0) {
397 msg_info("lost connection to EGD server %s -- "
398 "exiting to reconnect", EGD_PATH(var_tls_rand_source));
399 must_exit = 1;
400 }
401 }
402
403 /*
404 * Source is a regular file. Read the content once and close the
405 * file.
406 */
407 else if (rand_source_file) {
408 if (tls_prng_file_read(rand_source_file, var_tls_rand_bytes) <= 0)
409 msg_warn("cannot read from entropy file %s: %m",
410 var_tls_rand_source);
411 tls_prng_file_close(rand_source_file);
412 rand_source_file = 0;
413 var_tls_rand_source[0] = 0;
414 }
415
416 /*
417 * Could not open the external source upon start-up. See if we can
418 * open it this time. Save PRNG state before we exit.
419 */
420 else {
421 msg_info("exiting to reopen external entropy source %s",
422 var_tls_rand_source);
423 must_exit = 1;
424 }
425 }
426
427 /*
428 * Save PRNG state in case we must exit.
429 */
430 if (must_exit) {
431 if (rand_exch)
432 tls_prng_exch_update(rand_exch);
433 sleep(1);
434 exit(0);
435 }
436
437 /*
438 * Make prediction difficult for outsiders and calculate the time for the
439 * next execution randomly.
440 */
441 RAND_bytes(&randbyte, 1);
442 next_period = (var_tls_reseed_period * randbyte) / UCHAR_MAX;
443 event_request_timer(tlsmgr_reseed_event, dummy, next_period);
444 }
445
446 /* tlsmgr_cache_run_event - start TLS session cache scan */
447
tlsmgr_cache_run_event(int unused_event,void * ctx)448 static void tlsmgr_cache_run_event(int unused_event, void *ctx)
449 {
450 const char *myname = "tlsmgr_cache_run_event";
451 TLSMGR_SCACHE *cache = (TLSMGR_SCACHE *) ctx;
452
453 /*
454 * This routine runs when it is time for another TLS session cache scan.
455 * Make sure this routine gets called again in the future.
456 *
457 * Don't start a new scan when the timer goes off while cache cleanup is
458 * still in progress.
459 */
460 if (cache->cache_info->verbose)
461 msg_info("%s: start TLS %s session cache cleanup",
462 myname, cache->cache_label);
463
464 if (cache->cache_active == 0)
465 cache->cache_active =
466 tls_scache_sequence(cache->cache_info, DICT_SEQ_FUN_FIRST,
467 TLS_SCACHE_SEQUENCE_NOTHING);
468
469 event_request_timer(tlsmgr_cache_run_event, (void *) cache,
470 cache->cache_info->timeout);
471 }
472
473 /* tlsmgr_key - return matching or current RFC 5077 session ticket keys */
474
tlsmgr_key(VSTRING * buffer,int timeout)475 static int tlsmgr_key(VSTRING *buffer, int timeout)
476 {
477 TLS_TICKET_KEY *key;
478 TLS_TICKET_KEY tmp;
479 unsigned char *name;
480 time_t now = time((time_t *) 0);
481
482 /* In tlsmgr requests we encode null key names as empty strings. */
483 name = LEN(buffer) ? (unsigned char *) STR(buffer) : 0;
484
485 /*
486 * Each key's encrypt and subsequent decrypt-only timeout is half of the
487 * total session timeout.
488 */
489 timeout /= 2;
490
491 /* Attempt to locate existing key */
492 if ((key = tls_scache_key(name, now, timeout)) == 0) {
493 if (name == 0) {
494 /* Create new encryption key */
495 if (RAND_bytes(tmp.name, TLS_TICKET_NAMELEN) <= 0
496 || RAND_bytes(tmp.bits, TLS_TICKET_KEYLEN) <= 0
497 || RAND_bytes(tmp.hmac, TLS_TICKET_MACLEN) <= 0)
498 return (TLS_MGR_STAT_ERR);
499 tmp.tout = now + timeout - 1;
500 key = tls_scache_key_rotate(&tmp);
501 } else {
502 /* No matching decryption key found */
503 return (TLS_MGR_STAT_ERR);
504 }
505 }
506 /* Return value overrites name buffer */
507 vstring_memcpy(buffer, (char *) key, sizeof(*key));
508 return (TLS_MGR_STAT_OK);
509 }
510
511 /* tlsmgr_loop - TLS manager main loop */
512
tlsmgr_loop(char * unused_name,char ** unused_argv)513 static int tlsmgr_loop(char *unused_name, char **unused_argv)
514 {
515 struct timeval tv;
516 int active = 0;
517 TLSMGR_SCACHE *ent;
518
519 /*
520 * Update the PRNG pool with the time of day. We do it here after every
521 * event (including internal timer events and external client request
522 * events), instead of doing it in individual event call-back routines.
523 */
524 GETTIMEOFDAY(&tv);
525 RAND_seed(&tv, sizeof(struct timeval));
526
527 /*
528 * This routine runs as part of the event handling loop, after the event
529 * manager has delivered a timer or I/O event, or after it has waited for
530 * a specified amount of time. The result value of tlsmgr_loop()
531 * specifies how long the event manager should wait for the next event.
532 *
533 * We use this loop to interleave TLS session cache cleanup with other
534 * activity. Interleaved processing is needed when we use a client-server
535 * protocol for entropy and session state exchange with smtp(8) and
536 * smtpd(8) processes.
537 */
538 #define DONT_WAIT 0
539 #define WAIT_FOR_EVENT (-1)
540
541 for (ent = cache_table; ent->cache_label; ++ent) {
542 if (ent->cache_info && ent->cache_active)
543 active |= ent->cache_active =
544 tls_scache_sequence(ent->cache_info, DICT_SEQ_FUN_NEXT,
545 TLS_SCACHE_SEQUENCE_NOTHING);
546 }
547
548 return (active ? DONT_WAIT : WAIT_FOR_EVENT);
549 }
550
551 /* tlsmgr_request_receive - receive request */
552
tlsmgr_request_receive(VSTREAM * client_stream,VSTRING * request)553 static int tlsmgr_request_receive(VSTREAM *client_stream, VSTRING *request)
554 {
555 int count;
556
557 /*
558 * Kluge: choose the protocol depending on the request size.
559 */
560 if (read_wait(vstream_fileno(client_stream), var_ipc_timeout) < 0) {
561 msg_warn("timeout while waiting for data from %s",
562 VSTREAM_PATH(client_stream));
563 return (-1);
564 }
565 if ((count = peekfd(vstream_fileno(client_stream))) < 0) {
566 msg_warn("cannot examine read buffer of %s: %m",
567 VSTREAM_PATH(client_stream));
568 return (-1);
569 }
570
571 /*
572 * Short request: master trigger. Use the string+null protocol.
573 */
574 if (count <= 2) {
575 if (vstring_get_null(request, client_stream) == VSTREAM_EOF) {
576 msg_warn("end-of-input while reading request from %s: %m",
577 VSTREAM_PATH(client_stream));
578 return (-1);
579 }
580 }
581
582 /*
583 * Long request: real tlsmgr client. Use the attribute list protocol.
584 */
585 else {
586 if (attr_scan(client_stream,
587 ATTR_FLAG_MORE | ATTR_FLAG_STRICT,
588 RECV_ATTR_STR(TLS_MGR_ATTR_REQ, request),
589 ATTR_TYPE_END) != 1) {
590 return (-1);
591 }
592 }
593 return (0);
594 }
595
596 /* tlsmgr_service - respond to external request */
597
tlsmgr_service(VSTREAM * client_stream,char * unused_service,char ** argv)598 static void tlsmgr_service(VSTREAM *client_stream, char *unused_service,
599 char **argv)
600 {
601 static VSTRING *request = 0;
602 static VSTRING *cache_type = 0;
603 static VSTRING *cache_id = 0;
604 static VSTRING *buffer = 0;
605 int len;
606 static char wakeup[] = { /* master wakeup request */
607 TRIGGER_REQ_WAKEUP,
608 0,
609 };
610 TLSMGR_SCACHE *ent;
611 int status = TLS_MGR_STAT_FAIL;
612
613 /*
614 * Sanity check. This service takes no command-line arguments.
615 */
616 if (argv[0])
617 msg_fatal("unexpected command-line argument: %s", argv[0]);
618
619 /*
620 * Initialize. We're select threaded, so we can use static buffers.
621 */
622 if (request == 0) {
623 request = vstring_alloc(10);
624 cache_type = vstring_alloc(10);
625 cache_id = vstring_alloc(10);
626 buffer = vstring_alloc(10);
627 }
628
629 /*
630 * This routine runs whenever a client connects to the socket dedicated
631 * to the tlsmgr service (including wake up events sent by the master).
632 * All connection-management stuff is handled by the common code in
633 * multi_server.c.
634 */
635 if (tlsmgr_request_receive(client_stream, request) == 0) {
636
637 /*
638 * Load session from cache.
639 */
640 if (STREQ(STR(request), TLS_MGR_REQ_LOOKUP)) {
641 if (attr_scan(client_stream, ATTR_FLAG_STRICT,
642 RECV_ATTR_STR(TLS_MGR_ATTR_CACHE_TYPE, cache_type),
643 RECV_ATTR_STR(TLS_MGR_ATTR_CACHE_ID, cache_id),
644 ATTR_TYPE_END) == 2) {
645 for (ent = cache_table; ent->cache_label; ++ent)
646 if (strcmp(ent->cache_label, STR(cache_type)) == 0)
647 break;
648 if (ent->cache_label == 0) {
649 msg_warn("bogus cache type \"%s\" in \"%s\" request",
650 STR(cache_type), TLS_MGR_REQ_LOOKUP);
651 VSTRING_RESET(buffer);
652 } else if (ent->cache_info == 0) {
653
654 /*
655 * Cache type valid, but not enabled
656 */
657 VSTRING_RESET(buffer);
658 } else {
659 status = tls_scache_lookup(ent->cache_info,
660 STR(cache_id), buffer) ?
661 TLS_MGR_STAT_OK : TLS_MGR_STAT_ERR;
662 }
663 }
664 attr_print(client_stream, ATTR_FLAG_NONE,
665 SEND_ATTR_INT(MAIL_ATTR_STATUS, status),
666 SEND_ATTR_DATA(TLS_MGR_ATTR_SESSION,
667 LEN(buffer), STR(buffer)),
668 ATTR_TYPE_END);
669 }
670
671 /*
672 * Save session to cache.
673 */
674 else if (STREQ(STR(request), TLS_MGR_REQ_UPDATE)) {
675 if (attr_scan(client_stream, ATTR_FLAG_STRICT,
676 RECV_ATTR_STR(TLS_MGR_ATTR_CACHE_TYPE, cache_type),
677 RECV_ATTR_STR(TLS_MGR_ATTR_CACHE_ID, cache_id),
678 RECV_ATTR_DATA(TLS_MGR_ATTR_SESSION, buffer),
679 ATTR_TYPE_END) == 3) {
680 for (ent = cache_table; ent->cache_label; ++ent)
681 if (strcmp(ent->cache_label, STR(cache_type)) == 0)
682 break;
683 if (ent->cache_label == 0) {
684 msg_warn("bogus cache type \"%s\" in \"%s\" request",
685 STR(cache_type), TLS_MGR_REQ_UPDATE);
686 } else if (ent->cache_info != 0) {
687 status =
688 tls_scache_update(ent->cache_info, STR(cache_id),
689 STR(buffer), LEN(buffer)) ?
690 TLS_MGR_STAT_OK : TLS_MGR_STAT_ERR;
691 }
692 }
693 attr_print(client_stream, ATTR_FLAG_NONE,
694 SEND_ATTR_INT(MAIL_ATTR_STATUS, status),
695 ATTR_TYPE_END);
696 }
697
698 /*
699 * Delete session from cache.
700 */
701 else if (STREQ(STR(request), TLS_MGR_REQ_DELETE)) {
702 if (attr_scan(client_stream, ATTR_FLAG_STRICT,
703 RECV_ATTR_STR(TLS_MGR_ATTR_CACHE_TYPE, cache_type),
704 RECV_ATTR_STR(TLS_MGR_ATTR_CACHE_ID, cache_id),
705 ATTR_TYPE_END) == 2) {
706 for (ent = cache_table; ent->cache_label; ++ent)
707 if (strcmp(ent->cache_label, STR(cache_type)) == 0)
708 break;
709 if (ent->cache_label == 0) {
710 msg_warn("bogus cache type \"%s\" in \"%s\" request",
711 STR(cache_type), TLS_MGR_REQ_DELETE);
712 } else if (ent->cache_info != 0) {
713 status = tls_scache_delete(ent->cache_info,
714 STR(cache_id)) ?
715 TLS_MGR_STAT_OK : TLS_MGR_STAT_ERR;
716 }
717 }
718 attr_print(client_stream, ATTR_FLAG_NONE,
719 SEND_ATTR_INT(MAIL_ATTR_STATUS, status),
720 ATTR_TYPE_END);
721 }
722
723 /*
724 * RFC 5077 TLS session ticket keys
725 */
726 else if (STREQ(STR(request), TLS_MGR_REQ_TKTKEY)) {
727 if (attr_scan(client_stream, ATTR_FLAG_STRICT,
728 RECV_ATTR_DATA(TLS_MGR_ATTR_KEYNAME, buffer),
729 ATTR_TYPE_END) == 1) {
730 if (LEN(buffer) != 0 && LEN(buffer) != TLS_TICKET_NAMELEN) {
731 msg_warn("invalid session ticket key name length: %ld",
732 (long) LEN(buffer));
733 VSTRING_RESET(buffer);
734 } else if (*smtpd_cache.cache_timeout <= 0) {
735 status = TLS_MGR_STAT_ERR;
736 VSTRING_RESET(buffer);
737 } else {
738 status = tlsmgr_key(buffer, *smtpd_cache.cache_timeout);
739 }
740 }
741 attr_print(client_stream, ATTR_FLAG_NONE,
742 SEND_ATTR_INT(MAIL_ATTR_STATUS, status),
743 SEND_ATTR_DATA(TLS_MGR_ATTR_KEYBUF,
744 LEN(buffer), STR(buffer)),
745 ATTR_TYPE_END);
746 }
747
748 /*
749 * Entropy request.
750 */
751 else if (STREQ(STR(request), TLS_MGR_REQ_SEED)) {
752 if (attr_scan(client_stream, ATTR_FLAG_STRICT,
753 RECV_ATTR_INT(TLS_MGR_ATTR_SIZE, &len),
754 ATTR_TYPE_END) == 1) {
755 VSTRING_RESET(buffer);
756 if (len <= 0 || len > 255) {
757 msg_warn("bogus seed length \"%d\" in \"%s\" request",
758 len, TLS_MGR_REQ_SEED);
759 } else {
760 VSTRING_SPACE(buffer, len);
761 RAND_bytes((unsigned char *) STR(buffer), len);
762 vstring_set_payload_size(buffer, len);
763 status = TLS_MGR_STAT_OK;
764 }
765 }
766 attr_print(client_stream, ATTR_FLAG_NONE,
767 SEND_ATTR_INT(MAIL_ATTR_STATUS, status),
768 SEND_ATTR_DATA(TLS_MGR_ATTR_SEED,
769 LEN(buffer), STR(buffer)),
770 ATTR_TYPE_END);
771 }
772
773 /*
774 * Caching policy request.
775 */
776 else if (STREQ(STR(request), TLS_MGR_REQ_POLICY)) {
777 int cachable = 0;
778 int timeout = 0;
779
780 if (attr_scan(client_stream, ATTR_FLAG_STRICT,
781 RECV_ATTR_STR(TLS_MGR_ATTR_CACHE_TYPE, cache_type),
782 ATTR_TYPE_END) == 1) {
783 for (ent = cache_table; ent->cache_label; ++ent)
784 if (strcmp(ent->cache_label, STR(cache_type)) == 0)
785 break;
786 if (ent->cache_label == 0) {
787 msg_warn("bogus cache type \"%s\" in \"%s\" request",
788 STR(cache_type), TLS_MGR_REQ_POLICY);
789 } else {
790 cachable = (ent->cache_info != 0) ? 1 : 0;
791 timeout = *ent->cache_timeout;
792 status = TLS_MGR_STAT_OK;
793 }
794 }
795 attr_print(client_stream, ATTR_FLAG_NONE,
796 SEND_ATTR_INT(MAIL_ATTR_STATUS, status),
797 SEND_ATTR_INT(TLS_MGR_ATTR_CACHABLE, cachable),
798 SEND_ATTR_INT(TLS_MGR_ATTR_SESSTOUT, timeout),
799 ATTR_TYPE_END);
800 }
801
802 /*
803 * Master trigger. Normally, these triggers arrive only after some
804 * other process requested the tlsmgr's service. The purpose is to
805 * restart the tlsmgr after it aborted due to a fatal run-time error,
806 * so that it can continue its housekeeping even while nothing is
807 * using TLS.
808 *
809 * XXX Which begs the question, if TLS isn't used often, do we need a
810 * tlsmgr background process? It could terminate when the session
811 * caches are empty.
812 */
813 else if (STREQ(STR(request), wakeup)) {
814 if (msg_verbose)
815 msg_info("received master trigger");
816 multi_server_disconnect(client_stream);
817 return; /* NOT: vstream_fflush */
818 }
819 }
820
821 /*
822 * Protocol error.
823 */
824 else {
825 attr_print(client_stream, ATTR_FLAG_NONE,
826 SEND_ATTR_INT(MAIL_ATTR_STATUS, TLS_MGR_STAT_FAIL),
827 ATTR_TYPE_END);
828 }
829 vstream_fflush(client_stream);
830 }
831
832 /* tlsmgr_pre_init - pre-jail initialization */
833
tlsmgr_pre_init(char * unused_name,char ** unused_argv)834 static void tlsmgr_pre_init(char *unused_name, char **unused_argv)
835 {
836 char *path;
837 struct timeval tv;
838 TLSMGR_SCACHE *ent;
839 VSTRING *redirect;
840 HTABLE *dup_filter;
841 const char *dup_label;
842
843 /*
844 * If nothing else works then at least this will get us a few bits of
845 * entropy.
846 *
847 * XXX This is our first call into the OpenSSL library. We should find out
848 * if this can be moved to the post-jail initialization phase, without
849 * breaking compatibility with existing installations.
850 */
851 GETTIMEOFDAY(&tv);
852 tv.tv_sec ^= getpid();
853 RAND_seed(&tv, sizeof(struct timeval));
854
855 /*
856 * Open the external entropy source. We will not be able to open it again
857 * after we are sent to chroot jail, so we keep it open. Errors are not
858 * fatal. The exchange file (see below) is the only entropy source that
859 * really matters in the long run.
860 *
861 * Security note: we open the entropy source while privileged, but we don't
862 * access the source until after we release privileges. This way, none of
863 * the OpenSSL code gets to execute while we are privileged.
864 */
865 if (*var_tls_rand_source) {
866
867 /*
868 * Source is a random device.
869 */
870 if (!strncmp(var_tls_rand_source, DEV_PREF, DEV_PREF_LEN)) {
871 path = DEV_PATH(var_tls_rand_source);
872 rand_source_dev = tls_prng_dev_open(path, TLS_MGR_TIMEOUT);
873 if (rand_source_dev == 0)
874 msg_warn("cannot open entropy device %s: %m", path);
875 }
876
877 /*
878 * Source is an EGD compatible socket.
879 */
880 else if (!strncmp(var_tls_rand_source, EGD_PREF, EGD_PREF_LEN)) {
881 path = EGD_PATH(var_tls_rand_source);
882 rand_source_egd = tls_prng_egd_open(path, TLS_MGR_TIMEOUT);
883 if (rand_source_egd == 0)
884 msg_warn("cannot connect to EGD server %s: %m", path);
885 }
886
887 /*
888 * Source is regular file. We read this only once.
889 */
890 else {
891 rand_source_file =
892 tls_prng_file_open(var_tls_rand_source, TLS_MGR_TIMEOUT);
893 }
894 } else {
895 msg_warn("no entropy source specified with parameter %s",
896 VAR_TLS_RAND_SOURCE);
897 msg_warn("encryption keys etc. may be predictable");
898 }
899
900 /*
901 * Security: don't create root-owned files that contain untrusted data.
902 * And don't create Postfix-owned files in root-owned directories,
903 * either. We want a correct relationship between (file/directory)
904 * ownership and (file/directory) content.
905 */
906 SAVE_AND_SET_EUGID(var_owner_uid, var_owner_gid);
907 redirect = vstring_alloc(100);
908
909 /*
910 * Open the PRNG exchange file before going to jail, but don't use root
911 * privileges. Start the exchange file read/update pseudo thread after
912 * dropping privileges.
913 */
914 if (*var_tls_rand_exch_name) {
915 rand_exch =
916 tls_prng_exch_open(data_redirect_file(redirect,
917 var_tls_rand_exch_name));
918 if (rand_exch == 0)
919 msg_fatal("cannot open PRNG exchange file %s: %m",
920 var_tls_rand_exch_name);
921 }
922
923 /*
924 * Open the session cache files and discard old information before going
925 * to jail, but don't use root privilege. Start the cache maintenance
926 * pseudo threads after dropping privileges.
927 */
928 dup_filter = htable_create(sizeof(cache_table) / sizeof(cache_table[0]));
929 for (ent = cache_table; ent->cache_label; ++ent) {
930 /* Sanitize session timeout */
931 if (*ent->cache_timeout > 0) {
932 if (*ent->cache_timeout < TLS_SESSION_LIFEMIN)
933 *ent->cache_timeout = TLS_SESSION_LIFEMIN;
934 } else {
935 *ent->cache_timeout = 0;
936 }
937 /* External cache database disabled if timeout is non-positive */
938 if (*ent->cache_timeout > 0 && **ent->cache_db) {
939 if ((dup_label = htable_find(dup_filter, *ent->cache_db)) != 0)
940 msg_fatal("do not use the same TLS cache file %s for %s and %s",
941 *ent->cache_db, dup_label, ent->cache_label);
942 htable_enter(dup_filter, *ent->cache_db, ent->cache_label);
943 ent->cache_info =
944 tls_scache_open(data_redirect_map(redirect, *ent->cache_db),
945 ent->cache_label,
946 tls_log_mask(ent->log_param,
947 *ent->log_level) & TLS_LOG_CACHE,
948 *ent->cache_timeout);
949 }
950 }
951 htable_free(dup_filter, (void (*) (void *)) 0);
952
953 /*
954 * Clean up and restore privilege.
955 */
956 vstring_free(redirect);
957 RESTORE_SAVED_EUGID();
958 }
959
960 /* tlsmgr_post_init - post-jail initialization */
961
tlsmgr_post_init(char * unused_name,char ** unused_argv)962 static void tlsmgr_post_init(char *unused_name, char **unused_argv)
963 {
964 TLSMGR_SCACHE *ent;
965
966 #define NULL_EVENT (0)
967 #define NULL_CONTEXT ((char *) 0)
968
969 /*
970 * This routine runs after the skeleton code has entered the chroot jail,
971 * but before any client requests are serviced. Prevent automatic process
972 * suicide after a limited number of client requests or after a limited
973 * amount of idle time.
974 */
975 var_use_limit = 0;
976 var_idle_limit = 0;
977
978 /*
979 * Start the internal PRNG re-seeding pseudo thread first.
980 */
981 if (*var_tls_rand_source) {
982 if (var_tls_reseed_period > INT_MAX / UCHAR_MAX)
983 var_tls_reseed_period = INT_MAX / UCHAR_MAX;
984 tlsmgr_reseed_event(NULL_EVENT, NULL_CONTEXT);
985 }
986
987 /*
988 * Start the exchange file read/update pseudo thread.
989 */
990 if (*var_tls_rand_exch_name) {
991 if (var_tls_prng_exch_period > INT_MAX / UCHAR_MAX)
992 var_tls_prng_exch_period = INT_MAX / UCHAR_MAX;
993 tlsmgr_prng_exch_event(NULL_EVENT, NULL_CONTEXT);
994 }
995
996 /*
997 * Start the cache maintenance pseudo threads last. Strictly speaking
998 * there is nothing to clean up after we truncate the database to zero
999 * length, but early cleanup makes verbose logging more informative (we
1000 * get positive confirmation that the cleanup threads are running).
1001 */
1002 for (ent = cache_table; ent->cache_label; ++ent)
1003 if (ent->cache_info)
1004 tlsmgr_cache_run_event(NULL_EVENT, (void *) ent);
1005 }
1006
1007 /* tlsmgr_post_accept - announce our protocol */
1008
tlsmgr_post_accept(VSTREAM * stream,char * unused_name,char ** unused_argv,HTABLE * unused_table)1009 static void tlsmgr_post_accept(VSTREAM *stream, char *unused_name,
1010 char **unused_argv, HTABLE *unused_table)
1011 {
1012
1013 /*
1014 * Announce the protocol.
1015 */
1016 attr_print(stream, ATTR_FLAG_NONE,
1017 SEND_ATTR_STR(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_TLSMGR),
1018 ATTR_TYPE_END);
1019 (void) vstream_fflush(stream);
1020 }
1021
1022
1023 /* tlsmgr_before_exit - save PRNG state before exit */
1024
tlsmgr_before_exit(char * unused_service_name,char ** unused_argv)1025 static void tlsmgr_before_exit(char *unused_service_name, char **unused_argv)
1026 {
1027
1028 /*
1029 * Save state before we exit after "postfix reload".
1030 */
1031 if (rand_exch)
1032 tls_prng_exch_update(rand_exch);
1033 }
1034
1035 MAIL_VERSION_STAMP_DECLARE;
1036
1037 /* main - the main program */
1038
main(int argc,char ** argv)1039 int main(int argc, char **argv)
1040 {
1041 static const CONFIG_STR_TABLE str_table[] = {
1042 VAR_TLS_RAND_SOURCE, DEF_TLS_RAND_SOURCE, &var_tls_rand_source, 0, 0,
1043 VAR_TLS_RAND_EXCH_NAME, DEF_TLS_RAND_EXCH_NAME, &var_tls_rand_exch_name, 0, 0,
1044 VAR_SMTPD_TLS_SCACHE_DB, DEF_SMTPD_TLS_SCACHE_DB, &var_smtpd_tls_scache_db, 0, 0,
1045 VAR_SMTP_TLS_SCACHE_DB, DEF_SMTP_TLS_SCACHE_DB, &var_smtp_tls_scache_db, 0, 0,
1046 VAR_LMTP_TLS_SCACHE_DB, DEF_LMTP_TLS_SCACHE_DB, &var_lmtp_tls_scache_db, 0, 0,
1047 VAR_SMTPD_TLS_LOGLEVEL, DEF_SMTPD_TLS_LOGLEVEL, &var_smtpd_tls_loglevel, 0, 0,
1048 VAR_SMTP_TLS_LOGLEVEL, DEF_SMTP_TLS_LOGLEVEL, &var_smtp_tls_loglevel, 0, 0,
1049 VAR_LMTP_TLS_LOGLEVEL, DEF_LMTP_TLS_LOGLEVEL, &var_lmtp_tls_loglevel, 0, 0,
1050 0,
1051 };
1052 static const CONFIG_TIME_TABLE time_table[] = {
1053 VAR_TLS_RESEED_PERIOD, DEF_TLS_RESEED_PERIOD, &var_tls_reseed_period, 1, 0,
1054 VAR_TLS_PRNG_UPD_PERIOD, DEF_TLS_PRNG_UPD_PERIOD, &var_tls_prng_exch_period, 1, 0,
1055 VAR_SMTPD_TLS_SCACHTIME, DEF_SMTPD_TLS_SCACHTIME, &var_smtpd_tls_scache_timeout, 0, MAX_SMTPD_TLS_SCACHETIME,
1056 VAR_SMTP_TLS_SCACHTIME, DEF_SMTP_TLS_SCACHTIME, &var_smtp_tls_scache_timeout, 0, MAX_SMTP_TLS_SCACHETIME,
1057 VAR_LMTP_TLS_SCACHTIME, DEF_LMTP_TLS_SCACHTIME, &var_lmtp_tls_scache_timeout, 0, MAX_LMTP_TLS_SCACHETIME,
1058 0,
1059 };
1060 static const CONFIG_INT_TABLE int_table[] = {
1061 VAR_TLS_RAND_BYTES, DEF_TLS_RAND_BYTES, &var_tls_rand_bytes, 1, 0,
1062 0,
1063 };
1064
1065 /*
1066 * Fingerprint executables and core dumps.
1067 */
1068 MAIL_VERSION_STAMP_ALLOCATE;
1069
1070 /*
1071 * Use the multi service skeleton, and require that no-one else is
1072 * monitoring our service port while this process runs.
1073 */
1074 multi_server_main(argc, argv, tlsmgr_service,
1075 CA_MAIL_SERVER_TIME_TABLE(time_table),
1076 CA_MAIL_SERVER_INT_TABLE(int_table),
1077 CA_MAIL_SERVER_STR_TABLE(str_table),
1078 CA_MAIL_SERVER_PRE_INIT(tlsmgr_pre_init),
1079 CA_MAIL_SERVER_POST_INIT(tlsmgr_post_init),
1080 CA_MAIL_SERVER_POST_ACCEPT(tlsmgr_post_accept),
1081 CA_MAIL_SERVER_EXIT(tlsmgr_before_exit),
1082 CA_MAIL_SERVER_LOOP(tlsmgr_loop),
1083 CA_MAIL_SERVER_SOLITARY,
1084 0);
1085 }
1086
1087 #else
1088
1089 /* tlsmgr_service - respond to external trigger(s), non-TLS version */
1090
tlsmgr_service(VSTREAM * unused_stream,char * unused_service,char ** unused_argv)1091 static void tlsmgr_service(VSTREAM *unused_stream, char *unused_service,
1092 char **unused_argv)
1093 {
1094 msg_info("TLS support is not compiled in -- exiting");
1095 }
1096
1097 /* main - the main program, non-TLS version */
1098
main(int argc,char ** argv)1099 int main(int argc, char **argv)
1100 {
1101
1102 /*
1103 * 200411 We can't simply use msg_fatal() here, because the logging
1104 * hasn't been initialized. The text would disappear because stderr is
1105 * redirected to /dev/null.
1106 *
1107 * We invoke multi_server_main() to complete program initialization
1108 * (including logging) and then invoke the tlsmgr_service() routine to
1109 * log the message that says why this program will not run.
1110 */
1111 multi_server_main(argc, argv, tlsmgr_service,
1112 0);
1113 }
1114
1115 #endif
1116