This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new 810756627996 CAMEL-25622: camel-smpp - verify the host name of the
SMSC on SSL connections (#27803)
810756627996 is described below
commit 810756627996c733a53d4fa55d1a425443ddb3d4
Author: Andrea Cosentino <[email protected]>
AuthorDate: Wed Oct 14 21:19:57 2026 +0200
CAMEL-25622: camel-smpp - verify the host name of the SMSC on SSL
connections (#27803)
Co-Authored-By: Claude Opus 5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
---
.../org/apache/camel/catalog/components/smpp.json | 14 +-
.../org/apache/camel/catalog/components/smpps.json | 14 +-
.../apache/camel/catalog/docs/smpp-component.adoc | 15 +-
.../component/smpp/SmppComponentConfigurer.java | 6 +
.../component/smpp/SmppEndpointConfigurer.java | 6 +
.../component/smpp/SmppEndpointUriFactory.java | 3 +-
.../org/apache/camel/component/smpp/smpp.json | 14 +-
.../org/apache/camel/component/smpp/smpps.json | 14 +-
.../camel-smpp/src/main/docs/smpp-component.adoc | 15 +-
.../camel/component/smpp/SmppConfiguration.java | 15 +
.../component/smpp/SmppConnectionFactory.java | 68 ++++-
.../component/smpp/SmppConfigurationTest.java | 5 +
...pConnectionFactoryHostnameVerificationTest.java | 330 +++++++++++++++++++++
.../src/test/resources/jsse/localhost.p12 | Bin 0 -> 2606 bytes
.../java/org/apache/camel/util/SecurityUtils.java | 4 +-
.../ROOT/pages/camel-4x-upgrade-guide-4_24.adoc | 19 ++
.../component/dsl/SmppComponentBuilderFactory.java | 20 ++
.../dsl/SmppsComponentBuilderFactory.java | 20 ++
.../endpoint/dsl/SmppEndpointBuilderFactory.java | 102 +++++++
19 files changed, 644 insertions(+), 40 deletions(-)
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smpp.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smpp.json
index d5058e583f50..07732b4858e2 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smpp.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smpp.json
@@ -65,9 +65,10 @@
"httpProxyPort": { "index": 37, "kind": "property", "displayName": "Http
Proxy Port", "group": "proxy", "label": "proxy", "required": false, "type":
"integer", "javaType": "java.lang.Integer", "deprecated": false, "autowired":
false, "secret": false, "defaultValue": 3128, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "If you need to tunnel SMPP through a HTTP
proxy, set this attribute to the port of yo [...]
"httpProxyUsername": { "index": 38, "kind": "property", "displayName":
"Http Proxy Username", "group": "proxy", "label": "proxy", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "If your HTTP proxy requires basic
authentication, set this attribute to the username required for you [...]
"proxyHeaders": { "index": 39, "kind": "property", "displayName": "Proxy
Headers", "group": "proxy", "label": "proxy", "required": false, "type":
"object", "javaType": "java.util.Map<java.lang.String, java.lang.String>",
"deprecated": false, "autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "These headers will be passed to the proxy
server while establishing the connect [...]
- "password": { "index": 40, "kind": "property", "displayName": "Password",
"group": "security", "label": "security", "required": false, "type": "string",
"javaType": "java.lang.String", "deprecated": false, "autowired": false,
"secret": true, "security": "secret", "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "The password for connecting to SMSC server." },
- "systemId": { "index": 41, "kind": "property", "displayName": "System Id",
"group": "security", "label": "security", "required": false, "type": "string",
"javaType": "java.lang.String", "deprecated": false, "autowired": false,
"secret": true, "security": "secret", "defaultValue": "smppclient",
"configurationClass": "org.apache.camel.component.smpp.SmppConfiguration",
"configurationField": "configuration", "description": "The system id (username)
for connecting to SMSC server." },
- "usingSSL": { "index": 42, "kind": "property", "displayName": "Using SSL",
"group": "security", "label": "security", "required": false, "type": "boolean",
"javaType": "boolean", "deprecated": false, "autowired": false, "secret":
false, "defaultValue": false, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "Whether using SSL with the smpps protocol" }
+ "hostnameVerification": { "index": 40, "kind": "property", "displayName":
"Hostname Verification", "group": "security", "label": "security", "required":
false, "type": "boolean", "javaType": "boolean", "deprecated": false,
"autowired": false, "secret": false, "security": "insecure:ssl",
"insecureValue": "false", "defaultValue": true, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "Whether to check that [...]
+ "password": { "index": 41, "kind": "property", "displayName": "Password",
"group": "security", "label": "security", "required": false, "type": "string",
"javaType": "java.lang.String", "deprecated": false, "autowired": false,
"secret": true, "security": "secret", "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "The password for connecting to SMSC server." },
+ "systemId": { "index": 42, "kind": "property", "displayName": "System Id",
"group": "security", "label": "security", "required": false, "type": "string",
"javaType": "java.lang.String", "deprecated": false, "autowired": false,
"secret": true, "security": "secret", "defaultValue": "smppclient",
"configurationClass": "org.apache.camel.component.smpp.SmppConfiguration",
"configurationField": "configuration", "description": "The system id (username)
for connecting to SMSC server." },
+ "usingSSL": { "index": 43, "kind": "property", "displayName": "Using SSL",
"group": "security", "label": "security", "required": false, "type": "boolean",
"javaType": "boolean", "deprecated": false, "autowired": false, "secret":
false, "defaultValue": false, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "Whether using SSL with the smpps protocol" }
},
"headers": {
"CamelSmppAlphabet": { "index": 0, "kind": "header", "displayName": "",
"group": "producer", "label": "producer", "required": false, "javaType":
"Byte", "deprecated": false, "deprecationNote": "", "autowired": false,
"secret": false, "description": "For SubmitSm, SubmitMulti and ReplaceSm The
data coding according to the SMPP 3.4 specification, section 5.2.19. Use the
URI option alphabet settings above.", "constantName":
"org.apache.camel.component.smpp.SmppConstants#ALPHABET" },
@@ -156,8 +157,9 @@
"httpProxyPort": { "index": 39, "kind": "parameter", "displayName": "Http
Proxy Port", "group": "proxy", "label": "proxy", "required": false, "type":
"integer", "javaType": "java.lang.Integer", "deprecated": false, "autowired":
false, "secret": false, "defaultValue": 3128, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "If you need to tunnel SMPP through a HTTP
proxy, set this attribute to the port of y [...]
"httpProxyUsername": { "index": 40, "kind": "parameter", "displayName":
"Http Proxy Username", "group": "proxy", "label": "proxy", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "If your HTTP proxy requires basic
authentication, set this attribute to the username required for yo [...]
"proxyHeaders": { "index": 41, "kind": "parameter", "displayName": "Proxy
Headers", "group": "proxy", "label": "proxy", "required": false, "type":
"object", "javaType": "java.util.Map<java.lang.String, java.lang.String>",
"deprecated": false, "autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "These headers will be passed to the proxy
server while establishing the connec [...]
- "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, "security": "secret", "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "The password for connecting to SMSC server." },
- "systemId": { "index": 43, "kind": "parameter", "displayName": "System
Id", "group": "security", "label": "security", "required": false, "type":
"string", "javaType": "java.lang.String", "deprecated": false, "autowired":
false, "secret": true, "security": "secret", "defaultValue": "smppclient",
"configurationClass": "org.apache.camel.component.smpp.SmppConfiguration",
"configurationField": "configuration", "description": "The system id (username)
for connecting to SMSC server." },
- "usingSSL": { "index": 44, "kind": "parameter", "displayName": "Using
SSL", "group": "security", "label": "security", "required": false, "type":
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false,
"secret": false, "defaultValue": false, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "Whether using SSL with the smpps protocol" }
+ "hostnameVerification": { "index": 42, "kind": "parameter", "displayName":
"Hostname Verification", "group": "security", "label": "security", "required":
false, "type": "boolean", "javaType": "boolean", "deprecated": false,
"autowired": false, "secret": false, "security": "insecure:ssl",
"insecureValue": "false", "defaultValue": true, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "Whether to check that [...]
+ "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, "security": "secret", "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "The password for connecting to SMSC server." },
+ "systemId": { "index": 44, "kind": "parameter", "displayName": "System
Id", "group": "security", "label": "security", "required": false, "type":
"string", "javaType": "java.lang.String", "deprecated": false, "autowired":
false, "secret": true, "security": "secret", "defaultValue": "smppclient",
"configurationClass": "org.apache.camel.component.smpp.SmppConfiguration",
"configurationField": "configuration", "description": "The system id (username)
for connecting to SMSC server." },
+ "usingSSL": { "index": 45, "kind": "parameter", "displayName": "Using
SSL", "group": "security", "label": "security", "required": false, "type":
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false,
"secret": false, "defaultValue": false, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "Whether using SSL with the smpps protocol" }
}
}
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smpps.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smpps.json
index c48575775833..d20365fb1550 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smpps.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smpps.json
@@ -65,9 +65,10 @@
"httpProxyPort": { "index": 37, "kind": "property", "displayName": "Http
Proxy Port", "group": "proxy", "label": "proxy", "required": false, "type":
"integer", "javaType": "java.lang.Integer", "deprecated": false, "autowired":
false, "secret": false, "defaultValue": 3128, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "If you need to tunnel SMPP through a HTTP
proxy, set this attribute to the port of yo [...]
"httpProxyUsername": { "index": 38, "kind": "property", "displayName":
"Http Proxy Username", "group": "proxy", "label": "proxy", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "If your HTTP proxy requires basic
authentication, set this attribute to the username required for you [...]
"proxyHeaders": { "index": 39, "kind": "property", "displayName": "Proxy
Headers", "group": "proxy", "label": "proxy", "required": false, "type":
"object", "javaType": "java.util.Map<java.lang.String, java.lang.String>",
"deprecated": false, "autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "These headers will be passed to the proxy
server while establishing the connect [...]
- "password": { "index": 40, "kind": "property", "displayName": "Password",
"group": "security", "label": "security", "required": false, "type": "string",
"javaType": "java.lang.String", "deprecated": false, "autowired": false,
"secret": true, "security": "secret", "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "The password for connecting to SMSC server." },
- "systemId": { "index": 41, "kind": "property", "displayName": "System Id",
"group": "security", "label": "security", "required": false, "type": "string",
"javaType": "java.lang.String", "deprecated": false, "autowired": false,
"secret": true, "security": "secret", "defaultValue": "smppclient",
"configurationClass": "org.apache.camel.component.smpp.SmppConfiguration",
"configurationField": "configuration", "description": "The system id (username)
for connecting to SMSC server." },
- "usingSSL": { "index": 42, "kind": "property", "displayName": "Using SSL",
"group": "security", "label": "security", "required": false, "type": "boolean",
"javaType": "boolean", "deprecated": false, "autowired": false, "secret":
false, "defaultValue": false, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "Whether using SSL with the smpps protocol" }
+ "hostnameVerification": { "index": 40, "kind": "property", "displayName":
"Hostname Verification", "group": "security", "label": "security", "required":
false, "type": "boolean", "javaType": "boolean", "deprecated": false,
"autowired": false, "secret": false, "security": "insecure:ssl",
"insecureValue": "false", "defaultValue": true, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "Whether to check that [...]
+ "password": { "index": 41, "kind": "property", "displayName": "Password",
"group": "security", "label": "security", "required": false, "type": "string",
"javaType": "java.lang.String", "deprecated": false, "autowired": false,
"secret": true, "security": "secret", "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "The password for connecting to SMSC server." },
+ "systemId": { "index": 42, "kind": "property", "displayName": "System Id",
"group": "security", "label": "security", "required": false, "type": "string",
"javaType": "java.lang.String", "deprecated": false, "autowired": false,
"secret": true, "security": "secret", "defaultValue": "smppclient",
"configurationClass": "org.apache.camel.component.smpp.SmppConfiguration",
"configurationField": "configuration", "description": "The system id (username)
for connecting to SMSC server." },
+ "usingSSL": { "index": 43, "kind": "property", "displayName": "Using SSL",
"group": "security", "label": "security", "required": false, "type": "boolean",
"javaType": "boolean", "deprecated": false, "autowired": false, "secret":
false, "defaultValue": false, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "Whether using SSL with the smpps protocol" }
},
"headers": {
"CamelSmppAlphabet": { "index": 0, "kind": "header", "displayName": "",
"group": "producer", "label": "producer", "required": false, "javaType":
"Byte", "deprecated": false, "deprecationNote": "", "autowired": false,
"secret": false, "description": "For SubmitSm, SubmitMulti and ReplaceSm The
data coding according to the SMPP 3.4 specification, section 5.2.19. Use the
URI option alphabet settings above.", "constantName":
"org.apache.camel.component.smpp.SmppConstants#ALPHABET" },
@@ -156,8 +157,9 @@
"httpProxyPort": { "index": 39, "kind": "parameter", "displayName": "Http
Proxy Port", "group": "proxy", "label": "proxy", "required": false, "type":
"integer", "javaType": "java.lang.Integer", "deprecated": false, "autowired":
false, "secret": false, "defaultValue": 3128, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "If you need to tunnel SMPP through a HTTP
proxy, set this attribute to the port of y [...]
"httpProxyUsername": { "index": 40, "kind": "parameter", "displayName":
"Http Proxy Username", "group": "proxy", "label": "proxy", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "If your HTTP proxy requires basic
authentication, set this attribute to the username required for yo [...]
"proxyHeaders": { "index": 41, "kind": "parameter", "displayName": "Proxy
Headers", "group": "proxy", "label": "proxy", "required": false, "type":
"object", "javaType": "java.util.Map<java.lang.String, java.lang.String>",
"deprecated": false, "autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "These headers will be passed to the proxy
server while establishing the connec [...]
- "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, "security": "secret", "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "The password for connecting to SMSC server." },
- "systemId": { "index": 43, "kind": "parameter", "displayName": "System
Id", "group": "security", "label": "security", "required": false, "type":
"string", "javaType": "java.lang.String", "deprecated": false, "autowired":
false, "secret": true, "security": "secret", "defaultValue": "smppclient",
"configurationClass": "org.apache.camel.component.smpp.SmppConfiguration",
"configurationField": "configuration", "description": "The system id (username)
for connecting to SMSC server." },
- "usingSSL": { "index": 44, "kind": "parameter", "displayName": "Using
SSL", "group": "security", "label": "security", "required": false, "type":
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false,
"secret": false, "defaultValue": false, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "Whether using SSL with the smpps protocol" }
+ "hostnameVerification": { "index": 42, "kind": "parameter", "displayName":
"Hostname Verification", "group": "security", "label": "security", "required":
false, "type": "boolean", "javaType": "boolean", "deprecated": false,
"autowired": false, "secret": false, "security": "insecure:ssl",
"insecureValue": "false", "defaultValue": true, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "Whether to check that [...]
+ "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, "security": "secret", "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "The password for connecting to SMSC server." },
+ "systemId": { "index": 44, "kind": "parameter", "displayName": "System
Id", "group": "security", "label": "security", "required": false, "type":
"string", "javaType": "java.lang.String", "deprecated": false, "autowired":
false, "secret": true, "security": "secret", "defaultValue": "smppclient",
"configurationClass": "org.apache.camel.component.smpp.SmppConfiguration",
"configurationField": "configuration", "description": "The system id (username)
for connecting to SMSC server." },
+ "usingSSL": { "index": 45, "kind": "parameter", "displayName": "Using
SSL", "group": "security", "label": "security", "required": false, "type":
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false,
"secret": false, "defaultValue": false, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "Whether using SSL with the smpps protocol" }
}
}
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/smpp-component.adoc
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/smpp-component.adoc
index 8536d5ed7aa8..02358413bb5a 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/smpp-component.adoc
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/smpp-component.adoc
@@ -166,8 +166,19 @@ If no *username* is provided, then Camel will provide the
default value
`smppclient`. +
If no *port* number is provided, then Camel will provide the default
value `2775`. +
-If the protocol name is "smpps", camel-smpp with try to
-use SSLSocket to init a connection to the server.
+If the protocol name is "smpps", camel-smpp will try to
+use SSLSocket to init a connection to the server. The certificate of the
+server must be trusted by the JVM, and it must match the host Camel connects
+to, with the same rules as an HTTPS client: a connection to an IP address
+needs a certificate that lists that address as a subject alternative name.
+Set `hostnameVerification=false` to turn the host check off.
+
+The handshake runs while the connection is being created, so a certificate
that does not match makes the producer or
+consumer fail to start with an `IOException` caused by an
+`SSLHandshakeException: No subject alternative names matching IP address ...
found` (or
+`No subject alternative DNS name matching ... found` for a host name). An IP
address has to be listed as a subject
+alternative name of the certificate; a certificate issued for the host name
alone does not match a connection made to
+its address.
// component options: START
diff --git
a/components/camel-smpp/src/generated/java/org/apache/camel/component/smpp/SmppComponentConfigurer.java
b/components/camel-smpp/src/generated/java/org/apache/camel/component/smpp/SmppComponentConfigurer.java
index 8548cf208d77..120ba09c0e05 100644
---
a/components/camel-smpp/src/generated/java/org/apache/camel/component/smpp/SmppComponentConfigurer.java
+++
b/components/camel-smpp/src/generated/java/org/apache/camel/component/smpp/SmppComponentConfigurer.java
@@ -49,6 +49,8 @@ public class SmppComponentConfigurer extends
PropertyConfigurerSupport implement
case "encoding":
getOrCreateConfiguration(target).setEncoding(property(camelContext,
java.lang.String.class, value)); return true;
case "enquirelinktimer":
case "enquireLinkTimer":
getOrCreateConfiguration(target).setEnquireLinkTimer(property(camelContext,
java.lang.Integer.class, value)); return true;
+ case "hostnameverification":
+ case "hostnameVerification":
getOrCreateConfiguration(target).setHostnameVerification(property(camelContext,
boolean.class, value)); return true;
case "httpproxyhost":
case "httpProxyHost":
getOrCreateConfiguration(target).setHttpProxyHost(property(camelContext,
java.lang.String.class, value)); return true;
case "httpproxypassword":
@@ -138,6 +140,8 @@ public class SmppComponentConfigurer extends
PropertyConfigurerSupport implement
case "encoding": return java.lang.String.class;
case "enquirelinktimer":
case "enquireLinkTimer": return java.lang.Integer.class;
+ case "hostnameverification":
+ case "hostnameVerification": return boolean.class;
case "httpproxyhost":
case "httpProxyHost": return java.lang.String.class;
case "httpproxypassword":
@@ -228,6 +232,8 @@ public class SmppComponentConfigurer extends
PropertyConfigurerSupport implement
case "encoding": return getOrCreateConfiguration(target).getEncoding();
case "enquirelinktimer":
case "enquireLinkTimer": return
getOrCreateConfiguration(target).getEnquireLinkTimer();
+ case "hostnameverification":
+ case "hostnameVerification": return
getOrCreateConfiguration(target).isHostnameVerification();
case "httpproxyhost":
case "httpProxyHost": return
getOrCreateConfiguration(target).getHttpProxyHost();
case "httpproxypassword":
diff --git
a/components/camel-smpp/src/generated/java/org/apache/camel/component/smpp/SmppEndpointConfigurer.java
b/components/camel-smpp/src/generated/java/org/apache/camel/component/smpp/SmppEndpointConfigurer.java
index fd60b21db28f..4326c474d400 100644
---
a/components/camel-smpp/src/generated/java/org/apache/camel/component/smpp/SmppEndpointConfigurer.java
+++
b/components/camel-smpp/src/generated/java/org/apache/camel/component/smpp/SmppEndpointConfigurer.java
@@ -43,6 +43,8 @@ public class SmppEndpointConfigurer extends
PropertyConfigurerSupport implements
case "exceptionHandler":
target.setExceptionHandler(property(camelContext,
org.apache.camel.spi.ExceptionHandler.class, value)); return true;
case "exchangepattern":
case "exchangePattern":
target.setExchangePattern(property(camelContext,
org.apache.camel.ExchangePattern.class, value)); return true;
+ case "hostnameverification":
+ case "hostnameVerification":
target.getConfiguration().setHostnameVerification(property(camelContext,
boolean.class, value)); return true;
case "httpproxyhost":
case "httpProxyHost":
target.getConfiguration().setHttpProxyHost(property(camelContext,
java.lang.String.class, value)); return true;
case "httpproxypassword":
@@ -133,6 +135,8 @@ public class SmppEndpointConfigurer extends
PropertyConfigurerSupport implements
case "exceptionHandler": return
org.apache.camel.spi.ExceptionHandler.class;
case "exchangepattern":
case "exchangePattern": return org.apache.camel.ExchangePattern.class;
+ case "hostnameverification":
+ case "hostnameVerification": return boolean.class;
case "httpproxyhost":
case "httpProxyHost": return java.lang.String.class;
case "httpproxypassword":
@@ -224,6 +228,8 @@ public class SmppEndpointConfigurer extends
PropertyConfigurerSupport implements
case "exceptionHandler": return target.getExceptionHandler();
case "exchangepattern":
case "exchangePattern": return target.getExchangePattern();
+ case "hostnameverification":
+ case "hostnameVerification": return
target.getConfiguration().isHostnameVerification();
case "httpproxyhost":
case "httpProxyHost": return
target.getConfiguration().getHttpProxyHost();
case "httpproxypassword":
diff --git
a/components/camel-smpp/src/generated/java/org/apache/camel/component/smpp/SmppEndpointUriFactory.java
b/components/camel-smpp/src/generated/java/org/apache/camel/component/smpp/SmppEndpointUriFactory.java
index d2039c9bf1c6..e7ea820cb2e0 100644
---
a/components/camel-smpp/src/generated/java/org/apache/camel/component/smpp/SmppEndpointUriFactory.java
+++
b/components/camel-smpp/src/generated/java/org/apache/camel/component/smpp/SmppEndpointUriFactory.java
@@ -25,7 +25,7 @@ public class SmppEndpointUriFactory extends
org.apache.camel.support.component.E
private static final Set<String> ENDPOINT_IDENTITY_PROPERTY_NAMES;
private static final Map<String, String> MULTI_VALUE_PREFIXES;
static {
- Set<String> props = new HashSet<>(45);
+ Set<String> props = new HashSet<>(46);
props.add("addressRange");
props.add("alphabet");
props.add("bridgeErrorHandler");
@@ -38,6 +38,7 @@ public class SmppEndpointUriFactory extends
org.apache.camel.support.component.E
props.add("exceptionHandler");
props.add("exchangePattern");
props.add("host");
+ props.add("hostnameVerification");
props.add("httpProxyHost");
props.add("httpProxyPassword");
props.add("httpProxyPort");
diff --git
a/components/camel-smpp/src/generated/resources/META-INF/org/apache/camel/component/smpp/smpp.json
b/components/camel-smpp/src/generated/resources/META-INF/org/apache/camel/component/smpp/smpp.json
index d5058e583f50..07732b4858e2 100644
---
a/components/camel-smpp/src/generated/resources/META-INF/org/apache/camel/component/smpp/smpp.json
+++
b/components/camel-smpp/src/generated/resources/META-INF/org/apache/camel/component/smpp/smpp.json
@@ -65,9 +65,10 @@
"httpProxyPort": { "index": 37, "kind": "property", "displayName": "Http
Proxy Port", "group": "proxy", "label": "proxy", "required": false, "type":
"integer", "javaType": "java.lang.Integer", "deprecated": false, "autowired":
false, "secret": false, "defaultValue": 3128, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "If you need to tunnel SMPP through a HTTP
proxy, set this attribute to the port of yo [...]
"httpProxyUsername": { "index": 38, "kind": "property", "displayName":
"Http Proxy Username", "group": "proxy", "label": "proxy", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "If your HTTP proxy requires basic
authentication, set this attribute to the username required for you [...]
"proxyHeaders": { "index": 39, "kind": "property", "displayName": "Proxy
Headers", "group": "proxy", "label": "proxy", "required": false, "type":
"object", "javaType": "java.util.Map<java.lang.String, java.lang.String>",
"deprecated": false, "autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "These headers will be passed to the proxy
server while establishing the connect [...]
- "password": { "index": 40, "kind": "property", "displayName": "Password",
"group": "security", "label": "security", "required": false, "type": "string",
"javaType": "java.lang.String", "deprecated": false, "autowired": false,
"secret": true, "security": "secret", "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "The password for connecting to SMSC server." },
- "systemId": { "index": 41, "kind": "property", "displayName": "System Id",
"group": "security", "label": "security", "required": false, "type": "string",
"javaType": "java.lang.String", "deprecated": false, "autowired": false,
"secret": true, "security": "secret", "defaultValue": "smppclient",
"configurationClass": "org.apache.camel.component.smpp.SmppConfiguration",
"configurationField": "configuration", "description": "The system id (username)
for connecting to SMSC server." },
- "usingSSL": { "index": 42, "kind": "property", "displayName": "Using SSL",
"group": "security", "label": "security", "required": false, "type": "boolean",
"javaType": "boolean", "deprecated": false, "autowired": false, "secret":
false, "defaultValue": false, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "Whether using SSL with the smpps protocol" }
+ "hostnameVerification": { "index": 40, "kind": "property", "displayName":
"Hostname Verification", "group": "security", "label": "security", "required":
false, "type": "boolean", "javaType": "boolean", "deprecated": false,
"autowired": false, "secret": false, "security": "insecure:ssl",
"insecureValue": "false", "defaultValue": true, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "Whether to check that [...]
+ "password": { "index": 41, "kind": "property", "displayName": "Password",
"group": "security", "label": "security", "required": false, "type": "string",
"javaType": "java.lang.String", "deprecated": false, "autowired": false,
"secret": true, "security": "secret", "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "The password for connecting to SMSC server." },
+ "systemId": { "index": 42, "kind": "property", "displayName": "System Id",
"group": "security", "label": "security", "required": false, "type": "string",
"javaType": "java.lang.String", "deprecated": false, "autowired": false,
"secret": true, "security": "secret", "defaultValue": "smppclient",
"configurationClass": "org.apache.camel.component.smpp.SmppConfiguration",
"configurationField": "configuration", "description": "The system id (username)
for connecting to SMSC server." },
+ "usingSSL": { "index": 43, "kind": "property", "displayName": "Using SSL",
"group": "security", "label": "security", "required": false, "type": "boolean",
"javaType": "boolean", "deprecated": false, "autowired": false, "secret":
false, "defaultValue": false, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "Whether using SSL with the smpps protocol" }
},
"headers": {
"CamelSmppAlphabet": { "index": 0, "kind": "header", "displayName": "",
"group": "producer", "label": "producer", "required": false, "javaType":
"Byte", "deprecated": false, "deprecationNote": "", "autowired": false,
"secret": false, "description": "For SubmitSm, SubmitMulti and ReplaceSm The
data coding according to the SMPP 3.4 specification, section 5.2.19. Use the
URI option alphabet settings above.", "constantName":
"org.apache.camel.component.smpp.SmppConstants#ALPHABET" },
@@ -156,8 +157,9 @@
"httpProxyPort": { "index": 39, "kind": "parameter", "displayName": "Http
Proxy Port", "group": "proxy", "label": "proxy", "required": false, "type":
"integer", "javaType": "java.lang.Integer", "deprecated": false, "autowired":
false, "secret": false, "defaultValue": 3128, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "If you need to tunnel SMPP through a HTTP
proxy, set this attribute to the port of y [...]
"httpProxyUsername": { "index": 40, "kind": "parameter", "displayName":
"Http Proxy Username", "group": "proxy", "label": "proxy", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "If your HTTP proxy requires basic
authentication, set this attribute to the username required for yo [...]
"proxyHeaders": { "index": 41, "kind": "parameter", "displayName": "Proxy
Headers", "group": "proxy", "label": "proxy", "required": false, "type":
"object", "javaType": "java.util.Map<java.lang.String, java.lang.String>",
"deprecated": false, "autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "These headers will be passed to the proxy
server while establishing the connec [...]
- "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, "security": "secret", "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "The password for connecting to SMSC server." },
- "systemId": { "index": 43, "kind": "parameter", "displayName": "System
Id", "group": "security", "label": "security", "required": false, "type":
"string", "javaType": "java.lang.String", "deprecated": false, "autowired":
false, "secret": true, "security": "secret", "defaultValue": "smppclient",
"configurationClass": "org.apache.camel.component.smpp.SmppConfiguration",
"configurationField": "configuration", "description": "The system id (username)
for connecting to SMSC server." },
- "usingSSL": { "index": 44, "kind": "parameter", "displayName": "Using
SSL", "group": "security", "label": "security", "required": false, "type":
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false,
"secret": false, "defaultValue": false, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "Whether using SSL with the smpps protocol" }
+ "hostnameVerification": { "index": 42, "kind": "parameter", "displayName":
"Hostname Verification", "group": "security", "label": "security", "required":
false, "type": "boolean", "javaType": "boolean", "deprecated": false,
"autowired": false, "secret": false, "security": "insecure:ssl",
"insecureValue": "false", "defaultValue": true, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "Whether to check that [...]
+ "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, "security": "secret", "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "The password for connecting to SMSC server." },
+ "systemId": { "index": 44, "kind": "parameter", "displayName": "System
Id", "group": "security", "label": "security", "required": false, "type":
"string", "javaType": "java.lang.String", "deprecated": false, "autowired":
false, "secret": true, "security": "secret", "defaultValue": "smppclient",
"configurationClass": "org.apache.camel.component.smpp.SmppConfiguration",
"configurationField": "configuration", "description": "The system id (username)
for connecting to SMSC server." },
+ "usingSSL": { "index": 45, "kind": "parameter", "displayName": "Using
SSL", "group": "security", "label": "security", "required": false, "type":
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false,
"secret": false, "defaultValue": false, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "Whether using SSL with the smpps protocol" }
}
}
diff --git
a/components/camel-smpp/src/generated/resources/META-INF/org/apache/camel/component/smpp/smpps.json
b/components/camel-smpp/src/generated/resources/META-INF/org/apache/camel/component/smpp/smpps.json
index c48575775833..d20365fb1550 100644
---
a/components/camel-smpp/src/generated/resources/META-INF/org/apache/camel/component/smpp/smpps.json
+++
b/components/camel-smpp/src/generated/resources/META-INF/org/apache/camel/component/smpp/smpps.json
@@ -65,9 +65,10 @@
"httpProxyPort": { "index": 37, "kind": "property", "displayName": "Http
Proxy Port", "group": "proxy", "label": "proxy", "required": false, "type":
"integer", "javaType": "java.lang.Integer", "deprecated": false, "autowired":
false, "secret": false, "defaultValue": 3128, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "If you need to tunnel SMPP through a HTTP
proxy, set this attribute to the port of yo [...]
"httpProxyUsername": { "index": 38, "kind": "property", "displayName":
"Http Proxy Username", "group": "proxy", "label": "proxy", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "If your HTTP proxy requires basic
authentication, set this attribute to the username required for you [...]
"proxyHeaders": { "index": 39, "kind": "property", "displayName": "Proxy
Headers", "group": "proxy", "label": "proxy", "required": false, "type":
"object", "javaType": "java.util.Map<java.lang.String, java.lang.String>",
"deprecated": false, "autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "These headers will be passed to the proxy
server while establishing the connect [...]
- "password": { "index": 40, "kind": "property", "displayName": "Password",
"group": "security", "label": "security", "required": false, "type": "string",
"javaType": "java.lang.String", "deprecated": false, "autowired": false,
"secret": true, "security": "secret", "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "The password for connecting to SMSC server." },
- "systemId": { "index": 41, "kind": "property", "displayName": "System Id",
"group": "security", "label": "security", "required": false, "type": "string",
"javaType": "java.lang.String", "deprecated": false, "autowired": false,
"secret": true, "security": "secret", "defaultValue": "smppclient",
"configurationClass": "org.apache.camel.component.smpp.SmppConfiguration",
"configurationField": "configuration", "description": "The system id (username)
for connecting to SMSC server." },
- "usingSSL": { "index": 42, "kind": "property", "displayName": "Using SSL",
"group": "security", "label": "security", "required": false, "type": "boolean",
"javaType": "boolean", "deprecated": false, "autowired": false, "secret":
false, "defaultValue": false, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "Whether using SSL with the smpps protocol" }
+ "hostnameVerification": { "index": 40, "kind": "property", "displayName":
"Hostname Verification", "group": "security", "label": "security", "required":
false, "type": "boolean", "javaType": "boolean", "deprecated": false,
"autowired": false, "secret": false, "security": "insecure:ssl",
"insecureValue": "false", "defaultValue": true, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "Whether to check that [...]
+ "password": { "index": 41, "kind": "property", "displayName": "Password",
"group": "security", "label": "security", "required": false, "type": "string",
"javaType": "java.lang.String", "deprecated": false, "autowired": false,
"secret": true, "security": "secret", "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "The password for connecting to SMSC server." },
+ "systemId": { "index": 42, "kind": "property", "displayName": "System Id",
"group": "security", "label": "security", "required": false, "type": "string",
"javaType": "java.lang.String", "deprecated": false, "autowired": false,
"secret": true, "security": "secret", "defaultValue": "smppclient",
"configurationClass": "org.apache.camel.component.smpp.SmppConfiguration",
"configurationField": "configuration", "description": "The system id (username)
for connecting to SMSC server." },
+ "usingSSL": { "index": 43, "kind": "property", "displayName": "Using SSL",
"group": "security", "label": "security", "required": false, "type": "boolean",
"javaType": "boolean", "deprecated": false, "autowired": false, "secret":
false, "defaultValue": false, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "Whether using SSL with the smpps protocol" }
},
"headers": {
"CamelSmppAlphabet": { "index": 0, "kind": "header", "displayName": "",
"group": "producer", "label": "producer", "required": false, "javaType":
"Byte", "deprecated": false, "deprecationNote": "", "autowired": false,
"secret": false, "description": "For SubmitSm, SubmitMulti and ReplaceSm The
data coding according to the SMPP 3.4 specification, section 5.2.19. Use the
URI option alphabet settings above.", "constantName":
"org.apache.camel.component.smpp.SmppConstants#ALPHABET" },
@@ -156,8 +157,9 @@
"httpProxyPort": { "index": 39, "kind": "parameter", "displayName": "Http
Proxy Port", "group": "proxy", "label": "proxy", "required": false, "type":
"integer", "javaType": "java.lang.Integer", "deprecated": false, "autowired":
false, "secret": false, "defaultValue": 3128, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "If you need to tunnel SMPP through a HTTP
proxy, set this attribute to the port of y [...]
"httpProxyUsername": { "index": 40, "kind": "parameter", "displayName":
"Http Proxy Username", "group": "proxy", "label": "proxy", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "If your HTTP proxy requires basic
authentication, set this attribute to the username required for yo [...]
"proxyHeaders": { "index": 41, "kind": "parameter", "displayName": "Proxy
Headers", "group": "proxy", "label": "proxy", "required": false, "type":
"object", "javaType": "java.util.Map<java.lang.String, java.lang.String>",
"deprecated": false, "autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "These headers will be passed to the proxy
server while establishing the connec [...]
- "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, "security": "secret", "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "The password for connecting to SMSC server." },
- "systemId": { "index": 43, "kind": "parameter", "displayName": "System
Id", "group": "security", "label": "security", "required": false, "type":
"string", "javaType": "java.lang.String", "deprecated": false, "autowired":
false, "secret": true, "security": "secret", "defaultValue": "smppclient",
"configurationClass": "org.apache.camel.component.smpp.SmppConfiguration",
"configurationField": "configuration", "description": "The system id (username)
for connecting to SMSC server." },
- "usingSSL": { "index": 44, "kind": "parameter", "displayName": "Using
SSL", "group": "security", "label": "security", "required": false, "type":
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false,
"secret": false, "defaultValue": false, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "Whether using SSL with the smpps protocol" }
+ "hostnameVerification": { "index": 42, "kind": "parameter", "displayName":
"Hostname Verification", "group": "security", "label": "security", "required":
false, "type": "boolean", "javaType": "boolean", "deprecated": false,
"autowired": false, "secret": false, "security": "insecure:ssl",
"insecureValue": "false", "defaultValue": true, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "Whether to check that [...]
+ "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, "security": "secret", "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "The password for connecting to SMSC server." },
+ "systemId": { "index": 44, "kind": "parameter", "displayName": "System
Id", "group": "security", "label": "security", "required": false, "type":
"string", "javaType": "java.lang.String", "deprecated": false, "autowired":
false, "secret": true, "security": "secret", "defaultValue": "smppclient",
"configurationClass": "org.apache.camel.component.smpp.SmppConfiguration",
"configurationField": "configuration", "description": "The system id (username)
for connecting to SMSC server." },
+ "usingSSL": { "index": 45, "kind": "parameter", "displayName": "Using
SSL", "group": "security", "label": "security", "required": false, "type":
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false,
"secret": false, "defaultValue": false, "configurationClass":
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField":
"configuration", "description": "Whether using SSL with the smpps protocol" }
}
}
diff --git a/components/camel-smpp/src/main/docs/smpp-component.adoc
b/components/camel-smpp/src/main/docs/smpp-component.adoc
index 8536d5ed7aa8..02358413bb5a 100644
--- a/components/camel-smpp/src/main/docs/smpp-component.adoc
+++ b/components/camel-smpp/src/main/docs/smpp-component.adoc
@@ -166,8 +166,19 @@ If no *username* is provided, then Camel will provide the
default value
`smppclient`. +
If no *port* number is provided, then Camel will provide the default
value `2775`. +
-If the protocol name is "smpps", camel-smpp with try to
-use SSLSocket to init a connection to the server.
+If the protocol name is "smpps", camel-smpp will try to
+use SSLSocket to init a connection to the server. The certificate of the
+server must be trusted by the JVM, and it must match the host Camel connects
+to, with the same rules as an HTTPS client: a connection to an IP address
+needs a certificate that lists that address as a subject alternative name.
+Set `hostnameVerification=false` to turn the host check off.
+
+The handshake runs while the connection is being created, so a certificate
that does not match makes the producer or
+consumer fail to start with an `IOException` caused by an
+`SSLHandshakeException: No subject alternative names matching IP address ...
found` (or
+`No subject alternative DNS name matching ... found` for a host name). An IP
address has to be listed as a subject
+alternative name of the certificate; a certificate issued for the host name
alone does not match a connection made to
+its address.
// component options: START
diff --git
a/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppConfiguration.java
b/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppConfiguration.java
index a66ae9f66cd3..271f683b70ce 100644
---
a/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppConfiguration.java
+++
b/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppConfiguration.java
@@ -86,6 +86,8 @@ public class SmppConfiguration implements Cloneable {
private byte numberingPlanIndicator =
NumberingPlanIndicator.UNKNOWN.value();
@UriParam(label = "security")
private boolean usingSSL;
+ @UriParam(label = "security", defaultValue = "true", security =
"insecure:ssl", insecureValue = "false")
+ private boolean hostnameVerification = true;
@UriParam(label = "common", defaultValue = "5000")
private long initialReconnectDelay = 5000;
@UriParam(label = "common", defaultValue = "5000")
@@ -532,6 +534,18 @@ public class SmppConfiguration implements Cloneable {
this.usingSSL = usingSSL;
}
+ public boolean isHostnameVerification() {
+ return hostnameVerification;
+ }
+
+ /**
+ * Whether to check that the certificate of the SMSC matches the host
Camel connects to, when SSL is used. When
+ * disabled, any certificate trusted by the JVM is accepted, whatever host
it was issued for.
+ */
+ public void setHostnameVerification(boolean hostnameVerification) {
+ this.hostnameVerification = hostnameVerification;
+ }
+
public long getInitialReconnectDelay() {
return initialReconnectDelay;
}
@@ -757,6 +771,7 @@ public class SmppConfiguration implements Cloneable {
@Override
public String toString() {
return "SmppConfiguration[usingSSL=" + usingSSL
+ + ", hostnameVerification=" + hostnameVerification
+ ", enquireLinkTimer=" + enquireLinkTimer
+ ", host=" + host
+ ", password=" + password
diff --git
a/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppConnectionFactory.java
b/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppConnectionFactory.java
index 7a1a962343b5..0bbbbbb7e796 100644
---
a/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppConnectionFactory.java
+++
b/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppConnectionFactory.java
@@ -57,6 +57,7 @@ import java.util.Base64;
import java.util.Map;
import javax.net.SocketFactory;
+import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
@@ -71,9 +72,18 @@ import org.jsmpp.session.connection.socket.SocketConnection;
*/
public final class SmppConnectionFactory implements ConnectionFactory {
private final SmppConfiguration config;
+ private final SSLSocketFactory sslSocketFactory;
private SmppConnectionFactory(SmppConfiguration config) {
+ this(config, null);
+ }
+
+ /**
+ * Creates a factory that uses the given SSL socket factory instead of the
default one of the JVM (for testing).
+ */
+ SmppConnectionFactory(SmppConfiguration config, SSLSocketFactory
sslSocketFactory) {
this.config = config;
+ this.sslSocketFactory = sslSocketFactory;
}
public static SmppConnectionFactory getInstance(SmppConfiguration config) {
@@ -82,15 +92,15 @@ public final class SmppConnectionFactory implements
ConnectionFactory {
@Override
public Connection createConnection(String host, int port) throws
IOException {
+ Socket socket = null;
try {
- Socket socket;
SocketFactory socketFactory;
socketFactory = config.isUsingSSL() && config.getHttpProxyHost()
== null
- ? SSLSocketFactory
- .getDefault()
+ ? getSslSocketFactory()
: SocketFactory.getDefault();
// NOTE: the socket must be closed by the factory method client.
socket = socketFactory.createSocket(); // NOSONAR
+ configureHostnameVerification(socket);
if (config.getHttpProxyHost() != null) {
// setup the proxy tunnel
// jsmpp uses enquire link timer as socket read timeout, so
also use it to establish the initial connection
@@ -102,21 +112,59 @@ public final class SmppConnectionFactory implements
ConnectionFactory {
socket.connect(new InetSocketAddress(host, port),
config.getEnquireLinkTimer());
}
- if (config.isUsingSSL() && config.getHttpProxyHost() != null) {
- // Init the SSL socket which is based on the proxy socket
- SSLSocketFactory sslSocketFactory = (SSLSocketFactory)
SSLSocketFactory.getDefault();
- // NOTE: the socket must be closed by the factory method
client.
- SSLSocket sslSocket = (SSLSocket)
sslSocketFactory.createSocket(socket, host, port, true); // NOSONAR
- sslSocket.startHandshake();
- socket = sslSocket;
+ if (config.isUsingSSL()) {
+ if (config.getHttpProxyHost() != null) {
+ // Init the SSL socket which is based on the proxy socket
+ // NOTE: the socket must be closed by the factory method
client.
+ socket = getSslSocketFactory().createSocket(socket, host,
port, true); // NOSONAR
+ configureHostnameVerification(socket);
+ }
+ startHandshake((SSLSocket) socket);
}
return new SocketConnection(socket);
} catch (Exception e) {
+ // no Connection is returned, so jSMPP cannot close the socket
either. The JDK closes it on a fatal
+ // alert but not on a timed out connect or handshake, which leaks
one socket per reconnect attempt
+ // against an SMSC that accepts TCP and then does not answer. On
the proxy path the layered SSLSocket
+ // was created with autoClose=true, so closing it closes the
tunnel underneath as well
+ IOHelper.close(socket);
throw new IOException(e.getMessage(), e);
}
}
+ private SSLSocketFactory getSslSocketFactory() {
+ return sslSocketFactory != null ? sslSocketFactory :
(SSLSocketFactory) SSLSocketFactory.getDefault();
+ }
+
+ /**
+ * Completes the TLS handshake here, on the thread that is creating the
connection, instead of leaving it to the
+ * first read or write.
+ * <p/>
+ * {@code SMPPSession.connectAndBind} starts its {@code PDUReaderWorker}
before it writes the bind, so both threads
+ * reach the first I/O on this socket and only whichever of them drives
{@code SSLSocketImpl.ensureNegotiated()}
+ * sees the {@link javax.net.ssl.SSLHandshakeException}. The other gets
+ * {@code SocketException: Connection or outbound has closed}, which never
mentions the certificate - so a host name
+ * mismatch could surface as a bare closed-connection error on route
start. Handshaking eagerly makes the cause
+ * deterministic.
+ * <p/>
+ * The read timeout is set first: without it a server that accepts the
connection and then never answers blocks the
+ * handshake indefinitely. jsmpp uses the same value as its own read
timeout and sets it again later.
+ */
+ private void startHandshake(SSLSocket socket) throws IOException {
+ socket.setSoTimeout(config.getEnquireLinkTimer());
+ socket.startHandshake();
+ }
+
+ private void configureHostnameVerification(Socket socket) {
+ if (config.isHostnameVerification() && socket instanceof SSLSocket
sslSocket) {
+ // check that the certificate of the SMSC matches the host we
connect to
+ SSLParameters sslParameters = sslSocket.getSSLParameters();
+ sslParameters.setEndpointIdentificationAlgorithm("HTTPS");
+ sslSocket.setSSLParameters(sslParameters);
+ }
+ }
+
private void connectProxy(String host, int port, Socket socket) throws
IOException {
try {
OutputStream out = socket.getOutputStream();
diff --git
a/components/camel-smpp/src/test/java/org/apache/camel/component/smpp/SmppConfigurationTest.java
b/components/camel-smpp/src/test/java/org/apache/camel/component/smpp/SmppConfigurationTest.java
index 9801353c3f4d..46677b40e258 100644
---
a/components/camel-smpp/src/test/java/org/apache/camel/component/smpp/SmppConfigurationTest.java
+++
b/components/camel-smpp/src/test/java/org/apache/camel/component/smpp/SmppConfigurationTest.java
@@ -72,6 +72,7 @@ public class SmppConfigurationTest {
assertEquals(0x00, configuration.getNumberingPlanIndicator());
assertEquals(0x00, configuration.getTypeOfNumber());
assertEquals(false, configuration.isUsingSSL());
+ assertEquals(true, configuration.isHostnameVerification());
assertEquals(5000, configuration.getInitialReconnectDelay());
assertEquals(5000, configuration.getReconnectDelay());
assertNull(configuration.getHttpProxyHost());
@@ -112,6 +113,7 @@ public class SmppConfigurationTest {
assertEquals(0x08, configuration.getNumberingPlanIndicator());
assertEquals(0x02, configuration.getTypeOfNumber());
assertEquals(true, configuration.isUsingSSL());
+ assertEquals(false, configuration.isHostnameVerification());
assertEquals(5001, configuration.getInitialReconnectDelay());
assertEquals(5002, configuration.getReconnectDelay());
assertEquals("127.0.0.1", configuration.getHttpProxyHost());
@@ -176,6 +178,7 @@ public class SmppConfigurationTest {
assertEquals(config.getNumberingPlanIndicator(),
configuration.getNumberingPlanIndicator());
assertEquals(config.getTypeOfNumber(),
configuration.getTypeOfNumber());
assertEquals(config.isUsingSSL(), configuration.isUsingSSL());
+ assertEquals(config.isHostnameVerification(),
configuration.isHostnameVerification());
assertEquals(config.getInitialReconnectDelay(),
configuration.getInitialReconnectDelay());
assertEquals(config.getReconnectDelay(),
configuration.getReconnectDelay());
assertEquals(config.getHttpProxyHost(),
configuration.getHttpProxyHost());
@@ -193,6 +196,7 @@ public class SmppConfigurationTest {
public void toStringShouldListAllInstanceVariables() {
String expected = "SmppConfiguration["
+ "usingSSL=false, "
+ + "hostnameVerification=true, "
+ "enquireLinkTimer=60000, "
+ "host=localhost, "
+ "password=null, "
@@ -259,6 +263,7 @@ public class SmppConfigurationTest {
config.setNumberingPlanIndicator(NumberingPlanIndicator.NATIONAL.value());
config.setTypeOfNumber(TypeOfNumber.NATIONAL.value());
config.setUsingSSL(true);
+ config.setHostnameVerification(false);
config.setInitialReconnectDelay(5001);
config.setReconnectDelay(5002);
config.setHttpProxyHost("127.0.0.1");
diff --git
a/components/camel-smpp/src/test/java/org/apache/camel/component/smpp/SmppConnectionFactoryHostnameVerificationTest.java
b/components/camel-smpp/src/test/java/org/apache/camel/component/smpp/SmppConnectionFactoryHostnameVerificationTest.java
new file mode 100644
index 000000000000..938c0803e946
--- /dev/null
+++
b/components/camel-smpp/src/test/java/org/apache/camel/component/smpp/SmppConnectionFactoryHostnameVerificationTest.java
@@ -0,0 +1,330 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.smpp;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketTimeoutException;
+import java.nio.charset.StandardCharsets;
+import java.security.KeyStore;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManagerFactory;
+
+import org.jsmpp.session.connection.Connection;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * The connection factory checks that the certificate of the SMSC matches the
host it connects to, directly and through
+ * an HTTP proxy.
+ * <p>
+ * The certificate in jsse/localhost.p12 lists only DNS:localhost as subject
alternative name, so it matches "localhost"
+ * but not "127.0.0.1".
+ */
+class SmppConnectionFactoryHostnameVerificationTest {
+
+ private static final char[] PASSWORD = "changeit".toCharArray();
+ // the proxy test server ignores the target of the CONNECT request and
answers the TLS handshake itself
+ private static final int SMSC_PORT = 2775;
+
+ private final ExecutorService executor = Executors.newCachedThreadPool();
+ private final CountDownLatch stop = new CountDownLatch(1);
+ private SSLContext serverContext;
+ private SSLContext clientContext;
+ private ServerSocket server;
+
+ @BeforeEach
+ void createSslContexts() throws Exception {
+ KeyStore keyStore = KeyStore.getInstance("PKCS12");
+ try (InputStream in =
getClass().getClassLoader().getResourceAsStream("jsse/localhost.p12")) {
+ keyStore.load(in, PASSWORD);
+ }
+ KeyManagerFactory keyManagerFactory =
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+ keyManagerFactory.init(keyStore, PASSWORD);
+ serverContext = SSLContext.getInstance("TLS");
+ serverContext.init(keyManagerFactory.getKeyManagers(), null, null);
+
+ TrustManagerFactory trustManagerFactory
+ =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+ trustManagerFactory.init(keyStore);
+ clientContext = SSLContext.getInstance("TLS");
+ clientContext.init(null, trustManagerFactory.getTrustManagers(), null);
+ }
+
+ @AfterEach
+ void stopServer() throws IOException {
+ stop.countDown();
+ if (server != null) {
+ server.close();
+ }
+ executor.shutdownNow();
+ }
+
+ @Test
+ void connectsWhenTheCertificateMatchesTheHost() throws Exception {
+ startTlsServer();
+
+ Connection connection = factory(true,
false).createConnection("localhost", server.getLocalPort());
+ try {
+ write(connection);
+ } finally {
+ connection.close();
+ }
+ }
+
+ @Test
+ void failsWhenTheCertificateDoesNotMatchTheHost() throws Exception {
+ startTlsServer();
+
+ // the handshake runs in createConnection, so the mismatch is reported
there rather than on the first
+ // read or write - which is what SMPPSession.connectAndBind rethrows
when the bind fails
+ SmppConnectionFactory factory = factory(true, false);
+ IOException e = assertThrows(IOException.class, () ->
factory.createConnection("127.0.0.1", server.getLocalPort()));
+
+ SSLHandshakeException cause =
assertInstanceOf(SSLHandshakeException.class, e.getCause());
+ assertTrue(cause.getMessage().contains("127.0.0.1"),
cause.getMessage());
+ }
+
+ /**
+ * createConnection returns no Connection when it fails, so jSMPP cannot
close the socket either.
+ * <p/>
+ * An SMSC that accepts the connection and then never answers the
ClientHello makes the handshake time out, and the
+ * JDK does not close the socket on a read timeout - unlike a fatal alert,
which it does close. So without closing
+ * it here, every reconnect attempt against such an SMSC would leave one
socket open.
+ */
+ @Test
+ void closesTheSocketWhenTheHandshakeTimesOut() throws Exception {
+ startServerThatNeverAnswers();
+
+ List<SSLSocket> created = new ArrayList<>();
+ SSLSocketFactory recording = new
RecordingSslSocketFactory(clientContext.getSocketFactory(), created);
+
+ SmppConfiguration configuration = new SmppConfiguration();
+ configuration.setUsingSSL(true);
+ configuration.setHostnameVerification(true);
+ configuration.setEnquireLinkTimer(1000);
+ SmppConnectionFactory factory = new
SmppConnectionFactory(configuration, recording);
+
+ IOException e
+ = assertThrows(IOException.class, () ->
factory.createConnection("localhost", server.getLocalPort()));
+ assertInstanceOf(SocketTimeoutException.class, e.getCause());
+
+ assertEquals(1, created.size(), "the factory should have created
exactly one socket");
+ assertTrue(created.get(0).isClosed(), "the socket must be closed when
createConnection fails");
+ }
+
+ @Test
+ void
connectsToAHostTheCertificateDoesNotListWhenHostnameVerificationIsDisabled()
throws Exception {
+ startTlsServer();
+
+ Connection connection = factory(false,
false).createConnection("127.0.0.1", server.getLocalPort());
+ try {
+ write(connection);
+ } finally {
+ connection.close();
+ }
+ }
+
+ @Test
+ void connectsThroughTheProxyWhenTheCertificateMatchesTheHost() throws
Exception {
+ startProxyAnsweringWithTls();
+
+ Connection connection = factory(true,
true).createConnection("localhost", SMSC_PORT);
+ try {
+ write(connection);
+ } finally {
+ connection.close();
+ }
+ }
+
+ @Test
+ void failsThroughTheProxyWhenTheCertificateDoesNotMatchTheHost() throws
Exception {
+ startProxyAnsweringWithTls();
+
+ SmppConnectionFactory factory = factory(true, true);
+ IOException e = assertThrows(IOException.class, () ->
factory.createConnection("127.0.0.1", SMSC_PORT));
+
+ SSLHandshakeException cause =
assertInstanceOf(SSLHandshakeException.class, e.getCause());
+ assertTrue(cause.getMessage().contains("127.0.0.1"),
cause.getMessage());
+ }
+
+ @Test
+ void
connectsThroughTheProxyToAHostTheCertificateDoesNotListWhenHostnameVerificationIsDisabled()
throws Exception {
+ startProxyAnsweringWithTls();
+
+ Connection connection = factory(false,
true).createConnection("127.0.0.1", SMSC_PORT);
+ try {
+ write(connection);
+ } finally {
+ connection.close();
+ }
+ }
+
+ private SmppConnectionFactory factory(boolean hostnameVerification,
boolean throughProxy) {
+ SmppConfiguration configuration = new SmppConfiguration();
+ configuration.setUsingSSL(true);
+ configuration.setHostnameVerification(hostnameVerification);
+ configuration.setEnquireLinkTimer(5000);
+ if (throughProxy) {
+ configuration.setHttpProxyHost("localhost");
+ configuration.setHttpProxyPort(server.getLocalPort());
+ }
+ return new SmppConnectionFactory(configuration,
clientContext.getSocketFactory());
+ }
+
+ private static void write(Connection connection) throws IOException {
+ OutputStream out = connection.getOutputStream();
+ out.write(0);
+ out.flush();
+ }
+
+ private void startTlsServer() throws IOException {
+ // no host, so the server can be reached with a host name and with an
IP address
+ server = serverContext.getServerSocketFactory().createServerSocket();
+ server.bind(new InetSocketAddress(0));
+ executor.submit(() -> {
+ try (SSLSocket socket = (SSLSocket) server.accept()) {
+ socket.startHandshake();
+ socket.getInputStream().read();
+ }
+ return null;
+ });
+ }
+
+ private void startServerThatNeverAnswers() throws IOException {
+ server = new ServerSocket();
+ server.bind(new InetSocketAddress(0));
+ executor.submit(() -> {
+ try (Socket socket = server.accept()) {
+ // hold the connection open without answering the ClientHello,
until the test is done
+ stop.await();
+ }
+ return null;
+ });
+ }
+
+ private void startProxyAnsweringWithTls() throws IOException {
+ server = new ServerSocket();
+ server.bind(new InetSocketAddress(0));
+ executor.submit(() -> {
+ try (Socket socket = server.accept()) {
+ readRequestHeaders(socket.getInputStream());
+ socket.getOutputStream()
+ .write("HTTP/1.0 200 Connection
established\r\n\r\n".getBytes(StandardCharsets.US_ASCII));
+ socket.getOutputStream().flush();
+ try (SSLSocket tls = (SSLSocket)
serverContext.getSocketFactory().createSocket(socket, null, true)) {
+ tls.startHandshake();
+ tls.getInputStream().read();
+ }
+ }
+ return null;
+ });
+ }
+
+ private static void readRequestHeaders(InputStream in) throws IOException {
+ int matched = 0;
+ byte[] end = "\r\n\r\n".getBytes(StandardCharsets.US_ASCII);
+ while (matched < end.length) {
+ int b = in.read();
+ if (b == -1) {
+ throw new IOException("Connection closed before the end of the
CONNECT request");
+ }
+ matched = b == end[matched] ? matched + 1 : (b == end[0] ? 1 : 0);
+ }
+ }
+
+ /**
+ * Delegates to the real factory and keeps the sockets it handed out, so a
test can assert they were closed.
+ */
+ private static final class RecordingSslSocketFactory extends
SSLSocketFactory {
+
+ private final SSLSocketFactory delegate;
+ private final List<SSLSocket> created;
+
+ private RecordingSslSocketFactory(SSLSocketFactory delegate,
List<SSLSocket> created) {
+ this.delegate = delegate;
+ this.created = created;
+ }
+
+ private Socket record(Socket socket) {
+ created.add((SSLSocket) socket);
+ return socket;
+ }
+
+ @Override
+ public Socket createSocket() throws IOException {
+ return record(delegate.createSocket());
+ }
+
+ @Override
+ public Socket createSocket(Socket s, String host, int port, boolean
autoClose) throws IOException {
+ return record(delegate.createSocket(s, host, port, autoClose));
+ }
+
+ @Override
+ public Socket createSocket(String host, int port) throws IOException {
+ return record(delegate.createSocket(host, port));
+ }
+
+ @Override
+ public Socket createSocket(String host, int port, InetAddress
localHost, int localPort) throws IOException {
+ return record(delegate.createSocket(host, port, localHost,
localPort));
+ }
+
+ @Override
+ public Socket createSocket(InetAddress host, int port) throws
IOException {
+ return record(delegate.createSocket(host, port));
+ }
+
+ @Override
+ public Socket createSocket(InetAddress address, int port, InetAddress
localAddress, int localPort)
+ throws IOException {
+ return record(delegate.createSocket(address, port, localAddress,
localPort));
+ }
+
+ @Override
+ public String[] getDefaultCipherSuites() {
+ return delegate.getDefaultCipherSuites();
+ }
+
+ @Override
+ public String[] getSupportedCipherSuites() {
+ return delegate.getSupportedCipherSuites();
+ }
+ }
+}
diff --git a/components/camel-smpp/src/test/resources/jsse/localhost.p12
b/components/camel-smpp/src/test/resources/jsse/localhost.p12
new file mode 100644
index 000000000000..4ef81f6d3489
Binary files /dev/null and
b/components/camel-smpp/src/test/resources/jsse/localhost.p12 differ
diff --git
a/core/camel-util/src/main/java/org/apache/camel/util/SecurityUtils.java
b/core/camel-util/src/main/java/org/apache/camel/util/SecurityUtils.java
index bd43b81e49af..f1d220fab87c 100644
--- a/core/camel-util/src/main/java/org/apache/camel/util/SecurityUtils.java
+++ b/core/camel-util/src/main/java/org/apache/camel/util/SecurityUtils.java
@@ -160,7 +160,9 @@ public final class SecurityUtils {
"component:openfga"));
owners.put("hostnameverification", Set.of(
"component:netty",
- "component:nettyhttp"));
+ "component:nettyhttp",
+ "component:smpp",
+ "component:smpps"));
owners.put("httpshostnameverificationenabled", Set.of(
"component:paho",
"component:pahomqtt5"));
diff --git
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
index c06170b02292..92cb5dd34a98 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
@@ -457,6 +457,25 @@ failed (for example a 404 for a deleted account, or a
server error). Such a comm
for it. Its `CamelGitHubCommitAuthor` and `CamelGitHubCommitCommitter` headers
then have the name that git recorded in
the commit instead of the name of the GitHub profile, and are not set when the
commit has no name either.
+=== camel-smpp - the host name of the SMSC is verified over SSL
+
+With `smpps` (or `usingSSL=true`), directly or through an HTTP proxy, the
connection now checks that the certificate of
+the SMSC matches the host it connects to, with the same rules as an HTTPS
client. Before, any certificate trusted by the
+JVM was accepted, whatever host it was issued for.
+
+A connection to a host name or an IP address that the certificate does not
list now fails the SSL handshake; an IP
+address must be listed as a subject alternative name of the certificate. Use a
certificate that matches the host of the
+endpoint, or set the new `hostnameVerification` option to `false` to keep the
previous behaviour.
+
+A mismatch shows as the producer or consumer failing to start, with an
`IOException` whose cause names the host that
+was checked:
+
+[source]
+----
+java.io.IOException: No subject alternative names matching IP address
127.0.0.1 found
+ Caused by: javax.net.ssl.SSLHandshakeException: No subject alternative
names matching IP address 127.0.0.1 found
+----
+
=== camel-netty-http - the request body read as an InputStream
The body of a request received by the consumer is a
`NettyChannelBufferStreamCache`. Its `read()` method now returns
diff --git
a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SmppComponentBuilderFactory.java
b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SmppComponentBuilderFactory.java
index 5b4372ea14e4..20e0f19bf834 100644
---
a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SmppComponentBuilderFactory.java
+++
b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SmppComponentBuilderFactory.java
@@ -806,6 +806,25 @@ public interface SmppComponentBuilderFactory {
return this;
}
+
+ /**
+ * Whether to check that the certificate of the SMSC matches the host
+ * Camel connects to, when SSL is used. When disabled, any certificate
+ * trusted by the JVM is accepted, whatever host it was issued for.
+ *
+ * The option is a: <code>boolean</code> type.
+ *
+ * Default: true
+ * Group: security
+ *
+ * @param hostnameVerification the value to set
+ * @return the dsl builder
+ */
+ default SmppComponentBuilder hostnameVerification(boolean
hostnameVerification) {
+ doSetProperty("hostnameVerification", hostnameVerification);
+ return this;
+ }
+
/**
* The password for connecting to SMSC server.
*
@@ -915,6 +934,7 @@ public interface SmppComponentBuilderFactory {
case "httpProxyPort": getOrCreateConfiguration((SmppComponent)
component).setHttpProxyPort((java.lang.Integer) value); return true;
case "httpProxyUsername": getOrCreateConfiguration((SmppComponent)
component).setHttpProxyUsername((java.lang.String) value); return true;
case "proxyHeaders": getOrCreateConfiguration((SmppComponent)
component).setProxyHeaders((java.util.Map) value); return true;
+ case "hostnameVerification":
getOrCreateConfiguration((SmppComponent)
component).setHostnameVerification((boolean) value); return true;
case "password": getOrCreateConfiguration((SmppComponent)
component).setPassword((java.lang.String) value); return true;
case "systemId": getOrCreateConfiguration((SmppComponent)
component).setSystemId((java.lang.String) value); return true;
case "usingSSL": getOrCreateConfiguration((SmppComponent)
component).setUsingSSL((boolean) value); return true;
diff --git
a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SmppsComponentBuilderFactory.java
b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SmppsComponentBuilderFactory.java
index f24d78c450aa..3b23e53402dd 100644
---
a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SmppsComponentBuilderFactory.java
+++
b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SmppsComponentBuilderFactory.java
@@ -806,6 +806,25 @@ public interface SmppsComponentBuilderFactory {
return this;
}
+
+ /**
+ * Whether to check that the certificate of the SMSC matches the host
+ * Camel connects to, when SSL is used. When disabled, any certificate
+ * trusted by the JVM is accepted, whatever host it was issued for.
+ *
+ * The option is a: <code>boolean</code> type.
+ *
+ * Default: true
+ * Group: security
+ *
+ * @param hostnameVerification the value to set
+ * @return the dsl builder
+ */
+ default SmppsComponentBuilder hostnameVerification(boolean
hostnameVerification) {
+ doSetProperty("hostnameVerification", hostnameVerification);
+ return this;
+ }
+
/**
* The password for connecting to SMSC server.
*
@@ -915,6 +934,7 @@ public interface SmppsComponentBuilderFactory {
case "httpProxyPort": getOrCreateConfiguration((SmppComponent)
component).setHttpProxyPort((java.lang.Integer) value); return true;
case "httpProxyUsername": getOrCreateConfiguration((SmppComponent)
component).setHttpProxyUsername((java.lang.String) value); return true;
case "proxyHeaders": getOrCreateConfiguration((SmppComponent)
component).setProxyHeaders((java.util.Map) value); return true;
+ case "hostnameVerification":
getOrCreateConfiguration((SmppComponent)
component).setHostnameVerification((boolean) value); return true;
case "password": getOrCreateConfiguration((SmppComponent)
component).setPassword((java.lang.String) value); return true;
case "systemId": getOrCreateConfiguration((SmppComponent)
component).setSystemId((java.lang.String) value); return true;
case "usingSSL": getOrCreateConfiguration((SmppComponent)
component).setUsingSSL((boolean) value); return true;
diff --git
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SmppEndpointBuilderFactory.java
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SmppEndpointBuilderFactory.java
index b651366353fd..806c9fd636b0 100644
---
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SmppEndpointBuilderFactory.java
+++
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SmppEndpointBuilderFactory.java
@@ -414,6 +414,40 @@ public interface SmppEndpointBuilderFactory {
doSetProperty("proxyHeaders", proxyHeaders);
return this;
}
+ /**
+ * Whether to check that the certificate of the SMSC matches the host
+ * Camel connects to, when SSL is used. When disabled, any certificate
+ * trusted by the JVM is accepted, whatever host it was issued for.
+ *
+ * The option is a: <code>boolean</code> type.
+ *
+ * Default: true
+ * Group: security
+ *
+ * @param hostnameVerification the value to set
+ * @return the dsl builder
+ */
+ default SmppEndpointConsumerBuilder hostnameVerification(boolean
hostnameVerification) {
+ doSetProperty("hostnameVerification", hostnameVerification);
+ return this;
+ }
+ /**
+ * Whether to check that the certificate of the SMSC matches the host
+ * Camel connects to, when SSL is used. When disabled, any certificate
+ * trusted by the JVM is accepted, whatever host it was issued for.
+ *
+ * The option will be converted to a <code>boolean</code> type.
+ *
+ * Default: true
+ * Group: security
+ *
+ * @param hostnameVerification the value to set
+ * @return the dsl builder
+ */
+ default SmppEndpointConsumerBuilder hostnameVerification(String
hostnameVerification) {
+ doSetProperty("hostnameVerification", hostnameVerification);
+ return this;
+ }
/**
* The password for connecting to SMSC server.
*
@@ -1647,6 +1681,40 @@ public interface SmppEndpointBuilderFactory {
doSetProperty("proxyHeaders", proxyHeaders);
return this;
}
+ /**
+ * Whether to check that the certificate of the SMSC matches the host
+ * Camel connects to, when SSL is used. When disabled, any certificate
+ * trusted by the JVM is accepted, whatever host it was issued for.
+ *
+ * The option is a: <code>boolean</code> type.
+ *
+ * Default: true
+ * Group: security
+ *
+ * @param hostnameVerification the value to set
+ * @return the dsl builder
+ */
+ default SmppEndpointProducerBuilder hostnameVerification(boolean
hostnameVerification) {
+ doSetProperty("hostnameVerification", hostnameVerification);
+ return this;
+ }
+ /**
+ * Whether to check that the certificate of the SMSC matches the host
+ * Camel connects to, when SSL is used. When disabled, any certificate
+ * trusted by the JVM is accepted, whatever host it was issued for.
+ *
+ * The option will be converted to a <code>boolean</code> type.
+ *
+ * Default: true
+ * Group: security
+ *
+ * @param hostnameVerification the value to set
+ * @return the dsl builder
+ */
+ default SmppEndpointProducerBuilder hostnameVerification(String
hostnameVerification) {
+ doSetProperty("hostnameVerification", hostnameVerification);
+ return this;
+ }
/**
* The password for connecting to SMSC server.
*
@@ -2350,6 +2418,40 @@ public interface SmppEndpointBuilderFactory {
doSetProperty("proxyHeaders", proxyHeaders);
return this;
}
+ /**
+ * Whether to check that the certificate of the SMSC matches the host
+ * Camel connects to, when SSL is used. When disabled, any certificate
+ * trusted by the JVM is accepted, whatever host it was issued for.
+ *
+ * The option is a: <code>boolean</code> type.
+ *
+ * Default: true
+ * Group: security
+ *
+ * @param hostnameVerification the value to set
+ * @return the dsl builder
+ */
+ default SmppEndpointBuilder hostnameVerification(boolean
hostnameVerification) {
+ doSetProperty("hostnameVerification", hostnameVerification);
+ return this;
+ }
+ /**
+ * Whether to check that the certificate of the SMSC matches the host
+ * Camel connects to, when SSL is used. When disabled, any certificate
+ * trusted by the JVM is accepted, whatever host it was issued for.
+ *
+ * The option will be converted to a <code>boolean</code> type.
+ *
+ * Default: true
+ * Group: security
+ *
+ * @param hostnameVerification the value to set
+ * @return the dsl builder
+ */
+ default SmppEndpointBuilder hostnameVerification(String
hostnameVerification) {
+ doSetProperty("hostnameVerification", hostnameVerification);
+ return this;
+ }
/**
* The password for connecting to SMSC server.
*