From: Markus Valentin Date: Mon, 10 Mar 2025 14:29:27 +0000 (+0000) Subject: imap: Add imap4rev2 capability X-Git-Tag: 2.4.2~885 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8ce74f1afb7c283ed27f8b1a9be497b52119042d;p=thirdparty%2Fdovecot%2Fcore.git imap: Add imap4rev2 capability It can only be enabled if build with --enable-experimental-imap4rev2 --- diff --git a/configure.ac b/configure.ac index 0537fb6f20..8c711964de 100644 --- a/configure.ac +++ b/configure.ac @@ -54,6 +54,7 @@ AC_ARG_ENABLE([pro-build], experimental_capabilities="" have_mail_utf8=no +have_imap4rev2=no AC_ARG_ENABLE(experimental-mail-utf8, AS_HELP_STRING([--enable-experimental-mail-utf8], [Enable experimental support for SMTPUTF8 and UTF8=ACCEPT]), @@ -66,6 +67,17 @@ AS_HELP_STRING([--enable-experimental-mail-utf8], [Enable experimental support f AC_SUBST([DOVECOT_HAVE_MAIL_UTF8], $have_mail_utf8) +AC_ARG_ENABLE(experimental-imap4rev2, +AS_HELP_STRING([--enable-experimental-imap4rev2], [Enable experimental support for IMAP4REV2]), + AS_IF([test x$enableval = xyes], [ + AC_DEFINE([EXPERIMENTAL_IMAP4REV2],, [Build with IMAP4REV2 support]) + experimental_capabilities="${experimental_capabilities} IMAP4REV2" + have_imap4rev2=yes + ]) +) + +AC_SUBST([DOVECOT_HAVE_IMAP4REV2], $have_imap4rev2) + AC_ARG_WITH(shared-libs, AS_HELP_STRING([--with-shared-libs], [Link binaries using shared Dovecot libraries (default)]), want_shared_libs=$withval, diff --git a/src/imap-login/imap-login-client.c b/src/imap-login/imap-login-client.c index a31be22fc3..4e89ec0ae8 100644 --- a/src/imap-login/imap-login-client.c +++ b/src/imap-login/imap-login-client.c @@ -400,6 +400,10 @@ static int imap_client_create(struct client *client) settings_override(set_instance, "imap_capability/LITERAL-", "no", SETTINGS_OVERRIDE_TYPE_CODE); + if (!imap_client->set->imap4rev2_enable) + settings_override(set_instance, "imap_capability/IMAP4rev2", + "no", SETTINGS_OVERRIDE_TYPE_CODE); + if (imap_client_reload_config(client, &error) < 0) { e_error(client->event, "%s", error); return -1; diff --git a/src/imap-login/imap-login-settings.c b/src/imap-login/imap-login-settings.c index f4e0c49d7b..44ab187de0 100644 --- a/src/imap-login/imap-login-settings.c +++ b/src/imap-login/imap-login-settings.c @@ -56,6 +56,7 @@ static const struct setting_define imap_login_setting_defines[] = { DEF(BOOLLIST, imap_capability), DEF(BOOL, imap_literal_minus), DEF(BOOL, imap_id_retain), + DEF(BOOL, imap4rev2_enable), { .type = SET_STRLIST, .key = "imap_id_send", .offset = offsetof(struct imap_login_settings, imap_id_send) }, @@ -68,10 +69,12 @@ static const struct imap_login_settings imap_login_default_settings = { .imap_id_send = ARRAY_INIT, .imap_literal_minus = FALSE, .imap_id_retain = FALSE, + .imap4rev2_enable = FALSE, }; static const struct setting_keyvalue imap_login_default_settings_keyvalue[] = { {"service/imap-login/imap_capability/IMAP4rev1", "yes"}, + {"service/imap-login/imap_capability/IMAP4rev2", "yes"}, {"service/imap-login/imap_capability/LOGIN-REFERRALS", "yes"}, {"service/imap-login/imap_capability/ID", "yes"}, {"service/imap-login/imap_capability/ENABLE", "yes"}, diff --git a/src/imap-login/imap-login-settings.h b/src/imap-login/imap-login-settings.h index 3dd90ff237..70e95af493 100644 --- a/src/imap-login/imap-login-settings.h +++ b/src/imap-login/imap-login-settings.h @@ -7,6 +7,7 @@ struct imap_login_settings { ARRAY_TYPE(const_string) imap_id_send; bool imap_literal_minus; bool imap_id_retain; + bool imap4rev2_enable; }; extern const struct setting_parser_info imap_login_setting_parser_info; diff --git a/src/imap/imap-client.c b/src/imap/imap-client.c index e2bbbc43a2..9f3edbe6f1 100644 --- a/src/imap/imap-client.c +++ b/src/imap/imap-client.c @@ -46,6 +46,7 @@ unsigned int imap_client_count = 0; unsigned int imap_feature_condstore = UINT_MAX; unsigned int imap_feature_qresync = UINT_MAX; unsigned int imap_feature_utf8accept = UINT_MAX; +unsigned int imap_feature_imap4rev2 = UINT_MAX; static const char *client_command_state_names[] = { "wait-input", @@ -179,6 +180,8 @@ struct client *client_create(int fd_in, int fd_out, imap_unset_capability(set_instance, "METADATA"); if (!client->set->mail_utf8_extensions) imap_unset_capability(set_instance, "UTF8=ACCEPT"); + if (!client->set->imap4rev2_enable) + imap_unset_capability(set_instance, "IMAP4rev2"); const struct imap_settings *modified_set; if (settings_get(client->user->event, &imap_setting_parser_info, @@ -1638,6 +1641,20 @@ static bool imap_client_enable_utf8accept(struct client *client) } #endif +#ifdef EXPERIMENTAL_IMAP4REV2 +static bool imap_client_enable_imap4rev2(struct client *client) +{ + if (!client->set->imap4rev2_enable) { + e_debug(client->event, "Client attempted to enable IMAP4rev2 while it's disabled on the server."); + return FALSE; + } + + if (client->mailbox != NULL) + mailbox_enable(client->mailbox, MAILBOX_FEATURE_IMAP4REV2); + return TRUE; +} +#endif + enum mailbox_feature client_enabled_mailbox_features(struct client *client) { enum mailbox_feature mailbox_features = 0; @@ -1719,6 +1736,12 @@ void clients_init(void) imap_feature_register("UTF8=ACCEPT", MAILBOX_FEATURE_UTF8ACCEPT, imap_client_enable_utf8accept); #endif +#ifdef EXPERIMENTAL_IMAP4REV2 + imap_feature_imap4rev2 = + imap_feature_register("IMAP4rev2", MAILBOX_FEATURE_UTF8ACCEPT, + imap_client_enable_imap4rev2); + +#endif } void client_kick(struct client *client, bool shutdown) diff --git a/src/imap/imap-settings.c b/src/imap/imap-settings.c index aa0cd747cb..71186bccc9 100644 --- a/src/imap/imap-settings.c +++ b/src/imap/imap-settings.c @@ -82,6 +82,7 @@ static const struct setting_define imap_setting_defines[] = { DEF(BOOL, imap_metadata), DEF(BOOL, imap_literal_minus), DEF(BOOL, mail_utf8_extensions), + DEF(BOOL, imap4rev2_enable), #ifdef BUILD_IMAP_HIBERNATE DEF(TIME, imap_hibernate_timeout), #endif @@ -116,6 +117,7 @@ static const struct imap_settings imap_default_settings = { .imap_metadata = FALSE, .imap_literal_minus = FALSE, .mail_utf8_extensions = FALSE, + .imap4rev2_enable = FALSE, #ifdef DOVECOT_PRO_EDITION .imap_hibernate_timeout = 30, #else @@ -128,6 +130,7 @@ static const struct imap_settings imap_default_settings = { static const struct setting_keyvalue imap_default_settings_keyvalue[] = { { "service/imap/imap_capability/IMAP4rev1", "yes" }, + { "service/imap/imap_capability/IMAP4rev2", "yes" }, { "service/imap/imap_capability/SASL-IR", "yes" }, { "service/imap/imap_capability/LOGIN-REFERRALS", "yes" }, { "service/imap/imap_capability/ID", "yes" }, @@ -243,6 +246,12 @@ imap_settings_verify(void *_set, pool_t pool ATTR_UNUSED, const char **error_r) return FALSE; } #endif +#ifndef EXPERIMENTAL_IMAP4REV2 + if (set->imap4rev2_enable) { + *error_r = "Dovecot not built with --enable-experimental-imap4rev2."; + return FALSE; + } +#endif if (imap_settings_parse_workarounds(set, error_r) < 0) return FALSE; diff --git a/src/imap/imap-settings.h b/src/imap/imap-settings.h index 202ea45a30..1884c6debe 100644 --- a/src/imap/imap-settings.h +++ b/src/imap/imap-settings.h @@ -34,6 +34,7 @@ struct imap_settings { const char *imap_fetch_failure; bool imap_metadata; bool imap_literal_minus; + bool imap4rev2_enable; bool mail_utf8_extensions; unsigned int imap_hibernate_timeout; ARRAY_TYPE(const_string) imap_id_send; diff --git a/src/lib-storage/mail-storage.h b/src/lib-storage/mail-storage.h index 6768c972fa..1501c39199 100644 --- a/src/lib-storage/mail-storage.h +++ b/src/lib-storage/mail-storage.h @@ -95,6 +95,7 @@ enum mailbox_feature { /* Enable tracking modsequences */ MAILBOX_FEATURE_CONDSTORE = 0x01, MAILBOX_FEATURE_UTF8ACCEPT = 0x02, + MAILBOX_FEATURE_IMAP4REV2 = 0x04, }; enum mailbox_existence { diff --git a/src/master/main.c b/src/master/main.c index 7e1795e9ab..554cc50f16 100644 --- a/src/master/main.c +++ b/src/master/main.c @@ -723,6 +723,9 @@ static void print_build_options(void) #endif #ifdef DOVECOT_PRO_EDITION " pro" +#endif +#ifdef EXPERIMENTAL_IMAP4REV2 + " experimental-imap4rev2" #endif " openssl" " io_block_size=%u"