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