From: Wietse Venema
Date: Sun, 8 Dec 2013 05:00:00 +0000 (-0500)
Subject: postfix-2.11-20131208-nonprod
X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f1489cd448e3746ba88d13e71cfbff3826979953;p=thirdparty%2Fpostfix.git
postfix-2.11-20131208-nonprod
---
diff --git a/postfix/.indent.pro b/postfix/.indent.pro
index 441e160c2..982975fd0 100644
--- a/postfix/.indent.pro
+++ b/postfix/.indent.pro
@@ -155,6 +155,7 @@
-TLMTP_STATE
-TLOCAL_EXP
-TLOCAL_STATE
+-TLONG_NAME_MASK
-TMAC_EXP
-TMAC_HEAD
-TMAC_PARSE
@@ -372,6 +373,7 @@
-Tsfsistat
-Tsigset_t
-Tsize_t
+-Tsockaddr
-Tssize_t
-Tssl_cipher_stack_t
-Tssl_comp_stack_t
diff --git a/postfix/HISTORY b/postfix/HISTORY
index 4883ede54..396760acb 100644
--- a/postfix/HISTORY
+++ b/postfix/HISTORY
@@ -19303,3 +19303,16 @@ Apologies for any names omitted.
Bugfix (introduced: 20090106): the postconf '-#' option
erased prior options. File: postconf/postconf.c.
+
+20131129
+
+ Bugfix: Makefile example in MULTI_INSTANCE_README. Viktor
+ Dukhovni. File: proto/MULTI_INSTANCE_README.html.
+
+20131130
+
+ Cleanup: simplify fingerprint security level implementation
+ in new DANE code. Viktor Dukhovni. Files: src/tls/tls.h
+ src/smtp/smtp_tls_policy.c src/tls/tls_dane.c
+ src/posttls-finger/posttls-finger.c.
+
diff --git a/postfix/README_FILES/MULTI_INSTANCE_README b/postfix/README_FILES/MULTI_INSTANCE_README
index 6e2fb48c5..7e930f25c 100644
--- a/postfix/README_FILES/MULTI_INSTANCE_README
+++ b/postfix/README_FILES/MULTI_INSTANCE_README
@@ -177,7 +177,7 @@ database when none exists.
generic: Makefile
@echo Creating $@
@rm -f $@.tmp
- @printf '%s\t%s+root=%s\n' root $MTAADMIN `uname -n` > $@.tmp
+ @printf '%s\t%s+root=%s\n' root ${MTAADMIN} `uname -n` > $@.tmp
@mv $@.tmp generic
%.cdb: %
diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES
index 2c8619a89..cbe1a17fc 100644
--- a/postfix/RELEASE_NOTES
+++ b/postfix/RELEASE_NOTES
@@ -74,7 +74,7 @@ all Postfix daemons, use this:
$ postconf -F '*/*/chroot=n'
For a second example, let's look at the submission service. This
-service typically has multple "-o parameter=value" overrides. First
+service typically has multiple "-o parameter=value" overrides. First
the traditional view:
$ postconf -Mf submission
diff --git a/postfix/html/MULTI_INSTANCE_README.html b/postfix/html/MULTI_INSTANCE_README.html
index 6aca5f53d..39fc87da1 100644
--- a/postfix/html/MULTI_INSTANCE_README.html
+++ b/postfix/html/MULTI_INSTANCE_README.html
@@ -233,7 +233,7 @@ creates a "generic" database when none exists.
generic: Makefile
@echo Creating $@
@rm -f $@.tmp
- @printf '%s\t%s+root=%s\n' root $MTAADMIN `uname -n` > $@.tmp
+ @printf '%s\t%s+root=%s\n' root ${MTAADMIN} `uname -n` > $@.tmp
@mv $@.tmp generic
%.cdb: %
diff --git a/postfix/html/lmdb_table.5.html b/postfix/html/lmdb_table.5.html
index d8dd19faf..6cba132a5 100644
--- a/postfix/html/lmdb_table.5.html
+++ b/postfix/html/lmdb_table.5.html
@@ -56,10 +56,12 @@ LMDB_TABLE(5) LMDB_TABLE(5)
The Postfix LMDB adapter implements locking with fcntl(2)
locks at whole-file granularity. LMDB's native locking
scheme would require world-writable lockfiles and would
- therefore violate the Postfix security model. Unlike some
- other Postfix flat-file databases, LMDB databases can
- safely be updated without serializing requests through the
- proxymap(8) service.
+ therefore violate the Postfix security model.
+
+ Multiple processes can safely update an LMDB database
+ without serializing requests through the proxymap(8) ser-
+ vice. This makes LMDB suitable as a shared cache for ver-
+ ify(8) or postscreen(8) services.
CONFIGURATION PARAMETERS
Short-lived programs automatically pick up changes to
diff --git a/postfix/html/posttls-finger.1.html b/postfix/html/posttls-finger.1.html
index 1848d6d24..a9a4943c5 100644
--- a/postfix/html/posttls-finger.1.html
+++ b/postfix/html/posttls-finger.1.html
@@ -12,14 +12,14 @@ POSTTLS-FINGER(1) POSTTLS-FINGER(1)
SYNOPSIS
posttls-finger [options] [inet:]domain[:port] [match ...]
- posttls-finger -S [options] unix:pathname [match ...]
+ posttls-finger -S [options] unix:pathname [match ...]
DESCRIPTION
posttls-finger(1) connects to the specified destination
and reports TLS-related information about the server. With
SMTP, the destination is a domainname; with LMTP it is
either a domainname prefixed with inet: or a pathname pre-
- fixed with unix:. If Postfix is built without TLS sup-
+ fixed with unix:. If Postfix is built without TLS sup-
port, the resulting posttls-finger program has very lim-
ited functionality, and only the -a, -c, -h, -o, -S, -t,
-T and -v options are available.
@@ -83,7 +83,7 @@ POSTTLS-FINGER(1) POSTTLS-FINGER(1)
taken from the smtp/tcp entry in /etc/services, defaulting
to 25 if the entry is not found.
- With LMTP, specify unix:pathname to connect to a local
+ With LMTP, specify unix:pathname to connect to a local
server listening on a unix-domain socket bound to the
specified pathname; otherwise, specify an optional inet:
prefix followed by a domain and an optional port, with the
@@ -314,7 +314,7 @@ POSTTLS-FINGER(1) POSTTLS-FINGER(1)
validation information is available via native
lookups).
- unix:pathname
+ unix:pathname
Connect to the UNIX-domain socket at pathname. LMTP
only.
diff --git a/postfix/man/man5/lmdb_table.5 b/postfix/man/man5/lmdb_table.5
index a45d9de9b..d6315bd71 100644
--- a/postfix/man/man5/lmdb_table.5
+++ b/postfix/man/man5/lmdb_table.5
@@ -63,10 +63,12 @@ curruption due stray pointer bugs.
The Postfix LMDB adapter implements locking with fcntl(2)
locks at whole-file granularity. LMDB's native locking
scheme would require world-writable lockfiles and would
-therefore violate the Postfix security model. Unlike some
-other Postfix flat-file databases, LMDB databases can safely
-be updated without serializing requests through the proxymap(8)
-service.
+therefore violate the Postfix security model.
+
+Multiple processes can safely update an LMDB database without
+serializing requests through the proxymap(8) service. This
+makes LMDB suitable as a shared cache for verify(8) or
+postscreen(8) services.
.SH "CONFIGURATION PARAMETERS"
.na
.nf
diff --git a/postfix/man/man5/postconf.5 b/postfix/man/man5/postconf.5
index a44eaf15c..c68d90bc2 100644
--- a/postfix/man/man5/postconf.5
+++ b/postfix/man/man5/postconf.5
@@ -12,10 +12,10 @@ Postfix configuration parameters
.SH DESCRIPTION
.ad
.fi
-The Postfix main.cf configuration file specifies a small subset
-of all the parameters that control the operation of the Postfix
-mail system. Parameters not specified in main.cf are left at their
-default values.
+The Postfix main.cf configuration file specifies parameters that
+control the operation of the Postfix mail system. Typically the
+file contains only a small subset of all parameters; parameters
+not specified are left at their default values.
.PP
The general format of the main.cf file is as follows:
.IP \(bu
diff --git a/postfix/proto/MULTI_INSTANCE_README.html b/postfix/proto/MULTI_INSTANCE_README.html
index 59bb4fbd9..a2574df89 100644
--- a/postfix/proto/MULTI_INSTANCE_README.html
+++ b/postfix/proto/MULTI_INSTANCE_README.html
@@ -233,7 +233,7 @@ creates a "generic" database when none exists.
generic: Makefile
@echo Creating $@
@rm -f $@.tmp
- @printf '%s\t%s+root=%s\n' root $MTAADMIN `uname -n` > $@.tmp
+ @printf '%s\t%s+root=%s\n' root ${MTAADMIN} `uname -n` > $@.tmp
@mv $@.tmp generic
%.cdb: %
diff --git a/postfix/proto/lmdb_table b/postfix/proto/lmdb_table
index b1cc8169a..aa59635aa 100644
--- a/postfix/proto/lmdb_table
+++ b/postfix/proto/lmdb_table
@@ -53,10 +53,12 @@
# The Postfix LMDB adapter implements locking with fcntl(2)
# locks at whole-file granularity. LMDB's native locking
# scheme would require world-writable lockfiles and would
-# therefore violate the Postfix security model. Unlike some
-# other Postfix flat-file databases, LMDB databases can safely
-# be updated without serializing requests through the proxymap(8)
-# service.
+# therefore violate the Postfix security model.
+#
+# Multiple processes can safely update an LMDB database without
+# serializing requests through the proxymap(8) service. This
+# makes LMDB suitable as a shared cache for verify(8) or
+# postscreen(8) services.
# CONFIGURATION PARAMETERS
# .ad
# .fi
diff --git a/postfix/proto/postconf.man.prolog b/postfix/proto/postconf.man.prolog
index 37afa4e88..170838fe6 100644
--- a/postfix/proto/postconf.man.prolog
+++ b/postfix/proto/postconf.man.prolog
@@ -12,10 +12,10 @@ Postfix configuration parameters
.SH DESCRIPTION
.ad
.fi
-The Postfix main.cf configuration file specifies a small subset
-of all the parameters that control the operation of the Postfix
-mail system. Parameters not specified in main.cf are left at their
-default values.
+The Postfix main.cf configuration file specifies parameters that
+control the operation of the Postfix mail system. Typically the
+file contains only a small subset of all parameters; parameters
+not specified are left at their default values.
.PP
The general format of the main.cf file is as follows:
.IP \(bu
diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h
index 00973bb01..f5154456c 100644
--- a/postfix/src/global/mail_version.h
+++ b/postfix/src/global/mail_version.h
@@ -20,7 +20,7 @@
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20131126"
+#define MAIL_RELEASE_DATE "20131208"
#define MAIL_VERSION_NUMBER "2.11"
#ifdef SNAPSHOT
diff --git a/postfix/src/postconf/postconf_edit.c b/postfix/src/postconf/postconf_edit.c
index 7607c5687..05fdc1f40 100644
--- a/postfix/src/postconf/postconf_edit.c
+++ b/postfix/src/postconf/postconf_edit.c
@@ -2,7 +2,7 @@
/* NAME
/* postconf_edit 3
/* SUMMARY
-/* edit main.cf
+/* edit main.cf or master.cf
/* SYNOPSIS
/* #include
/*
@@ -25,19 +25,27 @@
/*
/* edit_master() edits the \fBmaster.cf\fR configuration file.
/* The file is copied to a temporary file then renamed into
-/* place. Depending on the value of \fBmode\fR:
+/* place. Depending on the flags in \fBmode\fR:
/* .IP MASTER_ENTRY
-/* edit_master() replaces or adds entire master.cf entries,
-/* specified on the command line as "\fIname/type = name type
-/* private unprivileged chroot wakeup process_limit command...\fR".
-/* ,IP MASTER_FIELD
-/* edit_master() replaces the value of specific service
-/* attributes, specified on the command line as
+/* With EDIT_CONF, edit_master() replaces or adds entire
+/* master.cf entries, specified on the command line as
+/* "\fIname/type = name type private unprivileged chroot wakeup
+/* process_limit command...\fR".
+/*
+/* With EDIT_EXCL or COMMENT_OUT, edit_master() removes or
+/* comments out entries specified on the command line as
+/* "\fIname/type\fR.
+/* .IP MASTER_FIELD
+/* With EDIT_CONF, edit_master() replaces the value of specific
+/* service attributes, specified on the command line as
/* "\fIname/type/attribute = value\fR".
/* .IP MASTER_PARAM
-/* edit_master() replaces the value of specific service
-/* parameters, specified on the command line as
+/* With EDIT_CONF, edit_master() replaces or adds the value
+/* of service parameters, specified on the command line as
/* "\fIname/type/parameter = value\fR".
+/*
+/* With EDIT_EXCL, edit_master() removes service parameters
+/* specified on the command line as "\fIparametername\fR".
/* DIAGNOSTICS
/* Problems are reported to the standard error stream.
/* FILES
@@ -346,7 +354,7 @@ void edit_master(int mode, int argc, char **argv)
#define PC_MASTER_MASK (MASTER_ENTRY | MASTER_FIELD | MASTER_PARAM)
/*
- * Split name/type or name/type/field pattern into components.
+ * Split name/type or name/type/whatever pattern into components.
*/
switch (mode & PC_MASTER_MASK) {
case MASTER_ENTRY:
diff --git a/postfix/src/posttls-finger/posttls-finger.c b/postfix/src/posttls-finger/posttls-finger.c
index 82d3aeb7d..2779ea075 100644
--- a/postfix/src/posttls-finger/posttls-finger.c
+++ b/postfix/src/posttls-finger/posttls-finger.c
@@ -798,7 +798,7 @@ static int doproto(STATE *state)
/* connect_sock - connect a socket over some transport */
-static VSTREAM *connect_sock(int sock, struct sockaddr * sa, int salen,
+static VSTREAM *connect_sock(int sock, struct sockaddr *sa, int salen,
const char *name, const char *addr, STATE *state)
{
DSN_BUF *why = state->why;
@@ -895,7 +895,7 @@ static VSTREAM *connect_unix(STATE *state, const char *path)
if (msg_verbose)
msg_info("%s: trying: %s...", myname, path);
- return (connect_sock(sock, (struct sockaddr *) & sock_un, sizeof(sock_un),
+ return (connect_sock(sock, (struct sockaddr *) &sock_un, sizeof(sock_un),
var_myhostname, path, state));
}
@@ -906,7 +906,7 @@ static VSTREAM *connect_addr(STATE *state, DNS_RR *addr)
static const char *myname = "connect_addr";
DSN_BUF *why = state->why;
struct sockaddr_storage ss; /* remote */
- struct sockaddr *sa = (struct sockaddr *) & ss;
+ struct sockaddr *sa = (struct sockaddr *) &ss;
SOCKADDR_SIZE salen = sizeof(ss);
MAI_HOSTADDR_STR hostaddr;
int sock;
@@ -1392,7 +1392,7 @@ static int finger(STATE *state)
state->why = dsb_create();
if (!(err = connect_dest(state))) {
- if (state->pass == 1)
+ if (state->pass == 1 && !state->nochat)
msg_info("Connected to %s", state->namaddrport);
err = doproto(state);
}
@@ -1745,10 +1745,10 @@ static void parse_match(STATE *state, int argc, char *argv[])
argv_add(state->match, "hostname", ARGV_END);
break;
case TLS_LEV_FPRINT:
- state->dane = tls_dane_alloc(TLS_DANE_FLAG_MIXED);
+ state->dane = tls_dane_alloc();
while (*argv)
- tls_dane_split((TLS_DANE *) state->dane, TLS_DANE_EE, TLS_DANE_PKEY,
- state->mdalg, *argv++, "");
+ tls_dane_add_ee_digests((TLS_DANE *) state->dane,
+ state->mdalg, *argv++, "");
break;
case TLS_LEV_DANE:
state->match = argv_alloc(2);
@@ -1773,7 +1773,7 @@ static void parse_tas(STATE *state)
return;
case TLS_LEV_SECURE:
case TLS_LEV_VERIFY:
- state->dane = tls_dane_alloc(TLS_DANE_FLAG_MIXED);
+ state->dane = tls_dane_alloc();
for (file = state->options.tas->argv; *file; ++file) {
if (!tls_dane_load_trustfile((TLS_DANE *) state->dane, *file))
break;
diff --git a/postfix/src/smtp/smtp_tls_policy.c b/postfix/src/smtp/smtp_tls_policy.c
index 4f3fae10b..7c93e464d 100644
--- a/postfix/src/smtp/smtp_tls_policy.c
+++ b/postfix/src/smtp/smtp_tls_policy.c
@@ -308,9 +308,9 @@ static void tls_policy_lookup_one(SMTP_TLS_POLICY *tls, int *site_level,
break;
case TLS_LEV_FPRINT:
if (!tls->dane)
- tls->dane = tls_dane_alloc(TLS_DANE_FLAG_MIXED);
- tls_dane_split(tls->dane, TLS_DANE_EE, TLS_DANE_PKEY,
- var_smtp_tls_fpt_dgst, val, "|");
+ tls->dane = tls_dane_alloc();
+ tls_dane_add_ee_digests(tls->dane,
+ var_smtp_tls_fpt_dgst, val, "|");
break;
case TLS_LEV_VERIFY:
case TLS_LEV_SECURE:
@@ -345,7 +345,7 @@ static void tls_policy_lookup_one(SMTP_TLS_POLICY *tls, int *site_level,
INVALID_RETURN(tls->why, site_level);
}
if (!tls->dane)
- tls->dane = tls_dane_alloc(TLS_DANE_FLAG_MIXED);
+ tls->dane = tls_dane_alloc();
if (!tls_dane_load_trustfile(tls->dane, val)) {
INVALID_RETURN(tls->why, site_level);
}
@@ -559,11 +559,10 @@ static void *policy_create(const char *unused_key, void *context)
break;
case TLS_LEV_FPRINT:
if (tls->dane == 0)
- tls->dane = tls_dane_alloc(TLS_DANE_FLAG_MIXED);
+ tls->dane = tls_dane_alloc();
if (!TLS_DANE_HASEE(tls->dane)) {
- tls_dane_split(tls->dane, TLS_DANE_EE, TLS_DANE_PKEY,
- var_smtp_tls_fpt_dgst, var_smtp_tls_fpt_cmatch,
- "\t\n\r, ");
+ tls_dane_add_ee_digests(tls->dane, var_smtp_tls_fpt_dgst,
+ var_smtp_tls_fpt_cmatch, "\t\n\r, ");
if (!TLS_DANE_HASEE(tls->dane)) {
msg_warn("nexthop domain %s: configured at fingerprint "
"security level, but with no fingerprints to match.",
@@ -582,7 +581,7 @@ static void *policy_create(const char *unused_key, void *context)
"\t\n\r, :");
if (*var_smtp_tls_tafile) {
if (tls->dane == 0)
- tls->dane = tls_dane_alloc(TLS_DANE_FLAG_MIXED);
+ tls->dane = tls_dane_alloc();
if (!TLS_DANE_HASTA(tls->dane)
&& !load_tas(tls->dane, var_smtp_tls_tafile)) {
MARK_INVALID(tls->why, &tls->level);
diff --git a/postfix/src/tls/tls.h b/postfix/src/tls/tls.h
index cd4c2fcd2..cf2976667 100644
--- a/postfix/src/tls/tls.h
+++ b/postfix/src/tls/tls.h
@@ -108,10 +108,9 @@ extern const NAME_CODE tls_level_table[];
#define TLS_DANE_CERT 0 /* Match the certificate digest */
#define TLS_DANE_PKEY 1 /* Match the public key digest */
-#define TLS_DANE_FLAG_MIXED (1<<0) /* Combined pkeys and certs */
-#define TLS_DANE_FLAG_NORRS (1<<1) /* Nothing found in DNS */
-#define TLS_DANE_FLAG_EMPTY (1<<2) /* Nothing usable found in DNS */
-#define TLS_DANE_FLAG_ERROR (1<<3) /* TLSA record lookup error */
+#define TLS_DANE_FLAG_NORRS (1<<0) /* Nothing found in DNS */
+#define TLS_DANE_FLAG_EMPTY (1<<1) /* Nothing usable found in DNS */
+#define TLS_DANE_FLAG_ERROR (1<<2) /* TLSA record lookup error */
#define tls_dane_unusable(dane) ((dane)->flags & TLS_DANE_FLAG_EMPTY)
#define tls_dane_notfound(dane) ((dane)->flags & TLS_DANE_FLAG_NORRS)
@@ -146,10 +145,6 @@ typedef struct TLS_PKEYS {
struct TLS_PKEYS *next;
} TLS_PKEYS;
- /*
- * When TLS_DANE_FLAG_MIXED is set, the pkeys digest list is not allocated
- * separately, and aliases the certs digest list for each algorithm.
- */
typedef struct TLS_DANE {
TLS_TLSA *ta; /* Trust-anchor cert/pubkey digests */
TLS_TLSA *ee; /* End-entity cert/pubkey digests */
@@ -170,9 +165,9 @@ typedef struct TLS_DANE {
extern int tls_dane_avail(void);
extern void tls_dane_flush(void);
extern void tls_dane_verbose(int);
-extern TLS_DANE *tls_dane_alloc(int);
-extern void tls_dane_split(TLS_DANE *, int, int, const char *, const char *,
- const char *);
+extern TLS_DANE *tls_dane_alloc(void);
+extern void tls_dane_add_ee_digests(TLS_DANE *, const char *, const char *,
+ const char *);
extern void tls_dane_free(TLS_DANE *);
extern TLS_DANE *tls_dane_resolve(unsigned, const char *, DNS_RR *, int);
extern int tls_dane_load_trustfile(TLS_DANE *, const char *);
diff --git a/postfix/src/tls/tls_dane.c b/postfix/src/tls/tls_dane.c
index 92f2b6fa0..3efb2eb6f 100644
--- a/postfix/src/tls/tls_dane.c
+++ b/postfix/src/tls/tls_dane.c
@@ -13,16 +13,13 @@
/* void tls_dane_verbose(on)
/* int on;
/*
-/* TLS_DANE *tls_dane_alloc(flags)
-/* int flags;
+/* TLS_DANE *tls_dane_alloc()
/*
/* void tls_dane_free(dane)
/* TLS_DANE *dane;
/*
-/* void tls_dane_split(dane, certusage, selector, mdalg, digest, delim)
+/* void tls_dane_add_ee_digests(dane, mdalg, digest, delim)
/* TLS_DANE *dane;
-/* int certusage;
-/* int selector;
/* const char *mdalg;
/* const char *digest;
/* const char *delim;
@@ -65,17 +62,15 @@
/* tls_dane_verbose() turns on verbose logging of TLSA record lookups.
/*
/* tls_dane_alloc() returns a pointer to a newly allocated TLS_DANE
-/* structure with null ta and ee digest sublists. If "flags" includes
-/* TLS_DANE_FLAG_MIXED, the cert and pkey digests are stored together on
-/* the pkeys list with the certs list empty, otherwise they are stored
-/* separately.
+/* structure with null ta and ee digest sublists.
/*
/* tls_dane_free() frees the structure allocated by tls_dane_alloc().
/*
-/* tls_dane_split() splits "digest" using the characters in "delim" as
-/* delimiters and stores the results with the requested "certusage"
-/* and "selector". This is an incremental interface, that builds a
-/* TLS_DANE structure outside the cache by manually adding entries.
+/* tls_dane_add_ee_digests() splits "digest" using the characters in
+/* "delim" as delimiters and stores the results on the EE match list
+/* to match either a certificate or a public key. This is an incremental
+/* interface, that builds a TLS_DANE structure outside the cache by
+/* manually adding entries.
/*
/* tls_dane_load_trustfile() imports trust-anchor certificates and
/* public keys from a file (rather than DNS TLSA records).
@@ -128,8 +123,6 @@
/* When true, TLSA lookups are performed even when the qname and rname
/* are insecure. This is only useful in the unlikely case that DLV is
/* used to secure the TLSA RRset in an otherwise insecure zone.
-/* .IP flags
-/* Only one flag is part of the public interface at this time:
/* .IP TLScontext
/* Client context with TA/EE matching data and related state.
/* .IP usage
@@ -141,17 +134,6 @@
/* .IP ssl_ctx
/* The global SSL_CTX structure used to initialize child SSL
/* conenctions.
-/* .RS
-/* .IP TLS_DANE_FLAG_MIXED
-/* Don't distinguish between certificate and public-key digests.
-/* A single digest list for both certificates and keys with be
-/* stored for each algorithm in the "pkeys" field, the "certs"
-/* field will be null.
-/* .RE
-/* .IP certusage
-/* Trust anchor (TLS_DANE_TA) or end-entity (TLS_DANE_EE) digests?
-/* .IP selector
-/* Full certificate (TLS_DANE_CERT) or pubkey (TLS_DANE_PKEY) digests?
/* .IP mdalg
/* Name of a message digest algorithm suitable for computing secure
/* (1st pre-image resistant) message digests of certificates. For now,
@@ -527,7 +509,7 @@ void tls_dane_flush(void)
/* tls_dane_alloc - allocate a TLS_DANE structure */
-TLS_DANE *tls_dane_alloc(int flags)
+TLS_DANE *tls_dane_alloc(void)
{
TLS_DANE *dane = (TLS_DANE *) mymalloc(sizeof(*dane));
@@ -536,7 +518,7 @@ TLS_DANE *tls_dane_alloc(int flags)
dane->certs = 0;
dane->pkeys = 0;
dane->base_domain = 0;
- dane->flags = flags;
+ dane->flags = 0;
dane->expires = 0;
dane->refs = 1;
return (dane);
@@ -663,36 +645,49 @@ static TLS_TLSA **dane_locate(TLS_TLSA **tlsap, const char *mdalg)
return (tlsap);
}
-/* tls_dane_split - split and append digests */
+/* tls_dane_add_ee_digests - split and append digests */
-void tls_dane_split(TLS_DANE *dane, int certusage, int selector,
- const char *mdalg, const char *digest, const char *delim)
+void tls_dane_add_ee_digests(TLS_DANE *dane, const char *mdalg,
+ const char *digest, const char *delim)
{
- TLS_TLSA **tlsap;
- TLS_TLSA *tlsa;
- ARGV **argvp;
-
- tlsap = (certusage == TLS_DANE_EE) ? &dane->ee : &dane->ta;
- tlsa = *(tlsap = dane_locate(tlsap, mdalg));
- argvp = ((dane->flags & TLS_DANE_FLAG_MIXED) || selector == TLS_DANE_PKEY) ?
- &tlsa->pkeys : &tlsa->certs;
+ TLS_TLSA **tlsap = dane_locate(&dane->ee, mdalg);
+ TLS_TLSA *tlsa = *tlsap;
/* Delimited append, may append nothing */
- if (*argvp == 0)
- *argvp = argv_split(digest, delim);
+ if (tlsa->pkeys == 0)
+ tlsa->pkeys = argv_split(digest, delim);
else
- argv_split_append(*argvp, digest, delim);
+ argv_split_append(tlsa->pkeys, digest, delim);
- if ((*argvp)->argc == 0) {
- argv_free(*argvp);
- *argvp = 0;
+ /* Remove empty elements from the list */
+ if (tlsa->pkeys->argc == 0) {
+ argv_free(tlsa->pkeys);
+ tlsa->pkeys = 0;
- /* Remove empty elements from the list */
- if (tlsa->pkeys == 0 && tlsa->certs == 0) {
+ if (tlsa->certs == 0) {
*tlsap = tlsa->next;
tlsa_free(tlsa);
}
+ return;
}
+
+ /*
+ * At the "fingerprint" security level certificate digests and public key
+ * digests are interchangeable. Each leaf certificate is matched via
+ * either the public key digest or full certificate digest. The DER
+ * encoding of a certificate is not a valid public key, and conversely,
+ * the DER encoding of a public key is not a valid certificate. An
+ * attacker would need a 2nd-preimage that is feasible across types
+ * (given cert digest == some pkey digest) and yet presumably difficult
+ * within a type (e.g. given cert digest == some other cert digest). No
+ * such attacks are known at this time, and it is expected that if any
+ * are found they would work within as well as across the cert/pkey data
+ * types.
+ */
+ if (tlsa->certs == 0)
+ tlsa->certs = argv_split(digest, delim);
+ else
+ argv_split_append(tlsa->certs, digest, delim);
}
/* dane_add - add a digest entry */
@@ -729,8 +724,7 @@ static void dane_add(TLS_DANE *dane, int certusage, int selector,
tlsap = (certusage == TLS_DANE_EE) ? &dane->ee : &dane->ta;
tlsa = *(tlsap = dane_locate(tlsap, mdalg));
- argvp = ((dane->flags & TLS_DANE_FLAG_MIXED) || selector == TLS_DANE_PKEY) ?
- &tlsa->pkeys : &tlsa->certs;
+ argvp = (selector == TLS_DANE_PKEY) ? &tlsa->pkeys : &tlsa->certs;
if (*argvp == 0)
*argvp = argv_alloc(1);
@@ -877,7 +871,7 @@ static int parse_tlsa_rr(DNS_RR *rr, filter_ctx *ctx)
if (ctx->target && ctx->target != ctx->count)
ctx->flags &= ~FILTER_CTX_AGILITY_OK;
else
- ctx->target = (change & ~0xff) ? 0 : ctx->count;
+ ctx->target = (change & 0xffff00) ? 0 : ctx->count;
ctx->count = 0;
}
}
@@ -969,8 +963,8 @@ static int parse_tlsa_rr(DNS_RR *rr, filter_ctx *ctx)
k = X509_get_pubkey(x);
EVP_PKEY_free(k);
if (k == 0) {
- msg_warn("%s public key malformed in RR: "
- "%s%s%s IN TLSA %u %u %u ...", "certificate",
+ msg_warn("malformed %s in RR: %s%s%s IN TLSA %u %u %u ...",
+ "or unsupported certificate public key",
q, a, r, usage, selector, mtype);
X509_free(x);
return (FILTER_RR_DROP);
@@ -989,14 +983,18 @@ static int parse_tlsa_rr(DNS_RR *rr, filter_ctx *ctx)
case DNS_TLSA_SELECTOR_SUBJECTPUBLICKEYINFO:
if (!d2i_PUBKEY(&k, &p, dlen) || dlen != p - data) {
- msg_warn("malformed %s in RR: "
- "%s%s%s IN TLSA %u %u %u ...", "public key",
- q, a, r, usage, selector, mtype);
+ msg_warn("malformed %s in RR: %s%s%s IN TLSA %u %u %u ...",
+ "public key", q, a, r, usage, selector, mtype);
if (k)
EVP_PKEY_free(k);
return (FILTER_RR_DROP);
}
- /* See full cert case above */
+
+ /*
+ * When a full trust-anchor public key is published via DNS, we
+ * may need to use it to validate the server trust chain. Store
+ * it away for later use.
+ */
if (usage == DNS_TLSA_USAGE_TRUST_ANCHOR_ASSERTION
&& (ctx->flags & FILTER_CTX_PARSE_DATA))
ta_pkey_insert(ctx->dane, k);
@@ -1073,7 +1071,7 @@ static void *dane_lookup(const char *tlsa_fqdn, void *unused_ctx)
if (why == 0)
why = vstring_alloc(10);
- dane = tls_dane_alloc(0);
+ dane = tls_dane_alloc();
ret = dns_lookup(tlsa_fqdn, T_TLSA, RES_USE_DNSSEC, &rrs, 0, why);
switch (ret) {
@@ -1163,7 +1161,7 @@ TLS_DANE *tls_dane_resolve(unsigned port, const char *proto, DNS_RR *hostrr,
*/
iscname = strcasecmp(hostrr->rname, hostrr->qname);
if (!forcetlsa && !hostrr->dnssec_valid && !iscname) {
- dane = tls_dane_alloc(0);
+ dane = tls_dane_alloc();
dane->flags = TLS_DANE_FLAG_NORRS;
} else {
@@ -1301,12 +1299,10 @@ int tls_dane_match(TLS_SESS_STATE *TLScontext, int usage,
TLS_TLSA *tlsa = (usage == TLS_DANE_EE) ? dane->ee : dane->ta;
const char *namaddr = TLScontext->namaddr;
const char *ustr = (usage == TLS_DANE_EE) ? "end entity" : "trust anchor";
- int mixed = (dane->flags & TLS_DANE_FLAG_MIXED);
int matched;
for (matched = 0; tlsa && !matched; tlsa = tlsa->next) {
char **dgst;
- ARGV *certs;
/*
* Note, set_trust() needs to know whether the match was for a pkey
@@ -1328,26 +1324,10 @@ int tls_dane_match(TLS_SESS_STATE *TLScontext, int usage,
namaddr, depth, ustr, tlsa->mdalg, pkey_dgst);
myfree(pkey_dgst);
}
-
- /*
- * Backwards compatible "fingerprint" security level interface:
- *
- * Certificate digests and public key digests are interchangeable, each
- * leaf certificate is matched via either the public key digest or
- * full certificate digest when "mixed" is true. The combined set of
- * digests is stored on the pkeys digest list and the certs list is
- * empty. An attacker would need a 2nd-preimage (not just a
- * collision) that is feasible across types (given cert digest ==
- * some key digest) while difficult within a type (e.g. given cert
- * some other cert digest). No such attacks are know at this time,
- * and it is expected that if any are found they would work within as
- * well as across the cert/key data types.
- */
- certs = mixed ? tlsa->pkeys : tlsa->certs;
- if (certs != 0 && !matched) {
+ if (tlsa->certs != 0 && !matched) {
char *cert_dgst = tls_cert_fprint(cert, tlsa->mdalg);
- for (dgst = certs->argv; !matched && *dgst; ++dgst)
+ for (dgst = tlsa->certs->argv; !matched && *dgst; ++dgst)
if (strcasecmp(cert_dgst, *dgst) == 0)
matched = MATCHED_CERT;
if (TLScontext->log_mask & (TLS_LOG_VERBOSE | TLS_LOG_CERTMATCH)
diff --git a/postfix/src/tls/tls_fprint.c b/postfix/src/tls/tls_fprint.c
index 40746ea55..abd5ff7d4 100644
--- a/postfix/src/tls/tls_fprint.c
+++ b/postfix/src/tls/tls_fprint.c
@@ -223,9 +223,6 @@ char *tls_serverid_digest(const TLS_CLIENT_START_PROPS *props, long protomask,
* we must include the SNI name in the session id.
*/
if (props->dane) {
- int mixed = (props->dane->flags & TLS_DANE_FLAG_MIXED);
-
- digest_object(&mixed);
digest_dane(props->dane, ta);
#if 0
digest_dane(props->dane, ee); /* See above */