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