This is an automated email from the ASF dual-hosted git repository.

Arsnael pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit c7408253d958eba594d7d520fc36304500ec291d
Author: Felix Auringer <[email protected]>
AuthorDate: Fri May 15 10:17:48 2026 +0200

    refactor(docs): completely rewrite docs for IMAP, SMTP, LMTP, ManageSieve, 
POP3, and TLS
    
    This includes the following major corrections:
    
    IMAP:
    - `auth.requireSSL`: This does not enforce TLS for authentication with OIDC
    - `disabledCaps`: Make clear that capabilities are enabled but only not 
advertised
    - Negative values for `timeout` throw an error.
    - Option `provisionDefaultMailboxes` was undocumented.
    
    POP3:
    - Properly document `handlerchain`.
    
    ManageSieve: No major corrections.
    
    SMTP:
    - Properly document `handlerchain`.
    - `authRequired` does not enforce authentication.
    - `auth.announce` influences announcement for PLAIN/LOGIN but disables OIDC.
    - `auth.requireSSL` only disallows clear text for OIDC.
    - `disabledFeatures`: Make clear that the features are not disabled.
    - Update security recommendations and add some warnings.
    
    LMTP:
    - Properly document `handlerchain`.
    
    TLS:
    - Document all options.
    - Strongly recommend to use implicit TLS everywhere except port 25.
    - Update commands for PEM and keystore certs.
    - Add some examples for using ACME clients for proper certificates.
---
 docs/modules/servers/partials/configure/imap.adoc  | 409 +++++++++-----------
 docs/modules/servers/partials/configure/pop3.adoc  |  82 +---
 docs/modules/servers/partials/configure/sieve.adoc |  88 +----
 docs/modules/servers/partials/configure/smtp.adoc  | 425 +++++++++------------
 docs/modules/servers/partials/configure/ssl.adoc   | 422 ++++++++++++--------
 .../apache/james/imapserver/netty/IMAPServer.java  |   2 +-
 6 files changed, 661 insertions(+), 767 deletions(-)

diff --git a/docs/modules/servers/partials/configure/imap.adoc 
b/docs/modules/servers/partials/configure/imap.adoc
index b482fc6d59..daaa86acce 100644
--- a/docs/modules/servers/partials/configure/imap.adoc
+++ b/docs/modules/servers/partials/configure/imap.adoc
@@ -1,224 +1,177 @@
-Consult this link:{sample-configuration-prefix-url}/imapserver.xml[example]
-to get some examples and hints.
+Consult this link:{sample-configuration-prefix-url}/imapserver.xml[example] 
for guidance on how to configure IMAP.
 
-The IMAP4 service is controlled by a configuration block in the 
imap4server.xml.
-The imap4server tag defines the boundaries of the configuration block.  It 
encloses
-all the relevant configuration for the IMAP4 server.  The behavior of the 
IMAP4 service is
-controlled by the attributes and children of this tag.
+The IMAP service is configured in the file `imapserver.xml`.
+It contains one `imapservers` element that can contain multiple `imapserver` 
elements.
 
-This tag has an optional boolean attribute - *enabled* - that defines whether 
the service is active or not.
-The value defaults to "true" if not present.
+The `imapserver` element can be configured using the common options described 
xref:{pages-path}/configure/server.adoc[here].
+Additional settings are described below.
 
-The standard children of the imapserver tag are:
-
-.imapserver.xml content
+.`imapserver` element
 |===
-| Property name | explanation
-
-| bind
-| Configure this to bind to a specific inetaddress. This is an optional 
integer value.  This value is the port on which this IMAP4 server is configured
-to listen. If the tag or value is absent then the service
-will bind to all network interfaces for the machine If the tag or value is 
omitted, the value will default to the standard IMAP4 port
-port 143 is the well-known/IANA registered port for IMAP
-port 993 is the well-known/IANA registered port for IMAPS  ie over SSL/TLS
-
-| connectionBacklog
-| Number of connection backlog of the server (maximum number of queued 
connection requests)
-
-| compress
-| true or false - Use or don't use COMPRESS extension. Defaults to false.
-
-| maxLineLength
-| Maximal allowed line-length before a BAD response will get returned to the 
client
-This should be set with caution as a to high value can make the server a 
target for DOS (Denial of Service)!
-
-| inMemorySizeLimit
-| Optional. Size limit before we will start to stream to a temporary file.
-Defaults to 10MB. Must be a positive integer, optionally with a unit: B, K, M, 
G.
-
-| literalSizeLimit
-| Optional. Maximum size of a literal (IMAP APPEND).
-Defaults to 0 (unlimited). Must be a positive integer, optionally with a unit: 
B, K, M, G.
-
-| plainAuthDisallowed
-|  Deprecated. Should use `auth.plainAuthEnabled`, `auth.requireSSL` instead.
-Whether to enable Authentication PLAIN if the connection is not encrypted via 
SSL or STARTTLS. Defaults to `true`.
-
-| auth.plainAuthEnabled
-| Whether to enable Authentication PLAIN/ LOGIN command. Defaults to `true`.
-
-| auth.requireSSL
-| true or false. Defaults to `true`. Whether to require SSL to authenticate. 
If this is required, the IMAP server will disable authentication on unencrypted 
channels.
-
-| auth.oidc.oidcConfigurationURL
-| Provide OIDC url address for information to user. Only configure this when 
you want to authenticate IMAP server using a OIDC provider.
-
-| auth.oidc.jwksURL
-| Provide url to get OIDC's JSON Web Key Set to validate user token. Only 
configure this when you want to authenticate IMAP server using a OIDC provider.
-
-| auth.oidc.claim
-| Claim string uses to identify user. E.g: "email_address". Only configure 
this when you want to authenticate IMAP server using a OIDC provider.
-
-| auth.oidc.scope
-| An OAuth scope that is valid to access the service (RF: RFC7628). Only 
configure this when you want to authenticate IMAP server using a OIDC provider.
-
-| auth.oidc.aud
-| An OAuth audience to access the service (RF: RFC7628). Only configure this 
when you want to authenticate IMAP server using a OIDC provider.
-Compulsory but can be relaxed with `-Djames.sasl.oidc.validate.aud=false`
-
-| auth.oidc.introspection.url
-| Optional. An OAuth introspection token URL will be called to validate the 
token (RF: RFC7662).
-Note that James always verifies the signature of the token even whether this 
configuration is provided or not.
-
-| auth.oidc.introspection.auth
-| Optional. Provide Authorization in header request when introspecting token.
-Eg: `Basic xyz`
-
-| auth.oidc.userinfo.url
-| Optional. An Userinfo URL will be called to retrieve additional user 
information
-(RF: OpenId.Core https://openid.net/specs/openid-connect-core-1_0.html).
-
-| auth.adminUsers.adminUser
-| XML list of administrators able to impersonate any IMAP users. This is 
typically enable on non publicly exposed IMAP servers eg port 994 for admin 
support or migration.
-
-| timeout
-| Default to 30 minutes. After this time, inactive channels that have not 
performed read, write, or both operation for a while
-will be closed. Negative value disable this behaviour.
-
-| enableIdle
-| Default to true. If enabled IDLE commands will generate a server heartbeat 
on a regular period.
-
-| idleTimeInterval
-| Defaults to 120. Needs to be a strictly positive integer.
-
-| idleTimeIntervalUnit
-| Default to SECONDS. Needs to be a parseable TimeUnit.
+| Property Name | Explanation
+
+| `compress`
+| Enables / Disables the IMAP COMPRESS extension
+It is an optional boolean that defaults to `false`.
+
+| `maxLineLength`
+| Sets the maximal allowed line-length.
+If a request is too long, a BAD response is returned to the client.
+This should be set with caution as larger values make the server more 
susceptible for denial of service attacks.
+If OIDC is used, it must be relative large as the encoded access tokens can 
become quite large.
+It is an optional integer with a generous default of 65536.
+The default should be enough for all applications, even when using OIDC.
+
+| `inMemorySizeLimit`
+| Sets a memory limit for incoming IMAP messages.
+If a message is too large, it is streamed to a temporary file.
+It is an optional value with a default of `10M` (10 mebibytes).
+The last character of the value may be a unit.
+Supported units are `B` for bytes, `K` for kibibyte (1,024 bytes), `M` for 
mebibyte (1,024 kibibytes), and `G` for gibibyte (1,024 mebibytes).
+If no unit is given, the value is interpreted as bytes.
+
+| `literalSizeLimit`
+| Sets a hard size limit for IMAP literals and incoming IMAP messages.
+If exceeded, an exception is thrown.
+This value is communicated to the client via the IMAP APPENDLIMIT extension.
+It is optional and defaults to 0 (unlimited).
+Unit parsing is the same as with `inMemorySizeLimit` above.
+
+| `timeout`
+| Sets a timeout for connections.
+If no read or write operations have been performed in this time, the 
connection is closed.
+Optional integer in seconds that defaults to 1,800 (30 minutes).
+The timeout can not be shorter than 30 minutes.
+
+| `auth`
+| Configures user authentication.
+More details of this element are given below.
+
+| `plainAuthDisallowed`
+| Deprecated. If `auth.requireSSL` is not present, this is used as fallback.
+It is an optional boolean that defaults to `true`.
+
+| `ignoreIDLEUponProcessing`
+| Disables sending heartbeats to the client while processing its request.
+It is an optional boolean that defaults to `true`.
+
+| `disabledCaps`
+| Removes capabilities from the response of the IMAP CAPABILITY command.
+This is an optional, pipe-separated list of strings.
+By default, no capabilities are omitted.
+Note that this only removes the capabilities from the response, it does not 
disable the capabilities!
+It prevents standard-conformant clients from using commands that only work 
with the disabled capabilities but **it is not a security feature**.
+
+| `enableIdle`
+| Allows the client to request live updates via the IMAP IDLE command.
+It is an optional boolean that defaults to `true`.
+
+| `idleTimeInterval`
+| Sets the interval in which the server sends heartbeats after the client 
issued an IDLE command.
+If `enableIdle` is `false`, this has no effect.
+It is an optinal integer that defaults to 120.
+
+| `idleTimeIntervalUnit`
+| Sets the unit of `idleTimeInterval`.
+If `enableIdle` is `false`, this has no effect.
+It is an optional value which must be a parseable `TimeUnit` and defaults to 
`SECONDS`.
+
+| `maxQueueSize`
+| Sets an upper bound for the IMAP throttler queue.
+Requests that can not be queued are rejected and not executed.
+It is an optional integer that defaults to 4,096.
+A value of 0 disables the queue.
+
+| `concurrentRequests`
+| Sets the maximum number of IMAP requests that are executed simultaneously.
+All requests past that limit are queued.
+It is an optional Integer that defaults to 20.
+A negative value deactivates this feature and leads to unbounded concurrency.
+
+| `provisionDefaultMailboxes`
+| Enables the provision of additional mailboxes.
+By default, only `INBOX` is created.
+If `true`, James additionally creates the mailboxes `Outbox`, `Sent`, `Trash`, 
`Drafts`, `Archive`, and `Spam` on first login of a user.
+It is an optional boolean which defaults to `true`.
+
+| `idCommandResponse`
+| Configures the server response to the IMAP ID command.
+It is an optional element containing up to 30 `field` elements.
+Every `field` element must have the attributes `name` and `value`.
+See RFC 2971 for more details.
 
-| disabledCaps
-| Implemented server capabilities NOT to advertise to the client. Coma 
separated list. Defaults to no disabled capabilities.
-
-| jmxName
-| The name given to the configuration
-
-| tls
-| Set to true to support STARTTLS or SSL for the Socket.
-To use this you need to copy sunjce_provider.jar to /path/james/lib directory. 
To create a new keystore execute:
-`keytool -genkey -alias james -keyalg RSA -storetype PKCS12 -keystore 
/path/to/james/conf/keystore`.
-Please note that each IMAP server exposed on different port can specify its 
own keystore, independently from any other
-TLS based protocols.
-
-| handler.helloName
-| This is the name used by the server to identify itself in the IMAP4
-protocol.  If autodetect is TRUE, the server will discover its
-own host name and use that in the protocol.  If discovery fails,
-the value of 'localhost' is used.  If autodetect is FALSE, James
-will use the specified value.
-
-| connectiontimeout
-| Connection timeout in seconds
-
-| connectionLimit
-| Set the maximum simultaneous incoming connections for this service
-
-| connectionLimitPerIP
-| Set the maximum simultaneous incoming connections per IP for this service
-
-| concurrentRequests
-| Maximum number of IMAP requests executed simultaneously. Past that limit 
requests are queued. Defaults to 20.
-Negative values deactivate this feature, leading to unbounded concurrency.
-
-| maxQueueSize
-| Upper bound to the IMAP throttler queue. Upon burst, requests that cannot be 
queued are rejected and not executed.
-Integer, defaults to 4096, must be positive, 0 means no queue.
-
-| proxyRequired
-| Enables proxy support for this service for incoming connections. HAProxy's 
protocol
-(https://www.haproxy.org/download/2.7/doc/proxy-protocol.txt) is used and 
might be compatible
-with other proxies (e.g. traefik). If enabled, it is *required* to initiate 
the connection
-using HAProxy's proxy protocol.
-
-| proxyFirst
-| Whether proxy frames should be handled before SSL handshakes. This allows 
setting either the loadbalancer in TCP mode
-(so transparent for SSL then Proxy frames needs to be handled first) or set up 
SSL termination between proxy and server
-(more suited for some cloud vendors). Defaults to true (TCP transparent).
+|===
 
-| bossWorkerCount
-| Set the maximum count of boss threads. Boss threads are responsible for 
accepting incoming IMAP connections
-and initializing associated resources. Optional integer, by default, boss 
threads are not used and this responsibility is being dealt with
-by IO threads.
+== Authentication
 
-| ioWorkerCount
-| Set the maximum count of IO threads. IO threads are responsible for 
receiving incoming IMAP messages and framing them
-(split line by line). IO threads also take care of compression and SSL 
encryption. Their tasks are short-lived and non-blocking.
-Optional integer, defaults to 2 times the count of CPUs.
+The `auth` element mentioned above has the following options.
 
-| ignoreIDLEUponProcessing
-| true or false - Allow disabling the heartbeat handler. Defaults to true.
+.`auth` element
+|===
+| Property Name | Explanation
 
-| useEpoll
-| true or false - If true uses native EPOLL implementation for Netty otherwise 
uses NIO. Defaults to false.
+| `auth.plainAuthEnabled`
+| Enables the authentication mechanisms `PLAIN` and `LOGIN`.
+It is an optional boolean that defaults to `true`.
 
-| gracefulShutdown
-| true or false - If true attempts a graceful shutdown, which is safer but can 
take time. Defaults to true.
+| `auth.requireSSL`
+| Configures whether the authentication mechanisms `PLAIN` and `LOGIN` require 
a secure connection (TLS or STARTTLS).
+It has no effect on other authentication mechanisms.
+It also has no effect if `plainAuthEnabled` is `false`.
+The value is optional.
+If not configured, it uses the value of `plainAuthDisallowed` (which defaults 
to `true`) as fallback.
 
-| highWriteBufferWaterMark
-| Netty's write buffer high watermark configuration. Unit supported: none, K, 
M. Netty defaults applied.
+| `auth.adminUsers`
+| Configures admin users that are authorized to impersonate any IMAP user.
+It is an optional element containing `adminUser` elements.
+**Do not configure this for publicly exposed IMAP servers!**
 
-| lowWriteBufferWaterMark
-| Netty's write buffer low watermark configuration. Unit supported: none, K, 
M. Netty defaults applied.
+| `auth.oidc`
+| Configures authentication via OIDC.
+The configuration is described in more detail 
xref:{pages-path}/configure/oidc.adoc[here].
 
-| idCommandResponse.field
-| Store the fields response for ID Command, with each tag containing a 
name-value pair corresponding to the attribute name. Ref: rfc2971
 |===
 
-== OIDC setup
-James IMAP support XOAUTH2 authentication mechanism which allow authenticating 
against a OIDC providers.
-Please configure `auth.oidc` part to use this.
-
-We do supply an 
link:https://github.com/apache/james-project/tree/master/examples/oidc[example] 
of such a setup.
-It uses the Keycloak OIDC provider, but usage of similar technologies is 
definitely doable.
-
 == Traffic Shaping
 
-James ships an optional 
link:https://netty.io/4.0/api/io/netty/handler/traffic/ChannelTrafficShapingHandler.html[Netty
 built in Traffic Shaping] that can be optionally configured.
+Including a `trafficShaping` element enables an optional 
link:https://netty.io/4.0/api/io/netty/handler/traffic/ChannelTrafficShapingHandler.html[Netty
 traffic shaping handler].
