]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.11-20131214-nonprod 20131214-nonprod
authorWietse Venema <wietse@porcupine.org>
Sat, 14 Dec 2013 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <postfix-users@dukhovni.org>
Sun, 15 Dec 2013 04:58:25 +0000 (23:58 -0500)
21 files changed:
postfix/HISTORY
postfix/conf/postfix-files
postfix/html/local.8.html
postfix/html/pipe.8.html
postfix/html/postconf.5.html
postfix/html/smtpd.8.html
postfix/html/trivial-rewrite.8.html
postfix/makedefs
postfix/man/man5/postconf.5
postfix/man/man8/local.8
postfix/man/man8/pipe.8
postfix/man/man8/smtpd.8
postfix/man/man8/trivial-rewrite.8
postfix/proto/postconf.proto
postfix/src/global/mail_version.h
postfix/src/local/local.c
postfix/src/pipe/pipe.c
postfix/src/smtpd/smtpd.c
postfix/src/tls/tls_dane.c
postfix/src/tls/tls_server.c
postfix/src/trivial-rewrite/trivial-rewrite.c

index 53f08e97112c7b40d97033b0c6b1bfb1743887c5..9d135a3b7f8fbc5138c59f4134aaa9013d09e821 100644 (file)
@@ -19332,5 +19332,35 @@ Apologies for any names omitted.
        range. Viktor Dukhovni.  Files: proto/TLS_README.html,
        proto/postconf.proto.
 
-       Bugfix (DANE support): handle OpenSSL memory allocation
+       Bugfix: DANE support: handle OpenSSL memory allocation
        error. Viktor Dukhovni.  File: tls/tls_dane.c.
+
+       Cleanup: LMDB_README was not installed. File: conf/postfix-files.
+
+20131214
+
+       Portability: on some platforms posttls-finger now requires
+       explicitly linking libdl.  File: posttls-finger/Makefile.in.
+
+       Cleanup: DANE support: extension gymnastics. Viktor Dukhovni.
+       File: tls/tls_dane.c.
+
+       Bugfix: DANE support: the wrap_cert() and wrap_key() calls
+       should never fail, but some callers ignored the return
+       value.  The only failure is for lack of memory, so we use
+       msg_fatal() internally and change wrap_cert() and wrap_key()
+       to return void. Viktor Dukhovni.  File: tls/tls_dane.c.
+
+       Bugfix: DANE support: avoid making DANE certificates with
+       replaced public-keys appear as if they were self-signed.
+       Viktor Dukhovni.  File: tls/tls_dane.c.
+
+       Cleanup: DANE support: simplify grow_chain() to always apply
+       trust consistently. Viktor Dukhovni.  File: tls/tls_dane.c.
+
+       Bugfix: DANE support: backport fixes from OpenSSL DANE
+       testing.  Discard errors generated by raw TA key signature
+       checks. Record the tadepth as zero with self-signed depth
+       0 TAs. Robustness: Though it should never happen, don't
+       update the tadepth if already set. Viktor Dukhovni.  Files:
+       tls/tls_dane.c, tls/tls_server.c.
index 2da438efc42a0fa65af276449eea47a8affe606e..3304edf9d62e3b86d80a60e540cff3b76f3cf129 100644 (file)
@@ -264,6 +264,7 @@ $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
@@ -319,6 +320,7 @@ $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
index ee4dff4de3fdd3b69e8c79c5a6e02e8c54edfd40..d88e556fcbe1d9509248b8824af79da340cb425e 100644 (file)
@@ -609,7 +609,9 @@ LOCAL(8)                                                              LOCAL(8)
 
        <b><a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> (empty)</b>
               The set of characters that can separate a user name
-              from its address extension (user+foo).
+              from its extension (example: user+foo), or a  .for-
+              ward  file  name from its extension (example: .for-
+              ward+foo).
 
        <b><a href="postconf.5.html#require_home_directory">require_home_directory</a> (no)</b>
               Require that a <a href="local.8.html"><b>local</b>(8)</a> recipient's home  directory
index 9705d00e5e84f9851038923e5ee88a9d526aad36..90e831fe200851a4ec4032591bf8523adb706ae3 100644 (file)
@@ -488,7 +488,9 @@ PIPE(8)                                                                PIPE(8)
 
        <b><a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> (empty)</b>
               The set of characters that can separate a user name
