This is an automated email from the ASF dual-hosted git repository. ritik pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/asterixdb.git
commit de80a9cbbf164f51eb435ddd21c65d3a747319f5 Author: Michael Blow <[email protected]> AuthorDate: Wed Oct 9 21:19:47 2024 -0400 [NO ISSUE][HYR][NET] Extend SSL engine API to indicate client use Ext-ref: MB-52099 Change-Id: Id46266849ded6d0ea632293e829aed78396e0ea1 Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/18950 Tested-by: Jenkins <[email protected]> Reviewed-by: Michael Blow <[email protected]> Reviewed-by: Murtadha Hubail <[email protected]> --- .../external/library/ExternalLibraryManager.java | 8 ++-- .../apache/asterix/metadata/RMIClientFactory.java | 2 +- .../apache/asterix/metadata/RMIServerFactory.java | 2 +- hyracks-fullstack/hyracks/hyracks-api/pom.xml | 4 ++ .../api/network/INetworkSecurityConfig.java | 40 +++++++++++++--- .../api/network/INetworkSecurityManager.java | 4 +- hyracks-fullstack/hyracks/hyracks-ipc/pom.xml | 4 ++ .../ipc/security/NetworkSecurityConfig.java | 30 ++++++++++-- .../ipc/security/NetworkSecurityManager.java | 56 +++++++++++----------- .../ipc/sockets/SslSocketChannelFactory.java | 6 +-- 10 files changed, 105 insertions(+), 51 deletions(-) diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/library/ExternalLibraryManager.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/library/ExternalLibraryManager.java index 050d9f0071..174369542a 100755 --- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/library/ExternalLibraryManager.java +++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/library/ExternalLibraryManager.java @@ -48,6 +48,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.function.Function; import java.util.zip.ZipEntry; @@ -657,11 +658,10 @@ public class ExternalLibraryManager implements ILibraryManager, ILifeCycleCompon final INetworkSecurityConfig configuration = networkSecurityManager.getConfiguration(); KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); try (FileInputStream trustStoreFile = new FileInputStream(configuration.getTrustStoreFile())) { - String ksPassword = configuration.getKeyStorePassword(); - trustStore.load(trustStoreFile, - ksPassword == null || ksPassword.isEmpty() ? null : ksPassword.toCharArray()); + Optional<char[]> ksPassword = configuration.getKeyStorePassword(); + trustStore.load(trustStoreFile, ksPassword.orElse(null)); } - SSLContext sslcontext = NetworkSecurityManager.newSSLContext(configuration); + SSLContext sslcontext = NetworkSecurityManager.newSSLContext(configuration, false); SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1.2" }, null, SSLConnectionSocketFactory.getDefaultHostnameVerifier()); return HttpClients.custom().setSSLSocketFactory(sslsf).build(); diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/RMIClientFactory.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/RMIClientFactory.java index ce459e27f7..da802a74f0 100644 --- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/RMIClientFactory.java +++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/RMIClientFactory.java @@ -68,7 +68,7 @@ public class RMIClientFactory implements RMIClientSocketFactory, Serializable { protected SSLSocketFactory factory; public RMITrustedClientSSLSocketFactory(INetworkSecurityConfig config) { - this.factory = NetworkSecurityManager.newSSLContext(config).getSocketFactory(); + this.factory = NetworkSecurityManager.newSSLContext(config, false).getSocketFactory(); } public Socket createSocket(InetAddress host, int port) throws IOException { diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/RMIServerFactory.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/RMIServerFactory.java index 6a0edc00e1..845324a157 100644 --- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/RMIServerFactory.java +++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/RMIServerFactory.java @@ -46,7 +46,7 @@ public class RMIServerFactory implements RMIServerSocketFactory { public ServerSocket createServerSocket(int port) throws IOException { ServerSocketFactory socketFactory; if (securityManager.getConfiguration().isSslEnabled()) { - socketFactory = securityManager.newSSLContext().getServerSocketFactory(); + socketFactory = securityManager.newSSLContext(false).getServerSocketFactory(); } else { socketFactory = ServerSocketFactory.getDefault(); } diff --git a/hyracks-fullstack/hyracks/hyracks-api/pom.xml b/hyracks-fullstack/hyracks/hyracks-api/pom.xml index 7a4eb58cf9..eee03f3570 100644 --- a/hyracks-fullstack/hyracks/hyracks-api/pom.xml +++ b/hyracks-fullstack/hyracks/hyracks-api/pom.xml @@ -105,5 +105,9 @@ <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> </dependency> + <dependency> + <groupId>io.netty</groupId> + <artifactId>netty-handler</artifactId> + </dependency> </dependencies> </project> diff --git a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/network/INetworkSecurityConfig.java b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/network/INetworkSecurityConfig.java index 7fc0335c5c..e581c5a00f 100644 --- a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/network/INetworkSecurityConfig.java +++ b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/network/INetworkSecurityConfig.java @@ -24,6 +24,8 @@ import java.net.InetAddress; import java.security.KeyStore; import java.util.Optional; +import io.netty.handler.ssl.ClientAuth; + public interface INetworkSecurityConfig extends Serializable { /** @@ -33,26 +35,52 @@ public interface INetworkSecurityConfig extends Serializable { */ boolean isSslEnabled(); + /** + * Indicates how to handle client authentication when ssl is enabled + */ + ClientAuth getClientAuth(); + /** * Gets the key store to be used for secured connections * - * @return the key store to be used + * @return the key store to be used, if present */ - KeyStore getKeyStore(); + Optional<KeyStore> getKeyStore(); /** - * Gets a key store file to be used if {@link INetworkSecurityConfig#getKeyStore()} returns null. + * Gets a key store file, password pair to be used if {@link INetworkSecurityConfig#getKeyStore()} returns empty. * * @return the key store file */ File getKeyStoreFile(); /** - * Gets the password for the key store file. + * Gets a password to be used to unlock or check integrity of the key store. + * + * @return the key store password, or {@link Optional#empty()} + */ + Optional<char[]> getKeyStorePassword(); + + /** + * Gets the client key store to be used for client auth, if applicable. + * + * @return the client key store to be used for client auth, or {@link Optional#empty()} + */ + Optional<KeyStore> getClientKeyStore(); + + /** + * Gets a client key store file to be used if {@link INetworkSecurityConfig#getClientKeyStore()} returns empty. + * + * @return the key store file + */ + File getClientKeyStoreFile(); + + /** + * Gets a password to be used to unlock or check integrity of the client key store. * - * @return the password to the key store file + * @return the client key store password, or {@link Optional#empty()} */ - String getKeyStorePassword(); + Optional<char[]> getClientKeyStorePassword(); /** * Gets the trust store to be used for validating certificates of secured connections diff --git a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/network/INetworkSecurityManager.java b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/network/INetworkSecurityManager.java index eb52436d4e..8462f915d1 100644 --- a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/network/INetworkSecurityManager.java +++ b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/network/INetworkSecurityManager.java @@ -28,14 +28,14 @@ public interface INetworkSecurityManager { * * @return a new ssl context */ - SSLContext newSSLContext(); + SSLContext newSSLContext(boolean clientMode); /** * Creates a new ssl engine based on the current configuration of this {@link INetworkSecurityManager} * * @return a new ssl engine */ - SSLEngine newSSLEngine(); + SSLEngine newSSLEngine(boolean clientMode); /** * Sets the configuration to be used for this {@link INetworkSecurityManager} diff --git a/hyracks-fullstack/hyracks/hyracks-ipc/pom.xml b/hyracks-fullstack/hyracks/hyracks-ipc/pom.xml index 939f48709e..8157554ed1 100644 --- a/hyracks-fullstack/hyracks/hyracks-ipc/pom.xml +++ b/hyracks-fullstack/hyracks/hyracks-ipc/pom.xml @@ -67,5 +67,9 @@ <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> </dependency> + <dependency> + <groupId>io.netty</groupId> + <artifactId>netty-handler</artifactId> + </dependency> </dependencies> </project> diff --git a/hyracks-fullstack/hyracks/hyracks-ipc/src/main/java/org/apache/hyracks/ipc/security/NetworkSecurityConfig.java b/hyracks-fullstack/hyracks/hyracks-ipc/src/main/java/org/apache/hyracks/ipc/security/NetworkSecurityConfig.java index bfcd623900..a8bd087dd4 100644 --- a/hyracks-fullstack/hyracks/hyracks-ipc/src/main/java/org/apache/hyracks/ipc/security/NetworkSecurityConfig.java +++ b/hyracks-fullstack/hyracks/hyracks-ipc/src/main/java/org/apache/hyracks/ipc/security/NetworkSecurityConfig.java @@ -31,6 +31,8 @@ import java.util.Optional; import org.apache.hyracks.api.network.INetworkSecurityConfig; +import io.netty.handler.ssl.ClientAuth; + public class NetworkSecurityConfig implements INetworkSecurityConfig { private static final long serialVersionUID = 2L; @@ -67,19 +69,39 @@ public class NetworkSecurityConfig implements INetworkSecurityConfig { return sslEnabled; } + @Override + public ClientAuth getClientAuth() { + return ClientAuth.NONE; + } + @Override public File getKeyStoreFile() { return keyStoreFile; } @Override - public String getKeyStorePassword() { - return keyStorePassword; + public Optional<char[]> getKeyStorePassword() { + return keyStorePassword != null ? Optional.of(keyStorePassword.toCharArray()) : Optional.empty(); } @Override - public KeyStore getKeyStore() { - return keyStore; + public Optional<KeyStore> getKeyStore() { + return Optional.ofNullable(keyStore); + } + + @Override + public Optional<KeyStore> getClientKeyStore() { + return Optional.empty(); + } + + @Override + public File getClientKeyStoreFile() { + return null; + } + + @Override + public Optional<char[]> getClientKeyStorePassword() { + return Optional.empty(); } @Override diff --git a/hyracks-fullstack/hyracks/hyracks-ipc/src/main/java/org/apache/hyracks/ipc/security/NetworkSecurityManager.java b/hyracks-fullstack/hyracks/hyracks-ipc/src/main/java/org/apache/hyracks/ipc/security/NetworkSecurityManager.java index db524ca3d5..d8f5cff225 100644 --- a/hyracks-fullstack/hyracks/hyracks-ipc/src/main/java/org/apache/hyracks/ipc/security/NetworkSecurityManager.java +++ b/hyracks-fullstack/hyracks/hyracks-ipc/src/main/java/org/apache/hyracks/ipc/security/NetworkSecurityManager.java @@ -18,6 +18,7 @@ */ package org.apache.hyracks.ipc.security; +import java.io.File; import java.io.FileInputStream; import java.security.KeyStore; import java.security.SecureRandom; @@ -37,7 +38,7 @@ public class NetworkSecurityManager implements INetworkSecurityManager { private volatile INetworkSecurityConfig config; protected final ISocketChannelFactory sslSocketFactory; - public static final String TSL_VERSION = "TLSv1.2"; + public static final String TLS_VERSION = "TLSv1.2"; public NetworkSecurityManager(INetworkSecurityConfig config) { this.config = config; @@ -45,15 +46,16 @@ public class NetworkSecurityManager implements INetworkSecurityManager { } @Override - public SSLContext newSSLContext() { - return newSSLContext(config); + public SSLContext newSSLContext(boolean clientMode) { + return newSSLContext(config, clientMode); } @Override - public SSLEngine newSSLEngine() { + public SSLEngine newSSLEngine(boolean clientMode) { try { - SSLContext ctx = newSSLContext(); - return ctx.createSSLEngine(); + SSLEngine sslEngine = newSSLContext(clientMode).createSSLEngine(); + sslEngine.setUseClientMode(clientMode); + return sslEngine; } catch (Exception ex) { throw new IllegalStateException("Failed to create SSLEngine", ex); } @@ -76,12 +78,22 @@ public class NetworkSecurityManager implements INetworkSecurityManager { this.config = config; } - public static SSLContext newSSLContext(INetworkSecurityConfig config) { + public static SSLContext newSSLContext(INetworkSecurityConfig config, boolean clientMode) { try { - final char[] password = getKeyStorePassword(config); - KeyStore engineKeyStore = config.getKeyStore(); - if (engineKeyStore == null) { - engineKeyStore = loadKeyStoreFromFile(password, config); + KeyStore engineKeyStore; + final char[] password; + if (clientMode) { + password = config.getClientKeyStorePassword().orElse(null); + engineKeyStore = config.getClientKeyStore().orElse(null); + if (engineKeyStore == null) { + engineKeyStore = loadKeyStoreFromFile(password, config.getClientKeyStoreFile()); + } + } else { + password = config.getKeyStorePassword().orElse(null); + engineKeyStore = config.getKeyStore().orElse(null); + if (engineKeyStore == null) { + engineKeyStore = loadKeyStoreFromFile(password, config.getKeyStoreFile()); + } } final String defaultAlgorithm = KeyManagerFactory.getDefaultAlgorithm(); KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(defaultAlgorithm); @@ -89,10 +101,10 @@ public class NetworkSecurityManager implements INetworkSecurityManager { keyManagerFactory.init(engineKeyStore, password); KeyStore trustStore = config.getTrustStore(); if (trustStore == null) { - trustStore = loadTrustStoreFromFile(password, config); + trustStore = loadKeyStoreFromFile(password, config.getTrustStoreFile()); } trustManagerFactory.init(trustStore); - SSLContext ctx = SSLContext.getInstance(TSL_VERSION); + SSLContext ctx = SSLContext.getInstance(TLS_VERSION); ctx.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom()); return ctx; } catch (Exception ex) { @@ -100,28 +112,14 @@ public class NetworkSecurityManager implements INetworkSecurityManager { } } - private static KeyStore loadKeyStoreFromFile(char[] password, INetworkSecurityConfig config) { + private static KeyStore loadKeyStoreFromFile(char[] password, File keystoreFile) { try { final KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); - ks.load(new FileInputStream(config.getKeyStoreFile()), password); + ks.load(new FileInputStream(keystoreFile), password); return ks; } catch (Exception e) { throw new IllegalStateException("failed to load key store", e); } } - private static KeyStore loadTrustStoreFromFile(char[] password, INetworkSecurityConfig config) { - try { - final KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); - ks.load(new FileInputStream(config.getTrustStoreFile()), password); - return ks; - } catch (Exception e) { - throw new IllegalStateException("failed to load trust store", e); - } - } - - private static char[] getKeyStorePassword(INetworkSecurityConfig config) { - final String pass = config.getKeyStorePassword(); - return pass == null || pass.isEmpty() ? null : pass.toCharArray(); - } } diff --git a/hyracks-fullstack/hyracks/hyracks-ipc/src/main/java/org/apache/hyracks/ipc/sockets/SslSocketChannelFactory.java b/hyracks-fullstack/hyracks/hyracks-ipc/src/main/java/org/apache/hyracks/ipc/sockets/SslSocketChannelFactory.java index 2a2fb62830..0e4b9da5b5 100644 --- a/hyracks-fullstack/hyracks/hyracks-ipc/src/main/java/org/apache/hyracks/ipc/sockets/SslSocketChannelFactory.java +++ b/hyracks-fullstack/hyracks/hyracks-ipc/src/main/java/org/apache/hyracks/ipc/sockets/SslSocketChannelFactory.java @@ -36,15 +36,13 @@ public class SslSocketChannelFactory implements ISocketChannelFactory { @Override public ISocketChannel createServerChannel(SocketChannel socketChannel) { - final SSLEngine sslEngine = networkSecurityManager.newSSLEngine(); - sslEngine.setUseClientMode(false); + final SSLEngine sslEngine = networkSecurityManager.newSSLEngine(false); return new SslSocketChannel(socketChannel, sslEngine); } @Override public ISocketChannel createClientChannel(SocketChannel socketChannel) { - final SSLEngine sslEngine = networkSecurityManager.newSSLEngine(); - sslEngine.setUseClientMode(true); + final SSLEngine sslEngine = networkSecurityManager.newSSLEngine(true); return new SslSocketChannel(socketChannel, sslEngine); } }
