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);