summaryrefslogtreecommitdiff
path: root/user/dovecot
diff options
context:
space:
mode:
Diffstat (limited to 'user/dovecot')
-rw-r--r--user/dovecot/APKBUILD275
-rw-r--r--user/dovecot/CVE-2022-30550.patch155
-rw-r--r--user/dovecot/default-config.patch46
-rw-r--r--user/dovecot/dovecot.initd40
-rw-r--r--user/dovecot/dovecot.logrotate12
-rw-r--r--user/dovecot/dovecot.post-install45
-rw-r--r--user/dovecot/dovecot.post-upgrade7
-rw-r--r--user/dovecot/dovecot.pre-install8
-rw-r--r--user/dovecot/fix-time64.patch13
-rw-r--r--user/dovecot/skip-iconv-check.patch11
-rw-r--r--user/dovecot/split-protocols.patch30
-rw-r--r--user/dovecot/ssl-paths.patch13
-rw-r--r--user/dovecot/test-file-cache-enomem.patch20
13 files changed, 675 insertions, 0 deletions
diff --git a/user/dovecot/APKBUILD b/user/dovecot/APKBUILD
new file mode 100644
index 000000000..b85f3a97e
--- /dev/null
+++ b/user/dovecot/APKBUILD
@@ -0,0 +1,275 @@
+# Contributor: Valery Kartel <valery.kartel@gmail.com>
+# Contributor: Łukasz Jendrysik <scadu@yandex.com>
+# Contributor: Michael Mason <ms13sp@gmail.com>
+# Contributor: Jakub Jirutka <jakub@jirutka.cz>
+# Contributor: Natanael Copa <ncopa@alpinelinux.org>
+# Maintainer: Lee Starnes <lee@canned-death.us>
+pkgname=dovecot
+pkgver=2.3.21.1
+case "$pkgver" in
+ *.*.*.*) _pkgvermajor=${pkgver%.*.*};;
+ *.*.*) _pkgvermajor=${pkgver%.*};;
+esac
+pkgrel=1
+_pigeonholevel=0.5.21.1
+pkgdesc="IMAP and POP3 server"
+url="https://www.dovecot.org/"
+arch="all"
+options="libtool"
+license="LGPL-2.0+"
+depends="openssl"
+makedepends="autoconf automake libtool bzip2-dev expat-dev krb5-dev libcap-dev
+ libsodium-dev linux-headers linux-pam-dev mariadb-dev openldap-dev
+ openssl-dev postgresql-dev sqlite-dev zlib-dev"
+pkgusers="dovecot dovenull"
+pkggroups="dovecot dovenull"
+install="$pkgname.pre-install $pkgname.post-install $pkgname.post-upgrade"
+subpackages="$pkgname-doc $pkgname-dev $pkgname-openrc $pkgname-lmtpd
+ $pkgname-pop3d $pkgname-submissiond
+ $pkgname-pigeonhole-plugin-ldap:_sieve_ldap
+ $pkgname-pigeonhole-plugin:_sieve
+ $pkgname-sql $pkgname-pgsql $pkgname-mysql $pkgname-sqlite
+ $pkgname-gssapi $pkgname-ldap $pkgname-fts-solr:_fts_solr
+ "
+source="https://www.dovecot.org/releases/$_pkgvermajor/dovecot-$pkgver.tar.gz
+ https://pigeonhole.dovecot.org/releases/$_pkgvermajor/$pkgname-$_pkgvermajor-pigeonhole-$_pigeonholevel.tar.gz
+ fix-time64.patch
+ skip-iconv-check.patch
+ split-protocols.patch
+ default-config.patch
+ ssl-paths.patch
+ test-file-cache-enomem.patch
+ dovecot.logrotate
+ dovecot.initd
+ CVE-2022-30550.patch
+ "
+_builddir_pigeonhole="$srcdir/$pkgname-$_pkgvermajor-pigeonhole-$_pigeonholevel"
+
+# secfixes:
+# 2.3.21.1-r0:
+# - CVE-2024-23184
+# - CVE-2024-23185
+# 2.3.19.1-r0:
+# - CVE-2022-30550
+# 2.3.19-r0:
+# - CVE-2020-28200
+# - CVE-2021-29157
+# - CVE-2021-33515
+# 2.3.13-r0:
+# - CVE-2020-24386
+# - CVE-2020-25275
+# 2.3.11.3-r0:
+# - CVE-2020-12100
+# - CVE-2020-12673
+# - CVE-2020-12674
+# 2.3.10.1-r0:
+# - CVE-2020-10957
+# - CVE-2020-10958
+# - CVE-2020-10967
+
+_configure() {
+ ./configure \
+ --build=$CBUILD \
+ --host=$CHOST \
+ --prefix=/usr \
+ --localstatedir=/var \
+ --sysconfdir=/etc \
+ --mandir=/usr/share/man \
+ --infodir=/usr/share/info \
+ --disable-static \
+ "$@"
+}
+
+build() {
+ _configure \
+ --with-gssapi=plugin \
+ --with-ldap=plugin \
+ --with-sql=plugin \
+ --with-pam \
+ --with-mysql \
+ --with-sqlite \
+ --with-pgsql \
+ --with-solr \
+ --with-ssl=openssl \
+ --with-ssldir=/etc/ssl/dovecot \
+ --with-rundir=/run/dovecot \
+ --without-lucene
+ make
+
+ # Build pigeonhole plugin
+ cd "$_builddir_pigeonhole"
+ _configure \
+ --with-dovecot="$builddir" \
+ --with-ldap=plugin
+ make
+}
+
+check() {
+ make check
+}
+
+package() {
+ make DESTDIR="$pkgdir" install
+
+ cd "$pkgdir"
+
+ install -d ./etc/ssl/dovecot
+ install -D -m 755 "$srcdir"/dovecot.initd ./etc/init.d/dovecot
+ install -D -m 644 "$srcdir"/dovecot.logrotate ./etc/logrotate.d/dovecot
+
+ # default config
+ rm ./etc/dovecot/*
+ rm ./usr/share/doc/dovecot/mkcert.sh
+ mv ./usr/share/doc/dovecot/dovecot-openssl.cnf ./etc/dovecot/
+ mv ./usr/share/doc/dovecot/example-config/dovecot* \
+ ./usr/share/doc/dovecot/example-config/conf.d \
+ ./etc/dovecot/
+ rm -fr ./usr/share/doc/dovecot/example-config
+
+ # Installing pigeonhole plugin.
+ cd "$_builddir_pigeonhole"
+ make install DESTDIR="$pkgdir"
+
+ # Moving config in the correct place
+ mv "$pkgdir"/usr/share/doc/dovecot/example-config/conf.d/* \
+ "$pkgdir"/etc/dovecot/conf.d
+
+ # Remove libtool archives. abuild doesn't remove them automatically even without options=libtool.
+ find "$pkgdir" -name '*.la' | xargs rm -f
+}
+
+dev() {
+ default_dev
+ mkdir -p "$subpkgdir"/usr/lib/dovecot
+ mv "$pkgdir"/usr/lib/dovecot/dovecot-config \
+ "$subpkgdir"/usr/lib/dovecot/
+}
+
+lmtpd() {
+ pkgdesc="$pkgdesc (LMTP server)"
+ _protocol lmtp
+}
+
+pop3d() {
+ pkgdesc="$pkgdesc (POP3 daemon)"
+ _protocol pop3
+}
+
+submissiond() {
+ pkgdesc="$pkgdesc (mail submission agent)"
+ _protocol submission
+}
+
+_protocol() {
+ depends="$pkgname=$pkgver-r$pkgrel"
+ _name="$1"
+ _protocolsd="$subpkgdir/usr/share/dovecot/protocols.d"
+
+ cd "$pkgdir"
+ _submv usr/libexec/dovecot/$_name*
+ _submv etc/dovecot/conf.d/*-$_name.conf
+
+ mkdir -p "$_protocolsd"
+ echo "protocols = \$protocols $_name" \
+ > "$_protocolsd"/${subpkgname#$pkgname-}.conf
+}
+
+_sieve() {
+ pkgdesc="Sieve and managesieve plugin for Dovecot"
+ depends="$pkgname=$pkgver-r$pkgrel"
+
+ cd "$pkgdir"
+ _submv $(find usr/ -name '*sieve_extprograms*')
+ _submv $(find usr/ -name '*sieve_imapsieve*')
+ _submv $(find usr/ -name '*sieve*')
+ _submv $(find usr/ -name '*pigeonhole*')
+ _submv $(find etc/dovecot/ -name '*sieve*')
+}
+
+_sieve_ldap() {
+ pkgdesc="Sieve and managesieve plugin for Dovecot (LDAP support)"
+ depends="$pkgname-pigeonhole-plugin=$pkgver-r$pkgrel $pkgname-ldap=$pkgver-r$pkgrel"
+
+ cd "$pkgdir"
+ _submv $(find usr/ -name '*_sieve_storage_ldap_*')
+}
+
+pgsql() {
+ pkgdesc="PostgreSQL driver for Dovecot"
+ depends="$pkgname-sql=$pkgver-r$pkgrel"
+
+ cd "$pkgdir"
+ _submv $(find usr/ -name '*_pgsql*')
+}
+
+mysql() {
+ pkgdesc="MySQL driver for Dovecot"
+ depends="$pkgname-sql=$pkgver-r$pkgrel"
+
+ cd "$pkgdir"
+ _submv $(find usr/ -name '*_mysql*')
+}
+
+sqlite() {
+ pkgdesc="SQLite driver for Dovecot"
+ depends="$pkgname-sql=$pkgver-r$pkgrel"
+
+ cd "$pkgdir"
+ _submv $(find usr/ -name '*_sqlite*')
+}
+
+gssapi() {
+ pkgdesc="GSSAPI auth plugin for Dovecot"
+ depends="$pkgname=$pkgver-r$pkgrel"
+
+ cd "$pkgdir"
+ _submv $(find usr/ -name '*_gssapi*')
+}
+
+ldap() {
+ pkgdesc="LDAP auth plugin for Dovecot"
+ depends="$pkgname=$pkgver-r$pkgrel"
+
+ cd "$pkgdir"
+ _submv $(find usr/ -name '*[_-]ldap*')
+ _submv $(find etc/dovecot/ -name '*-ldap.conf*')
+}
+
+sql() {
+ pkgdesc="SQL plugin for dovecot"
+ depends="$pkgname=$pkgver-r$pkgrel"
+
+ cd "$pkgdir"
+ _submv $(find usr/ -name '*-sql.*')
+ _submv $(find etc/dovecot/ -name '*-sql.conf*')
+}
+
+_fts_solr() {
+ pkgdesc="FTS-Solr plugin for dovecot"
+ depends="$pkgname=$pkgver-r$pkgrel"
+
+ cd "$pkgdir"
+ _submv $(find usr/ -name '*fts*solr*')
+}
+
+_submv() {
+ while [ $# -gt 0 ]; do
+ _dir=${1%/*}
+ mkdir -p "$subpkgdir"/$_dir
+ mv "$pkgdir/$1" "$subpkgdir/$_dir/"
+ [ "$(ls -A $pkgdir/$_dir)" ] || rmdir "$pkgdir"/$_dir
+ shift
+ done
+}
+
+sha512sums="9de6ce3a579ef2040248b692874a6d64a732bb735a9cee3144604927cad49690c4b0e29f7ecf3af23190d56f30956d955d13acd5d352534df62fbdfde4b60f9f dovecot-2.3.21.1.tar.gz
+7387b417611599fe70d1a83d3b408321e66f5a883bf78a9d55c7496b1a17220677daebaefde2061e0d7064fe07c410ecfc64662878bb253ddcd9e128dd83fbaa dovecot-2.3-pigeonhole-0.5.21.1.tar.gz
+a73e7323a582ea9504c33ea3591784af8187af8fffbcc47b69f549e33620c532d976853f0f7a9071af6ef2970d4899e2c5b30aac605dd5c933b3c6faa391bad4 fix-time64.patch
+fe4fbeaedb377d809f105d9dbaf7c1b961aa99f246b77189a73b491dc1ae0aa9c68678dde90420ec53ec877c08f735b42d23edb13117d7268420e001aa30967a skip-iconv-check.patch
+794875dbf0ded1e82c5c3823660cf6996a7920079149cd8eed54231a53580d931b966dfb17185ab65e565e108545ecf6591bae82f935ab1b6ff65bb8ee93d7d5 split-protocols.patch
+0d8f89c7ba6f884719b5f9fc89e8b2efbdc3e181de308abf9b1c1b0e42282f4df72c7bf62f574686967c10a8677356560c965713b9d146e2770aab17e95bcc07 default-config.patch
+5e68a0042a7c11b3d8c411fc157f5960e2e3305dac11f4b6b880441e2b4105769ddf6c56f67a995af6e1a58f3bfa2c199ea51318a3a0e37c7ef0ae6c4109b13f ssl-paths.patch
+277d0b55583908cd6c063fb190eb3d2a362a3a33306e35a069a0bca28968f11627c455887d82d01884313b7f7e18530c056bd7a4cda0a1f9c4be7065cd033aa9 test-file-cache-enomem.patch
+9f19698ab45969f1f94dc4bddf6de59317daee93c9421c81f2dbf8a7efe6acf89689f1d30f60f536737bb9526c315215d2bce694db27e7b8d7896036a59c31f0 dovecot.logrotate
+d91951b81150d7a3ef6a674c0dc7b012f538164dac4b9d27a6801d31da6813b764995a438f69b6a680463e1b60a3b4f2959654f68e565fe116ea60312d5e5e70 dovecot.initd
+b2ff67fd8b6c5cea93877651a1168ef1a5d399cc5f1a61d1cce407c7624f5b6d758996084c6a5714b6880de0ce11ce5eac74a1e02918758cb6983caedb651c58 CVE-2022-30550.patch"
diff --git a/user/dovecot/CVE-2022-30550.patch b/user/dovecot/CVE-2022-30550.patch
new file mode 100644
index 000000000..d7da1316f
--- /dev/null
+++ b/user/dovecot/CVE-2022-30550.patch
@@ -0,0 +1,155 @@
+From 7bad6a24160e34bce8f10e73dbbf9e5fbbcd1904 Mon Sep 17 00:00:00 2001
+From: Timo Sirainen <timo.sirainen@open-xchange.com>
+Date: Mon, 9 May 2022 15:23:33 +0300
+Subject: [PATCH 1/2] 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. */
+
+From a1022072e2ce36f853873d910287f466165b184b Mon Sep 17 00:00:00 2001
+From: Timo Sirainen <timo.sirainen@open-xchange.com>
+Date: Mon, 16 May 2022 14:58:45 +0200
+Subject: [PATCH 2/2] auth: Add a comment about updating userdb_find()
+
+---
+ src/auth/userdb.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/src/auth/userdb.c b/src/auth/userdb.c
+index 0849659102..830bc2dd64 100644
+--- a/src/auth/userdb.c
++++ b/src/auth/userdb.c
+@@ -158,7 +158,8 @@ userdb_preinit(pool_t pool, const struct auth_userdb_settings *set)
+ userdb->id = ++auth_userdb_id;
+ userdb->iface = iface;
+ userdb->args = p_strdup(pool, set->args);
+-
++ /* NOTE: if anything else than driver & args are added here,
++ userdb_find() also needs to be updated. */
+ array_push_back(&userdb_modules, &userdb);
+ return userdb;
+ }
diff --git a/user/dovecot/default-config.patch b/user/dovecot/default-config.patch
new file mode 100644
index 000000000..0f8a7385a
--- /dev/null
+++ b/user/dovecot/default-config.patch
@@ -0,0 +1,46 @@
+--- a/doc/example-config/conf.d/10-mail.conf
++++ b/doc/example-config/conf.d/10-mail.conf
+@@ -208,10 +208,10 @@
+
+ # UNIX socket path to master authentication server to find users.
+ # This is used by imap (for shared users) and lda.
+-#auth_socket_path = /var/run/dovecot/auth-userdb
++#auth_socket_path = /run/dovecot/auth-userdb
+
+ # Directory where to look up mail plugins.
+-#mail_plugin_dir = /usr/lib/dovecot
++#mail_plugin_dir = /usr/lib/dovecot/modules
+
+ # Space separated list of plugins to load for all services. Plugins specific to
+ # IMAP, LDA, etc. are added to this list in their own .conf files.
+@@ -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
+--- a/doc/example-config/conf.d/10-ssl.conf
++++ b/doc/example-config/conf.d/10-ssl.conf
+@@ -3,7 +3,10 @@
+ ##
+
+ # SSL/TLS support: yes, no, required. <doc/wiki/SSL.txt>
+-#ssl = yes
++# Disable plain (unencrypted) 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
+@@ -67,7 +67,7 @@
+ #ssl_curve_list =
+
+ # Prefer the server's order of ciphers over client's.
+-#ssl_prefer_server_ciphers = no
++ssl_prefer_server_ciphers = yes
+
+ # SSL crypto device to use, for valid values run "openssl engine"
+ #ssl_crypto_device =
diff --git a/user/dovecot/dovecot.initd b/user/dovecot/dovecot.initd
new file mode 100644
index 000000000..721f131ad
--- /dev/null
+++ b/user/dovecot/dovecot.initd
@@ -0,0 +1,40 @@
+#!/sbin/openrc-run
+
+[ "$RC_SVCNAME" != "${RC_SVCNAME##*.}" ] && instance=${RC_SVCNAME##*.}
+
+description="Secure POP3/IMAP server"
+
+cfgfile=/etc/dovecot/dovecot${instance:+.$instance}.conf
+pidfile=$(doveconf -c $cfgfile -h base_dir 2>/dev/null)/master.pid
+command=/usr/sbin/dovecot
+command_args=${instance:+-c $cfgfile}
+required_files="$cfgfile"
+extra_started_commands="reload reopen"
+description_reload="Reload configuration"
+description_reopen="Reopen log files"
+
+depend() {
+ need localmount net
+ before mta
+ after bootmisc firewall ldap mysql ntp-client ntpd postgresql saslauthd slapd
+ use logger
+}
+
+start_pre() {
+ ebegin
+ doveconf -c $cfgfile -x >/dev/null 2>&1 && \
+ checkpath --directory ${pidfile%/*}
+ eend $?
+}
+
+reload() {
+ ebegin "Reloading $RC_SVCNAME configs and restarting auth/login processes"
+ start_pre && start-stop-daemon --signal HUP --pidfile $pidfile
+ eend $?
+}
+
+reopen() {
+ ebegin "Reopening $RC_SVCNAME log files"
+ start-stop-daemon --signal USR1 --pidfile $pidfile
+ eend $?
+}
diff --git a/user/dovecot/dovecot.logrotate b/user/dovecot/dovecot.logrotate
new file mode 100644
index 000000000..b1a4087b4
--- /dev/null
+++ b/user/dovecot/dovecot.logrotate
@@ -0,0 +1,12 @@
+/var/log/dovecot*.log {
+ daily
+ missingok
+ copytruncate
+ rotate 7
+ compress
+ notifempty
+ sharedscripts
+ postrotate
+ /etc/init.d/dovecot --quiet --ifstarted reopen
+ endscript
+}
diff --git a/user/dovecot/dovecot.post-install b/user/dovecot/dovecot.post-install
new file mode 100644
index 000000000..eb70cdece
--- /dev/null
+++ b/user/dovecot/dovecot.post-install
@@ -0,0 +1,45 @@
+#!/bin/sh
+
+# based on doc/mkcert.sh
+
+# if ssl disabled then lets just exit
+doveconf ssl 2>/dev/null | grep -Eq '(yes|required)' || exit 0
+# Generates a self-signed certificate.
+
+OPENSSL=${OPENSSL-openssl}
+SSLDIR=${SSLDIR-/etc/ssl/dovecot}
+OPENSSLCONFIG=${OPENSSLCONFIG-/etc/dovecot/dovecot-openssl.cnf}
+
+CERTDIR=$SSLDIR
+KEYDIR=$SSLDIR
+
+# check if we have ssl_cert and/or key (for dovecot-2.0+)
+# try expand the cert/key itself and if found, lets just keep it
+[ -n "$(doveconf -x ssl_cert 2>/dev/null)" ] && exit 0
+[ -n "$(doveconf -x ssl_key 2>/dev/null)" ] && exit 0
+
+ssl_cert_file=$(doveconf ssl_cert | sed 's/.*= <//')
+ssl_key_file=$(doveconf ssl_key | sed 's/.*= <//')
+
+CERTFILE=${ssl_cert_file:-$CERTDIR/server.pem}
+KEYFILE=${ssl_key_file:-$KEYDIR/server.key}
+
+if [ -e "$CERTFILE" ]; then
+ echo "Keeping existing $CERTFILE"
+ exit 0
+fi
+
+if [ -e "$KEYFILE" ]; then
+ echo "Keeping existing $KEYFILE"
+ exit 0
+fi
+
+if [ ! -c /dev/urandom ] && [ ! -c /dev/random ]; then
+ echo "No /dev/urandom or /dev/random so ssl cert not created"
+ exit 1
+fi
+
+$OPENSSL req -new -x509 -nodes -config $OPENSSLCONFIG -out $CERTFILE -keyout $KEYFILE -days 365 || exit 2
+chmod 0600 $KEYFILE
+echo
+$OPENSSL x509 -subject -fingerprint -noout -in $CERTFILE || exit 2
diff --git a/user/dovecot/dovecot.post-upgrade b/user/dovecot/dovecot.post-upgrade
new file mode 100644
index 000000000..69f4366ed
--- /dev/null
+++ b/user/dovecot/dovecot.post-upgrade
@@ -0,0 +1,7 @@
+#!/bin/sh
+if ! grep ^"version_ignore=yes" /etc/dovecot/dovecot.conf; then
+ printf "dovecot restart required (version_ignore=yes not set)\n"
+fi
+
+exit $?
+
diff --git a/user/dovecot/dovecot.pre-install b/user/dovecot/dovecot.pre-install
new file mode 100644
index 000000000..0f6df4c75
--- /dev/null
+++ b/user/dovecot/dovecot.pre-install
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+groupadd -r dovecot 2>/dev/null
+groupadd -r dovenull 2>/dev/null
+useradd -r -u 90 -d / -s /sbin/nologin -g dovecot dovecot 2>/dev/null
+useradd -r -u 91 -d / -s /sbin/nologin -g dovenull dovenull 2>/dev/null
+
+exit 0
diff --git a/user/dovecot/fix-time64.patch b/user/dovecot/fix-time64.patch
new file mode 100644
index 000000000..30d0307d5
--- /dev/null
+++ b/user/dovecot/fix-time64.patch
@@ -0,0 +1,13 @@
+We need to case this on sizeof(time_t), not sizeof(void*).
+
+--- dovecot-2.3.20/src/lib-index/mail-cache-fields.c.old 2023-02-22 08:01:49.420556821 +0000
++++ dovecot-2.3.20/src/lib-index/mail-cache-fields.c 2023-02-23 09:45:11.417417626 +0000
+@@ -529,7 +529,7 @@
+ copy_to_buf_last_used(struct mail_cache *cache, buffer_t *dest, bool add_new)
+ {
+ size_t offset = offsetof(struct mail_cache_field, last_used);
+-#if defined(WORDS_BIGENDIAN) && SIZEOF_VOID_P == 8
++#if defined(WORDS_BIGENDIAN) && TIME_T_MAX_BITS > 32
+ /* 64bit time_t with big endian CPUs: copy the last 32 bits instead of
+ the first 32 bits (that are always 0). The 32 bits are enough until
+ year 2106, so we're not in a hurry to use 64 bits on disk. */
diff --git a/user/dovecot/skip-iconv-check.patch b/user/dovecot/skip-iconv-check.patch
new file mode 100644
index 000000000..bb1002c84
--- /dev/null
+++ b/user/dovecot/skip-iconv-check.patch
@@ -0,0 +1,11 @@
+--- a/src/lib-charset/test-charset.c
++++ b/src/lib-charset/test-charset.c
+@@ -159,7 +159,7 @@
+ static void (*const test_functions[])(void) = {
+ test_charset_is_utf8,
+ test_charset_utf8,
+-#ifdef HAVE_ICONV
++#if 0 //def HAVE_ICONV
+ test_charset_iconv,
+ test_charset_iconv_crashes,
+ test_charset_iconv_utf7_state,
diff --git a/user/dovecot/split-protocols.patch b/user/dovecot/split-protocols.patch
new file mode 100644
index 000000000..b4bed2ccb
--- /dev/null
+++ b/user/dovecot/split-protocols.patch
@@ -0,0 +1,30 @@
+For each protocol $prot, which is moved into subpackage $subname,
+is installed file /usr/share/dovecot/protocols.d/$subname.conf with:
+
+ protocols = $protocols $prot
+
+--- a/doc/example-config/dovecot.conf
++++ b/doc/example-config/dovecot.conf
+@@ -20,8 +20,9 @@
+ # options. The paths listed here are for configure --prefix=/usr
+ # --sysconfdir=/etc --localstatedir=/var
+
+-# Protocols we want to be serving.
+-#protocols = imap pop3 lmtp submission
++# Enable installed protocols.
++#protocols = imap
++!include_try /usr/share/dovecot/protocols.d/*.conf
+
+ # A comma separated list of IPs or hosts where to listen in for connections.
+ # "*" listens in all IPv4 interfaces, "::" listens in all IPv6 interfaces.
+--- a/src/master/master-settings.c.orig
++++ b/src/master/master-settings.c
+@@ -206,7 +206,7 @@
+ .state_dir = PKG_STATEDIR,
+ .libexec_dir = PKG_LIBEXECDIR,
+ .instance_name = PACKAGE,
+- .protocols = "imap pop3 lmtp",
++ .protocols = "imap",
+ .listen = "*, ::",
+ .ssl = "yes:no:required",
+ .default_internal_user = "dovecot",
diff --git a/user/dovecot/ssl-paths.patch b/user/dovecot/ssl-paths.patch
new file mode 100644
index 000000000..b354b607e
--- /dev/null
+++ b/user/dovecot/ssl-paths.patch
@@ -0,0 +1,13 @@
+--- dovecot-2.3.10/doc/example-config/conf.d/10-ssl.conf 2020-03-05 14:35:53.000000000 +0000
++++ dovecot-2.3.10.new/doc/example-config/conf.d/10-ssl.conf 2020-04-26 06:49:45.860000000 +0000
+@@ -9,8 +9,8 @@
+ # dropping root privileges, so keep the key file unreadable by anyone but
+ # root. Included doc/mkcert.sh can be used to easily generate self-signed
+ # certificate, just make sure to update the domains in dovecot-openssl.cnf
+-ssl_cert = </etc/ssl/certs/dovecot.pem
+-ssl_key = </etc/ssl/private/dovecot.pem
++ssl_cert = </etc/ssl/dovecot/server.pem
++ssl_key = </etc/ssl/dovecot/server.key
+
+ # If key file is password protected, give the password here. Alternatively
+ # give it when starting dovecot with -p parameter. Since this file is often
diff --git a/user/dovecot/test-file-cache-enomem.patch b/user/dovecot/test-file-cache-enomem.patch
new file mode 100644
index 000000000..536b857de
--- /dev/null
+++ b/user/dovecot/test-file-cache-enomem.patch
@@ -0,0 +1,20 @@
+--- a/src/lib/test-file-cache.c 2021-01-05 14:10:50.160000000 +0000
++++ b/src/lib/test-file-cache.c 2021-01-05 14:10:50.160000000 +0000
+@@ -263,7 +263,7 @@
+ };
+ const char *errstr =
+ t_strdup_printf("mmap_anon(.test_file_cache, %zu) failed: "
+- "Cannot allocate memory", page_size);
++ "Out of memory", page_size);
+ test_assert(setrlimit(RLIMIT_AS, &rl_new) == 0);
+ test_expect_error_string(errstr);
+ test_assert(file_cache_set_size(cache, 1024) == -1);
+@@ -271,7 +271,7 @@
+
+ /* same for mremap */
+ errstr = t_strdup_printf("mremap_anon(.test_file_cache, %zu) failed: "
+- "Cannot allocate memory", page_size*2);
++ "Out of memory", page_size*2);
+ test_assert(file_cache_set_size(cache, 1) == 0);
+ test_assert(setrlimit(RLIMIT_AS, &rl_new) == 0);
+ test_expect_error_string(errstr);