-              from its address extension (user+foo).
+              from its extension (example: user+foo), or a  .for-
+              ward  file  name from its extension (example: .for-
+              ward+foo).
 
        <b><a href="postconf.5.html#syslog_facility">syslog_facility</a> (mail)</b>
               The syslog facility of Postfix logging.
index 44edbb94f77e51ce521549ca0350eeb79e33384a..565659f358ad4df2ad162ab540eebbe8595b50f0 100644 (file)
@@ -8558,23 +8558,27 @@ Example:
 (default: empty)</b></DT><DD>
 
 <p> The set of characters that can separate a user name from its
-address extension (user+foo).  See <a href="canonical.5.html">canonical(5)</a>, <a href="local.8.html">local(8)</a>, <a href="relocated.5.html">relocated(5)</a>
-and <a href="virtual.5.html">virtual(5)</a> for the effects this has on aliases, canonical,
-virtual, and relocated lookups.  Basically, the software tries
-user+foo and .forward+foo before trying user and .forward.  </p>
-
-<p> This implementation recognizes one delimiter character per email
-address, and one address extension per email address.  </p>
+extension (example: user+foo), or a .forward file name from its
+extension (example: .forward+foo).  Basically, the software tries
+user+foo and .forward+foo before trying user and .forward.  This
+implementation recognizes one delimiter character and one extension
+per email address or .forward file name. </p>
 
 <p> When the <a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> set contains multiple characters
-(Postfix 2.11 and later), a user name is separated from its address
-extension by the first character that matches the <a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a>
-set. </p>
+(Postfix 2.11 and later), a user name or .forward file name is
+separated from its extension by the first character that matches
+the <a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> set. </p>
+
+<p> See <a href="canonical.5.html">canonical(5)</a>, <a href="local.8.html">local(8)</a>, <a href="relocated.5.html">relocated(5)</a> and <a href="virtual.5.html">virtual(5)</a> for the
+effects of <a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> on lookups in aliases, canonical,
+virtual, and relocated maps, and see the <a href="postconf.5.html#propagate_unmatched_extensions">propagate_unmatched_extensions</a>
+parameter for propagating an extension from one email address to
+another.  </p>
 
 <p> When used in <a href="postconf.5.html#command_execution_directory">command_execution_directory</a>, <a href="postconf.5.html#forward_path">forward_path</a>, or
-<a href="postconf.5.html#luser_relay">luser_relay</a>, ${<a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a>} is replaced
-with the recipient delimiter that was found in the recipient email
-address (Postfix 2.11 and later), or it is replaced with the <a href="postconf.5.html">main.cf</a>
+<a href="postconf.5.html#luser_relay">luser_relay</a>, ${<a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a>} is replaced with the actual
+recipient delimiter that was found in the recipient email address
+(Postfix 2.11 and later), or it is replaced with the <a href="postconf.5.html">main.cf</a>
 <a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> parameter value (Postfix 2.10 and earlier).
 </p>
 
index fe7f161526b163b760121070099ff83ab9ef1440..c44cbe9698f4afd973e4a2dd64946781eca516bf 100644 (file)
@@ -725,7 +725,7 @@ SMTPD(8)                                                              SMTPD(8)
               The  Internet protocols Postfix will attempt to use
               when making or accepting connections.
 
