Resolve conflicts from last import.
This commit is contained in:
parent
16d67a18c4
commit
8fd41761ab
@ -292,23 +292,35 @@ parameter specifies persistent storage for sender or recipient address
|
||||
verification results. If you specify an empty value, all address verification
|
||||
results are lost after "postfix reload" or "postfix stop".
|
||||
|
||||
# Example 1: Default setting for Postfix 2.7 and later.
|
||||
# Note: avoid hash files here. Use btree instead.
|
||||
/etc/postfix/main.cf:
|
||||
# Default setting for Postfix 2.7 and later.
|
||||
# Note: avoid hash files here. Use btree instead.
|
||||
address_verify_map = btree:$data_directory/verify_cache
|
||||
|
||||
# Shared persistent cache (requires Postfix 2.9 or later).
|
||||
address_verify_map = proxy:btree:$data_directory/verify_cache
|
||||
# Disable automatic cache cleanup in all Postfix instances except
|
||||
# for one instance that will be responsible for cache cleanup.
|
||||
# Example 2: Shared persistent lmdb: cache (Postfix 2.11 or later).
|
||||
# Disable automatic cache cleanup in all Postfix instances except
|
||||
# for one instance that will be responsible for cache cleanup.
|
||||
/etc/postfix/main.cf:
|
||||
address_verify_map = lmdb:$data_directory/verify_cache
|
||||
# address_verify_cache_cleanup_interval = 0
|
||||
|
||||
# Shared memory cache (requires Postfix 2.9 or later).
|
||||
# See memcache_table(5) for details.
|
||||
address_verify_map = memcache:/etc/postfix/verify-memcache.cf
|
||||
# Example 3: Shared persistent btree: cache (Postfix 2.9 or later).
|
||||
# Disable automatic cache cleanup in all Postfix instances except
|
||||
# for one instance that will be responsible for cache cleanup.
|
||||
/etc/postfix/main.cf:
|
||||
address_verify_map = proxy:btree:$data_directory/verify_cache
|
||||
# address_verify_cache_cleanup_interval = 0
|
||||
|
||||
# Default setting for Postfix 2.6 and earlier.
|
||||
# This uses non-persistent storage only.
|
||||
# Example 4: Shared memory cache (requires Postfix 2.9 or later).
|
||||
# Disable automatic cache cleanup in all Postfix instances.
|
||||
# See memcache_table(5) for details.
|
||||
/etc/postfix/main.cf:
|
||||
address_verify_map = memcache:/etc/postfix/verify-memcache.cf
|
||||
address_verify_cache_cleanup_interval = 0
|
||||
|
||||
# Example 5: Default setting for Postfix 2.6 and earlier.
|
||||
# This uses non-persistent storage only.
|
||||
/etc/postfix/main.cf:
|
||||
address_verify_map =
|
||||
|
||||
NOTE 1: The database file should be stored under a Postfix-owned directory,
|
||||
|
@ -148,18 +148,20 @@ compiler. Here are a few examples:
|
||||
|
||||
and so on. In some cases, optimization is turned off automatically.
|
||||
|
||||
44..33 -- BBuuiillddiinngg wwiitthh ooppttiioonnaall eexxtteennssiioonnss
|
||||
44..33 -- BBuuiillddiinngg wwiitthh ooppttiioonnaall ffeeaattuurreess
|
||||
|
||||
By default, Postfix builds as a mail system with relatively few bells and
|
||||
whistles. Support for third-party databases etc. must be configured when
|
||||
Postfix is compiled. The following documents describe how to build Postfix with
|
||||
support for extensions:
|
||||
support for optional features:
|
||||
|
||||
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
|PPoossttffiixx eexxtteennssiioonn |DDooccuummeenntt |AAvvaaiillaabbiilliittyy|
|
||||
|OOppttiioonnaall ffeeaattuurree |DDooccuummeenntt |AAvvaaiillaabbiilliittyy|
|
||||
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|Berkeley DB database |DB_README |Postfix 1.0 |
|
||||
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|LMDB database |LMDB_README |Postfix 2.11|
|
||||
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|LDAP database |LDAP_README |Postfix 1.0 |
|
||||
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|MySQL database |MYSQL_README |Postfix 1.0 |
|
||||
@ -192,31 +194,33 @@ IMPORTANT: Be sure to get the quotes right. These details matter a lot.
|
||||
|
||||
Parameters whose defaults can be specified in this way are:
|
||||
|
||||
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
|MMaaccrroo nnaammee |ddeeffaauulltt vvaalluuee ffoorr|ttyyppiiccaall ddeeffaauulltt |
|
||||
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|DEF_COMMAND_DIR |command_directory|/usr/sbin |
|
||||
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|DEF_CONFIG_DIR |config_directory |/etc/postfix |
|
||||
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|DEF_DAEMON_DIR |daemon_directory |/usr/libexec/postfix|
|
||||
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|DEF_DATA_DIR |data_directory |/var/db/postfix |
|
||||
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|DEF_MAILQ_PATH |mailq_path |/usr/bin/mailq |
|
||||
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|DEF_HTML_DIR |html_directory |no |
|
||||
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|DEF_MANPAGE_DIR |manpage_directory|/usr/local/man |
|
||||
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|DEF_NEWALIAS_PATH|newaliases_path |/usr/bin/newaliases |
|
||||
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|DEF_QUEUE_DIR |queue_directory |/var/spool/postfix |
|
||||
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|DEF_README_DIR |readme_directory |no |
|
||||
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|DEF_SENDMAIL_PATH|sendmail_path |/usr/sbin/sendmail |
|
||||
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
|MMaaccrroo nnaammee |ddeeffaauulltt vvaalluuee ffoorr |ttyyppiiccaall ddeeffaauulltt |
|
||||
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|DEF_COMMAND_DIR |command_directory |/usr/sbin |
|
||||
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|DEF_CONFIG_DIR |config_directory |/etc/postfix |
|
||||
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|DEF_DB_TYPE |default_database_type|hash |
|
||||
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|DEF_DAEMON_DIR |daemon_directory |/usr/libexec/postfix|
|
||||
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|DEF_DATA_DIR |data_directory |/var/db/postfix |
|
||||
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|DEF_MAILQ_PATH |mailq_path |/usr/bin/mailq |
|
||||
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|DEF_HTML_DIR |html_directory |no |
|
||||
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|DEF_MANPAGE_DIR |manpage_directory |/usr/local/man |
|
||||
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|DEF_NEWALIAS_PATH|newaliases_path |/usr/bin/newaliases |
|
||||
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|DEF_QUEUE_DIR |queue_directory |/var/spool/postfix |
|
||||
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|DEF_README_DIR |readme_directory |no |
|
||||
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|DEF_SENDMAIL_PATH|sendmail_path |/usr/sbin/sendmail |
|
||||
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|
||||
Note: the data_directory parameter (for caches and pseudo-random numbers) was
|
||||
introduced with Postfix version 2.5.
|
||||
@ -245,9 +249,11 @@ The following is an extensive list of names and values.
|
||||
| |at compile time: |
|
||||
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|| |Do not build with Berkeley DB support. By |
|
||||
||-DNO_DB |default, Berkeley DB support is compiled in on|
|
||||
|| |platforms that are known to support this |
|
||||
|| |feature. |
|
||||
|| |default, Berkeley DB support is compiled in on|
|
||||
||-DNO_DB |platforms that are known to support this |
|
||||
|| |feature. If you override this, then you |
|
||||
|| |probably should also override DEF_DB_TYPE as |
|
||||
|| |described in section 4.4. |
|
||||
|_|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|| |Do not build with Solaris /dev/poll support. |
|
||||
||-DNO_DEVPOLL |By default, /dev/poll support is compiled in |
|
||||
@ -271,8 +277,12 @@ The following is an extensive list of names and values.
|
||||
|| |known to support it. |
|
||||
|_|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|| |Do not build with NIS or NISPLUS support. NIS |
|
||||
||-DNO_NIS |is not available on some recent Linux or |
|
||||
|| |Solaris distributions. |
|
||||
||-DNO_NIS |is not available on some recent Linux |
|
||||
|| |distributions. |
|
||||
|_|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|| |Do not build with NISPLUS support. NISPLUS is |
|
||||
||-DNO_NISPLUS |not available on some recent Solaris |
|
||||
|| |distributions. |
|
||||
|_|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|| |Do not build with PCRE support. By default, |
|
||||
||-DNO_PCRE |PCRE support is compiled in when the pcre- |
|
||||
|
@ -86,14 +86,15 @@ a private key. Both must be in "PEM" format. The private key must not be
|
||||
encrypted, meaning: the key must be accessible without a password. The
|
||||
certificate and private key may be in the same file, in which case the
|
||||
certificate file should be owned by "root" and not be readable by any other
|
||||
user. If the key is stored separately, this applies to the key file only, and
|
||||
the certificate file may be "world-readable".
|
||||
user. If the key is stored separately, this access restriction applies to the
|
||||
key file only, and the certificate file may be "world-readable".
|
||||
|
||||
Public Internet MX hosts without certificates signed by a "reputable" CA must
|
||||
generate, and be prepared to present to most clients, a self-signed or private-
|
||||
CA signed certificate. The remote SMTP client will generally not be able to
|
||||
authenticate the self-signed certificate, but unless the client is running
|
||||
Postfix or similar software, it will still insist on a server certificate.
|
||||
Public Internet MX hosts without certificates signed by a well-known public CA
|
||||
must still generate, and be prepared to present to most clients, a self-signed
|
||||
or private-CA signed certificate. The remote SMTP client will generally not be
|
||||
able to verify the self-signed certificate, but unless the client is running
|
||||
Postfix or similar software, it will only negotiate TLS ciphersuites that
|
||||
require a server certificate.
|
||||
|
||||
For servers that are nnoott public Internet MX hosts, Postfix supports
|
||||
configurations with no certificates. This entails the use of just the anonymous
|
||||
@ -106,34 +107,73 @@ administrator explicitly sets "smtpd_tls_cert_file = none". This ensures that
|
||||
new Postfix SMTP server configurations will not accidentally run with no
|
||||
certificates.
|
||||
|
||||
RSA, DSA and ECDSA (Postfix >= 2.6) certificates are supported. Typically you
|
||||
will only have RSA certificates issued by a commercial CA. In addition, the
|
||||
tools supplied with OpenSSL will by default issue RSA certificates. You can
|
||||
configure all three at the same time, in which case the cipher used determines
|
||||
which certificate is presented. For Netscape and OpenSSL clients without
|
||||
special cipher choices, the RSA certificate is preferred.
|
||||
RSA, DSA and ECDSA (Postfix >= 2.6) certificates are supported. Most sites only
|
||||
have RSA certificates. You can configure all three at the same time, in which
|
||||
case the ciphersuite negotiated with the remote SMTP client determines which
|
||||
certificate is used. If your DNS zone is signed, and you want to publish RFC
|
||||
6698 TLSA records, these must match any of the configured certificates. Since
|
||||
the best practice is to publish "3 1 1" certificate associations, create a
|
||||
separate TLSA record for each public-key certificate digest.
|
||||
|
||||
To enable a remote SMTP client to verify the Postfix SMTP server certificate,
|
||||
the issuing CA certificates must be made available to the client. You should
|
||||
include the required certificates in the server certificate file, the server
|
||||
certificate first, then the issuing CA(s) (bottom-up order).
|
||||
CCrreeaattiinngg tthhee sseerrvveerr cceerrttiiffiiccaattee ffiillee
|
||||
|
||||
Example: the certificate for "server.example.com" was issued by "intermediate
|
||||
CA" which itself has a certificate issued by "root CA". Create the server.pem
|
||||
file with:
|
||||
|
||||
% ccaatt sseerrvveerr__cceerrtt..ppeemm iinntteerrmmeeddiiaattee__CCAA..ppeemm >> sseerrvveerr..ppeemm
|
||||
|
||||
A Postfix SMTP server certificate supplied here must be usable as SSL server
|
||||
To verify the Postfix SMTP server certificate, the remote SMTP client must
|
||||
receive the issuing CA certificates via the TLS handshake or via public-key
|
||||
infrastructure. This means that the Postfix server public-key certificate file
|
||||
must include the server certificate first, then the issuing CA(s) (bottom-up
|
||||
order). The Postfix SMTP server certificate must be usable as SSL server
|
||||
certificate and hence pass the "openssl verify -purpose sslserver ..." test.
|
||||
|
||||
A client 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 "server.pem" file reduces the overhead of the TLS exchange.
|
||||
The examples that follow show how to create a server certificate file. We
|
||||
assume that the certificate for "server.example.com" was issued by
|
||||
"intermediate CA" which itself has a certificate issued by "root CA".
|
||||
|
||||
* With legacy public CA trust verification, you can omit the root certificate
|
||||
from the "server.pem" certificate file. If the client trusts the root CA,
|
||||
it will already have a local copy of the root CA certificate. Omitting the
|
||||
root CA certificate reduces the size of the server TLS handshake.
|
||||
|
||||
% ccaatt sseerrvveerr__cceerrtt..ppeemm iinntteerrmmeeddiiaattee__CCAA..ppeemm >> sseerrvveerr..ppeemm
|
||||
|
||||
* If you publish RFC 6698 TLSA "2 0 1" or "2 1 1" records to specify root CA
|
||||
certificate digests, you must include the corresponding root CA
|
||||
certificates in the "server.pem" certificate file. See the documentation of
|
||||
the tls_dane_trust_anchor_digest_enable main.cf parameter.
|
||||
|
||||
% ccaatt sseerrvveerr__cceerrtt..ppeemm iinntteerrmmeeddiiaattee__CCAA..ppeemm rroooott..ppeemm >> sseerrvveerr..ppeemm
|
||||
|
||||
Remote SMTP clients will be able to use the TLSA record you publish (which
|
||||
only contains the certificate digest) only if they have access to the
|
||||
corresponding certificate. Failure to verify certificates per the server's
|
||||
published TLSA records will typically cause the SMTP client to defer mail
|
||||
delivery. The foregoing also applies to "2 0 2" and "2 1 2" TLSA records or
|
||||
any other digest of a CA certificate, but it is expected that SHA256 will
|
||||
be by far the most common digest for TLSA.
|
||||
|
||||
As a best practice, publish either "3 0 1" or "3 1 1" TLSA associations
|
||||
that specify the SHA256 digest of the server certificate public key with
|
||||
the alias-expanded hostname of each STARTTLS capable SMTP server. These
|
||||
continue to work when a certificate is renewed with the same public/private
|
||||
key pair.
|
||||
|
||||
For instructions on how to compute the digest of a certificate or its public
|
||||
key for use in TLSA records, see the documentation of the
|
||||
smtpd_tls_fingerprint_digest main.cf parameter.
|
||||
|
||||
When a new key or certificate is generated, an additional TLSA record with the
|
||||
new digest must be published in advance of the actual deployment of the new key
|
||||
or certificate on the server. You must allow sufficient time for any TLSA
|
||||
RRsets with only the old digest to expire from DNS caches. The safest practice
|
||||
is to wait until the DNSSEC signature on the previous TLSA RRset expires, and
|
||||
only then switch the server to use new keys published in the updated TLSA
|
||||
RRset. Once the new certificate trust chain and private key are in effect, the
|
||||
DNS should be updated once again to remove the old digest from the TLSA RRset.
|
||||
|
||||
If you want the Postfix SMTP server to accept remote SMTP client certificates
|
||||
issued by these CAs, append the root certificate to $smtpd_tls_CAfile or
|
||||
install it in the $smtpd_tls_CApath directory.
|
||||
issued by one or more root CAs, append the root certificate to
|
||||
$smtpd_tls_CAfile or install it in the $smtpd_tls_CApath directory.
|
||||
|
||||
CCoonnffiigguurriinngg tthhee sseerrvveerr cceerrttiiffiiccaattee aanndd kkeeyy ffiilleess
|
||||
|
||||
RSA key and certificate examples:
|
||||
|
||||
@ -207,27 +247,25 @@ To get additional information about Postfix SMTP server TLS activity you can
|
||||
increase the log level from 0..4. Each logging level also includes the
|
||||
information that is logged at a lower logging level.
|
||||
|
||||
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
|LLeevveell|PPoossttffiixx 22..99 aanndd llaatteerr |EEaarrlliieerr rreelleeaasseess.. |
|
||||
|_ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|0 |Log only a summary message on TLS |Disable logging of TLS activity.|
|
||||
| |handshake completion -- no logging| |
|
||||
| |of client certificate trust-chain | |
|
||||
| |verification errors if client | |
|
||||
| |certificate verification is not | |
|
||||
| |required. | |
|
||||
|_ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|1 |Also log trust-chain verification |Also log TLS handshake and |
|
||||
| |errors and peer certificate |certificate information. |
|
||||
| |summary 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. |
|
||||
|_ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
|LLeevveell|PPoossttffiixx 22..99 aanndd llaatteerr |EEaarrlliieerr rreelleeaasseess.. |
|
||||
|_ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|0 |Disable logging of TLS activity. |
|
||||
|_ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|1 |Log only a summary message on TLS |Log the summary message, peer |
|
||||
| |handshake completion -- no logging|certificate summary information|
|
||||
| |of client certificate trust-chain |and unconditionally log trust- |
|
||||
| |verification errors if client |chain verification errors. |
|
||||
| |certificate verification is not | |
|
||||
| |required. | |
|
||||
|_ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|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. |
|
||||
|_ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|
||||
Use log level 3 only in case of problems. Use of log level 4 is strongly
|
||||
discouraged.
|
||||
@ -364,16 +402,40 @@ Example:
|
||||
SSeerrvveerr--ssiiddee TTLLSS sseessssiioonn ccaacchhee
|
||||
|
||||
The Postfix SMTP server and the remote SMTP client negotiate a session, which
|
||||
takes some computer time and network bandwidth. By default, this session
|
||||
information is cached only in the smtpd(8) process actually using this session
|
||||
and is lost when the process terminates. To share the session information
|
||||
between multiple smtpd(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.
|
||||
takes some computer time and network bandwidth. SSL protocol versions other
|
||||
than SSLv2 support resumption of cached sessions. Not only is this more CPU and
|
||||
bandwidth efficient, it also reduces latency as only one network round-trip is
|
||||
used to resume a session while it takes two round-trips to create a session
|
||||
from scratch.
|
||||
|
||||
Since Postfix uses multiple smtpd(8) service processes, an in-memory cache is
|
||||
not sufficient for session re-use. Clients store at most one cached session per
|
||||
server and are very unlikely to repeatedly connect to the same server process.
|
||||
Thus session caching in the Postfix SMTP server generally requires a shared
|
||||
cache (an alternative available with Postfix >= 2.11 is described below).
|
||||
|
||||
To share the session information between multiple smtpd(8) processes, a session
|
||||
cache database is 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.
|
||||
|
||||
Starting with Postfix 2.11, linked with a compatible OpenSSL library (at least
|
||||
0.9.8h, preferably 1.0.0 or later) the Postfix SMTP server supports RFC 5077
|
||||
TLS session resumption without server-side state when the remote SMTP client
|
||||
also supports RFC 5077. The session is encrypted by the server in a session
|
||||
ticket returned to client for storage. When a client sends a valid session
|
||||
ticket, the server decrypts it and resumes the session, provided neither the
|
||||
ticket nor the session have expired. This makes it possible to resume cached
|
||||
sessions without allocating space for a shared database on the server. This
|
||||
feature can be disabled by setting the session cache timeout to zero, otherwise
|
||||
the timeout must be at least 2 minutes and at most 100 days.
|
||||
|
||||
Note, session tickets can only be negotiated if the client disables SSLv2 and
|
||||
does not use the legacy SSLv2 compatible HELLO message. This is true by default
|
||||
with the Postfix >= 2.6 SMTP client.
|
||||
|
||||
Example:
|
||||
|
||||
@ -395,11 +457,15 @@ Example:
|
||||
/etc/postfix/main.cf:
|
||||
smtpd_tls_session_cache_timeout = 3600s
|
||||
|
||||
As of Postfix 2.11 this setting cannot exceed 100 days. If set <= 0, session
|
||||
caching is disabled. If set to a positive value less than 2 minutes, the
|
||||
minimum value of 2 minutes is used instead.
|
||||
|
||||
When the Postfix SMTP server does not save TLS sessions to an external cache
|
||||
database, client-side session caching is unlikely to be useful. To prevent such
|
||||
wastage, the Postfix SMTP server can be configured to not issue TLS session
|
||||
ids. By default the Postfix SMTP server always issues TLS session ids. This
|
||||
works around known interoperability issues with some MUAs, and prevents
|
||||
database, client-side session caching is unlikely to be useful. To reduce waste
|
||||
of client resources, the Postfix SMTP server can be configured to not issue TLS
|
||||
session ids. By default the Postfix SMTP server always issues TLS session ids.
|
||||
This works around known interoperability issues with some MUAs, and prevents
|
||||
possible interoperability issues with other MTAs.
|
||||
|
||||
Example:
|
||||
@ -540,7 +606,8 @@ configurations with no server certificates that use oonnllyy the anonymous c
|
||||
This is enabled by explicitly setting "smtpd_tls_cert_file = none" and not
|
||||
specifying an smtpd_tls_dcert_file or smtpd_tls_eccert_file.
|
||||
|
||||
Example, MSA that requires TLSv1, not SSLv2 or SSLv3, with high grade ciphers:
|
||||
Example, MSA that requires TLSv1 or higher, not SSLv2 or SSLv3, with high grade
|
||||
ciphers:
|
||||
|
||||
/etc/postfix/main.cf:
|
||||
smtpd_tls_cert_file = /etc/postfix/cert.pem
|
||||
@ -548,55 +615,37 @@ Example, MSA that requires TLSv1, not SSLv2 or SSLv3, with high grade ciphers:
|
||||
smtpd_tls_mandatory_ciphers = high
|
||||
smtpd_tls_mandatory_exclude_ciphers = aNULL, MD5
|
||||
smtpd_tls_security_level = encrypt
|
||||
# Preferred form with Postfix >= 2.5:
|
||||
# Preferred syntax with Postfix >= 2.5:
|
||||
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3
|
||||
# Alternative form.
|
||||
# Legacy syntax:
|
||||
smtpd_tls_mandatory_protocols = TLSv1
|
||||
|
||||
If you want to take advantage of ciphers with ephemeral Diffie-Hellman (EDH)
|
||||
key exchange (this offers "forward-secrecy"), DH parameters are needed. Instead
|
||||
of using the built-in DH parameters for both 1024-bit (non-export ciphers) and
|
||||
512-bit (export ciphers), it is better to generate your own parameters, since
|
||||
otherwise it would "pay" for a possible attacker to start a brute force attack
|
||||
against parameters that are used by everybody. Postfix defaults to compiled-in
|
||||
parameters that are shared by all Postfix users who don't generate their own
|
||||
settings.
|
||||
|
||||
To generate your own set of DH parameters, use:
|
||||
|
||||
% ooppeennssssll ggeennddhh --oouutt //eettcc//ppoossttffiixx//ddhh__551122..ppeemm --22 551122
|
||||
% ooppeennssssll ggeennddhh --oouutt //eettcc//ppoossttffiixx//ddhh__11002244..ppeemm --22 11002244
|
||||
|
||||
Support for elliptic curve cryptography is available with Postfix 2.6 and
|
||||
OpenSSL 1.0.0 or later. To enable ephemeral elliptic curve Diffie-Hellman
|
||||
(EECDH) key-exchange, set "smtpd_tls_eecdh_grade = strong" or
|
||||
"smtpd_tls_eecdh_grade = ultra". The "ultra" setting is substantially more CPU
|
||||
intensive, and "strong" is sufficiently secure for most situations.
|
||||
|
||||
Examples:
|
||||
|
||||
/etc/postfix/main.cf:
|
||||
smtpd_tls_dh1024_param_file = /etc/postfix/dh_1024.pem
|
||||
smtpd_tls_dh512_param_file = /etc/postfix/dh_512.pem
|
||||
# Postfix >= 2.6:
|
||||
smtpd_tls_eecdh_grade = strong
|
||||
If you want to take maximal advantage of ciphers that offer forward secrecy see
|
||||
the Getting started section of FORWARD_SECRECY_README. The full document
|
||||
conveniently presents all information about Postfix "perfect" forward secrecy
|
||||
support in one place: what forward secrecy is, how to tweak settings, and what
|
||||
you can expect to see when Postfix uses ciphers with forward secrecy.
|
||||
|
||||
Postfix 2.8 and later, in combination with OpenSSL 0.9.7 and later allows TLS
|
||||
servers to preempt the TLS client's cipher preference list. This is possible
|
||||
only with SSLv3 and later, as in SSLv2 the client chooses the cipher from a
|
||||
list supplied by the server.
|
||||
servers to preempt the TLS client's cipher-suite preference list. This is
|
||||
possible only with SSLv3 and later, as in SSLv2 the client chooses the cipher-
|
||||
suite from a list supplied by the server.
|
||||
|
||||
By default, the OpenSSL server selects the client's most preferred cipher that
|
||||
the server supports. With SSLv3 and later, the server may choose its own most
|
||||
preferred cipher that is supported (offered) by the client. Setting
|
||||
"tls_preempt_cipherlist = yes" enables server cipher preferences. The default
|
||||
OpenSSL behavior applies with "tls_preempt_cipherlist = no".
|
||||
By default, the OpenSSL server selects the client's most preferred cipher-suite
|
||||
that the server supports. With SSLv3 and later, the server may choose its own
|
||||
most preferred cipher-suite that is supported (offered) by the client. Setting
|
||||
"tls_preempt_cipherlist = yes" enables server cipher-suite preferences. The
|
||||
default OpenSSL behavior applies with "tls_preempt_cipherlist = no".
|
||||
|
||||
While server cipher selection may in some cases lead to a more secure or
|
||||
performant cipher choice, there is some risk of interoperability issues. In the
|
||||
past, some SSL clients have listed lower priority ciphers that they did not
|
||||
implement correctly. If the server chooses a cipher that the client prefers
|
||||
less, it may select a cipher whose client implementation is flawed.
|
||||
While server cipher-suite selection may in some cases lead to a more secure or
|
||||
performant cipher-suite choice, there is some risk of interoperability issues.
|
||||
In the past, some SSL clients have listed lower priority ciphers that they did
|
||||
not implement correctly. If the server chooses a cipher that the client prefers
|
||||
less, it may select a cipher whose client implementation is flawed. Most
|
||||
notably Windows 2003 Microsoft Exchange servers have flawed implementations of
|
||||
DES-CBC3-SHA, which OpenSSL considers stronger than RC4-SHA. Enabling server
|
||||
cipher-suite selection may create interoperability issues with Windows 2003
|
||||
Microsoft Exchange clients.
|
||||
|
||||
MMiisscceellllaanneeoouuss sseerrvveerr ccoonnttrroollss
|
||||
|
||||
@ -619,11 +668,35 @@ Example:
|
||||
|
||||
/etc/postfix/main.cf:
|
||||
tls_disable_workarounds = 0xFFFFFFFF
|
||||
tls_disable_workarounds = CVE-2010-4180, LEGACY_SERVER_CONNECT
|
||||
tls_disable_workarounds = CVE-2010-4180
|
||||
|
||||
Note: Disabling LEGACY_SERVER_CONNECT is not wise at this time, lots of servers
|
||||
are still unpatched and Postfix is not significantly vulnerable to the
|
||||
renegotiation issue in the TLS protocol.
|
||||
With Postfix >= 2.11, the tls_ssl_options parameter specifies a list or bit-
|
||||
mask of OpenSSL options to enable. Specify one or more of the named options
|
||||
below, or a hexadecimal bitmask of options found in the ssl.h file
|
||||
corresponding to the run-time OpenSSL library. While it may be reasonable to
|
||||
turn off all bug workarounds (see above), it is not a good idea to attempt to
|
||||
turn on all features.
|
||||
|
||||
LLEEGGAACCYY__SSEERRVVEERR__CCOONNNNEECCTT
|
||||
See SSL_CTX_set_options(3).
|
||||
NNOO__TTIICCKKEETT
|
||||
See SSL_CTX_set_options(3).
|
||||
NNOO__CCOOMMPPRREESSSSIIOONN
|
||||
Disable SSL compression even if supported by the OpenSSL library.
|
||||
Compression is CPU-intensive, and compression before encryption does not
|
||||
always improve security.
|
||||
Example:
|
||||
|
||||
/etc/postfix/main.cf:
|
||||
tls_ssl_options = no_ticket, no_compression
|
||||
|
||||
You should only enable features via the hexadecimal mask when the need to
|
||||
control the feature is critical (to deal with a new vulnerability or a serious
|
||||
interoperability problem). Postfix DOES NOT promise backwards compatible
|
||||
behavior with respect to the mask bits. A feature enabled via the mask in one
|
||||
release may be enabled by other means in a later release, and the mask bit will
|
||||
then be ignored. Therefore, use of the hexadecimal mask is only a temporary
|
||||
measure until a new Postfix or OpenSSL release provides a better solution.
|
||||
|
||||
SSMMTTPP CClliieenntt ssppeecciiffiicc sseettttiinnggss
|
||||
|
||||
@ -653,6 +726,10 @@ mmaayy
|
||||
Opportunistic TLS.
|
||||
eennccrryypptt
|
||||
Mandatory TLS encryption.
|
||||
ddaannee
|
||||
Opportunistic DANE TLS.
|
||||
ddaannee--oonnllyy
|
||||
Mandatory DANE TLS.
|
||||
ffiinnggeerrpprriinntt
|
||||
Certificate fingerprint verification.
|
||||
vveerriiffyy
|
||||
@ -805,15 +882,191 @@ not specified consistently.
|
||||
[example.net]:msa encrypt protocols=TLSv1 ciphers=high
|
||||
[example.net]:submission encrypt protocols=TLSv1 ciphers=high
|
||||
|
||||
DDAANNEE TTLLSS aauutthheennttiiccaattiioonn..
|
||||
|
||||
The Postfix SMTP client supports two TLS security levels based on RFC6698 DANE
|
||||
TLSA records. The opportunistic "dane" level and the mandatory "dane-only"
|
||||
level.
|
||||
|
||||
The "dane" level is a stronger form of opportunistic TLS that is resistant to
|
||||
man in the middle and downgrade attacks when the destination domain uses DNSSEC
|
||||
to publish DANE TLSA records for its MX hosts. If a remote SMTP server has
|
||||
"usable" (see RFC 6698) DANE TLSA records, the server connection will be
|
||||
authenticated. When DANE authentication fails, there is no fallback to
|
||||
unauthenticated or plaintext delivery.
|
||||
|
||||
If TLSA records are published for a given remote SMTP server (implying TLS
|
||||
support), but are all "unusable" due to unsupported parameters or malformed
|
||||
data, the Postfix SMTP client will use mandatory unauthenticated TLS.
|
||||
Otherwise, when no TLSA records are published, the Postfix SMTP client behavior
|
||||
is the same as with may.
|
||||
|
||||
TLSA records must be published in DNSSEC validated DNS zones. Any TLSA records
|
||||
in DNS zones not protected via DNSSEC are ignored. The Postfix SMTP client will
|
||||
not look for TLSA records associated with MX hosts whose "A" or "AAAA" records
|
||||
lie in an "insecure" DNS zone. Such lookups have been observed to cause
|
||||
interoperability issues with poorly implemented DNS servers, and are in any
|
||||
case not expected to ever yield "secure" results, since that would require a
|
||||
very unlikely DLV DNS trust anchor configured between the host record and the
|
||||
associated "_25._tcp" child TLSA record.
|
||||
|
||||
The "dane-only" level is a form of secure-channel TLS based on the DANE PKI. If
|
||||
"usable" TLSA records are present these are used to authenticate the remote
|
||||
SMTP server. Otherwise, or when server certificate verification fails, delivery
|
||||
via the server in question tempfails.
|
||||
|
||||
At both security levels, the TLS policy for the destination is obtained via
|
||||
TLSA records validated with DNSSEC. For TLSA policy to be in effect, the
|
||||
destination domain's containing DNS zone must be signed and the Postfix SMTP
|
||||
client's operating system must be configured to send its DNS queries to a
|
||||
recursive DNS nameserver that is able to validate the signed records. Each MX
|
||||
host's DNS zone needs to also be signed, and needs to publish DANE TLSA (RFC
|
||||
6698) records that specify how that MX host's TLS certificate is to be
|
||||
verified.
|
||||
|
||||
TLSA records do not preempt the normal SMTP MX host selection algorithm, if
|
||||
some MX hosts support TLSA and others do not, TLS security will vary from
|
||||
delivery to delivery. It is up to the domain owner to configure their MX hosts
|
||||
and their DNS sensibly. To configure the Postfix SMTP client for DNSSEC lookups
|
||||
see the documentation for the smtp_dns_support_level main.cf parameter. The
|
||||
tls_dane_trust_anchor_digest_enable main.cf parameter controls support for
|
||||
trust-anchor digest TLSA records. The tls_dane_digests and
|
||||
tls_dane_digest_agility parameters control the list of supported digests and
|
||||
digest downgrade attack resistance.
|
||||
|
||||
DANE for SMTP MTAs deviates in some details from the baseline DANE protocol in
|
||||
RFC 6698. Most notably, it is not expected that SMTP MTAs can reasonably
|
||||
include every public CA that a remote SMTP server's administrator may believe
|
||||
to be well-known. Nor is there an interactive user to "click OK" when
|
||||
authentication fails.
|
||||
|
||||
Therefore, certificate usages "0" and "1" from RFC 6698 which are intended to
|
||||
"constrain" existing PKI trust, are not supported. TLSA records with usage "0"
|
||||
are treated as "unusable". TLSA records with usage "1" are instead treated as
|
||||
"trust assertions" and mapped to usage "3". Specifically, with certificate
|
||||
usage "1", Postfix will not require the remote SMTP server's certificate to be
|
||||
trusted with respect to any locally defined public CAs, it is the domain
|
||||
owner's responsibility to ensure that the certificate associations in their
|
||||
TLSA records are appropriate to authenticate their SMTP servers.
|
||||
|
||||
The Postfix SMTP client supports only certificate usages "2" and "3" (with "1"
|
||||
treated as though it were "3"). See tls_dane_trust_anchor_digest_enable for
|
||||
usage "2" usability considerations. Support for certificate usage "1" is an
|
||||
experiment, it may be withdrawn in the future. Server operators SHOULD NOT
|
||||
publish TLSA records with usage "1".
|
||||
|
||||
When usable TLSA records are obtained for the remote SMTP server the Postfix
|
||||
SMTP client sends the SNI TLS extension in its SSL client hello message. This
|
||||
may help the remote SMTP server live up to its promise to provide a certificate
|
||||
that matches its TLSA records.
|
||||
|
||||
For purposes of protocol and cipher selection, the "dane" security level is
|
||||
treated like a "mandatory" TLS security level, and weak ciphers and protocols
|
||||
are disabled. Since DANE authenticates server certificates the "aNULL" cipher-
|
||||
suites are transparently excluded at this level, no need to configure this
|
||||
manually. RFC 6698 (DANE) TLS authentication is available with Postfix 2.11 and
|
||||
later.
|
||||
|
||||
When a DANE TLSA record specifies a trust-anchor (TA) certificate (that is an
|
||||
issuing CA), the strategy used to verify the peername of the server certificate
|
||||
is unconditionally "nexthop, hostname". Both the nexthop domain and the
|
||||
hostname obtained from the DNSSEC-validated MX lookup are safe from forgery and
|
||||
the server certificate must contain at least one of these names.
|
||||
|
||||
When a DANE TLSA record specifies an end-entity (EE) certificate, (that is the
|
||||
actual server certificate), as with the fingerprint security level below, no
|
||||
name checks or certificate expiration checks are applied. The server
|
||||
certificate (or its public key) either matches the DANE record or not. Server
|
||||
administrators should publish such EE records in preference to all other types.
|
||||
|
||||
The pre-requisites for DANE support in the Postfix SMTP client are:
|
||||
|
||||
* A compile-time OpenSSL library that supports the TLS SNI extension and
|
||||
"SHA-2" message digests.
|
||||
* A compile-time DNS resolver library that supports DNSSEC. Postfix binaries
|
||||
built on an older system will not support DNSSEC even if deployed on a
|
||||
system with an updated resolver library.
|
||||
* The "smtp_dns_support_level" must be set to "dnssec".
|
||||
* The "smtp_host_lookup" parameter must include "dns".
|
||||
* A DNSSEC-validating recursive resolver (see note below).
|
||||
|
||||
The above client pre-requisites do not apply to the Postfix SMTP server. It
|
||||
will support DANE provided it supports TLSv1 and its TLSA records are published
|
||||
in a DNSSEC signed zone. To receive DANE secured mail for multiple domains, use
|
||||
the same hostname to add the server to each domain's MX records. There are no
|
||||
plans to implement SNI in the Postfix SMTP server.
|
||||
|
||||
Note: The Postfix SMTP client's internal stub DNS resolver is DNSSEC-aware, but
|
||||
it does not itself validate DNSSEC records, rather it delegates DNSSEC
|
||||
validation to the operating system's configured recursive DNS nameserver. The
|
||||
Postfix DNS client relies on a secure channel to the resolver's cache for
|
||||
DNSSEC integrity, but does not support TSIG to protect the transmission channel
|
||||
between itself and the nameserver. Therefore, it is strongly recommended (DANE
|
||||
security guarantee void otherwise) that each MTA run a local DNSSEC-validating
|
||||
recursive resolver ("unbound" from nlnetlabs.nl is a reasonable choice)
|
||||
listening on the loopback interface, and that the system be configured to use
|
||||
only this local nameserver. The local nameserver may forward queries to an
|
||||
upstream recursive resolver on another host if desired.
|
||||
|
||||
Note: When the operating system's recursive nameserver is not local, enabling
|
||||
EDNS0 expanded DNS packet sizes and turning on the DNSSEC "DO" bit in the DNS
|
||||
request and/or the new DNSSEC-specific records returned in the nameserver's
|
||||
replies may cause problems with older or buggy firewall and DNS server
|
||||
implementations. Therefore, Postfix does not enable DNSSEC by default. Since MX
|
||||
lookups happen before the security level is determined, DANE support is
|
||||
disabled for all destinations unless you set "smtp_dns_support_level = dnssec".
|
||||
To enable DNSSEC lookups selectively, define a new dedicated transport with a
|
||||
"-o smtp_dns_support_level=dnssec" override in master.cf and route selected
|
||||
domains to that transport. If DNSSEC proves to be sufficiently reliable for
|
||||
these domains, you can enable it for all destinations by changing the global
|
||||
smtp_dns_support_level in main.cf.
|
||||
|
||||
EExxaammppllee: "dane" security for selected destinations, with opportunistic TLS by
|
||||
default. This is the recommended configuration for early adopters.
|
||||
|
||||
* The "example.com" destination uses DANE, but if TLSA records are not
|
||||
present or are unusable, mail is deferred.
|
||||
|
||||
* The "example.org" destination uses DANE if possible, but if no TLSA records
|
||||
are found opportunistic TLS is used.
|
||||
|
||||
main.cf:
|
||||
indexed = ${default_database_type}:${config_directory}/
|
||||
#
|
||||
# default: Opportunistic TLS with no DNSSEC lookups.
|
||||
#
|
||||
smtp_tls_security_level = may
|
||||
smtp_dns_support_level = enabled
|
||||
#
|
||||
# Per-destination TLS policy
|
||||
#
|
||||
smtp_tls_policy_maps = ${indexed}tls_policy
|
||||
#
|
||||
# default_transport = smtp, but some destinations are special:
|
||||
#
|
||||
transport_maps = ${indexed}transport
|
||||
|
||||
transport:
|
||||
example.com dane
|
||||
example.org dane
|
||||
|
||||
tls_policy:
|
||||
example.com dane-only
|
||||
|
||||
master.cf:
|
||||
dane unix - - n - - smtp
|
||||
-o smtp_dns_support_level=dnssec
|
||||
-o smtp_tls_security_level=dane
|
||||
|
||||
CCeerrttiiffiiccaattee ffiinnggeerrpprriinntt vveerriiffiiccaattiioonn
|
||||
|
||||
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).
|
||||
At the fingerprint security level, no trusted certificate authorities are used
|
||||
or required. The certificate trust chain, expiration date, etc., 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. Certificate fingerprint verification is
|
||||
available with Postfix 2.5 and later, public-key fingerprint support is
|
||||
available with 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
|
||||
@ -858,7 +1111,7 @@ the example above, we show two matching fingerprints:
|
||||
smtp_tls_fingerprint_digest = md5
|
||||
|
||||
/etc/postfix/tls_policy:
|
||||
example.com fingerprint
|
||||
example.com fingerprint
|
||||
match=3D:95:34:51:24:66:33:B9:D2:40:99:C0:C1:17:0B:D1
|
||||
match=EC:3B:2D:B0:5B:B1:FB:6D:20:A3:9D:72:F6:8D:12:35
|
||||
|
||||
@ -892,7 +1145,7 @@ use public-key fingerprints, upgrade to Postfix 2.9.6 or later.
|
||||
|
||||
MMaannddaattoorryy sseerrvveerr cceerrttiiffiiccaattee vveerriiffiiccaattiioonn
|
||||
|
||||
At the "verify" TLS security level, messages are sent only over TLS encrypted
|
||||
At the verify TLS security level, messages are sent only over TLS encrypted
|
||||
sessions if the remote SMTP server certificate is valid (not expired or
|
||||
revoked, and signed by a trusted certificate authority) and where the server
|
||||
certificate name matches a known pattern. Mandatory server certificate
|
||||
@ -908,6 +1161,17 @@ extension are used to verify the remote SMTP server name. If no DNS names are
|
||||
specified, the certificate CommonName is checked. If you want mandatory
|
||||
encryption without server certificate verification, see above.
|
||||
|
||||
With Postfix >= 2.11 the "smtp_tls_trust_anchor_file" parameter or more
|
||||
typically the corresponding per-destination "tafile" attribute optionally
|
||||
modifies trust chain verification. If the parameter is not empty the root CAs
|
||||
in CAfile and CApath are no longer trusted. Rather, the Postfix SMTP client
|
||||
will only trust certificate-chains signed by one of the trust-anchors contained
|
||||
in the chosen files. The specified trust-anchor certificates and public keys
|
||||
are not subject to expiration, and need not be (self-signed) root CAs. They
|
||||
may, if desired, be intermediate certificates. Therefore, these certificates
|
||||
also may be found "in the middle" of the trust chain presented by the remote
|
||||
SMTP server, and any untrusted issuing parent certificates will be ignored.
|
||||
|
||||
Despite the potential for eliminating "man-in-the-middle" and other attacks,
|
||||
mandatory certificate trust chain and subject name verification is not viable
|
||||
as a default Internet mail delivery policy. Most MX hosts do not support TLS at
|
||||
@ -958,6 +1222,17 @@ extension are used to verify the remote SMTP server name. If no DNS names are
|
||||
specified, the CommonName is checked. If you want mandatory encryption without
|
||||
server certificate verification, see above.
|
||||
|
||||
With Postfix >= 2.11 the "smtp_tls_trust_anchor_file" parameter or more
|
||||
typically the corresponding per-destination "tafile" attribute optionally
|
||||
modifies trust chain verification. If the parameter is not empty the root CAs
|
||||
in CAfile and CApath are no longer trusted. Rather, the Postfix SMTP client
|
||||
will only trust certificate-chains signed by one of the trust-anchors contained
|
||||
in the chosen files. The specified trust-anchor certificates and public keys
|
||||
are not subject to expiration, and need not be (self-signed) root CAs. They
|
||||
may, if desired, be intermediate certificates. Therefore, these certificates
|
||||
also may be found "in the middle" of the trust chain presented by the remote
|
||||
SMTP server, and any untrusted issuing parent certificates will be ignored.
|
||||
|
||||
Despite the potential for eliminating "man-in-the-middle" and other attacks,
|
||||
mandatory secure server certificate verification is not viable as a default
|
||||
Internet mail delivery policy. Most MX hosts do not support TLS at all, and a
|
||||
@ -1044,27 +1319,25 @@ 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.
|
||||
|
||||
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
|LLeevveell|PPoossttffiixx 22..99 aanndd llaatteerr |EEaarrlliieerr rreelleeaasseess.. |
|
||||
|_ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|0 |Log only a summary message on TLS |Disable logging of TLS activity.|
|
||||
| |handshake completion -- no logging| |
|
||||
| |of remote SMTP server certificate | |
|
||||
| |trust-chain verification errors if| |
|
||||
| |server certificate verification is| |
|
||||
| |not required. | |
|
||||
|_ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|1 |Also log remote SMTP server trust-|Also log TLS handshake and |
|
||||
| |chain verification errors and peer|certificate information. |
|
||||
| |certificate summary 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. |
|
||||
|_ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
|LLeevveell|PPoossttffiixx 22..99 aanndd llaatteerr |EEaarrlliieerr rreelleeaasseess.. |
|
||||
|_ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|0 |Disable logging of TLS activity. |
|
||||
|_ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|1 |Log only a summary message on TLS |Log the summary message and |
|
||||
| |handshake completion -- no logging|unconditionally log trust-chain|
|
||||
| |of remote SMTP server certificate |verification errors. |
|
||||
| |trust-chain verification errors if| |
|
||||
| |server certificate verification is| |
|
||||
| |not required. | |
|
||||
|_ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|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:
|
||||
|
||||
@ -1210,6 +1483,10 @@ Example:
|
||||
/etc/postfix/main.cf:
|
||||
smtp_tls_session_cache_timeout = 3600s
|
||||
|
||||
As of Postfix 2.11 this setting cannot exceed 100 days. If set <= 0, session
|
||||
caching is disabled. If set to a positive value less than 2 minutes, the
|
||||
minimum value of 2 minutes is used instead.
|
||||
|
||||
CClliieenntt TTLLSS lliimmiittaattiioonnss
|
||||
|
||||
The security properties of TLS communication channels are application specific.
|
||||
@ -1258,9 +1535,15 @@ 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.
|
||||
- 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.
|
||||
|
||||
Adoption of DNSSEC and RFC6698 (DANE) may gradually (as domains implement
|
||||
DNSSEC and publish TLSA records for their MX hosts) address the DNS man-in-the-
|
||||
middle risk and provide scalable key management for SMTP with TLS. Postfix >=
|
||||
2.11 supports the new dane and dane-only security levels that take advantage of
|
||||
these standards.
|
||||
|
||||
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
|
||||
@ -1341,6 +1624,23 @@ eennccrryypptt
|
||||
overrides the main.cf smtp_tls_mandatory_ciphers parameter, and the
|
||||
optional "exclude" attribute (Postfix >= 2.6) overrides the main.cf
|
||||
smtp_tls_mandatory_exclude_ciphers parameter.
|
||||
ddaannee
|
||||
Opportunistic DANE TLS. The TLS policy for the destination is obtained via
|
||||
TLSA records in DNSSEC. If no TLSA records are found, the effective
|
||||
security level used is may. If TLSA records are found, but none are usable,
|
||||
the effective security level is encrypt. When usable TLSA records are
|
||||
obtained for the remote SMTP server, SSLv2 is automatically disabled (see
|
||||
smtp_tls_mandatory_protocols), and the server certificate must match the
|
||||
TLSA records. RFC 6698 (DANE) TLS authentication and DNSSEC support is
|
||||
available with Postfix 2.11 and later.
|
||||
ddaannee--oonnllyy
|
||||
Mandatory DANE TLS. The TLS policy for the destination is obtained via TLSA
|
||||
records in DNSSEC. If no TLSA records are found, or none are usable, no
|
||||
connection is made to the server. When usable TLSA records are obtained for
|
||||
the remote SMTP server, SSLv2 is automatically disabled (see
|
||||
smtp_tls_mandatory_protocols), and the server certificate must match the
|
||||
TLSA records. RFC 6698 (DANE) TLS authentication and DNSSEC support is
|
||||
available with Postfix 2.11 and later.
|
||||
ffiinnggeerrpprriinntt
|
||||
Certificate fingerprint verification. Available with Postfix 2.5 and later.
|
||||
At this security level, there are no trusted certificate authorities. The
|
||||
@ -1360,14 +1660,21 @@ vveerriiffyy
|
||||
validated (not expired or revoked, and signed by a trusted certificate
|
||||
authority), and if the server certificate name matches the optional "match"
|
||||
attribute (or the main.cf smtp_tls_verify_cert_match parameter value when
|
||||
no optional "match" attribute is specified).
|
||||
no optional "match" attribute is specified). With Postfix >= 2.11 the
|
||||
"tafile" attribute optionally modifies trust chain verification in the same
|
||||
manner as the "smtp_tls_trust_anchor_file" parameter. The "tafile"
|
||||
attribute may be specified multiple times to load multiple trust-anchor
|
||||
files.
|
||||
sseeccuurree
|
||||
Secure certificate verification. Mail is delivered only if the TLS
|
||||
handshake succeeds, if the remote SMTP server certificate can be validated
|
||||
(not expired or revoked, and signed by a trusted certificate authority),
|
||||
and if the server certificate name matches the optional "match" attribute
|
||||
(or the main.cf smtp_tls_secure_cert_match parameter value when no optional
|
||||
"match" attribute is specified).
|
||||
"match" attribute is specified). With Postfix >= 2.11 the "tafile"
|
||||
attribute optionally modifies trust chain verification in the same manner
|
||||
as the "smtp_tls_trust_anchor_file" parameter. The "tafile" attribute may
|
||||
be specified multiple times to load multiple trust-anchor files.
|
||||
Notes:
|
||||
|
||||
* The "match" attribute is especially useful to verify TLS certificates for
|
||||
@ -1404,16 +1711,15 @@ Example:
|
||||
/etc/postfix/tls_policy:
|
||||
example.edu none
|
||||
example.mil may
|
||||
example.gov encrypt protocols=SSLv3:TLSv1 ciphers=high
|
||||
example.com verify
|
||||
match=hostname:dot-nexthop protocols=SSLv3:TLSv1 ciphers=high
|
||||
example.gov encrypt ciphers=high
|
||||
example.com verify match=hostname:dot-nexthop ciphers=high
|
||||
example.net secure
|
||||
.example.net secure match=.example.net:example.net
|
||||
[mail.example.org]:587 secure match=nexthop
|
||||
# Postfix 2.5 and later
|
||||
[thumb.example.org] fingerprint
|
||||
match=EC:3B:2D:B0:5B:B1:FB:6D:20:A3:9D:72:F6:8D:12:35
|
||||
match=3D:95:34:51:24:66:33:B9:D2:40:99:C0:C1:17:0B:D1
|
||||
match=EC:3B:2D:B0:5B:B1:FB:6D:20:A3:9D:72:F6:8D:12:35
|
||||
match=3D:95:34:51:24:66:33:B9:D2:40:99:C0:C1:17:0B:D1
|
||||
# Postfix 2.6 and later
|
||||
example.info may protocols=!SSLv2 ciphers=medium
|
||||
exclude=3DES
|
||||
@ -1497,7 +1803,7 @@ Example:
|
||||
smtp_tls_exclude_ciphers = aNULL
|
||||
# Preferred form with Postfix >= 2.5:
|
||||
smtp_tls_mandatory_protocols = !SSLv2
|
||||
# Alternative form.
|
||||
# Legacy form for Postfix < 2.5:
|
||||
smtp_tls_mandatory_protocols = SSLv3, TLSv1
|
||||
# Also available with Postfix >= 2.6:
|
||||
smtp_tls_ciphers = export
|
||||
@ -1572,6 +1878,49 @@ Example:
|
||||
/etc/postfix/main.cf:
|
||||
smtp_starttls_timeout = 300s
|
||||
|
||||
With Postfix 2.8 and later, the tls_disable_workarounds parameter specifies a
|
||||
list or bit-mask of OpenSSL bug work-arounds to disable. This may be necessary
|
||||
if one of the work-arounds enabled by default in OpenSSL proves to pose a
|
||||
security risk, or introduces an unexpected interoperability issue. Some bug
|
||||
work-arounds known to be problematic are disabled in the default value of the
|
||||
parameter when linked with an OpenSSL library that could be vulnerable.
|
||||
|
||||
Example:
|
||||
|
||||
/etc/postfix/main.cf:
|
||||
tls_disable_workarounds = 0xFFFFFFFF
|
||||
tls_disable_workarounds = CVE-2010-4180, LEGACY_SERVER_CONNECT
|
||||
|
||||
Note: Disabling LEGACY_SERVER_CONNECT is not wise at this time, lots of servers
|
||||
are still unpatched and Postfix is not significantly vulnerable to the
|
||||
renegotiation issue in the TLS protocol.
|
||||
|
||||
With Postfix >= 2.11, the tls_ssl_options parameter specifies a list or bit-
|
||||
mask of OpenSSL options to enable. Specify one or more of the named options
|
||||
below, or a hexadecimal bitmask of options found in the ssl.h file
|
||||
corresponding to the run-time OpenSSL library. While it may be reasonable to
|
||||
turn off all bug workarounds (see above), it is not a good idea to attempt to
|
||||
turn on all features.
|
||||
|
||||
A future version of OpenSSL may by default no longer allow connections to
|
||||
servers that don't support secure renegotiation. Since the exposure for SMTP is
|
||||
minimal, and some SMTP servers may remain unpatched, you can add
|
||||
LEGACY_SERVER_CONNECT to the options to restore the more permissive default of
|
||||
current OpenSSL releases.
|
||||
|
||||
Example:
|
||||
|
||||
/etc/postfix/main.cf:
|
||||
tls_ssl_options = NO_TICKET, NO_COMPRESSION, LEGACY_SERVER_CONNECT
|
||||
|
||||
You should only enable features via the hexadecimal mask when the need to
|
||||
control the feature is critical (to deal with a new vulnerability or a serious
|
||||
interoperability problem). Postfix DOES NOT promise backwards compatible
|
||||
behavior with respect to the mask bits. A feature enabled via the mask in one
|
||||
release may be enabled by other means in a later release, and the mask bit will
|
||||
then be ignored. Therefore, use of the hexadecimal mask is only a temporary
|
||||
measure until a new Postfix or OpenSSL release provides a better solution.
|
||||
|
||||
TTLLSS mmaannaaggeerr ssppeecciiffiicc sseettttiinnggss
|
||||
|
||||
The security of cryptographic software such as TLS depends critically on the
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: main.cf,v 1.4 2013/01/06 13:58:24 tron Exp $
|
||||
# $NetBSD: main.cf,v 1.5 2014/07/06 19:45:50 tron Exp $
|
||||
#
|
||||
# Global Postfix configuration file. This file lists only a subset
|
||||
# of all parameters. For the syntax, and for a complete parameter
|
||||
@ -7,7 +7,7 @@
|
||||
# For common configuration examples, see BASIC_CONFIGURATION_README
|
||||
# and STANDARD_CONFIGURATION_README. To find these documents, use
|
||||
# the command "postconf html_directory readme_directory", or go to
|
||||
# http://www.postfix.org/.
|
||||
# http://www.postfix.org/BASIC_CONFIGURATION_README.html etc.
|
||||
#
|
||||
# For best results, change no more than 2-3 parameters at a time,
|
||||
# and test if Postfix still works after every change.
|
||||
|
11
external/ibm-public/postfix/dist/conf/master.cf
vendored
11
external/ibm-public/postfix/dist/conf/master.cf
vendored
@ -1,8 +1,9 @@
|
||||
# $NetBSD: master.cf,v 1.6 2013/09/25 19:12:34 tron Exp $
|
||||
# $NetBSD: master.cf,v 1.7 2014/07/06 19:45:50 tron Exp $
|
||||
#
|
||||
#
|
||||
# Postfix master process configuration file. For details on the format
|
||||
# of the file, see the master(5) manual page (command: "man 5 master").
|
||||
# of the file, see the master(5) manual page (command: "man 5 master" or
|
||||
# on-line: http://www.postfix.org/master.5.html).
|
||||
#
|
||||
# Do not forget to execute "postfix reload" after editing this file.
|
||||
#
|
||||
@ -23,7 +24,8 @@
|
||||
# -o smtpd_client_restrictions=$mua_client_restrictions
|
||||
# -o smtpd_helo_restrictions=$mua_helo_restrictions
|
||||
# -o smtpd_sender_restrictions=$mua_sender_restrictions
|
||||
# -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
|
||||
# -o smtpd_recipient_restrictions=
|
||||
# -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
|
||||
# -o milter_macro_daemon_name=ORIGINATING
|
||||
#smtps inet n - n - - smtpd
|
||||
# -o syslog_name=postfix/smtps
|
||||
@ -33,7 +35,8 @@
|
||||
# -o smtpd_client_restrictions=$mua_client_restrictions
|
||||
# -o smtpd_helo_restrictions=$mua_helo_restrictions
|
||||
# -o smtpd_sender_restrictions=$mua_sender_restrictions
|
||||
# -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
|
||||
# -o smtpd_recipient_restrictions=
|
||||
# -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
|
||||
# -o milter_macro_daemon_name=ORIGINATING
|
||||
#628 inet n - n - - qmqpd
|
||||
pickup unix n - n 60 1 pickup
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: postfix-files,v 1.4 2013/01/02 19:18:30 tron Exp $
|
||||
# $NetBSD: postfix-files,v 1.5 2014/07/06 19:45:50 tron Exp $
|
||||
#
|
||||
# Commented out entries mean files not installed under NetBSD.
|
||||
#
|
||||
@ -167,10 +167,12 @@ $manpage_directory/man5/cidr_table.5:f:root:-:644
|
||||
$manpage_directory/man5/generics.5:f:root:-:644:o
|
||||
$manpage_directory/man5/generic.5:f:root:-:644
|
||||
$manpage_directory/man5/header_checks.5:f:root:-:644
|
||||
#$manpage_directory/man5/ldap_table.5:f:root:-:644
|
||||
$manpage_directory/man5/ldap_table.5:f:root:-:644
|
||||
#$manpage_directory/man5/lmdb_table.5:f:root:-:644
|
||||
$manpage_directory/man5/master.5:f:root:-:644
|
||||
$manpage_directory/man5/memcache_table.5:f:root:-:644
|
||||
#$manpage_directory/man5/mysql_table.5:f:root:-:644
|
||||
$manpage_directory/man5/socketmap_table.5:f:root:-:644
|
||||
$manpage_directory/man5/sqlite_table.5:f:root:-:644
|
||||
$manpage_directory/man5/nisplus_table.5:f:root:-:644
|
||||
$manpage_directory/man5/pcre_table.5:f:root:-:644
|
||||
@ -260,11 +262,13 @@ $readme_directory/DEBUG_README:f:root:-:644
|
||||
$readme_directory/DSN_README:f:root:-:644
|
||||
$readme_directory/ETRN_README:f:root:-:644
|
||||
$readme_directory/FILTER_README:f:root:-:644
|
||||
$readme_directory/FORWARD_SECRECY_README:f:root:-:644
|
||||
$readme_directory/HOSTING_README:f:root:-:644:o
|
||||
#$readme_directory/INSTALL:f:root:-:644
|
||||
$readme_directory/IPV6_README:f:root:-:644
|
||||
$readme_directory/LDAP_README:f:root:-:644
|
||||
#$readme_directory/LINUX_README:f:root:-:644
|
||||
#$readme_directory/LMDB_README:f:root:-:644
|
||||
$readme_directory/LOCAL_RECIPIENT_README:f:root:-:644
|
||||
$readme_directory/MACOSX_README:f:root:-:644:o
|
||||
$readme_directory/MAILDROP_README:f:root:-:644
|
||||
@ -316,10 +320,12 @@ $html_directory/DEBUG_README.html:f:root:-:644
|
||||
$html_directory/DSN_README.html:f:root:-:644
|
||||
$html_directory/ETRN_README.html:f:root:-:644
|
||||
$html_directory/FILTER_README.html:f:root:-:644
|
||||
$html_directory/FORWARD_SECRECY_README.html:f:root:-:644
|
||||
#$html_directory/INSTALL.html:f:root:-:644
|
||||
$html_directory/IPV6_README.html:f:root:-:644
|
||||
$html_directory/LDAP_README.html:f:root:-:644
|
||||
#$html_directory/LINUX_README.html:f:root:-:644
|
||||
#$html_directory/LMDB_README.html:f:root:-:644
|
||||
$html_directory/LOCAL_RECIPIENT_README.html:f:root:-:644
|
||||
$html_directory/MAILDROP_README.html:f:root:-:644
|
||||
$html_directory/MILTER_README.html:f:root:-:644
|
||||
|
@ -333,7 +333,7 @@ in forged email. </p>
|
||||
<blockquote>
|
||||
<pre>
|
||||
/etc/postfix/<a href="postconf.5.html">main.cf</a>:
|
||||
<a href="postconf.5.html#smtpd_sender_restrictions">smtpd_sender_restrictions</a> = hash:/etc/postfix/sender_access
|
||||
<a href="postconf.5.html#smtpd_sender_restrictions">smtpd_sender_restrictions</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/sender_access
|
||||
<a href="postconf.5.html#unverified_sender_reject_code">unverified_sender_reject_code</a> = 550
|
||||
# Postfix 2.6 and later.
|
||||
# <a href="postconf.5.html#unverified_sender_defer_code">unverified_sender_defer_code</a> = 250
|
||||
@ -341,7 +341,7 @@ in forged email. </p>
|
||||
# Default setting for Postfix 2.7 and later.
|
||||
# Note 1: Be sure to read the "<a href="#caching">Caching</a>" section below!
|
||||
# Note 2: Avoid hash files here. Use btree instead.
|
||||
<a href="postconf.5.html#address_verify_map">address_verify_map</a> = btree:/var/db/postfix/verify
|
||||
<a href="postconf.5.html#address_verify_map">address_verify_map</a> = <a href="DATABASE_README.html#types">btree</a>:/var/db/postfix/verify
|
||||
|
||||
/etc/postfix/sender_access:
|
||||
# Don't do this when you handle lots of email.
|
||||
@ -378,7 +378,7 @@ you can see what mail would be blocked: </p>
|
||||
<a href="postconf.5.html#smtpd_sender_restrictions">smtpd_sender_restrictions</a> =
|
||||
<a href="postconf.5.html#permit_mynetworks">permit_mynetworks</a>
|
||||
...
|
||||
<a href="postconf.5.html#check_sender_access">check_sender_access</a> hash:/etc/postfix/sender_access
|
||||
<a href="postconf.5.html#check_sender_access">check_sender_access</a> <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/sender_access
|
||||
<a href="postconf.5.html#reject_unknown_sender_domain">reject_unknown_sender_domain</a>
|
||||
<a href="postconf.5.html#warn_if_reject">warn_if_reject</a> <a href="postconf.5.html#reject_unverified_sender">reject_unverified_sender</a>
|
||||
...
|
||||
@ -388,7 +388,7 @@ you can see what mail would be blocked: </p>
|
||||
# Default setting for Postfix 2.7 and later.
|
||||
# Note 1: Be sure to read the "<a href="#caching">Caching</a>" section below!
|
||||
# Note 2: Avoid hash files here. Use btree instead.
|
||||
<a href="postconf.5.html#address_verify_map">address_verify_map</a> = btree:/var/db/postfix/verify
|
||||
<a href="postconf.5.html#address_verify_map">address_verify_map</a> = <a href="DATABASE_README.html#types">btree</a>:/var/db/postfix/verify
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
@ -454,23 +454,35 @@ results are lost after "postfix reload" or "postfix stop". </p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
# Example 1: Default setting for Postfix 2.7 and later.
|
||||
# Note: avoid hash files here. Use btree instead.
|
||||
/etc/postfix/<a href="postconf.5.html">main.cf</a>:
|
||||
# Default setting for Postfix 2.7 and later.
|
||||
# Note: avoid hash files here. Use btree instead.
|
||||
<a href="postconf.5.html#address_verify_map">address_verify_map</a> = btree:$<a href="postconf.5.html#data_directory">data_directory</a>/verify_cache
|
||||
<a href="postconf.5.html#address_verify_map">address_verify_map</a> = <a href="DATABASE_README.html#types">btree</a>:$<a href="postconf.5.html#data_directory">data_directory</a>/verify_cache
|
||||
|
||||
# Shared persistent cache (requires Postfix 2.9 or later).
|
||||
<a href="postconf.5.html#address_verify_map">address_verify_map</a> = <a href="proxymap.8.html">proxy</a>:btree:$<a href="postconf.5.html#data_directory">data_directory</a>/verify_cache
|
||||
# Disable automatic cache cleanup in all Postfix instances except
|
||||
# for one instance that will be responsible for cache cleanup.
|
||||
# Example 2: Shared persistent <a href="lmdb_table.5.html">lmdb</a>: cache (Postfix 2.11 or later).
|
||||
# Disable automatic cache cleanup in all Postfix instances except
|
||||
# for one instance that will be responsible for cache cleanup.
|
||||
/etc/postfix/<a href="postconf.5.html">main.cf</a>:
|
||||
<a href="postconf.5.html#address_verify_map">address_verify_map</a> = <a href="lmdb_table.5.html">lmdb</a>:$<a href="postconf.5.html#data_directory">data_directory</a>/verify_cache
|
||||
# <a href="postconf.5.html#address_verify_cache_cleanup_interval">address_verify_cache_cleanup_interval</a> = 0
|
||||
|
||||
# Shared memory cache (requires Postfix 2.9 or later).
|
||||
# See <a href="memcache_table.5.html">memcache_table(5)</a> for details.
|
||||
<a href="postconf.5.html#address_verify_map">address_verify_map</a> = <a href="memcache_table.5.html">memcache</a>:/etc/postfix/verify-memcache.cf
|
||||
# Example 3: Shared persistent <a href="DATABASE_README.html#types">btree</a>: cache (Postfix 2.9 or later).
|
||||
# Disable automatic cache cleanup in all Postfix instances except
|
||||
# for one instance that will be responsible for cache cleanup.
|
||||
/etc/postfix/<a href="postconf.5.html">main.cf</a>:
|
||||
<a href="postconf.5.html#address_verify_map">address_verify_map</a> = <a href="proxymap.8.html">proxy</a>:<a href="DATABASE_README.html#types">btree</a>:$<a href="postconf.5.html#data_directory">data_directory</a>/verify_cache
|
||||
# <a href="postconf.5.html#address_verify_cache_cleanup_interval">address_verify_cache_cleanup_interval</a> = 0
|
||||
|
||||
# Default setting for Postfix 2.6 and earlier.
|
||||
# This uses non-persistent storage only.
|
||||
# Example 4: Shared memory cache (requires Postfix 2.9 or later).
|
||||
# Disable automatic cache cleanup in all Postfix instances.
|
||||
# See <a href="memcache_table.5.html">memcache_table(5)</a> for details.
|
||||
/etc/postfix/<a href="postconf.5.html">main.cf</a>:
|
||||
<a href="postconf.5.html#address_verify_map">address_verify_map</a> = <a href="memcache_table.5.html">memcache</a>:/etc/postfix/verify-memcache.cf
|
||||
<a href="postconf.5.html#address_verify_cache_cleanup_interval">address_verify_cache_cleanup_interval</a> = 0
|
||||
|
||||
# Example 5: Default setting for Postfix 2.6 and earlier.
|
||||
# This uses non-persistent storage only.
|
||||
/etc/postfix/<a href="postconf.5.html">main.cf</a>:
|
||||
<a href="postconf.5.html#address_verify_map">address_verify_map</a> =
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
@ -229,21 +229,25 @@ $ make
|
||||
|
||||
<p> and so on. In some cases, optimization is turned off automatically. </p>
|
||||
|
||||
<h3>4.3 - Building with optional extensions</h3>
|
||||
<h3>4.3 - Building with optional features</h3>
|
||||
|
||||
By default, Postfix builds as a mail system with relatively few
|
||||
bells and whistles. Support for third-party databases etc.
|
||||
must be configured when Postfix is compiled. The following documents describe how to build Postfix with support for extensions:
|
||||
must be configured when Postfix is compiled. The following documents
|
||||
describe how to build Postfix with support for optional features:
|
||||
|
||||
<blockquote>
|
||||
<table border="1">
|
||||
|
||||
<tr> <th>Postfix extension </th> <th>Document </th> <th>Availability</th>
|
||||
<tr> <th>Optional feature </th> <th>Document </th> <th>Availability</th>
|
||||
</tr>
|
||||
|
||||
<tr> <td> Berkeley DB database</td> <td><a href="DB_README.html">DB_README</a></td> <td> Postfix
|
||||
1.0 </td> </tr>
|
||||
|
||||
<tr> <td> LMDB database</td> <td><a href="LMDB_README.html">LMDB_README</a></td> <td> Postfix
|
||||
2.11 </td> </tr>
|
||||
|
||||
<tr> <td> LDAP database</td> <td><a href="LDAP_README.html">LDAP_README</a></td> <td> Postfix
|
||||
1.0 </td> </tr>
|
||||
|
||||
@ -306,6 +310,9 @@ default</th> </tr>
|
||||
<tr> <td>DEF_CONFIG_DIR</td> <td><a href="postconf.5.html#config_directory">config_directory</a></td>
|
||||
<td>/etc/postfix</td> </tr>
|
||||
|
||||
<tr> <td>DEF_DB_TYPE</td> <td><a href="postconf.5.html#default_database_type">default_database_type</a></td>
|
||||
<td>hash</td> </tr>
|
||||
|
||||
<tr> <td>DEF_DAEMON_DIR</td> <td><a href="postconf.5.html#daemon_directory">daemon_directory</a></td>
|
||||
<td>/usr/libexec/postfix</td> </tr>
|
||||
|
||||
@ -372,7 +379,9 @@ off Postfix features at compile time:</td> </tr>
|
||||
|
||||
<tr> <td> </td> <td> -DNO_DB </td> <td> Do not build with Berkeley
|
||||
DB support. By default, Berkeley DB support is compiled in on
|
||||
platforms that are known to support this feature. </td> </tr>
|
||||
platforms that are known to support this feature. If you override
|
||||
this, then you probably should also override DEF_DB_TYPE as described
|
||||
in section 4.4. </td> </tr>
|
||||
|
||||
<tr> <td> </td> <td> -DNO_DEVPOLL </td> <td> Do not build with
|
||||
Solaris <tt>/dev/poll</tt> support. By default, <tt>/dev/poll</tt>
|
||||
@ -395,7 +404,11 @@ support is compiled in on platforms that are known to support it.
|
||||
</td> </tr>
|
||||
|
||||
<tr> <td> </td> <td> -DNO_NIS </td> <td> Do not build with NIS or
|
||||
NISPLUS support. NIS is not available on some recent Linux or Solaris
|
||||
NISPLUS support. NIS is not available on some recent Linux
|
||||
distributions. </td> </tr>
|
||||
|
||||
<tr> <td> </td> <td> -DNO_NISPLUS </td> <td> Do not build with
|
||||
NISPLUS support. NISPLUS is not available on some recent Solaris
|
||||
distributions. </td> </tr>
|
||||
|
||||
<tr> <td> </td> <td> -DNO_PCRE </td> <td> Do not build with PCRE
|
||||
|
File diff suppressed because it is too large
Load Diff
1139
external/ibm-public/postfix/dist/html/postconf.5.html
vendored
1139
external/ibm-public/postfix/dist/html/postconf.5.html
vendored
File diff suppressed because it is too large
Load Diff
111
external/ibm-public/postfix/dist/makedefs
vendored
111
external/ibm-public/postfix/dist/makedefs
vendored
@ -48,7 +48,10 @@
|
||||
# are known to support it.
|
||||
# .IP \fB-DNO_NIS\fR
|
||||
# Do not build with NIS or NISPLUS support. Support for NIS
|
||||
# is unavailable on some recent Linux and Solaris distributions.
|
||||
# is unavailable on some recent Linux distributions.
|
||||
# .IP \fB-DNO_NISPLUS\fR
|
||||
# Do not build with NISPLUS support. Support for NISPLUS
|
||||
# is unavailable on some recent Solaris distributions.
|
||||
# .IP \fB-DNO_PCRE\fR
|
||||
# Do not build with PCRE support.
|
||||
# By default, PCRE support is compiled in when the \fBpcre-config\fR
|
||||
@ -155,6 +158,8 @@ case "$SYSTEM.$RELEASE" in
|
||||
;;
|
||||
FreeBSD.9*) SYSTYPE=FREEBSD9
|
||||
;;
|
||||
DragonFly.*) SYSTYPE=DRAGONFLY
|
||||
;;
|
||||
OpenBSD.2*) SYSTYPE=OPENBSD2
|
||||
;;
|
||||
OpenBSD.3*) SYSTYPE=OPENBSD3
|
||||
@ -175,6 +180,8 @@ case "$SYSTEM.$RELEASE" in
|
||||
;;
|
||||
NetBSD.5*) SYSTYPE=NETBSD5
|
||||
;;
|
||||
NetBSD.6*) SYSTYPE=NETBSD6
|
||||
;;
|
||||
BSD/OS.2*) SYSTYPE=BSDI2
|
||||
;;
|
||||
BSD/OS.3*) SYSTYPE=BSDI3
|
||||
@ -194,7 +201,7 @@ case "$SYSTEM.$RELEASE" in
|
||||
;;
|
||||
SunOS.5*) SYSTYPE=SUNOS5
|
||||
RANLIB=echo
|
||||
SYSLIBS="-lresolv -lsocket -lnsl"
|
||||
SYSLIBS="-lresolv -lsocket -lnsl -ldl"
|
||||
# Stock awk breaks with >10 files.
|
||||
test -x /usr/xpg4/bin/awk && AWK=/usr/xpg4/bin/awk
|
||||
# Solaris 2.5 added usleep(), POSIX regexp, POSIX getpwnam/uid_r
|
||||
@ -210,6 +217,10 @@ case "$SYSTEM.$RELEASE" in
|
||||
case $RELEASE in
|
||||
5.[0-8]|5.[0-8].*) CCARGS="$CCARGS -DNO_CLOSEFROM -DNO_DEV_URANDOM -DNO_FUTIMESAT -DSTREAM_CONNECTIONS";;
|
||||
esac
|
||||
# Somewhere NISPLUS went away.
|
||||
case $RELEASE in
|
||||
5.[0-9][0-9]*) CCARGS="$CCARGS -DNO_NISPLUS";;
|
||||
esac
|
||||
# Work around broken str*casecmp(). Do it all here instead
|
||||
# of having half the solution in the sys_defs.h file.
|
||||
CCARGS="$CCARGS -Dstrcasecmp=fix_strcasecmp \
|
||||
@ -274,12 +285,14 @@ case "$SYSTEM.$RELEASE" in
|
||||
Linux.1*) SYSTYPE=LINUX1
|
||||
case "$CCARGS" in
|
||||
*-DNO_DB*) ;;
|
||||
*-DHAS_DB*) ;;
|
||||
*) SYSLIBS="-ldb";;
|
||||
esac
|
||||
;;
|
||||
Linux.2*) SYSTYPE=LINUX2
|
||||
case "$CCARGS" in
|
||||
*-DNO_DB*) ;;
|
||||
*-DHAS_DB*) ;;
|
||||
*) if [ -f /usr/include/db.h ]
|
||||
then
|
||||
: we are all set
|
||||
@ -317,12 +330,12 @@ case "$SYSTEM.$RELEASE" in
|
||||
# Workaround for retarded libc
|
||||
2.6.*)
|
||||
if [ `expr "X$CCARGS" : "X.*-DNO_EPOLL"` -gt 0 ]
|
||||
then
|
||||
:
|
||||
elif [ ! -e /usr/include/sys/epoll.h ]
|
||||
then
|
||||
echo CCARGS="$CCARGS -DNO_EPOLL"
|
||||
else
|
||||
then
|
||||
:
|
||||
elif [ ! -e /usr/include/sys/epoll.h ]
|
||||
then
|
||||
echo CCARGS="$CCARGS -DNO_EPOLL"
|
||||
else
|
||||
trap 'rm -f makedefs.test makedefs.test.[co]' 1 2 3 15
|
||||
cat >makedefs.test.c <<'EOF'
|
||||
#include <sys/types.h>
|
||||
@ -352,6 +365,7 @@ EOF
|
||||
Linux.3*) SYSTYPE=LINUX3
|
||||
case "$CCARGS" in
|
||||
*-DNO_DB*) ;;
|
||||
*-DHAS_DB*) ;;
|
||||
*) if [ -f /usr/include/db.h ]
|
||||
then
|
||||
: we are all set
|
||||
@ -380,7 +394,7 @@ EOF
|
||||
done
|
||||
;;
|
||||
GNU.0*|GNU/kFreeBSD.[567]*)
|
||||
SYSTYPE=GNU0
|
||||
SYSTYPE=GNU0
|
||||
case "$CCARGS" in
|
||||
*-DNO_DB*) ;;
|
||||
*) if [ -f /usr/include/db.h ]
|
||||
@ -461,7 +475,7 @@ ReliantUNIX-?.5.43) SYSTYPE=ReliantUnix543
|
||||
case $RELEASE in
|
||||
1.[0-3]) AWK=gawk;;
|
||||
*) AWK=awk
|
||||
SYSLIBS=-flat_namespace;;
|
||||
SYSLIBS="$SYSLIBS -flat_namespace";;
|
||||
esac
|
||||
# Darwin 7 adds IPv6 support, BIND_8_COMPAT, NO_NETINFO
|
||||
case $RELEASE in
|
||||
@ -477,64 +491,16 @@ ReliantUNIX-?.5.43) SYSTYPE=ReliantUnix543
|
||||
?.*) CCARGS="$CCARGS -DRESOLVE_H_NEEDS_NAMESER8_COMPAT_H";;
|
||||
*) CCARGS="$CCARGS -DRESOLVE_H_NEEDS_ARPA_NAMESER_COMPAT_H";;
|
||||
esac
|
||||
# kqueue and/or poll are broken up to and including MacOS X 10.5
|
||||
CCARGS="$CCARGS -DNO_KQUEUE"
|
||||
# # Darwin 8.11.1 has kqueue support, but let's play safe
|
||||
# case $RELEASE in
|
||||
# [1-8].*) CCARGS="$CCARGS -DNO_KQUEUE";;
|
||||
# *) trap 'rm -f makedefs.test makedefs.test.[co]' 1 2 3 15
|
||||
# cat >makedefs.test.c <<'EOF'
|
||||
#/* Adapted from libevent. */
|
||||
#
|
||||
##include <sys/types.h>
|
||||
##include <sys/event.h>
|
||||
##include <sys/time.h>
|
||||
##include <string.h>
|
||||
##include <stdlib.h>
|
||||
##include <stdio.h>
|
||||
#
|
||||
##ifndef EV_SET
|
||||
##define EV_SET(kp, id, fi, fl, ffl, da, ud) do { \
|
||||
# struct kevent *__kp = (kp); \
|
||||
# __kp->ident = (id); \
|
||||
# __kp->filter = (fi); \
|
||||
# __kp->flags = (fl); \
|
||||
# __kp->fflags = (ffl); \
|
||||
# __kp->data = (da); \
|
||||
# __kp->udata = (ud); \
|
||||
# } while(0)
|
||||
##endif
|
||||
#
|
||||
#int main(int argc, char **argv)
|
||||
#{
|
||||
# int kq;
|
||||
# struct kevent test_change;
|
||||
# struct kevent test_result;
|
||||
#
|
||||
# if ((kq = kqueue()) < 0) {
|
||||
# perror("kqueue");
|
||||
# exit(1);
|
||||
# }
|
||||
##define TEST_FD (-1)
|
||||
#
|
||||
# EV_SET(&test_change, TEST_FD, EVFILT_READ, EV_ADD, 0, 0, 0);
|
||||
# if (kevent(kq,
|
||||
# &test_change, sizeof(test_change) / sizeof(struct kevent),
|
||||
# &test_result, sizeof(test_result) / sizeof(struct kevent),
|
||||
# (struct timespec *) 0) != 1 ||
|
||||
# test_result.ident != TEST_FD ||
|
||||
# test_result.flags != EV_ERROR) {
|
||||
# fprintf(stderr, "Error: kevent reports errors incorrectly\n");
|
||||
# exit(1);
|
||||
# }
|
||||
# exit(0);
|
||||
#}
|
||||
#EOF
|
||||
# $CC -o makedefs.test makedefs.test.c || exit 1
|
||||
# ./makedefs.test 2>/dev/null ||
|
||||
# CCARGS="$CCARGS -DNO_KQUEUE"
|
||||
# rm -f makedefs.test makedefs.test.[co];;
|
||||
# esac
|
||||
# Darwin 12.x (MacOS X 10.8.x), maybe earlier, needs libresolv.
|
||||
case $RELEASE in
|
||||
?.*|1[0-1].*) ;;
|
||||
*) SYSLIBS="$SYSLIBS -lresolv";;
|
||||
esac
|
||||
# kqueue and/or poll are broken in MacOS X 10.5 (Darwin 9).
|
||||
# kqueue works in Mac OS X 10.8 (Darwin 12).
|
||||
case $RELEASE in
|
||||
?.*|1[0-1].*) CCARGS="$CCARGS -DNO_KQUEUE";;
|
||||
esac
|
||||
;;
|
||||
dcosx.1*) SYSTYPE=DCOSX1
|
||||
RANLIB=echo
|
||||
@ -564,7 +530,7 @@ esac
|
||||
#
|
||||
case "$CCARGS" in
|
||||
*-DNO_SIGSETJMP*) ;;
|
||||
*) trap 'rm -f makedefs.test makedefs.test.[co]' 1 2 3 15
|
||||
*) trap 'rm -f makedefs.test makedefs.test.[co]' 1 2 3 15
|
||||
cat >makedefs.test.c <<'EOF'
|
||||
#include <setjmp.h>
|
||||
#include <stdlib.h>
|
||||
@ -630,7 +596,7 @@ esac
|
||||
case "$CCARGS" in
|
||||
*-DHAS_PCRE*) ;;
|
||||
*-DNO_PCRE*) ;;
|
||||
*) pcre_cflags=`(pcre-config --cflags) 2>/dev/null` &&
|
||||
*) pcre_cflags=`(pcre-config --cflags) 2>/dev/null` &&
|
||||
pcre_libs=`(pcre-config --libs) 2>/dev/null` && {
|
||||
CCARGS="$CCARGS -DHAS_PCRE $pcre_cflags"
|
||||
AUXLIBS="$AUXLIBS $pcre_libs"
|
||||
@ -649,7 +615,7 @@ case "$CC" in
|
||||
"gcc version 2.8"*) : ${OPT=};;
|
||||
esac;;
|
||||
*CC) error "Don't use CC. That's the C++ compiler";;
|
||||
*) : ${OPT='-O'};;
|
||||
*) : ${OPT='-O'};;
|
||||
esac
|
||||
#
|
||||
# "gcc -W" 3.4.2 no longer reports functions that fail to return a
|
||||
@ -672,6 +638,9 @@ export SYSTYPE AR ARFL RANLIB SYSLIBS CC OPT DEBUG AWK OPTS
|
||||
# needed before the code stabilizes.
|
||||
#CCARGS="$CCARGS -DNONPROD"
|
||||
|
||||
# Workaround: prepend Postfix include files before other include files.
|
||||
CCARGS="-I. -I../../include $CCARGS"
|
||||
|
||||
sed 's/ / /g' <<EOF
|
||||
SYSTYPE = $SYSTYPE
|
||||
AR = $AR
|
||||
|
942
external/ibm-public/postfix/dist/man/man5/postconf.5
vendored
942
external/ibm-public/postfix/dist/man/man5/postconf.5
vendored
File diff suppressed because it is too large
Load Diff
@ -454,23 +454,35 @@ results are lost after "postfix reload" or "postfix stop". </p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
# Example 1: Default setting for Postfix 2.7 and later.
|
||||
# Note: avoid hash files here. Use btree instead.
|
||||
/etc/postfix/main.cf:
|
||||
# Default setting for Postfix 2.7 and later.
|
||||
# Note: avoid hash files here. Use btree instead.
|
||||
address_verify_map = btree:$data_directory/verify_cache
|
||||
|
||||
# Shared persistent cache (requires Postfix 2.9 or later).
|
||||
address_verify_map = proxy:btree:$data_directory/verify_cache
|
||||
# Disable automatic cache cleanup in all Postfix instances except
|
||||
# for one instance that will be responsible for cache cleanup.
|
||||
# Example 2: Shared persistent lmdb: cache (Postfix 2.11 or later).
|
||||
# Disable automatic cache cleanup in all Postfix instances except
|
||||
# for one instance that will be responsible for cache cleanup.
|
||||
/etc/postfix/main.cf:
|
||||
address_verify_map = lmdb:$data_directory/verify_cache
|
||||
# address_verify_cache_cleanup_interval = 0
|
||||
|
||||
# Shared memory cache (requires Postfix 2.9 or later).
|
||||
# See memcache_table(5) for details.
|
||||
address_verify_map = memcache:/etc/postfix/verify-memcache.cf
|
||||
# Example 3: Shared persistent btree: cache (Postfix 2.9 or later).
|
||||
# Disable automatic cache cleanup in all Postfix instances except
|
||||
# for one instance that will be responsible for cache cleanup.
|
||||
/etc/postfix/main.cf:
|
||||
address_verify_map = proxy:btree:$data_directory/verify_cache
|
||||
# address_verify_cache_cleanup_interval = 0
|
||||
|
||||
# Default setting for Postfix 2.6 and earlier.
|
||||
# This uses non-persistent storage only.
|
||||
# Example 4: Shared memory cache (requires Postfix 2.9 or later).
|
||||
# Disable automatic cache cleanup in all Postfix instances.
|
||||
# See memcache_table(5) for details.
|
||||
/etc/postfix/main.cf:
|
||||
address_verify_map = memcache:/etc/postfix/verify-memcache.cf
|
||||
address_verify_cache_cleanup_interval = 0
|
||||
|
||||
# Example 5: Default setting for Postfix 2.6 and earlier.
|
||||
# This uses non-persistent storage only.
|
||||
/etc/postfix/main.cf:
|
||||
address_verify_map =
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
@ -229,21 +229,25 @@ $ make
|
||||
|
||||
<p> and so on. In some cases, optimization is turned off automatically. </p>
|
||||
|
||||
<h3>4.3 - Building with optional extensions</h3>
|
||||
<h3>4.3 - Building with optional features</h3>
|
||||
|
||||
By default, Postfix builds as a mail system with relatively few
|
||||
bells and whistles. Support for third-party databases etc.
|
||||
must be configured when Postfix is compiled. The following documents describe how to build Postfix with support for extensions:
|
||||
must be configured when Postfix is compiled. The following documents
|
||||
describe how to build Postfix with support for optional features:
|
||||
|
||||
<blockquote>
|
||||
<table border="1">
|
||||
|
||||
<tr> <th>Postfix extension </th> <th>Document </th> <th>Availability</th>
|
||||
<tr> <th>Optional feature </th> <th>Document </th> <th>Availability</th>
|
||||
</tr>
|
||||
|
||||
<tr> <td> Berkeley DB database</td> <td>DB_README</td> <td> Postfix
|
||||
1.0 </td> </tr>
|
||||
|
||||
<tr> <td> LMDB database</td> <td>LMDB_README</td> <td> Postfix
|
||||
2.11 </td> </tr>
|
||||
|
||||
<tr> <td> LDAP database</td> <td>LDAP_README</td> <td> Postfix
|
||||
1.0 </td> </tr>
|
||||
|
||||
@ -306,6 +310,9 @@ default</th> </tr>
|
||||
<tr> <td>DEF_CONFIG_DIR</td> <td>config_directory</td>
|
||||
<td>/etc/postfix</td> </tr>
|
||||
|
||||
<tr> <td>DEF_DB_TYPE</td> <td>default_database_type</td>
|
||||
<td>hash</td> </tr>
|
||||
|
||||
<tr> <td>DEF_DAEMON_DIR</td> <td>daemon_directory</td>
|
||||
<td>/usr/libexec/postfix</td> </tr>
|
||||
|
||||
@ -372,7 +379,9 @@ off Postfix features at compile time:</td> </tr>
|
||||
|
||||
<tr> <td> </td> <td> -DNO_DB </td> <td> Do not build with Berkeley
|
||||
DB support. By default, Berkeley DB support is compiled in on
|
||||
platforms that are known to support this feature. </td> </tr>
|
||||
platforms that are known to support this feature. If you override
|
||||
this, then you probably should also override DEF_DB_TYPE as described
|
||||
in section 4.4. </td> </tr>
|
||||
|
||||
<tr> <td> </td> <td> -DNO_DEVPOLL </td> <td> Do not build with
|
||||
Solaris <tt>/dev/poll</tt> support. By default, <tt>/dev/poll</tt>
|
||||
@ -395,7 +404,11 @@ support is compiled in on platforms that are known to support it.
|
||||
</td> </tr>
|
||||
|
||||
<tr> <td> </td> <td> -DNO_NIS </td> <td> Do not build with NIS or
|
||||
NISPLUS support. NIS is not available on some recent Linux or Solaris
|
||||
NISPLUS support. NIS is not available on some recent Linux
|
||||
distributions. </td> </tr>
|
||||
|
||||
<tr> <td> </td> <td> -DNO_NISPLUS </td> <td> Do not build with
|
||||
NISPLUS support. NISPLUS is not available on some recent Solaris
|
||||
distributions. </td> </tr>
|
||||
|
||||
<tr> <td> </td> <td> -DNO_PCRE </td> <td> Do not build with PCRE
|
||||
|
@ -32,7 +32,7 @@ Postfix. </p>
|
||||
<p> Transport Layer Security (TLS, formerly called SSL) provides
|
||||
certificate-based authentication and encrypted sessions. An
|
||||
encrypted session protects the information that is transmitted with
|
||||
SMTP mail or with SASL authentication.
|
||||
SMTP mail or with SASL authentication. </p>
|
||||
|
||||
<blockquote> <p> <a name="client_tls_obs"></a> <a
|
||||
name="client_tls_harden"></a> NOTE: This document describes a TLS
|
||||
@ -163,16 +163,16 @@ private key must not be encrypted, meaning: the key must be accessible
|
||||
without a password. The certificate and private key may be in the same
|
||||
file, in which case the certificate file should be owned by "root" and
|
||||
not be readable by any other user. If the key is stored separately,
|
||||
this applies to the key file only, and the certificate file may be
|
||||
"world-readable". </p>
|
||||
this access restriction applies to the key file only, and the
|
||||
certificate file may be "world-readable". </p>
|
||||
|
||||
<p> Public Internet MX hosts without certificates signed by a "reputable"
|
||||
CA must generate, and be prepared to present to most clients, a
|
||||
self-signed or private-CA signed certificate. The remote SMTP client
|
||||
will generally not be
|
||||
able to authenticate the self-signed certificate, but unless the
|
||||
client is running Postfix or
|
||||
similar software, it will still insist on a server certificate. </p>
|
||||
<p> Public Internet MX hosts without certificates signed by a
|
||||
well-known public CA must still generate, and be prepared to present
|
||||
to most clients, a self-signed or private-CA signed certificate.
|
||||
The remote SMTP client will generally not be able to verify the
|
||||
self-signed certificate, but unless the client is running Postfix
|
||||
or similar software, it will only negotiate TLS ciphersuites that
|
||||
require a server certificate. </p>
|
||||
|
||||
<p> For servers that are <b>not</b> public Internet MX hosts, Postfix
|
||||
supports configurations with no certificates. This entails the
|
||||
@ -188,23 +188,37 @@ SMTP server configurations will not accidentally run with no
|
||||
certificates. </p>
|
||||
|
||||
<p> RSA, DSA and ECDSA (Postfix ≥ 2.6) certificates are supported.
|
||||
Typically you will
|
||||
only have RSA certificates issued by a commercial CA. In addition,
|
||||
the tools supplied with OpenSSL will by default issue RSA certificates.
|
||||
You can configure all three at the same time, in which case the cipher used
|
||||
determines which certificate is presented. For Netscape and OpenSSL
|
||||
clients without special cipher choices, the RSA certificate is
|
||||
preferred. </p>
|
||||
Most sites only have RSA certificates. You can configure all three
|
||||
at the same time, in which case the ciphersuite negotiated with the
|
||||
remote SMTP client determines which certificate is used. If your
|
||||
DNS zone is signed, and you want to publish RFC 6698 TLSA records,
|
||||
these must match any of the configured certificates. Since the
|
||||
best practice is to publish "3 1 1" certificate associations, create
|
||||
a separate TLSA record for each public-key certificate digest. </p>
|
||||
|
||||
<p> To enable a remote SMTP client to verify the Postfix SMTP server
|
||||
certificate, the issuing CA certificates must be made available to the
|
||||
client. You should include the required certificates in the server
|
||||
certificate file, the server certificate first, then the issuing
|
||||
CA(s) (bottom-up order). </p>
|
||||
<h4> Creating the server certificate file </h4>
|
||||
|
||||
<p> Example: the certificate for "server.example.com" was issued by
|
||||
"intermediate CA" which itself has a certificate issued by "root
|
||||
CA". Create the server.pem file with: </p>
|
||||
<p> To verify the Postfix SMTP server certificate, the remote SMTP
|
||||
client must receive the issuing CA certificates via the TLS handshake
|
||||
or via public-key infrastructure. This means that the Postfix server
|
||||
public-key certificate file must include the server certificate
|
||||
first, then the issuing CA(s) (bottom-up order). The Postfix SMTP
|
||||
server certificate must be usable as SSL server certificate and
|
||||
hence pass the "<tt>openssl verify -purpose sslserver ...</tt>" test.
|
||||
</p>
|
||||
|
||||
<p> The examples that follow show how to create a server certificate
|
||||
file. We assume that the certificate for "server.example.com" was
|
||||
issued by "intermediate CA" which itself has a certificate issued
|
||||
by "root CA". </p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li> <p> With legacy public CA trust verification, you can omit the
|
||||
root certificate from the "server.pem" certificate file. If the
|
||||
client trusts the root CA, it will already have a local copy of the
|
||||
root CA certificate. Omitting the root CA certificate reduces the
|
||||
size of the server TLS handshake. </p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
@ -212,18 +226,56 @@ CA". Create the server.pem file with: </p>
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p> A Postfix SMTP server certificate supplied here must be usable
|
||||
as SSL server certificate and hence pass the "openssl verify -purpose
|
||||
sslserver ..." test. </p>
|
||||
<li> <p> If you publish RFC 6698 TLSA "2 0 1" or "2 1 1" records to
|
||||
specify root CA certificate digests, you must include the corresponding
|
||||
root CA certificates in the "server.pem" certificate file. See the
|
||||
documentation of the tls_dane_trust_anchor_digest_enable main.cf
|
||||
parameter. </p>
|
||||
|
||||
<p> A client 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 "server.pem" file reduces
|
||||
the overhead of the TLS exchange. </p>
|
||||
<blockquote>
|
||||
<pre>
|
||||
% <b>cat server_cert.pem intermediate_CA.pem root.pem > server.pem</b>
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p> Remote SMTP clients will be able to use the TLSA record you
|
||||
publish (which only contains the certificate digest) only if they
|
||||
have access to the corresponding certificate. Failure to verify
|
||||
certificates per the server's published TLSA records will typically
|
||||
cause the SMTP client to defer mail delivery. The foregoing also
|
||||
applies to "2 0 2" and "2 1 2" TLSA records or any other digest of
|
||||
a CA certificate, but it is expected that SHA256 will be by far the
|
||||
most common digest for TLSA. </p>
|
||||
|
||||
<p> As a best practice, publish either "3 0 1" or "3 1 1" TLSA
|
||||
associations that specify the SHA256 digest of the server certificate
|
||||
public key with the alias-expanded hostname of each STARTTLS capable
|
||||
SMTP server. These continue to work when a certificate is renewed
|
||||
with the same public/private key pair. </p>
|
||||
|
||||
</ul>
|
||||
|
||||
<p> For instructions on how to compute the digest of a certificate
|
||||
or its public key for use in TLSA records, see the documentation of
|
||||
the smtpd_tls_fingerprint_digest main.cf parameter. </p>
|
||||
|
||||
<p> When a new key or certificate is generated, an additional TLSA
|
||||
record with the new digest must be published in advance of the
|
||||
actual deployment of the new key or certificate on the server. You
|
||||
must allow sufficient time for any TLSA RRsets with only the old
|
||||
digest to expire from DNS caches. The safest practice is to wait
|
||||
until the DNSSEC signature on the previous TLSA RRset expires, and
|
||||
only then switch the server to use new keys published in the updated
|
||||
TLSA RRset. Once the new certificate trust chain and private key
|
||||
are in effect, the DNS should be updated once again to remove the
|
||||
old digest from the TLSA RRset. </p>
|
||||
|
||||
<p> If you want the Postfix SMTP server to accept remote SMTP client
|
||||
certificates issued by these CAs, append the root certificate to
|
||||
$smtpd_tls_CAfile or install it in the $smtpd_tls_CApath directory. </p>
|
||||
certificates issued by one or more root CAs, append the root
|
||||
certificate to $smtpd_tls_CAfile or install it in the $smtpd_tls_CApath
|
||||
directory. </p>
|
||||
|
||||
<h4> Configuring the server certificate and key files </h4>
|
||||
|
||||
<p> RSA key and certificate examples: </p>
|
||||
|
||||
@ -332,16 +384,15 @@ logging level. </p>
|
||||
<tr> <th> Level </th> <th> Postfix 2.9 and later</th> <th> Earlier
|
||||
releases. </th> </tr>
|
||||
|
||||
<tr> <td valign="top"> 0 </td> <td valign="top"> Log only a summary
|
||||
<tr> <td valign="top"> 0 </td> <td valign="top" colspan="2"> Disable
|
||||
logging of TLS activity. </td> </tr>
|
||||
|
||||
<tr> <td valign="top"> 1 </td> <td valign="top"> 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. </td> <td valign="top"> Disable logging
|
||||
of TLS activity.</td> </tr>
|
||||
|
||||
<tr> <td valign="top"> 1 </td> <td valign="top"> Also log trust-chain
|
||||
verification errors and peer certificate summary information. </td>
|
||||
<td valign="top"> Also log TLS handshake and certificate information.
|
||||
</td> </tr>
|
||||
verification is not required. </td> <td valign="top"> Log the summary
|
||||
message, peer certificate summary information and unconditionally log
|
||||
trust-chain verification errors. </td> </tr>
|
||||
|
||||
<tr> <td valign="top"> 2 </td> <td valign="top" colspan="2"> Also
|
||||
log levels during TLS negotiation. </td> </tr>
|
||||
@ -545,12 +596,24 @@ In order to change this behavior, set
|
||||
|
||||
<h3><a name="server_tls_cache">Server-side TLS session cache</a> </h3>
|
||||
|
||||
<p> The Postfix SMTP server and the remote SMTP client negotiate
|
||||
a session, which takes some computer time and network bandwidth.
|
||||
By default, this session information is cached only in the smtpd(8)
|
||||
process actually using this session and is lost when the process
|
||||
terminates. To share the session information between multiple
|
||||
smtpd(8) processes, a persistent session cache can be used. You
|
||||
<p> The Postfix SMTP server and the remote SMTP client negotiate a
|
||||
session, which takes some computer time and network bandwidth. SSL
|
||||
protocol versions other than SSLv2 support resumption of cached
|
||||
sessions. Not only is this more CPU and bandwidth efficient, it
|
||||
also reduces latency as only one network round-trip is used to
|
||||
resume a session while it takes two round-trips to create a session
|
||||
from scratch. </p>
|
||||
|
||||
<p> Since Postfix uses multiple smtpd(8) service processes, an
|
||||
in-memory cache is not sufficient for session re-use. Clients store
|
||||
at most one cached session per server and are very unlikely to
|
||||
repeatedly connect to the same server process. Thus session caching
|
||||
in the Postfix SMTP server generally requires a shared cache (an
|
||||
alternative available with Postfix ≥ 2.11 is described below).
|
||||
</p>
|
||||
|
||||
<p> To share the session information between multiple
|
||||
smtpd(8) processes, a session cache database is 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
|
||||
@ -558,6 +621,24 @@ 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.</p>
|
||||
|
||||
<p> Starting with Postfix 2.11, linked with a compatible OpenSSL
|
||||
library (at least 0.9.8h, preferably 1.0.0 or later) the Postfix
|
||||
SMTP server supports RFC 5077 TLS session resumption without
|
||||
server-side state when the remote SMTP client also supports RFC
|
||||
5077. The session is encrypted by the server in a <i>session
|
||||
ticket</i> returned to client for storage. When a client sends a
|
||||
valid session ticket, the server decrypts it and resumes the session,
|
||||
provided neither the ticket nor the session have expired. This
|
||||
makes it possible to resume cached sessions without allocating space
|
||||
for a shared database on the server. This feature can be disabled
|
||||
by setting the session cache timeout to zero, otherwise the timeout
|
||||
must be at least 2 minutes and at most 100 days. </p>
|
||||
|
||||
<p> Note, session tickets can only be negotiated if the client
|
||||
disables SSLv2 and does not use the legacy SSLv2 compatible HELLO
|
||||
message. This is true by default with the Postfix ≥ 2.6 SMTP
|
||||
client. </p>
|
||||
|
||||
<p> Example: </p>
|
||||
|
||||
<blockquote>
|
||||
@ -587,9 +668,13 @@ recommends a maximum of 24 hours. </p>
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p> As of Postfix 2.11 this setting cannot exceed 100 days. If set
|
||||
≤ 0, session caching is disabled. If set to a positive value
|
||||
less than 2 minutes, the minimum value of 2 minutes is used instead. </p>
|
||||
|
||||
<p> When the Postfix SMTP server does not save TLS sessions to an
|
||||
external cache database, client-side session caching is unlikely
|
||||
to be useful. To prevent such wastage, the Postfix SMTP server can
|
||||
to be useful. To reduce waste of client resources, the Postfix SMTP server can
|
||||
be configured to not issue TLS session ids. By default the Postfix
|
||||
SMTP server always issues TLS session ids. This works around known
|
||||
interoperability issues with some MUAs, and prevents possible
|
||||
@ -768,8 +853,8 @@ certificates</a> that use <b>only</b> the anonymous ciphers. This is
|
||||
enabled by explicitly setting "smtpd_tls_cert_file = none"
|
||||
and not specifying an smtpd_tls_dcert_file or smtpd_tls_eccert_file. </p>
|
||||
|
||||
<p> Example, MSA that requires TLSv1, not SSLv2 or SSLv3, with high grade
|
||||
ciphers: </p>
|
||||
<p> Example, MSA that requires TLSv1 or higher, not SSLv2 or SSLv3,
|
||||
with high grade ciphers: </p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
@ -779,69 +864,45 @@ ciphers: </p>
|
||||
smtpd_tls_mandatory_ciphers = high
|
||||
smtpd_tls_mandatory_exclude_ciphers = aNULL, MD5
|
||||
smtpd_tls_security_level = encrypt
|
||||
# Preferred form with Postfix ≥ 2.5:
|
||||
# Preferred syntax with Postfix ≥ 2.5:
|
||||
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3
|
||||
# Alternative form.
|
||||
# Legacy syntax:
|
||||
smtpd_tls_mandatory_protocols = TLSv1
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p> If you want to take advantage of ciphers with ephemeral Diffie-Hellman
|
||||
(EDH) key exchange (this offers "forward-secrecy"), DH parameters are
|
||||
needed. Instead of using the built-in DH parameters for both 1024-bit
|
||||
(non-export ciphers) and 512-bit (export ciphers), it is better to
|
||||
generate your own parameters, since otherwise it would "pay" for a
|
||||
possible attacker to start a brute force attack against parameters that
|
||||
are used by everybody. Postfix defaults to compiled-in parameters
|
||||
that are shared by all Postfix users who don't generate their own
|
||||
settings. </p>
|
||||
|
||||
<p> To generate your own set of DH parameters, use: </p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
% <b>openssl gendh -out /etc/postfix/dh_512.pem -2 512</b>
|
||||
% <b>openssl gendh -out /etc/postfix/dh_1024.pem -2 1024</b>
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p> Support for elliptic curve cryptography is available with Postfix
|
||||
2.6 and OpenSSL 1.0.0 or later. To enable ephemeral elliptic curve
|
||||
Diffie-Hellman (EECDH) key-exchange, set "smtpd_tls_eecdh_grade =
|
||||
strong" or "smtpd_tls_eecdh_grade = ultra". The "ultra" setting is
|
||||
substantially more CPU intensive, and "strong" is sufficiently
|
||||
secure for most situations. </p>
|
||||
|
||||
<p> Examples: </p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
/etc/postfix/main.cf:
|
||||
smtpd_tls_dh1024_param_file = /etc/postfix/dh_1024.pem
|
||||
smtpd_tls_dh512_param_file = /etc/postfix/dh_512.pem
|
||||
# Postfix ≥ 2.6:
|
||||
smtpd_tls_eecdh_grade = strong
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p> If you want to take maximal advantage of ciphers that offer <a
|
||||
href="FORWARD_SECRECY_README.html#dfn_fs">forward secrecy</a> see
|
||||
the <a href="FORWARD_SECRECY_README.html#quick-start">Getting
|
||||
started</a> section of <a
|
||||
href="FORWARD_SECRECY_README.html">FORWARD_SECRECY_README</a>. The
|
||||
full document conveniently presents all information about Postfix
|
||||
"perfect" forward secrecy support in one place: what forward secrecy
|
||||
is, how to tweak settings, and what you can expect to see when
|
||||
Postfix uses ciphers with forward secrecy. </p>
|
||||
|
||||
<p> Postfix 2.8 and later, in combination with OpenSSL 0.9.7 and later
|
||||
allows TLS servers to preempt the TLS client's cipher preference list.
|
||||
allows TLS servers to preempt the TLS client's cipher-suite preference list.
|
||||
This is possible only with SSLv3 and later, as in SSLv2 the client
|
||||
chooses the cipher from a list supplied by the server. </p>
|
||||
chooses the cipher-suite from a list supplied by the server. </p>
|
||||
|
||||
<p> By default, the OpenSSL server selects the client's most preferred
|
||||
cipher that the server supports. With SSLv3 and later, the server
|
||||
may choose its own most preferred cipher that is supported (offered)
|
||||
cipher-suite that the server supports. With SSLv3 and later, the server
|
||||
may choose its own most preferred cipher-suite that is supported (offered)
|
||||
by the client. Setting "tls_preempt_cipherlist = yes" enables server
|
||||
cipher preferences. The default OpenSSL behavior applies with
|
||||
cipher-suite preferences. The default OpenSSL behavior applies with
|
||||
"tls_preempt_cipherlist = no". </p>
|
||||
|
||||
<p> While server cipher selection may in some cases lead to a more secure
|
||||
or performant cipher choice, there is some risk of interoperability
|
||||
issues. In the past, some SSL clients have listed lower priority ciphers
|
||||
that they did not implement correctly. If the server chooses a cipher
|
||||
that the client prefers less, it may select a cipher whose client
|
||||
implementation is flawed. </p>
|
||||
<p> While server cipher-suite selection may in some cases lead to
|
||||
a more secure or performant cipher-suite choice, there is some risk
|
||||
of interoperability issues. In the past, some SSL clients have
|
||||
listed lower priority ciphers that they did not implement correctly.
|
||||
If the server chooses a cipher that the client prefers less, it may
|
||||
select a cipher whose client implementation is flawed. Most notably
|
||||
Windows 2003 Microsoft Exchange servers have flawed implementations
|
||||
of DES-CBC3-SHA, which OpenSSL considers stronger than RC4-SHA.
|
||||
Enabling server cipher-suite selection may create interoperability
|
||||
issues with Windows 2003 Microsoft Exchange clients. </p>
|
||||
|
||||
<h3><a name="server_misc"> Miscellaneous server controls</a> </h3>
|
||||
|
||||
@ -872,15 +933,48 @@ an OpenSSL library that could be vulnerable. </p>
|
||||
<pre>
|
||||
/etc/postfix/main.cf:
|
||||
tls_disable_workarounds = 0xFFFFFFFF
|
||||
tls_disable_workarounds = CVE-2010-4180, LEGACY_SERVER_CONNECT
|
||||
tls_disable_workarounds = CVE-2010-4180
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p> Note: Disabling LEGACY_SERVER_CONNECT is not wise at this
|
||||
time, lots of servers are still unpatched and Postfix is <a
|
||||
href="http://www.postfix.org/wip.html#tls-renegotiation">not
|
||||
significantly vulnerable</a> to the renegotiation issue in the TLS
|
||||
protocol. </p>
|
||||
<p> With Postfix ≥ 2.11, the tls_ssl_options parameter specifies
|
||||
a list or bit-mask of OpenSSL options to enable. Specify one or
|
||||
more of the named options below, or a hexadecimal bitmask of options
|
||||
found in the ssl.h file corresponding to the run-time OpenSSL
|
||||
library. While it may be reasonable to turn off all bug workarounds
|
||||
(see above), it is not a good idea to attempt to turn on all features.
|
||||
</p>
|
||||
|
||||
<dl>
|
||||
|
||||
<dt><b>LEGACY_SERVER_CONNECT</b></dt> <dd>See SSL_CTX_set_options(3).</dd>
|
||||
|
||||
<dt><b>NO_TICKET</b></dt> <dd>See SSL_CTX_set_options(3).</dd>
|
||||
|
||||
<dt><b>NO_COMPRESSION</b></dt> <dd>Disable SSL compression even if
|
||||
supported by the OpenSSL library. Compression is CPU-intensive,
|
||||
and compression before encryption does not always improve security. </dd>
|
||||
|
||||
</dl>
|
||||
|
||||
<p> Example: </p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
/etc/postfix/main.cf:
|
||||
tls_ssl_options = no_ticket, no_compression
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p> You should only enable features via the hexadecimal mask when
|
||||
the need to control the feature is critical (to deal with a new
|
||||
vulnerability or a serious interoperability problem). Postfix DOES
|
||||
NOT promise backwards compatible behavior with respect to the mask
|
||||
bits. A feature enabled via the mask in one release may be enabled
|
||||
by other means in a later release, and the mask bit will then be
|
||||
ignored. Therefore, use of the hexadecimal mask is only a temporary
|
||||
measure until a new Postfix or OpenSSL release provides a better
|
||||
solution. </p>
|
||||
|
||||
<h2> <a name="client_tls">SMTP Client specific settings</a> </h2>
|
||||
|
||||
@ -927,6 +1021,10 @@ in more detail in the sections that follow.</p>
|
||||
<dd><a href="#client_tls_may">Opportunistic TLS.</a></dd>
|
||||
<dt><b>encrypt</b></dt>
|
||||
<dd><a href="#client_tls_encrypt">Mandatory TLS encryption.</a>
|
||||
<dt><b>dane</b></dt>
|
||||
<dd><a href="#client_tls_dane">Opportunistic DANE TLS.</a>
|
||||
<dt><b>dane-only</b></dt>
|
||||
<dd><a href="#client_tls_dane">Mandatory DANE TLS.</a>
|
||||
<dt><b>fingerprint</b></dt>
|
||||
<dd><a href="#client_tls_fprint">Certificate fingerprint verification.</a>
|
||||
<dt><b>verify</b></dt>
|
||||
@ -1111,16 +1209,229 @@ just in case the transport table entries are not specified consistently. </p>
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="client_tls_dane">DANE TLS authentication.</a> </h4>
|
||||
|
||||
<p> The Postfix SMTP client supports two TLS security levels based
|
||||
on RFC6698 DANE TLSA records. The opportunistic "dane" level and
|
||||
the mandatory "dane-only" level. </p>
|
||||
|
||||
<p> The "dane" level is a stronger form of <a
|
||||
href="#client_tls_may">opportunistic</a> TLS that is resistant to
|
||||
man in the middle and downgrade attacks when the destination domain
|
||||
uses DNSSEC to publish DANE TLSA records for its MX hosts. If a
|
||||
remote SMTP server has "usable" (see RFC 6698) DANE TLSA records,
|
||||
the server connection will be authenticated. When DANE authentication
|
||||
fails, there is no fallback to unauthenticated or plaintext delivery. </p>
|
||||
|
||||
<p> If TLSA records are published for a given remote SMTP server
|
||||
(implying TLS support), but are all "unusable" due to unsupported
|
||||
parameters or malformed data, the Postfix SMTP client will use <a
|
||||
href="#client_tls_encrypt">mandatory</a> unauthenticated TLS.
|
||||
Otherwise, when no TLSA records are published, the Postfix SMTP
|
||||
client behavior is the same as with <a href="#client_tls_may">may</a>. </p>
|
||||
|
||||
<p> TLSA records must be published in DNSSEC validated DNS zones.
|
||||
Any TLSA records in DNS zones not protected via DNSSEC are ignored.
|
||||
The Postfix SMTP client will not look for TLSA records associated
|
||||
with MX hosts whose "A" or "AAAA" records lie in an "insecure" DNS
|
||||
zone. Such lookups have been observed to cause interoperability
|
||||
issues with poorly implemented DNS servers, and are in any case not
|
||||
expected to ever yield "secure" results, since that would require
|
||||
a very unlikely DLV DNS trust anchor configured between the host
|
||||
record and the associated "_25._tcp" child TLSA record. </p>
|
||||
|
||||
<p> The "dane-only" level is a form of <a
|
||||
href="#client_tls_secure">secure-channel</a> TLS based on the DANE PKI.
|
||||
If "usable" TLSA records are present these are used to authenticate the
|
||||
remote SMTP server. Otherwise, or when server certificate verification
|
||||
fails, delivery via the server in question tempfails. </p>
|
||||
|
||||
<p> At both security levels, the TLS policy for the destination is
|
||||
obtained via TLSA records validated with DNSSEC. For TLSA policy
|
||||
to be in effect, the destination domain's containing DNS zone must
|
||||
be signed and the Postfix SMTP client's operating system must be
|
||||
configured to send its DNS queries to a recursive DNS nameserver
|
||||
that is able to validate the signed records. Each MX host's DNS
|
||||
zone needs to also be signed, and needs to publish DANE TLSA (RFC 6698)
|
||||
records that specify how that MX host's TLS certificate is to be
|
||||
verified. </p>
|
||||
|
||||
<p> TLSA records do not preempt the normal SMTP MX host
|
||||
selection algorithm, if some MX hosts support TLSA and others do
|
||||
not, TLS security will vary from delivery to delivery. It is up
|
||||
to the domain owner to configure their MX hosts and their DNS
|
||||
sensibly. To configure the Postfix SMTP client for DNSSEC lookups
|
||||
see the documentation for the smtp_dns_support_level main.cf
|
||||
parameter. The tls_dane_trust_anchor_digest_enable main.cf parameter
|
||||
controls support for trust-anchor digest TLSA records. The
|
||||
tls_dane_digests and tls_dane_digest_agility parameters control
|
||||
the list of supported digests and digest downgrade attack resistance.
|
||||
</p>
|
||||
|
||||
<p> DANE for SMTP MTAs deviates in some details from the baseline
|
||||
DANE protocol in RFC 6698. Most notably, it is not expected that
|
||||
SMTP MTAs can reasonably include every public CA that a remote SMTP
|
||||
server's administrator may believe to be well-known. Nor is there
|
||||
an interactive user to "click OK" when authentication fails. </p>
|
||||
|
||||
<p> Therefore, certificate usages "0" and "1" from RFC 6698 which
|
||||
are intended to "constrain" existing PKI trust, are not supported.
|
||||
TLSA records with usage "0" are treated as "unusable". TLSA records
|
||||
with usage "1" are instead treated as "trust assertions" and mapped
|
||||
to usage "3". Specifically, with certificate usage "1", Postfix
|
||||
will not require the remote SMTP server's certificate to be trusted
|
||||
with respect to any locally defined public CAs, it is the domain
|
||||
owner's responsibility to ensure that the certificate associations
|
||||
in their TLSA records are appropriate to authenticate their SMTP
|
||||
servers. </p>
|
||||
|
||||
<p> The Postfix SMTP client supports only certificate usages "2"
|
||||
and "3" (with "1" treated as though it were "3"). See
|
||||
tls_dane_trust_anchor_digest_enable for usage "2" usability
|
||||
considerations. Support for certificate usage "1" is an experiment,
|
||||
it may be withdrawn in the future. Server operators SHOULD NOT
|
||||
publish TLSA records with usage "1". </p>
|
||||
|
||||
<p> When usable TLSA records are obtained for the remote SMTP server
|
||||
the Postfix SMTP client sends the SNI TLS extension in its SSL
|
||||
client hello message. This may help the remote SMTP server live
|
||||
up to its promise to provide a certificate that matches its TLSA
|
||||
records. </p>
|
||||
|
||||
<p> For purposes of protocol and cipher selection, the "dane"
|
||||
security level is treated like a "mandatory" TLS security level,
|
||||
and weak ciphers and protocols are disabled. Since DANE authenticates
|
||||
server certificates the "aNULL" cipher-suites are transparently
|
||||
excluded at this level, no need to configure this manually. RFC
|
||||
6698 (DANE) TLS authentication is available with Postfix 2.11 and
|
||||
later. </p>
|
||||
|
||||
<p> When a DANE TLSA record specifies a trust-anchor (TA) certificate
|
||||
(that is an issuing CA), the strategy used to verify the peername
|
||||
of the server certificate is unconditionally "nexthop, hostname".
|
||||
Both the nexthop domain and the hostname obtained from the
|
||||
DNSSEC-validated MX lookup are safe from forgery and the server
|
||||
certificate must contain at least one of these names. </p>
|
||||
|
||||
<p> When a DANE TLSA record specifies an end-entity (EE) certificate,
|
||||
(that is the actual server certificate), as with the fingerprint
|
||||
security level below, no name checks or certificate expiration checks
|
||||
are applied. The server certificate (or its public key) either matches
|
||||
the DANE record or not. Server administrators should publish such
|
||||
EE records in preference to all other types. </p>
|
||||
|
||||
<p> The pre-requisites for DANE support in the Postfix SMTP client are: </p>
|
||||
<ul>
|
||||
<li> A <i>compile-time</i> OpenSSL library that supports the TLS SNI
|
||||
extension and "SHA-2" message digests.
|
||||
<li> A <i>compile-time</i> DNS resolver library that supports DNSSEC.
|
||||
Postfix binaries built on an older system will not support DNSSEC even
|
||||
if deployed on a system with an updated resolver library.
|
||||
<li> The "smtp_dns_support_level" must be set to "dnssec".
|
||||
<li> The "smtp_host_lookup" parameter must include "dns".
|
||||
<li> A DNSSEC-validating recursive resolver (see note below).
|
||||
</ul>
|
||||
<p> The above client pre-requisites do not apply to the Postfix SMTP server.
|
||||
It will support DANE provided it supports TLSv1 and its TLSA records are
|
||||
published in a DNSSEC signed zone. To receive DANE secured mail for multiple
|
||||
domains, use the same hostname to add the server to each domain's MX
|
||||
records. There are no plans to implement SNI in the Postfix SMTP server. </p>
|
||||
|
||||
<p> Note: The Postfix SMTP client's internal stub DNS resolver is
|
||||
DNSSEC-aware, but it does not itself validate DNSSEC records, rather
|
||||
it delegates DNSSEC validation to the operating system's configured
|
||||
recursive DNS nameserver. The Postfix DNS client relies on a secure
|
||||
channel to the resolver's cache for DNSSEC integrity, but does not
|
||||
support TSIG to protect the transmission channel between itself and
|
||||
the nameserver. Therefore, it is strongly recommended (DANE security
|
||||
guarantee void otherwise) that each MTA run a local DNSSEC-validating
|
||||
recursive resolver ("unbound" from nlnetlabs.nl is a reasonable
|
||||
choice) listening on the loopback interface, and that the system
|
||||
be configured to use <i>only</i> this local nameserver. The local
|
||||
nameserver may forward queries to an upstream recursive resolver
|
||||
on another host if desired. </p>
|
||||
|
||||
<p> Note: When the operating system's recursive nameserver is not
|
||||
local, enabling EDNS0 expanded DNS packet sizes and turning on the
|
||||
DNSSEC "DO" bit in the DNS request and/or the new DNSSEC-specific
|
||||
records returned in the nameserver's replies may cause problems
|
||||
with older or buggy firewall and DNS server implementations.
|
||||
Therefore, Postfix does not enable DNSSEC by default. Since MX
|
||||
lookups happen before the security level is determined, DANE support
|
||||
is disabled for all destinations unless you set "smtp_dns_support_level
|
||||
= dnssec". To enable DNSSEC lookups selectively, define a new
|
||||
dedicated transport with a "-o smtp_dns_support_level=dnssec"
|
||||
override in master.cf and route selected domains to that transport.
|
||||
If DNSSEC proves to be sufficiently reliable for these domains, you
|
||||
can enable it for all destinations by changing the global
|
||||
smtp_dns_support_level in main.cf. </p>
|
||||
|
||||
<p><b>Example</b>: "dane" security for selected destinations, with
|
||||
opportunistic TLS by default. This is the recommended configuration
|
||||
for early adopters. <p>
|
||||
<ul>
|
||||
<li> <p> The "example.com" destination uses DANE, but if TLSA records
|
||||
are not present or are unusable, mail is deferred. </p>
|
||||
|
||||
<li> <p> The "example.org" destination uses DANE if possible, but if no TLSA
|
||||
records are found opportunistic TLS is used. </p>
|
||||
</ul>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
main.cf:
|
||||
indexed = ${default_database_type}:${config_directory}/
|
||||
#
|
||||
# default: Opportunistic TLS with no DNSSEC lookups.
|
||||
#
|
||||
smtp_tls_security_level = may
|
||||
smtp_dns_support_level = enabled
|
||||
#
|
||||
# Per-destination TLS policy
|
||||
#
|
||||
smtp_tls_policy_maps = ${indexed}tls_policy
|
||||
#
|
||||
# default_transport = smtp, but some destinations are special:
|
||||
#
|
||||
transport_maps = ${indexed}transport
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
transport:
|
||||
example.com dane
|
||||
example.org dane
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
tls_policy:
|
||||
example.com dane-only
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
master.cf:
|
||||
dane unix - - n - - smtp
|
||||
-o smtp_dns_support_level=dnssec
|
||||
-o smtp_tls_security_level=dane
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="client_tls_fprint"> Certificate fingerprint verification </a> </h4>
|
||||
|
||||
<p> 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 <a href="#client_tls_policy">policy</a>
|
||||
table lists the remote SMTP server certificate fingerprint or
|
||||
public key fingerprint (Postfix 2.9 and later). </p>
|
||||
<p> At the <i>fingerprint</i> security level, no trusted certificate
|
||||
authorities are used or required. The certificate trust chain,
|
||||
expiration date, etc., are not checked. Instead, the
|
||||
smtp_tls_fingerprint_cert_match parameter or the "match" attribute
|
||||
in the <a href="#client_tls_policy">policy</a> table lists the
|
||||
remote SMTP server certificate fingerprint or public key fingerprint.
|
||||
Certificate fingerprint verification is available with Postfix 2.5
|
||||
and later, public-key fingerprint support is available with Postfix
|
||||
2.9 and later. </p>
|
||||
|
||||
<p> If certificate fingerprints are exchanged securely, this is the
|
||||
strongest, and least scalable security level. The administrator needs
|
||||
@ -1217,7 +1528,7 @@ to Postfix 2.9.6 or later. </p>
|
||||
|
||||
<h4><a name="client_tls_verify"> Mandatory server certificate verification </a> </h4>
|
||||
|
||||
<p> At the "verify" TLS security level, messages are sent only over
|
||||
<p> At the <i>verify</i> TLS security level, messages are sent only over
|
||||
TLS encrypted sessions if the remote SMTP server certificate is
|
||||
valid (not
|
||||
expired or revoked, and signed by a trusted certificate authority)
|
||||
@ -1239,6 +1550,19 @@ DNS names are specified, the certificate CommonName is checked.
|
||||
If you want mandatory encryption without server certificate
|
||||
verification, see <a href="#client_tls_encrypt">above</a>. </p>
|
||||
|
||||
<p> With Postfix ≥ 2.11 the "smtp_tls_trust_anchor_file" parameter
|
||||
or more typically the corresponding per-destination "tafile" attribute
|
||||
optionally modifies trust chain verification. If the parameter is
|
||||
not empty the root CAs in CAfile and CApath are no longer trusted.
|
||||
Rather, the Postfix SMTP client will only trust certificate-chains
|
||||
signed by one of the trust-anchors contained in the chosen files.
|
||||
The specified trust-anchor certificates and public keys are not
|
||||
subject to expiration, and need not be (self-signed) root CAs. They
|
||||
may, if desired, be intermediate certificates. Therefore, these
|
||||
certificates also may be found "in the middle" of the trust chain
|
||||
presented by the remote SMTP server, and any untrusted issuing
|
||||
parent certificates will be ignored. </p>
|
||||
|
||||
<p> Despite the potential for eliminating "man-in-the-middle" and other
|
||||
attacks, mandatory certificate trust chain and subject name verification
|
||||
is not viable as a default Internet mail delivery policy. Most MX hosts
|
||||
@ -1300,6 +1624,19 @@ specified, the CommonName is checked. If you want mandatory encryption
|
||||
without server certificate verification, see <a
|
||||
href="#client_tls_encrypt">above</a>. </p>
|
||||
|
||||
<p> With Postfix ≥ 2.11 the "smtp_tls_trust_anchor_file" parameter
|
||||
or more typically the corresponding per-destination "tafile" attribute
|
||||
optionally modifies trust chain verification. If the parameter is
|
||||
not empty the root CAs in CAfile and CApath are no longer trusted.
|
||||
Rather, the Postfix SMTP client will only trust certificate-chains
|
||||
signed by one of the trust-anchors contained in the chosen files.
|
||||
The specified trust-anchor certificates and public keys are not
|
||||
subject to expiration, and need not be (self-signed) root CAs. They
|
||||
may, if desired, be intermediate certificates. Therefore, these
|
||||
certificates also may be found "in the middle" of the trust chain
|
||||
presented by the remote SMTP server, and any untrusted issuing
|
||||
parent certificates will be ignored. </p>
|
||||
|
||||
<p> Despite the potential for eliminating "man-in-the-middle" and other
|
||||
attacks, mandatory secure server certificate verification is not
|
||||
viable as a default Internet mail delivery policy. Most MX hosts
|
||||
@ -1412,16 +1749,15 @@ logging level. </p>
|
||||
<tr> <th> Level </th> <th> Postfix 2.9 and later</th> <th> Earlier
|
||||
releases. </th> </tr>
|
||||
|
||||
<tr> <td valign="top"> 0 </td> <td valign="top"> 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. </td> <td valign="top">
|
||||
Disable logging of TLS activity.</td> </tr>
|
||||
<tr> <td valign="top"> 0 </td> <td valign="top" colspan="2"> Disable
|
||||
logging of TLS activity. </td> </tr>
|
||||
|
||||
<tr> <td valign="top"> 1 </td> <td valign="top"> Also log remote
|
||||
SMTP server trust-chain verification errors and peer certificate
|
||||
summary information. </td> <td valign="top"> Also log TLS handshake
|
||||
and certificate information. </td> </tr>
|
||||
<tr> <td valign="top"> 1 </td> <td valign="top"> 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. </td> <td valign="top"> Log the summary
|
||||
message and unconditionally log trust-chain verification errors.
|
||||
</td> </tr>
|
||||
|
||||
<tr> <td valign="top"> 2 </td> <td valign="top" colspan="2"> Also
|
||||
log levels during TLS negotiation. </td> </tr>
|
||||
@ -1636,6 +1972,10 @@ recommends a maximum of 24 hours. </p>
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p> As of Postfix 2.11 this setting cannot exceed 100 days. If set
|
||||
≤ 0, session caching is disabled. If set to a positive value
|
||||
less than 2 minutes, the minimum value of 2 minutes is used instead. </p>
|
||||
|
||||
<h3><a name="client_tls_limits"> Client TLS limitations </a>
|
||||
</h3>
|
||||
|
||||
@ -1686,14 +2026,22 @@ 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. </p>
|
||||
|
||||
<p> 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
|
||||
<p> 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. </p>
|
||||
|
||||
<p> Adoption of DNSSEC and RFC6698 (DANE) may gradually (as domains
|
||||
implement DNSSEC and publish TLSA records for their MX hosts) address
|
||||
the DNS man-in-the-middle risk and provide scalable key management
|
||||
for SMTP with TLS. Postfix ≥ 2.11 supports the new <a
|
||||
href="#client_tls_dane">dane</a> and <a href="#client_tls_dane">dane-only</a>
|
||||
security levels that take advantage of these standards. </p>
|
||||
|
||||
<p> 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
|
||||
@ -1789,6 +2137,26 @@ main.cf smtp_tls_mandatory_ciphers parameter, and the optional
|
||||
"exclude" attribute (Postfix ≥ 2.6) overrides the main.cf
|
||||
smtp_tls_mandatory_exclude_ciphers parameter. </dd>
|
||||
|
||||
<dt><b>dane</b></dt> <dd><a href="#client_tls_dane">Opportunistic DANE TLS</a>.
|
||||
The TLS policy for the destination is obtained via TLSA records in
|
||||
DNSSEC. If no TLSA records are found, the effective security level
|
||||
used is <a href="#client_tls_may">may</a>. If TLSA records are
|
||||
found, but none are usable, the effective security level is <a
|
||||
href="#client_tls_encrypt">encrypt</a>. When usable TLSA records
|
||||
are obtained for the remote SMTP server, SSLv2 is automatically
|
||||
disabled (see smtp_tls_mandatory_protocols), and the server certificate
|
||||
must match the TLSA records. RFC 6698 (DANE) TLS authentication
|
||||
and DNSSEC support is available with Postfix 2.11 and later. </dd>
|
||||
|
||||
<dt><b>dane-only</b></dt> <dd><a href="#client_tls_dane">Mandatory DANE TLS</a>.
|
||||
The TLS policy for the destination is obtained via TLSA records in
|
||||
DNSSEC. If no TLSA records are found, or none are usable, no
|
||||
connection is made to the server. When usable TLSA records are
|
||||
obtained for the remote SMTP server, SSLv2 is automatically disabled
|
||||
(see smtp_tls_mandatory_protocols), and the server certificate must
|
||||
match the TLSA records. RFC 6698 (DANE) TLS authentication and
|
||||
DNSSEC support is available with Postfix 2.11 and later. </dd>
|
||||
|
||||
<dt><b>fingerprint</b></dt> <dd><a href="#client_tls_fprint">Certificate
|
||||
fingerprint verification.</a> Available with Postfix 2.5 and
|
||||
later. At this security level, there are no trusted certificate
|
||||
@ -1806,12 +2174,16 @@ digits. </dd>
|
||||
|
||||
<dt><b>verify</b></dt> <dd><a href="#client_tls_verify">Mandatory
|
||||
server certificate verification</a>. Mail is delivered only if the
|
||||
TLS handshake
|
||||
succeeds, if the remote SMTP server certificate can be validated (not
|
||||
expired or revoked, and signed by a trusted certificate authority), and
|
||||
if the server certificate name matches the optional "match" attribute (or
|
||||
the main.cf smtp_tls_verify_cert_match parameter value when no optional
|
||||
"match" attribute is specified). </dd>
|
||||
TLS handshake succeeds, if the remote SMTP server certificate can
|
||||
be validated (not expired or revoked, and signed by a trusted
|
||||
certificate authority), and if the server certificate name matches
|
||||
the optional "match" attribute (or the main.cf smtp_tls_verify_cert_match
|
||||
parameter value when no optional "match" attribute is specified).
|
||||
With Postfix ≥ 2.11 the "tafile" attribute optionally modifies
|
||||
trust chain verification in the same manner as the
|
||||
"smtp_tls_trust_anchor_file" parameter. The "tafile" attribute
|
||||
may be specified multiple times to load multiple trust-anchor
|
||||
files. </dd>
|
||||
|
||||
<dt><b>secure</b></dt> <dd><a href="#client_tls_secure">Secure certificate
|
||||
verification.</a> Mail is delivered only if the TLS handshake succeeds,
|
||||
@ -1819,7 +2191,11 @@ if the remote SMTP server certificate can be validated (not expired
|
||||
or revoked, and signed by a trusted certificate authority), and if the
|
||||
server certificate name matches the optional "match" attribute (or the
|
||||
main.cf smtp_tls_secure_cert_match parameter value when no optional
|
||||
"match" attribute is specified). </dd>
|
||||
"match" attribute is specified). With Postfix ≥ 2.11 the "tafile"
|
||||
attribute optionally modifies trust chain verification in the same manner
|
||||
as the "smtp_tls_trust_anchor_file" parameter. The "tafile" attribute
|
||||
may be specified multiple times to load multiple trust-anchor
|
||||
files. </dd>
|
||||
|
||||
</dl>
|
||||
|
||||
@ -1869,9 +2245,8 @@ Example:
|
||||
/etc/postfix/tls_policy:
|
||||
example.edu none
|
||||
example.mil may
|
||||
example.gov encrypt protocols=SSLv3:TLSv1 ciphers=high
|
||||
example.com verify
|
||||
match=hostname:dot-nexthop protocols=SSLv3:TLSv1 ciphers=high
|
||||
example.gov encrypt ciphers=high
|
||||
example.com verify match=hostname:dot-nexthop ciphers=high
|
||||
example.net secure
|
||||
.example.net secure match=.example.net:example.net
|
||||
[mail.example.org]:587 secure match=nexthop
|
||||
@ -1985,7 +2360,7 @@ the SSL/TLS protocols used with opportunistic TLS. </p>
|
||||
smtp_tls_exclude_ciphers = aNULL
|
||||
# Preferred form with Postfix ≥ 2.5:
|
||||
smtp_tls_mandatory_protocols = !SSLv2
|
||||
# Alternative form.
|
||||
# Legacy form for Postfix < 2.5:
|
||||
smtp_tls_mandatory_protocols = SSLv3, TLSv1
|
||||
# Also available with Postfix ≥ 2.6:
|
||||
smtp_tls_ciphers = export
|
||||
@ -2084,6 +2459,64 @@ defers delivery if no alternative server is available. </p>
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p> With Postfix 2.8 and later, the tls_disable_workarounds parameter
|
||||
specifies a list or bit-mask of OpenSSL bug work-arounds to disable. This
|
||||
may be necessary if one of the work-arounds enabled by default in
|
||||
OpenSSL proves to pose a security risk, or introduces an unexpected
|
||||
interoperability issue. Some bug work-arounds known to be problematic
|
||||
are disabled in the default value of the parameter when linked with
|
||||
an OpenSSL library that could be vulnerable. </p>
|
||||
|
||||
<p> Example: </p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
/etc/postfix/main.cf:
|
||||
tls_disable_workarounds = 0xFFFFFFFF
|
||||
tls_disable_workarounds = CVE-2010-4180, LEGACY_SERVER_CONNECT
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p> Note: Disabling LEGACY_SERVER_CONNECT is not wise at this
|
||||
time, lots of servers are still unpatched and Postfix is <a
|
||||
href="http://www.postfix.org/wip.html#tls-renegotiation">not
|
||||
significantly vulnerable</a> to the renegotiation issue in the TLS
|
||||
protocol. </p>
|
||||
|
||||
<p> With Postfix ≥ 2.11, the tls_ssl_options parameter specifies
|
||||
a list or bit-mask of OpenSSL options to enable. Specify one or
|
||||
more of the named options below, or a hexadecimal bitmask of options
|
||||
found in the ssl.h file corresponding to the run-time OpenSSL
|
||||
library. While it may be reasonable to turn off all bug workarounds
|
||||
(see above), it is not a good idea to attempt to turn on all features.
|
||||
</p>
|
||||
|
||||
<p> A future version of OpenSSL may by default no longer allow
|
||||
connections to servers that don't support secure renegotiation.
|
||||
Since the exposure for SMTP is minimal, and some SMTP servers may
|
||||
remain unpatched, you can add LEGACY_SERVER_CONNECT to the
|
||||
options to restore the more permissive default of current OpenSSL
|
||||
releases. </p>
|
||||
|
||||
<p> Example: </p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
/etc/postfix/main.cf:
|
||||
tls_ssl_options = NO_TICKET, NO_COMPRESSION, LEGACY_SERVER_CONNECT
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p> You should only enable features via the hexadecimal mask when
|
||||
the need to control the feature is critical (to deal with a new
|
||||
vulnerability or a serious interoperability problem). Postfix DOES
|
||||
NOT promise backwards compatible behavior with respect to the mask
|
||||
bits. A feature enabled via the mask in one release may be enabled
|
||||
by other means in a later release, and the mask bit will then be
|
||||
ignored. Therefore, use of the hexadecimal mask is only a temporary
|
||||
measure until a new Postfix or OpenSSL release provides a better
|
||||
solution. </p>
|
||||
|
||||
<h2><a name="tlsmgr_controls"> TLS manager specific settings </a> </h2>
|
||||
|
||||
<p> The security of cryptographic software such as TLS depends
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: cleanup.h,v 1.5 2013/01/02 19:18:33 tron Exp $ */
|
||||
/* $NetBSD: cleanup.h,v 1.6 2014/07/06 19:45:50 tron Exp $ */
|
||||
|
||||
/*++
|
||||
/* NAME
|
||||
@ -116,6 +116,7 @@ typedef struct CLEANUP_STATE {
|
||||
VSTRING *milter_err_text; /* milter call-back reply */
|
||||
HBC_CHECKS *milter_hbc_checks; /* Milter header checks */
|
||||
VSTRING *milter_hbc_reply; /* Milter header checks reply */
|
||||
VSTRING *milter_orcpt_buf; /* add_rcpt_par() orcpt */
|
||||
|
||||
/*
|
||||
* Support for Milter body replacement requests.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: dns_lookup.c,v 1.2 2012/07/05 17:40:11 christos Exp $ */
|
||||
/* $NetBSD: dns_lookup.c,v 1.3 2014/07/06 19:45:50 tron Exp $ */
|
||||
|
||||
/*++
|
||||
/* NAME
|
||||
@ -33,6 +33,37 @@
|
||||
/* VSTRING *why;
|
||||
/* int lflags;
|
||||
/* unsigned *ltype;
|
||||
/* AUXILIARY FUNCTIONS
|
||||
/* int dns_lookup_r(name, type, rflags, list, fqdn, why, rcode)
|
||||
/* const char *name;
|
||||
/* unsigned type;
|
||||
/* unsigned rflags;
|
||||
/* DNS_RR **list;
|
||||
/* VSTRING *fqdn;
|
||||
/* VSTRING *why;
|
||||
/* int *rcode;
|
||||
/*
|
||||
/* int dns_lookup_rl(name, rflags, list, fqdn, why, rcode, lflags,
|
||||
/* ltype, ...)
|
||||
/* const char *name;
|
||||
/* unsigned rflags;
|
||||
/* DNS_RR **list;
|
||||
/* VSTRING *fqdn;
|
||||
/* VSTRING *why;
|
||||
/* int *rcode;
|
||||
/* int lflags;
|
||||
/* unsigned ltype;
|
||||
/*
|
||||
/* int dns_lookup_rv(name, rflags, list, fqdn, why, rcode, lflags,
|
||||
/* ltype)
|
||||
/* const char *name;
|
||||
/* unsigned rflags;
|
||||
/* DNS_RR **list;
|
||||
/* VSTRING *fqdn;
|
||||
/* VSTRING *why;
|
||||
/* int *rcode;
|
||||
/* int lflags;
|
||||
/* unsigned *ltype;
|
||||
/* DESCRIPTION
|
||||
/* dns_lookup() looks up DNS resource records. When requested to
|
||||
/* look up data other than type CNAME, it will follow a limited
|
||||
@ -44,6 +75,9 @@
|
||||
/*
|
||||
/* dns_lookup_l() and dns_lookup_v() allow the user to specify
|
||||
/* a list of resource types.
|
||||
/*
|
||||
/* dns_lookup_r(), dns_lookup_rl() and dns_lookup_rv() provide
|
||||
/* additional information.
|
||||
/* INPUTS
|
||||
/* .ad
|
||||
/* .fi
|
||||
@ -62,6 +96,10 @@
|
||||
/* Search local domain and parent domains.
|
||||
/* .IP RES_DEFNAMES
|
||||
/* Append local domain to unqualified names.
|
||||
/* .IP RES_USE_DNSSEC
|
||||
/* Request DNSSEC validation. This flag is silently ignored
|
||||
/* when the system stub resolver API, resolver(3), does not
|
||||
/* implement DNSSEC.
|
||||
/* .RE
|
||||
/* .IP lflags
|
||||
/* Multi-type request control for dns_lookup_l() and dns_lookup_v().
|
||||
@ -93,6 +131,9 @@
|
||||
/* name found for \fIname\fR.
|
||||
/* .IP why
|
||||
/* A null pointer, or storage for the reason for failure.
|
||||
/* .IP rcode
|
||||
/* Pointer to storage for the reply RCODE value. This gives
|
||||
/* more detailed information than DNS_FAIL, DNS_RETRY, etc.
|
||||
/* DIAGNOSTICS
|
||||
/* dns_lookup() returns one of the following codes and sets the
|
||||
/* \fIwhy\fR argument accordingly:
|
||||
@ -159,11 +200,13 @@
|
||||
* Structure to keep track of things while decoding a name server reply.
|
||||
*/
|
||||
#define DEF_DNS_REPLY_SIZE 4096 /* in case we're using TCP */
|
||||
#define MAX_DNS_REPLY_SIZE 32768 /* in case we're using TCP */
|
||||
#define MAX_DNS_REPLY_SIZE 65536 /* in case we're using TCP */
|
||||
|
||||
typedef struct DNS_REPLY {
|
||||
unsigned char *buf; /* raw reply data */
|
||||
size_t buf_len; /* reply buffer length */
|
||||
int rcode; /* unfiltered reply code */
|
||||
int dnssec_ad; /* DNSSEC AD bit */
|
||||
int query_count; /* number of queries */
|
||||
int answer_count; /* number of answers */
|
||||
unsigned char *query_start; /* start of query data */
|
||||
@ -229,11 +272,26 @@ static int dns_query(const char *name, int type, int flags,
|
||||
* Set search options: debugging, parent domain search, append local
|
||||
* domain. Do not allow the user to control other features.
|
||||
*/
|
||||
#define USER_FLAGS (RES_DEBUG | RES_DNSRCH | RES_DEFNAMES)
|
||||
#define USER_FLAGS (RES_DEBUG | RES_DNSRCH | RES_DEFNAMES | RES_USE_DNSSEC)
|
||||
|
||||
if ((flags & USER_FLAGS) != flags)
|
||||
msg_panic("dns_query: bad flags: %d", flags);
|
||||
saved_options = (res.options & USER_FLAGS);
|
||||
|
||||
/*
|
||||
* Set extra options that aren't exposed to the application.
|
||||
*/
|
||||
#define XTRA_FLAGS (RES_USE_EDNS0)
|
||||
|
||||
if (flags & RES_USE_DNSSEC)
|
||||
flags |= RES_USE_EDNS0;
|
||||
|
||||
/*
|
||||
* Save and restore resolver options that we overwrite, to avoid
|
||||
* surprising behavior in other code that also invokes the resolver.
|
||||
*/
|
||||
#define SAVE_FLAGS (USER_FLAGS | XTRA_FLAGS)
|
||||
|
||||
saved_options = (res.options & SAVE_FLAGS);
|
||||
|
||||
/*
|
||||
* Perform the lookup. Claim that the information cannot be found if and
|
||||
@ -245,6 +303,8 @@ static int dns_query(const char *name, int type, int flags,
|
||||
len = res_nsearch(&res, name, C_IN, type, reply->buf, reply->buf_len);
|
||||
res.options &= ~flags;
|
||||
res.options |= saved_options;
|
||||
reply_header = (HEADER *) reply->buf;
|
||||
reply->rcode = reply_header->rcode;
|
||||
if (len < 0) {
|
||||
if (why)
|
||||
vstring_sprintf(why, "Host or domain name not found. "
|
||||
@ -266,7 +326,6 @@ static int dns_query(const char *name, int type, int flags,
|
||||
if (msg_verbose)
|
||||
msg_info("dns_query: %s (%s): OK", name, dns_strtype(type));
|
||||
|
||||
reply_header = (HEADER *) reply->buf;
|
||||
if (reply_header->tc == 0 || reply->buf_len >= MAX_DNS_REPLY_SIZE)
|
||||
break;
|
||||
reply->buf = (unsigned char *)
|
||||
@ -285,8 +344,13 @@ static int dns_query(const char *name, int type, int flags,
|
||||
|
||||
/*
|
||||
* Initialize the reply structure. Some structure members are filled on
|
||||
* the fly while the reply is being parsed.
|
||||
* the fly while the reply is being parsed. Coerce AD bit to boolean.
|
||||
*/
|
||||
#if RES_USE_DNSSEC != 0
|
||||
reply->dnssec_ad = (flags & RES_USE_DNSSEC) ? !!reply_header->ad : 0;
|
||||
#else
|
||||
reply->dnssec_ad = 0;
|
||||
#endif
|
||||
reply->end = reply->buf + len;
|
||||
reply->query_start = reply->buf + sizeof(HEADER);
|
||||
reply->answer_start = 0;
|
||||
@ -387,6 +451,7 @@ static int dns_get_rr(DNS_RR **list, const char *orig_name, DNS_REPLY *reply,
|
||||
DNS_FIXED *fixed)
|
||||
{
|
||||
char temp[DNS_NAME_LEN];
|
||||
char *tempbuf = temp;
|
||||
ssize_t data_len;
|
||||
unsigned pref = 0;
|
||||
unsigned char *src;
|
||||
@ -402,6 +467,7 @@ static int dns_get_rr(DNS_RR **list, const char *orig_name, DNS_REPLY *reply,
|
||||
msg_panic("dns_get_rr: don't know how to extract resource type %s",
|
||||
dns_strtype(fixed->type));
|
||||
case T_CNAME:
|
||||
case T_DNAME:
|
||||
case T_MB:
|
||||
case T_MG:
|
||||
case T_MR:
|
||||
@ -445,6 +511,11 @@ static int dns_get_rr(DNS_RR **list, const char *orig_name, DNS_REPLY *reply,
|
||||
data_len = fixed->length;
|
||||
break;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We impose the same length limit here as for DNS names. However,
|
||||
* see T_TLSA discussion below.
|
||||
*/
|
||||
case T_TXT:
|
||||
data_len = MIN2(pos[0] + 1, MIN2(fixed->length + 1, sizeof(temp)));
|
||||
for (src = pos + 1, dst = (unsigned char *) (temp);
|
||||
@ -454,9 +525,24 @@ static int dns_get_rr(DNS_RR **list, const char *orig_name, DNS_REPLY *reply,
|
||||
}
|
||||
*dst = 0;
|
||||
break;
|
||||
|
||||
/*
|
||||
* For a full certificate, fixed->length may be longer than
|
||||
* sizeof(tmpbuf) == DNS_NAME_LEN. Since we don't need a decode
|
||||
* buffer, just copy the raw data into the rr.
|
||||
*
|
||||
* XXX Reject replies with bogus length < 3.
|
||||
*
|
||||
* XXX What about enforcing a sane upper bound? The RFC 1035 hard
|
||||
* protocol limit is the RRDATA length limit of 65535.
|
||||
*/
|
||||
case T_TLSA:
|
||||
data_len = fixed->length;
|
||||
tempbuf = (char *) pos;
|
||||
break;
|
||||
}
|
||||
*list = dns_rr_create(orig_name, rr_name, fixed->type, fixed->class,
|
||||
fixed->ttl, pref, temp, data_len);
|
||||
fixed->ttl, pref, tempbuf, data_len);
|
||||
return (DNS_OK);
|
||||
}
|
||||
|
||||
@ -477,7 +563,8 @@ static int dns_get_alias(DNS_REPLY *reply, unsigned char *pos,
|
||||
/* dns_get_answer - extract answers from name server reply */
|
||||
|
||||
static int dns_get_answer(const char *orig_name, DNS_REPLY *reply, int type,
|
||||
DNS_RR **rrlist, VSTRING *fqdn, char *cname, int c_len)
|
||||
DNS_RR **rrlist, VSTRING *fqdn, char *cname, int c_len,
|
||||
int *maybe_secure)
|
||||
{
|
||||
char rr_name[DNS_NAME_LEN];
|
||||
unsigned char *pos;
|
||||
@ -553,6 +640,7 @@ static int dns_get_answer(const char *orig_name, DNS_REPLY *reply, int type,
|
||||
if ((status = dns_get_rr(&rr, orig_name, reply, pos, rr_name,
|
||||
&fixed)) == DNS_OK) {
|
||||
resource_found++;
|
||||
rr->dnssec_valid = *maybe_secure ? reply->dnssec_ad : 0;
|
||||
*rrlist = dns_rr_append(*rrlist, rr);
|
||||
} else if (not_found_status != DNS_RETRY)
|
||||
not_found_status = status;
|
||||
@ -563,6 +651,8 @@ static int dns_get_answer(const char *orig_name, DNS_REPLY *reply, int type,
|
||||
if (cname && c_len > 0)
|
||||
if ((status = dns_get_alias(reply, pos, &fixed, cname, c_len)) != DNS_OK)
|
||||
CORRUPT(status);
|
||||
if (!reply->dnssec_ad)
|
||||
*maybe_secure = 0;
|
||||
}
|
||||
pos += fixed.length;
|
||||
}
|
||||
@ -579,16 +669,18 @@ static int dns_get_answer(const char *orig_name, DNS_REPLY *reply, int type,
|
||||
return (not_found_status);
|
||||
}
|
||||
|
||||
/* dns_lookup - DNS lookup user interface */
|
||||
/* dns_lookup_r - DNS lookup user interface */
|
||||
|
||||
int dns_lookup(const char *name, unsigned type, unsigned flags,
|
||||
DNS_RR **rrlist, VSTRING *fqdn, VSTRING *why)
|
||||
int dns_lookup_r(const char *name, unsigned type, unsigned flags,
|
||||
DNS_RR **rrlist, VSTRING *fqdn, VSTRING *why,
|
||||
int *rcode)
|
||||
{
|
||||
char cname[DNS_NAME_LEN];
|
||||
int c_len = sizeof(cname);
|
||||
static DNS_REPLY reply;
|
||||
int count;
|
||||
int status;
|
||||
int maybe_secure = 1; /* Query name presumed secure */
|
||||
const char *orig_name = name;
|
||||
|
||||
/*
|
||||
@ -624,7 +716,10 @@ int dns_lookup(const char *name, unsigned type, unsigned flags,
|
||||
/*
|
||||
* Perform the DNS lookup, and pre-parse the name server reply.
|
||||
*/
|
||||
if ((status = dns_query(name, type, flags, &reply, why)) != DNS_OK)
|
||||
status = dns_query(name, type, flags, &reply, why);
|
||||
if (rcode)
|
||||
*rcode = reply.rcode;
|
||||
if (status != DNS_OK)
|
||||
return (status);
|
||||
|
||||
/*
|
||||
@ -632,7 +727,7 @@ int dns_lookup(const char *name, unsigned type, unsigned flags,
|
||||
* information just in case the requested data is not found.
|
||||
*/
|
||||
status = dns_get_answer(orig_name, &reply, type, rrlist, fqdn,
|
||||
cname, c_len);
|
||||
cname, c_len, &maybe_secure);
|
||||
switch (status) {
|
||||
default:
|
||||
if (why)
|
||||
@ -645,6 +740,16 @@ int dns_lookup(const char *name, unsigned type, unsigned flags,
|
||||
case DNS_RECURSE:
|
||||
if (msg_verbose)
|
||||
msg_info("dns_lookup: %s aliased to %s", name, cname);
|
||||
#if RES_USE_DNSSEC
|
||||
|
||||
/*
|
||||
* Once an intermediate CNAME reply is not validated, all
|
||||
* consequent RRs are deemed not validated, so we don't ask for
|
||||
* further DNSSEC replies.
|
||||
*/
|
||||
if (maybe_secure == 0)
|
||||
flags &= ~RES_USE_DNSSEC;
|
||||
#endif
|
||||
name = cname;
|
||||
}
|
||||
}
|
||||
@ -654,10 +759,11 @@ int dns_lookup(const char *name, unsigned type, unsigned flags,
|
||||
return (DNS_NOTFOUND);
|
||||
}
|
||||
|
||||
/* dns_lookup_l - DNS lookup interface with types list */
|
||||
/* dns_lookup_rl - DNS lookup interface with types list */
|
||||
|
||||
int dns_lookup_l(const char *name, unsigned flags, DNS_RR **rrlist,
|
||||
VSTRING *fqdn, VSTRING *why, int lflags,...)
|
||||
int dns_lookup_rl(const char *name, unsigned flags, DNS_RR **rrlist,
|
||||
VSTRING *fqdn, VSTRING *why, int *rcode,
|
||||
int lflags,...)
|
||||
{
|
||||
va_list ap;
|
||||
unsigned type;
|
||||
@ -673,8 +779,8 @@ int dns_lookup_l(const char *name, unsigned flags, DNS_RR **rrlist,
|
||||
if (msg_verbose)
|
||||
msg_info("lookup %s type %s flags %d",
|
||||
name, dns_strtype(type), flags);
|
||||
status = dns_lookup(name, type, flags, rrlist ? &rr : (DNS_RR **) 0,
|
||||
fqdn, why);
|
||||
status = dns_lookup_r(name, type, flags, rrlist ? &rr : (DNS_RR **) 0,
|
||||
fqdn, why, rcode);
|
||||
if (status == DNS_OK) {
|
||||
non_err = 1;
|
||||
if (rrlist)
|
||||
@ -693,11 +799,11 @@ int dns_lookup_l(const char *name, unsigned flags, DNS_RR **rrlist,
|
||||
return (non_err ? DNS_OK : soft_err ? DNS_RETRY : status);
|
||||
}
|
||||
|
||||
/* dns_lookup_v - DNS lookup interface with types vector */
|
||||
/* dns_lookup_rv - DNS lookup interface with types vector */
|
||||
|
||||
int dns_lookup_v(const char *name, unsigned flags, DNS_RR **rrlist,
|
||||
VSTRING *fqdn, VSTRING *why, int lflags,
|
||||
unsigned *types)
|
||||
int dns_lookup_rv(const char *name, unsigned flags, DNS_RR **rrlist,
|
||||
VSTRING *fqdn, VSTRING *why, int *rcode,
|
||||
int lflags, unsigned *types)
|
||||
{
|
||||
unsigned type;
|
||||
int status = DNS_NOTFOUND;
|
||||
@ -711,8 +817,8 @@ int dns_lookup_v(const char *name, unsigned flags, DNS_RR **rrlist,
|
||||
if (msg_verbose)
|
||||
msg_info("lookup %s type %s flags %d",
|
||||
name, dns_strtype(type), flags);
|
||||
status = dns_lookup(name, type, flags, rrlist ? &rr : (DNS_RR **) 0,
|
||||
fqdn, why);
|
||||
status = dns_lookup_r(name, type, flags, rrlist ? &rr : (DNS_RR **) 0,
|
||||
fqdn, why, rcode);
|
||||
if (status == DNS_OK) {
|
||||
non_err = 1;
|
||||
if (rrlist)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mail_params.h,v 1.11 2013/09/25 19:12:35 tron Exp $ */
|
||||
/* $NetBSD: mail_params.h,v 1.12 2014/07/06 19:45:50 tron Exp $ */
|
||||
|
||||
#ifndef _MAIL_PARAMS_H_INCLUDED_
|
||||
#define _MAIL_PARAMS_H_INCLUDED_
|
||||
@ -208,6 +208,16 @@ extern char *var_fallback_relay;
|
||||
#define DEF_DISABLE_DNS 0
|
||||
extern bool var_disable_dns;
|
||||
|
||||
#define SMTP_DNS_SUPPORT_DISABLED "disabled"
|
||||
#define SMTP_DNS_SUPPORT_ENABLED "enabled"
|
||||
#define SMTP_DNS_SUPPORT_DNSSEC "dnssec"
|
||||
|
||||
#define VAR_SMTP_DNS_SUPPORT "smtp_dns_support_level"
|
||||
#define DEF_SMTP_DNS_SUPPORT ""
|
||||
#define VAR_LMTP_DNS_SUPPORT "lmtp_dns_support_level"
|
||||
#define DEF_LMTP_DNS_SUPPORT ""
|
||||
extern char *var_smtp_dns_support;
|
||||
|
||||
#define SMTP_HOST_LOOKUP_DNS "dns"
|
||||
#define SMTP_HOST_LOOKUP_NATIVE "native"
|
||||
|
||||
@ -627,13 +637,20 @@ extern bool var_exp_own_alias;
|
||||
extern bool var_stat_home_dir;
|
||||
|
||||
/*
|
||||
* Queue manager: maximal size of the duplicate expansion filter. By
|
||||
* Cleanup server: maximal size of the duplicate expansion filter. By
|
||||
* default, we do graceful degradation with huge mailing lists.
|
||||
*/
|
||||
#define VAR_DUP_FILTER_LIMIT "duplicate_filter_limit"
|
||||
#define DEF_DUP_FILTER_LIMIT 1000
|
||||
extern int var_dup_filter_limit;
|
||||
|
||||
/*
|
||||
* Transport Layer Security (TLS) protocol support.
|
||||
*/
|
||||
#define VAR_TLS_MGR_SERVICE "tlsmgr_service_name"
|
||||
#define DEF_TLS_MGR_SERVICE "tlsmgr"
|
||||
extern char *var_tls_mgr_service;
|
||||
|
||||
#define VAR_TLS_APPEND_DEF_CA "tls_append_default_CA"
|
||||
#define DEF_TLS_APPEND_DEF_CA 0 /* Postfix < 2.8 BC break */
|
||||
extern bool var_tls_append_def_CA;
|
||||
@ -949,6 +966,12 @@ extern char *var_bestmx_transp;
|
||||
#define DEF_LMTP_CACHE_CONNT "2s"
|
||||
extern int var_smtp_cache_conn;
|
||||
|
||||
#define VAR_SMTP_REUSE_COUNT "smtp_connection_reuse_count_limit"
|
||||
#define DEF_SMTP_REUSE_COUNT 0
|
||||
#define VAR_LMTP_REUSE_COUNT "lmtp_connection_reuse_count_limit"
|
||||
#define DEF_LMTP_REUSE_COUNT 0
|
||||
extern int var_smtp_reuse_count;
|
||||
|
||||
#define VAR_SMTP_REUSE_TIME "smtp_connection_reuse_time_limit"
|
||||
#define DEF_SMTP_REUSE_TIME "300s"
|
||||
#define VAR_LMTP_REUSE_TIME "lmtp_connection_reuse_time_limit"
|
||||
@ -1306,6 +1329,7 @@ extern bool var_smtpd_tls_received_header;
|
||||
#define DEF_SMTPD_TLS_SCACHE_DB ""
|
||||
extern char *var_smtpd_tls_scache_db;
|
||||
|
||||
#define MAX_SMTPD_TLS_SCACHETIME 8640000
|
||||
#define VAR_SMTPD_TLS_SCACHTIME "smtpd_tls_session_cache_timeout"
|
||||
#define DEF_SMTPD_TLS_SCACHTIME "3600s"
|
||||
extern int var_smtpd_tls_scache_timeout;
|
||||
@ -1432,6 +1456,12 @@ extern char *var_smtp_tls_mand_excl;
|
||||
#define DEF_LMTP_TLS_FPT_DGST "md5"
|
||||
extern char *var_smtp_tls_fpt_dgst;
|
||||
|
||||
#define VAR_SMTP_TLS_TAFILE "smtp_tls_trust_anchor_file"
|
||||
#define DEF_SMTP_TLS_TAFILE ""
|
||||
#define VAR_LMTP_TLS_TAFILE "lmtp_tls_trust_anchor_file"
|
||||
#define DEF_LMTP_TLS_TAFILE ""
|
||||
extern char *var_smtp_tls_tafile;
|
||||
|
||||
#define VAR_SMTP_TLS_LOGLEVEL "smtp_tls_loglevel"
|
||||
#define DEF_SMTP_TLS_LOGLEVEL "0"
|
||||
#define VAR_LMTP_TLS_LOGLEVEL "lmtp_tls_loglevel"
|
||||
@ -1452,8 +1482,10 @@ extern bool var_smtp_tls_note_starttls_offer;
|
||||
extern char *var_smtp_tls_scache_db;
|
||||
extern char *var_lmtp_tls_scache_db;
|
||||
|
||||
#define MAX_SMTP_TLS_SCACHETIME 8640000
|
||||
#define VAR_SMTP_TLS_SCACHTIME "smtp_tls_session_cache_timeout"
|
||||
#define DEF_SMTP_TLS_SCACHTIME "3600s"
|
||||
#define MAX_LMTP_TLS_SCACHETIME 8640000
|
||||
#define VAR_LMTP_TLS_SCACHTIME "lmtp_tls_session_cache_timeout"
|
||||
#define DEF_LMTP_TLS_SCACHTIME "3600s"
|
||||
extern int var_smtp_tls_scache_timeout;
|
||||
@ -1505,6 +1537,12 @@ extern char *var_smtp_tls_fpt_cmatch;
|
||||
#define DEF_LMTP_TLS_BLK_EARLY_MAIL_REPLY 0
|
||||
extern bool var_smtp_tls_blk_early_mail_reply;
|
||||
|
||||
#define VAR_SMTP_TLS_FORCE_TLSA "smtp_tls_force_insecure_host_tlsa_lookup"
|
||||
#define DEF_SMTP_TLS_FORCE_TLSA 0
|
||||
#define VAR_LMTP_TLS_FORCE_TLSA "lmtp_tls_force_insecure_host_tlsa_lookup"
|
||||
#define DEF_LMTP_TLS_FORCE_TLSA 0
|
||||
extern bool var_smtp_tls_force_tlsa;
|
||||
|
||||
/*
|
||||
* SASL authentication support, SMTP server side.
|
||||
*/
|
||||
@ -1524,6 +1562,10 @@ extern char *var_smtpd_sasl_opts;
|
||||
#define DEF_SMTPD_SASL_PATH "smtpd"
|
||||
extern char *var_smtpd_sasl_path;
|
||||
|
||||
#define VAR_SMTPD_SASL_SERVICE "smtpd_sasl_service"
|
||||
#define DEF_SMTPD_SASL_SERVICE "smtp"
|
||||
extern char *var_smtpd_sasl_service;
|
||||
|
||||
#define VAR_CYRUS_CONF_PATH "cyrus_sasl_config_path"
|
||||
#define DEF_CYRUS_CONF_PATH ""
|
||||
extern char *var_cyrus_conf_path;
|
||||
@ -1555,6 +1597,8 @@ extern char *var_smtpd_snd_auth_maps;
|
||||
#define REJECT_SENDER_LOGIN_MISMATCH "reject_sender_login_mismatch"
|
||||
#define REJECT_AUTH_SENDER_LOGIN_MISMATCH \
|
||||
"reject_authenticated_sender_login_mismatch"
|
||||
#define REJECT_KNOWN_SENDER_LOGIN_MISMATCH \
|
||||
"reject_known_sender_login_mismatch"
|
||||
#define REJECT_UNAUTH_SENDER_LOGIN_MISMATCH \
|
||||
"reject_unauthenticated_sender_login_mismatch"
|
||||
|
||||
@ -2146,6 +2190,7 @@ extern int var_map_defer_code;
|
||||
#define CHECK_CLIENT_ACL "check_client_access"
|
||||
#define CHECK_REVERSE_CLIENT_ACL "check_reverse_client_hostname_access"
|
||||
#define CHECK_CCERT_ACL "check_ccert_access"
|
||||
#define CHECK_SASL_ACL "check_sasl_access"
|
||||
#define CHECK_HELO_ACL "check_helo_access"
|
||||
#define CHECK_SENDER_ACL "check_sender_access"
|
||||
#define CHECK_RECIP_ACL "check_recipient_access"
|
||||
@ -2730,6 +2775,13 @@ extern int var_db_create_buf;
|
||||
#define DEF_DB_READ_BUF (128 *1024)
|
||||
extern int var_db_read_buf;
|
||||
|
||||
/*
|
||||
* OpenLDAP LMDB settings.
|
||||
*/
|
||||
#define VAR_LMDB_MAP_SIZE "lmdb_map_size"
|
||||
#define DEF_LMDB_MAP_SIZE (16 * 1024 *1024)
|
||||
extern long var_lmdb_map_size;
|
||||
|
||||
/*
|
||||
* Named queue file attributes.
|
||||
*/
|
||||
@ -3029,6 +3081,10 @@ extern char *var_tls_eecdh_ultra;
|
||||
#define DEF_TLS_PREEMPT_CLIST 0
|
||||
extern bool var_tls_preempt_clist;
|
||||
|
||||
#define VAR_TLS_MULTI_WILDCARD "tls_wildcard_matches_multiple_labels"
|
||||
#define DEF_TLS_MULTI_WILDCARD 1
|
||||
extern bool var_tls_multi_wildcard;
|
||||
|
||||
/* The tweak for CVE-2010-4180 is needed in some versions prior to 1.0.1 */
|
||||
/* The tweak for CVE-2005-2969 is needed in some versions prior to 1.0.0 */
|
||||
#if defined(USE_TLS) && (OPENSSL_VERSION_NUMBER < 0x1000100fL)
|
||||
@ -3045,10 +3101,40 @@ extern bool var_tls_preempt_clist;
|
||||
#define DEF_TLS_BUG_TWEAKS TLS_BUG_TWEAKS
|
||||
extern char *var_tls_bug_tweaks;
|
||||
|
||||
#define VAR_TLS_SSL_OPTIONS "tls_ssl_options"
|
||||
#define DEF_TLS_SSL_OPTIONS ""
|
||||
extern char *var_tls_ssl_options;
|
||||
|
||||
#define VAR_TLS_BC_PKEY_FPRINT "tls_legacy_public_key_fingerprints"
|
||||
#define DEF_TLS_BC_PKEY_FPRINT 0
|
||||
extern bool var_tls_bc_pkey_fprint;
|
||||
|
||||
/*
|
||||
* Ordered list of DANE digest algorithms.
|
||||
*/
|
||||
#define TLS_DANE_AGILITY_OFF "off"
|
||||
#define TLS_DANE_AGILITY_ON "on"
|
||||
#define TLS_DANE_AGILITY_MAYBE "maybe"
|
||||
#define VAR_TLS_DANE_AGILITY "tls_dane_digest_agility"
|
||||
#define DEF_TLS_DANE_AGILITY TLS_DANE_AGILITY_ON
|
||||
extern char *var_tls_dane_agility;
|
||||
|
||||
/*
|
||||
* Ordered list of DANE digest algorithms.
|
||||
*/
|
||||
#define VAR_TLS_DANE_DIGESTS "tls_dane_digests"
|
||||
#define DEF_TLS_DANE_DIGESTS "sha512 sha256"
|
||||
extern char *var_tls_dane_digests;
|
||||
|
||||
/*
|
||||
* External interface for enabling trust-anchor digests, which are risky
|
||||
* when the corresponding certificate is missing from the peer chain (this
|
||||
* can't happen with the leaf certificate).
|
||||
*/
|
||||
#define VAR_TLS_DANE_TAA_DGST "tls_dane_trust_anchor_digest_enable"
|
||||
#define DEF_TLS_DANE_TAA_DGST 1
|
||||
extern bool var_tls_dane_taa_dgst;
|
||||
|
||||
/*
|
||||
* Sendmail-style mail filter support.
|
||||
*/
|
||||
@ -3339,6 +3425,10 @@ extern char *var_psc_dnsbl_sites;
|
||||
#define DEF_PSC_DNSBL_THRESH 1
|
||||
extern int var_psc_dnsbl_thresh;
|
||||
|
||||
#define VAR_PSC_DNSBL_WTHRESH "postscreen_dnsbl_whitelist_threshold"
|
||||
#define DEF_PSC_DNSBL_WTHRESH 0
|
||||
extern int var_psc_dnsbl_wthresh;
|
||||
|
||||
#define VAR_PSC_DNSBL_ENABLE "postscreen_dnsbl_enable"
|
||||
#define DEF_PSC_DNSBL_ENABLE 0
|
||||
extern char *var_psc_dnsbl_enable;
|
||||
@ -3463,8 +3553,10 @@ extern char *var_psc_acl;
|
||||
#define DEF_PSC_WLIST_IF "static:all"
|
||||
extern char *var_psc_wlist_if;
|
||||
|
||||
#define NOPROXY_PROTO_NAME ""
|
||||
|
||||
#define VAR_PSC_UPROXY_PROTO "postscreen_upstream_proxy_protocol"
|
||||
#define DEF_PSC_UPROXY_PROTO ""
|
||||
#define DEF_PSC_UPROXY_PROTO NOPROXY_PROTO_NAME
|
||||
extern char *var_psc_uproxy_proto;
|
||||
|
||||
#define VAR_PSC_UPROXY_TMOUT "postscreen_upstream_proxy_timeout"
|
||||
@ -3594,14 +3686,6 @@ extern char *var_tlsp_tls_loglevel;
|
||||
#define DEF_TLSP_TLS_RECHEAD "$" VAR_SMTPD_TLS_RECHEAD
|
||||
extern bool var_tlsp_tls_received_header;
|
||||
|
||||
#define VAR_TLSP_TLS_SCACHE_DB "tlsproxy_tls_session_cache_database"
|
||||
#define DEF_TLSP_TLS_SCACHE_DB "$" VAR_SMTPD_TLS_SCACHE_DB
|
||||
extern char *var_tlsp_tls_scache_db;
|
||||
|
||||
#define VAR_TLSP_TLS_SCACHTIME "tlsproxy_tls_session_cache_timeout"
|
||||
#define DEF_TLSP_TLS_SCACHTIME "$" VAR_SMTPD_TLS_SCACHTIME
|
||||
extern int var_tlsp_tls_scache_timeout;
|
||||
|
||||
#define VAR_TLSP_TLS_SET_SESSID "tlsproxy_tls_always_issue_session_ids"
|
||||
#define DEF_TLSP_TLS_SET_SESSID "$" VAR_SMTPD_TLS_SET_SESSID
|
||||
extern bool var_tlsp_tls_set_sessid;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: postconf_master.c,v 1.2 2013/11/14 01:39:26 christos Exp $ */
|
||||
/* $NetBSD: postconf_master.c,v 1.3 2014/07/06 19:45:50 tron Exp $ */
|
||||
|
||||
/*++
|
||||
/* NAME
|
||||
@ -8,24 +8,82 @@
|
||||
/* SYNOPSIS
|
||||
/* #include <postconf.h>
|
||||
/*
|
||||
/* const char daemon_options_expecting_value[];
|
||||
/* const char pcf_daemon_options_expecting_value[];
|
||||
/*
|
||||
/* void read_master(fail_on_open)
|
||||
/* void pcf_read_master(fail_on_open)
|
||||
/* int fail_on_open;
|
||||
/*
|
||||
/* void show_master(fp, mode, filters)
|
||||
/* void pcf_show_master_entries(fp, mode, service_filters)
|
||||
/* VSTREAM *fp;
|
||||
/* int mode;
|
||||
/* char **filters;
|
||||
/* DESCRIPTION
|
||||
/* read_master() reads entries from master.cf into memory.
|
||||
/* char **service_filters;
|
||||
/*
|
||||
/* show_master() writes the entries in the master.cf file
|
||||
/* void pcf_show_master_fields(fp, mode, n_filters, field_filters)
|
||||
/* VSTREAM *fp;
|
||||
/* int mode;
|
||||
/* int n_filters;
|
||||
/* char **field_filters;
|
||||
/*
|
||||
/* void pcf_edit_master_field(masterp, field, new_value)
|
||||
/* PCF_MASTER_ENT *masterp;
|
||||
/* int field;
|
||||
/* const char *new_value;
|
||||
/*
|
||||
/* void pcf_show_master_params(fp, mode, argc, **param_filters)
|
||||
/* VSTREAM *fp;
|
||||
/* int mode;
|
||||
/* int argc;
|
||||
/* char **param_filters;
|
||||
/*
|
||||
/* void pcf_edit_master_param(masterp, mode, param_name, param_value)
|
||||
/* PCF_MASTER_ENT *masterp;
|
||||
/* int mode;
|
||||
/* const char *param_name;
|
||||
/* const char *param_value;
|
||||
/* AUXILIARY FUNCTIONS
|
||||
/* const char *pcf_parse_master_entry(masterp, buf)
|
||||
/* PCF_MASTER_ENT *masterp;
|
||||
/* const char *buf;
|
||||
/*
|
||||
/* void pcf_print_master_entry(fp, mode, masterp)
|
||||
/* VSTREAM *fp;
|
||||
/* int mode;
|
||||
/* PCF_MASTER_ENT *masterp;
|
||||
/*
|
||||
/* void pcf_free_master_entry(masterp)
|
||||
/* PCF_MASTER_ENT *masterp;
|
||||
/* DESCRIPTION
|
||||
/* pcf_read_master() reads entries from master.cf into memory.
|
||||
/*
|
||||
/* pcf_show_master_entries() writes the entries in the master.cf
|
||||
/* file to the specified stream.
|
||||
/*
|
||||
/* pcf_show_master_fields() writes name/type/field=value records
|
||||
/* to the specified stream.
|
||||
/*
|
||||
/* daemon_options_expecting_value[] is an array of master.cf
|
||||
/* pcf_edit_master_field() updates the value of a single-column
|
||||
/* or multi-column attribute.
|
||||
/*
|
||||
/* pcf_show_master_params() writes name/type/parameter=value
|
||||
/* records to the specified stream.
|
||||
/*
|
||||
/* pcf_edit_master_param() updates, removes or adds the named
|
||||
/* parameter in a master.cf entry (the remove request ignores
|
||||
/* the parameter value).
|
||||
/*
|
||||
/* pcf_daemon_options_expecting_value[] is an array of master.cf
|
||||
/* daemon command-line options that expect an option value.
|
||||
/*
|
||||
/* pcf_parse_master_entry() parses a (perhaps multi-line)
|
||||
/* string that contains a complete master.cf entry, and
|
||||
/* normalizes daemon command-line options to simplify further
|
||||
/* handling.
|
||||
/*
|
||||
/* pcf_print_master_entry() prints a parsed master.cf entry.
|
||||
/*
|
||||
/* pcf_free_master_entry() returns storage to the heap that
|
||||
/* was allocated by pcf_parse_master_entry().
|
||||
/*
|
||||
/* Arguments
|
||||
/* .IP fail_on_open
|
||||
/* Specify FAIL_ON_OPEN if open failure is a fatal error,
|
||||
@ -33,12 +91,38 @@
|
||||
/* .IP fp
|
||||
/* Output stream.
|
||||
/* .IP mode
|
||||
/* If the FOLD_LINE flag is set, show_master() wraps long
|
||||
/* output lines.
|
||||
/* .IP filters
|
||||
/* A list of zero or more expressions in master_service(3)
|
||||
/* format. If no list is specified, show_master() outputs
|
||||
/* all master.cf entries in the specified order.
|
||||
/* Bit-wise OR of flags. Flags other than the following are
|
||||
/* ignored.
|
||||
/* .RS
|
||||
/* .IP PCF_FOLD_LINE
|
||||
/* Wrap long output lines.
|
||||
/* .IP PCF_SHOW_EVAL
|
||||
/* Expand $name in parameter values.
|
||||
/* .IP PCF_EDIT_EXCL
|
||||
/* Request that pcf_edit_master_param() removes the parameter.
|
||||
/* .RE
|
||||
/* .IP n_filters
|
||||
/* The number of command-line filters.
|
||||
/* .IP field_filters
|
||||
/* A list of zero or more service field patterns (name/type/field).
|
||||
/* The output is formatted as "name/type/field = value". If
|
||||
/* no filters are specified, pcf_show_master_fields() outputs
|
||||
/* the fields of all master.cf entries in the specified order.
|
||||
/* .IP param_filters
|
||||
/* A list of zero or more service parameter patterns
|
||||
/* (name/type/parameter). The output is formatted as
|
||||
/* "name/type/parameter = value". If no filters are specified,
|
||||
/* pcf_show_master_params() outputs the parameters of all
|
||||
/* master.cf entries in sorted order.
|
||||
/* .IP service_filters
|
||||
/* A list of zero or more service patterns (name or name/type).
|
||||
/* If no filters are specified, pcf_show_master_entries()
|
||||
/* outputs all master.cf entries in the specified order.
|
||||
/* .IP field
|
||||
/* Index into parsed master.cf entry.
|
||||
/* .IP new_value
|
||||
/* Replacement value for the specified field. It is split in
|
||||
/* whitespace in case of a multi-field attribute.
|
||||
/* DIAGNOSTICS
|
||||
/* Problems are reported to the standard error stream.
|
||||
/* LICENSE
|
||||
@ -56,6 +140,8 @@
|
||||
|
||||
#include <sys_defs.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/* Utility library. */
|
||||
|
||||
@ -66,23 +152,51 @@
|
||||
#include <vstream.h>
|
||||
#include <readlline.h>
|
||||
#include <stringops.h>
|
||||
#include <split_at.h>
|
||||
|
||||
/* Global library. */
|
||||
|
||||
#include <mail_params.h>
|
||||
#include <match_service.h>
|
||||
|
||||
/* Master library. */
|
||||
|
||||
#include <master_proto.h>
|
||||
|
||||
/* Application-specific. */
|
||||
|
||||
#include <postconf.h>
|
||||
|
||||
const char daemon_options_expecting_value[] = "o";
|
||||
const char pcf_daemon_options_expecting_value[] = "o";
|
||||
|
||||
/*
|
||||
* Data structure to capture a command-line service field filter.
|
||||
*/
|
||||
typedef struct {
|
||||
int match_count; /* hit count */
|
||||
const char *raw_text; /* full pattern text */
|
||||
ARGV *service_pattern; /* parsed service name, type, ... */
|
||||
int field_pattern; /* parsed field pattern */
|
||||
const char *param_pattern; /* parameter pattern */
|
||||
} PCF_MASTER_FLD_REQ;
|
||||
|
||||
/*
|
||||
* Valid inputs.
|
||||
*/
|
||||
static const char *pcf_valid_master_types[] = {
|
||||
MASTER_XPORT_NAME_UNIX,
|
||||
MASTER_XPORT_NAME_FIFO,
|
||||
MASTER_XPORT_NAME_INET,
|
||||
MASTER_XPORT_NAME_PASS,
|
||||
0,
|
||||
};
|
||||
|
||||
static const char pcf_valid_bool_types[] = "yn-";
|
||||
|
||||
#define STR(x) vstring_str(x)
|
||||
|
||||
/* normalize_options - bring options into canonical form */
|
||||
/* pcf_normalize_options - bring options into canonical form */
|
||||
|
||||
static void normalize_options(ARGV *argv)
|
||||
static void pcf_normalize_options(ARGV *argv)
|
||||
{
|
||||
int field;
|
||||
char *arg;
|
||||
@ -92,14 +206,14 @@ static void normalize_options(ARGV *argv)
|
||||
/*
|
||||
* Normalize options to simplify later processing.
|
||||
*/
|
||||
for (field = PC_MASTER_MIN_FIELDS; argv->argv[field] != 0; field++) {
|
||||
for (field = PCF_MASTER_MIN_FIELDS; argv->argv[field] != 0; field++) {
|
||||
arg = argv->argv[field];
|
||||
if (arg[0] != '-' || strcmp(arg, "--") == 0)
|
||||
break;
|
||||
for (cp = arg + 1; *cp; cp++) {
|
||||
if (strchr(daemon_options_expecting_value, *cp) != 0
|
||||
if (strchr(pcf_daemon_options_expecting_value, *cp) != 0
|
||||
&& cp > arg + 1) {
|
||||
/* Split "-stuffo" into "-stuff" and "-o". */
|
||||
/* Split "-stuffozz" into "-stuff" and "-ozz". */
|
||||
junk = concatenate("-", cp, (char *) 0);
|
||||
argv_insert_one(argv, field + 1, junk);
|
||||
myfree(junk);
|
||||
@ -107,7 +221,7 @@ static void normalize_options(ARGV *argv)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (strchr(daemon_options_expecting_value, arg[1]) == 0)
|
||||
if (strchr(pcf_daemon_options_expecting_value, arg[1]) == 0)
|
||||
/* Option requires no value. */
|
||||
continue;
|
||||
if (arg[2] != 0) {
|
||||
@ -122,9 +236,80 @@ static void normalize_options(ARGV *argv)
|
||||
}
|
||||
}
|
||||
|
||||
/* parse_master_line - parse one master line */
|
||||
/* pcf_fix_fatal - fix multiline text before release */
|
||||
|
||||
static const char *parse_master_line(PC_MASTER_ENT *masterp, const char *buf)
|
||||
static NORETURN PRINTFLIKE(1, 2) pcf_fix_fatal(const char *fmt,...)
|
||||
{
|
||||
VSTRING *buf = vstring_alloc(100);
|
||||
va_list ap;
|
||||
|
||||
/*
|
||||
* Replace newline with whitespace.
|
||||
*/
|
||||
va_start(ap, fmt);
|
||||
vstring_vsprintf(buf, fmt, ap);
|
||||
va_end(ap);
|
||||
translit(STR(buf), "\n", " ");
|
||||
msg_fatal("%s", STR(buf));
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* pcf_check_master_entry - sanity check master.cf entry */
|
||||
|
||||
static void pcf_check_master_entry(ARGV *argv, const char *raw_text)
|
||||
{
|
||||
const char **cpp;
|
||||
char *cp;
|
||||
int len;
|
||||
int field;
|
||||
|
||||
cp = argv->argv[PCF_MASTER_FLD_TYPE];
|
||||
for (cpp = pcf_valid_master_types; /* see below */ ; cpp++) {
|
||||
if (*cpp == 0)
|
||||
pcf_fix_fatal("invalid " PCF_MASTER_NAME_TYPE " field \"%s\" in \"%s\"",
|
||||
cp, raw_text);
|
||||
if (strcmp(*cpp, cp) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
for (field = PCF_MASTER_FLD_PRIVATE; field <= PCF_MASTER_FLD_CHROOT; field++) {
|
||||
cp = argv->argv[field];
|
||||
if (cp[1] != 0 || strchr(pcf_valid_bool_types, *cp) == 0)
|
||||
pcf_fix_fatal("invalid %s field \%s\" in \"%s\"",
|
||||
pcf_str_field_pattern(field), cp, raw_text);
|
||||
}
|
||||
|
||||
cp = argv->argv[PCF_MASTER_FLD_WAKEUP];
|
||||
len = strlen(cp);
|
||||
if (len > 0 && cp[len - 1] == '?')
|
||||
len--;
|
||||
if (!(cp[0] == '-' && len == 1) && strspn(cp, "0123456789") != len)
|
||||
pcf_fix_fatal("invalid " PCF_MASTER_NAME_WAKEUP " field \%s\" in \"%s\"",
|
||||
cp, raw_text);
|
||||
|
||||
cp = argv->argv[PCF_MASTER_FLD_MAXPROC];
|
||||
if (strcmp("-", cp) != 0 && cp[strspn(cp, "0123456789")] != 0)
|
||||
pcf_fix_fatal("invalid " PCF_MASTER_NAME_MAXPROC " field \%s\" in \"%s\"",
|
||||
cp, raw_text);
|
||||
}
|
||||
|
||||
/* pcf_free_master_entry - destroy parsed entry */
|
||||
|
||||
void pcf_free_master_entry(PCF_MASTER_ENT *masterp)
|
||||
{
|
||||
/* XX Fixme: allocation/deallocation asymmetry. */
|
||||
myfree(masterp->name_space);
|
||||
argv_free(masterp->argv);
|
||||
if (masterp->valid_names)
|
||||
htable_free(masterp->valid_names, myfree);
|
||||
if (masterp->all_params)
|
||||
dict_free(masterp->all_params);
|
||||
myfree((char *) masterp);
|
||||
}
|
||||
|
||||
/* pcf_parse_master_entry - parse one master line */
|
||||
|
||||
const char *pcf_parse_master_entry(PCF_MASTER_ENT *masterp, const char *buf)
|
||||
{
|
||||
ARGV *argv;
|
||||
|
||||
@ -136,28 +321,29 @@ static const char *parse_master_line(PC_MASTER_ENT *masterp, const char *buf)
|
||||
* The postconf command needs to show default fields as "-", and needs to
|
||||
* know about all service names so that it can generate service-dependent
|
||||
* parameter names (transport-dependent etc.).
|
||||
*
|
||||
* XXX Do per-field sanity checks.
|
||||
*/
|
||||
#define MASTER_BLANKS " \t\r\n" /* XXX */
|
||||
|
||||
argv = argv_split(buf, MASTER_BLANKS);
|
||||
if (argv->argc < PC_MASTER_MIN_FIELDS) {
|
||||
argv_free(argv);
|
||||
argv = argv_split(buf, PCF_MASTER_BLANKS);
|
||||
if (argv->argc < PCF_MASTER_MIN_FIELDS) {
|
||||
argv_free(argv); /* Coverity 201311 */
|
||||
return ("bad field count");
|
||||
}
|
||||
normalize_options(argv);
|
||||
pcf_check_master_entry(argv, buf);
|
||||
pcf_normalize_options(argv);
|
||||
masterp->name_space =
|
||||
concatenate(argv->argv[0], ".", argv->argv[1], (char *) 0);
|
||||
concatenate(argv->argv[0], PCF_NAMESP_SEP_STR, argv->argv[1], (char *) 0);
|
||||
masterp->argv = argv;
|
||||
masterp->valid_names = 0;
|
||||
masterp->all_params = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* read_master - read and digest the master.cf file */
|
||||
/* pcf_read_master - read and digest the master.cf file */
|
||||
|
||||
void read_master(int fail_on_open_error)
|
||||
void pcf_read_master(int fail_on_open_error)
|
||||
{
|
||||
const char *myname = "read_master";
|
||||
const char *myname = "pcf_read_master";
|
||||
char *path;
|
||||
VSTRING *buf;
|
||||
VSTREAM *fp;
|
||||
@ -168,20 +354,20 @@ void read_master(int fail_on_open_error)
|
||||
/*
|
||||
* Sanity check.
|
||||
*/
|
||||
if (master_table != 0)
|
||||
if (pcf_master_table != 0)
|
||||
msg_panic("%s: master table is already initialized", myname);
|
||||
|
||||
/*
|
||||
* Get the location of master.cf.
|
||||
*/
|
||||
if (var_config_dir == 0)
|
||||
set_config_dir();
|
||||
pcf_set_config_dir();
|
||||
path = concatenate(var_config_dir, "/", MASTER_CONF_FILE, (char *) 0);
|
||||
|
||||
/*
|
||||
* Initialize the in-memory master table.
|
||||
*/
|
||||
master_table = (PC_MASTER_ENT *) mymalloc(sizeof(*master_table));
|
||||
pcf_master_table = (PCF_MASTER_ENT *) mymalloc(sizeof(*pcf_master_table));
|
||||
|
||||
/*
|
||||
* Skip blank lines and comment lines. Degrade gracefully if master.cf is
|
||||
@ -194,10 +380,10 @@ void read_master(int fail_on_open_error)
|
||||
} else {
|
||||
buf = vstring_alloc(100);
|
||||
while (readlline(buf, fp, &line_count) != 0) {
|
||||
master_table = (PC_MASTER_ENT *) myrealloc((char *) master_table,
|
||||
(entry_count + 2) * sizeof(*master_table));
|
||||
if ((err = parse_master_line(master_table + entry_count,
|
||||
STR(buf))) != 0)
|
||||
pcf_master_table = (PCF_MASTER_ENT *) myrealloc((char *) pcf_master_table,
|
||||
(entry_count + 2) * sizeof(*pcf_master_table));
|
||||
if ((err = pcf_parse_master_entry(pcf_master_table + entry_count,
|
||||
STR(buf))) != 0)
|
||||
msg_fatal("file %s: line %d: %s", path, line_count, err);
|
||||
entry_count += 1;
|
||||
}
|
||||
@ -208,13 +394,13 @@ void read_master(int fail_on_open_error)
|
||||
/*
|
||||
* Null-terminate the master table and clean up.
|
||||
*/
|
||||
master_table[entry_count].argv = 0;
|
||||
pcf_master_table[entry_count].argv = 0;
|
||||
myfree(path);
|
||||
}
|
||||
|
||||
/* print_master_line - print one master line */
|
||||
/* pcf_print_master_entry - print one master line */
|
||||
|
||||
static void print_master_line(VSTREAM *fp, int mode, PC_MASTER_ENT *masterp)
|
||||
void pcf_print_master_entry(VSTREAM *fp, int mode, PCF_MASTER_ENT *masterp)
|
||||
{
|
||||
char **argv = masterp->argv->argv;
|
||||
const char *arg;
|
||||
@ -243,7 +429,7 @@ static void print_master_line(VSTREAM *fp, int mode, PC_MASTER_ENT *masterp)
|
||||
* Show the standard fields at their preferred column position. Use at
|
||||
* least one-space column separation.
|
||||
*/
|
||||
for (line_len = 0, field = 0; field < PC_MASTER_MIN_FIELDS; field++) {
|
||||
for (line_len = 0, field = 0; field < PCF_MASTER_MIN_FIELDS; field++) {
|
||||
arg = argv[field];
|
||||
if (line_len > 0) {
|
||||
do {
|
||||
@ -270,26 +456,29 @@ static void print_master_line(VSTREAM *fp, int mode, PC_MASTER_ENT *masterp)
|
||||
*/
|
||||
if (arg[0] != '-' || strcmp(arg, "--") == 0) {
|
||||
in_daemon_options = 0;
|
||||
if ((mode & FOLD_LINE)
|
||||
&& line_len > column_goal[PC_MASTER_MIN_FIELDS - 1]) {
|
||||
#if 0
|
||||
if (mode & PCF_FOLD_LINE)
|
||||
/* Force line wrap. */
|
||||
line_len = LINE_LIMIT;
|
||||
}
|
||||
line_len = PCF_LINE_LIMIT;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Special processing for options that require a value.
|
||||
*/
|
||||
else if (strchr(daemon_options_expecting_value, arg[1]) != 0
|
||||
else if (strchr(pcf_daemon_options_expecting_value, arg[1]) != 0
|
||||
&& (aval = argv[field + 1]) != 0) {
|
||||
|
||||
/* Force line wrap before option with value. */
|
||||
line_len = PCF_LINE_LIMIT;
|
||||
|
||||
/*
|
||||
* Optionally, expand $name in parameter value.
|
||||
*/
|
||||
if (strcmp(arg, "-o") == 0
|
||||
&& (mode & SHOW_EVAL) != 0)
|
||||
aval = expand_parameter_value((VSTRING *) 0, mode,
|
||||
aval, masterp);
|
||||
&& (mode & PCF_SHOW_EVAL) != 0)
|
||||
aval = pcf_expand_parameter_value((VSTRING *) 0, mode,
|
||||
aval, masterp);
|
||||
|
||||
/*
|
||||
* Keep option and value on the same line.
|
||||
@ -301,13 +490,13 @@ static void print_master_line(VSTREAM *fp, int mode, PC_MASTER_ENT *masterp)
|
||||
/*
|
||||
* Insert a line break when the next item won't fit.
|
||||
*/
|
||||
if (line_len > INDENT_LEN) {
|
||||
if ((mode & FOLD_LINE) == 0
|
||||
|| line_len + 1 + arg_len < LINE_LIMIT) {
|
||||
if (line_len > PCF_INDENT_LEN) {
|
||||
if ((mode & PCF_FOLD_LINE) == 0
|
||||
|| line_len + 1 + arg_len < PCF_LINE_LIMIT) {
|
||||
ADD_SPACE;
|
||||
} else {
|
||||
vstream_fputs("\n" INDENT_TEXT, fp);
|
||||
line_len = INDENT_LEN;
|
||||
vstream_fputs("\n" PCF_INDENT_TEXT, fp);
|
||||
line_len = PCF_INDENT_LEN;
|
||||
}
|
||||
}
|
||||
ADD_TEXT(arg, strlen(arg));
|
||||
@ -315,36 +504,500 @@ static void print_master_line(VSTREAM *fp, int mode, PC_MASTER_ENT *masterp)
|
||||
ADD_SPACE;
|
||||
ADD_TEXT(aval, strlen(aval));
|
||||
field += 1;
|
||||
|
||||
/* Force line wrap after option with value. */
|
||||
line_len = PCF_LINE_LIMIT;
|
||||
|
||||
}
|
||||
}
|
||||
vstream_fputs("\n", fp);
|
||||
|
||||
if (msg_verbose)
|
||||
vstream_fflush(fp);
|
||||
}
|
||||
|
||||
/* show_master - show master.cf entries */
|
||||
/* pcf_show_master_entries - show master.cf entries */
|
||||
|
||||
void show_master(VSTREAM *fp, int mode, char **filters)
|
||||
void pcf_show_master_entries(VSTREAM *fp, int mode, int argc, char **argv)
|
||||
{
|
||||
PC_MASTER_ENT *masterp;
|
||||
ARGV *service_filter = 0;
|
||||
PCF_MASTER_ENT *masterp;
|
||||
PCF_MASTER_FLD_REQ *field_reqs;
|
||||
PCF_MASTER_FLD_REQ *req;
|
||||
|
||||
/*
|
||||
* Initialize the service filter.
|
||||
* Parse the filter expressions.
|
||||
*/
|
||||
if (filters[0])
|
||||
service_filter = match_service_init_argv(filters);
|
||||
if (argc > 0) {
|
||||
field_reqs = (PCF_MASTER_FLD_REQ *)
|
||||
mymalloc(sizeof(*field_reqs) * argc);
|
||||
for (req = field_reqs; req < field_reqs + argc; req++) {
|
||||
req->match_count = 0;
|
||||
req->raw_text = *argv++;
|
||||
req->service_pattern =
|
||||
pcf_parse_service_pattern(req->raw_text, 1, 2);
|
||||
if (req->service_pattern == 0)
|
||||
msg_fatal("-M option requires service_name[/type]");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate over the master table.
|
||||
*/
|
||||
for (masterp = master_table; masterp->argv != 0; masterp++)
|
||||
if ((service_filter == 0
|
||||
|| match_service_match(service_filter, masterp->name_space))
|
||||
&& ((mode & SHOW_NONDEF) == 0 || masterp->all_params != 0))
|
||||
print_master_line(fp, mode, masterp);
|
||||
for (masterp = pcf_master_table; masterp->argv != 0; masterp++) {
|
||||
if (argc > 0) {
|
||||
for (req = field_reqs; req < field_reqs + argc; req++) {
|
||||
if (PCF_MATCH_SERVICE_PATTERN(req->service_pattern,
|
||||
masterp->argv->argv[0],
|
||||
masterp->argv->argv[1])) {
|
||||
req->match_count++;
|
||||
pcf_print_master_entry(fp, mode, masterp);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pcf_print_master_entry(fp, mode, masterp);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Cleanup.
|
||||
*/
|
||||
if (service_filter != 0)
|
||||
argv_free(service_filter);
|
||||
if (argc > 0) {
|
||||
for (req = field_reqs; req < field_reqs + argc; req++) {
|
||||
if (req->match_count == 0)
|
||||
msg_warn("unmatched request: \"%s\"", req->raw_text);
|
||||
argv_free(req->service_pattern);
|
||||
}
|
||||
myfree((char *) field_reqs);
|
||||
}
|
||||
}
|
||||
|
||||
/* pcf_print_master_field - scaffolding */
|
||||
|
||||
static void pcf_print_master_field(VSTREAM *fp, int mode,
|
||||
PCF_MASTER_ENT *masterp,
|
||||
int field)
|
||||
{
|
||||
char **argv = masterp->argv->argv;
|
||||
const char *arg;
|
||||
const char *aval;
|
||||
int arg_len;
|
||||
int line_len;
|
||||
int in_daemon_options;
|
||||
|
||||
/*
|
||||
* Show the field value, or the first value in the case of a multi-column
|
||||
* field.
|
||||
*/
|
||||
#define ADD_CHAR(ch) ADD_TEXT((ch), 1)
|
||||
|
||||
line_len = 0;
|
||||
if ((mode & PCF_HIDE_NAME) == 0) {
|
||||
ADD_TEXT(argv[0], strlen(argv[0]));
|
||||
ADD_CHAR(PCF_NAMESP_SEP_STR);
|
||||
ADD_TEXT(argv[1], strlen(argv[1]));
|
||||
ADD_CHAR(PCF_NAMESP_SEP_STR);
|
||||
ADD_TEXT(pcf_str_field_pattern(field), strlen(pcf_str_field_pattern(field)));
|
||||
ADD_TEXT(" = ", 3);
|
||||
if (line_len + strlen(argv[field]) > PCF_LINE_LIMIT) {
|
||||
vstream_fputs("\n" PCF_INDENT_TEXT, fp);
|
||||
line_len = PCF_INDENT_LEN;
|
||||
}
|
||||
}
|
||||
ADD_TEXT(argv[field], strlen(argv[field]));
|
||||
|
||||
/*
|
||||
* Format the daemon command-line options and non-option arguments. Here,
|
||||
* we have no data-dependent preference for column positions, but we do
|
||||
* have argument grouping preferences.
|
||||
*/
|
||||
if (field == PCF_MASTER_FLD_CMD) {
|
||||
in_daemon_options = 1;
|
||||
for (field += 1; (arg = argv[field]) != 0; field++) {
|
||||
arg_len = strlen(arg);
|
||||
aval = 0;
|
||||
if (in_daemon_options) {
|
||||
|
||||
/*
|
||||
* We make no special case for generic options (-v -D)
|
||||
* options.
|
||||
*/
|
||||
if (arg[0] != '-' || strcmp(arg, "--") == 0) {
|
||||
in_daemon_options = 0;
|
||||
} else if (strchr(pcf_daemon_options_expecting_value, arg[1]) != 0
|
||||
&& (aval = argv[field + 1]) != 0) {
|
||||
|
||||
/* Force line break before option with value. */
|
||||
line_len = PCF_LINE_LIMIT;
|
||||
|
||||
/*
|
||||
* Optionally, expand $name in parameter value.
|
||||
*/
|
||||
if (strcmp(arg, "-o") == 0
|
||||
&& (mode & PCF_SHOW_EVAL) != 0)
|
||||
aval = pcf_expand_parameter_value((VSTRING *) 0, mode,
|
||||
aval, masterp);
|
||||
|
||||
/*
|
||||
* Keep option and value on the same line.
|
||||
*/
|
||||
arg_len += strlen(aval) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert a line break when the next item won't fit.
|
||||
*/
|
||||
if (line_len > PCF_INDENT_LEN) {
|
||||
if ((mode & PCF_FOLD_LINE) == 0
|
||||
|| line_len + 1 + arg_len < PCF_LINE_LIMIT) {
|
||||
ADD_SPACE;
|
||||
} else {
|
||||
vstream_fputs("\n" PCF_INDENT_TEXT, fp);
|
||||
line_len = PCF_INDENT_LEN;
|
||||
}
|
||||
}
|
||||
ADD_TEXT(arg, strlen(arg));
|
||||
if (aval) {
|
||||
ADD_SPACE;
|
||||
ADD_TEXT(aval, strlen(aval));
|
||||
field += 1;
|
||||
|
||||
/* Force line break after option with value. */
|
||||
line_len = PCF_LINE_LIMIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
vstream_fputs("\n", fp);
|
||||
|
||||
if (msg_verbose)
|
||||
vstream_fflush(fp);
|
||||
}
|
||||
|
||||
/* pcf_show_master_fields - show master.cf fields */
|
||||
|
||||
void pcf_show_master_fields(VSTREAM *fp, int mode, int argc, char **argv)
|
||||
{
|
||||
const char *myname = "pcf_show_master_fields";
|
||||
PCF_MASTER_ENT *masterp;
|
||||
PCF_MASTER_FLD_REQ *field_reqs;
|
||||
PCF_MASTER_FLD_REQ *req;
|
||||
int field;
|
||||
|
||||
/*
|
||||
* Parse the filter expressions.
|
||||
*/
|
||||
if (argc > 0) {
|
||||
field_reqs = (PCF_MASTER_FLD_REQ *)
|
||||
mymalloc(sizeof(*field_reqs) * argc);
|
||||
for (req = field_reqs; req < field_reqs + argc; req++) {
|
||||
req->match_count = 0;
|
||||
req->raw_text = *argv++;
|
||||
req->service_pattern =
|
||||
pcf_parse_service_pattern(req->raw_text, 1, 3);
|
||||
if (req->service_pattern == 0)
|
||||
msg_fatal("-F option requires service_name[/type[/field]]");
|
||||
field = req->field_pattern =
|
||||
pcf_parse_field_pattern(req->service_pattern->argv[2]);
|
||||
if (pcf_is_magic_field_pattern(field) == 0
|
||||
&& (field < 0 || field > PCF_MASTER_FLD_CMD))
|
||||
msg_panic("%s: bad attribute field index: %d",
|
||||
myname, field);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate over the master table.
|
||||
*/
|
||||
for (masterp = pcf_master_table; masterp->argv != 0; masterp++) {
|
||||
if (argc > 0) {
|
||||
for (req = field_reqs; req < field_reqs + argc; req++) {
|
||||
if (PCF_MATCH_SERVICE_PATTERN(req->service_pattern,
|
||||
masterp->argv->argv[0],
|
||||
masterp->argv->argv[1])) {
|
||||
req->match_count++;
|
||||
field = req->field_pattern;
|
||||
if (pcf_is_magic_field_pattern(field)) {
|
||||
for (field = 0; field <= PCF_MASTER_FLD_CMD; field++)
|
||||
pcf_print_master_field(fp, mode, masterp, field);
|
||||
} else {
|
||||
pcf_print_master_field(fp, mode, masterp, field);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (field = 0; field <= PCF_MASTER_FLD_CMD; field++)
|
||||
pcf_print_master_field(fp, mode, masterp, field);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Cleanup.
|
||||
*/
|
||||
if (argc > 0) {
|
||||
for (req = field_reqs; req < field_reqs + argc; req++) {
|
||||
if (req->match_count == 0)
|
||||
msg_warn("unmatched request: \"%s\"", req->raw_text);
|
||||
argv_free(req->service_pattern);
|
||||
}
|
||||
myfree((char *) field_reqs);
|
||||
}
|
||||
}
|
||||
|
||||
/* pcf_edit_master_field - replace master.cf field value. */
|
||||
|
||||
void pcf_edit_master_field(PCF_MASTER_ENT *masterp, int field,
|
||||
const char *new_value)
|
||||
{
|
||||
|
||||
/*
|
||||
* Replace multi-column attribute.
|
||||
*/
|
||||
if (field == PCF_MASTER_FLD_CMD) {
|
||||
argv_truncate(masterp->argv, PCF_MASTER_FLD_CMD);
|
||||
argv_split_append(masterp->argv, new_value, PCF_MASTER_BLANKS);
|
||||
}
|
||||
|
||||
/*
|
||||
* Replace single-column attribute.
|
||||
*/
|
||||
else {
|
||||
argv_replace_one(masterp->argv, field, new_value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do per-field sanity checks.
|
||||
*/
|
||||
pcf_check_master_entry(masterp->argv, new_value);
|
||||
}
|
||||
|
||||
/* pcf_print_master_param - scaffolding */
|
||||
|
||||
static void pcf_print_master_param(VSTREAM *fp, int mode,
|
||||
PCF_MASTER_ENT *masterp,
|
||||
const char *param_name,
|
||||
const char *param_value)
|
||||
{
|
||||
if ((mode & PCF_SHOW_EVAL) != 0)
|
||||
param_value = pcf_expand_parameter_value((VSTRING *) 0, mode,
|
||||
param_value, masterp);
|
||||
if ((mode & PCF_HIDE_NAME) == 0) {
|
||||
pcf_print_line(fp, mode, "%s%c%s = %s\n",
|
||||
masterp->name_space, PCF_NAMESP_SEP_CH,
|
||||
param_name, param_value);
|
||||
} else {
|
||||
pcf_print_line(fp, mode, "%s\n", param_value);
|
||||
}
|
||||
if (msg_verbose)
|
||||
vstream_fflush(fp);
|
||||
}
|
||||
|
||||
/* pcf_sort_argv_cb - sort argv call-back */
|
||||
|
||||
static int pcf_sort_argv_cb(const void *a, const void *b)
|
||||
{
|
||||
return (strcmp(*(char **) a, *(char **) b));
|
||||
}
|
||||
|
||||
/* pcf_show_master_any_param - show any parameter in master.cf service entry */
|
||||
|
||||
static void pcf_show_master_any_param(VSTREAM *fp, int mode,
|
||||
PCF_MASTER_ENT *masterp)
|
||||
{
|
||||
const char *myname = "pcf_show_master_any_param";
|
||||
ARGV *argv = argv_alloc(10);
|
||||
DICT *dict = masterp->all_params;
|
||||
const char *param_name;
|
||||
const char *param_value;
|
||||
int param_count = 0;
|
||||
int how;
|
||||
char **cpp;
|
||||
|
||||
/*
|
||||
* Print parameters in sorted order. The number of parameters per
|
||||
* master.cf entry is small, so we optmiize for code simplicity and don't
|
||||
* worry about the cost of double lookup.
|
||||
*/
|
||||
|
||||
/* Look up the parameter names and ignore the values. */
|
||||
|
||||
for (how = DICT_SEQ_FUN_FIRST;
|
||||
dict->sequence(dict, how, ¶m_name, ¶m_value) == 0;
|
||||
how = DICT_SEQ_FUN_NEXT) {
|
||||
argv_add(argv, param_name, ARGV_END);
|
||||
param_count++;
|
||||
}
|
||||
|
||||
/* Print the parameters in sorted order. */
|
||||
|
||||
qsort(argv->argv, param_count, sizeof(argv->argv[0]), pcf_sort_argv_cb);
|
||||
for (cpp = argv->argv; (param_name = *cpp) != 0; cpp++) {
|
||||
if ((param_value = dict_get(dict, param_name)) == 0)
|
||||
msg_panic("%s: parameter name not found: %s", myname, param_name);
|
||||
pcf_print_master_param(fp, mode, masterp, param_name, param_value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up.
|
||||
*/
|
||||
argv_free(argv);
|
||||
}
|
||||
|
||||
/* pcf_show_master_params - show master.cf params */
|
||||
|
||||
void pcf_show_master_params(VSTREAM *fp, int mode, int argc, char **argv)
|
||||
{
|
||||
PCF_MASTER_ENT *masterp;
|
||||
PCF_MASTER_FLD_REQ *field_reqs;
|
||||
PCF_MASTER_FLD_REQ *req;
|
||||
DICT *dict;
|
||||
const char *param_value;
|
||||
|
||||
/*
|
||||
* Parse the filter expressions.
|
||||
*/
|
||||
if (argc > 0) {
|
||||
field_reqs = (PCF_MASTER_FLD_REQ *)
|
||||
mymalloc(sizeof(*field_reqs) * argc);
|
||||
for (req = field_reqs; req < field_reqs + argc; req++) {
|
||||
req->match_count = 0;
|
||||
req->raw_text = *argv++;
|
||||
req->service_pattern =
|
||||
pcf_parse_service_pattern(req->raw_text, 1, 3);
|
||||
if (req->service_pattern == 0)
|
||||
msg_fatal("-P option requires service_name[/type[/parameter]]");
|
||||
req->param_pattern = req->service_pattern->argv[2];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate over the master table.
|
||||
*/
|
||||
for (masterp = pcf_master_table; masterp->argv != 0; masterp++) {
|
||||
if ((dict = masterp->all_params) != 0) {
|
||||
if (argc > 0) {
|
||||
for (req = field_reqs; req < field_reqs + argc; req++) {
|
||||
if (PCF_MATCH_SERVICE_PATTERN(req->service_pattern,
|
||||
masterp->argv->argv[0],
|
||||
masterp->argv->argv[1])) {
|
||||
if (PCF_IS_MAGIC_PARAM_PATTERN(req->param_pattern)) {
|
||||
pcf_show_master_any_param(fp, mode, masterp);
|
||||
req->match_count += 1;
|
||||
} else if ((param_value = dict_get(dict,
|
||||
req->param_pattern)) != 0) {
|
||||
pcf_print_master_param(fp, mode, masterp,
|
||||
req->param_pattern,
|
||||
param_value);
|
||||
req->match_count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pcf_show_master_any_param(fp, mode, masterp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Cleanup.
|
||||
*/
|
||||
if (argc > 0) {
|
||||
for (req = field_reqs; req < field_reqs + argc; req++) {
|
||||
if (req->match_count == 0)
|
||||
msg_warn("unmatched request: \"%s\"", req->raw_text);
|
||||
argv_free(req->service_pattern);
|
||||
}
|
||||
myfree((char *) field_reqs);
|
||||
}
|
||||
}
|
||||
|
||||
/* pcf_edit_master_param - update, add or remove -o parameter=value */
|
||||
|
||||
void pcf_edit_master_param(PCF_MASTER_ENT *masterp, int mode,
|
||||
const char *param_name,
|
||||
const char *param_value)
|
||||
{
|
||||
const char *myname = "pcf_edit_master_param";
|
||||
ARGV *argv = masterp->argv;
|
||||
const char *arg;
|
||||
const char *aval;
|
||||
int param_match = 0;
|
||||
int name_len = strlen(param_name);
|
||||
int field;
|
||||
|
||||
for (field = PCF_MASTER_MIN_FIELDS; argv->argv[field] != 0; field++) {
|
||||
arg = argv->argv[field];
|
||||
|
||||
/*
|
||||
* Stop at the first non-option argument or end-of-list.
|
||||
*/
|
||||
if (arg[0] != '-' || strcmp(arg, "--") == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Zoom in on command-line options with a value.
|
||||
*/
|
||||
else if (strchr(pcf_daemon_options_expecting_value, arg[1]) != 0
|
||||
&& (aval = argv->argv[field + 1]) != 0) {
|
||||
|
||||
/*
|
||||
* Zoom in on "-o parameter=value".
|
||||
*/
|
||||
if (strcmp(arg, "-o") == 0) {
|
||||
if (strncmp(aval, param_name, name_len) == 0
|
||||
&& aval[name_len] == '=') {
|
||||
param_match = 1;
|
||||
switch (mode & (PCF_EDIT_CONF | PCF_EDIT_EXCL)) {
|
||||
|
||||
/*
|
||||
* Update parameter=value.
|
||||
*/
|
||||
case PCF_EDIT_CONF:
|
||||
aval = concatenate(param_name, "=",
|
||||
param_value, (char *) 0);
|
||||
argv_replace_one(argv, field + 1, aval);
|
||||
myfree((char *) aval);
|
||||
if (masterp->all_params)
|
||||
dict_put(masterp->all_params, param_name, param_value);
|
||||
/* XXX Update parameter "used/defined" status. */
|
||||
break;
|
||||
|
||||
/*
|
||||
* Delete parameter=value.
|
||||
*/
|
||||
case PCF_EDIT_EXCL:
|
||||
argv_delete(argv, field, 2);
|
||||
if (masterp->all_params)
|
||||
dict_del(masterp->all_params, param_name);
|
||||
/* XXX Update parameter "used/defined" status. */
|
||||
field -= 2;
|
||||
break;
|
||||
default:
|
||||
msg_panic("%s: unexpected mode: %d", myname, mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip over the command-line option value.
|
||||
*/
|
||||
field += 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Add unmatched parameter.
|
||||
*/
|
||||
if ((mode & PCF_EDIT_CONF) && param_match == 0) {
|
||||
/* XXX Generalize: argv_insert(argv, where, list...) */
|
||||
argv_insert_one(argv, field, "-o");
|
||||
aval = concatenate(param_name, "=",
|
||||
param_value, (char *) 0);
|
||||
argv_insert_one(argv, field + 1, aval);
|
||||
if (masterp->all_params)
|
||||
dict_put(masterp->all_params, param_name, param_value);
|
||||
/* XXX May affect parameter "used/defined" status. */
|
||||
myfree((char *) aval);
|
||||
param_match = 1;
|
||||
}
|
||||
}
|
||||
|
119
external/ibm-public/postfix/dist/src/smtp/smtp.c
vendored
119
external/ibm-public/postfix/dist/src/smtp/smtp.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: smtp.c,v 1.7 2013/09/25 19:12:35 tron Exp $ */
|
||||
/* $NetBSD: smtp.c,v 1.8 2014/07/06 19:45:50 tron Exp $ */
|
||||
|
||||
/*++
|
||||
/* NAME
|
||||
@ -63,7 +63,7 @@
|
||||
/* \fIpathname\fR. If the process runs chrooted, an absolute pathname
|
||||
/* is interpreted relative to the Postfix queue directory.
|
||||
/* .IP \fBinet\fR:\fIhostname\fR
|
||||
/* .IP \fBinet\fB:\fIhostname\fR:\fIport\fR
|
||||
/* .IP \fBinet\fR:\fIhostname\fR:\fIport\fR
|
||||
/* .IP \fBinet\fR:[\fIaddress\fR]
|
||||
/* .IP \fBinet\fR:[\fIaddress\fR]:\fIport\fR
|
||||
/* Connect to the specified TCP port on the specified local or
|
||||
@ -171,9 +171,7 @@
|
||||
/* A mechanism to transform replies from remote SMTP servers one
|
||||
/* line at a time.
|
||||
/* .IP "\fBsmtp_skip_5xx_greeting (yes)\fR"
|
||||
/* Skip remote SMTP servers that greet with a 5XX status code (go away,
|
||||
/* do
|
||||
/* not try again later).
|
||||
/* Skip remote SMTP servers that greet with a 5XX status code.
|
||||
/* .IP "\fBsmtp_skip_quit_response (yes)\fR"
|
||||
/* Do not wait for the response to the SMTP QUIT command.
|
||||
/* .PP
|
||||
@ -251,6 +249,10 @@
|
||||
/* .IP "\fBsmtp_send_dummy_mail_auth (no)\fR"
|
||||
/* Whether or not to append the "AUTH=<>" option to the MAIL
|
||||
/* FROM command in SASL-authenticated SMTP sessions.
|
||||
/* .PP
|
||||
/* Available in Postfix version 2.11 and later:
|
||||
/* .IP "\fBsmtp_dns_support_level (empty)\fR"
|
||||
/* Level of DNS support in the Postfix SMTP client.
|
||||
/* MIME PROCESSING CONTROLS
|
||||
/* .ad
|
||||
/* .fi
|
||||
@ -378,8 +380,7 @@
|
||||
/* The verification depth for remote SMTP server certificates.
|
||||
/* .IP "\fBsmtp_tls_secure_cert_match (nexthop, dot-nexthop)\fR"
|
||||
/* How the Postfix SMTP client verifies the server certificate
|
||||
/* peername for the
|
||||
/* "secure" TLS security level.
|
||||
/* 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
|
||||
/* TLS session cache.
|
||||
@ -442,6 +443,18 @@
|
||||
/* Available in Postfix version 2.8 and later:
|
||||
/* .IP "\fBtls_disable_workarounds (see 'postconf -d' output)\fR"
|
||||
/* List or bit-mask of OpenSSL bug work-arounds to disable.
|
||||
/* .PP
|
||||
/* Available in Postfix version 2.11 and later:
|
||||
/* .IP "\fBsmtp_tls_trust_anchor_file (empty)\fR"
|
||||
/* Zero or more PEM-format files with trust-anchor certificates
|
||||
/* and/or public keys.
|
||||
/* .IP "\fBsmtp_tls_force_insecure_host_tlsa_lookup (no)\fR"
|
||||
/* Lookup the associated DANE TLSA RRset even when a hostname is
|
||||
/* not an alias and its address records lie in an unsigned zone.
|
||||
/* .IP "\fBtls_dane_trust_anchor_digest_enable (yes)\fR"
|
||||
/* RFC 6698 trust-anchor digest support in the Postfix TLS library.
|
||||
/* .IP "\fBtlsmgr_service_name (tlsmgr)\fR"
|
||||
/* The name of the \fBtlsmgr\fR(8) service entry in master.cf.
|
||||
/* OBSOLETE STARTTLS CONTROLS
|
||||
/* .ad
|
||||
/* .fi
|
||||
@ -547,6 +560,12 @@
|
||||
/* time limit per read or write system call, to a time limit to send
|
||||
/* or receive a complete record (an SMTP command line, SMTP response
|
||||
/* line, SMTP message content line, or TLS protocol message).
|
||||
/* .PP
|
||||
/* Available in Postfix version 2.11 and later:
|
||||
/* .IP "\fBsmtp_connection_reuse_count_limit (0)\fR"
|
||||
/* When SMTP connection caching is enabled, the number of times
|
||||
/* that an SMTP session may be reused before it is closed, or zero (no
|
||||
/* limit).
|
||||
/* TROUBLE SHOOTING CONTROLS
|
||||
/* .ad
|
||||
/* .fi
|
||||
@ -628,8 +647,8 @@
|
||||
/* .IP "\fBlmtp_lhlo_name ($myhostname)\fR"
|
||||
/* The hostname to send in the LMTP LHLO command.
|
||||
/* .IP "\fBsmtp_host_lookup (dns)\fR"
|
||||
/* What mechanisms the Postfix SMTP client uses to look up a host's IP
|
||||
/* address.
|
||||
/* What mechanisms the Postfix SMTP client uses to look up a host's
|
||||
/* IP address.
|
||||
/* .IP "\fBsmtp_randomize_addresses (yes)\fR"
|
||||
/* Randomize the order of equal-preference MX host addresses.
|
||||
/* .IP "\fBsyslog_facility (mail)\fR"
|
||||
@ -791,6 +810,7 @@ int var_smtp_mxaddr_limit;
|
||||
int var_smtp_mxsess_limit;
|
||||
int var_smtp_cache_conn;
|
||||
int var_smtp_reuse_time;
|
||||
int var_smtp_reuse_count;
|
||||
char *var_smtp_cache_dest;
|
||||
char *var_scache_service; /* You can now leave this here. */
|
||||
bool var_smtp_cache_demand;
|
||||
@ -826,11 +846,13 @@ int var_smtp_tls_scert_vd;
|
||||
char *var_smtp_tls_vfy_cmatch;
|
||||
char *var_smtp_tls_fpt_cmatch;
|
||||
char *var_smtp_tls_fpt_dgst;
|
||||
char *var_smtp_tls_tafile;
|
||||
char *var_smtp_tls_proto;
|
||||
char *var_smtp_tls_ciph;
|
||||
char *var_smtp_tls_eccert_file;
|
||||
char *var_smtp_tls_eckey_file;
|
||||
bool var_smtp_tls_blk_early_mail_reply;
|
||||
bool var_smtp_tls_force_tlsa;
|
||||
|
||||
#endif
|
||||
|
||||
@ -850,6 +872,7 @@ char *var_smtp_body_chks;
|
||||
char *var_smtp_resp_filter;
|
||||
bool var_lmtp_assume_final;
|
||||
char *var_smtp_dns_res_opt;
|
||||
char *var_smtp_dns_support;
|
||||
bool var_smtp_rec_deadline;
|
||||
bool var_smtp_dummy_mail_auth;
|
||||
|
||||
@ -861,7 +884,9 @@ bool var_smtp_sasl_auth_soft_bounce;
|
||||
/*
|
||||
* Global variables.
|
||||
*/
|
||||
int smtp_mode;
|
||||
int smtp_host_lookup_mask;
|
||||
int smtp_dns_support;
|
||||
STRING_LIST *smtp_cache_dest;
|
||||
SCACHE *smtp_scache;
|
||||
MAPS *smtp_ehlo_dis_maps;
|
||||
@ -975,18 +1000,39 @@ static void post_init(char *unused_name, char **unused_argv)
|
||||
SMTP_DNS_RES_OPT_DNSRCH, RES_DNSRCH,
|
||||
0,
|
||||
};
|
||||
static const NAME_CODE dns_support[] = {
|
||||
SMTP_DNS_SUPPORT_DISABLED, SMTP_DNS_DISABLED,
|
||||
SMTP_DNS_SUPPORT_ENABLED, SMTP_DNS_ENABLED,
|
||||
#if (RES_USE_DNSSEC != 0) && (RES_USE_EDNS0 != 0)
|
||||
SMTP_DNS_SUPPORT_DNSSEC, SMTP_DNS_DNSSEC,
|
||||
#endif
|
||||
0, SMTP_DNS_INVALID,
|
||||
};
|
||||
|
||||
if (*var_smtp_dns_support == 0) {
|
||||
/* Backwards compatible empty setting */
|
||||
smtp_dns_support =
|
||||
var_disable_dns ? SMTP_DNS_DISABLED : SMTP_DNS_ENABLED;
|
||||
} else {
|
||||
smtp_dns_support =
|
||||
name_code(dns_support, NAME_CODE_FLAG_NONE, var_smtp_dns_support);
|
||||
if (smtp_dns_support == SMTP_DNS_INVALID)
|
||||
msg_fatal("invalid %s: \"%s\"", SMTP_X(DNS_SUPPORT),
|
||||
var_smtp_dns_support);
|
||||
var_disable_dns = (smtp_dns_support == SMTP_DNS_DISABLED);
|
||||
}
|
||||
|
||||
/*
|
||||
* Select hostname lookup mechanisms.
|
||||
*/
|
||||
if (var_disable_dns)
|
||||
if (smtp_dns_support == SMTP_DNS_DISABLED)
|
||||
smtp_host_lookup_mask = SMTP_HOST_FLAG_NATIVE;
|
||||
else
|
||||
smtp_host_lookup_mask = name_mask(VAR_SMTP_HOST_LOOKUP, lookup_masks,
|
||||
var_smtp_host_lookup);
|
||||
smtp_host_lookup_mask =
|
||||
name_mask(SMTP_X(HOST_LOOKUP), lookup_masks, var_smtp_host_lookup);
|
||||
if (msg_verbose)
|
||||
msg_info("host name lookup methods: %s",
|
||||
str_name_mask(VAR_SMTP_HOST_LOOKUP, lookup_masks,
|
||||
str_name_mask(SMTP_X(HOST_LOOKUP), lookup_masks,
|
||||
smtp_host_lookup_mask));
|
||||
|
||||
/*
|
||||
@ -1005,7 +1051,7 @@ static void post_init(char *unused_name, char **unused_argv)
|
||||
/*
|
||||
* Select DNS query flags.
|
||||
*/
|
||||
smtp_dns_res_opt = name_mask(VAR_SMTP_DNS_RES_OPT, dns_res_opt_masks,
|
||||
smtp_dns_res_opt = name_mask(SMTP_X(DNS_RES_OPT), dns_res_opt_masks,
|
||||
var_smtp_dns_res_opt);
|
||||
}
|
||||
|
||||
@ -1034,7 +1080,7 @@ static void pre_init(char *unused_name, char **unused_argv)
|
||||
smtp_sasl_initialize();
|
||||
#else
|
||||
msg_warn("%s is true, but SASL support is not compiled in",
|
||||
VAR_SMTP_SASL_ENABLE);
|
||||
SMTP_X(SASL_ENABLE));
|
||||
#endif
|
||||
|
||||
if (*var_smtp_tls_level != 0)
|
||||
@ -1042,10 +1088,12 @@ static void pre_init(char *unused_name, char **unused_argv)
|
||||
switch (tls_level_lookup(var_smtp_tls_level)) {
|
||||
case TLS_LEV_SECURE:
|
||||
case TLS_LEV_VERIFY:
|
||||
case TLS_LEV_DANE_ONLY:
|
||||
case TLS_LEV_FPRINT:
|
||||
case TLS_LEV_ENCRYPT:
|
||||
var_smtp_use_tls = var_smtp_enforce_tls = 1;
|
||||
break;
|
||||
case TLS_LEV_DANE:
|
||||
case TLS_LEV_MAY:
|
||||
var_smtp_use_tls = 1;
|
||||
var_smtp_enforce_tls = 0;
|
||||
@ -1067,7 +1115,6 @@ 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
|
||||
@ -1078,12 +1125,10 @@ 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_param = SMTP_X(TLS_LOGLEVEL),
|
||||
log_level = var_smtp_tls_loglevel,
|
||||
verifydepth = var_smtp_tls_scert_vd,
|
||||
cache_type = using_smtp ?
|
||||
TLS_MGR_SCACHE_SMTP : TLS_MGR_SCACHE_LMTP,
|
||||
cache_type = X_SMTP(TLS_MGR_SCACHE),
|
||||
cert_file = var_smtp_tls_cert_file,
|
||||
key_file = var_smtp_tls_key_file,
|
||||
dcert_file = var_smtp_tls_dcert_file,
|
||||
@ -1092,7 +1137,7 @@ static void pre_init(char *unused_name, char **unused_argv)
|
||||
eckey_file = var_smtp_tls_eckey_file,
|
||||
CAfile = var_smtp_tls_CAfile,
|
||||
CApath = var_smtp_tls_CApath,
|
||||
fpt_dgst = var_smtp_tls_fpt_dgst);
|
||||
mdalg = var_smtp_tls_fpt_dgst);
|
||||
smtp_tls_list_init();
|
||||
#else
|
||||
msg_warn("TLS has been selected, but TLS support is not compiled in");
|
||||
@ -1114,7 +1159,7 @@ static void pre_init(char *unused_name, char **unused_argv)
|
||||
* EHLO keyword filter.
|
||||
*/
|
||||
if (*var_smtp_ehlo_dis_maps)
|
||||
smtp_ehlo_dis_maps = maps_create(VAR_SMTP_EHLO_DIS_MAPS,
|
||||
smtp_ehlo_dis_maps = maps_create(SMTP_X(EHLO_DIS_MAPS),
|
||||
var_smtp_ehlo_dis_maps,
|
||||
DICT_FLAG_LOCK);
|
||||
|
||||
@ -1122,7 +1167,7 @@ static void pre_init(char *unused_name, char **unused_argv)
|
||||
* PIX bug workarounds.
|
||||
*/
|
||||
if (*var_smtp_pix_bug_maps)
|
||||
smtp_pix_bug_maps = maps_create(VAR_SMTP_PIX_BUG_MAPS,
|
||||
smtp_pix_bug_maps = maps_create(SMTP_X(PIX_BUG_MAPS),
|
||||
var_smtp_pix_bug_maps,
|
||||
DICT_FLAG_LOCK);
|
||||
|
||||
@ -1134,19 +1179,19 @@ static void pre_init(char *unused_name, char **unused_argv)
|
||||
ext_prop_mask(VAR_PROP_EXTENSION, var_prop_extension);
|
||||
if (*var_smtp_generic_maps)
|
||||
smtp_generic_maps =
|
||||
maps_create(VAR_SMTP_GENERIC_MAPS, var_smtp_generic_maps,
|
||||
maps_create(SMTP_X(GENERIC_MAPS), var_smtp_generic_maps,
|
||||
DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX);
|
||||
|
||||
/*
|
||||
* Header/body checks.
|
||||
*/
|
||||
smtp_header_checks = hbc_header_checks_create(
|
||||
VAR_SMTP_HEAD_CHKS, var_smtp_head_chks,
|
||||
VAR_SMTP_MIME_CHKS, var_smtp_mime_chks,
|
||||
VAR_SMTP_NEST_CHKS, var_smtp_nest_chks,
|
||||
SMTP_X(HEAD_CHKS), var_smtp_head_chks,
|
||||
SMTP_X(MIME_CHKS), var_smtp_mime_chks,
|
||||
SMTP_X(NEST_CHKS), var_smtp_nest_chks,
|
||||
smtp_hbc_callbacks);
|
||||
smtp_body_checks = hbc_body_checks_create(
|
||||
VAR_SMTP_BODY_CHKS, var_smtp_body_chks,
|
||||
SMTP_X(BODY_CHKS), var_smtp_body_chks,
|
||||
smtp_hbc_callbacks);
|
||||
|
||||
/*
|
||||
@ -1164,7 +1209,7 @@ static void pre_init(char *unused_name, char **unused_argv)
|
||||
smtp_addr_pref = name_code(addr_pref_map, NAME_CODE_FLAG_NONE,
|
||||
var_smtp_addr_pref);
|
||||
if (smtp_addr_pref < 0)
|
||||
msg_fatal("bad %s value: %s", VAR_SMTP_ADDR_PREF, var_smtp_addr_pref);
|
||||
msg_fatal("bad %s value: %s", SMTP_X(ADDR_PREF), var_smtp_addr_pref);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1186,9 +1231,10 @@ MAIL_VERSION_STAMP_DECLARE;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *sane_procname;
|
||||
|
||||
#include "smtp_params.c"
|
||||
#include "lmtp_params.c"
|
||||
int smtp_mode;
|
||||
|
||||
/*
|
||||
* Fingerprint executables and core dumps.
|
||||
@ -1197,8 +1243,19 @@ int main(int argc, char **argv)
|
||||
|
||||
/*
|
||||
* XXX At this point, var_procname etc. are not initialized.
|
||||
*
|
||||
* The process name, "smtp" or "lmtp", determines the protocol, the DSN
|
||||
* server reply type, SASL service information lookup, and more. Prepare
|
||||
* for the possibility there may be another personality.
|
||||
*/
|
||||
smtp_mode = (strcmp(sane_basename((VSTRING *) 0, argv[0]), "smtp") == 0);
|
||||
sane_procname = sane_basename((VSTRING *) 0, argv[0]);
|
||||
if (strcmp(sane_procname, "smtp") == 0)
|
||||
smtp_mode = 1;
|
||||
else if (strcmp(sane_procname, "lmtp") == 0)
|
||||
smtp_mode = 0;
|
||||
else
|
||||
msg_fatal("unexpected process name \"%s\" - "
|
||||
"specify \"smtp\" or \"lmtp\"", var_procname);
|
||||
|
||||
/*
|
||||
* Initialize with the LMTP or SMTP parameter name space.
|
||||
|
102
external/ibm-public/postfix/dist/src/smtpd/smtpd.c
vendored
102
external/ibm-public/postfix/dist/src/smtpd/smtpd.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: smtpd.c,v 1.10 2013/09/25 19:12:35 tron Exp $ */
|
||||
/* $NetBSD: smtpd.c,v 1.11 2014/07/06 19:45:50 tron Exp $ */
|
||||
|
||||
/*++
|
||||
/* NAME
|
||||
@ -92,10 +92,6 @@
|
||||
/* not contain RFC 822 style comments or phrases.
|
||||
/* .PP
|
||||
/* Available in Postfix version 2.1 and later:
|
||||
/* .IP "\fBresolve_null_domain (no)\fR"
|
||||
/* Resolve an address that ends in the "@" null domain as if the
|
||||
/* local hostname were specified, instead of rejecting the address as
|
||||
/* invalid.
|
||||
/* .IP "\fBsmtpd_reject_unlisted_sender (no)\fR"
|
||||
/* Request that the Postfix SMTP server rejects mail from unknown
|
||||
/* sender addresses, even when no explicit reject_unlisted_sender
|
||||
@ -136,7 +132,8 @@
|
||||
/* .PP
|
||||
/* Available in Postfix version 2.9 and later:
|
||||
/* .IP "\fBsmtpd_per_record_deadline (normal: no, overload: yes)\fR"
|
||||
/* Change the behavior of the smtpd_timeout time limit, from a
|
||||
/* Change the behavior of the smtpd_timeout and smtpd_starttls_timeout
|
||||
/* time limits, from a
|
||||
/* time limit per read or write system call, to a time limit to send
|
||||
/* or receive a complete record (an SMTP command line, SMTP response
|
||||
/* line, SMTP message content line, or TLS protocol message).
|
||||
@ -320,6 +317,11 @@
|
||||
/* .IP "\fBcyrus_sasl_config_path (empty)\fR"
|
||||
/* Search path for Cyrus SASL application configuration files,
|
||||
/* currently used only to locate the $smtpd_sasl_path.conf file.
|
||||
/* .PP
|
||||
/* Available in Postfix version 2.11 and later:
|
||||
/* .IP "\fBsmtpd_sasl_service (smtp)\fR"
|
||||
/* The service name that is passed to the SASL plug-in that is
|
||||
/* selected with \fBsmtpd_sasl_type\fR and \fBsmtpd_sasl_path\fR.
|
||||
/* STARTTLS SUPPORT CONTROLS
|
||||
/* .ad
|
||||
/* .fi
|
||||
@ -364,10 +366,10 @@
|
||||
/* File with the Postfix SMTP server DSA certificate in PEM format.
|
||||
/* .IP "\fBsmtpd_tls_dh1024_param_file (empty)\fR"
|
||||
/* File with DH parameters that the Postfix SMTP server should
|
||||
/* use with EDH ciphers.
|
||||
/* use with non-export EDH ciphers.
|
||||
/* .IP "\fBsmtpd_tls_dh512_param_file (empty)\fR"
|
||||
/* File with DH parameters that the Postfix SMTP server should
|
||||
/* use with EDH ciphers.
|
||||
/* use with export-grade EDH ciphers.
|
||||
/* .IP "\fBsmtpd_tls_dkey_file ($smtpd_tls_dcert_file)\fR"
|
||||
/* File with the Postfix SMTP server DSA private key in PEM format.
|
||||
/* .IP "\fBsmtpd_tls_key_file ($smtpd_tls_cert_file)\fR"
|
||||
@ -391,12 +393,6 @@
|
||||
/* .IP "\fBsmtpd_tls_req_ccert (no)\fR"
|
||||
/* With mandatory TLS encryption, require a trusted remote SMTP client
|
||||
/* certificate in order to allow TLS connections to proceed.
|
||||
/* .IP "\fBsmtpd_tls_session_cache_database (empty)\fR"
|
||||
/* Name of the file containing the optional Postfix SMTP server
|
||||
/* TLS session cache.
|
||||
/* .IP "\fBsmtpd_tls_session_cache_timeout (3600s)\fR"
|
||||
/* The expiration time of Postfix SMTP server TLS session cache
|
||||
/* information.
|
||||
/* .IP "\fBsmtpd_tls_wrappermode (no)\fR"
|
||||
/* Run the Postfix SMTP server in the non-standard "wrapper" mode,
|
||||
/* instead of using the STARTTLS command.
|
||||
@ -453,6 +449,10 @@
|
||||
/* order.
|
||||
/* .IP "\fBtls_disable_workarounds (see 'postconf -d' output)\fR"
|
||||
/* List or bit-mask of OpenSSL bug work-arounds to disable.
|
||||
/* .PP
|
||||
/* Available in Postfix version 2.11 and later:
|
||||
/* .IP "\fBtlsmgr_service_name (tlsmgr)\fR"
|
||||
/* The name of the \fBtlsmgr\fR(8) service entry in master.cf.
|
||||
/* OBSOLETE STARTTLS CONTROLS
|
||||
/* .ad
|
||||
/* .fi
|
||||
@ -531,7 +531,8 @@
|
||||
/* Available in Postfix version 2.10 and later:
|
||||
/* .IP "\fBsmtpd_log_access_permit_actions (empty)\fR"
|
||||
/* Enable logging of the named "permit" actions in SMTP server
|
||||
/* access lists.
|
||||
/* access lists (by default, the SMTP server logs "reject" actions but
|
||||
/* not "permit" actions).
|
||||
/* KNOWN VERSUS UNKNOWN RECIPIENT CONTROLS
|
||||
/* .ad
|
||||
/* .fi
|
||||
@ -667,7 +668,8 @@
|
||||
/* .PP
|
||||
/* Available in Postfix version 2.9 and later:
|
||||
/* .IP "\fBsmtpd_per_record_deadline (normal: no, overload: yes)\fR"
|
||||
/* Change the behavior of the smtpd_timeout time limit, from a
|
||||
/* Change the behavior of the smtpd_timeout and smtpd_starttls_timeout
|
||||
/* time limits, from a
|
||||
/* time limit per read or write system call, to a time limit to send
|
||||
/* or receive a complete record (an SMTP command line, SMTP response
|
||||
/* line, SMTP message content line, or TLS protocol message).
|
||||
@ -784,7 +786,7 @@
|
||||
/* applies in the context of the SMTP END-OF-DATA command.
|
||||
/* .PP
|
||||
/* Available in Postfix version 2.10 and later:
|
||||
/* .IP "\fBsmtpd_relay_restrictions (permit_mynetworks, reject_unauth_destination)\fR"
|
||||
/* .IP "\fBsmtpd_relay_restrictions (permit_mynetworks, permit_sasl_authenticated, defer_unauth_destination)\fR"
|
||||
/* Access restrictions for mail relay control that the Postfix
|
||||
/* SMTP server applies in the context of the RCPT TO command, before
|
||||
/* smtpd_recipient_restrictions.
|
||||
@ -957,7 +959,9 @@
|
||||
/* .IP "\fBqueue_directory (see 'postconf -d' output)\fR"
|
||||
/* The location of the Postfix top-level queue directory.
|
||||
/* .IP "\fBrecipient_delimiter (empty)\fR"
|
||||
/* The separator between user names and address extensions (user+foo).
|
||||
/* The set of characters that can separate a user name from its
|
||||
/* extension (example: user+foo), or a .forward file name from its
|
||||
/* extension (example: .forward+foo).
|
||||
/* .IP "\fBsmtpd_banner ($myhostname ESMTP $mail_name)\fR"
|
||||
/* The text that follows the 220 status code in the SMTP greeting
|
||||
/* banner.
|
||||
@ -1182,6 +1186,7 @@ bool var_smtpd_sasl_enable;
|
||||
bool var_smtpd_sasl_auth_hdr;
|
||||
char *var_smtpd_sasl_opts;
|
||||
char *var_smtpd_sasl_path;
|
||||
char *var_smtpd_sasl_service;
|
||||
char *var_cyrus_conf_path;
|
||||
char *var_smtpd_sasl_realm;
|
||||
char *var_smtpd_sasl_exceptions_networks;
|
||||
@ -1264,7 +1269,6 @@ char *var_smtpd_tls_loglevel;
|
||||
char *var_smtpd_tls_mand_proto;
|
||||
bool var_smtpd_tls_received_header;
|
||||
bool var_smtpd_tls_req_ccert;
|
||||
int var_smtpd_tls_scache_timeout;
|
||||
bool var_smtpd_tls_set_sessid;
|
||||
char *var_smtpd_tls_fpt_dgst;
|
||||
char *var_smtpd_tls_ciph;
|
||||
@ -1847,7 +1851,7 @@ static int mail_open_stream(SMTPD_STATE *state)
|
||||
if (smtpd_proxy_create(state, smtpd_proxy_opts, var_smtpd_proxy_filt,
|
||||
var_smtpd_proxy_tmout, var_smtpd_proxy_ehlo,
|
||||
state->proxy_mail) != 0) {
|
||||
smtpd_chat_reply(state, "%s", STR(state->proxy->buffer));
|
||||
smtpd_chat_reply(state, "%s", STR(state->proxy->reply));
|
||||
smtpd_proxy_free(state);
|
||||
return (-1);
|
||||
}
|
||||
@ -2690,7 +2694,7 @@ static int rcpt_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
|
||||
proxy = state->proxy;
|
||||
if (proxy != 0 && proxy->cmd(state, SMTPD_PROX_WANT_OK,
|
||||
"%s", STR(state->buffer)) != 0) {
|
||||
smtpd_chat_reply(state, "%s", STR(proxy->buffer));
|
||||
smtpd_chat_reply(state, "%s", STR(proxy->reply));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@ -2939,7 +2943,7 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
|
||||
proxy = state->proxy;
|
||||
if (proxy != 0 && proxy->cmd(state, SMTPD_PROX_WANT_MORE,
|
||||
"%s", STR(state->buffer)) != 0) {
|
||||
smtpd_chat_reply(state, "%s", STR(proxy->buffer));
|
||||
smtpd_chat_reply(state, "%s", STR(proxy->reply));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@ -3149,7 +3153,7 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
|
||||
if (state->err == CLEANUP_STAT_OK) {
|
||||
(void) proxy->cmd(state, SMTPD_PROX_WANT_ANY, ".");
|
||||
if (state->err == CLEANUP_STAT_OK &&
|
||||
*STR(proxy->buffer) != '2')
|
||||
*STR(proxy->reply) != '2')
|
||||
state->err = CLEANUP_STAT_CONT;
|
||||
}
|
||||
}
|
||||
@ -3238,7 +3242,7 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
|
||||
state->error_mask = 0;
|
||||
state->junk_cmds = 0;
|
||||
if (proxy)
|
||||
smtpd_chat_reply(state, "%s", STR(proxy->buffer));
|
||||
smtpd_chat_reply(state, "%s", STR(proxy->reply));
|
||||
else
|
||||
smtpd_chat_reply(state,
|
||||
"250 2.0.0 Ok: queued as %s", state->queue_id);
|
||||
@ -3274,7 +3278,7 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
|
||||
state->error_mask |= MAIL_ERROR_POLICY;
|
||||
detail = cleanup_stat_detail(CLEANUP_STAT_CONT);
|
||||
if (proxy) {
|
||||
smtpd_chat_reply(state, "%s", STR(proxy->buffer));
|
||||
smtpd_chat_reply(state, "%s", STR(proxy->reply));
|
||||
} else if (why && LEN(why) > 0) {
|
||||
/* Allow address-specific DSN status in header/body_checks. */
|
||||
smtpd_chat_reply(state, "%d %s", detail->smtp, STR(why));
|
||||
@ -3289,7 +3293,7 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
|
||||
detail->smtp, detail->dsn, detail->text);
|
||||
} else if ((state->err & CLEANUP_STAT_PROXY) != 0) {
|
||||
state->error_mask |= MAIL_ERROR_SOFTWARE;
|
||||
smtpd_chat_reply(state, "%s", STR(proxy->buffer));
|
||||
smtpd_chat_reply(state, "%s", STR(proxy->reply));
|
||||
} else {
|
||||
state->error_mask |= MAIL_ERROR_SOFTWARE;
|
||||
detail = cleanup_stat_detail(CLEANUP_STAT_BAD);
|
||||
@ -3303,7 +3307,7 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
|
||||
if (proxy)
|
||||
msg_info("proxy-%s: %s: %s;%s",
|
||||
(state->err == CLEANUP_STAT_OK) ? "accept" : "reject",
|
||||
state->where, STR(proxy->buffer), smtpd_whatsup(state));
|
||||
state->where, STR(proxy->reply), smtpd_whatsup(state));
|
||||
|
||||
/*
|
||||
* Cleanup. The client may send another MAIL command.
|
||||
@ -3373,6 +3377,7 @@ static int noop_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
|
||||
static int vrfy_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
|
||||
{
|
||||
const char *err = 0;
|
||||
int rate;
|
||||
|
||||
/*
|
||||
* The SMTP standard (RFC 821) disallows unquoted special characters in
|
||||
@ -3403,17 +3408,38 @@ static int vrfy_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
|
||||
smtpd_chat_reply(state, "502 5.5.1 VRFY command is disabled");
|
||||
return (-1);
|
||||
}
|
||||
if (argc < 2) {
|
||||
state->error_mask |= MAIL_ERROR_PROTOCOL;
|
||||
smtpd_chat_reply(state, "501 5.5.4 Syntax: VRFY address");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX The client event count/rate control must be consistent in its use
|
||||
* of client address information in connect and disconnect events. For
|
||||
* now we exclude xclient authorized hosts from event count/rate control.
|
||||
*/
|
||||
if (SMTPD_STAND_ALONE(state) == 0
|
||||
&& !xclient_allowed
|
||||
&& anvil_clnt
|
||||
&& var_smtpd_crcpt_limit > 0
|
||||
&& !namadr_list_match(hogger_list, state->name, state->addr)
|
||||
&& anvil_clnt_rcpt(anvil_clnt, state->service, state->addr,
|
||||
&rate) == ANVIL_STAT_OK
|
||||
&& rate > var_smtpd_crcpt_limit) {
|
||||
state->error_mask |= MAIL_ERROR_POLICY;
|
||||
msg_warn("Recipient address rate limit exceeded: %d from %s for service %s",
|
||||
rate, state->namaddr, state->service);
|
||||
smtpd_chat_reply(state, "450 4.7.1 Error: too many recipients from %s",
|
||||
state->addr);
|
||||
return (-1);
|
||||
}
|
||||
if (smtpd_milters != 0 && (err = milter_other_event(smtpd_milters)) != 0
|
||||
&& (err[0] == '5' || err[0] == '4')) {
|
||||
state->error_mask |= MAIL_ERROR_POLICY;
|
||||
smtpd_chat_reply(state, "%s", err);
|
||||
return (-1);
|
||||
}
|
||||
if (argc < 2) {
|
||||
state->error_mask |= MAIL_ERROR_PROTOCOL;
|
||||
smtpd_chat_reply(state, "501 5.5.4 Syntax: VRFY address");
|
||||
return (-1);
|
||||
}
|
||||
if (argc > 2)
|
||||
collapse_args(argc - 1, argv + 1);
|
||||
if (extract_addr(state, argv + 1, REJECT_EMPTY_ADDR, SLOPPY) != 0) {
|
||||
@ -4208,7 +4234,7 @@ static void smtpd_start_tls(SMTPD_STATE *state)
|
||||
namaddr = state->namaddr,
|
||||
cipher_grade = cipher_grade,
|
||||
cipher_exclusions = STR(cipher_exclusions),
|
||||
fpt_dgst = var_smtpd_tls_fpt_dgst);
|
||||
mdalg = var_smtpd_tls_fpt_dgst);
|
||||
|
||||
#endif /* USE_TLSPROXY */
|
||||
|
||||
@ -4348,14 +4374,14 @@ static int starttls_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
|
||||
state->port, var_smtpd_tmout);
|
||||
if (state->tlsproxy == 0) {
|
||||
state->error_mask |= MAIL_ERROR_SOFTWARE;
|
||||
/* RFC 4954 Section 6. */
|
||||
/* RFC 3207 Section 4. */
|
||||
smtpd_chat_reply(state, "454 4.7.0 TLS not available due to local problem");
|
||||
return (-1);
|
||||
}
|
||||
#else /* USE_TLSPROXY */
|
||||
if (smtpd_tls_ctx == 0) {
|
||||
state->error_mask |= MAIL_ERROR_SOFTWARE;
|
||||
/* RFC 4954 Section 6. */
|
||||
/* RFC 3207 Section 4. */
|
||||
smtpd_chat_reply(state, "454 4.7.0 TLS not available due to local problem");
|
||||
return (-1);
|
||||
}
|
||||
@ -5130,8 +5156,6 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
|
||||
log_level = var_smtpd_tls_loglevel,
|
||||
verifydepth = var_smtpd_tls_ccert_vd,
|
||||
cache_type = TLS_MGR_SCACHE_SMTPD,
|
||||
scache_timeout
|
||||
= var_smtpd_tls_scache_timeout,
|
||||
set_sessid = var_smtpd_tls_set_sessid,
|
||||
cert_file = cert_file,
|
||||
key_file = var_smtpd_tls_key_file,
|
||||
@ -5150,7 +5174,7 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
|
||||
var_smtpd_tls_mand_proto :
|
||||
var_smtpd_tls_proto,
|
||||
ask_ccert = ask_client_cert,
|
||||
fpt_dgst = var_smtpd_tls_fpt_dgst);
|
||||
mdalg = var_smtpd_tls_fpt_dgst);
|
||||
else
|
||||
msg_warn("No server certs available. TLS won't be enabled");
|
||||
#endif /* USE_TLSPROXY */
|
||||
@ -5304,7 +5328,6 @@ int main(int argc, char **argv)
|
||||
VAR_SMTPD_POLICY_TTL, DEF_SMTPD_POLICY_TTL, &var_smtpd_policy_ttl, 1, 0,
|
||||
#ifdef USE_TLS
|
||||
VAR_SMTPD_STARTTLS_TMOUT, DEF_SMTPD_STARTTLS_TMOUT, &var_smtpd_starttls_tmout, 1, 0,
|
||||
VAR_SMTPD_TLS_SCACHTIME, DEF_SMTPD_TLS_SCACHTIME, &var_smtpd_tls_scache_timeout, 0, 0,
|
||||
#endif
|
||||
VAR_MILT_CONN_TIME, DEF_MILT_CONN_TIME, &var_milt_conn_time, 1, 0,
|
||||
VAR_MILT_CMD_TIME, DEF_MILT_CMD_TIME, &var_milt_cmd_time, 1, 0,
|
||||
@ -5367,6 +5390,7 @@ int main(int argc, char **argv)
|
||||
VAR_LOCAL_RCPT_MAPS, DEF_LOCAL_RCPT_MAPS, &var_local_rcpt_maps, 0, 0,
|
||||
VAR_SMTPD_SASL_OPTS, DEF_SMTPD_SASL_OPTS, &var_smtpd_sasl_opts, 0, 0,
|
||||
VAR_SMTPD_SASL_PATH, DEF_SMTPD_SASL_PATH, &var_smtpd_sasl_path, 1, 0,
|
||||
VAR_SMTPD_SASL_SERVICE, DEF_SMTPD_SASL_SERVICE, &var_smtpd_sasl_service, 1, 0,
|
||||
VAR_CYRUS_CONF_PATH, DEF_CYRUS_CONF_PATH, &var_cyrus_conf_path, 0, 0,
|
||||
VAR_SMTPD_SASL_REALM, DEF_SMTPD_SASL_REALM, &var_smtpd_sasl_realm, 0, 0,
|
||||
VAR_SMTPD_SASL_EXCEPTIONS_NETWORKS, DEF_SMTPD_SASL_EXCEPTIONS_NETWORKS, &var_smtpd_sasl_exceptions_networks, 0, 0,
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: tls_client.c,v 1.8 2013/09/25 19:12:35 tron Exp $ */
|
||||
/* $NetBSD: tls_client.c,v 1.9 2014/07/06 19:45:50 tron Exp $ */
|
||||
|
||||
/*++
|
||||
/* NAME
|
||||
@ -93,7 +93,7 @@
|
||||
/* .IP TLScontext->issuer_CN
|
||||
/* Extracted CommonName of the issuer, or zero-length string if the
|
||||
/* information could not be extracted.
|
||||
/* .IP TLScontext->peer_fingerprint
|
||||
/* .IP TLScontext->peer_cert_fprint
|
||||
/* At the fingerprint security level, if the peer presented a certificate
|
||||
/* the fingerprint of the certificate.
|
||||
/* .PP
|
||||
@ -170,7 +170,7 @@ static SSL_SESSION *load_clnt_session(TLS_SESS_STATE *TLScontext)
|
||||
* Prepare the query.
|
||||
*/
|
||||
if (TLScontext->log_mask & TLS_LOG_CACHE)
|
||||
/* serverid already contains namaddrport information */
|
||||
/* serverid contains transport:addr:port information */
|
||||
msg_info("looking for session %s in %s cache",
|
||||
TLScontext->serverid, TLScontext->cache_type);
|
||||
|
||||
@ -192,7 +192,7 @@ static SSL_SESSION *load_clnt_session(TLS_SESS_STATE *TLScontext)
|
||||
session = tls_session_activate(STR(session_data), LEN(session_data));
|
||||
if (session) {
|
||||
if (TLScontext->log_mask & TLS_LOG_CACHE)
|
||||
/* serverid already contains namaddrport information */
|
||||
/* serverid contains transport:addr:port information */
|
||||
msg_info("reloaded session %s from %s cache",
|
||||
TLScontext->serverid, TLScontext->cache_type);
|
||||
}
|
||||
@ -232,25 +232,10 @@ static int new_client_session_cb(SSL *ssl, SSL_SESSION *session)
|
||||
myname);
|
||||
|
||||
if (TLScontext->log_mask & TLS_LOG_CACHE)
|
||||
/* serverid already contains namaddrport information */
|
||||
/* serverid contains transport:addr:port information */
|
||||
msg_info("save session %s to %s cache",
|
||||
TLScontext->serverid, TLScontext->cache_type);
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x00906011L) || (OPENSSL_VERSION_NUMBER == 0x00907000L)
|
||||
|
||||
/*
|
||||
* Ugly Hack: OpenSSL before 0.9.6a does not store the verify result in
|
||||
* sessions for the client side. We modify the session directly which is
|
||||
* version specific, but this bug is version specific, too.
|
||||
*
|
||||
* READ: 0-09-06-01-1 = 0-9-6-a-beta1: all versions before beta1 have this
|
||||
* bug, it has been fixed during development of 0.9.6a. The development
|
||||
* version of 0.9.7 can have this bug, too. It has been fixed on
|
||||
* 2000/11/29.
|
||||
*/
|
||||
session->verify_result = SSL_get_verify_result(TLScontext->con);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Passivate and save the session object. Errors are non-fatal, since
|
||||
* caching is only an optimization.
|
||||
@ -280,7 +265,7 @@ static void uncache_session(SSL_CTX *ctx, TLS_SESS_STATE *TLScontext)
|
||||
return;
|
||||
|
||||
if (TLScontext->log_mask & TLS_LOG_CACHE)
|
||||
/* serverid already contains namaddrport information */
|
||||
/* serverid contains transport:addr:port information */
|
||||
msg_info("remove session %s from client cache", TLScontext->serverid);
|
||||
|
||||
tls_mgr_delete(TLScontext->cache_type, TLScontext->serverid);
|
||||
@ -292,10 +277,9 @@ TLS_APPL_STATE *tls_client_init(const TLS_CLIENT_INIT_PROPS *props)
|
||||
{
|
||||
long off = 0;
|
||||
int cachable;
|
||||
int scache_timeout;
|
||||
SSL_CTX *client_ctx;
|
||||
TLS_APPL_STATE *app_ctx;
|
||||
const EVP_MD *md_alg;
|
||||
unsigned int md_len;
|
||||
int log_mask;
|
||||
|
||||
/*
|
||||
@ -337,40 +321,12 @@ TLS_APPL_STATE *tls_client_init(const TLS_CLIENT_INIT_PROPS *props)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Register SHA-2 digests, if implemented and not already registered.
|
||||
* Improves interoperability with clients and servers that prematurely
|
||||
* deploy SHA-2 certificates.
|
||||
*/
|
||||
#if defined(LN_sha256) && defined(NID_sha256) && !defined(OPENSSL_NO_SHA256)
|
||||
if (!EVP_get_digestbyname(LN_sha224))
|
||||
EVP_add_digest(EVP_sha224());
|
||||
if (!EVP_get_digestbyname(LN_sha256))
|
||||
EVP_add_digest(EVP_sha256());
|
||||
#endif
|
||||
#if defined(LN_sha512) && defined(NID_sha512) && !defined(OPENSSL_NO_SHA512)
|
||||
if (!EVP_get_digestbyname(LN_sha384))
|
||||
EVP_add_digest(EVP_sha384());
|
||||
if (!EVP_get_digestbyname(LN_sha512))
|
||||
EVP_add_digest(EVP_sha512());
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If the administrator specifies an unsupported digest algorithm, fail
|
||||
* now, rather than in the middle of a TLS handshake.
|
||||
*/
|
||||
if ((md_alg = EVP_get_digestbyname(props->fpt_dgst)) == 0) {
|
||||
msg_warn("Digest algorithm \"%s\" not found: disabling TLS support",
|
||||
props->fpt_dgst);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sanity check: Newer shared libraries may use larger digests.
|
||||
*/
|
||||
if ((md_len = EVP_MD_size(md_alg)) > EVP_MAX_MD_SIZE) {
|
||||
msg_warn("Digest algorithm \"%s\" output size %u too large:"
|
||||
" disabling TLS support", props->fpt_dgst, md_len);
|
||||
if (!tls_validate_digest(props->mdalg)) {
|
||||
msg_warn("disabling TLS support");
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -492,7 +448,10 @@ TLS_APPL_STATE *tls_client_init(const TLS_CLIENT_INIT_PROPS *props)
|
||||
* sessions from the external cache, so we must delete them directly (not
|
||||
* via a callback).
|
||||
*/
|
||||
if (tls_mgr_policy(props->cache_type, &cachable) != TLS_MGR_STAT_OK)
|
||||
if (tls_mgr_policy(props->cache_type, &cachable,
|
||||
&scache_timeout) != TLS_MGR_STAT_OK)
|
||||
scache_timeout = 0;
|
||||
if (scache_timeout <= 0)
|
||||
cachable = 0;
|
||||
|
||||
/*
|
||||
@ -531,69 +490,82 @@ TLS_APPL_STATE *tls_client_init(const TLS_CLIENT_INIT_PROPS *props)
|
||||
SSL_SESS_CACHE_NO_INTERNAL_STORE |
|
||||
SSL_SESS_CACHE_NO_AUTO_CLEAR);
|
||||
SSL_CTX_sess_set_new_cb(client_ctx, new_client_session_cb);
|
||||
|
||||
/*
|
||||
* OpenSSL ignores timed-out sessions. We need to set the internal
|
||||
* cache timeout at least as high as the external cache timeout. This
|
||||
* applies even if no internal cache is used. We set the session to
|
||||
* twice the cache lifetime. This way a session always lasts longer
|
||||
* than its lifetime in the cache.
|
||||
*/
|
||||
SSL_CTX_set_timeout(client_ctx, 2 * scache_timeout);
|
||||
}
|
||||
return (app_ctx);
|
||||
}
|
||||
|
||||
/* match_hostname - match hostname against pattern */
|
||||
/* match_servername - match servername against pattern */
|
||||
|
||||
static int match_hostname(const char *peerid,
|
||||
const TLS_CLIENT_START_PROPS *props)
|
||||
static int match_servername(const char *certid,
|
||||
const TLS_CLIENT_START_PROPS *props)
|
||||
{
|
||||
const ARGV *cmatch_argv;
|
||||
const char *nexthop = props->nexthop;
|
||||
const char *hname = props->host;
|
||||
const char *pattern;
|
||||
const char *pattern_left;
|
||||
int sub;
|
||||
const char *domain;
|
||||
const char *parent;
|
||||
int match_subdomain;
|
||||
int i;
|
||||
int idlen;
|
||||
int patlen;
|
||||
int domlen;
|
||||
|
||||
if ((cmatch_argv = props->matchargv) == 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Match the peerid against each pattern until we find a match.
|
||||
* Match the certid against each pattern until we find a match.
|
||||
*/
|
||||
for (i = 0; i < cmatch_argv->argc; ++i) {
|
||||
sub = 0;
|
||||
match_subdomain = 0;
|
||||
if (!strcasecmp(cmatch_argv->argv[i], "nexthop"))
|
||||
pattern = nexthop;
|
||||
domain = nexthop;
|
||||
else if (!strcasecmp(cmatch_argv->argv[i], "hostname"))
|
||||
pattern = hname;
|
||||
domain = hname;
|
||||
else if (!strcasecmp(cmatch_argv->argv[i], "dot-nexthop")) {
|
||||
pattern = nexthop;
|
||||
sub = 1;
|
||||
domain = nexthop;
|
||||
match_subdomain = 1;
|
||||
} else {
|
||||
pattern = cmatch_argv->argv[i];
|
||||
if (*pattern == '.' && pattern[1] != '\0') {
|
||||
++pattern;
|
||||
sub = 1;
|
||||
domain = cmatch_argv->argv[i];
|
||||
if (*domain == '.' && domain[1] != '\0') {
|
||||
++domain;
|
||||
match_subdomain = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Sub-domain match: peerid is any sub-domain of pattern.
|
||||
* Sub-domain match: certid is any sub-domain of hostname.
|
||||
*/
|
||||
if (sub) {
|
||||
if ((idlen = strlen(peerid)) > (patlen = strlen(pattern)) + 1
|
||||
&& peerid[idlen - patlen - 1] == '.'
|
||||
&& !strcasecmp(peerid + (idlen - patlen), pattern))
|
||||
if (match_subdomain) {
|
||||
if ((idlen = strlen(certid)) > (domlen = strlen(domain)) + 1
|
||||
&& certid[idlen - domlen - 1] == '.'
|
||||
&& !strcasecmp(certid + (idlen - domlen), domain))
|
||||
return (1);
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Exact match and initial "*" match. The initial "*" in a peerid
|
||||
* matches exactly one hostname component, under the condition that
|
||||
* the peerid contains multiple hostname components.
|
||||
* Exact match and initial "*" match. The initial "*" in a certid
|
||||
* matches one (if var_tls_multi_label is false) or more hostname
|
||||
* components under the condition that the certid contains multiple
|
||||
* hostname components.
|
||||
*/
|
||||
if (!strcasecmp(peerid, pattern)
|
||||
|| (peerid[0] == '*' && peerid[1] == '.' && peerid[2] != 0
|
||||
&& (pattern_left = strchr(pattern, '.')) != 0
|
||||
&& strcasecmp(pattern_left + 1, peerid + 2) == 0))
|
||||
if (!strcasecmp(certid, domain)
|
||||
|| (certid[0] == '*' && certid[1] == '.' && certid[2] != 0
|
||||
&& (parent = strchr(domain, '.')) != 0
|
||||
&& (idlen = strlen(certid + 1)) <= (domlen = strlen(parent))
|
||||
&& strcasecmp(var_tls_multi_wildcard == 0 ? parent :
|
||||
parent + domlen - idlen,
|
||||
certid + 1) == 0))
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
@ -613,8 +585,7 @@ static void verify_extract_name(TLS_SESS_STATE *TLScontext, X509 *peercert,
|
||||
int verbose;
|
||||
const char *dnsname;
|
||||
const GENERAL_NAME *gn;
|
||||
|
||||
STACK_OF(GENERAL_NAME) * gens;
|
||||
general_name_stack_t *gens;
|
||||
|
||||
/*
|
||||
* On exit both peer_CN and issuer_CN should be set.
|
||||
@ -627,7 +598,13 @@ 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)
|
||||
/*
|
||||
* With fingerprint or dane we may already be done. Otherwise, verify the
|
||||
* peername if using traditional PKI or DANE with trust-anchors.
|
||||
*/
|
||||
if (!TLS_CERT_IS_MATCHED(TLScontext)
|
||||
&& TLS_CERT_IS_TRUSTED(TLScontext)
|
||||
&& TLS_MUST_TRUST(props->tls_level))
|
||||
verify_peername = 1;
|
||||
|
||||
/* Force cert processing so we can log the data? */
|
||||
@ -678,7 +655,7 @@ 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) {
|
||||
if ((dnsname_match = match_hostname(dnsname, props)) != 0)
|
||||
if ((dnsname_match = match_servername(dnsname, props)) != 0)
|
||||
matched++;
|
||||
/* Keep the first matched name. */
|
||||
if (TLScontext->peer_CN
|
||||
@ -712,7 +689,7 @@ static void verify_extract_name(TLS_SESS_STATE *TLScontext, X509 *peercert,
|
||||
if (TLScontext->peer_CN == 0) {
|
||||
TLScontext->peer_CN = tls_peer_CN(peercert, TLScontext);
|
||||
if (*TLScontext->peer_CN)
|
||||
matched = match_hostname(TLScontext->peer_CN, props);
|
||||
matched = match_servername(TLScontext->peer_CN, props);
|
||||
if (verify_peername && matched)
|
||||
TLScontext->peer_status |= TLS_CERT_FLAG_MATCHED;
|
||||
if (verbose)
|
||||
@ -732,16 +709,19 @@ static void verify_extract_name(TLS_SESS_STATE *TLScontext, X509 *peercert,
|
||||
TLScontext->peer_CN = tls_peer_CN(peercert, TLScontext);
|
||||
|
||||
/*
|
||||
* Give them a clue. Problems with trust chain verification were logged
|
||||
* when the session was first negotiated, before the session was stored
|
||||
* Give them a clue. Problems with trust chain verification are logged
|
||||
* when the session is first negotiated, before the session is stored
|
||||
* into the cache. We don't want mystery failures, so log the fact the
|
||||
* real problem is to be found in the past.
|
||||
*/
|
||||
if (TLScontext->session_reused
|
||||
&& !TLS_CERT_IS_TRUSTED(TLScontext)
|
||||
&& (TLScontext->log_mask & TLS_LOG_UNTRUSTED))
|
||||
msg_info("%s: re-using session with untrusted certificate, "
|
||||
"look for details earlier in the log", props->namaddr);
|
||||
if (!TLS_CERT_IS_TRUSTED(TLScontext)
|
||||
&& (TLScontext->log_mask & TLS_LOG_UNTRUSTED)) {
|
||||
if (TLScontext->session_reused == 0)
|
||||
tls_log_verify_error(TLScontext);
|
||||
else
|
||||
msg_info("%s: re-using session with untrusted certificate, "
|
||||
"look for details earlier in the log", props->namaddr);
|
||||
}
|
||||
}
|
||||
|
||||
/* verify_extract_print - extract and verify peer fingerprint */
|
||||
@ -749,25 +729,22 @@ static void verify_extract_name(TLS_SESS_STATE *TLScontext, X509 *peercert,
|
||||
static void verify_extract_print(TLS_SESS_STATE *TLScontext, X509 *peercert,
|
||||
const TLS_CLIENT_START_PROPS *props)
|
||||
{
|
||||
char **cpp;
|
||||
|
||||
/* Non-null by contract */
|
||||
TLScontext->peer_fingerprint = tls_fingerprint(peercert, props->fpt_dgst);
|
||||
TLScontext->peer_pkey_fprint = tls_pkey_fprint(peercert, props->fpt_dgst);
|
||||
TLScontext->peer_cert_fprint = tls_cert_fprint(peercert, props->mdalg);
|
||||
TLScontext->peer_pkey_fprint = tls_pkey_fprint(peercert, props->mdalg);
|
||||
|
||||
/*
|
||||
* Compare the fingerprint against each acceptable value, ignoring
|
||||
* upper/lower case differences.
|
||||
* Whether the level is "dane" or "fingerprint" when the peer certificate
|
||||
* is matched without resorting to a separate CA, we set both the trusted
|
||||
* and matched bits. This simplifies logic in smtp_proto.c where "dane"
|
||||
* must be trusted and matched, since some "dane" TLSA RRsets do use CAs.
|
||||
*
|
||||
* This also suppresses spurious logging of the peer certificate as
|
||||
* untrusted in verify_extract_name().
|
||||
*/
|
||||
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 (TLS_DANE_HASEE(props->dane)
|
||||
&& tls_dane_match(TLScontext, TLS_DANE_EE, peercert, 0))
|
||||
TLScontext->peer_status |=
|
||||
TLS_CERT_FLAG_TRUSTED | TLS_CERT_FLAG_MATCHED;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -780,19 +757,21 @@ TLS_SESS_STATE *tls_client_start(const TLS_CLIENT_START_PROPS *props)
|
||||
int sts;
|
||||
int protomask;
|
||||
const char *cipher_list;
|
||||
SSL_SESSION *session;
|
||||
const SSL_CIPHER *cipher;
|
||||
SSL_SESSION *session = 0;
|
||||
SSL_CIPHER_const SSL_CIPHER *cipher;
|
||||
X509 *peercert;
|
||||
TLS_SESS_STATE *TLScontext;
|
||||
TLS_APPL_STATE *app_ctx = props->ctx;
|
||||
VSTRING *myserverid;
|
||||
char *myserverid;
|
||||
int log_mask = app_ctx->log_mask;
|
||||
|
||||
/*
|
||||
* When certificate verification is required, log trust chain validation
|
||||
* errors even when disabled by default for opportunistic sessions.
|
||||
* errors even when disabled by default for opportunistic sessions. For
|
||||
* "dane" this only applies when using trust-anchor associations.
|
||||
*/
|
||||
if (props->tls_level >= TLS_LEV_VERIFY)
|
||||
if (TLS_MUST_TRUST(props->tls_level)
|
||||
&& (props->tls_level != TLS_LEV_DANE || TLS_DANE_HASTA(props->dane)))
|
||||
log_mask |= TLS_LOG_UNTRUSTED;
|
||||
|
||||
if (log_mask & TLS_LOG_VERBOSE)
|
||||
@ -801,19 +780,8 @@ TLS_SESS_STATE *tls_client_start(const TLS_CLIENT_START_PROPS *props)
|
||||
/*
|
||||
* First make sure we have valid protocol and cipher parameters
|
||||
*
|
||||
* The cipherlist will be applied to the global SSL context, where it can be
|
||||
* repeatedly reset if necessary, but the protocol restrictions will be
|
||||
* is applied to the SSL connection, because protocol restrictions in the
|
||||
* global context cannot be cleared.
|
||||
*/
|
||||
|
||||
/*
|
||||
* OpenSSL will ignore cached sessions that use the wrong protocol. So we
|
||||
* do not need to filter out cached sessions with the "wrong" protocol,
|
||||
* rather OpenSSL will simply negotiate a new session.
|
||||
*
|
||||
* Still, we salt the session lookup key with the protocol list, so that
|
||||
* sessions found in the cache are always acceptable.
|
||||
* Per-session protocol restrictions must be applied to the SSL connection,
|
||||
* as restrictions in the global context cannot be cleared.
|
||||
*/
|
||||
protomask = tls_protocol_mask(props->protocols);
|
||||
if (protomask == TLS_PROTOCOL_INVALID) {
|
||||
@ -822,35 +790,51 @@ TLS_SESS_STATE *tls_client_start(const TLS_CLIENT_START_PROPS *props)
|
||||
props->namaddr, props->protocols);
|
||||
return (0);
|
||||
}
|
||||
myserverid = vstring_alloc(100);
|
||||
vstring_sprintf_append(myserverid, "%s&p=%d", props->serverid, protomask);
|
||||
/* The DANE level requires SSLv3 or later, not SSLv2. */
|
||||
if (props->tls_level == TLS_LEV_DANE)
|
||||
protomask |= TLS_PROTOCOL_SSLv2;
|
||||
|
||||
/*
|
||||
* Per session cipher selection for sessions with mandatory encryption
|
||||
*
|
||||
* By the time a TLS client is negotiating ciphers it has already offered to
|
||||
* re-use a session, it is too late to renege on the offer. So we must
|
||||
* not attempt to re-use sessions whose ciphers are too weak. We salt the
|
||||
* session lookup key with the cipher list, so that sessions found in the
|
||||
* cache are always acceptable.
|
||||
* The cipherlist is applied to the global SSL context, since it is likely
|
||||
* to stay the same between connections, so we make use of a 1-element
|
||||
* cache to return the same result for identical inputs.
|
||||
*/
|
||||
cipher_list = tls_set_ciphers(app_ctx, "TLS", props->cipher_grade,
|
||||
props->cipher_exclusions);
|
||||
if (cipher_list == 0) {
|
||||
msg_warn("%s: %s: aborting TLS session",
|
||||
props->namaddr, vstring_str(app_ctx->why));
|
||||
vstring_free(myserverid);
|
||||
return (0);
|
||||
}
|
||||
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);
|
||||
|
||||
/*
|
||||
* Finally, salt the session key with the OpenSSL library version,
|
||||
* (run-time, rather than compile-time, just in case that matters).
|
||||
* OpenSSL will ignore cached sessions that use the wrong protocol. So we
|
||||
* do not need to filter out cached sessions with the "wrong" protocol,
|
||||
* rather OpenSSL will simply negotiate a new session.
|
||||
*
|
||||
* We salt the session lookup key with the protocol list, so that sessions
|
||||
* found in the cache are plausibly acceptable.
|
||||
*
|
||||
* By the time a TLS client is negotiating ciphers it has already offered to
|
||||
* re-use a session, it is too late to renege on the offer. So we must
|
||||
* not attempt to re-use sessions whose ciphers are too weak. We salt the
|
||||
* session lookup key with the cipher list, so that sessions found in the
|
||||
* cache are always acceptable.
|
||||
*
|
||||
* With DANE, (more generally any TLScontext where we specified explicit
|
||||
* trust-anchor or end-entity certificates) the verification status of
|
||||
* the SSL session depends on the specified list. Since we verify the
|
||||
* certificate only during the initial handshake, we must segregate
|
||||
* sessions with different TA lists. Note, that TA re-verification is
|
||||
* not possible with cached sessions, since these don't hold the complete
|
||||
* peer trust chain. Therefore, we compute a digest of the sorted TA
|
||||
* parameters and append it to the serverid.
|
||||
*/
|
||||
vstring_sprintf_append(myserverid, "&l=%ld", (long) SSLeay());
|
||||
myserverid = tls_serverid_digest(props, protomask, cipher_list);
|
||||
|
||||
/*
|
||||
* Allocate a new TLScontext for the new connection and get an SSL
|
||||
@ -863,8 +847,12 @@ TLS_SESS_STATE *tls_client_start(const TLS_CLIENT_START_PROPS *props)
|
||||
TLScontext = tls_alloc_sess_context(log_mask, props->namaddr);
|
||||
TLScontext->cache_type = app_ctx->cache_type;
|
||||
|
||||
TLScontext->serverid = vstring_export(myserverid);
|
||||
TLScontext->serverid = myserverid;
|
||||
TLScontext->stream = props->stream;
|
||||
TLScontext->mdalg = props->mdalg;
|
||||
|
||||
/* Alias DANE digest info from props */
|
||||
TLScontext->dane = props->dane;
|
||||
|
||||
if ((TLScontext->con = SSL_new(app_ctx->ssl_ctx)) == NULL) {
|
||||
msg_warn("Could not allocate 'TLScontext->con' with SSL_new()");
|
||||
@ -883,12 +871,7 @@ TLS_SESS_STATE *tls_client_start(const TLS_CLIENT_START_PROPS *props)
|
||||
* Apply session protocol restrictions.
|
||||
*/
|
||||
if (protomask != 0)
|
||||
SSL_set_options(TLScontext->con,
|
||||
((protomask & TLS_PROTOCOL_TLSv1) ? SSL_OP_NO_TLSv1 : 0L)
|
||||
| ((protomask & TLS_PROTOCOL_TLSv1_1) ? SSL_OP_NO_TLSv1_1 : 0L)
|
||||
| ((protomask & TLS_PROTOCOL_TLSv1_2) ? SSL_OP_NO_TLSv1_2 : 0L)
|
||||
| ((protomask & TLS_PROTOCOL_SSLv3) ? SSL_OP_NO_SSLv3 : 0L)
|
||||
| ((protomask & TLS_PROTOCOL_SSLv2) ? SSL_OP_NO_SSLv2 : 0L));
|
||||
SSL_set_options(TLScontext->con, TLS_SSL_OP_PROTOMASK(protomask));
|
||||
|
||||
/*
|
||||
* XXX To avoid memory leaks we must always call SSL_SESSION_free() after
|
||||
@ -900,24 +883,38 @@ TLS_SESS_STATE *tls_client_start(const TLS_CLIENT_START_PROPS *props)
|
||||
if (session) {
|
||||
SSL_set_session(TLScontext->con, session);
|
||||
SSL_SESSION_free(session); /* 200411 */
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x00906011L) || (OPENSSL_VERSION_NUMBER == 0x00907000L)
|
||||
|
||||
/*
|
||||
* Ugly Hack: OpenSSL before 0.9.6a does not store the verify
|
||||
* result in sessions for the client side. We modify the session
|
||||
* directly which is version specific, but this bug is version
|
||||
* specific, too.
|
||||
*
|
||||
* READ: 0-09-06-01-1 = 0-9-6-a-beta1: all versions before beta1
|
||||
* have this bug, it has been fixed during development of 0.9.6a.
|
||||
* The development version of 0.9.7 can have this bug, too. It
|
||||
* has been fixed on 2000/11/29.
|
||||
*/
|
||||
SSL_set_verify_result(TLScontext->con, session->verify_result);
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
#ifdef TLSEXT_MAXLEN_host_name
|
||||
if (props->tls_level == TLS_LEV_DANE
|
||||
&& strlen(props->host) <= TLSEXT_MAXLEN_host_name) {
|
||||
|
||||
/*
|
||||
* With DANE sessions, send an SNI hint. We don't care whether the
|
||||
* server reports finding a matching certificate or not, so no
|
||||
* callback is required to process the server response. Our use of
|
||||
* SNI is limited to giving servers that are (mis)configured to use
|
||||
* SNI the best opportunity to find the certificate they promised via
|
||||
* the associated TLSA RRs. (Generally, server administrators should
|
||||
* avoid SNI, and there are no plans to support SNI in the Postfix
|
||||
* SMTP server).
|
||||
*
|
||||
* Since the hostname is DNSSEC-validated, it must be a DNS FQDN and
|
||||
* thererefore valid for use with SNI. Failure to set a valid SNI
|
||||
* hostname is a memory allocation error, and thus transient. Since
|
||||
* we must not cache the session if we failed to send the SNI name,
|
||||
* we have little choice but to abort.
|
||||
*/
|
||||
if (!SSL_set_tlsext_host_name(TLScontext->con, props->host)) {
|
||||
msg_warn("%s: error setting SNI hostname to: %s", props->namaddr,
|
||||
props->host);
|
||||
tls_free_context(TLScontext);
|
||||
return (0);
|
||||
}
|
||||
if (log_mask & TLS_LOG_DEBUG)
|
||||
msg_info("%s: SNI hostname: %s", props->namaddr, props->host);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Before really starting anything, try to seed the PRNG a little bit
|
||||
@ -962,6 +959,8 @@ TLS_SESS_STATE *tls_client_start(const TLS_CLIENT_START_PROPS *props)
|
||||
if (log_mask & TLS_LOG_TLSPKTS)
|
||||
BIO_set_callback(SSL_get_rbio(TLScontext->con), tls_bio_dump_cb);
|
||||
|
||||
tls_dane_set_callback(app_ctx->ssl_ctx, TLScontext);
|
||||
|
||||
/*
|
||||
* Start TLS negotiations. This process is a black box that invokes our
|
||||
* call-backs for certificate verification.
|
||||
@ -1006,23 +1005,25 @@ TLS_SESS_STATE *tls_client_start(const TLS_CLIENT_START_PROPS *props)
|
||||
|
||||
/*
|
||||
* Peer name or fingerprint verification as requested.
|
||||
* Unconditionally set peer_CN, issuer_CN and peer_fingerprint.
|
||||
* Unconditionally set peer_CN, issuer_CN and peer_cert_fprint. Check
|
||||
* fingerprint first, and avoid logging verified as untrusted in the
|
||||
* call to verify_extract_name().
|
||||
*/
|
||||
verify_extract_name(TLScontext, peercert, props);
|
||||
verify_extract_print(TLScontext, peercert, props);
|
||||
verify_extract_name(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_cert_fprint,
|
||||
TLScontext->peer_pkey_fprint);
|
||||
X509_free(peercert);
|
||||
} else {
|
||||
TLScontext->issuer_CN = mystrdup("");
|
||||
TLScontext->peer_CN = mystrdup("");
|
||||
TLScontext->peer_fingerprint = mystrdup("");
|
||||
TLScontext->peer_cert_fprint = mystrdup("");
|
||||
TLScontext->peer_pkey_fprint = mystrdup("");
|
||||
}
|
||||
|
||||
@ -1046,7 +1047,9 @@ TLS_SESS_STATE *tls_client_start(const TLS_CLIENT_START_PROPS *props)
|
||||
*/
|
||||
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" :
|
||||
"(%d/%d bits)",
|
||||
!TLS_CERT_IS_PRESENT(TLScontext) ? "Anonymous" :
|
||||
TLS_CERT_IS_MATCHED(TLScontext) ? "Verified" :
|
||||
TLS_CERT_IS_TRUSTED(TLScontext) ? "Trusted" : "Untrusted",
|
||||
props->namaddr, TLScontext->protocol, TLScontext->cipher_name,
|
||||
TLScontext->cipher_usebits, TLScontext->cipher_algbits);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: tls_server.c,v 1.7 2013/09/25 19:12:35 tron Exp $ */
|
||||
/* $NetBSD: tls_server.c,v 1.8 2014/07/06 19:45:50 tron Exp $ */
|
||||
|
||||
/*++
|
||||
/* NAME
|
||||
@ -72,7 +72,7 @@
|
||||
/* .IP TLScontext->issuer_CN
|
||||
/* Extracted CommonName of the issuer, or zero-length string
|
||||
/* when information could not be extracted.
|
||||
/* .IP TLScontext->peer_fingerprint
|
||||
/* .IP TLScontext->peer_cert_fprint
|
||||
/* Fingerprint of the certificate, or zero-length string when no peer
|
||||
/* certificate is available.
|
||||
/* .PP
|
||||
@ -185,8 +185,8 @@ static SSL_SESSION *get_server_session_cb(SSL *ssl, unsigned char *session_id,
|
||||
do { \
|
||||
buf = vstring_alloc(2 * (len + strlen(service))); \
|
||||
hex_encode(buf, (char *) (id), (len)); \
|
||||
vstring_sprintf_append(buf, "&s=%s", (service)); \
|
||||
vstring_sprintf_append(buf, "&l=%ld", (long) SSLeay()); \
|
||||
vstring_sprintf_append(buf, "&s=%s", (service)); \
|
||||
vstring_sprintf_append(buf, "&l=%ld", (long) SSLeay()); \
|
||||
} while (0)
|
||||
|
||||
|
||||
@ -278,6 +278,53 @@ static int new_server_session_cb(SSL *ssl, SSL_SESSION *session)
|
||||
return (1);
|
||||
}
|
||||
|
||||
#define NOENGINE ((ENGINE *) 0)
|
||||
#define TLS_TKT_NOKEYS -1 /* No keys for encryption */
|
||||
#define TLS_TKT_STALE 0 /* No matching keys for decryption */
|
||||
#define TLS_TKT_ACCEPT 1 /* Ticket decryptable and re-usable */
|
||||
#define TLS_TKT_REISSUE 2 /* Ticket decryptable, not re-usable */
|
||||
|
||||
/* ticket_cb - configure tls session ticket encrypt/decrypt context */
|
||||
|
||||
#if defined(SSL_OP_NO_TICKET) \
|
||||
&& !defined(OPENSSL_NO_TLSEXT) \
|
||||
&& OPENSSL_VERSION_NUMBER >= 0x0090808fL
|
||||
|
||||
static int ticket_cb(SSL *con, unsigned char name[], unsigned char iv[],
|
||||
EVP_CIPHER_CTX * ctx, HMAC_CTX * hctx, int create)
|
||||
{
|
||||
static const EVP_MD *sha256;
|
||||
static const EVP_CIPHER *aes128;
|
||||
TLS_TICKET_KEY *key;
|
||||
TLS_SESS_STATE *TLScontext = SSL_get_ex_data(con, TLScontext_index);
|
||||
int timeout = ((int) SSL_CTX_get_timeout(SSL_get_SSL_CTX(con))) / 2;
|
||||
|
||||
if ((!sha256 && (sha256 = EVP_sha256()) == 0)
|
||||
|| (!aes128 && (aes128 = EVP_aes_128_cbc()) == 0)
|
||||
|| (key = tls_mgr_key(create ? 0 : name, timeout)) == 0
|
||||
|| (create && RAND_bytes(iv, TLS_TICKET_IVLEN) <= 0))
|
||||
return (create ? TLS_TKT_NOKEYS : TLS_TKT_STALE);
|
||||
|
||||
HMAC_Init_ex(hctx, key->hmac, TLS_TICKET_MACLEN, sha256, NOENGINE);
|
||||
|
||||
if (create) {
|
||||
EVP_EncryptInit_ex(ctx, aes128, NOENGINE, key->bits, iv);
|
||||
memcpy((char *) name, (char *) key->name, TLS_TICKET_NAMELEN);
|
||||
if (TLScontext->log_mask & TLS_LOG_CACHE)
|
||||
msg_info("%s: Issuing session ticket, key expiration: %ld",
|
||||
TLScontext->namaddr, (long) key->tout);
|
||||
} else {
|
||||
EVP_DecryptInit_ex(ctx, aes128, NOENGINE, key->bits, iv);
|
||||
if (TLScontext->log_mask & TLS_LOG_CACHE)
|
||||
msg_info("%s: Decrypting session ticket, key expiration: %ld",
|
||||
TLScontext->namaddr, (long) key->tout);
|
||||
}
|
||||
TLScontext->ticketed = 1;
|
||||
return (TLS_TKT_ACCEPT);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* tls_server_init - initialize the server-side TLS engine */
|
||||
|
||||
TLS_APPL_STATE *tls_server_init(const TLS_SERVER_INIT_PROPS *props)
|
||||
@ -286,10 +333,10 @@ TLS_APPL_STATE *tls_server_init(const TLS_SERVER_INIT_PROPS *props)
|
||||
long off = 0;
|
||||
int verify_flags = SSL_VERIFY_NONE;
|
||||
int cachable;
|
||||
int scache_timeout;
|
||||
int ticketable = 0;
|
||||
int protomask;
|
||||
TLS_APPL_STATE *app_ctx;
|
||||
const EVP_MD *md_alg;
|
||||
unsigned int md_len;
|
||||
int log_mask;
|
||||
|
||||
/*
|
||||
@ -342,40 +389,12 @@ TLS_APPL_STATE *tls_server_init(const TLS_SERVER_INIT_PROPS *props)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Register SHA-2 digests, if implemented and not already registered.
|
||||
* Improves interoperability with clients and servers that prematurely
|
||||
* deploy SHA-2 certificates.
|
||||
*/
|
||||
#if defined(LN_sha256) && defined(NID_sha256) && !defined(OPENSSL_NO_SHA256)
|
||||
if (!EVP_get_digestbyname(LN_sha224))
|
||||
EVP_add_digest(EVP_sha224());
|
||||
if (!EVP_get_digestbyname(LN_sha256))
|
||||
EVP_add_digest(EVP_sha256());
|
||||
#endif
|
||||
#if defined(LN_sha512) && defined(NID_sha512) && !defined(OPENSSL_NO_SHA512)
|
||||
if (!EVP_get_digestbyname(LN_sha384))
|
||||
EVP_add_digest(EVP_sha384());
|
||||
if (!EVP_get_digestbyname(LN_sha512))
|
||||
EVP_add_digest(EVP_sha512());
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If the administrator specifies an unsupported digest algorithm, fail
|
||||
* now, rather than in the middle of a TLS handshake.
|
||||
*/
|
||||
if ((md_alg = EVP_get_digestbyname(props->fpt_dgst)) == 0) {
|
||||
msg_warn("Digest algorithm \"%s\" not found: disabling TLS support",
|
||||
props->fpt_dgst);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sanity check: Newer shared libraries may use larger digests.
|
||||
*/
|
||||
if ((md_len = EVP_MD_size(md_alg)) > EVP_MAX_MD_SIZE) {
|
||||
msg_warn("Digest algorithm \"%s\" output size %u too large:"
|
||||
" disabling TLS support", props->fpt_dgst, md_len);
|
||||
if (!tls_validate_digest(props->mdalg)) {
|
||||
msg_warn("disabling TLS support");
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -412,13 +431,42 @@ TLS_APPL_STATE *tls_server_init(const TLS_SERVER_INIT_PROPS *props)
|
||||
*/
|
||||
SSL_CTX_set_verify_depth(server_ctx, props->verifydepth + 1);
|
||||
|
||||
/*
|
||||
* The session cache is implemented by the tlsmgr(8) server.
|
||||
*
|
||||
* XXX 200502 Surprise: when OpenSSL purges an entry from the in-memory
|
||||
* cache, it also attempts to purge the entry from the on-disk cache.
|
||||
* This is undesirable, especially when we set the in-memory cache size
|
||||
* to 1. For this reason we don't allow OpenSSL to purge on-disk cache
|
||||
* entries, and leave it up to the tlsmgr process instead. Found by
|
||||
* Victor Duchovni.
|
||||
*/
|
||||
if (tls_mgr_policy(props->cache_type, &cachable,
|
||||
&scache_timeout) != TLS_MGR_STAT_OK)
|
||||
scache_timeout = 0;
|
||||
if (scache_timeout <= 0)
|
||||
cachable = 0;
|
||||
|
||||
/*
|
||||
* Protocol work-arounds, OpenSSL version dependent.
|
||||
*/
|
||||
#ifdef SSL_OP_NO_TICKET
|
||||
off |= SSL_OP_NO_TICKET;
|
||||
#endif
|
||||
off |= tls_bug_bits();
|
||||
|
||||
/*
|
||||
* Add SSL_OP_NO_TICKET when the timeout is zero or library support is
|
||||
* incomplete. The SSL_CTX_set_tlsext_ticket_key_cb feature was added in
|
||||
* OpenSSL 0.9.8h, while SSL_NO_TICKET was added in 0.9.8f.
|
||||
*/
|
||||
#ifdef SSL_OP_NO_TICKET
|
||||
#if !defined(OPENSSL_NO_TLSEXT) && OPENSSL_VERSION_NUMBER >= 0x0090808fL
|
||||
ticketable = (scache_timeout > 0 && !(off & SSL_OP_NO_TICKET));
|
||||
if (ticketable)
|
||||
SSL_CTX_set_tlsext_ticket_key_cb(server_ctx, ticket_cb);
|
||||
#endif
|
||||
if (!ticketable)
|
||||
off |= SSL_OP_NO_TICKET;
|
||||
#endif
|
||||
|
||||
SSL_CTX_set_options(server_ctx, off);
|
||||
|
||||
/*
|
||||
@ -432,8 +480,6 @@ TLS_APPL_STATE *tls_server_init(const TLS_SERVER_INIT_PROPS *props)
|
||||
| ((protomask & TLS_PROTOCOL_SSLv3) ? SSL_OP_NO_SSLv3 : 0L)
|
||||
| ((protomask & TLS_PROTOCOL_SSLv2) ? SSL_OP_NO_SSLv2 : 0L));
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x0090700fL
|
||||
|
||||
/*
|
||||
* Some sites may want to give the client less rope. On the other hand,
|
||||
* this could trigger inter-operability issues, the client should not
|
||||
@ -445,7 +491,6 @@ TLS_APPL_STATE *tls_server_init(const TLS_SERVER_INIT_PROPS *props)
|
||||
*/
|
||||
if (var_tls_preempt_clist)
|
||||
SSL_CTX_set_options(server_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set the call-back routine to debug handshake progress.
|
||||
@ -556,21 +601,7 @@ TLS_APPL_STATE *tls_server_init(const TLS_SERVER_INIT_PROPS *props)
|
||||
*/
|
||||
app_ctx = tls_alloc_app_context(server_ctx, log_mask);
|
||||
|
||||
/*
|
||||
* The session cache is implemented by the tlsmgr(8) server.
|
||||
*
|
||||
* XXX 200502 Surprise: when OpenSSL purges an entry from the in-memory
|
||||
* cache, it also attempts to purge the entry from the on-disk cache.
|
||||
* This is undesirable, especially when we set the in-memory cache size
|
||||
* to 1. For this reason we don't allow OpenSSL to purge on-disk cache
|
||||
* entries, and leave it up to the tlsmgr process instead. Found by
|
||||
* Victor Duchovni.
|
||||
*/
|
||||
|
||||
if (tls_mgr_policy(props->cache_type, &cachable) != TLS_MGR_STAT_OK)
|
||||
cachable = 0;
|
||||
|
||||
if (cachable || props->set_sessid) {
|
||||
if (cachable || ticketable || props->set_sessid) {
|
||||
|
||||
/*
|
||||
* Initialize the session cache.
|
||||
@ -607,9 +638,14 @@ TLS_APPL_STATE *tls_server_init(const TLS_SERVER_INIT_PROPS *props)
|
||||
/*
|
||||
* OpenSSL ignores timed-out sessions. We need to set the internal
|
||||
* cache timeout at least as high as the external cache timeout. This
|
||||
* applies even if no internal cache is used.
|
||||
* applies even if no internal cache is used. We set the session
|
||||
* lifetime to twice the cache lifetime, which is also the issuing
|
||||
* and retired key validation lifetime of session tickets keys. This
|
||||
* way a session always lasts longer than the server's ability to
|
||||
* decrypt its session ticket. Otherwise, a bug in OpenSSL may fail
|
||||
* to re-issue tickets when sessions decrypt, but are expired.
|
||||
*/
|
||||
SSL_CTX_set_timeout(server_ctx, props->scache_timeout);
|
||||
SSL_CTX_set_timeout(server_ctx, 2 * scache_timeout);
|
||||
} else {
|
||||
|
||||
/*
|
||||
@ -666,9 +702,8 @@ TLS_SESS_STATE *tls_server_start(const TLS_SERVER_START_PROPS *props)
|
||||
|
||||
TLScontext->serverid = mystrdup(props->serverid);
|
||||
TLScontext->am_server = 1;
|
||||
|
||||
TLScontext->fpt_dgst = mystrdup(props->fpt_dgst);
|
||||
TLScontext->stream = props->stream;
|
||||
TLScontext->mdalg = props->mdalg;
|
||||
|
||||
ERR_clear_error();
|
||||
if ((TLScontext->con = (SSL *) SSL_new(app_ctx->ssl_ctx)) == 0) {
|
||||
@ -764,7 +799,7 @@ TLS_SESS_STATE *tls_server_start(const TLS_SERVER_START_PROPS *props)
|
||||
|
||||
TLS_SESS_STATE *tls_server_post_accept(TLS_SESS_STATE *TLScontext)
|
||||
{
|
||||
const SSL_CIPHER *cipher;
|
||||
SSL_CIPHER_const SSL_CIPHER *cipher;
|
||||
X509 *peer;
|
||||
char buf[CCERT_BUFSIZ];
|
||||
|
||||
@ -778,7 +813,8 @@ TLS_SESS_STATE *tls_server_post_accept(TLS_SESS_STATE *TLScontext)
|
||||
*/
|
||||
TLScontext->session_reused = SSL_session_reused(TLScontext->con);
|
||||
if ((TLScontext->log_mask & TLS_LOG_CACHE) && TLScontext->session_reused)
|
||||
msg_info("%s: Reusing old session", TLScontext->namaddr);
|
||||
msg_info("%s: Reusing old session%s", TLScontext->namaddr,
|
||||
TLScontext->ticketed ? " (RFC 5077 session ticket)" : "");
|
||||
|
||||
/*
|
||||
* Let's see whether a peer certificate is available and what is the
|
||||
@ -800,24 +836,23 @@ TLS_SESS_STATE *tls_server_post_accept(TLS_SESS_STATE *TLScontext)
|
||||
}
|
||||
TLScontext->peer_CN = tls_peer_CN(peer, 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);
|
||||
TLScontext->peer_cert_fprint = tls_cert_fprint(peer, TLScontext->mdalg);
|
||||
TLScontext->peer_pkey_fprint = tls_pkey_fprint(peer, TLScontext->mdalg);
|
||||
|
||||
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,
|
||||
TLScontext->peer_CN, TLScontext->issuer_CN,
|
||||
TLScontext->peer_fingerprint,
|
||||
TLScontext->peer_cert_fprint,
|
||||
TLScontext->peer_pkey_fprint);
|
||||
}
|
||||
X509_free(peer);
|
||||
} else {
|
||||
TLScontext->peer_CN = mystrdup("");
|
||||
TLScontext->issuer_CN = mystrdup("");
|
||||
TLScontext->peer_fingerprint = mystrdup("");
|
||||
TLScontext->peer_cert_fprint = mystrdup("");
|
||||
TLScontext->peer_pkey_fprint = mystrdup("");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: dict_sockmap.c,v 1.3 2013/11/14 02:27:29 christos Exp $ */
|
||||
/* $NetBSD: dict_sockmap.c,v 1.4 2014/07/06 19:45:50 tron Exp $ */
|
||||
|
||||
/*++
|
||||
/* NAME
|
||||
@ -311,36 +311,44 @@ static void dict_sockmap_close(DICT *dict)
|
||||
DICT *dict_sockmap_open(const char *mapname, int open_flags, int dict_flags)
|
||||
{
|
||||
DICT_SOCKMAP *dp;
|
||||
char *saved_name;
|
||||
char *saved_name = 0;
|
||||
char *sockmap;
|
||||
DICT_SOCKMAP_REFC_HANDLE *ref_handle;
|
||||
HTABLE_INFO *client_info;
|
||||
|
||||
/*
|
||||
* Let the optimizer worry about eliminating redundant code.
|
||||
*/
|
||||
#define DICT_SOCKMAP_OPEN_RETURN(d) { \
|
||||
DICT *__d = (d); \
|
||||
if (saved_name != 0) \
|
||||
myfree(saved_name); \
|
||||
return (__d); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Sanity checks.
|
||||
*/
|
||||
if (open_flags != O_RDONLY)
|
||||
return (dict_surrogate(DICT_TYPE_SOCKMAP, mapname,
|
||||
open_flags, dict_flags,
|
||||
"%s:%s map requires O_RDONLY access mode",
|
||||
DICT_TYPE_SOCKMAP, mapname));
|
||||
DICT_SOCKMAP_OPEN_RETURN(dict_surrogate(DICT_TYPE_SOCKMAP, mapname,
|
||||
open_flags, dict_flags,
|
||||
"%s:%s map requires O_RDONLY access mode",
|
||||
DICT_TYPE_SOCKMAP, mapname));
|
||||
if (dict_flags & DICT_FLAG_NO_UNAUTH)
|
||||
return (dict_surrogate(DICT_TYPE_SOCKMAP, mapname,
|
||||
open_flags, dict_flags,
|
||||
DICT_SOCKMAP_OPEN_RETURN(dict_surrogate(DICT_TYPE_SOCKMAP, mapname,
|
||||
open_flags, dict_flags,
|
||||
"%s:%s map is not allowed for security-sensitive data",
|
||||
DICT_TYPE_SOCKMAP, mapname));
|
||||
DICT_TYPE_SOCKMAP, mapname));
|
||||
|
||||
/*
|
||||
* Separate the socketmap name from the socketmap server name.
|
||||
*/
|
||||
saved_name = mystrdup(mapname);
|
||||
if ((sockmap = split_at_right(saved_name, ':')) == 0) {
|
||||
myfree(saved_name);
|
||||
return (dict_surrogate(DICT_TYPE_SOCKMAP, mapname,
|
||||
open_flags, dict_flags,
|
||||
"%s requires server:socketmap argument",
|
||||
DICT_TYPE_SOCKMAP));
|
||||
}
|
||||
if ((sockmap = split_at_right(saved_name, ':')) == 0)
|
||||
DICT_SOCKMAP_OPEN_RETURN(dict_surrogate(DICT_TYPE_SOCKMAP, mapname,
|
||||
open_flags, dict_flags,
|
||||
"%s requires server:socketmap argument",
|
||||
DICT_TYPE_SOCKMAP));
|
||||
|
||||
/*
|
||||
* Use one reference-counted client handle for all socketmaps with the
|
||||
@ -374,10 +382,5 @@ DICT *dict_sockmap_open(const char *mapname, int open_flags, int dict_flags)
|
||||
/* Don't look up parent domains or network superblocks. */
|
||||
dp->dict.flags = dict_flags | DICT_FLAG_PATTERN;
|
||||
|
||||
/*
|
||||
* Clean up.
|
||||
*/
|
||||
myfree(saved_name);
|
||||
|
||||
return (DICT_DEBUG (&dp->dict));
|
||||
DICT_SOCKMAP_OPEN_RETURN(DICT_DEBUG (&dp->dict));
|
||||
}
|
||||
|
@ -1,138 +0,0 @@
|
||||
/* $NetBSD: read_wait.c,v 1.1.1.2 2010/06/17 18:07:15 tron Exp $ */
|
||||
|
||||
/*++
|
||||
/* NAME
|
||||
/* read_wait 3
|
||||
/* SUMMARY
|
||||
/* wait until descriptor becomes readable
|
||||
/* SYNOPSIS
|
||||
/* #include <iostuff.h>
|
||||
/*
|
||||
/* int read_wait(fd, timeout)
|
||||
/* int fd;
|
||||
/* int timeout;
|
||||
/* DESCRIPTION
|
||||
/* read_wait() blocks the current process until the specified file
|
||||
/* descriptor becomes readable, or until the deadline is exceeded.
|
||||
/*
|
||||
/* Arguments:
|
||||
/* .IP fd
|
||||
/* File descriptor in the range 0..FD_SETSIZE (on systems that
|
||||
/* need to use select(2)).
|
||||
/* .IP timeout
|
||||
/* If positive, deadline in seconds. A zero value effects a poll.
|
||||
/* A negative value means wait until something happens.
|
||||
/* DIAGNOSTICS
|
||||
/* Panic: interface violation. All system call errors are fatal.
|
||||
/*
|
||||
/* A zero result means success. When the specified deadline is
|
||||
/* exceeded, read_wait() returns -1 and sets errno to ETIMEDOUT.
|
||||
/* LICENSE
|
||||
/* .ad
|
||||
/* .fi
|
||||
/* The Secure Mailer license must be distributed with this software.
|
||||
/* AUTHOR(S)
|
||||
/* Wietse Venema
|
||||
/* IBM T.J. Watson Research
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*--*/
|
||||
|
||||
/* System library. */
|
||||
|
||||
#include <sys_defs.h>
|
||||
#include <sys/time.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef USE_SYSV_POLL
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_SYS_SELECT_H
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
/* Utility library. */
|
||||
|
||||
#include <msg.h>
|
||||
#include <iostuff.h>
|
||||
|
||||
/* read_wait - block with timeout until file descriptor is readable */
|
||||
|
||||
int read_wait(int fd, int timeout)
|
||||
{
|
||||
#ifndef USE_SYSV_POLL
|
||||
fd_set read_fds;
|
||||
fd_set except_fds;
|
||||
struct timeval tv;
|
||||
struct timeval *tp;
|
||||
|
||||
/*
|
||||
* Sanity checks.
|
||||
*/
|
||||
if (FD_SETSIZE <= fd)
|
||||
msg_panic("descriptor %d does not fit FD_SETSIZE %d", fd, FD_SETSIZE);
|
||||
|
||||
/*
|
||||
* Use select() so we do not depend on alarm() and on signal() handlers.
|
||||
* Restart the select when interrupted by some signal. Some select()
|
||||
* implementations reduce the time to wait when interrupted, which is
|
||||
* exactly what we want.
|
||||
*/
|
||||
FD_ZERO(&read_fds);
|
||||
FD_SET(fd, &read_fds);
|
||||
FD_ZERO(&except_fds);
|
||||
FD_SET(fd, &except_fds);
|
||||
if (timeout >= 0) {
|
||||
tv.tv_usec = 0;
|
||||
tv.tv_sec = timeout;
|
||||
tp = &tv;
|
||||
} else {
|
||||
tp = 0;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
switch (select(fd + 1, &read_fds, (fd_set *) 0, &except_fds, tp)) {
|
||||
case -1:
|
||||
if (errno != EINTR)
|
||||
msg_fatal("select: %m");
|
||||
continue;
|
||||
case 0:
|
||||
errno = ETIMEDOUT;
|
||||
return (-1);
|
||||
default:
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
/*
|
||||
* System-V poll() is optimal for polling a few descriptors.
|
||||
*/
|
||||
struct pollfd pollfd;
|
||||
|
||||
#define WAIT_FOR_EVENT (-1)
|
||||
|
||||
pollfd.fd = fd;
|
||||
pollfd.events = POLLIN;
|
||||
for (;;) {
|
||||
switch (poll(&pollfd, 1, timeout < 0 ?
|
||||
WAIT_FOR_EVENT : timeout * 1000)) {
|
||||
case -1:
|
||||
if (errno != EINTR)
|
||||
msg_fatal("poll: %m");
|
||||
continue;
|
||||
case 0:
|
||||
errno = ETIMEDOUT;
|
||||
return (-1);
|
||||
default:
|
||||
if (pollfd.revents & POLLNVAL)
|
||||
msg_fatal("poll: %m");
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
121
external/ibm-public/postfix/dist/src/util/readable.c
vendored
121
external/ibm-public/postfix/dist/src/util/readable.c
vendored
@ -1,121 +0,0 @@
|
||||
/* $NetBSD: readable.c,v 1.1.1.1 2009/06/23 10:09:00 tron Exp $ */
|
||||
|
||||
/*++
|
||||
/* NAME
|
||||
/* readable 3
|
||||
/* SUMMARY
|
||||
/* test if descriptor is readable
|
||||
/* SYNOPSIS
|
||||
/* #include <iostuff.h>
|
||||
/*
|
||||
/* int readable(fd)
|
||||
/* int fd;
|
||||
/* DESCRIPTION
|
||||
/* readable() asks the kernel if the specified file descriptor
|
||||
/* is readable, i.e. a read operation would not block.
|
||||
/*
|
||||
/* Arguments:
|
||||
/* .IP fd
|
||||
/* File descriptor in the range 0..FD_SETSIZE.
|
||||
/* DIAGNOSTICS
|
||||
/* All system call errors are fatal.
|
||||
/* LICENSE
|
||||
/* .ad
|
||||
/* .fi
|
||||
/* The Secure Mailer license must be distributed with this software.
|
||||
/* AUTHOR(S)
|
||||
/* Wietse Venema
|
||||
/* IBM T.J. Watson Research
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*--*/
|
||||
|
||||
/* System library. */
|
||||
|
||||
#include <sys_defs.h>
|
||||
#include <sys/time.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef USE_SYSV_POLL
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_SYS_SELECT_H
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
/* Utility library. */
|
||||
|
||||
#include <msg.h>
|
||||
#include <iostuff.h>
|
||||
|
||||
/* readable - see if file descriptor is readable */
|
||||
|
||||
int readable(int fd)
|
||||
{
|
||||
#ifndef USE_SYSV_POLL
|
||||
struct timeval tv;
|
||||
fd_set read_fds;
|
||||
fd_set except_fds;
|
||||
|
||||
/*
|
||||
* Sanity checks.
|
||||
*/
|
||||
if (fd >= FD_SETSIZE)
|
||||
msg_fatal("fd %d does not fit in FD_SETSIZE", fd);
|
||||
|
||||
/*
|
||||
* Initialize.
|
||||
*/
|
||||
FD_ZERO(&read_fds);
|
||||
FD_SET(fd, &read_fds);
|
||||
FD_ZERO(&except_fds);
|
||||
FD_SET(fd, &except_fds);
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
/*
|
||||
* Loop until we have an authoritative answer.
|
||||
*/
|
||||
for (;;) {
|
||||
switch (select(fd + 1, &read_fds, (fd_set *) 0, &except_fds, &tv)) {
|
||||
case -1:
|
||||
if (errno != EINTR)
|
||||
msg_fatal("select: %m");
|
||||
continue;
|
||||
default:
|
||||
return (FD_ISSET(fd, &read_fds));
|
||||
case 0:
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
/*
|
||||
* System-V poll() is optimal for polling a few descriptors.
|
||||
*/
|
||||
struct pollfd pollfd;
|
||||
|
||||
#define DONT_WAIT_FOR_EVENT 0
|
||||
|
||||
pollfd.fd = fd;
|
||||
pollfd.events = POLLIN;
|
||||
for (;;) {
|
||||
switch (poll(&pollfd, 1, DONT_WAIT_FOR_EVENT)) {
|
||||
case -1:
|
||||
if (errno != EINTR)
|
||||
msg_fatal("poll: %m");
|
||||
continue;
|
||||
case 0:
|
||||
return (0);
|
||||
default:
|
||||
if (pollfd.revents & POLLNVAL)
|
||||
msg_fatal("poll: %m");
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
137
external/ibm-public/postfix/dist/src/util/sys_defs.h
vendored
137
external/ibm-public/postfix/dist/src/util/sys_defs.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: sys_defs.h,v 1.6 2013/09/25 19:12:35 tron Exp $ */
|
||||
/* $NetBSD: sys_defs.h,v 1.7 2014/07/06 19:45:51 tron Exp $ */
|
||||
|
||||
#ifndef _SYS_DEFS_H_INCLUDED_
|
||||
#define _SYS_DEFS_H_INCLUDED_
|
||||
@ -32,8 +32,8 @@
|
||||
|| defined(OPENBSD2) || defined(OPENBSD3) || defined(OPENBSD4) \
|
||||
|| defined(OPENBSD5) \
|
||||
|| defined(NETBSD1) || defined(NETBSD2) || defined(NETBSD3) \
|
||||
|| defined(NETBSD4) \
|
||||
|| defined(EKKOBSD1)
|
||||
|| defined(NETBSD4) || defined(NETBSD5) || defined(NETBSD6) \
|
||||
|| defined(EKKOBSD1) || defined(DRAGONFLY)
|
||||
#define SUPPORTED
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
@ -48,15 +48,15 @@
|
||||
#define HAS_FSYNC
|
||||
#define HAS_DB
|
||||
#define HAS_SA_LEN
|
||||
#define DEF_DB_TYPE "hash"
|
||||
#define NATIVE_DB_TYPE "hash"
|
||||
#if (defined(__NetBSD_Version__) && __NetBSD_Version__ >= 104250000)
|
||||
#define ALIAS_DB_MAP "hash:/etc/mail/aliases" /* sendmail 8.10 */
|
||||
#define ALIAS_DB_MAP DEF_DB_TYPE ":/etc/mail/aliases" /* sendmail 8.10 */
|
||||
#endif
|
||||
#if (defined(OpenBSD) && OpenBSD >= 200006)
|
||||
#define ALIAS_DB_MAP "hash:/etc/mail/aliases" /* OpenBSD 2.7 */
|
||||
#define ALIAS_DB_MAP DEF_DB_TYPE ":/etc/mail/aliases" /* OpenBSD 2.7 */
|
||||
#endif
|
||||
#ifndef ALIAS_DB_MAP
|
||||
#define ALIAS_DB_MAP "hash:/etc/aliases"
|
||||
#define ALIAS_DB_MAP DEF_DB_TYPE ":/etc/aliases"
|
||||
#endif
|
||||
#define GETTIMEOFDAY(t) gettimeofday(t,(struct timezone *) 0)
|
||||
#define ROOT_PATH "/bin:/usr/bin:/sbin:/usr/sbin"
|
||||
@ -167,9 +167,19 @@
|
||||
#define HAS_FUTIMES
|
||||
#endif
|
||||
|
||||
#if defined(__DragonFly__)
|
||||
#define HAS_DEV_URANDOM
|
||||
#define HAS_ISSETUGID
|
||||
#define HAS_FUTIMES
|
||||
#define SOCKADDR_SIZE socklen_t
|
||||
#define SOCKOPT_SIZE socklen_t
|
||||
#define HAS_DUPLEX_PIPE
|
||||
#endif
|
||||
|
||||
#if (defined(__NetBSD_Version__) && __NetBSD_Version__ >= 105000000) \
|
||||
|| (defined(__FreeBSD__) && __FreeBSD__ >= 4) \
|
||||
|| (defined(OpenBSD) && OpenBSD >= 200003) \
|
||||
|| defined(__DragonFly__) \
|
||||
|| defined(USAGI_LIBINET6)
|
||||
#ifndef NO_IPV6
|
||||
# define HAS_IPV6
|
||||
@ -178,14 +188,16 @@
|
||||
|
||||
#if (defined(__FreeBSD_version) && __FreeBSD_version >= 300000) \
|
||||
|| (defined(__NetBSD_Version__) && __NetBSD_Version__ >= 103000000) \
|
||||
|| (defined(OpenBSD) && OpenBSD >= 199700) /* OpenBSD 2.0?? */
|
||||
|| (defined(OpenBSD) && OpenBSD >= 199700) /* OpenBSD 2.0?? */ \
|
||||
|| defined(__DragonFly__)
|
||||
# define USE_SYSV_POLL
|
||||
#endif
|
||||
|
||||
#ifndef NO_KQUEUE
|
||||
# if (defined(__FreeBSD_version) && __FreeBSD_version >= 410000) \
|
||||
|| (defined(__NetBSD_Version__) && __NetBSD_Version__ >= 200000000) \
|
||||
|| (defined(OpenBSD) && OpenBSD >= 200105) /* OpenBSD 2.9 */
|
||||
|| (defined(OpenBSD) && OpenBSD >= 200105) /* OpenBSD 2.9 */ \
|
||||
|| defined(__DragonFly__)
|
||||
# define EVENTS_STYLE EVENTS_STYLE_KQUEUE
|
||||
# endif
|
||||
#endif
|
||||
@ -217,8 +229,8 @@
|
||||
#define HAS_FSYNC
|
||||
#define HAS_DB
|
||||
#define HAS_SA_LEN
|
||||
#define DEF_DB_TYPE "hash"
|
||||
#define ALIAS_DB_MAP "hash:/etc/aliases"
|
||||
#define NATIVE_DB_TYPE "hash"
|
||||
#define ALIAS_DB_MAP DEF_DB_TYPE ":/etc/aliases"
|
||||
#define GETTIMEOFDAY(t) gettimeofday(t,(struct timezone *) 0)
|
||||
#define ROOT_PATH "/bin:/usr/bin:/sbin:/usr/sbin"
|
||||
#define USE_STATFS
|
||||
@ -244,8 +256,9 @@
|
||||
#define SOCKOPT_SIZE socklen_t
|
||||
#ifndef NO_KQUEUE
|
||||
# define EVENTS_STYLE EVENTS_STYLE_KQUEUE
|
||||
# define USE_SYSV_POLL
|
||||
# define USE_SYSV_POLL_THEN_SELECT
|
||||
#endif
|
||||
#define USE_MAX_FILES_PER_PROC
|
||||
#ifndef NO_POSIX_GETPW_R
|
||||
# define HAVE_POSIX_GETPW_R
|
||||
#endif
|
||||
@ -276,12 +289,12 @@
|
||||
#define HAS_FSYNC
|
||||
/* might be set by makedef */
|
||||
#ifdef HAS_DB
|
||||
#define DEF_DB_TYPE "hash"
|
||||
#define ALIAS_DB_MAP "hash:/etc/aliases"
|
||||
#define NATIVE_DB_TYPE "hash"
|
||||
#define ALIAS_DB_MAP DEF_DB_TYPE ":/etc/aliases"
|
||||
#else
|
||||
#define HAS_DBM
|
||||
#define DEF_DB_TYPE "dbm"
|
||||
#define ALIAS_DB_MAP "dbm:/etc/aliases"
|
||||
#define NATIVE_DB_TYPE "dbm"
|
||||
#define ALIAS_DB_MAP DEF_DB_TYPE ":/etc/aliases"
|
||||
#endif
|
||||
extern int optind;
|
||||
extern char *optarg;
|
||||
@ -325,8 +338,8 @@ extern int h_errno;
|
||||
#define HAS_FSYNC
|
||||
#define HAVE_BASENAME
|
||||
#define HAS_DBM
|
||||
#define DEF_DB_TYPE "dbm"
|
||||
#define ALIAS_DB_MAP "dbm:/var/adm/sendmail/aliases"
|
||||
#define NATIVE_DB_TYPE "dbm"
|
||||
#define ALIAS_DB_MAP DEF_DB_TYPE ":/var/adm/sendmail/aliases"
|
||||
extern int optind; /* XXX use <getopt.h> */
|
||||
extern char *optarg; /* XXX use <getopt.h> */
|
||||
extern int opterr; /* XXX use <getopt.h> */
|
||||
@ -372,8 +385,8 @@ extern int opterr; /* XXX use <getopt.h> */
|
||||
#define DEF_MAILBOX_LOCK "flock, dotlock"
|
||||
#define HAS_FSYNC
|
||||
#define HAS_DBM
|
||||
#define DEF_DB_TYPE "dbm"
|
||||
#define ALIAS_DB_MAP "dbm:/etc/aliases"
|
||||
#define NATIVE_DB_TYPE "dbm"
|
||||
#define ALIAS_DB_MAP DEF_DB_TYPE ":/etc/aliases"
|
||||
extern int optind;
|
||||
extern char *optarg;
|
||||
extern int opterr;
|
||||
@ -418,11 +431,13 @@ extern int opterr;
|
||||
#define DEF_MAILBOX_LOCK "fcntl, dotlock"
|
||||
#define HAS_FSYNC
|
||||
#define HAS_DBM
|
||||
#define DEF_DB_TYPE "dbm"
|
||||
#define ALIAS_DB_MAP "dbm:/etc/mail/aliases"
|
||||
#define NATIVE_DB_TYPE "dbm"
|
||||
#define ALIAS_DB_MAP DEF_DB_TYPE ":/etc/mail/aliases"
|
||||
#ifndef NO_NIS
|
||||
#define HAS_NIS
|
||||
#ifndef NO_NISPLUS
|
||||
#define HAS_NISPLUS
|
||||
#endif /* NO_NISPLUS */
|
||||
#endif
|
||||
#define USE_SYS_SOCKIO_H /* Solaris 2.5, changed sys/ioctl.h */
|
||||
#define GETTIMEOFDAY(t) gettimeofday(t)
|
||||
@ -495,8 +510,8 @@ extern int opterr;
|
||||
#define DEF_MAILBOX_LOCK "fcntl, dotlock"
|
||||
#define HAS_FSYNC
|
||||
#define HAS_DBM
|
||||
#define DEF_DB_TYPE "dbm"
|
||||
#define ALIAS_DB_MAP "dbm:/etc/mail/aliases"
|
||||
#define NATIVE_DB_TYPE "dbm"
|
||||
#define ALIAS_DB_MAP DEF_DB_TYPE ":/etc/mail/aliases"
|
||||
#ifndef NO_NIS
|
||||
#define HAS_NIS
|
||||
#endif
|
||||
@ -526,8 +541,8 @@ extern int opterr;
|
||||
#define DEF_MAILBOX_LOCK "fcntl, dotlock"
|
||||
#define HAS_FSYNC
|
||||
#define HAS_DBM
|
||||
#define DEF_DB_TYPE "dbm"
|
||||
#define ALIAS_DB_MAP "dbm:/etc/mail/aliases"
|
||||
#define NATIVE_DB_TYPE "dbm"
|
||||
#define ALIAS_DB_MAP DEF_DB_TYPE ":/etc/mail/aliases"
|
||||
#ifndef NO_NIS
|
||||
#define HAS_NIS */
|
||||
#endif
|
||||
@ -569,8 +584,8 @@ extern int opterr;
|
||||
#define USE_SYS_SELECT_H
|
||||
#define HAS_FSYNC
|
||||
#define HAS_DBM
|
||||
#define DEF_DB_TYPE "dbm"
|
||||
#define ALIAS_DB_MAP "dbm:/etc/aliases"
|
||||
#define NATIVE_DB_TYPE "dbm"
|
||||
#define ALIAS_DB_MAP DEF_DB_TYPE ":/etc/aliases"
|
||||
#ifndef NO_NIS
|
||||
#define HAS_NIS
|
||||
#endif
|
||||
@ -623,8 +638,8 @@ extern int opterr;
|
||||
#define USE_SYS_SELECT_H
|
||||
#define HAS_FSYNC
|
||||
#define HAS_DBM
|
||||
#define DEF_DB_TYPE "dbm"
|
||||
#define ALIAS_DB_MAP "dbm:/etc/aliases"
|
||||
#define NATIVE_DB_TYPE "dbm"
|
||||
#define ALIAS_DB_MAP DEF_DB_TYPE ":/etc/aliases"
|
||||
#ifndef NO_NIS
|
||||
#define HAS_NIS
|
||||
#endif
|
||||
@ -669,8 +684,8 @@ extern int initgroups(const char *, int);
|
||||
#define USE_SYS_SELECT_H
|
||||
#define HAS_FSYNC
|
||||
#define HAS_DBM
|
||||
#define DEF_DB_TYPE "dbm"
|
||||
#define ALIAS_DB_MAP "dbm:/etc/aliases"
|
||||
#define NATIVE_DB_TYPE "dbm"
|
||||
#define ALIAS_DB_MAP DEF_DB_TYPE ":/etc/aliases"
|
||||
#ifndef NO_NIS
|
||||
#define HAS_NIS
|
||||
#endif
|
||||
@ -711,8 +726,8 @@ extern int initgroups(const char *, int);
|
||||
#define DEF_MAILBOX_LOCK "fcntl, dotlock"
|
||||
#define HAS_FSYNC
|
||||
#define HAS_DBM
|
||||
#define DEF_DB_TYPE "dbm"
|
||||
#define ALIAS_DB_MAP "dbm:/etc/aliases"
|
||||
#define NATIVE_DB_TYPE "dbm"
|
||||
#define ALIAS_DB_MAP DEF_DB_TYPE ":/etc/aliases"
|
||||
#ifndef NO_NIS
|
||||
#define HAS_NIS
|
||||
#endif
|
||||
@ -755,8 +770,8 @@ extern int initgroups(const char *, int);
|
||||
#define DEF_MAILBOX_LOCK "fcntl, dotlock" /* RedHat >= 4.x */
|
||||
#define HAS_FSYNC
|
||||
#define HAS_DB
|
||||
#define DEF_DB_TYPE "hash"
|
||||
#define ALIAS_DB_MAP "hash:/etc/aliases"
|
||||
#define NATIVE_DB_TYPE "hash"
|
||||
#define ALIAS_DB_MAP DEF_DB_TYPE ":/etc/aliases"
|
||||
#ifndef NO_NIS
|
||||
#define HAS_NIS
|
||||
#endif
|
||||
@ -832,8 +847,8 @@ extern int initgroups(const char *, int);
|
||||
#define DEF_MAILBOX_LOCK "dotlock" /* verified RedHat 3.03 */
|
||||
#define HAS_FSYNC
|
||||
#define HAS_DB
|
||||
#define DEF_DB_TYPE "hash"
|
||||
#define ALIAS_DB_MAP "hash:/etc/aliases"
|
||||
#define NATIVE_DB_TYPE "hash"
|
||||
#define ALIAS_DB_MAP DEF_DB_TYPE ":/etc/aliases"
|
||||
#ifndef NO_NIS
|
||||
#define HAS_NIS
|
||||
#endif
|
||||
@ -866,8 +881,8 @@ extern int initgroups(const char *, int);
|
||||
#define DEF_MAILBOX_LOCK "fcntl, dotlock" /* RedHat >= 4.x */
|
||||
#define HAS_FSYNC
|
||||
#define HAS_DB
|
||||
#define DEF_DB_TYPE "hash"
|
||||
#define ALIAS_DB_MAP "hash:/etc/aliases"
|
||||
#define NATIVE_DB_TYPE "hash"
|
||||
#define ALIAS_DB_MAP DEF_DB_TYPE ":/etc/aliases"
|
||||
#ifndef NO_NIS
|
||||
#define HAS_NIS
|
||||
#endif
|
||||
@ -932,8 +947,8 @@ extern int initgroups(const char *, int);
|
||||
#define INTERNAL_LOCK MYFLOCK_STYLE_FCNTL
|
||||
#define DEF_MAILBOX_LOCK "fcntl, dotlock"
|
||||
#define HAS_FSYNC
|
||||
#define DEF_DB_TYPE "dbm"
|
||||
#define ALIAS_DB_MAP "dbm:/etc/mail/aliases"
|
||||
#define NATIVE_DB_TYPE "dbm"
|
||||
#define ALIAS_DB_MAP DEF_DB_TYPE ":/etc/mail/aliases"
|
||||
#define ROOT_PATH "/usr/bin:/sbin:/usr/sbin"
|
||||
#define MISSING_SETENV
|
||||
#ifndef NO_NIS
|
||||
@ -971,8 +986,8 @@ extern int h_errno; /* <netdb.h> imports too much stuff */
|
||||
#define INTERNAL_LOCK MYFLOCK_STYLE_FCNTL
|
||||
#define DEF_MAILBOX_LOCK "fcntl, dotlock"
|
||||
#define HAS_FSYNC
|
||||
#define DEF_DB_TYPE "dbm"
|
||||
#define ALIAS_DB_MAP "dbm:/etc/mail/aliases"
|
||||
#define NATIVE_DB_TYPE "dbm"
|
||||
#define ALIAS_DB_MAP DEF_DB_TYPE ":/etc/mail/aliases"
|
||||
#define ROOT_PATH "/usr/bin:/sbin:/usr/sbin"
|
||||
#define MISSING_SETENV
|
||||
#ifndef NO_NIS
|
||||
@ -1016,8 +1031,8 @@ extern int h_errno; /* <netdb.h> imports too much stuff */
|
||||
#define MISSING_SETENV
|
||||
#define MISSING_RLIMIT_FSIZE
|
||||
#define GETTIMEOFDAY(t) gettimeofday(t,(struct timezone *) 0)
|
||||
#define DEF_DB_TYPE "dbm"
|
||||
#define ALIAS_DB_MAP "dbm:/usr/lib/aliases"
|
||||
#define NATIVE_DB_TYPE "dbm"
|
||||
#define ALIAS_DB_MAP DEF_DB_TYPE ":/usr/lib/aliases"
|
||||
#define ROOT_PATH "/bin:/usr/bin:/etc"
|
||||
#define _PATH_BSHELL "/bin/sh"
|
||||
#define _PATH_MAILDIR "/usr/mail"
|
||||
@ -1076,7 +1091,7 @@ extern int h_errno;
|
||||
#define _PATH_DEFPATH "/bin:/usr/bin:/usr/ucb"
|
||||
#define _PATH_STDPATH "/bin:/usr/bin:/usr/ucb"
|
||||
#define ROOT_PATH "/bin:/usr/bin:/usr/etc:/usr/ucb"
|
||||
#define DEF_DB_TYPE "dbm"
|
||||
#define NATIVE_DB_TYPE "dbm"
|
||||
#define ALIAS_DB_MAP "netinfo:/aliases"
|
||||
#include <libc.h>
|
||||
#define MISSING_POSIX_S_IS
|
||||
@ -1131,7 +1146,7 @@ typedef unsigned short mode_t;
|
||||
#define _PATH_DEFPATH "/bin:/usr/bin:/usr/ucb"
|
||||
#define _PATH_STDPATH "/bin:/usr/bin:/usr/ucb"
|
||||
#define ROOT_PATH "/bin:/usr/bin:/usr/etc:/usr/ucb"
|
||||
#define DEF_DB_TYPE "dbm"
|
||||
#define NATIVE_DB_TYPE "dbm"
|
||||
#define ALIAS_DB_MAP "netinfo:/aliases"
|
||||
#include <libc.h>
|
||||
#define MISSING_POSIX_S_IS
|
||||
@ -1168,8 +1183,8 @@ typedef unsigned short mode_t;
|
||||
#define FIONREAD_IN_SYS_FILIO_H
|
||||
#define USE_SYS_SOCKIO_H
|
||||
#define HAS_DBM
|
||||
#define DEF_DB_TYPE "dbm"
|
||||
#define ALIAS_DB_MAP "dbm:/var/adm/sendmail/aliases"
|
||||
#define NATIVE_DB_TYPE "dbm"
|
||||
#define ALIAS_DB_MAP DEF_DB_TYPE ":/var/adm/sendmail/aliases"
|
||||
extern int optind; /* XXX use <getopt.h> */
|
||||
extern char *optarg; /* XXX use <getopt.h> */
|
||||
extern int opterr; /* XXX use <getopt.h> */
|
||||
@ -1198,8 +1213,8 @@ extern int opterr; /* XXX use <getopt.h> */
|
||||
#define INTERNAL_LOCK MYFLOCK_STYLE_FCNTL
|
||||
#define DEF_MAILBOX_LOCK "fcntl, dotlock"
|
||||
#define HAS_FSYNC
|
||||
#define DEF_DB_TYPE "hash"
|
||||
#define ALIAS_DB_MAP "hash:/etc/aliases"
|
||||
#define NATIVE_DB_TYPE "hash"
|
||||
#define ALIAS_DB_MAP DEF_DB_TYPE ":/etc/aliases"
|
||||
/* Uncomment the following line if you have NIS package installed */
|
||||
/* #define HAS_NIS */
|
||||
#define USE_SYS_SOCKIO_H
|
||||
@ -1231,8 +1246,8 @@ extern int h_errno;
|
||||
#define DEF_MAILBOX_LOCK "fcntl, dotlock"
|
||||
#define HAS_FSYNC
|
||||
#define HAS_DBM
|
||||
#define DEF_DB_TYPE "dbm"
|
||||
#define ALIAS_DB_MAP "dbm:/etc/mail/aliases"
|
||||
#define NATIVE_DB_TYPE "dbm"
|
||||
#define ALIAS_DB_MAP DEF_DB_TYPE ":/etc/mail/aliases"
|
||||
#define DBM_NO_TRAILING_NULL
|
||||
#ifndef NO_NIS
|
||||
#define HAS_NIS
|
||||
@ -1292,6 +1307,10 @@ extern int h_errno;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef DEF_DB_TYPE
|
||||
#define DEF_DB_TYPE NATIVE_DB_TYPE
|
||||
#endif
|
||||
|
||||
#define CAST_CHAR_PTR_TO_INT(cptr) ((int) (long) (cptr))
|
||||
#define CAST_INT_TO_CHAR_PTR(ival) ((char *) (long) (ival))
|
||||
|
||||
@ -1372,8 +1391,14 @@ extern int inet_pton(int, const char *, void *);
|
||||
#define EVENTS_STYLE_DEVPOLL 3 /* Solaris /dev/poll */
|
||||
#define EVENTS_STYLE_EPOLL 4 /* Linux epoll */
|
||||
|
||||
#if !defined(USE_SYSV_POLL) && (EVENTS_STYLE != EVENTS_STYLE_SELECT)
|
||||
#error "need USE_SYSV_POLL with EVENTS_STYLE != EVENTS_STYLE_SELECT"
|
||||
/*
|
||||
* We use poll() for read/write time limit enforcement on modern systems. We
|
||||
* use select() on historical systems without poll() support. And on systems
|
||||
* where poll() is not implemented for some file handle types, we try to use
|
||||
* select() as a fall-back solution (MacOS X needs this).
|
||||
*/
|
||||
#if !defined(USE_SYSV_POLL) && !defined(USE_SYSV_POLL_THEN_SELECT)
|
||||
#define USE_BSD_SELECT
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
121
external/ibm-public/postfix/dist/src/util/writable.c
vendored
121
external/ibm-public/postfix/dist/src/util/writable.c
vendored
@ -1,121 +0,0 @@
|
||||
/* $NetBSD: writable.c,v 1.1.1.1 2009/06/23 10:09:01 tron Exp $ */
|
||||
|
||||
/*++
|
||||
/* NAME
|
||||
/* writable 3
|
||||
/* SUMMARY
|
||||
/* test if descriptor is writable
|
||||
/* SYNOPSIS
|
||||
/* #include <iostuff.h>
|
||||
/*
|
||||
/* int writable(fd)
|
||||
/* int fd;
|
||||
/* DESCRIPTION
|
||||
/* writable() asks the kernel if the specified file descriptor
|
||||
/* is writable, i.e. a write operation would not block.
|
||||
/*
|
||||
/* Arguments:
|
||||
/* .IP fd
|
||||
/* File descriptor in the range 0..FD_SETSIZE.
|
||||
/* DIAGNOSTICS
|
||||
/* All system call errors are fatal.
|
||||
/* LICENSE
|
||||
/* .ad
|
||||
/* .fi
|
||||
/* The Secure Mailer license must be distributed with this software.
|
||||
/* AUTHOR(S)
|
||||
/* Wietse Venema
|
||||
/* IBM T.J. Watson Research
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*--*/
|
||||
|
||||
/* System library. */
|
||||
|
||||
#include <sys_defs.h>
|
||||
#include <sys/time.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef USE_SYSV_POLL
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_SYS_SELECT_H
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
/* Utility library. */
|
||||
|
||||
#include <msg.h>
|
||||
#include <iostuff.h>
|
||||
|
||||
/* writable - see if file descriptor is writable */
|
||||
|
||||
int writable(int fd)
|
||||
{
|
||||
#ifndef USE_SYSV_POLL
|
||||
struct timeval tv;
|
||||
fd_set write_fds;
|
||||
fd_set except_fds;
|
||||
|
||||
/*
|
||||
* Sanity checks.
|
||||
*/
|
||||
if (fd >= FD_SETSIZE)
|
||||
msg_fatal("fd %d does not fit in FD_SETSIZE", fd);
|
||||
|
||||
/*
|
||||
* Initialize.
|
||||
*/
|
||||
FD_ZERO(&write_fds);
|
||||
FD_SET(fd, &write_fds);
|
||||
FD_ZERO(&except_fds);
|
||||
FD_SET(fd, &except_fds);
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
/*
|
||||
* Loop until we have an authoritative answer.
|
||||
*/
|
||||
for (;;) {
|
||||
switch (select(fd + 1, (fd_set *) 0, &write_fds, &except_fds, &tv)) {
|
||||
case -1:
|
||||
if (errno != EINTR)
|
||||
msg_fatal("select: %m");
|
||||
continue;
|
||||
default:
|
||||
return (FD_ISSET(fd, &write_fds));
|
||||
case 0:
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
/*
|
||||
* System-V poll() is optimal for polling a few descriptors.
|
||||
*/
|
||||
struct pollfd pollfd;
|
||||
|
||||
#define DONT_WAIT_FOR_EVENT 0
|
||||
|
||||
pollfd.fd = fd;
|
||||
pollfd.events = POLLOUT;
|
||||
for (;;) {
|
||||
switch (poll(&pollfd, 1, DONT_WAIT_FOR_EVENT)) {
|
||||
case -1:
|
||||
if (errno != EINTR)
|
||||
msg_fatal("poll: %m");
|
||||
continue;
|
||||
case 0:
|
||||
return (0);
|
||||
default:
|
||||
if (pollfd.revents & POLLNVAL)
|
||||
msg_fatal("poll: %m");
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
@ -1,137 +0,0 @@
|
||||
/* $NetBSD: write_wait.c,v 1.1.1.1 2009/06/23 10:09:01 tron Exp $ */
|
||||
|
||||
/*++
|
||||
/* NAME
|
||||
/* write_wait 3
|
||||
/* SUMMARY
|
||||
/* wait until descriptor becomes writable
|
||||
/* SYNOPSIS
|
||||
/* #include <iostuff.h>
|
||||
/*
|
||||
/* int write_wait(fd, timeout)
|
||||
/* int fd;
|
||||
/* int timeout;
|
||||
/* DESCRIPTION
|
||||
/* write_wait() blocks the current process until the specified file
|
||||
/* descriptor becomes writable, or until the deadline is exceeded.
|
||||
/*
|
||||
/* Arguments:
|
||||
/* .IP fd
|
||||
/* File descriptor in the range 0..FD_SETSIZE.
|
||||
/* .IP timeout
|
||||
/* If positive, deadline in seconds. A zero value effects a poll.
|
||||
/* A negative value means wait until something happens.
|
||||
/* DIAGNOSTICS
|
||||
/* Panic: interface violation. All system call errors are fatal.
|
||||
/*
|
||||
/* A zero result means success. When the specified deadline is
|
||||
/* exceeded, write_wait() returns -1 and sets errno to ETIMEDOUT.
|
||||
/* LICENSE
|
||||
/* .ad
|
||||
/* .fi
|
||||
/* The Secure Mailer license must be distributed with this software.
|
||||
/* AUTHOR(S)
|
||||
/* Wietse Venema
|
||||
/* IBM T.J. Watson Research
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*--*/
|
||||
|
||||
/* System library. */
|
||||
|
||||
#include <sys_defs.h>
|
||||
#include <sys/time.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef USE_SYSV_POLL
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_SYS_SELECT_H
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
/* Utility library. */
|
||||
|
||||
#include <msg.h>
|
||||
#include <iostuff.h>
|
||||
|
||||
/* write_wait - block with timeout until file descriptor is writable */
|
||||
|
||||
int write_wait(int fd, int timeout)
|
||||
{
|
||||
#ifndef USE_SYSV_POLL
|
||||
fd_set write_fds;
|
||||
fd_set except_fds;
|
||||
struct timeval tv;
|
||||
struct timeval *tp;
|
||||
|
||||
/*
|
||||
* Sanity checks.
|
||||
*/
|
||||
if (FD_SETSIZE <= fd)
|
||||
msg_panic("descriptor %d does not fit FD_SETSIZE %d", fd, FD_SETSIZE);
|
||||
|
||||
/*
|
||||
* Guard the write() with select() so we do not depend on alarm() and on
|
||||
* signal() handlers. Restart the select when interrupted by some signal.
|
||||
* Some select() implementations may reduce the time to wait when
|
||||
* interrupted, which is exactly what we want.
|
||||
*/
|
||||
FD_ZERO(&write_fds);
|
||||
FD_SET(fd, &write_fds);
|
||||
FD_ZERO(&except_fds);
|
||||
FD_SET(fd, &except_fds);
|
||||
if (timeout >= 0) {
|
||||
tv.tv_usec = 0;
|
||||
tv.tv_sec = timeout;
|
||||
tp = &tv;
|
||||
} else {
|
||||
tp = 0;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
switch (select(fd + 1, (fd_set *) 0, &write_fds, &except_fds, tp)) {
|
||||
case -1:
|
||||
if (errno != EINTR)
|
||||
msg_fatal("select: %m");
|
||||
continue;
|
||||
case 0:
|
||||
errno = ETIMEDOUT;
|
||||
return (-1);
|
||||
default:
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
/*
|
||||
* System-V poll() is optimal for polling a few descriptors.
|
||||
*/
|
||||
struct pollfd pollfd;
|
||||
|
||||
#define WAIT_FOR_EVENT (-1)
|
||||
|
||||
pollfd.fd = fd;
|
||||
pollfd.events = POLLOUT;
|
||||
for (;;) {
|
||||
switch (poll(&pollfd, 1, timeout < 0 ?
|
||||
WAIT_FOR_EVENT : timeout * 1000)) {
|
||||
case -1:
|
||||
if (errno != EINTR)
|
||||
msg_fatal("poll: %m");
|
||||
continue;
|
||||
case 0:
|
||||
errno = ETIMEDOUT;
|
||||
return (-1);
|
||||
default:
|
||||
if (pollfd.revents & POLLNVAL)
|
||||
msg_fatal("poll: %m");
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
Loading…
Reference in New Issue
Block a user