]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.11-20131208-nonprod 20131208-nonprod
authorWietse Venema <wietse@porcupine.org>
Sun, 8 Dec 2013 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <postfix-users@dukhovni.org>
Sun, 8 Dec 2013 21:13:20 +0000 (16:13 -0500)
19 files changed:
postfix/.indent.pro
postfix/HISTORY
postfix/README_FILES/MULTI_INSTANCE_README
postfix/RELEASE_NOTES
postfix/html/MULTI_INSTANCE_README.html
postfix/html/lmdb_table.5.html
postfix/html/posttls-finger.1.html
postfix/man/man5/lmdb_table.5
postfix/man/man5/postconf.5
postfix/proto/MULTI_INSTANCE_README.html
postfix/proto/lmdb_table
postfix/proto/postconf.man.prolog
postfix/src/global/mail_version.h
postfix/src/postconf/postconf_edit.c
postfix/src/posttls-finger/posttls-finger.c
postfix/src/smtp/smtp_tls_policy.c
postfix/src/tls/tls.h
postfix/src/tls/tls_dane.c
postfix/src/tls/tls_fprint.c

index 441e160c2b17cff24a26c10f61cc9135d6c26e70..982975fd0b4289d17276ab4124e4fa4c9749d19b 100644 (file)
 -TLMTP_STATE
 -TLOCAL_EXP
 -TLOCAL_STATE
+-TLONG_NAME_MASK
 -TMAC_EXP
 -TMAC_HEAD
 -TMAC_PARSE
 -Tsfsistat
 -Tsigset_t
 -Tsize_t
+-Tsockaddr
 -Tssize_t
 -Tssl_cipher_stack_t
 -Tssl_comp_stack_t
index 4883ede548a873fac46719f611a40a3f8e9082e2..396760acbbbe0eb5e47104add217e0298404b45f 100644 (file)
@@ -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.
+
index 6e2fb48c56473cea1e2ab010fcf9884616b8ca50..7e930f25c353124a1a795d19d80cc511a95ed4cc 100644 (file)
@@ -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: %
index 2c8619a89573d1a90459dd08a77e4c89997b58ff..cbe1a17fc4a1bbbdd310c8927fec641d26e5e928 100644 (file)
@@ -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
index 6aca5f53d4b9276bba450aaa33e6b9226a8bca11..39fc87da10caa4be605272884ffe9fe58c28c35b 100644 (file)
@@ -233,7 +233,7 @@ creates a "generic" database when none exists. </p>
     generic: Makefile
             @echo Creating $@
             @rm -f $@.tmp
-            @printf '%s\t%s+root=%s\n' root $MTAADMIN `uname -n` &gt; $@.tmp
+            @printf '%s\t%s+root=%s\n' root ${MTAADMIN} `uname -n` &gt; $@.tmp
             @mv $@.tmp generic
 
     %.<a href="CDB_README.html">cdb</a>: %
index d8dd19fafd2e7938a863da3e6be8eafaaf99ffa1..6cba132a5fe74caf736bcf223e843c4c4e30c1c5 100644 (file)
@@ -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
-       <a href="proxymap.8.html">proxymap(8)</a> service.
+       therefore violate the Postfix security model.
+
+       Multiple  processes  can  safely  update  an LMDB database
+       without serializing requests through the <a href="proxymap.8.html">proxymap(8)</a>  ser-
+       vice.  This makes LMDB suitable as a shared cache for <a href="verify.8.html">ver-</a>
+       <a href="verify.8.html">ify(8)</a> or <a href="postscreen.8.html">postscreen(8)</a> services.
 
 <b>CONFIGURATION PARAMETERS</b>
        Short-lived programs  automatically  pick  up  changes  to
index 1848d6d249731a75a5a8d1b49512ca9f34e551f1..a9a4943c547d038e891599c5837c13748147e30a 100644 (file)
@@ -12,14 +12,14 @@ POSTTLS-FINGER(1)                                            POSTTLS-FINGER(1)
 
 <b>SYNOPSIS</b>
        <b>posttls-finger</b> [<i>options</i>] [<b>inet:</b>]<i>domain</i>[:<i>port</i>] [<i>match ...</i>]
-       <b>posttls-finger</b> -S [<i>options</i>] <b>unix:</b><i>pathname</i> [<i>match ...</i>]
+       <b>posttls-finger</b> -S [<i>options</i>] <b><a href="DATABASE_README.html#types">unix</a>:</b><i>pathname</i> [<i>match ...</i>]
 
 <b>DESCRIPTION</b>
        <a href="posttls-finger.1.html"><b>posttls-finger</b>(1)</a> 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 <b>inet:</b> or a pathname pre-
