From: Wietse Venema These instructions assume that you build Postfix from source
-code as described in the INSTALL document. Some modification may
-be required if you build Postfix from a vendor-specific source
-package. To build Postfix with TLS support, first we need to generate
-the make(1) files with the necessary definitions. This is
-done by invoking the command "make makefiles" in the Postfix
-top-level directory and with arguments as shown next. NOTE: Do not use Gnu TLS. It will spontaneously terminate
-a Postfix daemon process with exit status code 2, instead of allowing
-Postfix to 1) report the error to the maillog file, and to 2) provide
-plaintext service where this is appropriate. If the OpenSSL include files (such as ssl.h) are
-in directory /usr/include/openssl, and the OpenSSL libraries
-(such as libssl.so and libcrypto.so) are in
-directory /usr/lib: If the OpenSSL include files (such as ssl.h) are
-in directory /usr/local/include/openssl, and the OpenSSL
-libraries (such as libssl.so and libcrypto.so)
-are in directory /usr/local/lib: On Solaris, specify the -R option as shown below:
-
- If you need to apply other customizations (such as Berkeley DB
-databases, MySQL, PostgreSQL, LDAP or SASL), see the respective
-Postfix README documents, and combine their "make makefiles"
-instructions with the instructions above: To complete the build process, see the Postfix INSTALL
-instructions. Postfix has TLS support turned off by default, so
-you can start using Postfix as soon as it is installed. Topics covered in this section:
session
key cache
-Building Postfix with TLS support
-
-
-
-
-
-
-
-
-
-% make tidy # if you have left-over files from a previous build
-% make makefiles CCARGS="-DUSE_TLS" AUXLIBS="-lssl -lcrypto"
-
-
-
-
-
-% make tidy # if you have left-over files from a previous build
-% make makefiles CCARGS="-DUSE_TLS -I/usr/local/include" \
- AUXLIBS="-L/usr/local/lib -lssl -lcrypto"
-
-
-
-
-
-% make tidy # if you have left-over files from a previous build
-% make makefiles CCARGS="-DUSE_TLS -I/usr/local/include" \
- AUXLIBS="-R/usr/local/lib -L/usr/local/lib -lssl -lcrypto"
-
-
-
-
-
-% make tidy # if you have left-over files from a previous build
-% make makefiles CCARGS="-DUSE_TLS \
- (other -D or -I options)" \
- AUXLIBS="-lssl -lcrypto \
- (other -l options for libraries in /usr/lib) \
- (-L/path/name + -l options for other libraries)"
-
-SMTP Server specific settings
-Building Postfix with TLS support
- -These instructions assume that you build Postfix from source -code as described in the INSTALL document. Some modification may -be required if you build Postfix from a vendor-specific source -package.
- -To build Postfix with TLS support, first we need to generate -the make(1) files with the necessary definitions. This is -done by invoking the command "make makefiles" in the Postfix -top-level directory and with arguments as shown next.
- -NOTE: Do not use Gnu TLS. It will spontaneously terminate -a Postfix daemon process with exit status code 2, instead of allowing -Postfix to 1) report the error to the maillog file, and to 2) provide -plaintext service where this is appropriate.
- -- -
- -If the OpenSSL include files (such as ssl.h) are -in directory /usr/include/openssl, and the OpenSSL libraries -(such as libssl.so and libcrypto.so) are in -directory /usr/lib:
- --- --% make tidy # if you have left-over files from a previous build -% make makefiles CCARGS="-DUSE_TLS" AUXLIBS="-lssl -lcrypto" --If the OpenSSL include files (such as ssl.h) are -in directory /usr/local/include/openssl, and the OpenSSL -libraries (such as libssl.so and libcrypto.so) -are in directory /usr/local/lib:
- --- --% make tidy # if you have left-over files from a previous build -% make makefiles CCARGS="-DUSE_TLS -I/usr/local/include" \ - AUXLIBS="-L/usr/local/lib -lssl -lcrypto" --On Solaris, specify the -R option as shown below: - -
-- --% make tidy # if you have left-over files from a previous build -% make makefiles CCARGS="-DUSE_TLS -I/usr/local/include" \ - AUXLIBS="-R/usr/local/lib -L/usr/local/lib -lssl -lcrypto" --If you need to apply other customizations (such as Berkeley DB -databases, MySQL, PostgreSQL, LDAP or SASL), see the respective -Postfix README documents, and combine their "make makefiles" -instructions with the instructions above:
- --- --% make tidy # if you have left-over files from a previous build -% make makefiles CCARGS="-DUSE_TLS \ - (other -D or -I options)" \ - AUXLIBS="-lssl -lcrypto \ - (other -l options for libraries in /usr/lib) \ - (-L/path/name + -l options for other libraries)" --To complete the build process, see the Postfix INSTALL -instructions. Postfix has TLS support turned off by default, so -you can start using Postfix as soon as it is installed.
-SMTP Server specific settings
Topics covered in this section:
@@ -402,21 +326,32 @@ logging level.-+
+ +
@@ -693,26 +628,27 @@ Postfix SMTP server access control:- Level Postfix 2.9 and later Earlier +releases. + 0 Disable logging of TLS activity. - 0 Log only a summary +message on TLS handshake completion — no logging of client +certificate trust-chain verification errors if client certificate +verification is not required. Disable logging +of TLS activity. 1 Log TLS handshake and certificate information. + - 1 Also log trust-chain +verification errors and peer certificate summary information. +Also log TLS handshake and certificate information. + 2 Log levels during TLS negotiation. -- 2 Also +log levels during TLS negotiation. + 3 Log hexadecimal and ASCII dump of TLS -negotiation process - 3 Also +log hexadecimal and ASCII dump of TLS negotiation process. ++ 4 Log hexadecimal and ASCII dump of complete -transmission after STARTTLS 4 Also +log hexadecimal and ASCII dump of complete transmission after +STARTTLS. -
-- permit_tls_clientcerts
- +
Allow the remote SMTP client -request if the client certificate fingerprint is listed in the -client certificate table (see relay_clientcerts discussion below).
-- permit_tls_clientcerts
Allow the remote SMTP +client request if the client certificate fingerprint or certificate +public key fingerprint (Postfix 2.9 and later) is listed in the +client certificate table (see relay_clientcerts discussion below). +
- permit_tls_all_clientcerts
- -
Allow the remote SMTP client request if the client certificate passes trust chain verification. Useful with private-label CAs that only issue certificates to trusted clients (and not otherwise).
- check_ccert_access type:table
Use the remote SMTP -client -certificate fingerprint as the lookup key for the specified access(5) +
- check_ccert_access type:table
Use the remote +SMTP client certificate fingerprint or public key fingerprint +(Postfix 2.9 and later) as the lookup key for the specified access(5) table.
The digest algorithm used to construct the client certificate +
The digest algorithm used to compute the client certificate fingerprints is specified with the main.cf smtpd_tls_fingerprint_digest parameter. The default is "md5", for compatibility with Postfix versions < 2.5.
@@ -921,20 +857,17 @@ protocol.-
-- TLS support in the LMTP delivery agent +
- Configuring TLS in the SMTP/LMTP client + +
- Client-side TLS activity logging
- Client-side certificate and private key configuration -
- Client-side TLS activity logging - -
- Client-side TLS session cache
- Client TLS limitations -
- Configuring TLS in the SMTP/LMTP client -
- Per-destination TLS policy
- Obsolete per-site TLS policy support @@ -953,9 +886,30 @@ key configuration
TLS support in the LMTP delivery agent +
Configuring TLS in the SMTP/LMTP client
+Similar to the Postfix SMTP server, the Postfix SMTP/LMTP client +implements multiple TLS security levels. These levels are described +in more detail in the sections that follow.
+ ++
+ +- none
+- No TLS.
+- may
+- Opportunistic TLS.
+- encrypt
+- Mandatory TLS encryption. +
- fingerprint
+- Certificate fingerprint verification. +
- verify
+- Mandatory server certificate verification. +
- secure
+- Secure-channel TLS. +
TLS support in the LMTP delivery agent
+The smtp(8) and lmtp(8) delivery agents are implemented by a single dual-purpose program. Specifically, all the TLS features described below apply @@ -967,451 +921,108 @@ listening on UNIX-domain sockets. When server certificate verification is enabled and the server is listening on a UNIX-domain socket, the $myhostname parameter is used to set the TLS verification nexthop and -hostname. Note, opportunistic encryption of LMTP traffic over -UNIX-domain sockets is futile. TLS is only useful in this context when +hostname.
+ +NOTE: Opportunistic encryption of LMTP traffic over UNIX-domain +sockets or loopback TCP connections is futile. TLS is only useful +in this context when it is mandatory, typically to allow at least one of the server or the client to authenticate the other. The "null" cipher grade may be appropriate in this context, when available on both client and server. The "null" ciphers provide authentication without encryption.
-Client-side certificate and private -key configuration
+No TLS encryption
-Do not configure Postfix SMTP client certificates unless you must -present -client TLS certificates to one or more servers. Client certificates are -not usually needed, and can cause problems in configurations that work -well without them. The recommended setting is to let the defaults stand:
+At the "none" TLS security level, TLS encryption is +disabled. This is the default security level. With Postfix 2.3 and later, +it can be configured explicitly by setting "smtp_tls_security_level = none".
--+- smtp_tls_cert_file = - smtp_tls_dcert_file = - smtp_tls_key_file = - smtp_tls_dkey_file = - # Postfix ≥ 2.6 - smtp_tls_eccert_file = - smtp_tls_eckey_file = --With Postfix 2.2 and earlier, or when smtp_tls_security_level is set to +its default (backwards compatible) empty value, the appropriate configuration +settings are "smtp_use_tls = no" and "smtp_enforce_tls = no". +With either approach, TLS is not used even if supported by the server. +For LMTP, use the corresponding "lmtp_" parameters.
-The best way to use the default settings is to comment out the above -parameters in main.cf if present.
+Per destination settings may override this default setting, in which case +TLS is used selectively, only with destinations explicitly configured +for TLS.
-During TLS startup negotiation the Postfix SMTP client may present -a certificate to the remote SMTP server. The Netscape client is -rather clever here and lets the user select between only those -certificates that match CA certificates offered by the remote SMTP -server. As the Postfix SMTP client uses the "SSL_connect()" function -from the OpenSSL package, this is not possible and we have to choose -just one certificate. So for now the default is to use _no_ -certificate and key unless one is explicitly specified here.
+You can disable TLS for a subset of destinations, while leaving +it enabled for the rest. With the Postfix 2.3 and later TLS policy table, specify the "none" +security level. With the obsolete per-site +table, specify the "NONE" keyword.
-RSA, DSA and ECDSA (Postfix ≥ 2.6) certificates are supported. -You can configure all three at the same time, in which case the -cipher used determines which certificate is presented.
+Opportunistic TLS
-It is possible for the Postfix SMTP client to use the same -key/certificate pair as the Postfix SMTP server. If a certificate -is to be presented, it must be in "PEM" format. The private key -must not be encrypted, meaning: it must be accessible without -password. Both parts (certificate and private key) may be in the -same file.
+At the "may" TLS security level, TLS encryption is opportunistic. +The SMTP transaction is encrypted if the STARTTLS ESMTP feature +is supported by the server. Otherwise, messages are sent in the clear. +With Postfix 2.3 and later, opportunistic TLS can be configured by +setting "smtp_tls_security_level = may". -
To enable remote SMTP servers to verify the Postfix SMTP client -certificate, the issuing CA certificates must be made available to the -server. You should include the required certificates in the client -certificate file, the client certificate first, then the issuing -CA(s) (bottom-up order).
+Since sending in the clear is acceptable, demanding stronger +than default TLS security mostly reduces inter-operability. If you +must restrict TLS protocol or cipher selection even with opportunistic +TLS, the "smtp_tls_ciphers" and "smtp_tls_protocols" configuration +parameters (Postfix ≥ 2.6) provide control over the protocols +and cipher grade +used with opportunistic TLS. With earlier releases the opportunistic TLS +cipher grade is always "export" and no protocols are disabled.
-Example: the certificate for "client.example.com" was issued by -"intermediate CA" which itself has a certificate issued by "root CA". -Create the client.pem file with:
+With Postfix 2.2 and earlier, or when smtp_tls_security_level is +set to its default (backwards compatible) empty value, the appropriate +configuration settings are "smtp_use_tls = yes" and +"smtp_enforce_tls = no". +For LMTP use the corresponding "lmtp_" parameters.
--+-% cat client_cert.pem intermediate_CA.pem > client.pem --With opportunistic TLS, mail delivery continues even if the +server certificate is untrusted or bears the wrong name. Starting +with Postfix 2.3, when the TLS handshake fails for an opportunistic +TLS session, rather than give up on mail delivery, the transaction +is retried with TLS disabled. Trying an unencrypted connection makes +it possible to deliver mail to sites with non-interoperable server +TLS implementations.
-A Postfix SMTP client certificate supplied here must be usable -as SSL client certificate and hence pass the "openssl verify -purpose -sslclient ..." test.
+Opportunistic encryption is never used for LMTP over UNIX-domain +sockets. The communications channel is already confidential without +TLS, so the only potential benefit of TLS is authentication. Do not +configure opportunistic TLS for LMTP deliveries over UNIX-domain sockets. +Only configure TLS for LMTP over UNIX-domain sockets at the +encrypt security level or higher. +Attempts to configure opportunistic encryption of LMTP sessions will +be ignored with a warning written to the mail logs.
-A server that trusts the root CA has a local copy of the root -CA certificate, so it is not necessary to include the root CA -certificate here. Leaving it out of the "client.pem" file reduces -the overhead of the TLS exchange.
+You can enable opportunistic TLS just for selected destinations. With +the Postfix 2.3 and later TLS policy table, +specify the "may" security level. With the obsolete per-site table, specify the "MAY" keyword.
-If you want the Postfix SMTP client to accept remote SMTP server -certificates issued by these CAs, append the root certificate to -$smtp_tls_CAfile or install it in the $smtp_tls_CApath directory.
+This is the most common security level for TLS protected SMTP +sessions, stronger security is not generally available and, if needed, +is typically only configured on a per-destination basis. See the section +on TLS limitations above.
+ +Example:
-RSA key and certificate examples:
--/etc/postfix/main.cf: - smtp_tls_cert_file = /etc/postfix/client.pem - smtp_tls_key_file = $smtp_tls_cert_file + smtp_tls_security_level = mayTheir DSA counterparts:
+Postfix 2.2 syntax:
-/etc/postfix/main.cf: - smtp_tls_dcert_file = /etc/postfix/client-dsa.pem - smtp_tls_dkey_file = $smtp_tls_dcert_file -+ smtp_use_tls = yes + smtp_enforce_tls = no +Their ECDSA counterparts (Postfix ≥ 2.6 + OpenSSL ≥ 0.9.9):
- --- --/etc/postfix/main.cf: - smtp_tls_eccert_file = /etc/postfix/client-ecdsa.pem - smtp_tls_eckey_file = $smtp_tls_eccert_file --To verify a remote SMTP server certificate, the Postfix SMTP -client needs to trust the certificates of the issuing certification -authorities. These certificates in "pem" format can be stored in a -single $smtp_tls_CAfile or in multiple files, one CA per file in -the $smtp_tls_CApath directory. If you use a directory, don't forget -to create the necessary "hash" links with:
- --- --# $OPENSSL_HOME/bin/c_rehash /path/to/directory --The $smtp_tls_CAfile contains the CA certificates of one or more -trusted CAs. The file is opened (with root privileges) before Postfix -enters the optional chroot jail and so need not be accessible from inside the -chroot jail.
- -Additional trusted CAs can be specified via the $smtp_tls_CApath -directory, in which case the certificates are read (with $mail_owner -privileges) from the files in the directory when the information -is needed. Thus, the $smtp_tls_CApath directory needs to be accessible -inside the optional chroot jail.
- -The choice between $smtp_tls_CAfile and $smtp_tls_CApath is -a space/time tradeoff. If there are many trusted CAs, the cost of -preloading them all into memory may not pay off in reduced access time -when the certificate is needed.
- -Example:
- --- --/etc/postfix/main.cf: - smtp_tls_CAfile = /etc/postfix/CAcert.pem - smtp_tls_CApath = /etc/postfix/certs --Client-side TLS activity logging
- -To get additional information about Postfix SMTP client TLS -activity you can increase the loglevel from 0..4. Each logging -level also includes the information that is logged at a lower -logging level.
- -- -- -- -
- -- - 0 Disable logging of TLS activity. - - 1 Log TLS handshake and certificate information. - - - 2 Log levels during TLS negotiation. -- - 3 Log hexadecimal and ASCII dump of TLS -negotiation process - - 4 Log hexadecimal and ASCII dump of complete -transmission after STARTTLS Example:
- --- --/etc/postfix/main.cf: - smtp_tls_loglevel = 0 --Client-side TLS session cache
- -The remote SMTP server and the Postfix SMTP client negotiate a -session, which takes some computer time and network bandwidth. By -default, this session information is cached only in the smtp(8) -process actually using this session and is lost when the process -terminates. To share the session information between multiple -smtp(8) processes, a persistent session cache can be used. You -can specify any database type that can store objects of several -kbytes and that supports the sequence operator. DBM databases are -not suitable because they can only store small objects. The cache -is maintained by the tlsmgr(8) process, so there is no problem with -concurrent access. Session caching is highly recommended, because -the cost of repeatedly negotiating TLS session keys is high. Future -Postfix SMTP servers may limit the number of sessions that a client -is allowed to negotiate per unit time.
- - -Example:
- --- --/etc/postfix/main.cf: - smtp_tls_session_cache_database = btree:/var/lib/postfix/smtp_scache --Note: as of version 2.5, Postfix no longer uses root privileges -when opening this file. The file should now be stored under the -Postfix-owned data_directory. As a migration aid, an attempt to -open the file under a non-Postfix directory is redirected to the -Postfix-owned data_directory, and a warning is logged.
- -Cached Postfix SMTP client session information expires after -a certain amount of time. Postfix/TLS does not use the OpenSSL -default of 300s, but a longer time of 3600s (=1 hour). RFC 2246 -recommends a maximum of 24 hours.
- -Example:
- --- --/etc/postfix/main.cf: - smtp_tls_session_cache_timeout = 3600s --Client TLS limitations -
- -The security properties of TLS communication channels are -application specific. While the TLS protocol can provide a confidential, -tamper-resistant, mutually authenticated channel between client -and server, not all of these security features are applicable to every -communication.
- -For example, while mutual TLS authentication between browsers and web -servers is possible, it is not practical, or even useful, for web-servers -that serve the public to verify the identity of every potential user. In -practice, most HTTPS transactions are asymmetric: the browser verifies -the HTTPS server's identity, but the user remains anonymous. Much of -the security policy is up to the client. If the client chooses to not -verify the server's name, the server is not aware of this. There are many -interesting browser security topics, but we shall not dwell -on them here. Rather, our goal is to understand the security features -of TLS in conjunction with SMTP.
- -An important SMTP-specific observation is that a public MX host is -even more at the mercy of the SMTP client than is an HTTPS server. Not only -can it not enforce due care in the client's use of TLS, but it cannot even -enforce the use of TLS, because TLS support in SMTP clients is still the -exception rather than the rule. One cannot, in practice, limit access to -one's MX hosts to just TLS-enabled clients. Such a policy would result -in a vast reduction in one's ability to communicate by email with the -world at large.
- -One may be tempted to try enforcing TLS for mail from specific -sending organizations, but this, too, runs into obstacles. One such -obstacle is that we don't know who is (allegedly) sending mail until -we see the "MAIL FROM:" SMTP command, and at that point, if TLS -is not already in use, a potentially sensitive sender address (and -with SMTP PIPELINING one or more of the recipients) has (have) already been -leaked in the clear. Another obstacle is that mail from the sender to -the recipient may be forwarded, and the forwarding organization may not -have any security arrangements with the final destination. Bounces also -need to be protected. These can only be identified by the IP address and -HELO name of the connecting client, and it is difficult to keep track -of all the potential IP addresses or HELO names of the outbound email -servers of the sending organization.
- -Consequently, TLS security for mail delivery to public MX hosts is -almost entirely the client's responsibility. The server is largely a -passive enabler of TLS security, the rest is up to the client. While the -server has a greater opportunity to mandate client security policy when -it is a dedicated MSA that only handles outbound mail from trusted clients, -below we focus on the client security policy.
- -On the SMTP client, there are further complications. When delivering -mail to a given domain, in contrast to HTTPS, one rarely uses the domain -name directly as the target host of the SMTP session. More typically, -one uses MX lookups - these are usually unauthenticated - to obtain the domain's SMTP server -hostname(s). When, as is current practice, the client verifies the -insecurely obtained MX hostname, it is subject to a DNS man-in-the-middle -attack.
- -If clients instead attempted to verify the recipient domain name, -an SMTP server for multiple domains would need to -list all its email domain names in its certificate, and generate a -new certificate each time a new domain were added. At least some CAs set -fairly low limits (20 for one prominent CA) on the number of names that -server certificates can contain. This approach is not consistent with -current practice and does not scale.
- -It is regrettably the case that TLS secure-channels -(fully authenticated and immune to man-in-the-middle attacks) impose -constraints on the sending and receiving sites that preclude ubiquitous -deployment. One needs to manually configure this type of security for -each destination domain, and in many cases implement non-default TLS -policy table entries for additional -domains hosted at a common secured destination. With Postfix 2.3, we -make secure-channel configurations substantially easier to configure, -but they will never be the norm. For the generic domain with which you -have made no specific security arrangements, this security level is not -a good fit.
- -Given that strong authentication is not generally possible, and that -verifiable certificates cost time and money, many servers that implement -TLS use self-signed certificates or private CAs. This further limits -the applicability of verified TLS on the public Internet.
- -Historical note: while the documentation of these issues and many of the -related features are new with Postfix 2.3, the issue was well -understood before Postfix 1.0, when Lutz Jänicke was designing -the first unofficial Postfix TLS patch. See his original post http://www.imc.org/ietf-apps-tls/mail-archive/msg00304.html -and the first response http://www.imc.org/ietf-apps-tls/mail-archive/msg00305.html. -The problem is not even unique to SMTP or even TLS, similar issues exist -for secure connections via aliases for HTTPS and Kerberos. SMTP merely -uses indirect naming (via MX records) more frequently.
- -Configuring TLS in the SMTP/LMTP client -
- -Similar to the Postfix SMTP server, the Postfix SMTP/LMTP client -implements multiple TLS security levels. These levels are described -in more detail in the sections that follow.
- --
- -- none
-- No TLS.
-- may
-- Opportunistic TLS.
-- encrypt
-- Mandatory TLS encryption. -
- fingerprint
-- Certificate fingerprint verification. -
- verify
-- Mandatory server certificate verification. -
- secure
-- Secure-channel TLS. -
No TLS encryption -
- -At the "none" TLS security level, TLS encryption is -disabled. This is the default security level. With Postfix 2.3 and later, -it can be configured explicitly by setting "smtp_tls_security_level = none".
- -With Postfix 2.2 and earlier, or when smtp_tls_security_level is set to -its default (backwards compatible) empty value, the appropriate configuration -settings are "smtp_use_tls = no" and "smtp_enforce_tls = no". -With either approach, TLS is not used even if supported by the server. -For LMTP, use the corresponding "lmtp_" parameters.
- -Per destination settings may override this default setting, in which case -TLS is used selectively, only with destinations explicitly configured -for TLS.
- -You can disable TLS for a subset of destinations, while leaving -it enabled for the rest. With the Postfix 2.3 and later TLS policy table, specify the "none" -security level. With the obsolete per-site -table, specify the "NONE" keyword.
- -Opportunistic TLS -
- -At the "may" TLS security level, TLS encryption is opportunistic. -The SMTP transaction is encrypted if the STARTTLS ESMTP feature -is supported by the server. Otherwise, messages are sent in the clear. -With Postfix 2.3 and later, opportunistic TLS can be configured by -setting "smtp_tls_security_level = may". - -
Since sending in the clear is acceptable, demanding stronger -than default TLS security mostly reduces inter-operability. If you -must restrict TLS protocol or cipher selection even with opportunistic -TLS, the "smtp_tls_ciphers" and "smtp_tls_protocols" configuration -parameters (Postfix ≥ 2.6) provide control over the protocols -and cipher grade -used with opportunistic TLS. With earlier releases the opportunistic TLS -cipher grade is always "export" and no protocols are disabled.
- -With Postfix 2.2 and earlier, or when smtp_tls_security_level is -set to its default (backwards compatible) empty value, the appropriate -configuration settings are "smtp_use_tls = yes" and -"smtp_enforce_tls = no". -For LMTP use the corresponding "lmtp_" parameters.
- -With opportunistic TLS, mail delivery continues even if the -server certificate is untrusted or bears the wrong name. Starting -with Postfix 2.3, when the TLS handshake fails for an opportunistic -TLS session, rather than give up on mail delivery, the transaction -is retried with TLS disabled. Trying an unencrypted connection makes -it possible to deliver mail to sites with non-interoperable server -TLS implementations.
- -Opportunistic encryption is never used for LMTP over UNIX-domain -sockets. The communications channel is already confidential without -TLS, so the only potential benefit of TLS is authentication. Do not -configure opportunistic TLS for LMTP deliveries over UNIX-domain sockets. -Only configure TLS for LMTP over UNIX-domain sockets at the -encrypt security level or higher. -Attempts to configure opportunistic encryption of LMTP sessions will -be ignored with a warning written to the mail logs.
- -You can enable opportunistic TLS just for selected destinations. With -the Postfix 2.3 and later TLS policy table, -specify the "may" security level. With the obsolete per-site table, specify the "MAY" keyword.
- -This is the most common security level for TLS protected SMTP -sessions, stronger security is not generally available and, if needed, -is typically only configured on a per-destination basis. See the section -on TLS limitations above.
- -Example:
- --- --/etc/postfix/main.cf: - smtp_tls_security_level = may --Postfix 2.2 syntax:
- --- --/etc/postfix/main.cf: - smtp_use_tls = yes - smtp_enforce_tls = no --Mandatory TLS encryption -
+Mandatory TLS encryption
At the "encrypt" TLS security level, messages are sent only over TLS encrypted sessions. The SMTP transaction is aborted unless @@ -1539,28 +1150,32 @@ use the new policy table instead.
-Certificate fingerprint verification -
+Certificate fingerprint verification
-Certificate fingerprint verification is available with Postfix 2.5 and -later. At this security level ("smtp_tls_security_level = fingerprint"), -no trusted certificate authorities are used or required. The certificate -trust chain, expiration date, ... are not checked. Instead, the -smtp_tls_fingerprint_cert_match parameter or the "match" attribute -in the policy table lists the valid -"fingerprints" of the remote SMTP server certificate.
+Certificate fingerprint verification is available with Postfix +2.5 and later. At this security level ("smtp_tls_security_level = +fingerprint"), no trusted certificate authorities are used or +required. The certificate trust chain, expiration date, ... are +not checked. Instead, the smtp_tls_fingerprint_cert_match parameter +or the "match" attribute in the policy +table lists the remote SMTP server certificate fingerprint or +public key fingerprint (Postfix 2.9 and later).
If certificate fingerprints are exchanged securely, this is the -strongest, and least scalable security level. The administrator needs to -securely collect the fingerprints of the X.509 certificates of each peer -server, store them into a local file, and update this local file -whenever the peer server's public certificate -changes. This may be feasible for an SMTP "VPN" connecting a small -number of branch offices over the Internet, or for secure connections -to a central mail hub. It works poorly if the remote SMTP server is -managed by a -third party, and its public certificate changes periodically without -prior coordination with the verifying site.
+strongest, and least scalable security level. The administrator needs +to securely collect the fingerprints of the X.509 certificates of each +peer server, store them into a local file, and update this local file +whenever the peer server's public certificate changes. If public key +fingerprints are used in place of fingerprints of the entire certificate, +the fingerprints remain valid even after the certificate is renewed, +provided that the same public/private keys are used to obtain +the new certificate. + +Fingerprint verification may be feasible for an SMTP "VPN" connecting +a small number of branch offices over the Internet, or for secure +connections to a central mail hub. It works poorly if the remote SMTP +server is managed by a third party, and its public certificate changes +periodically without prior coordination with the verifying site.
The digest algorithm used to calculate the fingerprint is selected by the smtp_tls_fingerprint_digest parameter. In the -
+Mandatory server certificate verification -
+Mandatory server certificate verification
At the "verify" TLS security level, messages are sent only over TLS encrypted sessions if the remote SMTP server certificate is @@ -1694,8 +1308,7 @@ to example.com recipients uses "high" grade ciphers.
-Secure server certificate verification -
+Secure server certificate verification
At the secure TLS security level, messages are sent only over secure-channel TLS sessions where DNS forgery resistant server @@ -1783,78 +1396,410 @@ the first approach is more appropriate in most cases.
+ +/etc/postfix/main.cf: - smtp_tls_CAfile = /etc/postfix/CAfile.pem - smtp_tls_policy_maps = hash:/etc/postfix/tls_policy - -/etc/postfix/transport: - -/etc/postfix/tls_policy: - example.com secure - example.co.uk secure match=example.com:.example.com - example.co.jp secure match=example.com:.example.com + smtp_tls_CAfile = /etc/postfix/CAfile.pem + smtp_tls_policy_maps = hash:/etc/postfix/tls_policy + +/etc/postfix/transport: + +/etc/postfix/tls_policy: + example.com secure + example.co.uk secure match=example.com:.example.com + example.co.jp secure match=example.com:.example.com ++Secure-channel TLS with transport(5) table overrides:
+ +
In this case traffic to example.com and its related domains +is sent to a single logical gateway (to avoid a single point of failure, +its name may resolve to one or more load-balancer addresses, or to the +combined addresses of multiple physical hosts). All the physical hosts +reachable via the gateway's IP addresses have the logical gateway name +listed in their certificates. This secure-channel configuration can also +be implemented via a hardened variant of +the MUST policy in the obsolete per-site +table. As stated above, this approach has the potential to mis-deliver +email if the related domains change hands.
+ +++ ++/etc/postfix/main.cf: + smtp_tls_CAfile = /etc/postfix/CAfile.pem + transport_maps = hash:/etc/postfix/transport + smtp_tls_policy_maps = hash:/etc/postfix/tls_policy + +/etc/postfix/transport: + example.com smtp:[tls.example.com] + example.co.uk smtp:[tls.example.com] + example.co.jp smtp:[tls.example.com] + +/etc/postfix/tls_policy: + [tls.example.com] secure match=tls.example.com ++Postfix 2.2.9 and later syntax:
+ +Note: Avoid policy lookups with the bare hostname (for +example, "tls.example.com"). Instead, use the destination (for +example, "[tls.example.com]") as the per-site table lookup key (a recipient domain +or MX-enabled transport nexthop with no port suffix may look like a bare +hostname, but is still a suitable destination). With Postfix 2.3 +and later, +do not use the obsolete per-site table; +use the new policy table instead.
+ +++ ++/etc/postfix/main.cf: + smtp_cname_overrides_servername = no + smtp_tls_CAfile = /etc/postfix/CAfile.pem + transport_maps = hash:/etc/postfix/transport + smtp_tls_per_site = hash:/etc/postfix/tls_per_site + +/etc/postfix/transport: + example.com smtp:[tls.example.com] + example.co.uk smtp:[tls.example.com] + example.co.jp smtp:[tls.example.com] + +/etc/postfix/tls_per_site: + [tls.example.com] MUST ++Client-side TLS activity logging
+ +To get additional information about Postfix SMTP client TLS +activity you can increase the loglevel from 0..4. Each logging +level also includes the information that is logged at a lower +logging level.
+ ++ ++ ++ +
+ ++ + Level Postfix 2.9 and later Earlier +releases. + + 0 Log only a summary +message on TLS handshake completion — no logging of remote +SMTP server certificate trust-chain verification errors if server +certificate verification is not required. +Disable logging of TLS activity. + + 1 Also log remote +SMTP server trust-chain verification errors and peer certificate +summary information. Also log TLS handshake +and certificate information. + + 2 Also +log levels during TLS negotiation. + + 3 Also +log hexadecimal and ASCII dump of TLS negotiation process. ++ + 4 Also +log hexadecimal and ASCII dump of complete transmission after +STARTTLS. Example:
+ +++ ++/etc/postfix/main.cf: + smtp_tls_loglevel = 0 ++Client-side certificate and private +key configuration
+ +Do not configure Postfix SMTP client certificates unless you must +present +client TLS certificates to one or more servers. Client certificates are +not usually needed, and can cause problems in configurations that work +well without them. The recommended setting is to let the defaults stand:
+ +++ ++ smtp_tls_cert_file = + smtp_tls_dcert_file = + smtp_tls_key_file = + smtp_tls_dkey_file = + # Postfix ≥ 2.6 + smtp_tls_eccert_file = + smtp_tls_eckey_file = ++The best way to use the default settings is to comment out the above +parameters in main.cf if present.
+ +During TLS startup negotiation the Postfix SMTP client may present +a certificate to the remote SMTP server. The Netscape client is +rather clever here and lets the user select between only those +certificates that match CA certificates offered by the remote SMTP +server. As the Postfix SMTP client uses the "SSL_connect()" function +from the OpenSSL package, this is not possible and we have to choose +just one certificate. So for now the default is to use _no_ +certificate and key unless one is explicitly specified here.
+ +RSA, DSA and ECDSA (Postfix ≥ 2.6) certificates are supported. +You can configure all three at the same time, in which case the +cipher used determines which certificate is presented.
+ +It is possible for the Postfix SMTP client to use the same +key/certificate pair as the Postfix SMTP server. If a certificate +is to be presented, it must be in "PEM" format. The private key +must not be encrypted, meaning: it must be accessible without +password. Both parts (certificate and private key) may be in the +same file.
+ +To enable remote SMTP servers to verify the Postfix SMTP client +certificate, the issuing CA certificates must be made available to the +server. You should include the required certificates in the client +certificate file, the client certificate first, then the issuing +CA(s) (bottom-up order).
+ +Example: the certificate for "client.example.com" was issued by +"intermediate CA" which itself has a certificate issued by "root CA". +Create the client.pem file with:
+ +++ ++% cat client_cert.pem intermediate_CA.pem > client.pem ++A Postfix SMTP client certificate supplied here must be usable +as SSL client certificate and hence pass the "openssl verify -purpose +sslclient ..." test.
+ +A server that trusts the root CA has a local copy of the root +CA certificate, so it is not necessary to include the root CA +certificate here. Leaving it out of the "client.pem" file reduces +the overhead of the TLS exchange.
+ +If you want the Postfix SMTP client to accept remote SMTP server +certificates issued by these CAs, append the root certificate to +$smtp_tls_CAfile or install it in the $smtp_tls_CApath directory.
+ +RSA key and certificate examples:
+ +++ ++/etc/postfix/main.cf: + smtp_tls_cert_file = /etc/postfix/client.pem + smtp_tls_key_file = $smtp_tls_cert_file ++Their DSA counterparts:
+ +++ ++/etc/postfix/main.cf: + smtp_tls_dcert_file = /etc/postfix/client-dsa.pem + smtp_tls_dkey_file = $smtp_tls_dcert_file ++Their ECDSA counterparts (Postfix ≥ 2.6 + OpenSSL ≥ 0.9.9):
+ +++ ++/etc/postfix/main.cf: + smtp_tls_eccert_file = /etc/postfix/client-ecdsa.pem + smtp_tls_eckey_file = $smtp_tls_eccert_file ++To verify a remote SMTP server certificate, the Postfix SMTP +client needs to trust the certificates of the issuing certification +authorities. These certificates in "pem" format can be stored in a +single $smtp_tls_CAfile or in multiple files, one CA per file in +the $smtp_tls_CApath directory. If you use a directory, don't forget +to create the necessary "hash" links with:
+ +++ ++# $OPENSSL_HOME/bin/c_rehash /path/to/directory ++The $smtp_tls_CAfile contains the CA certificates of one or more +trusted CAs. The file is opened (with root privileges) before Postfix +enters the optional chroot jail and so need not be accessible from inside the +chroot jail.
+ +Additional trusted CAs can be specified via the $smtp_tls_CApath +directory, in which case the certificates are read (with $mail_owner +privileges) from the files in the directory when the information +is needed. Thus, the $smtp_tls_CApath directory needs to be accessible +inside the optional chroot jail.
+ +The choice between $smtp_tls_CAfile and $smtp_tls_CApath is +a space/time tradeoff. If there are many trusted CAs, the cost of +preloading them all into memory may not pay off in reduced access time +when the certificate is needed.
+ +Example:
+ ++-+/etc/postfix/main.cf: + smtp_tls_CAfile = /etc/postfix/CAcert.pem + smtp_tls_CApath = /etc/postfix/certsSecure-channel TLS with transport(5) table overrides:
+
Client-side TLS session cache
+ +The remote SMTP server and the Postfix SMTP client negotiate a +session, which takes some computer time and network bandwidth. By +default, this session information is cached only in the smtp(8) +process actually using this session and is lost when the process +terminates. To share the session information between multiple +smtp(8) processes, a persistent session cache can be used. You +can specify any database type that can store objects of several +kbytes and that supports the sequence operator. DBM databases are +not suitable because they can only store small objects. The cache +is maintained by the tlsmgr(8) process, so there is no problem with +concurrent access. Session caching is highly recommended, because +the cost of repeatedly negotiating TLS session keys is high. Future +Postfix SMTP servers may limit the number of sessions that a client +is allowed to negotiate per unit time.
-In this case traffic to example.com and its related domains -is sent to a single logical gateway (to avoid a single point of failure, -its name may resolve to one or more load-balancer addresses, or to the -combined addresses of multiple physical hosts). All the physical hosts -reachable via the gateway's IP addresses have the logical gateway name -listed in their certificates. This secure-channel configuration can also -be implemented via a hardened variant of -the MUST policy in the obsolete per-site -table. As stated above, this approach has the potential to mis-deliver -email if the related domains change hands.
+Example:
+-/etc/postfix/main.cf: - smtp_tls_CAfile = /etc/postfix/CAfile.pem - transport_maps = hash:/etc/postfix/transport - smtp_tls_policy_maps = hash:/etc/postfix/tls_policy - -/etc/postfix/transport: - example.com smtp:[tls.example.com] - example.co.uk smtp:[tls.example.com] - example.co.jp smtp:[tls.example.com] - -/etc/postfix/tls_policy: - [tls.example.com] secure match=tls.example.com + smtp_tls_session_cache_database = btree:/var/lib/postfix/smtp_scachePostfix 2.2.9 and later syntax:
+Note: as of version 2.5, Postfix no longer uses root privileges +when opening this file. The file should now be stored under the +Postfix-owned data_directory. As a migration aid, an attempt to +open the file under a non-Postfix directory is redirected to the +Postfix-owned data_directory, and a warning is logged.
-Note: Avoid policy lookups with the bare hostname (for -example, "tls.example.com"). Instead, use the destination (for -example, "[tls.example.com]") as the per-site table lookup key (a recipient domain -or MX-enabled transport nexthop with no port suffix may look like a bare -hostname, but is still a suitable destination). With Postfix 2.3 -and later, -do not use the obsolete per-site table; -use the new policy table instead.
+Cached Postfix SMTP client session information expires after +a certain amount of time. Postfix/TLS does not use the OpenSSL +default of 300s, but a longer time of 3600s (=1 hour). RFC 2246 +recommends a maximum of 24 hours.
+Example:
++/etc/postfix/main.cf: - smtp_cname_overrides_servername = no - smtp_tls_CAfile = /etc/postfix/CAfile.pem - transport_maps = hash:/etc/postfix/transport - smtp_tls_per_site = hash:/etc/postfix/tls_per_site - -/etc/postfix/transport: - example.com smtp:[tls.example.com] - example.co.uk smtp:[tls.example.com] - example.co.jp smtp:[tls.example.com] - -/etc/postfix/tls_per_site: - [tls.example.com] MUST + smtp_tls_session_cache_timeout = 3600sClient TLS limitations +
+ +The security properties of TLS communication channels are +application specific. While the TLS protocol can provide a confidential, +tamper-resistant, mutually authenticated channel between client +and server, not all of these security features are applicable to every +communication.
+ +For example, while mutual TLS authentication between browsers and web +servers is possible, it is not practical, or even useful, for web-servers +that serve the public to verify the identity of every potential user. In +practice, most HTTPS transactions are asymmetric: the browser verifies +the HTTPS server's identity, but the user remains anonymous. Much of +the security policy is up to the client. If the client chooses to not +verify the server's name, the server is not aware of this. There are many +interesting browser security topics, but we shall not dwell +on them here. Rather, our goal is to understand the security features +of TLS in conjunction with SMTP.
+ +An important SMTP-specific observation is that a public MX host is +even more at the mercy of the SMTP client than is an HTTPS server. Not only +can it not enforce due care in the client's use of TLS, but it cannot even +enforce the use of TLS, because TLS support in SMTP clients is still the +exception rather than the rule. One cannot, in practice, limit access to +one's MX hosts to just TLS-enabled clients. Such a policy would result +in a vast reduction in one's ability to communicate by email with the +world at large.
+ +One may be tempted to try enforcing TLS for mail from specific +sending organizations, but this, too, runs into obstacles. One such +obstacle is that we don't know who is (allegedly) sending mail until +we see the "MAIL FROM:" SMTP command, and at that point, if TLS +is not already in use, a potentially sensitive sender address (and +with SMTP PIPELINING one or more of the recipients) has (have) already been +leaked in the clear. Another obstacle is that mail from the sender to +the recipient may be forwarded, and the forwarding organization may not +have any security arrangements with the final destination. Bounces also +need to be protected. These can only be identified by the IP address and +HELO name of the connecting client, and it is difficult to keep track +of all the potential IP addresses or HELO names of the outbound email +servers of the sending organization.
+ +Consequently, TLS security for mail delivery to public MX hosts is +almost entirely the client's responsibility. The server is largely a +passive enabler of TLS security, the rest is up to the client. While the +server has a greater opportunity to mandate client security policy when +it is a dedicated MSA that only handles outbound mail from trusted clients, +below we focus on the client security policy.
+ +On the SMTP client, there are further complications. When delivering +mail to a given domain, in contrast to HTTPS, one rarely uses the domain +name directly as the target host of the SMTP session. More typically, +one uses MX lookups - these are usually unauthenticated - to obtain the domain's SMTP server +hostname(s). When, as is current practice, the client verifies the +insecurely obtained MX hostname, it is subject to a DNS man-in-the-middle +attack.
+ +If clients instead attempted to verify the recipient domain name, +an SMTP server for multiple domains would need to +list all its email domain names in its certificate, and generate a +new certificate each time a new domain were added. At least some CAs set +fairly low limits (20 for one prominent CA) on the number of names that +server certificates can contain. This approach is not consistent with +current practice and does not scale.
+ +It is regrettably the case that TLS secure-channels +(fully authenticated and immune to man-in-the-middle attacks) impose +constraints on the sending and receiving sites that preclude ubiquitous +deployment. One needs to manually configure this type of security for +each destination domain, and in many cases implement non-default TLS +policy table entries for additional +domains hosted at a common secured destination. With Postfix 2.3, we +make secure-channel configurations substantially easier to configure, +but they will never be the norm. For the generic domain with which you +have made no specific security arrangements, this security level is not +a good fit.
+ +Given that strong authentication is not generally possible, and that +verifiable certificates cost time and money, many servers that implement +TLS use self-signed certificates or private CAs. This further limits +the applicability of verified TLS on the public Internet.
+ +Historical note: while the documentation of these issues and many of the +related features are new with Postfix 2.3, the issue was well +understood before Postfix 1.0, when Lutz Jänicke was designing +the first unofficial Postfix TLS patch. See his original post http://www.imc.org/ietf-apps-tls/mail-archive/msg00304.html +and the first response http://www.imc.org/ietf-apps-tls/mail-archive/msg00305.html. +The problem is not even unique to SMTP or even TLS, similar issues exist +for secure connections via aliases for HTTPS and Kerberos. SMTP merely +uses indirect naming (via MX records) more frequently.
+TLS policy table
@@ -1927,8 +1872,9 @@ fingerprint verification. Available with Postfix 2.5 and later. At this security level, there are no trusted certificate authorities. The certificate trust chain, expiration date, ... are not checked. Instead, the optional match attribute, or else -the main.cf smtp_tls_fingerprint_cert_match parameter, -lists the valid fingerprints of the server certificate. The +the main.cf smtp_tls_fingerprint_cert_match parameter, lists +the server certificate fingerprints or public key fingerprints +(Postfix 2.9 and later). The digest algorithm used to calculate fingerprints is selected by the smtp_tls_fingerprint_digest parameter. Multiple fingerprints can be combined with a "|" delimiter in a single match attribute, or multiple @@ -2665,6 +2611,82 @@ but don't require them from all clients.Building Postfix with TLS support
+ +These instructions assume that you build Postfix from source +code as described in the INSTALL document. Some modification may +be required if you build Postfix from a vendor-specific source +package.
+ +To build Postfix with TLS support, first we need to generate +the make(1) files with the necessary definitions. This is +done by invoking the command "make makefiles" in the Postfix +top-level directory and with arguments as shown next.
+ +NOTE: Do not use Gnu TLS. It will spontaneously terminate +a Postfix daemon process with exit status code 2, instead of allowing +Postfix to 1) report the error to the maillog file, and to 2) provide +plaintext service where this is appropriate.
+ ++ +
+ +If the OpenSSL include files (such as ssl.h) are +in directory /usr/include/openssl, and the OpenSSL libraries +(such as libssl.so and libcrypto.so) are in +directory /usr/lib:
+ +++ ++% make tidy # if you have left-over files from a previous build +% make makefiles CCARGS="-DUSE_TLS" AUXLIBS="-lssl -lcrypto" ++If the OpenSSL include files (such as ssl.h) are +in directory /usr/local/include/openssl, and the OpenSSL +libraries (such as libssl.so and libcrypto.so) +are in directory /usr/local/lib:
+ +++ ++% make tidy # if you have left-over files from a previous build +% make makefiles CCARGS="-DUSE_TLS -I/usr/local/include" \ + AUXLIBS="-L/usr/local/lib -lssl -lcrypto" ++On Solaris, specify the -R option as shown below: + +
++ ++% make tidy # if you have left-over files from a previous build +% make makefiles CCARGS="-DUSE_TLS -I/usr/local/include" \ + AUXLIBS="-R/usr/local/lib -L/usr/local/lib -lssl -lcrypto" ++If you need to apply other customizations (such as Berkeley DB +databases, MySQL, PostgreSQL, LDAP or SASL), see the respective +Postfix README documents, and combine their "make makefiles" +instructions with the instructions above:
+ +++ ++% make tidy # if you have left-over files from a previous build +% make makefiles CCARGS="-DUSE_TLS \ + (other -D or -I options)" \ + AUXLIBS="-lssl -lcrypto \ + (other -l options for libraries in /usr/lib) \ + (-L/path/name + -l options for other libraries)" ++To complete the build process, see the Postfix INSTALL +instructions. Postfix has TLS support turned off by default, so +you can start using Postfix as soon as it is installed.
+Reporting problems
Problems are preferably reported via <postfix-users@postfix.org>. diff --git a/postfix/proto/postconf.proto b/postfix/proto/postconf.proto index 2177c3a0b..b34499579 100644 --- a/postfix/proto/postconf.proto +++ b/postfix/proto/postconf.proto @@ -1070,7 +1070,7 @@ in the master.cf file. %PARAM default_rbl_reply see "postconf -d" output
-The default SMTP server response template for a request that is +The default Postfix SMTP server response template for a request that is rejected by an RBL-based restriction. This template can be overruled by specific entries in the optional rbl_reply_maps lookup table.
@@ -1833,7 +1833,7 @@ turned on by default (it's disabled on SCO UNIX due to an SCO bug).-With the default 100 SMTP server process limit, "in_flow_delay +With the default 100 Postfix SMTP server process limit, "in_flow_delay = 1s" limits the mail inflow to 100 messages per second above the number of messages delivered per second.
@@ -1866,7 +1866,8 @@ for IPv6 is available in Postfix version 2.2 and later.On a multi-homed firewall with separate Postfix instances listening on the "inside" and "outside" interfaces, this can prevent each instance from -being able to reach servers on the "other side" of the firewall. Setting +being able to reach remote SMTP servers on the "other side" of the +firewall. Setting smtp_bind_address to 0.0.0.0 avoids the potential problem for IPv4, and setting smtp_bind_address6 to :: solves the problem for IPv6.
@@ -1985,9 +1986,9 @@ Do not change this unless you have a complete understanding of RFC 2821.The time after which a client closes an idle internal communication -channel. The purpose is to allow servers to terminate voluntarily -after they become idle. This is used, for example, by the address -resolving and rewriting clients. +channel. The purpose is to allow Postfix daemon processes to +terminate voluntarily after they become idle. This is used, for +example, by the Postfix address resolving and rewriting clients.
With Postfix 2.4 the default value was reduced from 100s to 5s.
@@ -2015,9 +2016,10 @@ The default time unit is s (seconds).The time after which a client closes an active internal communication -channel. The purpose is to allow servers to terminate voluntarily +channel. The purpose is to allow Postfix daemon processes to +terminate voluntarily after reaching their client limit. This is used, for example, by -the address resolving and rewriting clients. +the Postfix address resolving and rewriting clients.
@@ -2036,7 +2038,7 @@ this length; upon delivery, long lines are reconstructed.
%PARAM lmtp_connect_timeout 0s -The LMTP client time limit for completing a TCP connection, or +
The Postfix LMTP client time limit for completing a TCP connection, or zero (use the operating system built-in time limit). When no connection can be made within the deadline, the LMTP client tries the next address on the mail exchanger list.
@@ -2056,10 +2058,10 @@ lmtp_connect_timeout = 30s %PARAM lmtp_data_done_timeout 600s -The LMTP client time limit for sending the LMTP ".", and for -receiving the server response. When no response is received within -the deadline, a warning is logged that the mail may be delivered -multiple times.
+The Postfix LMTP client time limit for sending the LMTP ".", +and for receiving the remote LMTP server response. When no response +is received within the deadline, a warning is logged that the mail +may be delivered multiple times.
Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks). @@ -2069,8 +2071,9 @@ The default time unit is s (seconds). %PARAM lmtp_data_init_timeout 120s
-The LMTP client time limit for sending the LMTP DATA command, and -for receiving the server response. +The Postfix LMTP client time limit for sending the LMTP DATA command, +and +for receiving the remote LMTP server response.
@@ -2081,7 +2084,8 @@ The default time unit is s (seconds). %PARAM lmtp_data_xfer_timeout 180s
-The LMTP client time limit for sending the LMTP message content. +The Postfix LMTP client time limit for sending the LMTP message +content. When the connection stalls for more than $lmtp_data_xfer_timeout the LMTP client terminates the transfer.
@@ -2093,8 +2097,9 @@ The default time unit is s (seconds). %PARAM lmtp_lhlo_timeout 300s -The LMTP client time limit for receiving the LMTP greeting -banner. When the server drops the connection without sending a +
The Postfix LMTP client time limit for receiving the LMTP +greeting banner. When the remote LMTP server drops the connection +without sending a greeting banner, or when it sends no greeting banner within the deadline, the LMTP client tries the next address on the mail exchanger list.
@@ -2107,8 +2112,8 @@ The default time unit is s (seconds). %PARAM lmtp_mail_timeout 300s-The LMTP client time limit for sending the MAIL FROM command, and -for receiving the server response. +The Postfix LMTP client time limit for sending the MAIL FROM command, +and for receiving the remote LMTP server response.
@@ -2119,8 +2124,8 @@ The default time unit is s (seconds). %PARAM lmtp_quit_timeout 300s
-The LMTP client time limit for sending the QUIT command, and for -receiving the server response. +The Postfix LMTP client time limit for sending the QUIT command, +and for receiving the remote LMTP server response.
@@ -2131,8 +2136,8 @@ The default time unit is s (seconds). %PARAM lmtp_rcpt_timeout 300s
-The LMTP client time limit for sending the RCPT TO command, and -for receiving the server response. +The Postfix LMTP client time limit for sending the RCPT TO command, +and for receiving the remote LMTP server response.
@@ -2142,8 +2147,9 @@ The default time unit is s (seconds). %PARAM lmtp_rset_timeout 20s -
The LMTP client time limit for sending the RSET command, and -for receiving the server response. The LMTP client sends RSET in +
The Postfix LMTP client time limit for sending the RSET command, +and for receiving the remote LMTP server response. The LMTP client +sends RSET in order to finish a recipient address probe, or to verify that a cached connection is still alive.
@@ -2155,7 +2161,7 @@ The default time unit is s (seconds). %PARAM lmtp_send_xforward_command no-Send an XFORWARD command to the LMTP server when the LMTP LHLO +Send an XFORWARD command to the remote LMTP server when the LMTP LHLO server response announces XFORWARD support. This allows an lmtp(8) delivery agent, used for content filter message injection, to forward the name, address, protocol and HELO name of the original @@ -2177,8 +2183,8 @@ Wait for the response to the LMTP QUIT command. %PARAM lmtp_xforward_timeout 300s
-The LMTP client time limit for sending the XFORWARD command, and -for receiving the server response. +The Postfix LMTP client time limit for sending the XFORWARD command, +and for receiving the remote LMTP server response.
@@ -2934,7 +2940,7 @@ myhostname = host.example.com %PARAM mynetworks see "postconf -d" output
-The list of "trusted" SMTP clients that have more privileges than +The list of "trusted" remote SMTP clients that have more privileges than "strangers".
@@ -3181,7 +3187,8 @@ parameter is 1. %PARAM qmqpd_authorized_clients-What clients are allowed to connect to the QMQP server port. +What remote QMQP clients are allowed to connect to the Postfix QMQP +server port.
@@ -3215,9 +3222,9 @@ qmqpd_authorized_clients = !192.168.0.1, 192.168.0.0/24 %PARAM qmqpd_error_delay 1s
-How long the QMQP server will pause before sending a negative reply -to the client. The purpose is to slow down confused or malicious -clients. +How long the Postfix QMQP server will pause before sending a negative +reply to the remote QMQP client. The purpose is to slow down confused +or malicious clients.
@@ -3230,7 +3237,7 @@ The default time unit is s (seconds).
The time limit for sending or receiving information over the network. If a read or write operation blocks for more than $qmqpd_timeout -seconds the QMQP server gives up and disconnects. +seconds the Postfix QMQP server gives up and disconnects.
@@ -3242,8 +3249,8 @@ The default time unit is s (seconds).
The minimal amount of free space in bytes in the queue file system -that is needed to receive mail. This is currently used by the SMTP -server to decide if it will accept any mail at all. +that is needed to receive mail. This is currently used by the +Postfix SMTP server to decide if it will accept any mail at all.
@@ -3719,7 +3726,8 @@ Always send EHLO at the start of an SMTP session.
-With "smtp_always_send_ehlo = no", Postfix sends EHLO only when +With "smtp_always_send_ehlo = no", the Postfix SMTP client sends +EHLO only when the word "ESMTP" appears in the server greeting banner (example: 220 spike.porcupine.org ESMTP Postfix).
@@ -3901,7 +3909,7 @@ delivery performance. %PARAM smtp_connect_timeout 30s-The SMTP client time limit for completing a TCP connection, or +The Postfix SMTP client time limit for completing a TCP connection, or zero (use the operating system built-in time limit).
@@ -3921,8 +3929,8 @@ The default time unit is s (seconds). %PARAM smtp_data_done_timeout 600s-The SMTP client time limit for sending the SMTP ".", and for receiving -the server response. +The Postfix SMTP client time limit for sending the SMTP ".", and +for receiving the remote SMTP server response.
@@ -3938,8 +3946,8 @@ The default time unit is s (seconds). %PARAM smtp_data_init_timeout 120s
-The SMTP client time limit for sending the SMTP DATA command, and for -receiving the server response. +The Postfix SMTP client time limit for sending the SMTP DATA command, +and for receiving the remote SMTP server response.
@@ -3950,7 +3958,7 @@ The default time unit is s (seconds). %PARAM smtp_data_xfer_timeout 180s
-The SMTP client time limit for sending the SMTP message content. +The Postfix SMTP client time limit for sending the SMTP message content. When the connection makes no progress for more than $smtp_data_xfer_timeout seconds the Postfix SMTP client terminates the transfer.
@@ -3973,7 +3981,8 @@ until someone fixed the MX record or until the mail was too old.-Note: Postfix always ignores MX records with equal or worse preference +Note: the Postfix SMTP client always ignores MX records with equal +or worse preference than the local MTA itself.
@@ -4088,8 +4097,8 @@ This feature is available in Postfix 2.0 and later. %PARAM smtp_helo_timeout 300s-The SMTP client time limit for sending the HELO or EHLO command, -and for receiving the initial server response. +The Postfix SMTP client time limit for sending the HELO or EHLO command, +and for receiving the initial remote SMTP server response.
@@ -4150,8 +4159,8 @@ and earlier. %PARAM smtp_mail_timeout 300s
-The SMTP client time limit for sending the MAIL FROM command, and -for receiving the server response. +The Postfix SMTP client time limit for sending the MAIL FROM command, +and for receiving the remote SMTP server response.
@@ -4163,7 +4172,8 @@ The default time unit is s (seconds).
The maximal number of MX (mail exchanger) IP addresses that can -result from mail exchanger lookups, or zero (no limit). Prior to +result from Postfix SMTP client mail exchanger lookups, or zero (no +limit). Prior to Postfix version 2.3, this limit was disabled by default.
@@ -4174,7 +4184,8 @@ This feature is available in Postfix 2.1 and later. %PARAM smtp_mx_session_limit 2The maximal number of SMTP sessions per delivery request before -giving up or delivering to a fall-back relay host, or zero (no +the Postfix SMTP client +gives up or delivers to a fall-back relay host, or zero (no limit). This restriction ignores sessions that fail to complete the SMTP initial handshake (Postfix version 2.2 and earlier) or that fail to complete the EHLO and TLS handshake (Postfix version 2.3 and later).
@@ -4208,8 +4219,8 @@ first delivery attempt. %PARAM smtp_quit_timeout 300s-The SMTP client time limit for sending the QUIT command, and for -receiving the server response. +The Postfix SMTP client time limit for sending the QUIT command, +and for receiving the remote SMTP server response.
@@ -4220,7 +4231,8 @@ The default time unit is s (seconds). %PARAM smtp_quote_rfc821_envelope yes
-Quote addresses in SMTP MAIL FROM and RCPT TO commands as required +Quote addresses in Postfix SMTP client MAIL FROM and RCPT TO commands +as required by RFC 2821. This includes putting quotes around an address localpart that ends in ".".
@@ -4249,8 +4261,8 @@ This feature is available in Postfix 2.1 and later. %PARAM smtp_rcpt_timeout 300s-The SMTP client time limit for sending the SMTP RCPT TO command, and -for receiving the server response. +The Postfix SMTP client time limit for sending the SMTP RCPT TO +command, and for receiving the remote SMTP server response.
@@ -4276,7 +4288,8 @@ smtp_sasl_auth_enable = yes %PARAM smtp_sasl_password_maps
-Optional SMTP client lookup tables with one username:password entry +Optional Postfix SMTP client lookup tables with one username:password +entry per remote hostname or domain, or sender address when sender-dependent authentication is enabled. If no username:password entry is found, then the Postfix SMTP client will not @@ -4372,7 +4385,8 @@ EHLO response announces XFORWARD support.
-This allows an "smtp" delivery agent, used for injecting mail into +This allows a Postfix SMTP delivery agent, used for injecting mail +into a content filter, to forward the name, address, protocol and HELO name of the original client to the content filter and downstream queuing SMTP server. This can produce more useful logging than @@ -4391,19 +4405,22 @@ again later).
-By default, Postfix moves on the next mail exchanger. Specify +By default, the Postfix SMTP client moves on the next mail exchanger. +Specify "smtp_skip_4xx_greeting = no" if Postfix should defer delivery immediately.
This feature is available in Postfix 2.0 and earlier. -Later Postfix versions always skip SMTP servers that greet with a +Later Postfix versions always skip remote SMTP servers that greet +with a 4XX status code.
%PARAM smtp_skip_5xx_greeting yes-Skip SMTP servers that greet with a 5XX status code (go away, do +Skip remote SMTP servers that greet with a 5XX status code (go away, +do not try again later).
@@ -4421,8 +4438,8 @@ Do not wait for the response to the SMTP QUIT command. %PARAM smtp_xforward_timeout 300s-The SMTP client time limit for sending the XFORWARD command, and -for receiving the server response. +The Postfix SMTP client time limit for sending the XFORWARD command, +and for receiving the remote SMTP server response.
@@ -4436,7 +4453,7 @@ This feature is available in Postfix 2.1 and later. %PARAM authorized_verp_clients $mynetworks -
What SMTP clients are allowed to specify the XVERP command. +
What remote SMTP clients are allowed to specify the XVERP command. This command requests that mail be delivered one recipient at a time with a per recipient return address.
@@ -4467,7 +4484,7 @@ pattern. %PARAM smtpd_authorized_verp_clients $authorized_verp_clients -What SMTP clients are allowed to specify the XVERP command. +
What remote SMTP clients are allowed to specify the XVERP command. This command requests that mail be delivered one recipient at a time with a per recipient return address.
@@ -4497,8 +4514,8 @@ pattern. %PARAM smtpd_authorized_xclient_hosts-What SMTP clients are allowed to use the XCLIENT feature. This -command overrides SMTP client information that is used for access +What remote SMTP clients are allowed to use the XCLIENT feature. This +command overrides remote SMTP client information that is used for access control. Typical use is for SMTP-based content filters, fetchmail-like programs, or SMTP server access rule testing. See the XCLIENT_README document for details. @@ -4534,7 +4551,7 @@ pattern.
%PARAM smtpd_authorized_xforward_hosts-What SMTP clients are allowed to use the XFORWARD feature. This +What remote SMTP clients are allowed to use the XFORWARD feature. This command forwards information that is used to improve logging after SMTP-based content filters. See the XFORWARD_README document for details. @@ -4777,8 +4794,8 @@ smtpd_client_new_tls_session_rate_limit = 100 %PARAM smtpd_client_restrictions
-Optional SMTP server access restrictions in the context of a client -SMTP connection request. +Optional Postfix SMTP server access restrictions in the context of +a remote SMTP client connection request. See SMTPD_ACCESS_README, section "Delayed evaluation of SMTP access restriction lists" for a discussion of evaluation context and time.
@@ -4803,9 +4820,10 @@ client network address information.check_ccert_access type:table -Use the client certificate fingerprint as lookup key for the -specified access(5) database; with Postfix version 2.2, also require that -the SMTP client certificate is verified successfully. + Use the remote SMTP client certificate fingerprint or the public key +fingerprint (Postfix 2.9 and later) as lookup key for the specified +access(5) database; with Postfix version 2.2, also require that the +remote SMTP client certificate is verified successfully. The fingerprint digest algorithm is configurable via the smtpd_tls_fingerprint_digest parameter (hard-coded as md5 prior to Postfix version 2.5). This feature is available with Postfix version @@ -4889,7 +4907,8 @@ This feature is available with Postfix version 2.2. permit_tls_clientcerts Permit the request when the remote SMTP client certificate -fingerprint is listed in $relay_clientcerts. +fingerprint or public key fingerprint (Postfix 2.9 and later) is +listed in $relay_clientcerts. The fingerprint digest algorithm is configurable via the smtpd_tls_fingerprint_digest parameter (hard-coded as md5 prior to Postfix version 2.5). This feature is available with Postfix version @@ -6743,7 +6762,7 @@ remote_header_rewrite_domain parameter specifies a non-empty value. How long the postkick(1) command waits for a request to enter the -server's input buffer before giving up. +Postfix daemon process input buffer before giving up.
@@ -6888,7 +6907,7 @@ This feature is available in Postfix 2.0 and later. %PARAM broken_sasl_auth_clients no
-Enable inter-operability with SMTP clients that implement an obsolete +Enable inter-operability with remote SMTP clients that implement an obsolete version of the AUTH command (RFC 4954). Examples of such clients are MicroSoft Outlook Express version 4 and MicroSoft Exchange version 5.0. @@ -7296,14 +7315,14 @@ lmtp_connection_cache_destinations, or lmtp_connection_reuse_time_limit.
The effectiveness of cached connections will be determined by the -number of LMTP servers in use, and the concurrency limit specified -for the LMTP client. Cached connections are closed under any of +number of remote LMTP servers in use, and the concurrency limit specified +for the Postfix LMTP client. Cached connections are closed under any of the following conditions:
-
- The LMTP client idle time limit is reached. This limit is +
- The Postfix LMTP client idle time limit is reached. This limit is specified with the Postfix max_idle configuration parameter.
- A delivery request specifies a different destination than the @@ -7313,14 +7332,14 @@ one currently cached. reached. This limit is specified with the Postfix max_use configuration parameter. -
- Upon the onset of another delivery request, the LMTP server +
- Upon the onset of another delivery request, the remote LMTP server associated with the current session does not respond to the RSET command.
-Most of these limitations will be removed after Postfix implements +Most of these limitations have been with the Postfix a connection cache that is shared among multiple LMTP client programs.
@@ -7334,7 +7353,7 @@ Enable SASL authentication in the Postfix LMTP client. %PARAM lmtp_sasl_password_maps-Optional LMTP client lookup tables with one username:password entry +Optional Postfix LMTP client lookup tables with one username:password entry per host or domain. If a remote host or domain has no username:password entry, then the Postfix LMTP client will not attempt to authenticate to the remote host. @@ -7505,12 +7524,12 @@ This is the list of trusted networks for relay access control etc. "trust" only the local machine.
Specify "mynetworks_style = subnet" when Postfix -should "trust" SMTP clients in the same IP subnetworks as the local +should "trust" remote SMTP clients in the same IP subnetworks as the local machine. On Linux, this works correctly only with interfaces specified with the "ifconfig" command.
Specify "mynetworks_style = class" when Postfix should -"trust" SMTP clients in the same IP class A/B/C networks as the +"trust" remote SMTP clients in the same IP class A/B/C networks as the local machine. Don't do this with a dialup site - it would cause Postfix to "trust" your entire provider's network. Instead, specify an explicit mynetworks list by hand, as described with the mynetworks @@ -7842,8 +7861,9 @@ is a performance feature of the Postfix SMTP client. %PARAM smtp_rset_timeout 20s -
The SMTP client time limit for sending the RSET command, and -for receiving the server response. The SMTP client sends RSET in +
The Postfix SMTP client time limit for sending the RSET command, +and for receiving the remote SMTP server response. The SMTP client +sends RSET in order to finish a recipient address probe, or to verify that a cached session is still usable.
@@ -8201,7 +8221,7 @@ This feature is available in Postfix 2.0 and later. %PARAM unknown_virtual_alias_reject_code 550-The SMTP server reply code when a recipient address matches +The Postfix SMTP server reply code when a recipient address matches $virtual_alias_domains, and $virtual_alias_maps specifies a list of lookup tables that does not match the recipient address.
@@ -8213,7 +8233,7 @@ This feature is available in Postfix 2.0 and later. %PARAM unknown_virtual_mailbox_reject_code 550-The SMTP server reply code when a recipient address matches +The Postfix SMTP server reply code when a recipient address matches $virtual_mailbox_domains, and $virtual_mailbox_maps specifies a list of lookup tables that does not match the recipient address.
@@ -8485,7 +8505,8 @@ discard EHLO keywords selectively. %PARAM smtpd_discard_ehlo_keywordsA case insensitive list of EHLO keywords (pipelining, starttls, -auth, etc.) that the SMTP server will not send in the EHLO response +auth, etc.) that the Postfix SMTP server will not send in the EHLO +response to a remote SMTP client.
This feature is available in Postfix 2.2 and later.
@@ -8517,7 +8538,8 @@ smtpd_discard_ehlo_keyword_address_maps.Lookup tables, indexed by the remote SMTP client address, with case insensitive lists of EHLO keywords (pipelining, starttls, auth, -etc.) that the SMTP server will not send in the EHLO response to a +etc.) that the Postfix SMTP server will not send in the EHLO response +to a remote SMTP client. See smtpd_discard_ehlo_keywords for details. The table is not searched by hostname for robustness reasons.
@@ -8614,7 +8636,8 @@ protocol.permit_tls_clientcerts Append the domain name in $myorigin or $mydomain when the -client TLS certificate fingerprint is listed in $relay_clientcerts. +remote SMTP client TLS certificate fingerprint or public key fingerprint +(Postfix 2.9 and later) is listed in $relay_clientcerts. The fingerprint digest algorithm is configurable via the smtpd_tls_fingerprint_digest parameter (hard-coded as md5 prior to Postfix version 2.5). @@ -8622,7 +8645,7 @@ Postfix version 2.5).permit_tls_all_clientcerts Append the domain name in $myorigin or $mydomain when the -client TLS certificate is successfully verified, regardless of +remote SMTP client TLS certificate is successfully verified, regardless of whether it is listed on the server, and regardless of the certifying authority. @@ -8841,22 +8864,28 @@ a lower logging level.-
-- 0 Disable logging of TLS activity.
+- 0 Log only a summary message on TLS handshake completion +— no logging of remote SMTP client certificate trust-chain verification +errors +if client certificate verification is not required. With Postfix 2.8 +and earlier, disable logging of TLS activity.
-- 1 Log TLS handshake and certificate information.
+- 1 Also log trust-chain verification errors and peer +certificate name and issuer. With Postfix 2.8 and earlier, log TLS +handshake and certificate information.
-- 2 Log levels during TLS negotiation.
+- 2 Also log levels during TLS negotiation.
-- 3 Log hexadecimal and ASCII dump of TLS negotiation -process.
+- 3 Also log hexadecimal and ASCII dump of TLS negotiation +process.
- 4 Also log hexadecimal and ASCII dump of complete transmission after STARTTLS.
Use "smtpd_tls_loglevel = 3" only in case of problems. Use of -loglevel 4 is strongly discouraged.
+Do not use "smtpd_tls_loglevel = 2" or higher except in case +of problems. Use of loglevel 4 is strongly discouraged.
This feature is available in Postfix 2.2 and later.
@@ -8864,7 +8893,7 @@ loglevel 4 is strongly discouraged.Request that the Postfix SMTP server produces Received: message headers that include information about the protocol and cipher used, -as well as the client CommonName and client certificate issuer +as well as the remote SMTP client CommonName and client certificate issuer CommonName. This is disabled by default, as the information may be modified in transit through other mail servers. Only information that was recorded by the final destination can be trusted.
@@ -8873,7 +8902,7 @@ that was recorded by the final destination can be trusted. %PARAM smtpd_use_tls no -Opportunistic TLS: announce STARTTLS support to SMTP clients, +
Opportunistic TLS: announce STARTTLS support to remote SMTP clients, but do not require that clients use TLS encryption.
Note: when invoked via "sendmail -bs", Postfix will never offer @@ -8885,7 +8914,7 @@ Postfix 2.3 and later use smtpd_tls_security_level instead.
%PARAM smtpd_enforce_tls no -Mandatory TLS: announce STARTTLS support to SMTP clients, +
Mandatory TLS: announce STARTTLS support to remote SMTP clients, and require that clients use TLS encryption. According to RFC 2487 this MUST NOT be applied in case of a publicly-referenced SMTP server. This option is therefore off by default.
@@ -9006,10 +9035,10 @@ are not possible. %PARAM relay_clientcerts -List of tables with remote SMTP client-certificate fingerprints -for which the Postfix SMTP server will allow access with the -permit_tls_clientcerts feature. -The fingerprint digest algorithm is configurable via the +
List of tables with remote SMTP client-certificate fingerprints or +public key fingerprints (Postfix 2.9 and later) for which the Postfix +SMTP server will allow access with the permit_tls_clientcerts +feature. The fingerprint digest algorithm is configurable via the smtpd_tls_fingerprint_digest parameter (hard-coded as md5 prior to Postfix version 2.5).
@@ -9227,22 +9256,27 @@ a lower logging level.-
-- 0 Disable logging of TLS activity.
+- 0 Log only a summary message on TLS handshake completion +— no logging of remote SMTP server certificate trust-chain +verification errors if server certificate verification is not required. +With Postfix 2.8 and earlier, disable logging of TLS activity.
-- 1 Log TLS handshake and certificate information.
+- 1 Also log remote SMTP server trust-chain verification +errors and peer certificate summary information. With Postfix 2.8 +and earlier, log TLS handshake and certificate information.
-- 2 Log levels during TLS negotiation.
+- 2 Also log levels during TLS negotiation.
-- 3 Log hexadecimal and ASCII dump of TLS negotiation +
- 3 Also log hexadecimal and ASCII dump of TLS negotiation process.
-- 4 Log hexadecimal and ASCII dump of complete +
- 4 Also log hexadecimal and ASCII dump of complete transmission after STARTTLS.
Use "smtp_tls_loglevel = 3" only in case of problems. Use of -loglevel 4 is strongly discouraged.
+Do not use "smtp_tls_loglevel = 2" or higher except in case of +problems. Use of loglevel 4 is strongly discouraged.
This feature is available in Postfix 2.2 and later.
@@ -9596,7 +9630,7 @@ server uses for TLS encrypted SMTP sessions. %PARAM smtp_generic_mapsOptional lookup tables that perform address rewriting in the -SMTP client, typically to transform a locally valid address into +Postfix SMTP client, typically to transform a locally valid address into a globally valid address when sending mail across the Internet. This is needed when the local machine does not have its own Internet domain name, but uses something like localdomain.local @@ -9798,7 +9832,8 @@ This feature is available in Postfix 2.3 and later.
Lookup tables, indexed by the remote LMTP server address, with case insensitive lists of LHLO keywords (pipelining, starttls, -auth, etc.) that the LMTP client will ignore in the LHLO response +auth, etc.) that the Postfix LMTP client will ignore in the LHLO +response from a remote LMTP server. See lmtp_discard_lhlo_keywords for details. The table is not indexed by hostname for consistency with smtpd_discard_ehlo_keyword_address_maps.
@@ -9808,7 +9843,8 @@ smtpd_discard_ehlo_keyword_address_maps. %PARAM lmtp_discard_lhlo_keywordsA case insensitive list of LHLO keywords (pipelining, starttls, -auth, etc.) that the LMTP client will ignore in the LHLO response +auth, etc.) that the Postfix LMTP client will ignore in the LHLO +response from a remote LMTP server.
This feature is available in Postfix 2.3 and later.
@@ -9827,8 +9863,8 @@ discard LHLO keywords selectively. %PARAM lmtp_lhlo_timeout 300s -The LMTP client time limit for sending the LHLO command, and -for receiving the initial server response.
+The Postfix LMTP client time limit for sending the LHLO command, +and for receiving the initial remote LMTP server response.
Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks). The default time unit is s (seconds).
@@ -10203,7 +10239,8 @@ See there for details.Postpone the start of an SMTP mail transaction until a valid RCPT TO command is received. Specify "no" to create a mail transaction -as soon as the SMTP server receives a valid MAIL FROM command.
+as soon as the Postfix SMTP server receives a valid MAIL FROM +command.With sites that reject lots of mail, the default setting reduces the use of @@ -10340,8 +10377,9 @@ verification. Available with Postfix 2.5 and later. At this security level, there are no trusted certificate authorities. The certificate trust chain, expiration date, ... are not checked. Instead, the optional match attribute, or else the main.cf -smtp_tls_fingerprint_cert_match parameter, lists the -valid "fingerprints" of the server certificate. The digest +smtp_tls_fingerprint_cert_match parameter, lists the certificate +fingerprints or the public key fingerprint (Postfix 2.9 and later) +of the valid server certificate. The digest algorithm used to calculate the fingerprint is selected by the smtp_tls_fingerprint_digest parameter. Multiple fingerprints can be combined with a "|" delimiter in a single match attribute, or multiple @@ -10447,7 +10485,8 @@ smtp_tls_mandatory_protocols = !SSLv2, !SSLv3 %PARAM smtp_tls_verify_cert_match hostname -
The server certificate peername verification method for the +
How the Postfix SMTP client verifies the server certificate +peername for the "verify" TLS security level. In a "verify" TLS policy table ($smtp_tls_policy_maps) entry the optional "match" attribute overrides this main.cf setting.
@@ -10523,7 +10562,8 @@ example.com verify match=hostname:nexthop %PARAM smtp_tls_secure_cert_match nexthop, dot-nexthop -The server certificate peername verification method for the +
How the Postfix SMTP client verifies the server certificate +peername for the "secure" TLS security level. In a "secure" TLS policy table ($smtp_tls_policy_maps) entry the optional "match" attribute overrides this main.cf setting.
@@ -10660,9 +10700,10 @@ default for systems delivering mail to the Internet.fingerprint Certificate fingerprint verification. Available with Postfix 2.5 and later. At this security level, there are no trusted certificate authorities. The certificate -trust chain, expiration date, ... are not checked. Instead, -the smtp_tls_fingerprint_cert_match parameter lists -the valid "fingerprints" of the server certificate. The digest +trust chain, expiration date, ... are not checked. Instead, the +smtp_tls_fingerprint_cert_match parameter lists the certificate +fingerprint or public key fingerprint (Postfix 2.9 and later) of +the valid server certificate. The digest algorithm used to calculate the fingerprint is selected by the smtp_tls_fingerprint_digest parameter. @@ -11006,7 +11047,7 @@ TLS.The underlying cipherlists for grades other than "null" include anonymous ciphers, but these are automatically filtered out if the -server is configured to ask for client certificates. You are very +server is configured to ask for remote SMTP client certificates. You are very unlikely to need to take any steps to exclude anonymous ciphers, they are excluded automatically as required. If you must exclude anonymous ciphers even when Postfix does not need or use peer certificates, set @@ -11049,7 +11090,8 @@ key exchange with RSA authentication.
%PARAM smtpd_tls_mandatory_exclude_ciphersAdditional list of ciphers or cipher types to exclude from the -SMTP server cipher list at mandatory TLS security levels. This list +Postfix SMTP server cipher list at mandatory TLS security levels. +This list works in addition to the exclusions listed with smtpd_tls_exclude_ciphers (see there for syntax details).
@@ -11153,7 +11195,7 @@ key exchange with RSA authentication. %PARAM smtp_tls_mandatory_exclude_ciphersAdditional list of ciphers or cipher types to exclude from the -SMTP client cipher list at mandatory TLS security levels. This list +Postfix SMTP client cipher list at mandatory TLS security levels. This list works in addition to the exclusions listed with smtp_tls_exclude_ciphers (see there for syntax details).
@@ -11264,11 +11306,11 @@ smtpd_use_tls and smtpd_enforce_tls. This parameter is ignored withnone TLS will not be used. may Opportunistic TLS: announce STARTTLS support -to SMTP clients, but do not require that clients use TLS encryption. +to remote SMTP clients, but do not require that clients use TLS encryption. encrypt Mandatory TLS encryption: announce -STARTTLS support to SMTP clients, and require that clients use TLS +STARTTLS support to remote SMTP clients, and require that clients use TLS encryption. According to RFC 2487 this MUST NOT be applied in case of a publicly-referenced SMTP server. Instead, this option should be used only on dedicated servers. @@ -11278,7 +11320,7 @@ be used only on dedicated servers.Note 1: the "fingerprint", "verify" and "secure" levels are not supported here. The Postfix SMTP server logs a warning and uses "encrypt" instead. -To verify SMTP client certificates, see TLS_README for a discussion +To verify remote SMTP client certificates, see TLS_README for a discussion of the smtpd_tls_ask_ccert, smtpd_tls_req_ccert, and permit_tls_clientcerts features.
@@ -11321,7 +11363,7 @@ is empty). This behavior is compatible with Postfix < 2.3.With Postfix 2.3 and later the Postfix SMTP server can disable session id generation when TLS session caching is turned off. This -keeps clients from caching sessions that almost certainly cannot +keeps remote SMTP clients from caching sessions that almost certainly cannot be re-used.
By default, the Postfix SMTP server always generates TLS session @@ -11382,11 +11424,13 @@ configuration parameter. See there for details.
The message digest algorithm used to construct remote SMTP server certificate fingerprints. At the "fingerprint" TLS security level (smtp_tls_security_level = fingerprint), the server certificate is -verified by directly matching its fingerprint. The fingerprint -is the message digest of the server certificate using the selected +verified by directly matching its certificate fingerprint or its public +key fingerprint (Postfix 2.9 and later). The fingerprint is the +message digest of the server certificate (or its public key) +using the selected algorithm. With a digest algorithm resistant to "second pre-image" attacks, it is not feasible to create a new public key and a matching -certificate that has the same fingerprint.
+certificate (or public/private key-pair) that has the same fingerprint.The default algorithm is md5; this is consistent with the backwards compatible setting of the digest used to verify client @@ -11422,17 +11466,24 @@ SHA1 Fingerprint=D4:6A:AB:19:24:79:F8:32:BB:A6:CB:66:82:C0:8E:9B:EE:29:A8:1A +
Public key fingerprints are more difficult to extract, however, +the SHA-1 public key fingerprint is often present as the value of the +"Subject Key Identifier" extension in X.509v3 certificates. The Postfix +SMTP server and client log the peer certificate fingerprint and public +key fingerprint when TLS loglevel is 1 or higher.
+This feature is available in Postfix 2.5 and later.
%PARAM smtp_tls_fingerprint_cert_match -List of acceptable remote SMTP server certificate fingerprints -for the "fingerprint" TLS security level (smtp_tls_security_level = -fingerprint). At this security level, certificate authorities are -not used, and certificate expiration times are ignored. Instead, -server certificates are verified directly via their "fingerprint". The -fingerprint is a message digest of the server certificate. The digest -algorithm is selected via the smtp_tls_fingerprint_digest +
List of acceptable remote SMTP server certificate fingerprints for +the "fingerprint" TLS security level (smtp_tls_security_level = +fingerprint). At this security level, certificate authorities are not +used, and certificate expiration times are ignored. Instead, server +certificates are verified directly via their certificate fingerprint +or public key fingerprint (Postfix 2.9 and later). The fingerprint +is a message digest of the server certificate (or public key). The +digest algorithm is selected via the smtp_tls_fingerprint_digest parameter.
When an smtp_tls_policy_maps table entry specifies the @@ -11497,11 +11548,12 @@ configuration parameter. See there for details.
%PARAM smtpd_tls_fingerprint_digest md5 -The message digest algorithm used to construct client-certificate -fingerprints for check_ccert_access and -permit_tls_clientcerts. The default algorithm is md5, -for backwards compatibility with Postfix releases prior to 2.5. -
+The message digest algorithm to construct remote SMTP +client-certificate +fingerprints or public key fingerprints (Postfix 2.9 and later) +for check_ccert_access and permit_tls_clientcerts. The +default algorithm is md5, for backwards compatibility with Postfix +releases prior to 2.5.
Advances in hash function cryptanalysis have led to md5 being deprecated in favor of sha1. @@ -11532,6 +11584,12 @@ SHA1 Fingerprint=D4:6A:AB:19:24:79:F8:32:BB:A6:CB:66:82:C0:8E:9B:EE:29:A8:1A +
Public key fingerprints are more difficult to extract, however, +the SHA-1 public key fingerprint is often present as the value of the +"Subject Key Identifier" extension in X.509v3 certificates. The Postfix +SMTP server and client log the peer certificate fingerprint and public +key fingerprint when TLS loglevel is 1 or higher.
+Example: client-certificate access table, with sha1 fingerprints:
@@ -11721,7 +11779,8 @@ parameter. See there for details. %PARAM tls_eecdh_strong_curve prime256v1 -The elliptic curve used by the SMTP server for sensibly strong +
The elliptic curve used by the Postfix SMTP server for sensibly +strong ephemeral ECDH key exchange. This curve is used by the Postfix SMTP server when "smtpd_tls_eecdh_grade = strong". The phrase "sensibly strong" means approximately 128-bit security based on best known @@ -11745,7 +11804,8 @@ compiled and linked with OpenSSL 1.0.0 or later.
%PARAM tls_eecdh_ultra_curve secp384r1 -The elliptic curve used by the SMTP server for maximally strong +
The elliptic curve used by the Postfix SMTP server for maximally +strong ephemeral ECDH key exchange. This curve is used by the Postfix SMTP server when "smtpd_tls_eecdh_grade = ultra". The phrase "maximally strong" means approximately 192-bit security based on best known attacks. @@ -12661,7 +12721,8 @@ these commands, disabled instances are skipped.
%PARAM lmtp_assume_final no -When an LMTP server announces no DSN support, assume that the +
When a remote LMTP server announces no DSN support, assume that +the server performs final delivery, and send "delivered" delivery status notifications instead of "relayed". The default setting is backwards compatible to avoid the infinetisimal possibility of breaking @@ -12748,7 +12809,8 @@ classes of SMTP service.
%PARAM postscreen_post_queue_limit $default_process_limitThe number of clients that can be waiting for service from a -real SMTP server process. When this queue is full, all clients will +real Postfix SMTP server process. When this queue is full, all +clients will receive a 421 reponse.
This feature is available in Postfix 2.8.
@@ -12756,7 +12818,8 @@ receive a 421 reponse. %PARAM postscreen_pre_queue_limit $default_process_limitThe number of non-whitelisted clients that can be waiting for -a decision whether they will receive service from a real SMTP server +a decision whether they will receive service from a real Postfix +SMTP server process. When this queue is full, all non-whitelisted clients will receive a 421 reponse.
@@ -12836,7 +12899,7 @@ domain name. Use the postscreen_dnsbl_reply_map feature to hideWhen a client's score is equal to or greater than the threshold specified with postscreen_dnsbl_threshold, postscreen(8) can drop -the connection with the SMTP client.
+the connection with the remote SMTP client.Specify a list of domain=filter*weight entries, separated by comma or whitespace.
@@ -12850,9 +12913,9 @@ where each d is a number, or a pattern inside [] that contains one or more ";"-separated numbers or number..number ranges.When no "*weight" is specified, postscreen(8) increments -the SMTP client's DNSBL score by 1. Otherwise, the weight must be +the remote SMTP client's DNSBL score by 1. Otherwise, the weight must be an integral number, and postscreen(8) adds the specified weight to -the SMTP client's DNSBL score. Specify a negative number for +the remote SMTP client's DNSBL score. Specify a negative number for whitelisting.
When one postscreen_dnsbl_sites entry produces multiple @@ -12882,7 +12945,7 @@ postscreen_dnsbl_sites = example.com=127.0.0.4 %PARAM postscreen_dnsbl_action ignore -
The action that postscreen(8) takes when an SMTP client's combined +
The action that postscreen(8) takes when a remote SMTP client's combined DNSBL score is equal to or greater than a threshold (as defined with the postscreen_dnsbl_sites and postscreen_dnsbl_threshold parameters). Specify one of the following:
@@ -12913,7 +12976,7 @@ this test the next time the client connects. %PARAM postscreen_greet_action ignore -The action that postscreen(8) takes when an SMTP client speaks +
The action that postscreen(8) takes when a remote SMTP client speaks before its turn within the time specified with the postscreen_greet_wait parameter. Specify one of the following:
@@ -12939,7 +13002,7 @@ this test the next time the client connects. -In either case, postscreen(8) will not whitelist the SMTP client +
In either case, postscreen(8) will not whitelist the remote SMTP client IP address.
This feature is available in Postfix 2.8.
@@ -13036,7 +13099,7 @@ value to disable this feature. %PARAM postscreen_blacklist_action ignore -The action that postscreen(8) takes when an SMTP client is +
The action that postscreen(8) takes when a remote SMTP client is permanently blacklisted with the postscreen_access_list parameter. Specify one of the following:
@@ -13306,7 +13369,7 @@ configuration parameter. See there for details. %PARAM postscreen_dnsbl_threshold 1 -The inclusive lower bound for blocking an SMTP client, based on +
The inclusive lower bound for blocking a remote SMTP client, based on its combined DNSBL score as defined with the postscreen_dnsbl_sites parameter.
@@ -13345,7 +13408,8 @@ one-letter suffix that specifies the time unit). Time units: s %PARAM postscreen_pipelining_action enforce -The action that postscreen(8) takes when an SMTP client sends +
The action that postscreen(8) takes when a remote SMTP client +sends multiple commands instead of sending one command and waiting for the server to respond. Specify one of the following:
@@ -13400,7 +13464,7 @@ server. %PARAM postscreen_watchdog_timeout 10sHow much time a postscreen(8) process may take to respond to -an SMTP client command or to perform a cache operation before it +a remote SMTP client command or to perform a cache operation before it is terminated by a built-in watchdog timer. This is a safety mechanism that prevents postscreen(8) from becoming non-responsive due to a bug in Postfix itself or in system software. To avoid @@ -13438,7 +13502,7 @@ disable_vrfy_command for details.
%PARAM postscreen_non_smtp_command_action drop -The action that postscreen(8) takes when an SMTP client sends +
The action that postscreen(8) takes when a remote SMTP client sends non-SMTP commands as specified with the postscreen_forbidden_commands parameter. Specify one of the following:
@@ -13520,7 +13584,7 @@ the file is read). %PARAM postscreen_bare_newline_action ignore -The action that postscreen(8) takes when an SMTP client sends +
The action that postscreen(8) takes when a remote SMTP client sends a bare newline character, that is, a newline not preceded by carriage return. Specify one of the following:
@@ -13554,7 +13618,8 @@ this test the next time the client connects.The amount of time that postscreen(8) will use the result from a successful "bare newline" SMTP protocol test. During this time, the client IP address is excluded from this test. The default -is long because a client must disconnect after it passes the test, +is long because a remote SMTP client must disconnect after it passes +the test, before it can talk to a real Postfix SMTP server.
Specify a non-zero time value (an integral value plus an optional @@ -13566,7 +13631,8 @@ one-letter suffix that specifies the time unit). Time units: s %PARAM postscreen_bare_newline_enable no
Enable "bare newline" SMTP protocol tests in the postscreen(8) -server. These tests are expensive: a client must disconnect after +server. These tests are expensive: a remote SMTP client must +disconnect after it passes the test, before it can talk to a real Postfix SMTP server.
@@ -13574,7 +13640,8 @@ it passes the test, before it can talk to a real Postfix SMTP server. %PARAM postscreen_client_connection_count_limit $smtpd_client_connection_count_limit -How many simultaneous connections any client is allowed to have +
How many simultaneous connections any remote SMTP client is +allowed to have with the postscreen(8) daemon. By default, this limit is the same as with the Postfix SMTP server. Note that the triage process can take several seconds, with the time spent in postscreen_greet_wait @@ -13667,8 +13734,9 @@ The default time unit is s (seconds). %PARAM tls_preempt_cipherlist no -
With SSLv3 and later, use the server's cipher preference order -instead of the client's cipher preference order.
+With SSLv3 and later, use the Postfix SMTP server's cipher +preference order instead of the remote client's cipher preference +order.
By default, the OpenSSL server selects the client's most preferred cipher that the server supports. With SSLv3 and later, the server may @@ -13800,7 +13868,7 @@ The table is not searched by hostname for robustness reasons.
%PARAM postscreen_use_tls $smtpd_use_tls -Opportunistic TLS: announce STARTTLS support to SMTP clients, +
Opportunistic TLS: announce STARTTLS support to remote SMTP clients, but do not require that clients use TLS encryption.
This feature is available in Postfix 2.8 and later. @@ -13808,7 +13876,7 @@ Preferably, use postscreen_tls_security_level instead.
%PARAM postscreen_enforce_tls $smtpd_enforce_tls -Mandatory TLS: announce STARTTLS support to SMTP clients, and +
Mandatory TLS: announce STARTTLS support to remote SMTP clients, and require that clients use TLS encryption. See smtpd_postscreen_enforce_tls for details.
@@ -13826,7 +13894,7 @@ for details. %PARAM tlsproxy_enforce_tls $smtpd_enforce_tls -Mandatory TLS: announce STARTTLS support to SMTP clients, and +
Mandatory TLS: announce STARTTLS support to remote SMTP clients, and require that clients use TLS encryption. See smtpd_enforce_tls for further details.
@@ -13957,7 +14025,8 @@ smtpd_tls_exclude_ciphers for further details. %PARAM tlsproxy_tls_fingerprint_digest $smtpd_tls_fingerprint_digest -The message digest algorithm used to construct client-certificate +
The message digest algorithm to construct remote SMTP +client-certificate fingerprints. See smtpd_tls_fingerprint_digest for further details.
@@ -14042,7 +14111,7 @@ smtpd_tls_session_cache_timeout for further details. %PARAM tlsproxy_use_tls $smtpd_use_tls -Opportunistic TLS: announce STARTTLS support to SMTP clients, +
Opportunistic TLS: announce STARTTLS support to remote SMTP clients, but do not require that clients use TLS encryption. See smtpd_use_tls for further details.
@@ -14050,7 +14119,8 @@ for further details. %PARAM smtpd_reject_footer -Optional information that is appended after each SMTP server +
Optional information that is appended after each Postfix SMTP +server 4XX or 5XX response.
Example:
@@ -14133,7 +14203,8 @@ details. %PARAM postscreen_reject_footer $smtpd_reject_footer -Optional information that is appended after a 4XX or 5XX server +
Optional information that is appended after a 4XX or 5XX +postscreen(8) server response. See smtpd_reject_footer for further details.
This feature is available in Postfix 2.8 and later.
@@ -14207,7 +14278,7 @@ configuration parameter. See there for details. %PARAM postscreen_whitelist_interfaces static:allA list of local postscreen(8) server IP addresses where a -non-whitelisted SMTP client can obtain postscreen(8)'s temporary +non-whitelisted remote SMTP client can obtain postscreen(8)'s temporary whitelist status. This status is required before the client can talk to a Postfix SMTP server process. By default, a client can obtain postscreen(8)'s whitelist status on any local postscreen(8) diff --git a/postfix/src/global/mail_params.h b/postfix/src/global/mail_params.h index 163010da8..32b59c5ac 100644 --- a/postfix/src/global/mail_params.h +++ b/postfix/src/global/mail_params.h @@ -1293,8 +1293,8 @@ extern char *var_smtpd_tls_dh1024_param_file; extern char *var_smtpd_tls_eecdh; #define VAR_SMTPD_TLS_LOGLEVEL "smtpd_tls_loglevel" -#define DEF_SMTPD_TLS_LOGLEVEL 0 -extern int var_smtpd_tls_loglevel; +#define DEF_SMTPD_TLS_LOGLEVEL "0" +extern char *var_smtpd_tls_loglevel; #define VAR_SMTPD_TLS_RECHEAD "smtpd_tls_received_header" #define DEF_SMTPD_TLS_RECHEAD 0 @@ -1431,11 +1431,11 @@ extern char *var_smtp_tls_mand_excl; extern char *var_smtp_tls_fpt_dgst; #define VAR_SMTP_TLS_LOGLEVEL "smtp_tls_loglevel" -#define DEF_SMTP_TLS_LOGLEVEL 0 +#define DEF_SMTP_TLS_LOGLEVEL "0" #define VAR_LMTP_TLS_LOGLEVEL "lmtp_tls_loglevel" -#define DEF_LMTP_TLS_LOGLEVEL 0 -extern int var_smtp_tls_loglevel; /* In smtp(8) and tlsmgr(8) */ -extern int var_lmtp_tls_loglevel; /* In tlsmgr(8) */ +#define DEF_LMTP_TLS_LOGLEVEL "0" +extern char *var_smtp_tls_loglevel; /* In smtp(8) and tlsmgr(8) */ +extern char *var_lmtp_tls_loglevel; /* In tlsmgr(8) */ #define VAR_SMTP_TLS_NOTEOFFER "smtp_tls_note_starttls_offer" #define DEF_SMTP_TLS_NOTEOFFER 0 @@ -3569,7 +3569,7 @@ extern char *var_tlsp_tls_eecdh; #define VAR_TLSP_TLS_LOGLEVEL "tlsproxy_tls_loglevel" #define DEF_TLSP_TLS_LOGLEVEL "$" VAR_SMTPD_TLS_LOGLEVEL -extern int var_tlsp_tls_loglevel; +extern char *var_tlsp_tls_loglevel; #define VAR_TLSP_TLS_RECHEAD "tlsproxy_tls_received_header" #define DEF_TLSP_TLS_RECHEAD "$" VAR_SMTPD_TLS_RECHEAD diff --git a/postfix/src/global/mail_proto.h b/postfix/src/global/mail_proto.h index 529240662..ad0505b98 100644 --- a/postfix/src/global/mail_proto.h +++ b/postfix/src/global/mail_proto.h @@ -144,6 +144,7 @@ extern char *mail_pathname(const char *, const char *); #define MAIL_ATTR_CCERT_SUBJECT "ccert_subject" #define MAIL_ATTR_CCERT_ISSUER "ccert_issuer" #define MAIL_ATTR_CCERT_FINGERPRINT "ccert_fingerprint" +#define MAIL_ATTR_CCERT_PKEY_FPRINT "ccert_pubkey_fingerprint" #define MAIL_ATTR_CRYPTO_PROTOCOL "encryption_protocol" #define MAIL_ATTR_CRYPTO_CIPHER "encryption_cipher" #define MAIL_ATTR_CRYPTO_KEYSIZE "encryption_keysize" @@ -250,6 +251,7 @@ extern char *mail_pathname(const char *, const char *); #define MAIL_ATTR_PEER_CN "peer_CN" #define MAIL_ATTR_ISSUER_CN "issuer_CN" #define MAIL_ATTR_PEER_FPT "peer_fingerprint" +#define MAIL_ATTR_PEER_PKEY_FPT "peer_pubkey_fingerprint" #define MAIL_ATTR_PEER_STATUS "peer_status" #define MAIL_ATTR_CIPHER_PROTOCOL "cipher_protocol" #define MAIL_ATTR_CIPHER_NAME "cipher_name" diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 4f8c0fadb..b7c89e0f6 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -20,7 +20,7 @@ * Patches change both the patchlevel and the release date. Snapshots have no * patchlevel; they change the release date only. */ -#define MAIL_RELEASE_DATE "20111203" +#define MAIL_RELEASE_DATE "20111205" #define MAIL_VERSION_NUMBER "2.9" #ifdef SNAPSHOT diff --git a/postfix/src/global/verify_sender_addr.c b/postfix/src/global/verify_sender_addr.c index 28d65784f..c87181487 100644 --- a/postfix/src/global/verify_sender_addr.c +++ b/postfix/src/global/verify_sender_addr.c @@ -2,7 +2,7 @@ /* NAME /* verify_sender_addr 3 /* SUMMARY -/* address verification support +/* time-dependent probe sender addresses /* SYNOPSIS /* #include
/* @@ -19,25 +19,27 @@ /* time-dependent portion is appended to the address localpart /* specified with the address_verify_sender parameter. /* +/* When the address_verify_sender parameter is empty or <>, +/* the sender address always the empty address (i.e. always +/* time-independent). +/* /* The caller must initialize the address_verify_sender and /* address_verify_sender_ttl parameter values. /* /* make_verify_sender_addr() generates an envelope sender -/* address for an address verification probe. When the -/* address_verify_sender parameter is empty or <>, the result -/* is always the null address. +/* address for an address verification probe. /* /* valid_verify_sender_addr() verifies that the given address /* is a valid sender address for address verification probes. -/* When the address_verify_sender parameter is empty or <>, -/* the match succeeds only if the given address is empty. When -/* the address is time-dependent, it is allowed to differ by -/* +/-1 TTL unit from the expected address. The result is a -/* null pointer when no match is found. Otherwise, the result -/* is the sender address without the time-dependent portion; -/* this is the address that should be used for further delivery. +/* When probe sender addresses are configured to be time-dependent, +/* the given address is allowed to differ by +/-1 TTL unit +/* from the expected address. The result is a null pointer +/* when no match is found. Otherwise, the result is the sender +/* address without the time-dependent portion; this is the +/* address that should be used for further delivery. /* DIAGNOSTICS -/* Fatal errors: malformed address_verify_sender value. +/* Fatal errors: malformed address_verify_sender value; out +/* of memory. /* LICENSE /* .ad /* .fi @@ -78,17 +80,21 @@ /* * We convert the time-dependent portion to a safe string (no vowels) in a * reversible manner, so that we can check an incoming address against the - * previous, current, and next time slot. This allows for some time slippage - * between multiple MTAs that handle mail for the same site. + * current and +/-1 TTL time slot. This allows for some time slippage + * between multiple MTAs that handle mail for the same site. We use base 31 + * so that the time stamp contains B-Z0-9. This simplifies regression tests. */ #define VERIFY_BASE 31 /* - * The time-dependent address verification probe sender address has the form - * ``fixedvariable@fixed''. The fixed text is taken from var_verify_sender - * with perhaps domain information appended during address canonicalization. - * The variable part of the address changes every var_verify_sender_ttl - * seconds. + * We append the time-dependent portion to the localpart of the the address + * verification probe sender address, so that the result has the form + * ``fixed1variable@fixed2''. There is no delimiter between ``fixed1'' and + * ``variable'', because that could make "old" time stamps valid depending + * on how the recipient_delimiter feature is configured. The fixed text is + * taken from var_verify_sender with perhaps domain information appended + * during address canonicalization. The variable part of the address changes + * every var_verify_sender_ttl seconds. */ char *var_verify_sender; /* "bare" probe sender address */ int var_verify_sender_ttl; /* time between address changes */ @@ -117,7 +123,7 @@ const char *make_verify_sender_addr(void) { static VSTRING *verify_sender_buf; /* the complete sender address */ static VSTRING *my_epoch_buf; /* scratch space */ - char *at_domain; + char *my_at_domain; /* * The null sender is always time-independent. @@ -131,7 +137,7 @@ const char *make_verify_sender_addr(void) if (*var_verify_sender == '@') msg_fatal("parameter %s: value \"%s\" must not start with '@'", VAR_VERIFY_SENDER, var_verify_sender); - if ((at_domain = strchr(var_verify_sender, '@')) != 0 && at_domain[1] == 0) + if ((my_at_domain = strchr(var_verify_sender, '@')) != 0 && my_at_domain[1] == 0) msg_fatal("parameter %s: value \"%s\" must not end with '@'", VAR_VERIFY_SENDER, var_verify_sender); @@ -156,17 +162,17 @@ const char *make_verify_sender_addr(void) */ if (var_verify_sender_ttl > 0) { /* Strip the @domain portion, if applicable. */ - if (at_domain != 0) + if (my_at_domain != 0) vstring_truncate(verify_sender_buf, - (ssize_t) (at_domain - var_verify_sender)); + (ssize_t) (my_at_domain - var_verify_sender)); /* Append the time stamp to the address localpart. */ vstring_sprintf_append(verify_sender_buf, "%s", safe_ultostr(my_epoch_buf, VERIFY_SENDER_ADDR_EPOCH(), VERIFY_BASE, 0, 0)); /* Add back the @domain, if applicable. */ - if (at_domain != 0) - vstring_sprintf_append(verify_sender_buf, "%s", at_domain); + if (my_at_domain != 0) + vstring_sprintf_append(verify_sender_buf, "%s", my_at_domain); } /* @@ -180,9 +186,9 @@ const char *make_verify_sender_addr(void) /* valid_verify_sender_addr - decide if address matches time window +/-1 */ -const char *valid_verify_sender_addr(const char *addr) +const char *valid_verify_sender_addr(const char *their_addr) { - static VSTRING *fixed_sender_buf; /* sender without time stamp */ + static VSTRING *time_indep_sender_buf; /* sender without time stamp */ ssize_t base_len; unsigned long my_epoch; unsigned long their_epoch; @@ -194,44 +200,44 @@ const char *valid_verify_sender_addr(const char *addr) * The null address is always time-independent. */ if (*var_verify_sender == 0 || strcmp(var_verify_sender, "<>") == 0) - return (*addr ? 0 : ""); + return (*their_addr ? 0 : ""); /* * One-time initialization. Generate the time-independent address that we * will return if the match is successful. This address is also used as a * matching template. */ - if (fixed_sender_buf == 0) { - fixed_sender_buf = vstring_alloc(10); - vstring_strcpy(fixed_sender_buf, var_verify_sender); - rewrite_clnt_internal(MAIL_ATTR_RWR_LOCAL, STR(fixed_sender_buf), - fixed_sender_buf); + if (time_indep_sender_buf == 0) { + time_indep_sender_buf = vstring_alloc(10); + vstring_strcpy(time_indep_sender_buf, var_verify_sender); + rewrite_clnt_internal(MAIL_ATTR_RWR_LOCAL, STR(time_indep_sender_buf), + time_indep_sender_buf); } /* * Check the time-independent sender localpart. */ - if ((my_at_domain = strchr(STR(fixed_sender_buf), '@')) != 0) - base_len = my_at_domain - STR(fixed_sender_buf); + if ((my_at_domain = strchr(STR(time_indep_sender_buf), '@')) != 0) + base_len = my_at_domain - STR(time_indep_sender_buf); else - base_len = LEN(fixed_sender_buf); - if (strncasecmp(STR(fixed_sender_buf), addr, base_len) != 0) + base_len = LEN(time_indep_sender_buf); + if (strncasecmp(STR(time_indep_sender_buf), their_addr, base_len) != 0) return (0); /* sender localpart mis-match */ /* * Check the time-independent domain. */ - if ((their_at_domain = strchr(addr, '@')) == 0 && my_at_domain != 0) - return ("domain mis-match"); /* sender domain mis-match */ - if (their_at_domain != 0 && (my_at_domain == 0 - || strcasecmp(their_at_domain, my_at_domain) != 0)) + if ((their_at_domain = strchr(their_addr, '@')) == 0 && my_at_domain != 0) + return (0); /* sender domain mis-match */ + if (their_at_domain != 0 + && (my_at_domain == 0 || strcasecmp(their_at_domain, my_at_domain) != 0)) return (0); /* sender domain mis-match */ /* * Check the time-dependent portion. */ if (var_verify_sender_ttl > 0) { - their_epoch = safe_strtoul(addr + base_len, &cp, VERIFY_BASE); + their_epoch = safe_strtoul(their_addr + base_len, &cp, VERIFY_BASE); if ((*cp != '@' && *cp != 0) || (their_epoch == ULONG_MAX && errno == ERANGE)) return (0); /* malformed time stamp */ @@ -244,10 +250,10 @@ const char *valid_verify_sender_addr(const char *addr) * No time-dependent portion. */ else { - if (addr[base_len] != '@' && addr[base_len] != 0) + if (their_addr[base_len] != '@' && their_addr[base_len] != 0) return (0); /* garbage after sender base */ } - return (STR(fixed_sender_buf)); + return (STR(time_indep_sender_buf)); } /* diff --git a/postfix/src/postconf/Makefile.in b/postfix/src/postconf/Makefile.in index 71bbce953..abb6e3bb0 100644 --- a/postfix/src/postconf/Makefile.in +++ b/postfix/src/postconf/Makefile.in @@ -42,7 +42,7 @@ test: $(TESTPROG) tests: test1 test2 test3 test4 test5 test6 test7 test8 test9 test10 test11 \ test12 test13 test14 test15 test16 test17 test18 test19 test20 test21 \ - test22 test23 test24 test25 + test22 test23 test24 test25 test26 test27 root_tests: @@ -295,7 +295,7 @@ test22: $(PROG) test22.ref diff test22.ref test22.tmp rm -f main.cf master.cf test22.tmp -# Test the -C flag. +# Test the -C flag for each category. test23: $(PROG) test23.ref rm -f main.cf master.cf @@ -330,6 +330,30 @@ test25: $(PROG) test25.ref diff test25.ref test25.tmp rm -f main.cf master.cf test25.tmp +# Test completeness of "-C all". + +test26: $(PROG) test26.ref + rm -f main.cf master.cf + touch main.cf master.cf + echo always_bcc = yes >> main.cf + echo name = value >> main.cf + echo whatevershebrings unix - n n - 0 smtp >> master.cf + echo ' -o always_bcc=$$name' >> master.cf + ./$(PROG) -nc . -C all >test26.tmp 2>&1 + diff test26.ref test26.tmp + rm -f main.cf master.cf test26.tmp + +test27: $(PROG) test27.ref + rm -f main.cf master.cf + touch main.cf master.cf + echo always_bcc = yes >> main.cf + echo name = value >> main.cf + echo whatevershebrings unix - n n - 0 smtp >> master.cf + echo ' -o always_bcc=$$name' >> master.cf + ./$(PROG) -c . -C all 2>&1 | grep whatevershebrings >test27.tmp + diff test27.ref test27.tmp + rm -f main.cf master.cf test27.tmp + printfck: $(OBJS) $(PROG) rm -rf printfck mkdir printfck diff --git a/postfix/src/postconf/postconf.c b/postfix/src/postconf/postconf.c index 18ab79d85..0de2b48ec 100644 --- a/postfix/src/postconf/postconf.c +++ b/postfix/src/postconf/postconf.c @@ -95,9 +95,11 @@ /* a \fBmaster.cf\fR entry plus a Postfix-defined suffix). /* .IP \fBuser\fR /* Parameters with user-defined names. +/* .IP \fBall\fR +/* All the above classes. /* .RE /* .IP -/* The default is as if "\fB-C builtin,service,user\fR" is +/* The default is as if "\fB-C all\fR" is /* specified. /* .IP \fB-d\fR /* Print \fBmain.cf\fR default parameter settings instead of @@ -370,6 +372,7 @@ int main(int argc, char **argv) "builtin", PC_PARAM_FLAG_BUILTIN, "service", PC_PARAM_FLAG_SERVICE, "user", PC_PARAM_FLAG_USER, + "all", PC_PARAM_MASK_CLASS, 0, }; diff --git a/postfix/src/postconf/test26.ref b/postfix/src/postconf/test26.ref new file mode 100644 index 000000000..0b33025e9 --- /dev/null +++ b/postfix/src/postconf/test26.ref @@ -0,0 +1,3 @@ +always_bcc = yes +config_directory = . +name = value diff --git a/postfix/src/postconf/test27.ref b/postfix/src/postconf/test27.ref new file mode 100644 index 000000000..bb1c81e10 --- /dev/null +++ b/postfix/src/postconf/test27.ref @@ -0,0 +1,15 @@ +whatevershebrings_delivery_slot_cost = $default_delivery_slot_cost +whatevershebrings_delivery_slot_discount = $default_delivery_slot_discount +whatevershebrings_delivery_slot_loan = $default_delivery_slot_loan +whatevershebrings_destination_concurrency_failed_cohort_limit = $default_destination_concurrency_failed_cohort_limit +whatevershebrings_destination_concurrency_limit = $default_destination_concurrency_limit +whatevershebrings_destination_concurrency_negative_feedback = $default_destination_concurrency_negative_feedback +whatevershebrings_destination_concurrency_positive_feedback = $default_destination_concurrency_positive_feedback +whatevershebrings_destination_rate_delay = $default_destination_rate_delay +whatevershebrings_destination_recipient_limit = $default_destination_recipient_limit +whatevershebrings_extra_recipient_limit = $default_extra_recipient_limit +whatevershebrings_initial_destination_concurrency = $initial_destination_concurrency +whatevershebrings_minimum_delivery_slots = $default_minimum_delivery_slots +whatevershebrings_recipient_limit = $default_recipient_limit +whatevershebrings_recipient_refill_delay = $default_recipient_refill_delay +whatevershebrings_recipient_refill_limit = $default_recipient_refill_limit diff --git a/postfix/src/postscreen/postscreen.c b/postfix/src/postscreen/postscreen.c index 6b5fc3008..d7307f8dc 100644 --- a/postfix/src/postscreen/postscreen.c +++ b/postfix/src/postscreen/postscreen.c @@ -122,7 +122,8 @@ /* List of characters that are permitted in postscreen_reject_footer /* attribute expansions. /* .IP "\fBpostscreen_reject_footer ($smtpd_reject_footer)\fR" -/* Optional information that is appended after a 4XX or 5XX server +/* Optional information that is appended after a 4XX or 5XX +/* \fBpostscreen\fR(8) server /* response. /* .IP "\fBsoft_bounce (no)\fR" /* Safety net to keep mail queued that would otherwise be returned to @@ -137,7 +138,7 @@ /* .IP "\fBpostscreen_access_list (permit_mynetworks)\fR" /* Permanent white/blacklist for remote SMTP client IP addresses. /* .IP "\fBpostscreen_blacklist_action (ignore)\fR" -/* The action that \fBpostscreen\fR(8) takes when an SMTP client is +/* The action that \fBpostscreen\fR(8) takes when a remote SMTP client is /* permanently blacklisted with the postscreen_access_list parameter. /* MAIL EXCHANGER POLICY TESTS /* .ad @@ -152,8 +153,8 @@ /* to clients that connect only to backup MX hosts. /* .IP "\fBpostscreen_whitelist_interfaces (static:all)\fR" /* A list of local \fBpostscreen\fR(8) server IP addresses where a -/* non-whitelisted SMTP client can obtain \fBpostscreen\fR(8)'s temporary -/* whitelist status to talk to a Postfix SMTP server process. +/* non-whitelisted remote SMTP client can obtain \fBpostscreen\fR(8)'s temporary +/* whitelist status. /* BEFORE-GREETING TESTS /* .ad /* .fi @@ -165,7 +166,7 @@ /* .IP "\fBdnsblog_service_name (dnsblog)\fR" /* The name of the \fBdnsblog\fR(8) service entry in master.cf. /* .IP "\fBpostscreen_dnsbl_action (ignore)\fR" -/* The action that \fBpostscreen\fR(8) takes when an SMTP client's combined +/* The action that \fBpostscreen\fR(8) takes when a remote SMTP client's combined /* DNSBL score is equal to or greater than a threshold (as defined /* with the postscreen_dnsbl_sites and postscreen_dnsbl_threshold /* parameters). @@ -177,11 +178,11 @@ /* Optional list of DNS white/blacklist domains, filters and weight /* factors. /* .IP "\fBpostscreen_dnsbl_threshold (1)\fR" -/* The inclusive lower bound for blocking an SMTP client, based on +/* The inclusive lower bound for blocking a remote SMTP client, based on /* its combined DNSBL score as defined with the postscreen_dnsbl_sites /* parameter. /* .IP "\fBpostscreen_greet_action (ignore)\fR" -/* The action that \fBpostscreen\fR(8) takes when an SMTP client speaks +/* The action that \fBpostscreen\fR(8) takes when a remote SMTP client speaks /* before its turn within the time specified with the postscreen_greet_wait /* parameter. /* .IP "\fBpostscreen_greet_banner ($smtpd_banner)\fR" @@ -208,7 +209,7 @@ /* the client will be allowed to talk directly to a Postfix /* SMTP server process. /* .IP "\fBpostscreen_bare_newline_action (ignore)\fR" -/* The action that \fBpostscreen\fR(8) takes when an SMTP client sends +/* The action that \fBpostscreen\fR(8) takes when a remote SMTP client sends /* a bare newline character, that is, a newline not preceded by carriage /* return. /* .IP "\fBpostscreen_bare_newline_enable (no)\fR" @@ -223,13 +224,14 @@ /* Require that a remote SMTP client sends HELO or EHLO before /* commencing a MAIL transaction. /* .IP "\fBpostscreen_non_smtp_command_action (drop)\fR" -/* The action that \fBpostscreen\fR(8) takes when an SMTP client sends +/* The action that \fBpostscreen\fR(8) takes when a remote SMTP client sends /* non-SMTP commands as specified with the postscreen_forbidden_commands /* parameter. /* .IP "\fBpostscreen_non_smtp_command_enable (no)\fR" /* Enable "non-SMTP command" tests in the \fBpostscreen\fR(8) server. /* .IP "\fBpostscreen_pipelining_action (enforce)\fR" -/* The action that \fBpostscreen\fR(8) takes when an SMTP client sends +/* The action that \fBpostscreen\fR(8) takes when a remote SMTP client +/* sends /* multiple commands instead of sending one command and waiting for /* the server to respond. /* .IP "\fBpostscreen_pipelining_enable (no)\fR" @@ -267,7 +269,8 @@ /* Upon input, long lines are chopped up into pieces of at most /* this length; upon delivery, long lines are reconstructed. /* .IP "\fBpostscreen_client_connection_count_limit ($smtpd_client_connection_count_limit)\fR" -/* How many simultaneous connections any client is allowed to have +/* How many simultaneous connections any remote SMTP client is +/* allowed to have /* with the \fBpostscreen\fR(8) daemon. /* .IP "\fBpostscreen_command_count_limit (20)\fR" /* The limit on the total number of commands per SMTP session for @@ -277,14 +280,15 @@ /* built-in SMTP protocol engine. /* .IP "\fBpostscreen_post_queue_limit ($default_process_limit)\fR" /* The number of clients that can be waiting for service from a -/* real SMTP server process. +/* real Postfix SMTP server process. /* .IP "\fBpostscreen_pre_queue_limit ($default_process_limit)\fR" /* The number of non-whitelisted clients that can be waiting for -/* a decision whether they will receive service from a real SMTP server +/* a decision whether they will receive service from a real Postfix +/* SMTP server /* process. /* .IP "\fBpostscreen_watchdog_timeout (10s)\fR" /* How much time a \fBpostscreen\fR(8) process may take to respond to -/* an SMTP client command or to perform a cache operation before it +/* a remote SMTP client command or to perform a cache operation before it /* is terminated by a built-in watchdog timer. /* STARTTLS CONTROLS /* .ad @@ -301,10 +305,10 @@ /* These parameters are supported for compatibility with /* \fBsmtpd\fR(8) legacy parameters. /* .IP "\fBpostscreen_use_tls ($smtpd_use_tls)\fR" -/* Opportunistic TLS: announce STARTTLS support to SMTP clients, +/* Opportunistic TLS: announce STARTTLS support to remote SMTP clients, /* but do not require that clients use TLS encryption. /* .IP "\fBpostscreen_enforce_tls ($smtpd_enforce_tls)\fR" -/* Mandatory TLS: announce STARTTLS support to SMTP clients, and +/* Mandatory TLS: announce STARTTLS support to remote SMTP clients, and /* require that clients use TLS encryption. /* MISCELLANEOUS CONTROLS /* .ad diff --git a/postfix/src/smtp/lmtp_params.c b/postfix/src/smtp/lmtp_params.c index 58d9dfd02..4f68cecbd 100644 --- a/postfix/src/smtp/lmtp_params.c +++ b/postfix/src/smtp/lmtp_params.c @@ -26,6 +26,7 @@ VAR_LMTP_TLS_CIPH, DEF_LMTP_TLS_CIPH, &var_smtp_tls_ciph, 1, 0, VAR_LMTP_TLS_ECCERT_FILE, DEF_LMTP_TLS_ECCERT_FILE, &var_smtp_tls_eccert_file, 0, 0, VAR_LMTP_TLS_ECKEY_FILE, DEF_LMTP_TLS_ECKEY_FILE, &var_smtp_tls_eckey_file, 0, 0, + VAR_LMTP_TLS_LOGLEVEL, DEF_LMTP_TLS_LOGLEVEL, &var_smtp_tls_loglevel, 0, 0, #endif VAR_LMTP_SASL_MECHS, DEF_LMTP_SASL_MECHS, &var_smtp_sasl_mechs, 0, 0, VAR_LMTP_SASL_TYPE, DEF_LMTP_SASL_TYPE, &var_smtp_sasl_type, 1, 0, @@ -84,7 +85,6 @@ VAR_LMTP_MXSESS_LIMIT, DEF_LMTP_MXSESS_LIMIT, &var_smtp_mxsess_limit, 0, 0, #ifdef USE_TLS VAR_LMTP_TLS_SCERT_VD, DEF_LMTP_TLS_SCERT_VD, &var_smtp_tls_scert_vd, 0, 0, - VAR_LMTP_TLS_LOGLEVEL, DEF_LMTP_TLS_LOGLEVEL, &var_smtp_tls_loglevel, 0, 0, #endif 0, }; diff --git a/postfix/src/smtp/smtp.c b/postfix/src/smtp/smtp.c index 6d1c3c93c..831cfc7bf 100644 --- a/postfix/src/smtp/smtp.c +++ b/postfix/src/smtp/smtp.c @@ -161,13 +161,15 @@ /* Lookup tables, indexed by the remote SMTP server address, with /* per-destination workarounds for CISCO PIX firewall bugs. /* .IP "\fBsmtp_quote_rfc821_envelope (yes)\fR" -/* Quote addresses in SMTP MAIL FROM and RCPT TO commands as required +/* Quote addresses in Postfix SMTP client MAIL FROM and RCPT TO commands +/* as required /* by RFC 2821. /* .IP "\fBsmtp_reply_filter (empty)\fR" /* A mechanism to transform replies from remote SMTP servers one /* line at a time. /* .IP "\fBsmtp_skip_5xx_greeting (yes)\fR" -/* Skip SMTP servers that greet with a 5XX status code (go away, do +/* Skip remote SMTP servers that greet with a 5XX status code (go away, +/* do /* not try again later). /* .IP "\fBsmtp_skip_quit_response (yes)\fR" /* Do not wait for the response to the SMTP QUIT command. @@ -189,7 +191,7 @@ /* response from a remote SMTP server. /* .IP "\fBsmtp_generic_maps (empty)\fR" /* Optional lookup tables that perform address rewriting in the -/* SMTP client, typically to transform a locally valid address into +/* Postfix SMTP client, typically to transform a locally valid address into /* a globally valid address when sending mail across the Internet. /* .PP /* Available in Postfix version 2.2.9 and later: @@ -202,11 +204,13 @@ /* .IP "\fBlmtp_discard_lhlo_keyword_address_maps (empty)\fR" /* Lookup tables, indexed by the remote LMTP server address, with /* case insensitive lists of LHLO keywords (pipelining, starttls, -/* auth, etc.) that the LMTP client will ignore in the LHLO response +/* auth, etc.) that the Postfix LMTP client will ignore in the LHLO +/* response /* from a remote LMTP server. /* .IP "\fBlmtp_discard_lhlo_keywords (empty)\fR" /* A case insensitive list of LHLO keywords (pipelining, starttls, -/* auth, etc.) that the LMTP client will ignore in the LHLO response +/* auth, etc.) that the Postfix LMTP client will ignore in the LHLO +/* response /* from a remote LMTP server. /* .PP /* Available in Postfix version 2.4.4 and later: @@ -267,7 +271,8 @@ /* .IP "\fBsmtp_sasl_auth_enable (no)\fR" /* Enable SASL authentication in the Postfix SMTP client. /* .IP "\fBsmtp_sasl_password_maps (empty)\fR" -/* Optional SMTP client lookup tables with one username:password entry +/* Optional Postfix SMTP client lookup tables with one username:password +/* entry /* per remote hostname or domain, or sender address when sender-dependent /* authentication is enabled. /* .IP "\fBsmtp_sasl_security_options (noplaintext, noanonymous)\fR" @@ -347,7 +352,7 @@ /* list at all TLS security levels. /* .IP "\fBsmtp_tls_mandatory_exclude_ciphers (empty)\fR" /* Additional list of ciphers or cipher types to exclude from the -/* SMTP client cipher list at mandatory TLS security levels. +/* Postfix SMTP client cipher list at mandatory TLS security levels. /* .IP "\fBsmtp_tls_dcert_file (empty)\fR" /* File with the Postfix SMTP client DSA certificate in PEM format. /* .IP "\fBsmtp_tls_dkey_file ($smtp_tls_dcert_file)\fR" @@ -369,7 +374,8 @@ /* .IP "\fBsmtp_tls_scert_verifydepth (9)\fR" /* The verification depth for remote SMTP server certificates. /* .IP "\fBsmtp_tls_secure_cert_match (nexthop, dot-nexthop)\fR" -/* The server certificate peername verification method for the +/* How the Postfix SMTP client verifies the server certificate +/* peername for the /* "secure" TLS security level. /* .IP "\fBsmtp_tls_session_cache_database (empty)\fR" /* Name of the file containing the optional Postfix SMTP client @@ -378,7 +384,8 @@ /* The expiration time of Postfix SMTP client TLS session cache /* information. /* .IP "\fBsmtp_tls_verify_cert_match (hostname)\fR" -/* The server certificate peername verification method for the +/* How the Postfix SMTP client verifies the server certificate +/* peername for the /* "verify" TLS security level. /* .IP "\fBtls_daemon_random_bytes (32)\fR" /* The number of pseudo-random bytes that an \fBsmtp\fR(8) or \fBsmtpd\fR(8) @@ -404,8 +411,8 @@ /* .PP /* Available in Postfix version 2.5 and later: /* .IP "\fBsmtp_tls_fingerprint_cert_match (empty)\fR" -/* List of acceptable remote SMTP server certificate fingerprints -/* for the "fingerprint" TLS security level (\fBsmtp_tls_security_level\fR = +/* List of acceptable remote SMTP server certificate fingerprints for +/* the "fingerprint" TLS security level (\fBsmtp_tls_security_level\fR = /* fingerprint). /* .IP "\fBsmtp_tls_fingerprint_digest (md5)\fR" /* The message digest algorithm used to construct remote SMTP server @@ -464,46 +471,48 @@ /* The maximal number of recipients per message for the smtp /* message delivery transport. /* .IP "\fBsmtp_connect_timeout (30s)\fR" -/* The SMTP client time limit for completing a TCP connection, or +/* The Postfix SMTP client time limit for completing a TCP connection, or /* zero (use the operating system built-in time limit). /* .IP "\fBsmtp_helo_timeout (300s)\fR" -/* The SMTP client time limit for sending the HELO or EHLO command, -/* and for receiving the initial server response. +/* The Postfix SMTP client time limit for sending the HELO or EHLO command, +/* and for receiving the initial remote SMTP server response. /* .IP "\fBlmtp_lhlo_timeout (300s)\fR" -/* The LMTP client time limit for sending the LHLO command, and -/* for receiving the initial server response. +/* The Postfix LMTP client time limit for sending the LHLO command, +/* and for receiving the initial remote LMTP server response. /* .IP "\fBsmtp_xforward_timeout (300s)\fR" -/* The SMTP client time limit for sending the XFORWARD command, and -/* for receiving the server response. +/* The Postfix SMTP client time limit for sending the XFORWARD command, +/* and for receiving the remote SMTP server response. /* .IP "\fBsmtp_mail_timeout (300s)\fR" -/* The SMTP client time limit for sending the MAIL FROM command, and -/* for receiving the server response. +/* The Postfix SMTP client time limit for sending the MAIL FROM command, +/* and for receiving the remote SMTP server response. /* .IP "\fBsmtp_rcpt_timeout (300s)\fR" -/* The SMTP client time limit for sending the SMTP RCPT TO command, and -/* for receiving the server response. +/* The Postfix SMTP client time limit for sending the SMTP RCPT TO +/* command, and for receiving the remote SMTP server response. /* .IP "\fBsmtp_data_init_timeout (120s)\fR" -/* The SMTP client time limit for sending the SMTP DATA command, and for -/* receiving the server response. +/* The Postfix SMTP client time limit for sending the SMTP DATA command, +/* and for receiving the remote SMTP server response. /* .IP "\fBsmtp_data_xfer_timeout (180s)\fR" -/* The SMTP client time limit for sending the SMTP message content. +/* The Postfix SMTP client time limit for sending the SMTP message content. /* .IP "\fBsmtp_data_done_timeout (600s)\fR" -/* The SMTP client time limit for sending the SMTP ".", and for receiving -/* the server response. +/* The Postfix SMTP client time limit for sending the SMTP ".", and +/* for receiving the remote SMTP server response. /* .IP "\fBsmtp_quit_timeout (300s)\fR" -/* The SMTP client time limit for sending the QUIT command, and for -/* receiving the server response. +/* The Postfix SMTP client time limit for sending the QUIT command, +/* and for receiving the remote SMTP server response. /* .PP /* Available in Postfix version 2.1 and later: /* .IP "\fBsmtp_mx_address_limit (5)\fR" /* The maximal number of MX (mail exchanger) IP addresses that can -/* result from mail exchanger lookups, or zero (no limit). +/* result from Postfix SMTP client mail exchanger lookups, or zero (no +/* limit). /* .IP "\fBsmtp_mx_session_limit (2)\fR" /* The maximal number of SMTP sessions per delivery request before -/* giving up or delivering to a fall-back relay host, or zero (no +/* the Postfix SMTP client +/* gives up or delivers to a fall-back relay host, or zero (no /* limit). /* .IP "\fBsmtp_rset_timeout (20s)\fR" -/* The SMTP client time limit for sending the RSET command, and -/* for receiving the server response. +/* The Postfix SMTP client time limit for sending the RSET command, +/* and for receiving the remote SMTP server response. /* .PP /* Available in Postfix version 2.2 and earlier: /* .IP "\fBlmtp_cache_connection (yes)\fR" @@ -582,7 +591,8 @@ /* The time limit for sending or receiving information over an internal /* communication channel. /* .IP "\fBlmtp_assume_final (no)\fR" -/* When an LMTP server announces no DSN support, assume that the +/* When a remote LMTP server announces no DSN support, assume that +/* the /* server performs final delivery, and send "delivered" delivery status /* notifications instead of "relayed". /* .IP "\fBlmtp_tcp_port (24)\fR" @@ -805,7 +815,7 @@ char *var_smtp_tls_dcert_file; char *var_smtp_tls_dkey_file; bool var_smtp_tls_enforce_peername; char *var_smtp_tls_key_file; -int var_smtp_tls_loglevel; +char *var_smtp_tls_loglevel; bool var_smtp_tls_note_starttls_offer; char *var_smtp_tls_mand_proto; char *var_smtp_tls_sec_cmatch; @@ -1052,6 +1062,7 @@ static void pre_init(char *unused_name, char **unused_argv) if (use_tls || var_smtp_tls_per_site[0] || var_smtp_tls_policy[0]) { #ifdef USE_TLS TLS_CLIENT_INIT_PROPS props; + int using_smtp = (strcmp(var_procname, "smtp") == 0); /* * We get stronger type safety and a cleaner interface by combining @@ -1062,9 +1073,11 @@ static void pre_init(char *unused_name, char **unused_argv) */ smtp_tls_ctx = TLS_CLIENT_INIT(&props, + log_param = using_smtp ? + VAR_SMTP_TLS_LOGLEVEL : VAR_LMTP_TLS_LOGLEVEL, log_level = var_smtp_tls_loglevel, verifydepth = var_smtp_tls_scert_vd, - cache_type = strcmp(var_procname, "smtp") == 0 ? + cache_type = using_smtp ? TLS_MGR_SCACHE_SMTP : TLS_MGR_SCACHE_LMTP, cert_file = var_smtp_tls_cert_file, key_file = var_smtp_tls_key_file, diff --git a/postfix/src/smtp/smtp_params.c b/postfix/src/smtp/smtp_params.c index 193894e64..e4b841007 100644 --- a/postfix/src/smtp/smtp_params.c +++ b/postfix/src/smtp/smtp_params.c @@ -27,6 +27,7 @@ VAR_SMTP_TLS_CIPH, DEF_SMTP_TLS_CIPH, &var_smtp_tls_ciph, 1, 0, VAR_SMTP_TLS_ECCERT_FILE, DEF_SMTP_TLS_ECCERT_FILE, &var_smtp_tls_eccert_file, 0, 0, VAR_SMTP_TLS_ECKEY_FILE, DEF_SMTP_TLS_ECKEY_FILE, &var_smtp_tls_eckey_file, 0, 0, + VAR_SMTP_TLS_LOGLEVEL, DEF_SMTP_TLS_LOGLEVEL, &var_smtp_tls_loglevel, 0, 0, #endif VAR_SMTP_SASL_MECHS, DEF_SMTP_SASL_MECHS, &var_smtp_sasl_mechs, 0, 0, VAR_SMTP_SASL_TYPE, DEF_SMTP_SASL_TYPE, &var_smtp_sasl_type, 1, 0, @@ -85,7 +86,6 @@ VAR_SMTP_MXSESS_LIMIT, DEF_SMTP_MXSESS_LIMIT, &var_smtp_mxsess_limit, 0, 0, #ifdef USE_TLS VAR_SMTP_TLS_SCERT_VD, DEF_SMTP_TLS_SCERT_VD, &var_smtp_tls_scert_vd, 0, 0, - VAR_SMTP_TLS_LOGLEVEL, DEF_SMTP_TLS_LOGLEVEL, &var_smtp_tls_loglevel, 0, 0, #endif 0, }; diff --git a/postfix/src/smtp/smtp_proto.c b/postfix/src/smtp/smtp_proto.c index ae32f0a2b..408c57ec3 100644 --- a/postfix/src/smtp/smtp_proto.c +++ b/postfix/src/smtp/smtp_proto.c @@ -785,7 +785,6 @@ static int smtp_start_tls(SMTP_STATE *state) TLS_CLIENT_START(&tls_props, ctx = smtp_tls_ctx, stream = session->stream, - log_level = var_smtp_tls_loglevel, timeout = var_smtp_starttls_tmout, tls_level = session->tls_level, nexthop = session->tls_nexthop, diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c index 3acdee431..6dee4fbcb 100644 --- a/postfix/src/smtpd/smtpd.c +++ b/postfix/src/smtpd/smtpd.c @@ -76,7 +76,7 @@ /* .ad /* .fi /* .IP "\fBbroken_sasl_auth_clients (no)\fR" -/* Enable inter-operability with SMTP clients that implement an obsolete +/* Enable inter-operability with remote SMTP clients that implement an obsolete /* version of the AUTH command (RFC 4954). /* .IP "\fBdisable_vrfy_command (no)\fR" /* Disable the SMTP VRFY command. @@ -105,11 +105,13 @@ /* .IP "\fBsmtpd_discard_ehlo_keyword_address_maps (empty)\fR" /* Lookup tables, indexed by the remote SMTP client address, with /* case insensitive lists of EHLO keywords (pipelining, starttls, auth, -/* etc.) that the SMTP server will not send in the EHLO response to a +/* etc.) that the Postfix SMTP server will not send in the EHLO response +/* to a /* remote SMTP client. /* .IP "\fBsmtpd_discard_ehlo_keywords (empty)\fR" /* A case insensitive list of EHLO keywords (pipelining, starttls, -/* auth, etc.) that the SMTP server will not send in the EHLO response +/* auth, etc.) that the Postfix SMTP server will not send in the EHLO +/* response /* to a remote SMTP client. /* .IP "\fBsmtpd_delay_open_until_valid_rcpt (yes)\fR" /* Postpone the start of an SMTP mail transaction until a valid @@ -253,7 +255,7 @@ /* .PP /* Available in Postfix version 2.1 and later: /* .IP "\fBsmtpd_authorized_xforward_hosts (empty)\fR" -/* What SMTP clients are allowed to use the XFORWARD feature. +/* What remote SMTP clients are allowed to use the XFORWARD feature. /* SASL AUTHENTICATION CONTROLS /* .ad /* .fi @@ -262,7 +264,7 @@ /* Postfix SMTP client to a remote SMTP server. /* See the SASL_README document for details. /* .IP "\fBbroken_sasl_auth_clients (no)\fR" -/* Enable inter-operability with SMTP clients that implement an obsolete +/* Enable inter-operability with remote SMTP clients that implement an obsolete /* version of the AUTH command (RFC 4954). /* .IP "\fBsmtpd_sasl_auth_enable (no)\fR" /* Enable SASL authentication in the Postfix SMTP server. @@ -364,14 +366,14 @@ /* use with mandatory TLS encryption. /* .IP "\fBsmtpd_tls_mandatory_exclude_ciphers (empty)\fR" /* Additional list of ciphers or cipher types to exclude from the -/* SMTP server cipher list at mandatory TLS security levels. +/* Postfix SMTP server cipher list at mandatory TLS security levels. /* .IP "\fBsmtpd_tls_mandatory_protocols (SSLv3, TLSv1)\fR" /* The SSL/TLS protocols accepted by the Postfix SMTP server with /* mandatory TLS encryption. /* .IP "\fBsmtpd_tls_received_header (no)\fR" /* Request that the Postfix SMTP server produces Received: message /* headers that include information about the protocol and cipher used, -/* as well as the client CommonName and client certificate issuer +/* as well as the remote SMTP client CommonName and client certificate issuer /* CommonName. /* .IP "\fBsmtpd_tls_req_ccert (no)\fR" /* With mandatory TLS encryption, require a trusted remote SMTP client @@ -403,9 +405,10 @@ /* .PP /* Available in Postfix version 2.5 and later: /* .IP "\fBsmtpd_tls_fingerprint_digest (md5)\fR" -/* The message digest algorithm used to construct client-certificate -/* fingerprints for \fBcheck_ccert_access\fR and -/* \fBpermit_tls_clientcerts\fR. +/* The message digest algorithm to construct remote SMTP +/* client-certificate +/* fingerprints or public key fingerprints (Postfix 2.9 and later) +/* for \fBcheck_ccert_access\fR and \fBpermit_tls_clientcerts\fR. /* .PP /* Available in Postfix version 2.6 and later: /* .IP "\fBsmtpd_tls_protocols (empty)\fR" @@ -422,16 +425,19 @@ /* The Postfix SMTP server security grade for ephemeral elliptic-curve /* Diffie-Hellman (EECDH) key exchange. /* .IP "\fBtls_eecdh_strong_curve (prime256v1)\fR" -/* The elliptic curve used by the SMTP server for sensibly strong +/* The elliptic curve used by the Postfix SMTP server for sensibly +/* strong /* ephemeral ECDH key exchange. /* .IP "\fBtls_eecdh_ultra_curve (secp384r1)\fR" -/* The elliptic curve used by the SMTP server for maximally strong +/* The elliptic curve used by the Postfix SMTP server for maximally +/* strong /* ephemeral ECDH key exchange. /* .PP /* Available in Postfix version 2.8 and later: /* .IP "\fBtls_preempt_cipherlist (no)\fR" -/* With SSLv3 and later, use the server's cipher preference order -/* instead of the client's cipher preference order. +/* With SSLv3 and later, use the Postfix SMTP server's cipher +/* preference order instead of the remote client's cipher preference +/* order. /* .IP "\fBtls_disable_workarounds (see 'postconf -d' output)\fR" /* List or bit-mask of OpenSSL bug work-arounds to disable. /* OBSOLETE STARTTLS CONTROLS @@ -441,10 +447,10 @@ /* with Postfix versions before 2.3. Support for these will /* be removed in a future release. /* .IP "\fBsmtpd_use_tls (no)\fR" -/* Opportunistic TLS: announce STARTTLS support to SMTP clients, +/* Opportunistic TLS: announce STARTTLS support to remote SMTP clients, /* but do not require that clients use TLS encryption. /* .IP "\fBsmtpd_enforce_tls (no)\fR" -/* Mandatory TLS: announce STARTTLS support to SMTP clients, +/* Mandatory TLS: announce STARTTLS support to remote SMTP clients, /* and require that clients use TLS encryption. /* .IP "\fBsmtpd_tls_cipherlist (empty)\fR" /* Obsolete Postfix < 2.3 control for the Postfix SMTP server TLS @@ -468,11 +474,11 @@ /* .PP /* Available in Postfix version 1.1 and 2.0: /* .IP "\fBauthorized_verp_clients ($mynetworks)\fR" -/* What SMTP clients are allowed to specify the XVERP command. +/* What remote SMTP clients are allowed to specify the XVERP command. /* .PP /* Available in Postfix version 2.1 and later: /* .IP "\fBsmtpd_authorized_verp_clients ($authorized_verp_clients)\fR" -/* What SMTP clients are allowed to specify the XVERP command. +/* What remote SMTP clients are allowed to specify the XVERP command. /* TROUBLE SHOOTING CONTROLS /* .ad /* .fi @@ -498,7 +504,8 @@ /* .IP "\fBnotify_classes (resource, software)\fR" /* The list of error classes that are reported to the postmaster. /* .IP "\fBsmtpd_reject_footer (empty)\fR" -/* Optional information that is appended after each SMTP server +/* Optional information that is appended after each Postfix SMTP +/* server /* 4XX or 5XX response. /* .IP "\fBsoft_bounce (no)\fR" /* Safety net to keep mail queued that would otherwise be returned to @@ -506,7 +513,7 @@ /* .PP /* Available in Postfix version 2.1 and later: /* .IP "\fBsmtpd_authorized_xclient_hosts (empty)\fR" -/* What SMTP clients are allowed to use the XCLIENT feature. +/* What remote SMTP clients are allowed to use the XCLIENT feature. /* KNOWN VERSUS UNKNOWN RECIPIENT CONTROLS /* .ad /* .fi @@ -569,7 +576,7 @@ /* Optional lookup tables that alias specific mail addresses or domains /* to other local or remote address. /* .IP "\fBunknown_virtual_alias_reject_code (550)\fR" -/* The SMTP server reply code when a recipient address matches +/* The Postfix SMTP server reply code when a recipient address matches /* $virtual_alias_domains, and $virtual_alias_maps specifies a list /* of lookup tables that does not match the recipient address. /* .PP @@ -582,7 +589,7 @@ /* Optional lookup tables with all valid addresses in the domains that /* match $virtual_mailbox_domains. /* .IP "\fBunknown_virtual_mailbox_reject_code (550)\fR" -/* The SMTP server reply code when a recipient address matches +/* The Postfix SMTP server reply code when a recipient address matches /* $virtual_mailbox_domains, and $virtual_mailbox_maps specifies a list /* of lookup tables that does not match the recipient address. /* RESOURCE AND RATE CONTROLS @@ -705,8 +712,8 @@ /* What Postfix features match subdomains of "domain.tld" automatically, /* instead of requiring an explicit ".domain.tld" pattern. /* .IP "\fBsmtpd_client_restrictions (empty)\fR" -/* Optional SMTP server access restrictions in the context of a client -/* SMTP connection request. +/* Optional Postfix SMTP server access restrictions in the context of +/* a remote SMTP client connection request. /* .IP "\fBsmtpd_helo_required (no)\fR" /* Require that a remote SMTP client introduces itself with the HELO /* or EHLO command before sending the MAIL command or other commands @@ -858,7 +865,7 @@ /* .PP /* Available in Postfix version 2.0 and later: /* .IP "\fBdefault_rbl_reply (see 'postconf -d' output)\fR" -/* The default SMTP server response template for a request that is +/* The default Postfix SMTP server response template for a request that is /* rejected by an RBL-based restriction. /* .IP "\fBmulti_recipient_bounce_reject_code (550)\fR" /* The numerical Postfix SMTP server response code when a remote SMTP @@ -914,7 +921,7 @@ /* .IP "\fBmyhostname (see 'postconf -d' output)\fR" /* The internet hostname of this mail system. /* .IP "\fBmynetworks (see 'postconf -d' output)\fR" -/* The list of "trusted" SMTP clients that have more privileges than +/* The list of "trusted" remote SMTP clients that have more privileges than /* "strangers". /* .IP "\fBmyorigin ($myhostname)\fR" /* The domain name that locally-posted mail appears to come @@ -1226,7 +1233,7 @@ char *var_smtpd_tls_dh1024_param_file; char *var_smtpd_tls_dh512_param_file; char *var_smtpd_tls_dkey_file; char *var_smtpd_tls_key_file; -int var_smtpd_tls_loglevel; +char *var_smtpd_tls_loglevel; char *var_smtpd_tls_mand_proto; bool var_smtpd_tls_received_header; bool var_smtpd_tls_req_ccert; @@ -4068,7 +4075,6 @@ static void smtpd_start_tls(SMTPD_STATE *state) ctx = smtpd_tls_ctx, stream = state->client, fd = -1, - log_level = var_smtpd_tls_loglevel, timeout = var_smtpd_starttls_tmout, requirecert = requirecert, serverid = state->service, @@ -4991,6 +4997,7 @@ static void pre_jail_init(char *unused_name, char **unused_argv) */ smtpd_tls_ctx = TLS_SERVER_INIT(&props, + log_param = VAR_SMTPD_TLS_LOGLEVEL, log_level = var_smtpd_tls_loglevel, verifydepth = var_smtpd_tls_ccert_vd, cache_type = TLS_MGR_SCACHE_SMTPD, @@ -5155,7 +5162,6 @@ int main(int argc, char **argv) VAR_SMTPD_CNTLS_LIMIT, DEF_SMTPD_CNTLS_LIMIT, &var_smtpd_cntls_limit, 0, 0, #ifdef USE_TLS VAR_SMTPD_TLS_CCERT_VD, DEF_SMTPD_TLS_CCERT_VD, &var_smtpd_tls_ccert_vd, 0, 0, - VAR_SMTPD_TLS_LOGLEVEL, DEF_SMTPD_TLS_LOGLEVEL, &var_smtpd_tls_loglevel, 0, 0, #endif 0, }; @@ -5273,6 +5279,7 @@ int main(int argc, char **argv) VAR_SMTPD_TLS_1024_FILE, DEF_SMTPD_TLS_1024_FILE, &var_smtpd_tls_dh1024_param_file, 0, 0, VAR_SMTPD_TLS_EECDH, DEF_SMTPD_TLS_EECDH, &var_smtpd_tls_eecdh, 1, 0, VAR_SMTPD_TLS_FPT_DGST, DEF_SMTPD_TLS_FPT_DGST, &var_smtpd_tls_fpt_dgst, 1, 0, + VAR_SMTPD_TLS_LOGLEVEL, DEF_SMTPD_TLS_LOGLEVEL, &var_smtpd_tls_loglevel, 0, 0, #endif VAR_SMTPD_TLS_LEVEL, DEF_SMTPD_TLS_LEVEL, &var_smtpd_tls_level, 0, 0, VAR_SMTPD_SASL_TYPE, DEF_SMTPD_SASL_TYPE, &var_smtpd_sasl_type, 1, 0, diff --git a/postfix/src/smtpd/smtpd_check.c b/postfix/src/smtpd/smtpd_check.c index 93c7b83e5..45c4a53e6 100644 --- a/postfix/src/smtpd/smtpd_check.c +++ b/postfix/src/smtpd/smtpd_check.c @@ -427,7 +427,7 @@ static void rbl_byte_pageout(void *, void *); */ typedef struct { SMTPD_STATE *state; /* general state */ - char *domain; /* query domain */ + char *domain; /* query domain */ const char *what; /* rejected value */ const char *class; /* name of rejected value */ const char *txt; /* randomly selected trimmed TXT rr */ @@ -1223,7 +1223,7 @@ static int permit_auth_destination(SMTPD_STATE *state, char *recipient); static int permit_tls_clientcerts(SMTPD_STATE *state, int permit_all_certs) { #ifdef USE_TLS - const char *found; + const char *found = 0; dict_errno = 0; @@ -1241,15 +1241,22 @@ static int permit_tls_clientcerts(SMTPD_STATE *state, int permit_all_certs) * not trusted. */ if (TLS_CERT_IS_PRESENT(state->tls_context)) { - found = maps_find(relay_ccerts, state->tls_context->peer_fingerprint, - DICT_FLAG_NONE); + int i; + char *prints[2]; + + prints[0] = state->tls_context->peer_fingerprint; + prints[1] = state->tls_context->peer_pkey_fprint; + + /* After lookup error, leave dict_errno at its non-zero value. */ + for (i = 0; i < 2 && found == 0 && dict_errno == 0; ++i) + found = maps_find(relay_ccerts, prints[i], DICT_FLAG_NONE); if (found) { if (msg_verbose) msg_info("Relaying allowed for certified client: %s", found); return (SMTPD_CHECK_OK); } else if (msg_verbose) - msg_info("relay_clientcerts: No match for fingerprint '%s'", - state->tls_context->peer_fingerprint); + msg_info("relay_clientcerts: No match for fingerprint '%s', " + "pkey fingerprint %s", prints[0], prints[1]); } #else dict_errno = 0; @@ -2660,6 +2667,7 @@ static int check_server_access(SMTPD_STATE *state, const char *table, static int check_ccert_access(SMTPD_STATE *state, const char *table, const char *def_acl) { + int result = SMTPD_CHECK_DUNNO; #ifdef USE_TLS const char *myname = "check_ccert_access"; int found; @@ -2669,27 +2677,36 @@ static int check_ccert_access(SMTPD_STATE *state, const char *table, * not trusted. */ if (TLS_CERT_IS_PRESENT(state->tls_context)) { - if (msg_verbose) - msg_info("%s: %s", myname, state->tls_context->peer_fingerprint); + int i; + char *prints[2]; - /* - * Regexp tables don't make sense for certificate fingerprints. That - * may be so, but we can't ignore the entire check_ccert_access - * request without logging a warning. - * - * Log the peer CommonName when access is denied. Non-printable - * characters will be neutered by smtpd_check_reject(). The SMTP - * client name and address are always syslogged as part of a "reject" - * event. - */ - return (check_access(state, table, - state->tls_context->peer_fingerprint, - DICT_FLAG_NONE, &found, - state->tls_context->peer_CN, - SMTPD_NAME_CCERT, def_acl)); + prints[0] = state->tls_context->peer_fingerprint; + prints[1] = state->tls_context->peer_pkey_fprint; + + for (i = 0; i < 2; ++i) { + if (msg_verbose) + msg_info("%s: %s", myname, prints[i]); + + /* + * Regexp tables don't make sense for certificate fingerprints. + * That may be so, but we can't ignore the entire + * check_ccert_access request without logging a warning. + * + * Log the peer CommonName when access is denied. Non-printable + * characters will be neutered by smtpd_check_reject(). The SMTP + * client name and address are always syslogged as part of a + * "reject" event. + */ + result = check_access(state, table, prints[i], + DICT_FLAG_NONE, &found, + state->tls_context->peer_CN, + SMTPD_NAME_CCERT, def_acl); + if (result != SMTPD_CHECK_DUNNO) + break; + } } #endif - return (SMTPD_CHECK_DUNNO); + return (result); } /* check_mail_access - OK/FAIL based on mail address lookup */ @@ -3492,6 +3509,8 @@ static int check_policy_service(SMTPD_STATE *state, const char *server, */ ATTR_TYPE_STR, MAIL_ATTR_CCERT_FINGERPRINT, IF_ENCRYPTED(state->tls_context->peer_fingerprint, ""), + ATTR_TYPE_STR, MAIL_ATTR_CCERT_PKEY_FPRINT, + IF_ENCRYPTED(state->tls_context->peer_pkey_fprint, ""), ATTR_TYPE_STR, MAIL_ATTR_CRYPTO_PROTOCOL, IF_ENCRYPTED(state->tls_context->protocol, ""), ATTR_TYPE_STR, MAIL_ATTR_CRYPTO_CIPHER, @@ -3809,7 +3828,7 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions, } } else if (strcasecmp(name, PERMIT_NAKED_IP_ADDR) == 0) { msg_warn("restriction %s is deprecated. Use %s or %s instead", - PERMIT_NAKED_IP_ADDR, PERMIT_MYNETWORKS, PERMIT_SASL_AUTH); + PERMIT_NAKED_IP_ADDR, PERMIT_MYNETWORKS, PERMIT_SASL_AUTH); if (state->helo_name) { if (state->helo_name[strspn(state->helo_name, "0123456789.:")] == 0 && (status = reject_invalid_hostaddr(state, state->helo_name, @@ -3960,11 +3979,11 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions, #endif } else if (strcasecmp(name, PERMIT_TLS_ALL_CLIENTCERTS) == 0) { status = permit_tls_clientcerts(state, 1); - if (dict_errno != 0) + if (dict_errno != 0) reject_dict_retry(state, reply_name); } else if (strcasecmp(name, PERMIT_TLS_CLIENTCERTS) == 0) { status = permit_tls_clientcerts(state, 0); - if (dict_errno != 0) + if (dict_errno != 0) reject_dict_retry(state, reply_name); } else if (strcasecmp(name, REJECT_UNKNOWN_RCPTDOM) == 0) { if (state->recipient) diff --git a/postfix/src/tls/tls.h b/postfix/src/tls/tls.h index 5a06d8bd7..0ae91c839 100644 --- a/postfix/src/tls/tls.h +++ b/postfix/src/tls/tls.h @@ -85,6 +85,7 @@ typedef struct { char *peer_CN; /* Peer Common Name */ char *issuer_CN; /* Issuer Common Name */ char *peer_fingerprint; /* ASCII fingerprint */ + char *peer_pkey_fprint; /* ASCII public key fingerprint */ int peer_status; /* Certificate and match status */ const char *protocol; const char *cipher_name; @@ -95,7 +96,7 @@ typedef struct { char *cache_type; /* tlsmgr(8) cache type if enabled */ char *serverid; /* unique server identifier */ char *namaddr; /* nam[addr] for logging */ - int log_level; /* TLS library logging level */ + int log_mask; /* What to log */ int session_reused; /* this session was reused */ int am_server; /* Are we an SSL server or client? */ /* Built-in vs external SSL_accept/read/write/shutdown support. */ @@ -111,7 +112,6 @@ typedef struct { #define TLS_CERT_FLAG_ALTNAME (1<<1) #define TLS_CERT_FLAG_TRUSTED (1<<2) #define TLS_CERT_FLAG_MATCHED (1<<3) -#define TLS_CERT_FLAG_LOGGED (1<<4) /* Logged trust chain error */ #define TLS_CERT_IS_PRESENT(c) ((c) && ((c)->peer_status&TLS_CERT_FLAG_PRESENT)) #define TLS_CERT_IS_ALTNAME(c) ((c) && ((c)->peer_status&TLS_CERT_FLAG_ALTNAME)) @@ -125,11 +125,31 @@ typedef struct TLS_APPL_STATE TLS_APPL_STATE; #ifdef TLS_INTERNAL + /* + * Log mask details are internal to the library. + */ +extern int tls_log_mask(const char *, const char *); + + /* + * What to log. + */ +#define TLS_LOG_NONE (1<<0) +#define TLS_LOG_SUMMARY (1<<1) +#define TLS_LOG_UNTRUSTED (1<<2) +#define TLS_LOG_PEERCERT (1<<3) +#define TLS_LOG_CERTMATCH (1<<4) +#define TLS_LOG_VERBOSE (1<<5) +#define TLS_LOG_CACHE (1<<6) +#define TLS_LOG_DEBUG (1<<7) +#define TLS_LOG_TLSPKTS (1<<8) +#define TLS_LOG_ALLPKTS (1<<9) + /* * Client and Server application contexts */ struct TLS_APPL_STATE { SSL_CTX *ssl_ctx; + int log_mask; char *cache_type; char *cipher_exclusions; /* Last cipher selection state */ char *cipher_list; /* Last cipher selection state */ @@ -189,7 +209,8 @@ extern const char *tls_set_ciphers(TLS_APPL_STATE *, const char *, * tls_client.c */ typedef struct { - int log_level; + const char *log_param; + const char *log_level; int verifydepth; const char *cache_type; const char *cert_file; @@ -206,7 +227,6 @@ typedef struct { typedef struct { TLS_APPL_STATE *ctx; VSTREAM *stream; - int log_level; int timeout; int tls_level; /* Security level */ const char *nexthop; /* destination domain */ @@ -227,24 +247,25 @@ extern TLS_SESS_STATE *tls_client_start(const TLS_CLIENT_START_PROPS *); tls_session_stop(ctx, (stream), (timeout), (failure), (TLScontext)) #define TLS_CLIENT_INIT(props, a1, a2, a3, a4, a5, a6, a7, a8, a9, \ - a10, a11, a12) \ + a10, a11, a12, a13) \ tls_client_init((((props)->a1), ((props)->a2), ((props)->a3), \ ((props)->a4), ((props)->a5), ((props)->a6), ((props)->a7), \ ((props)->a8), ((props)->a9), ((props)->a10), ((props)->a11), \ - ((props)->a12), (props))) + ((props)->a12), ((props)->a13), (props))) #define TLS_CLIENT_START(props, a1, a2, a3, a4, a5, a6, a7, a8, a9, \ - a10, a11, a12, a13, a14) \ + a10, a11, a12, a13) \ tls_client_start((((props)->a1), ((props)->a2), ((props)->a3), \ ((props)->a4), ((props)->a5), ((props)->a6), ((props)->a7), \ ((props)->a8), ((props)->a9), ((props)->a10), ((props)->a11), \ - ((props)->a12), ((props)->a13), ((props)->a14), (props))) + ((props)->a12), ((props)->a13), (props))) /* * tls_server.c */ typedef struct { - int log_level; + const char *log_param; + const char *log_level; int verifydepth; const char *cache_type; long scache_timeout; @@ -269,7 +290,6 @@ typedef struct { TLS_APPL_STATE *ctx; /* TLS application context */ VSTREAM *stream; /* Client stream */ int fd; /* Event-driven file descriptor */ - int log_level; /* TLS log level */ int timeout; /* TLS handshake timeout */ int requirecert; /* Insist on client cert? */ const char *serverid; /* Server instance (salt cache key) */ @@ -287,17 +307,18 @@ extern TLS_SESS_STATE *tls_server_post_accept(TLS_SESS_STATE *); tls_session_stop(ctx, (stream), (timeout), (failure), (TLScontext)) #define TLS_SERVER_INIT(props, a1, a2, a3, a4, a5, a6, a7, a8, a9, \ - a10, a11, a12, a13, a14, a15, a16, a17, a18, a19) \ + a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) \ tls_server_init((((props)->a1), ((props)->a2), ((props)->a3), \ ((props)->a4), ((props)->a5), ((props)->a6), ((props)->a7), \ ((props)->a8), ((props)->a9), ((props)->a10), ((props)->a11), \ ((props)->a12), ((props)->a13), ((props)->a14), ((props)->a15), \ - ((props)->a16), ((props)->a17), ((props)->a18), ((props)->a19), (props))) + ((props)->a16), ((props)->a17), ((props)->a18), ((props)->a19), \ + ((props)->a20), (props))) -#define TLS_SERVER_START(props, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) \ +#define TLS_SERVER_START(props, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) \ tls_server_start((((props)->a1), ((props)->a2), ((props)->a3), \ ((props)->a4), ((props)->a5), ((props)->a6), ((props)->a7), \ - ((props)->a8), ((props)->a9), ((props)->a10), ((props)->a11), (props))) + ((props)->a8), ((props)->a9), ((props)->a10), (props))) /* * tls_session.c @@ -364,6 +385,7 @@ extern char *tls_peer_CN(X509 *, const TLS_SESS_STATE *); extern char *tls_issuer_CN(X509 *, const TLS_SESS_STATE *); extern const char *tls_dns_name(const GENERAL_NAME *, const TLS_SESS_STATE *); extern char *tls_fingerprint(X509 *, const char *); +extern char *tls_pkey_fprint(X509 *, const char *); extern int tls_verify_certificate_callback(int, X509_STORE_CTX *); /* @@ -380,7 +402,7 @@ extern int tls_set_my_certificate_key_info(SSL_CTX *, */ extern int TLScontext_index; -extern TLS_APPL_STATE *tls_alloc_app_context(SSL_CTX *); +extern TLS_APPL_STATE *tls_alloc_app_context(SSL_CTX *, int); extern TLS_SESS_STATE *tls_alloc_sess_context(int, const char *); extern void tls_free_context(TLS_SESS_STATE *); extern void tls_check_version(void); diff --git a/postfix/src/tls/tls_client.c b/postfix/src/tls/tls_client.c index 750fb5a83..37ee27a50 100644 --- a/postfix/src/tls/tls_client.c +++ b/postfix/src/tls/tls_client.c @@ -167,7 +167,8 @@ static SSL_SESSION *load_clnt_session(TLS_SESS_STATE *TLScontext) /* * Prepare the query. */ - if (TLScontext->log_level >= 2) + if (TLScontext->log_mask & TLS_LOG_CACHE) + /* serverid already contains namaddrport information */ msg_info("looking for session %s in %s cache", TLScontext->serverid, TLScontext->cache_type); @@ -188,7 +189,8 @@ static SSL_SESSION *load_clnt_session(TLS_SESS_STATE *TLScontext) session_data) == TLS_MGR_STAT_OK) { session = tls_session_activate(STR(session_data), LEN(session_data)); if (session) { - if (TLScontext->log_level >= 2) + if (TLScontext->log_mask & TLS_LOG_CACHE) + /* serverid already contains namaddrport information */ msg_info("reloaded session %s from %s cache", TLScontext->serverid, TLScontext->cache_type); } @@ -227,7 +229,8 @@ static int new_client_session_cb(SSL *ssl, SSL_SESSION *session) msg_panic("%s: null session cache type in new session callback", myname); - if (TLScontext->log_level >= 2) + if (TLScontext->log_mask & TLS_LOG_CACHE) + /* serverid already contains namaddrport information */ msg_info("save session %s to %s cache", TLScontext->serverid, TLScontext->cache_type); @@ -274,7 +277,8 @@ static void uncache_session(SSL_CTX *ctx, TLS_SESS_STATE *TLScontext) if (TLScontext->cache_type == 0 || TLScontext->serverid == 0) return; - if (TLScontext->log_level >= 2) + if (TLScontext->log_mask & TLS_LOG_CACHE) + /* serverid already contains namaddrport information */ msg_info("remove session %s from client cache", TLScontext->serverid); tls_mgr_delete(TLScontext->cache_type, TLScontext->serverid); @@ -290,8 +294,14 @@ TLS_APPL_STATE *tls_client_init(const TLS_CLIENT_INIT_PROPS *props) TLS_APPL_STATE *app_ctx; const EVP_MD *md_alg; unsigned int md_len; + int log_mask; - if (props->log_level >= 2) + /* + * Convert user loglevel to internal logmask. + */ + log_mask = tls_log_mask(props->log_param, props->log_level); + + if (log_mask & TLS_LOG_VERBOSE) msg_info("initializing the client-side TLS engine"); /* @@ -385,7 +395,7 @@ TLS_APPL_STATE *tls_client_init(const TLS_CLIENT_INIT_PROPS *props) /* * Set the call-back routine for verbose logging. */ - if (props->log_level >= 2) + if (log_mask & TLS_LOG_DEBUG) SSL_CTX_set_info_callback(client_ctx, tls_info_callback); /* @@ -469,7 +479,7 @@ TLS_APPL_STATE *tls_client_init(const TLS_CLIENT_INIT_PROPS *props) * Allocate an application context, and populate with mandatory protocol * and cipher data. */ - app_ctx = tls_alloc_app_context(client_ctx); + app_ctx = tls_alloc_app_context(client_ctx, log_mask); /* * The external session cache is implemented by the tlsmgr(8) process. @@ -510,7 +520,7 @@ TLS_APPL_STATE *tls_client_init(const TLS_CLIENT_INIT_PROPS *props) static int match_hostname(const char *peerid, const TLS_CLIENT_START_PROPS *props) { - const ARGV *cmatch_argv = props->matchargv; + const ARGV *cmatch_argv; const char *nexthop = props->nexthop; const char *hname = props->host; const char *pattern; @@ -520,6 +530,9 @@ static int match_hostname(const char *peerid, int idlen; int patlen; + if ((cmatch_argv = props->matchargv) == 0) + return 0; + /* * Match the peerid against each pattern until we find a match. */ @@ -574,6 +587,10 @@ static void verify_extract_name(TLS_SESS_STATE *TLScontext, X509 *peercert, int i; int r; int matched = 0; + int dnsname_match; + int verify_peername = 0; + int log_certmatch; + int verbose; const char *dnsname; const GENERAL_NAME *gn; @@ -590,7 +607,16 @@ static void verify_extract_name(TLS_SESS_STATE *TLScontext, X509 *peercert, if (SSL_get_verify_result(TLScontext->con) == X509_V_OK) TLScontext->peer_status |= TLS_CERT_FLAG_TRUSTED; - if (TLS_CERT_IS_TRUSTED(TLScontext) && props->tls_level >= TLS_LEV_VERIFY) { + if (TLS_CERT_IS_TRUSTED(TLScontext) && props->tls_level >= TLS_LEV_VERIFY) + verify_peername = 1; + + /* Force cert processing so we can log the data? */ + log_certmatch = TLScontext->log_mask & TLS_LOG_CERTMATCH; + + /* Log cert details when processing? */ + verbose = log_certmatch || (TLScontext->log_mask & TLS_LOG_VERBOSE); + + if (verify_peername || log_certmatch) { /* * Verify the dNSName(s) in the peer certificate against the nexthop @@ -614,7 +640,7 @@ static void verify_extract_name(TLS_SESS_STATE *TLScontext, X509 *peercert, gens = X509_get_ext_d2i(peercert, NID_subject_alt_name, 0, 0); if (gens) { r = sk_GENERAL_NAME_num(gens); - for (i = 0; i < r && !matched; ++i) { + for (i = 0; i < r; ++i) { gn = sk_GENERAL_NAME_value(gens, i); if (gn->type != GEN_DNS) continue; @@ -632,16 +658,26 @@ static void verify_extract_name(TLS_SESS_STATE *TLScontext, X509 *peercert, TLScontext->peer_status |= TLS_CERT_FLAG_ALTNAME; dnsname = tls_dns_name(gn, TLScontext); if (dnsname && *dnsname) { - matched = match_hostname(dnsname, props); + if ((dnsname_match = match_hostname(dnsname, props)) != 0) + matched++; + /* Keep the first matched name. */ if (TLScontext->peer_CN - && (matched || *TLScontext->peer_CN == 0)) { + && ((dnsname_match && matched == 1) + || *TLScontext->peer_CN == 0)) { myfree(TLScontext->peer_CN); TLScontext->peer_CN = 0; } + if (verbose) + msg_info("%s: %ssubjectAltName: %s", props->namaddr, + dnsname_match ? "Matched " : "", dnsname); } if (TLScontext->peer_CN == 0) TLScontext->peer_CN = mystrdup(dnsname ? dnsname : ""); + if (matched && !log_certmatch) + break; } + if (verify_peername && matched) + TLScontext->peer_status |= TLS_CERT_FLAG_MATCHED; /* * (Sam Rushing, Ironport) Free stack *and* member GENERAL_NAME @@ -657,20 +693,21 @@ static void verify_extract_name(TLS_SESS_STATE *TLScontext, X509 *peercert, TLScontext->peer_CN = tls_peer_CN(peercert, TLScontext); if (*TLScontext->peer_CN) matched = match_hostname(TLScontext->peer_CN, props); - } - if (matched) - TLScontext->peer_status |= TLS_CERT_FLAG_MATCHED; + if (verify_peername && matched) + TLScontext->peer_status |= TLS_CERT_FLAG_MATCHED; + if (verbose) + msg_info("%s %sCommonName %s", props->namaddr, + matched ? "Matched " : "", TLScontext->peer_CN); + } else if (verbose) { + char *tmpcn = tls_peer_CN(peercert, TLScontext); - /* - * - Matched: Trusted and peername matches - Trusted: Signed by - * trusted CA(s), but peername not matched - Untrusted: Can't verify - * the trust chain, reason already logged. - */ - if (TLScontext->log_level >= 2) - msg_info("%s: %s subject_CN=%s, issuer_CN=%s", props->namaddr, - TLS_CERT_IS_MATCHED(TLScontext) ? "Matched" : - TLS_CERT_IS_TRUSTED(TLScontext) ? "Trusted" : "Untrusted", - TLScontext->peer_CN, TLScontext->issuer_CN); + /* + * Though the CommonName was superceded by a subjectAltName, log + * it when certificate match debugging was requested. + */ + msg_info("%s CommonName %s", TLScontext->namaddr, tmpcn); + myfree(tmpcn); + } } else TLScontext->peer_CN = tls_peer_CN(peercert, TLScontext); @@ -682,7 +719,7 @@ static void verify_extract_name(TLS_SESS_STATE *TLScontext, X509 *peercert, */ if (TLScontext->session_reused && !TLS_CERT_IS_TRUSTED(TLScontext) - && TLScontext->log_level >= 1) + && (TLScontext->log_mask & TLS_LOG_UNTRUSTED)) msg_info("%s: re-using session with untrusted certificate, " "look for details earlier in the log", props->namaddr); } @@ -696,23 +733,21 @@ static void verify_extract_print(TLS_SESS_STATE *TLScontext, X509 *peercert, /* Non-null by contract */ TLScontext->peer_fingerprint = tls_fingerprint(peercert, props->fpt_dgst); - - if (props->tls_level != TLS_LEV_FPRINT) - return; + TLScontext->peer_pkey_fprint = tls_pkey_fprint(peercert, props->fpt_dgst); /* * Compare the fingerprint against each acceptable value, ignoring * upper/lower case differences. */ - for (cpp = props->matchargv->argv; *cpp; ++cpp) - if (strcasecmp(TLScontext->peer_fingerprint, *cpp) == 0) { - TLScontext->peer_status |= TLS_CERT_FLAG_MATCHED; - break; + if (props->tls_level == TLS_LEV_FPRINT) { + for (cpp = props->matchargv->argv; *cpp; ++cpp) { + if (strcasecmp(TLScontext->peer_fingerprint, *cpp) == 0 + || strcasecmp(TLScontext->peer_pkey_fprint, *cpp) == 0) { + TLScontext->peer_status |= TLS_CERT_FLAG_MATCHED; + break; + } } - if (props->log_level >= 2) - msg_info("%s %s%s fingerprint %s", props->namaddr, - TLS_CERT_IS_MATCHED(TLScontext) ? "Matched " : "", - props->fpt_dgst, TLScontext->peer_fingerprint); + } } /* @@ -731,8 +766,16 @@ TLS_SESS_STATE *tls_client_start(const TLS_CLIENT_START_PROPS *props) TLS_SESS_STATE *TLScontext; TLS_APPL_STATE *app_ctx = props->ctx; VSTRING *myserverid; + int log_mask = app_ctx->log_mask; - if (props->log_level >= 1) + /* + * When certificate verification is required, log trust chain validation + * errors even when disabled by default for opportunistic sessions. + */ + if (props->tls_level >= TLS_LEV_VERIFY) + log_mask |= TLS_LOG_UNTRUSTED; + + if (log_mask & TLS_LOG_VERBOSE) msg_info("setting up TLS connection to %s", props->namaddr); /* @@ -779,7 +822,7 @@ TLS_SESS_STATE *tls_client_start(const TLS_CLIENT_START_PROPS *props) vstring_free(myserverid); return (0); } - if (props->log_level >= 2) + if (log_mask & TLS_LOG_VERBOSE) msg_info("%s: TLS cipher list \"%s\"", props->namaddr, cipher_list); vstring_sprintf_append(myserverid, "&c=%s", cipher_list); @@ -791,7 +834,7 @@ TLS_SESS_STATE *tls_client_start(const TLS_CLIENT_START_PROPS *props) * If session caching was enabled when TLS was initialized, the cache type * is stored in the client SSL context. */ - TLScontext = tls_alloc_sess_context(props->log_level, props->namaddr); + TLScontext = tls_alloc_sess_context(log_mask, props->namaddr); TLScontext->cache_type = app_ctx->cache_type; TLScontext->serverid = vstring_export(myserverid); @@ -881,13 +924,14 @@ TLS_SESS_STATE *tls_client_start(const TLS_CLIENT_START_PROPS *props) /* * If the debug level selected is high enough, all of the data is dumped: - * 3 will dump the SSL negotiation, 4 will dump everything. + * TLS_LOG_TLSPKTS will dump the SSL negotiation, TLS_LOG_ALLPKTS will + * dump everything. * * We do have an SSL_set_fd() and now suddenly a BIO_ routine is called? * Well there is a BIO below the SSL routines that is automatically * created for us, so we can use it for debugging purposes. */ - if (props->log_level >= 3) + if (log_mask & TLS_LOG_TLSPKTS) BIO_set_callback(SSL_get_rbio(TLScontext->con), tls_bio_dump_cb); /* @@ -913,8 +957,8 @@ TLS_SESS_STATE *tls_client_start(const TLS_CLIENT_START_PROPS *props) tls_free_context(TLScontext); return (0); } - /* Only log_level==4 dumps everything */ - if (props->log_level < 4) + /* Turn off packet dump if only dumping the handshake */ + if ((log_mask & TLS_LOG_ALLPKTS) == 0) BIO_set_callback(SSL_get_rbio(TLScontext->con), 0); /* @@ -922,7 +966,7 @@ TLS_SESS_STATE *tls_client_start(const TLS_CLIENT_START_PROPS *props) * session was negotiated. */ TLScontext->session_reused = SSL_session_reused(TLScontext->con); - if (props->log_level >= 2 && TLScontext->session_reused) + if ((log_mask & TLS_LOG_CACHE) && TLScontext->session_reused) msg_info("%s: Reusing old session", TLScontext->namaddr); /* @@ -938,11 +982,20 @@ TLS_SESS_STATE *tls_client_start(const TLS_CLIENT_START_PROPS *props) */ verify_extract_name(TLScontext, peercert, props); verify_extract_print(TLScontext, peercert, props); + + if (TLScontext->log_mask & + (TLS_LOG_CERTMATCH | TLS_LOG_VERBOSE | TLS_LOG_PEERCERT)) + msg_info("%s: subject_CN=%s, issuer_CN=%s, " + "fingerprint %s, pkey_fingerprint=%s", props->namaddr, + TLScontext->peer_CN, TLScontext->issuer_CN, + TLScontext->peer_fingerprint, + TLScontext->peer_pkey_fprint); X509_free(peercert); } else { TLScontext->issuer_CN = mystrdup(""); TLScontext->peer_CN = mystrdup(""); TLScontext->peer_fingerprint = mystrdup(""); + TLScontext->peer_pkey_fprint = mystrdup(""); } /* @@ -963,7 +1016,7 @@ TLS_SESS_STATE *tls_client_start(const TLS_CLIENT_START_PROPS *props) /* * All the key facts in a single log entry. */ - if (props->log_level >= 1) + if (log_mask & TLS_LOG_SUMMARY) msg_info("%s TLS connection established to %s: %s with cipher %s " "(%d/%d bits)", TLS_CERT_IS_MATCHED(TLScontext) ? "Verified" : TLS_CERT_IS_TRUSTED(TLScontext) ? "Trusted" : "Untrusted", diff --git a/postfix/src/tls/tls_misc.c b/postfix/src/tls/tls_misc.c index e4d217d27..33dbdf3f5 100644 --- a/postfix/src/tls/tls_misc.c +++ b/postfix/src/tls/tls_misc.c @@ -18,14 +18,15 @@ /* bool var_tls_append_def_CA; /* bool var_tls_preempt_clist; /* -/* TLS_APPL_STATE *tls_alloc_app_context(ssl_ctx) +/* TLS_APPL_STATE *tls_alloc_app_context(ssl_ctx, log_mask) /* SSL_CTX *ssl_ctx; +/* int log_mask; /* /* void tls_free_app_context(app_ctx) /* void *app_ctx; /* -/* TLS_SESS_STATE *tls_alloc_sess_context(log_level, namaddr) -/* int log_level; +/* TLS_SESS_STATE *tls_alloc_sess_context(log_mask, namaddr) +/* int log_mask; /* const char *namaddr; /* /* void tls_free_context(TLScontext) @@ -66,6 +67,10 @@ /* int argi; /* long argl; /* unused */ /* long ret; +/* +/* int tls_log_mask(log_param, log_level) +/* const char *log_param; +/* const char *log_level; /* DESCRIPTION /* This module implements routines that support the TLS client /* and server internals. @@ -126,6 +131,10 @@ /* tls_bio_dump_cb() is a call-back routine for the /* BIO_set_callback() routine. It logs SSL content to the /* Postfix logfile. +/* +/* tls_log_mask() converts a TLS log_level value from string +/* to mask. The main.cf parameter name is passed along for +/* diagnostics. /* LICENSE /* .ad /* .fi @@ -293,6 +302,43 @@ const NAME_CODE tls_cipher_grade_table[] = { 0, TLS_CIPHER_NONE, }; + /* + * Log keyword <=> mask conversion. + */ +#define TLS_LOG_0 TLS_LOG_NONE +#define TLS_LOG_1 TLS_LOG_SUMMARY +#define TLS_LOG_2 (TLS_LOG_1 | TLS_LOG_VERBOSE | TLS_LOG_CACHE | TLS_LOG_DEBUG) +#define TLS_LOG_3 (TLS_LOG_2 | TLS_LOG_TLSPKTS) +#define TLS_LOG_4 (TLS_LOG_3 | TLS_LOG_ALLPKTS) + +static const NAME_MASK tls_log_table[] = { + "0", TLS_LOG_0, + "none", TLS_LOG_NONE, + "1", TLS_LOG_1, + "routine", TLS_LOG_1, + "2", TLS_LOG_2, + "debug", TLS_LOG_2, + "3", TLS_LOG_3, + "ssl-expert", TLS_LOG_3, + "4", TLS_LOG_4, + "ssl-developer", TLS_LOG_4, + "5", TLS_LOG_4, /* for good measure */ + "6", TLS_LOG_4, /* for good measure */ + "7", TLS_LOG_4, /* for good measure */ + "8", TLS_LOG_4, /* for good measure */ + "9", TLS_LOG_4, /* for good measure */ + "summary", TLS_LOG_SUMMARY, + "untrusted", TLS_LOG_UNTRUSTED, + "peercert", TLS_LOG_PEERCERT, + "certmatch", TLS_LOG_CERTMATCH, + "verbose", TLS_LOG_VERBOSE, /* Postfix TLS library verbose */ + "cache", TLS_LOG_CACHE, + "ssl-debug", TLS_LOG_DEBUG, /* SSL library debug/verbose */ + "ssl-handshake-packet-dump", TLS_LOG_TLSPKTS, + "ssl-session-packet-dump", TLS_LOG_TLSPKTS | TLS_LOG_ALLPKTS, + 0, 0, +}; + /* * Parsed OpenSSL version number. */ @@ -320,6 +366,17 @@ static const cipher_probe_t cipher_probes[] = { 0, 0, 0, }; +/* tls_log_mask - Convert user TLS loglevel to internal log feature mask */ + +int tls_log_mask(const char *log_param, const char *log_level) +{ + int mask; + + mask = name_mask_opt(log_param, tls_log_table, log_level, + NAME_MASK_ANY_CASE | NAME_MASK_RETURN); + return (mask); +} + /* tls_exclude_missing - Append exclusions for missing ciphers */ static const char *tls_exclude_missing(SSL_CTX *ctx, VSTRING *buf) @@ -602,14 +659,16 @@ const char *tls_set_ciphers(TLS_APPL_STATE *app_ctx, const char *context, /* tls_alloc_app_context - allocate TLS application context */ -TLS_APPL_STATE *tls_alloc_app_context(SSL_CTX *ssl_ctx) +TLS_APPL_STATE *tls_alloc_app_context(SSL_CTX *ssl_ctx, int log_mask) { TLS_APPL_STATE *app_ctx; app_ctx = (TLS_APPL_STATE *) mymalloc(sizeof(*app_ctx)); + /* See portability note below with other memset() call. */ memset((char *) app_ctx, 0, sizeof(*app_ctx)); app_ctx->ssl_ctx = ssl_ctx; + app_ctx->log_mask = log_mask; /* See also: cache purging code in tls_set_ciphers(). */ app_ctx->cipher_grade = TLS_CIPHER_NONE; @@ -641,7 +700,7 @@ void tls_free_app_context(TLS_APPL_STATE *app_ctx) /* tls_alloc_sess_context - allocate TLS session context */ -TLS_SESS_STATE *tls_alloc_sess_context(int log_level, const char *namaddr) +TLS_SESS_STATE *tls_alloc_sess_context(int log_mask, const char *namaddr) { TLS_SESS_STATE *TLScontext; @@ -662,9 +721,10 @@ TLS_SESS_STATE *tls_alloc_sess_context(int log_level, const char *namaddr) TLScontext->peer_CN = 0; TLScontext->issuer_CN = 0; TLScontext->peer_fingerprint = 0; + TLScontext->peer_pkey_fprint = 0; TLScontext->protocol = 0; TLScontext->cipher_name = 0; - TLScontext->log_level = log_level; + TLScontext->log_mask = log_mask; TLScontext->namaddr = lowercase(mystrdup(namaddr)); TLScontext->fpt_dgst = 0; @@ -695,6 +755,8 @@ void tls_free_context(TLS_SESS_STATE *TLScontext) myfree(TLScontext->issuer_CN); if (TLScontext->peer_fingerprint) myfree(TLScontext->peer_fingerprint); + if (TLScontext->peer_pkey_fprint) + myfree(TLScontext->peer_pkey_fprint); if (TLScontext->fpt_dgst) myfree(TLScontext->fpt_dgst); @@ -792,7 +854,6 @@ void tls_check_version(void) long tls_bug_bits(void) { long bits = SSL_OP_ALL; /* Work around all known bugs */ - long mask; #if OPENSSL_VERSION_NUMBER >= 0x00908000L long lib_version = SSLeay(); diff --git a/postfix/src/tls/tls_proxy_print.c b/postfix/src/tls/tls_proxy_print.c index 36bfc112f..e919a9ee8 100644 --- a/postfix/src/tls/tls_proxy_print.c +++ b/postfix/src/tls/tls_proxy_print.c @@ -53,7 +53,7 @@ /* tls_proxy_context_print - send TLS session state over stream */ int tls_proxy_context_print(ATTR_PRINT_MASTER_FN print_fn, VSTREAM *fp, - int flags, void *ptr) + int flags, void *ptr) { TLS_SESS_STATE *tp = (TLS_SESS_STATE *) ptr; int ret; @@ -67,6 +67,8 @@ int tls_proxy_context_print(ATTR_PRINT_MASTER_FN print_fn, VSTREAM *fp, STRING_OR_EMPTY(tp->issuer_CN), ATTR_TYPE_STR, MAIL_ATTR_PEER_FPT, STRING_OR_EMPTY(tp->peer_fingerprint), + ATTR_TYPE_STR, MAIL_ATTR_PEER_PKEY_FPT, + STRING_OR_EMPTY(tp->peer_pkey_fprint), ATTR_TYPE_INT, MAIL_ATTR_PEER_STATUS, tp->peer_status, ATTR_TYPE_STR, MAIL_ATTR_CIPHER_PROTOCOL, diff --git a/postfix/src/tls/tls_proxy_scan.c b/postfix/src/tls/tls_proxy_scan.c index fd5621036..33db215dd 100644 --- a/postfix/src/tls/tls_proxy_scan.c +++ b/postfix/src/tls/tls_proxy_scan.c @@ -53,13 +53,14 @@ /* tls_proxy_context_scan - receive TLS session state from stream */ int tls_proxy_context_scan(ATTR_SCAN_MASTER_FN scan_fn, VSTREAM *fp, - int flags, void *ptr) + int flags, void *ptr) { TLS_SESS_STATE *tls_context = (TLS_SESS_STATE *) ptr; int ret; VSTRING *peer_CN = vstring_alloc(25); VSTRING *issuer_CN = vstring_alloc(25); - VSTRING *peer_fingerprint = vstring_alloc(25); + VSTRING *peer_fingerprint = vstring_alloc(60); /* 60 for SHA-1 */ + VSTRING *peer_pkey_fprint = vstring_alloc(60); /* 60 for SHA-1 */ VSTRING *protocol = vstring_alloc(25); VSTRING *cipher_name = vstring_alloc(25); @@ -71,6 +72,7 @@ int tls_proxy_context_scan(ATTR_SCAN_MASTER_FN scan_fn, VSTREAM *fp, ATTR_TYPE_STR, MAIL_ATTR_PEER_CN, peer_CN, ATTR_TYPE_STR, MAIL_ATTR_ISSUER_CN, issuer_CN, ATTR_TYPE_STR, MAIL_ATTR_PEER_FPT, peer_fingerprint, + ATTR_TYPE_STR, MAIL_ATTR_PEER_PKEY_FPT, peer_pkey_fprint, ATTR_TYPE_INT, MAIL_ATTR_PEER_STATUS, &tls_context->peer_status, ATTR_TYPE_STR, MAIL_ATTR_CIPHER_PROTOCOL, protocol, @@ -83,9 +85,10 @@ int tls_proxy_context_scan(ATTR_SCAN_MASTER_FN scan_fn, VSTREAM *fp, tls_context->peer_CN = vstring_export(peer_CN); tls_context->issuer_CN = vstring_export(issuer_CN); tls_context->peer_fingerprint = vstring_export(peer_fingerprint); + tls_context->peer_pkey_fprint = vstring_export(peer_pkey_fprint); tls_context->protocol = vstring_export(protocol); tls_context->cipher_name = vstring_export(cipher_name); - return (ret == 8 ? 1 : -1); + return (ret == 9 ? 1 : -1); } #endif diff --git a/postfix/src/tls/tls_server.c b/postfix/src/tls/tls_server.c index 19b0fb2ae..ffc0ffad9 100644 --- a/postfix/src/tls/tls_server.c +++ b/postfix/src/tls/tls_server.c @@ -34,7 +34,7 @@ /* /* tls_server_start() activates the TLS feature for the VSTREAM /* passed as argument. We assume that network buffers are flushed -/* and the TLS handshake can begin immediately. +/* and the TLS handshake can begin immediately. /* /* tls_server_stop() sends the "close notify" alert via /* SSL_shutdown() to the peer and resets all connection specific @@ -82,7 +82,7 @@ /* programs cannot use the synchronous VSTREAM-over-TLS /* implementation that the current TLS library provides, /* including tls_server_stop() and the underlying tls_stream(3) -/* and tls_bio_ops(3) routines. +/* and tls_bio_ops(3) routines. /* /* With the current TLS library implementation, this means /* that the application is responsible for calling and retrying @@ -189,7 +189,7 @@ static SSL_SESSION *get_server_session_cb(SSL *ssl, unsigned char *session_id, GEN_CACHE_ID(cache_id, session_id, session_id_length, TLScontext->serverid); - if (TLScontext->log_level >= 2) + if (TLScontext->log_mask & TLS_LOG_CACHE) msg_info("%s: looking up session %s in %s cache", TLScontext->namaddr, STR(cache_id), TLScontext->cache_type); @@ -199,7 +199,7 @@ static SSL_SESSION *get_server_session_cb(SSL *ssl, unsigned char *session_id, if (tls_mgr_lookup(TLScontext->cache_type, STR(cache_id), session_data) == TLS_MGR_STAT_OK) { session = tls_session_activate(STR(session_data), LEN(session_data)); - if (session && (TLScontext->log_level >= 2)) + if (session && (TLScontext->log_mask & TLS_LOG_CACHE)) msg_info("%s: reloaded session %s from %s cache", TLScontext->namaddr, STR(cache_id), TLScontext->cache_type); @@ -229,7 +229,7 @@ static void uncache_session(SSL_CTX *ctx, TLS_SESS_STATE *TLScontext) GEN_CACHE_ID(cache_id, session->session_id, session->session_id_length, TLScontext->serverid); - if (TLScontext->log_level >= 2) + if (TLScontext->log_mask & TLS_LOG_CACHE) msg_info("%s: remove session %s from %s cache", TLScontext->namaddr, STR(cache_id), TLScontext->cache_type); @@ -252,7 +252,7 @@ static int new_server_session_cb(SSL *ssl, SSL_SESSION *session) GEN_CACHE_ID(cache_id, session->session_id, session->session_id_length, TLScontext->serverid); - if (TLScontext->log_level >= 2) + if (TLScontext->log_mask & TLS_LOG_CACHE) msg_info("%s: save session %s to %s cache", TLScontext->namaddr, STR(cache_id), TLScontext->cache_type); @@ -287,8 +287,14 @@ TLS_APPL_STATE *tls_server_init(const TLS_SERVER_INIT_PROPS *props) TLS_APPL_STATE *app_ctx; const EVP_MD *md_alg; unsigned int md_len; + int log_mask; - if (props->log_level >= 2) + /* + * Convert user loglevel to internal logmask. + */ + log_mask = tls_log_mask(props->log_param, props->log_level); + + if (log_mask & TLS_LOG_VERBOSE) msg_info("initializing the server-side TLS engine"); /* @@ -418,7 +424,7 @@ TLS_APPL_STATE *tls_server_init(const TLS_SERVER_INIT_PROPS *props) /* * Set the call-back routine to debug handshake progress. */ - if (props->log_level >= 2) + if (log_mask & TLS_LOG_DEBUG) SSL_CTX_set_info_callback(server_ctx, tls_info_callback); /* @@ -464,9 +470,9 @@ TLS_APPL_STATE *tls_server_init(const TLS_SERVER_INIT_PROPS *props) } /* - * According to the OpenSSL documentation, temporary RSA key is needed - * export ciphers are in use. We have to provide one, so well, we just do - * it. + * According to OpenSSL documentation, a temporary RSA key is needed when + * export ciphers are in use, because the certified key cannot be + * directly used. */ SSL_CTX_set_tmp_rsa_callback(server_ctx, tls_tmp_rsa_cb); @@ -522,7 +528,7 @@ TLS_APPL_STATE *tls_server_init(const TLS_SERVER_INIT_PROPS *props) * Initialize our own TLS server handle, before diving into the details * of TLS session cache management. */ - app_ctx = tls_alloc_app_context(server_ctx); + app_ctx = tls_alloc_app_context(server_ctx, log_mask); /* * The session cache is implemented by the tlsmgr(8) server. @@ -602,8 +608,16 @@ TLS_SESS_STATE *tls_server_start(const TLS_SERVER_START_PROPS *props) TLS_SESS_STATE *TLScontext; const char *cipher_list; TLS_APPL_STATE *app_ctx = props->ctx; + int log_mask = app_ctx->log_mask; + + /* + * Implicitly enable logging of trust chain errors when verified certs + * are required. + */ + if (props->requirecert) + log_mask |= TLS_LOG_UNTRUSTED; - if (props->log_level >= 1) + if (log_mask & TLS_LOG_VERBOSE) msg_info("setting up TLS connection from %s", props->namaddr); cipher_list = tls_set_ciphers(app_ctx, "TLS", props->cipher_grade, @@ -613,7 +627,7 @@ TLS_SESS_STATE *tls_server_start(const TLS_SERVER_START_PROPS *props) vstring_str(app_ctx->why)); return (0); } - if (props->log_level >= 2) + if (log_mask & TLS_LOG_VERBOSE) msg_info("%s: TLS cipher list \"%s\"", props->namaddr, cipher_list); /* @@ -621,7 +635,7 @@ TLS_SESS_STATE *tls_server_start(const TLS_SERVER_START_PROPS *props) * structure. Add the location of TLScontext to the SSL to later retrieve * the information inside the tls_verify_certificate_callback(). */ - TLScontext = tls_alloc_sess_context(props->log_level, props->namaddr); + TLScontext = tls_alloc_sess_context(log_mask, props->namaddr); TLScontext->cache_type = app_ctx->cache_type; TLScontext->serverid = mystrdup(props->serverid); @@ -672,13 +686,14 @@ TLS_SESS_STATE *tls_server_start(const TLS_SERVER_START_PROPS *props) /* * If the debug level selected is high enough, all of the data is dumped: - * 3 will dump the SSL negotiation, 4 will dump everything. + * TLS_LOG_TLSPKTS will dump the SSL negotiation, TLS_LOG_ALLPKTS will + * dump everything. * * We do have an SSL_set_fd() and now suddenly a BIO_ routine is called? * Well there is a BIO below the SSL routines that is automatically * created for us, so we can use it for debugging purposes. */ - if (props->log_level >= 3) + if (log_mask & TLS_LOG_TLSPKTS) BIO_set_callback(SSL_get_rbio(TLScontext->con), tls_bio_dump_cb); /* @@ -727,8 +742,8 @@ TLS_SESS_STATE *tls_server_post_accept(TLS_SESS_STATE *TLScontext) X509 *peer; char buf[CCERT_BUFSIZ]; - /* Only loglevel==4 dumps everything */ - if (TLScontext->log_level < 4) + /* Turn off packet dump if only dumping the handshake */ + if ((TLScontext->log_mask & TLS_LOG_ALLPKTS) == 0) BIO_set_callback(SSL_get_rbio(TLScontext->con), 0); /* @@ -736,7 +751,7 @@ TLS_SESS_STATE *tls_server_post_accept(TLS_SESS_STATE *TLScontext) * session was negotiated. */ TLScontext->session_reused = SSL_session_reused(TLScontext->con); - if (TLScontext->log_level >= 2 && TLScontext->session_reused) + if ((TLScontext->log_mask & TLS_LOG_CACHE) && TLScontext->session_reused) msg_info("%s: Reusing old session", TLScontext->namaddr); /* @@ -749,7 +764,7 @@ TLS_SESS_STATE *tls_server_post_accept(TLS_SESS_STATE *TLScontext) if (SSL_get_verify_result(TLScontext->con) == X509_V_OK) TLScontext->peer_status |= TLS_CERT_FLAG_TRUSTED; - if (TLScontext->log_level >= 2) { + if (TLScontext->log_mask & TLS_LOG_VERBOSE) { X509_NAME_oneline(X509_get_subject_name(peer), buf, sizeof(buf)); msg_info("subject=%s", buf); @@ -761,13 +776,16 @@ TLS_SESS_STATE *tls_server_post_accept(TLS_SESS_STATE *TLScontext) TLScontext->issuer_CN = tls_issuer_CN(peer, TLScontext); TLScontext->peer_fingerprint = tls_fingerprint(peer, TLScontext->fpt_dgst); + TLScontext->peer_pkey_fprint = + tls_pkey_fprint(peer, TLScontext->fpt_dgst); - if (TLScontext->log_level >= 1) { - msg_info("%s: %s: subject_CN=%s, issuer=%s, fingerprint=%s", + if (TLScontext->log_mask & (TLS_LOG_VERBOSE | TLS_LOG_PEERCERT)) { + msg_info("%s: subject_CN=%s, issuer=%s, fingerprint=%s" + ", pkey_fingerprint=%s", TLScontext->namaddr, - TLS_CERT_IS_TRUSTED(TLScontext) ? "Trusted" : "Untrusted", TLScontext->peer_CN, TLScontext->issuer_CN, - TLScontext->peer_fingerprint); + TLScontext->peer_fingerprint, + TLScontext->peer_pkey_fprint); } X509_free(peer); } else { @@ -797,7 +815,7 @@ TLS_SESS_STATE *tls_server_post_accept(TLS_SESS_STATE *TLScontext) /* * All the key facts in a single log entry. */ - if (TLScontext->log_level >= 1) + if (TLScontext->log_mask & TLS_LOG_SUMMARY) msg_info("%s TLS connection established from %s: %s with cipher %s " "(%d/%d bits)", !TLS_CERT_IS_PRESENT(TLScontext) ? "Anonymous" : TLS_CERT_IS_TRUSTED(TLScontext) ? "Trusted" : "Untrusted", diff --git a/postfix/src/tls/tls_stream.c b/postfix/src/tls/tls_stream.c index 73def41b9..e58a30b9a 100644 --- a/postfix/src/tls/tls_stream.c +++ b/postfix/src/tls/tls_stream.c @@ -103,7 +103,7 @@ static ssize_t tls_timed_read(int fd, void *buf, size_t len, int timeout, msg_panic("%s: no context", myname); ret = tls_bio_read(fd, buf, len, timeout, TLScontext); - if (ret > 0 && TLScontext->log_level >= 4) + if (ret > 0 && (TLScontext->log_mask & TLS_LOG_ALLPKTS)) msg_info("Read %ld chars: %.*s", (long) ret, (int) (ret > 40 ? 40 : ret), (char *) buf); return (NORMALIZED_VSTREAM_RETURN(ret)); @@ -122,7 +122,7 @@ static ssize_t tls_timed_write(int fd, void *buf, size_t len, int timeout, if (!TLScontext) msg_panic("%s: no context", myname); - if (TLScontext->log_level >= 4) + if (TLScontext->log_mask & TLS_LOG_ALLPKTS) msg_info("Write %ld chars: %.*s", (long) len, (int) (len > 40 ? 40 : len), (char *) buf); ret = tls_bio_write(fd, buf, len, timeout, TLScontext); diff --git a/postfix/src/tls/tls_verify.c b/postfix/src/tls/tls_verify.c index f2a07a8aa..d305cc692 100644 --- a/postfix/src/tls/tls_verify.c +++ b/postfix/src/tls/tls_verify.c @@ -197,7 +197,7 @@ int tls_verify_certificate_callback(int ok, X509_STORE_CTX *ctx) ok = 0; X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_CHAIN_TOO_LONG); } - if (TLScontext->log_level >= 2) { + if (TLScontext->log_mask & TLS_LOG_VERBOSE) { X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf)); msg_info("%s: certificate verification depth=%d verify=%d subject=%s", TLScontext->namaddr, depth, ok, printable(buf, '?')); @@ -206,13 +206,13 @@ int tls_verify_certificate_callback(int ok, X509_STORE_CTX *ctx) /* * If no errors, or we are not logging verification errors, we are done. */ - if (ok || (TLScontext->peer_status & TLS_CERT_FLAG_LOGGED) != 0) + if (ok || (TLScontext->log_mask & TLS_LOG_UNTRUSTED) == 0) return (1); /* * One counter-example is enough. */ - TLScontext->peer_status |= TLS_CERT_FLAG_LOGGED; + TLScontext->log_mask &= ~TLS_LOG_UNTRUSTED; #define PURPOSE ((depth>0) ? "CA": TLScontext->am_server ? "client": "server") @@ -490,9 +490,12 @@ char *tls_issuer_CN(X509 *peer, const TLS_SESS_STATE *TLScontext) return (cn ? cn : mystrdup("")); } -/* tls_fingerprint - extract fingerprint from certificate */ +typedef int (*x509_dgst_cb) (const X509 *, const EVP_MD *, unsigned char *, unsigned int *); -char *tls_fingerprint(X509 *peercert, const char *dgst) +/* tls_fprint - extract cert or pkey fingerprint from certificate */ + +static char *tls_fprint(X509 *peercert, x509_dgst_cb x509_dgst, + const char *dgst) { const char *myname = "tls_fingerprint"; const EVP_MD *md_alg; @@ -506,7 +509,7 @@ char *tls_fingerprint(X509 *peercert, const char *dgst) msg_panic("%s: digest algorithm \"%s\" not found", myname, dgst); /* Fails when serialization to ASN.1 runs out of memory */ - if (X509_digest(peercert, md_alg, md_buf, &md_len) == 0) + if (x509_dgst(peercert, md_alg, md_buf, &md_len) == 0) msg_fatal("%s: error computing certificate %s digest (out of memory?)", myname, dgst); @@ -524,4 +527,18 @@ char *tls_fingerprint(X509 *peercert, const char *dgst) return (result); } +/* tls_fingerprint - extract certificate fingerprint */ + +char *tls_fingerprint(X509 *peercert, const char *dgst) +{ + return (tls_fprint(peercert, X509_digest, dgst)); +} + +/* tls_pkey_fprint - extract public key fingerprint from certificate */ + +char *tls_pkey_fprint(X509 *peercert, const char *dgst) +{ + return (tls_fprint(peercert, X509_pubkey_digest, dgst)); +} + #endif diff --git a/postfix/src/tlsmgr/tlsmgr.c b/postfix/src/tlsmgr/tlsmgr.c index c3f214e15..efddb5c37 100644 --- a/postfix/src/tlsmgr/tlsmgr.c +++ b/postfix/src/tlsmgr/tlsmgr.c @@ -218,6 +218,7 @@ /* TLS library. */ #ifdef USE_TLS +#define TLS_INTERNAL #include /* TLS_MGR_SCACHE_ */ #include #include @@ -231,13 +232,13 @@ char *var_tls_rand_source; int var_tls_rand_bytes; int var_tls_reseed_period; int var_tls_prng_exch_period; -int var_smtpd_tls_loglevel; +char *var_smtpd_tls_loglevel; char *var_smtpd_tls_scache_db; int var_smtpd_tls_scache_timeout; -int var_smtp_tls_loglevel; +char *var_smtp_tls_loglevel; char *var_smtp_tls_scache_db; int var_smtp_tls_scache_timeout; -int var_lmtp_tls_loglevel; +char *var_lmtp_tls_loglevel; char *var_lmtp_tls_scache_db; int var_lmtp_tls_scache_timeout; char *var_tls_rand_exch_name; @@ -282,16 +283,20 @@ typedef struct { TLS_SCACHE *cache_info; /* cache handle */ int cache_active; /* cache status */ char **cache_db; /* main.cf parameter value */ - int *cache_loglevel; /* main.cf parameter value */ + const char *log_param; /* main.cf parameter name */ + char **log_level; /* main.cf parameter value */ int *cache_timeout; /* main.cf parameter value */ } TLSMGR_SCACHE; TLSMGR_SCACHE cache_table[] = { TLS_MGR_SCACHE_SMTPD, 0, 0, &var_smtpd_tls_scache_db, + VAR_SMTPD_TLS_LOGLEVEL, &var_smtpd_tls_loglevel, &var_smtpd_tls_scache_timeout, TLS_MGR_SCACHE_SMTP, 0, 0, &var_smtp_tls_scache_db, + VAR_SMTP_TLS_LOGLEVEL, &var_smtp_tls_loglevel, &var_smtp_tls_scache_timeout, TLS_MGR_SCACHE_LMTP, 0, 0, &var_lmtp_tls_scache_db, + VAR_LMTP_TLS_LOGLEVEL, &var_lmtp_tls_loglevel, &var_lmtp_tls_scache_timeout, 0, }; @@ -849,7 +854,8 @@ static void tlsmgr_pre_init(char *unused_name, char **unused_argv) ent->cache_info = tls_scache_open(data_redirect_map(redirect, *ent->cache_db), ent->cache_label, - *ent->cache_loglevel >= 2, + tls_log_mask(ent->log_param, + *ent->log_level) & TLS_LOG_CACHE, *ent->cache_timeout); } } @@ -933,6 +939,9 @@ int main(int argc, char **argv) VAR_SMTPD_TLS_SCACHE_DB, DEF_SMTPD_TLS_SCACHE_DB, &var_smtpd_tls_scache_db, 0, 0, VAR_SMTP_TLS_SCACHE_DB, DEF_SMTP_TLS_SCACHE_DB, &var_smtp_tls_scache_db, 0, 0, VAR_LMTP_TLS_SCACHE_DB, DEF_LMTP_TLS_SCACHE_DB, &var_lmtp_tls_scache_db, 0, 0, + VAR_SMTPD_TLS_LOGLEVEL, DEF_SMTPD_TLS_LOGLEVEL, &var_smtpd_tls_loglevel, 0, 0, + VAR_SMTP_TLS_LOGLEVEL, DEF_SMTP_TLS_LOGLEVEL, &var_smtp_tls_loglevel, 0, 0, + VAR_LMTP_TLS_LOGLEVEL, DEF_LMTP_TLS_LOGLEVEL, &var_lmtp_tls_loglevel, 0, 0, 0, }; static const CONFIG_TIME_TABLE time_table[] = { @@ -945,9 +954,6 @@ int main(int argc, char **argv) }; static const CONFIG_INT_TABLE int_table[] = { VAR_TLS_RAND_BYTES, DEF_TLS_RAND_BYTES, &var_tls_rand_bytes, 1, 0, - VAR_SMTPD_TLS_LOGLEVEL, DEF_SMTPD_TLS_LOGLEVEL, &var_smtpd_tls_loglevel, 0, 0, - VAR_SMTP_TLS_LOGLEVEL, DEF_SMTP_TLS_LOGLEVEL, &var_smtp_tls_loglevel, 0, 0, - VAR_LMTP_TLS_LOGLEVEL, DEF_LMTP_TLS_LOGLEVEL, &var_lmtp_tls_loglevel, 0, 0, 0, }; diff --git a/postfix/src/tlsproxy/tlsproxy.c b/postfix/src/tlsproxy/tlsproxy.c index 3c6b3c6c9..8a0fd74d7 100644 --- a/postfix/src/tlsproxy/tlsproxy.c +++ b/postfix/src/tlsproxy/tlsproxy.c @@ -102,7 +102,8 @@ /* List of ciphers or cipher types to exclude from the \fBtlsproxy\fR(8) /* server cipher list at all TLS security levels. /* .IP "\fBtlsproxy_tls_fingerprint_digest ($smtpd_tls_fingerprint_digest)\fR" -/* The message digest algorithm used to construct client-certificate +/* The message digest algorithm to construct remote SMTP +/* client-certificate /* fingerprints. /* .IP "\fBtlsproxy_tls_key_file ($smtpd_tls_key_file)\fR" /* File with the Postfix \fBtlsproxy\fR(8) server RSA private key in PEM @@ -138,10 +139,10 @@ /* These parameters are supported for compatibility with /* \fBsmtpd\fR(8) legacy parameters. /* .IP "\fBtlsproxy_use_tls ($smtpd_use_tls)\fR" -/* Opportunistic TLS: announce STARTTLS support to SMTP clients, +/* Opportunistic TLS: announce STARTTLS support to remote SMTP clients, /* but do not require that clients use TLS encryption. /* .IP "\fBtlsproxy_enforce_tls ($smtpd_enforce_tls)\fR" -/* Mandatory TLS: announce STARTTLS support to SMTP clients, and +/* Mandatory TLS: announce STARTTLS support to remote SMTP clients, and /* require that clients use TLS encryption. /* RESOURCE CONTROLS /* .ad @@ -229,7 +230,7 @@ * avoid any confusion about which parameters are used by this program. */ int var_smtpd_tls_ccert_vd; -int var_smtpd_tls_loglevel; +char *var_smtpd_tls_loglevel; int var_smtpd_tls_scache_timeout; bool var_smtpd_use_tls; bool var_smtpd_enforce_tls; @@ -258,7 +259,7 @@ char *var_smtpd_tls_fpt_dgst; char *var_smtpd_tls_level; int var_tlsp_tls_ccert_vd; -int var_tlsp_tls_loglevel; +char *var_tlsp_tls_loglevel; int var_tlsp_tls_scache_timeout; bool var_tlsp_use_tls; bool var_tlsp_enforce_tls; @@ -688,11 +689,10 @@ static void tlsp_start_tls(TLSP_STATE *state) ctx = tlsp_server_ctx, stream = (VSTREAM *) 0,/* unused */ fd = state->ciphertext_fd, - log_level = var_tlsp_tls_loglevel, timeout = 0, /* unused */ requirecert = (var_tlsp_tls_req_ccert && var_tlsp_enforce_tls), - serverid = state->service, + serverid = MAIL_SERVICE_SMTPD, /* XXX */ namaddr = state->remote_endpt, cipher_grade = cipher_grade, cipher_exclusions = STR(cipher_exclusions), @@ -963,6 +963,7 @@ static void pre_jail_init(char *unused_name, char **unused_argv) */ tlsp_server_ctx = TLS_SERVER_INIT(&props, + log_param = VAR_TLSP_TLS_LOGLEVEL, log_level = var_tlsp_tls_loglevel, verifydepth = var_tlsp_tls_ccert_vd, cache_type = TLS_MGR_SCACHE_SMTPD, @@ -1017,12 +1018,10 @@ int main(int argc, char **argv) { static const CONFIG_INT_TABLE int_table[] = { VAR_SMTPD_TLS_CCERT_VD, DEF_SMTPD_TLS_CCERT_VD, &var_smtpd_tls_ccert_vd, 0, 0, - VAR_SMTPD_TLS_LOGLEVEL, DEF_SMTPD_TLS_LOGLEVEL, &var_smtpd_tls_loglevel, 0, 0, 0, }; static const CONFIG_NINT_TABLE nint_table[] = { VAR_TLSP_TLS_CCERT_VD, DEF_TLSP_TLS_CCERT_VD, &var_tlsp_tls_ccert_vd, 0, 0, - VAR_TLSP_TLS_LOGLEVEL, DEF_TLSP_TLS_LOGLEVEL, &var_tlsp_tls_loglevel, 0, 0, 0, }; static const CONFIG_TIME_TABLE time_table[] = { @@ -1066,6 +1065,7 @@ int main(int argc, char **argv) VAR_SMTPD_TLS_1024_FILE, DEF_SMTPD_TLS_1024_FILE, &var_smtpd_tls_dh1024_param_file, 0, 0, VAR_SMTPD_TLS_EECDH, DEF_SMTPD_TLS_EECDH, &var_smtpd_tls_eecdh, 1, 0, VAR_SMTPD_TLS_FPT_DGST, DEF_SMTPD_TLS_FPT_DGST, &var_smtpd_tls_fpt_dgst, 1, 0, + VAR_SMTPD_TLS_LOGLEVEL, DEF_SMTPD_TLS_LOGLEVEL, &var_smtpd_tls_loglevel, 0, 0, VAR_SMTPD_TLS_LEVEL, DEF_SMTPD_TLS_LEVEL, &var_smtpd_tls_level, 0, 0, VAR_TLSP_TLS_CERT_FILE, DEF_TLSP_TLS_CERT_FILE, &var_tlsp_tls_cert_file, 0, 0, VAR_TLSP_TLS_KEY_FILE, DEF_TLSP_TLS_KEY_FILE, &var_tlsp_tls_key_file, 0, 0, @@ -1085,6 +1085,7 @@ int main(int argc, char **argv) VAR_TLSP_TLS_1024_FILE, DEF_TLSP_TLS_1024_FILE, &var_tlsp_tls_dh1024_param_file, 0, 0, VAR_TLSP_TLS_EECDH, DEF_TLSP_TLS_EECDH, &var_tlsp_tls_eecdh, 1, 0, VAR_TLSP_TLS_FPT_DGST, DEF_TLSP_TLS_FPT_DGST, &var_tlsp_tls_fpt_dgst, 1, 0, + VAR_TLSP_TLS_LOGLEVEL, DEF_TLSP_TLS_LOGLEVEL, &var_tlsp_tls_loglevel, 0, 0, VAR_TLSP_TLS_LEVEL, DEF_TLSP_TLS_LEVEL, &var_tlsp_tls_level, 0, 0, 0, };