[
https://issues.apache.org/jira/browse/CAMEL-26322?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Andrea Cosentino updated CAMEL-26322:
-------------------------------------
Description:
h3. Background
camel-as2 can request an asynchronous MDN (Message Disposition Notification).
When one is requested, {{AS2AsynchronousMDNManager.send()}} resolves the
delivery address from the sender-supplied {{Receipt-Delivery-Option}} URI and
opens a connection to it.
The {{asyncMdnAllowedHosts}} option on {{AS2Configuration}} (documented today
as "Comma separated list of host names an asynchronous MDN may be delivered
to") governs whether the asynchronous MDN is delivered to the resolved address
and whether the configured MDN credentials ({{mdnUserName}} / {{mdnPassword}} /
{{mdnAccessToken}}) are attached to it.
h3. Current behaviour
{{send()}} resolves both the host and the port of the delivery address (the
port via {{uri.getPort()}}, defaulted to 80 or 443 by scheme). The allow-list
match {{isAllowedHost(String host)}} then compares only the *host*: it splits
{{asyncMdnAllowedHosts}} on commas and does a case-insensitive equals against
the host. The resolved port is used to open the socket but is never compared
against the allow-list. An operator can therefore list a host, but every port
on that listed host is treated the same, both for delivery and for attaching
the credentials.
h3. Behaviour after the change
The allow-list match considers the full authority - host *and* port - of the
resolved delivery address, so the port is checked before the connection is
opened and before the credentials are attached. Each {{asyncMdnAllowedHosts}}
entry may carry an optional port in {{host:port}} form. A bare-host entry (for
example {{partner.example}}) matches only the default port for its scheme (80
or 443); an operator that receives asynchronous MDNs on a non-default port
lists it explicitly (for example {{partner.example:8443}}).
h3. Classes involved
*
{{components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2AsynchronousMDNManager.java}}
- the allow-list match {{isAllowedHost(...)}} (host-only today), the resolved
{{port}}, and the points where the connection is opened ({{createSocket}}) and
the credentials are attached ({{addAuthorizationHeader}}).
*
{{components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Configuration.java}}
- the {{asyncMdnAllowedHosts}} option and its description.
h3. Code-level change
* Replace {{isAllowedHost(String host)}} with an authority match that also
takes the resolved port (for example {{isAllowedAuthority(String host, int
port)}}): parse each {{asyncMdnAllowedHosts}} entry as {{host[:port]}} and
compare both the host (case-insensitive) and the port (default-port aware).
* Pass the already-resolved {{port}} into the match, so the single
{{hostIsAllowed}} decision that gates the connection and the attachment of
credentials now accounts for the port.
* Update the {{asyncMdnAllowedHosts}} description on {{AS2Configuration}} to
document the {{host[:port]}} form and the default-port rule, then regenerate
the catalog/component metadata.
h3. Tests
New JUnit methods in {{AS2AsynchronousMDNManagerDeliveryAddressTest}} (that
class uses JUnit assertions, so new methods there stay JUnit to match the file):
* a delivery address whose port is outside every allow-list entry is refused;
* a delivery address whose host and port both match an entry is accepted;
* a bare-host entry matches only the default port for its scheme.
Each new test is shown failing against the current code and passing after the
change.
h3. Documentation
The default-port behaviour above is a change for an operator that today lists a
bare host and delivers to a non-default port, so add a note to
{{docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc}} on
{{main}} describing the {{host[:port]}} matching and the default-port rule.
h3. Additional hardening: require https
The asynchronous MDN delivery scheme is also chosen by the sender, and plain
http is accepted, so the configured MDN credentials can be delivered over http
even when the operator intended https. A new opt-in option
{{asyncMdnRequireHttps}} on {{AS2Configuration}} (default {{false}}) is added:
when set, an asynchronous MDN whose delivery address does not use https is
refused before the connection is opened and before the configured credentials
are attached. The option applies per consumer endpoint, like
{{asyncMdnAllowedHosts}}. New JUnit tests cover: http refused when the option
is set, https accepted when it is set, and http still accepted by default.
was:
h3. Background
camel-as2 can request an asynchronous MDN (Message Disposition Notification).
When one is requested, {{AS2AsynchronousMDNManager.send()}} resolves the
delivery address from the sender-supplied {{Receipt-Delivery-Option}} URI and
opens a connection to it.
The {{asyncMdnAllowedHosts}} option on {{AS2Configuration}} (documented today
as "Comma separated list of host names an asynchronous MDN may be delivered
to") governs whether the asynchronous MDN is delivered to the resolved address
and whether the configured MDN credentials ({{mdnUserName}} / {{mdnPassword}} /
{{mdnAccessToken}}) are attached to it.
h3. Current behaviour
{{send()}} resolves both the host and the port of the delivery address (the
port via {{uri.getPort()}}, defaulted to 80 or 443 by scheme). The allow-list
match {{isAllowedHost(String host)}} then compares only the *host*: it splits
{{asyncMdnAllowedHosts}} on commas and does a case-insensitive equals against
the host. The resolved port is used to open the socket but is never compared
against the allow-list. An operator can therefore list a host, but every port
on that listed host is treated the same, both for delivery and for attaching
the credentials.
h3. Behaviour after the change
The allow-list match considers the full authority - host *and* port - of the
resolved delivery address, so the port is checked before the connection is
opened and before the credentials are attached. Each {{asyncMdnAllowedHosts}}
entry may carry an optional port in {{host:port}} form. A bare-host entry (for
example {{partner.example}}) matches only the default port for its scheme (80
or 443); an operator that receives asynchronous MDNs on a non-default port
lists it explicitly (for example {{partner.example:8443}}).
h3. Classes involved
*
{{components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2AsynchronousMDNManager.java}}
- the allow-list match {{isAllowedHost(...)}} (host-only today), the resolved
{{port}}, and the points where the connection is opened ({{createSocket}}) and
the credentials are attached ({{addAuthorizationHeader}}).
*
{{components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Configuration.java}}
- the {{asyncMdnAllowedHosts}} option and its description.
h3. Code-level change
* Replace {{isAllowedHost(String host)}} with an authority match that also
takes the resolved port (for example {{isAllowedAuthority(String host, int
port)}}): parse each {{asyncMdnAllowedHosts}} entry as {{host[:port]}} and
compare both the host (case-insensitive) and the port (default-port aware).
* Pass the already-resolved {{port}} into the match, so the single
{{hostIsAllowed}} decision that gates the connection and the attachment of
credentials now accounts for the port.
* Update the {{asyncMdnAllowedHosts}} description on {{AS2Configuration}} to
document the {{host[:port]}} form and the default-port rule, then regenerate
the catalog/component metadata.
h3. Tests
New JUnit methods in {{AS2AsynchronousMDNManagerDeliveryAddressTest}} (that
class uses JUnit assertions, so new methods there stay JUnit to match the file):
* a delivery address whose port is outside every allow-list entry is refused;
* a delivery address whose host and port both match an entry is accepted;
* a bare-host entry matches only the default port for its scheme.
Each new test is shown failing against the current code and passing after the
change.
h3. Documentation
The default-port behaviour above is a change for an operator that today lists a
bare host and delivers to a non-default port, so add a note to
{{docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc}} on
{{main}} describing the {{host[:port]}} matching and the default-port rule.
Summary: camel-as2 - scope the async MDN allow-list to host and port,
and add an option to require https (was: camel-as2 - match the async MDN
delivery allow-list on host and port)
> camel-as2 - scope the async MDN allow-list to host and port, and add an
> option to require https
> -----------------------------------------------------------------------------------------------
>
> Key: CAMEL-26322
> URL: https://issues.apache.org/jira/browse/CAMEL-26322
> Project: Camel
> Issue Type: Improvement
> Components: camel-as2
> Reporter: Andrea Cosentino
> Assignee: Andrea Cosentino
> Priority: Major
> Fix For: 4.24.0
>
>
> h3. Background
> camel-as2 can request an asynchronous MDN (Message Disposition Notification).
> When one is requested, {{AS2AsynchronousMDNManager.send()}} resolves the
> delivery address from the sender-supplied {{Receipt-Delivery-Option}} URI and
> opens a connection to it.
> The {{asyncMdnAllowedHosts}} option on {{AS2Configuration}} (documented today
> as "Comma separated list of host names an asynchronous MDN may be delivered
> to") governs whether the asynchronous MDN is delivered to the resolved
> address and whether the configured MDN credentials ({{mdnUserName}} /
> {{mdnPassword}} / {{mdnAccessToken}}) are attached to it.
> h3. Current behaviour
> {{send()}} resolves both the host and the port of the delivery address (the
> port via {{uri.getPort()}}, defaulted to 80 or 443 by scheme). The allow-list
> match {{isAllowedHost(String host)}} then compares only the *host*: it splits
> {{asyncMdnAllowedHosts}} on commas and does a case-insensitive equals against
> the host. The resolved port is used to open the socket but is never compared
> against the allow-list. An operator can therefore list a host, but every port
> on that listed host is treated the same, both for delivery and for attaching
> the credentials.
> h3. Behaviour after the change
> The allow-list match considers the full authority - host *and* port - of the
> resolved delivery address, so the port is checked before the connection is
> opened and before the credentials are attached. Each {{asyncMdnAllowedHosts}}
> entry may carry an optional port in {{host:port}} form. A bare-host entry
> (for example {{partner.example}}) matches only the default port for its
> scheme (80 or 443); an operator that receives asynchronous MDNs on a
> non-default port lists it explicitly (for example {{partner.example:8443}}).
> h3. Classes involved
> *
> {{components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2AsynchronousMDNManager.java}}
> - the allow-list match {{isAllowedHost(...)}} (host-only today), the
> resolved {{port}}, and the points where the connection is opened
> ({{createSocket}}) and the credentials are attached
> ({{addAuthorizationHeader}}).
> *
> {{components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Configuration.java}}
> - the {{asyncMdnAllowedHosts}} option and its description.
> h3. Code-level change
> * Replace {{isAllowedHost(String host)}} with an authority match that also
> takes the resolved port (for example {{isAllowedAuthority(String host, int
> port)}}): parse each {{asyncMdnAllowedHosts}} entry as {{host[:port]}} and
> compare both the host (case-insensitive) and the port (default-port aware).
> * Pass the already-resolved {{port}} into the match, so the single
> {{hostIsAllowed}} decision that gates the connection and the attachment of
> credentials now accounts for the port.
> * Update the {{asyncMdnAllowedHosts}} description on {{AS2Configuration}} to
> document the {{host[:port]}} form and the default-port rule, then regenerate
> the catalog/component metadata.
> h3. Tests
> New JUnit methods in {{AS2AsynchronousMDNManagerDeliveryAddressTest}} (that
> class uses JUnit assertions, so new methods there stay JUnit to match the
> file):
> * a delivery address whose port is outside every allow-list entry is refused;
> * a delivery address whose host and port both match an entry is accepted;
> * a bare-host entry matches only the default port for its scheme.
> Each new test is shown failing against the current code and passing after the
> change.
> h3. Documentation
> The default-port behaviour above is a change for an operator that today lists
> a bare host and delivers to a non-default port, so add a note to
> {{docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc}} on
> {{main}} describing the {{host[:port]}} matching and the default-port rule.
> h3. Additional hardening: require https
> The asynchronous MDN delivery scheme is also chosen by the sender, and plain
> http is accepted, so the configured MDN credentials can be delivered over
> http even when the operator intended https. A new opt-in option
> {{asyncMdnRequireHttps}} on {{AS2Configuration}} (default {{false}}) is
> added: when set, an asynchronous MDN whose delivery address does not use
> https is refused before the connection is opened and before the configured
> credentials are attached. The option applies per consumer endpoint, like
> {{asyncMdnAllowedHosts}}. New JUnit tests cover: http refused when the option
> is set, https accepted when it is set, and http still accepted by default.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)