Home | History | Annotate | Line # | Download | only in tlsproxy
      1 /*	$NetBSD: tlsproxy.c,v 1.8 2026/05/09 18:49:21 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 static const char *server_role_disabled;
    552 
    553  /*
    554   * TLS per-client status.
    555   */
    556 static HTABLE *tlsp_client_app_cache;	/* per-client init props */
    557 static BH_TABLE *tlsp_params_mismatch_filter;	/* per-client nag filter */
    558 
    559  /*
    560   * Error handling: if a function detects an error, then that function is
    561   * responsible for destroying TLSP_STATE. Exceptions to this principle are
    562   * indicated in the code.
    563   */
    564 
    565  /*
    566   * Internal status API.
    567   */
    568 #define TLSP_STAT_OK	0
    569 #define TLSP_STAT_ERR	(-1)
    570 
    571  /*
    572   * SLMs.
    573   */
    574 #define STR(x)	vstring_str(x)
    575 #define LEN(x)	VSTRING_LEN(x)
    576 
    577  /*
    578   * The code that implements the TLS engine looks simpler than expected. That
    579   * is the result of a great deal of effort, mainly in design and analysis.
    580   *
    581   * The initial use case was to provide TLS support for postscreen(8).
    582   *
    583   * By design, postscreen(8) is an event-driven server that must scale up to a
    584   * large number of clients. This means that postscreen(8) must avoid doing
    585   * CPU-intensive operations such as those in OpenSSL.
    586   *
    587   * tlsproxy(8) runs the OpenSSL code on behalf of postscreen(8), translating
    588   * plaintext SMTP messages from postscreen(8) into SMTP-over-TLS messages to
    589   * the remote SMTP client, and vice versa. As long as postscreen(8) does not
    590   * receive email messages, the cost of doing TLS operations will be modest.
    591   *
    592   * Like postscreen(8), one tlsproxy(8) process services multiple remote SMTP
    593   * clients. Unlike postscreen(8), there can be more than one tlsproxy(8)
    594   * process, although their number is meant to be much smaller than the
    595   * number of remote SMTP clients that talk TLS.
    596   *
    597   * As with postscreen(8), all I/O must be event-driven: encrypted traffic
    598   * between tlsproxy(8) and remote SMTP clients, and plaintext traffic
    599   * between tlsproxy(8) and postscreen(8). Event-driven plaintext I/O is
    600   * straightforward enough that it could be abstracted away with the nbbio(3)
    601   * module.
    602   *
    603   * The event-driven TLS I/O implementation is founded on on-line OpenSSL
    604   * documentation, supplemented by statements from OpenSSL developers on
    605   * public mailing lists. After some field experience with this code, we may
    606   * be able to factor it out as a library module, like nbbio(3), that can
    607   * become part of the TLS library.
    608   *
    609   * Later in the life cycle, tlsproxy(8) has also become an enabler for TLS
    610   * connection reuse across different SMTP client processes.
    611   */
    612 
    613 static void tlsp_ciphertext_event(int, void *);
    614 
    615 #define TLSP_INIT_TIMEOUT	100
    616 
    617 static void tlsp_plaintext_event(int event, void *context);
    618 
    619 /* tlsp_drain - delayed exit after "postfix reload" */
    620 
    621 static void tlsp_drain(char *unused_service, char **unused_argv)
    622 {
    623     int     count;
    624 
    625     /*
    626      * After "postfix reload", complete work-in-progress in the background,
    627      * instead of dropping already-accepted connections on the floor.
    628      *
    629      * All error retry counts shall be limited. Instead of blocking here, we
    630      * could retry failed fork() operations in the event call-back routines,
    631      * but we don't need perfection. The host system is severely overloaded
    632      * and service levels are already way down.
    633      */
    634     for (count = 0; /* see below */ ; count++) {
    635 	if (count >= 5) {
    636 	    msg_fatal("fork: %m");
    637 	} else if (event_server_drain() != 0) {
    638 	    msg_warn("fork: %m");
    639 	    sleep(1);
    640 	    continue;
    641 	} else {
    642 	    return;
    643 	}
    644     }
    645 }
    646 
    647 /* tlsp_eval_tls_error - translate TLS "error" result into action */
    648 
    649 static int tlsp_eval_tls_error(TLSP_STATE *state, int err)
    650 {
    651     int     ciphertext_fd = state->ciphertext_fd;
    652 
    653     /*
    654      * The ciphertext file descriptor is in non-blocking mode, meaning that
    655      * each SSL_accept/connect/read/write/shutdown request may return an
    656      * "error" indication that it needs to read or write more ciphertext. The
    657      * purpose of this routine is to translate those "error" indications into
    658      * the appropriate read/write/timeout event requests.
    659      */
    660     switch (err) {
    661 
    662 	/*
    663 	 * No error means a successful SSL_accept/connect/shutdown request or
    664 	 * sequence of SSL_read/write requests. Disable read/write events on
    665 	 * the ciphertext stream. Keep the ciphertext stream timer alive as a
    666 	 * safety mechanism for the case that the plaintext pseudothreads get
    667 	 * stuck.
    668 	 */
    669     case SSL_ERROR_NONE:
    670 	if (state->ssl_last_err != SSL_ERROR_NONE) {
    671 	    event_disable_readwrite(ciphertext_fd);
    672 	    event_request_timer(tlsp_ciphertext_event, (void *) state,
    673 				state->timeout);
    674 	    state->ssl_last_err = SSL_ERROR_NONE;
    675 	}
    676 	return (TLSP_STAT_OK);
    677 
    678 	/*
    679 	 * The TLS engine wants to write to the network. Turn on
    680 	 * write/timeout events on the ciphertext stream.
    681 	 */
    682     case SSL_ERROR_WANT_WRITE:
    683 	if (state->ssl_last_err == SSL_ERROR_WANT_READ)
    684 	    event_disable_readwrite(ciphertext_fd);
    685 	if (state->ssl_last_err != SSL_ERROR_WANT_WRITE) {
    686 	    event_enable_write(ciphertext_fd, tlsp_ciphertext_event,
    687 			       (void *) state);
    688 	    state->ssl_last_err = SSL_ERROR_WANT_WRITE;
    689 	}
    690 	event_request_timer(tlsp_ciphertext_event, (void *) state,
    691 			    state->timeout);
    692 	return (TLSP_STAT_OK);
    693 
    694 	/*
    695 	 * The TLS engine wants to read from the network. Turn on
    696 	 * read/timeout events on the ciphertext stream.
    697 	 */
    698     case SSL_ERROR_WANT_READ:
    699 	if (state->ssl_last_err == SSL_ERROR_WANT_WRITE)
    700 	    event_disable_readwrite(ciphertext_fd);
    701 	if (state->ssl_last_err != SSL_ERROR_WANT_READ) {
    702 	    event_enable_read(ciphertext_fd, tlsp_ciphertext_event,
    703 			      (void *) state);
    704 	    state->ssl_last_err = SSL_ERROR_WANT_READ;
    705 	}
    706 	event_request_timer(tlsp_ciphertext_event, (void *) state,
    707 			    state->timeout);
    708 	return (TLSP_STAT_OK);
    709 
    710 	/*
    711 	 * Some error. Self-destruct. This automagically cleans up all
    712 	 * pending read/write and timeout event requests, making state a
    713 	 * dangling pointer.
    714 	 */
    715     case SSL_ERROR_SSL:
    716 	tls_print_errors();
    717 	/* FALLTHROUGH */
    718     default:
    719 
    720 	/*
    721 	 * Allow buffered-up plaintext output to trickle out. Permanently
    722 	 * disable read/write activity on the ciphertext stream, so that this
    723 	 * function will no longer be called. Keep the ciphertext stream
    724 	 * timer alive as a safety mechanism for the case that the plaintext
    725 	 * pseudothreads get stuck. Return into tlsp_strategy(), which will
    726 	 * enable plaintext write events.
    727 	 */
    728 #define TLSP_CAN_TRICKLE_OUT_PLAINTEXT(buf) \
    729 	((buf) && !NBBIO_ERROR_FLAGS(buf) && NBBIO_WRITE_PEND(buf))
    730 
    731 	if (TLSP_CAN_TRICKLE_OUT_PLAINTEXT(state->plaintext_buf)) {
    732 	    event_disable_readwrite(ciphertext_fd);
    733 	    event_request_timer(tlsp_ciphertext_event, (void *) state,
    734 				state->timeout);
    735 	    state->flags |= TLSP_FLAG_NO_MORE_CIPHERTEXT_IO;
    736 	    return (TLSP_STAT_OK);
    737 	}
    738 
    739 	/*
    740 	 * Report a generic failure only if a more specific failure wasn't
    741 	 * already reported.
    742 	 */
    743 #ifdef USE_TLSRPT
    744 	if (state->is_server_role == 0
    745 	    && (state->flags & TLSP_FLAG_DO_HANDSHAKE)
    746 	    && state->client_start_props->tlsrpt)
    747 	    trw_report_failure(state->client_start_props->tlsrpt,
    748 			       TLSRPT_VALIDATION_FAILURE,
    749 			        /* additional_info= */ (char *) 0,
    750 			       "tls-handshake-failure");
    751 #endif
    752 	tlsp_state_free(state);
    753 	return (TLSP_STAT_ERR);
    754     }
    755 }
    756 
    757 /* tlsp_post_handshake - post-handshake processing */
    758 
    759 static int tlsp_post_handshake(TLSP_STATE *state)
    760 {
    761 
    762     /*
    763      * Do not assume that tls_server_post_accept() and
    764      * tls_client_post_connect() will always succeed.
    765      */
    766     if (state->is_server_role)
    767 	state->tls_context = tls_server_post_accept(state->tls_context);
    768     else
    769 	state->tls_context = tls_client_post_connect(state->tls_context,
    770 						 state->client_start_props);
    771     if (state->tls_context == 0) {
    772 	tlsp_state_free(state);
    773 	return (TLSP_STAT_ERR);
    774     }
    775 
    776     /*
    777      * Report TLS handshake results to the tlsproxy client.
    778      *
    779      * Security: this sends internal data over the same local plaintext stream
    780      * that will also be used for sending decrypted remote content from an
    781      * arbitrary remote peer. For this reason we enable decrypted I/O only
    782      * after reporting the TLS handshake results. The Postfix attribute
    783      * protocol is robust enough that an attacker cannot append content.
    784      */
    785     if ((state->req_flags & TLS_PROXY_FLAG_SEND_CONTEXT) != 0
    786 	&& (attr_print(state->plaintext_stream, ATTR_FLAG_NONE,
    787 		       SEND_ATTR_FUNC(tls_proxy_context_print,
    788 				      (void *) state->tls_context),
    789 		       ATTR_TYPE_END) != 0
    790 	    || vstream_fflush(state->plaintext_stream) != 0)) {
    791 	msg_warn("cannot send TLS context: %m");
    792 	tlsp_state_free(state);
    793 	return (TLSP_STAT_ERR);
    794     }
    795 
    796     /*
    797      * Initialize plaintext-related session state. Once we have this behind
    798      * us, the TLSP_STATE destructor will automagically clean up requests for
    799      * plaintext read/write/timeout events, which makes error recovery
    800      * easier.
    801      */
    802     state->plaintext_buf =
    803 	nbbio_create(vstream_fileno(state->plaintext_stream),
    804 		     VSTREAM_BUFSIZE, state->server_id,
    805 		     tlsp_plaintext_event,
    806 		     (void *) state);
    807     return (TLSP_STAT_OK);
    808 }
    809 
    810 /* tlsp_strategy - decide what to read or write next. */
    811 
    812 static void tlsp_strategy(TLSP_STATE *state)
    813 {
    814     TLS_SESS_STATE *tls_context = state->tls_context;
    815     NBBIO  *plaintext_buf;
    816     int     ssl_stat;
    817     int     ssl_read_err;
    818     int     ssl_write_err;
    819     int     handshake_err;
    820 
    821     /*
    822      * This function is called after every ciphertext or plaintext event, to
    823      * schedule new ciphertext or plaintext I/O.
    824      */
    825 
    826     /*
    827      * Try to make an SSL I/O request. If this fails with SSL_ERROR_WANT_READ
    828      * or SSL_ERROR_WANT_WRITE, enable ciphertext read or write events, and
    829      * retry the SSL I/O request in a later tlsp_strategy() call.
    830      */
    831     if ((state->flags & TLSP_FLAG_NO_MORE_CIPHERTEXT_IO) == 0) {
    832 
    833 	/*
    834 	 * Do not enable plain-text I/O before completing the TLS handshake.
    835 	 * Otherwise the remote peer can prepend plaintext to the optional
    836 	 * TLS_SESS_STATE object.
    837 	 */
    838 	if (state->flags & TLSP_FLAG_DO_HANDSHAKE) {
    839 	    state->timeout = state->handshake_timeout;
    840 	    ERR_clear_error();
    841 	    if (state->is_server_role)
    842 		ssl_stat = SSL_accept(tls_context->con);
    843 	    else
    844 		ssl_stat = SSL_connect(tls_context->con);
    845 	    if (ssl_stat != 1) {
    846 		handshake_err = SSL_get_error(tls_context->con, ssl_stat);
    847 		tlsp_eval_tls_error(state, handshake_err);
    848 		/* At this point, state could be a dangling pointer. */
    849 		return;
    850 	    }
    851 	    state->flags &= ~TLSP_FLAG_DO_HANDSHAKE;
    852 	    state->timeout = state->session_timeout;
    853 	    if (tlsp_post_handshake(state) != TLSP_STAT_OK) {
    854 		/* At this point, state is a dangling pointer. */
    855 		return;
    856 	    }
    857 	}
    858 
    859 	/*
    860 	 * Shutdown and self-destruct after NBBIO error. This automagically
    861 	 * cleans up all pending read/write and timeout event requests.
    862 	 * Before shutting down TLS, we stop all plain-text I/O events but
    863 	 * keep the NBBIO error flags.
    864 	 */
    865 	plaintext_buf = state->plaintext_buf;
    866 	if (NBBIO_ERROR_FLAGS(plaintext_buf)) {
    867 	    if (NBBIO_ACTIVE_FLAGS(plaintext_buf))
    868 		nbbio_disable_readwrite(state->plaintext_buf);
    869 	    ERR_clear_error();
    870 	    if (!SSL_in_init(tls_context->con)
    871 		&& (ssl_stat = SSL_shutdown(tls_context->con)) < 0) {
    872 		handshake_err = SSL_get_error(tls_context->con, ssl_stat);
    873 		tlsp_eval_tls_error(state, handshake_err);
    874 		/* At this point, state could be a dangling pointer. */
    875 		return;
    876 	    }
    877 	    tlsp_state_free(state);
    878 	    return;
    879 	}
    880 
    881 	/*
    882 	 * Try to move data from the plaintext input buffer to the TLS
    883 	 * engine.
    884 	 *
    885 	 * XXX We're supposed to repeat the exact same SSL_write() call
    886 	 * arguments after an SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE
    887 	 * result. Rumor has it that this is because each SSL_write() call
    888 	 * reads from the buffer incrementally, and returns > 0 only after
    889 	 * the final byte is processed. Rumor also has it that setting
    890 	 * SSL_MODE_ENABLE_PARTIAL_WRITE and
    891 	 * SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER voids this requirement, and
    892 	 * that repeating the request with an increased request size is OK.
    893 	 * Unfortunately all this is not or poorly documented, and one has to
    894 	 * rely on statements from OpenSSL developers in public mailing
    895 	 * archives.
    896 	 */
    897 	ssl_write_err = SSL_ERROR_NONE;
    898 	while (NBBIO_READ_PEND(plaintext_buf) > 0) {
    899 	    ERR_clear_error();
    900 	    ssl_stat = SSL_write(tls_context->con, NBBIO_READ_BUF(plaintext_buf),
    901 				 NBBIO_READ_PEND(plaintext_buf));
    902 	    ssl_write_err = SSL_get_error(tls_context->con, ssl_stat);
    903 	    if (ssl_write_err != SSL_ERROR_NONE)
    904 		break;
    905 	    /* Allow the plaintext pseudothread to read more data. */
    906 	    NBBIO_READ_PEND(plaintext_buf) -= ssl_stat;
    907 	    if (NBBIO_READ_PEND(plaintext_buf) > 0)
    908 		memmove(NBBIO_READ_BUF(plaintext_buf),
    909 			NBBIO_READ_BUF(plaintext_buf) + ssl_stat,
    910 			NBBIO_READ_PEND(plaintext_buf));
    911 	}
    912 
    913 	/*
    914 	 * Try to move data from the TLS engine to the plaintext output
    915 	 * buffer. Note: data may arrive as a side effect of calling
    916 	 * SSL_write(), therefore we call SSL_read() after calling
    917 	 * SSL_write().
    918 	 *
    919 	 * XXX We're supposed to repeat the exact same SSL_read() call arguments
    920 	 * after an SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE result. This
    921 	 * supposedly means that our plaintext writer must not memmove() the
    922 	 * plaintext output buffer until after the SSL_read() call succeeds.
    923 	 * For now I'll ignore this, because 1) SSL_read() is documented to
    924 	 * return the bytes available, instead of returning > 0 only after
    925 	 * the entire buffer is processed like SSL_write() does; and 2) there
    926 	 * is no "read" equivalent of the SSL_R_BAD_WRITE_RETRY,
    927 	 * SSL_MODE_ENABLE_PARTIAL_WRITE or
    928 	 * SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER features.
    929 	 */
    930 	ssl_read_err = SSL_ERROR_NONE;
    931 	while (NBBIO_WRITE_PEND(state->plaintext_buf) < NBBIO_BUFSIZE(plaintext_buf)) {
    932 	    ERR_clear_error();
    933 	    ssl_stat = SSL_read(tls_context->con,
    934 				NBBIO_WRITE_BUF(plaintext_buf)
    935 				+ NBBIO_WRITE_PEND(state->plaintext_buf),
    936 				NBBIO_BUFSIZE(plaintext_buf)
    937 				- NBBIO_WRITE_PEND(state->plaintext_buf));
    938 	    ssl_read_err = SSL_get_error(tls_context->con, ssl_stat);
    939 	    if (ssl_read_err != SSL_ERROR_NONE)
    940 		break;
    941 	    NBBIO_WRITE_PEND(plaintext_buf) += ssl_stat;
    942 	}
    943 
    944 	/*
    945 	 * Try to enable/disable ciphertext read/write events. If SSL_write()
    946 	 * was satisfied, see if SSL_read() wants to do some work. In case of
    947 	 * an unrecoverable error, this automagically destroys the session
    948 	 * state after cleaning up all pending read/write and timeout event
    949 	 * requests.
    950 	 */
    951 	if (tlsp_eval_tls_error(state, ssl_write_err != SSL_ERROR_NONE ?
    952 				ssl_write_err : ssl_read_err) < 0)
    953 	    /* At this point, state is a dangling pointer. */
    954 	    return;
    955     }
    956 
    957     /*
    958      * Destroy state when the ciphertext I/O was permanently disabled and we
    959      * can no longer trickle out plaintext.
    960      */
    961     else {
    962 	plaintext_buf = state->plaintext_buf;
    963 	if (!TLSP_CAN_TRICKLE_OUT_PLAINTEXT(plaintext_buf)) {
    964 	    tlsp_state_free(state);
    965 	    return;
    966 	}
    967     }
    968 
    969     /*
    970      * Try to enable/disable plaintext read/write events. Basically, if we
    971      * have nothing to write to the plaintext stream, see if there is
    972      * something to read. If the write buffer is empty and the read buffer is
    973      * full, suspend plaintext I/O until conditions change (but keep the
    974      * timer active, as a safety mechanism in case ciphertext I/O gets
    975      * stuck).
    976      *
    977      * XXX In theory, if the ciphertext peer keeps writing fast enough then we
    978      * would never read from the plaintext stream and cause the latter to
    979      * block. In practice, postscreen(8) limits the number of client
    980      * commands, and thus postscreen(8)'s output will fit in a kernel buffer.
    981      * A remote SMTP server is not supposed to flood the local SMTP client
    982      * with massive replies; if it does, then the local SMTP client should
    983      * deal with it.
    984      */
    985     if (NBBIO_WRITE_PEND(plaintext_buf) > 0) {
    986 	if (NBBIO_ACTIVE_FLAGS(plaintext_buf) & NBBIO_FLAG_READ)
    987 	    nbbio_disable_readwrite(plaintext_buf);
    988 	nbbio_enable_write(plaintext_buf, state->timeout);
    989     } else if (NBBIO_READ_PEND(plaintext_buf) < NBBIO_BUFSIZE(plaintext_buf)) {
    990 	if (NBBIO_ACTIVE_FLAGS(plaintext_buf) & NBBIO_FLAG_WRITE)
    991 	    nbbio_disable_readwrite(plaintext_buf);
    992 	nbbio_enable_read(plaintext_buf, state->timeout);
    993     } else {
    994 	if (NBBIO_ACTIVE_FLAGS(plaintext_buf))
    995 	    nbbio_slumber(plaintext_buf, state->timeout);
    996     }
    997 }
    998 
    999 /* tlsp_plaintext_event - plaintext was read/written */
   1000 
   1001 static void tlsp_plaintext_event(int event, void *context)
   1002 {
   1003     TLSP_STATE *state = (TLSP_STATE *) context;
   1004 
   1005     /*
   1006      * Safety alert: the plaintext pseudothreads have "slumbered" for too
   1007      * long (see code above). This means that the ciphertext pseudothreads
   1008      * are stuck.
   1009      */
   1010     if ((NBBIO_ERROR_FLAGS(state->plaintext_buf) & NBBIO_FLAG_TIMEOUT) != 0
   1011 	&& NBBIO_ACTIVE_FLAGS(state->plaintext_buf) == 0)
   1012 	msg_warn("deadlock on ciphertext stream for %s", state->remote_endpt);
   1013 
   1014     /*
   1015      * This is easy, because the NBBIO layer has already done the event
   1016      * decoding and plaintext I/O for us. All we need to do is decide if we
   1017      * want to read or write more plaintext.
   1018      */
   1019     tlsp_strategy(state);
   1020     /* At this point, state could be a dangling pointer. */
   1021 }
   1022 
   1023 /* tlsp_ciphertext_event - ciphertext is ready to read/write */
   1024 
   1025 static void tlsp_ciphertext_event(int event, void *context)
   1026 {
   1027     TLSP_STATE *state = (TLSP_STATE *) context;
   1028 
   1029     /*
   1030      * Without a TLS equivalent of the NBBIO layer, we must decode the events
   1031      * ourselves and do the ciphertext I/O. Then, we can decide if we want to
   1032      * read or write more ciphertext.
   1033      */
   1034     if (event == EVENT_READ || event == EVENT_WRITE) {
   1035 	tlsp_strategy(state);
   1036 	/* At this point, state could be a dangling pointer. */
   1037     } else {
   1038 	if (event == EVENT_TIME && state->ssl_last_err == SSL_ERROR_NONE)
   1039 	    msg_warn("deadlock on plaintext stream for %s",
   1040 		     state->remote_endpt);
   1041 	else
   1042 	    msg_warn("ciphertext read/write %s for %s",
   1043 		     event == EVENT_TIME ? "timeout" : "error",
   1044 		     state->remote_endpt);
   1045 	tlsp_state_free(state);
   1046     }
   1047 }
   1048 
   1049 /* tlsp_client_start_pre_handshake - turn on TLS or force disconnect */
   1050 
   1051 static int tlsp_client_start_pre_handshake(TLSP_STATE *state)
   1052 {
   1053     state->client_start_props->ctx = state->appl_state;
   1054     state->client_start_props->fd = state->ciphertext_fd;
   1055     state->tls_context = tls_client_start(state->client_start_props);
   1056     if (state->tls_context != 0)
   1057 	return (TLSP_STAT_OK);
   1058 
   1059     tlsp_state_free(state);
   1060     return (TLSP_STAT_ERR);
   1061 }
   1062 
   1063 /* tlsp_server_start_pre_handshake - turn on TLS or force disconnect */
   1064 
   1065 static int tlsp_server_start_pre_handshake(TLSP_STATE *state)
   1066 {
   1067     TLS_SERVER_START_PROPS props;
   1068     static char *cipher_grade;
   1069     static VSTRING *cipher_exclusions;
   1070 
   1071     /*
   1072      * The code in this routine is pasted literally from smtpd(8). I am not
   1073      * going to sanitize this because doing so surely will break things in
   1074      * unexpected ways.
   1075      */
   1076 
   1077     /*
   1078      * Perform the before-handshake portion of per-session initialization.
   1079      * Pass a null VSTREAM to indicate that this program will do the
   1080      * ciphertext I/O, not libtls.
   1081      *
   1082      * The cipher grade and exclusions don't change between sessions. Compute
   1083      * just once and cache.
   1084      */
   1085 #define ADD_EXCLUDE(vstr, str) \
   1086     do { \
   1087 	if (*(str)) \
   1088 	    vstring_sprintf_append((vstr), "%s%s", \
   1089 				   VSTRING_LEN(vstr) ? " " : "", (str)); \
   1090     } while (0)
   1091 
   1092     if (cipher_grade == 0) {
   1093 	cipher_grade =
   1094 	    var_tlsp_enforce_tls ? var_tlsp_tls_mand_ciph : var_tlsp_tls_ciph;
   1095 	cipher_exclusions = vstring_alloc(10);
   1096 	ADD_EXCLUDE(cipher_exclusions, var_tlsp_tls_excl_ciph);
   1097 	if (var_tlsp_enforce_tls)
   1098 	    ADD_EXCLUDE(cipher_exclusions, var_tlsp_tls_mand_excl);
   1099 	if (ask_client_cert)
   1100 	    ADD_EXCLUDE(cipher_exclusions, "aNULL");
   1101     }
   1102     state->tls_context =
   1103 	TLS_SERVER_START(&props,
   1104 			 ctx = tlsp_server_ctx,
   1105 			 stream = (VSTREAM *) 0,/* unused */
   1106 			 fd = state->ciphertext_fd,
   1107 			 timeout = 0,		/* unused */
   1108 			 requirecert = (var_tlsp_tls_req_ccert
   1109 					&& var_tlsp_enforce_tls),
   1110 			 enable_rpk = var_tlsp_tls_enable_rpk,
   1111 			 serverid = state->server_id,
   1112 			 namaddr = state->remote_endpt,
   1113 			 cipher_grade = cipher_grade,
   1114 			 cipher_exclusions = STR(cipher_exclusions),
   1115 			 mdalg = var_tlsp_tls_fpt_dgst);
   1116 
   1117     if (state->tls_context == 0) {
   1118 	tlsp_state_free(state);
   1119 	return (TLSP_STAT_ERR);
   1120     }
   1121 
   1122     /*
   1123      * XXX Do we care about TLS session rate limits? Good postscreen(8)
   1124      * clients will occasionally require the tlsproxy to renew their
   1125      * allowlist status, but bad clients hammering the server can suck up
   1126      * lots of CPU cycles. Per-client concurrency limits in postscreen(8)
   1127      * will divert only naive security "researchers".
   1128      */
   1129     return (TLSP_STAT_OK);
   1130 }
   1131 
   1132  /*
   1133   * From here on down is low-level code that sets up the plumbing before
   1134   * passing control to the TLS engine above.
   1135   */
   1136 
   1137 /* tlsp_request_read_event - pre-handshake event boiler plate */
   1138 
   1139 static void tlsp_request_read_event(int fd, EVENT_NOTIFY_FN handler,
   1140 				            int timeout, void *context)
   1141 {
   1142     event_enable_read(fd, handler, context);
   1143     event_request_timer(handler, context, timeout);
   1144 }
   1145 
   1146 /* tlsp_accept_event - pre-handshake event boiler plate */
   1147 
   1148 static void tlsp_accept_event(int event, EVENT_NOTIFY_FN handler,
   1149 			              void *context)
   1150 {
   1151     if (event != EVENT_TIME)
   1152 	event_cancel_timer(handler, context);
   1153     else
   1154 	errno = ETIMEDOUT;
   1155     /* tlsp_state_free() disables pre-handshake plaintext I/O events. */
   1156 }
   1157 
   1158 /* tlsp_get_fd_event - receive final connection hand-off information */
   1159 
   1160 static void tlsp_get_fd_event(int event, void *context)
   1161 {
   1162     const char *myname = "tlsp_get_fd_event";
   1163     TLSP_STATE *state = (TLSP_STATE *) context;
   1164     int     plaintext_fd = vstream_fileno(state->plaintext_stream);
   1165     int     status;
   1166 
   1167     /*
   1168      * At this point we still manually manage plaintext read/write/timeout
   1169      * events. Disable I/O events on the plaintext stream until the TLS
   1170      * handshake is completed. Every code path must either destroy state, or
   1171      * request the next event, otherwise we have a file and memory leak.
   1172      */
   1173     tlsp_accept_event(event, tlsp_get_fd_event, (void *) state);
   1174     event_disable_readwrite(plaintext_fd);
   1175 
   1176     if (event != EVENT_READ
   1177 	|| (state->ciphertext_fd = LOCAL_RECV_FD(plaintext_fd)) < 0) {
   1178 	msg_warn("%s: receive remote SMTP peer file descriptor: %m", myname);
   1179 	tlsp_state_free(state);
   1180 	return;
   1181     }
   1182 
   1183     /*
   1184      * This is a bit early, to ensure that timer events for this file handle
   1185      * are guaranteed to be turned off by the TLSP_STATE destructor.
   1186      */
   1187     state->ciphertext_timer = tlsp_ciphertext_event;
   1188     non_blocking(state->ciphertext_fd, NON_BLOCKING);
   1189 
   1190     /*
   1191      * Perform the TLS layer before-handshake initialization. We perform the
   1192      * remainder after the actual TLS handshake completes.
   1193      */
   1194     if (state->is_server_role)
   1195 	status = tlsp_server_start_pre_handshake(state);
   1196     else
   1197 	status = tlsp_client_start_pre_handshake(state);
   1198     if (status != TLSP_STAT_OK)
   1199 	/* At this point, state is a dangling pointer. */
   1200 	return;
   1201 
   1202     /*
   1203      * Trigger the initial proxy server I/Os.
   1204      */
   1205     tlsp_strategy(state);
   1206     /* At this point, state could be a dangling pointer. */
   1207 }
   1208 
   1209 /* tlsp_config_diff - report server-client config differences */
   1210 
   1211 static void tlsp_log_config_diff(const char *server_cfg, const char *client_cfg)
   1212 {
   1213     VSTRING *diff_summary = vstring_alloc(100);
   1214     char   *saved_server = mystrdup(server_cfg);
   1215     char   *saved_client = mystrdup(client_cfg);
   1216     char   *server_field;
   1217     char   *client_field;
   1218     char   *server_next;
   1219     char   *client_next;
   1220 
   1221     /*
   1222      * Not using argv_split(), because it would treat multiple consecutive
   1223      * newline characters as one.
   1224      */
   1225     for (server_field = saved_server, client_field = saved_client;
   1226 	 server_field && client_field;
   1227 	 server_field = server_next, client_field = client_next) {
   1228 	server_next = split_at(server_field, '\n');
   1229 	client_next = split_at(client_field, '\n');
   1230 	if (strcmp(server_field, client_field) != 0) {
   1231 	    if (LEN(diff_summary) > 0)
   1232 		vstring_sprintf_append(diff_summary, "; ");
   1233 	    vstring_sprintf_append(diff_summary,
   1234 				   "(server) '%s' != (client) '%s'",
   1235 				   server_field, client_field);
   1236 	}
   1237     }
   1238     msg_warn("%s", STR(diff_summary));
   1239 
   1240     vstring_free(diff_summary);
   1241     myfree(saved_client);
   1242     myfree(saved_server);
   1243 }
   1244 
   1245 /* tlsp_client_init - initialize a TLS client engine */
   1246 
   1247 static TLS_APPL_STATE *tlsp_client_init(TLS_CLIENT_PARAMS *tls_params,
   1248 				          TLS_CLIENT_INIT_PROPS *init_props)
   1249 {
   1250     TLS_APPL_STATE *appl_state;
   1251     VSTRING *param_buf;
   1252     char   *param_key;
   1253     VSTRING *init_buf;
   1254     char   *init_key;
   1255     int     log_hints = 0;
   1256 
   1257     /*
   1258      * Use one TLS_APPL_STATE object for all requests that specify the same
   1259      * TLS_CLIENT_INIT_PROPS. Each TLS_APPL_STATE owns an SSL_CTX, which is
   1260      * expensive to create. Bug: TLS_CLIENT_PARAMS are not used when creating
   1261      * a TLS_APPL_STATE instance.
   1262      *
   1263      * First, compute the TLS_APPL_STATE cache lookup key. Save a copy of the
   1264      * pre-jail request TLS_CLIENT_PARAMS and TLSPROXY_CLIENT_INIT_PROPS
   1265      * settings, so that we can detect post-jail requests that do not match.
   1266      */
   1267     param_buf = vstring_alloc(100);
   1268     param_key = tls_proxy_client_param_serialize(attr_print_plain, param_buf,
   1269 						 tls_params);
   1270     init_buf = vstring_alloc(100);
   1271     init_key = tls_proxy_client_init_serialize(attr_print_plain, init_buf,
   1272 					       init_props);
   1273 #define TLSP_CLIENT_INIT_RETURN(retval) do { \
   1274 	vstring_free(init_buf); \
   1275 	vstring_free(param_buf); \
   1276 	return (retval); \
   1277     } while (0)
   1278 
   1279     if (tlsp_pre_jail_done == 0) {
   1280 	if (tlsp_pre_jail_client_param_key == 0
   1281 	    || tlsp_pre_jail_client_init_key == 0) {
   1282 	    tlsp_pre_jail_client_param_key = mystrdup(param_key);
   1283 	    tlsp_pre_jail_client_init_key = mystrdup(init_key);
   1284 	} else if (strcmp(tlsp_pre_jail_client_param_key, param_key) != 0
   1285 		   || strcmp(tlsp_pre_jail_client_init_key, init_key) != 0) {
   1286 	    msg_panic("tlsp_client_init: too many pre-jail calls");
   1287 	}
   1288     }
   1289 
   1290     /*
   1291      * Log a warning if a post-jail request uses unexpected TLS_CLIENT_PARAMS
   1292      * settings. Bug: TLS_CLIENT_PARAMS settings are not used when creating a
   1293      * TLS_APPL_STATE instance; this makes a mismatch of TLS_CLIENT_PARAMS
   1294      * settings problematic.
   1295      */
   1296     else if (tlsp_pre_jail_client_param_key == 0
   1297 	     || tlsp_pre_jail_client_init_key == 0) {
   1298 	msg_warn("TLS client role is disabled by configuration");
   1299 	TLSP_CLIENT_INIT_RETURN(0);
   1300     } else if (!been_here_fixed(tlsp_params_mismatch_filter, param_key)
   1301 	       && strcmp(tlsp_pre_jail_client_param_key, param_key) != 0) {
   1302 	msg_warn("request from tlsproxy client with unexpected settings");
   1303 	tlsp_log_config_diff(tlsp_pre_jail_client_param_key, param_key);
   1304 	log_hints = 1;
   1305     }
   1306 
   1307     /*
   1308      * Look up the cached TLS_APPL_STATE for this tls_client_init request.
   1309      */
   1310     if ((appl_state = (TLS_APPL_STATE *)
   1311 	 htable_find(tlsp_client_app_cache, init_key)) == 0) {
   1312 
   1313 	/*
   1314 	 * Before creating a TLS_APPL_STATE instance, log a warning if a
   1315 	 * post-jail request differs from the saved pre-jail request AND the
   1316 	 * post-jail request specifies file/directory pathname arguments.
   1317 	 * Unexpected requests containing pathnames are problematic after
   1318 	 * chroot (pathname resolution) and after dropping privileges (key
   1319 	 * files must be root read-only). Unexpected requests are not a
   1320 	 * problem as long as they contain no pathnames (for example a
   1321 	 * tls_loglevel change).
   1322 	 *
   1323 	 * We could eliminate some of this complication by adding code that
   1324 	 * opens a cert/key lookup table at pre-jail time, and by reading
   1325 	 * cert/key info on-the-fly from that table. But then all requests
   1326 	 * would still have to specify the same table.
   1327 	 */
   1328 #define NOT_EMPTY(x) ((x) && *(x))
   1329 
   1330 	if (tlsp_pre_jail_done
   1331 	    && strcmp(tlsp_pre_jail_client_init_key, init_key) != 0
   1332 	    && (NOT_EMPTY(init_props->chain_files)
   1333 		|| NOT_EMPTY(init_props->cert_file)
   1334 		|| NOT_EMPTY(init_props->key_file)
   1335 		|| NOT_EMPTY(init_props->dcert_file)
   1336 		|| NOT_EMPTY(init_props->dkey_file)
   1337 		|| NOT_EMPTY(init_props->eccert_file)
   1338 		|| NOT_EMPTY(init_props->eckey_file)
   1339 		|| NOT_EMPTY(init_props->CAfile)
   1340 		|| NOT_EMPTY(init_props->CApath))) {
   1341 	    msg_warn("request from tlsproxy client with unexpected settings");
   1342 	    tlsp_log_config_diff(tlsp_pre_jail_client_init_key, init_key);
   1343 	    log_hints = 1;
   1344 	}
   1345     }
   1346     if (log_hints)
   1347 	msg_warn("to avoid this warning, 1) identify the tlsproxy "
   1348 		 "client that is making this request, 2) configure "
   1349 		 "a custom tlsproxy service with settings that "
   1350 		 "match that tlsproxy client, and 3) configure "
   1351 		 "that tlsproxy client with a tlsproxy_service_name "
   1352 		 "setting that resolves to that custom tlsproxy "
   1353 		 "service");
   1354 
   1355     /*
   1356      * TLS_APPL_STATE creation may fail when a post-jail request specifies
   1357      * unexpected cert/key information, but that is OK because we already
   1358      * logged a warning with configuration suggestions.
   1359      */
   1360     if (appl_state == 0
   1361 	&& (appl_state = tls_client_init(init_props)) != 0) {
   1362 	(void) htable_enter(tlsp_client_app_cache, init_key,
   1363 			    (void *) appl_state);
   1364 
   1365 	/*
   1366 	 * To maintain sanity, allow partial SSL_write() operations, and
   1367 	 * allow SSL_write() buffer pointers to change after a WANT_READ or
   1368 	 * WANT_WRITE result. This is based on OpenSSL developers talking on
   1369 	 * a mailing list, but is not supported by documentation. If this
   1370 	 * code stops working then no-one can be held responsible.
   1371 	 */
   1372 	SSL_CTX_set_mode(appl_state->ssl_ctx,
   1373 			 SSL_MODE_ENABLE_PARTIAL_WRITE
   1374 			 | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
   1375     }
   1376     TLSP_CLIENT_INIT_RETURN(appl_state);
   1377 }
   1378 
   1379 /* tlsp_close_event - pre-handshake plaintext-client close event */
   1380 
   1381 static void tlsp_close_event(int event, void *context)
   1382 {
   1383     TLSP_STATE *state = (TLSP_STATE *) context;
   1384 
   1385     tlsp_accept_event(event, tlsp_close_event, (void *) state);
   1386     tlsp_state_free(state);
   1387 }
   1388 
   1389 /* tlsp_get_request_event - receive initial hand-off info */
   1390 
   1391 static void tlsp_get_request_event(int event, void *context)
   1392 {
   1393     const char *myname = "tlsp_get_request_event";
   1394     TLSP_STATE *state = (TLSP_STATE *) context;
   1395     VSTREAM *plaintext_stream = state->plaintext_stream;
   1396     int     plaintext_fd = vstream_fileno(plaintext_stream);
   1397     static VSTRING *remote_endpt;
   1398     static VSTRING *server_id;
   1399     int     req_flags;
   1400     int     handshake_timeout;
   1401     int     session_timeout;
   1402     int     ready = 0;
   1403 
   1404     /*
   1405      * At this point we still manually manage plaintext read/write/timeout
   1406      * events. Every code path must either destroy state or request the next
   1407      * event, otherwise this pseudo-thread is idle until the client goes
   1408      * away.
   1409      */
   1410     tlsp_accept_event(event, tlsp_get_request_event, (void *) state);
   1411 
   1412     /*
   1413      * One-time initialization.
   1414      */
   1415     if (remote_endpt == 0) {
   1416 	remote_endpt = vstring_alloc(10);
   1417 	server_id = vstring_alloc(10);
   1418     }
   1419 
   1420     /*
   1421      * Receive the initial request attributes. Receive the remainder after we
   1422      * figure out what role we are expected to play.
   1423      *
   1424      * The tlsproxy server does not enforce per-request read/write deadlines or
   1425      * minimal data rates. Instead, the tlsproxy server relies on the
   1426      * tlsproxy client to enforce these context-dependent limits. When a
   1427      * tlsproxy client decides to time out, it will close its end of the
   1428      * tlsproxy stream, and the tlsproxy server will handle that immediately.
   1429      */
   1430     if (event != EVENT_READ
   1431 	|| attr_scan(plaintext_stream, ATTR_FLAG_STRICT,
   1432 		     RECV_ATTR_STR(TLS_ATTR_REMOTE_ENDPT, remote_endpt),
   1433 		     RECV_ATTR_INT(TLS_ATTR_FLAGS, &req_flags),
   1434 		     RECV_ATTR_INT(TLS_ATTR_TIMEOUT, &handshake_timeout),
   1435 		     RECV_ATTR_INT(TLS_ATTR_TIMEOUT, &session_timeout),
   1436 		     RECV_ATTR_STR(TLS_ATTR_SERVERID, server_id),
   1437 		     ATTR_TYPE_END) != 5) {
   1438 	msg_warn("%s: receive request attributes: %m", myname);
   1439 	tlsp_state_free(state);
   1440 	return;
   1441     }
   1442 
   1443     /*
   1444      * XXX We use the same fixed timeout throughout the entire session for
   1445      * both plaintext and ciphertext communication. This timeout is just a
   1446      * safety feature; the real timeout will be enforced by our plaintext
   1447      * peer (except during TLS the handshake, when we intentionally disable
   1448      * plaintext I/O).
   1449      */
   1450     state->remote_endpt = mystrdup(STR(remote_endpt));
   1451     state->server_id = mystrdup(STR(server_id));
   1452     msg_info("CONNECT %s %s",
   1453 	     (req_flags & TLS_PROXY_FLAG_ROLE_SERVER) ? "from" :
   1454 	     (req_flags & TLS_PROXY_FLAG_ROLE_CLIENT) ? "to" :
   1455 	     "(bogus_direction)", state->remote_endpt);
   1456     state->req_flags = req_flags;
   1457     /* state->is_server_role is set below. */
   1458     state->handshake_timeout = handshake_timeout;
   1459     state->session_timeout = session_timeout + 10;	/* XXX */
   1460 
   1461     /*
   1462      * Receive the TLS preferences now, to reduce the number of protocol
   1463      * roundtrips.
   1464      */
   1465     switch (req_flags & (TLS_PROXY_FLAG_ROLE_CLIENT | TLS_PROXY_FLAG_ROLE_SERVER)) {
   1466     case TLS_PROXY_FLAG_ROLE_CLIENT:
   1467 	state->is_server_role = 0;
   1468 	if (attr_scan(plaintext_stream, ATTR_FLAG_STRICT,
   1469 		      RECV_ATTR_FUNC(tls_proxy_client_param_scan,
   1470 				     (void *) &state->tls_params),
   1471 		      RECV_ATTR_FUNC(tls_proxy_client_init_scan,
   1472 				     (void *) &state->client_init_props),
   1473 		      RECV_ATTR_FUNC(tls_proxy_client_start_scan,
   1474 				     (void *) &state->client_start_props),
   1475 		      ATTR_TYPE_END) != 3) {
   1476 	    msg_warn("%s: receive client TLS settings: %m", myname);
   1477 	    tlsp_state_free(state);
   1478 	    return;
   1479 	}
   1480 	state->appl_state = tlsp_client_init(state->tls_params,
   1481 					     state->client_init_props);
   1482 	ready = state->appl_state != 0;
   1483 	break;
   1484     case TLS_PROXY_FLAG_ROLE_SERVER:
   1485 	state->is_server_role = 1;
   1486 	ready = (tlsp_server_ctx != 0);
   1487 	if (server_role_disabled)
   1488 	    msg_warn("%s", server_role_disabled);
   1489 	break;
   1490     default:
   1491 	state->is_server_role = 0;
   1492 	msg_warn("%s: bad request flags: 0x%x", myname, req_flags);
   1493 	ready = 0;
   1494     }
   1495 
   1496     /*
   1497      * For portability we must send some data, after receiving the request
   1498      * attributes and before receiving the remote file descriptor.
   1499      *
   1500      * If the requested TLS engine is unavailable, hang up after making sure
   1501      * that the plaintext peer has received our "sorry" indication.
   1502      */
   1503     if (attr_print(plaintext_stream, ATTR_FLAG_NONE,
   1504 		   SEND_ATTR_INT(MAIL_ATTR_STATUS, ready),
   1505 		   ATTR_TYPE_END) != 0
   1506 	|| vstream_fflush(plaintext_stream) != 0
   1507 	|| ready == 0) {
   1508 	tlsp_request_read_event(plaintext_fd, tlsp_close_event,
   1509 				TLSP_INIT_TIMEOUT, (void *) state);
   1510 	return;
   1511     } else {
   1512 	state->flags |= TLSP_FLAG_DO_HANDSHAKE;
   1513 	tlsp_request_read_event(plaintext_fd, tlsp_get_fd_event,
   1514 				TLSP_INIT_TIMEOUT, (void *) state);
   1515 	return;
   1516     }
   1517 }
   1518 
   1519 /* tlsp_service - handle new client connection */
   1520 
   1521 static void tlsp_service(VSTREAM *plaintext_stream,
   1522 			         char *service,
   1523 			         char **argv)
   1524 {
   1525     TLSP_STATE *state;
   1526     int     plaintext_fd = vstream_fileno(plaintext_stream);
   1527 
   1528     /*
   1529      * Sanity check. This service takes no command-line arguments.
   1530      */
   1531     if (argv[0])
   1532 	msg_fatal("unexpected command-line argument: %s", argv[0]);
   1533 
   1534     /*
   1535      * This program handles multiple connections, so it must not block. We
   1536      * use event-driven code for all operations that introduce latency.
   1537      * Except that attribute lists are sent/received synchronously, once the
   1538      * socket is found to be ready for transmission.
   1539      */
   1540     non_blocking(plaintext_fd, NON_BLOCKING);
   1541     vstream_control(plaintext_stream,
   1542 		    CA_VSTREAM_CTL_PATH("plaintext"),
   1543 		    CA_VSTREAM_CTL_TIMEOUT(5),
   1544 		    CA_VSTREAM_CTL_END);
   1545 
   1546     (void) attr_print(plaintext_stream, ATTR_FLAG_NONE,
   1547 		   SEND_ATTR_STR(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_TLSPROXY),
   1548 		      ATTR_TYPE_END);
   1549     if (vstream_fflush(plaintext_stream) != 0)
   1550 	msg_warn("write %s attribute: %m", MAIL_ATTR_PROTO);
   1551 
   1552     /*
   1553      * Receive postscreen's remote SMTP client address/port and socket.
   1554      */
   1555     state = tlsp_state_create(service, plaintext_stream);
   1556     tlsp_request_read_event(plaintext_fd, tlsp_get_request_event,
   1557 			    TLSP_INIT_TIMEOUT, (void *) state);
   1558 }
   1559 
   1560 /* pre_jail_init_server - pre-jail initialization */
   1561 
   1562 static void pre_jail_init_server(void)
   1563 {
   1564     TLS_SERVER_INIT_PROPS props;
   1565     const char *cert_file;
   1566     int     have_server_cert;
   1567     int     no_server_cert_ok;
   1568     int     require_server_cert;
   1569 
   1570     /*
   1571      * The code in this routine is pasted literally from smtpd(8). I am not
   1572      * going to sanitize this because doing so surely will break things in
   1573      * unexpected ways.
   1574      */
   1575     if (*var_tlsp_tls_level) {
   1576 	switch (tls_level_lookup(var_tlsp_tls_level)) {
   1577 	default:
   1578 	    msg_fatal("Invalid TLS level \"%s\"", var_tlsp_tls_level);
   1579 	    /* NOTREACHED */
   1580 	    break;
   1581 	case TLS_LEV_SECURE:
   1582 	case TLS_LEV_VERIFY:
   1583 	case TLS_LEV_FPRINT:
   1584 	    msg_warn("%s: unsupported TLS level \"%s\", using \"encrypt\"",
   1585 		     VAR_TLSP_TLS_LEVEL, var_tlsp_tls_level);
   1586 	    /* FALLTHROUGH */
   1587 	case TLS_LEV_ENCRYPT:
   1588 	    var_tlsp_enforce_tls = var_tlsp_use_tls = 1;
   1589 	    break;
   1590 	case TLS_LEV_MAY:
   1591 	    var_tlsp_enforce_tls = 0;
   1592 	    var_tlsp_use_tls = 1;
   1593 	    break;
   1594 	case TLS_LEV_NONE:
   1595 	    var_tlsp_enforce_tls = var_tlsp_use_tls = 0;
   1596 	    break;
   1597 	}
   1598     }
   1599     var_tlsp_use_tls = var_tlsp_use_tls || var_tlsp_enforce_tls;
   1600     if (!var_tlsp_use_tls) {
   1601 	server_role_disabled = "TLS server role is disabled by configuration";
   1602 	return;
   1603     }
   1604 
   1605     /*
   1606      * Load TLS keys before dropping privileges.
   1607      *
   1608      * Can't use anonymous ciphers if we want client certificates. Must use
   1609      * anonymous ciphers if we have no certificates.
   1610      */
   1611     ask_client_cert = require_server_cert =
   1612 	(var_tlsp_tls_ask_ccert
   1613 	 || (var_tlsp_enforce_tls && var_tlsp_tls_req_ccert));
   1614     if (strcasecmp(var_tlsp_tls_cert_file, "none") == 0) {
   1615 	no_server_cert_ok = 1;
   1616 	cert_file = "";
   1617     } else {
   1618 	no_server_cert_ok = 0;
   1619 	cert_file = var_tlsp_tls_cert_file;
   1620     }
   1621     have_server_cert =
   1622 	(*cert_file || *var_tlsp_tls_dcert_file || *var_tlsp_tls_eccert_file);
   1623 
   1624     if (*var_tlsp_tls_chain_files != 0) {
   1625 	if (!have_server_cert)
   1626 	    have_server_cert = 1;
   1627 	else
   1628 	    msg_warn("Both %s and one or more of the legacy "
   1629 		     " %s, %s or %s are non-empty; the legacy "
   1630 		     " parameters will be ignored",
   1631 		     VAR_TLSP_TLS_CHAIN_FILES,
   1632 		     VAR_TLSP_TLS_CERT_FILE,
   1633 		     VAR_TLSP_TLS_ECCERT_FILE,
   1634 		     VAR_TLSP_TLS_DCERT_FILE);
   1635     }
   1636     /* Some TLS configuration errors are not show stoppers. */
   1637     if (!have_server_cert && require_server_cert)
   1638 	msg_warn("Need a server cert to request client certs");
   1639     if (!var_tlsp_enforce_tls && var_tlsp_tls_req_ccert)
   1640 	msg_warn("Can't require client certs unless TLS is required");
   1641     /* After a show-stopper error, log a warning. */
   1642     if (have_server_cert || (no_server_cert_ok && !require_server_cert)) {
   1643 
   1644 	tls_pre_jail_init(TLS_ROLE_SERVER);
   1645 
   1646 	/*
   1647 	 * Large parameter lists are error-prone, so we emulate a language
   1648 	 * feature that C does not have natively: named parameter lists.
   1649 	 */
   1650 	tlsp_server_ctx =
   1651 	    TLS_SERVER_INIT(&props,
   1652 			    log_param = VAR_TLSP_TLS_LOGLEVEL,
   1653 			    log_level = var_tlsp_tls_loglevel,
   1654 			    verifydepth = var_tlsp_tls_ccert_vd,
   1655 			    cache_type = TLS_MGR_SCACHE_SMTPD,
   1656 			    set_sessid = var_tlsp_tls_set_sessid,
   1657 			    chain_files = var_tlsp_tls_chain_files,
   1658 			    cert_file = cert_file,
   1659 			    key_file = var_tlsp_tls_key_file,
   1660 			    dcert_file = var_tlsp_tls_dcert_file,
   1661 			    dkey_file = var_tlsp_tls_dkey_file,
   1662 			    eccert_file = var_tlsp_tls_eccert_file,
   1663 			    eckey_file = var_tlsp_tls_eckey_file,
   1664 			    CAfile = var_tlsp_tls_CAfile,
   1665 			    CApath = var_tlsp_tls_CApath,
   1666 			    dh1024_param_file
   1667 			    = var_tlsp_tls_dh1024_param_file,
   1668 			    dh512_param_file
   1669 			    = var_tlsp_tls_dh512_param_file,
   1670 			    eecdh_grade = var_tlsp_tls_eecdh,
   1671 			    protocols = var_tlsp_enforce_tls ?
   1672 			    var_tlsp_tls_mand_proto :
   1673 			    var_tlsp_tls_proto,
   1674 			    ask_ccert = ask_client_cert,
   1675 			    mdalg = var_tlsp_tls_fpt_dgst);
   1676     } else {
   1677 	msg_warn("No server certs available. TLS can't be enabled");
   1678     }
   1679 
   1680     /*
   1681      * To maintain sanity, allow partial SSL_write() operations, and allow
   1682      * SSL_write() buffer pointers to change after a WANT_READ or WANT_WRITE
   1683      * result. This is based on OpenSSL developers talking on a mailing list,
   1684      * but is not supported by documentation. If this code stops working then
   1685      * no-one can be held responsible.
   1686      */
   1687     if (tlsp_server_ctx)
   1688 	SSL_CTX_set_mode(tlsp_server_ctx->ssl_ctx,
   1689 			 SSL_MODE_ENABLE_PARTIAL_WRITE
   1690 			 | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
   1691 }
   1692 
   1693 /* pre_jail_init_client - pre-jail initialization */
   1694 
   1695 static void pre_jail_init_client(void)
   1696 {
   1697     int     clnt_use_tls;
   1698 
   1699     /*
   1700      * The cache with TLS_APPL_STATE instances for different TLS_CLIENT_INIT
   1701      * configurations.
   1702      */
   1703     tlsp_client_app_cache = htable_create(10);
   1704 
   1705     /* Postfix <= 3.10 backwards compatibility. */
   1706     if (warn_compat_break_tlsp_clnt_level
   1707 	&& warn_compat_break_smtp_tls_level)
   1708 	msg_info("using backwards-compatible default setting "
   1709 		 VAR_TLSP_CLNT_LEVEL "=(empty)");
   1710 
   1711     /*
   1712      * Most sites don't use TLS client certs/keys. In that case, enabling
   1713      * tlsproxy-based connection caching is trivial.
   1714      *
   1715      * But some sites do use TLS client certs/keys, and that is challenging when
   1716      * tlsproxy runs in a post-jail environment: chroot breaks pathname
   1717      * resolution, and an unprivileged process should not be able to open
   1718      * files with secrets. The workaround: assume that most of those sites
   1719      * will use a fixed TLS client identity. In that case, tlsproxy can load
   1720      * the corresponding certs/keys at pre-jail time, so that secrets can
   1721      * remain read-only for root. As long as the tlsproxy pre-jail TLS client
   1722      * configuration with cert or key pathnames is the same as the one used
   1723      * in the Postfix SMTP client, sites can selectively or globally enable
   1724      * tlsproxy-based connection caching without additional TLS
   1725      * configuration.
   1726      *
   1727      * Loading one TLS client configuration at pre-jail time is not sufficient
   1728      * for the minority of sites that want to use TLS connection caching with
   1729      * multiple TLS client identities. To alert the operator, tlsproxy will
   1730      * log a warning when a TLS_CLIENT_INIT message specifies a different
   1731      * configuration than the tlsproxy pre-jail client configuration, and
   1732      * that different configuration specifies file/directory pathname
   1733      * arguments. The workaround is to have one tlsproxy process per TLS
   1734      * client identity.
   1735      *
   1736      * The general solution for single-identity or multi-identity clients is to
   1737      * stop loading certs and keys from individual files. Instead, have a
   1738      * cert/key map, indexed by client identity, read-only by root. After
   1739      * opening the map as root at pre-jail time, tlsproxy can read certs/keys
   1740      * on-the-fly as an unprivileged process at post-jail time. This is the
   1741      * approach that was already proposed for server-side SNI support, and it
   1742      * could be reused here. It would also end the proliferation of RSA
   1743      * cert/key parameters, DSA cert/key parameters, EC cert/key parameters,
   1744      * and so on.
   1745      *
   1746      * Horror: In order to create the same pre-jail TLS client context as the
   1747      * one used in the Postfix SMTP client, we have to duplicate intricate
   1748      * SMTP client code, including a handful configuration parameters that
   1749      * tlsproxy does not need. We must duplicate the logic, so that we only
   1750      * load certs and keys when the SMTP client would load them.
   1751      */
   1752     if (*var_tlsp_clnt_level != 0)
   1753 	switch (tls_level_lookup(var_tlsp_clnt_level)) {
   1754 	case TLS_LEV_SECURE:
   1755 	case TLS_LEV_VERIFY:
   1756 	case TLS_LEV_DANE_ONLY:
   1757 	case TLS_LEV_FPRINT:
   1758 	case TLS_LEV_ENCRYPT:
   1759 	    var_tlsp_clnt_use_tls = var_tlsp_clnt_enforce_tls = 1;
   1760 	    break;
   1761 	case TLS_LEV_DANE:
   1762 	case TLS_LEV_MAY:
   1763 	    var_tlsp_clnt_use_tls = 1;
   1764 	    var_tlsp_clnt_enforce_tls = 0;
   1765 	    break;
   1766 	case TLS_LEV_NONE:
   1767 	    var_tlsp_clnt_use_tls = var_tlsp_clnt_enforce_tls = 0;
   1768 	    break;
   1769 	default:
   1770 	    /* tls_level_lookup() logs no warning. */
   1771 	    /* session_tls_init() assumes that var_tlsp_clnt_level is sane. */
   1772 	    msg_fatal("Invalid TLS level \"%s\"", var_tlsp_clnt_level);
   1773 	}
   1774     clnt_use_tls = (var_tlsp_clnt_use_tls || var_tlsp_clnt_enforce_tls);
   1775 
   1776     /*
   1777      * Initialize the TLS data before entering the chroot jail.
   1778      */
   1779     if (clnt_use_tls || var_tlsp_clnt_per_site[0] || var_tlsp_clnt_policy[0]) {
   1780 	TLS_CLIENT_PARAMS tls_params;
   1781 	TLS_CLIENT_INIT_PROPS init_props;
   1782 
   1783 	tls_pre_jail_init(TLS_ROLE_CLIENT);
   1784 
   1785 	/*
   1786 	 * We get stronger type safety and a cleaner interface by combining
   1787 	 * the various parameters into a single tls_client_props structure.
   1788 	 *
   1789 	 * Large parameter lists are error-prone, so we emulate a language
   1790 	 * feature that C does not have natively: named parameter lists.
   1791 	 */
   1792 	(void) tls_proxy_client_param_from_config(&tls_params);
   1793 	(void) TLS_CLIENT_INIT_ARGS(&init_props,
   1794 				    log_param = var_tlsp_clnt_logparam,
   1795 				    log_level = var_tlsp_clnt_loglevel,
   1796 				    verifydepth = var_tlsp_clnt_scert_vd,
   1797 				    cache_type = TLS_MGR_SCACHE_SMTP,
   1798 				    chain_files = var_tlsp_clnt_chain_files,
   1799 				    cert_file = var_tlsp_clnt_cert_file,
   1800 				    key_file = var_tlsp_clnt_key_file,
   1801 				    dcert_file = var_tlsp_clnt_dcert_file,
   1802 				    dkey_file = var_tlsp_clnt_dkey_file,
   1803 				    eccert_file = var_tlsp_clnt_eccert_file,
   1804 				    eckey_file = var_tlsp_clnt_eckey_file,
   1805 				    CAfile = var_tlsp_clnt_CAfile,
   1806 				    CApath = var_tlsp_clnt_CApath,
   1807 				    mdalg = var_tlsp_clnt_fpt_dgst);
   1808 	if (tlsp_client_init(&tls_params, &init_props) == 0)
   1809 	    msg_warn("TLS client initialization failed");
   1810     }
   1811 }
   1812 
   1813 /* pre_jail_init - pre-jail initialization */
   1814 
   1815 static void pre_jail_init(char *unused_name, char **unused_argv)
   1816 {
   1817 
   1818     /*
   1819      * Initialize roles separately.
   1820      */
   1821     pre_jail_init_server();
   1822     pre_jail_init_client();
   1823 
   1824     /*
   1825      * tlsp_client_init() needs to know if it is called pre-jail or
   1826      * post-jail.
   1827      */
   1828     tlsp_pre_jail_done = 1;
   1829 
   1830     /*
   1831      * Bug: TLS_CLIENT_PARAMS attributes are not used when creating a
   1832      * TLS_APPL_STATE instance; we can only warn about attribute mismatches.
   1833      */
   1834     tlsp_params_mismatch_filter = been_here_init(BH_BOUND_NONE, BH_FLAG_NONE);
   1835 }
   1836 
   1837 MAIL_VERSION_STAMP_DECLARE;
   1838 
   1839 /* main - the main program */
   1840 
   1841 int     main(int argc, char **argv)
   1842 {
   1843 
   1844     /*
   1845      * Each table below initializes the named variables to their implicit
   1846      * default value, or to the explicit value in main.cf or master.cf. Here,
   1847      * "compat" means that a table initializes a variable "smtpd_blah" or
   1848      * "smtp_blah" that provides the implicit default value for variable
   1849      * "tlsproxy_blah" which is initialized by a different table. To make
   1850      * this work, the variables in a "compat" table must be initialized
   1851      * before the variables in the corresponding non-compat table.
   1852      */
   1853     static const CONFIG_INT_TABLE compat_int_table[] = {
   1854 	VAR_SMTPD_TLS_CCERT_VD, DEF_SMTPD_TLS_CCERT_VD, &var_smtpd_tls_ccert_vd, 0, 0,
   1855 	VAR_SMTP_TLS_SCERT_VD, DEF_SMTP_TLS_SCERT_VD, &var_smtp_tls_scert_vd, 0, 0,
   1856 	0,
   1857     };
   1858     static const CONFIG_NINT_TABLE nint_table[] = {
   1859 	VAR_TLSP_TLS_CCERT_VD, DEF_TLSP_TLS_CCERT_VD, &var_tlsp_tls_ccert_vd, 0, 0,
   1860 	VAR_TLSP_CLNT_SCERT_VD, DEF_TLSP_CLNT_SCERT_VD, &var_tlsp_clnt_scert_vd, 0, 0,
   1861 	0,
   1862     };
   1863     static const CONFIG_TIME_TABLE time_table[] = {
   1864 	VAR_TLSP_WATCHDOG, DEF_TLSP_WATCHDOG, &var_tlsp_watchdog, 10, 0,
   1865 	0,
   1866     };
   1867     static const CONFIG_BOOL_TABLE compat_bool_table[] = {
   1868 	VAR_SMTPD_USE_TLS, DEF_SMTPD_USE_TLS, &var_smtpd_use_tls,
   1869 	VAR_SMTPD_ENFORCE_TLS, DEF_SMTPD_ENFORCE_TLS, &var_smtpd_enforce_tls,
   1870 	VAR_SMTPD_TLS_ACERT, DEF_SMTPD_TLS_ACERT, &var_smtpd_tls_ask_ccert,
   1871 	VAR_SMTPD_TLS_RCERT, DEF_SMTPD_TLS_RCERT, &var_smtpd_tls_req_ccert,
   1872 	VAR_SMTPD_TLS_ENABLE_RPK, DEF_SMTPD_TLS_ENABLE_RPK, &var_smtpd_tls_enable_rpk,
   1873 	VAR_SMTPD_TLS_SET_SESSID, DEF_SMTPD_TLS_SET_SESSID, &var_smtpd_tls_set_sessid,
   1874 	VAR_SMTP_USE_TLS, DEF_SMTP_USE_TLS, &var_smtp_use_tls,
   1875 	VAR_SMTP_ENFORCE_TLS, DEF_SMTP_ENFORCE_TLS, &var_smtp_enforce_tls,
   1876 	0,
   1877     };
   1878     static const CONFIG_NBOOL_TABLE nbool_table[] = {
   1879 	VAR_TLSP_USE_TLS, DEF_TLSP_USE_TLS, &var_tlsp_use_tls,
   1880 	VAR_TLSP_ENFORCE_TLS, DEF_TLSP_ENFORCE_TLS, &var_tlsp_enforce_tls,
   1881 	VAR_TLSP_TLS_ACERT, DEF_TLSP_TLS_ACERT, &var_tlsp_tls_ask_ccert,
   1882 	VAR_TLSP_TLS_RCERT, DEF_TLSP_TLS_RCERT, &var_tlsp_tls_req_ccert,
   1883 	VAR_TLSP_TLS_ENABLE_RPK, DEF_TLSP_TLS_ENABLE_RPK, &var_tlsp_tls_enable_rpk,
   1884 	VAR_TLSP_TLS_SET_SESSID, DEF_TLSP_TLS_SET_SESSID, &var_tlsp_tls_set_sessid,
   1885 	VAR_TLSP_CLNT_USE_TLS, DEF_TLSP_CLNT_USE_TLS, &var_tlsp_clnt_use_tls,
   1886 	VAR_TLSP_CLNT_ENFORCE_TLS, DEF_TLSP_CLNT_ENFORCE_TLS, &var_tlsp_clnt_enforce_tls,
   1887 	0,
   1888     };
   1889     static const CONFIG_STR_TABLE compat_str_table[] = {
   1890 	VAR_SMTPD_TLS_CHAIN_FILES, DEF_SMTPD_TLS_CHAIN_FILES, &var_smtpd_tls_chain_files, 0, 0,
   1891 	VAR_SMTPD_TLS_CERT_FILE, DEF_SMTPD_TLS_CERT_FILE, &var_smtpd_tls_cert_file, 0, 0,
   1892 	VAR_SMTPD_TLS_KEY_FILE, DEF_SMTPD_TLS_KEY_FILE, &var_smtpd_tls_key_file, 0, 0,
   1893 	VAR_SMTPD_TLS_DCERT_FILE, DEF_SMTPD_TLS_DCERT_FILE, &var_smtpd_tls_dcert_file, 0, 0,
   1894 	VAR_SMTPD_TLS_DKEY_FILE, DEF_SMTPD_TLS_DKEY_FILE, &var_smtpd_tls_dkey_file, 0, 0,
   1895 	VAR_SMTPD_TLS_ECCERT_FILE, DEF_SMTPD_TLS_ECCERT_FILE, &var_smtpd_tls_eccert_file, 0, 0,
   1896 	VAR_SMTPD_TLS_ECKEY_FILE, DEF_SMTPD_TLS_ECKEY_FILE, &var_smtpd_tls_eckey_file, 0, 0,
   1897 	VAR_SMTPD_TLS_CA_FILE, DEF_SMTPD_TLS_CA_FILE, &var_smtpd_tls_CAfile, 0, 0,
   1898 	VAR_SMTPD_TLS_CA_PATH, DEF_SMTPD_TLS_CA_PATH, &var_smtpd_tls_CApath, 0, 0,
   1899 	VAR_SMTPD_TLS_CIPH, DEF_SMTPD_TLS_CIPH, &var_smtpd_tls_ciph, 1, 0,
   1900 	VAR_SMTPD_TLS_MAND_CIPH, DEF_SMTPD_TLS_MAND_CIPH, &var_smtpd_tls_mand_ciph, 1, 0,
   1901 	VAR_SMTPD_TLS_EXCL_CIPH, DEF_SMTPD_TLS_EXCL_CIPH, &var_smtpd_tls_excl_ciph, 0, 0,
   1902 	VAR_SMTPD_TLS_MAND_EXCL, DEF_SMTPD_TLS_MAND_EXCL, &var_smtpd_tls_mand_excl, 0, 0,
   1903 	VAR_SMTPD_TLS_PROTO, DEF_SMTPD_TLS_PROTO, &var_smtpd_tls_proto, 0, 0,
   1904 	VAR_SMTPD_TLS_MAND_PROTO, DEF_SMTPD_TLS_MAND_PROTO, &var_smtpd_tls_mand_proto, 0, 0,
   1905 	VAR_SMTPD_TLS_512_FILE, DEF_SMTPD_TLS_512_FILE, &var_smtpd_tls_dh512_param_file, 0, 0,
   1906 	VAR_SMTPD_TLS_1024_FILE, DEF_SMTPD_TLS_1024_FILE, &var_smtpd_tls_dh1024_param_file, 0, 0,
   1907 	VAR_SMTPD_TLS_EECDH, DEF_SMTPD_TLS_EECDH, &var_smtpd_tls_eecdh, 1, 0,
   1908 	VAR_SMTPD_TLS_FPT_DGST, DEF_SMTPD_TLS_FPT_DGST, &var_smtpd_tls_fpt_dgst, 1, 0,
   1909 	VAR_SMTPD_TLS_LOGLEVEL, DEF_SMTPD_TLS_LOGLEVEL, &var_smtpd_tls_loglevel, 0, 0,
   1910 	VAR_SMTPD_TLS_LEVEL, DEF_SMTPD_TLS_LEVEL, &var_smtpd_tls_level, 0, 0,
   1911 	VAR_SMTP_TLS_CHAIN_FILES, DEF_SMTP_TLS_CHAIN_FILES, &var_smtp_tls_chain_files, 0, 0,
   1912 	VAR_SMTP_TLS_CERT_FILE, DEF_SMTP_TLS_CERT_FILE, &var_smtp_tls_cert_file, 0, 0,
   1913 	VAR_SMTP_TLS_KEY_FILE, DEF_SMTP_TLS_KEY_FILE, &var_smtp_tls_key_file, 0, 0,
   1914 	VAR_SMTP_TLS_DCERT_FILE, DEF_SMTP_TLS_DCERT_FILE, &var_smtp_tls_dcert_file, 0, 0,
   1915 	VAR_SMTP_TLS_DKEY_FILE, DEF_SMTP_TLS_DKEY_FILE, &var_smtp_tls_dkey_file, 0, 0,
   1916 	VAR_SMTP_TLS_CA_FILE, DEF_SMTP_TLS_CA_FILE, &var_smtp_tls_CAfile, 0, 0,
   1917 	VAR_SMTP_TLS_CA_PATH, DEF_SMTP_TLS_CA_PATH, &var_smtp_tls_CApath, 0, 0,
   1918 	VAR_SMTP_TLS_FPT_DGST, DEF_SMTP_TLS_FPT_DGST, &var_smtp_tls_fpt_dgst, 1, 0,
   1919 	VAR_SMTP_TLS_ECCERT_FILE, DEF_SMTP_TLS_ECCERT_FILE, &var_smtp_tls_eccert_file, 0, 0,
   1920 	VAR_SMTP_TLS_ECKEY_FILE, DEF_SMTP_TLS_ECKEY_FILE, &var_smtp_tls_eckey_file, 0, 0,
   1921 	VAR_SMTP_TLS_LOGLEVEL, DEF_SMTP_TLS_LOGLEVEL, &var_smtp_tls_loglevel, 0, 0,
   1922 	VAR_SMTP_TLS_PER_SITE, DEF_SMTP_TLS_PER_SITE, &var_smtp_tls_per_site, 0, 0,
   1923 	VAR_SMTP_TLS_LEVEL, DEF_SMTP_TLS_LEVEL, &var_smtp_tls_level, 0, 0,
   1924 	VAR_SMTP_TLS_POLICY, DEF_SMTP_TLS_POLICY, &var_smtp_tls_policy, 0, 0,
   1925 	0,
   1926     };
   1927     static const CONFIG_STR_TABLE str_table[] = {
   1928 	VAR_TLSP_TLS_CHAIN_FILES, DEF_TLSP_TLS_CHAIN_FILES, &var_tlsp_tls_chain_files, 0, 0,
   1929 	VAR_TLSP_TLS_CERT_FILE, DEF_TLSP_TLS_CERT_FILE, &var_tlsp_tls_cert_file, 0, 0,
   1930 	VAR_TLSP_TLS_KEY_FILE, DEF_TLSP_TLS_KEY_FILE, &var_tlsp_tls_key_file, 0, 0,
   1931 	VAR_TLSP_TLS_DCERT_FILE, DEF_TLSP_TLS_DCERT_FILE, &var_tlsp_tls_dcert_file, 0, 0,
   1932 	VAR_TLSP_TLS_DKEY_FILE, DEF_TLSP_TLS_DKEY_FILE, &var_tlsp_tls_dkey_file, 0, 0,
   1933 	VAR_TLSP_TLS_ECCERT_FILE, DEF_TLSP_TLS_ECCERT_FILE, &var_tlsp_tls_eccert_file, 0, 0,
   1934 	VAR_TLSP_TLS_ECKEY_FILE, DEF_TLSP_TLS_ECKEY_FILE, &var_tlsp_tls_eckey_file, 0, 0,
   1935 	VAR_TLSP_TLS_CA_FILE, DEF_TLSP_TLS_CA_FILE, &var_tlsp_tls_CAfile, 0, 0,
   1936 	VAR_TLSP_TLS_CA_PATH, DEF_TLSP_TLS_CA_PATH, &var_tlsp_tls_CApath, 0, 0,
   1937 	VAR_TLSP_TLS_CIPH, DEF_TLSP_TLS_CIPH, &var_tlsp_tls_ciph, 1, 0,
   1938 	VAR_TLSP_TLS_MAND_CIPH, DEF_TLSP_TLS_MAND_CIPH, &var_tlsp_tls_mand_ciph, 1, 0,
   1939 	VAR_TLSP_TLS_EXCL_CIPH, DEF_TLSP_TLS_EXCL_CIPH, &var_tlsp_tls_excl_ciph, 0, 0,
   1940 	VAR_TLSP_TLS_MAND_EXCL, DEF_TLSP_TLS_MAND_EXCL, &var_tlsp_tls_mand_excl, 0, 0,
   1941 	VAR_TLSP_TLS_PROTO, DEF_TLSP_TLS_PROTO, &var_tlsp_tls_proto, 0, 0,
   1942 	VAR_TLSP_TLS_MAND_PROTO, DEF_TLSP_TLS_MAND_PROTO, &var_tlsp_tls_mand_proto, 0, 0,
   1943 	VAR_TLSP_TLS_512_FILE, DEF_TLSP_TLS_512_FILE, &var_tlsp_tls_dh512_param_file, 0, 0,
   1944 	VAR_TLSP_TLS_1024_FILE, DEF_TLSP_TLS_1024_FILE, &var_tlsp_tls_dh1024_param_file, 0, 0,
   1945 	VAR_TLSP_TLS_EECDH, DEF_TLSP_TLS_EECDH, &var_tlsp_tls_eecdh, 1, 0,
   1946 	VAR_TLSP_TLS_FPT_DGST, DEF_TLSP_TLS_FPT_DGST, &var_tlsp_tls_fpt_dgst, 1, 0,
   1947 	VAR_TLSP_TLS_LOGLEVEL, DEF_TLSP_TLS_LOGLEVEL, &var_tlsp_tls_loglevel, 0, 0,
   1948 	VAR_TLSP_TLS_LEVEL, DEF_TLSP_TLS_LEVEL, &var_tlsp_tls_level, 0, 0,
   1949 	VAR_TLSP_CLNT_LOGLEVEL, DEF_TLSP_CLNT_LOGLEVEL, &var_tlsp_clnt_loglevel, 0, 0,
   1950 	VAR_TLSP_CLNT_LOGPARAM, DEF_TLSP_CLNT_LOGPARAM, &var_tlsp_clnt_logparam, 0, 0,
   1951 	VAR_TLSP_CLNT_CHAIN_FILES, DEF_TLSP_CLNT_CHAIN_FILES, &var_tlsp_clnt_chain_files, 0, 0,
   1952 	VAR_TLSP_CLNT_CERT_FILE, DEF_TLSP_CLNT_CERT_FILE, &var_tlsp_clnt_cert_file, 0, 0,
   1953 	VAR_TLSP_CLNT_KEY_FILE, DEF_TLSP_CLNT_KEY_FILE, &var_tlsp_clnt_key_file, 0, 0,
   1954 	VAR_TLSP_CLNT_DCERT_FILE, DEF_TLSP_CLNT_DCERT_FILE, &var_tlsp_clnt_dcert_file, 0, 0,
   1955 	VAR_TLSP_CLNT_DKEY_FILE, DEF_TLSP_CLNT_DKEY_FILE, &var_tlsp_clnt_dkey_file, 0, 0,
   1956 	VAR_TLSP_CLNT_ECCERT_FILE, DEF_TLSP_CLNT_ECCERT_FILE, &var_tlsp_clnt_eccert_file, 0, 0,
   1957 	VAR_TLSP_CLNT_ECKEY_FILE, DEF_TLSP_CLNT_ECKEY_FILE, &var_tlsp_clnt_eckey_file, 0, 0,
   1958 	VAR_TLSP_CLNT_CAFILE, DEF_TLSP_CLNT_CAFILE, &var_tlsp_clnt_CAfile, 0, 0,
   1959 	VAR_TLSP_CLNT_CAPATH, DEF_TLSP_CLNT_CAPATH, &var_tlsp_clnt_CApath, 0, 0,
   1960 	VAR_TLSP_CLNT_FPT_DGST, DEF_TLSP_CLNT_FPT_DGST, &var_tlsp_clnt_fpt_dgst, 1, 0,
   1961 	VAR_TLSP_CLNT_LEVEL, DEF_TLSP_CLNT_LEVEL, &var_tlsp_clnt_level, 0, 0,
   1962 	VAR_TLSP_CLNT_PER_SITE, DEF_TLSP_CLNT_PER_SITE, &var_tlsp_clnt_per_site, 0, 0,
   1963 	VAR_TLSP_CLNT_POLICY, DEF_TLSP_CLNT_POLICY, &var_tlsp_clnt_policy, 0, 0,
   1964 	0,
   1965     };
   1966 
   1967     /*
   1968      * Fingerprint executables and core dumps.
   1969      */
   1970     MAIL_VERSION_STAMP_ALLOCATE;
   1971 
   1972     /*
   1973      * Pass control to the event-driven service skeleton.
   1974      */
   1975     event_server_main(argc, argv, tlsp_service,
   1976 		      CA_MAIL_SERVER_INT_TABLE(compat_int_table),
   1977 		      CA_MAIL_SERVER_NINT_TABLE(nint_table),
   1978 		      CA_MAIL_SERVER_STR_TABLE(compat_str_table),
   1979 		      CA_MAIL_SERVER_STR_TABLE(str_table),
   1980 		      CA_MAIL_SERVER_BOOL_TABLE(compat_bool_table),
   1981 		      CA_MAIL_SERVER_NBOOL_TABLE(nbool_table),
   1982 		      CA_MAIL_SERVER_TIME_TABLE(time_table),
   1983 		      CA_MAIL_SERVER_PRE_INIT(pre_jail_init),
   1984 		      CA_MAIL_SERVER_SLOW_EXIT(tlsp_drain),
   1985 		      CA_MAIL_SERVER_RETIRE_ME,
   1986 		      CA_MAIL_SERVER_WATCHDOG(&var_tlsp_watchdog),
   1987 		      CA_MAIL_SERVER_UNLIMITED,
   1988 		      0);
   1989 }
   1990 
   1991 #else
   1992 
   1993 /* tlsp_service - respond to external trigger(s), non-TLS version */
   1994 
   1995 static void tlsp_service(VSTREAM *stream, char *unused_service,
   1996 			         char **unused_argv)
   1997 {
   1998     msg_info("TLS support is not compiled in -- exiting");
   1999     event_server_disconnect(stream);
   2000 }
   2001 
   2002 /* main - the main program */
   2003 
   2004 int     main(int argc, char **argv)
   2005 {
   2006 
   2007     /*
   2008      * We can't simply use msg_fatal() here, because the logging hasn't been
   2009      * initialized. The text would disappear because stderr is redirected to
   2010      * /dev/null.
   2011      *
   2012      * We invoke event_server_main() to complete program initialization
   2013      * (including logging) and then invoke the tlsp_service() routine to log
   2014      * the message that says why this program will not run.
   2015      */
   2016     event_server_main(argc, argv, tlsp_service,
   2017 		      0);
   2018 }
   2019 
   2020 #endif
   2021