From ada821005f493f6d5d6c85b695c5cffc1718b3a7 Mon Sep 17 00:00:00 2001 From: Aki Tuomi Date: Tue, 20 Oct 2026 12:46:51 +0200 Subject: [PATCH 01/13] spellcheck: Ignore base64 from 10 characters forward --- .github/actions/spelling/allow.txt | 3 +++ .github/actions/spelling/patterns.txt | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/actions/spelling/allow.txt b/.github/actions/spelling/allow.txt index 938b23b20..70b72ad48 100644 --- a/.github/actions/spelling/allow.txt +++ b/.github/actions/spelling/allow.txt @@ -19,6 +19,8 @@ istreams jvm JVM JVMs +KMail +learntype lfill libcap libpcre @@ -48,4 +50,5 @@ ssh ubsan ubuntu Uppercases +Websieve workarounds diff --git a/.github/actions/spelling/patterns.txt b/.github/actions/spelling/patterns.txt index 69e1fac26..622308ca4 100644 --- a/.github/actions/spelling/patterns.txt +++ b/.github/actions/spelling/patterns.txt @@ -17,6 +17,10 @@ # base64 encoded content, possibly wrapped in mime (?:^|[\s=;:?])[-a-zA-Z=;:/0-9+]{50,}(?:[\s=;:?]|$) +# hit-count: 0 file-count: 0 +# base64 lines, strict matching +[A-Za-z0-9+\/]{10,}={0,2} + # hit-count: 10 file-count: 8 # GitHub SHAs (markdown) (?:\[`?[0-9a-f]+`?\]\(https:/|)/(?:www\.|)github\.com(?:/[^/\s"]+){2,}(?:/[^/\s")]+)(?:[0-9a-f]+(?:[-0-9a-zA-Z/#.]*|)\b|) @@ -29,10 +33,6 @@ # hex runs \b[0-9a-fA-F]{16,}\b -# hit-count: 8 file-count: 5 -# base64 encoded content -([`'"])[-a-zA-Z=;:/0-9+]+=\g{-1} - # hit-count: 6 file-count: 3 # tar arguments \b(?:\\n|)g?tar(?:\.exe|)(?:(?:\s+--[-a-zA-Z]+|\s+-[a-zA-Z]+|\s[ABGJMOPRSUWZacdfh-pr-xz]+\b)(?:=[^ ]*|))+ From 16c1f687ddd6f30582a39268865b7c5d473fd01f Mon Sep 17 00:00:00 2001 From: Stephan Bosch Date: Wed, 19 Aug 2026 14:59:40 +0200 Subject: [PATCH 02/13] settings.js: Document the new client_auth* settings --- .github/actions/spelling/allow.txt | 3 + data/settings.js | 261 +++++++++++++++++++++++++++++ data/updates.js | 3 + 3 files changed, 267 insertions(+) diff --git a/.github/actions/spelling/allow.txt b/.github/actions/spelling/allow.txt index 70b72ad48..e33898afe 100644 --- a/.github/actions/spelling/allow.txt +++ b/.github/actions/spelling/allow.txt @@ -1,4 +1,6 @@ aarch +authid +authzid APPENDLIMIT bitmask bitmasks @@ -8,6 +10,7 @@ DESTPORT DOkv ede fcf +frop fuzzer github hardenings diff --git a/data/settings.js b/data/settings.js index e15d416ca..c3cc366b3 100644 --- a/data/settings.js +++ b/data/settings.js @@ -67,6 +67,211 @@ destination IP address belongs to, for instance, a load-balancer rather than the server itself.` }, + client_auth: { + tags: [ 'client-auth' ], + values: setting_types.NAMED_LIST_FILTER, + seealso: [ 'client_auth_mechanism', 'client_auth_authzid', + 'client_auth_authid', 'client_auth_password'], + text: ` +This settings filter provides a scope for client authentication settings for +a particular authentication mechanism and declares the availability of that +mechanism for client authentication. The mechanism will be used if support is +also indicated by the server. This way, several different mechanisms can be +configured, each with specific settings. + +The filter name refers to the [[setting,client_auth_mechanism]] setting. +Mechanisms are attempted in the order of configuration, so preferred mechanisms +should be configured first. + +Client authentication settings are expected to be scoped further by settings +filters for the various protocol clients that need authentication, such as +[[setting,imapc]] and [[setting,pop3c]]. + +Example: +\`\`\`[dovecot.conf] +mail_driver = imapc +mail_path = +mailbox_list_index = no +imapc { + host = 127.0.0.1 + port = 993 + ssl = imaps + + client_auth PLAIN { + authid = master-user + authzid = owner-user + password = frop + } + client_auth OAUTHBEARER { + authzid = owner-user + password = vF9dft4qmTc2Nvb3RlckBhbHRhdmlzdGEuY29tCg== + } +} + +submission_relay { + smtp_client_host = submission.example.com + smtp_client_port = 587 + smtp_client_ssl = no + + client_auth_authzid = user + client_auth_password = frop + + client_auth SCRAM-SHA-256 { + } + client_auth SCRAM-SHA-1 { + } + client_auth CRAM-MD5 { + } + client_auth PLAIN { + } +} + +mail_submit { + smtp_client_host = localhost + smtp_client_port = 25 + + client_auth PLAIN { + authzid = mail-out + password = frop + } +} +\`\`\`` + }, + + client_auth_authid: { + tags: [ 'client-auth' ], + seealso: [ 'client_auth_authzid', 'client_auth_password', + 'client_auth_mechanism' ], + values: setting_types.STRING, + text: ` +The authentication identity to be used for authenticating as a client to a +remote service. + +To authenticate as a master user to e.g. an IMAP server but use a separate login +user, the following configuration should be employed, where the credentials are +represented by masteruser and masteruser-secret: + +\`\`\` +imapc { + client_auth_authid = masteruser + client_auth_authzid = %{user} + client_auth_password = masteruser-secret +} +\`\`\` + +[[variable,mail-user]] can be used.` + }, + + client_auth_authzid: { + tags: [ 'client-auth' ], + seealso: [ 'client_auth_authid', 'client_auth_password', + 'client_auth_mechanism' ], + values: setting_types.STRING, + text: ` +The authorization identity to be used after authenticating as a client to a +remote service. + +[[variable,mail-user]] can be used.` + }, + + client_auth_password: { + tags: [ 'client-auth' ], + seealso: [ 'client_auth_authzid', 'client_auth_authid', + 'client_auth_mechanism' ], + values: setting_types.STRING, + text: ` +The password to be used for authenticating as a client to a remote service. This +is the password belonging to the authentication identity \`client_auth_authid\`.` + }, + + client_auth_mechanism: { + tags: [ 'client-auth' ], + seealso: [ 'client_auth_authzid', 'client_auth_authid', + 'client_auth_password' ], + values: setting_types.STRING, + text: ` +The authentication mechanism (sometimes called scheme) to be used for +authenticating as a client to a remote service. Currently, this is always a SASL +mechanism. + +Supported mechanisms are: + + * ANONYMOUS + * CRAM-MD5 + * DIGEST-MD5 + * EXTERNAL + * LOGIN + * OAUTHBEARER + * PLAIN + * SCRAM-SHA-1 + * SCRAM-SHA-1-PLUS + * SCRAM-SHA-256 + * SCRAM-SHA-256-PLUS + * XOAUTH2 + +Note that [[setting,client_auth_password]] is ignored for \`ANONYMOUS\` and +\`EXTERNAL\` mechanisms. For \`OAUTHBEARER\` and \`XOAUTH2\` +[[setting,client_auth_password]] should be a bearer token. + +Example: +\`\`\`[dovecot.conf] +imapc { + host = 127.0.0.1 + port = 993 + ssl = imaps + + # Authentication will fail if server does not announce SCRAM-SHA-256 support + client_auth SCRAM-SHA-256 { + authzid = owner-user + password = frop + } +} +\`\`\` + +If left unconfigured, SASL authentication will use the PLAIN mechanism by +default. For IMAP and POP3 clients, it will use the basic login +commands in that case if possible (LOGIN for IMAP and USER + PASS for POP3, so +SASL support is not required). However, if the authentication +\`client_auth_authid\` and authorization \`client_auth_authzid\` identities are +both also unconfigured, no authentication is configured at all. In that case, +authentication will be skipped if it is optional or this will be reported as an +error otherwise. + +Example: +\`\`\`[dovecot.conf] +imapc { + host = 127.0.0.1 + port = 993 + ssl = imaps + + # Will authenticate using IMAP LOGIN command, or use PLAIN mechanism if LOGIN + # command is disabled. + client_auth_authzid = owner-user + client_auth_password = frop +} +\`\`\` + +If no [[setting,client_auth]] filter block is present in a particular context +(e.g. a surrounding [[setting,imapc]] and [[setting,pop3c]] filter block), while +\`client_auth_mechanism\` is set within that context, the indicated mechanism is +used blindly; server support is not checked. + +Example: +\`\`\`[dovecot.conf] +imapc { + host = 127.0.0.1 + port = 993 + ssl = imaps + + # PLAIN mechanism will be used without consulting server capabilities + client_auth_mechanism = PLAIN + client_auth_authid = master-user + client_auth_authzid = owner-user + client_auth_password = frop +} +\`\`\`` + }, + fs: { tags: [ 'fs' ], values: setting_types.NAMED_LIST_FILTER, @@ -7201,6 +7406,16 @@ Variables allowed: The port is used with the URLAUTH extension in IMAP operation.` }, + imapc: { + tags: [ 'imapc', 'client-auth' ], + values: setting_types.NAMED_LIST_FILTER, + seealso: [ 'client_auth_mechanism', 'client_auth_authzid', + 'client_auth_authid', 'client_auth_password' ], + text: ` +This settings filter provides a scope for settings for imapc. This is for example +used to configure [[setting,client_auth] for imapc specifically.` + }, + imapc_cmd_timeout: { default: '5 mins', tags: [ 'imapc' ], @@ -7418,6 +7633,11 @@ imapc_list_prefix = INBOX }, imapc_master_user: { + removed: { + settings_imapc_credentials_removed: ` +Dropped in favor of using the global +[[setting,client_auth_authid]].` + }, tags: [ 'imapc' ], seealso: [ 'imapc_password', 'imapc_user' ], values: setting_types.STRING, @@ -7459,6 +7679,11 @@ This setting is used to limit maximum memory usage.` }, imapc_password: { + removed: { + settings_imapc_credentials_removed: ` +Dropped in favor of using the global +[[setting,client_auth_password]].` + }, tags: [ 'imapc' ], seealso: [ 'imapc_master_user', 'imapc_user', 'imapc_sasl_mechanisms' ], values: setting_types.STRING, @@ -7486,6 +7711,12 @@ If using master users, this setting will be the password of the master user.` }, imapc_sasl_mechanisms: { + deprecated: { + settings_imapc_sasl_mechanisms_deprecated: ` +The setting is obsolete, and kept only for backwards compatibility. + +Use [[setting,client_auth]] instead.` + }, default: 'plain', tags: [ 'imapc' ], values: setting_types.BOOLLIST, @@ -7555,6 +7786,11 @@ Only used if [[setting,imapc_ssl]] is enabled.` }, imapc_user: { + removed: { + settings_imapc_credentials_removed: ` +Dropped in favor of using the global +[[setting,client_auth_authzid]].` + }, tags: [ 'imapc', 'imapc-auth' ], seealso: [ 'imapc_master_user', 'imapc_password', 'imapc_sasl_mechanisms' ], values: setting_types.STRING, @@ -10890,6 +11126,16 @@ in uppercase) and with [[variable,global]]: | \`%{guid}\` | Dovecot GUID for the message |` }, + pop3c: { + tags: [ 'pop3c', 'client-auth' ], + values: setting_types.NAMED_LIST_FILTER, + seealso: [ 'client_auth_mechanism', 'client_auth_authzid', + 'client_auth_authid', 'client_auth_password' ], + text: ` +This settings filter provides a scope for settings for pop3c. This is for example +used to configure [[setting,client_auth] for pop3c specifically.` + }, + pop3c_features: { tags: [ 'pop3c' ], values: setting_types.BOOLLIST, @@ -10909,6 +11155,11 @@ Workarounds: }, pop3c_master_user: { + removed: { + settings_pop3c_credentials_removed: ` +Dropped in favor of using the global +[[setting,client_auth_authid]].` + }, tags: [ 'pop3c' ], seealso: [ 'pop3c_password', 'pop3c_user' ], values: setting_types.STRING, @@ -10929,6 +11180,11 @@ pop3c_password = masteruser-secret }, pop3c_password: { + removed: { + settings_pop3c_credentials_removed: ` +Dropped in favor of using the global +[[setting,client_auth_password]].` + }, tags: [ 'pop3c' ], seealso: [ 'pop3c_master_user', 'pop3c_user' ], values: setting_types.STRING, @@ -10994,6 +11250,11 @@ Only used if [[setting,pop3c_ssl]] is enabled.` }, pop3c_user: { + removed: { + settings_pop3c_credentials_removed: ` +Dropped in favor of using the global +[[setting,client_auth_authzid]].` + }, default: '%{user}', tags: [ 'pop3c' ], seealso: [ 'pop3c_master_user', 'pop3c_password' ], diff --git a/data/updates.js b/data/updates.js index c67a9fbdb..1461c4fb4 100644 --- a/data/updates.js +++ b/data/updates.js @@ -202,6 +202,8 @@ export const updates = { settings_imap_compress_on_proxy_added: '2.4.2', settings_imap_compress_on_proxy_changed: '2.4.5', settings_imap_filter_sieve_max_redirects_added: '2.4.6', + settings_imapc_credentials_removed: '2.4.6', + settings_imapc_sasl_mechanisms_deprecated: '2.4.6', settings_imapc_features_changed: '2.4.0', settings_imapc_ssl_verify_removed: '2.4.0', settings_inet_listener_type_added: '2.4.0', @@ -226,6 +228,7 @@ export const updates = { settings_passdb_mechanisms_filter_added: '2.4.0', settings_passdb_sql_update_query_removed: '2.4.5', settings_passdb_static_password_added: '2.4.0', + settings_pop3c_credentials_removed: '2.4.6', settings_service_reuse_port_added: '2.4.4', settings_service_type_client_added: '2.4.6', settings_sieve_max_cpu_time_changed: '2.4.5', From f3708003e8d610996ab812c5b82ac181055147f6 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Tue, 20 Oct 2026 11:58:37 +0000 Subject: [PATCH 03/13] spellcheck: Only ignore base64 strings that have padding The pattern matched every word of 10 or more characters, which effectively disabled spell checking for long words: the check-spelling report listed dozens of allow.txt entries as no longer needed. --- .github/actions/spelling/patterns.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/actions/spelling/patterns.txt b/.github/actions/spelling/patterns.txt index 622308ca4..cf5a88c1b 100644 --- a/.github/actions/spelling/patterns.txt +++ b/.github/actions/spelling/patterns.txt @@ -18,8 +18,8 @@ (?:^|[\s=;:?])[-a-zA-Z=;:/0-9+]{50,}(?:[\s=;:?]|$) # hit-count: 0 file-count: 0 -# base64 lines, strict matching -[A-Za-z0-9+\/]{10,}={0,2} +# base64 strings with padding +\b[A-Za-z0-9+/]{16,}={1,2} # hit-count: 10 file-count: 8 # GitHub SHAs (markdown) From bd904193b20b84694599ef2d4976686c2a4f6530 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Tue, 20 Oct 2026 11:58:37 +0000 Subject: [PATCH 04/13] settings.js: Fix the client_auth filter documentation - imapc and pop3c are plain named filters, not named list filters, and the [[setting,client_auth]] links were missing a bracket. - Describe how the mechanism is selected: the first configured mechanism that the server advertises is used and there is no fallback after an authentication failure. Without any configured mechanism PLAIN or the basic login commands are used, and if the server doesn't advertise PLAIN, the first server-advertised password mechanism. Authentication is never optionally skipped: imapc and pop3c fail with "Authentication not configured". - Document that an empty client_auth_authid falls back to client_auth_authzid, the %{owner_user} default inside imapc and pop3c, and the changed pop3c default. - Mention the implicit SCRAM channel binding upgrade. - Drop the submission_relay and mail_submit examples from the client_auth entry. They exist only with the SMTP client settings changes and are documented with their own filters. - Add the added tags. --- data/settings.js | 186 +++++++++++++++++++++++++++++------------------ data/updates.js | 2 + 2 files changed, 119 insertions(+), 69 deletions(-) diff --git a/data/settings.js b/data/settings.js index c3cc366b3..01c1c05be 100644 --- a/data/settings.js +++ b/data/settings.js @@ -68,10 +68,14 @@ than the server itself.` }, client_auth: { + added: { + settings_client_auth_added: false + }, tags: [ 'client-auth' ], values: setting_types.NAMED_LIST_FILTER, - seealso: [ 'client_auth_mechanism', 'client_auth_authzid', - 'client_auth_authid', 'client_auth_password'], + seealso: [ '[[link,client_auth]]', 'client_auth_mechanism', + 'client_auth_authzid', 'client_auth_authid', + 'client_auth_password' ], text: ` This settings filter provides a scope for client authentication settings for a particular authentication mechanism and declares the availability of that @@ -80,18 +84,19 @@ also indicated by the server. This way, several different mechanisms can be configured, each with specific settings. The filter name refers to the [[setting,client_auth_mechanism]] setting. -Mechanisms are attempted in the order of configuration, so preferred mechanisms -should be configured first. +The first configured mechanism that the server also advertises is used, so the +preferred mechanisms should be configured first. There is no fallback to the +next mechanism if the authentication itself fails. Client authentication settings are expected to be scoped further by settings filters for the various protocol clients that need authentication, such as -[[setting,imapc]] and [[setting,pop3c]]. +[[setting,imapc]] and [[setting,pop3c]]. See [[link,client_auth]] for an +overview. Example: \`\`\`[dovecot.conf] mail_driver = imapc mail_path = -mailbox_list_index = no imapc { host = 127.0.0.1 port = 993 @@ -107,51 +112,28 @@ imapc { password = vF9dft4qmTc2Nvb3RlckBhbHRhdmlzdGEuY29tCg== } } - -submission_relay { - smtp_client_host = submission.example.com - smtp_client_port = 587 - smtp_client_ssl = no - - client_auth_authzid = user - client_auth_password = frop - - client_auth SCRAM-SHA-256 { - } - client_auth SCRAM-SHA-1 { - } - client_auth CRAM-MD5 { - } - client_auth PLAIN { - } -} - -mail_submit { - smtp_client_host = localhost - smtp_client_port = 25 - - client_auth PLAIN { - authzid = mail-out - password = frop - } -} \`\`\`` }, client_auth_authid: { + added: { + settings_client_auth_added: false + }, tags: [ 'client-auth' ], seealso: [ 'client_auth_authzid', 'client_auth_password', - 'client_auth_mechanism' ], + 'client_auth_mechanism', '[[link,client_auth]]' ], values: setting_types.STRING, text: ` The authentication identity to be used for authenticating as a client to a -remote service. +remote service. This is the identity whose [[setting,client_auth_password]] +is used. If it is empty, [[setting,client_auth_authzid]] is used as the +authentication identity as well. To authenticate as a master user to e.g. an IMAP server but use a separate login user, the following configuration should be employed, where the credentials are represented by masteruser and masteruser-secret: -\`\`\` +\`\`\`[dovecot.conf] imapc { client_auth_authid = masteruser client_auth_authzid = %{user} @@ -163,31 +145,59 @@ imapc { }, client_auth_authzid: { + added: { + settings_client_auth_added: false + }, + changed: { + settings_pop3c_authzid_default_changed: ` +For pop3c the default used to be \`%{user}\` (the old [[setting,pop3c_user]] +default). It is now \`%{owner_user}\`, the same as for imapc. This makes a +difference only for shared namespaces.` + }, tags: [ 'client-auth' ], seealso: [ 'client_auth_authid', 'client_auth_password', - 'client_auth_mechanism' ], + 'client_auth_mechanism', '[[link,client_auth]]' ], values: setting_types.STRING, + default: { + value: '', + text: '`imapc { "%{owner_user}" }`
`pop3c { "%{owner_user}" }`' + }, text: ` The authorization identity to be used after authenticating as a client to a -remote service. +remote service, i.e. the user whose mails are accessed. If +[[setting,client_auth_authid]] is empty, this identity is also used for +authenticating. [[variable,mail-user]] can be used.` }, client_auth_password: { + added: { + settings_client_auth_added: false + }, tags: [ 'client-auth' ], seealso: [ 'client_auth_authzid', 'client_auth_authid', - 'client_auth_mechanism' ], + 'client_auth_mechanism', '[[link,client_auth]]' ], values: setting_types.STRING, text: ` The password to be used for authenticating as a client to a remote service. This -is the password belonging to the authentication identity \`client_auth_authid\`.` +is the password belonging to the authentication identity +[[setting,client_auth_authid]]. For the \`OAUTHBEARER\` and \`XOAUTH2\` +mechanisms this is the bearer token. The \`ANONYMOUS\` and \`EXTERNAL\` +mechanisms don't use it. + +The password is required for all the other mechanisms. Its existence is +checked already when the client is created (e.g. when the namespace is initialized for imapc), +not only when connecting.` }, client_auth_mechanism: { + added: { + settings_client_auth_added: false + }, tags: [ 'client-auth' ], - seealso: [ 'client_auth_authzid', 'client_auth_authid', - 'client_auth_password' ], + seealso: [ 'client_auth', 'client_auth_authzid', 'client_auth_authid', + 'client_auth_password', '[[link,client_auth]]' ], values: setting_types.STRING, text: ` The authentication mechanism (sometimes called scheme) to be used for @@ -213,14 +223,17 @@ Note that [[setting,client_auth_password]] is ignored for \`ANONYMOUS\` and \`EXTERNAL\` mechanisms. For \`OAUTHBEARER\` and \`XOAUTH2\` [[setting,client_auth_password]] should be a bearer token. -Example: +Normally this setting is not set directly, but through the name of a +[[setting,client_auth]] filter. The mechanism is then used only if the server +also advertises it: + \`\`\`[dovecot.conf] imapc { host = 127.0.0.1 port = 993 ssl = imaps - # Authentication will fail if server does not announce SCRAM-SHA-256 support + # Authentication fails if the server doesn't announce SCRAM-SHA-256 support client_auth SCRAM-SHA-256 { authzid = owner-user password = frop @@ -228,14 +241,20 @@ imapc { } \`\`\` -If left unconfigured, SASL authentication will use the PLAIN mechanism by -default. For IMAP and POP3 clients, it will use the basic login -commands in that case if possible (LOGIN for IMAP and USER + PASS for POP3, so -SASL support is not required). However, if the authentication -\`client_auth_authid\` and authorization \`client_auth_authzid\` identities are -both also unconfigured, no authentication is configured at all. In that case, -authentication will be skipped if it is optional or this will be reported as an -error otherwise. +When a non-PLUS SCRAM mechanism is configured and the server advertises the +corresponding \`-PLUS\` variant, the client automatically uses channel binding +if the connection is TLS encrypted and channel binding is available. See +[[link,client_auth_channel_binding]]. + +If no mechanism is configured, the PLAIN mechanism is used by default. For IMAP +and POP3 the basic login commands are used instead in that case, if possible +(LOGIN for IMAP and USER + PASS for POP3), so SASL support is not required from +the server. If the server doesn't advertise PLAIN, the first mechanism +advertised by the server that Dovecot supports and that uses a password is +used. However, if the authentication [[setting,client_auth_authid]] and +authorization [[setting,client_auth_authzid]] identities are both also +unconfigured, no authentication is configured at all and the connection fails +with an "Authentication not configured" error. Example: \`\`\`[dovecot.conf] @@ -251,10 +270,10 @@ imapc { } \`\`\` -If no [[setting,client_auth]] filter block is present in a particular context -(e.g. a surrounding [[setting,imapc]] and [[setting,pop3c]] filter block), while -\`client_auth_mechanism\` is set within that context, the indicated mechanism is -used blindly; server support is not checked. +If \`client_auth_mechanism\` is set directly, without any [[setting,client_auth]] +filter block in that context (e.g. inside a surrounding [[setting,imapc]] or +[[setting,pop3c]] filter block), the indicated mechanism is used blindly; +server support is not checked. Example: \`\`\`[dovecot.conf] @@ -7407,13 +7426,27 @@ The port is used with the URLAUTH extension in IMAP operation.` }, imapc: { - tags: [ 'imapc', 'client-auth' ], - values: setting_types.NAMED_LIST_FILTER, - seealso: [ 'client_auth_mechanism', 'client_auth_authzid', - 'client_auth_authid', 'client_auth_password' ], + tags: [ 'imapc', 'client-auth' ], + values: setting_types.NAMED_FILTER, + seealso: [ '[[link,imapc]]', 'client_auth', 'client_auth_authzid', + 'client_auth_authid', 'client_auth_password', + 'client_auth_mechanism', '[[link,client_auth]]' ], text: ` -This settings filter provides a scope for settings for imapc. This is for example -used to configure [[setting,client_auth] for imapc specifically.` +This settings filter provides a scope for settings for imapc. + +The filter is needed for configuring the generic [[setting,client_auth]] and +\`ssl_client_*\` settings for imapc specifically, since the same settings are +used also by other clients. + +Example: +\`\`\`[dovecot.conf] +imapc { + host = imap.example.com + ssl = imaps + client_auth_authzid = %{user} + client_auth_password = secret +} +\`\`\`` }, imapc_cmd_timeout: { @@ -11127,13 +11160,28 @@ in uppercase) and with [[variable,global]]: }, pop3c: { - tags: [ 'pop3c', 'client-auth' ], - values: setting_types.NAMED_LIST_FILTER, - seealso: [ 'client_auth_mechanism', 'client_auth_authzid', - 'client_auth_authid', 'client_auth_password' ], + tags: [ 'pop3c', 'client-auth' ], + values: setting_types.NAMED_FILTER, + seealso: [ '[[link,pop3c]]', 'client_auth', 'client_auth_authzid', + 'client_auth_authid', 'client_auth_password', + 'client_auth_mechanism', '[[link,client_auth]]' ], text: ` -This settings filter provides a scope for settings for pop3c. This is for example -used to configure [[setting,client_auth] for pop3c specifically.` +This settings filter provides a scope for settings for pop3c. + +The filter is needed for configuring the generic [[setting,client_auth]] and +\`ssl_client_*\` settings for pop3c specifically, since the same settings are +used also by other clients. + +Example: +\`\`\`[dovecot.conf] +pop3c { + host = pop3.example.com + ssl = pop3s + port = 995 + client_auth_authzid = %{user} + client_auth_password = secret +} +\`\`\`` }, pop3c_features: { diff --git a/data/updates.js b/data/updates.js index 1461c4fb4..29787c053 100644 --- a/data/updates.js +++ b/data/updates.js @@ -101,6 +101,7 @@ export const updates = { service_shutdown_clients_changed: '2.4.6', imap_unhibernate_config_check_added: '2.4.6', settings_boolean_values_changed: '2.4.6', + settings_client_auth_added: '2.4.6', settings_delayed_expansion_changed: '2.4.2', settings_fts_autoindex_direct_changed: '2.4.6', settings_list_key_variables_changed: '2.4.5', @@ -228,6 +229,7 @@ export const updates = { settings_passdb_mechanisms_filter_added: '2.4.0', settings_passdb_sql_update_query_removed: '2.4.5', settings_passdb_static_password_added: '2.4.0', + settings_pop3c_authzid_default_changed: '2.4.6', settings_pop3c_credentials_removed: '2.4.6', settings_service_reuse_port_added: '2.4.4', settings_service_type_client_added: '2.4.6', From 33400fdfe5eebcd2b9bfd2f695d7c33f086fe507 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Tue, 20 Oct 2026 11:59:19 +0000 Subject: [PATCH 05/13] settings.js: Document the imapc and pop3c credential settings as renamed They weren't removed. settings-history renames them to the client_auth_* settings inside the imapc { } and pop3c { } filters: the old names still work with an older dovecot_config_version and in -o and userdb overrides, and doveconf writes the new names. The new names aren't global either, they are filter-scoped. Also document the pop3c_ssl_verify -> pop3c/ssl_client_require_valid_cert rename, which was missing, and that imapc_sasl_mechanisms still works by being translated into client_auth filters. --- data/settings.js | 52 +++++++++++++++++++++++++++++------------------- data/updates.js | 5 +++-- 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/data/settings.js b/data/settings.js index 01c1c05be..7123e2de5 100644 --- a/data/settings.js +++ b/data/settings.js @@ -7667,9 +7667,9 @@ imapc_list_prefix = INBOX imapc_master_user: { removed: { - settings_imapc_credentials_removed: ` -Dropped in favor of using the global -[[setting,client_auth_authid]].` + settings_imapc_credentials_renamed: ` +Renamed to [[setting,client_auth_authid]] inside the [[setting,imapc]] +filter, i.e. \`imapc/client_auth_authid\`.` }, tags: [ 'imapc' ], seealso: [ 'imapc_password', 'imapc_user' ], @@ -7713,9 +7713,9 @@ This setting is used to limit maximum memory usage.` imapc_password: { removed: { - settings_imapc_credentials_removed: ` -Dropped in favor of using the global -[[setting,client_auth_password]].` + settings_imapc_credentials_renamed: ` +Renamed to [[setting,client_auth_password]] inside the [[setting,imapc]] +filter, i.e. \`imapc/client_auth_password\`.` }, tags: [ 'imapc' ], seealso: [ 'imapc_master_user', 'imapc_user', 'imapc_sasl_mechanisms' ], @@ -7746,9 +7746,10 @@ If using master users, this setting will be the password of the master user.` imapc_sasl_mechanisms: { deprecated: { settings_imapc_sasl_mechanisms_deprecated: ` -The setting is obsolete, and kept only for backwards compatibility. - -Use [[setting,client_auth]] instead.` +The setting is obsolete, and kept only for backwards compatibility. Each +listed mechanism is translated into a [[setting,client_auth]] filter in the +listed order, so existing configurations keep working. New configurations +should use [[setting,client_auth]] directly.` }, default: 'plain', tags: [ 'imapc' ], @@ -7820,9 +7821,9 @@ Only used if [[setting,imapc_ssl]] is enabled.` imapc_user: { removed: { - settings_imapc_credentials_removed: ` -Dropped in favor of using the global -[[setting,client_auth_authzid]].` + settings_imapc_credentials_renamed: ` +Renamed to [[setting,client_auth_authzid]] inside the [[setting,imapc]] +filter, i.e. \`imapc/client_auth_authzid\`.` }, tags: [ 'imapc', 'imapc-auth' ], seealso: [ 'imapc_master_user', 'imapc_password', 'imapc_sasl_mechanisms' ], @@ -11204,9 +11205,9 @@ Workarounds: pop3c_master_user: { removed: { - settings_pop3c_credentials_removed: ` -Dropped in favor of using the global -[[setting,client_auth_authid]].` + settings_pop3c_credentials_renamed: ` +Renamed to [[setting,client_auth_authid]] inside the [[setting,pop3c]] +filter, i.e. \`pop3c/client_auth_authid\`.` }, tags: [ 'pop3c' ], seealso: [ 'pop3c_password', 'pop3c_user' ], @@ -11229,9 +11230,9 @@ pop3c_password = masteruser-secret pop3c_password: { removed: { - settings_pop3c_credentials_removed: ` -Dropped in favor of using the global -[[setting,client_auth_password]].` + settings_pop3c_credentials_renamed: ` +Renamed to [[setting,client_auth_password]] inside the [[setting,pop3c]] +filter, i.e. \`pop3c/client_auth_password\`.` }, tags: [ 'pop3c' ], seealso: [ 'pop3c_master_user', 'pop3c_user' ], @@ -11284,6 +11285,11 @@ Use TLS to connect to the remote POP3 server. }, pop3c_ssl_verify: { + removed: { + settings_pop3c_ssl_verify_renamed: ` +Renamed to [[setting,ssl_client_require_valid_cert]] inside the +[[setting,pop3c]] filter, i.e. \`pop3c/ssl_client_require_valid_cert\`.` + }, default: 'yes', tags: [ 'pop3c' ], seealso: [ 'pop3c_ssl' ], @@ -11299,8 +11305,9 @@ Only used if [[setting,pop3c_ssl]] is enabled.` pop3c_user: { removed: { - settings_pop3c_credentials_removed: ` -Dropped in favor of using the global + settings_pop3c_credentials_renamed: ` +Renamed to [[setting,client_auth_authzid]] inside the [[setting,pop3c]] +filter, i.e. \`pop3c/client_auth_authzid\`. Note that the default changed too, see [[setting,client_auth_authzid]].` }, default: '%{user}', @@ -12095,7 +12102,10 @@ ssl_server_dh_file = /path/to/dh.pem tags: [ 'ssl-ldap', 'ssl-cassandra', 'ssl_client', 'sql-mysql' ], values: setting_types.BOOLEAN, text: ` -Require a valid certificate when connecting to external SSL services?` +Require a valid certificate when connecting to external SSL services? + +To change this for a single client only, set it inside that client's filter, +e.g. [[setting,imapc]] or [[setting,pop3c]].` }, ssl_server_key_file: { diff --git a/data/updates.js b/data/updates.js index 29787c053..714413d18 100644 --- a/data/updates.js +++ b/data/updates.js @@ -203,7 +203,7 @@ export const updates = { settings_imap_compress_on_proxy_added: '2.4.2', settings_imap_compress_on_proxy_changed: '2.4.5', settings_imap_filter_sieve_max_redirects_added: '2.4.6', - settings_imapc_credentials_removed: '2.4.6', + settings_imapc_credentials_renamed: '2.4.6', settings_imapc_sasl_mechanisms_deprecated: '2.4.6', settings_imapc_features_changed: '2.4.0', settings_imapc_ssl_verify_removed: '2.4.0', @@ -230,7 +230,8 @@ export const updates = { settings_passdb_sql_update_query_removed: '2.4.5', settings_passdb_static_password_added: '2.4.0', settings_pop3c_authzid_default_changed: '2.4.6', - settings_pop3c_credentials_removed: '2.4.6', + settings_pop3c_credentials_renamed: '2.4.6', + settings_pop3c_ssl_verify_renamed: '2.4.6', settings_service_reuse_port_added: '2.4.4', settings_service_type_client_added: '2.4.6', settings_sieve_max_cpu_time_changed: '2.4.5', From 94ac3047b8f4ef0cb137358cc1878e9a541378ac Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Tue, 20 Oct 2026 12:04:55 +0000 Subject: [PATCH 06/13] Add a client authentication configuration page The four client_auth_* setting descriptions can't carry the whole picture: which clients use them, how the mechanism is selected, how the SCRAM channel binding upgrade works and how the filter-scoped settings are given as overrides. Describe all of that in one place. The mapping of the old per-client credential settings belongs to the upgrade notes instead. --- docs/core/config/client_auth.md | 209 ++++++++++++++++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 docs/core/config/client_auth.md diff --git a/docs/core/config/client_auth.md b/docs/core/config/client_auth.md new file mode 100644 index 000000000..1eba9398a --- /dev/null +++ b/docs/core/config/client_auth.md @@ -0,0 +1,209 @@ +--- +layout: doc +title: Client Authentication +dovecotlinks: + client_auth: client authentication + client_auth_mechanism_selection: + hash: mechanism-selection + text: "client authentication: mechanism selection" + client_auth_channel_binding: + hash: channel-binding + text: "client authentication: channel binding" +--- + +# Client Authentication + +[[added,settings_client_auth_added]] + +Dovecot doesn't only authenticate its own users. In several places it is +itself a client that logs into another server: + +| Client | Settings filter | Notes | +| ------ | --------------- | ----- | +| [[link,imapc]] mailbox format | [[setting,imapc]] | Also used for migrations and shared mailboxes between backends. | +| [[link,pop3c]] mailbox format | [[setting,pop3c]] | | +| [[link,auth_imap,passdb imap]] | [[setting,imapc]] inside the `passdb` | The password given by the user is used as [[setting,client_auth_password]] automatically. | + +All of them use the same `client_auth_*` settings and the same SASL client +implementation, which this page describes. The settings are placed inside the +client's filter, because the same setting names are shared by all the +clients: + +```doveconf[dovecot.conf] +imapc { + host = imap.example.com + ssl = imaps + client_auth_authzid = %{user} + client_auth_password = secret +} +``` + +This is not to be confused with the [[link,authentication]] of Dovecot's own +users, nor with [[link,authentication_proxies]], where the passdb lookup +tells the login process where and how to log in. + +## Identities and Password + +SASL authentication has two identities: + +* [[setting,client_auth_authid]] is the *authentication identity*: the user + whose [[setting,client_auth_password]] is used to prove who the client is. +* [[setting,client_auth_authzid]] is the *authorization identity*: the user + whose mails are accessed after the authentication. + +For a regular login they are the same, so only +[[setting,client_auth_authzid]] needs to be set. An empty +[[setting,client_auth_authid]] means that the authorization identity is used +for authenticating as well. The two differ when logging in as a +[[link,auth_master_users,master user]]: the master user and its password are +the authentication identity and the actual user is the authorization +identity. + +```doveconf[dovecot.conf] +imapc { + client_auth_authid = masteruser + client_auth_password = masteruser-secret + client_auth_authzid = %{user} +} +``` + +Inside the [[setting,imapc]] and [[setting,pop3c]] filters +[[setting,client_auth_authzid]] defaults to `%{owner_user}`: the logged in +user, or the owner of a [[link,shared_mailboxes,shared namespace]]. + +The existence of the password is checked already when the client is +created, so a missing [[setting,client_auth_password]] for a mechanism that +needs one fails e.g. the namespace initialization for imapc, not only the +first connection. The `ANONYMOUS` and `EXTERNAL` mechanisms don't use a +password. For `OAUTHBEARER` and `XOAUTH2` the password is the bearer token. + +## Mechanism Selection + +The mechanism is chosen in one of three ways: + +### Configured Mechanism List + +Each [[setting,client_auth]] filter block declares a mechanism that the +client is allowed to use. The first configured mechanism that the server +also advertises is used, so the preferred mechanisms should be listed first. +Settings inside a block apply to that mechanism only, which allows e.g. a +different token for `OAUTHBEARER` than the password for `PLAIN`: + +```doveconf[dovecot.conf] +imapc { + host = imap.example.com + ssl = imaps + client_auth_authzid = %{user} + + client_auth SCRAM-SHA-256 { + password = secret + } + client_auth OAUTHBEARER { + password = vF9dft4qmTc2Nvb3RlckBhbHRhdmlzdGEuY29tCg== + } + client_auth PLAIN { + password = secret + } +} +``` + +If the server advertises none of the configured mechanisms, the login fails +with an error listing both the configured and the advertised mechanisms. +There is no fallback to the next mechanism if the authentication itself +fails, e.g. because of a wrong password. + +### Explicit Mechanism + +If [[setting,client_auth_mechanism]] is set directly inside the client's +filter, without any [[setting,client_auth]] blocks, that mechanism is used +without checking whether the server advertises it. This is mainly useful +when the server doesn't advertise its mechanisms correctly. + +```doveconf[dovecot.conf] +pop3c { + host = pop3.example.com + client_auth_mechanism = PLAIN + client_auth_authzid = %{user} + client_auth_password = secret +} +``` + +### No Configured Mechanism + +If neither is configured, the `PLAIN` mechanism is used if the server +advertises it, or if the server's mechanisms aren't known. For IMAP and POP3 +the basic `LOGIN` command and `USER` + `PASS` commands are used instead +whenever the server allows them, so SASL support isn't required from the +server at all. If the server doesn't advertise `PLAIN`, the first advertised +mechanism that Dovecot supports and that works with a password is used. + +If no mechanism and no identities are configured, there is nothing to +authenticate with. The connection fails with an "Authentication not +configured" error. + +### Supported Mechanisms + +See [[setting,client_auth_mechanism]] for the list. `GSSAPI` and `GSS-SPNEGO` +are currently available only for [[doveadm,auth test]] and +[[doveadm,auth login]], not for the clients listed above. + +## Channel Binding + +The `SCRAM-SHA-1-PLUS` and `SCRAM-SHA-256-PLUS` mechanisms bind the +authentication to the TLS connection, so that the credentials can't be +relayed through a man-in-the-middle. They require a TLS connection: +`tls-unique` channel binding is used with TLS 1.2 and `tls-exporter` with +TLS 1.3. + +When the non-PLUS `SCRAM-SHA-1` or `SCRAM-SHA-256` mechanism is used over a +TLS connection, channel binding is used anyway if the server also advertises +the corresponding `-PLUS` mechanism, as required by [[rfc,5802]]. + +If the server doesn't advertise the `-PLUS` mechanism, the authentication is +done without channel binding, but Dovecot tells the server that it would have +supported channel binding. If the server actually does support it, the +`-PLUS` mechanism must have been removed from the advertised list by an +attacker, and the server fails the authentication. + +The [[setting,client_auth]] filter names are matched against the server's +advertised mechanisms as-is. For example a server advertising only +`SCRAM-SHA-256-PLUS` doesn't match a `client_auth SCRAM-SHA-256 { }` filter, +so `client_auth SCRAM-SHA-256-PLUS { }` must be configured instead. + +## Overrides + +The filter-scoped settings are written with a `/` in overrides: + +```sh +doveadm -o imapc_host=imap.example.com \ + -o imapc/client_auth_authzid=user@example.com \ + -o imapc/client_auth_password=secret \ + -o mail_driver=imapc -o mail_path= mailbox list -u user@example.com +``` + +```doveconf[dovecot.conf] +passdb static { + fields { + userdb_imapc/client_auth_authzid = %{user} + userdb_imapc/client_auth_password = %{password} + } +} +``` + +## Debugging + +The client logs the mechanism selection and the identities it uses as debug +messages under the `sasl-client` event category, which is a child of the +client's own category: + +```doveconf[dovecot.conf] +log_debug = category=sasl-client +``` + +For imapc, [[doveadm,mailbox list]] with the imapc settings given as `-o` +overrides (see [Overrides](#overrides)) is a quick way to test the login +without changing the running configuration. + +## Settings + + From 086afc60dbc0a1c0f087a3005886cb99275daf9a Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Tue, 20 Oct 2026 12:07:31 +0000 Subject: [PATCH 07/13] Update the imapc and pop3c examples to the client_auth settings Also point the proxy_mech passdb field to client_auth_mechanism for the list of mechanisms, and explain in the passdb imap page that the password and the username are filled in automatically. --- docs/core/admin/migration.md | 43 ++++++++++++++--------- docs/core/config/auth/databases/imap.md | 20 ++++++++++- docs/core/config/mailbox_formats/imapc.md | 15 +++++--- docs/core/config/mailbox_formats/pop3c.md | 15 +++++--- docs/core/config/proxy/overview.md | 2 +- docs/core/settings/variables.md | 4 ++- docs/howto/imapc_proxy.md | 4 +-- 7 files changed, 72 insertions(+), 31 deletions(-) diff --git a/docs/core/admin/migration.md b/docs/core/admin/migration.md index a83c87ff2..0636bd198 100644 --- a/docs/core/admin/migration.md +++ b/docs/core/admin/migration.md @@ -139,7 +139,7 @@ If it's possible that the destination already has new mails (or other changes), use [[doveadm,sync,-1]] instead: ```sh -doveadm -o imapc_password=bar sync -1Ru user imapc: +doveadm -o imapc/client_auth_password=bar sync -1Ru user imapc: ``` You can run the command again to perform incremental updates. @@ -205,33 +205,42 @@ on how to turn these off when necessary. * These default to system. +The credentials are configured with the [[link,client_auth]] settings inside +the [[setting,imapc]] filter. + Master password auth: ```doveconf[dovecot.conf] -imapc_user = %{user} -imapc_password = supersecret +imapc { + client_auth_authzid = %{user} + client_auth_password = supersecret +} ``` Master user auth: ```doveconf[dovecot.conf] -imapc_user = %{user} -imapc_master_user = master-user -imapc_password = master-password +imapc { + client_auth_authzid = %{user} + client_auth_authid = master-user + client_auth_password = master-password +} ``` Individual password auth: ```doveconf[dovecot.conf] -imapc_user = %{user} +imapc { + client_auth_authzid = %{user} +} -# doveadm -o imapc_password=password backup -Ru user imapc: +# doveadm -o imapc/client_auth_password=password backup -Ru user imapc: ``` You can verify that the settings are done correctly with: ```sh -doveadm -o imapc_password=password -o mail_driver=imapc -o mail_path= mailbox list -u user +doveadm -o imapc/client_auth_password=password -o mail_driver=imapc -o mail_path= mailbox list -u user ``` ### POP3 notes @@ -244,10 +253,12 @@ pop3c_host = hostname # Authenticate as masteruser / masteruser-secret, but use a separate login # user. -# If you don't have a master user, remove the pop3c_master_user setting. -pop3c_user = %{user} -pop3c_master_user = masteruser -pop3c_password = masteruser-secret +# If you don't have a master user, remove the client_auth_authid setting. +pop3c { + client_auth_authzid = %{user} + client_auth_authid = masteruser + client_auth_password = masteruser-secret +} # if you are using TLS pop3c_ssl = pop3s @@ -282,13 +293,13 @@ You can alternatively configure compatible UIDL format in Dovecot. See To migrate users, use: ```sh -doveadm -o imapc_password=bar -o pop3c_password=bar backup -Ru user imapc: +doveadm -o imapc/client_auth_password=bar -o pop3c/client_auth_password=bar backup -Ru user imapc: ``` If you are experiencing problems, enable debugging with the `-D` parameter: ```sh -doveadm -D -o imapc_password=bar -o pop3c_password=bar backup -Ru username imapc: +doveadm -D -o imapc/client_auth_password=bar -o pop3c/client_auth_password=bar backup -Ru username imapc: ``` The doveadm backup command forces the destination to look exactly like the @@ -297,7 +308,7 @@ source, deleting mails and mailboxes if necessary. If it's possible that the destination already has new mails (or other changes), use [[doveadm,sync,-1]] instead: ```sh -doveadm -o imapc_password=bar -o pop3c_password=bar sync -1Ru user imapc: +doveadm -o imapc/client_auth_password=bar -o pop3c/client_auth_password=bar sync -1Ru user imapc: ``` Note that Public and Shared namespaces are synchronized automatically diff --git a/docs/core/config/auth/databases/imap.md b/docs/core/config/auth/databases/imap.md index a7baa7ae2..5c3a375b0 100644 --- a/docs/core/config/auth/databases/imap.md +++ b/docs/core/config/auth/databases/imap.md @@ -16,6 +16,13 @@ have been removed in favor of using the standard `imapc_*` settings. `allow_invalid_cert` settings have been removed. The standard `ssl_*` settings can be used instead (also inside `passdb { ... }` if wanted). +[[changed,settings_imapc_credentials_renamed]]: The `imapc_user`, +`imapc_master_user` and `imapc_password` settings are now the +[[link,client_auth]] settings inside the [[setting,imapc]] filter. The passdb +sets [[setting,client_auth_password]] automatically to the password given by +the user, and [[setting,client_auth_authzid]] defaults to the username, so +normally none of them need to be set. + ## Example @@ -26,10 +33,21 @@ Authenticates users against remote IMAP server in IP address 192.168.1.123: passdb imap { imapc_host = 192.168.1.123 imapc_port = 143 - imapc_user = %{owner_user} imapc_rawlog_dir = /tmp/imapc_rawlog/ imapc_ssl = starttls ssl_client_require_valid_cert = no } ``` + +To log in with a different username than what the user gave, e.g. without +the domain: + +```doveconf[dovecot.conf] +passdb imap { + imapc_host = 192.168.1.123 + imapc { + client_auth_authzid = %{user | username} + } +} +``` diff --git a/docs/core/config/mailbox_formats/imapc.md b/docs/core/config/mailbox_formats/imapc.md index 8f9e5d8b7..983151a3a 100644 --- a/docs/core/config/mailbox_formats/imapc.md +++ b/docs/core/config/mailbox_formats/imapc.md @@ -18,6 +18,9 @@ optionally a more capable storage. +The login to the remote server is configured with the [[link,client_auth]] +settings inside the [[setting,imapc]] filter. + ## Configuration Example Do a regular IMAP LOGIN, using STARTTLS, to imap.example.com: @@ -30,11 +33,13 @@ mail_path = # OR, Store index files locally: #mail_path = ~/imapc -imapc_host = imap.example.com -imapc_password = secret -imapc_port = 143 -imapc_ssl = starttls -imapc_user = user@example.com +imapc { + host = imap.example.com + port = 143 + ssl = starttls + client_auth_authzid = user@example.com + client_auth_password = secret +} ``` ## Quota diff --git a/docs/core/config/mailbox_formats/pop3c.md b/docs/core/config/mailbox_formats/pop3c.md index 06b341d67..3b1abd8ae 100644 --- a/docs/core/config/mailbox_formats/pop3c.md +++ b/docs/core/config/mailbox_formats/pop3c.md @@ -16,6 +16,9 @@ The remote POP3 mailbox is visible as the INBOX folder on the Dovecot side. +The login to the remote server is configured with the [[link,client_auth]] +settings inside the [[setting,pop3c]] filter. + ## Configuration Example Connect using STARTTLS to pop3.example.com: @@ -27,9 +30,11 @@ mail_path = # OR, Store index files locally: #mail_path = ~/pop3c -pop3c_host = pop3.example.com -pop3c_password = secret -pop3c_port = 110 -pop3c_ssl = starttls -pop3c_user = user@example.com +pop3c { + host = pop3.example.com + port = 110 + ssl = starttls + client_auth_authzid = user@example.com + client_auth_password = secret +} ``` diff --git a/docs/core/config/proxy/overview.md b/docs/core/config/proxy/overview.md index 388adde86..2372204e7 100644 --- a/docs/core/config/proxy/overview.md +++ b/docs/core/config/proxy/overview.md @@ -91,7 +91,7 @@ Tell client to use a different username when logging in. ### `proxy_mech=` Tell client to use this SASL authentication mechanism when logging in. -See [[setting,imapc_sasl_mechanisms]] for supported mechanisms +See [[setting,client_auth_mechanism]] for supported mechanisms. ### `proxy_timeout=` diff --git a/docs/core/settings/variables.md b/docs/core/settings/variables.md index f965c5612..163b43cbc 100644 --- a/docs/core/settings/variables.md +++ b/docs/core/settings/variables.md @@ -464,7 +464,9 @@ For best results, you should leave salt and IV management to Dovecot. import_environment { SECRET_KEY = %{env:SECRET_KEY} } -imapc_password = "%{literal('s=3-?I&-a|,r=10000$e80e6ab3c18c0da69b20bf201eaf6269$') | decrypt(key=env:SECRET_KEY)}" +imapc { + client_auth_password = "%{literal('s=3-?I&-a|,r=10000$e80e6ab3c18c0da69b20bf201eaf6269$') | decrypt(key=env:SECRET_KEY)}" +} ``` Stores imap client password securely so that it can be decrypted only if `SECRET_KEY` environment variable is provided. diff --git a/docs/howto/imapc_proxy.md b/docs/howto/imapc_proxy.md index cde5786d0..a3b45eff5 100644 --- a/docs/howto/imapc_proxy.md +++ b/docs/howto/imapc_proxy.md @@ -55,8 +55,8 @@ This is based on already having Dovecot already compiled and installed. # You can optionally override the IP here. # imapc_host = 10.1.2.5 fields { - userdb_imapc_user = %{user} - userdb_imapc_password = %{password} + userdb_imapc/client_auth_authzid = %{user} + userdb_imapc/client_auth_password = %{password} } } From 680621492b015a842590882b680a5fddaca014af Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Wed, 21 Oct 2026 18:06:47 +0000 Subject: [PATCH 08/13] upgrade: Add the 2.4.6 client authentication notes --- docs/installation/upgrade/2.4-to-2.4.x.md | 2 ++ .../upgrade/include/2.4.6-client-auth.inc | 25 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 docs/installation/upgrade/include/2.4.6-client-auth.inc diff --git a/docs/installation/upgrade/2.4-to-2.4.x.md b/docs/installation/upgrade/2.4-to-2.4.x.md index 30e0128be..e8fe8238d 100644 --- a/docs/installation/upgrade/2.4-to-2.4.x.md +++ b/docs/installation/upgrade/2.4-to-2.4.x.md @@ -193,6 +193,8 @@ INBOX namespace. + + diff --git a/docs/installation/upgrade/include/2.4.6-client-auth.inc b/docs/installation/upgrade/include/2.4.6-client-auth.inc new file mode 100644 index 000000000..8ceb99cbd --- /dev/null +++ b/docs/installation/upgrade/include/2.4.6-client-auth.inc @@ -0,0 +1,25 @@ +#### Client Authentication Settings + +The credentials that Dovecot uses when it logs into other servers (imapc, +pop3c, passdb imap) are now configured with the generic +[[link,client_auth,client authentication]] settings inside the client's +filter, instead of per-client settings. The old names are renamed +automatically as long as [[setting,dovecot_config_version]] is older than +`2.4.6`, but `doveconf` writes the new names: + +| Old setting | New setting | +| ----------- | ----------- | +| `imapc_user`, `imapc_master_user`, `imapc_password` | `imapc { client_auth_authzid, client_auth_authid, client_auth_password }` | +| `imapc_sasl_mechanisms` | Deprecated. Each listed mechanism becomes an `imapc { client_auth { } }` block in the listed order. | +| `pop3c_user`, `pop3c_master_user`, `pop3c_password` | `pop3c { client_auth_authzid, client_auth_authid, client_auth_password }` | +| `pop3c_ssl_verify` | `pop3c { ssl_client_require_valid_cert }` | + + * `-o` and userdb overrides use the `imapc/client_auth_password` syntax. + The old names are still translated in overrides regardless of the config + version, so for example `doveadm -o imapc_password=secret` keeps working. + * The pop3c default for the authorization identity changes from `%{user}` + to `%{owner_user}` with the new config version. This only affects shared + namespaces. + * The `SCRAM-SHA-1` and `SCRAM-SHA-256` client mechanisms now use channel + binding automatically when the server advertises the `-PLUS` variant over + a TLS connection. From 8b4641fc5349d4ad433c3b0cb221d5cccaa27cb7 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Tue, 20 Oct 2026 12:00:36 +0000 Subject: [PATCH 09/13] settings.js: Document the smtp_client_* and lmtp_client_* settings These are the generic settings of lib-smtp's SMTP and LMTP client. They are used inside the submission_relay, mail_submit and lmtp_proxy filters. --- data/settings.js | 255 ++++++++++++++++++++++++++++++++++++++++++++++- data/updates.js | 2 + 2 files changed, 254 insertions(+), 3 deletions(-) diff --git a/data/settings.js b/data/settings.js index 7123e2de5..b904513d0 100644 --- a/data/settings.js +++ b/data/settings.js @@ -6576,12 +6576,13 @@ for HAProxy are aborted immediately.` hostname: { default: '\\', - tags: [ 'submission' ], + tags: [ 'submission', 'smtp_client', 'lmtp_client' ], values: setting_types.STRING, text: ` The hostname to be used in email messages sent out by the local delivery -agent (such as the Message-ID: header), in LMTP replies, and as the -hostname advertised by submission SMTP service.` +agent (such as the Message-ID: header), in LMTP replies, as the +hostname advertised by submission SMTP service, and in the EHLO/LHLO command +of the outgoing SMTP and LMTP connections.` }, http_client_auto_redirect: { @@ -8066,6 +8067,132 @@ Alias for [[setting,inet_listener_listen]].` Controls if "Received:" header should be added to delivered mails.` }, + lmtp_client_command_timeout: { + added: { + settings_lmtp_client_added: false + }, + default: '5 mins', + tags: [ 'lmtp_client' ], + seealso: [ 'lmtp_client_connect_timeout' ], + values: setting_types.TIME_MSECS, + text: ` +Timeout for LMTP commands sent to the remote server. The timeout is reset +every time more data is being sent or received. + +The \`lmtp_client_*\` settings configure Dovecot's outgoing LMTP connections. +They are used inside the [[setting,lmtp_proxy]] filter, where the default is +\`125 secs\`.` + }, + + lmtp_client_connect_timeout: { + added: { + settings_lmtp_client_added: false + }, + default: '30 secs', + tags: [ 'lmtp_client' ], + seealso: [ 'lmtp_client_command_timeout' ], + values: setting_types.TIME_MSECS, + text: ` +Timeout for connecting to the remote LMTP server, including the TLS handshake. + +Inside the [[setting,lmtp_proxy]] filter the default is \`125 secs\`.` + }, + + lmtp_client_host: { + added: { + settings_lmtp_client_added: false + }, + tags: [ 'lmtp_client' ], + seealso: [ 'lmtp_client_port', 'lmtp_client_ssl' ], + values: setting_types.STRING, + text: ` +Host name or IP address of the remote LMTP server. The LMTP proxy gets the +host from the passdb lookup (see [[link,authentication_proxies]]), so this is +normally not set.` + }, + + lmtp_client_peer_trusted: { + added: { + settings_lmtp_client_added: false + }, + default: 'no', + tags: [ 'lmtp_client' ], + values: setting_types.BOOLEAN, + text: ` +Whether the remote LMTP server is trusted. If enabled, the original client's +connection information is forwarded to the remote server with the +(Postfix-specific) XCLIENT command, if the remote server advertises support +for it. + +Inside the [[setting,lmtp_proxy]] filter the default is \`yes\`.` + }, + + lmtp_client_port: { + added: { + settings_lmtp_client_added: false + }, + default: 24, + tags: [ 'lmtp_client' ], + seealso: [ 'lmtp_client_host', 'lmtp_client_ssl' ], + values: setting_types.IN_PORT, + text: ` +Port of the remote LMTP server. + +Inside the [[setting,lmtp_proxy]] filter the default is the port that the +local LMTP server received the connection on (\`%{local_port}\`), so that +proxying to the same port on the backend doesn't need any configuration. +The passdb lookup can override it.` + }, + + lmtp_client_rawlog_dir: { + added: { + settings_lmtp_client_added: false + }, + tags: [ 'lmtp_client' ], + seealso: [ '[[link,rawlog]]' ], + values: setting_types.PATH_DIR, + text: ` +Write protocol logs of the outgoing LMTP connections to this directory for +debugging. + +[[variable,mail-service-user]] can be used. However, because LMTP session +starts without a user, all user-specific variables expand to empty.` + }, + + lmtp_client_source_ip: { + added: { + settings_lmtp_client_added: false + }, + tags: [ 'lmtp_client' ], + values: setting_types.STRING, + text: ` +Local IP address to use as the source address of the outgoing LMTP +connections. If empty, the kernel chooses the address.` + }, + + lmtp_client_ssl: { + added: { + settings_lmtp_client_added: false + }, + default: 'no', + tags: [ 'lmtp_client' ], + seealso: [ 'ssl_client_require_valid_cert', '[[link,ssl_configuration]]' ], + values: setting_types.ENUM, + values_enum: [ 'no', 'lmtps', 'starttls' ], + text: ` +Whether to use TLS for the connection to the remote LMTP server. + +| Value | Description | +| ----- | ----------- | +| \`no\` | No TLS | +| \`lmtps\` | Connect using TLS immediately (implicit TLS) | +| \`starttls\` | Use the STARTTLS command to switch to TLS | + +The connection uses the \`ssl_client_*\` settings, which can be set inside the +same filter to apply to this client only. The passdb lookup can override this +setting for the LMTP proxy, see [[link,authentication_proxies]].` + }, + lmtp_client_workarounds: { tags: [ 'lmtp' ], values: setting_types.BOOLLIST, @@ -11795,6 +11922,128 @@ needs \`KillMode=mixed\` or \`KillMode=process\`. :::` }, + smtp_client_command_timeout: { + added: { + settings_smtp_client_added: false + }, + default: '5 mins', + tags: [ 'smtp_client' ], + seealso: [ 'smtp_client_connect_timeout' ], + values: setting_types.TIME_MSECS, + text: ` +Timeout for SMTP commands sent to the remote server. The timeout is reset +every time more data is being sent or received. + +The \`smtp_client_*\` settings configure Dovecot's outgoing SMTP connections. +They are used inside the [[setting,submission_relay]] and +[[setting,mail_submit]] filters.` + }, + + smtp_client_connect_timeout: { + added: { + settings_smtp_client_added: false + }, + default: '30 secs', + tags: [ 'smtp_client' ], + seealso: [ 'smtp_client_command_timeout' ], + values: setting_types.TIME_MSECS, + text: ` +Timeout for connecting to the remote SMTP server, including the TLS handshake +and authentication.` + }, + + smtp_client_host: { + added: { + settings_smtp_client_added: false + }, + tags: [ 'smtp_client' ], + seealso: [ 'smtp_client_port', 'smtp_client_ssl' ], + values: setting_types.STRING, + text: ` +Host name or IP address of the remote SMTP server. The port is configured +separately with [[setting,smtp_client_port]]. + +Inside the [[setting,submission_relay]] filter this is required. Inside the +[[setting,mail_submit]] filter setting it switches from executing the sendmail +binary to sending via SMTP. + +[[variable,mail-user]] can be used.` + }, + + smtp_client_peer_trusted: { + added: { + settings_smtp_client_added: false + }, + default: 'no', + tags: [ 'smtp_client' ], + values: setting_types.BOOLEAN, + text: ` +Whether the remote SMTP server is trusted. If enabled, the original client's +connection information is forwarded to the remote server with the +(Postfix-specific) XCLIENT command, if the remote server advertises support +for it.` + }, + + smtp_client_port: { + added: { + settings_smtp_client_added: false + }, + default: 25, + tags: [ 'smtp_client' ], + seealso: [ 'smtp_client_host', 'smtp_client_ssl' ], + values: setting_types.IN_PORT, + text: ` +Port of the remote SMTP server.` + }, + + smtp_client_rawlog_dir: { + added: { + settings_smtp_client_added: false + }, + tags: [ 'smtp_client' ], + seealso: [ '[[link,rawlog]]' ], + values: setting_types.PATH_DIR, + text: ` +Write protocol logs of the outgoing SMTP connections to this directory for +debugging. + +[[variable,mail-user]] can be used.` + }, + + smtp_client_source_ip: { + added: { + settings_smtp_client_added: false + }, + tags: [ 'smtp_client' ], + values: setting_types.STRING, + text: ` +Local IP address to use as the source address of the outgoing SMTP +connections. If empty, the kernel chooses the address.` + }, + + smtp_client_ssl: { + added: { + settings_smtp_client_added: false + }, + default: 'no', + tags: [ 'smtp_client' ], + seealso: [ 'ssl_client_require_valid_cert', '[[link,ssl_configuration]]' ], + values: setting_types.ENUM, + values_enum: [ 'no', 'smtps', 'submissions', 'starttls' ], + text: ` +Whether to use TLS for the connection to the remote SMTP server. + +| Value | Description | +| ----- | ----------- | +| \`no\` | No TLS | +| \`smtps\` | Connect using TLS immediately (implicit TLS) | +| \`submissions\` | Same as \`smtps\`, the name used by [[rfc,8314]] | +| \`starttls\` | Use the STARTTLS command to switch to TLS | + +The connection uses the \`ssl_client_*\` settings, which can be set inside the +same filter to apply to this client only.` + }, + sql_driver: { values: setting_types.STRING, text: ` diff --git a/data/updates.js b/data/updates.js index 714413d18..f20328e20 100644 --- a/data/updates.js +++ b/data/updates.js @@ -213,6 +213,7 @@ export const updates = { settings_local_name_nested_changed: '2.4.6', settings_login_socket_path_added: '2.4.0', settings_login_unauthenticated_client_limit_added: '2.4.6', + settings_lmtp_client_added: '2.4.6', settings_lmtp_user_concurrency_limit_changed: '2.4.1', settings_mail_access_groups_changed: '2.4.3', settings_mail_attachment_sis_option_changed: '2.4.0', @@ -235,6 +236,7 @@ export const updates = { settings_service_reuse_port_added: '2.4.4', settings_service_type_client_added: '2.4.6', settings_sieve_max_cpu_time_changed: '2.4.5', + settings_smtp_client_added: '2.4.6', settings_sieve_notify_mailto_max_headers_added: '2.4.5', settings_sieve_notify_mailto_max_recipients_added: '2.4.5', settings_sieve_notify_max_notifications_added: '2.4.5', From ec3c731bbced37c91a2a37a8bdb3ebe394ebbf14 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Tue, 20 Oct 2026 12:03:18 +0000 Subject: [PATCH 10/13] settings.js: Document the submission_relay, mail_submit and lmtp_proxy filters The SMTP client settings changes move the outgoing SMTP/LMTP connection settings into filters that hold the generic smtp_client_*/lmtp_client_*, client_auth_* and ssl_client_* settings: - submission_relay_* -> submission_relay { smtp_client_* / client_auth_* / ssl_client_require_valid_cert }. submission_relay_max_idle_time never did anything and is deprecated. - submission_host/submission_ssl -> mail_submit { smtp_client_host / smtp_client_port / smtp_client_ssl }, submission_timeout -> mail_submit_timeout, and sendmail_path -> mail_submit { execute sendmail { } }. The host:port syntax of submission_host is gone. - lmtp_proxy (boolean) -> lmtp_proxy_enabled, since lmtp_proxy { } is now the filter for the lmtp_client_* settings, and lmtp_proxy_rawlog_dir -> lmtp_proxy { lmtp_client_rawlog_dir }. A new lmtp_local { } filter scopes settings to local deliveries. Also list submission_relay and mail_submit as client_auth users in the client_auth and ssl_client_require_valid_cert descriptions. --- data/settings.js | 248 +++++++++++++++++++++++++++++++++++++++++++++-- data/updates.js | 6 ++ 2 files changed, 247 insertions(+), 7 deletions(-) diff --git a/data/settings.js b/data/settings.js index b904513d0..f62f1cf71 100644 --- a/data/settings.js +++ b/data/settings.js @@ -90,8 +90,8 @@ next mechanism if the authentication itself fails. Client authentication settings are expected to be scoped further by settings filters for the various protocol clients that need authentication, such as -[[setting,imapc]] and [[setting,pop3c]]. See [[link,client_auth]] for an -overview. +[[setting,imapc]], [[setting,pop3c]], [[setting,submission_relay]] and +[[setting,mail_submit]]. See [[link,client_auth]] for an overview. Example: \`\`\`[dovecot.conf] @@ -8230,18 +8230,71 @@ Options: : No address (always used for messages with multiple recipients)` }, + lmtp_local: { + added: { + settings_lmtp_local_added: false + }, + tags: [ 'lmtp' ], + values: setting_types.NAMED_FILTER, + seealso: [ 'lmtp_proxy' ], + text: ` +Filter for settings that apply only to local LMTP deliveries, as opposed to +proxied ones (see [[setting,lmtp_proxy]]). For example the +[[setting,mail_submit]] settings used for sending bounces can be placed +here.` + }, + lmtp_proxy: { + changed: { + settings_lmtp_proxy_renamed: ` +\`lmtp_proxy\` used to be a boolean setting. It is now a filter, and the +boolean is [[setting,lmtp_proxy_enabled]]. The old \`lmtp_proxy = yes\` still +works with an older [[setting,dovecot_config_version]].` + }, + tags: [ 'lmtp', 'lmtp_client' ], + values: setting_types.NAMED_FILTER, + seealso: [ 'lmtp_proxy_enabled', 'lmtp_local', + '[[link,authentication_proxies]]' ], + text: ` +Filter for the LMTP proxying settings: the generic \`lmtp_client_*\` settings +of the connection to the backend, and [[setting,lmtp_proxy_enabled]]. + +Inside this filter the defaults are the port of the incoming LMTP connection +for [[setting,lmtp_client_port]], [[setting,lmtp_client_peer_trusted,yes]], +and \`125 secs\` for both [[setting,lmtp_client_connect_timeout]] and +[[setting,lmtp_client_command_timeout]]. + +Example: +\`\`\`[dovecot.conf] +lmtp_proxy_enabled = yes +lmtp_proxy { + lmtp_client_rawlog_dir = /var/log/dovecot/lmtp-proxy-rawlog +} +\`\`\`` + }, + + lmtp_proxy_enabled: { + added: { + settings_lmtp_proxy_renamed: false + }, default: 'no', - seealso: [ '[[link,authentication_proxies]]' ], + seealso: [ 'lmtp_proxy', '[[link,authentication_proxies]]' ], tags: [ 'lmtp' ], values: setting_types.BOOLEAN, text: ` If yes, LMTP sessions perform a passdb lookup to see if the user should be proxied. The user is proxied only if the \`proxy\` extra field is returned. -The proxy destination is determined via returned passdb extra fields.` +The proxy destination is determined via returned passdb extra fields. + +Renamed from \`lmtp_proxy\`, which is now the [[setting,lmtp_proxy]] filter.` }, lmtp_proxy_rawlog_dir: { + removed: { + settings_lmtp_proxy_renamed: ` +Renamed to [[setting,lmtp_client_rawlog_dir]] inside the +[[setting,lmtp_proxy]] filter.` + }, seealso: [ '[[link,rawlog]]' ], tags: [ 'lmtp' ], values: setting_types.STRING, @@ -9177,6 +9230,63 @@ NO [LIMIT] Requested sort would have taken too long. \`\`\`` }, + mail_submit: { + added: { + settings_mail_submit_added: false + }, + tags: [ 'mail_submit', 'lda', 'lmtp', 'client-auth' ], + values: setting_types.NAMED_FILTER, + seealso: [ 'mail_submit_timeout', 'smtp_client_host', 'execute', + 'client_auth', '[[link,client_auth]]' ], + text: ` +Filter for configuring how Dovecot submits outgoing mails: bounces and +forwards from [[link,lda]] and [[link,lmtp]], Sieve redirects, vacation +replies and notifications, and so on. + +By default the mails are given to the local sendmail binary, which is +configured as an [[setting,execute]] block named \`sendmail\` inside this +filter: + +\`\`\`[dovecot.conf] +mail_submit { + execute sendmail { + driver = fork + fork_path = /usr/sbin/sendmail + } +} +\`\`\` + +If [[setting,smtp_client_host]] is set inside this filter, the mails are sent +via SMTP instead, using the generic \`smtp_client_*\` settings. The connection +can be authenticated with the [[setting,client_auth]] settings and secured +with the \`ssl_client_*\` settings: + +\`\`\`[dovecot.conf] +mail_submit { + smtp_client_host = mta.example.com + smtp_client_port = 587 + smtp_client_ssl = starttls + client_auth_authzid = dovecot + client_auth_password = secret +} +\`\`\` + +Inside this filter the defaults are [[setting,smtp_client_port,25]] and +[[setting,smtp_client_ssl,no]].` + }, + + mail_submit_timeout: { + changed: { + settings_submission_host_renamed: ` +Renamed from \`submission_timeout\`.` + }, + default: '30 secs', + tags: [ 'mail_submit', 'lda', 'lmtp' ], + seealso: [ 'mail_submit' ], + values: setting_types.TIME, + text: `Timeout for submitting outgoing messages.` + }, + mail_temp_dir: { default: '/tmp', tags: [ 'lda', 'lmtp' ], @@ -11569,12 +11679,23 @@ See [[setting,rejection_reason]] for the list of variables that can be used.` }, sendmail_path: { + deprecated: { + settings_sendmail_path_deprecated: ` +Replaced by an [[setting,execute]] block named \`sendmail\` inside the +[[setting,mail_submit]] filter. The setting still works: its value is +translated into the [[setting,execute_fork_path]] and +[[setting,execute_args]] settings of that block.` + }, default: '/usr/sbin/sendmail', + tags: [ 'mail_submit', 'lda', 'lmtp' ], + seealso: [ 'mail_submit' ], values: setting_types.STRING, text: ` -The binary to use for sending email. +The binary to use for sending email. Arguments can be given after the path, +separated by spaces. -Used only if [[setting,submission_host]] is not set.` +Used only if [[setting,smtp_client_host]] is not set inside the +[[setting,mail_submit]] filter.` }, service: { @@ -12354,7 +12475,7 @@ ssl_server_dh_file = /path/to/dh.pem Require a valid certificate when connecting to external SSL services? To change this for a single client only, set it inside that client's filter, -e.g. [[setting,imapc]] or [[setting,pop3c]].` +e.g. [[setting,imapc]], [[setting,pop3c]] or [[setting,submission_relay]].` }, ssl_server_key_file: { @@ -12558,6 +12679,13 @@ Supported workaround identifiers are: }, submission_host: { + removed: { + settings_submission_host_renamed: ` +Renamed to [[setting,smtp_client_host]] inside the [[setting,mail_submit]] +filter. With an older [[setting,dovecot_config_version]] the old name is +still accepted, but a \`host:port\` value is not: the port must be given +separately with [[setting,smtp_client_port]].` + }, tags: [ 'submission' ], values: setting_types.URL, text: ` @@ -12606,7 +12734,50 @@ unknown limit exists there, which will be passed back to the client.` Maximum number of recipients accepted per connection.` }, + submission_relay: { + added: { + settings_submission_relay_renamed: false + }, + tags: [ 'submission_relay', 'client-auth' ], + values: setting_types.NAMED_FILTER, + seealso: [ '[[link,submission_server]]', 'smtp_client_host', + 'client_auth', '[[link,client_auth]]' ], + text: ` +Filter for the settings of the connection from the [[link,submission_server]] +to the relay MTA. The connection is configured with the generic +\`smtp_client_*\`, [[setting,client_auth]] and \`ssl_client_*\` settings +placed inside this filter. [[setting,smtp_client_host]] is required to +provide the submission service. + +Inside this filter the defaults are [[setting,smtp_client_port,25]], +[[setting,smtp_client_connect_timeout,30 secs]] and +[[setting,smtp_client_command_timeout,5 mins]]. + +Example: +\`\`\`[dovecot.conf] +submission_relay { + smtp_client_host = mta.example.com + smtp_client_port = 587 + smtp_client_ssl = starttls + smtp_client_peer_trusted = yes + + client_auth_authzid = submission-relay + client_auth_password = secret + # Prefer SCRAM-SHA-256, use PLAIN if the MTA doesn't advertise it + client_auth SCRAM-SHA-256 { + } + client_auth PLAIN { + } +} +\`\`\`` + }, + submission_relay_command_timeout: { + removed: { + settings_submission_relay_renamed: ` +Renamed to [[setting,smtp_client_command_timeout]] inside the +[[setting,submission_relay]] filter.` + }, default: '5mins', tags: [ 'submission_relay' ], values: setting_types.TIME_MSECS, @@ -12617,6 +12788,11 @@ The timeout is reset every time more data is being sent or received.` }, submission_relay_connect_timeout: { + removed: { + settings_submission_relay_renamed: ` +Renamed to [[setting,smtp_client_connect_timeout]] inside the +[[setting,submission_relay]] filter.` + }, default: '30secs', tags: [ 'submission_relay' ], values: setting_types.TIME_MSECS, @@ -12626,6 +12802,11 @@ server.` }, submission_relay_host: { + removed: { + settings_submission_relay_renamed: ` +Renamed to [[setting,smtp_client_host]] inside the +[[setting,submission_relay]] filter.` + }, tags: [ 'submission_relay' ], values: setting_types.STRING, text: ` @@ -12633,6 +12814,11 @@ Host of the relay server (REQUIRED to provide the submission service).` }, submission_relay_master_user: { + removed: { + settings_submission_relay_renamed: ` +Renamed to [[setting,client_auth_authid]] inside the +[[setting,submission_relay]] filter.` + }, tags: [ 'submission_relay' ], values: setting_types.STRING, text: ` @@ -12641,6 +12827,10 @@ required.` }, submission_relay_max_idle_time: { + deprecated: { + settings_submission_relay_renamed: ` +The setting never had any effect. It is still accepted, but ignored.` + }, default: '29mins', tags: [ 'submission_relay' ], values: setting_types.TIME, @@ -12648,6 +12838,11 @@ required.` }, submission_relay_password: { + removed: { + settings_submission_relay_renamed: ` +Renamed to [[setting,client_auth_password]] inside the +[[setting,submission_relay]] filter.` + }, tags: [ 'submission_relay' ], values: setting_types.STRING, text: ` @@ -12655,6 +12850,11 @@ Password for authentication to the relay MTA if authentication is required.` }, submission_relay_port: { + removed: { + settings_submission_relay_renamed: ` +Renamed to [[setting,smtp_client_port]] inside the +[[setting,submission_relay]] filter.` + }, default: 25, tags: [ 'submission_relay' ], values: setting_types.IN_PORT, @@ -12666,6 +12866,11 @@ Port for the submission relay server.` changed: { settings_path_types_added: `Setting type changed.`, }, + removed: { + settings_submission_relay_renamed: ` +Renamed to [[setting,smtp_client_rawlog_dir]] inside the +[[setting,submission_relay]] filter.` + }, tags: [ 'submission_relay' ], seealso: [ '[[link,rawlog]]' ], values: setting_types.PATH_DIR, @@ -12676,6 +12881,11 @@ Write protocol logs for relay connection to this directory for debugging. }, submission_relay_ssl: { + removed: { + settings_submission_relay_renamed: ` +Renamed to [[setting,smtp_client_ssl]] inside the +[[setting,submission_relay]] filter.` + }, default: 'no', tags: [ 'submission_relay' ], values: setting_types.ENUM, @@ -12696,6 +12906,11 @@ Available values: }, submission_relay_ssl_verify: { + removed: { + settings_submission_relay_renamed: ` +Renamed to [[setting,ssl_client_require_valid_cert]] inside the +[[setting,submission_relay]] filter.` + }, default: 'yes', tags: [ 'submission_relay' ], values: setting_types.BOOLEAN, @@ -12704,6 +12919,11 @@ If enabled, TLS certificate of the relay server must be verified.` }, submission_relay_trusted: { + removed: { + settings_submission_relay_renamed: ` +Renamed to [[setting,smtp_client_peer_trusted]] inside the +[[setting,submission_relay]] filter.` + }, default: 'no', tags: [ 'submission_relay' ], values: setting_types.BOOLEAN, @@ -12715,6 +12935,11 @@ relay server (only if enabled).` }, submission_relay_user: { + removed: { + settings_submission_relay_renamed: ` +Renamed to [[setting,client_auth_authzid]] inside the +[[setting,submission_relay]] filter.` + }, tags: [ 'submission_relay' ], values: setting_types.STRING, text: ` @@ -12722,6 +12947,11 @@ User name for authentication to the relay MTA if authentication is required.` }, submission_ssl: { + removed: { + settings_submission_host_renamed: ` +Renamed to [[setting,smtp_client_ssl]] inside the [[setting,mail_submit]] +filter.` + }, default: 'no', seealso: [ 'submission_host' ], values: setting_types.STRING, @@ -12742,6 +12972,10 @@ Available values: }, submission_timeout: { + removed: { + settings_submission_host_renamed: ` +Renamed to [[setting,mail_submit_timeout]].` + }, default: '30secs', seealso: [ 'submission_host' ], values: setting_types.TIME, diff --git a/data/updates.js b/data/updates.js index f20328e20..197b83565 100644 --- a/data/updates.js +++ b/data/updates.js @@ -214,12 +214,15 @@ export const updates = { settings_login_socket_path_added: '2.4.0', settings_login_unauthenticated_client_limit_added: '2.4.6', settings_lmtp_client_added: '2.4.6', + settings_lmtp_local_added: '2.4.6', + settings_lmtp_proxy_renamed: '2.4.6', settings_lmtp_user_concurrency_limit_changed: '2.4.1', settings_mail_access_groups_changed: '2.4.3', settings_mail_attachment_sis_option_changed: '2.4.0', settings_mail_cache_max_headers_count_added: '2.4.0', settings_mail_cache_max_header_name_length_added: '2.4.0', settings_mail_lua_added: '2.4.0', + settings_mail_submit_added: '2.4.6', settings_mail_volatile_path_changed: '2.4.5', settings_mailbox_autoexpunge_hibernation_changed: '2.4.6', settings_mailbox_defaults_english_changed: '2.4.3', @@ -251,7 +254,10 @@ export const updates = { settings_quota_clone_unset_added: '2.4.0', settings_quota_mailbox_count_added: '2.4.0', settings_quota_mailbox_message_count_added: '2.4.0', + settings_sendmail_path_deprecated: '2.4.6', settings_submission_add_received_header_added: '2.4.0', + settings_submission_host_renamed: '2.4.6', + settings_submission_relay_renamed: '2.4.6', settings_verbose_ssl_removed: '2.4.0', } From 8351ad369ed025b5a6ece5e85bf6f9a451d00cbc Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Wed, 21 Oct 2026 19:57:49 +0000 Subject: [PATCH 11/13] client_auth: Add the submission relay and mail_submit clients The submission relay and mail_submit SMTP clients now use the same client_auth_* settings. Add them to the client list. --- docs/core/config/client_auth.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/core/config/client_auth.md b/docs/core/config/client_auth.md index 1eba9398a..8433a09e5 100644 --- a/docs/core/config/client_auth.md +++ b/docs/core/config/client_auth.md @@ -23,6 +23,8 @@ itself a client that logs into another server: | [[link,imapc]] mailbox format | [[setting,imapc]] | Also used for migrations and shared mailboxes between backends. | | [[link,pop3c]] mailbox format | [[setting,pop3c]] | | | [[link,auth_imap,passdb imap]] | [[setting,imapc]] inside the `passdb` | The password given by the user is used as [[setting,client_auth_password]] automatically. | +| [[link,submission_server]] relay | [[setting,submission_relay]] | Logging into the relay MTA. | +| [[setting,mail_submit]] via SMTP | [[setting,mail_submit]] | Bounces, Sieve redirects and other mails submitted by Dovecot. | All of them use the same `client_auth_*` settings and the same SASL client implementation, which this page describes. The settings are placed inside the @@ -69,7 +71,8 @@ imapc { Inside the [[setting,imapc]] and [[setting,pop3c]] filters [[setting,client_auth_authzid]] defaults to `%{owner_user}`: the logged in -user, or the owner of a [[link,shared_mailboxes,shared namespace]]. +user, or the owner of a [[link,shared_mailboxes,shared namespace]]. The other +clients have no default identity. The existence of the password is checked already when the client is created, so a missing [[setting,client_auth_password]] for a mechanism that From fa97a16436c446369e3901c5ea926434608b1497 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Tue, 20 Oct 2026 12:07:31 +0000 Subject: [PATCH 12/13] Update the submission, LMTP and delivery pages to the SMTP client settings submission_host and sendmail_path are now configured inside mail_submit { }, lmtp_proxy is lmtp_proxy_enabled, and the rawlog settings moved inside the lmtp_proxy and submission_relay filters. Add a relay example with authentication to the submission page. --- docs/core/admin/rawlog.md | 10 ++++---- docs/core/config/auth/passdb.md | 3 ++- .../delivery/include/delivery_common.inc | 11 +++++---- docs/core/config/delivery/lmtp.md | 16 ++++++++++++- docs/core/config/sieve/submission.md | 17 ++++++++++---- docs/core/config/spam_reporting.md | 5 +++- docs/core/config/submission.md | 23 +++++++++++++++++++ 7 files changed, 68 insertions(+), 17 deletions(-) diff --git a/docs/core/admin/rawlog.md b/docs/core/admin/rawlog.md index 0ef230c32..983d4c768 100644 --- a/docs/core/admin/rawlog.md +++ b/docs/core/admin/rawlog.md @@ -17,11 +17,13 @@ TLS/SSL encrypted). There are several possibilities for this: 3. For proxying (in \*-login processes), use [[setting,login_proxy_rawlog_dir]]. -4. For lmtp, you need to use [[setting,lmtp_rawlog_dir]] and - [[setting,lmtp_proxy_rawlog_dir]] settings. +4. For lmtp, you need to use [[setting,lmtp_rawlog_dir]] and, for the + proxying connections, [[setting,lmtp_client_rawlog_dir]] inside the + [[setting,lmtp_proxy]] filter. -5. For submission, you need to use [[setting,rawlog_dir]] and - [[setting,submission_relay_rawlog_dir]] settings. +5. For submission, you need to use [[setting,rawlog_dir]] and, for the relay + connection, [[setting,smtp_client_rawlog_dir]] inside the + [[setting,submission_relay]] filter. 6. Using rawlog binary, which is executed as post-login script. This is the legacy method, which shouldn't be necessary anymore. See below. diff --git a/docs/core/config/auth/passdb.md b/docs/core/config/auth/passdb.md index c8e04040c..f6809a6f4 100644 --- a/docs/core/config/auth/passdb.md +++ b/docs/core/config/auth/passdb.md @@ -393,7 +393,8 @@ ManageSieve). It is ignored with `doveadm`, because the intention is that admin could still be able to access a disabled user via `doveadm`. [[changed,lmtp_nologin_added]] The `nologin` field prevents LMTP access now -as long as [[setting,lmtp_proxy,yes]]. However, the `reason` field is ignored. +as long as [[setting,lmtp_proxy_enabled,yes]]. However, the `reason` field is +ignored. ::: ::: info diff --git a/docs/core/config/delivery/include/delivery_common.inc b/docs/core/config/delivery/include/delivery_common.inc index 32e700bd4..bda465076 100644 --- a/docs/core/config/delivery/include/delivery_common.inc +++ b/docs/core/config/delivery/include/delivery_common.inc @@ -6,12 +6,13 @@ * [[setting,hostname]] is used in generated Message-IDs and in `Reporting-UA:` header in bounce mails -* [[setting,sendmail_path]] is used to send mails. Note that the default is - `/usr/sbin/sendmail`, which doesn't necessarily work the same as - `/usr/lib/sendmail`. +* [[setting,mail_submit]] configures how mails (bounces, Sieve redirects, etc.) + are sent. By default the `/usr/sbin/sendmail` binary is executed, which + doesn't necessarily work the same as `/usr/lib/sendmail`. - * Alternatively you can use [[setting,submission_host]] to send mails via - the specified SMTP server. + * Alternatively you can set [[setting,smtp_client_host]] inside the + [[setting,mail_submit]] filter to send mails via the specified SMTP + server. * [[setting,auth_socket_path]] specifies the UNIX socket to auth-userdb where LDA can lookup userdb information when `-d` parameter is used. diff --git a/docs/core/config/delivery/lmtp.md b/docs/core/config/delivery/lmtp.md index c4f9232de..7b3bf6a92 100644 --- a/docs/core/config/delivery/lmtp.md +++ b/docs/core/config/delivery/lmtp.md @@ -82,7 +82,21 @@ It's possible to use Dovecot LMTP server as a proxy to remote LMTP or SMTP servers. The configuration is similar to [[link,authentication_proxies]], but you'll -need to tell Dovecot LMTP to issue passdb lookups: [[setting,lmtp_proxy,yes]]. +need to tell Dovecot LMTP to issue passdb lookups: +[[setting,lmtp_proxy_enabled,yes]]. + +The connections to the backends are configured with the `lmtp_client_*` +settings inside the [[setting,lmtp_proxy]] filter. The passdb lookup +normally provides the host and optionally the port and TLS settings, so the +defaults are usually enough: + +```doveconf[dovecot.conf] +lmtp_proxy_enabled = yes +lmtp_proxy { + # Write the backend connections' protocol logs for debugging + #lmtp_client_rawlog_dir = /var/log/dovecot/lmtp-proxy-rawlog +} +``` ## Performance diff --git a/docs/core/config/sieve/submission.md b/docs/core/config/sieve/submission.md index a88f22d0c..deb3f1433 100644 --- a/docs/core/config/sieve/submission.md +++ b/docs/core/config/sieve/submission.md @@ -75,12 +75,19 @@ passdb sql { } ``` -## `submission_host` +## `mail_submit` -`submission_host = smtp-out.example.com:25` +```doveconf[dovecot.conf] +mail_submit { + smtp_client_host = smtp-out.example.com + smtp_client_port = 25 +} +``` SMTP server which is used for sending email rejects, Sieve forwards, -vacations, etc. +vacations, etc. See [[setting,mail_submit]] for the details, including how +to authenticate to the SMTP server. -Alternatively, `sendmail_path` setting can be used to send mails using the -sendmail binary. +Without [[setting,smtp_client_host]] the mails are sent using the local +sendmail binary. [[changed,settings_submission_host_renamed]] Previously this +was configured with the `submission_host` and `sendmail_path` settings. diff --git a/docs/core/config/spam_reporting.md b/docs/core/config/spam_reporting.md index 94374dfe0..40a6aae7c 100644 --- a/docs/core/config/spam_reporting.md +++ b/docs/core/config/spam_reporting.md @@ -86,7 +86,10 @@ imapsieve_from Spam { } # Needed to send message to external mail server -submission_host = 127.0.0.1:587 +mail_submit { + smtp_client_host = 127.0.0.1 + smtp_client_port = 587 +} ``` ```[/etc/dovecot/sieve/report-spam.sieve] diff --git a/docs/core/config/submission.md b/docs/core/config/submission.md index d6db603d6..0a8dfb370 100644 --- a/docs/core/config/submission.md +++ b/docs/core/config/submission.md @@ -112,6 +112,29 @@ BURL support requires a working IMAP URLAUTH implementation. See The Dovecot SMTP submission service directly proxies the mail transaction to the SMTP relay. +The connection to the relay is configured inside the +[[setting,submission_relay]] filter with the generic `smtp_client_*` +settings, the [[link,client_auth]] settings for logging into the relay and +the `ssl_client_*` settings for TLS: + +```doveconf[dovecot.conf] +submission_relay { + smtp_client_host = mta.example.com + smtp_client_port = 587 + smtp_client_ssl = starttls + # Forward the original client's IP address etc. with XCLIENT + smtp_client_peer_trusted = yes + + # Log in to the relay, using the strongest mechanism it advertises + client_auth_authzid = dovecot + client_auth_password = secret + client_auth SCRAM-SHA-256 { + } + client_auth PLAIN { + } +} +``` + #### Settings From 754b166e1d6b6fb80067d33a6953301a0c6f432e Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Wed, 21 Oct 2026 18:07:01 +0000 Subject: [PATCH 13/13] upgrade: Add the 2.4.6 SMTP client settings notes --- docs/installation/upgrade/2.4-to-2.4.x.md | 2 ++ .../include/2.4.6-smtp-client-settings.inc | 27 +++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 docs/installation/upgrade/include/2.4.6-smtp-client-settings.inc diff --git a/docs/installation/upgrade/2.4-to-2.4.x.md b/docs/installation/upgrade/2.4-to-2.4.x.md index e8fe8238d..a28272a21 100644 --- a/docs/installation/upgrade/2.4-to-2.4.x.md +++ b/docs/installation/upgrade/2.4-to-2.4.x.md @@ -195,6 +195,8 @@ INBOX namespace. + + diff --git a/docs/installation/upgrade/include/2.4.6-smtp-client-settings.inc b/docs/installation/upgrade/include/2.4.6-smtp-client-settings.inc new file mode 100644 index 000000000..1340c7a8e --- /dev/null +++ b/docs/installation/upgrade/include/2.4.6-smtp-client-settings.inc @@ -0,0 +1,27 @@ +#### SMTP Client Settings + +The outgoing SMTP and LMTP connections (submission relay, mail submission from +LDA/LMTP/Sieve, LMTP proxying) are now configured with the generic +`smtp_client_*` and `lmtp_client_*` settings inside filters, together with the +[[link,client_auth,client authentication]] and `ssl_client_*` settings. The +old names are renamed automatically as long as +[[setting,dovecot_config_version]] is older than `2.4.6`, but `doveconf` writes +the new names: + +| Old setting | New setting | +| ----------- | ----------- | +| `submission_relay_host`, `submission_relay_port`, `submission_relay_ssl`, `submission_relay_rawlog_dir`, `submission_relay_connect_timeout`, `submission_relay_command_timeout` | `submission_relay { smtp_client_host, smtp_client_port, smtp_client_ssl, smtp_client_rawlog_dir, smtp_client_connect_timeout, smtp_client_command_timeout }` | +| `submission_relay_trusted` | `submission_relay { smtp_client_peer_trusted }` | +| `submission_relay_user`, `submission_relay_master_user`, `submission_relay_password` | `submission_relay { client_auth_authzid, client_auth_authid, client_auth_password }` | +| `submission_relay_ssl_verify` | `submission_relay { ssl_client_require_valid_cert }` | +| `submission_relay_max_idle_time` | Deprecated. It never had any effect. | +| `submission_host`, `submission_ssl` | `mail_submit { smtp_client_host, smtp_client_port, smtp_client_ssl }`. The `host:port` syntax is no longer supported, the port must be set separately. | +| `submission_timeout` | `mail_submit_timeout` | +| `sendmail_path` | Deprecated. The sendmail binary is now an `execute sendmail { }` block inside `mail_submit { }`. | +| `lmtp_proxy` | `lmtp_proxy_enabled`, since `lmtp_proxy { }` is now a filter. | +| `lmtp_proxy_rawlog_dir` | `lmtp_proxy { lmtp_client_rawlog_dir }` | + + * The submission relay and the `mail_submit` SMTP connection can now use any + [[link,client_auth,client authentication]] mechanism, not only PLAIN and + LOGIN. + * A new `lmtp_local { }` filter scopes settings to local LMTP deliveries.