How to disable certificate validation in JAX-WS Client? - java

How do you disable certificate validation in JAX-WS client using javax.xml.ws.Service?
I tried creating an all-trusting TrustManager in the SSLSocketFactory and tried to bind it with BindingProvider
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
Map<String, Object> ctxt = ((BindingProvider) wsport ).getRequestContext();
ctxt.put(JAXWSProperties.SSL_SOCKET_FACTORY, sc.getSocketFactory());
but I still getting Exception: unable to find valid certification path to requested target
But it works when I just use
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
Or is there a way to make javax.xml.ws.Service use the HttpsURLConnection that I created?

I found a solution here:
http://schrepfler.blogspot.com.br/2009/06/relaxing-ssl-validation-for-jaxws.html
I'm using that solution calling the two static methods on a static block at the main class, like this:
static {
SSLUtilities.trustAllHostnames();
SSLUtilities.trustAllHttpsCertificates();
}
Hope this helps
EDIT: As David J. Liszewski pointed out, this breaks SSL/TLS for all connections from this JVM. So, keep that in mind.

The truth can be found from Erik Wramner's blog here http://erikwramner.wordpress.com/2013/03/27/trust-self-signed-ssl-certificates-and-skip-host-name-verification-with-jax-ws
I include the full solution where Apache CXF is used to make SOAP web service requests to a self-signed SharePoint https service:
NaiveSSLHelper.java
import org.apache.cxf.configuration.jsse.TLSClientParameters;
import org.apache.cxf.transport.http.HTTPConduit;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.xml.ws.BindingProvider;
import java.security.GeneralSecurityException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Map;
public class NaiveSSLHelper {
public static void makeWebServiceClientTrustEveryone(
Object webServicePort) {
if (webServicePort instanceof BindingProvider) {
BindingProvider bp = (BindingProvider) webServicePort;
Map requestContext = bp.getRequestContext();
requestContext.put(JAXWS_SSL_SOCKET_FACTORY, getTrustingSSLSocketFactory());
requestContext.put(JAXWS_HOSTNAME_VERIFIER,
new NaiveHostnameVerifier());
} else {
throw new IllegalArgumentException(
"Web service port "
+ webServicePort.getClass().getName()
+ " does not implement "
+ BindingProvider.class.getName());
}
}
public static SSLSocketFactory getTrustingSSLSocketFactory() {
return SSLSocketFactoryHolder.INSTANCE;
}
private static SSLSocketFactory createSSLSocketFactory() {
TrustManager[] trustManagers = new TrustManager[] {
new NaiveTrustManager()
};
SSLContext sslContext;
try {
sslContext = SSLContext.getInstance("TLS");
sslContext.init(new KeyManager[0], trustManagers,
new SecureRandom());
return sslContext.getSocketFactory();
} catch (GeneralSecurityException e) {
return null;
}
}
public static void makeCxfWebServiceClientTrustEveryone(HTTPConduit http) {
TrustManager[] trustManagers = new TrustManager[]{
new NaiveTrustManager()
};
TLSClientParameters tlsParams = new TLSClientParameters();
tlsParams.setSecureSocketProtocol("TLS");
tlsParams.setKeyManagers(new KeyManager[0]);
tlsParams.setTrustManagers(trustManagers);
tlsParams.setDisableCNCheck(true);
http.setTlsClientParameters(tlsParams);
}
private interface SSLSocketFactoryHolder {
SSLSocketFactory INSTANCE = createSSLSocketFactory();
}
private static class NaiveHostnameVerifier implements
HostnameVerifier {
#Override
public boolean verify(String hostName,
SSLSession session) {
return true;
}
}
private static class NaiveTrustManager implements
X509TrustManager {
#Override
public void checkClientTrusted(X509Certificate[] certs,
String authType) throws CertificateException {
}
#Override
public void checkServerTrusted(X509Certificate[] certs,
String authType) throws CertificateException {
}
#Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
private static final java.lang.String JAXWS_HOSTNAME_VERIFIER =
"com.sun.xml.internal.ws.transport.https.client.hostname.verifier";
private static final java.lang.String JAXWS_SSL_SOCKET_FACTORY =
"com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory";
}
SoapTester.java
import crawler.common.sharepoint.stubs.sitedata.ArrayOfSList;
import crawler.common.sharepoint.stubs.sitedata.GetListCollectionResponse;
import crawler.common.sharepoint.stubs.sitedata.SList;
import crawler.common.sharepoint.stubs.sitedata.SiteData;
import crawler.common.sharepoint.stubs.sitedata.SiteDataSoap;
import org.apache.cxf.configuration.security.AuthorizationPolicy;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transport.http.asyncclient.AsyncHTTPConduit;
import org.apache.cxf.transport.http.auth.HttpAuthHeader;
import org.apache.cxf.transport.http.auth.SpnegoAuthSupplier;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import org.ietf.jgss.GSSName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.Configuration;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.Holder;
import javax.xml.ws.Service;
import javax.xml.ws.handler.Handler;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import java.io.ByteArrayOutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* This example will invoke a web service on SharePoint 2013+ with optional kerberos auth.
*/
public class SoapTester {
private static final Logger LOG = LoggerFactory.getLogger(SoapTester.class);
public static void main(String[] args) {
String endpointAddress = args[0];
String keytabFilePath = args.length > 2 ? args[1] : null;
String principalName = args.length > 2 ? args[2] : null;
String servicePrincipalName = args.length > 3 ? args[3] : null;
if (!endpointAddress.endsWith("/")) {
endpointAddress += "/";
}
endpointAddress += "_vti_bin/SiteData.asmx";
final String endpointAddressFinal = endpointAddress;
Service service = Service.create(SiteData.SERVICE);
SiteDataSoap soap = service.getPort(SiteDataSoap.class);
NaiveSSLHelper.makeWebServiceClientTrustEveryone(soap);
BindingProvider bindingProvider = (BindingProvider) soap;
bindingProvider.getRequestContext().put(AsyncHTTPConduit.USE_ASYNC,
Boolean.TRUE);
bindingProvider.getRequestContext().put(
BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpointAddress);
List<Handler> chain = bindingProvider.getBinding().getHandlerChain();
chain.add(new SOAPHandler<SOAPMessageContext>() {
#Override
public boolean handleMessage(SOAPMessageContext context) {
String endpointAddress = (String) context.get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY);
SOAPMessage msg = context.getMessage();
Boolean outbound = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
msg.writeTo(out);
String str = new String(out.toByteArray());
LOG.info("Sharepoint xml [" + endpointAddress + "]" + (outbound ? " (Outbound)" : " (Inbound)") + ": " + str);
} catch (Exception e) {
LOG.error("Cannot get soap xml from message ", e);
}
if (outbound.booleanValue()) {
try {
context.getMessage().setProperty(SOAPMessage.CHARACTER_SET_ENCODING, "UTF-8");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return true;
}
#Override
public boolean handleFault(SOAPMessageContext context) {
return true;
}
#Override
public void close(MessageContext context) {
}
#Override
public Set<QName> getHeaders() {
return null;
}
});
bindingProvider.getBinding().setHandlerChain(chain);
Client client = ClientProxy.getClient(bindingProvider);
client.getEndpoint().put("org.apache.cxf.stax.maxChildElements", System.getProperty("org.apache.cxf.stax.maxChildElements") != null ? System.getProperty("org.apache.cxf.stax.maxChildElements") : "5000000");
HTTPConduit http = (HTTPConduit) client.getConduit();
NaiveSSLHelper.makeCxfWebServiceClientTrustEveryone(http);
AuthorizationPolicy authorization = new AuthorizationPolicy();
authorization.setAuthorizationType(HttpAuthHeader.AUTH_TYPE_NEGOTIATE);
http.setAuthorization(authorization);
SpnegoAuthSupplier authSupplier = new SpnegoAuthSupplier();
if (servicePrincipalName != null) {
authSupplier.setServicePrincipalName(servicePrincipalName);
authSupplier.setServiceNameType(GSSName.NT_HOSTBASED_SERVICE);
}
Map<String, String> loginConfig = new HashMap<>();
loginConfig.put("useKeyTab", "true");
loginConfig.put("storeKey", "true");
loginConfig.put("refreshKrb5Config", "true");
loginConfig.put("keyTab", keytabFilePath);
loginConfig.put("principal", principalName);
loginConfig.put("useTicketCache", "true");
loginConfig.put("debug", String.valueOf(true));
authSupplier.setLoginConfig(new Configuration() {
#Override
public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
return new AppConfigurationEntry[] {
new AppConfigurationEntry("com.sun.security.auth.module.Krb5LoginModule",
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
loginConfig)};
}
});
http.setAuthSupplier(authSupplier);
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setAllowChunking(false);
httpClientPolicy.setAutoRedirect(true);
http.setClient(httpClientPolicy);
Holder<ArrayOfSList> vLists = new Holder<>();
Holder<Long> getListCollectionResult = new Holder<>();
soap.getListCollectionAsync(getListCollectionResult, vLists, res -> {
try {
GetListCollectionResponse listCollectionResponse = res.get();
ArrayOfSList arrayOfSList = listCollectionResponse.getVLists();
LOG.info("Successfully got {} lists from {}", arrayOfSList.getSList().size(), endpointAddressFinal);
for (SList slist : arrayOfSList.getSList()) {
LOG.info("Successfully got list {}", slist.getTitle());
}
System.exit(0);
} catch (Exception e) {
LOG.error("List collection response", e);
}
});
}
}
Here is another example with respect to JDK7 and glassfish. Please pay attention for Nikolay Smirnov's comment as well. I use jdk 7 and glassfish 3.1.2. In this environment the suggested solution works perfect if the server deal with a self signed cerfificate.
// import com.sun.xml.ws.developer.JAXWSProperties;
import java.security.GeneralSecurityException;
import java.security.SecureRandom;
import java.util.Map;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.xml.ws.BindingProvider;
import org.apache.cxf.configuration.jsse.TLSClientParameters;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.transport.http.HTTPConduit;
/**
*
* Usage examples (BindingProvider port):
* NaiveSSLHelper.makeWebServiceClientTrustEveryone(port); // GlassFish
* NaiveSSLHelper.makeCxfWebServiceClientTrustEveryone(port); // TomEE
*
* Based on Erik Wramner's example frome here:
* http://erikwramner.wordpress.com/2013/03/27/trust-self-signed-ssl-certificates-and-skip-host-name-verification-with-jax-ws/
*
* I have extended the functionality when Apache CXF is used.
*/
public class NaiveSSLHelper {
private static final String JAXWS_HOSTNAME_VERIFIER = "com.sun.xml.ws.transport.https.client.hostname.verifier"; // JAXWSProperties.HOSTNAME_VERIFIER;
private static final String JAXWS_SSL_SOCKET_FACTORY = "com.sun.xml.ws.transport.https.client.SSLSocketFactory"; // JAXWSProperties.SSL_SOCKET_FACTORY;
// In Glassfish (Metro) environment you can use this function (Erik Wramner's solution)
public static void makeWebServiceClientTrustEveryone(Object webServicePort) {
if (webServicePort instanceof BindingProvider) {
BindingProvider bp = (BindingProvider) webServicePort;
Map requestContext = bp.getRequestContext();
requestContext.put(JAXWS_SSL_SOCKET_FACTORY, getTrustingSSLSocketFactory());
requestContext.put(JAXWS_HOSTNAME_VERIFIER, new NaiveHostnameVerifier());
} else {
throw new IllegalArgumentException(
"Web service port "
+ webServicePort.getClass().getName()
+ " does not implement "
+ BindingProvider.class.getName());
}
}
// In TomEE (Apache CXF) environment you can use this function (my solution)
public static void makeCxfWebServiceClientTrustEveryone(Object port) {
TrustManager[] trustManagers = new TrustManager[]{
new NaiveTrustManager()
};
Client c = ClientProxy.getClient(port);
HTTPConduit httpConduit = (HTTPConduit) c.getConduit();
TLSClientParameters tlsParams = new TLSClientParameters();
tlsParams.setSecureSocketProtocol("SSL");
tlsParams.setKeyManagers(new KeyManager[0]);
tlsParams.setTrustManagers(trustManagers);
tlsParams.setDisableCNCheck(true);
httpConduit.setTlsClientParameters(tlsParams);
}
public static SSLSocketFactory getTrustingSSLSocketFactory() {
return SSLSocketFactoryHolder.INSTANCE;
}
private static SSLSocketFactory createSSLSocketFactory() {
TrustManager[] trustManagers = new TrustManager[]{
new NaiveTrustManager()
};
SSLContext sslContext;
try {
sslContext = SSLContext.getInstance("SSL");
sslContext.init(new KeyManager[0], trustManagers, new SecureRandom());
return sslContext.getSocketFactory();
} catch (GeneralSecurityException e) {
return null;
}
}
private static interface SSLSocketFactoryHolder {
public static final SSLSocketFactory INSTANCE = createSSLSocketFactory();
}
private static class NaiveHostnameVerifier implements
HostnameVerifier {
#Override
public boolean verify(String hostName,
SSLSession session) {
return true;
}
}
private static class NaiveTrustManager implements
X509TrustManager {
#Override
public void checkClientTrusted(java.security.cert.X509Certificate[] certs,
String authType) throws java.security.cert.CertificateException {
}
#Override
public void checkServerTrusted(java.security.cert.X509Certificate[] certs,
String authType) throws java.security.cert.CertificateException {
}
#Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[0];
}
}
}

