]> git.basschouten.com Git - openhab-addons.git/blob
5f6181dfca607142cd946b682fc9ec2fe03c444b
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.ihc.internal.ws.http;
14
15 import java.security.KeyManagementException;
16 import java.security.NoSuchAlgorithmException;
17 import java.security.SecureRandom;
18 import java.security.cert.X509Certificate;
19
20 import javax.net.ssl.HostnameVerifier;
21 import javax.net.ssl.SSLContext;
22 import javax.net.ssl.SSLSession;
23 import javax.net.ssl.TrustManager;
24 import javax.net.ssl.X509TrustManager;
25
26 import org.apache.http.client.CookieStore;
27 import org.apache.http.client.HttpClient;
28 import org.apache.http.client.protocol.HttpClientContext;
29 import org.apache.http.config.Registry;
30 import org.apache.http.config.RegistryBuilder;
31 import org.apache.http.conn.socket.ConnectionSocketFactory;
32 import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
33 import org.apache.http.impl.client.BasicCookieStore;
34 import org.apache.http.impl.client.HttpClientBuilder;
35 import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 /**
40  * Custom HTTP connection pool, which install all-trusting trust manager.
41  *
42  * @author Pauli Anttila - Initial contribution
43  */
44 public class IhcConnectionPool {
45
46     private final Logger logger = LoggerFactory.getLogger(IhcConnectionPool.class);
47
48     /**
49      * Controller TLS certificate is self signed, which means that certificate
50      * need to be manually added to java key store as a trusted certificate.
51      * This is special SSL context which will be configured to trust all
52      * certificates and manual work is not required.
53      */
54     private SSLContext sslContext;
55
56     /** Holds and share cookie information (session id) from authentication procedure */
57     private CookieStore cookieStore;
58
59     private HttpClientBuilder httpClientBuilder;
60     private HttpClientContext localContext;
61
62     public IhcConnectionPool() {
63         init();
64     }
65
66     private void init() {
67         // Create a local instance of cookie store
68         cookieStore = new BasicCookieStore();
69
70         // Create local HTTP context
71         localContext = HttpClientContext.create();
72
73         // Bind custom cookie store to the local context
74         localContext.setCookieStore(cookieStore);
75
76         httpClientBuilder = HttpClientBuilder.create();
77
78         // Setup a Trust Strategy that allows all certificates.
79
80         logger.debug("Initialize SSL context");
81
82         // Create a trust manager that does not validate certificate chains, but accept all.
83         TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
84
85             @Override
86             public X509Certificate[] getAcceptedIssuers() {
87                 return null;
88             }
89
90             @Override
91             public void checkClientTrusted(X509Certificate[] certs, String authType) {
92             }
93
94             @Override
95             public void checkServerTrusted(X509Certificate[] certs, String authType) {
96                 logger.trace("Trusting server cert: {}", certs[0].getIssuerDN());
97             }
98         } };
99
100         // Install the all-trusting trust manager
101
102         try {
103             // Controller supports only SSLv3 and TLSv1
104             sslContext = SSLContext.getInstance("TLSv1");
105             sslContext.init(null, trustAllCerts, new SecureRandom());
106         } catch (NoSuchAlgorithmException e) {
107             logger.warn("Exception", e);
108         } catch (KeyManagementException e) {
109             logger.warn("Exception", e);
110         }
111
112         // Controller accepts only HTTPS connections and because normally IP address are used on home network rather
113         // than DNS names, create custom host name verifier.
114         HostnameVerifier hostnameVerifier = new HostnameVerifier() {
115
116             @Override
117             public boolean verify(String arg0, SSLSession arg1) {
118                 logger.trace("HostnameVerifier: arg0 = {}, arg1 = {}", arg0, arg1);
119                 return true;
120             }
121         };
122
123         // Create an SSL Socket Factory, to use our weakened "trust strategy"
124         SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext,
125                 new String[] { "TLSv1" }, null, hostnameVerifier);
126
127         Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create()
128                 .register("https", sslSocketFactory).build();
129
130         // Create connection-manager using our Registry. Allows multi-threaded use
131         PoolingHttpClientConnectionManager connMngr = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
132
133         // Increase max connection counts
134         connMngr.setMaxTotal(20);
135         connMngr.setDefaultMaxPerRoute(6);
136
137         httpClientBuilder.setConnectionManager(connMngr);
138     }
139
140     public HttpClient getHttpClient() {
141         return httpClientBuilder.build();
142     }
143
144     public HttpClientContext getHttpContext() {
145         return localContext;
146     }
147 }