You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by lm...@apache.org on 2016/09/08 14:50:06 UTC

knox git commit: KNOX-733 - Add support for custom truststore to Knox shell client

Repository: knox
Updated Branches:
  refs/heads/master 495369f98 -> 684466faa


KNOX-733 - Add support for custom truststore to Knox shell client

Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/684466fa
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/684466fa
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/684466fa

Branch: refs/heads/master
Commit: 684466faadf4627391bd74042c782ec47a44d6b5
Parents: 495369f
Author: Larry McCay <lm...@hortonworks.com>
Authored: Thu Sep 8 10:49:44 2016 -0400
Committer: Larry McCay <lm...@hortonworks.com>
Committed: Thu Sep 8 10:49:44 2016 -0400

----------------------------------------------------------------------
 .../shell/ClearInputCredentialCollector.java    |   2 +-
 .../org/apache/hadoop/gateway/shell/Hadoop.java | 118 ++++++++++++++++++-
 .../shell/HiddenInputCredentialCollector.java   |   2 +-
 .../shell/hbase/table/row/InsertableColumn.java |   3 -
 .../security/impl/X509CertificateUtil.java      |   2 +-
 5 files changed, 119 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/knox/blob/684466fa/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/ClearInputCredentialCollector.java
----------------------------------------------------------------------
diff --git a/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/ClearInputCredentialCollector.java b/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/ClearInputCredentialCollector.java
index 49e086c..496f6ea 100644
--- a/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/ClearInputCredentialCollector.java
+++ b/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/ClearInputCredentialCollector.java
@@ -19,7 +19,7 @@ package org.apache.hadoop.gateway.shell;
 
 
 public class ClearInputCredentialCollector extends AbstractJavaConsoleCredentialCollector {
-  public static String COLLECTOR_TYPE = "ClearInput";
+  public static final String COLLECTOR_TYPE = "ClearInput";
   /* (non-Javadoc)
    * @see org.apache.hadoop.gateway.shell.CredentialCollector#collect()
    */

http://git-wip-us.apache.org/repos/asf/knox/blob/684466fa/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/Hadoop.java
----------------------------------------------------------------------
diff --git a/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/Hadoop.java b/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/Hadoop.java
index ac5e968..6bfc407 100644
--- a/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/Hadoop.java
+++ b/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/Hadoop.java
@@ -17,6 +17,7 @@
  */
 package org.apache.hadoop.gateway.shell;
 
+import org.apache.commons.io.IOUtils;
 import org.apache.http.HttpHost;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
@@ -27,6 +28,7 @@ import org.apache.http.client.protocol.ClientContext;
 import org.apache.http.conn.scheme.PlainSocketFactory;
 import org.apache.http.conn.scheme.Scheme;
 import org.apache.http.conn.scheme.SchemeRegistry;
+import org.apache.http.conn.ssl.SSLContextBuilder;
 import org.apache.http.conn.ssl.SSLSocketFactory;
 import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
 import org.apache.http.impl.auth.BasicScheme;
@@ -35,10 +37,18 @@ import org.apache.http.impl.client.DefaultHttpClient;
 import org.apache.http.impl.conn.PoolingClientConnectionManager;
 import org.apache.http.protocol.BasicHttpContext;
 
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.io.InputStream;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
@@ -47,8 +57,16 @@ import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
+import javax.net.ssl.SSLContext;
+
 public class Hadoop {
 
+  private static final String GATEWAY_CLIENT_TRUST_DEFAULT_PASS = "changeit";
+  private static final String KNOX_CLIENT_TRUSTSTORE_PASS = "KNOX_CLIENT_TRUSTSTORE_PASS";
+  private static final String GATEWAY_CLIENT_TRUST = "gateway-client-trust.jks";
+  private static final String KNOX_CLIENT_TRUSTSTORE_FILENAME = "KNOX_CLIENT_TRUSTSTORE_FILENAME";
+  private static final String KNOX_CLIENT_TRUSTSTORE_DIR = "KNOX_CLIENT_TRUSTSTORE_DIR";
+
   String base;
   HttpHost host;
   DefaultHttpClient client;
@@ -58,10 +76,25 @@ public class Hadoop {
   ExecutorService executor;
 
   public static Hadoop login( String url, String username, String password ) throws URISyntaxException {
+    return new Hadoop( url, username, password, true );
+  }
+
+  public static Hadoop loginInsecure( String url, String username, String password ) throws URISyntaxException {
+    System.out.println("**************** WARNING ******************\n"
+        + "This is an insecure client instance and may\n"
+        + "leave the interactions subject to a man in\n"
+        + "the middle attack. Please use the login()\n"
+        + "method instead of loginInsecure() for any\n"
+        + "sensitive or production usecases.\n"
+        + "*******************************************");
     return new Hadoop( url, username, password );
   }
 
   private Hadoop( String url, String username, String password ) throws HadoopException, URISyntaxException {
+    this(url, username, password, false);
+  }
+
+  private Hadoop( String url, String username, String password, boolean secure ) throws HadoopException, URISyntaxException {
     this.executor = Executors.newCachedThreadPool();
     this.base = url;
     this.username = username;
@@ -71,7 +104,12 @@ public class Hadoop {
     host = new HttpHost( uri.getHost(), uri.getPort(), uri.getScheme() );
 
     try {
-      client = createClient();
+      if (!secure) {
+        client = createInsecureClient();
+      }
+      else {
+        client = createClient();
+      }
       client.getCredentialsProvider().setCredentials(
           new AuthScope( host.getHostName(), host.getPort() ),
           new UsernamePasswordCredentials( username, password ) );
@@ -87,7 +125,83 @@ public class Hadoop {
 
   private static DefaultHttpClient createClient() throws GeneralSecurityException {
     SchemeRegistry registry = new SchemeRegistry();
-    SSLSocketFactory socketFactory = new SSLSocketFactory( new TrustSelfSignedStrategy(), SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER );
+    KeyStore trustStore = getTrustStore();
+    SSLSocketFactory socketFactory = new SSLSocketFactory(trustStore);
+    registry.register( new Scheme( "https", 443, socketFactory ) );
+    registry.register( new Scheme( "http", 80, new PlainSocketFactory() ) );
+    PoolingClientConnectionManager mgr = new PoolingClientConnectionManager( registry );
+    DefaultHttpClient client = new DefaultHttpClient( mgr, new DefaultHttpClient().getParams() );
+    return client;
+  }
+
+  private static KeyStore getTrustStore() throws GeneralSecurityException {
+    KeyStore ks = null;
+    String truststoreDir = System.getenv(KNOX_CLIENT_TRUSTSTORE_DIR);
+    if (truststoreDir == null) {
+      truststoreDir = System.getProperty("user.home");
+    }
+    String truststoreFileName = System.getenv(KNOX_CLIENT_TRUSTSTORE_FILENAME);
+    if (truststoreFileName == null) {
+      truststoreFileName = GATEWAY_CLIENT_TRUST;
+    }
+    String truststorePass = System.getenv(KNOX_CLIENT_TRUSTSTORE_PASS);
+    if (truststorePass == null) {
+      truststorePass = GATEWAY_CLIENT_TRUST_DEFAULT_PASS;
+    }
+
+    InputStream is = null;
+    try {
+      ks = KeyStore.getInstance("JKS");
+      File file = new File(truststoreDir, truststoreFileName);
+      if (!file.exists()) {
+        String truststore = System.getProperty("javax.net.ssl.trustStore");
+        if (truststore == null) {
+          truststoreDir = System.getProperty("java.home");
+          truststore = truststoreDir + File.separator + "lib" + File.separator
+              + "security" + File.separator + "cacerts";
+          truststorePass = System.getProperty("javax.net.ssl.trustStorePassword", "changeit");
+        }
+        file = new File(truststore);
+      }
+
+      if (file.exists()) {
+        is = new FileInputStream(file);
+        ks.load(is, truststorePass.toCharArray());
+      }
+      else {
+        throw new HadoopException("Unable to find a truststore for secure login."
+            + "Please import the gateway-identity certificate into the JVM"
+          + " truststore or set the truststore location ENV variables.");
+      }
+    } catch (KeyStoreException e) {
+      throw new HadoopException("Unable to create keystore of expected type.", e);
+    } catch (FileNotFoundException e) {
+      throw new HadoopException("Unable to read truststore."
+          + " Please import the gateway-identity certificate into the JVM"
+          + " truststore or set the truststore location ENV variables.", e);
+    } catch (NoSuchAlgorithmException e) {
+      throw new HadoopException("Unable to load the truststore."
+          + " Please import the gateway-identity certificate into the JVM"
+          + " truststore or set the truststore location ENV variables.", e);
+    } catch (CertificateException e) {
+      throw new HadoopException("Certificate cannot be found in the truststore."
+          + " Please import the gateway-identity certificate into the JVM"
+          + " truststore or set the truststore location ENV variables.", e);
+    } catch (IOException e) {
+      throw new HadoopException("Unable to load truststore."
+          + " May be related to password setting or truststore format.", e);
+    } finally {
+       IOUtils.closeQuietly(is);
+    }
+
+    return ks;
+  }
+
+  private static DefaultHttpClient createInsecureClient() throws GeneralSecurityException {
+    SchemeRegistry registry = new SchemeRegistry();
+    SSLSocketFactory socketFactory = new SSLSocketFactory(
+        new TrustSelfSignedStrategy(),
+        SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER );
     registry.register( new Scheme( "https", 443, socketFactory ) );
     registry.register( new Scheme( "http", 80, new PlainSocketFactory() ) );
     PoolingClientConnectionManager mgr = new PoolingClientConnectionManager( registry );

http://git-wip-us.apache.org/repos/asf/knox/blob/684466fa/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/HiddenInputCredentialCollector.java
----------------------------------------------------------------------
diff --git a/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/HiddenInputCredentialCollector.java b/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/HiddenInputCredentialCollector.java
index 6e350de..5d95d81 100644
--- a/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/HiddenInputCredentialCollector.java
+++ b/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/HiddenInputCredentialCollector.java
@@ -19,7 +19,7 @@ package org.apache.hadoop.gateway.shell;
 
 
 public class HiddenInputCredentialCollector extends AbstractJavaConsoleCredentialCollector {
-  public static String COLLECTOR_TYPE = "HiddenInput";
+  public static final String COLLECTOR_TYPE = "HiddenInput";
   /* (non-Javadoc)
    * @see org.apache.hadoop.gateway.shell.CredentialCollector#collect()
    */

http://git-wip-us.apache.org/repos/asf/knox/blob/684466fa/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/hbase/table/row/InsertableColumn.java
----------------------------------------------------------------------
diff --git a/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/hbase/table/row/InsertableColumn.java b/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/hbase/table/row/InsertableColumn.java
index 12c4c29..77198bf 100644
--- a/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/hbase/table/row/InsertableColumn.java
+++ b/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/hbase/table/row/InsertableColumn.java
@@ -45,9 +45,6 @@ public class InsertableColumn extends Column {
 
   public String encodedValue() throws UnsupportedEncodingException {
     String stringValue = value.toString();
-    if( stringValue == null ) {
-      stringValue = "";
-    }
     return Base64.encodeBase64String( stringValue.getBytes( "UTF-8" ) );
   }
 }

http://git-wip-us.apache.org/repos/asf/knox/blob/684466fa/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/impl/X509CertificateUtil.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/impl/X509CertificateUtil.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/impl/X509CertificateUtil.java
index e31c7d8..f6a7ecd 100644
--- a/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/impl/X509CertificateUtil.java
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/impl/X509CertificateUtil.java
@@ -291,7 +291,7 @@ public class X509CertificateUtil {
       throws IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException {
     KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
 
-    char[] password = "changeme".toCharArray();
+    char[] password = "changeit".toCharArray();
     ks.load(null, password);
     ks.setCertificateEntry("gateway-identity", cert);
     FileOutputStream fos = new FileOutputStream(file);