Putting aside all security issues that come with it, if anyone still want to disable certificate validation in a JAX-WS Client. This is how i do.
NB: And this way, instead of breaking SSL/TLS for ALL connections, you disable certificate validation for THAT client only.
import java.security.cert.X509Certificate;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.cxf.configuration.jsse.TLSClientParameters;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.transport.http.HTTPConduit;
/** Custom JAX-WS client factory used to ignore certificate validation */
public class NotSecureClientFactory extends JaxWsProxyFactoryBean {
#Override
protected ClientProxy clientClientProxy(Client c) {
// Create a client factory that does not validate certificate chains
ClientProxy cp = super.clientClientProxy(c);
HTTPConduit httpConduit = (HTTPConduit) cp.getClient().getConduit();
httpConduit.setTlsClientParameters(tlsClientParameters());
return cp;
}
public TLSClientParameters tlsClientParameters() {
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
} };
TLSClientParameters tlsClientParameters = new TLSClientParameters();
tlsClientParameters.setTrustManagers(trustAllCerts);
return tlsClientParameters;
}
}

Actually CXF comes w/ an InsecureTrustManager for testing purpose.
For a Spring Boot app, it would be as easy as the following to disable TLS validation in all your CXF clients. Needless to say, u should NEVER do this in a prod env.
import org.apache.cxf.configuration.jsse.TLSClientParameters;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transport.https.InsecureTrustManager;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import javax.inject.Inject;
import javax.xml.ws.BindingProvider;
import java.util.Set;
#ConditionalOnProperty(value = "soap.validate-tls.client", havingValue = "true")
#Configuration
class DisableTlsCxfClientConfig {
#Inject
DisableTlsCxfClientConfig(Set<BindingProvider> soapClients) {
var insecureTlsParam = new TLSClientParameters();
insecureTlsParam.setTrustManagers(InsecureTrustManager.getNoOpX509TrustManagers());
insecureTlsParam.setDisableCNCheck(true);
soapClients.stream()
.map(ClientProxy::getClient)
.map(Client::getConduit)
.map(HTTPConduit.class::cast)
.forEach(c -> c.setTlsClientParameters(insecureTlsParam));
}
}
Shout out to #addiene, #jontro & #Miklos Krivan who provided all the pieces! Thank u very much!

