OmniSciDB  04ee39c94c
SockTransportProperties.java
Go to the documentation of this file.
1 package com.mapd.common;
2 
3 import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
4 import org.apache.http.impl.client.CloseableHttpClient;
5 import org.apache.http.impl.client.HttpClients;
6 import org.apache.http.ssl.SSLContexts;
7 import org.apache.thrift.transport.THttpClient;
8 import org.apache.thrift.transport.TSSLTransportFactory;
9 import org.apache.thrift.transport.TServerSocket;
10 import org.apache.thrift.transport.TServerTransport;
11 import org.apache.thrift.transport.TSocket;
12 import org.apache.thrift.transport.TTransport;
13 import org.slf4j.LoggerFactory;
14 
15 import java.security.KeyStore;
16 import java.security.cert.X509Certificate;
17 
18 import javax.net.ssl.SSLContext;
19 import javax.net.ssl.TrustManager;
20 import javax.net.ssl.TrustManagerFactory;
21 import javax.net.ssl.X509TrustManager;
22 
24  final static org.slf4j.Logger MAPDLOGGER =
25  LoggerFactory.getLogger(SockTransportProperties.class);
26 
27  /*
28  * The following static 'factory' methods have been added to make usage of this
29  * class simpler. The previously defined constructors have been left public to
30  * limit the scope of the current change, though ideally they should be removed
31  * and the calling code replaced with use of these static methods.
32  */
33  static public SockTransportProperties getUnencryptedClient() throws Exception {
35  }
36 
37  static public SockTransportProperties getEncryptedClientPermisive() throws Exception {
39  }
40 
42  throws Exception {
44  }
45 
47  String trustStoreName, String trustStorePassword) throws Exception {
49  trustStoreName,
50  trustStorePassword);
51  }
52 
54  String keyStoreName, String keyStorePassword) throws Exception {
55  return new SockTransportProperties(
56  TransportType.encryptedServer, keyStoreName, keyStorePassword);
57  }
58 
59  static public SockTransportProperties getUnecryptedServer() throws Exception {
61  }
62 
63  /* There are nominally 5 different 'types' of this class. */
64  private enum TransportType {
70  encryptedClientSpecifiedTrustStore
71  }
72 
73  public SockTransportProperties(boolean load_trust) throws Exception {
74  this((load_trust == true) ? TransportType.encryptedClientDefaultTrustStore
76  }
77 
78  public SockTransportProperties(String truststore_name, String truststore_passwd)
79  throws Exception {
81  truststore_name,
82  truststore_passwd);
83  }
84 
86  throws Exception {
87  transportType = tT;
88  // Load the supplied file into a java keystore object to ensure it is okay. If
89  // the keystore
90  // contain client trust information it is used to initialize the TrustManager
91  // factory, otherwise it is discarded.
92  // The file name is stored in a member variable. When the required
93  // open method is called the stored file name is passed to the appropriate
94  // TSSLTransportParameters
95  // method.
96  KeyStore kS = KeyStore.getInstance(KeyStore.getDefaultType());
97  char[] store_password = null;
98  String store_name = null;
99  if (passwd != null && !passwd.isEmpty()) {
100  store_password = passwd.toCharArray();
101  }
102  if (name != null && !name.isEmpty()) {
103  store_name = name;
104  }
105  try {
106  java.io.FileInputStream fis = new java.io.FileInputStream(name);
107  kS.load(fis, store_password);
108  } catch (Exception eX) {
109  String err_str = new String("Error loading key/trut store [" + name + "]");
110  MAPDLOGGER.error(err_str, eX);
111  throw(eX);
112  }
113 
115  // key_store_set = true;
116  key_store_password = store_password;
117  key_store_name = store_name;
118  } else {
120  trust_store_password = store_password;
121  trust_store_name = store_name;
122  // trust_store_set = true;
123  }
124  }
125 
127  // This constructor will either not bother loading trust data (and then trust
128  // all server certs) or load from the java default trust stores.
130  switch (transportType) {
131  case encryptedClientDefaultTrustStore:
132  initializeAcceptedIssuers((KeyStore) null);
133  break;
134  case encryptedClientPermissive:
135  // trust_all_certs = true;
136  case unencryptedClient:
137  // do nothing
138  case unencryptedServer:
139  // do nothing
140  break;
141  default:
142  String errStr = new String(
143  "Invalid transportType [" + transportType + "] used in constructor");
144  RuntimeException rE = new RuntimeException(errStr);
145  MAPDLOGGER.error(errStr, rE);
146  throw(rE);
147  }
148  }
149 
150  private void initializeAcceptedIssuers(KeyStore kS) throws Exception {
151  TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("PKIX");
152  trustManagerFactory.init(kS);
153  trustManagers = trustManagerFactory.getTrustManagers();
154  X509TrustManager x509TrustManager = (X509TrustManager) trustManagers[0];
155  }
156 
157  /*
158  * open HTTPS *********************
159  */
160 
161  private static X509TrustManager createInsecureTrustManager() {
162  return new X509TrustManager() {
163  public X509Certificate[] getAcceptedIssuers() {
164  return null;
165  }
166 
167  public void checkClientTrusted(X509Certificate[] certs, String authType) {}
168 
169  public void checkServerTrusted(X509Certificate[] certs, String authType) {}
170  };
171  }
172 
173  public TTransport openHttpsClientTransport(String server_host, int port)
174  throws Exception {
175  // Simple TrustManager to trust all certs
176  TrustManager[] trustAllCerts = {createInsecureTrustManager()};
177 
178  TTransport transport = null;
179  try {
180  // Build a regular apache ClosableHttpClient based on a SSL connection
181  // that can be passed to the apache thrift THttpClient constructor.
182 
183  SSLContext sc = null;
184  sc = SSLContexts.custom().useProtocol("SSL").build();
185  SSLConnectionSocketFactory sslConnectionSocketFactory = null;
187  sc.init(null, trustManagers, new java.security.SecureRandom());
188  sslConnectionSocketFactory = new SSLConnectionSocketFactory(
189  sc, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
190  } else {
191  sc.init(null, trustAllCerts, new java.security.SecureRandom());
192  sslConnectionSocketFactory = new SSLConnectionSocketFactory(
193  sc, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
194  }
195  CloseableHttpClient closeableHttpClient =
196  HttpClients.custom()
197  .setSSLSocketFactory(sslConnectionSocketFactory)
198  .build();
199  transport =
200  new THttpClient("https://" + server_host + ":" + port, closeableHttpClient);
201  } catch (Exception ex) {
202  String err_str = new String("Exception:" + ex.getClass().getCanonicalName()
203  + " thown. Unable to create Secure socket for the HTTPS connection");
204  MAPDLOGGER.error(err_str, ex);
205  throw ex;
206  }
207 
208  return transport;
209  }
210 
211  /*
212  * open HTTP *********************
213  */
214  public TTransport openHttpClientTransport(String server_host, int port)
215  throws org.apache.thrift.TException {
216  String url = "http://" + server_host + ":" + port;
217  return (new THttpClient(url));
218  }
219 
220  /*
221  * open Binary Server *********************
222  */
223  public TServerTransport openServerTransport(int port)
224  throws org.apache.thrift.TException {
226  return openServerTransportEncrypted(port);
227  } else {
228  return (new TServerSocket(port));
229  }
230  }
231 
232  public TServerTransport openServerTransportEncrypted(int port)
233  throws org.apache.thrift.TException {
234  // Used to set Socket.setSoTimeout ms. 0 == inifinite.
235  int socket_so_timeout_ms = 0;
236  TSSLTransportFactory.TSSLTransportParameters params =
237  new TSSLTransportFactory.TSSLTransportParameters();
238  params.setKeyStore(key_store_name,
239  (key_store_password != null) ? new String(key_store_password) : null);
240  params.requireClientAuth(false);
241 
242  // return TSSLTransportFactory.getClientSocket(server_host, port,
243  // socket_so_timeout_ms, params);
244  TServerTransport t = TSSLTransportFactory.getServerSocket(
245  port, socket_so_timeout_ms, null, params);
246  return t;
247  }
248 
249  /*
250  * open Binary *********************
251  */
252  public TTransport openClientTransport(String server_host, int port)
253  throws org.apache.thrift.TException {
255  return openClientTransportEncrypted(server_host, port);
256  } else {
257  return (new TSocket(server_host, port));
258  }
259  }
260 
261  public TTransport openClientTransportEncrypted(String server_host, int port)
262  throws org.apache.thrift.TException {
263  // Used to set Socket.setSoTimeout ms. 0 == inifinite.
264  int socket_so_timeout_ms = 0;
266  return TSSLTransportFactory.getClientSocket(
267  server_host, port, socket_so_timeout_ms);
268  }
269  TSSLTransportFactory.TSSLTransportParameters params =
270  new TSSLTransportFactory.TSSLTransportParameters();
271  params.setTrustStore(trust_store_name,
272  (trust_store_password != null) ? new String(trust_store_password) : null);
273  params.requireClientAuth(false);
274 
275  return TSSLTransportFactory.getClientSocket(
276  server_host, port, socket_so_timeout_ms, params);
277  }
278 
279  private TrustManager[] trustManagers;
280  // private boolean trust_all_certs = false;
281 
282  // TODO MAT the latest set of changes here appear to use a
283  // SocketTransportProperties as the deciding mechanism of what
284  // kind of connection to create encrypted or unencrypted
285  // but the decision of which entry point to call has been passed
286  // upstream to the caller
287  // I have introduced this hack currently to get around broken
288  // catalog when certs are enabled to allow the call to open
289  // a connection to know to use and encrypted one when requested
290  // to from upstream (ie a trust store was explicitly give in the
291  // case of catalog connection)
292  private TransportType transportType = null;
293  private String trust_store_name = null;
294  private char[] trust_store_password = null;
295  private String key_store_name = null;
296  private char[] key_store_password = null;
297 }
static SockTransportProperties getEncryptedClientSpecifiedTrustStore(String trustStoreName, String trustStorePassword)
TTransport openHttpClientTransport(String server_host, int port)
TTransport openHttpsClientTransport(String server_host, int port)
static SockTransportProperties getUnecryptedServer()
SockTransportProperties(String truststore_name, String truststore_passwd)
TServerTransport openServerTransportEncrypted(int port)
TTransport openClientTransport(String server_host, int port)
static SockTransportProperties getEncryptedServer(String keyStoreName, String keyStorePassword)
TTransport openClientTransportEncrypted(String server_host, int port)
SockTransportProperties(TransportType tT, String name, String passwd)
static SockTransportProperties getEncryptedClientDefaultTrustStore()
static SockTransportProperties getUnencryptedClient()
SockTransportProperties(TransportType transportType)
static SockTransportProperties getEncryptedClientPermisive()