+This adds the following functionality:
 
-This enables both:
- - Record per channel bandwidth consumption
- - Allows defining per channel bandwidth limit, which helps at fairness and 
maintaining a good quality of service in terms of incoming/outgoing bandwidth.
+- Recording per channel bandwidth consumption.
+- Defining per channel bandwidth limit. This helps maintaining fairness and a 
good quality of service.
 
 Example:
 
 [source,xml]
 ----
-    <imapserver>
-        <!-- ... -->
-        <trafficShaping>
-            <writeTrafficPerSecond>0</writeTrafficPerSecond>
-            <readTrafficPerSecond>0</readTrafficPerSecond>
-            <checkInterval>1000</checkInterval>
-            <maxDelays>15000</maxDelays>
-        </trafficShaping>
-    </imapserver>
+<imapserver>
+    <!-- ... -->
+    <trafficShaping>
+        <writeTrafficPerSecond>0</writeTrafficPerSecond>
+        <readTrafficPerSecond>0</readTrafficPerSecond>
+        <checkInterval>1000</checkInterval>
+        <maxDelays>15000</maxDelays>
+    </trafficShaping>
+</imapserver>
 ----
 
-Those tags maps to the corresponding Netty argument.
-
-If omitted no traffic handle is added to the channel pipeline.
+All inner elements are optional.
+The example above shows the default values.
+The values are directly used for the instantiation of 
`io.netty.handler.traffic.ChannelTrafficShapingHandler`.
 
-== IMAP command throttler
+== Command Throttler
 
-James ships an optional IMAP command throttler aimed at slowing down 
lower-quality clients that generate a high
-volume of requests. It allows per command granularity and is applied at the 
scope of an IMAP session.
+James ships an optional IMAP command throttler aimed at slowing down 
lower-quality clients that generate a high volume of requests.
+It allows a different configuration for every command and is applied at the 
scope of an IMAP session.
+The throttler is enabled by including a `perSessionCommandThrottling` element 
in the configuration.
 
-The user can declare the list of commands on which throttling needs to be 
tracked and for each:
+For every command, the following configurations are available.
 
- - `thresholdCount`: below this number of occurrence, no throttling is 
applied. Integer.
- - `additionalDelayPerOperation`: delay to be applied when exceeding the 
threshold. The delay is cumulative and thus
- would always increase. Duration.
- - `observationPeriod`: the count of observed commands is reset after this 
period thus stopping delays. Duration.
- - `maxDelay`: maximum value the client will be delayed for.
-- `resetOn`: String. Optional default to none. Needs to be a command name. If 
specified, this command name will reset
-throttling on this specific entry.
+- `thresholdCount`: Throttling is enabled after the client issued the command 
`thresholdCount` number of times. It is a mandatory integer.
+- `additionalDelayPerOperation`: After the threshold above has been reached, a 
delay is introduced. It is calculated as the number of previous occurrences of 
the command times `additionalDelayPerOperation`. This means that with a 
threshold of 25 and a delay of 2ms, the 26th occurrence of the command has a 
delay of 50ms. It is a mandatory duration with unit. The unit should be `ms` 
(millisecond) or `s` (second) in most cases.
+- `observationPeriod`: After this time, the counter for the command is reset. 
This removes the delay. It is a mandatory duration with unit. The unit should 
be `s` (second) or `m` (minute) in most cases.
+- `maxDelay`: The maximum delay for the command. It is a mandatory duration 
with unit. The unit should be `ms` (millisecond) or `s` (second) in most cases.
+- `resetOn`: An different IMAP command that resets counter and delay for the 
command. It is an optional string. By default, no IMAP command triggers a reset.
 
 Sample configuration:
 
@@ -232,7 +185,7 @@ Sample configuration:
       <additionalDelayPerOperation>2ms</additionalDelayPerOperation>
       <observationPeriod>10m</observationPeriod>
       <maxDelay>1s</maxDelay>
-      <resetOn>APPEND</resetOn> <!-- Helps mitigate delays in Outlook upon 
sending email: a full refresh is needed for the operation to complete -->
+      <resetOn>APPEND</resetOn> <!-- Allows a full refresh after sending an 
email. -->
     </select>
     <append>
       <thresholdCount>5</thresholdCount>
@@ -244,50 +197,64 @@ Sample configuration:
 </imapserver>
 ----
 
-Note that commands are delayed prior the execution and thus are not subject to 
the IMAP upper concurrency limit until
-they are executed.
+Note that commands are delayed prior to their execution and thus are not 
subject to the setting `concurrentRequests` until they are executed.
 
 == Extending IMAP
 
-IMAP decoders, processors and encoder can be customized. 
xref:{pages-path}/customization/imap.adoc[Read more].
-
-Check this 
link:https://github.com/apache/james-project/tree/master/examples/custom-imap[example].
+IMAP decoders, processors and encoders can be customized.
+You can xref:{pages-path}/customization/imap.adoc[read more here].
 
 The following configuration properties are available for extensions:
 
-.imapserver.xml content
+.`imapserver` element
 |===