-       <b><a href="postconf.5.html#local_recipient_maps">local_recipient_maps</a>             (<a href="proxymap.8.html">proxy</a>:unix:passwd.byname</b>
+       <b><a href="postconf.5.html#local_recipient_maps">local_recipient_maps</a>             (<a href="proxymap.8.html">proxy</a>:<a href="DATABASE_README.html#types">unix</a>:passwd.byname</b>
        <b>$<a href="postconf.5.html#alias_maps">alias_maps</a>)</b>
               Lookup tables with all names or addresses of  local
               recipients:  a  recipient address is local when its
@@ -1287,7 +1287,9 @@ SMTPD(8)                                                              SMTPD(8)
 
        <b><a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> (empty)</b>
               The set of characters that can separate a user name
-              from its address extension (user+foo).
+              from its extension (example: user+foo), or a  .for-
+              ward  file  name from its extension (example: .for-
+              ward+foo).
 
        <b><a href="postconf.5.html#smtpd_banner">smtpd_banner</a> ($<a href="postconf.5.html#myhostname">myhostname</a> ESMTP $<a href="postconf.5.html#mail_name">mail_name</a>)</b>
               The text that follows the 220 status  code  in  the
index e417e9d082171f0ce7a1d4b6927cd8ea2299ace8..4d2fdac3d5e7f26005f2dde1f4141eb2db3c2ab4 100644 (file)
@@ -138,7 +138,9 @@ TRIVIAL-REWRITE(8)                                          TRIVIAL-REWRITE(8)
 
        <b><a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> (empty)</b>
               The set of characters that can separate a user name
-              from its address extension (user+foo).
+              from its extension (example: user+foo), or a  .for-
+              ward  file  name from its extension (example: .for-
+              ward+foo).
 
        <b><a href="postconf.5.html#swap_bangpath">swap_bangpath</a> (yes)</b>
               Enable   the   rewriting   of   "site!user"    into
index ad82b1193d5ea4ad66a49f71e79365e2cb20aa1b..8cf414f87bcaba70c7e241fe9198a99ef4c5e533 100644 (file)
@@ -201,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
index b989d556a9477c0bf1ea714c88c6108ecc3cb761..a46106d64cc37310d06c0c069f6f01309e1537c2 100644 (file)
@@ -5131,23 +5131,27 @@ recipient_canonical_maps = hash:/etc/postfix/recipient_canonical
 .ft R
 .SH recipient_delimiter (default: empty)
 The set of characters that can separate a user name from its
-address extension (user+foo).  See \fBcanonical\fR(5), \fBlocal\fR(8), \fBrelocated\fR(5)
-and \fBvirtual\fR(5) for the effects this has on aliases, canonical,
-virtual, and relocated lookups.  Basically, the software tries
-user+foo and .forward+foo before trying user and .forward.
-.PP
-This implementation recognizes one delimiter character per email
-address, and one address extension per email address.
+extension (example: user+foo), or a .forward file name from its
+extension (example: .forward+foo).  Basically, the software tries
+user+foo and .forward+foo before trying user and .forward.  This
+implementation recognizes one delimiter character and one extension
+per email address or .forward file name.
 .PP
 When the recipient_delimiter set contains multiple characters
-(Postfix 2.11 and later), a user name is separated from its address
-extension by the first character that matches the recipient_delimiter
-set.
+(Postfix 2.11 and later), a user name or .forward file name is
+separated from its extension by the first character that matches
+the recipient_delimiter set.
+.PP
+See \fBcanonical\fR(5), \fBlocal\fR(8), \fBrelocated\fR(5) and \fBvirtual\fR(5) for the
+effects of recipient_delimiter on lookups in aliases, canonical,
+virtual, and relocated maps, and see the propagate_unmatched_extensions
+parameter for propagating an extension from one email address to
+another.
 .PP
 When used in command_execution_directory, forward_path, or
-luser_relay, ${recipient_delimiter} is replaced
-with the recipient delimiter that was found in the recipient email
-address (Postfix 2.11 and later), or it is replaced with the main.cf
+luser_relay, ${recipient_delimiter} is replaced with the actual
+recipient delimiter that was found in the recipient email address
+(Postfix 2.11 and later), or it is replaced with the main.cf
 recipient_delimiter parameter value (Postfix 2.10 and earlier).
 .PP
 The recipient_delimiter is not applied to the mailer-daemon
index b872ce6fe8b061a727865d4ba01cf5db50abecd7..fb50757e3d65f7a5b27a3723e5239d81275be068 100644 (file)
@@ -576,7 +576,8 @@ key to the lookup result.
 The location of the Postfix top-level queue directory.
 .IP "\fBrecipient_delimiter (empty)\fR"
 The set of characters that can separate a user name from its
-address extension (user+foo).
+extension (example: user+foo), or a .forward file name from its
+extension (example: .forward+foo).
 .IP "\fBrequire_home_directory (no)\fR"
 Require that a \fBlocal\fR(8) recipient's home directory exists
 before mail delivery is attempted.
index dc594a814bd55d7f88ab56d8fd7b6a213510d855..41d5159648bb122a1e1db3d5591d9b2775340162 100644 (file)
@@ -417,7 +417,8 @@ The process name of a Postfix command or daemon process.
 The location of the Postfix top-level queue directory.
 .IP "\fBrecipient_delimiter (empty)\fR"
 The set of characters that can separate a user name from its
-address extension (user+foo).
+extension (example: user+foo), or a .forward file name from its
+extension (example: .forward+foo).
 .IP "\fBsyslog_facility (mail)\fR"
 The syslog facility of Postfix logging.
 .IP "\fBsyslog_name (see 'postconf -d' output)\fR"
index 3651a05382642cf2de6778ad98e6bed94a9b959f..ec95a4bca5862b9ee94c8a26c3507d027c292b35 100644 (file)
@@ -1009,7 +1009,8 @@ The process name of a Postfix command or daemon process.
 The location of the Postfix top-level queue directory.
 .IP "\fBrecipient_delimiter (empty)\fR"
 The set of characters that can separate a user name from its
-address extension (user+foo).
+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.
index ff0b25a9965d82454178f4abc0d7eddf057d015e..27a7bb3f88f427b0f4d2bc8465c4bc6f3a7dfd49 100644 (file)
@@ -135,7 +135,8 @@ With locally submitted mail, append the string ".$mydomain" to
 addresses that have no ".domain" information.
 .IP "\fBrecipient_delimiter (empty)\fR"
 The set of characters that can separate a user name from its
-address extension (user+foo).
+extension (example: user+foo), or a .forward file name from its
+extension (example: .forward+foo).
 .IP "\fBswap_bangpath (yes)\fR"
 Enable the rewriting of "site!user" into "user@site".
 .PP
index faebacf636b9f565a26c7412797fe8b40b7b8a14..b4204fc6ceddd636e7dea5f83baff8284c492998 100644 (file)
@@ -3505,23 +3505,27 @@ recipient_canonical_maps = hash:/etc/postfix/recipient_canonical
 %PARAM recipient_delimiter
 
 <p> The set of characters that can separate a user name from its
-address extension (user+foo).  See canonical(5), local(8), relocated(5)
-and virtual(5) for the effects this has on aliases, canonical,
-virtual, and relocated lookups.  Basically, the software tries
-user+foo and .forward+foo before trying user and .forward.  </p>
-
-<p> This implementation recognizes one delimiter character per email
-address, and one address extension per email address.  </p>
+extension (example: user+foo), or a .forward file name from its
+extension (example: .forward+foo).  Basically, the software tries
+user+foo and .forward+foo before trying user and .forward.  This
+implementation recognizes one delimiter character and one extension
+per email address or .forward file name. </p>
 
 <p> When the recipient_delimiter set contains multiple characters
-(Postfix 2.11 and later), a user name is separated from its address
-extension by the first character that matches the recipient_delimiter
-set. </p>
+(Postfix 2.11 and later), a user name or .forward file name is
+separated from its extension by the first character that matches
+the recipient_delimiter set. </p>
+
+<p> See canonical(5), local(8), relocated(5) and virtual(5) for the
+effects of recipient_delimiter on lookups in aliases, canonical,
+virtual, and relocated maps, and see the propagate_unmatched_extensions
+parameter for propagating an extension from one email address to
+another.  </p>
 
 <p> When used in command_execution_directory, forward_path, or
-luser_relay, ${recipient_delimiter} is replaced
-with the recipient delimiter that was found in the recipient email
-address (Postfix 2.11 and later), or it is replaced with the main.cf
+luser_relay, ${recipient_delimiter} is replaced with the actual
+recipient delimiter that was found in the recipient email address
+(Postfix 2.11 and later), or it is replaced with the main.cf
 recipient_delimiter parameter value (Postfix 2.10 and earlier).
 </p>
 
index 32071c698d5eaf22da8695efaf79b4a6745a0306..c0bd20eef9b7b1a9baebdce3f23e9db3d3122e1f 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      "20131210"
+#define MAIL_RELEASE_DATE      "20131214"
 #define MAIL_VERSION_NUMBER    "2.11"
 
 #ifdef SNAPSHOT
index 32da88bcabe854ec6e5f99807e1e609c73360b44..4b69a3032d124541909e2a7f2316222057c4a698 100644 (file)
 /*     The location of the Postfix top-level queue directory.
 /* .IP "\fBrecipient_delimiter (empty)\fR"
 /*     The set of characters that can separate a user name from its
-/*     address extension (user+foo).
+/*     extension (example: user+foo), or a .forward file name from its
+/*     extension (example: .forward+foo).
 /* .IP "\fBrequire_home_directory (no)\fR"
 /*     Require that a \fBlocal\fR(8) recipient's home directory exists
 /*     before mail delivery is attempted.
index 6c4da668cb82795a2f914c5fa4b14d10d394436a..b2e59e105bff908dce87a5133e049bf4c61e4dc3 100644 (file)
 /*     The location of the Postfix top-level queue directory.
 /* .IP "\fBrecipient_delimiter (empty)\fR"
 /*     The set of characters that can separate a user name from its
-/*     address extension (user+foo).
+/*     extension (example: user+foo), or a .forward file name from its
+/*     extension (example: .forward+foo).
 /* .IP "\fBsyslog_facility (mail)\fR"
 /*     The syslog facility of Postfix logging.
 /* .IP "\fBsyslog_name (see 'postconf -d' output)\fR"
index c3cc37c68b93cb8f3012064d528ffc39967d6859..08aa2e2b45a4ee70903df8a74d1e3ace9d822a10 100644 (file)
 /*     The location of the Postfix top-level queue directory.
 /* .IP "\fBrecipient_delimiter (empty)\fR"
 /*     The set of characters that can separate a user name from its
-/*     address extension (user+foo).
+/*     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.
index b6a78e92f2a5475cb03f803c6fa6eec933eaafc0..199b06c0c014f259cc22231953e2e3b3dbbf20ec 100644 (file)
@@ -1345,26 +1345,30 @@ int     tls_dane_match(TLS_SESS_STATE *TLScontext, int usage,
     return (matched);
 }
 
+/* push_ext - push extension onto certificate's stack, else free it */
+
+static int push_ext(X509 *cert, X509_EXTENSION *ext)
+{
+    x509_extension_stack_t *exts;
+
+    if (ext) {
+       if ((exts = cert->cert_info->extensions) == 0)
+           exts = cert->cert_info->extensions = sk_X509_EXTENSION_new_null();
+       if (exts && sk_X509_EXTENSION_push(exts, ext))
+           return 1;
+       X509_EXTENSION_free(ext);
+    }
+    return 0;
+}
+
 /* add_ext - add simple extension (no config section references) */
 
 static int add_ext(X509 *issuer, X509 *subject, int ext_nid, char *ext_val)
 {
     X509V3_CTX v3ctx;
-    X509_EXTENSION *ext;
-    x509_extension_stack_t *exts;
 
     X509V3_set_ctx(&v3ctx, issuer, subject, 0, 0, 0);
-    if ((exts = subject->cert_info->extensions) == 0)
-       exts = subject->cert_info->extensions = sk_X509_EXTENSION_new_null();
-    if (!exts)
-       return (0);
-
-    if ((ext = X509V3_EXT_conf_nid(0, &v3ctx, ext_nid, ext_val)) != 0
-       && sk_X509_EXTENSION_push(exts, ext))
-       return (1);
-    if (ext)
-       X509_EXTENSION_free(ext);
-    return (0);
+    return push_ext(subject, X509V3_EXT_conf_nid(0, &v3ctx, ext_nid, ext_val));
 }
 
 /* set_serial - set serial number to match akid or use subject's plus 1 */
@@ -1397,6 +1401,7 @@ static int add_akid(X509 *cert, AUTHORITY_KEYID *akid)
 {
     ASN1_STRING *id;
     unsigned char c = 0;
+    int     nid = NID_authority_key_identifier;
     int     ret = 0;
 
     /*
@@ -1413,7 +1418,7 @@ static int add_akid(X509 *cert, AUTHORITY_KEYID *akid)
     if ((akid = AUTHORITY_KEYID_new()) != 0
        && (akid->keyid = ASN1_OCTET_STRING_new()) != 0
        && M_ASN1_OCTET_STRING_set(akid->keyid, (void *) &c, 1)
-       && X509_add1_ext_i2d(cert, NID_authority_key_identifier, akid, 0, 0))
+       && X509_add1_ext_i2d(cert, nid, akid, 0, X509V3_ADD_DEFAULT) > 0)
        ret = 1;
     if (akid)
        AUTHORITY_KEYID_free(akid);
@@ -1424,20 +1429,12 @@ static int add_akid(X509 *cert, AUTHORITY_KEYID *akid)
 
 static int add_skid(X509 *cert, AUTHORITY_KEYID *akid)
 {
-    int     ret;
+    int     nid = NID_subject_key_identifier;
 
-    if (akid && akid->keyid) {
-       VSTRING *hexid = vstring_alloc(2 * EVP_MAX_MD_SIZE);
-       ASN1_STRING *id = (ASN1_STRING *) (akid->keyid);
-
-       hex_encode(hexid, (char *) M_ASN1_STRING_data(id),
-                  M_ASN1_STRING_length(id));
-       ret = add_ext(0, cert, NID_subject_key_identifier, STR(hexid));
-       vstring_free(hexid);
-    } else {
-       ret = add_ext(0, cert, NID_subject_key_identifier, "hash");
-    }
-    return (ret);
+    if (!akid || !akid->keyid)
+       return add_ext(0, cert, nid, "hash");
+    else
+       return X509_add1_ext_i2d(cert, nid, akid, 0, X509V3_ADD_DEFAULT) > 0;
 }
 
 /* akid_issuer_name - get akid issuer directory name */
@@ -1473,33 +1470,44 @@ static int set_issuer_name(X509 *cert, AUTHORITY_KEYID *akid)
     return (X509_set_issuer_name(cert, X509_get_subject_name(cert)));
 }
 
-/* grow_chain - add certificate to chain */
+/* grow_chain - add certificate to trusted or untrusted chain */
 
-static void grow_chain(x509_stack_t **skptr, X509 *cert, ASN1_OBJECT *trust)
+static void grow_chain(TLS_SESS_STATE *TLScontext, int trusted, X509 *cert)
 {
-    if (!*skptr && (*skptr = sk_X509_new_null()) == 0)
+    x509_stack_t **xs = trusted ? &TLScontext->trusted : &TLScontext->untrusted;
+
+#define UNTRUSTED 0
+#define TRUSTED 1
+
+    if (!*xs && (*xs = sk_X509_new_null()) == 0)
        msg_fatal("out of memory");
     if (cert) {
-       if (trust && !X509_add1_trust_object(cert, trust))
+       if (trusted && !X509_add1_trust_object(cert, serverAuth))
            msg_fatal("out of memory");
        CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509);
-       if (!sk_X509_push(*skptr, cert))
+       if (!sk_X509_push(*xs, cert))
            msg_fatal("out of memory");
     }
 }
 
 /* wrap_key - wrap TA "key" as issuer of "subject" */
 
