xref: /netbsd-src/external/ibm-public/postfix/dist/src/tlsproxy/tlsproxy.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /*	$NetBSD: tlsproxy.c,v 1.2 2017/02/14 01:16:48 christos Exp $	*/
2 
3 /*++
4 /* NAME
5 /*	tlsproxy 8
6 /* SUMMARY
7 /*	Postfix TLS proxy
8 /* SYNOPSIS
9 /*	\fBtlsproxy\fR [generic Postfix daemon options]
10 /* DESCRIPTION
11 /*	The \fBtlsproxy\fR(8) server implements a server-side TLS
12 /*	proxy. It is used by \fBpostscreen\fR(8) to talk SMTP-over-TLS
13 /*	with remote SMTP clients that are not whitelisted (including
14 /*	clients whose whitelist status has expired),
15 /*	but it should also work for non-SMTP protocols.
16 /*
17 /*	Although one \fBtlsproxy\fR(8) process can serve multiple
18 /*	sessions at the same time, it is a good idea to allow the
19 /*	number of processes to increase with load, so that the
20 /*	service remains responsive.
21 /* PROTOCOL EXAMPLE
22 /* .ad
23 /* .fi
24 /*	The example below concerns \fBpostscreen\fR(8). However,
25 /*	the \fBtlsproxy\fR(8) server is agnostic of the application
26 /*	protocol, and the example is easily adapted to other
27 /*	applications.
28 /*
29 /*	After receiving a valid remote SMTP client STARTTLS command,
30 /*	the \fBpostscreen\fR(8) server sends the remote SMTP client
31 /*	endpoint string, the requested role (server), and the
32 /*	requested timeout to \fBtlsproxy\fR(8).  \fBpostscreen\fR(8)
33 /*	then receives a "TLS available" indication from \fBtlsproxy\fR(8).
34 /*	If the TLS service is available, \fBpostscreen\fR(8) sends
35 /*	the remote SMTP client file descriptor to \fBtlsproxy\fR(8),
36 /*	and sends the plaintext 220 greeting to the remote SMTP
37 /*	client.  This triggers TLS negotiations between the remote
38 /*	SMTP client and \fBtlsproxy\fR(8).  Upon completion of the
39 /*	TLS-level handshake, \fBtlsproxy\fR(8) translates between
40 /*	plaintext from/to \fBpostscreen\fR(8) and ciphertext to/from
41 /*	the remote SMTP client.
42 /* SECURITY
43 /* .ad
44 /* .fi
45 /*	The \fBtlsproxy\fR(8) server is moderately security-sensitive.
46 /*	It talks to untrusted clients on the network. The process
47 /*	can be run chrooted at fixed low privilege.
48 /* DIAGNOSTICS
49 /*	Problems and transactions are logged to \fBsyslogd\fR(8).
50 /* CONFIGURATION PARAMETERS
51 /* .ad
52 /* .fi
53 /*	Changes to \fBmain.cf\fR are not picked up automatically,
54 /*	as \fBtlsproxy\fR(8) processes may run for a long time
55 /*	depending on mail server load.  Use the command "\fBpostfix
56 /*	reload\fR" to speed up a change.
57 /*
58 /*	The text below provides only a parameter summary. See
59 /*	\fBpostconf\fR(5) for more details including examples.
60 /* STARTTLS SUPPORT CONTROLS
61 /* .ad
62 /* .fi
63 /* .IP "\fBtlsproxy_tls_CAfile ($smtpd_tls_CAfile)\fR"
64 /*	A file containing (PEM format) CA certificates of root CAs
65 /*	trusted to sign either remote SMTP client certificates or intermediate
66 /*	CA certificates.
67 /* .IP "\fBtlsproxy_tls_CApath ($smtpd_tls_CApath)\fR"
68 /*	A directory containing (PEM format) CA certificates of root CAs
69 /*	trusted to sign either remote SMTP client certificates or intermediate
70 /*	CA certificates.
71 /* .IP "\fBtlsproxy_tls_always_issue_session_ids ($smtpd_tls_always_issue_session_ids)\fR"
72 /*	Force the Postfix \fBtlsproxy\fR(8) server to issue a TLS session id,
73 /*	even when TLS session caching is turned off.
74 /* .IP "\fBtlsproxy_tls_ask_ccert ($smtpd_tls_ask_ccert)\fR"
75 /*	Ask a remote SMTP client for a client certificate.
76 /* .IP "\fBtlsproxy_tls_ccert_verifydepth ($smtpd_tls_ccert_verifydepth)\fR"
77 /*	The verification depth for remote SMTP client certificates.
78 /* .IP "\fBtlsproxy_tls_cert_file ($smtpd_tls_cert_file)\fR"
79 /*	File with the Postfix \fBtlsproxy\fR(8) server RSA certificate in PEM
80 /*	format.
81 /* .IP "\fBtlsproxy_tls_ciphers ($smtpd_tls_ciphers)\fR"
82 /*	The minimum TLS cipher grade that the Postfix \fBtlsproxy\fR(8) server
83 /*	will use with opportunistic TLS encryption.
84 /* .IP "\fBtlsproxy_tls_dcert_file ($smtpd_tls_dcert_file)\fR"
85 /*	File with the Postfix \fBtlsproxy\fR(8) server DSA certificate in PEM
86 /*	format.
87 /* .IP "\fBtlsproxy_tls_dh1024_param_file ($smtpd_tls_dh1024_param_file)\fR"
88 /*	File with DH parameters that the Postfix \fBtlsproxy\fR(8) server
89 /*	should use with non-export EDH ciphers.
90 /* .IP "\fBtlsproxy_tls_dh512_param_file ($smtpd_tls_dh512_param_file)\fR"
91 /*	File with DH parameters that the Postfix \fBtlsproxy\fR(8) server
92 /*	should use with export-grade EDH ciphers.
93 /* .IP "\fBtlsproxy_tls_dkey_file ($smtpd_tls_dkey_file)\fR"
94 /*	File with the Postfix \fBtlsproxy\fR(8) server DSA private key in PEM
95 /*	format.
96 /* .IP "\fBtlsproxy_tls_eccert_file ($smtpd_tls_eccert_file)\fR"
97 /*	File with the Postfix \fBtlsproxy\fR(8) server ECDSA certificate in
98 /*	PEM format.
99 /* .IP "\fBtlsproxy_tls_eckey_file ($smtpd_tls_eckey_file)\fR"
100 /*	File with the Postfix \fBtlsproxy\fR(8) server ECDSA private key in
101 /*	PEM format.
102 /* .IP "\fBtlsproxy_tls_eecdh_grade ($smtpd_tls_eecdh_grade)\fR"
103 /*	The Postfix \fBtlsproxy\fR(8) server security grade for ephemeral
104 /*	elliptic-curve Diffie-Hellman (EECDH) key exchange.
105 /* .IP "\fBtlsproxy_tls_exclude_ciphers ($smtpd_tls_exclude_ciphers)\fR"
106 /*	List of ciphers or cipher types to exclude from the \fBtlsproxy\fR(8)
107 /*	server cipher list at all TLS security levels.
108 /* .IP "\fBtlsproxy_tls_fingerprint_digest ($smtpd_tls_fingerprint_digest)\fR"
109 /*	The message digest algorithm to construct remote SMTP
110 /*	client-certificate
111 /*	fingerprints.
112 /* .IP "\fBtlsproxy_tls_key_file ($smtpd_tls_key_file)\fR"
113 /*	File with the Postfix \fBtlsproxy\fR(8) server RSA private key in PEM
114 /*	format.
115 /* .IP "\fBtlsproxy_tls_loglevel ($smtpd_tls_loglevel)\fR"
116 /*	Enable additional Postfix \fBtlsproxy\fR(8) server logging of TLS
117 /*	activity.
118 /* .IP "\fBtlsproxy_tls_mandatory_ciphers ($smtpd_tls_mandatory_ciphers)\fR"
119 /*	The minimum TLS cipher grade that the Postfix \fBtlsproxy\fR(8) server
120 /*	will use with mandatory TLS encryption.
121 /* .IP "\fBtlsproxy_tls_mandatory_exclude_ciphers ($smtpd_tls_mandatory_exclude_ciphers)\fR"
122 /*	Additional list of ciphers or cipher types to exclude from the
123 /*	\fBtlsproxy\fR(8) server cipher list at mandatory TLS security levels.
124 /* .IP "\fBtlsproxy_tls_mandatory_protocols ($smtpd_tls_mandatory_protocols)\fR"
125 /*	The SSL/TLS protocols accepted by the Postfix \fBtlsproxy\fR(8) server
126 /*	with mandatory TLS encryption.
127 /* .IP "\fBtlsproxy_tls_protocols ($smtpd_tls_protocols)\fR"
128 /*	List of TLS protocols that the Postfix \fBtlsproxy\fR(8) server will
129 /*	exclude or include with opportunistic TLS encryption.
130 /* .IP "\fBtlsproxy_tls_req_ccert ($smtpd_tls_req_ccert)\fR"
131 /*	With mandatory TLS encryption, require a trusted remote SMTP
132 /*	client certificate in order to allow TLS connections to proceed.
133 /* .IP "\fBtlsproxy_tls_security_level ($smtpd_tls_security_level)\fR"
134 /*	The SMTP TLS security level for the Postfix \fBtlsproxy\fR(8) server;
135 /*	when a non-empty value is specified, this overrides the obsolete
136 /*	parameters smtpd_use_tls and smtpd_enforce_tls.
137 /* .PP
138 /*	Available in Postfix version 2.11 and later:
139 /* .IP "\fBtlsmgr_service_name (tlsmgr)\fR"
140 /*	The name of the \fBtlsmgr\fR(8) service entry in master.cf.
141 /* OBSOLETE STARTTLS SUPPORT CONTROLS
142 /* .ad
143 /* .fi
144 /*	These parameters are supported for compatibility with
145 /*	\fBsmtpd\fR(8) legacy parameters.
146 /* .IP "\fBtlsproxy_use_tls ($smtpd_use_tls)\fR"
147 /*	Opportunistic TLS: announce STARTTLS support to remote SMTP clients,
148 /*	but do not require that clients use TLS encryption.
149 /* .IP "\fBtlsproxy_enforce_tls ($smtpd_enforce_tls)\fR"
150 /*	Mandatory TLS: announce STARTTLS support to remote SMTP clients, and
151 /*	require that clients use TLS encryption.
152 /* RESOURCE CONTROLS
153 /* .ad
154 /* .fi
155 /* .IP "\fBtlsproxy_watchdog_timeout (10s)\fR"
156 /*	How much time a \fBtlsproxy\fR(8) process may take to process local
157 /*	or remote I/O before it is terminated by a built-in watchdog timer.
158 /* MISCELLANEOUS CONTROLS
159 /* .ad
160 /* .fi
161 /* .IP "\fBconfig_directory (see 'postconf -d' output)\fR"
162 /*	The default location of the Postfix main.cf and master.cf
163 /*	configuration files.
164 /* .IP "\fBprocess_id (read-only)\fR"
165 /*	The process ID of a Postfix command or daemon process.
166 /* .IP "\fBprocess_name (read-only)\fR"
167 /*	The process name of a Postfix command or daemon process.
168 /* .IP "\fBsyslog_facility (mail)\fR"
169 /*	The syslog facility of Postfix logging.
170 /* .IP "\fBsyslog_name (see 'postconf -d' output)\fR"
171 /*	The mail system name that is prepended to the process name in syslog
172 /*	records, so that "smtpd" becomes, for example, "postfix/smtpd".
173 /* SEE ALSO
174 /*	postscreen(8), Postfix zombie blocker
175 /*	smtpd(8), Postfix SMTP server
176 /*	postconf(5), configuration parameters
177 /*	syslogd(5), system logging
178 /* LICENSE
179 /* .ad
180 /* .fi
181 /*	The Secure Mailer license must be distributed with this software.
182 /* HISTORY
183 /* .ad
184 /* .fi
185 /*	This service was introduced with Postfix version 2.8.
186 /* AUTHOR(S)
187 /*	Wietse Venema
188 /*	IBM T.J. Watson Research
189 /*	P.O. Box 704
190 /*	Yorktown Heights, NY 10598, USA
191 /*
192 /*	Wietse Venema
193 /*	Google, Inc.
194 /*	111 8th Avenue
195 /*	New York, NY 10011, USA
196 /*--*/
197 
198  /*
199   * System library.
200   */
201 #include <sys_defs.h>
202 #include <errno.h>
203 
204 #ifdef STRCASECMP_IN_STRINGS_H
205 #include <strings.h>
206 #endif
207 
208  /*
209   * Utility library.
210   */
211 #include <msg.h>
212 #include <vstream.h>
213 #include <iostuff.h>
214 #include <nbbio.h>
215 #include <mymalloc.h>
216 
217  /*
218   * Global library.
219   */
220 #include <mail_proto.h>
221 #include <mail_params.h>
222 #include <mail_conf.h>
223 #include <mail_version.h>
224 
225  /*
226   * Master library.
227   */
228 #include <mail_server.h>
229 
230  /*
231   * TLS library.
232   */
233 #ifdef USE_TLS
234 #define TLS_INTERNAL			/* XXX */
235 #include <tls.h>
236 #include <tls_proxy.h>
237 
238  /*
239   * Application-specific.
240   */
241 #include <tlsproxy.h>
242 
243  /*
244   * Tunable parameters. We define our clones of the smtpd(8) parameters to
245   * avoid any confusion about which parameters are used by this program.
246   */
247 int     var_smtpd_tls_ccert_vd;
248 char   *var_smtpd_tls_loglevel;
249 bool    var_smtpd_use_tls;
250 bool    var_smtpd_enforce_tls;
251 bool    var_smtpd_tls_ask_ccert;
252 bool    var_smtpd_tls_req_ccert;
253 bool    var_smtpd_tls_set_sessid;
254 char   *var_smtpd_relay_ccerts;
255 char   *var_smtpd_tls_cert_file;
256 char   *var_smtpd_tls_key_file;
257 char   *var_smtpd_tls_dcert_file;
258 char   *var_smtpd_tls_dkey_file;
259 char   *var_smtpd_tls_eccert_file;
260 char   *var_smtpd_tls_eckey_file;
261 char   *var_smtpd_tls_CAfile;
262 char   *var_smtpd_tls_CApath;
263 char   *var_smtpd_tls_ciph;
264 char   *var_smtpd_tls_mand_ciph;
265 char   *var_smtpd_tls_excl_ciph;
266 char   *var_smtpd_tls_mand_excl;
267 char   *var_smtpd_tls_proto;
268 char   *var_smtpd_tls_mand_proto;
269 char   *var_smtpd_tls_dh512_param_file;
270 char   *var_smtpd_tls_dh1024_param_file;
271 char   *var_smtpd_tls_eecdh;
272 char   *var_smtpd_tls_fpt_dgst;
273 char   *var_smtpd_tls_level;
274 
275 int     var_tlsp_tls_ccert_vd;
276 char   *var_tlsp_tls_loglevel;
277 bool    var_tlsp_use_tls;
278 bool    var_tlsp_enforce_tls;
279 bool    var_tlsp_tls_ask_ccert;
280 bool    var_tlsp_tls_req_ccert;
281 bool    var_tlsp_tls_set_sessid;
282 char   *var_tlsp_tls_cert_file;
283 char   *var_tlsp_tls_key_file;
284 char   *var_tlsp_tls_dcert_file;
285 char   *var_tlsp_tls_dkey_file;
286 char   *var_tlsp_tls_eccert_file;
287 char   *var_tlsp_tls_eckey_file;
288 char   *var_tlsp_tls_CAfile;
289 char   *var_tlsp_tls_CApath;
290 char   *var_tlsp_tls_ciph;
291 char   *var_tlsp_tls_mand_ciph;
292 char   *var_tlsp_tls_excl_ciph;
293 char   *var_tlsp_tls_mand_excl;
294 char   *var_tlsp_tls_proto;
295 char   *var_tlsp_tls_mand_proto;
296 char   *var_tlsp_tls_dh512_param_file;
297 char   *var_tlsp_tls_dh1024_param_file;
298 char   *var_tlsp_tls_eecdh;
299 char   *var_tlsp_tls_fpt_dgst;
300 char   *var_tlsp_tls_level;
301 
302 int     var_tlsp_watchdog;
303 
304  /*
305   * TLS per-process status.
306   */
307 static TLS_APPL_STATE *tlsp_server_ctx;
308 static int ask_client_cert;
309 
310  /*
311   * SLMs.
312   */
313 #define STR(x)	vstring_str(x)
314 
315  /*
316   * This code looks simpler than expected. That is the result of a great deal
317   * of effort, mainly in design and analysis.
318   *
319   * By design, postscreen(8) is an event-driven server that must scale up to a
320   * large number of clients. This means that postscreen(8) must avoid doing
321   * CPU-intensive operations such as those in OpenSSL.
322   *
323   * tlsproxy(8) runs the OpenSSL code on behalf of postscreen(8), translating
324   * plaintext SMTP messages from postscreen(8) into SMTP-over-TLS messages to
325   * the remote SMTP client, and vice versa. As long as postscreen(8) does not
326   * receive email messages, the cost of doing TLS operations will be modest.
327   *
328   * Like postscreen(8), one tlsproxy(8) process services multiple remote SMTP
329   * clients. Unlike postscreen(8), there can be more than one tlsproxy(8)
330   * process, although their number is meant to be much smaller than the
331   * number of remote SMTP clients that talk TLS.
332   *
333   * As with postscreen(8), all I/O must be event-driven: encrypted traffic
334   * between tlsproxy(8) and remote SMTP clients, and plaintext traffic
335   * between tlsproxy(8) and postscreen(8). Event-driven plaintext I/O is
336   * straightforward enough that it could be abstracted away with the nbbio(3)
337   * module.
338   *
339   * The event-driven TLS I/O implementation is founded on on-line OpenSSL
340   * documentation, supplemented by statements from OpenSSL developers on
341   * public mailing lists. After some field experience with this code, we may
342   * be able to factor it out as a library module, like nbbio(3), that can
343   * become part of the TLS library.
344   */
345 
346 static void tlsp_ciphertext_event(int, void *);
347 
348 #define TLSP_INIT_TIMEOUT	100
349 
350 /* tlsp_drain - delayed exit after "postfix reload" */
351 
352 static void tlsp_drain(char *unused_service, char **unused_argv)
353 {
354     int     count;
355 
356     /*
357      * After "postfix reload", complete work-in-progress in the background,
358      * instead of dropping already-accepted connections on the floor.
359      *
360      * All error retry counts shall be limited. Instead of blocking here, we
361      * could retry failed fork() operations in the event call-back routines,
362      * but we don't need perfection. The host system is severely overloaded
363      * and service levels are already way down.
364      */
365     for (count = 0; /* see below */ ; count++) {
366 	if (count >= 5) {
367 	    msg_fatal("fork: %m");
368 	} else if (event_server_drain() != 0) {
369 	    msg_warn("fork: %m");
370 	    sleep(1);
371 	    continue;
372 	} else {
373 	    return;
374 	}
375     }
376 }
377 
378 /* tlsp_eval_tls_error - translate TLS "error" result into action */
379 
380 static int tlsp_eval_tls_error(TLSP_STATE *state, int err)
381 {
382     int     ciphertext_fd = state->ciphertext_fd;
383 
384     /*
385      * The ciphertext file descriptor is in non-blocking mode, meaning that
386      * each SSL_accept/connect/read/write/shutdown request may return an
387      * "error" indication that it needs to read or write more ciphertext. The
388      * purpose of this routine is to translate those "error" indications into
389      * the appropriate read/write/timeout event requests.
390      */
391     switch (err) {
392 
393 	/*
394 	 * No error from SSL_read and SSL_write means that the plaintext
395 	 * output buffer is full and that the plaintext input buffer is
396 	 * empty. Stop read/write events on the ciphertext stream. Keep the
397 	 * timer alive as a safety mechanism for the case that the plaintext
398 	 * pseudothreads get stuck.
399 	 */
400     case SSL_ERROR_NONE:
401 	if (state->ssl_last_err != SSL_ERROR_NONE) {
402 	    event_disable_readwrite(ciphertext_fd);
403 	    event_request_timer(tlsp_ciphertext_event, (void *) state,
404 				state->timeout);
405 	    state->ssl_last_err = SSL_ERROR_NONE;
406 	}
407 	return (0);
408 
409 	/*
410 	 * The TLS engine wants to write to the network. Turn on
411 	 * write/timeout events on the ciphertext stream.
412 	 */
413     case SSL_ERROR_WANT_WRITE:
414 	if (state->ssl_last_err == SSL_ERROR_WANT_READ)
415 	    event_disable_readwrite(ciphertext_fd);
416 	if (state->ssl_last_err != SSL_ERROR_WANT_WRITE) {
417 	    event_enable_write(ciphertext_fd, tlsp_ciphertext_event,
418 			       (void *) state);
419 	    state->ssl_last_err = SSL_ERROR_WANT_WRITE;
420 	}
421 	event_request_timer(tlsp_ciphertext_event, (void *) state,
422 			    state->timeout);
423 	return (0);
424 
425 	/*
426 	 * The TLS engine wants to read from the network. Turn on
427 	 * read/timeout events on the ciphertext stream.
428 	 */
429     case SSL_ERROR_WANT_READ:
430 	if (state->ssl_last_err == SSL_ERROR_WANT_WRITE)
431 	    event_disable_readwrite(ciphertext_fd);
432 	if (state->ssl_last_err != SSL_ERROR_WANT_READ) {
433 	    event_enable_read(ciphertext_fd, tlsp_ciphertext_event,
434 			      (void *) state);
435 	    state->ssl_last_err = SSL_ERROR_WANT_READ;
436 	}
437 	event_request_timer(tlsp_ciphertext_event, (void *) state,
438 			    state->timeout);
439 	return (0);
440 
441 	/*
442 	 * Some error. Self-destruct. This automagically cleans up all
443 	 * pending read/write and timeout event requests, making state a
444 	 * dangling pointer.
445 	 */
446     case SSL_ERROR_SSL:
447 	tls_print_errors();
448 	/* FALLTHROUGH */
449     default:
450 	tlsp_state_free(state);
451 	return (-1);
452     }
453 }
454 
455 /* tlsp_strategy - decide what to read or write next. */
456 
457 static void tlsp_strategy(TLSP_STATE *state)
458 {
459     TLS_SESS_STATE *tls_context = state->tls_context;
460     NBBIO  *plaintext_buf;
461     int     ssl_stat;
462     int     ssl_read_err;
463     int     ssl_write_err;
464     int     handshake_err;
465 
466     /*
467      * Be sure to complete the TLS handshake before enabling plain-text I/O.
468      * In case of an unrecoverable error, this automagically cleans up all
469      * pending read/write and timeout event requests.
470      */
471     if (state->flags & TLSP_FLAG_DO_HANDSHAKE) {
472 	ssl_stat = SSL_accept(tls_context->con);
473 	if (ssl_stat != 1) {
474 	    handshake_err = SSL_get_error(tls_context->con, ssl_stat);
475 	    tlsp_eval_tls_error(state, handshake_err);
476 	    /* At this point, state could be a dangling pointer. */
477 	    return;
478 	}
479 	if ((state->tls_context = tls_server_post_accept(tls_context)) == 0) {
480 	    tlsp_state_free(state);
481 	    return;
482 	}
483 	if ((state->req_flags & TLS_PROXY_FLAG_SEND_CONTEXT) != 0
484 	    && (attr_print(state->plaintext_stream, ATTR_FLAG_NONE,
485 			   SEND_ATTR_FUNC(tls_proxy_context_print,
486 					  (void *) state->tls_context),
487 			   ATTR_TYPE_END) != 0
488 		|| vstream_fflush(state->plaintext_stream) != 0)) {
489 	    msg_warn("cannot send TLS context: %m");
490 	    tlsp_state_free(state);
491 	    return;
492 	}
493 	state->flags &= ~TLSP_FLAG_DO_HANDSHAKE;
494     }
495 
496     /*
497      * Shutdown and self-destruct after NBBIO error. This automagically
498      * cleans up all pending read/write and timeout event requests. Before
499      * shutting down TLS, we stop all plain-text I/O events but keep the
500      * NBBIO error flags.
501      */
502     plaintext_buf = state->plaintext_buf;
503     if (NBBIO_ERROR_FLAGS(plaintext_buf)) {
504 	if (NBBIO_ACTIVE_FLAGS(plaintext_buf))
505 	    nbbio_disable_readwrite(state->plaintext_buf);
506 	ssl_stat = SSL_shutdown(tls_context->con);
507 	/* XXX Wait for return value 1 if sessions are to be reused? */
508 	if (ssl_stat < 0) {
509 	    handshake_err = SSL_get_error(tls_context->con, ssl_stat);
510 	    tlsp_eval_tls_error(state, handshake_err);
511 	    /* At this point, state could be a dangling pointer. */
512 	    return;
513 	}
514 	tlsp_state_free(state);
515 	return;
516     }
517 
518     /*
519      * Try to move data from the plaintext input buffer to the TLS engine.
520      *
521      * XXX We're supposed to repeat the exact same SSL_write() call arguments
522      * after an SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE result. Rumor has
523      * it that this is because each SSL_write() call reads from the buffer
524      * incrementally, and returns > 0 only after the final byte is processed.
525      * Rumor also has it that setting SSL_MODE_ENABLE_PARTIAL_WRITE and
526      * SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER voids this requirement, and that
527      * repeating the request with an increased request size is OK.
528      * Unfortunately all this is not or poorly documented, and one has to
529      * rely on statements from OpenSSL developers in public mailing archives.
530      */
531     ssl_write_err = SSL_ERROR_NONE;
532     while (NBBIO_READ_PEND(plaintext_buf) > 0) {
533 	ssl_stat = SSL_write(tls_context->con, NBBIO_READ_BUF(plaintext_buf),
534 			     NBBIO_READ_PEND(plaintext_buf));
535 	ssl_write_err = SSL_get_error(tls_context->con, ssl_stat);
536 	if (ssl_write_err != SSL_ERROR_NONE)
537 	    break;
538 	/* Allow the plaintext pseudothread to read more data. */
539 	NBBIO_READ_PEND(plaintext_buf) -= ssl_stat;
540 	if (NBBIO_READ_PEND(plaintext_buf) > 0)
541 	    memmove(NBBIO_READ_BUF(plaintext_buf),
542 		    NBBIO_READ_BUF(plaintext_buf) + ssl_stat,
543 		    NBBIO_READ_PEND(plaintext_buf));
544     }
545 
546     /*
547      * Try to move data from the TLS engine to the plaintext output buffer.
548      * Note: data may arrive as a side effect of calling SSL_write(),
549      * therefore we call SSL_read() after calling SSL_write().
550      *
551      * XXX We're supposed to repeat the exact same SSL_read() call arguments
552      * after an SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE result. This
553      * supposedly means that our plaintext writer must not memmove() the
554      * plaintext output buffer until after the SSL_read() call succeeds. For
555      * now I'll ignore this, because 1) SSL_read() is documented to return
556      * the bytes available, instead of returning > 0 only after the entire
557      * buffer is processed like SSL_write() does; and 2) there is no "read"
558      * equivalent of the SSL_R_BAD_WRITE_RETRY, SSL_MODE_ENABLE_PARTIAL_WRITE
559      * or SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER features.
560      */
561     ssl_read_err = SSL_ERROR_NONE;
562     while (NBBIO_WRITE_PEND(state->plaintext_buf) < NBBIO_BUFSIZE(plaintext_buf)) {
563 	ssl_stat = SSL_read(tls_context->con,
564 			    NBBIO_WRITE_BUF(plaintext_buf)
565 			    + NBBIO_WRITE_PEND(state->plaintext_buf),
566 			    NBBIO_BUFSIZE(plaintext_buf)
567 			    - NBBIO_WRITE_PEND(state->plaintext_buf));
568 	ssl_read_err = SSL_get_error(tls_context->con, ssl_stat);
569 	if (ssl_read_err != SSL_ERROR_NONE)
570 	    break;
571 	NBBIO_WRITE_PEND(plaintext_buf) += ssl_stat;
572     }
573 
574     /*
575      * Try to enable/disable ciphertext read/write events. If SSL_write() was
576      * satisfied, see if SSL_read() wants to do some work. In case of an
577      * unrecoverable error, this automagically destroys the session state
578      * after cleaning up all pending read/write and timeout event requests.
579      */
580     if (tlsp_eval_tls_error(state, ssl_write_err != SSL_ERROR_NONE ?
581 			    ssl_write_err : ssl_read_err) < 0)
582 	return;
583 
584     /*
585      * Try to enable/disable plaintext read/write events. Basically, if we
586      * have nothing to write to the postscreen(8) server, see if there is
587      * something to read. If the write buffer is empty and the read buffer is
588      * full, suspend plaintext I/O until conditions change (but keep the
589      * timer active, as a safety mechanism in case ciphertext I/O gets
590      * stuck).
591      *
592      * XXX In theory, if the client keeps writing fast enough then we would
593      * never read from postscreen(8), and cause postscreen(8) to block. In
594      * practice, postscreen(8) limits the number of client commands, and thus
595      * postscreen(8)'s output will fit in a kernel buffer. This may not be
596      * true in other scenarios where the tlsproxy(8) server could be used.
597      */
598     if (NBBIO_WRITE_PEND(plaintext_buf) > 0) {
599 	if (NBBIO_ACTIVE_FLAGS(plaintext_buf) & NBBIO_FLAG_READ)
600 	    nbbio_disable_readwrite(plaintext_buf);
601 	if ((NBBIO_ACTIVE_FLAGS(plaintext_buf) & NBBIO_FLAG_WRITE) == 0)
602 	    nbbio_enable_write(plaintext_buf, state->timeout);
603     } else if (NBBIO_READ_PEND(plaintext_buf) < NBBIO_BUFSIZE(plaintext_buf)) {
604 	if (NBBIO_ACTIVE_FLAGS(plaintext_buf) & NBBIO_FLAG_WRITE)
605 	    nbbio_disable_readwrite(plaintext_buf);
606 	if ((NBBIO_ACTIVE_FLAGS(plaintext_buf) & NBBIO_FLAG_READ) == 0)
607 	    nbbio_enable_read(plaintext_buf, state->timeout);
608     } else {
609 	if (NBBIO_ACTIVE_FLAGS(plaintext_buf))
610 	    nbbio_slumber(plaintext_buf, state->timeout);
611     }
612 }
613 
614 /* tlsp_plaintext_event - plaintext was read/written */
615 
616 static void tlsp_plaintext_event(int event, void *context)
617 {
618     TLSP_STATE *state = (TLSP_STATE *) context;
619 
620     /*
621      * Safety alert: the plaintext pseudothreads have "slumbered" for too
622      * long (see code above). This means that the ciphertext pseudothreads
623      * are stuck.
624      */
625     if ((NBBIO_ERROR_FLAGS(state->plaintext_buf) & NBBIO_FLAG_TIMEOUT) != 0
626 	&& NBBIO_ACTIVE_FLAGS(state->plaintext_buf) == 0)
627 	msg_warn("deadlock on ciphertext stream for %s", state->remote_endpt);
628 
629     /*
630      * This is easy, because the NBBIO layer has already done the event
631      * decoding and plaintext I/O for us. All we need to do is decide if we
632      * want to read or write more plaintext.
633      */
634     tlsp_strategy(state);
635 }
636 
637 /* tlsp_ciphertext_event - ciphertext is ready to read/write */
638 
639 static void tlsp_ciphertext_event(int event, void *context)
640 {
641     TLSP_STATE *state = (TLSP_STATE *) context;
642 
643     /*
644      * Without a TLS quivalent of the NBBIO layer, we must decode the events
645      * ourselves and do the ciphertext I/O. Then, we can decide if we want to
646      * read or write more ciphertext.
647      */
648     if (event == EVENT_READ || event == EVENT_WRITE) {
649 	tlsp_strategy(state);
650     } else {
651 	if (event == EVENT_TIME && state->ssl_last_err == SSL_ERROR_NONE)
652 	    msg_warn("deadlock on plaintext stream for %s",
653 		     state->remote_endpt);
654 	else
655 	    msg_warn("ciphertext read/write %s for %s",
656 		     event == EVENT_TIME ? "timeout" : "error",
657 		     state->remote_endpt);
658 	tlsp_state_free(state);
659     }
660 }
661 
662 /* tlsp_start_tls - turn on TLS or force disconnect */
663 
664 static void tlsp_start_tls(TLSP_STATE *state)
665 {
666     TLS_SERVER_START_PROPS props;
667     static char *cipher_grade;
668     static VSTRING *cipher_exclusions;
669 
670     /*
671      * The code in this routine is pasted literally from smtpd(8). I am not
672      * going to sanitize this because doing so surely will break things in
673      * unexpected ways.
674      */
675 
676     /*
677      * Perform the before-handshake portion of the per-session initalization.
678      * Pass a null VSTREAM to indicate that this program, will do the
679      * ciphertext I/O, not libtls.
680      *
681      * The cipher grade and exclusions don't change between sessions. Compute
682      * just once and cache.
683      */
684 #define ADD_EXCLUDE(vstr, str) \
685     do { \
686 	if (*(str)) \
687 	    vstring_sprintf_append((vstr), "%s%s", \
688 				   VSTRING_LEN(vstr) ? " " : "", (str)); \
689     } while (0)
690 
691     if (cipher_grade == 0) {
692 	cipher_grade =
693 	    var_tlsp_enforce_tls ? var_tlsp_tls_mand_ciph : var_tlsp_tls_ciph;
694 	cipher_exclusions = vstring_alloc(10);
695 	ADD_EXCLUDE(cipher_exclusions, var_tlsp_tls_excl_ciph);
696 	if (var_tlsp_enforce_tls)
697 	    ADD_EXCLUDE(cipher_exclusions, var_tlsp_tls_mand_excl);
698 	if (ask_client_cert)
699 	    ADD_EXCLUDE(cipher_exclusions, "aNULL");
700     }
701     state->tls_context =
702 	TLS_SERVER_START(&props,
703 			 ctx = tlsp_server_ctx,
704 			 stream = (VSTREAM *) 0,/* unused */
705 			 fd = state->ciphertext_fd,
706 			 timeout = 0,		/* unused */
707 			 requirecert = (var_tlsp_tls_req_ccert
708 					&& var_tlsp_enforce_tls),
709 			 serverid = state->server_id,
710 			 namaddr = state->remote_endpt,
711 			 cipher_grade = cipher_grade,
712 			 cipher_exclusions = STR(cipher_exclusions),
713 			 mdalg = var_tlsp_tls_fpt_dgst);
714 
715     if (state->tls_context == 0) {
716 	tlsp_state_free(state);
717 	return;
718     }
719 
720     /*
721      * XXX Do we care about TLS session rate limits? Good postscreen(8)
722      * clients will occasionally require the tlsproxy to renew their
723      * whitelist status, but bad clients hammering the server can suck up
724      * lots of CPU cycles. Per-client concurrency limits in postscreen(8)
725      * will divert only naive security "researchers".
726      *
727      * XXX Do we care about certificate verification results? Not as long as
728      * postscreen(8) doesn't actually receive email.
729      */
730 }
731 
732 /* tlsp_get_fd_event - receive final postscreen(8) hand-off information */
733 
734 static void tlsp_get_fd_event(int event, void *context)
735 {
736     const char *myname = "tlsp_get_fd_event";
737     TLSP_STATE *state = (TLSP_STATE *) context;
738     int     plaintext_fd = vstream_fileno(state->plaintext_stream);
739 
740     /*
741      * At this point we still manually manage plaintext read/write/timeout
742      * events. Disable I/O and timer events. Don't assume that the first
743      * plaintext request will be a read.
744      */
745     event_disable_readwrite(plaintext_fd);
746     if (event != EVENT_TIME)
747 	event_cancel_timer(tlsp_get_fd_event, (void *) state);
748     else
749 	errno = ETIMEDOUT;
750 
751     /*
752      * Initialize plaintext-related session state.  Once we have this behind
753      * us, the TLSP_STATE destructor will automagically clean up requests for
754      * read/write/timeout events, which makes error recovery easier.
755      *
756      * Register the plaintext event handler for timer cleanup in the TLSP_STATE
757      * destructor. Insert the NBBIO event-driven I/O layer between the
758      * postscreen(8) server and the TLS engine.
759      */
760     if (event != EVENT_READ
761 	|| (state->ciphertext_fd = LOCAL_RECV_FD(plaintext_fd)) < 0) {
762 	msg_warn("%s: receive SMTP client file descriptor: %m", myname);
763 	tlsp_state_free(state);
764 	return;
765     }
766     non_blocking(state->ciphertext_fd, NON_BLOCKING);
767     state->ciphertext_timer = tlsp_ciphertext_event;
768     state->plaintext_buf = nbbio_create(plaintext_fd,
769 					VSTREAM_BUFSIZE, "postscreen",
770 					tlsp_plaintext_event,
771 					(void *) state);
772 
773     /*
774      * Perform the TLS layer before-handshake initialization. We perform the
775      * remainder after the TLS handshake completes.
776      */
777     tlsp_start_tls(state);
778 
779     /*
780      * Trigger the initial proxy server I/Os.
781      */
782     tlsp_strategy(state);
783 }
784 
785 /* tlsp_get_request_event - receive initial postscreen(8) hand-off info */
786 
787 static void tlsp_get_request_event(int event, void *context)
788 {
789     const char *myname = "tlsp_get_request_event";
790     TLSP_STATE *state = (TLSP_STATE *) context;
791     VSTREAM *plaintext_stream = state->plaintext_stream;
792     int     plaintext_fd = vstream_fileno(plaintext_stream);
793     static VSTRING *remote_endpt;
794     static VSTRING *server_id;
795     int     req_flags;
796     int     timeout;
797     int     ready;
798 
799     /*
800      * One-time initialization.
801      */
802     if (remote_endpt == 0) {
803 	remote_endpt = vstring_alloc(10);
804 	server_id = vstring_alloc(10);
805     }
806 
807     /*
808      * At this point we still manually manage plaintext read/write/timeout
809      * events. Turn off timer events. Below we disable read events on error,
810      * and redefine read events on success.
811      */
812     if (event != EVENT_TIME)
813 	event_cancel_timer(tlsp_get_request_event, (void *) state);
814     else
815 	errno = ETIMEDOUT;
816 
817     /*
818      * We must send some data, after receiving the request attributes and
819      * before receiving the remote file descriptor. We can't assume
820      * UNIX-domain socket semantics here.
821      */
822     if (event != EVENT_READ
823 	|| attr_scan(plaintext_stream, ATTR_FLAG_STRICT,
824 		     RECV_ATTR_STR(MAIL_ATTR_REMOTE_ENDPT, remote_endpt),
825 		     RECV_ATTR_INT(MAIL_ATTR_FLAGS, &req_flags),
826 		     RECV_ATTR_INT(MAIL_ATTR_TIMEOUT, &timeout),
827 		     RECV_ATTR_STR(MAIL_ATTR_SERVER_ID, server_id),
828 		     ATTR_TYPE_END) != 4) {
829 	msg_warn("%s: receive request attributes: %m", myname);
830 	event_disable_readwrite(plaintext_fd);
831 	tlsp_state_free(state);
832 	return;
833     }
834 
835     /*
836      * If the requested TLS engine is unavailable, hang up after making sure
837      * that the plaintext peer has received our "sorry" indication.
838      */
839     ready = ((req_flags & TLS_PROXY_FLAG_ROLE_SERVER) != 0
840 	     && tlsp_server_ctx != 0);
841     if (attr_print(plaintext_stream, ATTR_FLAG_NONE,
842 		   SEND_ATTR_INT(MAIL_ATTR_STATUS, ready),
843 		   ATTR_TYPE_END) != 0
844 	|| vstream_fflush(plaintext_stream) != 0
845 	|| ready == 0) {
846 	read_wait(plaintext_fd, TLSP_INIT_TIMEOUT);	/* XXX */
847 	event_disable_readwrite(plaintext_fd);
848 	tlsp_state_free(state);
849 	return;
850     }
851 
852     /*
853      * XXX We use the same fixed timeout throughout the entire session for
854      * both plaintext and ciphertext communication. This timeout is just a
855      * safety feature; the real timeout will be enforced by our plaintext
856      * peer.
857      */
858     else {
859 	state->remote_endpt = mystrdup(STR(remote_endpt));
860 	state->server_id = mystrdup(STR(server_id));
861 	msg_info("CONNECT %s %s",
862 		 (req_flags & TLS_PROXY_FLAG_ROLE_SERVER) ? "from" :
863 		 (req_flags & TLS_PROXY_FLAG_ROLE_CLIENT) ? "to" :
864 		 "(bogus_direction)", state->remote_endpt);
865 	state->req_flags = req_flags;
866 	state->timeout = timeout + 10;		/* XXX */
867 	event_enable_read(plaintext_fd, tlsp_get_fd_event, (void *) state);
868 	event_request_timer(tlsp_get_fd_event, (void *) state,
869 			    TLSP_INIT_TIMEOUT);
870 	return;
871     }
872 }
873 
874 /* tlsp_service - handle new client connection */
875 
876 static void tlsp_service(VSTREAM *plaintext_stream,
877 			         char *service,
878 			         char **argv)
879 {
880     TLSP_STATE *state;
881     int     plaintext_fd = vstream_fileno(plaintext_stream);
882 
883     /*
884      * Sanity check. This service takes no command-line arguments.
885      */
886     if (argv[0])
887 	msg_fatal("unexpected command-line argument: %s", argv[0]);
888 
889     /*
890      * This program handles multiple connections, so it must not block. We
891      * use event-driven code for all operations that introduce latency.
892      * Except that attribute lists are sent/received synchronously, once the
893      * socket is found to be ready for transmission.
894      */
895     non_blocking(plaintext_fd, NON_BLOCKING);
896     vstream_control(plaintext_stream,
897 		    CA_VSTREAM_CTL_PATH("plaintext"),
898 		    CA_VSTREAM_CTL_TIMEOUT(5),
899 		    CA_VSTREAM_CTL_END);
900 
901     /*
902      * Receive postscreen's remote SMTP client address/port and socket.
903      */
904     state = tlsp_state_create(service, plaintext_stream);
905     event_enable_read(plaintext_fd, tlsp_get_request_event, (void *) state);
906     event_request_timer(tlsp_get_request_event, (void *) state,
907 			TLSP_INIT_TIMEOUT);
908 }
909 
910 /* pre_jail_init - pre-jail initialization */
911 
912 static void pre_jail_init(char *unused_name, char **unused_argv)
913 {
914     TLS_SERVER_INIT_PROPS props;
915     const char *cert_file;
916     int     have_server_cert;
917     int     no_server_cert_ok;
918     int     require_server_cert;
919 
920     /*
921      * The code in this routine is pasted literally from smtpd(8). I am not
922      * going to sanitize this because doing so surely will break things in
923      * unexpected ways.
924      */
925     if (*var_tlsp_tls_level) {
926 	switch (tls_level_lookup(var_tlsp_tls_level)) {
927 	default:
928 	    msg_fatal("Invalid TLS level \"%s\"", var_tlsp_tls_level);
929 	    /* NOTREACHED */
930 	    break;
931 	case TLS_LEV_SECURE:
932 	case TLS_LEV_VERIFY:
933 	case TLS_LEV_FPRINT:
934 	    msg_warn("%s: unsupported TLS level \"%s\", using \"encrypt\"",
935 		     VAR_TLSP_TLS_LEVEL, var_tlsp_tls_level);
936 	    /* FALLTHROUGH */
937 	case TLS_LEV_ENCRYPT:
938 	    var_tlsp_enforce_tls = var_tlsp_use_tls = 1;
939 	    break;
940 	case TLS_LEV_MAY:
941 	    var_tlsp_enforce_tls = 0;
942 	    var_tlsp_use_tls = 1;
943 	    break;
944 	case TLS_LEV_NONE:
945 	    var_tlsp_enforce_tls = var_tlsp_use_tls = 0;
946 	    break;
947 	}
948     }
949     var_tlsp_use_tls = var_tlsp_use_tls || var_tlsp_enforce_tls;
950     if (!var_tlsp_use_tls) {
951 	msg_warn("TLS service is requested, but disabled with %s or %s",
952 		 VAR_TLSP_TLS_LEVEL, VAR_TLSP_USE_TLS);
953 	return;
954     }
955 
956     /*
957      * Load TLS keys before dropping privileges.
958      *
959      * Can't use anonymous ciphers if we want client certificates. Must use
960      * anonymous ciphers if we have no certificates.
961      */
962     ask_client_cert = require_server_cert =
963 	(var_tlsp_tls_ask_ccert
964 	 || (var_tlsp_enforce_tls && var_tlsp_tls_req_ccert));
965     if (strcasecmp(var_tlsp_tls_cert_file, "none") == 0) {
966 	no_server_cert_ok = 1;
967 	cert_file = "";
968     } else {
969 	no_server_cert_ok = 0;
970 	cert_file = var_tlsp_tls_cert_file;
971     }
972     have_server_cert =
973 	(*cert_file || *var_tlsp_tls_dcert_file || *var_tlsp_tls_eccert_file);
974 
975     /* Some TLS configuration errors are not show stoppers. */
976     if (!have_server_cert && require_server_cert)
977 	msg_warn("Need a server cert to request client certs");
978     if (!var_tlsp_enforce_tls && var_tlsp_tls_req_ccert)
979 	msg_warn("Can't require client certs unless TLS is required");
980     /* After a show-stopper error, log a warning. */
981     if (have_server_cert || (no_server_cert_ok && !require_server_cert))
982 
983 	/*
984 	 * Large parameter lists are error-prone, so we emulate a language
985 	 * feature that C does not have natively: named parameter lists.
986 	 */
987 	tlsp_server_ctx =
988 	    TLS_SERVER_INIT(&props,
989 			    log_param = VAR_TLSP_TLS_LOGLEVEL,
990 			    log_level = var_tlsp_tls_loglevel,
991 			    verifydepth = var_tlsp_tls_ccert_vd,
992 			    cache_type = TLS_MGR_SCACHE_SMTPD,
993 			    set_sessid = var_tlsp_tls_set_sessid,
994 			    cert_file = cert_file,
995 			    key_file = var_tlsp_tls_key_file,
996 			    dcert_file = var_tlsp_tls_dcert_file,
997 			    dkey_file = var_tlsp_tls_dkey_file,
998 			    eccert_file = var_tlsp_tls_eccert_file,
999 			    eckey_file = var_tlsp_tls_eckey_file,
1000 			    CAfile = var_tlsp_tls_CAfile,
1001 			    CApath = var_tlsp_tls_CApath,
1002 			    dh1024_param_file
1003 			    = var_tlsp_tls_dh1024_param_file,
1004 			    dh512_param_file
1005 			    = var_tlsp_tls_dh512_param_file,
1006 			    eecdh_grade = var_tlsp_tls_eecdh,
1007 			    protocols = var_tlsp_enforce_tls ?
1008 			    var_tlsp_tls_mand_proto :
1009 			    var_tlsp_tls_proto,
1010 			    ask_ccert = ask_client_cert,
1011 			    mdalg = var_tlsp_tls_fpt_dgst);
1012     else
1013 	msg_warn("No server certs available. TLS can't be enabled");
1014 
1015     /*
1016      * To maintain sanity, allow partial SSL_write() operations, and allow
1017      * SSL_write() buffer pointers to change after a WANT_READ or WANT_WRITE
1018      * result. This is based on OpenSSL developers talking on a mailing list,
1019      * but is not supported by documentation. If this code stops working then
1020      * no-one can be held responsible.
1021      */
1022     if (tlsp_server_ctx)
1023 	SSL_CTX_set_mode(tlsp_server_ctx->ssl_ctx,
1024 			 SSL_MODE_ENABLE_PARTIAL_WRITE
1025 			 | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
1026 }
1027 
1028 /* post_jail_init - post-jail initialization */
1029 
1030 static void post_jail_init(char *unused_name, char **unused_argv)
1031 {
1032      /* void */ ;
1033 }
1034 
1035 MAIL_VERSION_STAMP_DECLARE;
1036 
1037 /* main - the main program */
1038 
1039 int     main(int argc, char **argv)
1040 {
1041     static const CONFIG_INT_TABLE int_table[] = {
1042 	VAR_SMTPD_TLS_CCERT_VD, DEF_SMTPD_TLS_CCERT_VD, &var_smtpd_tls_ccert_vd, 0, 0,
1043 	0,
1044     };
1045     static const CONFIG_NINT_TABLE nint_table[] = {
1046 	VAR_TLSP_TLS_CCERT_VD, DEF_TLSP_TLS_CCERT_VD, &var_tlsp_tls_ccert_vd, 0, 0,
1047 	0,
1048     };
1049     static const CONFIG_TIME_TABLE time_table[] = {
1050 	VAR_TLSP_WATCHDOG, DEF_TLSP_WATCHDOG, &var_tlsp_watchdog, 10, 0,
1051 	0,
1052     };
1053     static const CONFIG_BOOL_TABLE bool_table[] = {
1054 	VAR_SMTPD_USE_TLS, DEF_SMTPD_USE_TLS, &var_smtpd_use_tls,
1055 	VAR_SMTPD_ENFORCE_TLS, DEF_SMTPD_ENFORCE_TLS, &var_smtpd_enforce_tls,
1056 	VAR_SMTPD_TLS_ACERT, DEF_SMTPD_TLS_ACERT, &var_smtpd_tls_ask_ccert,
1057 	VAR_SMTPD_TLS_RCERT, DEF_SMTPD_TLS_RCERT, &var_smtpd_tls_req_ccert,
1058 	VAR_SMTPD_TLS_SET_SESSID, DEF_SMTPD_TLS_SET_SESSID, &var_smtpd_tls_set_sessid,
1059 	0,
1060     };
1061     static const CONFIG_NBOOL_TABLE nbool_table[] = {
1062 	VAR_TLSP_USE_TLS, DEF_TLSP_USE_TLS, &var_tlsp_use_tls,
1063 	VAR_TLSP_ENFORCE_TLS, DEF_TLSP_ENFORCE_TLS, &var_tlsp_enforce_tls,
1064 	VAR_TLSP_TLS_ACERT, DEF_TLSP_TLS_ACERT, &var_tlsp_tls_ask_ccert,
1065 	VAR_TLSP_TLS_RCERT, DEF_TLSP_TLS_RCERT, &var_tlsp_tls_req_ccert,
1066 	VAR_TLSP_TLS_SET_SESSID, DEF_TLSP_TLS_SET_SESSID, &var_tlsp_tls_set_sessid,
1067 	0,
1068     };
1069     static const CONFIG_STR_TABLE str_table[] = {
1070 	VAR_SMTPD_TLS_CERT_FILE, DEF_SMTPD_TLS_CERT_FILE, &var_smtpd_tls_cert_file, 0, 0,
1071 	VAR_SMTPD_TLS_KEY_FILE, DEF_SMTPD_TLS_KEY_FILE, &var_smtpd_tls_key_file, 0, 0,
1072 	VAR_SMTPD_TLS_DCERT_FILE, DEF_SMTPD_TLS_DCERT_FILE, &var_smtpd_tls_dcert_file, 0, 0,
1073 	VAR_SMTPD_TLS_DKEY_FILE, DEF_SMTPD_TLS_DKEY_FILE, &var_smtpd_tls_dkey_file, 0, 0,
1074 	VAR_SMTPD_TLS_ECCERT_FILE, DEF_SMTPD_TLS_ECCERT_FILE, &var_smtpd_tls_eccert_file, 0, 0,
1075 	VAR_SMTPD_TLS_ECKEY_FILE, DEF_SMTPD_TLS_ECKEY_FILE, &var_smtpd_tls_eckey_file, 0, 0,
1076 	VAR_SMTPD_TLS_CA_FILE, DEF_SMTPD_TLS_CA_FILE, &var_smtpd_tls_CAfile, 0, 0,
1077 	VAR_SMTPD_TLS_CA_PATH, DEF_SMTPD_TLS_CA_PATH, &var_smtpd_tls_CApath, 0, 0,
1078 	VAR_SMTPD_TLS_CIPH, DEF_SMTPD_TLS_CIPH, &var_smtpd_tls_ciph, 1, 0,
1079 	VAR_SMTPD_TLS_MAND_CIPH, DEF_SMTPD_TLS_MAND_CIPH, &var_smtpd_tls_mand_ciph, 1, 0,
1080 	VAR_SMTPD_TLS_EXCL_CIPH, DEF_SMTPD_TLS_EXCL_CIPH, &var_smtpd_tls_excl_ciph, 0, 0,
1081 	VAR_SMTPD_TLS_MAND_EXCL, DEF_SMTPD_TLS_MAND_EXCL, &var_smtpd_tls_mand_excl, 0, 0,
1082 	VAR_SMTPD_TLS_PROTO, DEF_SMTPD_TLS_PROTO, &var_smtpd_tls_proto, 0, 0,
1083 	VAR_SMTPD_TLS_MAND_PROTO, DEF_SMTPD_TLS_MAND_PROTO, &var_smtpd_tls_mand_proto, 0, 0,
1084 	VAR_SMTPD_TLS_512_FILE, DEF_SMTPD_TLS_512_FILE, &var_smtpd_tls_dh512_param_file, 0, 0,
1085 	VAR_SMTPD_TLS_1024_FILE, DEF_SMTPD_TLS_1024_FILE, &var_smtpd_tls_dh1024_param_file, 0, 0,
1086 	VAR_SMTPD_TLS_EECDH, DEF_SMTPD_TLS_EECDH, &var_smtpd_tls_eecdh, 1, 0,
1087 	VAR_SMTPD_TLS_FPT_DGST, DEF_SMTPD_TLS_FPT_DGST, &var_smtpd_tls_fpt_dgst, 1, 0,
1088 	VAR_SMTPD_TLS_LOGLEVEL, DEF_SMTPD_TLS_LOGLEVEL, &var_smtpd_tls_loglevel, 0, 0,
1089 	VAR_SMTPD_TLS_LEVEL, DEF_SMTPD_TLS_LEVEL, &var_smtpd_tls_level, 0, 0,
1090 	VAR_TLSP_TLS_CERT_FILE, DEF_TLSP_TLS_CERT_FILE, &var_tlsp_tls_cert_file, 0, 0,
1091 	VAR_TLSP_TLS_KEY_FILE, DEF_TLSP_TLS_KEY_FILE, &var_tlsp_tls_key_file, 0, 0,
1092 	VAR_TLSP_TLS_DCERT_FILE, DEF_TLSP_TLS_DCERT_FILE, &var_tlsp_tls_dcert_file, 0, 0,
1093 	VAR_TLSP_TLS_DKEY_FILE, DEF_TLSP_TLS_DKEY_FILE, &var_tlsp_tls_dkey_file, 0, 0,
1094 	VAR_TLSP_TLS_ECCERT_FILE, DEF_TLSP_TLS_ECCERT_FILE, &var_tlsp_tls_eccert_file, 0, 0,
1095 	VAR_TLSP_TLS_ECKEY_FILE, DEF_TLSP_TLS_ECKEY_FILE, &var_tlsp_tls_eckey_file, 0, 0,
1096 	VAR_TLSP_TLS_CA_FILE, DEF_TLSP_TLS_CA_FILE, &var_tlsp_tls_CAfile, 0, 0,
1097 	VAR_TLSP_TLS_CA_PATH, DEF_TLSP_TLS_CA_PATH, &var_tlsp_tls_CApath, 0, 0,
1098 	VAR_TLSP_TLS_CIPH, DEF_TLSP_TLS_CIPH, &var_tlsp_tls_ciph, 1, 0,
1099 	VAR_TLSP_TLS_MAND_CIPH, DEF_TLSP_TLS_MAND_CIPH, &var_tlsp_tls_mand_ciph, 1, 0,
1100 	VAR_TLSP_TLS_EXCL_CIPH, DEF_TLSP_TLS_EXCL_CIPH, &var_tlsp_tls_excl_ciph, 0, 0,
1101 	VAR_TLSP_TLS_MAND_EXCL, DEF_TLSP_TLS_MAND_EXCL, &var_tlsp_tls_mand_excl, 0, 0,
1102 	VAR_TLSP_TLS_PROTO, DEF_TLSP_TLS_PROTO, &var_tlsp_tls_proto, 0, 0,
1103 	VAR_TLSP_TLS_MAND_PROTO, DEF_TLSP_TLS_MAND_PROTO, &var_tlsp_tls_mand_proto, 0, 0,
1104 	VAR_TLSP_TLS_512_FILE, DEF_TLSP_TLS_512_FILE, &var_tlsp_tls_dh512_param_file, 0, 0,
1105 	VAR_TLSP_TLS_1024_FILE, DEF_TLSP_TLS_1024_FILE, &var_tlsp_tls_dh1024_param_file, 0, 0,
1106 	VAR_TLSP_TLS_EECDH, DEF_TLSP_TLS_EECDH, &var_tlsp_tls_eecdh, 1, 0,
1107 	VAR_TLSP_TLS_FPT_DGST, DEF_TLSP_TLS_FPT_DGST, &var_tlsp_tls_fpt_dgst, 1, 0,
1108 	VAR_TLSP_TLS_LOGLEVEL, DEF_TLSP_TLS_LOGLEVEL, &var_tlsp_tls_loglevel, 0, 0,
1109 	VAR_TLSP_TLS_LEVEL, DEF_TLSP_TLS_LEVEL, &var_tlsp_tls_level, 0, 0,
1110 	0,
1111     };
1112 
1113     /*
1114      * Fingerprint executables and core dumps.
1115      */
1116     MAIL_VERSION_STAMP_ALLOCATE;
1117 
1118     /*
1119      * Pass control to the single-threaded service skeleton.
1120      */
1121     event_server_main(argc, argv, tlsp_service,
1122 		      CA_MAIL_SERVER_INT_TABLE(int_table),
1123 		      CA_MAIL_SERVER_NINT_TABLE(nint_table),
1124 		      CA_MAIL_SERVER_STR_TABLE(str_table),
1125 		      CA_MAIL_SERVER_BOOL_TABLE(bool_table),
1126 		      CA_MAIL_SERVER_NBOOL_TABLE(nbool_table),
1127 		      CA_MAIL_SERVER_TIME_TABLE(time_table),
1128 		      CA_MAIL_SERVER_PRE_INIT(pre_jail_init),
1129 		      CA_MAIL_SERVER_POST_INIT(post_jail_init),
1130 		      CA_MAIL_SERVER_SLOW_EXIT(tlsp_drain),
1131 		      CA_MAIL_SERVER_WATCHDOG(&var_tlsp_watchdog),
1132 		      0);
1133 }
1134 
1135 #else
1136 
1137 /* tlsp_service - respond to external trigger(s), non-TLS version */
1138 
1139 static void tlsp_service(VSTREAM *stream, char *unused_service,
1140 			         char **unused_argv)
1141 {
1142     msg_info("TLS support is not compiled in -- exiting");
1143     event_server_disconnect(stream);
1144 }
1145 
1146 /* main - the main program */
1147 
1148 int     main(int argc, char **argv)
1149 {
1150 
1151     /*
1152      * We can't simply use msg_fatal() here, because the logging hasn't been
1153      * initialized. The text would disappear because stderr is redirected to
1154      * /dev/null.
1155      *
1156      * We invoke event_server_main() to complete program initialization
1157      * (including logging) and then invoke the tlsp_service() routine to log
1158      * the message that says why this program will not run.
1159      */
1160     event_server_main(argc, argv, tlsp_service,
1161 		      0);
1162 }
1163 
1164 #endif
1165