From: Wietse Venema Date: Wed, 27 Mar 2013 01:44:46 +0000 (-0400) Subject: postfix-2.11-20130327 X-Git-Tag: v2.11.0-RC1~43 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b7f38732d966e18c031109908cb1a52384070691;p=thirdparty%2Fpostfix.git postfix-2.11-20130327 --- diff --git a/postfix/HISTORY b/postfix/HISTORY index 91b190cf0..6ef1a2bdc 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -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. diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index fe4f14218..78e976e07 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 "20130326" +#define MAIL_RELEASE_DATE "20130327" #define MAIL_VERSION_NUMBER "2.11" #ifdef SNAPSHOT diff --git a/postfix/src/tls/tls.h b/postfix/src/tls/tls.h index 3592f97bd..0c65743dd 100644 --- a/postfix/src/tls/tls.h +++ b/postfix/src/tls/tls.h @@ -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, diff --git a/postfix/src/tls/tls_fprint.c b/postfix/src/tls/tls_fprint.c index f7c10eaf9..88f7c03fa 100644 --- a/postfix/src/tls/tls_fprint.c +++ b/postfix/src/tls/tls_fprint.c @@ -6,11 +6,20 @@ /* SYNOPSIS /* #include /* -/* 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; @@ -19,8 +28,19 @@ /* 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(). @@ -29,20 +49,32 @@ /* 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 */ diff --git a/postfix/src/util/open_limit.c b/postfix/src/util/open_limit.c index 7aec951b9..8d4943375 100644 --- a/postfix/src/util/open_limit.c +++ b/postfix/src/util/open_limit.c @@ -34,7 +34,7 @@ #include #include -#ifdef MACOSX +#ifdef USE_MAX_FILES_PER_PROC #include #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); diff --git a/postfix/src/util/poll_fd.c b/postfix/src/util/poll_fd.c index d7f84a222..5b22b1289 100644 --- a/postfix/src/util/poll_fd.c +++ b/postfix/src/util/poll_fd.c @@ -12,13 +12,13 @@ /* 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; @@ -95,54 +95,48 @@ #include #include -#ifdef USE_SYSV_POLL -#include -#endif - -#ifdef USE_SYS_SELECT_H -#include -#endif - -/* Utility library. */ - -#include -#include + /* + * 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 #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 #endif +/* Utility library. */ + +#include +#include + #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); } } diff --git a/postfix/src/util/sys_defs.h b/postfix/src/util/sys_defs.h index 60d6b7f60..2bb01d792 100644 --- a/postfix/src/util/sys_defs.h +++ b/postfix/src/util/sys_defs.h @@ -254,8 +254,9 @@ #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.