-| Property name | explanation
+| Property Name | Explanation
+
+| `imapPackages`
+| Configures which packages to load for IMAP.
+IMAP packages bundle decoders (IMAP command parsing), command processors, and 
encoders.
+The setting is optional and defaults to 
`org.apache.James.modules.protocols.DefaultImapPackage`.
+The element must contain a Java classpath and can appear multiple times.
+If configured, the union of all packages is used.
+Remember to include `DefaultImapPackage` if you want to use its functionality.
+
+| `additionalConnectionChecks`
+| Configures an additional connection check.
+A connection check decides whether the client IP of a connection is secure.
+It must contain a Java classpath.
+This element can be used multiple times.
+
+| `customProperties`
+| This element can be used to set an arbitrary property.
+The value must have the form `key=value`.
+This element can be used multiple times.
+Using this enables configuring custom IMAP extensions without touching the 
code responsible for loading the configuration.
 
-| imapPackages
-| Configure (union) of IMAP packages. IMAP packages bundles decoders (parsing 
IMAP commands) processors and encoders,
-thus enable implementing new IMAP commands or replace existing IMAP 
processors. List of FQDNs, which can be located in
-James extensions.
-
-| additionalConnectionChecks
-| Configure (union) of additional connection checks. ConnectionCheck will 
check if the connection IP is secure or not.
-| customProperties
-| Properties for custom extension. Each tag is a property entry, and holds a 
string under the form key=value.
 |===
 
-== Mail user agents auto-configuration
+== Auto-Configuration for Mail User Agents
 
-Check this example on 
link:https://github.com/apache/james-project/tree/master/examples/imap-autoconf[Mail
 user agents auto-configuration].
+Check 
link:https://github.com/apache/james-project/tree/master/examples/imap-autoconf[this
 example] for the auto-configuration of mail user agents.
 
-== Local cache for partial Fetch
+== Local Cache for Partial Fetch
 
-Because some clients uses partial fetch in order to emulate retriable download 
of individual body parts
-we offer a way for James to cache in the IMAP session the latest partially 
fetched message. This is done using
-a weak reference, a total size dedicated to the cache as well as a time to 
leave cache cleanup, all of this
-being configurable.
+Some clients use partial fetch in order to emulate retriable downloads of 
individual body parts.
+Therefore, we offer a way for James to cache the latest partially fetched 
message in the IMAP session.
+This is done using a weak reference.
 
-Example:
+The following configuration options are available.
+
+- `partialBodyFetchCacheEnabled`: Enables the cache. It is an optional boolean 
that defaults to `false`.
+- `partialBodyFetchCacheDuration`: Configures how long partial bodies are 
cached. It is an optional integer with an optional unit. The default value is 2 
minutes and the default unit is minute. The unit should be `s` (second) or `m` 
(minute) in most cases.
+- `partialBodyFetchCacheSize`: Sets the size of the cache. It is an optional 
integer with an optional unit. The default value is 500 mebibyte and the 
default unit is byte. The unit should be `MiB` (mebibyte) or `GiB` (gibibyte) 
in most cases.
+
+Example with the default values:
 
 [source,xml]
 ----
 <imapserver>
-  <partialBodyFetchCacheEnabled>true</partialBodyFetchCacheEnabled>
-  <partialBodyFetchCacheDuration>2min</partialBodyFetchCacheDuration>
-  <partialBodyFetchCacheSize>500 MiB</partialBodyFetchCacheSize>
+  <partialBodyFetchCacheEnabled>false</partialBodyFetchCacheEnabled>
+  <partialBodyFetchCacheDuration>2m</partialBodyFetchCacheDuration>
+  <partialBodyFetchCacheSize>500MiB</partialBodyFetchCacheSize>
 </imapserver>
-----
\ No newline at end of file
+----
diff --git a/docs/modules/servers/partials/configure/pop3.adoc 
b/docs/modules/servers/partials/configure/pop3.adoc
index dc01589791..9987551795 100644
--- a/docs/modules/servers/partials/configure/pop3.adoc
+++ b/docs/modules/servers/partials/configure/pop3.adoc
@@ -1,74 +1,18 @@
-Consult this link:{sample-configuration-prefix-url}/pop3server.xml[example]
-to get some examples and hints.
+Consult this link:{sample-configuration-prefix-url}/pop3server.xml[example] 
for guidance on how to configure POP3.
 
-The POP3 service is controlled by a configuration block in the pop3server.xml.
-The pop3server tag defines the boundaries of the configuration block.  It 
encloses
-all the relevant configuration for the POP3 server.  The behavior of the POP 
service is
-controlled by the attributes and children of this tag.
+The POP3 service is configured in the file `pop3server.xml`.
+It contains one `pop3servers` element that can contain multiple `pop3server` 
elements.
 
-This tag has an optional boolean attribute - *enabled* - that defines whether 
the service is active or not.
-The value defaults to "true" if not present.
+The `pop3server` element can be configured using the common options described 
xref:{pages-path}/configure/server.adoc[here].
 
-The standard children of the pop3server tag are:
+Additionally, it contains a mandatory `handlerchain` element that configures 
the behavior of the server using handlers.
+The `handlerchain` element has the following optional attributes:
 
-.jmx.properties content
-|===
-| Property name | explanation
+- `coreHandlersPackage` is a string specifying a handler loader. All handlers 
of this loader are added to the end of the handlerchain. The default is 
`org.apache.james.pop3server.core.CoreCmdHandlerLoader`.
+- `enableJmx` enables the JMX for this server. It is a boolean which is `true` 
by default.
+- `jmxHandlersPackage` is a string specifying a handler loader for JMX. All 
handlers of this loader are added to the handlerchain after the core handlers. 
The default is `org.apache.james.pop3server.jmx.JMXHandlersLoader`. It only has 
an effect if `enableJmx` is `true`.
 
-| bind
-| Configure this to bind to a specific inetaddress. This is an optional 
integer value.
-This value is the port on which this POP3 server is configured
-to listen. If the tag or value is absent then the service
-will bind to all network interfaces for the machine If the tag or value is 
omitted,
-the value will default to the standard POP3 port, 11
-port 995 is the well-known/IANA registered port for POP3S  ie over SSL/TLS
-port 110 is the well-known/IANA registered port for Standard POP3
-
-| connectionBacklog
-|
-
-| tls
-| Set to true to support STARTTLS or SSL for the Socket.
-To create a new keystore execute:
-`keytool -genkey -alias james -keyalg RSA -storetype PKCS12 -keystore 
/path/to/james/conf/keystore`
-Please note that each POP3 server exposed on different port can specify its 
own keystore, independently from any other
-TLS based protocols. Read xref:{pages-path}/configure/ssl.adoc[SSL 
configuration page] for more information.
-
-| handler.helloName
-| This is the name used by the server to identify itself in the POP3
-protocol.  If autodetect is TRUE, the server will discover its
-own host name and use that in the protocol.  If discovery fails,
-the value of 'localhost' is used.  If autodetect is FALSE, James
-will use the specified value.
-
-| handler.connectiontimeout
-| Connection timeout in seconds
-
-| handler.connectionLimit
-| Set the maximum simultaneous incoming connections for this service
-
-| handler.connectionLimitPerIP
-| Set the maximum simultaneous incoming connections per IP for this service
-
-| handler.handlerchain
-| This loads the core CommandHandlers. Only remove this if you really know 
what you are doing.
-
-| bossWorkerCount
-| Set the maximum count of boss threads. Boss threads are responsible for 
accepting incoming POP3 connections
-and initializing associated resources. Optional integer, by default, boss 
threads are not used and this responsibility is being dealt with
-by IO threads.
-
-| ioWorkerCount
-| Set the maximum count of IO threads. IO threads are responsible for 
receiving incoming POP3 messages and framing them
-(split line by line). IO threads also take care of compression and SSL 
encryption. Their tasks are short-lived and non-blocking.
-Optional integer, defaults to 2 times the count of CPUs.
-
-| maxExecutorCount
-| Set the maximum count of worker threads. Worker threads takes care of 
potentially blocking tasks like executing POP3 requests. Optional integer, 
defaults to 16.
-
-| useEpoll
-| true or false - If true uses native EPOLL implementation for Netty otherwise 
uses NIO. Defaults to false.
-
-| gracefulShutdown
-| true or false - If true attempts a graceful shutdown, which is safer but can 
take time. Defaults to true.
-|===
\ No newline at end of file
+The `handlerchain` element may contain an arbitrary number of `handler` 
elements.
+Every `handler` element must have the string attribute `class`.
+They are inserted in order at the beginning of the handlerchain.
+The handlers of the `coreHandlersPackage` or `jmxHandlersPackage` do not need 
their own `handler` elements.
diff --git a/docs/modules/servers/partials/configure/sieve.adoc 
b/docs/modules/servers/partials/configure/sieve.adoc
index 25f2219aff..47e62761b5 100644
--- a/docs/modules/servers/partials/configure/sieve.adoc
+++ b/docs/modules/servers/partials/configure/sieve.adoc
@@ -19,7 +19,7 @@ The following Sieve capabilities are supported by Apache 
James:
 To be correctly executed, please note that the *Sieve* mailet is required to 
be positioned prior the
 *LocalDelivery* mailet.
 
-== Managing Sieve scripts
+== Managing Sieve Scripts
 
 A user willing to manage his Sieve scripts on the server can do so via several 
means:
 
@@ -28,86 +28,16 @@ He can ask an admin to upload his script via the 
xref:{pages-path}/operate/cli.a
 As James supports ManageSieve 
