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