Related

How to resolve "org.eclipse.jetty.websocket.api.MessageTooLargeException" for Java WebSocketStompClient

When I'm running a Java WebSocketStompClient, I got below error:
org.eclipse.jetty.websocket.api.MessageTooLargeException: Text message size [73728] exceeds maximum size [65536]
Sample code:
import org.apache.log4j.Logger;
import org.springframework.messaging.simp.stomp.StompFrameHandler;
import org.springframework.messaging.simp.stomp.StompHeaders;
import org.springframework.messaging.simp.stomp.StompSession;
import org.springframework.messaging.simp.stomp.StompSessionHandlerAdapter;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.web.socket.WebSocketHttpHeaders;
import org.springframework.web.socket.client.WebSocketClient;
import org.springframework.web.socket.client.standard.StandardWebSocketClient;
import org.springframework.web.socket.messaging.WebSocketStompClient;
import org.springframework.web.socket.sockjs.client.SockJsClient;
import org.springframework.web.socket.sockjs.client.Transport;
import org.springframework.web.socket.sockjs.client.WebSocketTransport;
import org.springframework.web.socket.sockjs.frame.Jackson2SockJsMessageCodec;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutionException;
public class HelloClient {
private static Logger logger = Logger.getLogger(HelloClient.class);
StompSession session;
private final static WebSocketHttpHeaders headers = new WebSocketHttpHeaders();
public ListenableFuture<StompSession> connect() {
Transport webSocketTransport = new WebSocketTransport(new StandardWebSocketClient());
List<Transport> transports = Collections.singletonList(webSocketTransport);
SockJsClient sockJsClient = new SockJsClient(transports);
sockJsClient.setMessageCodec(new Jackson2SockJsMessageCodec());
WebSocketStompClient stompClient = new WebSocketStompClient(sockJsClient);
long[] hb = stompClient.getDefaultHeartbeat();
boolean en = stompClient.isDefaultHeartbeatEnabled();
long timeout = stompClient.getReceiptTimeLimit();
String url = "https://www.test.com";
return stompClient.connect(url, headers, new MyHandler());
}
public void subscribeMsg(StompSession stompSession) throws ExecutionException, InterruptedException {
stompSession.subscribe("/topic/test", new StompFrameHandler() {
public Type getPayloadType(StompHeaders stompHeaders) {
return byte[].class;
}
public void handleFrame(StompHeaders stompHeaders, Object o) {
logger.info("Received message " + new String((byte[]) o));
String response = new String((byte[]) o);
}
});
}
private class MyHandler extends StompSessionHandlerAdapter {
public void afterConnected(StompSession stompSession, StompHeaders stompHeaders) {
logger.info("Now connected");
session = stompSession;
}
}
public boolean isConnected() {
try {
Thread.sleep(500);
return session != null && session.isConnected();
} catch (Exception e) {
logger.warn("Error happens when checking connection status, ", e);
return false;
}
}
public static void main(String[] args) throws Exception {
HelloClient helloClient = new HelloClient();
ListenableFuture<StompSession> f = helloClient.connect();
StompSession stompSession = f.get();
helloClient.subscribeMsg(stompSession);
while (true) {
if (!helloClient.isConnected()) {
logger.info("wss diconnected ");
logger.info("need re-create ");
}
}
}
}
How to increase the limitation for a Java stomp websocket client? I found some not related answers How can I set max buffer size for web socket client(Jetty) in Java which are not suitable for stomp websocket client.
Also tried stompClient.setInboundMessageSizeLimit(Integer.MAX_VALUE); which doesn't work.

