]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.11-20130327
authorWietse Venema <wietse@porcupine.org>
Wed, 27 Mar 2013 01:44:46 +0000 (21:44 -0400)
committerViktor Dukhovni <postfix-users@dukhovni.org>
Sat, 6 Apr 2013 03:31:49 +0000 (23:31 -0400)
postfix/HISTORY
postfix/src/global/mail_version.h
postfix/src/tls/tls.h
postfix/src/tls/tls_fprint.c
postfix/src/util/open_limit.c
postfix/src/util/poll_fd.c
postfix/src/util/sys_defs.h

index 91b190cf0863465c1ad0999bb2fc5091f5dcc612..6ef1a2bdc8376af516e242296a4dd3be2b35cec8 100644 (file)
@@ -18374,3 +18374,12 @@ Apologies for any names omitted.
        src/tls/tls.h, src/tls/tls_client.c, src/tls/tls_fprint.c,
        src/tls/tls_level.c, src/tls/tls_misc.c, src/tls/tls_server.c,
        src/tls/tls_verify.c, src/tlsproxy/tlsproxy.c.
+
+20130327
+
+       Cleanup: final polish for MacOSX workarounds; replaced
+       #ifdef MacOSX by feature test as required by PORTING
+       document.  Files: util/poll_fd.c, util/open_limit.c.
+
+       Export tls_fprint() and tls_digest_encode() for use in DANE.
+       Viktor Dukhovni. Files: src/tls/tls.h, src/tls/tls_fprint.c.
index fe4f14218119748f820ce028c15192b2c266db77..78e976e072b22c2f12f6f19416cdef736a355bc5 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      "20130326"
+#define MAIL_RELEASE_DATE      "20130327"
 #define MAIL_VERSION_NUMBER    "2.11"
 
 #ifdef SNAPSHOT
index 3592f97bd2e61db07b75653e8ad599f73b3e14fe..0c65743dd66eb410d9afb7919116c5827a1a4a19 100644 (file)
@@ -404,6 +404,8 @@ extern int tls_verify_certificate_callback(int, X509_STORE_CTX *);
  /*
   * tls_fprint.c
   */