-       fixed with <b>unix:</b>.  If Postfix is built  without  TLS  sup-
+       fixed with <b><a href="DATABASE_README.html#types">unix</a>:</b>.  If Postfix is built  without  TLS  sup-
        port,  the  resulting posttls-finger program has very lim-
        ited functionality, and only the <b>-a</b>, <b>-c</b>, <b>-h</b>, <b>-o</b>,  <b>-S</b>,  <b>-t</b>,
        <b>-T</b> and <b>-v</b> options are available.
@@ -83,7 +83,7 @@ POSTTLS-FINGER(1)                                            POSTTLS-FINGER(1)
        taken from the <b>smtp/tcp</b> entry in /etc/services, defaulting
        to 25 if the entry is not found.
 
-       With  LMTP,  specify  <b>unix:</b><i>pathname</i>  to connect to a local
+       With  LMTP,  specify  <b><a href="DATABASE_README.html#types">unix</a>:</b><i>pathname</i>  to connect to a local
        server listening on a  unix-domain  socket  bound  to  the
        specified  pathname;  otherwise, specify an optional <b>inet:</b>
        prefix followed by a <i>domain</i> and an optional port, with the
@@ -314,7 +314,7 @@ POSTTLS-FINGER(1)                                            POSTTLS-FINGER(1)
               validation  information  is  available  via  <b>native</b>
               lookups).
 
-       <b>unix:</b><i>pathname</i>
+       <b><a href="DATABASE_README.html#types">unix</a>:</b><i>pathname</i>
               Connect to the UNIX-domain socket at <i>pathname</i>. LMTP
               only.
 
index a45d9de9bd68b481fad2ce272aa7f09531579902..d6315bd715d320b4073bd6e0791d0938d4478903 100644 (file)
@@ -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
index a44eaf15c7bf5058278cb78c81c1527134f2ccb3..c68d90bc21daaf6a2d2ca83bc649ddc606aff84a 100644 (file)
@@ -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
index 59bb4fbd9301c3334bd0db6719d466a7ab3219f3..a2574df8921fba9c24af58e36e7604d06226c499 100644 (file)
@@ -233,7 +233,7 @@ creates a "generic" database when none exists. </p>
     generic: Makefile
            @echo Creating $@
            @rm -f $@.tmp
-           @printf '%s\t%s+root=%s\n' root $MTAADMIN `uname -n` &gt; $@.tmp
+           @printf '%s\t%s+root=%s\n' root ${MTAADMIN} `uname -n` &gt; $@.tmp
            @mv $@.tmp generic
 
     %.cdb: %
index b1cc8169a5e355d114e026621632177ba7f723b4..aa59635aa2161788d2df38467d402de4e205cb23 100644 (file)
 #      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
index 37afa4e88fe98307ac19819fdd048d1f736cadc6..170838fe64ab1e78724f86853d48712a75ae0b3c 100644 (file)
@@ -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
index 00973bb0198e31632e8b3c5599443d496c79c4c0..f5154456c672a83592b41b64ab58e0e7033c4802 100644 (file)
@@ -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
index 7607c56874a3b188e7d479c2ed55b4d61c0129da..05fdc1f403c2820ee355f0905bbccc80c6c6684a 100644 (file)
@@ -2,7 +2,7 @@
 /* NAME
 /*     postconf_edit 3
 /* SUMMARY
-/*     edit main.cf
+/*     edit main.cf or master.cf
 /* SYNOPSIS
 /*     #include <postconf.h>
 /*
 /*
 /*     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:
index 82d3aeb7d8cafec6261c27ad56a38b91e2eeef00..2779ea075d76d9810d31cc743c3b6df5ee97fb75 100644 (file)
@@ -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;
index 4f3fae10b92bc6fcb30107e6fbf6ff0c1159839a..7c93e464d44d9d2c5c66c88a091820b530c8e239 100644 (file)
@@ -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);
index cd4c2fcd2eff2881f3c5acc1ff64916d601f4b80..cf29766671a12bab4680293a43833f702a16b95e 100644 (file)
@@ -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 *);
index 92f2b6fa08256b05d437e3f35c0500a7c276c0ef..3efb2eb6fa59ddc3f3993cf01e5597d2d7ad3c3b 100644 (file)
 /*     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;
 /*     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).
 /*     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
 /* .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)
index 40746ea55fb4af8f25cbb47ce8a079d5b8e07f1c..abd5ff7d42f6b35acc9809ac38424c99a6dd4363 100644 (file)
@@ -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 */