Java Quarkus/MicroProfile Restclient inject sslContext

How I can inject a custom sslContext by use the #RegisterRestClient inside a interface ?
Nor Quarkus or Microprofile allow you to programmatically build the rest client (that's the purpose of providing you a interface auto-implemented afterall).
You could nevertheless implement by yourself the rest-client interface and set your javax.net.ssl.SSLContext.
The example below is meant to provide a SSLContext trusting all hosts:
package org.me.rest;
import java.net.URI;
import java.security.KeyManagementException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.annotation.Priority;
import javax.enterprise.context.ApplicationScoped;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.eclipse.microprofile.rest.client.RestClientBuilder;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import org.me.rest.MyRestClient;
#Priority(value = 1) //choose an appropriate value here
#RestClient
#ApplicationScoped
public class MyRestClientImpl implements MyRestClient {
#Override
public Response getTheResource() {
SSLContext sslContext = null;
try {
sslContext = SSLContext.getInstance("TLS");
TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
sslContext.init(null, new TrustManager[] {
tm
}, null);
} catch (Exception e) {
e.printStackTrace();
}
AuthRestClient client =
RestClientBuilder.newBuilder().baseUri(URI.create("https://hostname:port/some/rest/resource/"))
.hostnameVerifier(new NoopHostnameVerifier()).sslContext(sslContext).build(AuthRestClient.class);
return client.getTheResource();
}
}

SNMP-CAMEL-KAFKA

I am looking for reference where I can get simple program to send a SNMP trap to Apache Kafka topic using Apache Camel.
Please help me if someone can explain the it using simple java program.
My RouteBuilder configuration
import org.apache.camel.builder.RouteBuilder;
public class SimpleRouteBuilder extends RouteBuilder{
#Override
public void configure() throws Exception {
String topicName = "topic=first_topic";
String kafkaServer = "kafka:localhost:9092";
String zooKeeperHost = "zookeeperHost=localhost&zookeeperPort=2181";
String serializerClass = "serializerClass=kafka.serializer.StringEncoder";
String toKafka = new StringBuilder().append(kafkaServer).append("?").append(topicName).append("&")
.append(zooKeeperHost).append("&").append(serializerClass).toString();
System.out.println(toKafka);
from("snmp:127.0.0.1:161?protocol=udp&type=POLL&oids=1.3.6.1.2.1.1.5.0").split().tokenize("\n").to(toKafka);
}
}
Main Method
import org.apache.camel.CamelContext;
import org.apache.camel.impl.DefaultCamelContext;
import org.snmp4j.Snmp;
public class MainApp {
public static void main(String[] args) {
SimpleRouteBuilder routeBuilder = new SimpleRouteBuilder();
CamelContext ctx = new DefaultCamelContext();
try {
ctx.addRoutes(routeBuilder);
ctx.start();
Thread.sleep(5 * 60 * 1000);
ctx.stop();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
I was in wrong direction. The write direction is as below -
Create a Trap sender program.
Create Trap receiver/listener program.
Inside Trap receiver or listener, receive trap and send it to Apache Kafka topic through Apache camel.
POM.XML
add below dependencies -
camel-core
snmp4j
camel-kafka
Trap Sender Program
package <>;
import org.apache.camel.CamelContext;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultCamelContext;
import org.snmp4j.*;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.mp.MPv2c;
import org.snmp4j.mp.MPv3;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.security.*;
import org.snmp4j.smi.*;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import java.util.Date;
public class Trapsender {
public static final String community = "public";
public static final String Oid = ".1.3.6.1.2.1.1.8";
public static final String ipAddress = "127.0.0.1";
public static final int port = 162;
public static void main(String[] args) {
Trapsender trapv3 = new Trapsender();
trapv3.sendTrap_Version3();
}
public void sendTrap_Version3() {
try {
// Create Transport Mapping
TransportMapping transport = new DefaultUdpTransportMapping();
transport.listen();
// Create Target
CommunityTarget cTarget = new CommunityTarget();
cTarget.setCommunity(new OctetString(community));
cTarget.setVersion(SnmpConstants.version2c);
cTarget.setAddress(new UdpAddress(ipAddress + "/" + port));
cTarget.setRetries(2);
cTarget.setTimeout(10000);
// Create PDU for V3
PDU pdu = new PDU();
pdu.setType(PDU.TRAP);
// need to specify the system up time
pdu.add(new VariableBinding(SnmpConstants.sysUpTime, new OctetString(new Date().toString())));
pdu.add(new VariableBinding(SnmpConstants.snmpTrapOID, new OID(Oid)));
pdu.add(new VariableBinding(new OID(Oid), new OctetString("Major")));
// Send the PDU
Snmp snmp = new Snmp(transport);
System.out.println("Sending V2 Trap... Check Wheather NMS is Listening or not? ");
ResponseEvent send = snmp.send(pdu, cTarget);
snmp.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Receiver Trap with Apache Camel
package <>;
import org.apache.camel.CamelContext;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.RoutesBuilder;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultCamelContext;
import org.snmp4j.*;
import org.snmp4j.mp.MPv1;
import org.snmp4j.mp.MPv2c;
import org.snmp4j.security.Priv3DES;
import org.snmp4j.security.SecurityProtocols;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.TcpAddress;
import org.snmp4j.smi.TransportIpAddress;
import org.snmp4j.smi.UdpAddress;
import org.snmp4j.transport.AbstractTransportMapping;
import org.snmp4j.transport.DefaultTcpTransportMapping;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import org.snmp4j.util.MultiThreadedMessageDispatcher;
import org.snmp4j.util.ThreadPool;
import java.io.IOException;
public class Trapreceiver implements CommandResponder {
public static CamelContext ctx=null;
public static ProducerTemplate producer=null;
public static void main(String[] args) {
Trapreceiver snmp4jTrapReceiver = new Trapreceiver();
SimpleRouteBuilder routeBuilder = new SimpleRouteBuilder();
ctx = new DefaultCamelContext();
producer = ctx.createProducerTemplate();
try {
ctx.addRoutes(routeBuilder);
ctx.start();
}
catch (Exception e) {
e.printStackTrace();
}
// producer.sendBody("direct:start", snmp);
try {
snmp4jTrapReceiver.listen(new UdpAddress("localhost/162"), producer);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Trap Listner
*/
public synchronized void listen(TransportIpAddress address, ProducerTemplate producer)
throws IOException {
AbstractTransportMapping transport;
if (address instanceof TcpAddress) {
transport = new DefaultTcpTransportMapping((TcpAddress) address);
} else {
transport = new DefaultUdpTransportMapping((UdpAddress) address);
}
ThreadPool threadPool = ThreadPool.create("DispatcherPool", 10);
MessageDispatcher mDispathcher = new MultiThreadedMessageDispatcher(
threadPool, new MessageDispatcherImpl());
// add message processing models
mDispathcher.addMessageProcessingModel(new MPv1());
mDispathcher.addMessageProcessingModel(new MPv2c());
// add all security protocols
SecurityProtocols.getInstance().addDefaultProtocols();
SecurityProtocols.getInstance().addPrivacyProtocol(new Priv3DES());
// Create Target
CommunityTarget target = new CommunityTarget();
target.setCommunity(new OctetString("public"));
Snmp snmp = new Snmp(mDispathcher, transport);
snmp.addCommandResponder(this);
transport.listen();
System.out.println("Listening on " + address);
try {
this.wait();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
/**
* This method will be called whenever a pdu is received on the given port
* specified in the listen() method
*/
public synchronized void processPdu(CommandResponderEvent cmdRespEvent) {
System.out.println("Received PDU...");
PDU pdu = cmdRespEvent.getPDU();
if (pdu != null) {
System.out.println("Trap Type = " + pdu.getType());
System.out.println("Variables = " + pdu.getVariableBindings());
producer.sendBody("direct:start","Variables = " + pdu.getVariableBindings() );
}
}
}

HTTPS Volley Invalid header issue

Before all : if you don't know the exact answer so just give me advice how to check. Thanks
I have alreary tried a lot of different way how to implement ssl to my volley request but without success.
I can not understand way I get this error
ResponseJsonString = <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
<HTML><HEAD><TITLE>Bad Request</TITLE>
<META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD>
<BODY><h2>Bad Request - Invalid Header</h2>
<hr><p>HTTP Error 400. The request has an invalid header name.</p>
</BODY></HTML>
So step by step my code implementation
This is how I get the volley queue
mRequestQueue = Volley.newRequestQueue(this, new SslHurlStuck(SslUtils.KEYSTORE, SslUtils.PASSWORD_SSL, this));
there is my SslHurlStuck
package utils.ssl;
import android.content.Context;
import android.util.Log;
import com.android.volley.toolbox.HurlStack;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
import utils.global.AppUtils;
public class SslHurlStuck extends HurlStack
{
private final static String TAG = SslHurlStuck.class.getSimpleName();
private String mTrustStoreAssetName;
private String mTrustStorePassword;
private Context mContext;
public SslHurlStuck(final String iTrustStoreAssetName, final String iTrustStorePassword, Context iContext)
{
super();
mTrustStoreAssetName = iTrustStoreAssetName;
mTrustStorePassword = iTrustStorePassword;
mContext = iContext;
}
#Override
protected HttpURLConnection createConnection(URL url) throws IOException
{
HttpsURLConnection urlConnection = null;
try
{
urlConnection = new PinnedCertificateHttpsURLConnectionFactory(mContext).createHttpsURLConnection(url.toString(), mTrustStoreAssetName, mTrustStorePassword);
}
catch (Throwable iThrowable)
{
AppUtils.printLog(Log.ERROR, TAG, iThrowable.getMessage());
}
return urlConnection;
}
}
And eventually there is my PinnedCertificateHttpsURLConnectionFactory
package utils.ssl;
import android.content.Context;
import android.util.Log;
import java.net.URL;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import utils.global.AppUtils;
import webServices.global.RequestStringBuilder;
public class PinnedCertificateHttpsURLConnectionFactory
{
private final static String TAG = PinnedCertificateHttpsURLConnectionFactory.class.getSimpleName();
private final Context mContext;
public PinnedCertificateHttpsURLConnectionFactory(Context iContext)
{
mContext = iContext;
}
HttpsURLConnection createHttpsURLConnection(String urlString, final String iTrustStoreAssetName, final String iTrustStorePassword) throws Throwable
{
// Initialize the trust manager factory instance with our trust store
// as source of certificate authorities and trust material.
KeyStore trustStore = new TrustStoreFactory(iTrustStoreAssetName, iTrustStorePassword, mContext).createTrustStore();
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(tmfAlgorithm);
trustManagerFactory.init(trustStore);
// Initialize the SSL context.
TrustManager[] wrappedTrustManagers = getWrappedTrustManagers(trustManagerFactory.getTrustManagers());
SSLContext sslContext = SSLContext.getInstance(SslUtils.PROTOCOL_TLS);
sslContext.init(null, wrappedTrustManagers, null);
// Create the https URL connection.
URL url = new URL(urlString);
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
urlConnection.setSSLSocketFactory(sslContext.getSocketFactory());
urlConnection.setHostnameVerifier(getHostnameVerifier());
return urlConnection;
}
// Let's assume your server app is hosting inside a server machine
// which has a server certificate in which "Issued to" is "localhost",for example.
// Then, inside verify method you can verify "localhost".
// If not, you can temporarily return true
private HostnameVerifier getHostnameVerifier()
{
return new HostnameVerifier()
{
#Override
public boolean verify(String hostname, SSLSession session)
{
HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();
String localHost = SslUtils.SSL_LOCAL_HOST_DEV;
if (RequestStringBuilder.isEnvironmentProd())
{
localHost = SslUtils.SSL_LOCAL_HOST_PROD;
}
return hv.verify(localHost, session);
// return hv.verify("localhost", session);
// return true;
}
};
}
private TrustManager[] getWrappedTrustManagers(TrustManager[] trustManagers)
{
final X509TrustManager originalTrustManager = (X509TrustManager) trustManagers[0];
final X509TrustManager x509TrustManager = new X509TrustManager()
{
public X509Certificate[] getAcceptedIssuers()
{
return originalTrustManager.getAcceptedIssuers();
}
public void checkClientTrusted(X509Certificate[] certs, String authType)
{
try
{
if (certs != null && certs.length > 0)
{
for (X509Certificate cer : certs)
{
cer.checkValidity();
}
}
else
{
originalTrustManager.checkClientTrusted(certs, authType);
}
}
catch (CertificateException e)
{
AppUtils.printLog(Log.ERROR, TAG, "checkClientTrusted" + e.toString());
}
}
public void checkServerTrusted(X509Certificate[] certs, String authType)
{
try
{
if (certs != null && certs.length > 0)
{
for (X509Certificate cer : certs)
{
cer.checkValidity();
}
}
else
{
originalTrustManager.checkServerTrusted(certs, authType);
}
}
catch (CertificateException e)
{
AppUtils.printLog(Log.ERROR, TAG, "checkServerTrusted" + e.toString());
}
}
};
return new TrustManager[] {x509TrustManager};
}
}
And last one TrustStoreFactory
public class TrustStoreFactory
{
private String mTrustStoreAssetName;
private String mTrustStorePassword;
private Context mContext;
public TrustStoreFactory(final String iTrustStoreAssetName, final String iTrustStorePassword, final Context iContext)
{
mTrustStoreAssetName = iTrustStoreAssetName;
mTrustStorePassword = iTrustStorePassword;
mContext = iContext;
}
KeyStore createTrustStore() throws Throwable
{
// Retrieve the trust store file from the assets.
InputStream inputStream = mContext.getAssets().open(mTrustStoreAssetName);
try
{
// Create a key store with the retrieved input stream.
KeyStore trustStore = KeyStore.getInstance(SslUtils.KEYSTORE_EXTENSION_BKS);
trustStore.load(inputStream, mTrustStorePassword.toCharArray());
return trustStore;
}
finally
{
inputStream.close();
}
}
}
So, question is , what am I doing wrong?
My keystore consist 2 cer files, I tried different combinations to add the cer to the keystore... but nothing was changed.
Actually I don't think that there is a problems with a code, I think some issue with certificates , but I can not understand what exactly, and how to fix it
And also what is intresting that in iOS the same ssl checking work in another way, we just need to get certificate from response and then getPublicKey() on it, and compare if public key from response certificate equal to certificate public key that consist within app... But in android it is much more difficult...
Feel free to ask
So eventyally in my case, I don't know why , but I just deleted Content-type header with the value from the response, and all is ok.
My answer was found here
Android Volley gives me 400 error
The Content-Type header is not treated the same way as other headers by Volley. In particular, overriding getHeaders() to change the content type does not always work. Check this ans for more information
Try this
headers.put("Content-Type", "application/json");

Java Simpleframework and SSL

When I run the code below i can access it okay over a browser, but I can't seem to get it to work using curl with this command:
curl -v -s -k "https://localhost:8080"
I am running the following code:
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.security.KeyStore;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import org.simpleframework.http.Request;
import org.simpleframework.http.Response;
import org.simpleframework.http.core.Container;
import org.simpleframework.transport.connect.Connection;
import org.simpleframework.transport.connect.SocketConnection;
/**
* Simple Server SSL Hello World Example.
*
*/
public class SimpleSSLHelloWorld implements Container {
public static int count = 0;
public static String EMTPY_STRING = "";
public static int serverPort;
public static String KEYSTORE_PROPERTY = "javax.net.ssl.keyStore";
public static String KEYSTORE_PASSWORD_PROPERTY = "javax.net.ssl.keyStorePassword";
public static String KEYSTORE_TYPE_PROPERTY = "javax.net.ssl.keyStoreType";
public static String KEYSTORE_ALIAS_PROPERTY = "javax.net.ssl.keyStoreAlias";
public static void main(final String[] args) throws Exception {
SimpleSSLHelloWorld.serverPort = 8080;
// System.setProperty("javax.net.debug", "all");
System.setProperty(SimpleSSLHelloWorld.KEYSTORE_PROPERTY, "mySrvKeystore");
System.setProperty(SimpleSSLHelloWorld.KEYSTORE_PASSWORD_PROPERTY, "123456");
Container container = new SimpleSSLHelloWorld();
SocketAddress address = new InetSocketAddress(SimpleSSLHelloWorld.serverPort);
SSLContext sslContext = SimpleSSLHelloWorld.createSSLContext();
Connection connectionHttps = new SocketConnection(container);
connectionHttps.connect(address, sslContext);
System.out.println("Simple Server started on port: " + SimpleSSLHelloWorld.serverPort);
}
public void handle(final Request request, final Response response) {
try {
System.out.println("what");
SimpleSSLHelloWorld.logRequest(request);
SimpleSSLHelloWorld.dummyResponse(response);
SimpleSSLHelloWorld.logResponse(response);
} catch (Exception e) {
e.printStackTrace();
}
}
public static SSLContext createSSLContext() throws Exception {
String keyStoreFile = System.getProperty(SimpleSSLHelloWorld.KEYSTORE_PROPERTY);
String keyStorePassword = System.getProperty(SimpleSSLHelloWorld.KEYSTORE_PASSWORD_PROPERTY,
SimpleSSLHelloWorld.EMTPY_STRING);
String keyStoreType = System.getProperty(SimpleSSLHelloWorld.KEYSTORE_TYPE_PROPERTY, KeyStore.getDefaultType());
KeyStore keyStore = SimpleSSLHelloWorld.loadKeyStore(keyStoreFile, keyStorePassword, null);
FileInputStream keyStoreFileInpuStream = null;
try {
if (keyStoreFile != null) {
keyStoreFileInpuStream = new FileInputStream(keyStoreFile);
keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(keyStoreFileInpuStream, keyStorePassword.toCharArray());
}
} finally {
if (keyStoreFileInpuStream != null) {
keyStoreFileInpuStream.close();
}
}
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, keyStorePassword.toCharArray());
SSLContext sslContext = SSLContext.getInstance("SSLv3");
// sslContext.init(keyManagerFactory.getKeyManagers(), new TrustManager[]{new NaiveX509TrustManager()}, null);
sslContext.init(keyManagerFactory.getKeyManagers(), null, null);
return sslContext;
}
public static KeyStore loadKeyStore(final String keyStoreFilePath, final String keyStorePassword,
final String keyStoreType) throws Exception {
KeyStore keyStore = null;
File keyStoreFile = new File(keyStoreFilePath);
if (keyStoreFile.isFile()) {
keyStore = KeyStore.getInstance(keyStoreType != null ? keyStoreType : KeyStore.getDefaultType());
keyStore.load(new FileInputStream(keyStoreFile), keyStorePassword != null ? keyStorePassword
.toCharArray() : SimpleSSLHelloWorld.EMTPY_STRING.toCharArray());
}
return keyStore;
}
public static void logRequest(final Request request) throws IOException {
StringBuilder builder = new StringBuilder();
builder.append(">>> REQUEST\n");
builder.append(request);
builder.append(request.getContent());
System.out.println(builder);
}
public static void logResponse(final Response response) throws IOException {
StringBuilder builder = new StringBuilder();
builder.append("<<< RESPONSE\n");
builder.append(response);
if (response.getContentLength() > 0) {
builder.append("... ").append(response.getContentLength()).append(" bytes ...\n");
}
System.out.println(builder);
}
public static void dummyResponse(final Response response) throws IOException {
PrintStream body = response.getPrintStream();
long time = System.currentTimeMillis();
response.set("Content-Type", "text/plain");
response.set("Server", "SSL HelloWorld/1.0 (Simple 4.0)");
response.setDate("Date", time);
response.setDate("Last-Modified", time);
body.println("Hello World: " + ++SimpleSSLHelloWorld.count);
body.close();
}
}
I'm stumped and not really sure why it doesn't work over curl.

Categories

Resources