This is an automated email from the ASF dual-hosted git repository.

abti pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/gobblin.git


The following commit(s) were added to refs/heads/master by this push:
     new c6a8da8  [GOBBLIN-1429] Add secure TrustManager for LDAP Utils
c6a8da8 is described below

commit c6a8da8eab1b923c311003b5689b912ccaf9aac1
Author: Abhishek Tiwari <[email protected]>
AuthorDate: Sat Apr 17 01:34:30 2021 -0700

    [GOBBLIN-1429] Add secure TrustManager for LDAP Utils
    
    Closes #3264 from abti/master
---
 .../java/org/apache/gobblin/util/LdapUtils.java    |  13 ++-
 .../util/TrustManagerSecureSocketFactory.java      | 126 +++++++++++++++++++++
 2 files changed, 138 insertions(+), 1 deletion(-)

diff --git 
a/gobblin-utility/src/main/java/org/apache/gobblin/util/LdapUtils.java 
b/gobblin-utility/src/main/java/org/apache/gobblin/util/LdapUtils.java
index 9d30d86..305c46b 100644
--- a/gobblin-utility/src/main/java/org/apache/gobblin/util/LdapUtils.java
+++ b/gobblin-utility/src/main/java/org/apache/gobblin/util/LdapUtils.java
@@ -42,6 +42,7 @@ public class LdapUtils {
   public static final String LDAP_PORT_KEY = LDAP_PREFIX + ".port";
   public static final String LDAP_USER_KEY = LDAP_PREFIX + ".username";
   public static final String LDAP_PASSWORD_KEY = LDAP_PREFIX + ".password";
+  public static final String LDAP_USE_SECURE_TRUSTMANAGER = LDAP_PREFIX + 
".useSecureTrustManager";
 
   private static final Logger logger = Logger.getLogger(LdapUtils.class);
 
@@ -52,6 +53,7 @@ public class LdapUtils {
   // Creds of headless account for searching LDAP
   private final String _ldapUser;
   private final String _ldapPassword;
+  private final boolean _ldapUseSecureTrustManager;
 
   private final String _personSearchFilter = 
"(&(objectcategory=Person)(samaccountname=%s))";
   private final String _groupSearchFilter = "(&(objectcategory=Group)(cn=%s))";
@@ -69,6 +71,11 @@ public class LdapUtils {
     _ldapUser = config.getString(LDAP_USER_KEY);
     _ldapPassword = password;
     _ldapBaseDN = config.getString(LDAP_BASE_DN_KEY);
+    if(config.hasPath(LDAP_USE_SECURE_TRUSTMANAGER)) {
+      _ldapUseSecureTrustManager = 
config.getBoolean(LDAP_USE_SECURE_TRUSTMANAGER);
+    } else {
+      _ldapUseSecureTrustManager = false;
+    }
   }
 
   /**
@@ -87,7 +94,11 @@ public class LdapUtils {
     env.put(Context.SECURITY_PRINCIPAL, username);
     env.put(Context.SECURITY_CREDENTIALS, password);
 
-    env.put("java.naming.ldap.factory.socket", 
TrustManagerSocketFactory.class.getCanonicalName());
+    if (_ldapUseSecureTrustManager) {
+      env.put("java.naming.ldap.factory.socket", 
TrustManagerSecureSocketFactory.class.getCanonicalName());
+    } else {
+      env.put("java.naming.ldap.factory.socket", 
TrustManagerSocketFactory.class.getCanonicalName());
+    }
 
     return new InitialDirContext(env);
   }
diff --git 
a/gobblin-utility/src/main/java/org/apache/gobblin/util/TrustManagerSecureSocketFactory.java
 
b/gobblin-utility/src/main/java/org/apache/gobblin/util/TrustManagerSecureSocketFactory.java
new file mode 100644
index 0000000..d3f822f
--- /dev/null
+++ 
b/gobblin-utility/src/main/java/org/apache/gobblin/util/TrustManagerSecureSocketFactory.java
@@ -0,0 +1,126 @@
+/*
+ * 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.gobblin.util;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.slf4j.LoggerFactory;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+
+
+public class TrustManagerSecureSocketFactory extends SSLSocketFactory {
+  private static final org.slf4j.Logger LOG = 
LoggerFactory.getLogger(TrustManagerSecureSocketFactory.class);
+
+  private SSLSocketFactory sslSocketFactory;
+  private String[] ciphers;
+  private String protocol;
+
+  public TrustManagerSecureSocketFactory() {
+    this(null, null);
+  }
+
+  public TrustManagerSecureSocketFactory(String[] ciphers, String protocol) {
+    try {
+      SSLContext ctx = SSLContext.getInstance("TLS");
+      this.sslSocketFactory = ctx.getSocketFactory();
+      this.ciphers = (null == ciphers) ? 
sslSocketFactory.getSupportedCipherSuites() : ciphers;
+      this.protocol = (null == protocol) ? ctx.getProtocol() : protocol;
+    } catch (NoSuchAlgorithmException e) {
+      throw new RuntimeException("Issue in initializing 
TrustManagerSecureSocketFactory.", e);
+    }
+  }
+
+  public String[] getDefaultCipherSuites() {
+    return sslSocketFactory.getDefaultCipherSuites();
+  }
+
+  public String[] getSupportedCipherSuites() {
+    return sslSocketFactory.getSupportedCipherSuites();
+  }
+
+  public Socket createSocket(Socket s, String host, int port, boolean 
autoClose)
+      throws IOException  {
+    return enableCipherSuites(sslSocketFactory.createSocket(s, host, port, 
autoClose),
+        new Object[]{host, port});
+  }
+
+  public Socket createSocket(String host, int port) throws IOException {
+    return enableCipherSuites(sslSocketFactory.createSocket(host, port),
+        new Object[]{host, port});
+  }
+
+  public Socket createSocket(String host, int port, InetAddress localHost, int 
localPort)
+      throws IOException {
+    return enableCipherSuites(sslSocketFactory.createSocket(host, port, 
localHost, localPort),
+        new Object[]{host, port});
+  }
+
+  public Socket createSocket(InetAddress host, int port) throws IOException {
+    return enableCipherSuites(sslSocketFactory.createSocket(host, port),
+        new Object[]{host, port});
+  }
+
+  public Socket createSocket(InetAddress address, int port, InetAddress 
localAddress, int localPort)
+      throws IOException {
+    return enableCipherSuites(sslSocketFactory.createSocket(address, port, 
localAddress, localPort),
+        new Object[]{address, port});
+  }
+
+  private Socket enableCipherSuites(Socket s, Object[] logParams) {
+    SSLSocket socket = (SSLSocket)s;
+
+    if (socket == null) {
+      LOG.warn("PROBLEM_CREATING_OUTBOUND_REQUEST_SOCKET", logParams);
+      return null;
+    }
+
+    if (protocol != null) {
+      String[] p = findProtocols(protocol, socket.getSupportedProtocols());
+      if (p != null) {
+        socket.setEnabledProtocols(p);
+      }
+    }
+    if (ciphers != null) {
+      socket.setEnabledCipherSuites(ciphers);
+    }
+
+    return socket;
+  }
+  private String[] findProtocols(String p, String[] options) {
+    List<String> list = new ArrayList<>();
+    for (String s : options) {
+      if (s.equals(p)) {
+        return new String[] {p};
+      } else if (s.startsWith(p)) {
+        list.add(s);
+      }
+    }
+    if (list.isEmpty()) {
+      return null;
+    }
+    return list.toArray(new String[0]);
+  }
+}
\ No newline at end of file

Reply via email to