This is an automated email from the ASF dual-hosted git repository.
gnodet pushed a commit to branch camel-4.18.x
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/camel-4.18.x by this push:
new 0017726711dd [backport camel-4.18.x] CAMEL-26322: camel-as2 - scope
the async MDN allow-list to host and port, and add an option to require https
(#29055)
0017726711dd is described below
commit 0017726711dd6114f800f9d16c9671dbc9dcf526
Author: Guillaume Nodet <[email protected]>
AuthorDate: Wed Nov 4 09:27:33 2026 +0100
[backport camel-4.18.x] CAMEL-26322: camel-as2 - scope the async MDN
allow-list to host and port, and add an option to require https (#29055)
* [backport camel-4.18.x] CAMEL-26322: camel-as2 - scope the async MDN
allow-list to host and port, and add an option to require https
* fix: remove spurious this.sslContext assignment — field not declared in
backport
* fix: enforce requireHttps in send() and adapt test to backport API (no
SSLContext)
* CAMEL-26322: fix doc inaccuracies for asyncMdnAllowedHosts and
asyncMdnRequireHttps on camel-4.18.x
- asyncMdnAllowedHosts: bare-host entries match only port 80 (TLS not
supported);
remove '443 for https' from Javadoc, user docs and catalog JSON
- asyncMdnRequireHttps: clarify that only http is accepted in this branch;
TLS delivery of async MDNs is not yet implemented
- Add upgrade guide entry for the host-and-port matching behavior change
* fix: regenerate as2.json and AS2EndpointBuilderFactory to match Javadoc
fixes
* nit: wrap long Javadoc line in setAsyncMdnRequireHttps
* fix: align Javadoc wrapping in AS2 generated files to match regen output
CI's regen.sh detected comment wrap differences in AS2ServerConnection.java,
AS2Configuration.java, and the generated AS2EndpointBuilderFactory.java.
Apply the exact rewrapping the code generator produces to eliminate the
"uncommitted changes" CI failure.
* docs: add IPv6 bracket-notation migration note to 4.18.6 upgrade guide
---
.../org/apache/camel/catalog/components/as2.json | 33 ++--
.../as2/api/AS2AsynchronousMDNManager.java | 113 +++++++++--
.../component/as2/api/AS2ServerConnection.java | 54 +++++-
...2AsynchronousMDNManagerDeliveryAddressTest.java | 97 ++++++++-
.../AS2ConsumerConfigurationMdnSettingsTest.java | 19 ++
...rverManagerEndpointConfigurationConfigurer.java | 7 +
...ientManagerEndpointConfigurationConfigurer.java | 7 +
.../component/as2/AS2ConfigurationConfigurer.java | 7 +
.../camel/component/as2/AS2EndpointConfigurer.java | 7 +
.../camel/component/as2/AS2EndpointUriFactory.java | 3 +-
...rverManagerEndpointConfigurationConfigurer.java | 7 +
.../org/apache/camel/component/as2/as2.json | 33 ++--
.../src/main/docs/as2-component.adoc | 12 ++
.../camel/component/as2/AS2Configuration.java | 33 +++-
.../apache/camel/component/as2/AS2Consumer.java | 3 +-
.../as2/internal/AS2ConnectionHelper.java | 3 +-
.../as2/AS2AsyncMdnBasicAuthHeaderTest.java | 6 +-
.../as2/AS2AsyncMdnTokenAuthHeaderTest.java | 6 +-
.../as2/AS2ServerBasicAuthHeaderTest.java | 7 +-
.../as2/AS2ServerBearerAuthHeaderTest.java | 7 +-
.../AS2ServerTwoConsumerAsyncMdnSettingsTest.java | 21 +-
.../ROOT/pages/camel-4x-upgrade-guide-4_18.adoc | 9 +
.../endpoint/dsl/AS2EndpointBuilderFactory.java | 216 ++++++++++++++++++---
23 files changed, 605 insertions(+), 105 deletions(-)
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/as2.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/as2.json
index 92f53d024ce0..0edd6093f310 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/as2.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/as2.json
@@ -67,22 +67,23 @@
"exchangePattern": { "index": 31, "kind": "parameter", "displayName":
"Exchange Pattern", "group": "consumer (advanced)", "label":
"consumer,advanced", "required": false, "type": "enum", "javaType":
"org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut" ],
"deprecated": false, "autowired": false, "secret": false, "description": "Sets
the exchange pattern when the consumer creates an exchange." },
"lazyStartProducer": { "index": 32, "kind": "parameter", "displayName":
"Lazy Start Producer", "group": "producer (advanced)", "label":
"producer,advanced", "required": false, "type": "boolean", "javaType":
"boolean", "deprecated": false, "autowired": false, "secret": false,
"defaultValue": false, "description": "Whether the producer should be started
lazy (on the first message). By starting lazy you can use this to allow
CamelContext and routes to startup in situations where a produ [...]
"accessToken": { "index": 33, "kind": "parameter", "displayName": "Access
Token", "group": "security", "label": "security", "required": false, "type":
"string", "javaType": "java.lang.String", "deprecated": false, "autowired":
false, "secret": true, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The access token that is used by the client
for bearer authentication." },
- "asyncMdnAllowedHosts": { "index": 34, "kind": "parameter", "displayName":
"Async Mdn Allowed Hosts", "group": "security", "label": "security",
"required": false, "type": "string", "javaType": "java.lang.String",
"deprecated": false, "autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "Comma separated list of host names an
asynchronous MDN may be delivered to. The delivery [...]
- "decryptingPrivateKey": { "index": 35, "kind": "parameter", "displayName":
"Decrypting Private Key", "group": "security", "label": "security", "required":
false, "type": "object", "javaType": "java.security.PrivateKey", "deprecated":
false, "autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The key used to encrypt the EDI message." },
- "encryptingAlgorithm": { "index": 36, "kind": "parameter", "displayName":
"Encrypting Algorithm", "group": "security", "label": "security", "required":
false, "type": "enum", "javaType":
"org.apache.camel.component.as2.api.AS2EncryptionAlgorithm", "enum": [
"AES128_CBC", "AES192_CBC", "AES256_CBC", "AES128_CCM", "AES192_CCM",
"AES256_CCM", "AES128_GCM", "AES192_GCM", "AES256_GCM", "CAMELLIA128_CBC",
"CAMELLIA192_CBC", "CAMELLIA256_CBC", "CAST5_CBC", "DES_CBC", "DES_EDE3_CBC",
"GOST28 [...]
- "encryptingCertificateChain": { "index": 37, "kind": "parameter",
"displayName": "Encrypting Certificate Chain", "group": "security", "label":
"security", "required": false, "type": "object", "javaType":
"java.security.cert.Certificate[]", "deprecated": false, "autowired": false,
"secret": false, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The chain of certificates used to encrypt EDI
message." },
- "hostnameVerifier": { "index": 38, "kind": "parameter", "displayName":
"Hostname Verifier", "group": "security", "label": "security", "required":
false, "type": "object", "javaType": "javax.net.ssl.HostnameVerifier",
"deprecated": false, "autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "Set hostname verifier for SSL session." },
- "mdnAccessToken": { "index": 39, "kind": "parameter", "displayName": "Mdn
Access Token", "group": "security", "label": "security", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": true, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The access token that is used by the server
when it sends an async MDN. The option applies to the consu [...]
- "mdnPassword": { "index": 40, "kind": "parameter", "displayName": "Mdn
Password", "group": "security", "label": "security", "required": false, "type":
"string", "javaType": "java.lang.String", "deprecated": false, "autowired":
false, "secret": true, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The password that is used by the server for
basic authentication when it sends an async MDN. The option applie [...]
- "mdnUserName": { "index": 41, "kind": "parameter", "displayName": "Mdn
User Name", "group": "security", "label": "security", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": true, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The user-name that is used by the server for
basic authentication when it sends an async MDN. If options for [...]
- "password": { "index": 42, "kind": "parameter", "displayName": "Password",
"group": "security", "label": "security", "required": false, "type": "string",
"javaType": "java.lang.String", "deprecated": false, "autowired": false,
"secret": true, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The password that is used by the client for
basic authentication." },
- "signedReceiptMicAlgorithms": { "index": 43, "kind": "parameter",
"displayName": "Signed Receipt Mic Algorithms", "group": "security", "label":
"security", "required": false, "type": "string", "javaType":
"java.lang.String", "deprecated": false, "autowired": false, "secret": false,
"configurationClass": "org.apache.camel.component.as2.AS2Configuration",
"configurationField": "configuration", "description": "The list of algorithms,
in order of preference, requested to generate a messa [...]
- "signingAlgorithm": { "index": 44, "kind": "parameter", "displayName":
"Signing Algorithm", "group": "security", "label": "security", "required":
false, "type": "enum", "javaType":
"org.apache.camel.component.as2.api.AS2SignatureAlgorithm", "enum": [
"SHA3_224WITHRSA", "SHA3_256WITHRSA", "SHA3_384withRSA", "SHA3_512WITHRSA",
"MD5WITHRSA", "SHA1WITHRSA", "MD2WITHRSA", "SHA224WITHRSA", "SHA256WITHRSA",
"SHA384WITHRSA", "SHA512WITHRSA", "RIPEMD128WITHRSA", "RIPEMD160WITHRSA",
"RIPEMD256 [...]
- "signingCertificateChain": { "index": 45, "kind": "parameter",
"displayName": "Signing Certificate Chain", "group": "security", "label":
"security", "required": false, "type": "object", "javaType":
"java.security.cert.Certificate[]", "deprecated": false, "autowired": false,
"secret": false, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The chain of certificates used to sign EDI
message." },
- "signingPrivateKey": { "index": 46, "kind": "parameter", "displayName":
"Signing Private Key", "group": "security", "label": "security", "required":
false, "type": "object", "javaType": "java.security.PrivateKey", "deprecated":
false, "autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The key used to sign the EDI message." },
- "sslContext": { "index": 47, "kind": "parameter", "displayName": "Ssl
Context", "group": "security", "label": "security", "required": false, "type":
"object", "javaType": "javax.net.ssl.SSLContext", "deprecated": false,
"autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "Set SSL context for connection to remote
server." },
- "userName": { "index": 48, "kind": "parameter", "displayName": "User
Name", "group": "security", "label": "security", "required": false, "type":
"string", "javaType": "java.lang.String", "deprecated": false, "autowired":
false, "secret": true, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The user-name that is used by the client for
basic authentication. If options for basic authentication and bearer au [...]
- "validateSigningCertificateChain": { "index": 49, "kind": "parameter",
"displayName": "Validate Signing Certificate Chain", "group": "security",
"label": "security", "required": false, "type": "object", "javaType":
"java.security.cert.Certificate[]", "deprecated": false, "autowired": false,
"secret": false, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "Certificates to validate the message's
signature ag [...]
+ "asyncMdnAllowedHosts": { "index": 34, "kind": "parameter", "displayName":
"Async Mdn Allowed Hosts", "group": "security", "label": "security",
"required": false, "type": "string", "javaType": "java.lang.String",
"deprecated": false, "autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "Comma separated list of hosts an asynchronous
MDN may be delivered to. The delivery addre [...]
+ "asyncMdnRequireHttps": { "index": 35, "kind": "parameter", "displayName":
"Async Mdn Require Https", "group": "security", "label": "security",
"required": false, "type": "boolean", "javaType": "boolean", "deprecated":
false, "autowired": false, "secret": false, "defaultValue": false,
"configurationClass": "org.apache.camel.component.as2.AS2Configuration",
"configurationField": "configuration", "description": "Whether an asynchronous
MDN may only be delivered over https. The delivery [...]
+ "decryptingPrivateKey": { "index": 36, "kind": "parameter", "displayName":
"Decrypting Private Key", "group": "security", "label": "security", "required":
false, "type": "object", "javaType": "java.security.PrivateKey", "deprecated":
false, "autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The key used to encrypt the EDI message." },
+ "encryptingAlgorithm": { "index": 37, "kind": "parameter", "displayName":
"Encrypting Algorithm", "group": "security", "label": "security", "required":
false, "type": "enum", "javaType":
"org.apache.camel.component.as2.api.AS2EncryptionAlgorithm", "enum": [
"AES128_CBC", "AES192_CBC", "AES256_CBC", "AES128_CCM", "AES192_CCM",
"AES256_CCM", "AES128_GCM", "AES192_GCM", "AES256_GCM", "CAMELLIA128_CBC",
"CAMELLIA192_CBC", "CAMELLIA256_CBC", "CAST5_CBC", "DES_CBC", "DES_EDE3_CBC",
"GOST28 [...]
+ "encryptingCertificateChain": { "index": 38, "kind": "parameter",
"displayName": "Encrypting Certificate Chain", "group": "security", "label":
"security", "required": false, "type": "object", "javaType":
"java.security.cert.Certificate[]", "deprecated": false, "autowired": false,
"secret": false, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The chain of certificates used to encrypt EDI
message." },
+ "hostnameVerifier": { "index": 39, "kind": "parameter", "displayName":
"Hostname Verifier", "group": "security", "label": "security", "required":
false, "type": "object", "javaType": "javax.net.ssl.HostnameVerifier",
"deprecated": false, "autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "Set hostname verifier for SSL session." },
+ "mdnAccessToken": { "index": 40, "kind": "parameter", "displayName": "Mdn
Access Token", "group": "security", "label": "security", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": true, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The access token that is used by the server
when it sends an async MDN. The option applies to the consu [...]
+ "mdnPassword": { "index": 41, "kind": "parameter", "displayName": "Mdn
Password", "group": "security", "label": "security", "required": false, "type":
"string", "javaType": "java.lang.String", "deprecated": false, "autowired":
false, "secret": true, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The password that is used by the server for
basic authentication when it sends an async MDN. The option applie [...]
+ "mdnUserName": { "index": 42, "kind": "parameter", "displayName": "Mdn
User Name", "group": "security", "label": "security", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": true, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The user-name that is used by the server for
basic authentication when it sends an async MDN. If options for [...]
+ "password": { "index": 43, "kind": "parameter", "displayName": "Password",
"group": "security", "label": "security", "required": false, "type": "string",
"javaType": "java.lang.String", "deprecated": false, "autowired": false,
"secret": true, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The password that is used by the client for
basic authentication." },
+ "signedReceiptMicAlgorithms": { "index": 44, "kind": "parameter",
"displayName": "Signed Receipt Mic Algorithms", "group": "security", "label":
"security", "required": false, "type": "string", "javaType":
"java.lang.String", "deprecated": false, "autowired": false, "secret": false,
"configurationClass": "org.apache.camel.component.as2.AS2Configuration",
"configurationField": "configuration", "description": "The list of algorithms,
in order of preference, requested to generate a messa [...]
+ "signingAlgorithm": { "index": 45, "kind": "parameter", "displayName":
"Signing Algorithm", "group": "security", "label": "security", "required":
false, "type": "enum", "javaType":
"org.apache.camel.component.as2.api.AS2SignatureAlgorithm", "enum": [
"SHA3_224WITHRSA", "SHA3_256WITHRSA", "SHA3_384withRSA", "SHA3_512WITHRSA",
"MD5WITHRSA", "SHA1WITHRSA", "MD2WITHRSA", "SHA224WITHRSA", "SHA256WITHRSA",
"SHA384WITHRSA", "SHA512WITHRSA", "RIPEMD128WITHRSA", "RIPEMD160WITHRSA",
"RIPEMD256 [...]
+ "signingCertificateChain": { "index": 46, "kind": "parameter",
"displayName": "Signing Certificate Chain", "group": "security", "label":
"security", "required": false, "type": "object", "javaType":
"java.security.cert.Certificate[]", "deprecated": false, "autowired": false,
"secret": false, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The chain of certificates used to sign EDI
message." },
+ "signingPrivateKey": { "index": 47, "kind": "parameter", "displayName":
"Signing Private Key", "group": "security", "label": "security", "required":
false, "type": "object", "javaType": "java.security.PrivateKey", "deprecated":
false, "autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The key used to sign the EDI message." },
+ "sslContext": { "index": 48, "kind": "parameter", "displayName": "Ssl
Context", "group": "security", "label": "security", "required": false, "type":
"object", "javaType": "javax.net.ssl.SSLContext", "deprecated": false,
"autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "Set SSL context for connection to remote
server." },
+ "userName": { "index": 49, "kind": "parameter", "displayName": "User
Name", "group": "security", "label": "security", "required": false, "type":
"string", "javaType": "java.lang.String", "deprecated": false, "autowired":
false, "secret": true, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The user-name that is used by the client for
basic authentication. If options for basic authentication and bearer au [...]
+ "validateSigningCertificateChain": { "index": 50, "kind": "parameter",
"displayName": "Validate Signing Certificate Chain", "group": "security",
"label": "security", "required": false, "type": "object", "javaType":
"java.security.cert.Certificate[]", "deprecated": false, "autowired": false,
"secret": false, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "Certificates to validate the message's
signature ag [...]
},
"apis": {
"client": { "consumerOnly": false, "producerOnly": true, "description":
"Sends EDI Messages over HTTP", "methods": { "send": { "description": "Send
ediMessage to trading partner", "signatures": [
"org.apache.hc.core5.http.protocol.HttpCoreContext send(Object ediMessage,
String requestUri, String subject, String from, String as2From, String as2To,
org.apache.camel.component.as2.api.AS2MessageStructure as2MessageStructure,
String ediMessageContentType, String ediMessageCharset, String [...]
diff --git
a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2AsynchronousMDNManager.java
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2AsynchronousMDNManager.java
index ed8b3b2e709f..26cfe570414a 100644
---
a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2AsynchronousMDNManager.java
+++
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2AsynchronousMDNManager.java
@@ -98,6 +98,7 @@ public class AS2AsynchronousMDNManager {
private String password;
private String accessToken;
private String allowedHosts;
+ private boolean requireHttps;
/**
* @deprecated use
@@ -127,7 +128,22 @@ public class AS2AsynchronousMDNManager {
String password,
String accessToken,
String allowedHosts) {
+ this(as2Version, userAgent, senderFQDN, signingCertificateChain,
signingPrivateKey, userName, password,
+ accessToken, allowedHosts, false);
+ }
+
+ public AS2AsynchronousMDNManager(String as2Version,
+ String userAgent,
+ String senderFQDN,
+ Certificate[] signingCertificateChain,
+ PrivateKey signingPrivateKey,
+ String userName,
+ String password,
+ String accessToken,
+ String allowedHosts,
+ boolean requireHttps) {
this.allowedHosts = allowedHosts;
+ this.requireHttps = requireHttps;
this.signingCertificateChain = signingCertificateChain;
this.signingPrivateKey = signingPrivateKey;
this.userName = userName;
@@ -155,6 +171,14 @@ public class AS2AsynchronousMDNManager {
// header), so it is untrusted input that selects an outbound
destination.
URI uri = URI.create(recipientDeliveryAddress);
String scheme = uri.getScheme() == null ? null :
uri.getScheme().toLowerCase(Locale.US);
+ // When the operator requires https (asyncMdnRequireHttps), refuse a
plain-http delivery address before the
+ // connection is opened and before the credentials are attached, so
they are never written in cleartext to a
+ // sender-chosen destination.
+ if (requireHttps && !"https".equals(scheme)) {
+ throw new HttpException(
+ "Refusing to deliver the asynchronous MDN:
asyncMdnRequireHttps is set but the delivery address"
+ + " does not use https");
+ }
// Only http. This class delivers over a plain Socket and has no TLS
of any kind, so accepting https
// would mean writing the request - including the Authorization header
- in cleartext to the TLS port.
// https delivery has never worked here for that reason, so refusing
it removes nothing that functioned.
@@ -167,12 +191,15 @@ public class AS2AsynchronousMDNManager {
if (host == null) {
throw new HttpException("Refusing to deliver the asynchronous MDN:
the delivery address has no host");
}
- int port = uri.getPort() != -1 ? uri.getPort() : 80;
+ int defaultPort = 80;
+ int port = uri.getPort() != -1 ? uri.getPort() : defaultPort;
- boolean hostIsAllowed = isAllowedHost(host);
- if (allowedHosts != null && !allowedHosts.isBlank() && !hostIsAllowed)
{
+ // Match the full authority - host and port - of the delivery address
against the allow-list, not the host
+ // alone, so a listed host does not authorise every port on that host.
+ boolean authorityIsAllowed = isAllowedAuthority(host, port,
defaultPort);
+ if (allowedHosts != null && !allowedHosts.isBlank() &&
!authorityIsAllowed) {
throw new HttpException(
- "Refusing to deliver the asynchronous MDN: the delivery
address host is not in asyncMdnAllowedHosts");
+ "Refusing to deliver the asynchronous MDN: the delivery
address is not in asyncMdnAllowedHosts");
}
int buffSize = 8 * 1024;
@@ -189,14 +216,14 @@ public class AS2AsynchronousMDNManager {
ClassicHttpRequest request = new BasicClassicHttpRequest("POST",
uri);
request.setHeader(AS2Header.CONTENT_TYPE, contentType);
- // Credentials are only attached to a host the operator has
vouched for. Without an allow-list the
- // destination is entirely sender-chosen, so the MDN is still
delivered but without them.
- if (hostIsAllowed) {
+ // Credentials are only attached to an authority - host and port -
the operator has vouched for. Without an
+ // allow-list the destination is entirely sender-chosen, so the
MDN is still delivered but without them.
+ if (authorityIsAllowed) {
AS2HeaderUtils.addAuthorizationHeader(request, userName,
password, accessToken);
} else if (userName != null || accessToken != null) {
- LOG.warn("Asynchronous MDN credentials not sent to
sender-supplied host {}:"
+ LOG.warn("Asynchronous MDN credentials not sent to
sender-supplied authority {}:"
+ " set asyncMdnAllowedHosts to authorise it",
- host);
+ formatAuthority(host, port));
}
httpContext.setAttribute(HttpCoreContext.HTTP_REQUEST, request);
multipartMimeEntity.setMainBody(true);
@@ -228,18 +255,82 @@ public class AS2AsynchronousMDNManager {
return host;
}
- private boolean isAllowedHost(String host) {
+ /**
+ * Writes a delivery authority the way an {@code asyncMdnAllowedHosts}
entry is written, so a log message names an
+ * entry the operator can copy. The host has been through normalizeHost,
so an IPv6 literal (the only host that
+ * contains a colon) is put back in square brackets ({@code [::1]:8443}):
unbracketed, {@code ::1:8443} would be
+ * read as another IPv6 address on the default port. Any other host is
written as {@code host:port}.
+ */
+ static String formatAuthority(String host, int port) {
+ return host.indexOf(':') >= 0 ? "[" + host + "]:" + port : host + ":"
+ port;
+ }
+
+ /**
+ * Matches the resolved delivery authority - host and port - against
{@code asyncMdnAllowedHosts}. Each entry is a
+ * host with an optional port ({@code host} or {@code host:port}); a
bare-host entry matches only the default port
+ * for the scheme ({@code defaultPort}), so a listed host does not
authorise every port on that host.
+ */
+ boolean isAllowedAuthority(String host, int port, int defaultPort) {
if (allowedHosts == null || allowedHosts.isBlank()) {
return false;
}
for (String allowed : allowedHosts.split(",")) {
- if (allowed.trim().equalsIgnoreCase(host)) {
+ String entry = allowed.trim();
+ if (!entry.isEmpty() && authorityMatches(entry, host, port,
defaultPort)) {
return true;
}
}
return false;
}
+ private static boolean authorityMatches(String entry, String host, int
port, int defaultPort) {
+ String entryHost;
+ int entryPort;
+ if (entry.charAt(0) == '[') {
+ // bracketed IPv6 literal, optionally followed by :port
+ int close = entry.indexOf(']');
+ if (close < 0) {
+ return false;
+ }
+ entryHost = entry.substring(1, close);
+ entryPort = defaultPort;
+ if (close + 1 < entry.length()) {
+ if (entry.charAt(close + 1) != ':') {
+ return false;
+ }
+ Integer parsed = parsePort(entry.substring(close + 2));
+ if (parsed == null) {
+ return false;
+ }
+ entryPort = parsed;
+ }
+ } else {
+ int colon = entry.indexOf(':');
+ if (colon >= 0 && entry.indexOf(':', colon + 1) < 0) {
+ // a single colon separates host and port; an unbracketed IPv6
literal has several and keeps the default
+ entryHost = entry.substring(0, colon);
+ Integer parsed = parsePort(entry.substring(colon + 1));
+ if (parsed == null) {
+ return false;
+ }
+ entryPort = parsed;
+ } else {
+ entryHost = entry;
+ entryPort = defaultPort;
+ }
+ }
+ return entryPort == port && entryHost.equalsIgnoreCase(host);
+ }
+
+ private static Integer parsePort(String value) {
+ try {
+ int parsed = Integer.parseInt(value.trim());
+ return parsed >= 0 && parsed <= 65535 ? parsed : null;
+ } catch (NumberFormatException e) {
+ return null;
+ }
+ }
+
private HttpResponse send(HttpClientConnection httpConnection,
ClassicHttpRequest request, HttpCoreContext httpContext)
throws HttpException, IOException {
diff --git
a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ServerConnection.java
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ServerConnection.java
index 05f47c4a49d7..b05c24eb342d 100644
---
a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ServerConnection.java
+++
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ServerConnection.java
@@ -138,6 +138,7 @@ public class AS2ServerConnection {
private final String mdnPassword;
private final String mdnAccessToken;
private final String asyncMdnAllowedHosts;
+ private final boolean asyncMdnRequireHttps;
/**
* Creates a configuration without asynchronous MDN settings: an
asynchronous MDN for a request matched by it is
@@ -168,6 +169,26 @@ public class AS2ServerConnection {
String mdnPassword,
String mdnAccessToken,
String asyncMdnAllowedHosts) {
+ this(signingAlgorithm, signingCertificateChain, signingPrivateKey,
decryptingPrivateKey,
+ validateSigningCertificateChain, mdnUserName, mdnPassword,
mdnAccessToken, asyncMdnAllowedHosts, false);
+ }
+
+ /**
+ * Creates a configuration that additionally requires asynchronous MDN
delivery to use https
+ * ({@code asyncMdnRequireHttps}): a delivery address matched by it
that does not use https is refused before
+ * the connection is opened and before the credentials are attached.
+ */
+ public AS2ConsumerConfiguration(
+ AS2SignatureAlgorithm signingAlgorithm,
+ Certificate[] signingCertificateChain,
+ PrivateKey signingPrivateKey,
+ PrivateKey decryptingPrivateKey,
+ Certificate[]
validateSigningCertificateChain,
+ String mdnUserName,
+ String mdnPassword,
+ String mdnAccessToken,
+ String asyncMdnAllowedHosts,
+ boolean asyncMdnRequireHttps) {
this.signingAlgorithm = signingAlgorithm;
this.signingCertificateChain = signingCertificateChain;
this.signingPrivateKey = signingPrivateKey;
@@ -177,6 +198,7 @@ public class AS2ServerConnection {
this.mdnPassword = mdnPassword;
this.mdnAccessToken = mdnAccessToken;
this.asyncMdnAllowedHosts = asyncMdnAllowedHosts;
+ this.asyncMdnRequireHttps = asyncMdnRequireHttps;
}
// Getters
@@ -215,6 +237,10 @@ public class AS2ServerConnection {
public String getAsyncMdnAllowedHosts() {
return asyncMdnAllowedHosts;
}
+
+ public boolean isAsyncMdnRequireHttps() {
+ return asyncMdnRequireHttps;
+ }
}
/**
@@ -543,7 +569,8 @@ public class AS2ServerConnection {
config.getMdnUserName(),
config.getMdnPassword(),
config.getMdnAccessToken(),
- config.getAsyncMdnAllowedHosts());
+ config.getAsyncMdnAllowedHosts(),
+ config.isAsyncMdnRequireHttps());
HttpRequest request =
coreContext.getAttribute(HttpCoreContext.HTTP_REQUEST, HttpRequest.class);
AS2SignedDataGenerator gen =
ResponseMDN.createSigningGenerator(
@@ -624,6 +651,28 @@ public class AS2ServerConnection {
String accessToken,
String asyncMdnAllowedHosts)
throws IOException
{
+ this(as2Version, originServer, serverFqdn, serverPortNumber,
signingAlgorithm, signingCertificateChain,
+ signingPrivateKey, decryptingPrivateKey, mdnMessageTemplate,
validateSigningCertificateChain, sslContext,
+ userName, password, accessToken, asyncMdnAllowedHosts, false);
+ }
+
+ public AS2ServerConnection(String as2Version,
+ String originServer,
+ String serverFqdn,
+ Integer serverPortNumber,
+ AS2SignatureAlgorithm signingAlgorithm,
+ Certificate[] signingCertificateChain,
+ PrivateKey signingPrivateKey,
+ PrivateKey decryptingPrivateKey,
+ String mdnMessageTemplate,
+ Certificate[] validateSigningCertificateChain,
+ SSLContext sslContext,
+ String userName,
+ String password,
+ String accessToken,
+ String asyncMdnAllowedHosts,
+ boolean asyncMdnRequireHttps)
+ throws
IOException {
this.as2Version = ObjectHelper.notNull(as2Version, "as2Version");
this.originServer = ObjectHelper.notNull(originServer, "userAgent");
this.serverFqdn = ObjectHelper.notNull(serverFqdn, "serverFqdn");
@@ -643,7 +692,8 @@ public class AS2ServerConnection {
userName,
password,
accessToken,
- asyncMdnAllowedHosts);
+ asyncMdnAllowedHosts,
+ asyncMdnRequireHttps);
registerConsumerConfiguration("/", consumerConfig);
listenerService = new RequestListenerService(
diff --git
a/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/AS2AsynchronousMDNManagerDeliveryAddressTest.java
b/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/AS2AsynchronousMDNManagerDeliveryAddressTest.java
index 09ea7b6cca42..6b1cf887be58 100644
---
a/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/AS2AsynchronousMDNManagerDeliveryAddressTest.java
+++
b/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/AS2AsynchronousMDNManagerDeliveryAddressTest.java
@@ -21,6 +21,7 @@ import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.HttpException;
import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -71,16 +72,102 @@ class AS2AsynchronousMDNManagerDeliveryAddressTest {
}
@Test
- void anIpv6AllowListEntryIsMatchedWithoutItsBrackets() {
- // URI.getHost() yields "[::1]", but an operator writes "::1" in the
allow-list
- Exception e = assertThrows(Exception.class, () ->
deliver("http://[::1]:1/receipts", "::1"));
+ void anIpv6AllowListEntryIsMatchedOnHostAndPort() {
+ // URI.getHost() yields "[::1]"; the operator lists the bracketed
literal and its port as "[::1]:1"
+ Exception e = assertThrows(Exception.class, () ->
deliver("http://[::1]:1/receipts", "[::1]:1"));
assertTrue(!(e instanceof HttpException) ||
!e.getMessage().contains("asyncMdnAllowedHosts"),
- "an IPv6 literal should match its unbracketed allow-list
entry: " + e.getMessage());
+ "an IPv6 literal should match its allow-list entry on host and
port: " + e.getMessage());
+ }
+
+ /**
+ * An entry may pin the port in host:port form. A delivery address whose
host and port both match the entry is
+ * accepted, so it gets past the address checks and fails on the
connection instead - which is what tells us the
+ * address itself was accepted.
+ */
+ @Test
+ void aMatchingHostAndPortIsAccepted() {
+ Exception e = assertThrows(Exception.class, () ->
deliver("http://localhost:1/receipts", "localhost:1"));
+ assertTrue(!(e instanceof HttpException) ||
!e.getMessage().contains("asyncMdnAllowedHosts"),
+ "a delivery matching an allow-list entry on host and port must
be accepted: " + e.getMessage());
+ }
+
+ /**
+ * The entry lists the host only, so it matches the default port (80 for
http). A delivery to another port on that
+ * host is refused before the connection is opened, and the credentials
are not attached.
+ */
+ @Test
+ void aDifferentPortOnAListedHostIsRefused() {
+ HttpException e = assertThrows(HttpException.class,
+ () -> deliver("http://partner.example:8443/receipts",
ALLOWED));
+ assertTrue(e.getMessage().contains("asyncMdnAllowedHosts"),
"unexpected message: " + e.getMessage());
+ }
+
+ /**
+ * A bare-host entry matches the default port for the scheme (80 for http,
443 for https).
+ */
+ @Test
+ void aBareHostEntryMatchesTheDefaultPort() {
+ AS2AsynchronousMDNManager manager = new AS2AsynchronousMDNManager(
+ "1.1", "Camel", "sender.example.com", null, null, "user",
"password", null, ALLOWED,
+ false);
+ assertTrue(manager.isAllowedAuthority("partner.example", 80, 80),
+ "a bare-host entry must match the default port for the
scheme");
+ }
+
+ /**
+ * When credentials are withheld, the warning names the delivery authority
as an asyncMdnAllowedHosts entry the
+ * operator can copy. An IPv6 literal is written in square brackets:
unbracketed, ::1:8443 is itself an IPv6 address
+ * and the entry would be read as that host on the default port.
+ */
+ @Test
+ void theWarningNamesTheAuthorityAsAnAllowListEntry() {
+ assertEquals("partner.example:4080",
AS2AsynchronousMDNManager.formatAuthority("partner.example", 4080));
+ assertEquals("[::1]:8443",
AS2AsynchronousMDNManager.formatAuthority("::1", 8443));
+
+ for (String[] authority : new String[][] { { "partner.example", "4080"
}, { "::1", "8443" } }) {
+ String host = authority[0];
+ int port = Integer.parseInt(authority[1]);
+ AS2AsynchronousMDNManager manager = new AS2AsynchronousMDNManager(
+ "1.1", "Camel", "sender.example.com", null, null, "user",
"password", null,
+ AS2AsynchronousMDNManager.formatAuthority(host, port),
false);
+ assertTrue(manager.isAllowedAuthority(host, port, 80),
+ "the entry the warning names must authorise the authority
it was written for: " + host + " " + port);
+ }
+ }
+
+ /**
+ * With asyncMdnRequireHttps set, a plain-http delivery address is refused
before the connection is opened and
+ * before the credentials are attached, even when its host is on the
allow-list, so the credentials are never
+ * written in cleartext to a sender-chosen address.
+ */
+ @Test
+ void httpIsRefusedWhenHttpsIsRequired() {
+ HttpException e = assertThrows(HttpException.class,
+ () -> deliver("http://partner.example/receipts", ALLOWED,
true));
+ assertTrue(e.getMessage().contains("asyncMdnRequireHttps"),
"unexpected message: " + e.getMessage());
+ }
+
+ /**
+ * By default asyncMdnRequireHttps is not set, so a plain-http delivery
address is still accepted (it gets past the
+ * scheme checks and fails on the connection instead): the control is
opt-in and does not change the default.
+ */
+ @Test
+ void httpIsAcceptedWhenHttpsIsNotRequired() {
+ Exception e = assertThrows(Exception.class,
+ () -> deliver("http://localhost:1/receipts", "localhost:1"));
+ assertTrue(!(e instanceof HttpException) ||
!e.getMessage().contains("asyncMdnRequireHttps"),
+ "http must be accepted when asyncMdnRequireHttps is not set: "
+ e.getMessage());
}
private static void deliver(String deliveryAddress, String allowedHosts)
throws Exception {
+ deliver(deliveryAddress, allowedHosts, false);
+ }
+
+ private static void deliver(String deliveryAddress, String allowedHosts,
boolean requireHttps)
+ throws Exception {
AS2AsynchronousMDNManager manager = new AS2AsynchronousMDNManager(
- "1.1", "Camel", "sender.example.com", null, null, "user",
"password", null, allowedHosts);
+ "1.1", "Camel", "sender.example.com", null, null, "user",
"password", null, allowedHosts,
+ requireHttps);
manager.send(new TestEntity(), AS2MimeType.MULTIPART_REPORT,
deliveryAddress);
}
diff --git
a/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/AS2ConsumerConfigurationMdnSettingsTest.java
b/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/AS2ConsumerConfigurationMdnSettingsTest.java
index 1a297f6a10b3..e37bdcbb40c9 100644
---
a/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/AS2ConsumerConfigurationMdnSettingsTest.java
+++
b/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/AS2ConsumerConfigurationMdnSettingsTest.java
@@ -20,7 +20,9 @@ import
org.apache.camel.component.as2.api.AS2ServerConnection.AS2ConsumerConfigu
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* The asynchronous MDN settings (the credentials attached to an asynchronous
MDN and the hosts it may be delivered to)
@@ -40,6 +42,21 @@ class AS2ConsumerConfigurationMdnSettingsTest {
assertEquals("password", config.getMdnPassword());
assertEquals("token", config.getMdnAccessToken());
assertEquals("receipts.example.com", config.getAsyncMdnAllowedHosts());
+ assertFalse(config.isAsyncMdnRequireHttps());
+ }
+
+ @Test
+ void configurationWithRequireHttps() {
+ AS2ConsumerConfiguration config = new AS2ConsumerConfiguration(
+ AS2SignatureAlgorithm.SHA256WITHRSA, null, null, null, null,
+ "user", "password", "token", "receipts.example.com", true);
+
+ assertEquals(AS2SignatureAlgorithm.SHA256WITHRSA,
config.getSigningAlgorithm());
+ assertEquals("user", config.getMdnUserName());
+ assertEquals("password", config.getMdnPassword());
+ assertEquals("token", config.getMdnAccessToken());
+ assertEquals("receipts.example.com", config.getAsyncMdnAllowedHosts());
+ assertTrue(config.isAsyncMdnRequireHttps());
}
@Test
@@ -51,6 +68,7 @@ class AS2ConsumerConfigurationMdnSettingsTest {
assertNull(config.getMdnPassword());
assertNull(config.getMdnAccessToken());
assertNull(config.getAsyncMdnAllowedHosts());
+ assertFalse(config.isAsyncMdnRequireHttps());
}
@Test
@@ -65,6 +83,7 @@ class AS2ConsumerConfigurationMdnSettingsTest {
assertEquals("password", fallback.getMdnPassword());
assertEquals("token", fallback.getMdnAccessToken());
assertEquals("receipts.example.com",
fallback.getAsyncMdnAllowedHosts());
+ assertFalse(fallback.isAsyncMdnRequireHttps());
// a consumer registered for another path keeps its own settings,
not the fallback's
connection.registerConsumerConfiguration("/partner", new
AS2ConsumerConfiguration(
diff --git
a/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2AsyncMDNServerManagerEndpointConfigurationConfigurer.java
b/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2AsyncMDNServerManagerEndpointConfigurationConfigurer.java
index b5d43287bf4d..8f98d6e462f5 100644
---
a/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2AsyncMDNServerManagerEndpointConfigurationConfigurer.java
+++
b/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2AsyncMDNServerManagerEndpointConfigurationConfigurer.java
@@ -30,6 +30,7 @@ public class
AS2AsyncMDNServerManagerEndpointConfigurationConfigurer extends org
map.put("As2Version", java.lang.String.class);
map.put("AsyncMdnAllowedHosts", java.lang.String.class);
map.put("AsyncMdnPortNumber", java.lang.Integer.class);
+ map.put("AsyncMdnRequireHttps", boolean.class);
map.put("AttachedFileName", java.lang.String.class);
map.put("ClientFqdn", java.lang.String.class);
map.put("CompressionAlgorithm",
org.apache.camel.component.as2.api.AS2CompressionAlgorithm.class);
@@ -92,6 +93,8 @@ public class
AS2AsyncMDNServerManagerEndpointConfigurationConfigurer extends org
case "asyncMdnAllowedHosts":
target.setAsyncMdnAllowedHosts(property(camelContext, java.lang.String.class,
value)); return true;
case "asyncmdnportnumber":
case "asyncMdnPortNumber":
target.setAsyncMdnPortNumber(property(camelContext, java.lang.Integer.class,
value)); return true;
+ case "asyncmdnrequirehttps":
+ case "asyncMdnRequireHttps":
target.setAsyncMdnRequireHttps(property(camelContext, boolean.class, value));
return true;
case "attachedfilename":
case "attachedFileName":
target.setAttachedFileName(property(camelContext, java.lang.String.class,
value)); return true;
case "clientfqdn":
@@ -194,6 +197,8 @@ public class
AS2AsyncMDNServerManagerEndpointConfigurationConfigurer extends org
case "asyncMdnAllowedHosts": return java.lang.String.class;
case "asyncmdnportnumber":
case "asyncMdnPortNumber": return java.lang.Integer.class;
+ case "asyncmdnrequirehttps":
+ case "asyncMdnRequireHttps": return boolean.class;
case "attachedfilename":
case "attachedFileName": return java.lang.String.class;
case "clientfqdn":
@@ -292,6 +297,8 @@ public class
AS2AsyncMDNServerManagerEndpointConfigurationConfigurer extends org
case "asyncMdnAllowedHosts": return target.getAsyncMdnAllowedHosts();
case "asyncmdnportnumber":
case "asyncMdnPortNumber": return target.getAsyncMdnPortNumber();
+ case "asyncmdnrequirehttps":
+ case "asyncMdnRequireHttps": return target.isAsyncMdnRequireHttps();
case "attachedfilename":
case "attachedFileName": return target.getAttachedFileName();
case "clientfqdn":
diff --git
a/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2ClientManagerEndpointConfigurationConfigurer.java
b/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2ClientManagerEndpointConfigurationConfigurer.java
index 6712d20d0868..1e6607ad880c 100644
---
a/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2ClientManagerEndpointConfigurationConfigurer.java
+++
b/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2ClientManagerEndpointConfigurationConfigurer.java
@@ -30,6 +30,7 @@ public class AS2ClientManagerEndpointConfigurationConfigurer
extends org.apache.
map.put("As2Version", java.lang.String.class);
map.put("AsyncMdnAllowedHosts", java.lang.String.class);
map.put("AsyncMdnPortNumber", java.lang.Integer.class);
+ map.put("AsyncMdnRequireHttps", boolean.class);
map.put("AttachedFileName", java.lang.String.class);
map.put("ClientFqdn", java.lang.String.class);
map.put("CompressionAlgorithm",
org.apache.camel.component.as2.api.AS2CompressionAlgorithm.class);
@@ -93,6 +94,8 @@ public class AS2ClientManagerEndpointConfigurationConfigurer
extends org.apache.
case "asyncMdnAllowedHosts":
target.setAsyncMdnAllowedHosts(property(camelContext, java.lang.String.class,
value)); return true;
case "asyncmdnportnumber":
case "asyncMdnPortNumber":
target.setAsyncMdnPortNumber(property(camelContext, java.lang.Integer.class,
value)); return true;
+ case "asyncmdnrequirehttps":
+ case "asyncMdnRequireHttps":
target.setAsyncMdnRequireHttps(property(camelContext, boolean.class, value));
return true;
case "attachedfilename":
case "attachedFileName":
target.setAttachedFileName(property(camelContext, java.lang.String.class,
value)); return true;
case "clientfqdn":
@@ -197,6 +200,8 @@ public class
AS2ClientManagerEndpointConfigurationConfigurer extends org.apache.
case "asyncMdnAllowedHosts": return java.lang.String.class;
case "asyncmdnportnumber":
case "asyncMdnPortNumber": return java.lang.Integer.class;
+ case "asyncmdnrequirehttps":
+ case "asyncMdnRequireHttps": return boolean.class;
case "attachedfilename":
case "attachedFileName": return java.lang.String.class;
case "clientfqdn":
@@ -297,6 +302,8 @@ public class
AS2ClientManagerEndpointConfigurationConfigurer extends org.apache.
case "asyncMdnAllowedHosts": return target.getAsyncMdnAllowedHosts();
case "asyncmdnportnumber":
case "asyncMdnPortNumber": return target.getAsyncMdnPortNumber();
+ case "asyncmdnrequirehttps":
+ case "asyncMdnRequireHttps": return target.isAsyncMdnRequireHttps();
case "attachedfilename":
case "attachedFileName": return target.getAttachedFileName();
case "clientfqdn":
diff --git
a/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2ConfigurationConfigurer.java
b/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2ConfigurationConfigurer.java
index 44315e8155e5..0f951505bafa 100644
---
a/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2ConfigurationConfigurer.java
+++
b/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2ConfigurationConfigurer.java
@@ -30,6 +30,7 @@ public class AS2ConfigurationConfigurer extends
org.apache.camel.support.compone
map.put("As2Version", java.lang.String.class);
map.put("AsyncMdnAllowedHosts", java.lang.String.class);
map.put("AsyncMdnPortNumber", java.lang.Integer.class);
+ map.put("AsyncMdnRequireHttps", boolean.class);
map.put("AttachedFileName", java.lang.String.class);
map.put("ClientFqdn", java.lang.String.class);
map.put("CompressionAlgorithm",
org.apache.camel.component.as2.api.AS2CompressionAlgorithm.class);
@@ -91,6 +92,8 @@ public class AS2ConfigurationConfigurer extends
org.apache.camel.support.compone
case "asyncMdnAllowedHosts":
target.setAsyncMdnAllowedHosts(property(camelContext, java.lang.String.class,
value)); return true;
case "asyncmdnportnumber":
case "asyncMdnPortNumber":
target.setAsyncMdnPortNumber(property(camelContext, java.lang.Integer.class,
value)); return true;
+ case "asyncmdnrequirehttps":
+ case "asyncMdnRequireHttps":
target.setAsyncMdnRequireHttps(property(camelContext, boolean.class, value));
return true;
case "attachedfilename":
case "attachedFileName":
target.setAttachedFileName(property(camelContext, java.lang.String.class,
value)); return true;
case "clientfqdn":
@@ -191,6 +194,8 @@ public class AS2ConfigurationConfigurer extends
org.apache.camel.support.compone
case "asyncMdnAllowedHosts": return java.lang.String.class;
case "asyncmdnportnumber":
case "asyncMdnPortNumber": return java.lang.Integer.class;
+ case "asyncmdnrequirehttps":
+ case "asyncMdnRequireHttps": return boolean.class;
case "attachedfilename":
case "attachedFileName": return java.lang.String.class;
case "clientfqdn":
@@ -287,6 +292,8 @@ public class AS2ConfigurationConfigurer extends
org.apache.camel.support.compone
case "asyncMdnAllowedHosts": return target.getAsyncMdnAllowedHosts();
case "asyncmdnportnumber":
case "asyncMdnPortNumber": return target.getAsyncMdnPortNumber();
+ case "asyncmdnrequirehttps":
+ case "asyncMdnRequireHttps": return target.isAsyncMdnRequireHttps();
case "attachedfilename":
case "attachedFileName": return target.getAttachedFileName();
case "clientfqdn":
diff --git
a/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2EndpointConfigurer.java
b/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2EndpointConfigurer.java
index 0eab1fb6e4b0..847fdb0a2223 100644
---
a/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2EndpointConfigurer.java
+++
b/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2EndpointConfigurer.java
@@ -57,6 +57,7 @@ public class AS2EndpointConfigurer extends
PropertyConfigurerSupport implements
map.put("LazyStartProducer", boolean.class);
map.put("AccessToken", java.lang.String.class);
map.put("AsyncMdnAllowedHosts", java.lang.String.class);
+ map.put("AsyncMdnRequireHttps", boolean.class);
map.put("DecryptingPrivateKey", java.security.PrivateKey.class);
map.put("EncryptingAlgorithm",
org.apache.camel.component.as2.api.AS2EncryptionAlgorithm.class);
map.put("EncryptingCertificateChain",
java.security.cert.Certificate[].class);
@@ -93,6 +94,8 @@ public class AS2EndpointConfigurer extends
PropertyConfigurerSupport implements
case "asyncMdnAllowedHosts":
target.getConfiguration().setAsyncMdnAllowedHosts(property(camelContext,
java.lang.String.class, value)); return true;
case "asyncmdnportnumber":
case "asyncMdnPortNumber":
target.getConfiguration().setAsyncMdnPortNumber(property(camelContext,
java.lang.Integer.class, value)); return true;
+ case "asyncmdnrequirehttps":
+ case "asyncMdnRequireHttps":
target.getConfiguration().setAsyncMdnRequireHttps(property(camelContext,
boolean.class, value)); return true;
case "attachedfilename":
case "attachedFileName":
target.getConfiguration().setAttachedFileName(property(camelContext,
java.lang.String.class, value)); return true;
case "clientfqdn":
@@ -197,6 +200,8 @@ public class AS2EndpointConfigurer extends
PropertyConfigurerSupport implements
case "asyncMdnAllowedHosts": return java.lang.String.class;
case "asyncmdnportnumber":
case "asyncMdnPortNumber": return java.lang.Integer.class;
+ case "asyncmdnrequirehttps":
+ case "asyncMdnRequireHttps": return boolean.class;
case "attachedfilename":
case "attachedFileName": return java.lang.String.class;
case "clientfqdn":
@@ -297,6 +302,8 @@ public class AS2EndpointConfigurer extends
PropertyConfigurerSupport implements
case "asyncMdnAllowedHosts": return
target.getConfiguration().getAsyncMdnAllowedHosts();
case "asyncmdnportnumber":
case "asyncMdnPortNumber": return
target.getConfiguration().getAsyncMdnPortNumber();
+ case "asyncmdnrequirehttps":
+ case "asyncMdnRequireHttps": return
target.getConfiguration().isAsyncMdnRequireHttps();
case "attachedfilename":
case "attachedFileName": return
target.getConfiguration().getAttachedFileName();
case "clientfqdn":
diff --git
a/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2EndpointUriFactory.java
b/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2EndpointUriFactory.java
index 0d45c9920fff..45fab9f28fee 100644
---
a/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2EndpointUriFactory.java
+++
b/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2EndpointUriFactory.java
@@ -23,7 +23,7 @@ public class AS2EndpointUriFactory extends
org.apache.camel.support.component.En
private static final Set<String> SECRET_PROPERTY_NAMES;
private static final Map<String, String> MULTI_VALUE_PREFIXES;
static {
- Set<String> props = new HashSet<>(53);
+ Set<String> props = new HashSet<>(54);
props.add("accessToken");
props.add("apiName");
props.add("as2From");
@@ -32,6 +32,7 @@ public class AS2EndpointUriFactory extends
org.apache.camel.support.component.En
props.add("as2Version");
props.add("asyncMdnAllowedHosts");
props.add("asyncMdnPortNumber");
+ props.add("asyncMdnRequireHttps");
props.add("attachedFileName");
props.add("clientFqdn");
props.add("compressionAlgorithm");
diff --git
a/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2ServerManagerEndpointConfigurationConfigurer.java
b/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2ServerManagerEndpointConfigurationConfigurer.java
index da0d11a61f11..0b1bcf7206e0 100644
---
a/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2ServerManagerEndpointConfigurationConfigurer.java
+++
b/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2ServerManagerEndpointConfigurationConfigurer.java
@@ -30,6 +30,7 @@ public class AS2ServerManagerEndpointConfigurationConfigurer
extends org.apache.
map.put("As2Version", java.lang.String.class);
map.put("AsyncMdnAllowedHosts", java.lang.String.class);
map.put("AsyncMdnPortNumber", java.lang.Integer.class);
+ map.put("AsyncMdnRequireHttps", boolean.class);
map.put("AttachedFileName", java.lang.String.class);
map.put("ClientFqdn", java.lang.String.class);
map.put("CompressionAlgorithm",
org.apache.camel.component.as2.api.AS2CompressionAlgorithm.class);
@@ -92,6 +93,8 @@ public class AS2ServerManagerEndpointConfigurationConfigurer
extends org.apache.
case "asyncMdnAllowedHosts":
target.setAsyncMdnAllowedHosts(property(camelContext, java.lang.String.class,
value)); return true;
case "asyncmdnportnumber":
case "asyncMdnPortNumber":
target.setAsyncMdnPortNumber(property(camelContext, java.lang.Integer.class,
value)); return true;
+ case "asyncmdnrequirehttps":
+ case "asyncMdnRequireHttps":
target.setAsyncMdnRequireHttps(property(camelContext, boolean.class, value));
return true;
case "attachedfilename":
case "attachedFileName":
target.setAttachedFileName(property(camelContext, java.lang.String.class,
value)); return true;
case "clientfqdn":
@@ -194,6 +197,8 @@ public class
AS2ServerManagerEndpointConfigurationConfigurer extends org.apache.
case "asyncMdnAllowedHosts": return java.lang.String.class;
case "asyncmdnportnumber":
case "asyncMdnPortNumber": return java.lang.Integer.class;
+ case "asyncmdnrequirehttps":
+ case "asyncMdnRequireHttps": return boolean.class;
case "attachedfilename":
case "attachedFileName": return java.lang.String.class;
case "clientfqdn":
@@ -292,6 +297,8 @@ public class
AS2ServerManagerEndpointConfigurationConfigurer extends org.apache.
case "asyncMdnAllowedHosts": return target.getAsyncMdnAllowedHosts();
case "asyncmdnportnumber":
case "asyncMdnPortNumber": return target.getAsyncMdnPortNumber();
+ case "asyncmdnrequirehttps":
+ case "asyncMdnRequireHttps": return target.isAsyncMdnRequireHttps();
case "attachedfilename":
case "attachedFileName": return target.getAttachedFileName();
case "clientfqdn":
diff --git
a/components/camel-as2/camel-as2-component/src/generated/resources/META-INF/org/apache/camel/component/as2/as2.json
b/components/camel-as2/camel-as2-component/src/generated/resources/META-INF/org/apache/camel/component/as2/as2.json
index 92f53d024ce0..0edd6093f310 100644
---
a/components/camel-as2/camel-as2-component/src/generated/resources/META-INF/org/apache/camel/component/as2/as2.json
+++
b/components/camel-as2/camel-as2-component/src/generated/resources/META-INF/org/apache/camel/component/as2/as2.json
@@ -67,22 +67,23 @@
"exchangePattern": { "index": 31, "kind": "parameter", "displayName":
"Exchange Pattern", "group": "consumer (advanced)", "label":
"consumer,advanced", "required": false, "type": "enum", "javaType":
"org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut" ],
"deprecated": false, "autowired": false, "secret": false, "description": "Sets
the exchange pattern when the consumer creates an exchange." },
"lazyStartProducer": { "index": 32, "kind": "parameter", "displayName":
"Lazy Start Producer", "group": "producer (advanced)", "label":
"producer,advanced", "required": false, "type": "boolean", "javaType":
"boolean", "deprecated": false, "autowired": false, "secret": false,
"defaultValue": false, "description": "Whether the producer should be started
lazy (on the first message). By starting lazy you can use this to allow
CamelContext and routes to startup in situations where a produ [...]
"accessToken": { "index": 33, "kind": "parameter", "displayName": "Access
Token", "group": "security", "label": "security", "required": false, "type":
"string", "javaType": "java.lang.String", "deprecated": false, "autowired":
false, "secret": true, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The access token that is used by the client
for bearer authentication." },
- "asyncMdnAllowedHosts": { "index": 34, "kind": "parameter", "displayName":
"Async Mdn Allowed Hosts", "group": "security", "label": "security",
"required": false, "type": "string", "javaType": "java.lang.String",
"deprecated": false, "autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "Comma separated list of host names an
asynchronous MDN may be delivered to. The delivery [...]
- "decryptingPrivateKey": { "index": 35, "kind": "parameter", "displayName":
"Decrypting Private Key", "group": "security", "label": "security", "required":
false, "type": "object", "javaType": "java.security.PrivateKey", "deprecated":
false, "autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The key used to encrypt the EDI message." },
- "encryptingAlgorithm": { "index": 36, "kind": "parameter", "displayName":
"Encrypting Algorithm", "group": "security", "label": "security", "required":
false, "type": "enum", "javaType":
"org.apache.camel.component.as2.api.AS2EncryptionAlgorithm", "enum": [
"AES128_CBC", "AES192_CBC", "AES256_CBC", "AES128_CCM", "AES192_CCM",
"AES256_CCM", "AES128_GCM", "AES192_GCM", "AES256_GCM", "CAMELLIA128_CBC",
"CAMELLIA192_CBC", "CAMELLIA256_CBC", "CAST5_CBC", "DES_CBC", "DES_EDE3_CBC",
"GOST28 [...]
- "encryptingCertificateChain": { "index": 37, "kind": "parameter",
"displayName": "Encrypting Certificate Chain", "group": "security", "label":
"security", "required": false, "type": "object", "javaType":
"java.security.cert.Certificate[]", "deprecated": false, "autowired": false,
"secret": false, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The chain of certificates used to encrypt EDI
message." },
- "hostnameVerifier": { "index": 38, "kind": "parameter", "displayName":
"Hostname Verifier", "group": "security", "label": "security", "required":
false, "type": "object", "javaType": "javax.net.ssl.HostnameVerifier",
"deprecated": false, "autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "Set hostname verifier for SSL session." },
- "mdnAccessToken": { "index": 39, "kind": "parameter", "displayName": "Mdn
Access Token", "group": "security", "label": "security", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": true, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The access token that is used by the server
when it sends an async MDN. The option applies to the consu [...]
- "mdnPassword": { "index": 40, "kind": "parameter", "displayName": "Mdn
Password", "group": "security", "label": "security", "required": false, "type":
"string", "javaType": "java.lang.String", "deprecated": false, "autowired":
false, "secret": true, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The password that is used by the server for
basic authentication when it sends an async MDN. The option applie [...]
- "mdnUserName": { "index": 41, "kind": "parameter", "displayName": "Mdn
User Name", "group": "security", "label": "security", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": true, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The user-name that is used by the server for
basic authentication when it sends an async MDN. If options for [...]
- "password": { "index": 42, "kind": "parameter", "displayName": "Password",
"group": "security", "label": "security", "required": false, "type": "string",
"javaType": "java.lang.String", "deprecated": false, "autowired": false,
"secret": true, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The password that is used by the client for
basic authentication." },
- "signedReceiptMicAlgorithms": { "index": 43, "kind": "parameter",
"displayName": "Signed Receipt Mic Algorithms", "group": "security", "label":
"security", "required": false, "type": "string", "javaType":
"java.lang.String", "deprecated": false, "autowired": false, "secret": false,
"configurationClass": "org.apache.camel.component.as2.AS2Configuration",
"configurationField": "configuration", "description": "The list of algorithms,
in order of preference, requested to generate a messa [...]
- "signingAlgorithm": { "index": 44, "kind": "parameter", "displayName":
"Signing Algorithm", "group": "security", "label": "security", "required":
false, "type": "enum", "javaType":
"org.apache.camel.component.as2.api.AS2SignatureAlgorithm", "enum": [
"SHA3_224WITHRSA", "SHA3_256WITHRSA", "SHA3_384withRSA", "SHA3_512WITHRSA",
"MD5WITHRSA", "SHA1WITHRSA", "MD2WITHRSA", "SHA224WITHRSA", "SHA256WITHRSA",
"SHA384WITHRSA", "SHA512WITHRSA", "RIPEMD128WITHRSA", "RIPEMD160WITHRSA",
"RIPEMD256 [...]
- "signingCertificateChain": { "index": 45, "kind": "parameter",
"displayName": "Signing Certificate Chain", "group": "security", "label":
"security", "required": false, "type": "object", "javaType":
"java.security.cert.Certificate[]", "deprecated": false, "autowired": false,
"secret": false, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The chain of certificates used to sign EDI
message." },
- "signingPrivateKey": { "index": 46, "kind": "parameter", "displayName":
"Signing Private Key", "group": "security", "label": "security", "required":
false, "type": "object", "javaType": "java.security.PrivateKey", "deprecated":
false, "autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The key used to sign the EDI message." },
- "sslContext": { "index": 47, "kind": "parameter", "displayName": "Ssl
Context", "group": "security", "label": "security", "required": false, "type":
"object", "javaType": "javax.net.ssl.SSLContext", "deprecated": false,
"autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "Set SSL context for connection to remote
server." },
- "userName": { "index": 48, "kind": "parameter", "displayName": "User
Name", "group": "security", "label": "security", "required": false, "type":
"string", "javaType": "java.lang.String", "deprecated": false, "autowired":
false, "secret": true, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The user-name that is used by the client for
basic authentication. If options for basic authentication and bearer au [...]
- "validateSigningCertificateChain": { "index": 49, "kind": "parameter",
"displayName": "Validate Signing Certificate Chain", "group": "security",
"label": "security", "required": false, "type": "object", "javaType":
"java.security.cert.Certificate[]", "deprecated": false, "autowired": false,
"secret": false, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "Certificates to validate the message's
signature ag [...]
+ "asyncMdnAllowedHosts": { "index": 34, "kind": "parameter", "displayName":
"Async Mdn Allowed Hosts", "group": "security", "label": "security",
"required": false, "type": "string", "javaType": "java.lang.String",
"deprecated": false, "autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "Comma separated list of hosts an asynchronous
MDN may be delivered to. The delivery addre [...]
+ "asyncMdnRequireHttps": { "index": 35, "kind": "parameter", "displayName":
"Async Mdn Require Https", "group": "security", "label": "security",
"required": false, "type": "boolean", "javaType": "boolean", "deprecated":
false, "autowired": false, "secret": false, "defaultValue": false,
"configurationClass": "org.apache.camel.component.as2.AS2Configuration",
"configurationField": "configuration", "description": "Whether an asynchronous
MDN may only be delivered over https. The delivery [...]
+ "decryptingPrivateKey": { "index": 36, "kind": "parameter", "displayName":
"Decrypting Private Key", "group": "security", "label": "security", "required":
false, "type": "object", "javaType": "java.security.PrivateKey", "deprecated":
false, "autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The key used to encrypt the EDI message." },
+ "encryptingAlgorithm": { "index": 37, "kind": "parameter", "displayName":
"Encrypting Algorithm", "group": "security", "label": "security", "required":
false, "type": "enum", "javaType":
"org.apache.camel.component.as2.api.AS2EncryptionAlgorithm", "enum": [
"AES128_CBC", "AES192_CBC", "AES256_CBC", "AES128_CCM", "AES192_CCM",
"AES256_CCM", "AES128_GCM", "AES192_GCM", "AES256_GCM", "CAMELLIA128_CBC",
"CAMELLIA192_CBC", "CAMELLIA256_CBC", "CAST5_CBC", "DES_CBC", "DES_EDE3_CBC",
"GOST28 [...]
+ "encryptingCertificateChain": { "index": 38, "kind": "parameter",
"displayName": "Encrypting Certificate Chain", "group": "security", "label":
"security", "required": false, "type": "object", "javaType":
"java.security.cert.Certificate[]", "deprecated": false, "autowired": false,
"secret": false, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The chain of certificates used to encrypt EDI
message." },
+ "hostnameVerifier": { "index": 39, "kind": "parameter", "displayName":
"Hostname Verifier", "group": "security", "label": "security", "required":
false, "type": "object", "javaType": "javax.net.ssl.HostnameVerifier",
"deprecated": false, "autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "Set hostname verifier for SSL session." },
+ "mdnAccessToken": { "index": 40, "kind": "parameter", "displayName": "Mdn
Access Token", "group": "security", "label": "security", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": true, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The access token that is used by the server
when it sends an async MDN. The option applies to the consu [...]
+ "mdnPassword": { "index": 41, "kind": "parameter", "displayName": "Mdn
Password", "group": "security", "label": "security", "required": false, "type":
"string", "javaType": "java.lang.String", "deprecated": false, "autowired":
false, "secret": true, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The password that is used by the server for
basic authentication when it sends an async MDN. The option applie [...]
+ "mdnUserName": { "index": 42, "kind": "parameter", "displayName": "Mdn
User Name", "group": "security", "label": "security", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": true, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The user-name that is used by the server for
basic authentication when it sends an async MDN. If options for [...]
+ "password": { "index": 43, "kind": "parameter", "displayName": "Password",
"group": "security", "label": "security", "required": false, "type": "string",
"javaType": "java.lang.String", "deprecated": false, "autowired": false,
"secret": true, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The password that is used by the client for
basic authentication." },
+ "signedReceiptMicAlgorithms": { "index": 44, "kind": "parameter",
"displayName": "Signed Receipt Mic Algorithms", "group": "security", "label":
"security", "required": false, "type": "string", "javaType":
"java.lang.String", "deprecated": false, "autowired": false, "secret": false,
"configurationClass": "org.apache.camel.component.as2.AS2Configuration",
"configurationField": "configuration", "description": "The list of algorithms,
in order of preference, requested to generate a messa [...]
+ "signingAlgorithm": { "index": 45, "kind": "parameter", "displayName":
"Signing Algorithm", "group": "security", "label": "security", "required":
false, "type": "enum", "javaType":
"org.apache.camel.component.as2.api.AS2SignatureAlgorithm", "enum": [
"SHA3_224WITHRSA", "SHA3_256WITHRSA", "SHA3_384withRSA", "SHA3_512WITHRSA",
"MD5WITHRSA", "SHA1WITHRSA", "MD2WITHRSA", "SHA224WITHRSA", "SHA256WITHRSA",
"SHA384WITHRSA", "SHA512WITHRSA", "RIPEMD128WITHRSA", "RIPEMD160WITHRSA",
"RIPEMD256 [...]
+ "signingCertificateChain": { "index": 46, "kind": "parameter",
"displayName": "Signing Certificate Chain", "group": "security", "label":
"security", "required": false, "type": "object", "javaType":
"java.security.cert.Certificate[]", "deprecated": false, "autowired": false,
"secret": false, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The chain of certificates used to sign EDI
message." },
+ "signingPrivateKey": { "index": 47, "kind": "parameter", "displayName":
"Signing Private Key", "group": "security", "label": "security", "required":
false, "type": "object", "javaType": "java.security.PrivateKey", "deprecated":
false, "autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The key used to sign the EDI message." },
+ "sslContext": { "index": 48, "kind": "parameter", "displayName": "Ssl
Context", "group": "security", "label": "security", "required": false, "type":
"object", "javaType": "javax.net.ssl.SSLContext", "deprecated": false,
"autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "Set SSL context for connection to remote
server." },
+ "userName": { "index": 49, "kind": "parameter", "displayName": "User
Name", "group": "security", "label": "security", "required": false, "type":
"string", "javaType": "java.lang.String", "deprecated": false, "autowired":
false, "secret": true, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "The user-name that is used by the client for
basic authentication. If options for basic authentication and bearer au [...]
+ "validateSigningCertificateChain": { "index": 50, "kind": "parameter",
"displayName": "Validate Signing Certificate Chain", "group": "security",
"label": "security", "required": false, "type": "object", "javaType":
"java.security.cert.Certificate[]", "deprecated": false, "autowired": false,
"secret": false, "configurationClass":
"org.apache.camel.component.as2.AS2Configuration", "configurationField":
"configuration", "description": "Certificates to validate the message's
signature ag [...]
},
"apis": {
"client": { "consumerOnly": false, "producerOnly": true, "description":
"Sends EDI Messages over HTTP", "methods": { "send": { "description": "Send
ediMessage to trading partner", "signatures": [
"org.apache.hc.core5.http.protocol.HttpCoreContext send(Object ediMessage,
String requestUri, String subject, String from, String as2From, String as2To,
org.apache.camel.component.as2.api.AS2MessageStructure as2MessageStructure,
String ediMessageContentType, String ediMessageCharset, String [...]
diff --git
a/components/camel-as2/camel-as2-component/src/main/docs/as2-component.adoc
b/components/camel-as2/camel-as2-component/src/main/docs/as2-component.adoc
index ab03de9141b4..acf66bb1e1a2 100644
--- a/components/camel-as2/camel-as2-component/src/main/docs/as2-component.adoc
+++ b/components/camel-as2/camel-as2-component/src/main/docs/as2-component.adoc
@@ -56,4 +56,16 @@ The settings of the shared server connection still come from
the first endpoint
`sslContextParameters` and `sslContext` (used for the TLS listener),
`mdnMessageTemplate`, `server`, `serverFqdn` and `as2Version`. They are per
port, not per consumer.
+=== Delivering asynchronous MDNs
+
+When a received message asks for an asynchronous MDN, the
`as2://server/listen` consumer delivers the MDN to the
+address that the sender gave in the `Receipt-Delivery-Option` header. When
`asyncMdnAllowedHosts` is set, the MDN is
+delivered only to an address on the list, and the `mdnUserName`, `mdnPassword`
and `mdnAccessToken` credentials are
+attached only for such an address. Each entry of the list is a host with an
optional port:
+
+* a bare host, such as `partner.example`, matches only the default port (80),
so a non-default port is listed explicitly (for example `partner.example:8443`);
+* a host and a port, such as `partner.example:8443`, match that port only;
+* an IPv6 literal is written in square brackets, as in a URL: `[::1]` matches
the default port, and `[::1]:8443`
+matches port 8443. Without the brackets, `::1:8443` is read as another IPv6
address, not as `::1` with a port.
+
include::spring-boot:partial$starter.adoc[]
diff --git
a/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Configuration.java
b/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Configuration.java
index acf459b7feb3..ef97b61fcbc8 100644
---
a/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Configuration.java
+++
b/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Configuration.java
@@ -118,6 +118,8 @@ public class AS2Configuration {
private SSLContext sslContext;
@UriParam(label = "security")
private String asyncMdnAllowedHosts;
+ @UriParam(label = "security")
+ private boolean asyncMdnRequireHttps;
// If you use localhost-based AS2 server, you don't need to specify a
hostnameVerifier
@UriParam(label = "security")
private HostnameVerifier hostnameVerifier;
@@ -665,12 +667,15 @@ public class AS2Configuration {
}
/**
- * Comma separated list of host names an asynchronous MDN may be delivered
to. The delivery address is chosen by the
- * sender of the AS2 message, so this is the list of hosts the operator
vouches for.
+ * Comma separated list of hosts an asynchronous MDN may be delivered to.
The delivery address is chosen by the
+ * sender of the AS2 message, so this is the list of destinations the
operator vouches for. Each entry is a host
+ * with an optional port in host:port form; an IPv6 literal is written in
square brackets, as in a URL, optionally
+ * followed by :port. A bare-host entry (for example partner.example)
matches only the default port (80), so a
+ * non-default port is listed explicitly (for example
partner.example:8443).
*
- * When set, an asynchronous MDN whose delivery address names a host
outside the list is refused, and the configured
- * mdnUserName/mdnPassword/mdnAccessToken are attached only to a host on
the list. When not set, the MDN is still
- * delivered to the sender-supplied address but no credentials are
attached.
+ * When set, an asynchronous MDN whose delivery address is not on the list
is refused, and the configured
+ * mdnUserName/mdnPassword/mdnAccessToken are attached only to an address
on the list. When not set, the MDN is
+ * still delivered to the sender-supplied address but no credentials are
attached.
*
* The option applies to the consumer endpoint it is set on: consumers
sharing a serverPortNumber each apply their
* own list.
@@ -678,4 +683,22 @@ public class AS2Configuration {
public void setAsyncMdnAllowedHosts(String asyncMdnAllowedHosts) {
this.asyncMdnAllowedHosts = asyncMdnAllowedHosts;
}
+
+ public boolean isAsyncMdnRequireHttps() {
+ return asyncMdnRequireHttps;
+ }
+
+ /**
+ * Whether an asynchronous MDN may only be delivered over https. The
delivery address, including its scheme, is
+ * chosen by the sender of the AS2 message; by default only http is
accepted (TLS delivery of asynchronous MDNs is
+ * not yet implemented). When set to true, an asynchronous MDN whose
delivery address does not use https is refused,
+ * before the connection is opened and before the configured
mdnUserName/mdnPassword/mdnAccessToken are attached, so
+ * the credentials are never sent in cleartext to a sender-chosen address.
+ *
+ * The option applies to the consumer endpoint it is set on: consumers
sharing a serverPortNumber each apply their
+ * own value.
+ */
+ public void setAsyncMdnRequireHttps(boolean asyncMdnRequireHttps) {
+ this.asyncMdnRequireHttps = asyncMdnRequireHttps;
+ }
}
diff --git
a/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Consumer.java
b/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Consumer.java
index 8d8c43edd542..6696af5647bf 100644
---
a/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Consumer.java
+++
b/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Consumer.java
@@ -107,7 +107,8 @@ public class AS2Consumer extends
AbstractApiConsumer<AS2ApiName, AS2Configuratio
configuration.getMdnUserName(),
configuration.getMdnPassword(),
configuration.getMdnAccessToken(),
- configuration.getAsyncMdnAllowedHosts());
+ configuration.getAsyncMdnAllowedHosts(),
+ configuration.isAsyncMdnRequireHttps());
as2ServerConnection.registerConsumerConfiguration(uri, consumerConfig);
as2ServerConnection.listen(uri, this);
diff --git
a/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/internal/AS2ConnectionHelper.java
b/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/internal/AS2ConnectionHelper.java
index 15474412e8df..aeaa009d0d95 100644
---
a/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/internal/AS2ConnectionHelper.java
+++
b/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/internal/AS2ConnectionHelper.java
@@ -111,7 +111,8 @@ public final class AS2ConnectionHelper {
configuration.getSslContext(),
configuration.getMdnUserName(),
configuration.getMdnPassword(),
configuration.getMdnAccessToken(),
- configuration.getAsyncMdnAllowedHosts());
+ configuration.getAsyncMdnAllowedHosts(),
+ configuration.isAsyncMdnRequireHttps());
} catch (IOException e) {
throw new UncheckedIOException(e);
}
diff --git
a/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2AsyncMdnBasicAuthHeaderTest.java
b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2AsyncMdnBasicAuthHeaderTest.java
index 52cf5658acf0..5ae685ec1401 100644
---
a/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2AsyncMdnBasicAuthHeaderTest.java
+++
b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2AsyncMdnBasicAuthHeaderTest.java
@@ -196,9 +196,9 @@ public class AS2AsyncMdnBasicAuthHeaderTest extends
AbstractAS2ITSupport {
"TBD", null, null,
// server authorization config
MDN_USER_NAME, MDN_PASSWORD, MDN_ACCESS_TOKEN,
- // the MDN delivery address comes from the
receiptDeliveryOption header, so the host it names
- // has to be authorised before the credentials above are
attached to it
- "localhost");
+ // the MDN delivery address comes from the
receiptDeliveryOption header, so the host and port it
+ // names have to be authorised before the credentials above
are attached to it
+ "localhost:" + JETTY_PORT + ",localhost:" +
RECEIPT_SERVER_PORT);
serverConnection.listen("/", new
AS2AsyncMDNServerManagerIT.RequestHandler());
}
}
diff --git
a/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2AsyncMdnTokenAuthHeaderTest.java
b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2AsyncMdnTokenAuthHeaderTest.java
index 62685a588c05..a85e80268473 100644
---
a/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2AsyncMdnTokenAuthHeaderTest.java
+++
b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2AsyncMdnTokenAuthHeaderTest.java
@@ -148,9 +148,9 @@ public class AS2AsyncMdnTokenAuthHeaderTest extends
AbstractAS2ITSupport {
"TBD", null, null,
// server authorization config
null, null, MDN_ACCESS_TOKEN,
- // the MDN delivery address comes from the
receiptDeliveryOption header, so the host it names
- // has to be authorised before the credentials above are
attached to it
- "localhost");
+ // the MDN delivery address comes from the
receiptDeliveryOption header, so the host and port it
+ // names have to be authorised before the credentials above
are attached to it
+ "localhost:" + RECEIPT_SERVER_PORT);
serverConnection.listen("/", new
AS2AsyncMDNServerManagerIT.RequestHandler());
}
}
diff --git
a/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ServerBasicAuthHeaderTest.java
b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ServerBasicAuthHeaderTest.java
index 8114e3d7476c..f65e4bdbecf4 100644
---
a/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ServerBasicAuthHeaderTest.java
+++
b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ServerBasicAuthHeaderTest.java
@@ -125,8 +125,9 @@ public class AS2ServerBasicAuthHeaderTest extends
AbstractAS2ITSupport {
@Override
protected void customizeConfiguration(AS2Configuration configuration) {
configuration.setServerPortNumber(TARGET_PORT);
- // The MDN credentials are only attached to a delivery host the
operator has authorised, and the
- // delivery address here comes from the receiptDeliveryOption header,
so localhost has to be listed.
- configuration.setAsyncMdnAllowedHosts("localhost");
+ // The MDN credentials are only attached to a delivery address the
operator has authorised, and the
+ // delivery address here comes from the receiptDeliveryOption header,
so localhost and the port of the
+ // receipt endpoint have to be listed.
+ configuration.setAsyncMdnAllowedHosts("localhost:" + JETTY_PORT);
}
}
diff --git
a/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ServerBearerAuthHeaderTest.java
b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ServerBearerAuthHeaderTest.java
index 4d338a81279b..61c9bd6a864f 100644
---
a/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ServerBearerAuthHeaderTest.java
+++
b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ServerBearerAuthHeaderTest.java
@@ -122,8 +122,9 @@ public class AS2ServerBearerAuthHeaderTest extends
AbstractAS2ITSupport {
@Override
protected void customizeConfiguration(AS2Configuration configuration) {
configuration.setServerPortNumber(TARGET_PORT);
- // The MDN credentials are only attached to a delivery host the
operator has authorised, and the
- // delivery address here comes from the receiptDeliveryOption header,
so localhost has to be listed.
- configuration.setAsyncMdnAllowedHosts("localhost");
+ // The MDN credentials are only attached to a delivery address the
operator has authorised, and the
+ // delivery address here comes from the receiptDeliveryOption header,
so localhost and the port of the
+ // receipt endpoint have to be listed.
+ configuration.setAsyncMdnAllowedHosts("localhost:" + JETTY_PORT);
}
}
diff --git
a/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ServerTwoConsumerAsyncMdnSettingsTest.java
b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ServerTwoConsumerAsyncMdnSettingsTest.java
index 2420baafa10c..45e1a06c5221 100644
---
a/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ServerTwoConsumerAsyncMdnSettingsTest.java
+++
b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ServerTwoConsumerAsyncMdnSettingsTest.java
@@ -124,12 +124,21 @@ class AS2ServerTwoConsumerAsyncMdnSettingsTest extends
AS2ServerSecTestBase {
null, receiptDeliveryAddress, null, null, null);
}
+ // the host and port of each receipt endpoint, as listed in
asyncMdnAllowedHosts
+ private String localhostReceiptAuthority() {
+ return "localhost:" + localhostReceiptPort.getPort();
+ }
+
+ private String loopbackReceiptAuthority() {
+ return "127.0.0.1:" + loopbackReceiptPort.getPort();
+ }
+
private String localhostReceiptAddress() {
- return "http://localhost:" + localhostReceiptPort.getPort() +
RECEIPT_PATH;
+ return "http://" + localhostReceiptAuthority() + RECEIPT_PATH;
}
private String loopbackReceiptAddress() {
- return "http://127.0.0.1:" + loopbackReceiptPort.getPort() +
RECEIPT_PATH;
+ return "http://" + loopbackReceiptAuthority() + RECEIPT_PATH;
}
@Override
@@ -139,12 +148,13 @@ class AS2ServerTwoConsumerAsyncMdnSettingsTest extends
AS2ServerSecTestBase {
// the first consumer creates the server connection shared by
every consumer on the port
from("as2://server/listen?requestUriPattern=" + FIRST_PATTERN
+ "&mdnUserName=" + FIRST_USER_NAME + "&mdnPassword=" +
FIRST_PASSWORD
- + "&asyncMdnAllowedHosts=localhost,127.0.0.1")
+ + "&asyncMdnAllowedHosts=" + localhostReceiptAuthority()
+ "," + loopbackReceiptAuthority())
.routeId("first")
.to("mock:first");
from("as2://server/listen?requestUriPattern=" + SECOND_PATTERN
- + "&mdnAccessToken=" + SECOND_ACCESS_TOKEN +
"&asyncMdnAllowedHosts=127.0.0.1")
+ + "&mdnAccessToken=" + SECOND_ACCESS_TOKEN
+ + "&asyncMdnAllowedHosts=" + loopbackReceiptAuthority())
.routeId("second")
.to("mock:second");
@@ -155,7 +165,8 @@ class AS2ServerTwoConsumerAsyncMdnSettingsTest extends
AS2ServerSecTestBase {
// the root pattern, on the connection another consumer created
from("as2://server/listen?requestUriPattern=" + ROOT_PATTERN
- + "&mdnAccessToken=" + ROOT_ACCESS_TOKEN +
"&asyncMdnAllowedHosts=localhost")
+ + "&mdnAccessToken=" + ROOT_ACCESS_TOKEN
+ + "&asyncMdnAllowedHosts=" + localhostReceiptAuthority())
.routeId("root")
.to("mock:root");
diff --git
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_18.adoc
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_18.adoc
index e61fa43cb49f..bfe17f833ef4 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_18.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_18.adoc
@@ -58,6 +58,15 @@ credentials. A deployment that counted on the inherited list
as a restriction ha
A consumer whose `requestUriPattern` is `/` now also uses its own keys,
certificates and asynchronous MDN settings when
another consumer created the shared server connection; before, it used the
first consumer's.
+=== camel-as2 - the asynchronous MDN allow-list matches the host and port
+
+The `asyncMdnAllowedHosts` option now matches the full authority — host and
port — of the asynchronous MDN delivery
+address. A bare-host entry (for example `partner.example`) now matches only
the default port (80). Deployments that
+receive asynchronous MDNs on a non-default port must add the port to their
allow-list entry (for example
+`partner.example:8443`). IPv6 entries must also be updated to use bracket
notation: an unbracketed entry such as `::1`
+is now treated as a bare-host matching the default port (80) only; use `[::1]`
for port 80 or `[::1]:port` for a
+specific port.
+
=== camel-azure-eventhubs - per-partition checkpoint counters and timer;
checkpoint window boundary fix
Several fixes from 4.22.x have been brought forward to 4.18.6 to give this
change a sound base.
diff --git
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/AS2EndpointBuilderFactory.java
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/AS2EndpointBuilderFactory.java
index c9336a11f5e6..adeb131165e6 100644
---
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/AS2EndpointBuilderFactory.java
+++
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/AS2EndpointBuilderFactory.java
@@ -623,16 +623,20 @@ public interface AS2EndpointBuilderFactory {
return this;
}
/**
- * Comma separated list of host names an asynchronous MDN may be
- * delivered to. The delivery address is chosen by the sender of the
AS2
- * message, so this is the list of hosts the operator vouches for. When
- * set, an asynchronous MDN whose delivery address names a host outside
- * the list is refused, and the configured
- * mdnUserName/mdnPassword/mdnAccessToken are attached only to a host
on
- * the list. When not set, the MDN is still delivered to the
- * sender-supplied address but no credentials are attached. The option
- * applies to the consumer endpoint it is set on: consumers sharing a
- * serverPortNumber each apply their own list.
+ * Comma separated list of hosts an asynchronous MDN may be delivered
+ * to. The delivery address is chosen by the sender of the AS2 message,
+ * so this is the list of destinations the operator vouches for. Each
+ * entry is a host with an optional port in host:port form; an IPv6
+ * literal is written in square brackets, as in a URL, optionally
+ * followed by :port. A bare-host entry (for example partner.example)
+ * matches only the default port (80), so a non-default port is listed
+ * explicitly (for example partner.example:8443). When set, an
+ * asynchronous MDN whose delivery address is not on the list is
+ * refused, and the configured mdnUserName/mdnPassword/mdnAccessToken
+ * are attached only to an address on the list. When not set, the MDN
is
+ * still delivered to the sender-supplied address but no credentials
are
+ * attached. The option applies to the consumer endpoint it is set on:
+ * consumers sharing a serverPortNumber each apply their own list.
*
* The option is a: <code>java.lang.String</code> type.
*
@@ -645,6 +649,54 @@ public interface AS2EndpointBuilderFactory {
doSetProperty("asyncMdnAllowedHosts", asyncMdnAllowedHosts);
return this;
}
+ /**
+ * Whether an asynchronous MDN may only be delivered over https. The
+ * delivery address, including its scheme, is chosen by the sender of
+ * the AS2 message; by default only http is accepted (TLS delivery of
+ * asynchronous MDNs is not yet implemented). When set to true, an
+ * asynchronous MDN whose delivery address does not use https is
+ * refused, before the connection is opened and before the configured
+ * mdnUserName/mdnPassword/mdnAccessToken are attached, so the
+ * credentials are never sent in cleartext to a sender-chosen address.
+ * The option applies to the consumer endpoint it is set on: consumers
+ * sharing a serverPortNumber each apply their own value.
+ *
+ * The option is a: <code>boolean</code> type.
+ *
+ * Default: false
+ * Group: security
+ *
+ * @param asyncMdnRequireHttps the value to set
+ * @return the dsl builder
+ */
+ default AS2EndpointConsumerBuilder asyncMdnRequireHttps(boolean
asyncMdnRequireHttps) {
+ doSetProperty("asyncMdnRequireHttps", asyncMdnRequireHttps);
+ return this;
+ }
+ /**
+ * Whether an asynchronous MDN may only be delivered over https. The
+ * delivery address, including its scheme, is chosen by the sender of
+ * the AS2 message; by default only http is accepted (TLS delivery of
+ * asynchronous MDNs is not yet implemented). When set to true, an
+ * asynchronous MDN whose delivery address does not use https is
+ * refused, before the connection is opened and before the configured
+ * mdnUserName/mdnPassword/mdnAccessToken are attached, so the
+ * credentials are never sent in cleartext to a sender-chosen address.
+ * The option applies to the consumer endpoint it is set on: consumers
+ * sharing a serverPortNumber each apply their own value.
+ *
+ * The option will be converted to a <code>boolean</code> type.
+ *
+ * Default: false
+ * Group: security
+ *
+ * @param asyncMdnRequireHttps the value to set
+ * @return the dsl builder
+ */
+ default AS2EndpointConsumerBuilder asyncMdnRequireHttps(String
asyncMdnRequireHttps) {
+ doSetProperty("asyncMdnRequireHttps", asyncMdnRequireHttps);
+ return this;
+ }
/**
* The key used to encrypt the EDI message.
*
@@ -1681,16 +1733,20 @@ public interface AS2EndpointBuilderFactory {
return this;
}
/**
- * Comma separated list of host names an asynchronous MDN may be
- * delivered to. The delivery address is chosen by the sender of the
AS2
- * message, so this is the list of hosts the operator vouches for. When
- * set, an asynchronous MDN whose delivery address names a host outside
- * the list is refused, and the configured
- * mdnUserName/mdnPassword/mdnAccessToken are attached only to a host
on
- * the list. When not set, the MDN is still delivered to the
- * sender-supplied address but no credentials are attached. The option
- * applies to the consumer endpoint it is set on: consumers sharing a
- * serverPortNumber each apply their own list.
+ * Comma separated list of hosts an asynchronous MDN may be delivered
+ * to. The delivery address is chosen by the sender of the AS2 message,
+ * so this is the list of destinations the operator vouches for. Each
+ * entry is a host with an optional port in host:port form; an IPv6
+ * literal is written in square brackets, as in a URL, optionally
+ * followed by :port. A bare-host entry (for example partner.example)
+ * matches only the default port (80), so a non-default port is listed
+ * explicitly (for example partner.example:8443). When set, an
+ * asynchronous MDN whose delivery address is not on the list is
+ * refused, and the configured mdnUserName/mdnPassword/mdnAccessToken
+ * are attached only to an address on the list. When not set, the MDN
is
+ * still delivered to the sender-supplied address but no credentials
are
+ * attached. The option applies to the consumer endpoint it is set on:
+ * consumers sharing a serverPortNumber each apply their own list.
*
* The option is a: <code>java.lang.String</code> type.
*
@@ -1703,6 +1759,54 @@ public interface AS2EndpointBuilderFactory {
doSetProperty("asyncMdnAllowedHosts", asyncMdnAllowedHosts);
return this;
}
+ /**
+ * Whether an asynchronous MDN may only be delivered over https. The
+ * delivery address, including its scheme, is chosen by the sender of
+ * the AS2 message; by default only http is accepted (TLS delivery of
+ * asynchronous MDNs is not yet implemented). When set to true, an
+ * asynchronous MDN whose delivery address does not use https is
+ * refused, before the connection is opened and before the configured
+ * mdnUserName/mdnPassword/mdnAccessToken are attached, so the
+ * credentials are never sent in cleartext to a sender-chosen address.
+ * The option applies to the consumer endpoint it is set on: consumers
+ * sharing a serverPortNumber each apply their own value.
+ *
+ * The option is a: <code>boolean</code> type.
+ *
+ * Default: false
+ * Group: security
+ *
+ * @param asyncMdnRequireHttps the value to set
+ * @return the dsl builder
+ */
+ default AS2EndpointProducerBuilder asyncMdnRequireHttps(boolean
asyncMdnRequireHttps) {
+ doSetProperty("asyncMdnRequireHttps", asyncMdnRequireHttps);
+ return this;
+ }
+ /**
+ * Whether an asynchronous MDN may only be delivered over https. The
+ * delivery address, including its scheme, is chosen by the sender of
+ * the AS2 message; by default only http is accepted (TLS delivery of
+ * asynchronous MDNs is not yet implemented). When set to true, an
+ * asynchronous MDN whose delivery address does not use https is
+ * refused, before the connection is opened and before the configured
+ * mdnUserName/mdnPassword/mdnAccessToken are attached, so the
+ * credentials are never sent in cleartext to a sender-chosen address.
+ * The option applies to the consumer endpoint it is set on: consumers
+ * sharing a serverPortNumber each apply their own value.
+ *
+ * The option will be converted to a <code>boolean</code> type.
+ *
+ * Default: false
+ * Group: security
+ *
+ * @param asyncMdnRequireHttps the value to set
+ * @return the dsl builder
+ */
+ default AS2EndpointProducerBuilder asyncMdnRequireHttps(String
asyncMdnRequireHttps) {
+ doSetProperty("asyncMdnRequireHttps", asyncMdnRequireHttps);
+ return this;
+ }
/**
* The key used to encrypt the EDI message.
*
@@ -2720,16 +2824,20 @@ public interface AS2EndpointBuilderFactory {
return this;
}
/**
- * Comma separated list of host names an asynchronous MDN may be
- * delivered to. The delivery address is chosen by the sender of the
AS2
- * message, so this is the list of hosts the operator vouches for. When
- * set, an asynchronous MDN whose delivery address names a host outside
- * the list is refused, and the configured
- * mdnUserName/mdnPassword/mdnAccessToken are attached only to a host
on
- * the list. When not set, the MDN is still delivered to the
- * sender-supplied address but no credentials are attached. The option
- * applies to the consumer endpoint it is set on: consumers sharing a
- * serverPortNumber each apply their own list.
+ * Comma separated list of hosts an asynchronous MDN may be delivered
+ * to. The delivery address is chosen by the sender of the AS2 message,
+ * so this is the list of destinations the operator vouches for. Each
+ * entry is a host with an optional port in host:port form; an IPv6
+ * literal is written in square brackets, as in a URL, optionally
+ * followed by :port. A bare-host entry (for example partner.example)
+ * matches only the default port (80), so a non-default port is listed
+ * explicitly (for example partner.example:8443). When set, an
+ * asynchronous MDN whose delivery address is not on the list is
+ * refused, and the configured mdnUserName/mdnPassword/mdnAccessToken
+ * are attached only to an address on the list. When not set, the MDN
is
+ * still delivered to the sender-supplied address but no credentials
are
+ * attached. The option applies to the consumer endpoint it is set on:
+ * consumers sharing a serverPortNumber each apply their own list.
*
* The option is a: <code>java.lang.String</code> type.
*
@@ -2742,6 +2850,54 @@ public interface AS2EndpointBuilderFactory {
doSetProperty("asyncMdnAllowedHosts", asyncMdnAllowedHosts);
return this;
}
+ /**
+ * Whether an asynchronous MDN may only be delivered over https. The
+ * delivery address, including its scheme, is chosen by the sender of
+ * the AS2 message; by default only http is accepted (TLS delivery of
+ * asynchronous MDNs is not yet implemented). When set to true, an
+ * asynchronous MDN whose delivery address does not use https is
+ * refused, before the connection is opened and before the configured
+ * mdnUserName/mdnPassword/mdnAccessToken are attached, so the
+ * credentials are never sent in cleartext to a sender-chosen address.
+ * The option applies to the consumer endpoint it is set on: consumers
+ * sharing a serverPortNumber each apply their own value.
+ *
+ * The option is a: <code>boolean</code> type.
+ *
+ * Default: false
+ * Group: security
+ *
+ * @param asyncMdnRequireHttps the value to set
+ * @return the dsl builder
+ */
+ default AS2EndpointBuilder asyncMdnRequireHttps(boolean
asyncMdnRequireHttps) {
+ doSetProperty("asyncMdnRequireHttps", asyncMdnRequireHttps);
+ return this;
+ }
+ /**
+ * Whether an asynchronous MDN may only be delivered over https. The
+ * delivery address, including its scheme, is chosen by the sender of
+ * the AS2 message; by default only http is accepted (TLS delivery of
+ * asynchronous MDNs is not yet implemented). When set to true, an
+ * asynchronous MDN whose delivery address does not use https is
+ * refused, before the connection is opened and before the configured
+ * mdnUserName/mdnPassword/mdnAccessToken are attached, so the
+ * credentials are never sent in cleartext to a sender-chosen address.
+ * The option applies to the consumer endpoint it is set on: consumers
+ * sharing a serverPortNumber each apply their own value.
+ *
+ * The option will be converted to a <code>boolean</code> type.
+ *
+ * Default: false
+ * Group: security
+ *
+ * @param asyncMdnRequireHttps the value to set
+ * @return the dsl builder
+ */
+ default AS2EndpointBuilder asyncMdnRequireHttps(String
asyncMdnRequireHttps) {
+ doSetProperty("asyncMdnRequireHttps", asyncMdnRequireHttps);
+ return this;
+ }
/**
* The key used to encrypt the EDI message.
*