1 /*        $NetBSD: tlsproxy.c,v 1.7 2025/02/25 19:15:51 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 two-way TLS proxy. It
12 /*        is used by the \fBpostscreen\fR(8) server to talk SMTP-over-TLS
13 /*        with remote SMTP clients that are not allowlisted (including
14 /*        clients whose allowlist status has expired), and by the
15 /*        \fBsmtp\fR(8) client to support TLS connection reuse, but it
16 /*        should also work for non-SMTP protocols.
17 /*
18 /*        Although one \fBtlsproxy\fR(8) process can serve multiple
19 /*        sessions at the same time, it is a good idea to allow the
20 /*        number of processes to increase with load, so that the
21 /*        service remains responsive.
22 /* PROTOCOL EXAMPLE
23 /* .ad
24 /* .fi
25 /*        The example below concerns \fBpostscreen\fR(8). However,
26 /*        the \fBtlsproxy\fR(8) server is agnostic of the application
27 /*        protocol, and the example is easily adapted to other
28 /*        applications.
29 /*
30 /*        After receiving a valid remote SMTP client STARTTLS command,
31 /*        the \fBpostscreen\fR(8) server sends the remote SMTP client
32 /*        endpoint string, the requested role (server), and the
33 /*        requested timeout to \fBtlsproxy\fR(8).  \fBpostscreen\fR(8)
34 /*        then receives a "TLS available" indication from \fBtlsproxy\fR(8).
35 /*        If the TLS service is available, \fBpostscreen\fR(8) sends
36 /*        the remote SMTP client file descriptor to \fBtlsproxy\fR(8),
37 /*        and sends the plaintext 220 greeting to the remote SMTP
38 /*        client.  This triggers TLS negotiations between the remote
39 /*        SMTP client and \fBtlsproxy\fR(8).  Upon completion of the
40 /*        TLS-level handshake, \fBtlsproxy\fR(8) translates between
41 /*        plaintext from/to \fBpostscreen\fR(8) and ciphertext to/from
42 /*        the remote SMTP client.
43 /* SECURITY
44 /* .ad
45 /* .fi
46 /*        The \fBtlsproxy\fR(8) server is moderately security-sensitive.
47 /*        It talks to untrusted clients on the network. The process
48 /*        can be run chrooted at fixed low privilege.
49 /* DIAGNOSTICS
50 /*        Problems and transactions are logged to \fBsyslogd\fR(8)
51 /*        or \fBpostlogd\fR(8).
52 /* CONFIGURATION PARAMETERS
53 /* .ad
54 /* .fi
55 /*        Changes to \fBmain.cf\fR are not picked up automatically,
56 /*        as \fBtlsproxy\fR(8) processes may run for a long time
57 /*        depending on mail server load.  Use the command "\fBpostfix
58 /*        reload\fR" to speed up a change.
59 /*
60 /*        The text below provides only a parameter summary. See
61 /*        \fBpostconf\fR(5) for more details including examples.
62 /* STARTTLS GLOBAL CONTROLS
63 /* .ad
64 /* .fi
65 /*        The following settings are global and therefore cannot be
66 /*        overruled by information specified in a \fBtlsproxy\fR(8)
67 /*        client request.
68 /* .IP "\fBtls_append_default_CA (no)\fR"
69 /*        Append the system-supplied default Certification Authority
70 /*        certificates to the ones specified with *_tls_CApath or *_tls_CAfile.
71 /* .IP "\fBtls_daemon_random_bytes (32)\fR"
72 /*        The number of pseudo-random bytes that an \fBsmtp\fR(8) or \fBsmtpd\fR(8)
73 /*        process requests from the \fBtlsmgr\fR(8) server in order to seed its
74 /*        internal pseudo random number generator (PRNG).
75 /* .IP "\fBtls_high_cipherlist (see 'postconf -d' output)\fR"
76 /*        The OpenSSL cipherlist for "high" grade ciphers.
77 /* .IP "\fBtls_medium_cipherlist (see 'postconf -d' output)\fR"
78 /*        The OpenSSL cipherlist for "medium" or higher grade ciphers.
79 /* .IP "\fBtls_null_cipherlist (eNULL:!aNULL)\fR"
80 /*        The OpenSSL cipherlist for "NULL" grade ciphers that provide
81 /*        authentication without encryption.
82 /* .IP "\fBtls_eecdh_strong_curve (prime256v1)\fR"
83 /*        The elliptic curve used by the Postfix SMTP server for sensibly
84 /*        strong
85 /*        ephemeral ECDH key exchange.
86 /* .IP "\fBtls_eecdh_ultra_curve (secp384r1)\fR"
87 /*        The elliptic curve used by the Postfix SMTP server for maximally
88 /*        strong
89 /*        ephemeral ECDH key exchange.
90 /* .IP "\fBtls_disable_workarounds (see 'postconf -d' output)\fR"
91 /*        List or bit-mask of OpenSSL bug work-arounds to disable.
92 /* .IP "\fBtls_preempt_cipherlist (no)\fR"
93 /*        With SSLv3 and later, use the Postfix SMTP server's cipher
94 /*        preference order instead of the remote client's cipher preference
95 /*        order.
96 /* .PP
97 /*        Available in Postfix version 2.8..3.7:
98 /* .IP "\fBtls_low_cipherlist (see 'postconf -d' output)\fR"
99 /*        The OpenSSL cipherlist for "low" or higher grade ciphers.
100 /* .IP "\fBtls_export_cipherlist (see 'postconf -d' output)\fR"
101 /*        The OpenSSL cipherlist for "export" or higher grade ciphers.
102 /* .PP
103 /*        Available in Postfix version 2.9 and later:
104 /* .IP "\fBtls_legacy_public_key_fingerprints (no)\fR"
105 /*        A temporary migration aid for sites that use certificate
106 /*        \fIpublic-key\fR fingerprints with Postfix 2.9.0..2.9.5, which use
107 /*        an incorrect algorithm.
108 /* .PP
109 /*        Available in Postfix version 2.11-3.1:
110 /* .IP "\fBtls_dane_digest_agility (on)\fR"
111 /*        Configure RFC7671 DANE TLSA digest algorithm agility.
112 /* .IP "\fBtls_dane_trust_anchor_digest_enable (yes)\fR"
113 /*        Enable support for RFC 6698 (DANE TLSA) DNS records that contain
114 /*        digests of trust-anchors with certificate usage "2".
115 /* .PP
116 /*        Available in Postfix version 2.11 and later:
117 /* .IP "\fBtlsmgr_service_name (tlsmgr)\fR"
118 /*        The name of the \fBtlsmgr\fR(8) service entry in master.cf.
119 /* .PP
120 /*        Available in Postfix version 3.0 and later:
121 /* .IP "\fBtls_session_ticket_cipher (Postfix >= 3.0: aes-256-cbc, Postfix < 3.0: aes-128-cbc)\fR"
122 /*        Algorithm used to encrypt RFC5077 TLS session tickets.
123 /* .IP "\fBopenssl_path (openssl)\fR"
124 /*        The location of the OpenSSL command line program \fBopenssl\fR(1).
125 /* .PP
126 /*        Available in Postfix version 3.2 and later:
127 /* .IP "\fBtls_eecdh_auto_curves (see 'postconf -d' output)\fR"
128 /*        The prioritized list of elliptic curves, that should be enabled in the
129 /*        Postfix SMTP client and server.
130 /* .PP
131 /*        Available in Postfix version 3.4 and later:
132 /* .IP "\fBtls_server_sni_maps (empty)\fR"
133 /*        Optional lookup tables that map names received from remote SMTP
134 /*        clients via the TLS Server Name Indication (SNI) extension to the
135 /*        appropriate keys and certificate chains.
136 /* .PP
137 /*        Available in Postfix 3.5, 3.4.6, 3.3.5, 3.2.10, 3.1.13 and later:
138 /* .IP "\fBtls_fast_shutdown_enable (yes)\fR"
139 /*        A workaround for implementations that hang Postfix while shutting
140 /*        down a TLS session, until Postfix times out.
141 /* .PP
142 /*        Available in Postfix version 3.8 and later:
143 /* .IP "\fBtls_ffdhe_auto_groups (see 'postconf -d' output)\fR"
144 /*        The prioritized list of finite-field Diffie-Hellman ephemeral
145 /*        (FFDHE) key exchange groups supported by the Postfix SMTP client and
146 /*        server.
147 /* .PP
148 /*        Available in Postfix 3.9, 3.8.1, 3.7.6, 3.6.10, 3.5.20 and later:
149 /* .IP "\fBtls_config_file (default)\fR"
150 /*        Optional configuration file with baseline OpenSSL settings.
151 /* .IP "\fBtls_config_name (empty)\fR"
152 /*        The application name passed by Postfix to OpenSSL library
153 /*        initialization functions.
154 /* STARTTLS SERVER CONTROLS
155 /* .ad
156 /* .fi
157 /*        These settings are clones of Postfix SMTP server settings.
158 /*        They allow \fBtlsproxy\fR(8) to load the same certificate
159 /*        and private key information as the Postfix SMTP server,
160 /*        before dropping privileges, so that the key files can be
161 /*        kept read-only for root. These settings can currently not
162 /*        be overruled by information in a \fBtlsproxy\fR(8) client
163 /*        request, but that limitation may be removed in a future
164 /*        version.
165 /* .IP "\fBtlsproxy_tls_CAfile ($smtpd_tls_CAfile)\fR"
166 /*        A file containing (PEM format) CA certificates of root CAs
167 /*        trusted to sign either remote SMTP client certificates or intermediate
168 /*        CA certificates.
169 /* .IP "\fBtlsproxy_tls_CApath ($smtpd_tls_CApath)\fR"
170 /*        A directory containing (PEM format) CA certificates of root CAs
171 /*        trusted to sign either remote SMTP client certificates or intermediate
172 /*        CA certificates.
173 /* .IP "\fBtlsproxy_tls_always_issue_session_ids ($smtpd_tls_always_issue_session_ids)\fR"
174 /*        Force the Postfix \fBtlsproxy\fR(8) server to issue a TLS session id,
175 /*        even when TLS session caching is turned off.
176 /* .IP "\fBtlsproxy_tls_ask_ccert ($smtpd_tls_ask_ccert)\fR"
177 /*        Ask a remote SMTP client for a client certificate.
178 /* .IP "\fBtlsproxy_tls_ccert_verifydepth ($smtpd_tls_ccert_verifydepth)\fR"
179 /*        The verification depth for remote SMTP client certificates.
180 /* .IP "\fBtlsproxy_tls_cert_file ($smtpd_tls_cert_file)\fR"
181 /*        File with the Postfix \fBtlsproxy\fR(8) server RSA certificate in PEM
182 /*        format.
183 /* .IP "\fBtlsproxy_tls_ciphers ($smtpd_tls_ciphers)\fR"
184 /*        The minimum TLS cipher grade that the Postfix \fBtlsproxy\fR(8) server
185 /*        will use with opportunistic TLS encryption.
186 /* .IP "\fBtlsproxy_tls_dcert_file ($smtpd_tls_dcert_file)\fR"
187 /*        File with the Postfix \fBtlsproxy\fR(8) server DSA certificate in PEM
188 /*        format.
189 /* .IP "\fBtlsproxy_tls_dh1024_param_file ($smtpd_tls_dh1024_param_file)\fR"
190 /*        File with DH parameters that the Postfix \fBtlsproxy\fR(8) server
191 /*        should use with non-export EDH ciphers.
192 /* .IP "\fBtlsproxy_tls_dh512_param_file ($smtpd_tls_dh512_param_file)\fR"
193 /*        File with DH parameters that the Postfix \fBtlsproxy\fR(8) server
194 /*        should use with export-grade EDH ciphers.
195 /* .IP "\fBtlsproxy_tls_dkey_file ($smtpd_tls_dkey_file)\fR"
196 /*        File with the Postfix \fBtlsproxy\fR(8) server DSA private key in PEM
197 /*        format.
198 /* .IP "\fBtlsproxy_tls_eccert_file ($smtpd_tls_eccert_file)\fR"
199 /*        File with the Postfix \fBtlsproxy\fR(8) server ECDSA certificate in PEM
200 /*        format.
201 /* .IP "\fBtlsproxy_tls_eckey_file ($smtpd_tls_eckey_file)\fR"
202 /*        File with the Postfix \fBtlsproxy\fR(8) server ECDSA private key in PEM
203 /*        format.
204 /* .IP "\fBtlsproxy_tls_eecdh_grade ($smtpd_tls_eecdh_grade)\fR"
205 /*        The Postfix \fBtlsproxy\fR(8) server security grade for ephemeral
206 /*        elliptic-curve Diffie-Hellman (EECDH) key exchange.
207 /* .IP "\fBtlsproxy_tls_exclude_ciphers ($smtpd_tls_exclude_ciphers)\fR"
208 /*        List of ciphers or cipher types to exclude from the \fBtlsproxy\fR(8)
209 /*        server cipher list at all TLS security levels.
210 /* .IP "\fBtlsproxy_tls_fingerprint_digest ($smtpd_tls_fingerprint_digest)\fR"
211 /*        The message digest algorithm to construct remote SMTP
212 /*        client-certificate
213 /*        fingerprints.
214 /* .IP "\fBtlsproxy_tls_key_file ($smtpd_tls_key_file)\fR"
215 /*        File with the Postfix \fBtlsproxy\fR(8) server RSA private key in PEM
216 /*        format.
217 /* .IP "\fBtlsproxy_tls_loglevel ($smtpd_tls_loglevel)\fR"
218 /*        Enable additional Postfix \fBtlsproxy\fR(8) server logging of TLS
219 /*        activity.
220 /* .IP "\fBtlsproxy_tls_mandatory_ciphers ($smtpd_tls_mandatory_ciphers)\fR"
221 /*        The minimum TLS cipher grade that the Postfix \fBtlsproxy\fR(8) server
222 /*        will use with mandatory TLS encryption.
223 /* .IP "\fBtlsproxy_tls_mandatory_exclude_ciphers ($smtpd_tls_mandatory_exclude_ciphers)\fR"
224 /*        Additional list of ciphers or cipher types to exclude from the
225 /*        \fBtlsproxy\fR(8) server cipher list at mandatory TLS security levels.
226 /* .IP "\fBtlsproxy_tls_mandatory_protocols ($smtpd_tls_mandatory_protocols)\fR"
227 /*        The SSL/TLS protocols accepted by the Postfix \fBtlsproxy\fR(8) server
228 /*        with mandatory TLS encryption.
229 /* .IP "\fBtlsproxy_tls_protocols ($smtpd_tls_protocols)\fR"
230 /*        List of TLS protocols that the Postfix \fBtlsproxy\fR(8) server will
231 /*        exclude or include with opportunistic TLS encryption.
232 /* .IP "\fBtlsproxy_tls_req_ccert ($smtpd_tls_req_ccert)\fR"
233 /*        With mandatory TLS encryption, require a trusted remote SMTP
234 /*        client certificate in order to allow TLS connections to proceed.
235 /* .IP "\fBtlsproxy_tls_security_level ($smtpd_tls_security_level)\fR"
236 /*        The SMTP TLS security level for the Postfix \fBtlsproxy\fR(8) server;
237 /*        when a non-empty value is specified, this overrides the obsolete
238 /*        parameters smtpd_use_tls and smtpd_enforce_tls.
239 /* .IP "\fBtlsproxy_tls_chain_files ($smtpd_tls_chain_files)\fR"
240 /*        Files with the Postfix \fBtlsproxy\fR(8) server keys and certificate
241 /*        chains in PEM format.
242 /* .PP
243 /*        Available in Postfix version 3.9 and later:
244 /* .IP "\fBtlsproxy_tls_enable_rpk ($smtpd_tls_enable_rpk)\fR"
245 /*        Request that remote SMTP clients send an RFC7250 raw public key
246 /*        instead of an X.509 certificate, when asking or requiring client
247 /*        authentication.
248 /* STARTTLS CLIENT CONTROLS
249 /* .ad
250 /* .fi
251 /*        These settings are clones of Postfix SMTP client settings.
252 /*        They allow \fBtlsproxy\fR(8) to load the same certificate
253 /*        and private key information as the Postfix SMTP client,
254 /*        before dropping privileges, so that the key files can be
255 /*        kept read-only for root. Some settings may be overruled by
256 /*        information in a \fBtlsproxy\fR(8) client request.
257 /* .PP
258 /*        Available in Postfix version 3.4 and later:
259 /* .IP "\fBtlsproxy_client_CAfile ($smtp_tls_CAfile)\fR"
260 /*        A file containing CA certificates of root CAs trusted to sign
261 /*        either remote TLS server certificates or intermediate CA certificates.
262 /* .IP "\fBtlsproxy_client_CApath ($smtp_tls_CApath)\fR"
263 /*        Directory with PEM format Certification Authority certificates
264 /*        that the Postfix \fBtlsproxy\fR(8) client uses to verify a remote TLS
265 /*        server certificate.
266 /* .IP "\fBtlsproxy_client_chain_files ($smtp_tls_chain_files)\fR"
267 /*        Files with the Postfix \fBtlsproxy\fR(8) client keys and certificate
268 /*        chains in PEM format.
269 /* .IP "\fBtlsproxy_client_cert_file ($smtp_tls_cert_file)\fR"
270 /*        File with the Postfix \fBtlsproxy\fR(8) client RSA certificate in PEM
271 /*        format.
272 /* .IP "\fBtlsproxy_client_key_file ($smtp_tls_key_file)\fR"
273 /*        File with the Postfix \fBtlsproxy\fR(8) client RSA private key in PEM
274 /*        format.
275 /* .IP "\fBtlsproxy_client_dcert_file ($smtp_tls_dcert_file)\fR"
276 /*        File with the Postfix \fBtlsproxy\fR(8) client DSA certificate in PEM
277 /*        format.
278 /* .IP "\fBtlsproxy_client_dkey_file ($smtp_tls_dkey_file)\fR"
279 /*        File with the Postfix \fBtlsproxy\fR(8) client DSA private key in PEM
280 /*        format.
281 /* .IP "\fBtlsproxy_client_eccert_file ($smtp_tls_eccert_file)\fR"
282 /*        File with the Postfix \fBtlsproxy\fR(8) client ECDSA certificate in PEM
283 /*        format.
284 /* .IP "\fBtlsproxy_client_eckey_file ($smtp_tls_eckey_file)\fR"
285 /*        File with the Postfix \fBtlsproxy\fR(8) client ECDSA private key in PEM
286 /*        format.
287 /* .IP "\fBtlsproxy_client_fingerprint_digest ($smtp_tls_fingerprint_digest)\fR"
288 /*        The message digest algorithm used to construct remote TLS server
289 /*        certificate fingerprints.
290 /* .IP "\fBtlsproxy_client_loglevel ($smtp_tls_loglevel)\fR"
291 /*        Enable additional Postfix \fBtlsproxy\fR(8) client logging of TLS
292 /*        activity.
293 /* .IP "\fBtlsproxy_client_loglevel_parameter (smtp_tls_loglevel)\fR"
294 /*        The name of the parameter that provides the tlsproxy_client_loglevel
295 /*        value.
296 /* .IP "\fBtlsproxy_client_scert_verifydepth ($smtp_tls_scert_verifydepth)\fR"
297 /*        The verification depth for remote TLS server certificates.
298 /* .IP "\fBtlsproxy_client_use_tls ($smtp_use_tls)\fR"
299 /*        Opportunistic mode: use TLS when a remote server announces TLS
300 /*        support.
301 /* .IP "\fBtlsproxy_client_enforce_tls ($smtp_enforce_tls)\fR"
302 /*        Enforcement mode: require that SMTP servers use TLS encryption.
303 /* .IP "\fBtlsproxy_client_per_site ($smtp_tls_per_site)\fR"
304 /*        Optional lookup tables with the Postfix \fBtlsproxy\fR(8) client TLS
305 /*        usage policy by next-hop destination and by remote TLS server
306 /*        hostname.
307 /* .PP
308 /*        Available in Postfix version 3.4-3.6:
309 /* .IP "\fBtlsproxy_client_level ($smtp_tls_security_level)\fR"
310 /*        The default TLS security level for the Postfix \fBtlsproxy\fR(8)
311 /*        client.
312 /* .IP "\fBtlsproxy_client_policy ($smtp_tls_policy_maps)\fR"
313 /*        Optional lookup tables with the Postfix \fBtlsproxy\fR(8) client TLS
314 /*        security policy by next-hop destination.
315 /* .PP
316 /*        Available in Postfix version 3.7 and later:
317 /* .IP "\fBtlsproxy_client_security_level ($smtp_tls_security_level)\fR"
318 /*        The default TLS security level for the Postfix \fBtlsproxy\fR(8)
319 /*        client.
320 /* .IP "\fBtlsproxy_client_policy_maps ($smtp_tls_policy_maps)\fR"
321 /*        Optional lookup tables with the Postfix \fBtlsproxy\fR(8) client TLS
322 /*        security policy by next-hop destination.
323 /* OBSOLETE STARTTLS SUPPORT CONTROLS
324 /* .ad
325 /* .fi
326 /*        These parameters are supported for compatibility with
327 /*        \fBsmtpd\fR(8) legacy parameters.
328 /* .IP "\fBtlsproxy_use_tls ($smtpd_use_tls)\fR"
329 /*        Opportunistic TLS: announce STARTTLS support to remote SMTP clients,
330 /*        but do not require that clients use TLS encryption.
331 /* .IP "\fBtlsproxy_enforce_tls ($smtpd_enforce_tls)\fR"
332 /*        Mandatory TLS: announce STARTTLS support to remote SMTP clients, and
333 /*        require that clients use TLS encryption.
334 /* .IP "\fBtlsproxy_client_use_tls ($smtp_use_tls)\fR"
335 /*        Opportunistic mode: use TLS when a remote server announces TLS
336 /*        support.
337 /* .IP "\fBtlsproxy_client_enforce_tls ($smtp_enforce_tls)\fR"
338 /*        Enforcement mode: require that SMTP servers use TLS encryption.
339 /* RESOURCE CONTROLS
340 /* .ad
341 /* .fi
342 /* .IP "\fBtlsproxy_watchdog_timeout (10s)\fR"
343 /*        How much time a \fBtlsproxy\fR(8) process may take to process local
344 /*        or remote I/O before it is terminated by a built-in watchdog timer.
345 /* MISCELLANEOUS CONTROLS
346 /* .ad
347 /* .fi
348 /* .IP "\fBconfig_directory (see 'postconf -d' output)\fR"
349 /*        The default location of the Postfix main.cf and master.cf
350 /*        configuration files.
351 /* .IP "\fBprocess_id (read-only)\fR"
352 /*        The process ID of a Postfix command or daemon process.
353 /* .IP "\fBprocess_name (read-only)\fR"
354 /*        The process name of a Postfix command or daemon process.
355 /* .IP "\fBsyslog_facility (mail)\fR"
356 /*        The syslog facility of Postfix logging.
357 /* .IP "\fBsyslog_name (see 'postconf -d' output)\fR"
358 /*        A prefix that is prepended to the process name in syslog
359 /*        records, so that, for example, "smtpd" becomes "prefix/smtpd".
360 /* .PP
361 /*        Available in Postfix 3.3 and later:
362 /* .IP "\fBservice_name (read-only)\fR"
363 /*        The master.cf service name of a Postfix daemon process.
364 /* SEE ALSO
365 /*        postscreen(8), Postfix zombie blocker
366 /*        smtpd(8), Postfix SMTP server
367 /*        postconf(5), configuration parameters
368 /*        postlogd(8), Postfix logging
369 /*        syslogd(8), system logging
370 /* LICENSE
371 /* .ad
372 /* .fi
373 /*        The Secure Mailer license must be distributed with this software.
374 /* HISTORY
375 /* .ad
376 /* .fi
377 /*        This service was introduced with Postfix version 2.8.
378 /* AUTHOR(S)
379 /*        Wietse Venema
380 /*        IBM T.J. Watson Research
381 /*        P.O. Box 704
382 /*        Yorktown Heights, NY 10598, USA
383 /*
384 /*        Wietse Venema
385 /*        Google, Inc.
386 /*        111 8th Avenue
387 /*        New York, NY 10011, USA
388 /*--*/
389 
390  /*
391   * System library.
392   */
393 #include <sys_defs.h>
394 #include <errno.h>
395 
396 #ifdef STRCASECMP_IN_STRINGS_H
397 #include <strings.h>
398 #endif
399 
400  /*
401   * Utility library.
402   */
403 #include <msg.h>
404 #include <vstream.h>
405 #include <iostuff.h>
406 #include <nbbio.h>
407 #include <mymalloc.h>
408 #include <split_at.h>
409 
410  /*
411   * Global library.
412   */
413 #include <been_here.h>
414 #include <mail_proto.h>
415 #include <mail_params.h>
416 #include <mail_conf.h>
417 #include <mail_version.h>
418 
419  /*
420   * Master library.
421   */
422 #include <mail_server.h>
423 
424  /*
425   * TLS library.
426   */
427 #ifdef USE_TLS
428 #define TLS_INTERNAL                              /* XXX */
429 #include <tls.h>
430 #include <tls_proxy.h>
431 #include <tlsrpt_wrapper.h>
432 
433  /*
434   * Application-specific.
435   */
436 #include <tlsproxy.h>
437 
438  /*
439   * Tunable parameters. We define our clones of the smtpd(8) parameters to
440   * avoid any confusion about which parameters are used by this program.
441   */
442 int     var_smtpd_tls_ccert_vd;
443 char   *var_smtpd_tls_loglevel;
444 bool    var_smtpd_use_tls;
445 bool    var_smtpd_enforce_tls;
446 bool    var_smtpd_tls_ask_ccert;
447 bool    var_smtpd_tls_req_ccert;
448 bool    var_smtpd_tls_enable_rpk;
449 bool    var_smtpd_tls_set_sessid;
450 char   *var_smtpd_relay_ccerts;
451 char   *var_smtpd_tls_chain_files;
452 char   *var_smtpd_tls_cert_file;
453 char   *var_smtpd_tls_key_file;
454 char   *var_smtpd_tls_dcert_file;
455 char   *var_smtpd_tls_dkey_file;
456 char   *var_smtpd_tls_eccert_file;
457 char   *var_smtpd_tls_eckey_file;
458 char   *var_smtpd_tls_CAfile;
459 char   *var_smtpd_tls_CApath;
460 char   *var_smtpd_tls_ciph;
461 char   *var_smtpd_tls_mand_ciph;
462 char   *var_smtpd_tls_excl_ciph;
463 char   *var_smtpd_tls_mand_excl;
464 char   *var_smtpd_tls_proto;
465 char   *var_smtpd_tls_mand_proto;
466 char   *var_smtpd_tls_dh512_param_file;
467 char   *var_smtpd_tls_dh1024_param_file;
468 char   *var_smtpd_tls_eecdh;
469 char   *var_smtpd_tls_fpt_dgst;
470 char   *var_smtpd_tls_level;
471 
472 int     var_tlsp_tls_ccert_vd;
473 char   *var_tlsp_tls_loglevel;
474 bool    var_tlsp_use_tls;
475 bool    var_tlsp_enforce_tls;
476 bool    var_tlsp_tls_ask_ccert;
477 bool    var_tlsp_tls_req_ccert;
478 bool    var_tlsp_tls_enable_rpk;
479 bool    var_tlsp_tls_set_sessid;
480 char   *var_tlsp_tls_chain_files;
481 char   *var_tlsp_tls_cert_file;
482 char   *var_tlsp_tls_key_file;
483 char   *var_tlsp_tls_dcert_file;
484 char   *var_tlsp_tls_dkey_file;
485 char   *var_tlsp_tls_eccert_file;
486 char   *var_tlsp_tls_eckey_file;
487 char   *var_tlsp_tls_CAfile;
488 char   *var_tlsp_tls_CApath;
489 char   *var_tlsp_tls_ciph;
490 char   *var_tlsp_tls_mand_ciph;
491 char   *var_tlsp_tls_excl_ciph;
492 char   *var_tlsp_tls_mand_excl;
493 char   *var_tlsp_tls_proto;
494 char   *var_tlsp_tls_mand_proto;
495 char   *var_tlsp_tls_dh512_param_file;
496 char   *var_tlsp_tls_dh1024_param_file;
497 char   *var_tlsp_tls_eecdh;
498 char   *var_tlsp_tls_fpt_dgst;
499 char   *var_tlsp_tls_level;
500 
501 int     var_tlsp_watchdog;
502 
503  /*
504   * Defaults for tlsp_clnt_*.
505   */
506 char   *var_smtp_tls_loglevel;
507 int     var_smtp_tls_scert_vd;
508 char   *var_smtp_tls_chain_files;
509 char   *var_smtp_tls_cert_file;
510 char   *var_smtp_tls_key_file;
511 char   *var_smtp_tls_dcert_file;
512 char   *var_smtp_tls_dkey_file;
513 char   *var_smtp_tls_eccert_file;
514 char   *var_smtp_tls_eckey_file;
515 char   *var_smtp_tls_CAfile;
516 char   *var_smtp_tls_CApath;
517 char   *var_smtp_tls_fpt_dgst;
518 char   *var_smtp_tls_level;
519 bool    var_smtp_use_tls;
520 bool    var_smtp_enforce_tls;
521 char   *var_smtp_tls_per_site;
522 char   *var_smtp_tls_policy;
523 
524 char   *var_tlsp_clnt_loglevel;
525 char   *var_tlsp_clnt_logparam;
526 int     var_tlsp_clnt_scert_vd;
527 char   *var_tlsp_clnt_chain_files;
528 char   *var_tlsp_clnt_cert_file;
529 char   *var_tlsp_clnt_key_file;
530 char   *var_tlsp_clnt_dcert_file;
531 char   *var_tlsp_clnt_dkey_file;
532 char   *var_tlsp_clnt_eccert_file;
533 char   *var_tlsp_clnt_eckey_file;
534 char   *var_tlsp_clnt_CAfile;
535 char   *var_tlsp_clnt_CApath;
536 char   *var_tlsp_clnt_fpt_dgst;
537 char   *var_tlsp_clnt_level;
538 bool    var_tlsp_clnt_use_tls;
539 bool    var_tlsp_clnt_enforce_tls;
540 char   *var_tlsp_clnt_per_site;
541 char   *var_tlsp_clnt_policy;
542 
543  /*
544   * TLS per-process status.
545   */
546 static TLS_APPL_STATE *tlsp_server_ctx;
547 static bool tlsp_pre_jail_done;
548 static int ask_client_cert;
549 static char *tlsp_pre_jail_client_param_key;      /* pre-jail global params */
550 static char *tlsp_pre_jail_client_init_key;       /* pre-jail init props */
551 
552  /*
553   * TLS per-client status.
554   */
555 static HTABLE *tlsp_client_app_cache;   /* per-client init props */
556 static BH_TABLE *tlsp_params_mismatch_filter;     /* per-client nag filter */
557 
558  /*
559   * Error handling: if a function detects an error, then that function is
560   * responsible for destroying TLSP_STATE. Exceptions to this principle are
561   * indicated in the code.
562   */
563 
564  /*
565   * Internal status API.
566   */
567 #define TLSP_STAT_OK          0
568 #define TLSP_STAT_ERR         (-1)
569 
570  /*
571   * SLMs.
572   */
573 #define STR(x)      vstring_str(x)
574 #define LEN(x)      VSTRING_LEN(x)
575 
576  /*
577   * The code that implements the TLS engine looks simpler than expected. That
578   * is the result of a great deal of effort, mainly in design and analysis.
579   *
580   * The initial use case was to provide TLS support for postscreen(8).
581   *
582   * By design, postscreen(8) is an event-driven server that must scale up to a
583   * large number of clients. This means that postscreen(8) must avoid doing
584   * CPU-intensive operations such as those in OpenSSL.
585   *
586   * tlsproxy(8) runs the OpenSSL code on behalf of postscreen(8), translating
587   * plaintext SMTP messages from postscreen(8) into SMTP-over-TLS messages to
588   * the remote SMTP client, and vice versa. As long as postscreen(8) does not
589   * receive email messages, the cost of doing TLS operations will be modest.
590   *
591   * Like postscreen(8), one tlsproxy(8) process services multiple remote SMTP
592   * clients. Unlike postscreen(8), there can be more than one tlsproxy(8)
593   * process, although their number is meant to be much smaller than the
594   * number of remote SMTP clients that talk TLS.
595   *
596   * As with postscreen(8), all I/O must be event-driven: encrypted traffic
597   * between tlsproxy(8) and remote SMTP clients, and plaintext traffic
598   * between tlsproxy(8) and postscreen(8). Event-driven plaintext I/O is
599   * straightforward enough that it could be abstracted away with the nbbio(3)
600   * module.
601   *
602   * The event-driven TLS I/O implementation is founded on on-line OpenSSL
603   * documentation, supplemented by statements from OpenSSL developers on
604   * public mailing lists. After some field experience with this code, we may
605   * be able to factor it out as a library module, like nbbio(3), that can
606   * become part of the TLS library.
607   *
608   * Later in the life cycle, tlsproxy(8) has also become an enabler for TLS
609   * connection reuse across different SMTP client processes.
610   */
611 
612 static void tlsp_ciphertext_event(int, void *);
613 
614 #define TLSP_INIT_TIMEOUT     100
615 
616 static void tlsp_plaintext_event(int event, void *context);
617 
618 /* tlsp_drain - delayed exit after "postfix reload" */
619 
tlsp_drain(char * unused_service,char ** unused_argv)620 static void tlsp_drain(char *unused_service, char **unused_argv)
621 {
622     int     count;
623 
624     /*
625      * After "postfix reload", complete work-in-progress in the background,
626      * instead of dropping already-accepted connections on the floor.
627      *
628      * All error retry counts shall be limited. Instead of blocking here, we
629      * could retry failed fork() operations in the event call-back routines,
630      * but we don't need perfection. The host system is severely overloaded
631      * and service levels are already way down.
632      */
633     for (count = 0; /* see below */ ; count++) {
634           if (count >= 5) {
635               msg_fatal("fork: %m");
636           } else if (event_server_drain() != 0) {
637               msg_warn("fork: %m");
638               sleep(1);
639               continue;
640           } else {
641               return;
642           }
643     }
644 }
645 
646 /* tlsp_eval_tls_error - translate TLS "error" result into action */
647 
tlsp_eval_tls_error(TLSP_STATE * state,int err)648 static int tlsp_eval_tls_error(TLSP_STATE *state, int err)
649 {
650     int     ciphertext_fd = state->ciphertext_fd;
651 
652     /*
653      * The ciphertext file descriptor is in non-blocking mode, meaning that
654      * each SSL_accept/connect/read/write/shutdown request may return an
655      * "error" indication that it needs to read or write more ciphertext. The
656      * purpose of this routine is to translate those "error" indications into
657      * the appropriate read/write/timeout event requests.
658      */
659     switch (err) {
660 
661           /*
662            * No error means a successful SSL_accept/connect/shutdown request or
663            * sequence of SSL_read/write requests. Disable read/write events on
664            * the ciphertext stream. Keep the ciphertext stream timer alive as a
665            * safety mechanism for the case that the plaintext pseudothreads get
666            * stuck.
667            */
668     case SSL_ERROR_NONE:
669           if (state->ssl_last_err != SSL_ERROR_NONE) {
670               event_disable_readwrite(ciphertext_fd);
671               event_request_timer(tlsp_ciphertext_event, (void *) state,
672                                         state->timeout);
673               state->ssl_last_err = SSL_ERROR_NONE;
674           }
675           return (TLSP_STAT_OK);
676 
677           /*
678            * The TLS engine wants to write to the network. Turn on
679            * write/timeout events on the ciphertext stream.
680            */
681     case SSL_ERROR_WANT_WRITE:
682           if (state->ssl_last_err == SSL_ERROR_WANT_READ)
683               event_disable_readwrite(ciphertext_fd);
684           if (state->ssl_last_err != SSL_ERROR_WANT_WRITE) {
685               event_enable_write(ciphertext_fd, tlsp_ciphertext_event,
686                                      (void *) state);
687               state->ssl_last_err = SSL_ERROR_WANT_WRITE;
688           }
689           event_request_timer(tlsp_ciphertext_event, (void *) state,
690                                   state->timeout);
691           return (TLSP_STAT_OK);
692 
693           /*
694            * The TLS engine wants to read from the network. Turn on
695            * read/timeout events on the ciphertext stream.
696            */
697     case SSL_ERROR_WANT_READ:
698           if (state->ssl_last_err == SSL_ERROR_WANT_WRITE)
699               event_disable_readwrite(ciphertext_fd);
700           if (state->ssl_last_err != SSL_ERROR_WANT_READ) {
701               event_enable_read(ciphertext_fd, tlsp_ciphertext_event,
702                                     (void *) state);
703               state->ssl_last_err = SSL_ERROR_WANT_READ;
704           }
705           event_request_timer(tlsp_ciphertext_event, (void *) state,
706                                   state->timeout);
707           return (TLSP_STAT_OK);
708 
709           /*
710            * Some error. Self-destruct. This automagically cleans up all
711            * pending read/write and timeout event requests, making state a
712            * dangling pointer.
713            */
714     case SSL_ERROR_SSL:
715           tls_print_errors();
716           /* FALLTHROUGH */
717     default:
718 
719           /*
720            * Allow buffered-up plaintext output to trickle out. Permanently
721            * disable read/write activity on the ciphertext stream, so that this
722            * function will no longer be called. Keep the ciphertext stream
723            * timer alive as a safety mechanism for the case that the plaintext
724            * pseudothreads get stuck. Return into tlsp_strategy(), which will
725            * enable plaintext write events.
726            */
727 #define TLSP_CAN_TRICKLE_OUT_PLAINTEXT(buf) \
728           ((buf) && !NBBIO_ERROR_FLAGS(buf) && NBBIO_WRITE_PEND(buf))
729 
730           if (TLSP_CAN_TRICKLE_OUT_PLAINTEXT(state->plaintext_buf)) {
731               event_disable_readwrite(ciphertext_fd);
732               event_request_timer(tlsp_ciphertext_event, (void *) state,
733                                         state->timeout);
734               state->flags |= TLSP_FLAG_NO_MORE_CIPHERTEXT_IO;
735               return (TLSP_STAT_OK);
736           }
737 
738           /*
739            * Report a generic failure only if a more specific failure wasn't
740            * already reported.
741            */
742 #ifdef USE_TLSRPT
743           if (state->is_server_role == 0
744               && (state->flags & TLSP_FLAG_DO_HANDSHAKE)
745               && state->client_start_props->tlsrpt)
746               trw_report_failure(state->client_start_props->tlsrpt,
747                                      TLSRPT_VALIDATION_FAILURE,
748                                       /* additional_info= */ (char *) 0,
749                                      "tls-handshake-failure");
750 #endif
751           tlsp_state_free(state);
752           return (TLSP_STAT_ERR);
753     }
754 }
755 
756 /* tlsp_post_handshake - post-handshake processing */
757 
tlsp_post_handshake(TLSP_STATE * state)758 static int tlsp_post_handshake(TLSP_STATE *state)
759 {
760 
761     /*
762      * Do not assume that tls_server_post_accept() and
763      * tls_client_post_connect() will always succeed.
764      */
765     if (state->is_server_role)
766           state->tls_context = tls_server_post_accept(state->tls_context);
767     else
768           state->tls_context = tls_client_post_connect(state->tls_context,
769                                                              state->client_start_props);
770     if (state->tls_context == 0) {
771           tlsp_state_free(state);
772           return (TLSP_STAT_ERR);
773     }
774 
775     /*
776      * Report TLS handshake results to the tlsproxy client.
777      *
778      * Security: this sends internal data over the same local plaintext stream
779      * that will also be used for sending decrypted remote content from an
780      * arbitrary remote peer. For this reason we enable decrypted I/O only
781      * after reporting the TLS handshake results. The Postfix attribute
782      * protocol is robust enough that an attacker cannot append content.
783      */
784     if ((state->req_flags & TLS_PROXY_FLAG_SEND_CONTEXT) != 0
785           && (attr_print(state->plaintext_stream, ATTR_FLAG_NONE,
786                            SEND_ATTR_FUNC(tls_proxy_context_print,
787                                               (void *) state->tls_context),
788                            ATTR_TYPE_END) != 0
789               || vstream_fflush(state->plaintext_stream) != 0)) {
790           msg_warn("cannot send TLS context: %m");
791           tlsp_state_free(state);
792           return (TLSP_STAT_ERR);
793     }
794 
795     /*
796      * Initialize plaintext-related session state. Once we have this behind
797      * us, the TLSP_STATE destructor will automagically clean up requests for
798      * plaintext read/write/timeout events, which makes error recovery
799      * easier.
800      */
801     state->plaintext_buf =
802           nbbio_create(vstream_fileno(state->plaintext_stream),
803                          VSTREAM_BUFSIZE, state->server_id,
804                          tlsp_plaintext_event,
805                          (void *) state);
806     return (TLSP_STAT_OK);
807 }
808 
809 /* tlsp_strategy - decide what to read or write next. */
810 
tlsp_strategy(TLSP_STATE * state)811 static void tlsp_strategy(TLSP_STATE *state)
812 {
813     TLS_SESS_STATE *tls_context = state->tls_context;
814     NBBIO  *plaintext_buf;
815     int     ssl_stat;
816     int     ssl_read_err;
817     int     ssl_write_err;
818     int     handshake_err;
819 
820     /*
821      * This function is called after every ciphertext or plaintext event, to
822      * schedule new ciphertext or plaintext I/O.
823      */
824 
825     /*
826      * Try to make an SSL I/O request. If this fails with SSL_ERROR_WANT_READ
827      * or SSL_ERROR_WANT_WRITE, enable ciphertext read or write events, and
828      * retry the SSL I/O request in a later tlsp_strategy() call.
829      */
830     if ((state->flags & TLSP_FLAG_NO_MORE_CIPHERTEXT_IO) == 0) {
831 
832           /*
833            * Do not enable plain-text I/O before completing the TLS handshake.
834            * Otherwise the remote peer can prepend plaintext to the optional
835            * TLS_SESS_STATE object.
836            */
837           if (state->flags & TLSP_FLAG_DO_HANDSHAKE) {
838               state->timeout = state->handshake_timeout;
839               ERR_clear_error();
840               if (state->is_server_role)
841                     ssl_stat = SSL_accept(tls_context->con);
842               else
843                     ssl_stat = SSL_connect(tls_context->con);
844               if (ssl_stat != 1) {
845                     handshake_err = SSL_get_error(tls_context->con, ssl_stat);
846                     tlsp_eval_tls_error(state, handshake_err);
847                     /* At this point, state could be a dangling pointer. */
848                     return;
849               }
850               state->flags &= ~TLSP_FLAG_DO_HANDSHAKE;
851               state->timeout = state->session_timeout;
852               if (tlsp_post_handshake(state) != TLSP_STAT_OK) {
853                     /* At this point, state is a dangling pointer. */
854                     return;
855               }
856           }
857 
858           /*
859            * Shutdown and self-destruct after NBBIO error. This automagically
860            * cleans up all pending read/write and timeout event requests.
861            * Before shutting down TLS, we stop all plain-text I/O events but
862            * keep the NBBIO error flags.
863            */
864           plaintext_buf = state->plaintext_buf;
865           if (NBBIO_ERROR_FLAGS(plaintext_buf)) {
866               if (NBBIO_ACTIVE_FLAGS(plaintext_buf))
867                     nbbio_disable_readwrite(state->plaintext_buf);
868               ERR_clear_error();
869               if (!SSL_in_init(tls_context->con)
870                     && (ssl_stat = SSL_shutdown(tls_context->con)) < 0) {
871                     handshake_err = SSL_get_error(tls_context->con, ssl_stat);
872                     tlsp_eval_tls_error(state, handshake_err);
873                     /* At this point, state could be a dangling pointer. */
874                     return;
875               }
876               tlsp_state_free(state);
877               return;
878           }
879 
880           /*
881            * Try to move data from the plaintext input buffer to the TLS
882            * engine.
883            *
884            * XXX We're supposed to repeat the exact same SSL_write() call
885            * arguments after an SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE
886            * result. Rumor has it that this is because each SSL_write() call
887            * reads from the buffer incrementally, and returns > 0 only after
888            * the final byte is processed. Rumor also has it that setting
889            * SSL_MODE_ENABLE_PARTIAL_WRITE and
890            * SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER voids this requirement, and
891            * that repeating the request with an increased request size is OK.
892            * Unfortunately all this is not or poorly documented, and one has to
893            * rely on statements from OpenSSL developers in public mailing
894            * archives.
895            */
896           ssl_write_err = SSL_ERROR_NONE;
897           while (NBBIO_READ_PEND(plaintext_buf) > 0) {
898               ERR_clear_error();
899               ssl_stat = SSL_write(tls_context->con, NBBIO_READ_BUF(plaintext_buf),
900                                          NBBIO_READ_PEND(plaintext_buf));
901               ssl_write_err = SSL_get_error(tls_context->con, ssl_stat);
902               if (ssl_write_err != SSL_ERROR_NONE)
903                     break;
904               /* Allow the plaintext pseudothread to read more data. */
905               NBBIO_READ_PEND(plaintext_buf) -= ssl_stat;
906               if (NBBIO_READ_PEND(plaintext_buf) > 0)
907                     memmove(NBBIO_READ_BUF(plaintext_buf),
908                               NBBIO_READ_BUF(plaintext_buf) + ssl_stat,
909                               NBBIO_READ_PEND(plaintext_buf));
910           }
911 
912           /*
913            * Try to move data from the TLS engine to the plaintext output
914            * buffer. Note: data may arrive as a side effect of calling
915            * SSL_write(), therefore we call SSL_read() after calling
916            * SSL_write().
917            *
918            * XXX We're supposed to repeat the exact same SSL_read() call arguments
919            * after an SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE result. This
920            * supposedly means that our plaintext writer must not memmove() the
921            * plaintext output buffer until after the SSL_read() call succeeds.
922            * For now I'll ignore this, because 1) SSL_read() is documented to
923            * return the bytes available, instead of returning > 0 only after
924            * the entire buffer is processed like SSL_write() does; and 2) there
925            * is no "read" equivalent of the SSL_R_BAD_WRITE_RETRY,
926            * SSL_MODE_ENABLE_PARTIAL_WRITE or
927            * SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER features.
928            */
929           ssl_read_err = SSL_ERROR_NONE;
930           while (NBBIO_WRITE_PEND(state->plaintext_buf) < NBBIO_BUFSIZE(plaintext_buf)) {
931               ERR_clear_error();
932               ssl_stat = SSL_read(tls_context->con,
933                                         NBBIO_WRITE_BUF(plaintext_buf)
934                                         + NBBIO_WRITE_PEND(state->plaintext_buf),
935                                         NBBIO_BUFSIZE(plaintext_buf)
936                                         - NBBIO_WRITE_PEND(state->plaintext_buf));
937               ssl_read_err = SSL_get_error(tls_context->con, ssl_stat);
938               if (ssl_read_err != SSL_ERROR_NONE)
939                     break;
940               NBBIO_WRITE_PEND(plaintext_buf) += ssl_stat;
941           }
942 
943           /*
944            * Try to enable/disable ciphertext read/write events. If SSL_write()
945            * was satisfied, see if SSL_read() wants to do some work. In case of
946            * an unrecoverable error, this automagically destroys the session
947            * state after cleaning up all pending read/write and timeout event
948            * requests.
949            */
950           if (tlsp_eval_tls_error(state, ssl_write_err != SSL_ERROR_NONE ?
951                                         ssl_write_err : ssl_read_err) < 0)
952               /* At this point, state is a dangling pointer. */
953               return;
954     }
955 
956     /*
957      * Destroy state when the ciphertext I/O was permanently disabled and we
958      * can no longer trickle out plaintext.
959      */
960     else {
961           plaintext_buf = state->plaintext_buf;
962           if (!TLSP_CAN_TRICKLE_OUT_PLAINTEXT(plaintext_buf)) {
963               tlsp_state_free(state);
964               return;
965           }
966     }
967 
968     /*
969      * Try to enable/disable plaintext read/write events. Basically, if we
970      * have nothing to write to the plaintext stream, see if there is
971      * something to read. If the write buffer is empty and the read buffer is
972      * full, suspend plaintext I/O until conditions change (but keep the
973      * timer active, as a safety mechanism in case ciphertext I/O gets
974      * stuck).
975      *
976      * XXX In theory, if the ciphertext peer keeps writing fast enough then we
977      * would never read from the plaintext stream and cause the latter to
978      * block. In practice, postscreen(8) limits the number of client
979      * commands, and thus postscreen(8)'s output will fit in a kernel buffer.
980      * A remote SMTP server is not supposed to flood the local SMTP client
981      * with massive replies; if it does, then the local SMTP client should
982      * deal with it.
983      */
984     if (NBBIO_WRITE_PEND(plaintext_buf) > 0) {
985           if (NBBIO_ACTIVE_FLAGS(plaintext_buf) & NBBIO_FLAG_READ)
986               nbbio_disable_readwrite(plaintext_buf);
987           nbbio_enable_write(plaintext_buf, state->timeout);
988     } else if (NBBIO_READ_PEND(plaintext_buf) < NBBIO_BUFSIZE(plaintext_buf)) {
989           if (NBBIO_ACTIVE_FLAGS(plaintext_buf) & NBBIO_FLAG_WRITE)
990               nbbio_disable_readwrite(plaintext_buf);
991           nbbio_enable_read(plaintext_buf, state->timeout);
992     } else {
993           if (NBBIO_ACTIVE_FLAGS(plaintext_buf))
994               nbbio_slumber(plaintext_buf, state->timeout);
995     }
996 }
997 
998 /* tlsp_plaintext_event - plaintext was read/written */
999 
tlsp_plaintext_event(int event,void * context)1000 static void tlsp_plaintext_event(int event, void *context)
1001 {
1002     TLSP_STATE *state = (TLSP_STATE *) context;
1003 
1004     /*
1005      * Safety alert: the plaintext pseudothreads have "slumbered" for too
1006      * long (see code above). This means that the ciphertext pseudothreads
1007      * are stuck.
1008      */
1009     if ((NBBIO_ERROR_FLAGS(state->plaintext_buf) & NBBIO_FLAG_TIMEOUT) != 0
1010           && NBBIO_ACTIVE_FLAGS(state->plaintext_buf) == 0)
1011           msg_warn("deadlock on ciphertext stream for %s", state->remote_endpt);
1012 
1013     /*
1014      * This is easy, because the NBBIO layer has already done the event
1015      * decoding and plaintext I/O for us. All we need to do is decide if we
1016      * want to read or write more plaintext.
1017      */
1018     tlsp_strategy(state);
1019     /* At this point, state could be a dangling pointer. */
1020 }
1021 
1022 /* tlsp_ciphertext_event - ciphertext is ready to read/write */
1023 
tlsp_ciphertext_event(int event,void * context)1024 static void tlsp_ciphertext_event(int event, void *context)
1025 {
1026     TLSP_STATE *state = (TLSP_STATE *) context;
1027 
1028     /*
1029      * Without a TLS equivalent of the NBBIO layer, we must decode the events
1030      * ourselves and do the ciphertext I/O. Then, we can decide if we want to
1031      * read or write more ciphertext.
1032      */
1033     if (event == EVENT_READ || event == EVENT_WRITE) {
1034           tlsp_strategy(state);
1035           /* At this point, state could be a dangling pointer. */
1036     } else {
1037           if (event == EVENT_TIME && state->ssl_last_err == SSL_ERROR_NONE)
1038               msg_warn("deadlock on plaintext stream for %s",
1039                          state->remote_endpt);
1040           else
1041               msg_warn("ciphertext read/write %s for %s",
1042                          event == EVENT_TIME ? "timeout" : "error",
1043                          state->remote_endpt);
1044           tlsp_state_free(state);
1045     }
1046 }
1047 
1048 /* tlsp_client_start_pre_handshake - turn on TLS or force disconnect */
1049 
tlsp_client_start_pre_handshake(TLSP_STATE * state)1050 static int tlsp_client_start_pre_handshake(TLSP_STATE *state)
1051 {
1052     state->client_start_props->ctx = state->appl_state;
1053     state->client_start_props->fd = state->ciphertext_fd;
1054     state->tls_context = tls_client_start(state->client_start_props);
1055     if (state->tls_context != 0)
1056           return (TLSP_STAT_OK);
1057 
1058     tlsp_state_free(state);
1059     return (TLSP_STAT_ERR);
1060 }
1061 
1062 /* tlsp_server_start_pre_handshake - turn on TLS or force disconnect */
1063 
tlsp_server_start_pre_handshake(TLSP_STATE * state)1064 static int tlsp_server_start_pre_handshake(TLSP_STATE *state)
1065 {
1066     TLS_SERVER_START_PROPS props;
1067     static char *cipher_grade;
1068     static VSTRING *cipher_exclusions;
1069 
1070     /*
1071      * The code in this routine is pasted literally from smtpd(8). I am not
1072      * going to sanitize this because doing so surely will break things in
1073      * unexpected ways.
1074      */
1075 
1076     /*
1077      * Perform the before-handshake portion of per-session initialization.
1078      * Pass a null VSTREAM to indicate that this program will do the
1079      * ciphertext I/O, not libtls.
1080      *
1081      * The cipher grade and exclusions don't change between sessions. Compute
1082      * just once and cache.
1083      */
1084 #define ADD_EXCLUDE(vstr, str) \
1085     do { \
1086           if (*(str)) \
1087               vstring_sprintf_append((vstr), "%s%s", \
1088                                            VSTRING_LEN(vstr) ? " " : "", (str)); \
1089     } while (0)
1090 
1091     if (cipher_grade == 0) {
1092           cipher_grade =
1093               var_tlsp_enforce_tls ? var_tlsp_tls_mand_ciph : var_tlsp_tls_ciph;
1094           cipher_exclusions = vstring_alloc(10);
1095           ADD_EXCLUDE(cipher_exclusions, var_tlsp_tls_excl_ciph);
1096           if (var_tlsp_enforce_tls)
1097               ADD_EXCLUDE(cipher_exclusions, var_tlsp_tls_mand_excl);
1098           if (ask_client_cert)
1099               ADD_EXCLUDE(cipher_exclusions, "aNULL");
1100     }
1101     state->tls_context =
1102           TLS_SERVER_START(&props,
1103                                ctx = tlsp_server_ctx,
1104                                stream = (VSTREAM *) 0,/* unused */
1105                                fd = state->ciphertext_fd,
1106                                timeout = 0,                 /* unused */
1107                                requirecert = (var_tlsp_tls_req_ccert
1108                                                   && var_tlsp_enforce_tls),
1109                                enable_rpk = var_tlsp_tls_enable_rpk,
1110                                serverid = state->server_id,
1111                                namaddr = state->remote_endpt,
1112                                cipher_grade = cipher_grade,
1113                                cipher_exclusions = STR(cipher_exclusions),
1114                                mdalg = var_tlsp_tls_fpt_dgst);
1115 
1116     if (state->tls_context == 0) {
1117           tlsp_state_free(state);
1118           return (TLSP_STAT_ERR);
1119     }
1120 
1121     /*
1122      * XXX Do we care about TLS session rate limits? Good postscreen(8)
1123      * clients will occasionally require the tlsproxy to renew their
1124      * allowlist status, but bad clients hammering the server can suck up
1125      * lots of CPU cycles. Per-client concurrency limits in postscreen(8)
1126      * will divert only naive security "researchers".
1127      */
1128     return (TLSP_STAT_OK);
1129 }
1130 
1131  /*
1132   * From here on down is low-level code that sets up the plumbing before
1133   * passing control to the TLS engine above.
1134   */
1135 
1136 /* tlsp_request_read_event - pre-handshake event boiler plate */
1137 
tlsp_request_read_event(int fd,EVENT_NOTIFY_FN handler,int timeout,void * context)1138 static void tlsp_request_read_event(int fd, EVENT_NOTIFY_FN handler,
1139                                                     int timeout, void *context)
1140 {
1141     event_enable_read(fd, handler, context);
1142     event_request_timer(handler, context, timeout);
1143 }
1144 
1145 /* tlsp_accept_event - pre-handshake event boiler plate */
1146 
tlsp_accept_event(int event,EVENT_NOTIFY_FN handler,void * context)1147 static void tlsp_accept_event(int event, EVENT_NOTIFY_FN handler,
1148                                             void *context)
1149 {
1150     if (event != EVENT_TIME)
1151           event_cancel_timer(handler, context);
1152     else
1153           errno = ETIMEDOUT;
1154     /* tlsp_state_free() disables pre-handshake plaintext I/O events. */
1155 }
1156 
1157 /* tlsp_get_fd_event - receive final connection hand-off information */
1158 
tlsp_get_fd_event(int event,void * context)1159 static void tlsp_get_fd_event(int event, void *context)
1160 {
1161     const char *myname = "tlsp_get_fd_event";
1162     TLSP_STATE *state = (TLSP_STATE *) context;
1163     int     plaintext_fd = vstream_fileno(state->plaintext_stream);
1164     int     status;
1165 
1166     /*
1167      * At this point we still manually manage plaintext read/write/timeout
1168      * events. Disable I/O events on the plaintext stream until the TLS
1169      * handshake is completed. Every code path must either destroy state, or
1170      * request the next event, otherwise we have a file and memory leak.
1171      */
1172     tlsp_accept_event(event, tlsp_get_fd_event, (void *) state);
1173     event_disable_readwrite(plaintext_fd);
1174 
1175     if (event != EVENT_READ
1176           || (state->ciphertext_fd = LOCAL_RECV_FD(plaintext_fd)) < 0) {
1177           msg_warn("%s: receive remote SMTP peer file descriptor: %m", myname);
1178           tlsp_state_free(state);
1179           return;
1180     }
1181 
1182     /*
1183      * This is a bit early, to ensure that timer events for this file handle
1184      * are guaranteed to be turned off by the TLSP_STATE destructor.
1185      */
1186     state->ciphertext_timer = tlsp_ciphertext_event;
1187     non_blocking(state->ciphertext_fd, NON_BLOCKING);
1188 
1189     /*
1190      * Perform the TLS layer before-handshake initialization. We perform the
1191      * remainder after the actual TLS handshake completes.
1192      */
1193     if (state->is_server_role)
1194           status = tlsp_server_start_pre_handshake(state);
1195     else
1196           status = tlsp_client_start_pre_handshake(state);
1197     if (status != TLSP_STAT_OK)
1198           /* At this point, state is a dangling pointer. */
1199           return;
1200 
1201     /*
1202      * Trigger the initial proxy server I/Os.
1203      */
1204     tlsp_strategy(state);
1205     /* At this point, state could be a dangling pointer. */
1206 }
1207 
1208 /* tlsp_config_diff - report server-client config differences */
1209 
tlsp_log_config_diff(const char * server_cfg,const char * client_cfg)1210 static void tlsp_log_config_diff(const char *server_cfg, const char *client_cfg)
1211 {
1212     VSTRING *diff_summary = vstring_alloc(100);
1213     char   *saved_server = mystrdup(server_cfg);
1214     char   *saved_client = mystrdup(client_cfg);
1215     char   *server_field;
1216     char   *client_field;
1217     char   *server_next;
1218     char   *client_next;
1219 
1220     /*
1221      * Not using argv_split(), because it would treat multiple consecutive
1222      * newline characters as one.
1223      */
1224     for (server_field = saved_server, client_field = saved_client;
1225            server_field && client_field;
1226            server_field = server_next, client_field = client_next) {
1227           server_next = split_at(server_field, '\n');
1228           client_next = split_at(client_field, '\n');
1229           if (strcmp(server_field, client_field) != 0) {
1230               if (LEN(diff_summary) > 0)
1231                     vstring_sprintf_append(diff_summary, "; ");
1232               vstring_sprintf_append(diff_summary,
1233                                            "(server) '%s' != (client) '%s'",
1234                                            server_field, client_field);
1235           }
1236     }
1237     msg_warn("%s", STR(diff_summary));
1238 
1239     vstring_free(diff_summary);
1240     myfree(saved_client);
1241     myfree(saved_server);
1242 }
1243 
1244 /* tlsp_client_init - initialize a TLS client engine */
1245 
tlsp_client_init(TLS_CLIENT_PARAMS * tls_params,TLS_CLIENT_INIT_PROPS * init_props)1246 static TLS_APPL_STATE *tlsp_client_init(TLS_CLIENT_PARAMS *tls_params,
1247                                                   TLS_CLIENT_INIT_PROPS *init_props)
1248 {
1249     TLS_APPL_STATE *appl_state;
1250     VSTRING *param_buf;
1251     char   *param_key;
1252     VSTRING *init_buf;
1253     char   *init_key;
1254     int     log_hints = 0;
1255 
1256     /*
1257      * Use one TLS_APPL_STATE object for all requests that specify the same
1258      * TLS_CLIENT_INIT_PROPS. Each TLS_APPL_STATE owns an SSL_CTX, which is
1259      * expensive to create. Bug: TLS_CLIENT_PARAMS are not used when creating
1260      * a TLS_APPL_STATE instance.
1261      *
1262      * First, compute the TLS_APPL_STATE cache lookup key. Save a copy of the
1263      * pre-jail request TLS_CLIENT_PARAMS and TLSPROXY_CLIENT_INIT_PROPS
1264      * settings, so that we can detect post-jail requests that do not match.
1265      */
1266     param_buf = vstring_alloc(100);
1267     param_key = tls_proxy_client_param_serialize(attr_print_plain, param_buf,
1268                                                              tls_params);
1269     init_buf = vstring_alloc(100);
1270     init_key = tls_proxy_client_init_serialize(attr_print_plain, init_buf,
1271                                                          init_props);
1272     if (tlsp_pre_jail_done == 0) {
1273           if (tlsp_pre_jail_client_param_key == 0
1274               || tlsp_pre_jail_client_init_key == 0) {
1275               tlsp_pre_jail_client_param_key = mystrdup(param_key);
1276               tlsp_pre_jail_client_init_key = mystrdup(init_key);
1277           } else if (strcmp(tlsp_pre_jail_client_param_key, param_key) != 0
1278                        || strcmp(tlsp_pre_jail_client_init_key, init_key) != 0) {
1279               msg_panic("tlsp_client_init: too many pre-jail calls");
1280           }
1281     }
1282 
1283     /*
1284      * Log a warning if a post-jail request uses unexpected TLS_CLIENT_PARAMS
1285      * settings. Bug: TLS_CLIENT_PARAMS settings are not used when creating a
1286      * TLS_APPL_STATE instance; this makes a mismatch of TLS_CLIENT_PARAMS
1287      * settings problematic.
1288      */
1289     if (tlsp_pre_jail_done
1290           && !been_here_fixed(tlsp_params_mismatch_filter, param_key)
1291           && strcmp(tlsp_pre_jail_client_param_key, param_key) != 0) {
1292           msg_warn("request from tlsproxy client with unexpected settings");
1293           tlsp_log_config_diff(tlsp_pre_jail_client_param_key, param_key);
1294           log_hints = 1;
1295     }
1296 
1297     /*
1298      * Look up the cached TLS_APPL_STATE for this tls_client_init request.
1299      */
1300     if ((appl_state = (TLS_APPL_STATE *)
1301            htable_find(tlsp_client_app_cache, init_key)) == 0) {
1302 
1303           /*
1304            * Before creating a TLS_APPL_STATE instance, log a warning if a
1305            * post-jail request differs from the saved pre-jail request AND the
1306            * post-jail request specifies file/directory pathname arguments.
1307            * Unexpected requests containing pathnames are problematic after
1308            * chroot (pathname resolution) and after dropping privileges (key
1309            * files must be root read-only). Unexpected requests are not a
1310            * problem as long as they contain no pathnames (for example a
1311            * tls_loglevel change).
1312            *
1313            * We could eliminate some of this complication by adding code that
1314            * opens a cert/key lookup table at pre-jail time, and by reading
1315            * cert/key info on-the-fly from that table. But then all requests
1316            * would still have to specify the same table.
1317            */
1318 #define NOT_EMPTY(x) ((x) && *(x))
1319 
1320           if (tlsp_pre_jail_done
1321               && strcmp(tlsp_pre_jail_client_init_key, init_key) != 0
1322               && (NOT_EMPTY(init_props->chain_files)
1323                     || NOT_EMPTY(init_props->cert_file)
1324                     || NOT_EMPTY(init_props->key_file)
1325                     || NOT_EMPTY(init_props->dcert_file)
1326                     || NOT_EMPTY(init_props->dkey_file)
1327                     || NOT_EMPTY(init_props->eccert_file)
1328                     || NOT_EMPTY(init_props->eckey_file)
1329                     || NOT_EMPTY(init_props->CAfile)
1330                     || NOT_EMPTY(init_props->CApath))) {
1331               msg_warn("request from tlsproxy client with unexpected settings");
1332               tlsp_log_config_diff(tlsp_pre_jail_client_init_key, init_key);
1333               log_hints = 1;
1334           }
1335     }
1336     if (log_hints)
1337           msg_warn("to avoid this warning, 1) identify the tlsproxy "
1338                      "client that is making this request, 2) configure "
1339                      "a custom tlsproxy service with settings that "
1340                      "match that tlsproxy client, and 3) configure "
1341                      "that tlsproxy client with a tlsproxy_service_name "
1342                      "setting that resolves to that custom tlsproxy "
1343                      "service");
1344 
1345     /*
1346      * TLS_APPL_STATE creation may fail when a post-jail request specifies
1347      * unexpected cert/key information, but that is OK because we already
1348      * logged a warning with configuration suggestions.
1349      */
1350     if (appl_state == 0
1351           && (appl_state = tls_client_init(init_props)) != 0) {
1352           (void) htable_enter(tlsp_client_app_cache, init_key,
1353                                   (void *) appl_state);
1354 
1355           /*
1356            * To maintain sanity, allow partial SSL_write() operations, and
1357            * allow SSL_write() buffer pointers to change after a WANT_READ or
1358            * WANT_WRITE result. This is based on OpenSSL developers talking on
1359            * a mailing list, but is not supported by documentation. If this
1360            * code stops working then no-one can be held responsible.
1361            */
1362           SSL_CTX_set_mode(appl_state->ssl_ctx,
1363                                SSL_MODE_ENABLE_PARTIAL_WRITE
1364                                | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
1365     }
1366     vstring_free(init_buf);
1367     vstring_free(param_buf);
1368     return (appl_state);
1369 }
1370 
1371 /* tlsp_close_event - pre-handshake plaintext-client close event */
1372 
tlsp_close_event(int event,void * context)1373 static void tlsp_close_event(int event, void *context)
1374 {
1375     TLSP_STATE *state = (TLSP_STATE *) context;
1376 
1377     tlsp_accept_event(event, tlsp_close_event, (void *) state);
1378     tlsp_state_free(state);
1379 }
1380 
1381 /* tlsp_get_request_event - receive initial hand-off info */
1382 
tlsp_get_request_event(int event,void * context)1383 static void tlsp_get_request_event(int event, void *context)
1384 {
1385     const char *myname = "tlsp_get_request_event";
1386     TLSP_STATE *state = (TLSP_STATE *) context;
1387     VSTREAM *plaintext_stream = state->plaintext_stream;
1388     int     plaintext_fd = vstream_fileno(plaintext_stream);
1389     static VSTRING *remote_endpt;
1390     static VSTRING *server_id;
1391     int     req_flags;
1392     int     handshake_timeout;
1393     int     session_timeout;
1394     int     ready = 0;
1395 
1396     /*
1397      * At this point we still manually manage plaintext read/write/timeout
1398      * events. Every code path must either destroy state or request the next
1399      * event, otherwise this pseudo-thread is idle until the client goes
1400      * away.
1401      */
1402     tlsp_accept_event(event, tlsp_get_request_event, (void *) state);
1403 
1404     /*
1405      * One-time initialization.
1406      */
1407     if (remote_endpt == 0) {
1408           remote_endpt = vstring_alloc(10);
1409           server_id = vstring_alloc(10);
1410     }
1411 
1412     /*
1413      * Receive the initial request attributes. Receive the remainder after we
1414      * figure out what role we are expected to play.
1415      *
1416      * The tlsproxy server does not enforce per-request read/write deadlines or
1417      * minimal data rates. Instead, the tlsproxy server relies on the
1418      * tlsproxy client to enforce these context-dependent limits. When a
1419      * tlsproxy client decides to time out, it will close its end of the
1420      * tlsproxy stream, and the tlsproxy server will handle that immediately.
1421      */
1422     if (event != EVENT_READ
1423           || attr_scan(plaintext_stream, ATTR_FLAG_STRICT,
1424                          RECV_ATTR_STR(TLS_ATTR_REMOTE_ENDPT, remote_endpt),
1425                          RECV_ATTR_INT(TLS_ATTR_FLAGS, &req_flags),
1426                          RECV_ATTR_INT(TLS_ATTR_TIMEOUT, &handshake_timeout),
1427                          RECV_ATTR_INT(TLS_ATTR_TIMEOUT, &session_timeout),
1428                          RECV_ATTR_STR(TLS_ATTR_SERVERID, server_id),
1429                          ATTR_TYPE_END) != 5) {
1430           msg_warn("%s: receive request attributes: %m", myname);
1431           tlsp_state_free(state);
1432           return;
1433     }
1434 
1435     /*
1436      * XXX We use the same fixed timeout throughout the entire session for
1437      * both plaintext and ciphertext communication. This timeout is just a
1438      * safety feature; the real timeout will be enforced by our plaintext
1439      * peer (except during TLS the handshake, when we intentionally disable
1440      * plaintext I/O).
1441      */
1442     state->remote_endpt = mystrdup(STR(remote_endpt));
1443     state->server_id = mystrdup(STR(server_id));
1444     msg_info("CONNECT %s %s",
1445                (req_flags & TLS_PROXY_FLAG_ROLE_SERVER) ? "from" :
1446                (req_flags & TLS_PROXY_FLAG_ROLE_CLIENT) ? "to" :
1447                "(bogus_direction)", state->remote_endpt);
1448     state->req_flags = req_flags;
1449     /* state->is_server_role is set below. */
1450     state->handshake_timeout = handshake_timeout;
1451     state->session_timeout = session_timeout + 10;          /* XXX */
1452 
1453     /*
1454      * Receive the TLS preferences now, to reduce the number of protocol
1455      * roundtrips.
1456      */
1457     switch (req_flags & (TLS_PROXY_FLAG_ROLE_CLIENT | TLS_PROXY_FLAG_ROLE_SERVER)) {
1458     case TLS_PROXY_FLAG_ROLE_CLIENT:
1459           state->is_server_role = 0;
1460           if (attr_scan(plaintext_stream, ATTR_FLAG_STRICT,
1461                           RECV_ATTR_FUNC(tls_proxy_client_param_scan,
1462                                              (void *) &state->tls_params),
1463                           RECV_ATTR_FUNC(tls_proxy_client_init_scan,
1464                                              (void *) &state->client_init_props),
1465                           RECV_ATTR_FUNC(tls_proxy_client_start_scan,
1466                                              (void *) &state->client_start_props),
1467                           ATTR_TYPE_END) != 3) {
1468               msg_warn("%s: receive client TLS settings: %m", myname);
1469               tlsp_state_free(state);
1470               return;
1471           }
1472           state->appl_state = tlsp_client_init(state->tls_params,
1473                                                        state->client_init_props);
1474           ready = state->appl_state != 0;
1475           break;
1476     case TLS_PROXY_FLAG_ROLE_SERVER:
1477           state->is_server_role = 1;
1478           ready = (tlsp_server_ctx != 0);
1479           break;
1480     default:
1481           state->is_server_role = 0;
1482           msg_warn("%s: bad request flags: 0x%x", myname, req_flags);
1483           ready = 0;
1484     }
1485 
1486     /*
1487      * For portability we must send some data, after receiving the request
1488      * attributes and before receiving the remote file descriptor.
1489      *
1490      * If the requested TLS engine is unavailable, hang up after making sure
1491      * that the plaintext peer has received our "sorry" indication.
1492      */
1493     if (attr_print(plaintext_stream, ATTR_FLAG_NONE,
1494                        SEND_ATTR_INT(MAIL_ATTR_STATUS, ready),
1495                        ATTR_TYPE_END) != 0
1496           || vstream_fflush(plaintext_stream) != 0
1497           || ready == 0) {
1498           tlsp_request_read_event(plaintext_fd, tlsp_close_event,
1499                                         TLSP_INIT_TIMEOUT, (void *) state);
1500           return;
1501     } else {
1502           tlsp_request_read_event(plaintext_fd, tlsp_get_fd_event,
1503                                         TLSP_INIT_TIMEOUT, (void *) state);
1504           return;
1505     }
1506 }
1507 
1508 /* tlsp_service - handle new client connection */
1509 
tlsp_service(VSTREAM * plaintext_stream,char * service,char ** argv)1510 static void tlsp_service(VSTREAM *plaintext_stream,
1511                                        char *service,
1512                                        char **argv)
1513 {
1514     TLSP_STATE *state;
1515     int     plaintext_fd = vstream_fileno(plaintext_stream);
1516 
1517     /*
1518      * Sanity check. This service takes no command-line arguments.
1519      */
1520     if (argv[0])
1521           msg_fatal("unexpected command-line argument: %s", argv[0]);
1522 
1523     /*
1524      * This program handles multiple connections, so it must not block. We
1525      * use event-driven code for all operations that introduce latency.
1526      * Except that attribute lists are sent/received synchronously, once the
1527      * socket is found to be ready for transmission.
1528      */
1529     non_blocking(plaintext_fd, NON_BLOCKING);
1530     vstream_control(plaintext_stream,
1531                         CA_VSTREAM_CTL_PATH("plaintext"),
1532                         CA_VSTREAM_CTL_TIMEOUT(5),
1533                         CA_VSTREAM_CTL_END);
1534 
1535     (void) attr_print(plaintext_stream, ATTR_FLAG_NONE,
1536                        SEND_ATTR_STR(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_TLSPROXY),
1537                           ATTR_TYPE_END);
1538     if (vstream_fflush(plaintext_stream) != 0)
1539           msg_warn("write %s attribute: %m", MAIL_ATTR_PROTO);
1540 
1541     /*
1542      * Receive postscreen's remote SMTP client address/port and socket.
1543      */
1544     state = tlsp_state_create(service, plaintext_stream);
1545     tlsp_request_read_event(plaintext_fd, tlsp_get_request_event,
1546                                   TLSP_INIT_TIMEOUT, (void *) state);
1547 }
1548 
1549 /* pre_jail_init_server - pre-jail initialization */
1550 
pre_jail_init_server(void)1551 static void pre_jail_init_server(void)
1552 {
1553     TLS_SERVER_INIT_PROPS props;
1554     const char *cert_file;
1555     int     have_server_cert;
1556     int     no_server_cert_ok;
1557     int     require_server_cert;
1558 
1559     /*
1560      * The code in this routine is pasted literally from smtpd(8). I am not
1561      * going to sanitize this because doing so surely will break things in
1562      * unexpected ways.
1563      */
1564     if (*var_tlsp_tls_level) {
1565           switch (tls_level_lookup(var_tlsp_tls_level)) {
1566           default:
1567               msg_fatal("Invalid TLS level \"%s\"", var_tlsp_tls_level);
1568               /* NOTREACHED */
1569               break;
1570           case TLS_LEV_SECURE:
1571           case TLS_LEV_VERIFY:
1572           case TLS_LEV_FPRINT:
1573               msg_warn("%s: unsupported TLS level \"%s\", using \"encrypt\"",
1574                          VAR_TLSP_TLS_LEVEL, var_tlsp_tls_level);
1575               /* FALLTHROUGH */
1576           case TLS_LEV_ENCRYPT:
1577               var_tlsp_enforce_tls = var_tlsp_use_tls = 1;
1578               break;
1579           case TLS_LEV_MAY:
1580               var_tlsp_enforce_tls = 0;
1581               var_tlsp_use_tls = 1;
1582               break;
1583           case TLS_LEV_NONE:
1584               var_tlsp_enforce_tls = var_tlsp_use_tls = 0;
1585               break;
1586           }
1587     }
1588     var_tlsp_use_tls = var_tlsp_use_tls || var_tlsp_enforce_tls;
1589     if (!var_tlsp_use_tls) {
1590           msg_warn("TLS server role is disabled with %s or %s",
1591                      VAR_TLSP_TLS_LEVEL, VAR_TLSP_USE_TLS);
1592           return;
1593     }
1594 
1595     /*
1596      * Load TLS keys before dropping privileges.
1597      *
1598      * Can't use anonymous ciphers if we want client certificates. Must use
1599      * anonymous ciphers if we have no certificates.
1600      */
1601     ask_client_cert = require_server_cert =
1602           (var_tlsp_tls_ask_ccert
1603            || (var_tlsp_enforce_tls && var_tlsp_tls_req_ccert));
1604     if (strcasecmp(var_tlsp_tls_cert_file, "none") == 0) {
1605           no_server_cert_ok = 1;
1606           cert_file = "";
1607     } else {
1608           no_server_cert_ok = 0;
1609           cert_file = var_tlsp_tls_cert_file;
1610     }
1611     have_server_cert =
1612           (*cert_file || *var_tlsp_tls_dcert_file || *var_tlsp_tls_eccert_file);
1613 
1614     if (*var_tlsp_tls_chain_files != 0) {
1615           if (!have_server_cert)
1616               have_server_cert = 1;
1617           else
1618               msg_warn("Both %s and one or more of the legacy "
1619                          " %s, %s or %s are non-empty; the legacy "
1620                          " parameters will be ignored",
1621                          VAR_TLSP_TLS_CHAIN_FILES,
1622                          VAR_TLSP_TLS_CERT_FILE,
1623                          VAR_TLSP_TLS_ECCERT_FILE,
1624                          VAR_TLSP_TLS_DCERT_FILE);
1625     }
1626     /* Some TLS configuration errors are not show stoppers. */
1627     if (!have_server_cert && require_server_cert)
1628           msg_warn("Need a server cert to request client certs");
1629     if (!var_tlsp_enforce_tls && var_tlsp_tls_req_ccert)
1630           msg_warn("Can't require client certs unless TLS is required");
1631     /* After a show-stopper error, log a warning. */
1632     if (have_server_cert || (no_server_cert_ok && !require_server_cert)) {
1633 
1634           tls_pre_jail_init(TLS_ROLE_SERVER);
1635 
1636           /*
1637            * Large parameter lists are error-prone, so we emulate a language
1638            * feature that C does not have natively: named parameter lists.
1639            */
1640           tlsp_server_ctx =
1641               TLS_SERVER_INIT(&props,
1642                                   log_param = VAR_TLSP_TLS_LOGLEVEL,
1643                                   log_level = var_tlsp_tls_loglevel,
1644                                   verifydepth = var_tlsp_tls_ccert_vd,
1645                                   cache_type = TLS_MGR_SCACHE_SMTPD,
1646                                   set_sessid = var_tlsp_tls_set_sessid,
1647                                   chain_files = var_tlsp_tls_chain_files,
1648                                   cert_file = cert_file,
1649                                   key_file = var_tlsp_tls_key_file,
1650                                   dcert_file = var_tlsp_tls_dcert_file,
1651                                   dkey_file = var_tlsp_tls_dkey_file,
1652                                   eccert_file = var_tlsp_tls_eccert_file,
1653                                   eckey_file = var_tlsp_tls_eckey_file,
1654                                   CAfile = var_tlsp_tls_CAfile,
1655                                   CApath = var_tlsp_tls_CApath,
1656                                   dh1024_param_file
1657                                   = var_tlsp_tls_dh1024_param_file,
1658                                   dh512_param_file
1659                                   = var_tlsp_tls_dh512_param_file,
1660                                   eecdh_grade = var_tlsp_tls_eecdh,
1661                                   protocols = var_tlsp_enforce_tls ?
1662                                   var_tlsp_tls_mand_proto :
1663                                   var_tlsp_tls_proto,
1664                                   ask_ccert = ask_client_cert,
1665                                   mdalg = var_tlsp_tls_fpt_dgst);
1666     } else {
1667           msg_warn("No server certs available. TLS can't be enabled");
1668     }
1669 
1670     /*
1671      * To maintain sanity, allow partial SSL_write() operations, and allow
1672      * SSL_write() buffer pointers to change after a WANT_READ or WANT_WRITE
1673      * result. This is based on OpenSSL developers talking on a mailing list,
1674      * but is not supported by documentation. If this code stops working then
1675      * no-one can be held responsible.
1676      */
1677     if (tlsp_server_ctx)
1678           SSL_CTX_set_mode(tlsp_server_ctx->ssl_ctx,
1679                                SSL_MODE_ENABLE_PARTIAL_WRITE
1680                                | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
1681 }
1682 
1683 /* pre_jail_init_client - pre-jail initialization */
1684 
pre_jail_init_client(void)1685 static void pre_jail_init_client(void)
1686 {
1687     int     clnt_use_tls;
1688 
1689     /*
1690      * The cache with TLS_APPL_STATE instances for different TLS_CLIENT_INIT
1691      * configurations.
1692      */
1693     tlsp_client_app_cache = htable_create(10);
1694 
1695     /*
1696      * Most sites don't use TLS client certs/keys. In that case, enabling
1697      * tlsproxy-based connection caching is trivial.
1698      *
1699      * But some sites do use TLS client certs/keys, and that is challenging when
1700      * tlsproxy runs in a post-jail environment: chroot breaks pathname
1701      * resolution, and an unprivileged process should not be able to open
1702      * files with secrets. The workaround: assume that most of those sites
1703      * will use a fixed TLS client identity. In that case, tlsproxy can load
1704      * the corresponding certs/keys at pre-jail time, so that secrets can
1705      * remain read-only for root. As long as the tlsproxy pre-jail TLS client
1706      * configuration with cert or key pathnames is the same as the one used
1707      * in the Postfix SMTP client, sites can selectively or globally enable
1708      * tlsproxy-based connection caching without additional TLS
1709      * configuration.
1710      *
1711      * Loading one TLS client configuration at pre-jail time is not sufficient
1712      * for the minority of sites that want to use TLS connection caching with
1713      * multiple TLS client identities. To alert the operator, tlsproxy will
1714      * log a warning when a TLS_CLIENT_INIT message specifies a different
1715      * configuration than the tlsproxy pre-jail client configuration, and
1716      * that different configuration specifies file/directory pathname
1717      * arguments. The workaround is to have one tlsproxy process per TLS
1718      * client identity.
1719      *
1720      * The general solution for single-identity or multi-identity clients is to
1721      * stop loading certs and keys from individual files. Instead, have a
1722      * cert/key map, indexed by client identity, read-only by root. After
1723      * opening the map as root at pre-jail time, tlsproxy can read certs/keys
1724      * on-the-fly as an unprivileged process at post-jail time. This is the
1725      * approach that was already proposed for server-side SNI support, and it
1726      * could be reused here. It would also end the proliferation of RSA
1727      * cert/key parameters, DSA cert/key parameters, EC cert/key parameters,
1728      * and so on.
1729      *
1730      * Horror: In order to create the same pre-jail TLS client context as the
1731      * one used in the Postfix SMTP client, we have to duplicate intricate
1732      * SMTP client code, including a handful configuration parameters that
1733      * tlsproxy does not need. We must duplicate the logic, so that we only
1734      * load certs and keys when the SMTP client would load them.
1735      */
1736     if (*var_tlsp_clnt_level != 0)
1737           switch (tls_level_lookup(var_tlsp_clnt_level)) {
1738           case TLS_LEV_SECURE:
1739           case TLS_LEV_VERIFY:
1740           case TLS_LEV_DANE_ONLY:
1741           case TLS_LEV_FPRINT:
1742           case TLS_LEV_ENCRYPT:
1743               var_tlsp_clnt_use_tls = var_tlsp_clnt_enforce_tls = 1;
1744               break;
1745           case TLS_LEV_DANE:
1746           case TLS_LEV_MAY:
1747               var_tlsp_clnt_use_tls = 1;
1748               var_tlsp_clnt_enforce_tls = 0;
1749               break;
1750           case TLS_LEV_NONE:
1751               var_tlsp_clnt_use_tls = var_tlsp_clnt_enforce_tls = 0;
1752               break;
1753           default:
1754               /* tls_level_lookup() logs no warning. */
1755               /* session_tls_init() assumes that var_tlsp_clnt_level is sane. */
1756               msg_fatal("Invalid TLS level \"%s\"", var_tlsp_clnt_level);
1757           }
1758     clnt_use_tls = (var_tlsp_clnt_use_tls || var_tlsp_clnt_enforce_tls);
1759 
1760     /*
1761      * Initialize the TLS data before entering the chroot jail.
1762      */
1763     if (clnt_use_tls || var_tlsp_clnt_per_site[0] || var_tlsp_clnt_policy[0]) {
1764           TLS_CLIENT_PARAMS tls_params;
1765           TLS_CLIENT_INIT_PROPS init_props;
1766 
1767           tls_pre_jail_init(TLS_ROLE_CLIENT);
1768 
1769           /*
1770            * We get stronger type safety and a cleaner interface by combining
1771            * the various parameters into a single tls_client_props structure.
1772            *
1773            * Large parameter lists are error-prone, so we emulate a language
1774            * feature that C does not have natively: named parameter lists.
1775            */
1776           (void) tls_proxy_client_param_from_config(&tls_params);
1777           (void) TLS_CLIENT_INIT_ARGS(&init_props,
1778                                             log_param = var_tlsp_clnt_logparam,
1779                                             log_level = var_tlsp_clnt_loglevel,
1780                                             verifydepth = var_tlsp_clnt_scert_vd,
1781                                             cache_type = TLS_MGR_SCACHE_SMTP,
1782                                             chain_files = var_tlsp_clnt_chain_files,
1783                                             cert_file = var_tlsp_clnt_cert_file,
1784                                             key_file = var_tlsp_clnt_key_file,
1785                                             dcert_file = var_tlsp_clnt_dcert_file,
1786                                             dkey_file = var_tlsp_clnt_dkey_file,
1787                                             eccert_file = var_tlsp_clnt_eccert_file,
1788                                             eckey_file = var_tlsp_clnt_eckey_file,
1789                                             CAfile = var_tlsp_clnt_CAfile,
1790                                             CApath = var_tlsp_clnt_CApath,
1791                                             mdalg = var_tlsp_clnt_fpt_dgst);
1792           if (tlsp_client_init(&tls_params, &init_props) == 0)
1793               msg_warn("TLS client initialization failed");
1794     }
1795 }
1796 
1797 /* pre_jail_init - pre-jail initialization */
1798 
pre_jail_init(char * unused_name,char ** unused_argv)1799 static void pre_jail_init(char *unused_name, char **unused_argv)
1800 {
1801 
1802     /*
1803      * Initialize roles separately.
1804      */
1805     pre_jail_init_server();
1806     pre_jail_init_client();
1807 
1808     /*
1809      * tlsp_client_init() needs to know if it is called pre-jail or
1810      * post-jail.
1811      */
1812     tlsp_pre_jail_done = 1;
1813 
1814     /*
1815      * Bug: TLS_CLIENT_PARAMS attributes are not used when creating a
1816      * TLS_APPL_STATE instance; we can only warn about attribute mismatches.
1817      */
1818     tlsp_params_mismatch_filter = been_here_init(BH_BOUND_NONE, BH_FLAG_NONE);
1819 }
1820 
1821 MAIL_VERSION_STAMP_DECLARE;
1822 
1823 /* main - the main program */
1824 
main(int argc,char ** argv)1825 int     main(int argc, char **argv)
1826 {
1827 
1828     /*
1829      * Each table below initializes the named variables to their implicit
1830      * default value, or to the explicit value in main.cf or master.cf. Here,
1831      * "compat" means that a table initializes a variable "smtpd_blah" or
1832      * "smtp_blah" that provides the implicit default value for variable
1833      * "tlsproxy_blah" which is initialized by a different table. To make
1834      * this work, the variables in a "compat" table must be initialized
1835      * before the variables in the corresponding non-compat table.
1836      */
1837     static const CONFIG_INT_TABLE compat_int_table[] = {
1838           VAR_SMTPD_TLS_CCERT_VD, DEF_SMTPD_TLS_CCERT_VD, &var_smtpd_tls_ccert_vd, 0, 0,
1839           VAR_SMTP_TLS_SCERT_VD, DEF_SMTP_TLS_SCERT_VD, &var_smtp_tls_scert_vd, 0, 0,
1840           0,
1841     };
1842     static const CONFIG_NINT_TABLE nint_table[] = {
1843           VAR_TLSP_TLS_CCERT_VD, DEF_TLSP_TLS_CCERT_VD, &var_tlsp_tls_ccert_vd, 0, 0,
1844           VAR_TLSP_CLNT_SCERT_VD, DEF_TLSP_CLNT_SCERT_VD, &var_tlsp_clnt_scert_vd, 0, 0,
1845           0,
1846     };
1847     static const CONFIG_TIME_TABLE time_table[] = {
1848           VAR_TLSP_WATCHDOG, DEF_TLSP_WATCHDOG, &var_tlsp_watchdog, 10, 0,
1849           0,
1850     };
1851     static const CONFIG_BOOL_TABLE compat_bool_table[] = {
1852           VAR_SMTPD_USE_TLS, DEF_SMTPD_USE_TLS, &var_smtpd_use_tls,
1853           VAR_SMTPD_ENFORCE_TLS, DEF_SMTPD_ENFORCE_TLS, &var_smtpd_enforce_tls,
1854           VAR_SMTPD_TLS_ACERT, DEF_SMTPD_TLS_ACERT, &var_smtpd_tls_ask_ccert,
1855           VAR_SMTPD_TLS_RCERT, DEF_SMTPD_TLS_RCERT, &var_smtpd_tls_req_ccert,
1856           VAR_SMTPD_TLS_ENABLE_RPK, DEF_SMTPD_TLS_ENABLE_RPK, &var_smtpd_tls_enable_rpk,
1857           VAR_SMTPD_TLS_SET_SESSID, DEF_SMTPD_TLS_SET_SESSID, &var_smtpd_tls_set_sessid,
1858           VAR_SMTP_USE_TLS, DEF_SMTP_USE_TLS, &var_smtp_use_tls,
1859           VAR_SMTP_ENFORCE_TLS, DEF_SMTP_ENFORCE_TLS, &var_smtp_enforce_tls,
1860           0,
1861     };
1862     static const CONFIG_NBOOL_TABLE nbool_table[] = {
1863           VAR_TLSP_USE_TLS, DEF_TLSP_USE_TLS, &var_tlsp_use_tls,
1864           VAR_TLSP_ENFORCE_TLS, DEF_TLSP_ENFORCE_TLS, &var_tlsp_enforce_tls,
1865           VAR_TLSP_TLS_ACERT, DEF_TLSP_TLS_ACERT, &var_tlsp_tls_ask_ccert,
1866           VAR_TLSP_TLS_RCERT, DEF_TLSP_TLS_RCERT, &var_tlsp_tls_req_ccert,
1867           VAR_TLSP_TLS_ENABLE_RPK, DEF_TLSP_TLS_ENABLE_RPK, &var_tlsp_tls_enable_rpk,
1868           VAR_TLSP_TLS_SET_SESSID, DEF_TLSP_TLS_SET_SESSID, &var_tlsp_tls_set_sessid,
1869           VAR_TLSP_CLNT_USE_TLS, DEF_TLSP_CLNT_USE_TLS, &var_tlsp_clnt_use_tls,
1870           VAR_TLSP_CLNT_ENFORCE_TLS, DEF_TLSP_CLNT_ENFORCE_TLS, &var_tlsp_clnt_enforce_tls,
1871           0,
1872     };
1873     static const CONFIG_STR_TABLE compat_str_table[] = {
1874           VAR_SMTPD_TLS_CHAIN_FILES, DEF_SMTPD_TLS_CHAIN_FILES, &var_smtpd_tls_chain_files, 0, 0,
1875           VAR_SMTPD_TLS_CERT_FILE, DEF_SMTPD_TLS_CERT_FILE, &var_smtpd_tls_cert_file, 0, 0,
1876           VAR_SMTPD_TLS_KEY_FILE, DEF_SMTPD_TLS_KEY_FILE, &var_smtpd_tls_key_file, 0, 0,
1877           VAR_SMTPD_TLS_DCERT_FILE, DEF_SMTPD_TLS_DCERT_FILE, &var_smtpd_tls_dcert_file, 0, 0,
1878           VAR_SMTPD_TLS_DKEY_FILE, DEF_SMTPD_TLS_DKEY_FILE, &var_smtpd_tls_dkey_file, 0, 0,
1879           VAR_SMTPD_TLS_ECCERT_FILE, DEF_SMTPD_TLS_ECCERT_FILE, &var_smtpd_tls_eccert_file, 0, 0,
1880           VAR_SMTPD_TLS_ECKEY_FILE, DEF_SMTPD_TLS_ECKEY_FILE, &var_smtpd_tls_eckey_file, 0, 0,
1881           VAR_SMTPD_TLS_CA_FILE, DEF_SMTPD_TLS_CA_FILE, &var_smtpd_tls_CAfile, 0, 0,
1882           VAR_SMTPD_TLS_CA_PATH, DEF_SMTPD_TLS_CA_PATH, &var_smtpd_tls_CApath, 0, 0,
1883           VAR_SMTPD_TLS_CIPH, DEF_SMTPD_TLS_CIPH, &var_smtpd_tls_ciph, 1, 0,
1884           VAR_SMTPD_TLS_MAND_CIPH, DEF_SMTPD_TLS_MAND_CIPH, &var_smtpd_tls_mand_ciph, 1, 0,
1885           VAR_SMTPD_TLS_EXCL_CIPH, DEF_SMTPD_TLS_EXCL_CIPH, &var_smtpd_tls_excl_ciph, 0, 0,
1886           VAR_SMTPD_TLS_MAND_EXCL, DEF_SMTPD_TLS_MAND_EXCL, &var_smtpd_tls_mand_excl, 0, 0,
1887           VAR_SMTPD_TLS_PROTO, DEF_SMTPD_TLS_PROTO, &var_smtpd_tls_proto, 0, 0,
1888           VAR_SMTPD_TLS_MAND_PROTO, DEF_SMTPD_TLS_MAND_PROTO, &var_smtpd_tls_mand_proto, 0, 0,
1889           VAR_SMTPD_TLS_512_FILE, DEF_SMTPD_TLS_512_FILE, &var_smtpd_tls_dh512_param_file, 0, 0,
1890           VAR_SMTPD_TLS_1024_FILE, DEF_SMTPD_TLS_1024_FILE, &var_smtpd_tls_dh1024_param_file, 0, 0,
1891           VAR_SMTPD_TLS_EECDH, DEF_SMTPD_TLS_EECDH, &var_smtpd_tls_eecdh, 1, 0,
1892           VAR_SMTPD_TLS_FPT_DGST, DEF_SMTPD_TLS_FPT_DGST, &var_smtpd_tls_fpt_dgst, 1, 0,
1893           VAR_SMTPD_TLS_LOGLEVEL, DEF_SMTPD_TLS_LOGLEVEL, &var_smtpd_tls_loglevel, 0, 0,
1894           VAR_SMTPD_TLS_LEVEL, DEF_SMTPD_TLS_LEVEL, &var_smtpd_tls_level, 0, 0,
1895           VAR_SMTP_TLS_CHAIN_FILES, DEF_SMTP_TLS_CHAIN_FILES, &var_smtp_tls_chain_files, 0, 0,
1896           VAR_SMTP_TLS_CERT_FILE, DEF_SMTP_TLS_CERT_FILE, &var_smtp_tls_cert_file, 0, 0,
1897           VAR_SMTP_TLS_KEY_FILE, DEF_SMTP_TLS_KEY_FILE, &var_smtp_tls_key_file, 0, 0,
1898           VAR_SMTP_TLS_DCERT_FILE, DEF_SMTP_TLS_DCERT_FILE, &var_smtp_tls_dcert_file, 0, 0,
1899           VAR_SMTP_TLS_DKEY_FILE, DEF_SMTP_TLS_DKEY_FILE, &var_smtp_tls_dkey_file, 0, 0,
1900           VAR_SMTP_TLS_CA_FILE, DEF_SMTP_TLS_CA_FILE, &var_smtp_tls_CAfile, 0, 0,
1901           VAR_SMTP_TLS_CA_PATH, DEF_SMTP_TLS_CA_PATH, &var_smtp_tls_CApath, 0, 0,
1902           VAR_SMTP_TLS_FPT_DGST, DEF_SMTP_TLS_FPT_DGST, &var_smtp_tls_fpt_dgst, 1, 0,
1903           VAR_SMTP_TLS_ECCERT_FILE, DEF_SMTP_TLS_ECCERT_FILE, &var_smtp_tls_eccert_file, 0, 0,
1904           VAR_SMTP_TLS_ECKEY_FILE, DEF_SMTP_TLS_ECKEY_FILE, &var_smtp_tls_eckey_file, 0, 0,
1905           VAR_SMTP_TLS_LOGLEVEL, DEF_SMTP_TLS_LOGLEVEL, &var_smtp_tls_loglevel, 0, 0,
1906           VAR_SMTP_TLS_PER_SITE, DEF_SMTP_TLS_PER_SITE, &var_smtp_tls_per_site, 0, 0,
1907           VAR_SMTP_TLS_LEVEL, DEF_SMTP_TLS_LEVEL, &var_smtp_tls_level, 0, 0,
1908           VAR_SMTP_TLS_POLICY, DEF_SMTP_TLS_POLICY, &var_smtp_tls_policy, 0, 0,
1909           0,
1910     };
1911     static const CONFIG_STR_TABLE str_table[] = {
1912           VAR_TLSP_TLS_CHAIN_FILES, DEF_TLSP_TLS_CHAIN_FILES, &var_tlsp_tls_chain_files, 0, 0,
1913           VAR_TLSP_TLS_CERT_FILE, DEF_TLSP_TLS_CERT_FILE, &var_tlsp_tls_cert_file, 0, 0,
1914           VAR_TLSP_TLS_KEY_FILE, DEF_TLSP_TLS_KEY_FILE, &var_tlsp_tls_key_file, 0, 0,
1915           VAR_TLSP_TLS_DCERT_FILE, DEF_TLSP_TLS_DCERT_FILE, &var_tlsp_tls_dcert_file, 0, 0,
1916           VAR_TLSP_TLS_DKEY_FILE, DEF_TLSP_TLS_DKEY_FILE, &var_tlsp_tls_dkey_file, 0, 0,
1917           VAR_TLSP_TLS_ECCERT_FILE, DEF_TLSP_TLS_ECCERT_FILE, &var_tlsp_tls_eccert_file, 0, 0,
1918           VAR_TLSP_TLS_ECKEY_FILE, DEF_TLSP_TLS_ECKEY_FILE, &var_tlsp_tls_eckey_file, 0, 0,
1919           VAR_TLSP_TLS_CA_FILE, DEF_TLSP_TLS_CA_FILE, &var_tlsp_tls_CAfile, 0, 0,
1920           VAR_TLSP_TLS_CA_PATH, DEF_TLSP_TLS_CA_PATH, &var_tlsp_tls_CApath, 0, 0,
1921           VAR_TLSP_TLS_CIPH, DEF_TLSP_TLS_CIPH, &var_tlsp_tls_ciph, 1, 0,
1922           VAR_TLSP_TLS_MAND_CIPH, DEF_TLSP_TLS_MAND_CIPH, &var_tlsp_tls_mand_ciph, 1, 0,
1923           VAR_TLSP_TLS_EXCL_CIPH, DEF_TLSP_TLS_EXCL_CIPH, &var_tlsp_tls_excl_ciph, 0, 0,
1924           VAR_TLSP_TLS_MAND_EXCL, DEF_TLSP_TLS_MAND_EXCL, &var_tlsp_tls_mand_excl, 0, 0,
1925           VAR_TLSP_TLS_PROTO, DEF_TLSP_TLS_PROTO, &var_tlsp_tls_proto, 0, 0,
1926           VAR_TLSP_TLS_MAND_PROTO, DEF_TLSP_TLS_MAND_PROTO, &var_tlsp_tls_mand_proto, 0, 0,
1927           VAR_TLSP_TLS_512_FILE, DEF_TLSP_TLS_512_FILE, &var_tlsp_tls_dh512_param_file, 0, 0,
1928           VAR_TLSP_TLS_1024_FILE, DEF_TLSP_TLS_1024_FILE, &var_tlsp_tls_dh1024_param_file, 0, 0,
1929           VAR_TLSP_TLS_EECDH, DEF_TLSP_TLS_EECDH, &var_tlsp_tls_eecdh, 1, 0,
1930           VAR_TLSP_TLS_FPT_DGST, DEF_TLSP_TLS_FPT_DGST, &var_tlsp_tls_fpt_dgst, 1, 0,
1931           VAR_TLSP_TLS_LOGLEVEL, DEF_TLSP_TLS_LOGLEVEL, &var_tlsp_tls_loglevel, 0, 0,
1932           VAR_TLSP_TLS_LEVEL, DEF_TLSP_TLS_LEVEL, &var_tlsp_tls_level, 0, 0,
1933           VAR_TLSP_CLNT_LOGLEVEL, DEF_TLSP_CLNT_LOGLEVEL, &var_tlsp_clnt_loglevel, 0, 0,
1934           VAR_TLSP_CLNT_LOGPARAM, DEF_TLSP_CLNT_LOGPARAM, &var_tlsp_clnt_logparam, 0, 0,
1935           VAR_TLSP_CLNT_CHAIN_FILES, DEF_TLSP_CLNT_CHAIN_FILES, &var_tlsp_clnt_chain_files, 0, 0,
1936           VAR_TLSP_CLNT_CERT_FILE, DEF_TLSP_CLNT_CERT_FILE, &var_tlsp_clnt_cert_file, 0, 0,
1937           VAR_TLSP_CLNT_KEY_FILE, DEF_TLSP_CLNT_KEY_FILE, &var_tlsp_clnt_key_file, 0, 0,
1938           VAR_TLSP_CLNT_DCERT_FILE, DEF_TLSP_CLNT_DCERT_FILE, &var_tlsp_clnt_dcert_file, 0, 0,
1939           VAR_TLSP_CLNT_DKEY_FILE, DEF_TLSP_CLNT_DKEY_FILE, &var_tlsp_clnt_dkey_file, 0, 0,
1940           VAR_TLSP_CLNT_ECCERT_FILE, DEF_TLSP_CLNT_ECCERT_FILE, &var_tlsp_clnt_eccert_file, 0, 0,
1941           VAR_TLSP_CLNT_ECKEY_FILE, DEF_TLSP_CLNT_ECKEY_FILE, &var_tlsp_clnt_eckey_file, 0, 0,
1942           VAR_TLSP_CLNT_CAFILE, DEF_TLSP_CLNT_CAFILE, &var_tlsp_clnt_CAfile, 0, 0,
1943           VAR_TLSP_CLNT_CAPATH, DEF_TLSP_CLNT_CAPATH, &var_tlsp_clnt_CApath, 0, 0,
1944           VAR_TLSP_CLNT_FPT_DGST, DEF_TLSP_CLNT_FPT_DGST, &var_tlsp_clnt_fpt_dgst, 1, 0,
1945           VAR_TLSP_CLNT_LEVEL, DEF_TLSP_CLNT_LEVEL, &var_tlsp_clnt_level, 0, 0,
1946           VAR_TLSP_CLNT_PER_SITE, DEF_TLSP_CLNT_PER_SITE, &var_tlsp_clnt_per_site, 0, 0,
1947           VAR_TLSP_CLNT_POLICY, DEF_TLSP_CLNT_POLICY, &var_tlsp_clnt_policy, 0, 0,
1948           0,
1949     };
1950 
1951     /*
1952      * Fingerprint executables and core dumps.
1953      */
1954     MAIL_VERSION_STAMP_ALLOCATE;
1955 
1956     /*
1957      * Pass control to the event-driven service skeleton.
1958      */
1959     event_server_main(argc, argv, tlsp_service,
1960                           CA_MAIL_SERVER_INT_TABLE(compat_int_table),
1961                           CA_MAIL_SERVER_NINT_TABLE(nint_table),
1962                           CA_MAIL_SERVER_STR_TABLE(compat_str_table),
1963                           CA_MAIL_SERVER_STR_TABLE(str_table),
1964                           CA_MAIL_SERVER_BOOL_TABLE(compat_bool_table),
1965                           CA_MAIL_SERVER_NBOOL_TABLE(nbool_table),
1966                           CA_MAIL_SERVER_TIME_TABLE(time_table),
1967                           CA_MAIL_SERVER_PRE_INIT(pre_jail_init),
1968                           CA_MAIL_SERVER_SLOW_EXIT(tlsp_drain),
1969                           CA_MAIL_SERVER_RETIRE_ME,
1970                           CA_MAIL_SERVER_WATCHDOG(&var_tlsp_watchdog),
1971                           CA_MAIL_SERVER_UNLIMITED,
1972                           0);
1973 }
1974 
1975 #else
1976 
1977 /* tlsp_service - respond to external trigger(s), non-TLS version */
1978 
tlsp_service(VSTREAM * stream,char * unused_service,char ** unused_argv)1979 static void tlsp_service(VSTREAM *stream, char *unused_service,
1980                                        char **unused_argv)
1981 {
1982     msg_info("TLS support is not compiled in -- exiting");
1983     event_server_disconnect(stream);
1984 }
1985 
1986 /* main - the main program */
1987 
main(int argc,char ** argv)1988 int     main(int argc, char **argv)
1989 {
1990 
1991     /*
1992      * We can't simply use msg_fatal() here, because the logging hasn't been
1993      * initialized. The text would disappear because stderr is redirected to
1994      * /dev/null.
1995      *
1996      * We invoke event_server_main() to complete program initialization
1997      * (including logging) and then invoke the tlsp_service() routine to log
1998      * the message that says why this program will not run.
1999      */
2000     event_server_main(argc, argv, tlsp_service,
2001                           0);
2002 }
2003 
2004 #endif
2005