-static int wrap_key(TLS_SESS_STATE *TLScontext, int depth,
-                           EVP_PKEY *key, X509 *subject)
+static void wrap_key(TLS_SESS_STATE *TLScontext, int depth,
+                            EVP_PKEY *key, X509 *subject)
 {
-    int     ret = 1;
-    int     selfsigned = 0;
     X509   *cert = 0;
     AUTHORITY_KEYID *akid;
     X509_NAME *name = X509_get_issuer_name(subject);
     X509_NAME *akid_name;
 
+    /*
+     * The subject name is never a NULL object unless we run out of memory.
+     * It may be an empty sequence, but the containing object always exists
+     * and its storage is owned by the certificate itself.
+     */
+    if (name == 0 || (cert = X509_new()) == 0)
+       msg_fatal("Out of memory");
+
     /*
      * Record the depth of the intermediate wrapper certificate, logged in
      * the verify callback.
@@ -1510,22 +1518,16 @@ static int wrap_key(TLS_SESS_STATE *TLScontext, int depth,
            msg_info("%s: depth=%d chain is trust-anchor signed",
                     TLScontext->namaddr, depth);
     }
+    akid = X509_get_ext_d2i(subject, NID_authority_key_identifier, 0, 0);
+
+    ERR_clear_error();
 
     /*
      * If key is NULL generate a self-signed root CA, with key "danekey",
      * otherwise an intermediate CA signed by above.
+     * 
+     * CA cert valid for +/- 30 days.
      */
-    if ((cert = X509_new()) == 0)
-       return (0);
-
-    akid = X509_get_ext_d2i(subject, NID_authority_key_identifier, 0, 0);
-    if ((akid_name = akid_issuer_name(akid)) == 0
-       || X509_NAME_cmp(name, akid_name) == 0)
-       selfsigned = 1;
-
-    ERR_clear_error();
-
-    /* CA cert valid for +/- 30 days */
     if (!X509_set_version(cert, 2)
        || !set_serial(cert, akid, subject)
        || !X509_set_subject_name(cert, name)
@@ -1534,41 +1536,35 @@ static int wrap_key(TLS_SESS_STATE *TLScontext, int depth,
        || !X509_gmtime_adj(X509_get_notAfter(cert), 30 * 86400L)
        || !X509_set_pubkey(cert, key ? key : danekey)
        || !add_ext(0, cert, NID_basic_constraints, "CA:TRUE")
-       || (key && !selfsigned && !add_akid(cert, akid))
+       || (key && !add_akid(cert, akid))
        || !add_skid(cert, akid)
-       || (wrap_signed
-           && (!X509_sign(cert, danekey, signmd)
-               || (key && !selfsigned
-                   && !wrap_key(TLScontext, depth + 1, 0, cert))))) {
-       msg_warn("error generating DANE wrapper certificate");
+       || (wrap_signed && !X509_sign(cert, danekey, signmd))) {
        tls_print_errors();
-       ret = 0;
+       msg_fatal("error generating DANE wrapper certificate");
     }
     if (akid)
        AUTHORITY_KEYID_free(akid);
-    if (ret) {
-       if (key && !selfsigned && wrap_signed)
-           grow_chain(&TLScontext->untrusted, cert, 0);
-       else
-           grow_chain(&TLScontext->trusted, cert, serverAuth);
-    }
+    if (key && wrap_signed) {
+       wrap_key(TLScontext, depth + 1, 0, cert);
+       grow_chain(TLScontext, UNTRUSTED, cert);
+    } else
+       grow_chain(TLScontext, TRUSTED, cert);
     if (cert)
        X509_free(cert);
-    return (ret);
 }
 
-/* wrap_cert - wrap "tacert" as issuer of "subject" */
+/* wrap_cert - wrap "tacert" as trust-anchor. */
 
-static int wrap_cert(TLS_SESS_STATE *TLScontext, int depth,
-                            X509 *tacert, X509 *subject)
+static void wrap_cert(TLS_SESS_STATE *TLScontext, X509 *tacert, int depth)
 {
-    int     ret = 1;
     X509   *cert;
     int     len;
     unsigned char *asn1;
     unsigned char *buf;
 
-    TLScontext->tadepth = depth;
+    if (TLScontext->tadepth < 0)
+       TLScontext->tadepth = depth + 1;
+
     if (TLScontext->log_mask & (TLS_LOG_VERBOSE | TLS_LOG_CERTMATCH))
        msg_info("%s: depth=%d trust-anchor certificate",
                 TLScontext->namaddr, depth);
@@ -1576,10 +1572,9 @@ static int wrap_cert(TLS_SESS_STATE *TLScontext, int depth,
     /*
      * If the TA certificate is self-issued, use it directly.
      */
-    if (!wrap_signed
-       || X509_check_issued(tacert, tacert) == X509_V_OK) {
-       grow_chain(&TLScontext->trusted, tacert, serverAuth);
-       return (ret);
+    if (!wrap_signed || X509_check_issued(tacert, tacert) == X509_V_OK) {
+       grow_chain(TLScontext, TRUSTED, tacert);
+       return;
     }
     /* Deep-copy tacert by converting to ASN.1 and back */
     len = i2d_X509(tacert, NULL);
@@ -1594,17 +1589,15 @@ static int wrap_cert(TLS_SESS_STATE *TLScontext, int depth,
        msg_panic("d2i_X509 failed to decode TA certificate");
     myfree((char *) asn1);
 
-    grow_chain(&TLScontext->untrusted, cert, 0);
+    grow_chain(TLScontext, UNTRUSTED, cert);
 
     /* Sign and wrap TA cert with internal "danekey" */
-    if (!X509_sign(cert, danekey, signmd)
-       || !wrap_key(TLScontext, depth + 1, danekey, cert)) {
-       msg_warn("error generating DANE wrapper certificate");
+    if (!X509_sign(cert, danekey, signmd)) {
        tls_print_errors();
-       ret = 0;
+       msg_fatal("error generating DANE wrapper certificate");
     }
+    wrap_key(TLScontext, depth + 1, danekey, cert);
     X509_free(cert);
-    return (ret);
 }
 
 /* ta_signed - is certificate signed by a TLSA cert or pkey */
@@ -1629,8 +1622,8 @@ static int ta_signed(TLS_SESS_STATE *TLScontext, X509 *cert, int depth)
            if ((pk = X509_get_pubkey(x->cert)) == 0)
                continue;
            /* Check signature, since some other TA may work if not this. */
-           if (X509_verify(cert, pk) > 0)
-               done = wrap_cert(TLScontext, depth + 1, x->cert, cert);
+           if ((done = (X509_verify(cert, pk) > 0)) != 0)
+               wrap_cert(TLScontext, x->cert, depth);
            EVP_PKEY_free(pk);
        }
     }
@@ -1651,10 +1644,15 @@ static int ta_signed(TLS_SESS_STATE *TLScontext, X509 *cert, int depth)
      * ASN1 tag and length thus also excluding the unused bits field that is
      * logically part of the length).  However, some CAs have a non-standard
      * authority keyid, so we lose.  Too bad.
+     * 
+     * This may push errors onto the stack when the certificate signature is not
+     * of the right type or length, throw these away.
      */
     for (k = dane->pkeys; !done && k; k = k->next)
-       if (X509_verify(cert, k->pkey) > 0)
-           done = wrap_key(TLScontext, depth, k->pkey, cert);
+       if ((done = (X509_verify(cert, k->pkey) > 0)) != 0)
+           wrap_key(TLScontext, depth, k->pkey, cert);
+       else
+           ERR_clear_error();
 
     return (done);
 }
@@ -1704,7 +1702,7 @@ static void set_trust(TLS_SESS_STATE *TLScontext, X509_STORE_CTX *ctx)
        if (match) {
            switch (match) {
            case MATCHED_CERT:
-               wrap_cert(TLScontext, depth, ca, cert);
+               wrap_cert(TLScontext, ca, depth);
                break;
            case MATCHED_PKEY:
                if ((takey = X509_get_pubkey(ca)) == 0)
@@ -1719,7 +1717,7 @@ static void set_trust(TLS_SESS_STATE *TLScontext, X509_STORE_CTX *ctx)
            break;
        }
        /* Add untrusted ca. */
-       grow_chain(&TLScontext->untrusted, ca, 0);
+       grow_chain(TLScontext, UNTRUSTED, ca);
 
        /* Final untrusted self-signed element? */
        if (X509_check_issued(ca, ca) == X509_V_OK) {
@@ -1738,7 +1736,7 @@ static void set_trust(TLS_SESS_STATE *TLScontext, X509_STORE_CTX *ctx)
      */
     if (!cert || !ta_signed(TLScontext, cert, depth)) {
        /* Create empty trust list if null, else NOP */
-       grow_chain(&TLScontext->trusted, 0, 0);
+       grow_chain(TLScontext, TRUSTED, 0);
     }
     /* shallow free */
     if (in)
@@ -1767,11 +1765,12 @@ static int dane_cb(X509_STORE_CTX *ctx, void *app_ctx)
         * Empty untrusted chain, could be NULL, but then ABI check less
         * reliable, we may zero some other field, ...
         */
-       grow_chain(&TLScontext->untrusted, 0, 0);
-       if (tls_dane_match(TLScontext, TLS_DANE_TA, cert, 0))
-           grow_chain(&TLScontext->trusted, cert, serverAuth);
-       else
-           grow_chain(&TLScontext->trusted, 0, 0);
+       grow_chain(TLScontext, UNTRUSTED, 0);
+       if (tls_dane_match(TLScontext, TLS_DANE_TA, cert, 0)) {
+           TLScontext->tadepth = 0;
+           grow_chain(TLScontext, TRUSTED, cert);
+       } else
+           grow_chain(TLScontext, TRUSTED, 0);
     } else {
        set_trust(TLScontext, ctx);
     }
index f6de965c25a41e60146f0a2100707bd56512c99a..2e74132b8781498e41e9f10945d227df82e4584f 100644 (file)
@@ -183,8 +183,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)
 
 
index c5dbe066333a4d49b41e7d720031837a2344ace4..e3889ac24b6c85b91e9b04947c0f249d352cab64 100644 (file)
 /*     addresses that have no ".domain" information.
 /* .IP "\fBrecipient_delimiter (empty)\fR"
 /*     The set of characters that can separate a user name from its
-/*     address extension (user+foo).
+/*     extension (example: user+foo), or a .forward file name from its
+/*     extension (example: .forward+foo).
 /* .IP "\fBswap_bangpath (yes)\fR"
 /*     Enable the rewriting of "site!user" into "user@site".
 /* .PP