(link:https://datatracker.ietf.org/doc/html/rfc5804[RFC-5804]) a user
 can thus use compatible software to manage his Sieve scripts.</p>
 
-== ManageSieve protocol
+== ManageSieve Protocol
 
-*WARNING*: ManageSieve protocol should be considered experimental.
+*WARNING*: Support for the ManageSieve protocol should be considered 
experimental.
 
-Consult 
link:{sample-configuration-prefix-url}/managesieveserver.xml[managesieveserver.xml]
-in GIT to get some examples and hints.
+Consult this 
link:{sample-configuration-prefix-url}/managesieveserver.xml[example] for 
guidance on how to configure ManageSieve.
 
-The  service is controlled by a configuration block in the 
managesieveserver.xml.
-The managesieveserver tag defines the boundaries of the configuration block.  
It encloses
-all the relevant configuration for the ManageSieve server.  The behavior of 
the ManageSieve service is
-controlled by the attributes and children of this tag.
+The ManageSieve service is configured in the file `managesieveserver.xml`.
+It contains one `managesieveservers` element that can contain multiple 
`managesieveserver` elements.
 
-This tag has an optional boolean attribute - *enabled* - that defines whether 
the service is active or not.
-The value defaults to "false" if
-not present.
+The `managesieveserver` element can be configured using the common options 
described xref:{pages-path}/configure/server.adoc[here].
 
-The standard children of the managesieveserver tag are:
-
-.managesieveserver.xml content
-|===
-| Property name | explanation
-
-| bind
-| Configure this to bind to a specific inetaddress. This is an optional 
integer value.  This value is the port on which this ManageSieve server is 
configured to listen. If the tag or value is absent then the service
-will bind to all network interfaces for the machine If the tag or value is 
omitted, the value will default to the standard ManageSieve port (port 4190 is 
the well-known/IANA registered port for ManageSieve.)
-
-| tls
-| Set to true to support STARTTLS or SSL for the Socket.
-To use this you need to copy sunjce_provider.jar to /path/james/lib directory. 
To create a new keystore execute:
-`keytool -genkey -alias james -keyalg RSA -storetype PKCS12 -keystore 
/path/to/james/conf/keystore`.
-Please note that each ManageSieve server exposed on different port can specify 
its own keystore, independently from any other
-TLS based protocols.
-
-| connectionBacklog
-| Number of connection backlog of the server (maximum number of queued 
connection requests)
-
-| connectiontimeout
-| Connection timeout in seconds
-
-| connectionLimit
-| Set the maximum simultaneous incoming connections for this service
-
-| connectionLimitPerIP
-| Set the maximum simultaneous incoming connections per IP for this service
-
-| bossWorkerCount
-| Set the maximum count of boss threads. Boss threads are responsible for 
accepting incoming ManageSieve connections
-and initializing associated resources. Optional integer, by default, boss 
threads are not used and this responsibility is being dealt with
-by IO threads.
-
-| ioWorkerCount
-| Set the maximum count of IO threads. IO threads are responsible for 
receiving incoming ManageSieve messages and framing them
-(split line by line). IO threads also take care of compression and SSL 
encryption. Their tasks are short-lived and non-blocking.
-Optional integer, defaults to 2 times the count of CPUs.
-
-| maxExecutorCount
-| Set the maximum count of worker threads. Worker threads takes care of 
potentially blocking tasks like executing ManageSieve commands.
-Optional integer, defaults to 16.
-
-| oidc
-| If this property is present, OIDC will be configured and the following 
properties are mandatory (unless otherwise specified).
-
-| oidc.oidcConfigurationURL
-| Your identity provider's OIDC discovery URL. This is currently not used for 
managesieve but is still required when OIDC is configured.
-
-| oidc.jwksURL
-| URL to the endpoint for the JSON Web Key Set of your provider. This is used 
to locally validate tokens.
-
-| oidc.claim
-| Name of the claim in the token you want to use as the identifier for the 
user (e.g. "email_address").
-
-| oidc.scope
-| OIDC scope. This is currently not used for managesieve but is still required 
when OIDC is configured.
-
-| oidc.introspection.url
-| URL to your identity provider's introspection endpoint. It is optional and 
if specified James will use the endpoint to validate the token in addition to 
local validation.
-
-| oidc.introspection.auth
-| Provide Authorization header for introspection requests (optional, e.g. 
`Basic xyz`).
-
-| oidc.userinfo.url
-| URL to your identity provider's userinfo endpoint. It is optional and if 
specified James will use the endpoint to validate the token in addition to 
local validation. James will ignore this option if `oidc.introspection.url` is 
already configured.
-|===
+Additionally, it can contain an optional `oidc` element.
+The OIDC configuration is described 
xref:{pages-path}/configure/oidc.adoc[here].
diff --git a/docs/modules/servers/partials/configure/smtp.adoc 
b/docs/modules/servers/partials/configure/smtp.adoc
index 5c794bacdf..c5da1dffa9 100644
--- a/docs/modules/servers/partials/configure/smtp.adoc
+++ b/docs/modules/servers/partials/configure/smtp.adoc
@@ -1,333 +1,290 @@
-== Incoming SMTP
+Consult this link:{sample-configuration-prefix-url}/smtpserver.xml[example] 
for guidance on how to configure SMTP.
 
-Consult this link:{sample-configuration-prefix-url}/smtpserver.xml[example]
-to get some examples and hints.
+The SMTP service is configured in the file `smtpserver.xml`.
+It contains one `smtpservers` element that can contain multiple `smtpserver` 
elements.
 
-The SMTP service is controlled by a configuration block in the smptserver.xml.
-The smtpserver tag defines the boundaries of the configuration block.  It 
encloses
-all the relevant configuration for the SMTP server. The behavior of the SMTP 
service is
-controlled by the attributes and children of this tag.
+The `smtpserver` element can be configured using the common options described 
xref:{pages-path}/configure/server.adoc[here].
+Additional settings are described below.
 
-This tag has an optional boolean attribute - *enabled* - that defines whether 
the service is active or not.  The value defaults to "true" if
-not present.
-
-The standard children of the smtpserver tag are:
-
-.smtpserver.xml content
+.`smtpserver` element
 |===
-| Property name | explanation
-
-| bind
-| A list of address:port separed by comma - This is an optional value.  If 
present, this value is a string describing
-the IP address to which this service should be bound.  If the tag or value is 
absent then the service
-will bind to all network interfaces for the machine on port 25. Port 25 is the 
well-known/IANA registered port for SMTP.
-Port 465 is the well-known/IANA registered port for SMTP over TLS.
-
-| connectBacklog
-|The IP address (host name) the MBean Server will bind/listen to.
+| Property Name | Explanation
 
-| tls
-| Set to true to support STARTTLS or SSL for the Socket.
-To use this you need to copy sunjce_provider.jar to /path/james/lib directory. 
To create a new keystore execute:
-`keytool -genkey -alias james -keyalg RSA -storetype PKCS12 -keystore 
/path/to/james/conf/keystore`.
-The algorithm is optional and only needs to be specified when using something 
other
-than the Sun JCE provider - You could use IbmX509 with IBM Java runtime.
-Please note that each SMTP/LMTP server exposed on different port can specify 
its own keystore, independently from any other
-TLS based protocols.
+| `auth`
+| Configures user authentication.
+More details of this element are given below.
 
-| helloName
-| This is a required tag with an optional body that defines the server name
-used in the initial service greeting.  The tag may have an optional attribute 
- *autodetect*.  If
-the autodetect attribute is present and true, the service will use the local 
hostname
-returned by the Java libraries.  If autodetect is absent or false, the body of 
the tag will be used.  In
-this case, if nobody is present, the value "localhost" will be used.
+| `authRequired`
+a| Deprecated. If `auth.announce` is not present, this is used as fallback.
+It is an optional string that defaults to `false`.
 
-| connectionTimeout
-| This is an optional tag with a non-negative integer body. Connection timeout 
in seconds.
+Its value is mapped to the allowed values for `auth.announce` (`always`, 
`never`, and `forUnauthorizedAddresses`) as described below.
 
-| connectionLimit
-| Set the maximum simultaneous incoming connections for this service.
+- `true` maps to `forUnauthorizedAddresses`.
+- `announce` maps to `always`.
+- All other values (including the default `false`) map to `never`.
 
-| connectionLimitPerIP
-| Set the maximum simultaneous incoming connections per IP for this service.
+| `authorizedAddresses`
+| Configures IP networks that are considered trustworthy.
+Normally, clients are only authorized to relay emails after a successful SMTP 
AUTH command.
+If the remote IP of a connection is included in one of these networks, the 
client is authorized to relay without authentication.
+It is an optional list separated by ``, `` (note the space).
 
-| proxyRequired
-| Enables proxy support for this service for incoming connections. HAProxy's 
protocol
-(https://www.haproxy.org/download/2.7/doc/proxy-protocol.txt) is used and 
might be compatible
-with other proxies (e.g. traefik). If enabled, it is *required* to initiate 
the connection
-using HAProxy's proxy protocol.
+**We strongly recommend to omit this element!**
+Caution is especially required if James is behind a reverse proxy.
+In that case, it is essential that PROXY protocol is used so that James sees 
the real client IP and not some internal IP that might be included in the 
`authorizedAddresses`.
 
-| proxyFirst
-| Whether proxy frames should be handled before SSL handshakes. This allows 
setting either the loadbalancer in TCP mode
-(so transparent for SSL then Proxy frames needs to be handled first) or set up 
SSL termination between proxy and server
-(more suited for some cloud vendors). Defaults to true (TCP transparent).
+Networks may be specified as IP address or domain name, with an optional 
netmask.
+`127.*`, `127.0.0.0/8`, `127.0.0.0/255.0.0.0`, and `localhost/8` are 
equivalent values that can all be parsed.
+See `org.apache.james.dnsservice.library.inetnetwork` for more details.
 
-| authRequired
-| (deprecated) use auth.announce instead.
+Also see the `RemoteAddrNotInNetwork` matcher in the transport processor.
+You would generally use one **or** the other approach.
 
-This is an optional tag with a boolean body.  If true, then the server will
-announce authentication after HELO command.  If this tag is absent, or the 
value
-is false then the client will not be prompted for authentication.  Only simple 
user/password authentication is
-supported at this time. Supported values:
+| `maxmessagesize`
+| Configures the maximum size of SMTP messages the server will accept.
+If it is set to 0, no limit will be imposed.
+Any value larger than 0 will enable the SMTP SIZE extension (RFC 1870) and 
enforce the limit.
 
- * true: announced only to not authorizedAddresses
+It is an optional integer which defaults to 0.
+The last character of the value may be a unit.
+Supported units are `B` for bytes, `K` for kibibyte (1,024 bytes), `M` for 
mebibyte (1,024 kibibytes), and `G` for gibibyte (1,024 mebibytes).
+If no unit is given, the value is interpreted as kibibytes.
 
- * false: don't announce AUTH. If absent, *authorizedAddresses* are set to a 
wildcard to accept all remote hosts.
+| `heloEhloEnforcement`
+| Configures whether to enforce the use of the HELO / EHLO salutation before a 
MAIL command is accepted.
+It is an optional boolean that defaults to `true`.
 
- * announce: like true, but always announce AUTH capability to clients
+| `smtpGreeting`
+| Sets the greeting which the server sends when a client connects.
+It is an optional string.
+If not configured, a greeting is constructed from the server `helloName`.
 
-Please note that emails are only relayed if, and only if, the user did 
authenticate, or is in an authorized network,
-regardless of this option.
+| `addressBracketsEnforcement`
+| Enforces that addresses in the MAIL and RCPT commands are enclosed in `<` 
and `>` as required by RFC 5321.
+It is an optional boolean which defaults to `true`.
 
-| auth.announce
-| This is an optional tag.  Possible values are:
+| `verifyIdentity`
+a| Configures how the identity in the MAIL command is verified for local users.
 
-* never: Don't announce auth.
+This is an optional string with the following possible values.
 
-* always: always announce AUTH capability to clients.
+- `strict`: If the email used in the MAIL command has a local domain, 
authentication is required. Verification succeeds if the authenticated user's 
email address or one of its aliases matches the sender address in the MAIL 
command. It prevents spoofing local email addresses on this server. Spoofing of 
external email addresses when sending to local users can not be prevented. For 
backward compatibility, `true` has the same effect as `strict`.
+- `disabled`: The sender address is not verified. However, authentication is 
still required for relaying. This allows spoofing local email addresses on this 
server. External users can send emails to local users as any local user. 
Authenticated local users can send emails to local and external users as any 
local user. For backward compatibility, `false` has the same effect as 
`disabled`.
+- `relaxed`: If the user is authenticated, this acts like `strict`. If the 
sender is local and not authenticated, a simple heuristic decides whether the 
sender is accepted. The heuristic categorizes a client that uses a valid domain 
in its EHLO command as a MX and as a MUA otherwise. Authentication is only 
required for MUAs, not for MXs. Note that this heuristic **can easily be 
circumvented**. See 
link:https://issues.apache.org/jira/browse/JAMES-4032[JAMES-4032] for the 
reasoning behind  [...]
 
-* forUnauthorizedAddresses: announced only to not authorizedAddresses
+The default value is `strict`.
+**Changing it always decreases the security** and should only be done if 
absolutely necessary.
 
-Please note that emails are only relayed if, and only if, the user did 
authenticate, or is in an authorized network,
-regardless of this option.
+| `handlerchain`
+a| Configures the behavior of the server using handlers.
+The `handlerchain` element has the following optional attributes:
 
-| auth.requireSSL
-| This is an optional tag, defaults to true. If true, authentication is not 
advertised via capabilities on unencrypted
-channels.
+- `coreHandlersPackage` is a string specifying a handler loader. All handlers 
of this loader are added to the end of the handlerchain. The default is 
`org.apache.james.smtpserver.CoreCmdHandlerLoader`.
+- `enableJmx` enables the JMX for this server. It is a boolean which is `true` 
by default.
+- `jmxHandlersPackage` is a string specifying a handler loader for JMX. All 
handlers of this loader are added to the handlerchain after the core handlers. 
The default is `org.apache.james.smtpserver.jmx.JMXHandlersLoader`. It only has 
an effect if `enableJmx` is `true`.
 
-| auth.plainAuthEnabled
-| This is an optional tag, defaults to true. If false, AUTH PLAIN and AUTH 
LOGIN will not be exposed. This setting
-can be used to enforce strong authentication mechanisms.
+The `handlerchain` element may contain an arbitrary number of `handler` 
elements.
+Every `handler` element must have the string attribute `class`.
+They are inserted in order at the beginning of the handlerchain.
+The handlers of the `coreHandlersPackage` or `jmxHandlersPackage` do not need 
their own `handler` elements.
 
-| auth.required
-| Authentication is required to send emails. Adapted for submission ports.
+See xref:{pages-path}/configure/smtp-hooks.adoc[this page] for a list of 
handlers that are included in James.
 
-Note that if false (legacy value and default for backward compatibility) then 
unauthenticated senders are allowed but
-limited by sender verification (prevent spoofing) and relaying limits (must be 
authenticated to relay).
+| `disabledFeatures`
+| Removes features from the feature announcement sent to clients after their 
EHLO.
+The element may be omitted or appear multiple times.
+Every occurrence must contain exactly one feature.
+By default, no features are omitted.
 
-We encourage setting this value to true on submission ports (465 + 587). MUST 
be set to false on port 25 or for any port with MX external mail receival role.
+Note that this only removes the features from the announcement, it does not 
disable the features!
+It prevents standard-conformant clients from using commands that only work 
with the disabled features but **it is not a security feature**.
 
-Please note that `authorizedAddresses` are considered authenticated.
-
-| auth.oidc.oidcConfigurationURL
-| Provide OIDC url address for information to user. Only configure this when 
you want to authenticate SMTP server using a OIDC provider.
-
-| auth.oidc.jwksURL
-| Provide url to get OIDC's JSON Web Key Set to validate user token. Only 
configure this when you want to authenticate SMTP server using a OIDC provider.
+|===
 
-| auth.oidc.claim
-| Claim string uses to identify user. E.g: "email_address". Only configure 
this when you want to authenticate SMTP server using a OIDC provider.
+== Authentication
 
-| auth.oidc.scope
-| An OAuth scope that is valid to access the service (RF: RFC7628). Only 
configure this when you want to authenticate SMTP server using a OIDC provider.
+The `auth` element mentioned above has the following options.
 
-| auth.oidc.aud
-| An OAuth audience to access the service (RF: RFC7628). Only configure this 
when you want to authenticate IMAP server using a OIDC provider.
-Compulsory but can be relaxed with `-Djames.sasl.oidc.validate.aud=false`
+.`auth` element
+|===
+| Property Name | Explanation
 
-| auth.oidc.introspection.url
-| Optional. An OAuth introspection token URL will be called to validate the 
token (RF: RFC7662).
-Note that James always verifies the signature of the token even whether this 
configuration is provided or not.
+| `auth.announce`
+a| Configures when to announce authentication to the client.
+This is an optional string with the following possible values:
 
-| auth.oidc.introspection.auth
-| Optional. Provide Authorization in header request when introspecting token.
-Eg: `Basic xyz`
+- `never`: Do not announce authentication capabilities.
+- `always`: Always announce authentication capabilities.
+- `forUnauthorizedAddresses`: Announce authentication capabilities only to 
clients which are not in `authorizedAddresses`.
 
-| auth.oidc.userinfo.url
-| Optional. An Userinfo URL will be called to retrieve additional user 
information
-(RF: OpenId.Core https://openid.net/specs/openid-connect-core-1_0.html).
+If not configured, it uses the value of `authRequired` (of which the default 
maps to `never`) as fallback.
 
-| authorizedAddresses
-| Authorize specific addresses/networks.
+Note that this configures only the **announcement** of authentication 
capabilities.
+`auth.requireSSL` also has an influence on whether authentication capabilities 
are announced.
 
-If you use SMTP AUTH, addresses that match those specified here will
-be permitted to relay without SMTP AUTH.  If you do not use SMTP
-AUTH, and you specify addresses here, then only addresses that match
-those specified will be permitted to relay.
+Even if authentication capabilities are not announced, clients can still use 
the SMTP AUTH command.
+However, if authentication capabilities are not announced, only the mechanisms 
`PLAIN` and `LOGIN` are available.
+`XOAUTH2` and `OAUTHBEARER` are disabled if authentication capabilities are 
not announced.
 
-Addresses may be specified as a IP address or domain name, with an
-optional netmask, e.g.,
+| `auth.requireSSL`
+| Configures whether announcing authentication capabilities requires a secure 
connection (TLS or STARTTLS).
+If this value is `true` and the connection is not secure, authentication 
capabilities are not announced.
+This always holds, even if `auth.announce` is set to `always`.
 
-127.*, 127.0.0.0/8, 127.0.0.0/255.0.0.0, and localhost/8 are all the same
+It is an optional boolean that defaults to `true`.
 
-See also the RemoteAddrNotInNetwork matcher in the transport processor.
-You would generally use one OR the other approach.
+Note that this configures only the **announcement** of authentication 
capabilities.
+Even if authentication capabilities are not announced, clients can still use 
the SMTP AUTH command with the mechanisms `PLAIN` and `LOGIN`.
+However, as the mechanisms `XOAUTH2` and `OAUTHBEARER` are only available if 
authentication mechanisms are announced, those mechanisms can only be used in 
secure connections if `auth.requireSSL` is set to `true`.
 
-| verifyIdentity
-| This is an optional tag. This options governs MAIL FROM verifications, and 
prevents spoofing of the MAIL FROM
-envelop field.
+| `auth.plainAuthEnabled`
+| Enables the authentication mechanisms `PLAIN` and `LOGIN`.
+It is an optional boolean that defaults to `true`.
 
-The following values are supported:
+| `auth.oidc`
+| Configures authentication via OIDC.
+The configuration is described in more detail 
xref:{pages-path}/configure/oidc.adoc[here].
 
- - `strict`: use of a local domain in MAIL FROM requires the SMTP client to be 
authenticated with a matching user or one
- of its aliases. It will verify that the sender address matches the address of 
the user or one of its alias (from user or domain aliases).
- This prevents a user of your mail server from acting as someone else
- - `disabled`: no check is performed and third party are free to send emails 
as local users. Note that relaying emails will
- need third party to be authenticated thus preventing open relays.
- - `relaxed`: Based on a simple heuristic to determine if the SMTP client is a 
MUA or a MX (use of a valid domain in EHLO),
- we do act as `strict` for MUAs thus prompting them early for the need of 
authentication, but accept use of local MAIL FROM for
- MX. Authentication can then be delayed to later, eg after DATA transaction 
with the DKIMHook which might allow email looping through
- third party domains via mail redirection, effectively enforcing that the mail 
originates from our servers. See
- link:https://issues.apache.org/jira/browse/JAMES-4032[JAMES-4032] for 
detailed explanation.
+| `auth.required`
+| Requires authentication for submitting an email to the SMTP server.
+This configuration is intended for submission-only SMTP servers (e.g, port 
587).
+It should never be set to `true` on SMTP servers that receive emails from 
external servers as external users have no account and can not authenticate.
+Therefore, it must be `false` for SMTP servers on port 25 and 465.
 
-Backward compatibility is provided and thus the following values are supported:
+It is an optional boolean that defaults to `false`.
 
- - `true`: act as `strict`
- - `false`: act as `disabled`
+Note that `authorizedAddresses` are considered authenticated.
 
-Please note that this parameter only intend to prevent spoofing, and still 
allow unauthenticated remote users (that do not use local identity) to send 
email to local users.
+|===
 
-| maxmessagesize
-| This is an optional tag with a non-negative integer body.  It specifies the 
maximum
-size, in kbytes, of any message that will be transmitted by this SMTP server.  
It is a service-wide, as opposed to
-a per user, limit.  If the value is zero then there is no limit.  If the tag 
isn't specified, the service will
-default to an unlimited message size. Must be a positive integer, optionally 
with a unit: B, K, M, G.
+== Security
 
-| heloEhloEnforcement
-| This sets whether to enforce the use of HELO/EHLO salutation before a
-MAIL command is accepted. If unspecified, the value defaults to true.
+James supports authentication with username / password (`PLAIN` and `LOGIN`) 
and OIDC (`XOAUTH2` and `OAUTHBEARER`).
+SMTP authentication is essential to prevent sender address spoofing and open 
relays.
 
-| smtpGreeting
-| This sets the SMTPGreeting which will be used when connect to the smtpserver
-If none is specified a default is generated
+For the concepts explained below, the distinction between local and external 
users is important.
+James makes this distinction by matching the domain of an email address 
against the list of domains handled by it.
+This list can be configured in 
xref:{pages-path}/configure/domainlist.adoc[*domainlist.xml*].
 
-| handlerchain
-| The configuration handler chain. See 
xref:{pages-path}/configure/smtp-hooks.adoc[this page] for configuring out-of 
the
-box extra SMTP handlers and hooks.
+=== Open Relays
 
-| bossWorkerCount
-| Set the maximum count of boss threads. Boss threads are responsible for 
accepting incoming SMTP connections
-and initializing associated resources. Optional integer, by default, boss 
threads are not used and this responsibility is being dealt with
-by IO threads.
+The process of sending an email from one email server to another is called 
relaying.
+An open relay is an email server that allows any user to send emails to other 
email servers.
+Open relays are used by spammers to send spam emails with spoofed sender 
addresses.
+Open relays can be prevented using the SMTP AUTH extension.
 
-| ioWorkerCount
-| Set the maximum count of IO threads. IO threads are responsible for 
receiving incoming SMTP messages and framing them
-(split line by line). IO threads also take care of compression and SSL 
encryption. Their tasks are short-lived and non-blocking.
-Optional integer, defaults to 2 times the count of CPUs.
+By default, James is not an open relay.
+James relays emails if, and only if, they originate from one of the trusted 
sources below.
 
-| maxExecutorCount
-| Set the maximum count of worker threads. Worker threads takes care of 
potentially blocking tasks like executing SMTP commands.
-Optional integer, defaults to 16.
+- Authenticated SMTP/JMAP users
+- Emails generated by the server (e.g., bounces)
+- Emails originating from a trusted network (see `authorizedAddresses`)
 
-| useEpoll
-| true or false - If true uses native EPOLL implementation for Netty otherwise 
uses NIO. Defaults to false.
+This means that emails are only relayed for local users as external users have 
no way of authenticating.
+External users can still send emails to local users because those emails do 
not need to be relayed and therefore do not require authentication.
 
-| gracefulShutdown
-| true or false - If true attempts a graceful shutdown, which is safer but can 
take time. Defaults to true.
+It is extremely important to prevent your server from being an open relay.
+Aside from potential costs associated with usage by spammers,
+open relays are identified as such relatively quickly because of the spam 
originating from them.
+Hence, other SMTP servers routinely reject emails coming from open relays 
which severely impedes the ability of them to send emails to external users.
 
-| disabledFeatures
-| Extended SMTP features to hide in EHLO responses.
-|===
+==== Verification
 
-=== OIDC setup
-James SMTP support XOAUTH2 authentication mechanism which allow authenticating 
against a OIDC providers.
-Please configure `auth.oidc` part to use this.
+To verify that you have not inadvertently configured your server as an open 
relay, you can use a service such as 
https://mxtoolbox.com/diagnostic.aspx[mxtoolbox.com].
+This checks among other things:
 
-We do supply an 
link:https://github.com/apache/james-project/tree/master/examples/oidc[example] 
of such a setup.
-It uses the Keycloak OIDC provider, but usage of similar technologies is 
definitely doable.
+- Whether your email server is an open relay.
+- Your DNS configuration, especially whether your email server has a valid 
record for reverse DNS.
+- Support for secure connections with STARTTLS.
 
-== About open relays
+=== Spoofing
 
-Authenticated SMTP is a method of securing your SMTP server.  With SMTP AUTH 
enabled senders who wish to
-relay mail through the SMTP server (that is, send mail that is eventually to 
be delivered to another SMTP
-server) must authenticate themselves to Apache James Server before sending 
their message.  Mail that is to be delivered
-locally does not require authentication.  This method ensures that spammers 
cannot use your SMTP server
-to send unauthorized mail, while still enabling users who may not have fixed 
IP addresses to send their
-messages.
+In addition to preventing open relays, SMTP authentication can also be used to 
prevent spoofing.
+Spoofing is the assumption of the identity of another person without 
authorization to do so.
 
-Mail servers that allow spammers to send unauthorized email are known as open 
relays.  So SMTP AUTH
-is a mechanism for ensuring that your server is not an open relay.
+For emails from local addresses, spoofing can be prevented by requiring 
authentication for a user with authorization for the sender address.
+This can be configured with `verifyIdentity` as described above.
 
-It is extremely important that your server not be configured as an open relay. 
 Aside from potential
-costs associated with usage by spammers, connections from servers that are 
determined to be open relays
-are routinely rejected by SMTP servers.  This can severely impede the ability 
of your mail server to
-send mail.
+Sender verification does not work for emails sent by an external address.
+As external users can not authenticate, James has to trust the sender address.
 
-At this time Apache James Server only supports simple user name / password 
authentication.
+== LMTP Configuration
 
-As mentioned above, SMTP AUTH requires that Apache James Server be able to 
distinguish between mail intended
-for local delivery and mail intended for remote delivery. Apache James Server 
makes this determination by matching the
-domain to which the mail was sent against the *DomainList* component, 
configured by
-xref:{pages-path}/configure/domainlist.adoc[*domainlist.xml*].
+Consult this link:{sample-configuration-prefix-url}/lmtpserver.xml[example] 
for guidance on how to configure LMTP.
 
-The {server-name} is configured out of the box so as to not serve as an open 
relay for spammers.  This is done
-by relayed emails originate from a trusted source. This includes:
+The LMTP service is configured in the file `lmtpserver.xml`.
+It contains one `lmtpservers` element that can contain multiple `lmtpserver` 
elements.
 
-* Authenticated SMTP/JMAP users
-* Mails generated by the server (eg: bounces)
-* Mails originating from a trusted network as configured in *smtpserver.xml*
+The `lmtpserver` element can be configured using most of the common options 
described xref:{pages-path}/configure/server.adoc[here].
+Additional settings are described below.
 
-If you wish to ensure that authenticated users can only send email from their 
own account, you may
-optionally set the verifyIdentity element of the smtpserver configuration 
block to "true".
+**Note:** Neither any form of TLS nor proxies are supported.
 
-=== Verification
+.`lmtpserver` element
+|===
+| Property Name | Explanation
 
-Verify that you have not inadvertently configured your server as an open 
relay. This is most easily
-accomplished by using the service provided at 
https://mxtoolbox.com/diagnostic.aspx[mxtoolbox.com]. mxtoolbox.com will
-check your mail server and inform you if it is an open relay. This tool 
further more verifies additional properties like:
+| `maxmessagesize`
+| Configures the maximum size of LMTP messages the server will accept.
+If it is set to 0, no limit will be imposed.
+Any value larger than 0 will enable the SMTP SIZE extension (RFC 1870) and 
enforce the limit.
 
-* Your DNS configuration, especially that you mail server IP has a valid 
reverse DNS entry
-* That your SMTP connection is secured
-* That you are not an OpenRelay
-* This website also allow a quick lookup to ensure your mail server is not in 
public blacklists.
+It is an optional integer which defaults to 0.
+The last character of the value may be a unit.
+Supported units are `B` for bytes, `K` for kibibyte (1,024 bytes), `M` for 
mebibyte (1,024 kibibytes), and `G` for gibibyte (1,024 mebibytes).
+If no unit is given, the value is interpreted as kibibytes.
 
-Of course it is also necessary to confirm that users and log in and send
-mail through your server.  This can be accomplished using any standard mail 
client (i.e. Thunderbird, Outlook,
-Eudora, Evolution).
+| `lmtpGreeting`
+| Sets the greeting which the server sends when a client connects.
+It is an optional string.
+If not configured, a greeting is constructed from the server `helloName`.
 
-== LMTP Configuration
+| `handlerchain`
+a| Configures the behavior of the server using handlers.
+The `handlerchain` element has the following optional attributes:
 
-Consult this link:{sample-configuration-prefix-url}/lmtpserver.xml[example]
-to get some examples and hints.
+- `coreHandlersPackage` is a string specifying a handler loader. All handlers 
of this loader are added to the end of the handlerchain. The default is 
`org.apache.james.lmtpserver.CoreCmdHandlerLoader`.
+- `enableJmx` enables the JMX for this server. It is a boolean which is `true` 
by default.
+- `jmxHandlersPackage` is a string specifying a handler loader for JMX. All 
handlers of this loader are added to the handlerchain after the core handlers. 
The default is `org.apache.james.lmtpserver.jmx.JMXHandlersLoader`. It only has 
an effect if `enableJmx` is `true`.
 
-The configuration is the same of for SMTP.
+The `handlerchain` element may contain an arbitrary number of `handler` 
elements.
+Every `handler` element must have the string attribute `class`.
+They are inserted in order at the beginning of the handlerchain.
+The handlers of the `coreHandlersPackage` or `jmxHandlersPackage` do not need 
their own `handler` elements.
 
-By default, it is deactivated. You can activate it alongside SMTP and bind for 
example on port 24.
+|===
 
-The default LMTP server stores directly emails in user mailboxes, without 
further treatment.
+=== LMTP Examples
 
-However we do ship an alternative handler chain allowing to execute the mailet 
container, thus achieving a behaviour similar
-to the default SMTP protocol. Here is how to achieve this:
+The default LMTP server stores emails without further treatment in user 
mailboxes.
+However, we do ship an alternative handlerchain allowing to execute a 
mailetcontainer, thus achieving a behavior similar to SMTP.
+You can enable the mailetcontainer with the following configuration:
 
 [source,xml]
 ....
 <lmtpservers>
     <lmtpserver enabled="true">
-        <jmxName>lmtpserver</jmxName>
-        <bind>0.0.0.0:24</bind>
-        <connectionBacklog>200</connectionBacklog>
-        <connectiontimeout>1200</connectiontimeout>
-        <connectionLimit>0</connectionLimit>
-        <connectionLimitPerIP>0</connectionLimitPerIP>
-        <maxmessagesize>0</maxmessagesize>
+        <!-- ... -->
         <handlerchain 
coreHandlersPackage="org.apache.james.lmtpserver.MailetContainerCmdHandlerLoader">
-            <handler 
class="org.apache.james.lmtpserver.MailetContainerCmdHandlerLoader"/>
         </handlerchain>
     </lmtpserver>
 </lmtpservers>
 ....
 
-Note that by default the mailet container is executed with all recipients at 
once and do not allow per recipient
-error reporting. An option <code>splitExecution</code> allow to execute the 
mailet container for each recipient separately and mitigate this
-limitation at the cost of performance.
+Note that by default the mailetcontainer is executed with all recipients at 
once and does not allow per recipient error reporting.
+The option `splitExecution` allows to execute the mailetcontainer for each 
recipient separately and mitigate this limitation at the cost of performance.
 
 [source,xml]
 ....
 <lmtpservers>
     <lmtpserver enabled="true">
-        <jmxName>lmtpserver</jmxName>
-        <bind>0.0.0.0:24</bind>
-        <connectionBacklog>200</connectionBacklog>
-        <connectiontimeout>1200</connectiontimeout>
-        <connectionLimit>0</connectionLimit>
-        <connectionLimitPerIP>0</connectionLimitPerIP>
-        <maxmessagesize>0</maxmessagesize>
+        <!-- ... -->
         <handlerchain 
coreHandlersPackage="org.apache.james.lmtpserver.MailetContainerCmdHandlerLoader">
-            <handler 
class="org.apache.james.lmtpserver.MailetContainerCmdHandlerLoader"/>
             <handler 
class="org.apache.james.lmtpserver.MailetContainerHandler">
                 <splitExecution>true</splitExecution>
             </handler>
         </handlerchain>
     </lmtpserver>
 </lmtpservers>
-....
\ No newline at end of file
+....
diff --git a/docs/modules/servers/partials/configure/ssl.adoc 
b/docs/modules/servers/partials/configure/ssl.adoc
index 5cb4f9470c..46c4f99da8 100644
--- a/docs/modules/servers/partials/configure/ssl.adoc
+++ b/docs/modules/servers/partials/configure/ssl.adoc
@@ -1,21 +1,159 @@
-This document explains how to enable James 3.0 servers to use Transport Layer 
Security (TLS)
-for encrypted client-server communication.
+The servers
+xref:{pages-path}/configure/smtp.adoc[SMTP],
+xref:{pages-path}/configure/pop3.adoc[POP3],
+xref:{pages-path}/configure/imap.adoc[IMAP], and
+xref:{pages-path}/configure/sieve.adoc[Managesieve]
+support TLS.
+The configuration is the same for all of them and this document explains how 
to do it.
 
-== Configure a Server to Use SSL/TLS
+== Configure a Server to Use TLS
 
-Each of the servers xref:{pages-path}/configure/smtp.adoc[SMTP - LMTP],
-xref:{pages-path}/configure/pop3.adoc[POP3] and 
xref:{pages-path}/configure/imap.adoc[IMAP]
-supports use of SSL/TLS.
+As described in xref:{pages-path}/configure/server.adoc[SMTP],
+there is a `tls` element inside the XML server element.
 
-TLS (Transport Layer Security) and SSL (Secure Sockets Layer) are protocols 
that provide
-data encryption and authentication between applications in scenarios where 
that data is
-being sent across an insecure network, such as checking your email
-(How does the Secure Socket Layer work?). The terms SSL and TLS are often used
-interchangeably or in conjunction with each other (TLS/SSL),
-but one is in fact the predecessor of the other — SSL 3.0 served as the basis
-for TLS 1.0 which, as a result, is sometimes referred to as SSL 3.1.
+It supports two attributes:
 
-You need to add a block in the corresponding configuration file 
(smtpserver.xml, pop3server.xml, imapserver.xml,..)
+- `socketTLS`: Enables STARTTLS for this server. The client can upgrade the 
connection using the `STARTTLS` command.
+- `startTLS`: Enables implicit TLS on this port.
+
+By default, both attributes are `false`.
+However, it is highly recommended to use TLS and set one of these to `true` 
for every server.
+They can not both be `true` for one server.
+
+Additionally, the `tls` element can have the following child elements.
+There are also examples after the table.
+
+.`tls` element
+|===
+| Property Name | Explanation
+
+| `supportedCipherSuites`
+| Contains the ciphersuites that should be enabled.
+Every ciphersuite is in its own `cipherSuite` element.
+If not configured, the library's default is used.
+
+| `supportedProtocols`
+| Contains the protocols that should be enabled.
+Every protocol is in its own `protocol` element.
+If not configured, the library's default is used.
+
+| `keystore`
+| The path to a keystore.
+The keystore **must** have only one certificate.
+Either the keystore or both private key and certificates must be configured.
+
+| `keystoreType`
+| The type of the keystore.
+It is an optinal string with the default value `JKS`.
+A common alternative is `PKCS12`.
+
+| `privateKey`
+| The path to a private key.
+If configured, `certificates` must also be configured.
+
+| `certificates`
+| A path to a certificate bundle.
+The last certificate in the bundle is the one signed by a root CA.
+If configured, `privateKey` must also be configured.
+
+| `secret`
+| A secret for the keystore or private key.
+It is optional.
+
+| `clientAuth`
+a| Configures TLS client authentication.
+If this is present, all clients are required to authenticate on the TLS level.
+It has the following child elements:
+
+- `clientAuth.truststore`: An optional path to the truststore for verifying 
client certificates. The truststore can contain client certificates directly or 
CAs that issued client certificates. If not configured, the library's default 
is used.
+- `clientAuth.truststoreType`: The type of the keystore. It is optional and 
defaults to `JKS`.
+- `clientAuth.truststoreSecret`: An optional secret for the truststore.
+
+| `enableOCSPCRLChecks`
+| Enables revocation checks for client authentication.
+It is an optional boolean that is `false` by default.
+
+| `sessionCache.size`
+| Sets the maximum number of TLS sessions in the session cache.
+If not configured, the library's default is used.
+
+| `sessionCache.timeout`
+| Sets the duration after which TLS sessions in the cache time out.
+If not configured, the library's default is used.
+It is an integer followed by an optional unit.
+The default unit is `ms` (millisecond) and other reasonable values are `s` 
(second) or `m` (minute).
+
+|===
+
+The paths in the table above are usually file paths and prefixed with 
`file://`.
+They can either be relative (e.g., `file://conf/imap.crt`) or absolute (e.g., 
`file:///james/conf/imap.crt`).
+
+== TLS for Email Services
+
+Email was established before protocols like TLS that can secure TCP 
connections independent of the application layer.
+Therefore, the email services on the initially established ports never had a 
security layer.
+Because of backward compatibility, this will not change.
+STARTTLS was introduced to negotiate a security layer over the insecure 
channel.
+For it to work, both the server and the client must abort sessions if STARTTLS 
is not used.
+
+Alternatively, other ports that are expected to use implicit TLS have been 
established by RFC 8314.
+
+.Ports for email services
+|===
+| Service | Client | Ports
+
+| SMTP
+| Remote MX
+| insecure: 25, TLS: not defined by RFC
+
+When trying to deliver emails to another email server using implicit TLS, 
James attempts to use port 465.
+
+| SMTP Submission
+| MUA
+| insecure: 587, TLS: 465
+
+| IMAP
+| MUA
+| insecure: 143, TLS: 993
+
+| POP3
+| MUA
+| insecure: 110, TLS: 995
+
+| LMTP
+| Local MX
+| insecure: 24, no TLS port defined
+
+TLS for LMTP is not supported by James.
+
+|===
+
+As all modern email clients support TLS nowadays, there is no need to offer 
SMTP submission, IMAP, or POP3 without implicit TLS.
+In most cases, it should suffice to offer only one version with implicit TLS 
for each of these services.
+
+As the MX DNS record only resolves to an IP, other email servers can not know 
whether the other server offers SMTP with implicit TLS and on which port.
+Every email server **must** therefore offer SMTP on port 25.
+You may choose to additionally offer SMTP with implicit TLS on port 465 as 
some email servers (e.g., James) also try that endpoint.
+Note that you need to move the SMTP submission service with implicit TLS to 
another port in that case (this works well as it is only used by MUAs).
+
+As James does not support TLS or authentication for LMTP,
+the port **must only be exposed** to the local SMTP server that uses it.
+
+**We strongly recommend that you enable STARTTLS for all services that you 
choose to offer without implicit TLS.**
+
+== Examples
+
+=== JKS with Password
+
+[source,xml]
+....
+<tls socketTLS="false" startTLS="true">
+  <keystore>file://conf/keystore</keystore>
+  <secret>yoursecret</secret>
+</tls>
+....
+
+=== PKCS12 Keystore with Password
 
 [source,xml]
 ....
@@ -23,33 +161,34 @@ You need to add a block in the corresponding configuration 
file (smtpserver.xml,
   <keystore>file://conf/keystore</keystore>
   <keystoreType>PKCS12</keystoreType>
   <secret>yoursecret</secret>
-  <provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider>
 </tls>
 ....
 
-Alternatively TLS keys can be supplied via PEM files:
+=== Certificates and Private Key as PEM Files
 
 [source,xml]
 ....
 <tls socketTLS="true" startTLS="false">
-  <privateKey>file://conf/private.key</privateKey>
-  <certificates>file://conf/certs.self-signed.csr</certificates>
+  <privateKey>file://conf/imap.key</privateKey>
+  <certificates>file://conf/imap.crt</certificates>
 </tls>
 ....
 
-An optional secret might be specified for the private key:
+=== Certificates and Private Key with Password as PEM Files
 
 [source,xml]
 ....
 <tls socketTLS="true" startTLS="false">
-  <privateKey>file://conf/private.key</privateKey>
-  <certificates>file://conf/certs.self-signed.csr</certificates>
+  <privateKey>file://conf/imap.key</privateKey>
+  <certificates>file://conf/imap.crt</certificates>
   <secret>yoursecret</secret>
 </tls>
 ....
 
-Optionally, TLS protocols and/or cipher suites can be specified explicitly 
(smtpserver.xml, pop3server.xml, imapserver.xml,..).
-Otherwise, the default protocols and cipher suites of the used JDK will be 
used:
+=== Explicitly Selected Protocol Versions and Ciphersuites
+
+**Note:** Only modify the following settings if you know exactly what you are 
doing.
+The configuration below is extremely insecure.
 
 [source,xml]
 ....
@@ -64,52 +203,14 @@ Otherwise, the default protocols and cipher suites of the 
used JDK will be used:
     <cipherSuite>TLS_AES_256_GCM_SHA384</cipherSuite>
     <cipherSuite>TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256</cipherSuite>
   </supportedCipherSuites>
+  <!-- ... -->
 </tls>
 ....
 
-Each of these block has an optional boolean configuration element 
<b>socketTLS</b> and <b>startTLS</b> which is used to toggle
-use of SSL or TLS for the service.
-
-With socketTLS (SSL/TLS in Thunderbird), all the communication is encrypted.
-
-With startTLS (STARTTLS in Thunderbird), the preamble is readable, but the 
rest is encrypted.
-
-....
-* OK JAMES IMAP4rev1 Server  Server 192.168.1.4 is ready.
-* CAPABILITY IMAP4rev1 LITERAL+ CHILDREN WITHIN STARTTLS IDLE NAMESPACE 
UIDPLUS UNSELECT AUTH=PLAIN
-1 OK CAPABILITY completed.
-2 OK STARTTLS Begin TLS negotiation now.
-... rest is encrypted...
-....
-
-You can only enable one of the both at the same time for a service.
-
-It is also recommended to change the port number on which the service will 
listen:
-
-* POP3 - port 110, Secure POP3 - port 995
-* IMAP - port 143, Secure IMAP4 - port 993
-* SMTP - port 25, Secure SMTP - port 465
-
-You will now need to create your certificate store and place it in the 
james/conf/ folder with the name you defined in the keystore tag.
-
-Please note `JKS` keystore format is also supported (default value if no 
keystore type is specified):
-
-[source,xml]
-....
-<tls socketTLS="false" startTLS="true">
-  <keystore>file://conf/keystore</keystore>
-  <keystoreType>JKS</keystoreType>
-  <secret>yoursecret</secret>
-  <provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider>
-</tls>
-....
-
-
-=== TLS session cache
+=== TLS Session Cache
 
 TLS session resumption allows clients to reconnect without performing a full 
TLS handshake, reducing CPU usage and connection latency.
-
-James caches completed TLS sessions server-side using the JDK 
`SSLSessionContext`. The cache size can be configured with `sessionCacheSize`:
+James caches completed TLS sessions server-side using the JDK 
`SSLSessionContext`.
 
 [source,xml]
 ....
@@ -118,22 +219,20 @@ James caches completed TLS sessions server-side using the 
JDK `SSLSessionContext
   <keystoreType>PKCS12</keystoreType>
   <secret>yoursecret</secret>
 
- <sessionCache>
-  <size>1024</size>
-  <timeout>600s</timeout>
- </sessionCache>
+  <sessionCache>
+    <size>1024</size>
+    <timeout>600s</timeout>
+  </sessionCache>
 </tls>
 ....
 
 When a cached session is found, the client and server skip the asymmetric key 
exchange and certificate verification,
-reusing the previously negotiated symmetric keys. This is particularly 
effective for mail clients that open many
-short-lived connections (e.g. mobile push sync).
+reusing the previously negotiated symmetric keys. This is particularly 
effective for email clients that open many
+short-lived connections (e.g., mobile push sync).
 
-The `timeout` is expressed in seconds (`s`), minutes (`m`), or hours (`h`). If 
`sessionCache` is omitted, the JDK defaults are used.
+=== Client Authentication
 
-=== Client authentication via certificates
-
-When you enable TLS, you may also configure the server to require a client 
certificate for authentication:
+When you enable TLS, you may also configure the server to require a client 
certificate for authentication.
 
 [source,xml]
 ....
@@ -146,134 +245,131 @@ When you enable TLS, you may also configure the server 
to require a client certi
     <truststore>file://conf/truststore</truststore>
     <truststoreType>JKS</truststoreType>
     <truststoreSecret>yoursecret</truststoreSecret>
-    <enableOCSPCRLChecks>false</enableOCSPCRLChecks>
   </clientAuth>
+  <enableOCSPCRLChecks>false</enableOCSPCRLChecks>
 </tls>
 ....
 
-James verifies client certificates against the provided truststore. You can 
fill it with trusted peer certificates directly, or an issuer certificate (CA) 
if you trust all certificates created by it. If you omit the truststore 
configuration, James will use the Java default truststore instead, effectively 
trusting any known CA.
-
-James can optionally enable OCSP verifications for client certificates against 
Certificate Revocation List referenced
-in the certificate itself.
+== Certificates by Well-Known Root CA (Preferred)
 
-== Creating your own PEM keys
+In order for MUAs and other email servers to trust the certificates by your 
email server out of the box, they need to be issued (at least transitively) by 
a trusted root CA.
+The easiest and cheapest way to get such a certificate is by using ACME.
 
-The following commands can be used to create self signed PEM keys:
-
-[source,xml]
-....
-# Generating your private key
-openssl genrsa -des3 -out private.key 2048
+We recommend to use either RSA (with at least 4,096 bits key size) or ECDSA as 
signature algorithm.
+Those may not provide the best security but they are the algorithms with the 
best support among MUAs and MXs.
+The tools presented below choose a reasonable default so you do not have to 
configure the algorithm at all.
 
-# Creating your certificates
-openssl req -new -key private.key -out certs.csr
+Although most ACME clients are built for requesting certificates for websites,
+you can easily use them to request certificates for an email server.
+Some ACME clients that work well are Caddy and certbot.
+You must only be able to set up an ACME client to listen on port 80 on the 
domain you want a certificate for.
 
-# Signing the certificate yourself
-openssl x509 -req -days 365 -in certs.csr -signkey private.key -out 
certs.self-signed.csr
+A Caddy server with the following configuration file obtains a certificate for 
the domain `imap.example.internal`.
 
-# Removing the password from the private key
-# Not necessary if you supply the secret in the configuration
-openssl rsa -in private.key -out private.nopass.key
+.Caddyfile
+[source]
+....
+{
+       email <Email address for Let's Encrypt>
+       events {
+               on cert_obtained exec cert-hook.sh {event.data.identifier} 
{event.data.private_key_path} {event.data.certificate_path}
+       }
+}
+
+imap.example.internal {
+       respond 204
+}
 ....
 
-You may then supply this TLS configuration:
+With certbot, you can use the command
 
-[source,xml]
+[source]
 ....
-<tls socketTLS="true" startTLS="false">
-  <privateKey>file://conf/private.nopass.key</privateKey>
-  <certificates>file://conf/certs.self-signed.csr</certificates>
-</tls>
+certbot certonly \
+  -c config.ini \
+  --non-interactive \
+  --cert-name imap \
+  --domains imap.example.internal \
+  --keep-until-expiring \
+  --deploy-hook 'imap-deploy-hook.sh'
 ....
 
-== Certificate Keystores
-
-This section gives more indication for users relying on keystores.
-
-=== Creating your own Certificate Keystore
-
-(Adapted from the Tomcat 4.1 documentation)
-
-James currently operates only on JKS or PKCS12 format keystores. This is 
Java's standard "Java KeyStore" format, and is
-the format created by the keytool command-line utility. This tool is included 
in the JDK.
-
-To import an existing certificate into a JKS keystore, please read the 
documentation (in your JDK documentation package)
-about keytool.
-
-To create a new keystore from scratch, containing a single self-signed 
Certificate, execute the following from a terminal
-command line:
+with the following config file to obtain a certificate for the same domain.
 
+[source]
 ....
-keytool -genkey -alias james -keyalg RSA -storetype PKCS12 -keystore 
your_keystore_filename
+email = <Email address for Let's Encrypt>
+agree-tos = true
+authenticator = standalone
+preferred-challenges = http
 ....
 
-(The RSA algorithm should be preferred as a secure algorithm, and this also 
ensures general compatibility with other
-servers and components.)
-
-As a suggested standard, create the keystore in the james/conf directory, with 
a name like james.keystore.
-
-After executing this command, you will first be prompted for the keystore 
password.
+=== Automatic Certificate Renewal
 
-Next, you will be prompted for general information about this Certificate, 
such as company, contact name, and so on.
-This information may be displayed to users when importing into the certificate 
store of the client, so make sure that
-the information provided here matches what they will expect.
+As long as Caddy runs, it refreshes the certificate.
+With a link:https://github.com/mholt/caddy-events-exec[plugin], Caddy can 
automatically execute a script after obtaining a new certificate.
 
-Important: in the "distinguished name", set the "common name" (CN) to the DNS 
name of your James server, the one
-you will use to access it from your mail client (like "mail.xyz.com").
+The solution with certbot requires you to execute the command regularly to 
refresh the certificate.
+Using the deploy hook argument, a script can be executed after a certificate 
has been obtained.
 
-Finally, you will be prompted for the key password, which is the password 
specifically for this Certificate
-(as opposed to any other Certificates stored in the same keystore file).
+These hooks should be used to make James aware of the new certificate.
+First, the PEM files for private key and certificate must be copied to the 
path configured in James.
+Afterward, James can be triggered to reload its certificates by POSTing to the 
`/servers?reload-certificate` endpoint of the webadmin API.
 
-If everything was successful, you now have a keystore file with a Certificate 
that can be used by your server.
+== Creating your own PEM Keys
 
-You MUST have only one certificate in the keystore file used by James.
+This approach should only be used during development.
+The certificate will not be accepted by MUAs or other email servers.
 
-=== Installing a Certificate provided by a Certificate Authority
+The following commands can be used to create a self-signed PEM certificate:
 
-(Adapted from the Tomcat 4.1 documentation
-
-To obtain and install a Certificate from a Certificate Authority (like 
verisign.com, thawte.com or trustcenter.de)
-you should have read the previous section and then follow these instructions:
-
-==== Create a local Certificate Signing Request (CSR)
-
-In order to obtain a Certificate from the Certificate Authority of your choice 
you have to create a so called
-Certificate Signing Request (CSR). That CSR will be used by the Certificate 
Authority to create a Certificate
-that will identify your James server as "secure". To create a CSR follow these 
steps:
+[source]
+....
+# Generate a private key.
+openssl genpkey -outform pem -out imap.key -algorithm rsa -pkeyopt 
rsa_keygen_bits:4096
 
-* Create a local Certificate as described in the previous section.
+# Create a self-signed certificate.
+# Note that this is missing the SAN extension and is therefore not compliant 
to RFC 9525.
+openssl x509 -new -set_subject '/CN=imap.example.internal' -key imap.key 
-keyform pem -outform pem -out imap.crt
+....
 
-The CSR is then created with:
+You may then supply this TLS configuration:
 
+[source,xml]
 ....
-  keytool -certreq -keyalg RSA -alias james -file certreq.csr -keystore 
your_keystore_filename
+<tls socketTLS="true" startTLS="false">
+  <privateKey>file://conf/imap.key</privateKey>
+  <certificates>file://conf/imap.crt</certificates>
+</tls>
 ....
 
-Now you have a file called certreq.csr. The file is encoded in PEM format. You 
can submit it to the Certificate Authority
-(look at the documentation of the Certificate Authority website on how to do 
this). In return you get a Certificate.
+== Keystores
 
-Now that you have your Certificate you can import it into you local keystore. 
First of all you may have to import a so
-called Chain Certificate or Root Certificate into your keystore (the major 
Certificate Authorities are already in place,
-so it's unlikely that you will need to perform this step). After that you can 
procede with importing your Certificate.
+Keystores can be managed using the `keytool` utility which is included in the 
JDK.
+It is possible to load certificates in the keystore that have been obtained by 
a trusted CA.
 
-==== Optionally Importing a so called Chain Certificate or Root Certificate
+The following approach shows how to create a keystore with a self-signed 
certificate and should only be used during development.
+The certificate will not be accepted by MUAs or other email servers.
 
-Download a Chain Certificate from the Certificate Authority you obtained the 
Certificate from.
-
-* For Verisign.com go to: 
http://www.verisign.com/support/install/intermediate.html
-* For Trustcenter.de go to: 
http://www.trustcenter.de/certservices/cacerts/en/en.htm#server
-* For Thawte.com go to: http://www.thawte.com/certs/trustmap.html (seems no 
longer valid)
-
-==== Import the Chain Certificate into you keystore
+The following command creates a keystore with a self-signed certificate:
 
+[source]
 ....
-keytool -import -alias root -keystore your_keystore_filename -trustcacerts 
-file filename_of_the_chain_certificate
+keytool \
+  -alias imap \
+  -genkeypair -keyalg rsa -keysize 4096 \
+  -storetype pkcs12 -keystore keystore.p12 -storepass yoursecret \
+  -dname 'CN=imap.example.internal' \
+  -ext san=dns:imap.example.internal
 ....
 
-And finally import your new Certificate (It must be in X509 format):
+You may then supply this TLS configuration:
 
+[source,xml]
 ....
-keytool -import -alias james -keystore your_keystore_filename -trustcacerts 
-file your_certificate_filename
+<tls socketTLS="true" startTLS="false">
+  <keystore>file://conf/keystore.p12</keystore>
+  <keystoreType>PKCS12</keystoreType>
+  <secret>yoursecret</secret>
+</tls>
 ....
-
-See also http://www.agentbob.info/agentbob/79.html[this page]
\ No newline at end of file
diff --git 
a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServer.java
 
b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServer.java
index 89a2469a07..d0b43c0ff0 100644
--- 
a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServer.java
+++ 
b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServer.java
@@ -156,7 +156,7 @@ public class IMAPServer extends 
AbstractConfigurableAsyncServer implements ImapC
     private static final String DEFAULT_TIME_UNIT = "SECONDS";
     private static final String CAPABILITY_SEPARATOR = "|";
     public static final int DEFAULT_MAX_LINE_LENGTH = 65536; // Use a big 
default
-    public static final Size DEFAULT_IN_MEMORY_SIZE_LIMIT = Size.of(10L, 
Size.Unit.M); // Use 10MB as default
+    public static final Size DEFAULT_IN_MEMORY_SIZE_LIMIT = Size.of(10L, 
Size.Unit.M); // Use 10MiB as default
     public static final int DEFAULT_TIMEOUT = 30 * 60; // default timeout is 
30 minutes
     public static final int DEFAULT_LITERAL_SIZE_LIMIT = 0;
 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to