From f9bd795ae035e597da0d57dc1f9a52498efb5b5c Mon Sep 17 00:00:00 2001 From: MSVSphere Packaging Team Date: Fri, 25 Oct 2024 14:28:52 +0300 Subject: [PATCH] import dovecot-2.3.21-14.el10 --- .dovecot.metadata | 2 + .gitignore | 2 + ...dovecot-1.0.beta2-mkcert-permissions.patch | 11 + SOURCES/dovecot-1.0.rc7-mkcert-paths.patch | 14 + SOURCES/dovecot-2.0-defaultconfig.patch | 42 + SOURCES/dovecot-2.1.10-waitonline.patch | 11 + SOURCES/dovecot-2.2.20-initbysystemd.patch | 51 + ...vecot-2.2.22-systemd_w_protectsystem.patch | 11 + SOURCES/dovecot-2.3-ph_optglob.patch | 48 + SOURCES/dovecot-2.3-ph_scriptcmp.patch | 12 + SOURCES/dovecot-2.3.0.1-libxcrypt.patch | 11 + SOURCES/dovecot-2.3.11-bigkey.patch | 10 + SOURCES/dovecot-2.3.14-opensslv3.patch | 34 + SOURCES/dovecot-2.3.15-fixvalcond.patch | 24 + SOURCES/dovecot-2.3.15-valbasherr.patch | 20 + SOURCES/dovecot-2.3.19.1-7bad6a24.patch | 131 + SOURCES/dovecot-2.3.20-nolibotp.patch | 295 ++ SOURCES/dovecot-2.3.21-noengine.patch | 200 ++ SOURCES/dovecot-2.3.21-test-socket-path.patch | 22 + SOURCES/dovecot-2.3.21.1-CVE-2024-23184.patch | 976 ++++++ SOURCES/dovecot-2.3.21.1-CVE-2024-23185.patch | 493 +++ SOURCES/dovecot-2.3.6-opensslhmac.patch | 813 +++++ SOURCES/dovecot-configure-c99.patch | 25 + SOURCES/dovecot.conf.5 | 19 + SOURCES/dovecot.init | 108 + SOURCES/dovecot.pam | 5 + SOURCES/dovecot.sysconfig | 3 + SOURCES/dovecot.sysusers | 9 + SOURCES/dovecot.tmpfilesd | 2 + SOURCES/prestartscript | 3 + SPECS/dovecot.spec | 2768 +++++++++++++++++ 31 files changed, 6175 insertions(+) create mode 100644 .dovecot.metadata create mode 100644 .gitignore create mode 100644 SOURCES/dovecot-1.0.beta2-mkcert-permissions.patch create mode 100644 SOURCES/dovecot-1.0.rc7-mkcert-paths.patch create mode 100644 SOURCES/dovecot-2.0-defaultconfig.patch create mode 100644 SOURCES/dovecot-2.1.10-waitonline.patch create mode 100644 SOURCES/dovecot-2.2.20-initbysystemd.patch create mode 100644 SOURCES/dovecot-2.2.22-systemd_w_protectsystem.patch create mode 100644 SOURCES/dovecot-2.3-ph_optglob.patch create mode 100644 SOURCES/dovecot-2.3-ph_scriptcmp.patch create mode 100644 SOURCES/dovecot-2.3.0.1-libxcrypt.patch create mode 100644 SOURCES/dovecot-2.3.11-bigkey.patch create mode 100644 SOURCES/dovecot-2.3.14-opensslv3.patch create mode 100644 SOURCES/dovecot-2.3.15-fixvalcond.patch create mode 100644 SOURCES/dovecot-2.3.15-valbasherr.patch create mode 100644 SOURCES/dovecot-2.3.19.1-7bad6a24.patch create mode 100644 SOURCES/dovecot-2.3.20-nolibotp.patch create mode 100644 SOURCES/dovecot-2.3.21-noengine.patch create mode 100644 SOURCES/dovecot-2.3.21-test-socket-path.patch create mode 100644 SOURCES/dovecot-2.3.21.1-CVE-2024-23184.patch create mode 100644 SOURCES/dovecot-2.3.21.1-CVE-2024-23185.patch create mode 100644 SOURCES/dovecot-2.3.6-opensslhmac.patch create mode 100644 SOURCES/dovecot-configure-c99.patch create mode 100644 SOURCES/dovecot.conf.5 create mode 100755 SOURCES/dovecot.init create mode 100644 SOURCES/dovecot.pam create mode 100644 SOURCES/dovecot.sysconfig create mode 100644 SOURCES/dovecot.sysusers create mode 100644 SOURCES/dovecot.tmpfilesd create mode 100644 SOURCES/prestartscript create mode 100644 SPECS/dovecot.spec diff --git a/.dovecot.metadata b/.dovecot.metadata new file mode 100644 index 0000000..4f1b2f8 --- /dev/null +++ b/.dovecot.metadata @@ -0,0 +1,2 @@ +e0707a46cb9e1342a74cb03803430f9198608e5e SOURCES/dovecot-2.3-pigeonhole-0.5.21.tar.gz +20300087e8575a42dc16245d05b0905b588396f9 SOURCES/dovecot-2.3.21.tar.gz diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fdb17e0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +SOURCES/dovecot-2.3-pigeonhole-0.5.21.tar.gz +SOURCES/dovecot-2.3.21.tar.gz diff --git a/SOURCES/dovecot-1.0.beta2-mkcert-permissions.patch b/SOURCES/dovecot-1.0.beta2-mkcert-permissions.patch new file mode 100644 index 0000000..68ac01b --- /dev/null +++ b/SOURCES/dovecot-1.0.beta2-mkcert-permissions.patch @@ -0,0 +1,11 @@ +--- dovecot-1.0.beta2/doc/mkcert.sh.configfile 2006-01-16 21:14:54.000000000 +0100 ++++ dovecot-1.0.beta2/doc/mkcert.sh 2006-01-26 14:28:38.000000000 +0100 +@@ -29,6 +29,7 @@ + fi + + $OPENSSL req -new -x509 -nodes -config $OPENSSLCONFIG -out $CERTFILE -keyout $KEYFILE -days 365 || exit 2 +-chmod 0600 $KEYFILE ++chown root:root $CERTFILE $KEYFILE ++chmod 0600 $CERTFILE $KEYFILE + echo + $OPENSSL x509 -subject -fingerprint -noout -in $CERTFILE || exit 2 diff --git a/SOURCES/dovecot-1.0.rc7-mkcert-paths.patch b/SOURCES/dovecot-1.0.rc7-mkcert-paths.patch new file mode 100644 index 0000000..e8354e5 --- /dev/null +++ b/SOURCES/dovecot-1.0.rc7-mkcert-paths.patch @@ -0,0 +1,14 @@ +diff -up dovecot-2.2.27/doc/mkcert.sh.mkcert-paths dovecot-2.2.27/doc/mkcert.sh +--- dovecot-2.2.27/doc/mkcert.sh.mkcert-paths 2016-12-05 10:26:07.913515286 +0100 ++++ dovecot-2.2.27/doc/mkcert.sh 2016-12-05 10:28:25.439634417 +0100 +@@ -5,8 +5,8 @@ + + umask 077 + OPENSSL=${OPENSSL-openssl} +-SSLDIR=${SSLDIR-/etc/ssl} +-OPENSSLCONFIG=${OPENSSLCONFIG-dovecot-openssl.cnf} ++SSLDIR=${SSLDIR-/etc/pki/dovecot} ++OPENSSLCONFIG=${OPENSSLCONFIG-/etc/pki/dovecot/dovecot-openssl.cnf} + + CERTDIR=$SSLDIR/certs + KEYDIR=$SSLDIR/private diff --git a/SOURCES/dovecot-2.0-defaultconfig.patch b/SOURCES/dovecot-2.0-defaultconfig.patch new file mode 100644 index 0000000..21f00ec --- /dev/null +++ b/SOURCES/dovecot-2.0-defaultconfig.patch @@ -0,0 +1,42 @@ +diff -up dovecot-2.3.16/doc/example-config/conf.d/10-mail.conf.default-settings dovecot-2.3.16/doc/example-config/conf.d/10-mail.conf +--- dovecot-2.3.16/doc/example-config/conf.d/10-mail.conf.default-settings 2021-08-06 11:25:51.000000000 +0200 ++++ dovecot-2.3.16/doc/example-config/conf.d/10-mail.conf 2021-10-27 11:13:45.666956339 +0200 +@@ -175,7 +175,7 @@ namespace inbox { + # to make sure that users can't log in as daemons or other system users. + # Note that denying root logins is hardcoded to dovecot binary and can't + # be done even if first_valid_uid is set to 0. +-#first_valid_uid = 500 ++first_valid_uid = 1000 + #last_valid_uid = 0 + + # Valid GID range for users, defaults to non-root/wheel. Users having +@@ -322,6 +322,7 @@ protocol !indexer-worker { + # them simultaneously. + #mbox_read_locks = fcntl + #mbox_write_locks = dotlock fcntl ++mbox_write_locks = fcntl + + # Maximum time to wait for lock (all of them) before aborting. + #mbox_lock_timeout = 5 mins +diff -up dovecot-2.3.16/doc/example-config/conf.d/10-ssl.conf.default-settings dovecot-2.3.16/doc/example-config/conf.d/10-ssl.conf +--- dovecot-2.3.16/doc/example-config/conf.d/10-ssl.conf.default-settings 2021-08-06 11:25:51.000000000 +0200 ++++ dovecot-2.3.16/doc/example-config/conf.d/10-ssl.conf 2021-10-27 11:13:02.834533975 +0200 +@@ -3,7 +3,9 @@ + ## + + # SSL/TLS support: yes, no, required. +-#ssl = yes ++# disable plain pop3 and imap, allowed are only pop3+TLS, pop3s, imap+TLS and imaps ++# plain imap and pop3 are still allowed for local connections ++ssl = required + + # PEM encoded X.509 SSL/TLS certificate and private key. They're opened before + # dropping root privileges, so keep the key file unreadable by anyone but +@@ -64,6 +66,7 @@ ssl_key = &1;\ ++fi' ++ +diff -up dovecot-2.3.15/dovecot.service.in.initbysystemd dovecot-2.3.15/dovecot.service.in +--- dovecot-2.3.15/dovecot.service.in.initbysystemd 2021-06-21 20:21:49.250680889 +0200 ++++ dovecot-2.3.15/dovecot.service.in 2021-06-21 20:22:46.935981920 +0200 +@@ -11,7 +11,8 @@ + Description=Dovecot IMAP/POP3 email server + Documentation=man:dovecot(1) + Documentation=https://doc.dovecot.org/ +-After=local-fs.target network-online.target ++After=local-fs.target network-online.target dovecot-init.service ++Requires=dovecot-init.service + Wants=network-online.target + + [Service] +diff -up dovecot-2.3.15/Makefile.am.initbysystemd dovecot-2.3.15/Makefile.am +--- dovecot-2.3.15/Makefile.am.initbysystemd 2021-06-21 20:21:49.250680889 +0200 ++++ dovecot-2.3.15/Makefile.am 2021-06-21 20:24:26.676765849 +0200 +@@ -21,6 +21,7 @@ EXTRA_DIST = \ + run-test-valgrind.supp \ + dovecot.service.in \ + dovecot.socket \ ++ dovecot-init.service \ + $(conf_DATA) + + noinst_DATA = dovecot-config +@@ -69,7 +70,8 @@ dovecot-config: dovecot-config.in Makefi + if WANT_SYSTEMD + systemdsystemunit_DATA = \ + dovecot.socket \ +- dovecot.service ++ dovecot.service \ ++ dovecot-init.service + endif + + install-exec-hook: diff --git a/SOURCES/dovecot-2.2.22-systemd_w_protectsystem.patch b/SOURCES/dovecot-2.2.22-systemd_w_protectsystem.patch new file mode 100644 index 0000000..d00a9b9 --- /dev/null +++ b/SOURCES/dovecot-2.2.22-systemd_w_protectsystem.patch @@ -0,0 +1,11 @@ +diff -up dovecot-2.3.2/dovecot.service.in.systemd_w_protectsystem dovecot-2.3.2/dovecot.service.in +--- dovecot-2.3.2/dovecot.service.in.systemd_w_protectsystem 2018-07-09 12:00:13.359193526 +0200 ++++ dovecot-2.3.2/dovecot.service.in 2018-07-09 12:00:46.387716884 +0200 +@@ -23,6 +23,7 @@ ExecReload=@bindir@/doveadm reload + ExecStop=@bindir@/doveadm stop + PrivateTmp=true + NonBlocking=yes ++# this will make /usr /boot /etc read only for dovecot + ProtectSystem=full + ProtectHome=no + PrivateDevices=true diff --git a/SOURCES/dovecot-2.3-ph_optglob.patch b/SOURCES/dovecot-2.3-ph_optglob.patch new file mode 100644 index 0000000..d31527c --- /dev/null +++ b/SOURCES/dovecot-2.3-ph_optglob.patch @@ -0,0 +1,48 @@ +diff -up dovecot-2.3.21/dovecot-pigeonhole/src/lib-sieve/plugins/include/cmd-include.c.ph_optglob dovecot-2.3.21/dovecot-pigeonhole/src/lib-sieve/plugins/include/cmd-include.c +--- dovecot-2.3.21/dovecot-pigeonhole/src/lib-sieve/plugins/include/cmd-include.c.ph_optglob 2024-06-04 09:11:28.514189662 +0200 ++++ dovecot-2.3.21/dovecot-pigeonhole/src/lib-sieve/plugins/include/cmd-include.c 2024-06-04 09:18:23.219809778 +0200 +@@ -368,11 +368,13 @@ static bool opc_include_dump + return FALSE; + + sieve_code_descend(denv); +- sieve_code_dumpf(denv, "script: `%s' from %s %s%s[ID: %d, BLOCK: %d]", ++ sieve_code_dumpf(denv, "script: `%s' from %s %s%s%s[ID: %d, BLOCK: %d]", + sieve_script_name(included->script), sieve_script_location(included->script), + ((flags & EXT_INCLUDE_FLAG_ONCE) != 0 ? "(once) " : ""), + ((flags & EXT_INCLUDE_FLAG_OPTIONAL) != 0 ? "(optional) " : ""), +- include_id, sieve_binary_block_get_id(included->block)); ++ (included->block == NULL ? "(missing) " : ""), ++ include_id, ++ (included->block == NULL ? -1 : sieve_binary_block_get_id(included->block))); + + return TRUE; + } +diff -up dovecot-2.3.21/dovecot-pigeonhole/src/lib-sieve/plugins/include/ext-include-common.c.ph_optglob dovecot-2.3.21/dovecot-pigeonhole/src/lib-sieve/plugins/include/ext-include-common.c +--- dovecot-2.3.21/dovecot-pigeonhole/src/lib-sieve/plugins/include/ext-include-common.c.ph_optglob 2023-09-14 15:18:26.000000000 +0200 ++++ dovecot-2.3.21/dovecot-pigeonhole/src/lib-sieve/plugins/include/ext-include-common.c 2024-06-04 09:10:45.187823805 +0200 +@@ -693,6 +693,25 @@ int ext_include_execute_include(const st + } + + ctx = ext_include_get_interpreter_context(this_ext, renv->interp); ++ if (included->block == NULL) { ++ if ((flags & EXT_INCLUDE_FLAG_OPTIONAL) != 0) { ++ sieve_runtime_trace( ++ renv, SIEVE_TRLVL_NONE, ++ "include: skipped include for script '%s' " ++ "[inc id: %d, block: NULL]; optional and unavailable", ++ sieve_script_name(included->script), ++ include_id); ++ return result; ++ } else { ++ sieve_runtime_trace( ++ renv, SIEVE_TRLVL_NONE, ++ "include: unavailable script '%s' " ++ "[inc id: %d, block: NULL]", ++ sieve_script_name(included->script), ++ include_id); ++ return SIEVE_EXEC_BIN_CORRUPT; ++ } ++ } + block_id = sieve_binary_block_get_id(included->block); + + /* If :once modifier is specified, check for duplicate include */ diff --git a/SOURCES/dovecot-2.3-ph_scriptcmp.patch b/SOURCES/dovecot-2.3-ph_scriptcmp.patch new file mode 100644 index 0000000..2bcaade --- /dev/null +++ b/SOURCES/dovecot-2.3-ph_scriptcmp.patch @@ -0,0 +1,12 @@ +diff -up dovecot-2.3.21/dovecot-pigeonhole/src/lib-sieve/storage/file/sieve-file-script.c.testfix4 dovecot-2.3.21/dovecot-pigeonhole/src/lib-sieve/storage/file/sieve-file-script.c +--- dovecot-2.3.21/dovecot-pigeonhole/src/lib-sieve/storage/file/sieve-file-script.c.testfix4 2024-06-03 13:35:24.408858593 +0200 ++++ dovecot-2.3.21/dovecot-pigeonhole/src/lib-sieve/storage/file/sieve-file-script.c 2024-06-03 13:35:24.434858849 +0200 +@@ -800,7 +800,7 @@ static bool sieve_file_script_equals + (struct sieve_file_script *)other; + + return ( CMP_DEV_T(fscript->st.st_dev, fother->st.st_dev) && +- fscript->st.st_ino == fother->st.st_ino ); ++ fscript->st.st_ino == fother->st.st_ino && (fscript->st.st_ino != 0 || script->location != NULL && other->location != NULL && strcmp(script->location, other->location) == 0)); + } + + /* diff --git a/SOURCES/dovecot-2.3.0.1-libxcrypt.patch b/SOURCES/dovecot-2.3.0.1-libxcrypt.patch new file mode 100644 index 0000000..a8c33bf --- /dev/null +++ b/SOURCES/dovecot-2.3.0.1-libxcrypt.patch @@ -0,0 +1,11 @@ +diff -up dovecot-2.3.0.1/src/auth/mycrypt.c.libxcrypt dovecot-2.3.0.1/src/auth/mycrypt.c +--- dovecot-2.3.0.1/src/auth/mycrypt.c.libxcrypt 2018-02-28 15:28:58.000000000 +0100 ++++ dovecot-2.3.0.1/src/auth/mycrypt.c 2018-03-27 10:57:38.447769201 +0200 +@@ -14,6 +14,7 @@ + # define _XPG6 /* Some Solaris versions require this, some break with this */ + #endif + #include ++#include + + #include "mycrypt.h" + diff --git a/SOURCES/dovecot-2.3.11-bigkey.patch b/SOURCES/dovecot-2.3.11-bigkey.patch new file mode 100644 index 0000000..dc81a33 --- /dev/null +++ b/SOURCES/dovecot-2.3.11-bigkey.patch @@ -0,0 +1,10 @@ +diff -up dovecot-2.3.15/doc/dovecot-openssl.cnf.bigkey dovecot-2.3.15/doc/dovecot-openssl.cnf +--- dovecot-2.3.15/doc/dovecot-openssl.cnf.bigkey 2021-06-21 20:24:51.913456628 +0200 ++++ dovecot-2.3.15/doc/dovecot-openssl.cnf 2021-06-21 20:25:36.352912123 +0200 +@@ -1,5 +1,5 @@ + [ req ] +-default_bits = 2048 ++default_bits = 3072 + encrypt_key = yes + distinguished_name = req_dn + x509_extensions = cert_type diff --git a/SOURCES/dovecot-2.3.14-opensslv3.patch b/SOURCES/dovecot-2.3.14-opensslv3.patch new file mode 100644 index 0000000..fa6c44f --- /dev/null +++ b/SOURCES/dovecot-2.3.14-opensslv3.patch @@ -0,0 +1,34 @@ +diff -up dovecot-2.3.14/src/lib-dcrypt/dcrypt-openssl.c.opensslv3 dovecot-2.3.14/src/lib-dcrypt/dcrypt-openssl.c +--- dovecot-2.3.14/src/lib-dcrypt/dcrypt-openssl.c.opensslv3 2021-06-03 18:56:52.573174433 +0200 ++++ dovecot-2.3.14/src/lib-dcrypt/dcrypt-openssl.c 2021-06-03 18:56:52.585174274 +0200 +@@ -73,10 +73,30 @@ + 2key algo oid1symmetric algo namesalthash algoroundsE(RSA = i2d_PrivateKey, EC=Private Point)key id + **/ + ++#if OPENSSL_VERSION_MAJOR == 3 ++static EC_KEY *EVP_PKEY_get0_EC_KEYv3(EVP_PKEY *key) ++{ ++ EC_KEY *eck = EVP_PKEY_get1_EC_KEY(key); ++ EVP_PKEY_set1_EC_KEY(key, eck); ++ EC_KEY_free(eck); ++ return eck; ++} ++ ++static EC_KEY *EVP_PKEY_get1_EC_KEYv3(EVP_PKEY *key) ++{ ++ EC_KEY *eck = EVP_PKEY_get1_EC_KEY(key); ++ EVP_PKEY_set1_EC_KEY(key, eck); ++ return eck; ++} ++ ++#define EVP_PKEY_get0_EC_KEY EVP_PKEY_get0_EC_KEYv3 ++#define EVP_PKEY_get1_EC_KEY EVP_PKEY_get1_EC_KEYv3 ++#else + #ifndef HAVE_EVP_PKEY_get0 + #define EVP_PKEY_get0_EC_KEY(x) x->pkey.ec + #define EVP_PKEY_get0_RSA(x) x->pkey.rsa + #endif ++#endif + + #ifndef HAVE_OBJ_LENGTH + #define OBJ_length(o) ((o)->length) diff --git a/SOURCES/dovecot-2.3.15-fixvalcond.patch b/SOURCES/dovecot-2.3.15-fixvalcond.patch new file mode 100644 index 0000000..a064c26 --- /dev/null +++ b/SOURCES/dovecot-2.3.15-fixvalcond.patch @@ -0,0 +1,24 @@ +diff -up dovecot-2.3.17/dovecot-pigeonhole/src/lib-sieve/storage/dict/sieve-dict-script.c.fixvalcond dovecot-2.3.17/dovecot-pigeonhole/src/lib-sieve/storage/dict/sieve-dict-script.c +--- dovecot-2.3.17/dovecot-pigeonhole/src/lib-sieve/storage/dict/sieve-dict-script.c.fixvalcond 2021-11-02 21:51:36.109032050 +0100 ++++ dovecot-2.3.17/dovecot-pigeonhole/src/lib-sieve/storage/dict/sieve-dict-script.c 2021-11-02 21:52:28.409344118 +0100 +@@ -114,7 +114,7 @@ static int sieve_dict_script_get_stream + (struct sieve_dict_script *)script; + struct sieve_dict_storage *dstorage = + (struct sieve_dict_storage *)script->storage; +- const char *path, *name = script->name, *data, *error; ++ const char *path, *name = script->name, *data, *error = NULL; + int ret; + + dscript->data_pool = +diff -up dovecot-2.3.17/src/lib-storage/index/index-attribute.c.fixvalcond dovecot-2.3.17/src/lib-storage/index/index-attribute.c +--- dovecot-2.3.17/src/lib-storage/index/index-attribute.c.fixvalcond 2021-10-27 13:09:04.000000000 +0200 ++++ dovecot-2.3.17/src/lib-storage/index/index-attribute.c 2021-11-02 21:51:36.109032050 +0100 +@@ -248,7 +248,7 @@ int index_storage_attribute_get(struct m + struct mail_attribute_value *value_r) + { + struct dict *dict; +- const char *mailbox_prefix, *error; ++ const char *mailbox_prefix, *error = NULL; + int ret; + + i_zero(value_r); diff --git a/SOURCES/dovecot-2.3.15-valbasherr.patch b/SOURCES/dovecot-2.3.15-valbasherr.patch new file mode 100644 index 0000000..bbcb86f --- /dev/null +++ b/SOURCES/dovecot-2.3.15-valbasherr.patch @@ -0,0 +1,20 @@ +diff -up dovecot-2.3.15/run-test-valgrind.supp.valbasherr dovecot-2.3.15/run-test-valgrind.supp +--- dovecot-2.3.15/run-test-valgrind.supp.valbasherr 2021-06-21 22:52:53.272707239 +0200 ++++ dovecot-2.3.15/run-test-valgrind.supp 2021-06-21 22:54:19.786668430 +0200 +@@ -1,4 +1,16 @@ + { ++ ++ Memcheck:Leak ++ match-leak-kinds: definite ++ fun:malloc ++ fun:make_if_command ++ fun:yyparse ++ fun:parse_command ++ fun:read_command ++ fun:reader_loop ++ fun:main ++} ++{ + + Memcheck:Leak + fun:malloc diff --git a/SOURCES/dovecot-2.3.19.1-7bad6a24.patch b/SOURCES/dovecot-2.3.19.1-7bad6a24.patch new file mode 100644 index 0000000..c980dde --- /dev/null +++ b/SOURCES/dovecot-2.3.19.1-7bad6a24.patch @@ -0,0 +1,131 @@ +From 7bad6a24160e34bce8f10e73dbbf9e5fbbcd1904 Mon Sep 17 00:00:00 2001 +From: Timo Sirainen +Date: Mon, 9 May 2022 15:23:33 +0300 +Subject: [PATCH] auth: Fix handling passdbs with identical driver/args but + different mechanisms/username_filter + +The passdb was wrongly deduplicated in this situation, causing wrong +mechanisms or username_filter setting to be used. This would be a rather +unlikely configuration though. + +Fixed by moving mechanisms and username_filter from struct passdb_module +to struct auth_passdb, which is where they should have been in the first +place. +--- + src/auth/auth-request.c | 6 +++--- + src/auth/auth.c | 18 ++++++++++++++++++ + src/auth/auth.h | 5 +++++ + src/auth/passdb.c | 15 ++------------- + src/auth/passdb.h | 4 ---- + 5 files changed, 28 insertions(+), 20 deletions(-) + +diff --git a/src/auth/auth-request.c b/src/auth/auth-request.c +index cd08b1fa02..0ca29f3674 100644 +--- a/src/auth/auth-request.c ++++ b/src/auth/auth-request.c +@@ -534,8 +534,8 @@ auth_request_want_skip_passdb(struct auth_request *request, + struct auth_passdb *passdb) + { + /* if mechanism is not supported, skip */ +- const char *const *mechs = passdb->passdb->mechanisms; +- const char *const *username_filter = passdb->passdb->username_filter; ++ const char *const *mechs = passdb->mechanisms; ++ const char *const *username_filter = passdb->username_filter; + const char *username; + + username = request->fields.user; +@@ -548,7 +548,7 @@ auth_request_want_skip_passdb(struct auth_request *request, + return TRUE; + } + +- if (passdb->passdb->username_filter != NULL && ++ if (passdb->username_filter != NULL && + !auth_request_username_accepted(username_filter, username)) { + auth_request_log_debug(request, + request->mech != NULL ? AUTH_SUBSYS_MECH +diff --git a/src/auth/auth.c b/src/auth/auth.c +index f2f3fda20c..9f6c4ba60c 100644 +--- a/src/auth/auth.c ++++ b/src/auth/auth.c +@@ -99,6 +99,24 @@ auth_passdb_preinit(struct auth *auth, const struct auth_passdb_settings *set, + auth_passdb->override_fields_tmpl = + passdb_template_build(auth->pool, set->override_fields); + ++ if (*set->mechanisms == '\0') { ++ auth_passdb->mechanisms = NULL; ++ } else if (strcasecmp(set->mechanisms, "none") == 0) { ++ auth_passdb->mechanisms = (const char *const[]){ NULL }; ++ } else { ++ auth_passdb->mechanisms = ++ (const char *const *)p_strsplit_spaces(auth->pool, ++ set->mechanisms, " ,"); ++ } ++ ++ if (*set->username_filter == '\0') { ++ auth_passdb->username_filter = NULL; ++ } else { ++ auth_passdb->username_filter = ++ (const char *const *)p_strsplit_spaces(auth->pool, ++ set->username_filter, " ,"); ++ } ++ + /* for backwards compatibility: */ + if (set->pass) + auth_passdb->result_success = AUTH_DB_RULE_CONTINUE; +diff --git a/src/auth/auth.h b/src/auth/auth.h +index f700e29d5c..460a179765 100644 +--- a/src/auth/auth.h ++++ b/src/auth/auth.h +@@ -41,6 +41,11 @@ struct auth_passdb { + struct passdb_template *default_fields_tmpl; + struct passdb_template *override_fields_tmpl; + ++ /* Supported authentication mechanisms, NULL is all, {NULL} is none */ ++ const char *const *mechanisms; ++ /* Username filter, NULL is no filter */ ++ const char *const *username_filter; ++ + enum auth_passdb_skip skip; + enum auth_db_rule result_success; + enum auth_db_rule result_failure; +diff --git a/src/auth/passdb.c b/src/auth/passdb.c +index eb4ac8ae82..f5eed1af4f 100644 +--- a/src/auth/passdb.c ++++ b/src/auth/passdb.c +@@ -224,19 +224,8 @@ passdb_preinit(pool_t pool, const struct auth_passdb_settings *set) + passdb->id = ++auth_passdb_id; + passdb->iface = *iface; + passdb->args = p_strdup(pool, set->args); +- if (*set->mechanisms == '\0') { +- passdb->mechanisms = NULL; +- } else if (strcasecmp(set->mechanisms, "none") == 0) { +- passdb->mechanisms = (const char *const[]){NULL}; +- } else { +- passdb->mechanisms = (const char* const*)p_strsplit_spaces(pool, set->mechanisms, " ,"); +- } +- +- if (*set->username_filter == '\0') { +- passdb->username_filter = NULL; +- } else { +- passdb->username_filter = (const char* const*)p_strsplit_spaces(pool, set->username_filter, " ,"); +- } ++ /* NOTE: if anything else than driver & args are added here, ++ passdb_find() also needs to be updated. */ + array_push_back(&passdb_modules, &passdb); + return passdb; + } +diff --git a/src/auth/passdb.h b/src/auth/passdb.h +index 2e95328e5c..e466a9fdb6 100644 +--- a/src/auth/passdb.h ++++ b/src/auth/passdb.h +@@ -63,10 +63,6 @@ struct passdb_module { + /* Default password scheme for this module. + If default_cache_key is set, must not be NULL. */ + const char *default_pass_scheme; +- /* Supported authentication mechanisms, NULL is all, [NULL] is none*/ +- const char *const *mechanisms; +- /* Username filter, NULL is no filter */ +- const char *const *username_filter; + + /* If blocking is set to TRUE, use child processes to access + this passdb. */ diff --git a/SOURCES/dovecot-2.3.20-nolibotp.patch b/SOURCES/dovecot-2.3.20-nolibotp.patch new file mode 100644 index 0000000..4ec0b78 --- /dev/null +++ b/SOURCES/dovecot-2.3.20-nolibotp.patch @@ -0,0 +1,295 @@ +diff -up dovecot-2.3.20/configure.ac.nolibotp dovecot-2.3.20/configure.ac +--- dovecot-2.3.20/configure.ac.nolibotp 2022-12-21 09:49:12.000000000 +0100 ++++ dovecot-2.3.20/configure.ac 2023-02-14 16:54:02.118531016 +0100 +@@ -854,7 +854,6 @@ src/lib-lua/Makefile + src/lib-mail/Makefile + src/lib-master/Makefile + src/lib-program-client/Makefile +-src/lib-otp/Makefile + src/lib-dovecot/Makefile + src/lib-sasl/Makefile + src/lib-settings/Makefile +diff -up dovecot-2.3.20/src/auth/main.c.nolibotp dovecot-2.3.20/src/auth/main.c +--- dovecot-2.3.20/src/auth/main.c.nolibotp 2022-12-21 09:49:12.000000000 +0100 ++++ dovecot-2.3.20/src/auth/main.c 2023-02-14 16:54:02.118531016 +0100 +@@ -19,8 +19,6 @@ + #include "password-scheme.h" + #include "passdb-cache.h" + #include "mech.h" +-#include "otp.h" +-#include "mech-otp-common.h" + #include "auth.h" + #include "auth-penalty.h" + #include "auth-token.h" +@@ -283,7 +281,6 @@ static void main_deinit(void) + + auth_policy_deinit(); + mech_register_deinit(&mech_reg); +- mech_otp_deinit(); + mech_deinit(global_auth_settings); + + /* allow modules to unregister their dbs/drivers/etc. before freeing +diff -up dovecot-2.3.20/src/auth/Makefile.am.nolibotp dovecot-2.3.20/src/auth/Makefile.am +--- dovecot-2.3.20/src/auth/Makefile.am.nolibotp 2022-12-21 09:49:12.000000000 +0100 ++++ dovecot-2.3.20/src/auth/Makefile.am 2023-02-14 16:54:02.118531016 +0100 +@@ -45,7 +45,6 @@ AM_CPPFLAGS = \ + -I$(top_srcdir)/src/lib-sql \ + -I$(top_srcdir)/src/lib-settings \ + -I$(top_srcdir)/src/lib-old-stats \ +- -I$(top_srcdir)/src/lib-otp \ + -I$(top_srcdir)/src/lib-master \ + -I$(top_srcdir)/src/lib-oauth2 \ + -I$(top_srcdir)/src/lib-ssl-iostream \ +@@ -67,7 +66,6 @@ libpassword_la_SOURCES = \ + password-scheme-crypt.c \ + password-scheme-md5crypt.c \ + password-scheme-scram.c \ +- password-scheme-otp.c \ + password-scheme-pbkdf2.c \ + password-scheme-sodium.c + libpassword_la_CFLAGS = $(AM_CPPFLAGS) $(LIBSODIUM_CFLAGS) +@@ -76,7 +74,6 @@ auth_libs = \ + libauth.la \ + libstats_auth.la \ + libpassword.la \ +- ../lib-otp/libotp.la \ + $(AUTH_LUA_LIBS) \ + $(LIBDOVECOT_SQL) + +@@ -95,7 +92,6 @@ libauth_la_SOURCES = \ + auth-client-connection.c \ + auth-master-connection.c \ + auth-policy.c \ +- mech-otp-common.c \ + mech-plain-common.c \ + auth-penalty.c \ + auth-request.c \ +@@ -122,7 +118,6 @@ libauth_la_SOURCES = \ + mech-digest-md5.c \ + mech-external.c \ + mech-gssapi.c \ +- mech-otp.c \ + mech-scram.c \ + mech-apop.c \ + mech-winbind.c \ +@@ -161,7 +156,6 @@ headers = \ + auth-client-connection.h \ + auth-common.h \ + auth-master-connection.h \ +- mech-otp-common.h \ + mech-plain-common.h \ + mech-digest-md5-private.h \ + mech-scram.h \ +@@ -260,7 +254,6 @@ test_libs = \ + test_libpassword_SOURCES = test-libpassword.c + test_libpassword_LDADD = \ + libpassword.la \ +- ../lib-otp/libotp.la \ + $(CRYPT_LIBS) \ + $(LIBDOVECOT_SQL) \ + $(LIBSODIUM_LIBS) \ +diff -up dovecot-2.3.20/src/auth/mech.c.nolibotp dovecot-2.3.20/src/auth/mech.c +--- dovecot-2.3.20/src/auth/mech.c.nolibotp 2023-02-14 16:55:38.421231797 +0100 ++++ dovecot-2.3.20/src/auth/mech.c 2023-02-14 16:55:38.434231892 +0100 +@@ -71,7 +71,6 @@ extern const struct mech_module mech_apo + extern const struct mech_module mech_cram_md5; + extern const struct mech_module mech_digest_md5; + extern const struct mech_module mech_external; +-extern const struct mech_module mech_otp; + extern const struct mech_module mech_scram_sha1; + extern const struct mech_module mech_scram_sha256; + extern const struct mech_module mech_anonymous; +@@ -206,7 +205,6 @@ void mech_init(const struct auth_setting + mech_register_module(&mech_gssapi_spnego); + #endif + } +- mech_register_module(&mech_otp); + mech_register_module(&mech_scram_sha1); + mech_register_module(&mech_scram_sha256); + mech_register_module(&mech_anonymous); +@@ -233,7 +231,6 @@ void mech_deinit(const struct auth_setti + mech_unregister_module(&mech_gssapi_spnego); + #endif + } +- mech_unregister_module(&mech_otp); + mech_unregister_module(&mech_scram_sha1); + mech_unregister_module(&mech_scram_sha256); + mech_unregister_module(&mech_anonymous); +diff -up dovecot-2.3.20/src/auth/password-scheme.c.nolibotp dovecot-2.3.20/src/auth/password-scheme.c +--- dovecot-2.3.20/src/auth/password-scheme.c.nolibotp 2023-02-14 16:54:02.109530950 +0100 ++++ dovecot-2.3.20/src/auth/password-scheme.c 2023-02-14 16:54:02.119531023 +0100 +@@ -13,7 +13,6 @@ + #include "randgen.h" + #include "sha1.h" + #include "sha2.h" +-#include "otp.h" + #include "str.h" + #include "password-scheme.h" + +@@ -709,32 +708,6 @@ plain_md5_generate(const char *plaintext + *size_r = MD5_RESULTLEN; + } + +-static int otp_verify(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, +- const unsigned char *raw_password, size_t size, +- const char **error_r) +-{ +- const char *password, *generated; +- +- password = t_strndup(raw_password, size); +- if (password_generate_otp(plaintext, password, UINT_MAX, &generated) < 0) { +- *error_r = "Invalid OTP data in passdb"; +- return -1; +- } +- +- return strcasecmp(password, generated) == 0 ? 1 : 0; +-} +- +-static void +-otp_generate(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, +- const unsigned char **raw_password_r, size_t *size_r) +-{ +- const char *password; +- +- if (password_generate_otp(plaintext, NULL, OTP_HASH_SHA1, &password) < 0) +- i_unreached(); +- *raw_password_r = (const unsigned char *)password; +- *size_r = strlen(password); +-} + + static const struct password_scheme builtin_schemes[] = { + { "MD5", PW_ENCODING_NONE, 0, md5_verify, md5_crypt_generate }, +@@ -770,7 +743,6 @@ static const struct password_scheme buil + NULL, plain_md5_generate }, + { "LDAP-MD5", PW_ENCODING_BASE64, MD5_RESULTLEN, + NULL, plain_md5_generate }, +- { "OTP", PW_ENCODING_NONE, 0, otp_verify, otp_generate }, + { "PBKDF2", PW_ENCODING_NONE, 0, pbkdf2_verify, pbkdf2_generate }, + }; + +diff -up dovecot-2.3.20/src/auth/password-scheme.h.nolibotp dovecot-2.3.20/src/auth/password-scheme.h +--- dovecot-2.3.20/src/auth/password-scheme.h.nolibotp 2023-02-14 16:56:50.929759540 +0100 ++++ dovecot-2.3.20/src/auth/password-scheme.h 2023-02-14 16:56:50.947759671 +0100 +@@ -92,9 +92,6 @@ void password_set_encryption_rounds(unsi + /* INTERNAL: */ + const char *password_generate_salt(size_t len); + const char *password_generate_md5_crypt(const char *pw, const char *salt); +-int password_generate_otp(const char *pw, const char *state_data, +- unsigned int algo, const char **result_r) +- ATTR_NULL(2); + + int crypt_verify(const char *plaintext, + const struct password_generate_params *params, +diff -up dovecot-2.3.20/src/auth/test-libpassword.c.nolibotp dovecot-2.3.20/src/auth/test-libpassword.c +--- dovecot-2.3.20/src/auth/test-libpassword.c.nolibotp 2023-02-14 16:54:55.880922175 +0100 ++++ dovecot-2.3.20/src/auth/test-libpassword.c 2023-02-14 16:54:55.896922291 +0100 +@@ -106,7 +106,6 @@ static void test_password_schemes(void) + test_password_scheme("SHA512", "{SHA512}7iaw3Ur350mqGo7jwQrpkj9hiYB3Lkc/iBml1JQODbJ6wYX4oOHV+E+IvIh/1nsUNzLDBMxfqa2Ob1f1ACio/w==", "test"); + test_password_scheme("SSHA", "{SSHA}H/zrDv8FXUu1JmwvVYijfrYEF34jVZcO", "test"); + test_password_scheme("MD5-CRYPT", "{MD5-CRYPT}$1$GgvxyNz8$OjZhLh4P.gF1lxYEbLZ3e/", "test"); +- test_password_scheme("OTP", "{OTP}sha1 1024 ae6b49aa481f7233 f69fc7f98b8fbf54", "test"); + test_password_scheme("PBKDF2", "{PBKDF2}$1$bUnT4Pl7yFtYX0KU$5000$50a83cafdc517b9f46519415e53c6a858908680a", "test"); + test_password_scheme("CRAM-MD5", "{CRAM-MD5}e02d374fde0dc75a17a557039a3a5338c7743304777dccd376f332bee68d2cf6", "test"); + test_password_scheme("DIGEST-MD5", "{DIGEST-MD5}77c1a8c437c9b08ba2f460fe5d58db5d", "test"); +diff -up dovecot-2.3.20/src/auth/test-mech.c.nolibotp dovecot-2.3.20/src/auth/test-mech.c +--- dovecot-2.3.20/src/auth/test-mech.c.nolibotp 2022-12-21 09:49:12.000000000 +0100 ++++ dovecot-2.3.20/src/auth/test-mech.c 2023-02-14 16:54:02.119531023 +0100 +@@ -8,8 +8,6 @@ + #include "auth-request-handler-private.h" + #include "auth-settings.h" + #include "mech-digest-md5-private.h" +-#include "otp.h" +-#include "mech-otp-common.h" + #include "settings-parser.h" + #include "password-scheme.h" + #include "auth-token.h" +@@ -27,7 +25,6 @@ extern const struct mech_module mech_dov + extern const struct mech_module mech_external; + extern const struct mech_module mech_login; + extern const struct mech_module mech_oauthbearer; +-extern const struct mech_module mech_otp; + extern const struct mech_module mech_plain; + extern const struct mech_module mech_scram_sha1; + extern const struct mech_module mech_scram_sha256; +@@ -65,10 +62,7 @@ request_handler_reply_mock_callback(stru + + if (request->passdb_result == PASSDB_RESULT_OK) + request->failed = FALSE; +- else if (request->mech == &mech_otp) { +- if (null_strcmp(request->fields.user, "otp_phase_2") == 0) +- request->failed = FALSE; +- } else if (request->mech == &mech_oauthbearer) { ++ else if (request->mech == &mech_oauthbearer) { + } + }; + +@@ -224,10 +218,6 @@ static void test_mechs(void) + {&mech_plain, UCHAR_LEN("\0testuser\0testpass"), "testuser", NULL, TRUE, FALSE, FALSE}, + {&mech_plain, UCHAR_LEN("normaluser\0masteruser\0masterpass"), "masteruser", NULL, TRUE, FALSE, FALSE}, + {&mech_plain, UCHAR_LEN("normaluser\0normaluser\0masterpass"), "normaluser", NULL, TRUE, FALSE, FALSE}, +- {&mech_otp, UCHAR_LEN("hex:5Bf0 75d9 959d 036f"), "otp_phase_2", NULL, TRUE, TRUE, FALSE}, +- {&mech_otp, UCHAR_LEN("word:BOND FOGY DRAB NE RISE MART"), "otp_phase_2", NULL, TRUE, TRUE, FALSE}, +- {&mech_otp, UCHAR_LEN("init-hex:f6bd 6b33 89b8 7203:md5 499 ke6118:23d1 b253 5ae0 2b7e"), "otp_phase_2", NULL, TRUE, TRUE, FALSE}, +- {&mech_otp, UCHAR_LEN("init-word:END KERN BALM NICK EROS WAVY:md5 499 ke1235:BABY FAIN OILY NIL TIDY DADE"), "otp_phase_2", NULL , TRUE, TRUE, FALSE}, + {&mech_oauthbearer, UCHAR_LEN("n,a=testuser,p=cHJvb2Y=,f=nonstandart\x01host=server\x01port=143\x01""auth=Bearer vF9dft4qmTc2Nvb3RlckBhbHRhdmlzdGEuY29tCg==\x01\x01"), "testuser", NULL, FALSE, TRUE, FALSE}, + {&mech_scram_sha1, UCHAR_LEN("n,,n=testuser,r=rOprNGfwEbeRWgbNEkqO"), "testuser", NULL, TRUE, FALSE, FALSE}, + {&mech_scram_sha256, UCHAR_LEN("n,,n=testuser,r=rOprNGfwEbeRWgbNEkqO"), "testuser", NULL, TRUE, FALSE, FALSE}, +@@ -242,8 +232,6 @@ static void test_mechs(void) + {&mech_external, UCHAR_LEN(""), "testuser", NULL, FALSE, TRUE, FALSE}, + {&mech_external, UCHAR_LEN(""), NULL, NULL, FALSE, FALSE, FALSE}, + {&mech_login, UCHAR_LEN(""), NULL, NULL, FALSE, FALSE, FALSE}, +- {&mech_otp, UCHAR_LEN(""), NULL, "invalid input", FALSE, FALSE, FALSE}, +- {&mech_otp, UCHAR_LEN(""), "testuser", "invalid input", FALSE, FALSE, FALSE}, + {&mech_plain, UCHAR_LEN(""), NULL, NULL, FALSE, FALSE, FALSE}, + {&mech_oauthbearer, UCHAR_LEN(""), NULL, NULL, FALSE, FALSE, FALSE}, + {&mech_xoauth2, UCHAR_LEN(""), NULL, NULL, FALSE, FALSE, FALSE}, +@@ -255,7 +243,6 @@ static void test_mechs(void) + {&mech_apop, UCHAR_LEN("1.1.1\0testuser\0tooshort"), NULL, NULL, FALSE, FALSE, FALSE}, + {&mech_apop, UCHAR_LEN("1.1.1\0testuser\0responseoflen16-"), NULL, NULL, FALSE, FALSE, FALSE}, + {&mech_apop, UCHAR_LEN("1.1.1"), NULL, NULL, FALSE, FALSE, FALSE}, +- {&mech_otp, UCHAR_LEN("somebody\0testuser"), "testuser", "otp(testuser): unsupported response type", FALSE, TRUE, FALSE}, + {&mech_cram_md5, UCHAR_LEN("testuser\0response"), "testuser", NULL, FALSE, FALSE, FALSE}, + {&mech_plain, UCHAR_LEN("testuser\0"), "testuser", NULL, FALSE, FALSE, FALSE}, + +@@ -297,9 +284,7 @@ static void test_mechs(void) + {&mech_plain, UCHAR_LEN("\0fa\0il\0ing\0withthis"), NULL, NULL, FALSE, FALSE, FALSE}, + {&mech_plain, UCHAR_LEN("failingwiththis"), NULL, NULL, FALSE, FALSE, FALSE}, + {&mech_plain, UCHAR_LEN("failing\0withthis"), NULL, NULL, FALSE, FALSE, FALSE}, +- {&mech_otp, UCHAR_LEN("someb\0ody\0testuser"), NULL, "invalid input", FALSE, FALSE, FALSE}, + /* phase 2 */ +- {&mech_otp, UCHAR_LEN("someb\0ody\0testuser"), "testuser", "otp(testuser): unsupported response type", FALSE, TRUE, FALSE}, + {&mech_scram_sha1, UCHAR_LEN("c=biws,r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j,p=v0X8v3Bz2T0CJGbJQyF0X+HI4Ts="), NULL, NULL, FALSE, FALSE, FALSE}, + {&mech_scram_sha1, UCHAR_LEN("iws0X8v3Bz2T0CJGbJQyF0X+HI4Ts=,,,,"), NULL, NULL, FALSE, FALSE, FALSE}, + {&mech_scram_sha1, UCHAR_LEN("n,a=masteruser,,"), NULL, NULL, FALSE, FALSE, FALSE}, +@@ -387,7 +372,6 @@ static void test_mechs(void) + + test_end(); + } T_END; +- mech_otp_deinit(); + auths_deinit(); + auth_token_deinit(); + password_schemes_deinit(); +diff -up dovecot-2.3.20/src/doveadm/Makefile.am.nolibotp dovecot-2.3.20/src/doveadm/Makefile.am +--- dovecot-2.3.20/src/doveadm/Makefile.am.nolibotp 2022-12-21 09:49:12.000000000 +0100 ++++ dovecot-2.3.20/src/doveadm/Makefile.am 2023-02-14 16:54:02.119531023 +0100 +@@ -36,8 +36,7 @@ AM_CPPFLAGS = \ + $(BINARY_CFLAGS) + + cmd_pw_libs = \ +- ../auth/libpassword.la \ +- ../lib-otp/libotp.la ++ ../auth/libpassword.la + + libs = \ + dsync/libdsync.la \ +diff -up dovecot-2.3.20/src/Makefile.am.nolibotp dovecot-2.3.20/src/Makefile.am +--- dovecot-2.3.20/src/Makefile.am.nolibotp 2022-12-21 09:49:12.000000000 +0100 ++++ dovecot-2.3.20/src/Makefile.am 2023-02-14 16:54:02.119531023 +0100 +@@ -40,7 +40,6 @@ SUBDIRS = \ + lib-index \ + lib-storage \ + lib-sql \ +- lib-otp \ + lib-lda \ + lib-dict-backend \ + anvil \ diff --git a/SOURCES/dovecot-2.3.21-noengine.patch b/SOURCES/dovecot-2.3.21-noengine.patch new file mode 100644 index 0000000..7532b91 --- /dev/null +++ b/SOURCES/dovecot-2.3.21-noengine.patch @@ -0,0 +1,200 @@ +diff -up dovecot-2.3.21/src/lib-dcrypt/dcrypt-openssl.c.noengine dovecot-2.3.21/src/lib-dcrypt/dcrypt-openssl.c +--- dovecot-2.3.21/src/lib-dcrypt/dcrypt-openssl.c.noengine 2024-07-23 13:18:35.040720598 -0400 ++++ dovecot-2.3.21/src/lib-dcrypt/dcrypt-openssl.c 2024-07-23 13:20:16.250720598 -0400 +@@ -20,7 +20,6 @@ + #include + #include + #include +-#include + #include + #include + #include +diff -up dovecot-2.3.21/m4/ssl.m4.noengine dovecot-2.3.21/m4/ssl.m4 +--- dovecot-2.3.21/m4/ssl.m4.noengine 2024-05-06 17:39:59.362886891 +0200 ++++ dovecot-2.3.21/m4/ssl.m4 2024-05-06 17:42:17.945312656 +0200 +@@ -233,6 +233,27 @@ AC_DEFUN([DOVECOT_SSL], [ + AC_CHECK_LIB(ssl, ECDSA_SIG_set0, [ + AC_DEFINE(HAVE_ECDSA_SIG_SET0,, [Build with ECDSA_SIG_set0 support]) + ],, $SSL_LIBS) ++ AC_CHECK_LIB(ssl, OSSL_PROVIDER_try_load, [ ++ AC_DEFINE(HAVE_OSSL_PROVIDER_try_load,, [Build with OSSL_PROVIDER_try_load support]) ++ ],, $SSL_LIBS) ++ AC_CHECK_LIB(ssl, OPENSSL_init_ssl, [ ++ AC_DEFINE(HAVE_OPENSSL_init_ssl,, [Build with OPENSSL_init_ssl support]) ++ ],, $SSL_LIBS) ++ AC_CHECK_LIB(ssl, OPENSSL_cleanup, [ ++ AC_DEFINE(HAVE_OPENSSL_cleanup,, [OpenSSL supports OPENSSL_cleanup()]) ++ ],, $SSL_LIBS) ++ AC_CHECK_LIB(ssl, OPENSSL_thread_stop, [ ++ AC_DEFINE(HAVE_OPENSSL_thread_stop,, [OpenSSL supports OPENSSL_thread_stop()]) ++ ],, $SSL_LIBS) ++ AC_CHECK_LIB(ssl, ERR_remove_thread_state, [ ++ AC_DEFINE(HAVE_ERR_remove_thread_state,, [OpenSSL supports ERR_remove_thread_state()]) ++ ],, $SSL_LIBS) ++ AC_CHECK_LIB(ssl, ERR_remove_state, [ ++ AC_DEFINE(HAVE_ERR_remove_state,, [OpenSSL supports ERR_remove_state()]) ++ ],, $SSL_LIBS) ++ AC_CHECK_LIB(ssl, ENGINE_by_id_DISABLED, [ ++ AC_DEFINE(HAVE_ENGINE_by_id,, [OpenSSL supports ENGINE_by_id() - !!!EXPLICITELY DISABLED!!! ]) ++ ],, $SSL_LIBS) + AC_CHECK_LIB(ssl, EC_GROUP_order_bits, [ + AC_DEFINE(HAVE_EC_GROUP_order_bits,, [Build with EC_GROUP_order_bits support]) + ],, $SSL_LIBS) +diff -up dovecot-2.3.21/src/lib-ssl-iostream/dovecot-openssl-common.c.noengine dovecot-2.3.21/src/lib-ssl-iostream/dovecot-openssl-common.c +--- dovecot-2.3.21/src/lib-ssl-iostream/dovecot-openssl-common.c.noengine 2023-09-14 15:17:46.000000000 +0200 ++++ dovecot-2.3.21/src/lib-ssl-iostream/dovecot-openssl-common.c 2024-05-06 17:39:59.363886901 +0200 +@@ -3,13 +3,23 @@ + #include "lib.h" + #include "randgen.h" + #include "dovecot-openssl-common.h" ++#include "iostream-openssl.h" + + #include +-#include ++#include ++#ifdef HAVE_OSSL_PROVIDER_try_load ++# include ++#else ++# include ++#endif + #include + + static int openssl_init_refcount = 0; +-static ENGINE *dovecot_openssl_engine; ++#ifdef HAVE_OSSL_PROVIDER_try_load ++static OSSL_PROVIDER *dovecot_openssl_engine = NULL; ++#else ++static ENGINE *dovecot_openssl_engine = NULL; ++#endif + + #ifdef HAVE_SSL_NEW_MEM_FUNCS + static void *dovecot_openssl_malloc(size_t size, const char *u0 ATTR_UNUSED, int u1 ATTR_UNUSED) +@@ -17,12 +27,14 @@ static void *dovecot_openssl_malloc(size + static void *dovecot_openssl_malloc(size_t size) + #endif + { ++ if (size == 0) ++ return NULL; + /* this may be performance critical, so don't use + i_malloc() or calloc() */ + void *mem = malloc(size); +- if (mem == NULL) { ++ if (unlikely(mem == NULL)) { + i_fatal_status(FATAL_OUTOFMEM, +- "OpenSSL: malloc(%zu): Out of memory", size); ++ "OpenSSL: malloc(%zu): Out of memory", size); + } + return mem; + } +@@ -33,10 +45,14 @@ static void *dovecot_openssl_realloc(voi + static void *dovecot_openssl_realloc(void *ptr, size_t size) + #endif + { ++ if (size == 0) { ++ free(ptr); ++ return NULL; ++ } + void *mem = realloc(ptr, size); +- if (mem == NULL) { ++ if (unlikely(mem == NULL)) { + i_fatal_status(FATAL_OUTOFMEM, +- "OpenSSL: realloc(%zu): Out of memory", size); ++ "OpenSSL: realloc(%zu): Out of memory", size); + } + return mem; + } +@@ -63,9 +79,13 @@ void dovecot_openssl_common_global_ref(v + /*i_warning("CRYPTO_set_mem_functions() was called too late");*/ + } + ++#ifdef HAVE_OPENSSL_init_ssl ++ OPENSSL_init_ssl(0, NULL); ++#else + SSL_library_init(); + SSL_load_error_strings(); + OpenSSL_add_all_algorithms(); ++#endif + } + + bool dovecot_openssl_common_global_unref(void) +@@ -76,30 +96,35 @@ bool dovecot_openssl_common_global_unref + return TRUE; + + if (dovecot_openssl_engine != NULL) { ++#ifdef HAVE_OSSL_PROVIDER_try_load ++ OSSL_PROVIDER_unload(dovecot_openssl_engine); ++#else + ENGINE_finish(dovecot_openssl_engine); ++#endif + dovecot_openssl_engine = NULL; + } ++#ifdef HAVE_OPENSSL_cleanup ++ OPENSSL_cleanup(); ++#else + /* OBJ_cleanup() is called automatically by EVP_cleanup() in + newer versions. Doesn't hurt to call it anyway. */ + OBJ_cleanup(); +-#ifdef HAVE_SSL_COMP_FREE_COMPRESSION_METHODS ++# if !defined(OPENSSL_NO_COMP) + SSL_COMP_free_compression_methods(); +-#endif ++# endif + ENGINE_cleanup(); + EVP_cleanup(); + CRYPTO_cleanup_all_ex_data(); +-#ifdef HAVE_OPENSSL_AUTO_THREAD_DEINIT ++# ifdef HAVE_OPENSSL_thread_stop + /* no cleanup needed */ +-#elif defined(HAVE_OPENSSL_ERR_REMOVE_THREAD_STATE) ++# elif defined(HAVE_ERR_remove_thread_state) + /* This was marked as deprecated in v1.1. */ + ERR_remove_thread_state(NULL); +-#else ++# elif defined(HAVE_ERR_remove_state) + /* This was deprecated by ERR_remove_thread_state(NULL) in v1.0.0. */ + ERR_remove_state(0); +-#endif ++# endif + ERR_free_strings(); +-#ifdef HAVE_OPENSSL_CLEANUP +- OPENSSL_cleanup(); + #endif + return FALSE; + } +@@ -110,6 +135,7 @@ int dovecot_openssl_common_global_set_en + if (dovecot_openssl_engine != NULL) + return 1; + ++#ifdef HAVE_ENGINE_by_id + ENGINE_load_builtin_engines(); + dovecot_openssl_engine = ENGINE_by_id(engine); + if (dovecot_openssl_engine == NULL) { +@@ -128,5 +154,15 @@ int dovecot_openssl_common_global_set_en + dovecot_openssl_engine = NULL; + return -1; + } ++#elif defined(HAVE_OSSL_PROVIDER_try_load) ++ if ((dovecot_openssl_engine = OSSL_PROVIDER_try_load(NULL, engine, 1)) == NULL) { ++ *error_r = t_strdup_printf("Cannot load '%s': %s", engine, ++ openssl_iostream_error()); ++ return 0; ++ } ++ return 1; ++#else ++ *error_r = t_strdup_printf("Cannot load '%s': No engine/provider support available", engine); ++#endif + return 1; + } +diff -up dovecot-2.3.21/src/lib-ssl-iostream/Makefile.am.noengine dovecot-2.3.21/src/lib-ssl-iostream/Makefile.am +--- dovecot-2.3.21/src/lib-ssl-iostream/Makefile.am.noengine 2023-09-14 15:17:46.000000000 +0200 ++++ dovecot-2.3.21/src/lib-ssl-iostream/Makefile.am 2024-05-06 17:39:59.363886901 +0200 +@@ -5,7 +5,8 @@ NOPLUGIN_LDFLAGS = + AM_CPPFLAGS = \ + -I$(top_srcdir)/src/lib \ + -I$(top_srcdir)/src/lib-test \ +- -DMODULE_DIR=\""$(moduledir)"\" ++ -DMODULE_DIR=\""$(moduledir)"\" \ ++ $(SSL_CFLAGS) + + if BUILD_OPENSSL + module_LTLIBRARIES = libssl_iostream_openssl.la diff --git a/SOURCES/dovecot-2.3.21-test-socket-path.patch b/SOURCES/dovecot-2.3.21-test-socket-path.patch new file mode 100644 index 0000000..8132244 --- /dev/null +++ b/SOURCES/dovecot-2.3.21-test-socket-path.patch @@ -0,0 +1,22 @@ +From 9a3e0d099044d3a7478c3a24ccb8990181767f7c Mon Sep 17 00:00:00 2001 +From: Duncan Bellamy +Date: Sat, 6 Mar 2021 14:25:29 +0000 +Subject: [PATCH] imap: Shorten test-imap-client-hibernate socket path length + +--- + src/imap/test-imap-client-hibernate.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/imap/test-imap-client-hibernate.c b/src/imap/test-imap-client-hibernate.c +index 9b90e1bd9a..c5392fa3fc 100644 +--- a/src/imap/test-imap-client-hibernate.c ++++ b/src/imap/test-imap-client-hibernate.c +@@ -19,7 +19,7 @@ + + #include + +-#define TEMP_DIRNAME ".test-imap-client-hibernate" ++#define TEMP_DIRNAME ".test-ich" + + #define EVILSTR "\t\r\n\001" + diff --git a/SOURCES/dovecot-2.3.21.1-CVE-2024-23184.patch b/SOURCES/dovecot-2.3.21.1-CVE-2024-23184.patch new file mode 100644 index 0000000..0de58c7 --- /dev/null +++ b/SOURCES/dovecot-2.3.21.1-CVE-2024-23184.patch @@ -0,0 +1,976 @@ +From 8e4c42dbb3c770fcdbc396f2abcf1bc228ec548d Mon Sep 17 00:00:00 2001 +From: Timo Sirainen +Date: Fri, 9 Feb 2024 00:32:39 +0200 +Subject: [PATCH 1/6] lib: test-llist - Fix dllist2 test name + +--- + src/lib/test-llist.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/lib/test-llist.c b/src/lib/test-llist.c +index d57006ce2aa..ed584318fa3 100644 +--- a/src/lib/test-llist.c ++++ b/src/lib/test-llist.c +@@ -71,7 +71,7 @@ static void test_dllist2(void) + l2 = t_new(struct dllist, 1); + l1 = t_new(struct dllist, 1); + +- test_begin("dllist"); ++ test_begin("dllist2"); + /* prepend to empty */ + DLLIST2_PREPEND(&head, &tail, l3); + test_assert(head == l3 && tail == l3); + +From cee08202c759a3bdf185d998dcf888ebd1bc6e36 Mon Sep 17 00:00:00 2001 +From: Timo Sirainen +Date: Fri, 9 Feb 2024 00:33:00 +0200 +Subject: [PATCH 2/6] lib: Add DLLIST2_JOIN() + +--- + src/lib/llist.h | 14 ++++++++++++++ + src/lib/test-llist.c | 39 +++++++++++++++++++++++++++++++++++++++ + 2 files changed, 53 insertions(+) + +diff --git a/src/lib/llist.h b/src/lib/llist.h +index 8a52e873352..5ad5d75c0df 100644 +--- a/src/lib/llist.h ++++ b/src/lib/llist.h +@@ -78,4 +78,18 @@ + #define DLLIST2_REMOVE(head, tail, item) \ + DLLIST2_REMOVE_FULL(head, tail, item, prev, next) + ++#define DLLIST2_JOIN_FULL(head1, tail1, head2, tail2, prev, next) STMT_START { \ ++ if (*(head1) == NULL) { \ ++ *(head1) = *(head2); \ ++ *(tail1) = *(tail2); \ ++ } else if (*(head2) != NULL) { \ ++ (*(tail1))->next = *(head2); \ ++ (*(head2))->prev = *(tail1); \ ++ (*tail1) = (*tail2); \ ++ } \ ++ } STMT_END ++ ++#define DLLIST2_JOIN(head1, tail1, head2, tail2) \ ++ DLLIST2_JOIN_FULL(head1, tail1, head2, tail2, prev, next) ++ + #endif +diff --git a/src/lib/test-llist.c b/src/lib/test-llist.c +index ed584318fa3..e293eb6a603 100644 +--- a/src/lib/test-llist.c ++++ b/src/lib/test-llist.c +@@ -131,8 +131,47 @@ static void test_dllist2(void) + test_end(); + } + ++static void test_dllist2_join(void) ++{ ++ struct dllist *head, *tail, *elem[4]; ++ struct dllist *head2, *tail2, *elem2[N_ELEMENTS(elem)]; ++ ++ test_begin("dllist2 join"); ++ for (unsigned int i = 0; i < N_ELEMENTS(elem); i++) { ++ elem[i] = t_new(struct dllist, 1); ++ elem2[i] = t_new(struct dllist, 1); ++ } ++ for (unsigned int i = 0; i < N_ELEMENTS(elem); i++) { ++ for (unsigned int j = 0; j < N_ELEMENTS(elem2); j++) { ++ head = tail = head2 = tail2 = NULL; ++ for (unsigned int n = 0; n < i; n++) ++ DLLIST2_APPEND(&head, &tail, elem[n]); ++ for (unsigned int n = 0; n < j; n++) ++ DLLIST2_APPEND(&head2, &tail2, elem2[n]); ++ DLLIST2_JOIN(&head, &tail, &head2, &tail2); ++ ++ /* verify */ ++ struct dllist *tmp = head, *last = NULL; ++ for (unsigned int n = 0; n < i; n++) { ++ test_assert(tmp == elem[n]); ++ last = tmp; ++ tmp = tmp->next; ++ } ++ for (unsigned int n = 0; n < j; n++) { ++ test_assert(tmp == elem2[n]); ++ last = tmp; ++ tmp = tmp->next; ++ } ++ test_assert(tmp == NULL); ++ test_assert(tail == last); ++ } ++ } ++ test_end(); ++} ++ + void test_llist(void) + { + test_dllist(); + test_dllist2(); ++ test_dllist2_join(); + } + +From 0bae091859c905dc335f21eed01347e6b8338672 Mon Sep 17 00:00:00 2001 +From: Timo Sirainen +Date: Tue, 30 Jan 2024 22:42:50 +0200 +Subject: [PATCH 3/6] lib-mail: test-imap-envelope - Use test_assert_idx() + where possible + +--- + src/lib-imap/test-imap-envelope.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/lib-imap/test-imap-envelope.c b/src/lib-imap/test-imap-envelope.c +index 1f295e58bab..c9b92b4be2b 100644 +--- a/src/lib-imap/test-imap-envelope.c ++++ b/src/lib-imap/test-imap-envelope.c +@@ -157,7 +157,7 @@ static void test_imap_envelope_write(void) + envlp = msg_parse(pool, test->message); + + imap_envelope_write(envlp, str); +- test_assert(strcmp(str_c(str), test->envelope) == 0); ++ test_assert_idx(strcmp(str_c(str), test->envelope) == 0, i); + + pool_unref(&pool); + test_end(); +@@ -179,12 +179,12 @@ static void test_imap_envelope_parse(void) + test_begin(t_strdup_printf("imap envelope parser [%u]", i)); + + ret = imap_envelope_parse(test->envelope, pool, &envlp, &error); +- test_assert(ret); ++ test_assert_idx(ret, i); + + if (ret) { + str_truncate(str, 0); + imap_envelope_write(envlp, str); +- test_assert(strcmp(str_c(str), test->envelope) == 0); ++ test_assert_idx(strcmp(str_c(str), test->envelope) == 0, i); + } else { + i_error("Invalid envelope: %s", error); + } + +From a1c9b0409454e45937bf7e9c3685f5e91d6a5a43 Mon Sep 17 00:00:00 2001 +From: Timo Sirainen +Date: Sun, 4 Feb 2024 00:26:57 +0200 +Subject: [PATCH 4/6] lib-mail: Change message_address to be doubly linked list + +--- + src/lib-imap/imap-envelope.c | 11 +- + src/lib-mail/message-address.c | 8 +- + src/lib-mail/message-address.h | 2 +- + src/lib-mail/test-message-address.c | 226 ++++++++++++++-------------- + 4 files changed, 121 insertions(+), 126 deletions(-) + +diff --git a/src/lib-imap/imap-envelope.c b/src/lib-imap/imap-envelope.c +index 87297f4f691..1312eae2ff3 100644 +--- a/src/lib-imap/imap-envelope.c ++++ b/src/lib-imap/imap-envelope.c +@@ -1,6 +1,7 @@ + /* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */ + + #include "lib.h" ++#include "llist.h" + #include "istream.h" + #include "str.h" + #include "message-address.h" +@@ -127,7 +128,7 @@ static bool + imap_envelope_parse_addresses(const struct imap_arg *arg, + pool_t pool, struct message_address **addrs_r) + { +- struct message_address *first, *addr, *prev; ++ struct message_address *first, *last, *addr; + const struct imap_arg *list_args; + + if (arg->type == IMAP_ARG_NIL) { +@@ -138,16 +139,12 @@ imap_envelope_parse_addresses(const struct imap_arg *arg, + if (!imap_arg_get_list(arg, &list_args)) + return FALSE; + +- first = addr = prev = NULL; ++ first = last = addr = NULL; + for (; !IMAP_ARG_IS_EOL(list_args); list_args++) { + if (!imap_envelope_parse_address + (list_args, pool, &addr)) + return FALSE; +- if (first == NULL) +- first = addr; +- if (prev != NULL) +- prev->next = addr; +- prev = addr; ++ DLLIST2_APPEND(&first, &last, addr); + } + + *addrs_r = first; +diff --git a/src/lib-mail/message-address.c b/src/lib-mail/message-address.c +index fb06afae7b7..9d192799468 100644 +--- a/src/lib-mail/message-address.c ++++ b/src/lib-mail/message-address.c +@@ -1,6 +1,7 @@ + /* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */ + + #include "lib.h" ++#include "llist.h" + #include "str.h" + #include "strescape.h" + #include "smtp-address.h" +@@ -27,11 +28,7 @@ static void add_address(struct message_address_parser_context *ctx) + memcpy(addr, &ctx->addr, sizeof(ctx->addr)); + i_zero(&ctx->addr); + +- if (ctx->first_addr == NULL) +- ctx->first_addr = addr; +- else +- ctx->last_addr->next = addr; +- ctx->last_addr = addr; ++ DLLIST2_APPEND(&ctx->first_addr, &ctx->last_addr, addr); + } + + /* quote with "" and escape all '\', '"' and "'" characters if need */ +@@ -631,6 +628,7 @@ const char *message_address_first_to_string(const struct message_address *addr) + struct message_address first_addr; + + first_addr = *addr; ++ first_addr.prev = NULL; + first_addr.next = NULL; + first_addr.route = NULL; + return message_address_to_string(&first_addr); +diff --git a/src/lib-mail/message-address.h b/src/lib-mail/message-address.h +index 8370397741c..85cff3dcc6f 100644 +--- a/src/lib-mail/message-address.h ++++ b/src/lib-mail/message-address.h +@@ -18,7 +18,7 @@ enum message_address_parse_flags { + {name = NULL, NULL, "group", NULL}, ..., {NULL, NULL, NULL, NULL} + */ + struct message_address { +- struct message_address *next; ++ struct message_address *prev, *next; + + /* display-name */ + const char *name; +diff --git a/src/lib-mail/test-message-address.c b/src/lib-mail/test-message-address.c +index e6204bb0588..261cbfba70a 100644 +--- a/src/lib-mail/test-message-address.c ++++ b/src/lib-mail/test-message-address.c +@@ -47,174 +47,174 @@ static void test_message_address(void) + } tests[] = { + /* user@domain -> */ + { "user@domain", "", NULL, +- { NULL, NULL, NULL, "user", "domain", FALSE }, +- { NULL, NULL, NULL, "user", "domain", FALSE }, 0 }, ++ { NULL, NULL, NULL, NULL, "user", "domain", FALSE }, ++ { NULL, NULL, NULL, NULL, "user", "domain", FALSE }, 0 }, + { "\"user\"@domain", "", NULL, +- { NULL, NULL, NULL, "user", "domain", FALSE }, +- { NULL, NULL, NULL, "user", "domain", FALSE }, 0 }, ++ { NULL, NULL, NULL, NULL, "user", "domain", FALSE }, ++ { NULL, NULL, NULL, NULL, "user", "domain", FALSE }, 0 }, + { "\"user name\"@domain", "<\"user name\"@domain>", NULL, +- { NULL, NULL, NULL, "user name", "domain", FALSE }, +- { NULL, NULL, NULL, "user name", "domain", FALSE }, 0 }, ++ { NULL, NULL, NULL, NULL, "user name", "domain", FALSE }, ++ { NULL, NULL, NULL, NULL, "user name", "domain", FALSE }, 0 }, + { "\"user@na\\\\me\"@domain", "<\"user@na\\\\me\"@domain>", NULL, +- { NULL, NULL, NULL, "user@na\\me", "domain", FALSE }, +- { NULL, NULL, NULL, "user@na\\me", "domain", FALSE }, 0 }, ++ { NULL, NULL, NULL, NULL, "user@na\\me", "domain", FALSE }, ++ { NULL, NULL, NULL, NULL, "user@na\\me", "domain", FALSE }, 0 }, + { "\"user\\\"name\"@domain", "<\"user\\\"name\"@domain>", NULL, +- { NULL, NULL, NULL, "user\"name", "domain", FALSE }, +- { NULL, NULL, NULL, "user\"name", "domain", FALSE }, 0 }, ++ { NULL, NULL, NULL, NULL, "user\"name", "domain", FALSE }, ++ { NULL, NULL, NULL, NULL, "user\"name", "domain", FALSE }, 0 }, + { "\"\"@domain", "<\"\"@domain>", NULL, +- { NULL, NULL, NULL, "", "domain", FALSE }, +- { NULL, NULL, NULL, "", "domain", FALSE }, 0 }, ++ { NULL, NULL, NULL, NULL, "", "domain", FALSE }, ++ { NULL, NULL, NULL, NULL, "", "domain", FALSE }, 0 }, + { "user", "", "", +- { NULL, NULL, NULL, "user", "", TRUE }, +- { NULL, NULL, NULL, "user", "MISSING_DOMAIN", TRUE }, 0 }, ++ { NULL, NULL, NULL, NULL, "user", "", TRUE }, ++ { NULL, NULL, NULL, NULL, "user", "MISSING_DOMAIN", TRUE }, 0 }, + { "@domain", "<\"\"@domain>", "", +- { NULL, NULL, NULL, "", "domain", TRUE }, +- { NULL, NULL, NULL, "MISSING_MAILBOX", "domain", TRUE }, 0 }, ++ { NULL, NULL, NULL, NULL, "", "domain", TRUE }, ++ { NULL, NULL, NULL, NULL, "MISSING_MAILBOX", "domain", TRUE }, 0 }, + + /* Display Name -> Display Name */ + { "Display Name", "\"Display Name\"", "\"Display Name\" ", +- { NULL, "Display Name", NULL, "", "", TRUE }, +- { NULL, "Display Name", NULL, "MISSING_MAILBOX", "MISSING_DOMAIN", TRUE }, 0 }, ++ { NULL, NULL, "Display Name", NULL, "", "", TRUE }, ++ { NULL, NULL, "Display Name", NULL, "MISSING_MAILBOX", "MISSING_DOMAIN", TRUE }, 0 }, + { "\"Display Name\"", "\"Display Name\"", "\"Display Name\" ", +- { NULL, "Display Name", NULL, "", "", TRUE }, +- { NULL, "Display Name", NULL, "MISSING_MAILBOX", "MISSING_DOMAIN", TRUE }, 0 }, ++ { NULL, NULL, "Display Name", NULL, "", "", TRUE }, ++ { NULL, NULL, "Display Name", NULL, "MISSING_MAILBOX", "MISSING_DOMAIN", TRUE }, 0 }, + { "Display \"Name\"", "\"Display Name\"", "\"Display Name\" ", +- { NULL, "Display Name", NULL, "", "", TRUE }, +- { NULL, "Display Name", NULL, "MISSING_MAILBOX", "MISSING_DOMAIN", TRUE }, 0 }, ++ { NULL, NULL, "Display Name", NULL, "", "", TRUE }, ++ { NULL, NULL, "Display Name", NULL, "MISSING_MAILBOX", "MISSING_DOMAIN", TRUE }, 0 }, + { "\"Display\" \"Name\"", "\"Display Name\"", "\"Display Name\" ", +- { NULL, "Display Name", NULL, "", "", TRUE }, +- { NULL, "Display Name", NULL, "MISSING_MAILBOX", "MISSING_DOMAIN", TRUE }, 0 }, ++ { NULL, NULL, "Display Name", NULL, "", "", TRUE }, ++ { NULL, NULL, "Display Name", NULL, "MISSING_MAILBOX", "MISSING_DOMAIN", TRUE }, 0 }, + { "\"\"", "", "", +- { NULL, "", NULL, "", "", TRUE }, +- { NULL, "", NULL, "MISSING_MAILBOX", "MISSING_DOMAIN", TRUE }, 0 }, ++ { NULL, NULL, "", NULL, "", "", TRUE }, ++ { NULL, NULL, "", NULL, "MISSING_MAILBOX", "MISSING_DOMAIN", TRUE }, 0 }, + + /* -> */ + { "", NULL, NULL, +- { NULL, NULL, NULL, "user", "domain", FALSE }, +- { NULL, NULL, NULL, "user", "domain", FALSE }, 0 }, ++ { NULL, NULL, NULL, NULL, "user", "domain", FALSE }, ++ { NULL, NULL, NULL, NULL, "user", "domain", FALSE }, 0 }, + { "<\"user\"@domain>", "", NULL, +- { NULL, NULL, NULL, "user", "domain", FALSE }, +- { NULL, NULL, NULL, "user", "domain", FALSE }, 0 }, ++ { NULL, NULL, NULL, NULL, "user", "domain", FALSE }, ++ { NULL, NULL, NULL, NULL, "user", "domain", FALSE }, 0 }, + { "<\"user name\"@domain>", NULL, NULL, +- { NULL, NULL, NULL, "user name", "domain", FALSE }, +- { NULL, NULL, NULL, "user name", "domain", FALSE }, 0 }, ++ { NULL, NULL, NULL, NULL, "user name", "domain", FALSE }, ++ { NULL, NULL, NULL, NULL, "user name", "domain", FALSE }, 0 }, + { "<\"user@na\\\\me\"@domain>", NULL, NULL, +- { NULL, NULL, NULL, "user@na\\me", "domain", FALSE }, +- { NULL, NULL, NULL, "user@na\\me", "domain", FALSE }, 0 }, ++ { NULL, NULL, NULL, NULL, "user@na\\me", "domain", FALSE }, ++ { NULL, NULL, NULL, NULL, "user@na\\me", "domain", FALSE }, 0 }, + { "<\"user\\\"name\"@domain>", NULL, NULL, +- { NULL, NULL, NULL, "user\"name", "domain", FALSE }, +- { NULL, NULL, NULL, "user\"name", "domain", FALSE }, 0 }, ++ { NULL, NULL, NULL, NULL, "user\"name", "domain", FALSE }, ++ { NULL, NULL, NULL, NULL, "user\"name", "domain", FALSE }, 0 }, + { "<\"\"@domain>", NULL, NULL, +- { NULL, NULL, NULL, "", "domain", FALSE }, +- { NULL, NULL, NULL, "", "domain", FALSE }, 0 }, ++ { NULL, NULL, NULL, NULL, "", "domain", FALSE }, ++ { NULL, NULL, NULL, NULL, "", "domain", FALSE }, 0 }, + { "", NULL, "", +- { NULL, NULL, NULL, "user", "", TRUE }, +- { NULL, NULL, NULL, "user", "MISSING_DOMAIN", TRUE }, 0 }, ++ { NULL, NULL, NULL, NULL, "user", "", TRUE }, ++ { NULL, NULL, NULL, NULL, "user", "MISSING_DOMAIN", TRUE }, 0 }, + { "<@route>", "<@route:\"\">", "", +- { NULL, NULL, "@route", "", "", TRUE }, +- { NULL, NULL, "INVALID_ROUTE", "MISSING_MAILBOX", "MISSING_DOMAIN", TRUE }, 0 }, ++ { NULL, NULL, NULL, "@route", "", "", TRUE }, ++ { NULL, NULL, NULL, "INVALID_ROUTE", "MISSING_MAILBOX", "MISSING_DOMAIN", TRUE }, 0 }, + + /* user@domain (Display Name) -> "Display Name" */ + { "user@domain (DisplayName)", "DisplayName ", NULL, +- { NULL, "DisplayName", NULL, "user", "domain", FALSE }, +- { NULL, "DisplayName", NULL, "user", "domain", FALSE }, 0 }, ++ { NULL, NULL, "DisplayName", NULL, "user", "domain", FALSE }, ++ { NULL, NULL, "DisplayName", NULL, "user", "domain", FALSE }, 0 }, + { "user@domain (Display Name)", "\"Display Name\" ", NULL, +- { NULL, "Display Name", NULL, "user", "domain", FALSE }, +- { NULL, "Display Name", NULL, "user", "domain", FALSE }, 0 }, ++ { NULL, NULL, "Display Name", NULL, "user", "domain", FALSE }, ++ { NULL, NULL, "Display Name", NULL, "user", "domain", FALSE }, 0 }, + { "user@domain (Display\"Name)", "\"Display\\\"Name\" ", NULL, +- { NULL, "Display\"Name", NULL, "user", "domain", FALSE }, +- { NULL, "Display\"Name", NULL, "user", "domain", FALSE }, 0 }, ++ { NULL, NULL, "Display\"Name", NULL, "user", "domain", FALSE }, ++ { NULL, NULL, "Display\"Name", NULL, "user", "domain", FALSE }, 0 }, + { "user (Display Name)", "\"Display Name\" ", "\"Display Name\" ", +- { NULL, "Display Name", NULL, "user", "", TRUE }, +- { NULL, "Display Name", NULL, "user", "MISSING_DOMAIN", TRUE }, 0 }, ++ { NULL, NULL, "Display Name", NULL, "user", "", TRUE }, ++ { NULL, NULL, "Display Name", NULL, "user", "MISSING_DOMAIN", TRUE }, 0 }, + { "@domain (Display Name)", "\"Display Name\" <\"\"@domain>", "\"Display Name\" ", +- { NULL, "Display Name", NULL, "", "domain", TRUE }, +- { NULL, "Display Name", NULL, "MISSING_MAILBOX", "domain", TRUE }, 0 }, ++ { NULL, NULL, "Display Name", NULL, "", "domain", TRUE }, ++ { NULL, NULL, "Display Name", NULL, "MISSING_MAILBOX", "domain", TRUE }, 0 }, + { "user@domain ()", "", NULL, +- { NULL, NULL, NULL, "user", "domain", FALSE }, +- { NULL, NULL, NULL, "user", "domain", FALSE }, 0 }, ++ { NULL, NULL, NULL, NULL, "user", "domain", FALSE }, ++ { NULL, NULL, NULL, NULL, "user", "domain", FALSE }, 0 }, + + /* Display Name -> "Display Name" */ + { "DisplayName ", NULL, NULL, +- { NULL, "DisplayName", NULL, "user", "domain", FALSE }, +- { NULL, "DisplayName", NULL, "user", "domain", FALSE }, 0 }, ++ { NULL, NULL, "DisplayName", NULL, "user", "domain", FALSE }, ++ { NULL, NULL, "DisplayName", NULL, "user", "domain", FALSE }, 0 }, + { "Display Name ", "\"Display Name\" ", NULL, +- { NULL, "Display Name", NULL, "user", "domain", FALSE }, +- { NULL, "Display Name", NULL, "user", "domain", FALSE }, 0 }, ++ { NULL, NULL, "Display Name", NULL, "user", "domain", FALSE }, ++ { NULL, NULL, "Display Name", NULL, "user", "domain", FALSE }, 0 }, + { "\"Display Name\" ", NULL, NULL, +- { NULL, "Display Name", NULL, "user", "domain", FALSE }, +- { NULL, "Display Name", NULL, "user", "domain", FALSE }, 0 }, ++ { NULL, NULL, "Display Name", NULL, "user", "domain", FALSE }, ++ { NULL, NULL, "Display Name", NULL, "user", "domain", FALSE }, 0 }, + { "\"Display\\\"Name\" ", NULL, NULL, +- { NULL, "Display\"Name", NULL, "user", "domain", FALSE }, +- { NULL, "Display\"Name", NULL, "user", "domain", FALSE }, 0 }, ++ { NULL, NULL, "Display\"Name", NULL, "user", "domain", FALSE }, ++ { NULL, NULL, "Display\"Name", NULL, "user", "domain", FALSE }, 0 }, + { "Display Name ", "\"Display Name\" ", "\"Display Name\" ", +- { NULL, "Display Name", NULL, "user", "", TRUE }, +- { NULL, "Display Name", NULL, "user", "MISSING_DOMAIN", TRUE }, 0 }, ++ { NULL, NULL, "Display Name", NULL, "user", "", TRUE }, ++ { NULL, NULL, "Display Name", NULL, "user", "MISSING_DOMAIN", TRUE }, 0 }, + { "\"\" ", "", NULL, +- { NULL, NULL, NULL, "user", "domain", FALSE }, +- { NULL, NULL, NULL, "user", "domain", FALSE }, 0 }, ++ { NULL, NULL, NULL, NULL, "user", "domain", FALSE }, ++ { NULL, NULL, NULL, NULL, "user", "domain", FALSE }, 0 }, + + /* <@route:user@domain> -> <@route:user@domain> */ + { "<@route:user@domain>", NULL, NULL, +- { NULL, NULL, "@route", "user", "domain", FALSE }, +- { NULL, NULL, "@route", "user", "domain", FALSE }, 0 }, ++ { NULL, NULL, NULL, "@route", "user", "domain", FALSE }, ++ { NULL, NULL, NULL, "@route", "user", "domain", FALSE }, 0 }, + { "<@route,@route2:user@domain>", NULL, NULL, +- { NULL, NULL, "@route,@route2", "user", "domain", FALSE }, +- { NULL, NULL, "@route,@route2", "user", "domain", FALSE }, 0 }, ++ { NULL, NULL, NULL, "@route,@route2", "user", "domain", FALSE }, ++ { NULL, NULL, NULL, "@route,@route2", "user", "domain", FALSE }, 0 }, + { "<@route@route2:user@domain>", "<@route,@route2:user@domain>", NULL, +- { NULL, NULL, "@route,@route2", "user", "domain", FALSE }, +- { NULL, NULL, "@route,@route2", "user", "domain", FALSE }, 0 }, ++ { NULL, NULL, NULL, "@route,@route2", "user", "domain", FALSE }, ++ { NULL, NULL, NULL, "@route,@route2", "user", "domain", FALSE }, 0 }, + { "<@route@route2:user>", "<@route,@route2:user>", "<@route,@route2:user@MISSING_DOMAIN>", +- { NULL, NULL, "@route,@route2", "user", "", TRUE }, +- { NULL, NULL, "@route,@route2", "user", "MISSING_DOMAIN", TRUE }, 0 }, ++ { NULL, NULL, NULL, "@route,@route2", "user", "", TRUE }, ++ { NULL, NULL, NULL, "@route,@route2", "user", "MISSING_DOMAIN", TRUE }, 0 }, + { "<@route@route2:\"\"@domain>", "<@route,@route2:\"\"@domain>", NULL, +- { NULL, NULL, "@route,@route2", "", "domain", FALSE }, +- { NULL, NULL, "@route,@route2", "", "domain", FALSE }, 0 }, ++ { NULL, NULL, NULL, "@route,@route2", "", "domain", FALSE }, ++ { NULL, NULL, NULL, "@route,@route2", "", "domain", FALSE }, 0 }, + + /* Display Name <@route:user@domain> -> + "Display Name" <@route:user@domain> */ + { "Display Name <@route:user@domain>", "\"Display Name\" <@route:user@domain>", NULL, +- { NULL, "Display Name", "@route", "user", "domain", FALSE }, +- { NULL, "Display Name", "@route", "user", "domain", FALSE }, 0 }, ++ { NULL, NULL, "Display Name", "@route", "user", "domain", FALSE }, ++ { NULL, NULL, "Display Name", "@route", "user", "domain", FALSE }, 0 }, + { "Display Name <@route,@route2:user@domain>", "\"Display Name\" <@route,@route2:user@domain>", NULL, +- { NULL, "Display Name", "@route,@route2", "user", "domain", FALSE }, +- { NULL, "Display Name", "@route,@route2", "user", "domain", FALSE }, 0 }, ++ { NULL, NULL, "Display Name", "@route,@route2", "user", "domain", FALSE }, ++ { NULL, NULL, "Display Name", "@route,@route2", "user", "domain", FALSE }, 0 }, + { "Display Name <@route@route2:user@domain>", "\"Display Name\" <@route,@route2:user@domain>", NULL, +- { NULL, "Display Name", "@route,@route2", "user", "domain", FALSE }, +- { NULL, "Display Name", "@route,@route2", "user", "domain", FALSE }, 0 }, ++ { NULL, NULL, "Display Name", "@route,@route2", "user", "domain", FALSE }, ++ { NULL, NULL, "Display Name", "@route,@route2", "user", "domain", FALSE }, 0 }, + { "Display Name <@route@route2:user>", "\"Display Name\" <@route,@route2:user>", "\"Display Name\" <@route,@route2:user@MISSING_DOMAIN>", +- { NULL, "Display Name", "@route,@route2", "user", "", TRUE }, +- { NULL, "Display Name", "@route,@route2", "user", "MISSING_DOMAIN", TRUE }, 0 }, ++ { NULL, NULL, "Display Name", "@route,@route2", "user", "", TRUE }, ++ { NULL, NULL, "Display Name", "@route,@route2", "user", "MISSING_DOMAIN", TRUE }, 0 }, + { "Display Name <@route@route2:\"\"@domain>", "\"Display Name\" <@route,@route2:\"\"@domain>", NULL, +- { NULL, "Display Name", "@route,@route2", "", "domain", FALSE }, +- { NULL, "Display Name", "@route,@route2", "", "domain", FALSE }, 0 }, ++ { NULL, NULL, "Display Name", "@route,@route2", "", "domain", FALSE }, ++ { NULL, NULL, "Display Name", "@route,@route2", "", "domain", FALSE }, 0 }, + + /* other tests: */ + { "\"foo: ;,\" ", NULL, NULL, +- { NULL, "foo: ;,", NULL, "user", "domain", FALSE }, +- { NULL, "foo: ;,", NULL, "user", "domain", FALSE }, 0 }, ++ { NULL, NULL, "foo: ;,", NULL, "user", "domain", FALSE }, ++ { NULL, NULL, "foo: ;,", NULL, "user", "domain", FALSE }, 0 }, + { "<>", "", "", +- { NULL, NULL, NULL, "", "", TRUE }, +- { NULL, NULL, NULL, "MISSING_MAILBOX", "MISSING_DOMAIN", TRUE }, 0 }, ++ { NULL, NULL, NULL, NULL, "", "", TRUE }, ++ { NULL, NULL, NULL, NULL, "MISSING_MAILBOX", "MISSING_DOMAIN", TRUE }, 0 }, + { "<@>", "", "", +- { NULL, NULL, NULL, "", "", TRUE }, +- { NULL, NULL, "INVALID_ROUTE", "MISSING_MAILBOX", "MISSING_DOMAIN", TRUE }, 0 }, ++ { NULL, NULL, NULL, NULL, "", "", TRUE }, ++ { NULL, NULL, NULL, "INVALID_ROUTE", "MISSING_MAILBOX", "MISSING_DOMAIN", TRUE }, 0 }, + + /* Test against a out-of-bounds read bug - keep these two tests + together in this same order: */ + { "aaaa@", "", "", +- { NULL, NULL, NULL, "aaaa", "", TRUE }, +- { NULL, NULL, NULL, "aaaa", "MISSING_DOMAIN", TRUE }, 0 }, ++ { NULL, NULL, NULL, NULL, "aaaa", "", TRUE }, ++ { NULL, NULL, NULL, NULL, "aaaa", "MISSING_DOMAIN", TRUE }, 0 }, + { "a(aa", "", "", +- { NULL, NULL, NULL, "", "", TRUE }, +- { NULL, NULL, NULL, "MISSING_MAILBOX", "MISSING_DOMAIN", TRUE }, ++ { NULL, NULL, NULL, NULL, "", "", TRUE }, ++ { NULL, NULL, NULL, NULL, "MISSING_MAILBOX", "MISSING_DOMAIN", TRUE }, + TEST_MESSAGE_ADDRESS_FLAG_SKIP_LIST }, + }; + static struct message_address group_prefix = { +- NULL, NULL, NULL, "group", NULL, FALSE ++ NULL, NULL, NULL, NULL, "group", NULL, FALSE + }; + static struct message_address group_suffix = { +- NULL, NULL, NULL, NULL, NULL, FALSE ++ NULL, NULL, NULL, NULL, NULL, NULL, FALSE + }; + const struct message_address *addr; + string_t *str, *group; +@@ -327,7 +327,7 @@ static void test_message_address_nuls(void) + const unsigned char input[] = + "\"user\0nuls\\\0-esc\"@[domain\0nuls\\\0-esc] (comment\0nuls\\\0-esc)"; + const struct message_address output = { +- NULL, "comment\xEF\xBF\xBDnuls\\\xEF\xBF\xBD-esc", NULL, ++ NULL, NULL, "comment\xEF\xBF\xBDnuls\\\xEF\xBF\xBD-esc", NULL, + "user\xEF\xBF\xBDnuls\\\xEF\xBF\xBD-esc", + "[domain\xEF\xBF\xBDnuls\\\xEF\xBF\xBD-esc]", FALSE + }; +@@ -345,7 +345,7 @@ static void test_message_address_nuls_display_name(void) + const unsigned char input[] = + "\"displayname\0nuls\\\0-esc\" <\"user\0nuls\\\0-esc\"@[domain\0nuls\\\0-esc]>"; + const struct message_address output = { +- NULL, "displayname\xEF\xBF\xBDnuls\\\xEF\xBF\xBD-esc", NULL, ++ NULL, NULL, "displayname\xEF\xBF\xBDnuls\\\xEF\xBF\xBD-esc", NULL, + "user\xEF\xBF\xBDnuls\\\xEF\xBF\xBD-esc", + "[domain\xEF\xBF\xBDnuls\\\xEF\xBF\xBD-esc]", FALSE + }; +@@ -369,7 +369,7 @@ static void test_message_address_non_strict_dots(void) + }; + const struct message_address *addr; + struct message_address output = { +- NULL, NULL, NULL, "local-part", ++ NULL, NULL, NULL, NULL, "local-part", + "example.com", FALSE + }; + +@@ -421,29 +421,29 @@ static void test_message_address_path(void) + struct message_address addr; + } tests[] = { + { "<>", NULL, +- { NULL, NULL, NULL, NULL, NULL, FALSE } }, ++ { NULL, NULL, NULL, NULL, NULL, NULL, FALSE } }, + { " < > ", "<>", +- { NULL, NULL, NULL, NULL, NULL, FALSE } }, ++ { NULL, NULL, NULL, NULL, NULL, NULL, FALSE } }, + { "", NULL, +- { NULL, NULL, NULL, "user", "domain", FALSE } }, ++ { NULL, NULL, NULL, NULL, "user", "domain", FALSE } }, + { " ", "", +- { NULL, NULL, NULL, "user", "domain", FALSE } }, ++ { NULL, NULL, NULL, NULL, "user", "domain", FALSE } }, + { "user@domain", "", +- { NULL, NULL, NULL, "user", "domain", FALSE } }, ++ { NULL, NULL, NULL, NULL, "user", "domain", FALSE } }, + { " user@domain ", "", +- { NULL, NULL, NULL, "user", "domain", FALSE } }, ++ { NULL, NULL, NULL, NULL, "user", "domain", FALSE } }, + { "<\"user\"@domain>", "", +- { NULL, NULL, NULL, "user", "domain", FALSE } }, ++ { NULL, NULL, NULL, NULL, "user", "domain", FALSE } }, + { "<\"user name\"@domain>", NULL, +- { NULL, NULL, NULL, "user name", "domain", FALSE } }, ++ { NULL, NULL, NULL, NULL, "user name", "domain", FALSE } }, + { "<\"user@na\\\\me\"@domain>", NULL, +- { NULL, NULL, NULL, "user@na\\me", "domain", FALSE } }, ++ { NULL, NULL, NULL, NULL, "user@na\\me", "domain", FALSE } }, + { "<\"user\\\"name\"@domain>", NULL, +- { NULL, NULL, NULL, "user\"name", "domain", FALSE } }, ++ { NULL, NULL, NULL, NULL, "user\"name", "domain", FALSE } }, + { "<\"\"@domain>", NULL, +- { NULL, NULL, NULL, "", "domain", FALSE } }, ++ { NULL, NULL, NULL, NULL, "", "domain", FALSE } }, + { "<@source", "<>", +- { NULL, NULL, NULL, NULL, NULL, TRUE } }, ++ { NULL, NULL, NULL, NULL, NULL, NULL, TRUE } }, + }; + const struct message_address *addr; + string_t *str; + +From da61d20311da34f22944c6111a0b97ea2a1f8a47 Mon Sep 17 00:00:00 2001 +From: Timo Sirainen +Date: Tue, 30 Jan 2024 22:17:38 +0200 +Subject: [PATCH 5/6] lib-mail: Add message_address_parse_full() and struct + message_address_list + +--- + src/lib-mail/message-address.c | 37 +++++++++++++--------- + src/lib-mail/message-address.h | 10 ++++++ + src/lib-mail/test-message-address.c | 48 +++++++++++++++++++++++++---- + 3 files changed, 75 insertions(+), 20 deletions(-) + +diff --git a/src/lib-mail/message-address.c b/src/lib-mail/message-address.c +index 9d192799468..ae37014079a 100644 +--- a/src/lib-mail/message-address.c ++++ b/src/lib-mail/message-address.c +@@ -13,7 +13,8 @@ struct message_address_parser_context { + pool_t pool; + struct rfc822_parser_context parser; + +- struct message_address *first_addr, *last_addr, addr; ++ struct message_address addr; ++ struct message_address_list addr_list; + string_t *str; + + bool fill_missing, non_strict_dots; +@@ -28,7 +29,7 @@ static void add_address(struct message_address_parser_context *ctx) + memcpy(addr, &ctx->addr, sizeof(ctx->addr)); + i_zero(&ctx->addr); + +- DLLIST2_APPEND(&ctx->first_addr, &ctx->last_addr, addr); ++ DLLIST2_APPEND(&ctx->addr_list.head, &ctx->addr_list.tail, addr); + } + + /* quote with "" and escape all '\', '"' and "'" characters if need */ +@@ -439,10 +440,11 @@ static int parse_path(struct message_address_parser_context *ctx) + return ret; + } + +-static struct message_address * ++static void + message_address_parse_real(pool_t pool, const unsigned char *data, size_t size, + unsigned int max_addresses, +- enum message_address_parse_flags flags) ++ enum message_address_parse_flags flags, ++ struct message_address_list *list_r) + { + struct message_address_parser_context ctx; + +@@ -461,7 +463,7 @@ message_address_parse_real(pool_t pool, const unsigned char *data, size_t size, + (void)parse_address_list(&ctx, max_addresses); + } + rfc822_parser_deinit(&ctx.parser); +- return ctx.first_addr; ++ *list_r = ctx.addr_list; + } + + static int +@@ -481,7 +483,7 @@ message_address_parse_path_real(pool_t pool, const unsigned char *data, + ret = parse_path(&ctx); + + rfc822_parser_deinit(&ctx.parser); +- *addr_r = ctx.first_addr; ++ *addr_r = ctx.addr_list.head; + return (ret < 0 ? -1 : 0); + } + +@@ -490,17 +492,24 @@ message_address_parse(pool_t pool, const unsigned char *data, size_t size, + unsigned int max_addresses, + enum message_address_parse_flags flags) + { +- struct message_address *addr; ++ struct message_address_list list; ++ message_address_parse_full(pool, data, size, max_addresses, flags, ++ &list); ++ return list.head; ++} + ++void message_address_parse_full(pool_t pool, const unsigned char *data, ++ size_t size, unsigned int max_addresses, ++ enum message_address_parse_flags flags, ++ struct message_address_list *list_r) ++{ + if (pool->datastack_pool) { +- return message_address_parse_real(pool, data, size, +- max_addresses, flags); +- } +- T_BEGIN { +- addr = message_address_parse_real(pool, data, size, +- max_addresses, flags); ++ message_address_parse_real(pool, data, size, ++ max_addresses, flags, list_r); ++ } else T_BEGIN { ++ message_address_parse_real(pool, data, size, ++ max_addresses, flags, list_r); + } T_END; +- return addr; + } + + int message_address_parse_path(pool_t pool, const unsigned char *data, +diff --git a/src/lib-mail/message-address.h b/src/lib-mail/message-address.h +index 85cff3dcc6f..224f7a75605 100644 +--- a/src/lib-mail/message-address.h ++++ b/src/lib-mail/message-address.h +@@ -31,12 +31,22 @@ struct message_address { + bool invalid_syntax; + }; + ++struct message_address_list { ++ struct message_address *head, *tail; ++}; ++ + /* Parse message addresses from given data. Note that giving an empty string + will return NULL since there are no addresses. */ + struct message_address * + message_address_parse(pool_t pool, const unsigned char *data, size_t size, + unsigned int max_addresses, + enum message_address_parse_flags flags); ++/* Same as message_address_parse(), but return message_address_list containing ++ both the first and the last address in the linked list. */ ++void message_address_parse_full(pool_t pool, const unsigned char *data, ++ size_t size, unsigned int max_addresses, ++ enum message_address_parse_flags flags, ++ struct message_address_list *list_r); + + /* Parse RFC 5322 "path" (Return-Path header) from given data. Returns -1 if + the path is invalid and 0 otherwise. +diff --git a/src/lib-mail/test-message-address.c b/src/lib-mail/test-message-address.c +index 261cbfba70a..54aa9a83101 100644 +--- a/src/lib-mail/test-message-address.c ++++ b/src/lib-mail/test-message-address.c +@@ -19,8 +19,9 @@ static bool cmp_addr(const struct message_address *a1, + a1->invalid_syntax == a2->invalid_syntax; + } + +-static const struct message_address * +-test_parse_address(const char *input, bool fill_missing) ++static void ++test_parse_address_full(const char *input, bool fill_missing, ++ struct message_address_list *list_r) + { + const enum message_address_parse_flags flags = + fill_missing ? MESSAGE_ADDRESS_PARSE_FLAG_FILL_MISSING : 0; +@@ -28,11 +29,18 @@ test_parse_address(const char *input, bool fill_missing) + if there's any out-of-bounds access */ + size_t input_len = strlen(input); + unsigned char *input_dup = i_memdup(input, input_len); +- const struct message_address *addr = +- message_address_parse(pool_datastack_create(), +- input_dup, input_len, UINT_MAX, flags); ++ message_address_parse_full(pool_datastack_create(), ++ input_dup, input_len, UINT_MAX, flags, ++ list_r); + i_free(input_dup); +- return addr; ++} ++ ++static const struct message_address * ++test_parse_address(const char *input, bool fill_missing) ++{ ++ struct message_address_list list; ++ test_parse_address_full(input, fill_missing, &list); ++ return list.head; + } + + static void test_message_address(void) +@@ -322,6 +330,33 @@ static void test_message_address(void) + test_end(); + } + ++static void test_message_address_list(void) ++{ ++ test_begin("message address list"); ++ ++ const char *test_input = ++ "user1@example1.com, user2@example2.com, user3@example3.com"; ++ const struct message_address wanted_addrs[] = { ++ { NULL, NULL, NULL, NULL, "user1", "example1.com", FALSE }, ++ { NULL, NULL, NULL, NULL, "user2", "example2.com", FALSE }, ++ { NULL, NULL, NULL, NULL, "user3", "example3.com", FALSE }, ++ }; ++ ++ struct message_address_list list; ++ struct message_address *addr, *scanned_last_addr; ++ test_parse_address_full(test_input, FALSE, &list); ++ addr = list.head; ++ for (unsigned int i = 0; i < N_ELEMENTS(wanted_addrs); i++) { ++ test_assert_idx(cmp_addr(addr, &wanted_addrs[i]), i); ++ scanned_last_addr = addr; ++ addr = addr->next; ++ } ++ test_assert(list.tail == scanned_last_addr); ++ test_assert(addr == NULL); ++ ++ test_end(); ++} ++ + static void test_message_address_nuls(void) + { + const unsigned char input[] = +@@ -521,6 +556,7 @@ int main(void) + { + static void (*const test_functions[])(void) = { + test_message_address, ++ test_message_address_list, + test_message_address_nuls, + test_message_address_nuls_display_name, + test_message_address_non_strict_dots, + +From 1481c04f02df7647f520df65d63df7626bf0ee32 Mon Sep 17 00:00:00 2001 +From: Timo Sirainen +Date: Fri, 9 Feb 2024 00:57:12 +0200 +Subject: [PATCH 6/6] lib-mail, lib-imap: Optimize parsing large number of + address headers + +Every header was appended to a linked list by walking through the whole +list, causing excessive CPU usage when the list became large enough. +Fixed by changing struct message_part_envelope to use struct +message_address_list, which stores also linked list tail pointers. This +allows quickly appending to the end of the linked list. +--- + src/lib-imap/imap-envelope.c | 27 ++++++++++------------- + src/lib-mail/message-part-data.c | 17 +++++++------- + src/lib-mail/message-part-data.h | 6 +++-- + src/lib-storage/index/index-search-mime.c | 4 ++-- + 4 files changed, 27 insertions(+), 27 deletions(-) + +diff --git a/src/lib-imap/imap-envelope.c b/src/lib-imap/imap-envelope.c +index 1312eae2ff3..da3177025a5 100644 +--- a/src/lib-imap/imap-envelope.c ++++ b/src/lib-imap/imap-envelope.c +@@ -67,17 +67,17 @@ void imap_envelope_write(struct message_part_envelope *data, + } + + str_append_c(str, ' '); +- imap_write_address(str, data->from); ++ imap_write_address(str, data->from.head); + str_append_c(str, ' '); +- imap_write_address(str, NVL(data->sender, data->from)); ++ imap_write_address(str, NVL(data->sender.head, data->from.head)); + str_append_c(str, ' '); +- imap_write_address(str, NVL(data->reply_to, data->from)); ++ imap_write_address(str, NVL(data->reply_to.head, data->from.head)); + str_append_c(str, ' '); +- imap_write_address(str, data->to); ++ imap_write_address(str, data->to.head); + str_append_c(str, ' '); +- imap_write_address(str, data->cc); ++ imap_write_address(str, data->cc.head); + str_append_c(str, ' '); +- imap_write_address(str, data->bcc); ++ imap_write_address(str, data->bcc.head); + + str_append_c(str, ' '); + imap_append_nstring_nolf(str, data->in_reply_to); +@@ -126,28 +126,25 @@ imap_envelope_parse_address(const struct imap_arg *arg, + + static bool + imap_envelope_parse_addresses(const struct imap_arg *arg, +- pool_t pool, struct message_address **addrs_r) ++ pool_t pool, struct message_address_list *addrs_r) + { +- struct message_address *first, *last, *addr; ++ struct message_address *addr; + const struct imap_arg *list_args; + +- if (arg->type == IMAP_ARG_NIL) { +- *addrs_r = NULL; ++ i_zero(addrs_r); ++ if (arg->type == IMAP_ARG_NIL) + return TRUE; +- } + + if (!imap_arg_get_list(arg, &list_args)) + return FALSE; + +- first = last = addr = NULL; ++ addr = NULL; + for (; !IMAP_ARG_IS_EOL(list_args); list_args++) { + if (!imap_envelope_parse_address + (list_args, pool, &addr)) + return FALSE; +- DLLIST2_APPEND(&first, &last, addr); ++ DLLIST2_APPEND(&addrs_r->head, &addrs_r->tail, addr); + } +- +- *addrs_r = first; + return TRUE; + } + +diff --git a/src/lib-mail/message-part-data.c b/src/lib-mail/message-part-data.c +index a5771f87e2e..25019ab432d 100644 +--- a/src/lib-mail/message-part-data.c ++++ b/src/lib-mail/message-part-data.c +@@ -4,6 +4,7 @@ + #include "str.h" + #include "wildcard-match.h" + #include "array.h" ++#include "llist.h" + #include "rfc822-parser.h" + #include "rfc2231-parser.h" + #include "message-address.h" +@@ -176,7 +177,7 @@ void message_part_envelope_parse_from_header(pool_t pool, + { + struct message_part_envelope *d; + enum envelope_field field; +- struct message_address **addr_p, *addr; ++ struct message_address_list *addr_p, new_addr; + const char **str_p; + + if (*data == NULL) { +@@ -234,18 +235,18 @@ void message_part_envelope_parse_from_header(pool_t pool, + } + + if (addr_p != NULL) { +- addr = message_address_parse(pool, hdr->full_value, +- hdr->full_value_len, +- UINT_MAX, +- MESSAGE_ADDRESS_PARSE_FLAG_FILL_MISSING); ++ message_address_parse_full(pool, hdr->full_value, ++ hdr->full_value_len, ++ UINT_MAX, ++ MESSAGE_ADDRESS_PARSE_FLAG_FILL_MISSING, ++ &new_addr); + /* Merge multiple headers the same as if they were comma + separated in a single line. This is better from security + point of view, because attacker could intentionally write + addresses in a way that e.g. the first From header is + validated while MUA only shows the second From header. */ +- while (*addr_p != NULL) +- addr_p = &(*addr_p)->next; +- *addr_p = addr; ++ DLLIST2_JOIN(&addr_p->head, &addr_p->tail, ++ &new_addr.head, &new_addr.tail); + } else if (str_p != NULL) { + *str_p = message_header_strdup(pool, hdr->full_value, + hdr->full_value_len); +diff --git a/src/lib-mail/message-part-data.h b/src/lib-mail/message-part-data.h +index 5ff9ffe1bc6..7ec878de68e 100644 +--- a/src/lib-mail/message-part-data.h ++++ b/src/lib-mail/message-part-data.h +@@ -2,6 +2,7 @@ + #define MESSAGE_PART_DATA_H + + #include "message-part.h" ++#include "message-address.h" + + #define MESSAGE_PART_DEFAULT_CHARSET "us-ascii" + +@@ -14,8 +15,9 @@ struct message_part_param { + + struct message_part_envelope { + const char *date, *subject; +- struct message_address *from, *sender, *reply_to; +- struct message_address *to, *cc, *bcc; ++ ++ struct message_address_list from, sender, reply_to; ++ struct message_address_list to, cc, bcc; + + const char *in_reply_to, *message_id; + }; +diff --git a/src/lib-storage/index/index-search-mime.c b/src/lib-storage/index/index-search-mime.c +index da7e5e17092..3328ce98af1 100644 +--- a/src/lib-storage/index/index-search-mime.c ++++ b/src/lib-storage/index/index-search-mime.c +@@ -205,7 +205,7 @@ seach_arg_mime_envelope_address_match( + enum mail_search_mime_arg_type type, const char *key, + const struct message_part_envelope *envelope) + { +- const struct message_address *addrs; ++ struct message_address_list addrs; + string_t *addrs_enc; + + if (envelope == NULL) +@@ -239,7 +239,7 @@ seach_arg_mime_envelope_address_match( + probably be normalized directly in the struct message_address. */ + + addrs_enc = t_str_new(128); +- message_address_write(addrs_enc, addrs); ++ message_address_write(addrs_enc, addrs.head); + return (strstr(str_c(addrs_enc), key) != NULL ? 1 : 0); + } + diff --git a/SOURCES/dovecot-2.3.21.1-CVE-2024-23185.patch b/SOURCES/dovecot-2.3.21.1-CVE-2024-23185.patch new file mode 100644 index 0000000..794425a --- /dev/null +++ b/SOURCES/dovecot-2.3.21.1-CVE-2024-23185.patch @@ -0,0 +1,493 @@ +From f020e139c519121d9630a966310ea8e100ee33b7 Mon Sep 17 00:00:00 2001 +From: Marco Bettini +Date: Fri, 12 Apr 2024 15:06:43 +0000 +Subject: [PATCH 1/2] lib-mail: message-header-parser - Limit header block to + 10MB by default + +--- + src/lib-mail/message-header-parser.c | 48 ++++++++++++---- + src/lib-mail/message-header-parser.h | 10 ++++ + src/lib-mail/test-message-header-parser.c | 67 +++++++++++++++++++++++ + 3 files changed, 114 insertions(+), 11 deletions(-) + +diff --git a/src/lib-mail/message-header-parser.c b/src/lib-mail/message-header-parser.c +index c5026f1bb7..5e020bbeb3 100644 +--- a/src/lib-mail/message-header-parser.c ++++ b/src/lib-mail/message-header-parser.c +@@ -21,6 +21,9 @@ struct message_header_parser_ctx { + string_t *name; + buffer_t *value_buf; + ++ size_t header_block_max_size; ++ size_t header_block_total_size; ++ + enum message_header_parser_flags flags; + bool skip_line:1; + bool has_nuls:1; +@@ -38,6 +41,7 @@ message_parse_header_init(struct istream *input, struct message_size *hdr_size, + ctx->name = str_new(default_pool, 128); + ctx->flags = flags; + ctx->value_buf = buffer_create_dynamic(default_pool, 4096); ++ ctx->header_block_max_size = MESSAGE_HEADER_BLOCK_DEFAULT_MAX_SIZE; + i_stream_ref(input); + + if (hdr_size != NULL) +@@ -45,6 +49,21 @@ message_parse_header_init(struct istream *input, struct message_size *hdr_size, + return ctx; + } + ++void ++message_parse_header_set_limit(struct message_header_parser_ctx *parser, ++ size_t header_block_max_size) ++{ ++ parser->header_block_max_size = header_block_max_size; ++} ++ ++void ++message_parse_header_lower_limit(struct message_header_parser_ctx *parser, ++ size_t header_block_max_size) ++{ ++ if (header_block_max_size < parser->header_block_max_size) ++ message_parse_header_set_limit(parser, header_block_max_size); ++} ++ + void message_parse_header_deinit(struct message_header_parser_ctx **_ctx) + { + struct message_header_parser_ctx *ctx = *_ctx; +@@ -77,6 +96,7 @@ int message_parse_header_next(struct message_header_parser_ctx *ctx, + /* new header line */ + line->name_offset = ctx->input->v_offset; + colon_pos = UINT_MAX; ++ ctx->header_block_total_size += ctx->value_buf->used; + buffer_set_used_size(ctx->value_buf, 0); + } + +@@ -342,33 +362,39 @@ int message_parse_header_next(struct message_header_parser_ctx *ctx, + } + } + ++ line->value_len = I_MIN(line->value_len, ctx->header_block_max_size); ++ size_t line_value_size = line->value_len; ++ size_t header_total_used = ctx->header_block_total_size + ctx->value_buf->used; ++ size_t line_available = ctx->header_block_max_size <= header_total_used ? 0 : ++ ctx->header_block_max_size - header_total_used; ++ line_value_size = I_MIN(line_value_size, line_available); ++ + if (!line->continued) { + /* first header line. make a copy of the line since we can't + really trust input stream not to lose it. */ +- buffer_append(ctx->value_buf, line->value, line->value_len); ++ buffer_append(ctx->value_buf, line->value, line_value_size); + line->value = line->full_value = ctx->value_buf->data; +- line->full_value_len = line->value_len; ++ line->full_value_len = line->value_len = line_value_size; + } else if (line->use_full_value) { + /* continue saving the full value. */ + if (last_no_newline) { + /* line is longer than fit into our buffer, so we + were forced to break it into multiple + message_header_lines */ +- } else { +- if (last_crlf) ++ } else if (line_value_size > 1) { ++ if (last_crlf && line_value_size > 2) + buffer_append_c(ctx->value_buf, '\r'); + buffer_append_c(ctx->value_buf, '\n'); + } + if ((ctx->flags & MESSAGE_HEADER_PARSER_FLAG_CLEAN_ONELINE) != 0 && + line->value_len > 0 && line->value[0] != ' ' && +- IS_LWSP(line->value[0])) { ++ IS_LWSP(line->value[0]) && ++ line_value_size > 0) { + buffer_append_c(ctx->value_buf, ' '); +- buffer_append(ctx->value_buf, +- line->value + 1, line->value_len - 1); +- } else { +- buffer_append(ctx->value_buf, +- line->value, line->value_len); +- } ++ buffer_append(ctx->value_buf, line->value + 1, line_value_size - 1); ++ } else ++ buffer_append(ctx->value_buf, line->value, line_value_size); ++ + line->full_value = ctx->value_buf->data; + line->full_value_len = ctx->value_buf->used; + } else { +diff --git a/src/lib-mail/message-header-parser.h b/src/lib-mail/message-header-parser.h +index ce0825c8e5..43cf95e56a 100644 +--- a/src/lib-mail/message-header-parser.h ++++ b/src/lib-mail/message-header-parser.h +@@ -1,6 +1,9 @@ + #ifndef MESSAGE_HEADER_PARSER_H + #define MESSAGE_HEADER_PARSER_H + ++/* This can be overridden by message_parse_header_set_limit() */ ++#define MESSAGE_HEADER_BLOCK_DEFAULT_MAX_SIZE ((size_t) 10 * 1024*1024) ++ + #define IS_LWSP(c) \ + ((c) == ' ' || (c) == '\t') + +@@ -48,6 +51,13 @@ message_parse_header_init(struct istream *input, struct message_size *hdr_size, + enum message_header_parser_flags flags) ATTR_NULL(2); + void message_parse_header_deinit(struct message_header_parser_ctx **ctx); + ++void ++message_parse_header_set_limit(struct message_header_parser_ctx *parser, ++ size_t header_block_max_size); ++void ++message_parse_header_lower_limit(struct message_header_parser_ctx *parser, ++ size_t header_block_max_size); ++ + /* Read and return next header line. Returns 1 if header is returned, 0 if + input stream is non-blocking and more data needs to be read, -1 when all is + done or error occurred (see stream's error status). */ +diff --git a/src/lib-mail/test-message-header-parser.c b/src/lib-mail/test-message-header-parser.c +index 700d3413f1..93d8842002 100644 +--- a/src/lib-mail/test-message-header-parser.c ++++ b/src/lib-mail/test-message-header-parser.c +@@ -463,6 +463,71 @@ static void test_message_header_parser_extra_crlf_in_name(void) + test_end(); + } + ++#define assert_parsed_field(line, expected, actual, len) STMT_START { \ ++ test_assert_idx(memcmp(expected, actual, strlen(expected)) == 0, line); \ ++ test_assert_cmp_idx(strlen(expected), ==, len, line); \ ++} STMT_END ++ ++/* NOTE: implicit variables: (parser, hdr) */ ++#define assert_parse_line(line, exp_name, exp_value, exp_full) STMT_START { \ ++ test_assert_idx(message_parse_header_next(parser, &hdr) > 0, line); \ ++ assert_parsed_field(line, exp_name, hdr->name, hdr->name_len); \ ++ assert_parsed_field(line, exp_value, hdr->value, hdr->value_len); \ ++ assert_parsed_field(line, exp_full, hdr->full_value, hdr->full_value_len); \ ++ if (hdr->continues) hdr->use_full_value = TRUE; \ ++} STMT_END ++ ++static const unsigned char test_message_header_truncation_input[] = ++ /*01*/ "header1: this is short\n" ++ /*02*/ "header2: this is multiline\n" ++ /*03*/ " and long 343638404244464850525456586062\n" ++ /*04*/ " 64666870727476788082848688909294969800\n" ++ /*05*/ " 02040608101214161820222426283032343638\n" ++ /*06*/ "header3: I should not appear at all\n" ++ /*07*/ "\n"; ++ ++static void test_message_header_truncation_clean_oneline(void) ++{ ++ test_begin("message header parser truncate + CLEAN_ONELINE flag"); ++ struct message_header_line *hdr = NULL; ++ struct istream *input = test_istream_create_data(test_message_header_truncation_input, sizeof(test_message_header_truncation_input)); ++ struct message_header_parser_ctx *parser = message_parse_header_init(input, NULL, MESSAGE_HEADER_PARSER_FLAG_CLEAN_ONELINE); ++ message_parse_header_set_limit(parser, 96); ++ ++ assert_parse_line( 1, "header1", "this is short", "this is short"); ++ assert_parse_line( 2, "header2", "this is multiline", "this is multiline"); ++ assert_parse_line( 3, "header2", " and long 343638404244464850525456586062", "this is multiline and long 343638404244464850525456586062"); ++ assert_parse_line( 4, "header2", " 64666870727476788082848688909294969800", "this is multiline and long 343638404244464850525456586062 6466687072747678808284868"); ++ assert_parse_line( 5, "header2", " 02040608101214161820222426283032343638", "this is multiline and long 343638404244464850525456586062 6466687072747678808284868"); ++ assert_parse_line( 6, "header3", "", ""); ++ test_assert(message_parse_header_next(parser, &hdr) > 0 && hdr->eoh); ++ ++ message_parse_header_deinit(&parser); ++ i_stream_unref(&input); ++ test_end(); ++} ++ ++static void test_message_header_truncation_flag0(void) ++{ ++ test_begin("message header parser truncate + NO flags"); ++ struct message_header_line *hdr = NULL; ++ struct istream *input = test_istream_create_data(test_message_header_truncation_input, sizeof(test_message_header_truncation_input)); ++ struct message_header_parser_ctx *parser = message_parse_header_init(input, NULL, 0); ++ message_parse_header_set_limit(parser, 96); ++ ++ assert_parse_line( 1, "header1", "this is short", "this is short"); ++ assert_parse_line( 2, "header2", "this is multiline", "this is multiline"); ++ assert_parse_line( 3, "header2", " and long 343638404244464850525456586062", "this is multiline\n and long 343638404244464850525456586062"); ++ assert_parse_line( 4, "header2", " 64666870727476788082848688909294969800", "this is multiline\n and long 343638404244464850525456586062\n 646668707274767880828486"); ++ assert_parse_line( 5, "header2", " 02040608101214161820222426283032343638", "this is multiline\n and long 343638404244464850525456586062\n 646668707274767880828486"); ++ assert_parse_line( 6, "header3", "", ""); ++ test_assert(message_parse_header_next(parser, &hdr) > 0 && hdr->eoh); ++ ++ message_parse_header_deinit(&parser); ++ i_stream_unref(&input); ++ test_end(); ++} ++ + int main(void) + { + static void (*const test_functions[])(void) = { +@@ -473,6 +538,8 @@ int main(void) + test_message_header_parser_no_eoh, + test_message_header_parser_nul, + test_message_header_parser_extra_crlf_in_name, ++ test_message_header_truncation_flag0, ++ test_message_header_truncation_clean_oneline, + NULL + }; + return test_run(test_functions); + +From ce88c33abc37e408592eff70aeefa28f803effb9 Mon Sep 17 00:00:00 2001 +From: Marco Bettini +Date: Wed, 24 Apr 2024 10:45:46 +0000 +Subject: [PATCH 2/2] lib-mail: message-parser - Limit headers total count to + 50MB by default + +(including top headers and all mime-sections headers) +--- + src/lib-mail/message-parser-private.h | 2 + + src/lib-mail/message-parser.c | 15 +++ + src/lib-mail/message-parser.h | 6 + + src/lib-mail/test-message-parser.c | 154 ++++++++++++++++++++++++++ + 4 files changed, 177 insertions(+) + +diff --git a/src/lib-mail/message-parser-private.h b/src/lib-mail/message-parser-private.h +index 41c32daf3a..8b362a9e71 100644 +--- a/src/lib-mail/message-parser-private.h ++++ b/src/lib-mail/message-parser-private.h +@@ -30,6 +30,8 @@ struct message_parser_ctx { + enum message_parser_flags flags; + unsigned int max_nested_mime_parts; + unsigned int max_total_mime_parts; ++ size_t all_headers_max_size; ++ size_t all_headers_total_size; + + char *last_boundary; + struct message_boundary *boundaries; +diff --git a/src/lib-mail/message-parser.c b/src/lib-mail/message-parser.c +index 9a9c9a3515..c7e3b1e96a 100644 +--- a/src/lib-mail/message-parser.c ++++ b/src/lib-mail/message-parser.c +@@ -617,7 +617,18 @@ static int parse_next_header(struct message_parser_ctx *ctx, + } + if (ret < 0) { + /* no boundary */ ++ size_t headers_available = ++ ctx->all_headers_max_size > ctx->all_headers_total_size ? ++ ctx->all_headers_max_size - ctx->all_headers_total_size : 0; ++ message_parse_header_lower_limit(ctx->hdr_parser_ctx, headers_available); + ret = message_parse_header_next(ctx->hdr_parser_ctx, &hdr); ++ if (ret > 0) { ++ if (!hdr->continues) { ++ ctx->all_headers_total_size += hdr->name_len; ++ ctx->all_headers_total_size += hdr->middle_len; ++ } ++ ctx->all_headers_total_size += hdr->value_len; ++ } + if (ret == 0 || (ret < 0 && ctx->input->stream_errno != 0)) { + ctx->want_count = i_stream_get_data_size(ctx->input) + 1; + return ret; +@@ -762,6 +773,9 @@ message_parser_init_int(struct istream *input, + ctx->max_total_mime_parts = set->max_total_mime_parts != 0 ? + set->max_total_mime_parts : + MESSAGE_PARSER_DEFAULT_MAX_TOTAL_MIME_PARTS; ++ ctx->all_headers_max_size = set->all_headers_max_size != 0 ? ++ set->all_headers_max_size : ++ MESSAGE_PARSER_DEFAULT_ALL_HEADERS_MAX_SIZE; + ctx->input = input; + i_stream_ref(input); + return ctx; +@@ -779,6 +793,7 @@ message_parser_init(pool_t part_pool, struct istream *input, + ctx->next_part = &ctx->part->children; + ctx->parse_next_block = parse_next_header_init; + ctx->total_parts_count = 1; ++ ctx->all_headers_total_size = 0; + i_array_init(&ctx->next_part_stack, 4); + return ctx; + } +diff --git a/src/lib-mail/message-parser.h b/src/lib-mail/message-parser.h +index f19e526284..8d70d73f05 100644 +--- a/src/lib-mail/message-parser.h ++++ b/src/lib-mail/message-parser.h +@@ -19,6 +19,7 @@ enum message_parser_flags { + + #define MESSAGE_PARSER_DEFAULT_MAX_NESTED_MIME_PARTS 100 + #define MESSAGE_PARSER_DEFAULT_MAX_TOTAL_MIME_PARTS 10000 ++#define MESSAGE_PARSER_DEFAULT_ALL_HEADERS_MAX_SIZE ((size_t) 50 * 1024*1024) + + struct message_parser_settings { + enum message_header_parser_flags hdr_flags; +@@ -30,6 +31,11 @@ struct message_parser_settings { + /* Maximum MIME parts in total. + 0 = MESSAGE_PARSER_DEFAULT_MAX_TOTAL_MIME_PARTS. */ + unsigned int max_total_mime_parts; ++ ++ /* Maximum bytes fore headers in top header plus all ++ MIME sections headers ++ 0 = MESSAGE_PARSER_DEFAULT_ALL_HEADERS_MAX_SIZE */ ++ size_t all_headers_max_size; + }; + + struct message_parser_ctx; +diff --git a/src/lib-mail/test-message-parser.c b/src/lib-mail/test-message-parser.c +index 663bfe8c5a..b6bada2303 100644 +--- a/src/lib-mail/test-message-parser.c ++++ b/src/lib-mail/test-message-parser.c +@@ -1369,6 +1369,158 @@ static const char input_msg[] = + test_end(); + } + ++#define test_assert_virtual_size(part) \ ++ test_assert((part).virtual_size == (part).lines + (part).physical_size) ++ ++#define test_assert_part(part, flags_, children, h_lines, h_size, b_lines, b_size ) \ ++STMT_START { \ ++ test_assert((part)->flags == (flags_)); \ ++ test_assert((part)->children_count == children); \ ++ test_assert((part)->header_size.lines == h_lines); \ ++ test_assert((part)->header_size.physical_size == h_size); \ ++ test_assert((part)->body_size.lines == b_lines); \ ++ test_assert((part)->body_size.physical_size == b_size); \ ++ test_assert_virtual_size((part)->header_size); \ ++ test_assert_virtual_size((part)->body_size); \ ++} STMT_END ++ ++static const enum message_part_flags FLAGS_MULTIPART = ++ MESSAGE_PART_FLAG_IS_MIME | MESSAGE_PART_FLAG_MULTIPART; ++static const enum message_part_flags FLAGS_RFC822 = ++ MESSAGE_PART_FLAG_IS_MIME | MESSAGE_PART_FLAG_MESSAGE_RFC822; ++static const enum message_part_flags FLAGS_TEXT = ++ MESSAGE_PART_FLAG_IS_MIME | MESSAGE_PART_FLAG_TEXT; ++ ++static const char too_many_header_bytes_input_msg[] = ++ "Content-Type: multipart/mixed; boundary=\"1\"\n\n" ++ "--1\n" ++ "Content-Type: multipart/mixed; boundary=\"2\"\n\n" ++ "--2\n" ++ "Content-Type: message/rfc822\n\n" ++ "Content-Type: text/plain\n\n1-rfc822\n" ++ "--2\n" ++ "Content-Type: message/rfc822\n\n" ++ "Content-Type: text/plain\n\n2-rfc822\n" ++ "--1\n" ++ "Content-Type: message/rfc822\n\n" ++ "Content-Type: text/plain\n\n3-rfc822\n"; ++ ++static void test_message_parser_too_many_header_bytes_run( ++ const struct message_parser_settings *parser_set, ++ pool_t *pool_r, struct istream **input_r, ++ struct message_part **parts_r) ++{ ++ *pool_r = pool_alloconly_create("message parser", 10240); ++ *input_r = test_istream_create(too_many_header_bytes_input_msg); ++ struct message_parser_ctx *parser = message_parser_init(*pool_r, *input_r, parser_set); ++ ++ int ret; ++ struct message_block block ATTR_UNUSED; ++ while ((ret = message_parser_parse_next_block(parser, &block)) > 0); ++ test_assert(ret < 0); ++ ++ message_parser_deinit(&parser, parts_r); ++} ++ ++static void test_message_parser_too_many_header_bytes_default(void) ++{ ++ test_begin("message parser too many header bytes default"); ++ ++ pool_t pool; ++ struct istream *input; ++ struct message_part *part_root; ++ const struct message_parser_settings parser_set = { .all_headers_max_size = 0 }; ++ ++ test_message_parser_too_many_header_bytes_run(&parser_set, &pool, &input, &part_root); ++ ++ // test_assert_part(part, flags_, children, h_lines, h_size, b_lines, b_size ) ++ ++ test_assert_part(part_root, FLAGS_MULTIPART, 7, 2, 45, 21, 256); ++ test_assert(part_root->parent == NULL); ++ ++ struct message_part *part_1 = part_root->children; ++ test_assert_part(part_1, FLAGS_MULTIPART, 4, 2, 45, 11, 137); ++ ++ struct message_part *part_1_1 = part_1->children; ++ test_assert_part(part_1_1, FLAGS_RFC822, 1, 2, 30, 2, 34); ++ ++ struct message_part *part_1_1_1 = part_1_1->children; ++ test_assert_part(part_1_1_1, FLAGS_TEXT, 0, 2, 26, 0, 8); ++ ++ test_assert(part_1_1_1->next == NULL); ++ ++ struct message_part *part_1_2 = part_1_1->next; ++ test_assert_part(part_1_2, FLAGS_RFC822, 1, 2, 30, 2, 34); ++ ++ struct message_part *part_1_2_1 = part_1_2->children; ++ test_assert_part(part_1_2_1, FLAGS_TEXT, 0, 2, 26, 0, 8); ++ ++ test_assert(part_1_2_1->next == NULL); ++ ++ test_assert(part_1_2->next == NULL); ++ ++ struct message_part *part_2 = part_1->next; ++ test_assert_part(part_2, FLAGS_RFC822, 1, 2, 30, 3, 35); ++ ++ struct message_part *part_2_1 = part_2->children; ++ test_assert_part(part_2_1, FLAGS_TEXT, 0, 2, 26, 1, 9); ++ test_assert(part_2_1->next == NULL); ++ ++ test_assert(part_2->next == NULL); ++ ++ test_assert(part_root->next == NULL); ++ ++ test_parsed_parts(input, part_root); ++ i_stream_unref(&input); ++ pool_unref(&pool); ++ test_end(); ++} ++ ++static void test_message_parser_too_many_header_bytes_100(void) ++{ ++ test_begin("message parser too many header bytes 100"); ++ ++ pool_t pool; ++ struct istream *input; ++ struct message_part *part_root; ++ const struct message_parser_settings parser_set = { .all_headers_max_size = 100 }; ++ ++ test_message_parser_too_many_header_bytes_run(&parser_set, &pool, &input, &part_root); ++ ++ // test_assert_part(part, flags_, children, h_lines, h_size, b_lines, b_size ) ++ ++ test_assert_part(part_root, FLAGS_MULTIPART, 5, 2, 45, 21, 256); ++ test_assert(part_root->parent == NULL); ++ ++ struct message_part *part_1 = part_root->children; ++ test_assert_part(part_1, FLAGS_MULTIPART, 3, 2, 45, 11, 137); ++ ++ struct message_part *part_1_1 = part_1->children; ++ test_assert_part(part_1_1, FLAGS_RFC822, 1, 2, 30, 2, 34); ++ ++ struct message_part *part_1_1_1 = part_1_1->children; ++ test_assert_part(part_1_1_1, MESSAGE_PART_FLAG_IS_MIME, 0, 2, 26, 0, 8); ++ ++ test_assert(part_1_1_1->next == NULL); ++ ++ struct message_part *part_1_2 = part_1_1->next; ++ test_assert_part(part_1_2, MESSAGE_PART_FLAG_IS_MIME, 0, 2, 30, 2, 34); ++ ++ test_assert(part_1_2->next == NULL); ++ ++ struct message_part *part_2 = part_1->next; ++ test_assert_part(part_2, MESSAGE_PART_FLAG_IS_MIME, 0, 2, 30, 3, 35); ++ ++ test_assert(part_2->next == NULL); ++ ++ test_assert(part_root->next == NULL); ++ ++ test_parsed_parts(input, part_root); ++ i_stream_unref(&input); ++ pool_unref(&pool); ++ test_end(); ++} ++ + int main(void) + { + static void (*const test_functions[])(void) = { +@@ -1392,6 +1544,8 @@ int main(void) + test_message_parser_mime_part_limit_rfc822, + test_message_parser_mime_version, + test_message_parser_mime_version_missing, ++ test_message_parser_too_many_header_bytes_default, ++ test_message_parser_too_many_header_bytes_100, + NULL + }; + return test_run(test_functions); diff --git a/SOURCES/dovecot-2.3.6-opensslhmac.patch b/SOURCES/dovecot-2.3.6-opensslhmac.patch new file mode 100644 index 0000000..53f3321 --- /dev/null +++ b/SOURCES/dovecot-2.3.6-opensslhmac.patch @@ -0,0 +1,813 @@ +diff -up dovecot-2.3.18/src/auth/auth-token.c.opensslhmac dovecot-2.3.18/src/auth/auth-token.c +--- dovecot-2.3.18/src/auth/auth-token.c.opensslhmac 2022-02-02 12:42:23.000000000 +0100 ++++ dovecot-2.3.18/src/auth/auth-token.c 2022-02-09 09:27:15.887883359 +0100 +@@ -161,17 +161,17 @@ void auth_token_deinit(void) + const char *auth_token_get(const char *service, const char *session_pid, + const char *username, const char *session_id) + { +- struct hmac_context ctx; ++ struct openssl_hmac_context ctx; + unsigned char result[SHA1_RESULTLEN]; + +- hmac_init(&ctx, (const unsigned char*)username, strlen(username), ++ openssl_hmac_init(&ctx, (const unsigned char*)username, strlen(username), + &hash_method_sha1); +- hmac_update(&ctx, session_pid, strlen(session_pid)); ++ openssl_hmac_update(&ctx, session_pid, strlen(session_pid)); + if (session_id != NULL && *session_id != '\0') +- hmac_update(&ctx, session_id, strlen(session_id)); +- hmac_update(&ctx, service, strlen(service)); +- hmac_update(&ctx, auth_token_secret, sizeof(auth_token_secret)); +- hmac_final(&ctx, result); ++ openssl_hmac_update(&ctx, session_id, strlen(session_id)); ++ openssl_hmac_update(&ctx, service, strlen(service)); ++ openssl_hmac_update(&ctx, auth_token_secret, sizeof(auth_token_secret)); ++ openssl_hmac_final(&ctx, result); + + return binary_to_hex(result, sizeof(result)); + } +diff -up dovecot-2.3.18/src/auth/mech-cram-md5.c.opensslhmac dovecot-2.3.18/src/auth/mech-cram-md5.c +--- dovecot-2.3.18/src/auth/mech-cram-md5.c.opensslhmac 2022-02-02 12:42:23.000000000 +0100 ++++ dovecot-2.3.18/src/auth/mech-cram-md5.c 2022-02-09 09:27:15.887883359 +0100 +@@ -51,7 +51,7 @@ static bool verify_credentials(struct cr + { + + unsigned char digest[MD5_RESULTLEN]; +- struct hmac_context ctx; ++ struct orig_hmac_context ctx; + const char *response_hex; + + if (size != CRAM_MD5_CONTEXTLEN) { +@@ -60,10 +60,10 @@ static bool verify_credentials(struct cr + return FALSE; + } + +- hmac_init(&ctx, NULL, 0, &hash_method_md5); ++ orig_hmac_init(&ctx, NULL, 0, &hash_method_md5); + hmac_md5_set_cram_context(&ctx, credentials); +- hmac_update(&ctx, request->challenge, strlen(request->challenge)); +- hmac_final(&ctx, digest); ++ orig_hmac_update(&ctx, request->challenge, strlen(request->challenge)); ++ orig_hmac_final(&ctx, digest); + + response_hex = binary_to_hex(digest, sizeof(digest)); + +diff -up dovecot-2.3.18/src/auth/mech-scram.c.opensslhmac dovecot-2.3.18/src/auth/mech-scram.c +--- dovecot-2.3.18/src/auth/mech-scram.c.opensslhmac 2022-02-02 12:42:23.000000000 +0100 ++++ dovecot-2.3.18/src/auth/mech-scram.c 2022-02-09 09:31:50.927146858 +0100 +@@ -93,7 +93,7 @@ get_scram_server_first(struct scram_auth + static const char *get_scram_server_final(struct scram_auth_request *request) + { + const struct hash_method *hmethod = request->hash_method; +- struct hmac_context ctx; ++ struct openssl_hmac_context ctx; + const char *auth_message; + unsigned char server_signature[hmethod->digest_size]; + string_t *str; +@@ -109,9 +109,9 @@ static const char *get_scram_server_fina + request->server_first_message, ",", + request->client_final_message_without_proof, NULL); + +- hmac_init(&ctx, request->server_key, hmethod->digest_size, hmethod); +- hmac_update(&ctx, auth_message, strlen(auth_message)); +- hmac_final(&ctx, server_signature); ++ openssl_hmac_init(&ctx, request->server_key, hmethod->digest_size, hmethod); ++ openssl_hmac_update(&ctx, auth_message, strlen(auth_message)); ++ openssl_hmac_final(&ctx, server_signature); + + /* RFC 5802, Section 7: + +@@ -292,7 +292,7 @@ parse_scram_client_first(struct scram_au + static bool verify_credentials(struct scram_auth_request *request) + { + const struct hash_method *hmethod = request->hash_method; +- struct hmac_context ctx; ++ struct openssl_hmac_context ctx; + const char *auth_message; + unsigned char client_key[hmethod->digest_size]; + unsigned char client_signature[hmethod->digest_size]; +@@ -310,9 +310,9 @@ static bool verify_credentials(struct sc + request->server_first_message, ",", + request->client_final_message_without_proof, NULL); + +- hmac_init(&ctx, request->stored_key, hmethod->digest_size, hmethod); +- hmac_update(&ctx, auth_message, strlen(auth_message)); +- hmac_final(&ctx, client_signature); ++ openssl_hmac_init(&ctx, request->stored_key, hmethod->digest_size, hmethod); ++ openssl_hmac_update(&ctx, auth_message, strlen(auth_message)); ++ openssl_hmac_final(&ctx, client_signature); + + /* ClientProof := ClientKey XOR ClientSignature */ + const unsigned char *proof_data = request->proof->data; +diff -up dovecot-2.3.18/src/auth/password-scheme.c.opensslhmac dovecot-2.3.18/src/auth/password-scheme.c +--- dovecot-2.3.18/src/auth/password-scheme.c.opensslhmac 2022-02-02 12:42:23.000000000 +0100 ++++ dovecot-2.3.18/src/auth/password-scheme.c 2022-02-09 09:27:15.888883345 +0100 +@@ -639,11 +639,11 @@ static void + cram_md5_generate(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, + const unsigned char **raw_password_r, size_t *size_r) + { +- struct hmac_context ctx; ++ struct orig_hmac_context ctx; + unsigned char *context_digest; + + context_digest = t_malloc_no0(CRAM_MD5_CONTEXTLEN); +- hmac_init(&ctx, (const unsigned char *)plaintext, ++ orig_hmac_init(&ctx, (const unsigned char *)plaintext, + strlen(plaintext), &hash_method_md5); + hmac_md5_get_cram_context(&ctx, context_digest); + +diff -up dovecot-2.3.18/src/auth/password-scheme-scram.c.opensslhmac dovecot-2.3.18/src/auth/password-scheme-scram.c +--- dovecot-2.3.18/src/auth/password-scheme-scram.c.opensslhmac 2022-02-02 12:42:23.000000000 +0100 ++++ dovecot-2.3.18/src/auth/password-scheme-scram.c 2022-02-09 09:27:15.888883345 +0100 +@@ -30,23 +30,23 @@ Hi(const struct hash_method *hmethod, co + const unsigned char *salt, size_t salt_size, unsigned int i, + unsigned char *result) + { +- struct hmac_context ctx; ++ struct openssl_hmac_context ctx; + unsigned char U[hmethod->digest_size]; + unsigned int j, k; + + /* Calculate U1 */ +- hmac_init(&ctx, str, str_size, hmethod); +- hmac_update(&ctx, salt, salt_size); +- hmac_update(&ctx, "\0\0\0\1", 4); +- hmac_final(&ctx, U); ++ openssl_hmac_init(&ctx, str, str_size, hmethod); ++ openssl_hmac_update(&ctx, salt, salt_size); ++ openssl_hmac_update(&ctx, "\0\0\0\1", 4); ++ openssl_hmac_final(&ctx, U); + + memcpy(result, U, hmethod->digest_size); + + /* Calculate U2 to Ui and Hi */ + for (j = 2; j <= i; j++) { +- hmac_init(&ctx, str, str_size, hmethod); +- hmac_update(&ctx, U, sizeof(U)); +- hmac_final(&ctx, U); ++ openssl_hmac_init(&ctx, str, str_size, hmethod); ++ openssl_hmac_update(&ctx, U, sizeof(U)); ++ openssl_hmac_final(&ctx, U); + for (k = 0; k < hmethod->digest_size; k++) + result[k] ^= U[k]; + } +@@ -102,7 +102,7 @@ int scram_verify(const struct hash_metho + const char *plaintext, const unsigned char *raw_password, + size_t size, const char **error_r) + { +- struct hmac_context ctx; ++ struct openssl_hmac_context ctx; + const char *salt_base64; + unsigned int iter_count; + const unsigned char *salt; +@@ -126,9 +126,9 @@ int scram_verify(const struct hash_metho + salt, salt_len, iter_count, salted_password); + + /* Calculate ClientKey */ +- hmac_init(&ctx, salted_password, sizeof(salted_password), hmethod); +- hmac_update(&ctx, "Client Key", 10); +- hmac_final(&ctx, client_key); ++ openssl_hmac_init(&ctx, salted_password, sizeof(salted_password), hmethod); ++ openssl_hmac_update(&ctx, "Client Key", 10); ++ openssl_hmac_final(&ctx, client_key); + + /* Calculate StoredKey */ + hash_method_get_digest(hmethod, client_key, sizeof(client_key), +@@ -147,7 +147,7 @@ void scram_generate(const struct hash_me + const unsigned char **raw_password_r, size_t *size_r) + { + string_t *str; +- struct hmac_context ctx; ++ struct openssl_hmac_context ctx; + unsigned char salt[16]; + unsigned char salted_password[hmethod->digest_size]; + unsigned char client_key[hmethod->digest_size]; +@@ -165,9 +165,9 @@ void scram_generate(const struct hash_me + sizeof(salt), SCRAM_DEFAULT_ITERATE_COUNT, salted_password); + + /* Calculate ClientKey */ +- hmac_init(&ctx, salted_password, sizeof(salted_password), hmethod); +- hmac_update(&ctx, "Client Key", 10); +- hmac_final(&ctx, client_key); ++ openssl_hmac_init(&ctx, salted_password, sizeof(salted_password), hmethod); ++ openssl_hmac_update(&ctx, "Client Key", 10); ++ openssl_hmac_final(&ctx, client_key); + + /* Calculate StoredKey */ + hash_method_get_digest(hmethod, client_key, sizeof(client_key), +@@ -176,9 +176,9 @@ void scram_generate(const struct hash_me + base64_encode(stored_key, sizeof(stored_key), str); + + /* Calculate ServerKey */ +- hmac_init(&ctx, salted_password, sizeof(salted_password), hmethod); +- hmac_update(&ctx, "Server Key", 10); +- hmac_final(&ctx, server_key); ++ openssl_hmac_init(&ctx, salted_password, sizeof(salted_password), hmethod); ++ openssl_hmac_update(&ctx, "Server Key", 10); ++ openssl_hmac_final(&ctx, server_key); + str_append_c(str, ','); + base64_encode(server_key, sizeof(server_key), str); + +diff -up dovecot-2.3.18/src/lib/hmac.c.opensslhmac dovecot-2.3.18/src/lib/hmac.c +--- dovecot-2.3.18/src/lib/hmac.c.opensslhmac 2022-02-02 12:42:23.000000000 +0100 ++++ dovecot-2.3.18/src/lib/hmac.c 2022-02-09 09:27:15.888883345 +0100 +@@ -7,6 +7,10 @@ + * This software is released under the MIT license. + */ + ++#include ++#include ++#include ++#include + #include "lib.h" + #include "hmac.h" + #include "safe-memset.h" +@@ -14,10 +18,65 @@ + + #include "hex-binary.h" + +-void hmac_init(struct hmac_context *_ctx, const unsigned char *key, ++#ifndef HAVE_HMAC_CTX_NEW ++# define HMAC_Init_ex(ctx, key, key_len, md, impl) \ ++ HMAC_Init_ex(&(ctx), key, key_len, md, impl) ++# define HMAC_Update(ctx, data, len) HMAC_Update(&(ctx), data, len) ++# define HMAC_Final(ctx, md, len) HMAC_Final(&(ctx), md, len) ++# define HMAC_CTX_free(ctx) HMAC_cleanup(&(ctx)) ++#else ++# define HMAC_CTX_free(ctx) \ ++ STMT_START { HMAC_CTX_free(ctx); (ctx) = NULL; } STMT_END ++#endif ++ ++ ++void openssl_hmac_init(struct openssl_hmac_context *_ctx, const unsigned char *key, + size_t key_len, const struct hash_method *meth) + { +- struct hmac_context_priv *ctx = &_ctx->u.priv; ++ struct openssl_hmac_context_priv *ctx = &_ctx->u.priv; ++ ++ const EVP_MD *md; ++ const char *ebuf = NULL; ++ const char **error_r = &ebuf; ++ ++ md = EVP_get_digestbyname(meth->name); ++ if(md == NULL) { ++ if (error_r != NULL) { ++ *error_r = t_strdup_printf("Invalid digest %s", ++ meth->name); ++ } ++ //return FALSE; ++ } ++ ++// int ec; ++ ++ i_assert(md != NULL); ++#ifdef HAVE_HMAC_CTX_NEW ++ ctx->ctx = HMAC_CTX_new(); ++/* if (ctx->ctx == NULL) ++ dcrypt_openssl_error(error_r);*/ ++#endif ++ /*ec = */HMAC_Init_ex(ctx->ctx, key, key_len, md, NULL); ++} ++ ++void orig_hmac_init(struct orig_hmac_context *_ctx, const unsigned char *key, ++ size_t key_len, const struct hash_method *meth) ++{ ++ static int no_fips = -1; ++ if (no_fips == -1) { ++ int fd = open("/proc/sys/crypto/fips_enabled", O_RDONLY); ++ if (fd != -1) ++ { ++ char buf[4]; ++ if (read(fd, buf, 4) > 0) ++ { ++ no_fips = buf[0] == '0'; ++ } ++ close(fd); ++ } ++ } ++ i_assert(no_fips); ++ struct orig_hmac_context_priv *ctx = &_ctx->u.priv; + unsigned int i; + unsigned char k_ipad[meth->block_size]; + unsigned char k_opad[meth->block_size]; +@@ -53,9 +112,27 @@ void hmac_init(struct hmac_context *_ctx + safe_memset(k_opad, 0, meth->block_size); + } + +-void hmac_final(struct hmac_context *_ctx, unsigned char *digest) ++void openssl_hmac_final(struct openssl_hmac_context *_ctx, unsigned char *digest) ++{ ++ int ec; ++ unsigned char buf[HMAC_MAX_MD_CBLOCK]; ++ unsigned int outl; ++// const char *ebuf = NULL; ++// const char **error_r = &ebuf; ++ ++ struct openssl_hmac_context_priv *ctx = &_ctx->u.priv; ++ ec = HMAC_Final(ctx->ctx, buf, &outl); ++ HMAC_CTX_free(ctx->ctx); ++ if (ec == 1) ++ memcpy(digest, buf, outl); ++// else ++// dcrypt_openssl_error(error_r); ++ ++} ++ ++void orig_hmac_final(struct orig_hmac_context *_ctx, unsigned char *digest) + { +- struct hmac_context_priv *ctx = &_ctx->u.priv; ++ struct orig_hmac_context_priv *ctx = &_ctx->u.priv; + + ctx->hash->result(ctx->ctx, digest); + +@@ -63,53 +140,50 @@ void hmac_final(struct hmac_context *_ct + ctx->hash->result(ctx->ctxo, digest); + } + +-buffer_t *t_hmac_data(const struct hash_method *meth, ++buffer_t *openssl_t_hmac_data(const struct hash_method *meth, + const unsigned char *key, size_t key_len, + const void *data, size_t data_len) + { +- struct hmac_context ctx; ++ struct openssl_hmac_context ctx; + i_assert(meth != NULL); + i_assert(key != NULL && key_len > 0); + i_assert(data != NULL || data_len == 0); + + buffer_t *res = t_buffer_create(meth->digest_size); +- hmac_init(&ctx, key, key_len, meth); ++ openssl_hmac_init(&ctx, key, key_len, meth); + if (data_len > 0) +- hmac_update(&ctx, data, data_len); ++ openssl_hmac_update(&ctx, data, data_len); + unsigned char *buf = buffer_get_space_unsafe(res, 0, meth->digest_size); +- hmac_final(&ctx, buf); ++ openssl_hmac_final(&ctx, buf); + return res; + } + +-buffer_t *t_hmac_buffer(const struct hash_method *meth, ++buffer_t *openssl_t_hmac_buffer(const struct hash_method *meth, + const unsigned char *key, size_t key_len, + const buffer_t *data) + { +- return t_hmac_data(meth, key, key_len, data->data, data->used); ++ return openssl_t_hmac_data(meth, key, key_len, data->data, data->used); + } + +-buffer_t *t_hmac_str(const struct hash_method *meth, ++buffer_t *openssl_t_hmac_str(const struct hash_method *meth, + const unsigned char *key, size_t key_len, + const char *data) + { +- return t_hmac_data(meth, key, key_len, data, strlen(data)); ++ return openssl_t_hmac_data(meth, key, key_len, data, strlen(data)); + } + +-void hmac_hkdf(const struct hash_method *method, ++void openssl_hmac_hkdf(const struct hash_method *method, + const unsigned char *salt, size_t salt_len, + const unsigned char *ikm, size_t ikm_len, + const unsigned char *info, size_t info_len, + buffer_t *okm_r, size_t okm_len) + { ++ const EVP_MD *md; ++ EVP_PKEY_CTX *pctx; ++ int r = 1; ++ + i_assert(method != NULL); + i_assert(okm_len < 255*method->digest_size); +- struct hmac_context key_mac; +- struct hmac_context info_mac; +- size_t remain = okm_len; +- unsigned char prk[method->digest_size]; +- unsigned char okm[method->digest_size]; +- /* N = ceil(L/HashLen) */ +- unsigned int rounds = (okm_len + method->digest_size - 1)/method->digest_size; + + /* salt and info can be NULL */ + i_assert(salt != NULL || salt_len == 0); +@@ -118,35 +192,30 @@ void hmac_hkdf(const struct hash_method + i_assert(ikm != NULL && ikm_len > 0); + i_assert(okm_r != NULL && okm_len > 0); + +- /* but they still need valid pointer, reduces +- complains from static analysers */ +- if (salt == NULL) +- salt = &uchar_nul; +- if (info == NULL) +- info = &uchar_nul; +- +- /* extract */ +- hmac_init(&key_mac, salt, salt_len, method); +- hmac_update(&key_mac, ikm, ikm_len); +- hmac_final(&key_mac, prk); +- +- /* expand */ +- for (unsigned int i = 0; remain > 0 && i < rounds; i++) { +- unsigned char round = (i+1); +- size_t amt = remain; +- if (amt > method->digest_size) +- amt = method->digest_size; +- hmac_init(&info_mac, prk, method->digest_size, method); +- if (i > 0) +- hmac_update(&info_mac, okm, method->digest_size); +- hmac_update(&info_mac, info, info_len); +- hmac_update(&info_mac, &round, 1); +- memset(okm, 0, method->digest_size); +- hmac_final(&info_mac, okm); +- buffer_append(okm_r, okm, amt); +- remain -= amt; ++ ++ md = EVP_get_digestbyname(method->name); ++ pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL); ++ unsigned char *okm_buf = buffer_get_space_unsafe(okm_r, 0, okm_len); ++ ++ if ((r=EVP_PKEY_derive_init(pctx)) <= 0) ++ goto out; ++ if ((r=EVP_PKEY_CTX_set_hkdf_md(pctx, md)) <= 0) ++ goto out; ++ if ((r=EVP_PKEY_CTX_set1_hkdf_salt(pctx, salt, salt_len)) <= 0) ++ goto out; ++ if ((r=EVP_PKEY_CTX_set1_hkdf_key(pctx, ikm, ikm_len)) <= 0) ++ goto out; ++ if ((r=EVP_PKEY_CTX_add1_hkdf_info(pctx, info, info_len)) <= 0) ++ goto out; ++ if ((r=EVP_PKEY_derive(pctx, okm_buf, &okm_len)) <= 0) ++ goto out; ++ ++ out: ++ EVP_PKEY_CTX_free(pctx); ++ if (r <= 0) { ++ unsigned long ec = ERR_get_error(); ++ unsigned char *error = t_strdup_printf("%s", ERR_error_string(ec, NULL)); ++ i_error("%s", error); + } + +- safe_memset(prk, 0, sizeof(prk)); +- safe_memset(okm, 0, sizeof(okm)); + } +diff -up dovecot-2.3.18/src/lib/hmac-cram-md5.c.opensslhmac dovecot-2.3.18/src/lib/hmac-cram-md5.c +--- dovecot-2.3.18/src/lib/hmac-cram-md5.c.opensslhmac 2022-02-02 12:42:23.000000000 +0100 ++++ dovecot-2.3.18/src/lib/hmac-cram-md5.c 2022-02-09 09:27:15.888883345 +0100 +@@ -9,10 +9,10 @@ + #include "md5.h" + #include "hmac-cram-md5.h" + +-void hmac_md5_get_cram_context(struct hmac_context *_hmac_ctx, ++void hmac_md5_get_cram_context(struct orig_hmac_context *_hmac_ctx, + unsigned char context_digest[CRAM_MD5_CONTEXTLEN]) + { +- struct hmac_context_priv *hmac_ctx = &_hmac_ctx->u.priv; ++ struct orig_hmac_context_priv *hmac_ctx = &_hmac_ctx->u.priv; + unsigned char *cdp; + + struct md5_context *ctx = (void*)hmac_ctx->ctx; +@@ -35,10 +35,10 @@ void hmac_md5_get_cram_context(struct hm + CDPUT(cdp, ctx->d); + } + +-void hmac_md5_set_cram_context(struct hmac_context *_hmac_ctx, ++void hmac_md5_set_cram_context(struct orig_hmac_context *_hmac_ctx, + const unsigned char context_digest[CRAM_MD5_CONTEXTLEN]) + { +- struct hmac_context_priv *hmac_ctx = &_hmac_ctx->u.priv; ++ struct orig_hmac_context_priv *hmac_ctx = &_hmac_ctx->u.priv; + const unsigned char *cdp; + + struct md5_context *ctx = (void*)hmac_ctx->ctx; +diff -up dovecot-2.3.18/src/lib/hmac-cram-md5.h.opensslhmac dovecot-2.3.18/src/lib/hmac-cram-md5.h +--- dovecot-2.3.18/src/lib/hmac-cram-md5.h.opensslhmac 2022-02-02 12:42:23.000000000 +0100 ++++ dovecot-2.3.18/src/lib/hmac-cram-md5.h 2022-02-09 09:27:15.888883345 +0100 +@@ -5,9 +5,9 @@ + + #define CRAM_MD5_CONTEXTLEN 32 + +-void hmac_md5_get_cram_context(struct hmac_context *ctx, ++void hmac_md5_get_cram_context(struct orig_hmac_context *ctx, + unsigned char context_digest[CRAM_MD5_CONTEXTLEN]); +-void hmac_md5_set_cram_context(struct hmac_context *ctx, ++void hmac_md5_set_cram_context(struct orig_hmac_context *ctx, + const unsigned char context_digest[CRAM_MD5_CONTEXTLEN]); + + +diff -up dovecot-2.3.18/src/lib/hmac.h.opensslhmac dovecot-2.3.18/src/lib/hmac.h +--- dovecot-2.3.18/src/lib/hmac.h.opensslhmac 2022-02-02 12:42:23.000000000 +0100 ++++ dovecot-2.3.18/src/lib/hmac.h 2022-02-09 09:27:15.888883345 +0100 +@@ -4,60 +4,97 @@ + #include "hash-method.h" + #include "sha1.h" + #include "sha2.h" ++#include ++#include ++#include ++#include + + #define HMAC_MAX_CONTEXT_SIZE sizeof(struct sha512_ctx) + +-struct hmac_context_priv { ++struct openssl_hmac_context_priv { ++#ifdef HAVE_HMAC_CTX_NEW ++ HMAC_CTX *ctx; ++#else ++ HMAC_CTX ctx; ++#endif ++ const struct hash_method *hash; ++}; ++ ++struct orig_hmac_context_priv { + char ctx[HMAC_MAX_CONTEXT_SIZE]; + char ctxo[HMAC_MAX_CONTEXT_SIZE]; + const struct hash_method *hash; + }; + +-struct hmac_context { ++struct openssl_hmac_context { ++ union { ++ struct openssl_hmac_context_priv priv; ++ uint64_t padding_requirement; ++ } u; ++}; ++ ++struct orig_hmac_context { + union { +- struct hmac_context_priv priv; ++ struct orig_hmac_context_priv priv; + uint64_t padding_requirement; + } u; + }; + +-void hmac_init(struct hmac_context *ctx, const unsigned char *key, ++void openssl_hmac_init(struct openssl_hmac_context *ctx, const unsigned char *key, ++ size_t key_len, const struct hash_method *meth); ++void openssl_hmac_final(struct openssl_hmac_context *ctx, unsigned char *digest); ++ ++static inline void ++openssl_hmac_update(struct openssl_hmac_context *_ctx, const void *data, size_t size) ++{ ++ struct openssl_hmac_context_priv *ctx = &_ctx->u.priv; ++ HMAC_Update(ctx->ctx, data, size); ++/* if (ec != 1) ++ { ++ const char *ebuf = NULL; ++ const char **error_r = &ebuf; ++ dcrypt_openssl_error(error_r); ++ }*/ ++} ++ ++void orig_hmac_init(struct orig_hmac_context *ctx, const unsigned char *key, + size_t key_len, const struct hash_method *meth); +-void hmac_final(struct hmac_context *ctx, unsigned char *digest); ++void orig_hmac_final(struct orig_hmac_context *ctx, unsigned char *digest); + + + static inline void +-hmac_update(struct hmac_context *_ctx, const void *data, size_t size) ++orig_hmac_update(struct orig_hmac_context *_ctx, const void *data, size_t size) + { +- struct hmac_context_priv *ctx = &_ctx->u.priv; ++ struct orig_hmac_context_priv *ctx = &_ctx->u.priv; + + ctx->hash->loop(ctx->ctx, data, size); + } + +-buffer_t *t_hmac_data(const struct hash_method *meth, ++buffer_t *openssl_t_hmac_data(const struct hash_method *meth, + const unsigned char *key, size_t key_len, + const void *data, size_t data_len); +-buffer_t *t_hmac_buffer(const struct hash_method *meth, ++buffer_t *openssl_t_hmac_buffer(const struct hash_method *meth, + const unsigned char *key, size_t key_len, + const buffer_t *data); +-buffer_t *t_hmac_str(const struct hash_method *meth, ++buffer_t *openssl_t_hmac_str(const struct hash_method *meth, + const unsigned char *key, size_t key_len, + const char *data); + +-void hmac_hkdf(const struct hash_method *method, ++void openssl_hmac_hkdf(const struct hash_method *method, + const unsigned char *salt, size_t salt_len, + const unsigned char *ikm, size_t ikm_len, + const unsigned char *info, size_t info_len, + buffer_t *okm_r, size_t okm_len); + + static inline buffer_t * +-t_hmac_hkdf(const struct hash_method *method, ++openssl_t_hmac_hkdf(const struct hash_method *method, + const unsigned char *salt, size_t salt_len, + const unsigned char *ikm, size_t ikm_len, + const unsigned char *info, size_t info_len, + size_t okm_len) + { + buffer_t *okm_buffer = t_buffer_create(okm_len); +- hmac_hkdf(method, salt, salt_len, ikm, ikm_len, info, info_len, ++ openssl_hmac_hkdf(method, salt, salt_len, ikm, ikm_len, info, info_len, + okm_buffer, okm_len); + return okm_buffer; + } +diff -up dovecot-2.3.18/src/lib-imap-urlauth/imap-urlauth.c.opensslhmac dovecot-2.3.18/src/lib-imap-urlauth/imap-urlauth.c +--- dovecot-2.3.18/src/lib-imap-urlauth/imap-urlauth.c.opensslhmac 2022-02-02 12:42:23.000000000 +0100 ++++ dovecot-2.3.18/src/lib-imap-urlauth/imap-urlauth.c 2022-02-09 09:27:15.888883345 +0100 +@@ -85,15 +85,15 @@ imap_urlauth_internal_generate(const cha + const unsigned char mailbox_key[IMAP_URLAUTH_KEY_LEN], + size_t *token_len_r) + { +- struct hmac_context hmac; ++ struct openssl_hmac_context hmac; + unsigned char *token; + + token = t_new(unsigned char, SHA1_RESULTLEN + 1); + token[0] = IMAP_URLAUTH_MECH_INTERNAL_VERSION; + +- hmac_init(&hmac, mailbox_key, IMAP_URLAUTH_KEY_LEN, &hash_method_sha1); +- hmac_update(&hmac, rumpurl, strlen(rumpurl)); +- hmac_final(&hmac, token+1); ++ openssl_hmac_init(&hmac, mailbox_key, IMAP_URLAUTH_KEY_LEN, &hash_method_sha1); ++ openssl_hmac_update(&hmac, rumpurl, strlen(rumpurl)); ++ openssl_hmac_final(&hmac, token+1); + + *token_len_r = SHA1_RESULTLEN + 1; + return token; +diff -up dovecot-2.3.18/src/lib/Makefile.am.opensslhmac dovecot-2.3.18/src/lib/Makefile.am +--- dovecot-2.3.18/src/lib/Makefile.am.opensslhmac 2022-02-02 12:42:23.000000000 +0100 ++++ dovecot-2.3.18/src/lib/Makefile.am 2022-02-09 09:27:15.889883331 +0100 +@@ -354,6 +354,9 @@ headers = \ + wildcard-match.h \ + write-full.h + ++liblib_la_LIBADD = $(SSL_LIBS) ++liblib_la_CFLAGS = $(SSL_CFLAGS) ++ + test_programs = test-lib + noinst_PROGRAMS = $(test_programs) + +diff -up dovecot-2.3.18/src/lib-oauth2/oauth2-jwt.c.opensslhmac dovecot-2.3.18/src/lib-oauth2/oauth2-jwt.c +--- dovecot-2.3.18/src/lib-oauth2/oauth2-jwt.c.opensslhmac 2022-02-02 12:42:23.000000000 +0100 ++++ dovecot-2.3.18/src/lib-oauth2/oauth2-jwt.c 2022-02-09 09:27:15.889883331 +0100 +@@ -144,14 +144,14 @@ oauth2_validate_hmac(const struct oauth2 + if (oauth2_lookup_hmac_key(set, azp, alg, key_id, &key, error_r) < 0) + return -1; + +- struct hmac_context ctx; +- hmac_init(&ctx, key->data, key->used, method); +- hmac_update(&ctx, blobs[0], strlen(blobs[0])); +- hmac_update(&ctx, ".", 1); +- hmac_update(&ctx, blobs[1], strlen(blobs[1])); ++ struct openssl_hmac_context ctx; ++ openssl_hmac_init(&ctx, key->data, key->used, method); ++ openssl_hmac_update(&ctx, blobs[0], strlen(blobs[0])); ++ openssl_hmac_update(&ctx, ".", 1); ++ openssl_hmac_update(&ctx, blobs[1], strlen(blobs[1])); + unsigned char digest[method->digest_size]; + +- hmac_final(&ctx, digest); ++ openssl_hmac_final(&ctx, digest); + + buffer_t *their_digest = + t_base64url_decode_str(BASE64_DECODE_FLAG_NO_PADDING, blobs[2]); +diff -up dovecot-2.3.18/src/lib-oauth2/test-oauth2-jwt.c.opensslhmac dovecot-2.3.18/src/lib-oauth2/test-oauth2-jwt.c +--- dovecot-2.3.18/src/lib-oauth2/test-oauth2-jwt.c.opensslhmac 2022-02-02 12:42:23.000000000 +0100 ++++ dovecot-2.3.18/src/lib-oauth2/test-oauth2-jwt.c 2022-02-09 09:27:15.889883331 +0100 +@@ -248,7 +248,7 @@ static void save_key_azp_to(const char * + static void sign_jwt_token_hs256(buffer_t *tokenbuf, buffer_t *key) + { + i_assert(key != NULL); +- buffer_t *sig = t_hmac_buffer(&hash_method_sha256, key->data, key->used, ++ buffer_t *sig = openssl_t_hmac_buffer(&hash_method_sha256, key->data, key->used, + tokenbuf); + buffer_append(tokenbuf, ".", 1); + base64url_encode(BASE64_ENCODE_FLAG_NO_PADDING, SIZE_MAX, +@@ -258,7 +258,7 @@ static void sign_jwt_token_hs256(buffer_ + static void sign_jwt_token_hs384(buffer_t *tokenbuf, buffer_t *key) + { + i_assert(key != NULL); +- buffer_t *sig = t_hmac_buffer(&hash_method_sha384, key->data, key->used, ++ buffer_t *sig = openssl_t_hmac_buffer(&hash_method_sha384, key->data, key->used, + tokenbuf); + buffer_append(tokenbuf, ".", 1); + base64url_encode(BASE64_ENCODE_FLAG_NO_PADDING, SIZE_MAX, +@@ -268,7 +268,7 @@ static void sign_jwt_token_hs384(buffer_ + static void sign_jwt_token_hs512(buffer_t *tokenbuf, buffer_t *key) + { + i_assert(key != NULL); +- buffer_t *sig = t_hmac_buffer(&hash_method_sha512, key->data, key->used, ++ buffer_t *sig = openssl_t_hmac_buffer(&hash_method_sha512, key->data, key->used, + tokenbuf); + buffer_append(tokenbuf, ".", 1); + base64url_encode(BASE64_ENCODE_FLAG_NO_PADDING, SIZE_MAX, +diff -up dovecot-2.3.18/src/lib/pkcs5.c.opensslhmac dovecot-2.3.18/src/lib/pkcs5.c +--- dovecot-2.3.18/src/lib/pkcs5.c.opensslhmac 2022-02-02 12:42:23.000000000 +0100 ++++ dovecot-2.3.18/src/lib/pkcs5.c 2022-02-09 09:27:15.889883331 +0100 +@@ -52,7 +52,7 @@ int pkcs5_pbkdf2(const struct hash_metho + size_t l = (length + hash->digest_size - 1)/hash->digest_size; /* same as ceil(length/hash->digest_size) */ + unsigned char dk[l * hash->digest_size]; + unsigned char *block; +- struct hmac_context hctx; ++ struct openssl_hmac_context hctx; + unsigned int c,i,t; + unsigned char U_c[hash->digest_size]; + +@@ -60,17 +60,17 @@ int pkcs5_pbkdf2(const struct hash_metho + block = &(dk[t*hash->digest_size]); + /* U_1 = PRF(Password, Salt|| INT_BE32(Block_Number)) */ + c = htonl(t+1); +- hmac_init(&hctx, password, password_len, hash); +- hmac_update(&hctx, salt, salt_len); +- hmac_update(&hctx, &c, sizeof(c)); +- hmac_final(&hctx, U_c); ++ openssl_hmac_init(&hctx, password, password_len, hash); ++ openssl_hmac_update(&hctx, salt, salt_len); ++ openssl_hmac_update(&hctx, &c, sizeof(c)); ++ openssl_hmac_final(&hctx, U_c); + /* block = U_1 ^ .. ^ U_iter */ + memcpy(block, U_c, hash->digest_size); + /* U_c = PRF(Password, U_c-1) */ + for(c = 1; c < iter; c++) { +- hmac_init(&hctx, password, password_len, hash); +- hmac_update(&hctx, U_c, hash->digest_size); +- hmac_final(&hctx, U_c); ++ openssl_hmac_init(&hctx, password, password_len, hash); ++ openssl_hmac_update(&hctx, U_c, hash->digest_size); ++ openssl_hmac_final(&hctx, U_c); + for(i = 0; i < hash->digest_size; i++) + block[i] ^= U_c[i]; + } +diff -up dovecot-2.3.18/src/lib/test-hmac.c.opensslhmac dovecot-2.3.18/src/lib/test-hmac.c +--- dovecot-2.3.18/src/lib/test-hmac.c.opensslhmac 2022-02-02 12:42:23.000000000 +0100 ++++ dovecot-2.3.18/src/lib/test-hmac.c 2022-02-09 09:27:15.889883331 +0100 +@@ -206,11 +206,11 @@ static void test_hmac_rfc(void) + test_begin("hmac sha256 rfc4231 vectors"); + for(size_t i = 0; i < N_ELEMENTS(test_vectors); i++) { + const struct test_vector *vec = &(test_vectors[i]); +- struct hmac_context ctx; +- hmac_init(&ctx, vec->key, vec->key_len, hash_method_lookup(vec->prf)); +- hmac_update(&ctx, vec->data, vec->data_len); ++ struct openssl_hmac_context ctx; ++ openssl_hmac_init(&ctx, vec->key, vec->key_len, hash_method_lookup(vec->prf)); ++ openssl_hmac_update(&ctx, vec->data, vec->data_len); + unsigned char res[SHA256_RESULTLEN]; +- hmac_final(&ctx, res); ++ openssl_hmac_final(&ctx, res); + test_assert_idx(memcmp(res, vec->res, vec->res_len) == 0, i); + } + test_end(); +@@ -221,11 +221,11 @@ static void test_hmac384_rfc(void) + test_begin("hmac sha384 rfc4231 vectors"); + for (size_t i = 0; i < N_ELEMENTS(test_vectors_hmac384); i++) { + const struct test_vector *vec = &(test_vectors_hmac384[i]); +- struct hmac_context ctx; +- hmac_init(&ctx, vec->key, vec->key_len, hash_method_lookup(vec->prf)); +- hmac_update(&ctx, vec->data, vec->data_len); ++ struct openssl_hmac_context ctx; ++ openssl_hmac_init(&ctx, vec->key, vec->key_len, hash_method_lookup(vec->prf)); ++ openssl_hmac_update(&ctx, vec->data, vec->data_len); + unsigned char res[SHA384_RESULTLEN]; +- hmac_final(&ctx, res); ++ openssl_hmac_final(&ctx, res); + test_assert_idx(memcmp(res, vec->res, vec->res_len) == 0, i); + } + test_end(); +@@ -236,11 +236,11 @@ static void test_hmac512_rfc(void) + test_begin("hmac sha512 rfc4231 vectors"); + for (size_t i = 0; i < N_ELEMENTS(test_vectors_hmac512); i++) { + const struct test_vector *vec = &(test_vectors_hmac512[i]); +- struct hmac_context ctx; +- hmac_init(&ctx, vec->key, vec->key_len, hash_method_lookup(vec->prf)); +- hmac_update(&ctx, vec->data, vec->data_len); ++ struct openssl_hmac_context ctx; ++ openssl_hmac_init(&ctx, vec->key, vec->key_len, hash_method_lookup(vec->prf)); ++ openssl_hmac_update(&ctx, vec->data, vec->data_len); + unsigned char res[SHA512_RESULTLEN]; +- hmac_final(&ctx, res); ++ openssl_hmac_final(&ctx, res); + test_assert_idx(memcmp(res, vec->res, vec->res_len) == 0, i); + } + test_end(); +@@ -253,7 +253,7 @@ static void test_hmac_buffer(void) + + buffer_t *tmp; + +- tmp = t_hmac_data(hash_method_lookup(vec->prf), vec->key, vec->key_len, ++ tmp = openssl_t_hmac_data(hash_method_lookup(vec->prf), vec->key, vec->key_len, + vec->data, vec->data_len); + + test_assert(tmp->used == vec->res_len && +@@ -270,7 +270,7 @@ static void test_hkdf_rfc(void) + buffer_set_used_size(res, 0); + const struct test_vector_5869 *vec = &(test_vectors_5869[i]); + const struct hash_method *m = hash_method_lookup(vec->prf); +- hmac_hkdf(m, vec->salt, vec->salt_len, vec->ikm, vec->ikm_len, ++ openssl_hmac_hkdf(m, vec->salt, vec->salt_len, vec->ikm, vec->ikm_len, + vec->info, vec->info_len, res, vec->okm_len); + test_assert_idx(memcmp(res->data, vec->okm, vec->okm_len) == 0, i); + } +@@ -283,7 +283,7 @@ static void test_hkdf_buffer(void) + test_begin("hkdf temporary buffer"); + const struct test_vector_5869 *vec = &(test_vectors_5869[0]); + const struct hash_method *m = hash_method_lookup(vec->prf); +- buffer_t *tmp = t_hmac_hkdf(m, vec->salt, vec->salt_len, vec->ikm, ++ buffer_t *tmp = openssl_t_hmac_hkdf(m, vec->salt, vec->salt_len, vec->ikm, + vec->ikm_len, vec->info, vec->info_len, + vec->okm_len); + test_assert(tmp->used == vec->okm_len && diff --git a/SOURCES/dovecot-configure-c99.patch b/SOURCES/dovecot-configure-c99.patch new file mode 100644 index 0000000..17a49fe --- /dev/null +++ b/SOURCES/dovecot-configure-c99.patch @@ -0,0 +1,25 @@ +m4: crypt_xxpg6.m4: Define _DEFAULT_SOURCE for current glibc + +Current glibc no longer implements the CRYPT extension, so it does not +declare crypt in in strict standard modes. The check +defines _XOPEN_SOURCE, which enables one of these modes. Defining +_DEFAULT_SOURCE as well again makes available the crypt function +prototype. + +This avoids a configure check result change with compilers which do +not support implicit function declarations. + +Submitted upstream: + +diff --git a/m4/crypt_xpg6.m4 b/m4/crypt_xpg6.m4 +index 0085b2ac76..3a288a3713 100644 +--- a/m4/crypt_xpg6.m4 ++++ b/m4/crypt_xpg6.m4 +@@ -6,6 +6,7 @@ AC_DEFUN([DOVECOT_CRYPT_XPG6], [ + #define _XOPEN_SOURCE 4 + #define _XOPEN_SOURCE_EXTENDED 1 + #define _XOPEN_VERSION 4 ++ #define _DEFAULT_SOURCE + #define _XPG4_2 + #define _XPG6 + #include diff --git a/SOURCES/dovecot.conf.5 b/SOURCES/dovecot.conf.5 new file mode 100644 index 0000000..a15f1f6 --- /dev/null +++ b/SOURCES/dovecot.conf.5 @@ -0,0 +1,19 @@ +.TH DOVECOT.CONF 5 2010/06/27 "dovecot" "File Formats and Conventions" +.SH NAME +\fBdovecot.conf\fP \- The configuration file for dovecot imap and pop3 server + +.SH FULL PATH +.B /etc/dovecot.conf + +.SH DESCRIPTION +The dovecot.conf file is a configuration file for the +.BR dovecot (1) +imap and pop3 server. The dovecot.conf configuration file contains description to all available options. Some of these options are described also in offline wiki documentation placed in /usr/share/doc/dovecot*/wiki/. + +For backup purposes unmodified version of dovecot.conf can be found in /usr/share/doc/dovecot-/example-config/dovecot.conf.default + +.SH "SEE ALSO" +.BR doveadm (1), +.BR dovecot (1), +.I /usr/share/doc/dovecot*/wiki/ +.I /usr/share/doc/dovecot*/dovecot.conf.default diff --git a/SOURCES/dovecot.init b/SOURCES/dovecot.init new file mode 100755 index 0000000..49206f0 --- /dev/null +++ b/SOURCES/dovecot.init @@ -0,0 +1,108 @@ +#!/bin/bash +# +# /etc/rc.d/init.d/dovecot +# +# Starts the dovecot daemon +# +# chkconfig: - 65 35 +# description: Dovecot Imap Server +# processname: dovecot +# config: /etc/dovecot.conf +# config: /etc/sysconfig/dovecot +# pidfile: /var/run/dovecot/master.pid + +### BEGIN INIT INFO +# Provides: dovecot +# Required-Start: $local_fs $network +# Required-Stop: $local_fs $network +# Should-Start: $remote_fs +# Should-Stop: $remote_fs +# Default-Start: +# Default-Stop: 0 1 2 3 4 5 6 +# Short-Description: start and stop Dovecot Imap server +# Description: Dovecot is an IMAP server for Linux/UNIX-like systems, +# written with security primarily in mind. It also contains +# a small POP3 server. +### END INIT INFO + +# Source function library. +. /etc/init.d/functions + +if [ -f /etc/sysconfig/dovecot -a $UID -eq 0 ]; then + . /etc/sysconfig/dovecot +fi + +RETVAL=0 +prog="Dovecot Imap" +exec="/usr/sbin/dovecot" +config="/etc/dovecot/dovecot.conf" +pidfile="/var/run/dovecot/master.pid" +lockfile="/var/lock/subsys/dovecot" + +start() { + [ $UID -eq 0 ] || exit 4 + [ -x $exec ] || exit 5 + [ -f $config ] || exit 6 + + echo -n $"Starting $prog: " + daemon --pidfile $pidfile $exec $OPTIONS + RETVAL=$? + [ $RETVAL -eq 0 ] && touch $lockfile + echo +} + +stop() { + [ $UID -eq 0 ] || exit 4 + echo -n $"Stopping $prog: " + killproc -p $pidfile $exec + RETVAL=$? + [ $RETVAL -eq 0 ] && rm -f $lockfile + echo +} + +reload() { + [ $UID -eq 0 ] || exit 4 + echo -n $"Reloading $prog: " + killproc -p $pidfile $exec -HUP + RETVAL=$? + echo +} + +# +# See how we were called. +# +case "$1" in + start) + start + ;; + stop) + stop + ;; + reload) + reload + ;; + force-reload|restart) + stop + sleep 1 + start + RETVAL=$? + ;; + condrestart|try-restart) + if [ -f $lockfile ]; then + stop + sleep 3 + start + fi + ;; + status) + status -p $pidfile $exec + RETVAL=$? + ;; + *) + echo $"Usage: $0 {condrestart|try-restart|start|stop|restart|reload|force-reload|status}" + RETVAL=2 + [ "$1" = 'usage' ] && RETVAL=0 +esac + +exit $RETVAL + diff --git a/SOURCES/dovecot.pam b/SOURCES/dovecot.pam new file mode 100644 index 0000000..5b9f05f --- /dev/null +++ b/SOURCES/dovecot.pam @@ -0,0 +1,5 @@ +#%PAM-1.0 +auth required pam_nologin.so +auth include password-auth +account include password-auth +session include password-auth diff --git a/SOURCES/dovecot.sysconfig b/SOURCES/dovecot.sysconfig new file mode 100644 index 0000000..3cb4bd4 --- /dev/null +++ b/SOURCES/dovecot.sysconfig @@ -0,0 +1,3 @@ +# Here you can specify your dovecot command line options. +# +#OPTIONS="" diff --git a/SOURCES/dovecot.sysusers b/SOURCES/dovecot.sysusers new file mode 100644 index 0000000..c286ee4 --- /dev/null +++ b/SOURCES/dovecot.sysusers @@ -0,0 +1,9 @@ +#Type Name ID GECOS Home directory Shell +g dovecot 97 +u dovecot 97 "Dovecot IMAP server" /usr/libexec/dovecot /sbin/nologin +m dovecot dovecot + +g dovenull - +u dovenull - "Dovecot - unauthorized user" /usr/libexec/dovecot /sbin/nologin +m dovenull dovenull + diff --git a/SOURCES/dovecot.tmpfilesd b/SOURCES/dovecot.tmpfilesd new file mode 100644 index 0000000..d96639a --- /dev/null +++ b/SOURCES/dovecot.tmpfilesd @@ -0,0 +1,2 @@ +d /run/dovecot 0755 root dovecot - + diff --git a/SOURCES/prestartscript b/SOURCES/prestartscript new file mode 100644 index 0000000..0c5492c --- /dev/null +++ b/SOURCES/prestartscript @@ -0,0 +1,3 @@ +#!/bin/sh +/bin/systemctl -q is-enabled NetworkManager.service >/dev/null 2>&1 && /usr/bin/nm-online -q --timeout 30 ||: + diff --git a/SPECS/dovecot.spec b/SPECS/dovecot.spec new file mode 100644 index 0000000..af577ad --- /dev/null +++ b/SPECS/dovecot.spec @@ -0,0 +1,2768 @@ +%global __provides_exclude_from %{_docdir} +%global __requires_exclude_from %{_docdir} + +Summary: Secure imap and pop3 server +Name: dovecot +Epoch: 1 +Version: 2.3.21 +%global prever %{nil} +Release: 14%{?dist} +#dovecot itself is MIT, a few sources are PD, pigeonhole is LGPLv2 +License: MIT AND LGPL-2.1-only + +URL: https://www.dovecot.org/ +Source: https://www.dovecot.org/releases/2.3/%{name}-%{version}%{?prever}.tar.gz +Source1: dovecot.init +Source2: dovecot.pam +%global pigeonholever 0.5.21 +Source8: https://pigeonhole.dovecot.org/releases/2.3/dovecot-2.3-pigeonhole-%{pigeonholever}.tar.gz +Source9: dovecot.sysconfig +Source10: dovecot.tmpfilesd + +#our own +Source14: dovecot.conf.5 +Source15: prestartscript +Source16: dovecot.sysusers + +# 3x Fedora/RHEL specific +Patch1: dovecot-2.0-defaultconfig.patch +Patch2: dovecot-1.0.beta2-mkcert-permissions.patch +Patch3: dovecot-1.0.rc7-mkcert-paths.patch + +#wait for network +Patch6: dovecot-2.1.10-waitonline.patch + +Patch8: dovecot-2.2.20-initbysystemd.patch +Patch9: dovecot-2.2.22-systemd_w_protectsystem.patch +Patch10: dovecot-2.3.0.1-libxcrypt.patch +Patch15: dovecot-2.3.11-bigkey.patch + +# do not use own implementation of HMAC, use OpenSSL for certification purposes +# not sent upstream as proper fix would use dovecot's lib-dcrypt but it introduces +# hard to break circular dependency between lib and lib-dcrypt +Patch16: dovecot-2.3.6-opensslhmac.patch + +# FTBFS +Patch17: dovecot-2.3.15-fixvalcond.patch +Patch18: dovecot-2.3.15-valbasherr.patch +Patch20: dovecot-2.3.14-opensslv3.patch +Patch21: dovecot-2.3.19.1-7bad6a24.patch +Patch22: dovecot-configure-c99.patch + +# Fedora/RHEL specific, drop OTP which uses SHA1 so we dont use SHA1 for crypto purposes +Patch23: dovecot-2.3.20-nolibotp.patch + +# adapted from 2.4 dovecot, issue #RHEL-33733 +Patch24: dovecot-2.3.21-noengine.patch + +# sent upstream, issue #RHEL-52541 +Patch25: dovecot-2.3-ph_optglob.patch +Patch26: dovecot-2.3-ph_scriptcmp.patch + +# fix test failing due to too long path with all the mock path prefixes +Patch27: dovecot-2.3.21-test-socket-path.patch + +# from upstream for < 2.3.21.1, RHEL-55205 +# https://github.com/dovecot/core/compare/8e4c42d%5E...1481c04.patch +Patch28: dovecot-2.3.21.1-CVE-2024-23184.patch + +# from upstream for < 2.3.21.1, RHEL-55218 +# https://github.com/dovecot/core/compare/f020e13%5E...ce88c33.patch +Patch29: dovecot-2.3.21.1-CVE-2024-23185.patch + +BuildRequires: gcc, gcc-c++, openssl-devel, pam-devel, zlib-devel, bzip2-devel, libcap-devel +BuildRequires: libtool, autoconf, automake, pkgconfig +BuildRequires: sqlite-devel +BuildRequires: libpq-devel +BuildRequires: mariadb-connector-c-devel +BuildRequires: libxcrypt-devel +BuildRequires: openldap-devel +BuildRequires: krb5-devel +BuildRequires: quota-devel +BuildRequires: xz-devel +BuildRequires: lz4-devel +BuildRequires: libzstd-devel +%if %{?rhel}0 == 0 +BuildRequires: libsodium-devel +BuildRequires: lua-devel +%endif +BuildRequires: libicu-devel +%if 0%{?rhel} == 0 && 0%{?fedora}0 < 38 +BuildRequires: libexttextcat-devel +BuildRequires: clucene-core-devel +%endif +BuildRequires: multilib-rpm-config +BuildRequires: flex, bison +BuildRequires: systemd-devel +BuildRequires: systemd-rpm-macros + +# gettext-devel is needed for running autoconf because of the +# presence of AM_ICONV +BuildRequires: gettext-devel + +# Explicit Runtime Requirements for executalbe +Requires: openssl >= 0.9.7f-4 + +# Package includes an initscript service file, needs to require initscripts package +Requires(pre): shadow-utils +Requires: systemd +Requires(post): systemd-units +Requires(preun): systemd-units +Requires(postun): systemd-units + +%global ssldir %{_sysconfdir}/pki/%{name} + +BuildRequires: libcurl-devel expat-devel +BuildRequires: make + +%global restart_flag /run/%{name}/%{name}-restart-after-rpm-install + +%description +Dovecot is an IMAP server for Linux/UNIX-like systems, written with security +primarily in mind. It also contains a small POP3 server. It supports mail +in either of maildir or mbox formats. + +The SQL drivers and authentication plug-ins are in their subpackages. + +%package pigeonhole +Requires: %{name} = %{epoch}:%{version}-%{release} +Summary: Sieve and managesieve plug-in for dovecot +License: MIT AND LGPL-2.1-only + +%description pigeonhole +This package provides sieve and managesieve plug-in for dovecot LDA. + +%package pgsql +Requires: %{name} = %{epoch}:%{version}-%{release} +Summary: Postgres SQL back end for dovecot +%description pgsql +This package provides the Postgres SQL back end for dovecot-auth etc. + +%package mysql +Requires: %{name} = %{epoch}:%{version}-%{release} +Summary: MySQL back end for dovecot +%description mysql +This package provides the MySQL back end for dovecot-auth etc. + +%package devel +Requires: %{name} = %{epoch}:%{version}-%{release} +Summary: Development files for dovecot +%description devel +This package provides the development files for dovecot. + +%prep +%setup -q -n %{name}-%{version}%{?prever} -a 8 + +# standardize name, so we don't have to update patches and scripts +mv dovecot-2.3-pigeonhole-%{pigeonholever} dovecot-pigeonhole + +%patch -P 1 -p1 -b .default-settings +%patch -P 2 -p1 -b .mkcert-permissions +%patch -P 3 -p1 -b .mkcert-paths +%patch -P 6 -p1 -b .waitonline +%patch -P 8 -p1 -b .initbysystemd +%patch -P 9 -p1 -b .systemd_w_protectsystem +%patch -P 15 -p1 -b .bigkey +%patch -P 16 -p1 -b .opensslhmac +%patch -P 17 -p1 -b .fixvalcond +%patch -P 18 -p1 -b .valbasherr +%patch -P 20 -p1 -b .opensslv3 +%patch -P 21 -p1 -b .7bad6a24 +%patch -P 22 -p1 -b .c99 +%patch -P 23 -p1 -b .nolibotp +%patch -P 24 -p1 -b .noengine +%patch -P 25 -p1 -b .ph_optglob +%patch -P 26 -p1 -b .ph_scriptcmp +%patch -P 27 -p1 -b .test-socket-path +%patch -P 28 -p1 -b .CVE-2024-23184 +%patch -P 29 -p1 -b .CVE-2024-23185 +cp run-test-valgrind.supp dovecot-pigeonhole/ +# valgrind would fail with shell wrapper +echo "testsuite" >dovecot-pigeonhole/run-test-valgrind.exclude + +#pushd dovecot-pigeonhole +#popd +%if 0%{?rhel} == 0 && 0%{?fedora}0 < 38 +sed -i '/DEFAULT_INCLUDES *=/s|$| '"$(pkg-config --cflags libclucene-core)|" src/plugins/fts-lucene/Makefile.in +%endif + + +# drop OTP which uses SHA1 so we dont use SHA1 for crypto purposes +rm -rf src/lib-otp + +%build +#required for fdpass.c line 125,190: dereferencing type-punned pointer will break strict-aliasing rules +%global _hardened_build 1 +export CFLAGS="%{__global_cflags} -fno-strict-aliasing -fstack-reuse=none" +export LDFLAGS="-Wl,-z,now -Wl,-z,relro %{?__global_ldflags}" +mkdir -p m4 +autoreconf -I . -fiv #required for aarch64 support +%configure \ + INSTALL_DATA="install -c -p -m644" \ + --with-rundir=%{_rundir}/%{name} \ + --with-systemd \ + --docdir=%{_docdir}/%{name} \ + --disable-static \ + --disable-rpath \ + --with-nss \ + --with-shadow \ + --with-pam \ + --with-gssapi=plugin \ + --with-ldap=plugin \ + --with-sql=plugin \ + --with-pgsql \ + --with-mysql \ + --with-sqlite \ + --with-zlib \ + --with-zstd \ + --with-libcap \ + --with-icu \ +%if %{?rhel}0 == 0 + --with-lua=plugin \ +%endif +%if 0%{?rhel} == 0 && 0%{?fedora}0 < 38 + --with-lucene \ + --with-exttextcat \ +%else + --without-lucene \ + --without-exttextcat \ +%endif + --without-libstemmer \ + --with-ssl=openssl \ + --with-ssldir=%{ssldir} \ + --with-solr \ + --with-docs \ + systemdsystemunitdir=%{_unitdir} + +sed -i 's|/etc/ssl|/etc/pki/dovecot|' doc/mkcert.sh doc/example-config/conf.d/10-ssl.conf + +%make_build + +#pigeonhole +pushd dovecot-pigeonhole + +# required for snapshot +[ -f configure ] || autoreconf -fiv +[ -f ChangeLog ] || echo "Pigeonhole ChangeLog is not available, yet" >ChangeLog + +%configure \ + INSTALL_DATA="install -c -p -m644" \ + --disable-static \ + --with-dovecot=../ \ + --without-unfinished-features + +%make_build +popd + +%install +rm -rf $RPM_BUILD_ROOT + +%make_install + +# move doc dir back to build dir so doc macro in files section can use it +mv $RPM_BUILD_ROOT/%{_docdir}/%{name} %{_builddir}/%{name}-%{version}%{?prever}/docinstall + +# fix multilib issues +%multilib_fix_c_header --file %{_includedir}/dovecot/config.h + +pushd dovecot-pigeonhole +%make_install + +mv $RPM_BUILD_ROOT/%{_docdir}/%{name} $RPM_BUILD_ROOT/%{_docdir}/%{name}-pigeonhole + +install -m 644 AUTHORS ChangeLog COPYING COPYING.LGPL INSTALL NEWS README $RPM_BUILD_ROOT/%{_docdir}/%{name}-pigeonhole +popd + +install -p -D -m 644 %{SOURCE2} $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/dovecot + +#install man pages +install -p -D -m 644 %{SOURCE14} $RPM_BUILD_ROOT%{_mandir}/man5/dovecot.conf.5 + +#install waitonline script +install -p -D -m 755 %{SOURCE15} $RPM_BUILD_ROOT%{_libexecdir}/dovecot/prestartscript + +install -p -D -m 0644 %{SOURCE16} $RPM_BUILD_ROOT%{_sysusersdir}/dovecot.sysusers + +# generate ghost .pem files +mkdir -p $RPM_BUILD_ROOT%{ssldir}/certs +mkdir -p $RPM_BUILD_ROOT%{ssldir}/private +touch $RPM_BUILD_ROOT%{ssldir}/certs/dovecot.pem +chmod 600 $RPM_BUILD_ROOT%{ssldir}/certs/dovecot.pem +touch $RPM_BUILD_ROOT%{ssldir}/private/dovecot.pem +chmod 600 $RPM_BUILD_ROOT%{ssldir}/private/dovecot.pem + +install -p -D -m 644 %{SOURCE10} $RPM_BUILD_ROOT%{_tmpfilesdir}/dovecot.conf + +mkdir -p $RPM_BUILD_ROOT/run/dovecot/{login,empty,token-login} + +# Install dovecot configuration and dovecot-openssl.cnf +mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/dovecot/conf.d +install -p -m 644 docinstall/example-config/dovecot.conf $RPM_BUILD_ROOT%{_sysconfdir}/dovecot +install -p -m 644 docinstall/example-config/conf.d/*.conf $RPM_BUILD_ROOT%{_sysconfdir}/dovecot/conf.d +install -p -m 644 $RPM_BUILD_ROOT/%{_docdir}/%{name}-pigeonhole/example-config/conf.d/*.conf $RPM_BUILD_ROOT%{_sysconfdir}/dovecot/conf.d +install -p -m 644 docinstall/example-config/conf.d/*.conf.ext $RPM_BUILD_ROOT%{_sysconfdir}/dovecot/conf.d +install -p -m 644 $RPM_BUILD_ROOT/%{_docdir}/%{name}-pigeonhole/example-config/conf.d/*.conf.ext $RPM_BUILD_ROOT%{_sysconfdir}/dovecot/conf.d ||: +install -p -m 644 doc/dovecot-openssl.cnf $RPM_BUILD_ROOT%{ssldir}/dovecot-openssl.cnf + +install -p -m755 doc/mkcert.sh $RPM_BUILD_ROOT%{_libexecdir}/%{name}/mkcert.sh + +mkdir -p $RPM_BUILD_ROOT/var/lib/dovecot + +#remove the libtool archives +find $RPM_BUILD_ROOT%{_libdir}/%{name}/ -name '*.la' | xargs rm -f + +#remove what we don't want +rm -f $RPM_BUILD_ROOT%{_sysconfdir}/dovecot/README +pushd docinstall +rm -f securecoding.txt thread-refs.txt +popd + + +%pre +#dovecot uid and gid are reserved, see /usr/share/doc/setup-*/uidgid +%sysusers_create_compat %{SOURCE16} + +if [ -z "$LEAPP_IPU_IN_PROGRESS" ] +then + # during LEAPP upgrade, services are not running anyway + + # do not let dovecot run during upgrade rhbz#134325 + if [ "$1" = "2" ]; then + rm -f %restart_flag + /bin/systemctl is-active %{name}.service >/dev/null 2>&1 && touch %restart_flag ||: + /bin/systemctl stop %{name}.service >/dev/null 2>&1 + fi +fi + +%post +if [ $1 -eq 1 ] +then + %systemd_post dovecot.service +fi + +install -d -m 0755 -g dovecot -d /run/dovecot +install -d -m 0755 -d /run/dovecot/empty +install -d -m 0750 -g dovenull -d /run/dovecot/login +install -d -m 0750 -g dovenull -d /run/dovecot/token-login +[ -x /sbin/restorecon ] && /sbin/restorecon -R /run/dovecot ||: + +%preun +if [ $1 = 0 ]; then + /bin/systemctl disable dovecot.service dovecot.socket >/dev/null 2>&1 || : + /bin/systemctl stop dovecot.service dovecot.socket >/dev/null 2>&1 || : + rm -rf /run/dovecot +fi + +%postun +if [ -z "$LEAPP_IPU_IN_PROGRESS" ] +then + # during LEAPP upgrade, services are not running anyway + /bin/systemctl daemon-reload >/dev/null 2>&1 || : + + if [ "$1" -ge "1" -a -e %restart_flag ]; then + /bin/systemctl start dovecot.service >/dev/null 2>&1 || : + rm -f %restart_flag + fi +fi + +%posttrans + +if [ -z "$LEAPP_IPU_IN_PROGRESS" ] +then + # during LEAPP upgrade, services are not running anyway + + # dovecot should be started again in %%postun, but it's not executed on reinstall + # if it was already started, restart_flag won't be here, so it's ok to test it again + if [ -e %restart_flag ]; then + /bin/systemctl start dovecot.service >/dev/null 2>&1 || : + rm -f %restart_flag + fi +fi + +%check +%ifnarch aarch64 +# some aarch64 tests timeout, skip for now +make check +cd dovecot-pigeonhole +make check +%endif + +%files +%doc docinstall/* AUTHORS ChangeLog COPYING COPYING.LGPL COPYING.MIT NEWS README +%{_sbindir}/dovecot + +%{_bindir}/doveadm +%{_bindir}/doveconf +%{_bindir}/dsync +%{_bindir}/dovecot-sysreport + + +%_tmpfilesdir/dovecot.conf +%{_sysusersdir}/dovecot.sysusers +%{_unitdir}/dovecot.service +%{_unitdir}/dovecot-init.service +%{_unitdir}/dovecot.socket + +%dir %{_sysconfdir}/dovecot +%dir %{_sysconfdir}/dovecot/conf.d +%config(noreplace) %{_sysconfdir}/dovecot/dovecot.conf +#list all so we'll be noticed if upstream changes anything +%config(noreplace) %{_sysconfdir}/dovecot/conf.d/10-auth.conf +%config(noreplace) %{_sysconfdir}/dovecot/conf.d/10-director.conf +%config(noreplace) %{_sysconfdir}/dovecot/conf.d/10-logging.conf +%config(noreplace) %{_sysconfdir}/dovecot/conf.d/10-mail.conf +%config(noreplace) %{_sysconfdir}/dovecot/conf.d/10-master.conf +%config(noreplace) %{_sysconfdir}/dovecot/conf.d/10-metrics.conf +%config(noreplace) %{_sysconfdir}/dovecot/conf.d/10-ssl.conf +%config(noreplace) %{_sysconfdir}/dovecot/conf.d/15-lda.conf +%config(noreplace) %{_sysconfdir}/dovecot/conf.d/15-mailboxes.conf +%config(noreplace) %{_sysconfdir}/dovecot/conf.d/20-imap.conf +%config(noreplace) %{_sysconfdir}/dovecot/conf.d/20-lmtp.conf +%config(noreplace) %{_sysconfdir}/dovecot/conf.d/20-pop3.conf +%config(noreplace) %{_sysconfdir}/dovecot/conf.d/20-submission.conf +%config(noreplace) %{_sysconfdir}/dovecot/conf.d/90-acl.conf +%config(noreplace) %{_sysconfdir}/dovecot/conf.d/90-quota.conf +%config(noreplace) %{_sysconfdir}/dovecot/conf.d/90-plugin.conf +%config(noreplace) %{_sysconfdir}/dovecot/conf.d/auth-checkpassword.conf.ext +%config(noreplace) %{_sysconfdir}/dovecot/conf.d/auth-deny.conf.ext +%config(noreplace) %{_sysconfdir}/dovecot/conf.d/auth-dict.conf.ext +%config(noreplace) %{_sysconfdir}/dovecot/conf.d/auth-ldap.conf.ext +%config(noreplace) %{_sysconfdir}/dovecot/conf.d/auth-master.conf.ext +%config(noreplace) %{_sysconfdir}/dovecot/conf.d/auth-passwdfile.conf.ext +%config(noreplace) %{_sysconfdir}/dovecot/conf.d/auth-sql.conf.ext +%config(noreplace) %{_sysconfdir}/dovecot/conf.d/auth-static.conf.ext +%config(noreplace) %{_sysconfdir}/dovecot/conf.d/auth-system.conf.ext +%config(noreplace) %{_sysconfdir}/pam.d/dovecot +%config(noreplace) %{ssldir}/dovecot-openssl.cnf + +%dir %{ssldir} +%dir %{ssldir}/certs +%dir %{ssldir}/private +%attr(0600,root,root) %ghost %config(missingok,noreplace) %verify(not md5 size mtime) %{ssldir}/certs/dovecot.pem +%attr(0600,root,root) %ghost %config(missingok,noreplace) %verify(not md5 size mtime) %{ssldir}/private/dovecot.pem + +%dir %{_libdir}/dovecot +%dir %{_libdir}/dovecot/auth +%dir %{_libdir}/dovecot/dict +%{_libdir}/dovecot/doveadm +%exclude %{_libdir}/dovecot/doveadm/*sieve* +%{_libdir}/dovecot/*.so.* +#these (*.so files) are plugins, not devel files +%{_libdir}/dovecot/*_plugin.so +%exclude %{_libdir}/dovecot/*_sieve_plugin.so +%{_libdir}/dovecot/auth/lib20_auth_var_expand_crypt.so +%{_libdir}/dovecot/auth/libauthdb_imap.so +%{_libdir}/dovecot/auth/libauthdb_ldap.so +%if %{?rhel}0 == 0 +%{_libdir}/dovecot/auth/libauthdb_lua.so +%endif +%{_libdir}/dovecot/auth/libmech_gssapi.so +%{_libdir}/dovecot/auth/libdriver_sqlite.so +%{_libdir}/dovecot/dict/libdriver_sqlite.so +%{_libdir}/dovecot/dict/libdict_ldap.so +%{_libdir}/dovecot/libdriver_sqlite.so +%{_libdir}/dovecot/libssl_iostream_openssl.so +%{_libdir}/dovecot/libfs_compress.so +%{_libdir}/dovecot/libfs_crypt.so +%{_libdir}/dovecot/libfs_mail_crypt.so +%{_libdir}/dovecot/libdcrypt_openssl.so +%{_libdir}/dovecot/lib20_var_expand_crypt.so +%{_libdir}/dovecot/old-stats/libold_stats_mail.so +%{_libdir}/dovecot/old-stats/libstats_auth.so + +%dir %{_libdir}/dovecot/settings + +%{_libexecdir}/%{name} +%exclude %{_libexecdir}/%{name}/managesieve* + +%dir %attr(0755,root,dovecot) %ghost /run/dovecot +%attr(0750,root,dovenull) %ghost /run/dovecot/login +%attr(0750,root,dovenull) %ghost /run/dovecot/token-login +%attr(0755,root,root) %ghost /run/dovecot/empty + +%attr(0750,dovecot,dovecot) /var/lib/dovecot + +%{_datadir}/%{name} + +%{_mandir}/man1/deliver.1* +%{_mandir}/man1/doveadm*.1* +%{_mandir}/man1/doveconf.1* +%{_mandir}/man1/dovecot*.1* +%{_mandir}/man1/dsync.1* +%{_mandir}/man5/dovecot.conf.5* +%{_mandir}/man7/doveadm-search-query.7* + +%files devel +%{_includedir}/dovecot +%{_datadir}/aclocal/dovecot*.m4 +%{_libdir}/dovecot/libdovecot*.so +%{_libdir}/dovecot/dovecot-config + +%files pigeonhole +%{_bindir}/sieve-dump +%{_bindir}/sieve-filter +%{_bindir}/sieve-test +%{_bindir}/sievec +%config(noreplace) %{_sysconfdir}/dovecot/conf.d/20-managesieve.conf +%config(noreplace) %{_sysconfdir}/dovecot/conf.d/90-sieve.conf +%config(noreplace) %{_sysconfdir}/dovecot/conf.d/90-sieve-extprograms.conf + +%{_docdir}/%{name}-pigeonhole + +%{_libexecdir}/%{name}/managesieve +%{_libexecdir}/%{name}/managesieve-login + +%{_libdir}/dovecot/doveadm/*sieve* +%{_libdir}/dovecot/*_sieve_plugin.so +%{_libdir}/dovecot/settings/libmanagesieve_*.so +%{_libdir}/dovecot/settings/libpigeonhole_*.so +%{_libdir}/dovecot/sieve/ + +%{_mandir}/man1/sieve-dump.1* +%{_mandir}/man1/sieve-filter.1* +%{_mandir}/man1/sieve-test.1* +%{_mandir}/man1/sievec.1* +%{_mandir}/man1/sieved.1* +%{_mandir}/man7/pigeonhole.7* + +%files mysql +%{_libdir}/%{name}/libdriver_mysql.so +%{_libdir}/%{name}/auth/libdriver_mysql.so +%{_libdir}/%{name}/dict/libdriver_mysql.so + +%files pgsql +%{_libdir}/%{name}/libdriver_pgsql.so +%{_libdir}/%{name}/auth/libdriver_pgsql.so +%{_libdir}/%{name}/dict/libdriver_pgsql.so + +%changelog +* Tue Aug 20 2024 Michal Hlavinka - 1:2.3.21-14 +- fix CVE-2024-23185: very large headers can cause resource exhaustion + when parsing message (RHEL-55218) +- fix CVE-2024-23184: using a large number of address headers may trigger + a denial of service (RHEL-55205) + +* Mon Aug 05 2024 Michal Hlavinka - 1:2.3.21-13 +- fix crash when user has sieve script that includes two missing scripts (RHEL-52541) + +* Tue Jul 23 2024 Michal Hlavinka - 1:2.3.21-12 +- fix building with noengine openssl + +* Mon Jun 24 2024 Troy Dawson - 1:2.3.21-11 +- Bump release for June 2024 mass rebuild + +* Tue Jun 18 2024 Michal Hlavinka - 1:2.3.21-10 +- set min uid to 1000 + +* Thu Jun 13 2024 Michal Hlavinka - 1:2.3.21-9 +- do not run during systemd commands during leap upgrade + +* Tue Jun 11 2024 Michal Hlavinka - 1:2.3.21-8 +- drop dependency on libstemmer (#RHEL-40657) + +* Mon May 13 2024 Michal Hlavinka - 1:2.3.21-7 +- do not use deprecated openssl v3 engine api (#RHEL-33733) + +* Wed Jan 31 2024 Pete Walter - 1:2.3.21-6 +- Rebuild for ICU 74 + +* Wed Jan 24 2024 Fedora Release Engineering - 1:2.3.21-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Fri Jan 19 2024 Fedora Release Engineering - 1:2.3.21-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Tue Oct 24 2023 Michal Hlavinka - 1:2.3.21-3 +- drop lucene to reduce dependency, use solr for fts instead + +* Thu Oct 05 2023 Remi Collet - 1:2.3.21-2 +- rebuild for new libsodium + +* Mon Sep 18 2023 Michal Hlavinka - 1:2.3.21-1 +- updated to 2.3.21(2239134) + +* Wed Jul 19 2023 Fedora Release Engineering - 1:2.3.20-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild + +* Tue Jul 11 2023 FrantiÅ¡ek Zatloukal - 1:2.3.20-5 +- Rebuilt for ICU 73.2 + +* Wed Apr 26 2023 Michal Hlavinka - 1:2.3.20-4 +- update license tag format (SPDX migration) for https://fedoraproject.org/wiki/Changes/SPDX_Licenses_Phase_1 + +* Tue Feb 14 2023 Michal Hlavinka - 1:2.3.20-3 +- drop SHA1 OTP + +* Thu Jan 19 2023 Fedora Release Engineering - 1:2.3.20-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + +* Mon Jan 02 2023 Michal Hlavinka - 1:2.3.20-1 +- updated to 2.3.20, pigeonhole to 0.5.20 + +* Mon Jan 02 2023 Florian Weimer - 1:2.3.19.1-8 +- Port configure script to C99 + +* Sat Dec 31 2022 Pete Walter - 1:2.3.19.1-7 +- Rebuild for ICU 72 + +* Tue Nov 08 2022 Michal Hlavinka - 1:2.3.19.1-6 +- use Wants=network-online.target instead of preexec nm-online (#2095949) + +* Tue Oct 11 2022 Michal Hlavinka - 1:2.3.19.1-5 +- build with lua support (#2132420) + +* Mon Aug 01 2022 Frantisek Zatloukal - 1:2.3.19.1-4 +- Rebuilt for ICU 71.1 + +* Thu Jul 21 2022 Fedora Release Engineering - 1:2.3.19.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild + +* Tue Jul 12 2022 Michal Hlavinka - 1:2.3.19.1-2 +- fix possible privilege escalation when similar master and non-master passdbs are used + +* Mon Jun 20 2022 Michal Hlavinka - 1:2.3.19.1-1 +- updated to 2.3.19.1 + +* Mon May 30 2022 Michal Hlavinka - 1:2.3.19-1 +- updated to 2.3.19, pigeonhole to 0.5.19 + +* Wed Feb 09 2022 Michal Hlavinka - 1:2.3.18-1 +- updated to 2.3.18, pigeonhole to 0.5.18 + +* Thu Jan 20 2022 Fedora Release Engineering - 1:2.3.17.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + +* Tue Dec 07 2021 Michal Hlavinka - 1:2.3.17.1-1 +- dovecot updated to 2.3.17.1, pigeonhole to 0.5.17.1 +- dsync: Add back accidentically removed parameters. +- lib-ssl-iostream: Fix assert-crash when OpenSSL returned syscall error + without errno. +- dovecot, managesieve and sieve-tool failed to run if ssl_ca was too large. + +* Tue Nov 02 2021 Michal Hlavinka - 1:2.3.17-1 +- dovecot updated to 2.3.17, pigeonhole to 0.5.17 + +* Tue Sep 28 2021 Michal Hlavinka - 1:2.3.16-4 +- reenable LTO + +* Mon Sep 27 2021 Michal Hlavinka - 1:2.3.16-3 +- fix OpenSSLv3 issues 2005884 + +* Tue Sep 14 2021 Sahana Prasad - 1:2.3.16-2 +- Rebuilt with OpenSSL 3.0.0 + +* Fri Aug 20 2021 Michal Hlavinka - 1:2.3.16-1 +- dovecot updated to 2.3.16, pigeonhole to 0.5.16 +- fixes several regressions + +* Wed Jul 21 2021 Fedora Release Engineering - 1:2.3.15-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + +* Mon Jun 21 2021 Michal Hlavinka - 1:2.3.15-1 +- dovecot updated to 2.3.15, pigeonhole updated to 0.5.15 +- CVE-2021-29157: Dovecot does not correctly escape kid and azp fields in + JWT tokens. This may be used to supply attacker controlled keys to + validate tokens, if attacker has local access. +- CVE-2021-33515: On-path attacker could have injected plaintext commands + before STARTTLS negotiation that would be executed after STARTTLS + finished with the client. +- Add TSLv1.3 support to min_protocols. +- Allow configuring ssl_cipher_suites. (for TLSv1.3+) + +* Wed May 19 2021 Pete Walter - 1:2.3.14-4 +- Rebuild for ICU 69 + +* Wed May 19 2021 Pete Walter - 1:2.3.14-3 +- Rebuild for ICU 69 + +* Mon May 10 2021 Jeff Law - 1:2.3.14-2 +- Re-enable LTO + +* Mon Mar 22 2021 Michal Hlavinka - 1:2.3.14-1 +- dovecot updated to 2.3.14, pigeonhole to 0.5.14 +- use OpenSSL's implementation of HMAC +- Remove autocreate, expire, snarf and mail-filter plugins. +- Remove cydir storage driver. +- Remove XZ/LZMA write support. Read support will be removed in future release. + +* Mon Feb 08 2021 Pavel Raiskup - 1:2.3.13-7 +- rebuild for libpq ABI fix rhbz#1908268 + +* Mon Feb 01 2021 Michal Hlavinka - 1:2.3.13-6 +- use make macros + +* Tue Jan 26 2021 Fedora Release Engineering - 1:2.3.13-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Mon Jan 18 2021 Michal Hlavinka - 1:2.3.13-4 +- fix multilib issues + +* Mon Jan 18 2021 Michal Hlavinka - 1:2.3.13-3 +- bump release and rebuild + +* Thu Jan 07 2021 Michal Hlavinka - 1:2.3.13-2 +- fix rundir location + +* Wed Jan 06 2021 Michal Hlavinka - 1:2.3.13-1 +- fix release number + +* Mon Jan 04 2021 Michal Hlavinka - 1:2.3.13-0 +- dovecot updated to 2.3.13, pigeonhole to 0.5.13 +- CVE-2020-24386: Specially crafted command can cause IMAP hibernate to + allow logged in user to access other people's emails and filesystem + information. +- Metric filter and global event filter variable syntax changed to a + SQL-like format. +- auth: Added new aliases for %{variables}. Usage of the old ones is + possible, but discouraged. +- auth: Removed RPA auth mechanism, SKEY auth mechanism, NTLM auth + mechanism and related password schemes. +- auth: Removed passdb-sia, passdb-vpopmail and userdb-vpopmail. +- auth: Removed postfix postmap socket + +* Wed Oct 21 2020 Michal Hlavinka - 1:2.3.11.3-7 +- change run directory from /var/run to /run (#1777922) + +* Wed Oct 21 2020 Michal Hlavinka - 1:2.3.11.3-6 +- use bigger default key size (#1882939) + +* Wed Sep 02 2020 Michal Hlavinka - 1:2.3.11.3-5 +- fix gssapi issue + +* Wed Aug 26 2020 Michal Hlavinka - 1:2.3.11.3-4 +- fix FTBFS on 32bit systems + +* Mon Aug 17 2020 Jeff Law - 1:2.3.11.3-2 +- Disable LTO + +* Sat Aug 15 2020 Michal Hlavinka - 1:2.3.11.3-1 +- CVE-2020-12100: Parsing mails with a large number of MIME parts could + have resulted in excessive CPU usage or a crash due to running out of + stack memory. +- CVE-2020-12673: Dovecot's NTLM implementation does not correctly check + message buffer size, which leads to reading past allocation which can + lead to crash. +- CVE-2020-10967: lmtp/submission: Issuing the RCPT command with an + address that has the empty quoted string as local-part causes the lmtp + service to crash. +- CVE-2020-12674: Dovecot's RPA mechanism implementation accepts + zero-length message, which leads to assert-crash later on. + +* Sat Aug 01 2020 Fedora Release Engineering - 1:2.3.10.1-3 +- Second attempt - Rebuilt for + https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Mon Jul 27 2020 Fedora Release Engineering - 1:2.3.10.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Mon May 18 2020 Michal Hlavinka - 1:2.3.10.1-1 +- dovecot updated to 2.3.10.1 +- fixes CVE-2020-10967, CVE-2020-10958, CVE-2020-10957 + +* Tue Apr 21 2020 Michal Hlavinka - 1:2.3.10-1 +- dovecot updated to 2.3.10, pigeonhole updated to 0.5.10 + +* Wed Feb 12 2020 Michal Hlavinka - 1:2.3.9.3-1 +- dovecot updated to 2.3.9.3 +- fixes CVE-2020-7046: Truncated UTF-8 can be used to DoS + submission-login and lmtp processes. +- fixes CVE-2020-7957: Specially crafted mail can crash snippet generation. + + +* Tue Jan 28 2020 Fedora Release Engineering - 1:2.3.9.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Thu Dec 19 2019 Michal Hlavinka - 1:2.3.9.2-1 +- CVE-2019-19722: Mails with group addresses in From or To fields + caused crash in push notification drivers. + +* Wed Dec 04 2019 Michal Hlavinka - 1:2.3.9-1 +- dovecot updated to 2.3.9, pigeonhole updated to 0.5.9 + +* Thu Oct 10 2019 Michal Hlavinka - 1:2.3.8-1 +- dovecot updated to 2.3.8, pigeonhole 0.5.8 + +* Thu Aug 29 2019 Michal Hlavinka - 1:2.3.7.2-1 +- dovecot updated to 2.3.7.2, pigeonhole 0.5.7.2 +- fixes CVE-2019-11500: IMAP protocol parser does not properly handle NUL byte + when scanning data in quoted strings, leading to out of bounds heap + memory writes + +* Mon Aug 19 2019 Michal Hlavinka - 1:1-2.3.7.1 +- dovecot updated to 2.3.7.1, pigeonhole updated to 0.5.7.1 + +* Wed Jul 24 2019 Fedora Release Engineering - 1:2.3.6-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Fri May 31 2019 Michal Hlavinka - 1:2.3.6-3 +- disable gcc 9 stack reuse temporarily + +* Mon May 13 2019 Michal Hlavinka - 1:2.3.6-2 +- use /run instead of /var/run (#1706372) + +* Thu May 02 2019 Michal Hlavinka - 1:2.3.6-1 +- dovecot updated to 2.3.6, pigeonhole updated to 0.5.6 + +* Thu Apr 18 2019 Michal Hlavinka - 1:2.3.5.2-1 +- dovecot updated to 2.3.5.2 +- fixes CVE-2019-10691: Trying to login with 8bit username containing + invalid UTF8 input causes auth process to crash if auth policy is enabled. + +* Thu Mar 28 2019 Michal Hlavinka - 1:2.3.5.1-1 +- dovecot updated to 2.3.5.1 +- CVE-2019-7524: Missing input buffer size validation leads into + arbitrary buffer overflow when reading fts or pop3 uidl header + from Dovecot index. + +* Wed Mar 06 2019 Michal Hlavinka - 1:2.3.5-1 +- dovecot updated to 2.3.5, pigeonhole updated to 0.5.5 + +* Thu Jan 31 2019 Fedora Release Engineering - 1:2.3.4-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Mon Jan 14 2019 Björn Esser - 1:2.3.4-2 +- Rebuilt for libcrypt.so.2 (#1666033) + +* Wed Jan 09 2019 Michal Hlavinka - 1:2.3.4-1 +- dovecot updated to 2.3.4, pigeonhole updated to 0.5.4 + +* Tue Oct 02 2018 Michal Hlavinka - 1:2.3.3-1 +- dovecot updated to 2.3.3, pigeonhole pdated to 0.5.3 +- doveconf hides more secrets now in the default output +- NUL bytes in mail headers can cause truncated replies when fetched. +- virtual plugin: Some searches used 100% CPU for many seconds +- dsync assert-crashed with acl plugin in some situations. +- imapc: Fixed various assert-crashes when reconnecting to server. + + +* Tue Oct 02 2018 Michal Hlavinka - 1:2.3.2.1-4 +- fix dovecot-init service syntax error (#1635017) + +* Mon Aug 13 2018 Michal Hlavinka - 1:2.3.2.1-3 +- do not try to generate ssl-params as its obsolete (#1614640) + +* Thu Jul 12 2018 Fedora Release Engineering - 1:2.3.2.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Tue Jul 10 2018 Michal Hlavinka - 1:2.3.2.1-1 +- SSL/TLS servers may have crashed during client disconnection + +* Mon Jul 09 2018 Michal Hlavinka - 1:2.3.2-1 +- dovecot updated to 2.3.2, pigeonhole to 0.5.2 + +* Wed Mar 28 2018 Michal Hlavinka - 1:2.3.1-2 +- fix ftbfs - murmurhash3 check fail + +* Wed Mar 28 2018 Michal Hlavinka - 1:2.3.1-1 +- dovecot updated to 2.3.1, pigeonhole updated to 0.5.1 + +* Tue Mar 27 2018 Michal Hlavinka - 1:2.3.0.1-3 +- use libxcrypt for Fedora >= 28, part of ftbfs fix (#1548520) + +* Wed Mar 07 2018 Michal Hlavinka - 1:2.3.0.1-2 +- add gcc buildrequire + +* Thu Mar 01 2018 Michal Hlavinka - 1:2.3.0.1-1 +- dovecot updated to 2.3.0.1, pigeonhole updated to 0.5.0.1 + +* Fri Feb 09 2018 Igor Gnatenko - 1:2.2.33.2-5 +- Escape macros in %%changelog + +* Wed Feb 07 2018 Fedora Release Engineering - 1:2.2.33.2-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Sat Jan 20 2018 Björn Esser - 1:2.2.33.2-3 +- Rebuilt for switch to libxcrypt + +* Mon Jan 08 2018 Michal Hlavinka - 1:2.2.33.2-2 +- remove tcp_wrappers on Fedora 28 and later (#1518761) +- use use mariadb-connector-c-devel instead of mysql-devel on Fedora 28 and later (#1493624) + +* Tue Oct 24 2017 Michal Hlavinka - 1:2.2.33.2-1 +- dovecot updated to 2.2.33.2 +- doveadm: Fix crash in proxying (or dsync replication) if remote is + running older than v2.2.33 +- auth: Fix memory leak in %%{ldap_dn} +- dict-sql: Fix data types to work correctly with Cassandra + +* Wed Oct 18 2017 Michal Hlavinka - 1:2.2.33.1-1 +- dovecot updated to 2.2.33.1, pigeonhole updated to +- Added %%{if}, see https://wiki2.dovecot.org/Variables#Conditionals +- sdbox: Mails were always opened when expunging, unless + mail_attachment_fs was explicitly set to empty. +- lmtp/doveadm proxy: hostip passdb field was ignored, which caused + unnecessary DNS lookups if host field wasn't an IP +- lmtp proxy: Fix crash when receiving unexpected reply in RCPT TO +- quota_clone: Update also when quota is unlimited (broken in v2.2.31) +- mbox, zlib: Fix assert-crash when accessing compressed mbox +- doveadm director kick -f parameter didn't work +- doveadm director flush resulted flushing all hosts, if + wasn't an IP address. +- director: Various fixes to handling backend/director changes at + abnormal times, especially while ring was unsynced. +- director: Use less CPU in imap-login processes when moving/kicking + many users. +- lmtp: Session IDs were duplicated/confusing with multiple RCPT TOs + when lmtp_rcpt_check_quota=yes +- LDA Sieve plugin: Fixed sequential execution of LDAP-based scripts. A + missing LDAP-based script could cause the script sequence to exit earlier. +- sieve-filter: Removed the (now) duplicate utf8 to mutf7 mailbox name + conversion. This caused problems with mailbox names containing UTF-8 + characters. + +* Mon Aug 28 2017 Michal Hlavinka - 1:2.2.32-2 +- pigeonhole updated to 0.4.20 +- Made the retention period for redirect duplicate identifiers + configurable. Changed the default retention period from 24 to 12 hours. +- sieve-filter: Fixed memory leak: forgot to clean up script binary at + end of execution +- managesieve-login: Fixed handling of AUTHENTICATE command. A second + authenticate command would be parsed wrong. + +* Fri Aug 25 2017 Michal Hlavinka - 1:2.2.32-1 +- dovecot updated to 2.2.32 +- Modseq tracking didn't always work correctly. This could have caused + imap unhibernation to fail or IMAP QRESYNC/CONDSTORE extensions to + not work perfectly. +- mdbox: "Inconsistency in map index" wasn't fixed automatically +- dict-ldap: %%variable values used in the LDAP filter weren't escaped. +- quota=count: quota_warning = -storage=.. was never executed (try #2). +- imapc: >= 32 kB mail bodies were supposed to be cached for subsequent + FETCHes, but weren't. +- quota-status service didn't support recipient_delimiter +- acl: Don't access dovecot-acl-list files with acl_globals_only=yes +- mail_location: If INDEX dir is set, mailbox deletion deletes its + childrens' indexes. +- director: v2.2.31 caused rapid reconnection loops to directors + that were down. + +* Wed Aug 02 2017 Fedora Release Engineering - 1:2.2.31-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Wed Jul 26 2017 Fedora Release Engineering - 1:2.2.31-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Tue Jul 11 2017 Michal Hlavinka - 1:2.2.31-3 +- enable tcpwrap support (#1450587) + +* Tue Jul 04 2017 Michal Hlavinka - 1:2.2.31-2 +- revert commit breaking NOTIFY support + +* Tue Jun 27 2017 Michal Hlavinka - 1:2.2.31-1 +- dovecot updated to 2.2.31 +- Various fixes to handling mailbox listing. Especially related to + handling nonexistent autocreated/autosubscribed mailboxes and ACLs. +- Global ACL file was parsed as if it was local ACL file. This caused + some of the ACL rule interactions to not work exactly as intended. +- Using mail_sort_max_read_count may have caused very high CPU usage. +- Message address parsing could have crashed on invalid input. +- imapc_features=fetch-headers wasn't always working correctly and + caused the full header to be fetched. +- imapc: Various bugfixes related to connection failure handling. +- quota=count: quota_warning = -storage=.. was never executed +- quota=count: Add support for "ns" parameter +- dsync: Fix incremental syncing for mails that don't have Date or + Message-ID headers. +- imap: Fix hang when client sends pipelined SEARCH + + EXPUNGE/CLOSE/LOGOUT. +- oauth2: Token validation didn't accept empty server responses. +- imap: NOTIFY command has been almost completely broken since the + beginning. +- pigeonhole updated to 0.4.19 +- Fixed bug in handling of implicit keep in some cases. +- include extension: Fixed segfault that (sometimes) occurred when the + global script location was left unconfigured. + +* Wed Jun 07 2017 Michal Hlavinka - 1:2.2.30.2-1 +- dovecot updated to 2.2.30.2 +- auth: Multiple failed authentications within short time caused crashes +- push-notification: OX driver crashed at deinit + +* Thu Jun 01 2017 Michal Hlavinka - 1:2.2.30.1-1 +- dovecot updated to 2.2.30.1 +- More fixes to automatically fix corruption in dovecot.list.index +- dsync-server: Fix support for dsync_features=empty-header-workaround +- imapc: Various bugfixes, including infinite loops on some errors +- IMAP NOTIFY wasn't working for non-INBOX if IMAP client hadn't + enabled modseq tracking via CONDSTORE/QRESYNC. +- fts-lucene: Fix it to work again with mbox format +- Some internal error messages may have contained garbage in v2.2.29 +- mail-crypt: Re-encrypt when copying/moving mails and per-mailbox keys + are used. Otherwise the copied mails can't be opened. + +* Wed Apr 12 2017 Michal Hlavinka - 1:2.2.29.1-1 +- dovecot updated to 2.2.29.1 +- dict-sql: Merging multiple UPDATEs to a single statement wasn't + actually working. +- pigeonhole updated to 0.4.18 +- imapsieve plugin: Implemented the copy_source_after rule action. When this + is enabled for a mailbox rule, the specified Sieve script is executed for + the message in the source mailbox during a "COPY" event. This happens only + after the Sieve script that is executed for the corresponding message in the + destination mailbox finishes running successfully. +- imapsieve plugin: Added non-standard Sieve environment items for the source + and destination mailbox. +- multiscript: The execution of the discard script had an implicit "keep", + rather than an implicit "discard". + +* Tue Apr 11 2017 Michal Hlavinka - 1:2.2.29-1 +- dovecot updated to 2.2.29 +- fts-tika: Fixed crash when parsing attachment without + Content-Disposition header. Broken by 2.2.28. +- trash plugin was broken in 2.2.28 +- auth: When passdb/userdb lookups were done via auth-workers, too much + data was added to auth cache. This could have resulted in wrong + replies when using multiple passdbs/userdbs. +- auth: passdb { skip & mechanisms } were ignored for the first passdb +- oauth2: Various fixes, including fixes to crashes +- dsync: Large Sieve scripts (or other large metadata) weren't always + synced. +- Index rebuild (e.g. doveadm force-resync) set all mails as \Recent +- imap-hibernate: %%{userdb:*} wasn't expanded in mail_log_prefix +- doveadm: Exit codes weren't preserved when proxying commands via + doveadm-server. Almost all errors used exit code 75 (tempfail). +- ACLs weren't applied to not-yet-existing autocreated mailboxes. +- Fixed a potential crash when parsing a broken message header. +- cassandra: Fallback consistency settings weren't working correctly. +- doveadm director status : "Initial config" was always empty +- imapc: Various reconnection fixes. + +* Mon Feb 27 2017 Michal Hlavinka - 1:2.2.28-1 +- dovecot updated to 2.2.28, pigeonhole to 0.4.17 +- auth: Support OAUTHBEARER and XOAUTH2 mechanisms. Also support them + in lib-dsasl for client side. +- imap: SEARCH/SORT may have assert-crashed in + client_check_command_hangs +- imap: FETCH X-MAILBOX may have assert-crashed in virtual mailboxes. +- search: Using NOT n:* or NOT UID n:* wasn't handled correctly +- fts: fts_autoindex_exclude = \Special-use caused crashes +- doveadm-server: Fix leaks and other problems when process is reused + for multiple requests (service_count != 1) +- sdbox: Fix assert-crash on mailbox create race +- lda/lmtp: deliver_log_format values weren't entirely correct if Sieve + was used. especially %%{storage_id} was broken. +- imapsieve plugin: Fixed assert failure occurring when used with virtual + mailboxes. +- doveadm sieve plugin: Fixed crash when setting Sieve script via attribute's + string value. + +* Fri Feb 10 2017 Fedora Release Engineering - 1:2.2.27-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Wed Dec 14 2016 Than Ngo - 1:2.2.27-2 +- fixed bz#1403760, big endian issue + +* Mon Dec 05 2016 Michal Hlavinka - 1:2.2.27-1 +- Fixed crash in auth process when auth-policy was configured and + authentication was aborted/failed without a username set. +- director: If two users had different tags but the same hash, + the users may have been redirected to the wrong tag's hosts. +- Index files may have been thought incorrectly lost, causing + "Missing middle file seq=.." to be logged and index rebuild. + This happened more easily with IMAP hibernation enabled. +- Various fixes to restoring state correctly in un-hibernation. +- dovecot.index files were commonly 4 bytes per email too large. This + is because 3 bytes per email were being wasted that could have been + used for IMAP keywords. +- Various fixes to handle dovecot.list.index corruption better. +- lib-fts: Fixed assert-crash in address tokenizer with specific input. +- Fixed assert-crash in HTML to text parsing with specific input + (e.g. for FTS indexing or snippet generation) +- doveadm sync -1: Fixed handling mailbox GUID conflicts. +- sdbox, mdbox: Perform full index rebuild if corruption is detected + inside lib-index, which runs index fsck. +- quota: Don't skip quota checks when moving mails between different + quota roots. +- search: Multiple sequence sets or UID sets in search parameters + weren't handled correctly. They were incorrectly merged together. + +* Fri Dec 02 2016 Michal Hlavinka - 1:2.2.26.0-2 +- fix remote crash when auth-policy component is activated (CVE-2016-8652,#1401025) + +* Mon Oct 31 2016 Michal Hlavinka - 1:2.2.26.0-1 +- dovecot updated to 2.2.26.0, pigeonhole updated to 0.4.16 +- master process's listener socket was leaked to all child processes. + This might have allowed untrusted processes to capture and prevent + "doveadm service stop" comands from working. +- login proxy: Fixed crash when outgoing SSL connections were hanging. +- auth: userdb fields weren't passed to auth-workers, so %%{userdb:*} + from previous userdbs didn't work there. +- auth: Fixed auth_bind=yes + sasl_bind=yes to work together +- lmtp: %%{userdb:*} variables didn't work in mail_log_prefix +- Fixed writing >2GB to iostream-temp files (used by fs-compress, + fs-metawrap, doveadm-http) +- fts-solr: Fixed searching multiple mailboxes +- and more... + +* Mon Jul 04 2016 Michal Hlavinka - 1:2.2.25-1 +- dovecot updated to 2.2.25 +- doveadm backup was sometimes deleting entire mailboxes unnecessarily. +- doveadm: Command -parameters weren't being sent to doveadm-server. +- if dovecot.index read failed e.g. because mmap() reached VSZ limit, + an empty index could have been opened instead, corrupting the + mailbox state. +- lazy-expunge: Fixed a crash when copying failed. Various other fixes. +- fts-lucene: Fixed crash on index rescan. +- dict-ldap: Various fixes +- dict-sql: NULL values crashed. Now they're treated as "not found". + + +* Wed Apr 27 2016 Michal Hlavinka - 1:2.2.24-1 +- dovecot updated to 2.2.24 +- Huge header lines could have caused Dovecot to use too much memory +- dsync: Detect and handle invalid/stale -s state string better. +- dsync: Fixed crash caused by specific mailbox renames +- auth: Auth cache is now disabled passwd-file. +- fts-tika: Don't crash if it returns 500 error +- dict-redis: Fixed timeout handling +- SEARCH INTHREAD was crashing +- stats: Only a single fifo_listeners was supported, making it impossible to + use both auth_stats=yes and mail stats plugin. +- SSL errors were logged in separate "Stacked error" log lines instead of as + part of the disconnection reason. +- MIME body parser didn't handle properly when a child MIME part's --boundary + had the same prefix as the parent. +- pigeonhole updated to 0.4.14 +- extprograms plugin: Fixed epoll() panic caused by closing the output + FD before the output stream. +- Made sure that the local part of a mail address is encoded properly + using quoted string syntax when it is not a dot-atom. + +* Thu Mar 31 2016 Michal Hlavinka - 1:2.2.23-1 +- dovecot updated to 2.2.23, pigeonhole updated to 0.4.13 +- Various fixes to doveadm. Especially running commands via + doveadm-server was broken. +- director: Fixed user weakness getting stuck in some situations +- director: Fixed a situation where directors keep re-sending + different states to each others and never becoming synced. +- director: Fixed assert-crash related to a slow "user killed" reply +- Fixed assert-crash related to istream-concat, which could have + been triggered at least by a Sieve script. + +* Wed Mar 16 2016 Michal Hlavinka - 1:2.2.22-1 +- dovecot updated to 2.2.22 +- auth: Auth caching was done too aggressively when %%variables were + used in default_fields, override_fields or LDAP pass/user_attrs. + userdb result_* were also ignored when user was found from cache. +- imap: Fixed various assert-crashes caused v2.2.20+. Some of them + caught actual hangs or otherwise unwanted behavior towards IMAP + clients. +- Expunges were forgotten in some situations, for example when + pipelining multiple IMAP MOVE commands. +- quota: Per-namespaces quota were broken for dict and count backends + in v2.2.20+ +- fts-solr: Search queries were using OR instead of AND as the + separator for multi-token search queries in v2.2.20+. +- Single instance storage support wasn't really working in v2.2.16+ +- dbox: POP3 message ordering wasn't working correctly. +- virtual plugin: Fixed crashes related to backend mailbox deletions. + +* Mon Feb 08 2016 Michal Hlavinka - 1:2.2.21-4 +- pigeonhole updated to 0.4.12 +- multiscript: Fixed bug in handling of (implicit) keep; final keep action was + always executed as though there was a failure. +- managesieve-login: Fixed proxy to allow SASL mechanisms other than PLAIN. +- ldap storage: Prevent segfault occurring when assigning certain (global) + configuration options. + +* Wed Feb 03 2016 Fedora Release Engineering - 1:2.2.21-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Thu Jan 28 2016 Michal Hlavinka - 1:2.2.21-2 +- pigeonhole updated to 0.4.11 +- Sieve mime extension: Fixed the header :mime :anychild test to work properly + outside a foreverypart loop. +- Fixed assert failure occurring when text extraction is attempted on a + empty or broken text part. +- Fixed assert failure in handling of body parts that are converted to text. +- Fixed header unfolding for (mime) headers parsed from any mime part. +- Fixed trimming for (mime) headers parsed from any mime part. +- Fixed erroneous changes to the message part tree structure performed when + re-parsing the message. +- LDA Sieve plugin: Fixed bug in error handling of script storage initialization +- Fixed duplication of discard actions in the script result. +- Made sure that quota errors never get logged as errors in syslog. + +* Wed Dec 16 2015 Michal Hlavinka - 1:2.2.21-1 +- dovecot updated to 2.2.21 +- doveadm mailbox list (and some others) were broken in v2.2.20 +- director: Fixed making backend changes when running with only a + single director server. +- virtual plugin: Fixed crash when trying to open nonexistent + autocreated backend mailbox. +- pigeonhole updated to 0.4.10 +- implemented the Sieve mime and foreverypart extensions (RFC 5703). ++ sieve body extension: Properly implemented the `:text' body + transform. It now extracts text for HTML message parts. +- variables extension: Fixed handling of empty string by the `:length' + set modifier. An empty string yielded an empty string rather than "0". +- Fixed memory leak in the Sieve script byte code dumping facility. + Extension contexts were never actually freed. +- doveadm sieve plugin: Fixed crashes caused by incorrect context + allocation in the sieve command implementations. + +* Tue Dec 08 2015 Michal Hlavinka - 1:2.2.20-2 +- move ssl initialization from %%post to dovecot-init.service + +* Tue Dec 08 2015 Michal Hlavinka - 1:2.2.20-1 +- dovecot updated to 2.2.20 +- director: Backend tags weren't working correctly. +- ldap: tls_* settings weren't used for ldaps URIs. +- ldap, mysql: Fixed setting connect timeout. +- auth: userdb lookups via auth-worker couldn't change username +- dsync: Fixed handling deleted directories. Make sure we don't go to + infinite mailbox renaming loop. +- imap: Fixed crash in NOTIFY when there were watched namespaces that + didn't support NOTIFY. +- imap: After SETMETADATA was used, various commands (especially FETCH) + could have started hanging when their output was large. +- stats: Idle sessions weren't refreshed often enough, causing stats + process to forget them and log errors about unknown sessions when + they were updated later. +- stats: Fixed "Duplicate session ID" errors when LMTP delivered to + multiple recipients and fts_autoindex=yes. +- zlib plugin: Fixed copying causing cache corruption when zlib_save + wasn't set, but the source message was compressed. +- fts-solr: Fixed escaping Solr query parameters. +- lmtp: quota_full_tempfail=yes was ignored with + lmtp_rcpt_check_quota=yes + +* Mon Oct 05 2015 Michal Hlavinka - 1:2.2.19-1 +- dovecot updated to 2.2.19 +- mdbox: Rebuilding could have caused message's reference count to + overflow the 16bit number in some situations, causing problems when + trying to expunge the duplicates. +- Various search fixes (fts, solr, tika, lib-charset, indexer) +- Various virtual plugin fixes +- Various fixes and optimizations to dsync, imapc and pop3-migration +- imap: Various RFC compliancy and crash fixes to NOTIFY +- pigeonhole updated to 0.4.9 +- ManageSieve: Fixed an assert failure occurring when a client + disconnects during the GETSCRIPT command. +- doveadm sieve plugin: Fixed incorrect initialization (mem leaks) of mail user. +- sieve-filter command line tool: Fixed handling of failure-related + implicit keep when there is an explicit default destination folder. +- lib-sieve: Fixed bug in RFC5322 header folding. + +* Mon Aug 24 2015 Michal Hlavinka - 1:2.2.18-5 +- use the system crypto policy (#1109114) + +* Fri Jun 19 2015 Michal Hlavinka - 1:2.2.18-4 +- fix build for s390x and ppc64 (#1232650) + +* Wed Jun 17 2015 Fedora Release Engineering - 1:2.2.18-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Mon May 18 2015 Michal Hlavinka - 1:2.2.18-2 +- update pigeonhole to 0.4.8 +- Fixed problem in address test: erroneously decoded mime-encoded words in + address headers. +- extprograms plugin: Fixed failure occurring when connecting to script + service without the need to read back the output from the external program. +- Fixed bug in script storage path normalization occurring with relative + symbolic links below root. + +* Fri May 15 2015 Michal Hlavinka - 1:2.2.18-1 +- director: Login UNIX sockets were normally detected as doveadm or + director ring sockets, causing it to break in existing installations. +- sdbox: When copying a mail in alt storage, place the destination to + alt storage as well. + +* Thu May 14 2015 Michal Hlavinka - 1:2.2.17-1 +- dovecot updated to 2.2.17 +- pigeonhole updated to 0.4.7 +- auth: If auth_master_user_separator was set, auth process could be + crashed by trying to log in with empty master username. +- imap-login, pop3-login: Fixed crash on handshake failures with new + OpenSSL versions (v1.0.2) when SSLv3 was disabled. +- auth: If one passdb fails allow_nets check, it shouldn't have failed + all the other passdb checks later on. +- imap: Server METADATA couldn't be accessed +- imapc: Fixed \Muted label handling in gmail-migration. +- imapc: Various bugfixes and improvements. +- Trash plugin fixes by Alexei Gradinari +- mbox: Fixed crash/corruption in some situations + +* Tue Apr 28 2015 Michal Hlavinka - 1:2.2.16-2 +- fix CVE-2015-3420: SSL/TLS handshake failures leading to a crash of the login process + +* Mon Mar 16 2015 Michal Hlavinka - 1:2.2.16-1 +- dovecot updated to 2.2.16 +- auth: Don't crash if master user login is attempted without + any configured master=yes passdbs +- Parsing UTF-8 text for mails could have caused broken results + sometimes if buffering was split in the middle of a UTF-8 character. + This affected at least searching messages. +- String sanitization for some logged output wasn't done properly: + UTF-8 text could have been truncated wrongly or the truncation may + not have happened at all. +- fts-lucene: Lookups from virtual mailbox consisting of over 32 + physical mailboxes could have caused crashes. + +* Thu Feb 05 2015 Michal Hlavinka - 1:2.2.15-3 +- fix mbox istream crashes (#1189198, #1186504) + +* Mon Jan 05 2015 Michal Hlavinka - 1:2.2.15-2 +- fix crash related to logging BYE notifications (#1176282) +- update pigeonhole to 0.4.6 + +* Thu Oct 30 2014 Michal Hlavinka - 1:2.2.15-1 +- dovecot updated to 2.2.15 +- various race condition fixes to LAYOUT=index +- v2.2.14 virtual plugin crashed in some situations + +* Fri Oct 17 2014 Michal Hlavinka - 1:2.2.14-1 +- dovecot updated to 2.2.14, pigeonhole updated to 0.4.3 +- fixed several race conditions with dovecot.index.cache handling that + may have caused unnecessary "cache is corrupted" errors. +- auth: If auth client listed userdb and disconnected before finishing, + the auth worker process got stuck +- imap-login, pop3-login: Fixed potential crashes when client + disconnected unexpectedly. +- imap proxy: The connection was hanging in some usage patterns. + +* Thu Aug 21 2014 Michal Hlavinka - 1:2.2.13-4 +- use network-online target instead of just network (#1119814) + +* Sat Aug 16 2014 Fedora Release Engineering - 1:2.2.13-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Sat Jun 07 2014 Fedora Release Engineering - 1:2.2.13-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Mon May 12 2014 Michal Hlavinka - 1:2.2.13-1 +- dovecot updated to 2.2.13 +- fixes CVE-2014-3430: denial of service through maxxing out SSL connections +- pop3 server was still crashing in v2.2.12 +- maildir: Various fixes and improvements to handling compressed mails +- fts-lucene, fts-solr: Fixed crash on search when the index contained + duplicate entries. +- mail_attachment_dir: Attachments with the last base64-encoded line + longer than the rest wasn't handled correctly. +- IMAP: SEARCH/SORT PARTIAL was handled completely wrong in v2.2.11+ +- acl: Global ACL file handling was broken when multiple entries + matched the mailbox name + +* Sun Mar 30 2014 John Morris - 1:2.2.12-2 +- el6 build fixes (#1082384): +- el6 autoconf too old to regen; use packaged files +- fix compile error when __global_ldflags macro undefined + +* Fri Feb 14 2014 Michal Hlavinka - 1:2.2.12-1 +- dovecot updated to 2.2.12 +- fixes pop3 crash + +* Thu Feb 13 2014 Michal Hlavinka - 1:2.2.11-1 +- dovecot updated to 2.2.11 +- imap: SEARCH/SORT PARTIAL reponses may have been too large. +- doveadm backup: Fixed assert-crash when syncing mailbox deletion. + +* Thu Jan 02 2014 Michal Hlavinka - 1:2.2.10-1 +- dovecot updated to 2.2.10 +- quota-status: quota_grace was ignored +- ldap: Fixed memory leak with auth_bind=yes and without + auth_bind_userdn. +- imap: Don't send HIGHESTMODSEQ anymore on SELECT/EXAMINE when + CONDSTORE/QRESYNC has never before been enabled for the mailbox. +- imap: Fixes to handling mailboxes without permanent modseqs. + (When [NOMODSEQ] is returned by SELECT, mainly with in-memory + indexes.) +- imap: Various fixes to METADATA support. +- stats plugin: Processes that only temporarily dropped privileges + (e.g. indexer-worker) may have been logging errors about not being + able to open /proc/self/io. + +* Mon Nov 25 2013 Michal Hlavinka - 1:2.2.9-1 +- improved cache file handling exposed several old bugs related to fetching + mail headers. +- iostream handling changes were causing some connections to be disconnected + before flushing their output + +* Wed Nov 20 2013 Michal Hlavinka - 1:2.2.8-1 +- Fixed infinite loop in message parsing if message ends with + "--boundary" and CR (without LF). Messages saved via SMTP/LMTP can't + trigger this, because messages must end with an "LF.". A user could + trigger this for him/herself though. +- lmtp: Client was sometimes disconnected before all the output was + sent to it. +- replicator: Database wasn't being exported to disk every 15 minutes + as it should have. Instead it was being imported, causing "doveadm + replicator remove" commands to not work very well. + +* Thu Nov 14 2013 Michal Hlavinka - 1:2.2.7-2 +- fix ostream infinite loop (#1029906) + +* Mon Nov 04 2013 Michal Hlavinka - 1:2.2.7-1 +- dovecot updated to 2.2.7 +- master process was doing a hostname.domain lookup for each created + process, which may have caused a lot of unnecessary DNS lookups. +- dsync: Syncing over 100 messages at once caused problems in some + situations, causing messages to get new UIDs. +- fts-solr: Different Solr hosts for different users didn't work. + +* Tue Oct 01 2013 Michal Hlavinka - 1:2.2.6-1 +- dovecot updated to 2.2.6, pigeonhole updated to 0.4.2 +- director: v2.2.5 changes caused "SYNC lost" errors +- dsync: Many fixes and error handling improvements +- doveadm -A: Don't waste CPU by doing a separate config lookup + for each user +- Long-running ssl-params process no longer prevents Dovecot restart +- mbox: Fixed mailbox_list_index=yes to work correctly + +* Thu Aug 08 2013 Michal Hlavinka - 1:2.2.5-2 +- use unversioned doc dir (#993731) + +* Wed Aug 07 2013 Michal Hlavinka - 1:2.2.5-1 +- dovecot updated to 2.2.5 +- added some missing man pages (by Pascal Volk) +- director: Users near expiration could have been redirected to + different servers at the same time. +- pop3: Avoid assert-crash if client disconnects during LIST. +- mdbox: Corrupted index header still wasn't automatically fixed. +- dsync: Various fixes to work better with imapc and pop3c storages. +- ldap: sasl_bind=yes caused crashes, because Dovecot's lib-sasl + symbols conflicted with Cyrus SASL library. + +* Tue Jul 30 2013 Michal Hlavinka - 1:2.2.4-3 +- dovecot pigeonhole updated to 0.4.1 + +* Wed Jul 10 2013 Michal Hlavinka - 1:2.2.4-2 +- fix name conflict with cyrus-sasl (#975869) + +* Tue Jun 25 2013 Michal Hlavinka - 1:2.2.4-1 +- dovecot updated to 2.2.4 +- imap/pop3 proxy: Master user logins were broken in v2.2.3 +- sdbox/mdbox: A corrupted index header with wrong size was never + automatically fixed in v2.2.3. +- mbox: Fixed assert-crashes related to locking. + +* Mon Jun 17 2013 Michal Hlavinka - 1:2.2.3-1 +- dovecot updated to 2.2.3 +- IMAP: If subject contained only whitespace, Dovecot returned an + ENVELOPE reply with a huge literal value, effectively causing the + IMAP client to wait for more data forever. +- IMAP: Various URLAUTH fixes. +- imapc: Various bugfixes and improvements +- pop3c: Various fixes to make it work in dsync (without imapc) +- dsync: Fixes to syncing subscriptions. Fixes to syncing mailbox + renames. + +* Tue May 21 2013 Michal Hlavinka - 1:2.2.2-2 +- fix location of tmpfiles configuration (#964448) + +* Mon May 20 2013 Michal Hlavinka - 1:2.2.2-1 +- dovecot updated to 2.2.2 +- IMAP: Various URLAUTH fixes. +- IMAP: Fixed a hang with invalid APPEND parameters. +- IMAP LIST-EXTENDED: INBOX was never listed with \Subscribed flag. +- mailbox_list_index=yes still caused crashes. +- maildir: Fixed a crash after dovecot-keywords file was re-read. +- maildir: If files had reappeared unexpectedly to a Maildir, they + were ignored until index files were deleted. +- Maildir: Fixed handling over 26 keywords in a mailbox. +- imap/pop3-login proxying: Fixed a crash if TCP connection succeeded, + but the remote login timed out. + +* Thu May 16 2013 Michal Hlavinka - 1:2.2.1-4 +- update pigeonhole to 0.4.0 + +* Mon Apr 29 2013 Michal Hlavinka - 1:2.2.1-3 +- revert last change and use different fix + +* Wed Apr 24 2013 Kalev Lember - 1:2.2.1-2 +- Filter out autogenerated perl deps (#956194) + +* Fri Apr 19 2013 Michal Hlavinka - 1:2.2.1-1 +- dovecot updated to 2.2.1 +- mailbox_list_index=yes was broken. +- LAYOUT=index didn't list subscriptions. +- auth: Multiple master passdbs didn't work. +- Message parsing (e.g. during search) crashed when multipart message + didn't actually contain any parts. +- dovecot updated to 2.2.1 + +* Mon Apr 15 2013 Michal Hlavinka - 1:2.2.0-1 +- dovecot updated to 2.2.0 +- Mailbox list indexes weren't using proper file permissions based + on the root directory. +- replicator: doveadm commands and user list export may have skipped + some users. +- Various fixes to mailbox_list_index=yes + +* Fri Apr 05 2013 Michal Hlavinka - 1:2.2-0.4 +- dovecot updated to 2.2 RC4 +- various bugfixes to LDAP changes in rc3 + +* Wed Mar 27 2013 Michal Hlavinka - 1:2.2-0.3 +- dovecot updated to 2.2 RC3 +- Fixed a crash when decoding quoted-printable content. +- dsync: Various bugfixes + +* Thu Feb 28 2013 Michal Hlavinka - 1:2.2-0.2 +- do not print error when NetworkManager is not installed (#916456) + +* Wed Feb 27 2013 Michal Hlavinka - 1:2.2-0.1 +- major update to dovecot 2.2 RC2 + +* Mon Feb 11 2013 Michal Hlavinka - 1:2.1.15-1 +- dovecot updated to 2.1.15 +- v2.1.14's dovecot.index.cache fixes caused Dovecot to use more disk I/O + and memory than was necessary. + +* Tue Feb 05 2013 Michal Hlavinka - 1:2.1.14-2 +- spec clean up + +* Thu Jan 31 2013 Michal Hlavinka - 1:2.1.14-1 +- dovecot updated to 2.1.14 +- v2.1.11+ had a race condition where it sometimes overwrote data in + dovecot.index.cache file. This could have caused Dovecot to return + the same cached data to two different messages. +- mdbox: Fixes to handling duplicate GUIDs during index rebuild + +* Tue Jan 15 2013 Michal Hlavinka - 1:2.1.13-1 +- dovecot updated to 2.1.13 +- Some fixes to cache file changes in v2.1.11. +- virtual storage: Sorting mailbox by from/to/cc/bcc didn't work. + +* Mon Dec 03 2012 Michal Hlavinka - 1:2.1.12-1 +- dovecot updated to 2.1.12 +- lmtp proxy: Fixed hanging if remote server was down. +- doveadm: Various fixes to handling doveadm-server connections. +- auth: passdb imap was broken in v2.1.10. + +* Thu Nov 08 2012 Michal Hlavinka - 1:2.1.10-3 +- fix network still not ready race condition (#871623) + +* Fri Nov 02 2012 Michal Hlavinka - 1:2.1.10-2 +- add reload command to service file + +* Wed Sep 19 2012 Michal Hlavinka - 1:2.1.10-1 +- dovecot updated to 2.1.10, pigeonhole updated to 0.3.3 +- director: In some conditions director may have disconnected from + another director (without logging about it), thinking it was sending + invalid data. +- imap: Various fixes to listing mailboxes. +- login processes crashed if there were a lot of local {} or remote {} + settings blocks. + +* Fri Aug 24 2012 Michal Hlavinka - 1:2.1.9-2 +- use new systemd rpm macros (#851238) + +* Thu Aug 02 2012 Michal Hlavinka - 1:2.1.9-1 +- dovecot updated to 2.1.9 +- Full text search indexing might have failed for some messages, + always causing indexer-worker process to run out of memory. +- fts-lucene: Fixed handling SEARCH HEADER FROM/TO/SUBJECT/CC/BCC when + the header wasn't lowercased. +- fts-squat: Fixed crash when searching a virtual mailbox. +- pop3: Fixed assert crash when doing UIDL on empty mailbox on some + setups. +- auth: GSSAPI RFC compliancy and error handling fixes. +- Various fixes related to handling shared namespaces + +* Wed Jul 18 2012 Fedora Release Engineering - 1:2.1.8-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Tue Jul 03 2012 Michal Hlavinka - 1:2.1.8-2 +- pigeonhole updated to 0.3.1 +- Fixed several small issues, including a few potential segfault bugs, based + on static source code analysis. + +* Tue Jul 03 2012 Michal Hlavinka - 1:2.1.8-1 +- dovecot updated to 2.1.8 +- imap: Mailbox names were accidentally sent as UTF-8 instead of mUTF-7 + in previous v2.1.x releases for STATUS, MYRIGHTS and GETQUOTAROOT commands. +- lmtp proxy: Don't timeout connections too early when mail has a lot of RCPT TOs. +- director: Don't crash if the director is working alone. +- shared mailboxes: Avoid doing "@domain" userdb lookups. +- doveadm: Fixed crash with proxying some commands. +- fts-squat: Fixed handling multiple SEARCH parameters. +- imapc: Fixed a crash when message had more than 8 keywords. +- imapc: Don't crash on APPEND/COPY if server doesn't support UIDPLUS. + + +* Mon Jul 02 2012 Michal Hlavinka - 1:2.1.7-5 +- make quota work with NFS mounted mailboxes + +* Fri Jun 22 2012 Michal Hlavinka - 1:2.1.7-4 +- posttrans argument is always zero + +* Fri Jun 15 2012 Michal Hlavinka - 1:2.1.7-3 +- do not let dovecot run during upgrade (#134325) + +* Wed May 30 2012 Michal Hlavinka - 1:2.1.7-2 +- fix changelog, 2.1.7-1 had copy-pasted upstream changelog, which was wrong +- director: Don't crash with quickly disconnecting incoming director + connections. +- mdbox: If mail was originally saved to non-INBOX, and namespace + prefix is non-empty, don't assert-crash when rebuilding indexes. +- sdbox: Don't use more fds than necessary when copying mails. +- auth: Fixed crash with DIGEST-MD5 when attempting to do master user + login without master passdbs. +- Several fixes to mail_shared_explicit_inbox=no +- imapc: Use imapc_list_prefix also for listing subscriptions. + +* Wed May 30 2012 Michal Hlavinka - 1:2.1.7-1 +- updated to 2.1.7 +- v2.1.5: Using "~/" as mail_location or elsewhere failed to actually + expand it to home directory. +- dbox: Fixed potential assert-crash when reading dbox files. +- trash plugin: Fixed behavior when quota is already over limit. +- mail_log plugin: Logging "copy" event didn't work. +- Proxying to backend server with SSL: Verifying server certificate + name always failed, because it was compared to an IP address. + +* Wed May 09 2012 Michal Hlavinka - 1:2.1.6-2 +- fix socket activation again, fix in 2.1.6 is incomplete + +* Wed May 09 2012 Michal Hlavinka - 1:2.1.6-1 +- v2.1.5: Using "~/" as mail_location or elsewhere failed to actually + expand it to home directory. +- dbox: Fixed potential assert-crash when reading dbox files. +- trash plugin: Fixed behavior when quota is already over limit. +- Proxying to backend server with SSL: Verifying server certificate + name always failed, because it was compared to an IP address. + +* Tue Apr 24 2012 Michal Hlavinka - 1:2.1.5-1 +- IMAP: Several fixes related to mailbox listing in some configs +- director: A lot of fixes and performance improvements +- mbox: Deleting a mailbox didn't delete its index files. +- pop3c: TOP command was sent incorrectly +- trash plugin didn't work properly +- LMTP: Don't add a duplicate Return-Path: header when proxying. +- listescape: Don't unescape namespace prefixes. + +* Tue Apr 24 2012 Michal Hlavinka - 1:2.1.4-2 +- close systemd extra sockets that are not configured + +* Tue Apr 10 2012 Michal Hlavinka - 1:2.1.4-1 +- dovecot updated to 2.1.4 +- Proxying SSL connections crashed in v2.1.[23] +- fts-solr: Indexing mail bodies was broken. +- director: Several changes to significantly improve error handling +- doveadm import didn't import messages' flags +- mail_full_filesystem_access=yes was broken +- Make sure IMAP clients can't create directories when accessing + nonexistent users' mailboxes via shared namespace. +- Dovecot auth clients authenticating via TCP socket could have failed + with bogus "PID already in use" errors. + +* Mon Mar 19 2012 Michal Hlavinka - 1:2.1.3-1 +- dovecot updated to 2.1.3 +- multi-dbox format in dovecot 2.1.2 was broken +- temporarily disable check phase until bug #798968 is fixed + +* Fri Mar 16 2012 Michal Hlavinka - 1:2.1.2-1 +- dovecot updated to 2.1.2 +- doveadm sync: If mailbox was expunged empty, messages may have + become back instead of also being expunged in the other side. +- imap_id_* settings were ignored before login. +- Several fixes to mailbox_list_index=yes +- Previous v2.1.x didn't log all messages at shutdown. + +* Thu Mar 01 2012 Michal Hlavinka - 1:2.1.1-2 +- enable fts_lucene plugin (#798661) + +* Fri Feb 24 2012 Michal Hlavinka - 1:2.1.1-1 +- dovecot updated to 2.1.1 +- acl plugin + autocreated mailboxes crashed when listing mailboxes +- doveadm force-resync: Don't skip autocreated mailboxes (especially + INBOX). +- If process runs out of fds, stop listening for new connections only + temporarily, not permanently (avoids hangs with process_limit=1 + services) +- auth: passdb imap crashed for non-login authentication (e.g. smtp). + + +* Mon Feb 20 2012 Michal Hlavinka - 1:2.1.0-1 +- updated to 2.1.0 (no major changes since .rc6) +- include pigeonhole doc files (NEWS, README, ...) + +* Tue Feb 14 2012 Michal Hlavinka - 1:2.1-0.7.rc6 +- updated to 2.1.rc6 +- dbox: Fixed error handling when saving failed or was aborted +- IMAP: Using COMPRESS extension may have caused assert-crashes +- IMAP: THREAD REFS sometimes returned invalid (0) nodes. +- dsync: Fixed handling non-ASCII characters in mailbox names. + +* Tue Feb 07 2012 Michal Hlavinka - 1:2.1-0.6.rc5 +- use PrivateTmp in systemd unit file + +* Tue Feb 07 2012 Michal Hlavinka - 1:2.1-0.5.rc5 +- updated to 2.1.rc5 +- director: With >2 directors ring syncing might have stalled during + director connect/disconnect, causing logins to fail. +- LMTP client/proxy: Fixed potential hanging when sending (big) mails +- Compressed mails with external attachments (dbox + SIS + zlib) failed + sometimes with bogus "cached message size wrong" errors. + +* Mon Jan 09 2012 Michal Hlavinka - 1:2.1-0.4.rc3 +- updated to 2.1.rc3 +- dsync was merged into doveadm +- added pop3c (= POP3 client) storage backend + +* Wed Dec 14 2011 Michal Hlavinka - 1:2.1-0.3.rc1 +- allow imap+TLS and pop3+TLS by default + +* Fri Dec 02 2011 Michal Hlavinka - 1:2.1-0.2.rc1 +- call systemd reload in postun + +* Wed Nov 30 2011 Michal Hlavinka - 1:2.1-0.1.rc1 +- updated to 2.1.rc1 +- major changes since 2.0.x: +- plugins now use UTF-8 mailbox names rather than mUTF-7 +- auth_username_format default changed to %%Lu +- solr full text search backend changed to use mailbox GUIDs instead of + mailbox names, requiring reindexing everything + +* Mon Nov 21 2011 Michal Hlavinka - 1:2.0.16-1 +- dovecot updated to 2.0.16 + +* Mon Oct 24 2011 Michal Hlavinka - 1:2.0.15-2 +- do not use obsolete settings in default configuration (#743444) + +* Mon Sep 19 2011 Michal Hlavinka - 1:2.0.15-1 +- dovecot updated to 2.0.15 +- v2.0.14: Index reading could have eaten a lot of memory in some + situations +- mbox: Fixed crash during mail delivery when mailbox didn't yet have + GUID assigned to it. +- zlib+mbox: Fetching last message from compressed mailboxes crashed. + +* Tue Sep 13 2011 Michal Hlavinka - 1:2.0.14-2 +- do not enable insecure connections by default + +* Mon Aug 29 2011 Michal Hlavinka - 1:2.0.14-1 +- dovecot updated to 2.0.14 +- userdb extra fields can now return name+=value to append to an + existing name +- script-login attempted an unnecessary config lookup, which usually + failed with "Permission denied". +- lmtp: Fixed parsing quoted strings with spaces as local-part for + MAIL FROM and RCPT TO. +- imap: FETCH BODY[HEADER.FIELDS (..)] may have crashed or not + returned all data sometimes. +- ldap: Fixed random assert-crashing with with sasl_bind=yes. +- Fixes to handling mail chroots +- Fixed renaming mailboxes under different parent with FS layout when + using separate ALT, INDEX or CONTROL paths. +- zlib: Fixed reading concatenated .gz files. + +* Fri Jul 15 2011 Michal Hlavinka - 1:2.0.13-2 +- do not include sysv init script + +* Thu May 12 2011 Michal Hlavinka - 1:2.0.13-1 +- dovecot updated to 2.0.13 +- mdbox purge: Fixed wrong warning about corrupted extrefs. +- script-login binary wasn't actually dropping privileges to the + user/group/chroot specified by its service settings. +- Fixed potential crashes and other problems when parsing header names + that contained NUL characters. + +* Fri Apr 15 2011 Michal Hlavinka - 1:2.0.12-2 +- pigeonhole updated to 0.2.3, which includes: +- managesieve: fixed bug in UTF-8 checking of string values +- sieve command line tools now avoid initializing the mail store unless necessary +- removed header MIME-decoding to fix erroneous address parsing +- fixed segfault bug in extension configuration, triggered when unknown + extension is mentioned in sieve_extensions setting. + +* Wed Apr 13 2011 Michal Hlavinka - 1:2.0.12-1 +- dbox: Fixes to handling external attachments +- dsync: More fixes to avoid hanging with remote syncs +- dsync: Many other syncing/correctness fixes +- doveconf: v2.0.10 and v2.0.11 didn't output plugin {} section right + +* Mon Mar 28 2011 Michal Hlavinka - 1:2.0.11-5 +- rebuild with new patch + +* Mon Mar 28 2011 Michal Hlavinka - 1:2.0.11-4 +- fix regression in config file parsing (#690401) + +* Wed Mar 23 2011 Dan HorĂ¡k - 1:2.0.11-3 +- rebuilt for mysql 5.5.10 (soname bump in libmysqlclient) + +* Wed Mar 23 2011 Michal Hlavinka - 1:2.0.11-2 +- rebuild because of updated dependencies + +* Mon Mar 07 2011 Michal Hlavinka - 1:2.0.11-1 +- IMAP: Fixed hangs with COMPRESS extension +- IMAP: Fixed a hang when trying to COPY to a nonexistent mailbox. +- IMAP: Fixed hang/crash with SEARCHRES + pipelining $. +- IMAP: Fixed assert-crash if IDLE+DONE is sent in same TCP packet. + +* Thu Feb 17 2011 Michal Hlavinka - 1:2.0.9-3 +- add missing section to dovecot's systemd service file + +* Tue Feb 08 2011 Fedora Release Engineering - 1:2.0.9-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Thu Jan 13 2011 Michal Hlavinka - 1:2.0.9-1 +- dovecot updated to 2.0.9 +- fixed a high system CPU usage / high context switch count performance problem +- lda: Fixed a crash when trying to send "out of quota" reply + +* Mon Dec 20 2010 Michal Hlavinka - 1:2.0.8-3 +- add full path and check to restorecon in post + +* Tue Dec 07 2010 Michal Hlavinka - 1:2.0.8-2 +- fix s/foobar/dovecot/ typo in post script + +* Tue Dec 07 2010 Michal Hlavinka - 1:2.0.8-1 +- dovecot updated to 2.0.8, pigeonhole updated to 0.2.2 +- services' default vsz_limits weren't being enforced correctly +- added systemd support +- dbox: Fixes to handling external mail attachments +- imap, pop3: When service { client_count } was larger than 1, the + log messages didn't use the correct prefix +- MySQL: Only the first specified host was ever used + +* Mon Nov 29 2010 Michal Hlavinka - 1:2.0.7-3 +- make it work with /var/run on tmpfs (#656577) + +* Tue Nov 23 2010 Michal Hlavinka - 1:2.0.7-2 +- fix regression with valid_chroot_dirs being ignored (#654083) + +* Tue Nov 09 2010 Michal Hlavinka - 1:2.0.7-1 +- dovecot updated to 2.0.7 +- IMAP: Fixed LIST-STATUS when listing subscriptions with subscriptions=no namespaces. +- IMAP: Fixed SELECT QRESYNC not to crash on mailbox close if a lot of changes were being sent. +- quota: Don't count virtual mailboxes in quota +- doveadm expunge didn't always actually do the physical expunging +- Fixed some index reading optimizations introduced by v2.0.5. +- LMTP proxying fixes + +* Fri Oct 22 2010 Michal Hlavinka - 1:2.0.6-1 +- dovecot updated to 2.0.6 +- Pre-login CAPABILITY includes IDLE again. Mainly to make Blackberry + servers happy. +- auth: auth_cache_negative_ttl default was 0 in earlier v2.0.x, but it + was supposed to be 1 hour as in v1.x. Changed it back to 1h. +- doveadm: Added import command for importing mails from other storages. +- Reduced NFS I/O operations for index file accesses +- dbox, Maildir: When copying messages, copy also already cached fields + from dovecot.index.cache +- Maildir: LDA/LMTP assert-crashed sometimes when saving a mail. +- Fixed leaking fds when writing to dovecot.mailbox.log. +- Fixed rare dovecot.index.cache corruption +- IMAP: SEARCH YOUNGER/OLDER wasn't working correctly + +* Mon Oct 04 2010 Michal Hlavinka - 1:2.0.5-1 +- dovecot updated to 2.0.5 +- acl: Fixed the logic of merging multiple ACL entries +- sdbox: Fixed memory leak when copying messages with hard links. +- zlib: Fixed several crashes, which mainly showed up with mbox. +- quota: Don't crash if user has quota disabled, but plugin loaded. +- acl: Fixed crashing when sometimes listing shared mailboxes via dict proxy. + +* Tue Sep 28 2010 Michal Hlavinka - 1:2.0.4-1 +- dovecot updated to 2.0.4 +- multi-dbox: If :INDEX=path is specified, keep storage/dovecot.map.index* + files also in the index path rather than in the main storage directory. +- dsync: POP3 UIDLs weren't copied with Maildir +- dict file: Fixed fd leak (showed up easily with LMTP + quota) + +* Mon Sep 20 2010 Michal Hlavinka - 1:2.0.3-1 +- dovecot updated to 2.0.3 +- dovecot-lda: Removed use of non-standard Envelope-To: header as + a default for -a +- dsync: Fixed handling \Noselect mailboxes +- Fixed an infinite loop introduced by v2.0.2's message parser changes. +- Fixed a crash introduced by v2.0.2's istream-crlf changes. + +* Thu Sep 16 2010 Michal Hlavinka - 1:2.0.2-1 +- dovecot updated +- vpopmail support is disabled for now, since it's broken. You can use + it via checkpassword support or its sql/ldap database directly. +- maildir: Fixed "duplicate uidlist entry" errors that happened at + least with LMTP when mail was delivered to multiple recipients +- Deleting ACLs didn't cause entries to be removed from acl_shared_dict +- mail_max_lock_timeout setting wasn't working with all locks + +* Wed Aug 25 2010 Michal Hlavinka - 1:2.0.1-1 +- dovecot and pigeonhole updated +- sieve: sieved renamed to sieve-dump +- when dsync is started as root, remote dsync command is now also executed + as root instead of with dropped privileges. +- IMAP: QRESYNC parameters for SELECT weren't handled correctly. +- UTF-8 string validity checking wasn't done correctly +- dsync: Fixed a random assert-crash with remote dsyncing + +* Tue Aug 17 2010 Michal Hlavinka - 1:2.0-1 +- dovecot and pigeonhole updated +- dict quota didn't always decrease quota when messages were expunged +- Shared INBOX wasn't always listed with FS layout + +* Wed Aug 11 2010 Michal Hlavinka - 1:2.0-0.21.rc5 +- dovecot and pigeonhole updated +- Using more than 2 plugins could have caused broken behavior +- Listescape plugin fixes +- mbox: Fixed a couple of assert-crashes +- mdbox: Fixed potential assert-crash when saving multiple messages + in one transaction + +* Thu Aug 05 2010 Michal Hlavinka - 1:2.0-0.20.rc4 +- dovecot and pigeonhole updated +- doveadm mailbox status: Fixed listing non-ASCII mailbox names. +- doveadm fetch: Fixed output when fetching message header or body +- doveadm director map/add/remove: Fixed handling IP address as parameter. +- dsync: A few more fixes + +* Wed Jul 21 2010 Michal Hlavinka - 1:2.0-0.19.rc3 +- dovecot and pigeonhole updated +- fixed lda + sieve crash +- added mail_temp_dir setting, used by deliver and lmtp for creating + temporary mail files. Default is /tmp. +- imap: Fixed checking if list=children namespace has children. +- mdbox: Race condition fixes related to copying and purging + +* Fri Jul 16 2010 Michal Hlavinka - 1:2.0-0.18.rc2.20100716 +- dovecot and pigeonhole updated +- enabled pigeonhole's build time test suite +- acl: Fixed crashon FS layout with non-default hierarchy separator +- dbox renamed to sdbox +- dsync fixes and improvements + +* Mon Jul 12 2010 Michal Hlavinka - 1:2.0-0.17.rc2.20100712 +- dovecot and pigeonhole updated +- fixed a crash with empty mail_plugins +- fixed sharing INBOX to other users +- director+LMTP proxy wasn't working correctly +- v1.x config parser failed with some settings if pigeonhole wasn't installed. +- virtual: If non-matching messages weren't expunged within same session, + they never got expunged. + +* Wed Jul 07 2010 Michal Hlavinka - 1:2.0-0.16.rc1.20100707 +- updated dovecot and pigeonhole +- a lot of dsync fixes +- improved (m)dbox recovery + +* Mon Jun 28 2010 Michal Hlavinka - 1:2.0-0.15.beta6.20100626 +- updated dovecot, pigeonhole and man pages +- moved disable_plaintext_auth to 10-auth.conf +- mdbox: Fixed assert-crash on storage rebuild if file got lost +- lib-charset: Don't assert-crash when iconv() skips lots of invalid input +- master: Fixed crash on deinit (maybe also on reload) + +* Thu Jun 10 2010 Michal Hlavinka - 1:2.0-0.14.beta5.20100610 +- dovecot updated +- lib-storage: Fixed accessing uncommitted saved mails with dsync +- example-config: Moved ACL and quota settings to a separate .conf files +- dbox, mdbox: Fixed race conditions when creating mailboxes + +* Mon May 31 2010 Michal Hlavinka - 1:2.0-0.13.beta5.20100529 +- dovecot and pigeonhole updated +- enable solr fulltext search +- master: Fixed crash on config reload +- lib-storage: Don't assert-crash when copying a mail fails + +* Tue May 18 2010 Michal Hlavinka - 1:2.0-0.12.beta5.20100515 +- dovenull is unauthorized user, needs own dovenull group + +* Tue May 18 2010 Michal Hlavinka - 1:2.0-0.11.beta5.20100515 +- fix typo in dovenull username + +* Mon May 17 2010 Michal Hlavinka - 1:2.0-0.9.beta5.20100515 +- pigeonhole and dovecot updated to snapshot 20100515 +- fix crash for THREAD command + +* Wed May 05 2010 Michal Hlavinka - 1:2.0-0.8.beta4.20100505 +- pigeonhole and dovecot updated to snapshot 20100505 +- mdbox: Avoid rebuilding storage if another process already did it +- lib-storage: Fixed () sublists in IMAP SEARCH parser +- example-config: auth-checkpassword include wasn't listed in 10-auth.conf +- doveadm: Added search command +- lib-master: Don't crash after timeouting an auth-master request +- master: If inet listener uses DNS name, which returns multiple IPs, + listen in all of them + +* Wed Apr 28 2010 Michal Hlavinka - 1:2.0-0.7.beta4.20100427 +- updated to snapshot 20100427 +- doveconf now prints only the one setting's value +- mdbox: Automatically delete old temp.* files from storage/ directory +- mdbox: use flock locking by default + +* Wed Apr 21 2010 Michal Hlavinka - 1:2.0-0.6.beta4.20100421 +- updated to snapshot 20100421 +- mdbox: Purge crashed if it purged all messages from a file +- lib-storage: Shared namespace's prefix_len wasn't updated after prefix was truncated +- imap-quota: Iterate quota roots only once when replying to GETQUOTAROOT +- idle: Do cork/uncork when sending "OK Still here" notification +- login: If proxy returns ssl=yes and no port, switch port to imaps/pop3s + +* Wed Apr 14 2010 Michal Hlavinka - 1:2.0-0.5.beta4.20100414 +- add make check +- updated to snapshot 20100414 +- config: Added nn- prefix to *.conf files so the sort ordering makes more sense +- lib-master: Log an error if login client disconnects too early +- mdbox: If purging found corrupted files, it didn't auto-rebuild storage +- lib-storage: Added support for searching save date +- and more... +- pigeonhole updated: +- Mailbox extension: fixed memory leak in the mailboxexists test +- added login failure handler + +* Tue Apr 06 2010 Michal Hlavinka - 1:2.0-0.4.beta4.20100406 +- updated to snapshot 20100406 +- auth: If userdb lookup fails internally, don't cache the result. +- Added support for userdb lookup to fail with a reason +- sdbox: mailbox_update() could have changed UIDVALIDITY incorrectly +- layout=maildir++: Fixed deleting mailboxes with mailbox=file storages +- Fixed potential problems with parsing invalid address groups. +- dsync: Don't repeatedly try to keep opening the same failing mailbox +- lib-storage: Don't crash if root mail directory isn't given. + +* Tue Mar 30 2010 Michal Hlavinka - 1:2.0-0.3.beta4.20100330 +- fix certs location in ssl.conf + +* Mon Mar 29 2010 Michal Hlavinka - 1:2.0-0.2.beta4.aefa279e2c70 +- update to snapshot aefa279e2c70 from 2010-03-27 +- fixes complains about missing tcpwrap (#577426) + +* Thu Mar 25 2010 Michal Hlavinka - 1:2.0-0.1.beta4 +- dovecot updated to 2.0 beta 4 + +* Fri Mar 12 2010 Michal Hlavinka - 1:1.2.11-2 +- fix missing bzip2 support in zlib plugin (#572797) + +* Tue Mar 09 2010 Michal Hlavinka - 1:1.2.11-1 +- updated to 1.2.11 +- mbox: Message header reading was unnecessarily slow. Fetching a + huge header could have resulted in Dovecot eating a lot of CPU. + Also searching messages was much slower than necessary. +- maildir: Reading uidlist could have ended up in an infinite loop. +- IMAP IDLE: v1.2.7+ caused extra load by checking changes every + 0.5 seconds after a change had occurred in mailbox + +* Tue Feb 23 2010 Michal Hlavinka - 1:1.2.10-4 +- move libs to correct package + +* Fri Feb 19 2010 Michal Hlavinka - 1:1.2.10-3 +- merged dovecot-sieve and dovecot-managesieve into dovecot-pigeonhole +- merged dovecot-sqlite, dovecot-gssapi and dovecot-ldap into dovecot + +* Mon Jan 25 2010 Michal Hlavinka - 1:1.2.10-2 +- updated sive and managesieve +- Added preliminary support for Sieve plugins and added support for + installing Sieve development headers +- Variables extension: added support for variable namespaces. +- Added configurable script size limit. Compiler will refuse to + compile files larger than sieve_max_script_size. +- Fixed a bug in the i;ascii-numeric comparator. If one of the + strings started with a non-digit character, the comparator would + always yield less-than. +- Imap4flags extension: fixed bug in removeflag: removing a single + flag failed due to off-by-one error (bug report by Julian Cowley). +- Fixed parser recovery. In particular cases it would trigger spurious + errors after an initial valid error and sometimes additional errors + were inappropriately ignored. +- Implemented ManageSieve QUOTA enforcement. +- Added MAXREDIRECTS capability after login. +- Implemented new script name rules specified in most recent + ManageSieve draft. +- Fixed assertion failure occuring with challenge-response SASL + mechanisms. + +* Mon Jan 25 2010 Michal Hlavinka - 1:1.2.10-1 +- updated to 1.2.10 +- %%variables now support %%{host}, %%{pid} and %%{env:ENVIRONMENT_NAME} + everywhere. +- LIST-STATUS capability is now advertised +- maildir: Fixed several assert-crashes. +- imap: LIST "" inbox shouldn't crash when using namespace with + "INBOX." prefix. +- lazy_expunge now ignores non-private namespaces. + +* Tue Dec 22 2009 Michal Hlavinka - 1:1.2.9-2 +- sieve updated to 0.1.14 +- managesieve updated to 0.11.10 + +* Fri Dec 18 2009 Michal Hlavinka - 1:1.2.9-1 +- updated to 1.2.9 +- maildir: When saving, filenames now always contain ,S=. + Previously this was done only when quota plugin was loaded. It's + required for zlib plugin and may be useful for other things too. +- maildir: v1.2.7 and v1.2.8 caused assert-crashes in + maildir_uidlist_records_drop_expunges() +- maildir_copy_preserve_filename=yes could have caused crashes. +- Maildir++ quota: % limits weren't updated when limits were read + from maildirsize. +- virtual: v1.2.8 didn't fully fix the "lots of mailboxes" bug +- virtual: Fixed updating virtual mailbox based on flag changes. +- fts-squat: Fixed searching multi-byte characters. + +* Wed Nov 25 2009 Michal Hlavinka - 1:1.2.8-4 +- spec cleanup + +* Tue Nov 24 2009 Michal Hlavinka - 1:1.2.8-3 +- fix dovecot's restart after update (#518753) + +* Tue Nov 24 2009 Michal Hlavinka - 1:1.2.8-2 +- fix initdddir typo (for rhel rebuilds) + +* Fri Nov 20 2009 Michal Hlavinka - 1:1.2.8-1 +- update to dovecot 1.2.8 + +* Mon Nov 16 2009 Michal Hlavinka - 1:1.2.7-2 +- use originall managesieve to dovecot diff +- EPEL-ize spec for rhel5 rebuilds (#537666) + +* Fri Nov 13 2009 Michal Hlavinka - 1:1.2.7-1 +- updated to dovecot 1.2.7 +- add man pages +- IMAP: IDLE now sends "Still here" notifications to same user's + connections at the same time. This hopefully reduces power usage + of some mobile clients that use multiple IDLEing connections. +- IMAP: If imap_capability is set, show it in the login banner. +- IMAP: Implemented SORT=DISPLAY extension. +- Login process creation could have sometimes failed with epoll_ctl() + errors or without epoll probably some other strange things could + have happened. +- Maildir: Fixed some performance issues +- Maildir: Fixed crash when using a lot of keywords. +- Several fixes to QRESYNC extension and modseq handling +- mbox: Make sure failed saves get rolled back with NFS. +- dbox: Several fixes. + +* Mon Nov 02 2009 Michal Hlavinka - 1:1.2.6-5 +- spec cleanup + +* Wed Oct 21 2009 Michal Hlavinka - 1:1.2.6-4 +- imap-login: If imap_capability is set, show it in the banner + instead of the default (#524485) + +* Mon Oct 19 2009 Michal Hlavinka - 1:1.2.6-3 +- sieve updated to 0.1.13 which brings these changes: +- Body extension: implemented proper handling of the :raw transform + and added various new tests to the test suite. However, :content + "multipart" and :content "message/rfc822" are still not working. +- Fixed race condition occuring when multiple instances are saving the + same binary (patch by Timo Sirainen). +- Body extension: don't give SKIP_BODY_BLOCK flag to message parser, + we want the body! +- Fixed bugs in multiscript support; subsequent keep actions were not + always merged correctly and implicit side effects were not always + handled correctly. +- Fixed a segfault bug in the sieve-test tool occuring when compile + fails. +- Fixed segfault bug in action procesing. It was triggered while + merging side effects in duplicate actions. +- Fixed bug in the Sieve plugin that caused it to try to stat() a NULL + path, yielding a 'Bad address' error. + +* Fri Oct 09 2009 Michal Hlavinka - 1:1.2.6-2 +- fix init script for case when no action was specified + +* Tue Oct 06 2009 Michal Hlavinka - 1:1.2.6-1 +- dovecot updated to 1.2.6 +- Added authtest utility for doing passdb and userdb lookups. +- login: ssl_security string now also shows the used compression. +- quota: Don't crash with non-Maildir++ quota backend. +- imap proxy: Fixed crashing with some specific password characters. +- fixed broken dovecot --exec-mail. +- Avoid assert-crashing when two processes try to create index at the + same time. + +* Tue Sep 29 2009 Michal Hlavinka - 1:1.2.5-2 +- build with libcap enabled + +* Thu Sep 17 2009 Michal Hlavinka - 1:1.2.5-1 +- updated to dovecot 1.2.5 +- Authentication: DIGEST-MD5 and RPA mechanisms no longer require + user's login realm to be listed in auth_realms. It only made + configuration more difficult without really providing extra security. +- zlib plugin: Don't allow clients to save compressed data directly. + This prevents users from exploiting (most of the) potential security + holes in zlib/bzlib. +- fix index file handling that could have caused an assert-crash +- IMAP: Fixes to QRESYNC extension. +- deliver: Don't send rejects to any messages that have Auto-Submitted + header. This avoids emails loops. + +* Wed Sep 16 2009 Tomas Mraz - 1:1.2.4-3 +- use password-auth common PAM configuration instead of system-auth + +* Fri Aug 21 2009 Tomas Mraz - 1:1.2.4-2 +- rebuilt with new openssl + +* Fri Aug 21 2009 Michal Hlavinka - 1:1.2.4-1 +- updated: dovecot 1.2.4, managesieve 0.11.9, sieve 0.1.12 +- fixed a crash in index file handling +- fixed a crash in saving messages where message contained a CR + character that wasn't followed by LF +- fixed a crash when listing shared namespace prefix +- sieve: implemented the new date extension. This allows matching + against date values in header fields and the current date at + the time of script evaluation +- managesieve: reintroduced ability to abort SASL with "*" response + +* Mon Aug 10 2009 Michal Hlavinka - 1:1.2.3-1 +- updated: dovecot 1.2.3, managesieve 0.11.8, sieve 0.1.11 +- Mailbox names with control characters can't be created anymore. + Existing mailboxes can still be accessed though. +- Allow namespace prefix to be opened as mailbox, if a mailbox + already exists in the root dir. +- Maildir: dovecot-uidlist was being recreated every time a mailbox + was accessed, even if nothing changed. +- listescape plugin was somewhat broken +- ldap: Fixed hang when >128 requests were sent at once. +- fts_squat: Fixed crashing when searching virtual mailbox. +- imap: Fixed THREAD .. INTHREAD crashing. + +* Tue Jul 28 2009 Michal Hlavinka - 1:1.2.2-1.20090728snap +- updated to post 1.2.2 snapshot (including post release GSSAPI fix) +- Fixed "corrupted index cache file" errors +- IMAP: FETCH X-* parameters weren't working. +- Maildir++ quota: Quota was sometimes updated wrong +- Dovecot master process could hang if it received signals too rapidly + +* Fri Jul 24 2009 Fedora Release Engineering - 1:1.2.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Thu Jul 23 2009 Michal Hlavinka - 1:1.2.1-2 +- updated sieve plugin to 0.1.9 + +* Mon Jul 13 2009 Michal Hlavinka - 1:1.2.1-1 +- updated to 1.2.1 +- GSSAPI authentication is fixed (#506782) +- logins now fail if home directory path is relative, because it was + not working correctly and never was expected to work +- sieve and managesieve update + +* Mon Apr 20 2009 Michal Hlavinka - 1:1.2-0.rc3.1 +- updated to 1.2.rc3 + +* Mon Apr 06 2009 Michal Hlavinka - 1:1.2-0.rc2.1 +- updated to 1.2.rc2 + +* Mon Mar 30 2009 Michal Hlavinka - 1:1.2-0.beta4.2 +- fix typo and rebuild + +* Mon Mar 30 2009 Michal Hlavinka - 1:1.2-0.beta4.1 +- spec clean-up +- updated to 1.2.beta4 + +* Tue Feb 24 2009 Fedora Release Engineering - 1:1.1.11-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Wed Feb 11 2009 Michal Hlavinka - 1:1.1.11-1 +- updated to 1.1.11 +- IMAP: PERMANENTFLAGS list didn't contain \*, causing some clients + not to save keywords. +- auth: Using "username" or "domain" passdb fields caused problems + with cache and blocking passdbs in v1.1.8 .. v1.1.10. +- userdb prefetch + blocking passdbs was broken with non-plaintext + auth in v1.1.8 .. v1.1.10. + +* Tue Jan 27 2009 Michal Hlavinka - 1:1.1.10-1 +- updated to 1.1.10 + +* Sat Jan 24 2009 Dan Horak - 1:1.1.8-3 +- rebuild with new mysql + +* Tue Jan 13 2009 Michal Hlavinka - 1:1.1.8-2 +- added managesieve support (thanks Helmut K. C. Tessarek) + +* Thu Jan 8 2009 Michal Hlavinka - 1:1.1.8-1 +- dovecot updated to 1.1.8 +- sieve-plugin updated to 1.1.6 + +* Tue Dec 2 2008 Michal Hlavinka - 1:1.1.7-2 +- revert changes from 1:1.1.6-2 and 1:1.1.6-1 +- password can be stored in different file readable only for root + via !include_try directive + +* Tue Dec 2 2008 Michal Hlavinka - 1:1.1.7-1 +- update to upstream version 1.1.7 + +* Mon Nov 3 2008 Michal Hlavinka - 1:1.1.6-2 +- changed comment in sysconfig to match actual state + +* Mon Nov 3 2008 Michal Hlavinka - 1:1.1.6-1 +- update to upstream version 1.1.6 +- change permissions of deliver and dovecot.conf to prevent possible password exposure + +* Wed Oct 29 2008 Michal Hlavinka - 1:1.1.5-1 +- update to upstream version 1.1.5 (Resolves: CVE-2008-4577, CVE-2008-4578) + +* Tue Sep 2 2008 Dan Horak - 1:1.1.3-1 +- update to upstream version 1.1.3 + +* Tue Jul 29 2008 Dan Horak - 1:1.1.2-2 +- really ask for the password during start-up + +* Tue Jul 29 2008 Dan Horak - 1:1.1.2-1 +- update to upstream version 1.1.2 +- final solution for #445200 (add /etc/sysconfig/dovecot for start-up options) + +* Fri Jun 27 2008 Dan Horak - 1:1.1.1-2 +- update default settings to listen on both IPv4 and IPv6 instead of IPv6 only + +* Sun Jun 22 2008 Dan Horak - 1:1.1.1-1 +- update to upstream version 1.1.1 + +* Sat Jun 21 2008 Dan Horak - 1:1.1.0-1 +- update to upstream version 1.1.0 +- update sieve plugin to 1.1.5 +- remove unnecessary patches +- enable ldap and gssapi plugins +- change ownership of dovecot.conf (Resolves: #452088) + +* Wed Jun 18 2008 Dan Horak - 1:1.0.14-4 +- update init script (Resolves: #451838) + +* Fri Jun 6 2008 Dan Horak - 1:1.0.14-3 +- build devel subpackage (Resolves: #306881) + +* Thu Jun 5 2008 Dan Horak - 1:1.0.14-2 +- install convert-tool (Resolves: #450010) + +* Tue Jun 3 2008 Dan Horak - 1:1.0.14-1 +- update to upstream version 1.0.14 +- remove setcred patch (use of setcred must be explictly enabled in config) + +* Thu May 29 2008 Dan Horak - 1:1.0.13-8 +- update scriptlets to follow UsersAndGroups guideline +- remove support for upgrading from version < 1.0 from scriptlets +- Resolves: #448095 + +* Tue May 20 2008 Dan Horak - 1:1.0.13-7 +- spec file cleanup +- update sieve plugin to 1.0.3 +- Resolves: #445200, #238018 + +* Sun Mar 09 2008 Tomas Janousek - 1:1.0.13-6 +- update to latest upstream stable (1.0.13) + +* Wed Feb 20 2008 Fedora Release Engineering - 1:1.0.10-5 +- Autorebuild for GCC 4.3 + +* Mon Jan 07 2008 Tomas Janousek - 1:1.0.10-4 +- update to latest upstream stable (1.0.10) + +* Wed Dec 05 2007 Jesse Keating - 1:1.0.7-3 +- Bump for deps + +* Mon Nov 05 2007 Tomas Janousek - 1:1.0.7-2 +- update to latest upstream stable (1.0.7) +- added the winbind patch (#286351) + +* Tue Sep 25 2007 Tomas Janousek - 1:1.0.5-1 +- downgraded to lastest upstream stable (1.0.5) + +* Wed Aug 22 2007 Tomas Janousek - 1.1-16.1.alpha3 +- updated license tags + +* Mon Aug 13 2007 Tomas Janousek - 1.1-16.alpha3 +- updated to latest upstream alpha +- update dovecot-sieve to 0367450c9382 from hg + +* Fri Aug 10 2007 Tomas Janousek - 1.1-15.alpha2 +- updated to latest upstream alpha +- split ldap and gssapi plugins to subpackages + +* Wed Jul 25 2007 Tomas Janousek - 1.1-14.6.hg.a744ae38a9e1 +- update to a744ae38a9e1 from hg +- update dovecot-sieve to 131e25f6862b from hg and enable it again + +* Thu Jul 19 2007 Tomas Janousek - 1.1-14.5.alpha1 +- update to latest upstream alpha +- don't build dovecot-sieve, it's only for 1.0 + +* Sun Jul 15 2007 Tomas Janousek - 1.0.2-13.5 +- update to latest upstream + +* Mon Jun 18 2007 Tomas Janousek - 1.0.1-12.5 +- update to latest upstream + +* Fri Jun 08 2007 Tomas Janousek - 1.0.0-11.7 +- specfile merge from 145241 branch + - new sql split patch + - support for not building all sql modules + - split sql libraries to separate packages + +* Sat Apr 14 2007 Tomas Janousek - 1.0.0-11.1 +- dovecot-1.0.beta2-pam-tty.patch is no longer needed + +* Fri Apr 13 2007 Tomas Janousek - 1.0.0-11 +- update to latest upstream + +* Tue Apr 10 2007 Tomas Janousek - 1.0-10.rc31 +- update to latest upstream + +* Fri Apr 06 2007 Tomas Janousek - 1.0-9.rc30 +- update to latest upstream + +* Fri Mar 30 2007 Tomas Janousek - 1.0-8.1.rc28 +- spec file cleanup (fixes docs path) + +* Fri Mar 23 2007 Tomas Janousek - 1.0-8.rc28 +- update to latest upstream + +* Mon Mar 19 2007 Tomas Janousek - 1.0-7.rc27 +- use dovecot-sieve's version for the package + +* Mon Mar 19 2007 Tomas Janousek - 1.0-6.rc27 +- update to latest upstream +- added dovecot-sieve + +* Fri Mar 02 2007 Tomas Janousek - 1.0-5.rc25 +- update to latest upstream + +* Sun Feb 25 2007 Jef Spaleta - 1.0-4.rc22 +- Merge review changes + +* Thu Feb 08 2007 Tomas Janousek - 1.0-3.rc22 +- update to latest upstream, fixes a few bugs + +* Mon Jan 08 2007 Tomas Janousek - 1.0-2.rc17 +- update to latest upstream, fixes a few bugs + +* Thu Dec 21 2006 Tomas Janousek - 1.0-1.1.rc15 +- reenabled GSSAPI (#220377) + +* Tue Dec 05 2006 Tomas Janousek - 1.0-1.rc15 +- update to latest upstream, fixes a few bugs, plus a security + vulnerability (#216508, CVE-2006-5973) + +* Tue Oct 10 2006 Petr Rockai - 1.0-0.3.rc7 +- fix few inconsistencies in specfile, fixes #198940 + +* Wed Oct 04 2006 Petr Rockai - 1.0-0.2.rc7 +- fix default paths in the example mkcert.sh to match configuration + defaults (fixes #183151) + +* Sun Oct 01 2006 Jesse Keating - 1.0-0.1.rc7 +- rebuilt for unwind info generation, broken in gcc-4.1.1-21 + +* Fri Sep 22 2006 Petr Rockai - 1.0-0.rc7 +- update to latest upstream release candidate, should fix occasional + hangs and mbox issues... INBOX. namespace is still broken though +- do not run over symlinked certificates in new locations on upgrade + +* Tue Aug 15 2006 Petr Rockai - 1.0-0.rc2.2 +- include /var/lib/dovecot in the package, prevents startup failure + on new installs + +* Mon Jul 17 2006 Petr Rockai - 1.0-0.rc2.1 +- reenable inotify and see what happens + +* Thu Jul 13 2006 Petr Rockai - 1.0-0.rc2 +- update to latest upstream release candidate +- disable inotify for now, doesn't build -- this needs fixing though + +* Wed Jul 12 2006 Jesse Keating - 1.0-0.beta8.2.1 +- rebuild + +* Thu Jun 08 2006 Petr Rockai - 1.0-0.beta8.2 +- put back pop3_uidl_format default that got lost + in the beta2->beta7 upgrade (would cause pop3 to not work + at all in many situations) + +* Thu May 04 2006 Petr Rockai - 1.0-0.beta8.1 +- upgrade to latest upstream beta release (beta8) +- contains a security fix in mbox handling + +* Thu May 04 2006 Petr Rockai - 1.0-0.beta7.1 +- upgrade to latest upstream beta release +- fixed BR 173048 + +* Fri Mar 17 2006 Petr Rockai - 1.0-0.beta2.8 +- fix sqlite detection in upstream configure checks, second part + of #182240 + +* Wed Mar 8 2006 Bill Nottingham - 1.0-0.beta2.7 +- fix scriplet noise some more + +* Mon Mar 6 2006 Jeremy Katz - 1.0-0.beta2.6 +- fix scriptlet error (mitr, #184151) + +* Mon Feb 27 2006 Petr Rockai - 1.0-0.beta2.5 +- fix #182240 by looking in lib64 for libs first and then lib +- fix comment #1 in #182240 by copying over the example config files + to documentation directory + +* Fri Feb 10 2006 Jesse Keating - 1.0-0.beta2.4.1 +- bump again for double-long bug on ppc(64) + +* Thu Feb 09 2006 Petr Rockai - 1.0-0.beta2.4 +- enable inotify as it should work now (#179431) + +* Tue Feb 07 2006 Jesse Keating - 1.0-0.beta2.3.1 +- rebuilt for new gcc4.1 snapshot and glibc changes + +* Thu Feb 02 2006 Petr Rockai - 1.0-0.beta2.3 +- change the compiled-in defaults and adjust the default's configfile + commented-out example settings to match compiled-in defaults, + instead of changing the defaults only in the configfile, as per #179432 +- fix #179574 by providing a default uidl_format for pop3 +- half-fix #179620 by having plaintext auth enabled by default... this + needs more thinking (which one we really want) and documentation + either way + +* Tue Jan 31 2006 Petr Rockai - 1.0-0.beta2.2 +- update URL in description +- call dovecot --build-ssl-parameters in postinst as per #179430 + +* Mon Jan 30 2006 Petr Rockai - 1.0-0.beta2.1 +- fix spec to work with BUILD_DIR != SOURCE_DIR +- forward-port and split pam-nocred patch + +* Mon Jan 23 2006 Petr Rockai - 1.0-0.beta2 +- new upstream version, hopefully fixes #173928, #163550 +- fix #168866, use install -p to install documentation + +* Fri Dec 09 2005 Jesse Keating +- rebuilt + +* Sat Nov 12 2005 Tom Lane - 0.99.14-10.fc5 +- Rebuild due to mysql update. + +* Wed Nov 9 2005 Tomas Mraz - 0.99.14-9.fc5 +- rebuilt with new openssl + +* Fri Sep 30 2005 Tomas Mraz - 0.99.14-8.fc5 +- use include instead of pam_stack in pam config + +* Wed Jul 27 2005 John Dennis - 0.99.14-7.fc5 +- fix bug #150888, log authenication failures with ip address + +* Fri Jul 22 2005 John Dennis - 0.99.14-6.fc5 +- fix bug #149673, add dummy PAM_TTY + +* Thu Apr 28 2005 John Dennis - 0.99.14-5.fc4 +- fix bug #156159 insecure location of restart flag file + +* Fri Apr 22 2005 John Dennis - 0.99.14-4.fc4 +- openssl moved its certs, CA, etc. from /usr/share/ssl to /etc/pki + +* Tue Apr 12 2005 Tom Lane 0.99.14-3.fc4 +- Rebuild for Postgres 8.0.2 (new libpq major version). + +* Mon Mar 7 2005 John Dennis 0.99.14-2.fc4 +- bump rev for gcc4 build + +* Mon Feb 14 2005 John Dennis - 0.99.14-1.fc4 +- fix bug #147874, update to 0.99.14 release + v0.99.14 2005-02-11 Timo Sirainen + - Message address fields are now parsed differently, fixing some + issues with spaces. Affects only clients which use FETCH ENVELOPE + command. + - Message MIME parser was somewhat broken with missing MIME boundaries + - mbox: Don't allow X-UID headers in mails to override the UIDs we + would otherwise set. Too large values can break some clients and + cause other trouble. + - passwd-file userdb wasn't working + - PAM crashed with 64bit systems + - non-SSL inetd startup wasn't working + - If UID FETCH notices and skips an expunged message, don't return + a NO reply. It's not needed and only makes clients give error + messages. + +* Wed Feb 2 2005 John Dennis - 0.99.13-4.devel +- fix bug #146198, clean up temp kerberos tickets + +* Mon Jan 17 2005 John Dennis 0.99.13-3.devel +- fix bug #145214, force mbox_locks to fcntl only +- fix bug #145241, remove prereq on postgres and mysql, allow rpm auto + dependency generator to pick up client lib dependency if needed. + +* Thu Jan 13 2005 John Dennis 0.99.13-2.devel +- make postgres & mysql conditional build +- remove execute bit on migration example scripts so rpm does not pull + in additional dependences on perl and perl modules that are not present + in dovecot proper. +- add REDHAT-FAQ.txt to doc directory + +* Thu Jan 6 2005 John Dennis 0.99.13-1.devel +- bring up to date with latest upstream, 0.99.13, bug #143707 + also fix bug #14462, bad dovecot-uid macro name + +* Thu Jan 6 2005 John Dennis 0.99.11-10.devel +- fix bug #133618, removed LITERAL+ capability from capability string + +* Wed Jan 5 2005 John Dennis 0.99.11-9.devel +- fix bug #134325, stop dovecot during installation + +* Wed Jan 5 2005 John Dennis 0.99.11-8.devel +- fix bug #129539, dovecot starts too early, + set chkconfig to 65 35 to match cyrus-imapd +- also delete some old commented out code from SSL certificate creation + +* Thu Dec 23 2004 John Dennis 0.99.11-7.devel +- add UW to Dovecot migration documentation and scripts, bug #139954 + fix SSL documentation and scripts, add missing documentation, bug #139276 + +* Mon Nov 15 2004 Warren Togami 0.99.11-2.FC4.1 +- rebuild against MySQL4 + +* Thu Oct 21 2004 John Dennis +- fix bug #136623 + Change License field from GPL to LGPL to reflect actual license + +* Thu Sep 30 2004 John Dennis 0.99.11-1.FC3.3 +- fix bug #124786, listen to ipv6 as well as ipv4 + +* Wed Sep 8 2004 John Dennis 0.99.11-1.FC3.1 +- bring up to latest upstream, + comments from Timo Sirainen on release v0.99.11 2004-09-04 + + 127.* and ::1 IP addresses are treated as secured with + disable_plaintext_auth = yes + + auth_debug setting for extra authentication debugging + + Some documentation and error message updates + + Create PID file in /var/run/dovecot/master.pid + + home setting is now optional in static userdb + + Added mail setting to static userdb + - After APPENDing to selected mailbox Dovecot didn't always notice the + new mail immediately which broke some clients + - THREAD and SORT commands crashed with some mails + - If APPENDed mail ended with CR character, Dovecot aborted the saving + - Output streams sometimes sent data duplicated and lost part of it. + This could have caused various strange problems, but looks like in + practise it rarely caused real problems. + +* Wed Aug 4 2004 John Dennis +- change release field separator from comma to dot, bump build number + +* Mon Aug 2 2004 John Dennis 0.99.10.9-1,FC3,1 +- bring up to date with latest upstream, fixes include: +- LDAP support compiles now with Solaris LDAP library +- IMAP BODY and BODYSTRUCTURE replies were wrong for MIME parts which + didn't contain Content-Type header. +- MySQL and PostgreSQL auth didn't reconnect if connection was lost + to SQL server +- Linking fixes for dovecot-auth with some systems +- Last fix for disconnecting client when downloading mail longer than + 30 seconds actually made it never disconnect client. Now it works + properly: disconnect when client hasn't read _any_ data for 30 + seconds. +- MySQL compiling got broken in last release +- More PostgreSQL reconnection fixing + + +* Mon Jul 26 2004 John Dennis 0.99.10.7-1,FC3,1 +- enable postgres and mySQL in build +- fix configure to look for mysql in alternate locations +- nuke configure script in tar file, recreate from configure.in using autoconf + +- bring up to latest upstream, which included: +- Added outlook-pop3-no-nuls workaround to fix Outlook hang in mails with NULs. +- Config file lines can now contain quoted strings ("value ") +- If client didn't finish downloading a single mail in 30 seconds, + Dovecot closed the connection. This was supposed to work so that + if client hasn't read data at all in 30 seconds, it's disconnected. +- Maildir: LIST now doesn't skip symlinks + + +* Wed Jun 30 2004 John Dennis +- bump rev for build +- change rev for FC3 build + +* Fri Jun 25 2004 John Dennis - 0.99.10.6-1 +- bring up to date with upstream, + recent change log comments from Timo Sirainen were: + SHA1 password support using OpenSSL crypto library + mail_extra_groups setting + maildir_stat_dirs setting + Added NAMESPACE capability and command + Autocreate missing maildirs (instead of crashing) + Fixed occational crash in maildir synchronization + Fixed occational assertion crash in ioloop.c + Fixed FreeBSD compiling issue + Fixed issues with 64bit Solaris binary + +* Tue Jun 15 2004 Elliot Lee +- rebuilt + +* Thu May 27 2004 David Woodhouse 0.99.10.5-1 +- Update to 0.99.10.5 to fix maildir segfaults (#123022) + +* Fri May 07 2004 Warren Togami 0.99.10.4-4 +- default auth config that is actually usable +- Timo Sirainen (author) suggested functionality fixes + maildir, imap-fetch-body-section, customflags-fix + +* Mon Feb 23 2004 Tim Waugh +- Use ':' instead of '.' as separator for chown. + +* Tue Feb 17 2004 Jeremy Katz - 0.99.10.4-3 +- restart properly if it dies (#115594) + +* Fri Feb 13 2004 Elliot Lee +- rebuilt + +* Mon Nov 24 2003 Jeremy Katz 0.99.10.4-1 +- update to 0.99.10.4 + +* Mon Oct 6 2003 Jeremy Katz 0.99.10-7 +- another patch from upstream to fix returning invalid data on partial + BODY[part] fetches +- patch to avoid confusion of draft/deleted in indexes + +* Tue Sep 23 2003 Jeremy Katz 0.99.10-6 +- add some patches from upstream (#104288) + +* Thu Sep 4 2003 Jeremy Katz 0.99.10-5 +- fix startup with 2.6 with patch from upstream (#103801) + +* Tue Sep 2 2003 Jeremy Katz 0.99.10-4 +- fix assert in search code (#103383) + +* Tue Jul 22 2003 Nalin Dahyabhai 0.99.10-3 +- rebuild + +* Thu Jul 17 2003 Bill Nottingham 0.99.10-2 +- don't run by default + +* Thu Jun 26 2003 Jeremy Katz 0.99.10-1 +- 0.99.10 + +* Mon Jun 23 2003 Jeremy Katz 0.99.10-0.2 +- 0.99.10-rc2 (includes ssl detection fix) +- a few tweaks from fedora + - noreplace the config file + - configure --with-ldap to get LDAP enabled + +* Mon Jun 23 2003 Jeremy Katz 0.99.10-0.1 +- 0.99.10-rc1 +- add fix for ssl detection +- add zlib-devel to BuildRequires +- change pam service name to dovecot +- include pam config + +* Thu May 8 2003 Jeremy Katz 0.99.9.1-1 +- update to 0.99.9.1 +- add patch from upstream to fix potential bug when fetching with + CR+LF linefeeds +- tweak some things in the initscript and config file noticed by the + fedora folks + +* Sun Mar 16 2003 Jeremy Katz 0.99.8.1-2 +- fix ssl dir +- own /var/run/dovecot/login with the correct perms +- fix chmod/chown in post + +* Fri Mar 14 2003 Jeremy Katz 0.99.8.1-1 +- update to 0.99.8.1 + +* Tue Mar 11 2003 Jeremy Katz 0.99.8-2 +- add a patch to fix quoting problem from CVS + +* Mon Mar 10 2003 Jeremy Katz 0.99.8-1 +- 0.99.8 +- add some buildrequires +- fixup to build with openssl 0.9.7 +- now includes a pop3 daemon (off by default) +- clean up description and %%preun +- add dovecot user (uid/gid of 97) +- add some buildrequires +- move the ssl cert to %%{_datadir}/ssl/certs +- create a dummy ssl cert in %%post +- own /var/run/dovecot +- make the config file a source so we get default mbox locks of fcntl + +* Sun Dec 1 2002 Seth Vidal +- 0.99.4 and fix startup so it starts imap-master not vsftpd :) + +* Tue Nov 26 2002 Seth Vidal +- first build