From pigeonhole at rename-it.nl Tue Dec 1 13:24:46 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 01 Dec 2015 14:24:46 +0100 Subject: dovecot-2.2-pigeonhole: Forced distribution of pigeonhole.m4 file. Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/7022bc15bbb4 changeset: 2156:7022bc15bbb4 user: Stephan Bosch date: Tue Dec 01 14:24:33 2015 +0100 description: Forced distribution of pigeonhole.m4 file. For some inapparent reason it was not included in the output tarball. diffstat: Makefile.am | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 7e9392cc0ed5 -r 7022bc15bbb4 Makefile.am --- a/Makefile.am Sun Nov 29 21:47:14 2015 +0100 +++ b/Makefile.am Tue Dec 01 14:24:33 2015 +0100 @@ -33,7 +33,7 @@ hg log --style=changelog > ChangeLog endif -aclocal_DATA = pigeonhole.m4 +dist_aclocal_DATA = pigeonhole.m4 pigeonhole-version.h: noop $(SHELL) $(top_srcdir)/update-version.sh $(top_srcdir) $(top_builddir) From dovecot at dovecot.org Tue Dec 1 14:45:51 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 01 Dec 2015 14:45:51 +0000 Subject: dovecot-2.2: lib-mail: test-rfc822-parser unit test fix Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/374db78da9f0 changeset: 19442:374db78da9f0 user: Timo Sirainen date: Tue Dec 01 16:45:37 2015 +0200 description: lib-mail: test-rfc822-parser unit test fix We didn't check that all the output was necessarily verified. Also this makes static analyzer happier. diffstat: src/lib-mail/test-rfc822-parser.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (19 lines): diff -r b0e2a14d5a40 -r 374db78da9f0 src/lib-mail/test-rfc822-parser.c --- a/src/lib-mail/test-rfc822-parser.c Mon Nov 30 21:39:56 2015 +0200 +++ b/src/lib-mail/test-rfc822-parser.c Tue Dec 01 16:45:37 2015 +0200 @@ -54,12 +54,14 @@ test_begin("rfc822 parse content param"); rfc822_parser_init(&parser, (const void *)input, strlen(input), NULL); - while ((ret = rfc822_parse_content_param(&parser, &key, &value)) > 0) { + while ((ret = rfc822_parse_content_param(&parser, &key, &value)) > 0 && + i < N_ELEMENTS(output)) { test_assert_idx(strcmp(output[i].key, key) == 0, i); test_assert_idx(strcmp(output[i].value, value) == 0, i); i++; } test_assert(ret == 0); + test_assert(i == N_ELEMENTS(output)); test_end(); } From dovecot at dovecot.org Tue Dec 1 15:31:21 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 01 Dec 2015 15:31:21 +0000 Subject: dovecot-2.2: mail-log: If uid field is used, make sure newly sav... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/25d63d9c7f5a changeset: 19443:25d63d9c7f5a user: Timo Sirainen date: Tue Dec 01 17:31:08 2015 +0200 description: mail-log: If uid field is used, make sure newly saved mails actually get an UID. With Maildir the UID is otherwise assigned on mail deliveries only if dovecot-uidlist happens to get locked. diffstat: src/plugins/mail-log/mail-log-plugin.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r 374db78da9f0 -r 25d63d9c7f5a src/plugins/mail-log/mail-log-plugin.c --- a/src/plugins/mail-log/mail-log-plugin.c Tue Dec 01 16:45:37 2015 +0200 +++ b/src/plugins/mail-log/mail-log-plugin.c Tue Dec 01 17:31:08 2015 +0200 @@ -263,6 +263,8 @@ this consistently with all mailbox formats */ mail_log_append_uid(ctx, msg, text, 0); } + /* make sure UID is assigned to this mail */ + mail->transaction->flags |= MAILBOX_TRANSACTION_FLAG_ASSIGN_UIDS; str_append(text, ", "); } if ((muser->fields & MAIL_LOG_FIELD_MSGID) != 0) { From dovecot at dovecot.org Thu Dec 3 10:03:27 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 03 Dec 2015 10:03:27 +0000 Subject: dovecot-2.2: lib-ssl-iostream: Fixes to error handling. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/151df65d2de5 changeset: 19445:151df65d2de5 user: Timo Sirainen date: Thu Dec 03 11:55:33 2015 +0200 description: lib-ssl-iostream: Fixes to error handling. Copy behavior from login-common/ssl-proxy-openssl.c: - Handle stacked errors. - Improve errors with ERR_TXT_STRING flag. diffstat: src/lib-ssl-iostream/iostream-openssl-context.c | 37 ++++++++++++++++++------ 1 files changed, 27 insertions(+), 10 deletions(-) diffs (56 lines): diff -r 2f823d983832 -r 151df65d2de5 src/lib-ssl-iostream/iostream-openssl-context.c --- a/src/lib-ssl-iostream/iostream-openssl-context.c Thu Dec 03 11:41:58 2015 +0200 +++ b/src/lib-ssl-iostream/iostream-openssl-context.c Thu Dec 03 11:55:33 2015 +0200 @@ -28,25 +28,42 @@ static int ssl_iostream_init_global(const struct ssl_iostream_settings *set, const char **error_r); +static const char *ssl_err2str(unsigned long err, const char *data, int flags) +{ + const char *ret; + char *buf; + size_t err_size = 256; + + buf = t_malloc(err_size); + buf[err_size-1] = '\0'; + ERR_error_string_n(err, buf, err_size-1); + ret = buf; + + if ((flags & ERR_TXT_STRING) != 0) + ret = t_strdup_printf("%s: %s", buf, data); + return ret; +} + const char *openssl_iostream_error(void) { unsigned long err; - char *buf; - size_t err_size = 256; + const char *data; + int flags; - err = ERR_get_error(); + while ((err = ERR_get_error_line_data(NULL, NULL, &data, &flags)) != 0) { + if (ERR_GET_REASON(err) == ERR_R_MALLOC_FAILURE) + i_fatal_status(FATAL_OUTOFMEM, "OpenSSL malloc() failed"); + if (ERR_peek_error() != 0) + break; + i_error("SSL: Stacked error: %s", + ssl_err2str(err, data, flags)); + } if (err == 0) { if (errno != 0) return strerror(errno); return "Unknown error"; } - if (ERR_GET_REASON(err) == ERR_R_MALLOC_FAILURE) - i_fatal_status(FATAL_OUTOFMEM, "OpenSSL malloc() failed"); - - buf = t_malloc(err_size); - buf[err_size-1] = '\0'; - ERR_error_string_n(err, buf, err_size-1); - return buf; + return ssl_err2str(err, data, flags); } const char *openssl_iostream_key_load_error(void) From dovecot at dovecot.org Thu Dec 3 10:03:26 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 03 Dec 2015 10:03:26 +0000 Subject: dovecot-2.2: lib-ssl-iostream: Don't ignore errors on SSL certif... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/2f823d983832 changeset: 19444:2f823d983832 user: Timo Sirainen date: Thu Dec 03 11:41:58 2015 +0200 description: lib-ssl-iostream: Don't ignore errors on SSL certificate loading. Patch by Sebastiaan Hoogeveen. diffstat: src/lib-ssl-iostream/iostream-openssl-context.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 25d63d9c7f5a -r 2f823d983832 src/lib-ssl-iostream/iostream-openssl-context.c --- a/src/lib-ssl-iostream/iostream-openssl-context.c Tue Dec 01 17:31:08 2015 +0200 +++ b/src/lib-ssl-iostream/iostream-openssl-context.c Thu Dec 03 11:41:58 2015 +0200 @@ -379,7 +379,7 @@ } if (set->cert != NULL && - ssl_ctx_use_certificate_chain(ctx->ssl_ctx, set->cert) < 0) { + ssl_ctx_use_certificate_chain(ctx->ssl_ctx, set->cert) == 0) { *error_r = t_strdup_printf("Can't load SSL certificate: %s", ssl_iostream_get_use_certificate_error(set->cert)); return -1; From dovecot at dovecot.org Thu Dec 3 10:03:27 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 03 Dec 2015 10:03:27 +0000 Subject: dovecot-2.2: login, lib-ssl-iostream: Deduplicate code with shar... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/dbbfa124b27d changeset: 19447:dbbfa124b27d user: Timo Sirainen date: Thu Dec 03 12:02:56 2015 +0200 description: login, lib-ssl-iostream: Deduplicate code with shared openssl_iostream_use_certificate_error() diffstat: src/lib-ssl-iostream/iostream-openssl-context.c | 10 ++++++-- src/lib-ssl-iostream/iostream-openssl.c | 2 +- src/lib-ssl-iostream/iostream-openssl.h | 3 +- src/login-common/ssl-proxy-openssl.c | 29 ++---------------------- 4 files changed, 13 insertions(+), 31 deletions(-) diffs (127 lines): diff -r 77990d0b1a42 -r dbbfa124b27d src/lib-ssl-iostream/iostream-openssl-context.c --- a/src/lib-ssl-iostream/iostream-openssl-context.c Thu Dec 03 11:58:11 2015 +0200 +++ b/src/lib-ssl-iostream/iostream-openssl-context.c Thu Dec 03 12:02:56 2015 +0200 @@ -174,7 +174,8 @@ return strstr(cert, "PRIVATE KEY---") != NULL; } -const char *ssl_iostream_get_use_certificate_error(const char *cert) +const char * +openssl_iostream_use_certificate_error(const char *cert, const char *set_name) { unsigned long err; @@ -185,8 +186,11 @@ else if (is_pem_key(cert)) { return "The file contains a private key " "(you've mixed ssl_cert and ssl_key settings)"; + } else if (set_name != NULL && strchr(cert, '\n') == NULL) { + return t_strdup_printf("There is no valid PEM certificate. " + "(You probably forgot '<' from %s=<%s)", set_name, cert); } else { - return "There is no certificate."; + return "There is no valid PEM certificate."; } } @@ -398,7 +402,7 @@ if (set->cert != NULL && ssl_ctx_use_certificate_chain(ctx->ssl_ctx, set->cert) == 0) { *error_r = t_strdup_printf("Can't load SSL certificate: %s", - ssl_iostream_get_use_certificate_error(set->cert)); + openssl_iostream_use_certificate_error(set->cert, NULL)); return -1; } if (set->key != NULL) { diff -r 77990d0b1a42 -r dbbfa124b27d src/lib-ssl-iostream/iostream-openssl.c --- a/src/lib-ssl-iostream/iostream-openssl.c Thu Dec 03 11:58:11 2015 +0200 +++ b/src/lib-ssl-iostream/iostream-openssl.c Thu Dec 03 12:02:56 2015 +0200 @@ -71,7 +71,7 @@ if (ret == 0) { *error_r = t_strdup_printf("Can't load ssl_cert: %s", - ssl_iostream_get_use_certificate_error(cert)); + openssl_iostream_use_certificate_error(cert, NULL)); return -1; } return 0; diff -r 77990d0b1a42 -r dbbfa124b27d src/lib-ssl-iostream/iostream-openssl.h --- a/src/lib-ssl-iostream/iostream-openssl.h Thu Dec 03 11:58:11 2015 +0200 +++ b/src/lib-ssl-iostream/iostream-openssl.h Thu Dec 03 12:02:56 2015 +0200 @@ -68,7 +68,6 @@ int openssl_iostream_load_key(const struct ssl_iostream_settings *set, EVP_PKEY **pkey_r, const char **error_r); -const char *ssl_iostream_get_use_certificate_error(const char *cert); int openssl_cert_match_name(SSL *ssl, const char *verify_name); int openssl_get_protocol_options(const char *protocols); #define OPENSSL_ALL_PROTOCOL_OPTIONS \ @@ -92,6 +91,8 @@ const char *openssl_iostream_error(void); const char *openssl_iostream_key_load_error(void); +const char * +openssl_iostream_use_certificate_error(const char *cert, const char *set_name); int openssl_iostream_generate_params(buffer_t *output, unsigned int dh_length, const char **error_r); diff -r 77990d0b1a42 -r dbbfa124b27d src/login-common/ssl-proxy-openssl.c --- a/src/login-common/ssl-proxy-openssl.c Thu Dec 03 11:58:11 2015 +0200 +++ b/src/login-common/ssl-proxy-openssl.c Thu Dec 03 12:02:56 2015 +0200 @@ -935,11 +935,6 @@ return ssl_proxy_count; } -static bool is_pem_key(const char *cert) -{ - return strstr(cert, "PRIVATE KEY---") != NULL; -} - static void load_ca(X509_STORE *store, const char *ca, STACK_OF(X509_NAME) **xnames_r) { @@ -1080,25 +1075,6 @@ SSL_CTX_set_client_CA_list(ssl_ctx, ca_names); } -static const char *ssl_proxy_get_use_certificate_error(const char *cert) -{ - unsigned long err; - - err = ERR_peek_error(); - if (ERR_GET_LIB(err) != ERR_LIB_PEM || - ERR_GET_REASON(err) != PEM_R_NO_START_LINE) - return openssl_iostream_error(); - else if (is_pem_key(cert)) { - return "The file contains a private key " - "(you've mixed ssl_cert and ssl_key settings)"; - } else if (strchr(cert, '\n') == NULL) { - return t_strdup_printf("There is no valid PEM certificate. " - "(You probably forgot '<' from ssl_cert=<%s)", cert); - } else { - return "There is no valid PEM certificate."; - } -} - static EVP_PKEY * ATTR_NULL(2) ssl_proxy_load_key(const char *key, const char *password) { @@ -1277,7 +1253,7 @@ if (ssl_proxy_ctx_use_certificate_chain(ctx->ctx, ctx->cert) != 1) { i_fatal("Can't load ssl_cert: %s", - ssl_proxy_get_use_certificate_error(ctx->cert)); + openssl_iostream_use_certificate_error(ctx->cert, "ssl_cert")); } #ifdef HAVE_SSL_GET_SERVERNAME @@ -1317,7 +1293,8 @@ if (ssl_proxy_ctx_use_certificate_chain(ctx, set->ssl_client_cert) != 1) { i_fatal("Can't load ssl_client_cert: %s", - ssl_proxy_get_use_certificate_error(set->ssl_client_cert)); + openssl_iostream_use_certificate_error( + set->ssl_client_cert, "ssl_client_cert")); } pkey = ssl_proxy_load_key(set->ssl_client_key, NULL); From dovecot at dovecot.org Thu Dec 3 10:03:27 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 03 Dec 2015 10:03:27 +0000 Subject: dovecot-2.2: login-common: Use openssl_iostream_*error() to avoi... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/77990d0b1a42 changeset: 19446:77990d0b1a42 user: Timo Sirainen date: Thu Dec 03 11:58:11 2015 +0200 description: login-common: Use openssl_iostream_*error() to avoid code duplication. diffstat: src/login-common/ssl-proxy-openssl.c | 69 +++++------------------------------ 1 files changed, 11 insertions(+), 58 deletions(-) diffs (156 lines): diff -r 151df65d2de5 -r 77990d0b1a42 src/login-common/ssl-proxy-openssl.c --- a/src/login-common/ssl-proxy-openssl.c Thu Dec 03 11:55:33 2015 +0200 +++ b/src/login-common/ssl-proxy-openssl.c Thu Dec 03 11:58:11 2015 +0200 @@ -381,42 +381,6 @@ ssl_proxy_unref(proxy); } -static const char *ssl_err2str(unsigned long err, const char *data, int flags) -{ - const char *ret; - char *buf; - size_t err_size = 256; - - buf = t_malloc(err_size); - buf[err_size-1] = '\0'; - ERR_error_string_n(err, buf, err_size-1); - ret = buf; - - if ((flags & ERR_TXT_STRING) != 0) - ret = t_strdup_printf("%s: %s", buf, data); - return ret; -} - -static const char *ssl_last_error(void) -{ - unsigned long err; - const char *data; - int flags; - - err = ERR_get_error_line_data(NULL, NULL, &data, &flags); - while (err != 0 && ERR_peek_error() != 0) { - i_error("SSL: Stacked error: %s", - ssl_err2str(err, data, flags)); - err = ERR_get_error(); - } - if (err == 0) { - if (errno != 0) - return strerror(errno); - return "Unknown error"; - } - return ssl_err2str(err, data, flags); -} - static void ssl_handle_error(struct ssl_proxy *proxy, int ret, const char *func_name) { @@ -438,7 +402,7 @@ case SSL_ERROR_SYSCALL: /* eat up the error queue */ if (ERR_peek_error() != 0) - errstr = ssl_last_error(); + errstr = openssl_iostream_error(); else if (ret != 0) errstr = strerror(errno); else { @@ -460,11 +424,11 @@ login_binary->process_name); } errstr = t_strdup_printf("%s failed: %s", - func_name, ssl_last_error()); + func_name, openssl_iostream_error()); break; default: errstr = t_strdup_printf("%s failed: unknown failure %d (%s)", - func_name, err, ssl_last_error()); + func_name, err, openssl_iostream_error()); break; } @@ -594,12 +558,12 @@ ssl = SSL_new(ssl_ctx); if (ssl == NULL) { - i_error("SSL_new() failed: %s", ssl_last_error()); + i_error("SSL_new() failed: %s", openssl_iostream_error()); return -1; } if (SSL_set_fd(ssl, fd) != 1) { - i_error("SSL_set_fd() failed: %s", ssl_last_error()); + i_error("SSL_set_fd() failed: %s", openssl_iostream_error()); SSL_free(ssl); return -1; } @@ -991,7 +955,7 @@ i_fatal("BIO_new_mem_buf() failed"); inf = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL); if (inf == NULL) - i_fatal("Couldn't parse ssl_ca: %s", ssl_last_error()); + i_fatal("Couldn't parse ssl_ca: %s", openssl_iostream_error()); BIO_free(bio); if (xnames_r != NULL) { @@ -1123,7 +1087,7 @@ err = ERR_peek_error(); if (ERR_GET_LIB(err) != ERR_LIB_PEM || ERR_GET_REASON(err) != PEM_R_NO_START_LINE) - return ssl_last_error(); + return openssl_iostream_error(); else if (is_pem_key(cert)) { return "The file contains a private key " "(you've mixed ssl_cert and ssl_key settings)"; @@ -1135,17 +1099,6 @@ } } -static const char *ssl_key_load_error(void) -{ - unsigned long err = ERR_peek_error(); - - if (ERR_GET_LIB(err) == ERR_LIB_X509 && - ERR_GET_REASON(err) == X509_R_KEY_VALUES_MISMATCH) - return "Key is for a different cert than ssl_cert"; - else - return ssl_last_error(); -} - static EVP_PKEY * ATTR_NULL(2) ssl_proxy_load_key(const char *key, const char *password) { @@ -1162,7 +1115,7 @@ dup_password); if (pkey == NULL) { i_fatal("Couldn't parse private ssl_key: %s", - ssl_key_load_error()); + openssl_iostream_key_load_error()); } BIO_free(bio); return pkey; @@ -1179,7 +1132,7 @@ getenv(MASTER_SSL_KEY_PASSWORD_ENV); pkey = ssl_proxy_load_key(set->ssl_key, password); if (SSL_CTX_use_PrivateKey(ctx, pkey) != 1) - i_fatal("Can't load private ssl_key: %s", ssl_key_load_error()); + i_fatal("Can't load private ssl_key: %s", openssl_iostream_key_load_error()); EVP_PKEY_free(pkey); } @@ -1316,7 +1269,7 @@ if (SSL_CTX_set_cipher_list(ssl_ctx, ctx->cipher_list) != 1) { i_fatal("Can't set cipher list to '%s': %s", - ctx->cipher_list, ssl_last_error()); + ctx->cipher_list, openssl_iostream_error()); } if (ctx->prefer_server_ciphers) SSL_CTX_set_options(ssl_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); @@ -1370,7 +1323,7 @@ pkey = ssl_proxy_load_key(set->ssl_client_key, NULL); if (SSL_CTX_use_PrivateKey(ctx, pkey) != 1) { i_fatal("Can't load private ssl_client_key: %s", - ssl_key_load_error()); + openssl_iostream_key_load_error()); } EVP_PKEY_free(pkey); } From dovecot at dovecot.org Thu Dec 3 10:13:28 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 03 Dec 2015 10:13:28 +0000 Subject: dovecot-2.2: lib-ssl-iostream: Check for SSL_CTX_set_ecdh_auto()... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/a0df8b106de1 changeset: 19448:a0df8b106de1 user: Timo Sirainen date: Thu Dec 03 12:13:11 2015 +0200 description: lib-ssl-iostream: Check for SSL_CTX_set_ecdh_auto() failure. This shouldn't happen though. diffstat: src/lib-ssl-iostream/iostream-openssl-context.c | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-) diffs (26 lines): diff -r dbbfa124b27d -r a0df8b106de1 src/lib-ssl-iostream/iostream-openssl-context.c --- a/src/lib-ssl-iostream/iostream-openssl-context.c Thu Dec 03 12:02:56 2015 +0200 +++ b/src/lib-ssl-iostream/iostream-openssl-context.c Thu Dec 03 12:13:11 2015 +0200 @@ -465,7 +465,7 @@ static int ssl_proxy_ctx_set_crypto_params(SSL_CTX *ssl_ctx, const struct ssl_iostream_settings *set ATTR_UNUSED, - const char **error_r ATTR_UNUSED) + const char **error_r) { #if defined(HAVE_ECDH) && !defined(SSL_CTRL_SET_ECDH_AUTO) EC_KEY *ecdh; @@ -483,7 +483,12 @@ #ifdef SSL_CTRL_SET_ECDH_AUTO /* OpenSSL >= 1.0.2 automatically handles ECDH temporary key parameter selection. */ - SSL_CTX_set_ecdh_auto(ssl_ctx, 1); + if (!SSL_CTX_set_ecdh_auto(ssl_ctx, 1)) { + /* shouldn't happen */ + *error_r = t_strdup_printf("SSL_CTX_set_ecdh_auto() failed: %s", + openssl_iostream_error()); + return -1; + } #else /* For OpenSSL < 1.0.2, ECDH temporary key parameter selection must be performed manually. Attempt to select the same curve as that used From dovecot at dovecot.org Thu Dec 3 10:23:22 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 03 Dec 2015 10:23:22 +0000 Subject: dovecot-2.2: login, lib-ssl-iostream: Clear errors caused by man... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/302c3c7e11f8 changeset: 19449:302c3c7e11f8 user: Timo Sirainen date: Thu Dec 03 12:19:12 2015 +0200 description: login, lib-ssl-iostream: Clear errors caused by manual EC key selection when there was no EC key. EVP_PKEY_get1_EC_KEY() would return an error, which should be ignored instead of being logged later on. diffstat: src/lib-ssl-iostream/iostream-openssl-context.c | 4 ++++ src/login-common/ssl-proxy-openssl.c | 4 ++++ 2 files changed, 8 insertions(+), 0 deletions(-) diffs (28 lines): diff -r a0df8b106de1 -r 302c3c7e11f8 src/lib-ssl-iostream/iostream-openssl-context.c --- a/src/lib-ssl-iostream/iostream-openssl-context.c Thu Dec 03 12:13:11 2015 +0200 +++ b/src/lib-ssl-iostream/iostream-openssl-context.c Thu Dec 03 12:19:12 2015 +0200 @@ -454,6 +454,10 @@ if ((eckey = EVP_PKEY_get1_EC_KEY(pkey)) != NULL && (ecgrp = EC_KEY_get0_group(eckey)) != NULL) nid = EC_GROUP_get_curve_name(ecgrp); + else { + /* clear errors added by the above calls */ + (void)openssl_iostream_error(); + } EVP_PKEY_free(pkey); } diff -r a0df8b106de1 -r 302c3c7e11f8 src/login-common/ssl-proxy-openssl.c --- a/src/login-common/ssl-proxy-openssl.c Thu Dec 03 12:13:11 2015 +0200 +++ b/src/login-common/ssl-proxy-openssl.c Thu Dec 03 12:19:12 2015 +0200 @@ -1129,6 +1129,10 @@ (eckey = EVP_PKEY_get1_EC_KEY(pkey)) != NULL && (ecgrp = EC_KEY_get0_group(eckey)) != NULL) nid = EC_GROUP_get_curve_name(ecgrp); + else { + /* clear errors added by the above calls */ + (void)openssl_iostream_error(); + } EVP_PKEY_free(pkey); return nid; } From dovecot at dovecot.org Thu Dec 3 10:23:22 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 03 Dec 2015 10:23:22 +0000 Subject: dovecot-2.2: lib-ssl-iostream: Moved openssl_iostream_*error() t... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/be47ca42cbc4 changeset: 19450:be47ca42cbc4 user: Timo Sirainen date: Thu Dec 03 12:22:24 2015 +0200 description: lib-ssl-iostream: Moved openssl_iostream_*error() to -common.c login-common code only links with this file, so that's required for the previous changes to actually work. diffstat: src/lib-ssl-iostream/iostream-openssl-common.c | 75 +++++++++++++++++++++++++ src/lib-ssl-iostream/iostream-openssl-context.c | 74 ------------------------ 2 files changed, 75 insertions(+), 74 deletions(-) diffs (180 lines): diff -r 302c3c7e11f8 -r be47ca42cbc4 src/lib-ssl-iostream/iostream-openssl-common.c --- a/src/lib-ssl-iostream/iostream-openssl-common.c Thu Dec 03 12:19:12 2015 +0200 +++ b/src/lib-ssl-iostream/iostream-openssl-common.c Thu Dec 03 12:22:24 2015 +0200 @@ -4,6 +4,7 @@ #include "iostream-openssl.h" #include +#include enum { DOVECOT_SSL_PROTO_SSLv2 = 0x01, @@ -165,3 +166,77 @@ X509_free(cert); return ret; } + +static const char *ssl_err2str(unsigned long err, const char *data, int flags) +{ + const char *ret; + char *buf; + size_t err_size = 256; + + buf = t_malloc(err_size); + buf[err_size-1] = '\0'; + ERR_error_string_n(err, buf, err_size-1); + ret = buf; + + if ((flags & ERR_TXT_STRING) != 0) + ret = t_strdup_printf("%s: %s", buf, data); + return ret; +} + +const char *openssl_iostream_error(void) +{ + unsigned long err; + const char *data; + int flags; + + while ((err = ERR_get_error_line_data(NULL, NULL, &data, &flags)) != 0) { + if (ERR_GET_REASON(err) == ERR_R_MALLOC_FAILURE) + i_fatal_status(FATAL_OUTOFMEM, "OpenSSL malloc() failed"); + if (ERR_peek_error() != 0) + break; + i_error("SSL: Stacked error: %s", + ssl_err2str(err, data, flags)); + } + if (err == 0) { + if (errno != 0) + return strerror(errno); + return "Unknown error"; + } + return ssl_err2str(err, data, flags); +} + +const char *openssl_iostream_key_load_error(void) +{ + unsigned long err = ERR_peek_error(); + + if (ERR_GET_LIB(err) == ERR_LIB_X509 && + ERR_GET_REASON(err) == X509_R_KEY_VALUES_MISMATCH) + return "Key is for a different cert than ssl_cert"; + else + return openssl_iostream_error(); +} + +static bool is_pem_key(const char *cert) +{ + return strstr(cert, "PRIVATE KEY---") != NULL; +} + +const char * +openssl_iostream_use_certificate_error(const char *cert, const char *set_name) +{ + unsigned long err; + + err = ERR_peek_error(); + if (ERR_GET_LIB(err) != ERR_LIB_PEM || + ERR_GET_REASON(err) != PEM_R_NO_START_LINE) + return openssl_iostream_error(); + else if (is_pem_key(cert)) { + return "The file contains a private key " + "(you've mixed ssl_cert and ssl_key settings)"; + } else if (set_name != NULL && strchr(cert, '\n') == NULL) { + return t_strdup_printf("There is no valid PEM certificate. " + "(You probably forgot '<' from %s=<%s)", set_name, cert); + } else { + return "There is no valid PEM certificate."; + } +} diff -r 302c3c7e11f8 -r be47ca42cbc4 src/lib-ssl-iostream/iostream-openssl-context.c --- a/src/lib-ssl-iostream/iostream-openssl-context.c Thu Dec 03 12:19:12 2015 +0200 +++ b/src/lib-ssl-iostream/iostream-openssl-context.c Thu Dec 03 12:22:24 2015 +0200 @@ -28,55 +28,6 @@ static int ssl_iostream_init_global(const struct ssl_iostream_settings *set, const char **error_r); -static const char *ssl_err2str(unsigned long err, const char *data, int flags) -{ - const char *ret; - char *buf; - size_t err_size = 256; - - buf = t_malloc(err_size); - buf[err_size-1] = '\0'; - ERR_error_string_n(err, buf, err_size-1); - ret = buf; - - if ((flags & ERR_TXT_STRING) != 0) - ret = t_strdup_printf("%s: %s", buf, data); - return ret; -} - -const char *openssl_iostream_error(void) -{ - unsigned long err; - const char *data; - int flags; - - while ((err = ERR_get_error_line_data(NULL, NULL, &data, &flags)) != 0) { - if (ERR_GET_REASON(err) == ERR_R_MALLOC_FAILURE) - i_fatal_status(FATAL_OUTOFMEM, "OpenSSL malloc() failed"); - if (ERR_peek_error() != 0) - break; - i_error("SSL: Stacked error: %s", - ssl_err2str(err, data, flags)); - } - if (err == 0) { - if (errno != 0) - return strerror(errno); - return "Unknown error"; - } - return ssl_err2str(err, data, flags); -} - -const char *openssl_iostream_key_load_error(void) -{ - unsigned long err = ERR_peek_error(); - - if (ERR_GET_LIB(err) == ERR_LIB_X509 && - ERR_GET_REASON(err) == X509_R_KEY_VALUES_MISMATCH) - return "Key is for a different cert than ssl_cert"; - else - return openssl_iostream_error(); -} - static RSA *ssl_gen_rsa_key(SSL *ssl ATTR_UNUSED, int is_export ATTR_UNUSED, int keylength) { @@ -169,31 +120,6 @@ return ret; } -static bool is_pem_key(const char *cert) -{ - return strstr(cert, "PRIVATE KEY---") != NULL; -} - -const char * -openssl_iostream_use_certificate_error(const char *cert, const char *set_name) -{ - unsigned long err; - - err = ERR_peek_error(); - if (ERR_GET_LIB(err) != ERR_LIB_PEM || - ERR_GET_REASON(err) != PEM_R_NO_START_LINE) - return openssl_iostream_error(); - else if (is_pem_key(cert)) { - return "The file contains a private key " - "(you've mixed ssl_cert and ssl_key settings)"; - } else if (set_name != NULL && strchr(cert, '\n') == NULL) { - return t_strdup_printf("There is no valid PEM certificate. " - "(You probably forgot '<' from %s=<%s)", set_name, cert); - } else { - return "There is no valid PEM certificate."; - } -} - static int ssl_ctx_use_certificate_chain(SSL_CTX *ctx, const char *cert) { /* mostly just copy&pasted from SSL_CTX_use_certificate_chain_file() */ From dovecot at dovecot.org Thu Dec 3 12:24:25 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 03 Dec 2015 12:24:25 +0000 Subject: dovecot-2.2: fts: Added support for per-language tokenizer setti... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0cb2c54fa452 changeset: 19451:0cb2c54fa452 user: Timo Sirainen date: Thu Dec 03 14:24:06 2015 +0200 description: fts: Added support for per-language tokenizer settings. fts_tokenizer_ now overrides fts_tokenizers setting. fts_tokenizer__ now overrides fts_tokenizer_ setting. diffstat: src/plugins/fts/fts-build-mail.c | 34 ++++++---- src/plugins/fts/fts-search-args.c | 86 ++++++++++++++++----------- src/plugins/fts/fts-user.c | 119 ++++++++++++++++++++----------------- src/plugins/fts/fts-user.h | 3 +- 4 files changed, 134 insertions(+), 108 deletions(-) diffs (truncated from 445 to 300 lines): diff -r be47ca42cbc4 -r 0cb2c54fa452 src/plugins/fts/fts-build-mail.c --- a/src/plugins/fts/fts-build-mail.c Thu Dec 03 12:22:24 2015 +0200 +++ b/src/plugins/fts/fts-build-mail.c Thu Dec 03 14:24:06 2015 +0200 @@ -135,6 +135,18 @@ return FALSE; } +static void fts_mail_build_ctx_set_lang(struct fts_mail_build_context *ctx, + struct fts_user_language *user_lang) +{ + i_assert(user_lang != NULL); + + ctx->cur_user_lang = user_lang; + /* reset tokenizer between fields - just to be sure no state + leaks between fields (especially if previous indexing had + failed) */ + fts_tokenizer_reset(user_lang->index_tokenizer); +} + static void fts_build_tokenized_hdr_update_lang(struct fts_mail_build_context *ctx, const struct message_header_line *hdr) @@ -148,8 +160,10 @@ if (header_has_language(hdr->name) || data_has_8bit(hdr->full_value, hdr->full_value_len)) ctx->cur_user_lang = NULL; - else - ctx->cur_user_lang = fts_user_get_data_lang(ctx->update_ctx->backend->ns->user); + else { + fts_mail_build_ctx_set_lang(ctx, + fts_user_get_data_lang(ctx->update_ctx->backend->ns->user)); + } } static int fts_build_mail_header(struct fts_mail_build_context *ctx, @@ -268,12 +282,11 @@ fts_build_add_tokens_with_filter(struct fts_mail_build_context *ctx, const unsigned char *data, size_t size) { - struct fts_tokenizer *tokenizer; + struct fts_tokenizer *tokenizer = ctx->cur_user_lang->index_tokenizer; struct fts_filter *filter = ctx->cur_user_lang->filter; const char *token, *error; int ret = 1, ret2; - tokenizer = fts_user_get_index_tokenizer(ctx->update_ctx->backend->ns->user); while (ret > 0) T_BEGIN { ret = ret2 = fts_tokenizer_next(tokenizer, data, size, &token, &error); if (ret2 > 0 && filter != NULL) @@ -341,8 +354,7 @@ /* wait for more data */ return 0; } else { - ctx->cur_user_lang = fts_user_language_find(user, lang); - i_assert(ctx->cur_user_lang != NULL); + fts_mail_build_ctx_set_lang(ctx, fts_user_language_find(user, lang)); if (ctx->pending_input->used > 0) { if (fts_build_add_tokens_with_filter(ctx, @@ -480,16 +492,8 @@ memset(&ctx, 0, sizeof(ctx)); ctx.update_ctx = update_ctx; ctx.mail = mail; - if ((update_ctx->backend->flags & FTS_BACKEND_FLAG_TOKENIZED_INPUT) != 0) { + if ((update_ctx->backend->flags & FTS_BACKEND_FLAG_TOKENIZED_INPUT) != 0) ctx.pending_input = buffer_create_dynamic(default_pool, 128); - /* reset tokenizer between mails - just to be sure no state - leaks between mails (especially if previous indexing had - failed) */ - struct fts_tokenizer *tokenizer; - - tokenizer = fts_user_get_index_tokenizer(update_ctx->backend->ns->user); - fts_tokenizer_reset(tokenizer); - } prev_part = NULL; parser = message_parser_init(pool_datastack_create(), input, diff -r be47ca42cbc4 -r 0cb2c54fa452 src/plugins/fts/fts-search-args.c --- a/src/plugins/fts/fts-search-args.c Thu Dec 03 12:22:24 2015 +0200 +++ b/src/plugins/fts/fts-search-args.c Thu Dec 03 14:24:06 2015 +0200 @@ -54,14 +54,14 @@ } static int -fts_backend_dovecot_expand_lang_tokens(const ARRAY_TYPE(fts_user_language) *languages, - pool_t pool, - struct mail_search_arg *parent_arg, - const struct mail_search_arg *orig_arg, - const char *orig_token, const char *token) +fts_backend_dovecot_expand_tokens(struct fts_filter *filter, + pool_t pool, + struct mail_search_arg *parent_arg, + const struct mail_search_arg *orig_arg, + const char *orig_token, const char *token, + const char **error_r) { struct mail_search_arg *arg; - struct fts_user_language *const *langp; ARRAY_TYPE(const_string) tokens; const char *token2, *error; int ret; @@ -73,15 +73,14 @@ array_append(&tokens, &token, 1); /* add the word filtered */ - array_foreach(languages, langp) { + if (filter != NULL) { token2 = t_strdup(token); - ret = (*langp)->filter == NULL ? 1 : - fts_filter_filter((*langp)->filter, &token2, &error); + ret = fts_filter_filter(filter, &token2, &error); if (ret > 0) { token2 = t_strdup(token2); array_append(&tokens, &token2, 1); } else if (ret < 0) { - i_error("fts: Couldn't filter search tokens: %s", error); + *error_r = t_strdup_printf("Couldn't filter search token: %s", error); return -1; } } @@ -94,18 +93,50 @@ return 0; } +static int +fts_backend_dovecot_tokenize_lang(struct fts_user_language *user_lang, + pool_t pool, struct mail_search_arg *and_arg, + struct mail_search_arg *orig_arg, + const char *orig_token, const char **error_r) +{ + unsigned int orig_token_len = strlen(orig_token); + const char *token, *error; + int ret; + + /* reset tokenizer between search args in case there's any state left + from some previous failure */ + fts_tokenizer_reset(user_lang->search_tokenizer); + while ((ret = fts_tokenizer_next(user_lang->search_tokenizer, + (const void *)orig_token, + orig_token_len, &token, error_r)) > 0) { + if (fts_backend_dovecot_expand_tokens(user_lang->filter, pool, + and_arg, orig_arg, orig_token, + token, error_r) < 0) + return -1; + } + while (ret >= 0 && + (ret = fts_tokenizer_final(user_lang->search_tokenizer, &token, &error)) > 0) { + if (fts_backend_dovecot_expand_tokens(user_lang->filter, pool, + and_arg, orig_arg, orig_token, + token, error_r) < 0) + return -1; + } + if (ret < 0) { + *error_r = t_strdup_printf("Couldn't tokenize search args: %s", error); + return -1; + } + return 0; +} + static int fts_search_arg_expand(struct fts_backend *backend, pool_t pool, struct mail_search_arg **argp) { const ARRAY_TYPE(fts_user_language) *languages; + struct fts_user_language *const *langp; struct mail_search_arg *and_arg, *orig_arg = *argp; - const char *error, *token, *orig_token = orig_arg->value.str; - unsigned int orig_token_len = strlen(orig_token); - struct fts_tokenizer *tokenizer; - int ret; + const char *error, *orig_token = orig_arg->value.str; languages = fts_user_get_all_languages(backend->ns->user); - tokenizer = fts_user_get_search_tokenizer(backend->ns->user); /* we want all the tokens found from the string to be found, so create a parent AND and place all the filtered token alternatives under @@ -115,27 +146,12 @@ and_arg->match_not = orig_arg->match_not; and_arg->next = orig_arg->next; - /* reset tokenizer between search args in case there's any state left - from some previous failure */ - fts_tokenizer_reset(tokenizer); - while ((ret = fts_tokenizer_next(tokenizer, - (const void *)orig_token, - orig_token_len, &token, &error)) > 0) { - if (fts_backend_dovecot_expand_lang_tokens(languages, pool, and_arg, - orig_arg, orig_token, - token) < 0) + array_foreach(languages, langp) { + if (fts_backend_dovecot_tokenize_lang(*langp, pool, and_arg, + orig_arg, orig_token, &error) < 0) { + i_error("fts: %s", error); return -1; - } - while (ret >= 0 && - (ret = fts_tokenizer_final(tokenizer, &token, &error)) > 0) { - if (fts_backend_dovecot_expand_lang_tokens(languages, pool, and_arg, - orig_arg, orig_token, - token) < 0) - return -1; - } - if (ret < 0) { - i_error("fts: Couldn't tokenize search args: %s", error); - return -1; + } } if (and_arg->value.subargs == NULL) { diff -r be47ca42cbc4 -r 0cb2c54fa452 src/plugins/fts/fts-user.c --- a/src/plugins/fts/fts-user.c Thu Dec 03 12:22:24 2015 +0200 +++ b/src/plugins/fts/fts-user.c Thu Dec 03 14:24:06 2015 +0200 @@ -16,7 +16,6 @@ int refcount; struct fts_language_list *lang_list; - struct fts_tokenizer *index_tokenizer, *search_tokenizer; struct fts_user_language *data_lang; ARRAY_TYPE(fts_user_language) languages; }; @@ -148,6 +147,7 @@ static int fts_user_create_tokenizer(struct mail_user *user, + const struct fts_language *lang, struct fts_tokenizer **tokenizer_r, bool search, const char **error_r) { @@ -158,11 +158,15 @@ unsigned int i; int ret = 0; - tokenizers_key = "fts_tokenizers"; + tokenizers_key = t_strconcat("fts_tokenizers_", lang->name, NULL); str = mail_user_plugin_getenv(user, tokenizers_key); if (str == NULL) { - *error_r = "fts_tokenizers setting is missing"; - return -1; + str = mail_user_plugin_getenv(user, "fts_tokenizers"); + if (str == NULL) { + *error_r = t_strdup_printf("%s or fts_tokenizers setting must exist", tokenizers_key); + return -1; + } + tokenizers_key = "fts_tokenizers"; } tokenizers = t_strsplit_spaces(str, " "); @@ -177,8 +181,12 @@ } tokenizer_set_name = t_str_replace(tokenizers[i], '-', '_'); - set_key = t_strdup_printf("fts_tokenizer_%s", tokenizer_set_name); + set_key = t_strdup_printf("fts_tokenizer_%s_%s", tokenizer_set_name, lang->name); str = mail_user_plugin_getenv(user, set_key); + if (str == NULL) { + set_key = t_strdup_printf("fts_tokenizer_%s", tokenizer_set_name); + str = mail_user_plugin_getenv(user, set_key); + } /* tell the tokenizers that we're tokenizing a search string (instead of tokenizing indexed data) */ @@ -205,18 +213,20 @@ return 0; } -static int fts_user_init_tokenizers(struct mail_user *user, - struct fts_user *fuser, - const char **error_r) +static int +fts_user_language_init_tokenizers(struct mail_user *user, + struct fts_user_language *user_lang, + const char **error_r) { - if (fts_user_create_tokenizer(user, &fuser->index_tokenizer, FALSE, + if (fts_user_create_tokenizer(user, user_lang->lang, + &user_lang->index_tokenizer, FALSE, error_r) < 0) return -1; - if (fts_user_create_tokenizer(user, &fuser->search_tokenizer, TRUE, + if (fts_user_create_tokenizer(user, user_lang->lang, + &user_lang->search_tokenizer, TRUE, error_r) < 0) return -1; - return 0; } @@ -234,35 +244,21 @@ return NULL; } -struct fts_tokenizer *fts_user_get_index_tokenizer(struct mail_user *user) -{ - struct fts_user *fuser = FTS_USER_CONTEXT(user); - - return fuser->index_tokenizer; -} - -struct fts_tokenizer *fts_user_get_search_tokenizer(struct mail_user *user) From dovecot at dovecot.org Thu Dec 3 13:54:00 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 03 Dec 2015 13:54:00 +0000 Subject: dovecot-2.2: Released v2.2.20.rc1. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c35e62a9e710 changeset: 19452:c35e62a9e710 user: Timo Sirainen date: Thu Dec 03 15:31:39 2015 +0200 description: Released v2.2.20.rc1. diffstat: NEWS | 39 +++++++++++++++++++++++++++++++++++++++ configure.ac | 4 ++-- 2 files changed, 41 insertions(+), 2 deletions(-) diffs (60 lines): diff -r 0cb2c54fa452 -r c35e62a9e710 NEWS --- a/NEWS Thu Dec 03 14:24:06 2015 +0200 +++ b/NEWS Thu Dec 03 15:31:39 2015 +0200 @@ -1,3 +1,42 @@ +v2.2.20 2015-12-xx Timo Sirainen + + + Added mailbox { autoexpunge=