+extern char *tls_digest_encode(const unsigned char *, int);
+extern char *tls_fprint(const char *, int, const char *);
 extern char *tls_fingerprint(X509 *, const char *);
 extern char *tls_pkey_fprint(X509 *, const char *);
 extern char *tls_serverid_digest(const TLS_CLIENT_START_PROPS *, long,
index f7c10eaf9715ae5ba805faafcd5cc2b08792d979..88f7c03fad901c8d69b7d99b0bd5780af3cd151b 100644 (file)
@@ -6,11 +6,20 @@
 /* SYNOPSIS
 /*     #include <tls.h>
 /*
-/*     char    *tls_serverid_digest(props, protomask, ciphers);
+/*     char    *tls_serverid_digest(props, protomask, ciphers)
 /*     const TLS_CLIENT_START_PROPS *props;
 /*     long    protomask;
 /*     const char *ciphers;
 /*
+/*     char    *tls_digest_encode(md_buf, md_len)
+/*     const unsigned char *md_buf;
+/*     const char *md_len;
+/*
+/*     char    *tls_fprint(buf, len, mdalg)
+/*     const char *buf;
+/*     int     len;
+/*     const char *mdalg;
+/*
 /*     char    *tls_fingerprint(peercert, mdalg)
 /*     X509    *peercert;
 /*     const char *mdalg;
 /*     X509    *peercert;
 /*     const char *mdalg;
 /* DESCRIPTION
+/*     tls_digest_encode() converts a binary message digest to a hex ASCII
+/*     format with ':' separators between each pair of hex digits.
+/*     The return value is dynamically allocated with mymalloc(),
+/*     and the caller must eventually free it with myfree().
+/*
+/*     tls_fprint() digests unstructured data, and encodes the digested
+/*     result via tls_digest_encode().
+/*     The return value is dynamically allocated with mymalloc(),
+/*     and the caller must eventually free it with myfree().
+/*
 /*     tls_fingerprint() returns a fingerprint of the the given
-/*     certificate using the requested message digest. Panics if the
+/*     certificate using the requested message digest, formatted
+/*     with tls_digest_encode(). Panics if the
 /*     (previously verified) digest algorithm is not found. The return
 /*     value is dynamically allocated with mymalloc(), and the caller
 /*     must eventually free it with myfree().
 /*     other respects the function behaves as tls_fingerprint().
 /*     The var_tls_bc_pkey_fprint variable enables an incorrect
 /*     algorithm that was used in Postfix versions 2.9.[0-5].
+/*     The return value is dynamically allocated with mymalloc(),
+/*     and the caller must eventually free it with myfree().
 /*
 /*     tls_serverid_digest() suffixes props->serverid computed by the SMTP
-/*     client with a digest of additional parameters needed to ensure
-/*     that re-used sessions are more likely to be reused and will satisfy
-/*     all protocol and security requirements. The caller should pass
-/*     the result to myfree().
+/*     client with ":" plus a digest of additional parameters
+/*     needed to ensure that re-used sessions are more likely to
+/*     be reused and that they will satisfy all protocol and
+/*     security requirements.
+/*     The return value is dynamically allocated with mymalloc(),
+/*     and the caller must eventually free it with myfree().
 /*
 /*     Arguments:
 /* .IP peercert
 /*     Server or client X.509 certificate.
+/* .IP md_buf
+/*     The raw binary digest.
+/* .IP md_len
+/*     The digest length in bytes.
 /* .IP mdalg
 /*     Name of a message digest algorithm suitable for computing secure
 /*     (1st pre-image resistant) message digests of certificates. For now,
 /*     md5, sha1, or member of SHA-2 family if supported by OpenSSL.
+/* .IP buf
+/*     Input data for the message digest algorithm mdalg.
+/* .IP len
+/*     The length of the input data.
 /* .IP props
 /*     The client start properties for the session, which include the
 /*     initial serverid from the SMTP client.
@@ -155,9 +187,29 @@ char   *tls_serverid_digest(const TLS_CLIENT_START_PROPS *props, long protomask,
     return (vstring_export(result));
 }
 
+/* tls_digest_encode - encode message digest binary blob as xx:xx:... */
+
+char   *tls_digest_encode(const unsigned char *md_buf, int md_len)
+{
+    int     i;
+    char   *result = mymalloc(md_len * 3);
+
+    /* Check for contract violation */
+    if (md_len > EVP_MAX_MD_SIZE || md_len >= INT_MAX / 3)
+       msg_panic("unexpectedly large message digest size: %u", md_len);
+
+    /* No risk of overrunes, len is bounded by OpenSSL digest length */
+    for (i = 0; i < md_len; i++) {
+       result[i * 3] = hexcodes[(md_buf[i] & 0xf0) >> 4U];
+       result[(i * 3) + 1] = hexcodes[(md_buf[i] & 0x0f)];
+       result[(i * 3) + 2] = (i + 1 != md_len) ? ':' : '\0';
+    }
+    return (result);
+}
+
 /* tls_fprint - compute and encode digest of DER-encoded object */
 
-static char *tls_fprint(const char *buf, int len, const char *mdalg)
+char   *tls_fprint(const char *buf, int len, const char *mdalg)
 {
     EVP_MD_CTX *mdctx;
     const EVP_MD *md;
@@ -179,17 +231,7 @@ static char *tls_fprint(const char *buf, int len, const char *mdalg)
     if (!ok)
        msg_fatal("error computing %s message digest", mdalg);
 
-    /* Check for OpenSSL contract violation */
-    if (md_len > EVP_MAX_MD_SIZE || md_len >= INT_MAX / 3)
-       msg_panic("unexpectedly large %s digest size: %u", mdalg, md_len);
-
-    result = mymalloc(md_len * 3);
-    for (i = 0; i < md_len; i++) {
-       result[i * 3] = hexcodes[(md_buf[i] & 0xf0) >> 4U];
-       result[(i * 3) + 1] = hexcodes[(md_buf[i] & 0x0f)];
-       result[(i * 3) + 2] = (i + 1 != md_len) ? ':' : '\0';
-    }
-    return (result);
+    return (tls_digest_encode(md_buf, md_len));
 }
 
 /* tls_fingerprint - extract certificate fingerprint */
index 7aec951b92cfae51451570ce24aff87607f0521e..8d494337566a678f146973c83146bc1f8ef7da98 100644 (file)
@@ -34,7 +34,7 @@
 #include <sys/resource.h>
 #include <errno.h>
 
-#ifdef MACOSX
+#ifdef USE_MAX_FILES_PER_PROC
 #include <sys/sysctl.h>
 #define MAX_FILES_PER_PROC      "kern.maxfilesperproc"
 #endif
@@ -73,7 +73,7 @@ int     open_limit(int limit)
         * MacOSX incorrectly reports rlim_max as RLIM_INFINITY. The true
         * hard limit is finite and equals the kern.maxfilesperproc value.
         */
-#ifdef MACOSX
+#ifdef USE_MAX_FILES_PER_PROC
        int     max_files_per_proc;
        size_t  len = sizeof(max_files_per_proc);
 
index d7f84a222d1e37a5f73685ff72f1ed1e9d102d8d..5b22b1289131515d241ae2c82be3f5435d800fa4 100644 (file)
 /*     int     writable(fd)
 /*     int     fd;
 /*
-/*     int     read_wait(fd, timeout)
+/*     int     read_wait(fd, time_limit)
 /*     int     fd;
-/*     int     timeout
+/*     int     time_limit;
 /*
-/*     int     write_wait(fd, timeout)
+/*     int     write_wait(fd, time_limit)
 /*     int     fd;
-/*     int     timeout
+/*     int     time_limit;
 /*
 /*     int     poll_fd(fd, request, time_limit, success_val)
 /*     int     fd;
 #include <unistd.h>
 #include <string.h>
 
-#ifdef USE_SYSV_POLL
-#include <poll.h>
-#endif
-
-#ifdef USE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-
-/* Utility library. */
-
-#include <msg.h>
-#include <iostuff.h>
+ /*
+  * Use poll() with fall-back to select(). MacOSX needs this for devices.
+  */
+#if defined(USE_SYSV_POLL_THEN_SELECT)
+#define poll_fd_sysv   poll_fd
+#define USE_SYSV_POLL
+#define USE_BSD_SELECT
+int     poll_fd_bsd(int, int, int, int);
 
  /*
   * Use select() only.
   */
-#ifdef USE_BSD_SELECT
+#elif defined(USE_BSD_SELECT)
 #define poll_fd_bsd    poll_fd
 #undef USE_SYSV_POLL
-#undef USE_SYSV_POLL_WITH_SELECT
-#endif
 
  /*
   * Use poll() only.
   */
-#ifdef USE_SYSV_POLL
+#elif defined(USE_SYSV_POLL)
 #define poll_fd_sysv   poll_fd
-#undef USE_SYSV_POLL_WITH_SELECT
-#endif
 
  /*
-  * Use poll() with fall-back to select(). MacOSX needs this for devices.
+  * Sanity check.
   */
-#ifdef USE_SYSV_POLL_WITH_SELECT
-#define poll_fd_sysv   poll_fd
-#define USE_SYSV_POLL
-#define USE_BSD_SELECT
-int     poll_fd_bsd(int, int, int, int);
+#else
+#error "specify USE_SYSV_POLL, USE_BSD_SELECT or USE_SYSV_POLL_THEN_SELECT"
+#endif
 
+#ifdef USE_SYSV_POLL
+#include <poll.h>
 #endif
 
- /*
-  * Sanity check.
-  */
-#if !defined(USE_BSD_SELECT) && !defined(USE_SYSV_POLL)
-#error "specify USE_BSD_SELECT, USE_SYSV_POLL or USE_SYSV_POLL_WITH_SELECT"
+#ifdef USE_SYS_SELECT_H
+#include <sys/select.h>
 #endif
 
+/* Utility library. */
+
+#include <msg.h>
+#include <iostuff.h>
+
 #ifdef USE_BSD_SELECT
 
 /* poll_fd_bsd - block with time_limit until file descriptor is ready */
@@ -168,7 +162,7 @@ int     poll_fd_bsd(int fd, int request, int time_limit, int success_val)
 
     /*
      * Use select() so we do not depend on alarm() and on signal() handlers.
-     * Restart the select when interrupted by some signal. Some select()
+     * Restart select() when interrupted by some signal. Some select()
      * implementations reduce the time to wait when interrupted, which is
      * exactly what we want.
      */
@@ -220,6 +214,14 @@ int     poll_fd_bsd(int fd, int request, int time_limit, int success_val)
 
 #ifdef USE_SYSV_POLL
 
+#ifdef USE_SYSV_POLL_THEN_SELECT
+#define HANDLE_SYSV_POLL_ERROR(fd, request, time_limit, success_val) \
+       return (poll_fd_bsd((fd), (request), (time_limit), (success_val)))
+#else
+#define HANDLE_SYSV_POLL_ERROR(fd, request, time_limit, success_val) \
+       msg_fatal("poll: %m")
+#endif
+
 /* poll_fd_sysv - block with time_limit until file descriptor is ready */
 
 int     poll_fd_sysv(int fd, int request, int time_limit, int success_val)
@@ -232,23 +234,20 @@ int     poll_fd_sysv(int fd, int request, int time_limit, int success_val)
 #define WAIT_FOR_EVENT (-1)
 
     pollfd.fd = fd;
-    if (request == POLL_FD_READ)
+    if (request == POLL_FD_READ) {
        pollfd.events = POLLIN;
-    else if (request == POLL_FD_WRITE)
+    } else if (request == POLL_FD_WRITE) {
        pollfd.events = POLLOUT;
-    else
+    } else {
        msg_panic("poll_fd: bad request %d", request);
+    }
 
     for (;;) {
        switch (poll(&pollfd, 1, time_limit < 0 ?
                     WAIT_FOR_EVENT : time_limit * 1000)) {
        case -1:
            if (errno != EINTR)
-#ifdef USE_SYSV_POLL_WITH_SELECT
-               return (poll_fd_bsd(fd, request, time_limit, success_val));
-#else
-               msg_fatal("poll: %m");
-#endif
+               HANDLE_SYSV_POLL_ERROR(fd, request, time_limit, success_val);
            continue;
        case 0:
            if (time_limit == 0) {
@@ -259,7 +258,7 @@ int     poll_fd_sysv(int fd, int request, int time_limit, int success_val)
            }
        default:
            if (pollfd.revents & POLLNVAL)
-               msg_fatal("poll: %m");
+               HANDLE_SYSV_POLL_ERROR(fd, request, time_limit, success_val);
            return (success_val);
        }
     }
index 60d6b7f603ddc3a9184af95d84691b310f712d26..2bb01d79250347a85f524be417573112d3bc49de 100644 (file)
 #define SOCKOPT_SIZE   socklen_t
 #ifndef NO_KQUEUE
 # define EVENTS_STYLE  EVENTS_STYLE_KQUEUE
-# define USE_SYSV_POLL_WITH_SELECT
+# define USE_SYSV_POLL_THEN_SELECT
 #endif
+#define USE_MAX_FILES_PER_PROC
 #ifndef NO_POSIX_GETPW_R
 # define HAVE_POSIX_GETPW_R
 #endif
@@ -1374,15 +1375,22 @@ extern int inet_pton(int, const char *, void *);
 #if !defined(EVENTS_STYLE)
 #define EVENTS_STYLE   EVENTS_STYLE_SELECT
 #endif
-#if !defined(USE_SYSV_POLL) && !defined(USE_SYSV_POLL_WITH_SELECT)
-#define USE_BSD_SELECT
-#endif
 
 #define EVENTS_STYLE_SELECT    1       /* Traditional BSD select */
 #define EVENTS_STYLE_KQUEUE    2       /* FreeBSD kqueue */
 #define EVENTS_STYLE_DEVPOLL   3       /* Solaris /dev/poll */
 #define EVENTS_STYLE_EPOLL     4       /* Linux epoll */
 
+ /*
+  * We use poll() for read/write time limit enforcement on modern systems. We
+  * use select() on historical systems without poll() support. And on systems
+  * where poll() is not implemented for some file handle types, we try to use
+  * select() as a fall-back solution (MacOS X needs this).
+  */
+#if !defined(USE_SYSV_POLL) && !defined(USE_SYSV_POLL_THEN_SELECT)
+#define USE_BSD_SELECT
+#endif
+
  /*
   * The Postfix 2.9 post-install workaround assumes that the inet_protocols
   * default value is "ipv4" when Postfix is compiled without IPv6 support.