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

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


The following commit(s) were added to refs/heads/master by this push:
     new c72eadf4a7 add insecure mode when Pinot uses TLS connections (#12525)
c72eadf4a7 is described below

commit c72eadf4a704e6836428605635580de6ff0165a8
Author: Haitao Zhang <[email protected]>
AuthorDate: Mon Mar 11 10:44:46 2024 -0700

    add insecure mode when Pinot uses TLS connections (#12525)
    
    * add insecure mode when Pinot uses TLS connections
    
    * add test cases
---
 .../broker/broker/helix/BaseBrokerStarter.java     |   5 +
 .../pinot/common/utils/grpc/GrpcQueryClient.java   |   5 +-
 .../common/utils/tls/JvmDefaultSslContext.java     |   2 +-
 .../pinot/common/utils/tls/PinotInsecureMode.java  |  38 ++++++
 .../pinot/common/utils/tls/RenewableTlsUtils.java  |  41 ++++--
 .../apache/pinot/common/utils/tls/TlsUtils.java    |  11 +-
 .../pinot/common/utils/tls/TlsUtilsTest.java       | 140 ++++++++++++++++-----
 .../pinot/controller/BaseControllerStarter.java    |   5 +
 .../pinot/core/transport/grpc/GrpcQueryServer.java |   5 +-
 .../apache/pinot/core/util/ListenerConfigUtil.java |   5 +-
 .../org/apache/pinot/minion/BaseMinionStarter.java |   5 +
 .../server/starter/helix/BaseServerStarter.java    |   5 +
 .../apache/pinot/spi/utils/CommonConstants.java    |   3 +
 13 files changed, 223 insertions(+), 47 deletions(-)

diff --git 
a/pinot-broker/src/main/java/org/apache/pinot/broker/broker/helix/BaseBrokerStarter.java
 
b/pinot-broker/src/main/java/org/apache/pinot/broker/broker/helix/BaseBrokerStarter.java
index 5b0a254f80..3bf78a56d6 100644
--- 
a/pinot-broker/src/main/java/org/apache/pinot/broker/broker/helix/BaseBrokerStarter.java
+++ 
b/pinot-broker/src/main/java/org/apache/pinot/broker/broker/helix/BaseBrokerStarter.java
@@ -62,6 +62,7 @@ import org.apache.pinot.common.utils.ServiceStartableUtils;
 import org.apache.pinot.common.utils.ServiceStatus;
 import org.apache.pinot.common.utils.config.TagNameUtils;
 import org.apache.pinot.common.utils.helix.HelixHelper;
+import org.apache.pinot.common.utils.tls.PinotInsecureMode;
 import org.apache.pinot.common.utils.tls.TlsUtils;
 import org.apache.pinot.common.version.PinotVersion;
 import org.apache.pinot.core.query.executor.sql.SqlQueryExecutor;
@@ -138,6 +139,10 @@ public abstract class BaseBrokerStarter implements 
ServiceStartable {
     _clusterName = brokerConf.getProperty(Helix.CONFIG_OF_CLUSTER_NAME);
     ServiceStartableUtils.applyClusterConfig(_brokerConf, _zkServers, 
_clusterName, ServiceRole.BROKER);
 
+    PinotInsecureMode.setPinotInInsecureMode(
+        
Boolean.valueOf(_brokerConf.getProperty(CommonConstants.CONFIG_OF_PINOT_INSECURE_MODE,
+            CommonConstants.DEFAULT_PINOT_INSECURE_MODE)));
+
     if (_brokerConf.getProperty(MultiStageQueryRunner.KEY_OF_QUERY_RUNNER_PORT,
         MultiStageQueryRunner.DEFAULT_QUERY_RUNNER_PORT) == 0) {
       _brokerConf.setProperty(MultiStageQueryRunner.KEY_OF_QUERY_RUNNER_PORT, 
NetUtils.findOpenPort());
diff --git 
a/pinot-common/src/main/java/org/apache/pinot/common/utils/grpc/GrpcQueryClient.java
 
b/pinot-common/src/main/java/org/apache/pinot/common/utils/grpc/GrpcQueryClient.java
index 3ba78d98d6..ac05ec70d3 100644
--- 
a/pinot-common/src/main/java/org/apache/pinot/common/utils/grpc/GrpcQueryClient.java
+++ 
b/pinot-common/src/main/java/org/apache/pinot/common/utils/grpc/GrpcQueryClient.java
@@ -36,6 +36,7 @@ import org.apache.pinot.common.config.GrpcConfig;
 import org.apache.pinot.common.config.TlsConfig;
 import org.apache.pinot.common.proto.PinotQueryServerGrpc;
 import org.apache.pinot.common.proto.Server;
+import org.apache.pinot.common.utils.tls.PinotInsecureMode;
 import org.apache.pinot.common.utils.tls.RenewableTlsUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -73,7 +74,9 @@ public class GrpcQueryClient {
     LOGGER.info("Building gRPC SSL context");
     SslContext sslContext = 
CLIENT_SSL_CONTEXTS_CACHE.computeIfAbsent(tlsConfig.hashCode(), 
tlsConfigHashCode -> {
       try {
-        SSLFactory sslFactory = 
RenewableTlsUtils.createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(tlsConfig);
+        SSLFactory sslFactory =
+            
RenewableTlsUtils.createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(
+                tlsConfig, PinotInsecureMode::isPinotInInsecureMode);
         SslContextBuilder sslContextBuilder = SslContextBuilder.forClient();
         
sslFactory.getKeyManagerFactory().ifPresent(sslContextBuilder::keyManager);
         
sslFactory.getTrustManagerFactory().ifPresent(sslContextBuilder::trustManager);
diff --git 
a/pinot-common/src/main/java/org/apache/pinot/common/utils/tls/JvmDefaultSslContext.java
 
b/pinot-common/src/main/java/org/apache/pinot/common/utils/tls/JvmDefaultSslContext.java
index ecd424ef45..ef678e4391 100644
--- 
a/pinot-common/src/main/java/org/apache/pinot/common/utils/tls/JvmDefaultSslContext.java
+++ 
b/pinot-common/src/main/java/org/apache/pinot/common/utils/tls/JvmDefaultSslContext.java
@@ -100,7 +100,7 @@ public class JvmDefaultSslContext {
           Optional.ofNullable(System.getProperty(JVM_TRUST_STORE_PASSWORD))
               .map(String::trim).filter(StringUtils::isNotBlank).orElse(null);
       
RenewableTlsUtils.enableAutoRenewalFromFileStoreForSSLFactory(jvmSslFactory, 
jvmKeystoreType, jvmKeyStorePath,
-          jvmKeystorePassword, jvmTrustStoreType, jvmTrustStorePath, 
jvmTrustStorePassword, null, null, false);
+          jvmKeystorePassword, jvmTrustStoreType, jvmTrustStorePath, 
jvmTrustStorePassword, null, null, () -> false);
     }
     _initialized = true;
     LOGGER.info("Successfully initialized mvm default SSL context");
diff --git 
a/pinot-common/src/main/java/org/apache/pinot/common/utils/tls/PinotInsecureMode.java
 
b/pinot-common/src/main/java/org/apache/pinot/common/utils/tls/PinotInsecureMode.java
new file mode 100644
index 0000000000..23e57d3b6b
--- /dev/null
+++ 
b/pinot-common/src/main/java/org/apache/pinot/common/utils/tls/PinotInsecureMode.java
@@ -0,0 +1,38 @@
+/**
+ * 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.pinot.common.utils.tls;
+
+/**
+ * This class is used to determine if Pinot is running in insecure mode. This 
is used to determine if Pinot components
+ * should use trust all CA certificates when using TLS.
+ */
+public class PinotInsecureMode {
+  private static volatile boolean _pinotInInsecureMode = false;
+
+  private PinotInsecureMode() {
+  }
+
+  public static synchronized void setPinotInInsecureMode(boolean 
pinotInInsecureMode) {
+    _pinotInInsecureMode = pinotInInsecureMode;
+  }
+
+  public static synchronized boolean isPinotInInsecureMode() {
+    return _pinotInInsecureMode;
+  }
+}
diff --git 
a/pinot-common/src/main/java/org/apache/pinot/common/utils/tls/RenewableTlsUtils.java
 
b/pinot-common/src/main/java/org/apache/pinot/common/utils/tls/RenewableTlsUtils.java
index e8cb6140c8..8c50dfaf59 100644
--- 
a/pinot-common/src/main/java/org/apache/pinot/common/utils/tls/RenewableTlsUtils.java
+++ 
b/pinot-common/src/main/java/org/apache/pinot/common/utils/tls/RenewableTlsUtils.java
@@ -20,6 +20,7 @@ package org.apache.pinot.common.utils.tls;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
+import com.google.common.base.Supplier;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URISyntaxException;
@@ -68,10 +69,26 @@ public class RenewableTlsUtils {
    * @return a {@link SSLFactory} instance with identity material and trust 
material swappable
    */
   public static SSLFactory 
createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(TlsConfig tlsConfig) {
-    SSLFactory sslFactory = createSSLFactory(tlsConfig);
+    return createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(tlsConfig, 
() -> false);
+  }
+
+  /**
+   * Create a {@link SSLFactory} instance with identity material and trust 
material swappable for a given TlsConfig,
+   * and nables auto renewal of the {@link SSLFactory} instance when
+   * 1. the {@link SSLFactory} is created with a key manager and trust manager 
swappable
+   * 2. the key store is null or a local file
+   * 3. the trust store is null or a local file
+   * 4. the key store or trust store file changes.
+   * @param tlsConfig {@link TlsConfig}
+   * @param insecureModeSupplier a supplier to check if using insecure mode
+   * @return a {@link SSLFactory} instance with identity material and trust 
material swappable
+   */
+  public static SSLFactory 
createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(
+      TlsConfig tlsConfig, Supplier<Boolean> insecureModeSupplier) {
+    SSLFactory sslFactory = createSSLFactory(tlsConfig, 
insecureModeSupplier.get());
     if 
(TlsUtils.isKeyOrTrustStorePathNullOrHasFileScheme(tlsConfig.getKeyStorePath())
         && 
TlsUtils.isKeyOrTrustStorePathNullOrHasFileScheme(tlsConfig.getTrustStorePath()))
 {
-      enableAutoRenewalFromFileStoreForSSLFactory(sslFactory, tlsConfig);
+      enableAutoRenewalFromFileStoreForSSLFactory(sslFactory, tlsConfig, 
insecureModeSupplier);
     }
     return sslFactory;
   }
@@ -79,13 +96,14 @@ public class RenewableTlsUtils {
   /**
    * Create a {@link SSLFactory} instance with identity material and trust 
material swappable for a given TlsConfig
    * @param tlsConfig {@link TlsConfig}
+   * @param insecureMode if true, trust all certificates
    * @return a {@link SSLFactory} instance with identity material and trust 
material swappable
    */
-  private static SSLFactory createSSLFactory(TlsConfig tlsConfig) {
+  private static SSLFactory createSSLFactory(TlsConfig tlsConfig, boolean 
insecureMode) {
     return createSSLFactory(
         tlsConfig.getKeyStoreType(), tlsConfig.getKeyStorePath(), 
tlsConfig.getKeyStorePassword(),
         tlsConfig.getTrustStoreType(), tlsConfig.getTrustStorePath(), 
tlsConfig.getTrustStorePassword(),
-        null, null, true, tlsConfig.isInsecure());
+        null, null, true, tlsConfig.isInsecure() || insecureMode);
   }
 
   static SSLFactory createSSLFactory(
@@ -147,18 +165,21 @@ public class RenewableTlsUtils {
    * 4. the key store or trust store file changes.
    * @param sslFactory the {@link SSLFactory} to enable key manager and trust 
manager auto renewal
    * @param tlsConfig the {@link TlsConfig} to get the key store and trust 
store information
+   * @param insecureModeSupplier a supplier to check if using insecure mode
    */
   @VisibleForTesting
-  static void enableAutoRenewalFromFileStoreForSSLFactory(SSLFactory 
sslFactory, TlsConfig tlsConfig) {
+  static void enableAutoRenewalFromFileStoreForSSLFactory(
+      SSLFactory sslFactory, TlsConfig tlsConfig, Supplier<Boolean> 
insecureModeSupplier) {
     enableAutoRenewalFromFileStoreForSSLFactory(sslFactory,
         tlsConfig.getKeyStoreType(), tlsConfig.getKeyStorePath(), 
tlsConfig.getKeyStorePassword(),
         tlsConfig.getTrustStoreType(), tlsConfig.getTrustStorePath(), 
tlsConfig.getTrustStorePassword(),
-        null, null, tlsConfig.isInsecure());
+        null, null, () -> tlsConfig.isInsecure() || 
insecureModeSupplier.get());
   }
 
   static void enableAutoRenewalFromFileStoreForSSLFactory(SSLFactory 
sslFactory, String keyStoreType,
       String keyStorePath, String keyStorePassword, String trustStoreType, 
String trustStorePath,
-      String trustStorePassword, String sslContextProtocol, SecureRandom 
secureRandom, boolean isInsecure) {
+      String trustStorePassword, String sslContextProtocol, SecureRandom 
secureRandom,
+      Supplier<Boolean> insecureModeSupplier) {
     try {
       URL keyStoreURL = keyStorePath == null ? null : 
TlsUtils.makeKeyOrTrustStoreUrl(keyStorePath);
       URL trustStoreURL = trustStorePath == null ? null : 
TlsUtils.makeKeyOrTrustStoreUrl(trustStorePath);
@@ -190,7 +211,7 @@ public class RenewableTlsUtils {
           reloadSslFactoryWhenFileStoreChanges(sslFactory,
               keyStoreType, keyStorePath, keyStorePassword,
               trustStoreType, trustStorePath, trustStorePassword,
-              sslContextProtocol, secureRandom, isInsecure);
+              sslContextProtocol, secureRandom, insecureModeSupplier);
         } catch (Exception e) {
           throw new RuntimeException(e);
         }
@@ -204,7 +225,7 @@ public class RenewableTlsUtils {
   static void reloadSslFactoryWhenFileStoreChanges(SSLFactory baseSslFactory,
       String keyStoreType, String keyStorePath, String keyStorePassword,
       String trustStoreType, String trustStorePath, String trustStorePassword,
-      String sslContextProtocol, SecureRandom secureRandom, boolean isInsecure)
+      String sslContextProtocol, SecureRandom secureRandom, Supplier<Boolean> 
insecureModeSupplier)
       throws IOException, URISyntaxException, InterruptedException {
     LOGGER.info("Enable auto renewal of SSLFactory {} when key store {} or 
trust store {} changes",
         baseSslFactory, keyStorePath, trustStorePath);
@@ -230,7 +251,7 @@ public class RenewableTlsUtils {
                   try {
                     SSLFactory updatedSslFactory =
                         createSSLFactory(keyStoreType, keyStorePath, 
keyStorePassword, trustStoreType, trustStorePath,
-                            trustStorePassword, sslContextProtocol, 
secureRandom, false, isInsecure);
+                            trustStorePassword, sslContextProtocol, 
secureRandom, false, insecureModeSupplier.get());
                     SSLFactoryUtils.reload(baseSslFactory, updatedSslFactory);
                     LOGGER.info("Successfully renewed SSLFactory {} (built 
from key store {} and truststore {}) on file"
                         + " {} changes", baseSslFactory, keyStorePath, 
trustStorePath, changedFile);
diff --git 
a/pinot-common/src/main/java/org/apache/pinot/common/utils/tls/TlsUtils.java 
b/pinot-common/src/main/java/org/apache/pinot/common/utils/tls/TlsUtils.java
index 8ccf5c0e51..f9c462bd93 100644
--- a/pinot-common/src/main/java/org/apache/pinot/common/utils/tls/TlsUtils.java
+++ b/pinot-common/src/main/java/org/apache/pinot/common/utils/tls/TlsUtils.java
@@ -233,7 +233,8 @@ public final class TlsUtils {
       if (isKeyOrTrustStorePathNullOrHasFileScheme(keyStorePath)
           && isKeyOrTrustStorePathNullOrHasFileScheme(trustStorePath)) {
         
RenewableTlsUtils.enableAutoRenewalFromFileStoreForSSLFactory(sslFactory, 
keyStoreType, keyStorePath,
-            keyStorePassword, trustStoreType, trustStorePath, 
trustStorePassword, "SSL", secureRandom, false);
+            keyStorePassword, trustStoreType, trustStorePath, 
trustStorePassword, "SSL", secureRandom,
+            PinotInsecureMode::isPinotInInsecureMode);
       }
       // HttpsURLConnection
       
HttpsURLConnection.setDefaultSSLSocketFactory(sslFactory.getSslSocketFactory());
@@ -300,7 +301,9 @@ public final class TlsUtils {
    * @param tlsConfig TLS config
    */
   public static SslContext buildClientContext(TlsConfig tlsConfig) {
-    SSLFactory sslFactory = 
RenewableTlsUtils.createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(tlsConfig);
+    SSLFactory sslFactory =
+        
RenewableTlsUtils.createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(
+            tlsConfig, PinotInsecureMode::isPinotInInsecureMode);
     SslContextBuilder sslContextBuilder =
         
SslContextBuilder.forClient().sslProvider(SslProvider.valueOf(tlsConfig.getSslProvider()));
     sslFactory.getKeyManagerFactory().ifPresent(sslContextBuilder::keyManager);
@@ -321,7 +324,9 @@ public final class TlsUtils {
     if (tlsConfig.getKeyStorePath() == null) {
       throw new IllegalArgumentException("Must provide key store path for 
secured server");
     }
-    SSLFactory sslFactory = 
RenewableTlsUtils.createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(tlsConfig);
+    SSLFactory sslFactory =
+        
RenewableTlsUtils.createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(
+            tlsConfig, PinotInsecureMode::isPinotInInsecureMode);
     SslContextBuilder sslContextBuilder = 
SslContextBuilder.forServer(sslFactory.getKeyManagerFactory().get())
         .sslProvider(SslProvider.valueOf(tlsConfig.getSslProvider()));
     
sslFactory.getTrustManagerFactory().ifPresent(sslContextBuilder::trustManager);
diff --git 
a/pinot-common/src/test/java/org/apache/pinot/common/utils/tls/TlsUtilsTest.java
 
b/pinot-common/src/test/java/org/apache/pinot/common/utils/tls/TlsUtilsTest.java
index 2ae9a12839..ab118b9abd 100644
--- 
a/pinot-common/src/test/java/org/apache/pinot/common/utils/tls/TlsUtilsTest.java
+++ 
b/pinot-common/src/test/java/org/apache/pinot/common/utils/tls/TlsUtilsTest.java
@@ -51,15 +51,15 @@ import javax.net.ssl.X509ExtendedTrustManager;
 import javax.net.ssl.X509KeyManager;
 import javax.net.ssl.X509TrustManager;
 import nl.altindag.ssl.SSLFactory;
+import nl.altindag.ssl.trustmanager.HotSwappableX509ExtendedTrustManager;
+import nl.altindag.ssl.trustmanager.UnsafeX509ExtendedTrustManager;
 import org.apache.commons.io.FileUtils;
 import org.apache.pinot.common.config.TlsConfig;
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeClass;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotEquals;
-import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.*;
 
 
 /**
@@ -86,7 +86,7 @@ public class TlsUtilsTest {
   private static final String TLS_KEYSTORE_FILE_PATH = DEFAULT_TEST_TLS_DIR + 
"/" + TLS_KEYSTORE_FILE;
   private static final String TLS_TRUSTSTORE_FILE_PATH = DEFAULT_TEST_TLS_DIR 
+ "/" + TLS_TRUSTSTORE_FILE;
 
-  @BeforeClass
+  @BeforeMethod
   public void setUp()
       throws IOException, URISyntaxException {
     copyResourceFilesToTempFolder(
@@ -114,7 +114,7 @@ public class TlsUtilsTest {
     }
   }
 
-  @AfterClass
+  @AfterMethod
   public void tearDown() {
     FileUtils.deleteQuietly(new File(DEFAULT_TEST_TLS_DIR));
   }
@@ -188,29 +188,12 @@ public class TlsUtilsTest {
         () -> {
           try {
             RenewableTlsUtils.reloadSslFactoryWhenFileStoreChanges(sslFactory, 
KEYSTORE_TYPE, TLS_KEYSTORE_FILE_PATH,
-                PASSWORD, TRUSTSTORE_TYPE, TLS_TRUSTSTORE_FILE_PATH, PASSWORD, 
"TLS", secureRandom, false);
+                PASSWORD, TRUSTSTORE_TYPE, TLS_TRUSTSTORE_FILE_PATH, PASSWORD, 
"TLS", secureRandom, () -> false);
           } catch (Exception e) {
             throw new RuntimeException(e);
           }
         });
-
-    WatchService watchService = FileSystems.getDefault().newWatchService();
-    Map<WatchKey, Set<Path>> watchKeyPathMap = new HashMap<>();
-    RenewableTlsUtils.registerFile(watchService, watchKeyPathMap, 
TLS_KEYSTORE_FILE_PATH);
-    RenewableTlsUtils.registerFile(watchService, watchKeyPathMap, 
TLS_TRUSTSTORE_FILE_PATH);
-
-    // wait for the new thread to start
-    Thread.sleep(100);
-
-    // update tls files
-    copyResourceFilesToTempFolder(
-        ImmutableMap.of(TLS_KEYSTORE_UPDATED_FILE, TLS_KEYSTORE_FILE, 
TLS_TRUSTSTORE_UPDATED_FILE,
-            TLS_TRUSTSTORE_FILE));
-
-    // wait for the file change event to be detected
-    watchService.take();
-    // it will take some time for the thread to be notified and reload the ssl 
factory
-    Thread.sleep(500);
+    updateTlsFilesAndWaitForSslFactoryToBeRenewed();
     executorService.shutdown();
 
     // after tls file update, the returned values should be the same, since 
the wrapper is the same
@@ -241,7 +224,8 @@ public class TlsUtilsTest {
     tlsConfig.setTrustStorePassword(PASSWORD);
     RuntimeException e = null;
     try {
-      
RenewableTlsUtils.enableAutoRenewalFromFileStoreForSSLFactory(swappableSslFactory,
 tlsConfig);
+      RenewableTlsUtils.enableAutoRenewalFromFileStoreForSSLFactory(
+          swappableSslFactory, tlsConfig, () -> false);
     } catch (RuntimeException ex) {
       e = ex;
     }
@@ -253,7 +237,8 @@ public class TlsUtilsTest {
     tlsConfig.setTrustStorePath("ftp://"; + TLS_TRUSTSTORE_FILE_PATH);
     e = null;
     try {
-      
RenewableTlsUtils.enableAutoRenewalFromFileStoreForSSLFactory(swappableSslFactory,
 tlsConfig);
+      RenewableTlsUtils.enableAutoRenewalFromFileStoreForSSLFactory(
+          swappableSslFactory, tlsConfig, () -> false);
     } catch (RuntimeException ex) {
       e = ex;
     }
@@ -266,7 +251,8 @@ public class TlsUtilsTest {
     e = null;
     tlsConfig.setTrustStorePath(TLS_TRUSTSTORE_FILE_PATH);
     try {
-      
RenewableTlsUtils.enableAutoRenewalFromFileStoreForSSLFactory(nonSwappableSslFactory,
 tlsConfig);
+      RenewableTlsUtils.enableAutoRenewalFromFileStoreForSSLFactory(
+          nonSwappableSslFactory, tlsConfig, () -> false);
     } catch (RuntimeException ex) {
       e = ex;
     }
@@ -276,11 +262,105 @@ public class TlsUtilsTest {
     tlsConfig.setKeyStorePath(null);
     e = null;
     try {
-      
RenewableTlsUtils.enableAutoRenewalFromFileStoreForSSLFactory(nonSwappableSslFactory,
 tlsConfig);
+      RenewableTlsUtils.enableAutoRenewalFromFileStoreForSSLFactory(
+          nonSwappableSslFactory, tlsConfig, () -> false);
     } catch (RuntimeException ex) {
       e = ex;
     }
     assertEquals(e.getMessage(),
         "java.lang.IllegalArgumentException: trust manager of the existing 
SSLFactory must be swappable");
   }
+
+  @Test
+  public void createSslFactoryInInsecureMode() {
+    SecureRandom secureRandom = new SecureRandom();
+    SSLFactory sslFactory = RenewableTlsUtils.createSSLFactory(KEYSTORE_TYPE, 
TLS_KEYSTORE_FILE_PATH, PASSWORD,
+        TRUSTSTORE_TYPE, TLS_TRUSTSTORE_FILE_PATH, PASSWORD, "TLS", 
secureRandom, false, true);
+
+    X509ExtendedTrustManager x509ExtendedTrustManager = 
sslFactory.getTrustManager().get();
+    assertTrue(x509ExtendedTrustManager instanceof 
UnsafeX509ExtendedTrustManager);
+    assertEquals(x509ExtendedTrustManager.getAcceptedIssuers().length, 0);
+
+    sslFactory = RenewableTlsUtils.createSSLFactory(KEYSTORE_TYPE, 
TLS_KEYSTORE_FILE_PATH, PASSWORD,
+        TRUSTSTORE_TYPE, TLS_TRUSTSTORE_FILE_PATH, PASSWORD, "TLS", 
secureRandom, true, true);
+    ensurSslFactoryUseUnsafeTrustManager(sslFactory);
+  }
+
+  @Test
+  public void 
createSSLFactoryAndEnableAutoRenewalWhenUsingFileStoresWithPinotSecureMode()
+      throws IOException, URISyntaxException, InterruptedException {
+    TlsConfig tlsConfig = createTlsConfig();
+    SSLFactory sslFactory =
+        
RenewableTlsUtils.createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(tlsConfig,
 () -> false);
+    ensurSslFactoryUseNormalTrustManager(sslFactory);
+
+    updateTlsFilesAndWaitForSslFactoryToBeRenewed();
+
+    ensurSslFactoryUseNormalTrustManager(sslFactory);
+  }
+
+  @Test
+  public void 
createSSLFactoryAndEnableAutoRenewalWhenUsingFileStoresWithPinotInsecureMode()
+      throws IOException, URISyntaxException, InterruptedException {
+    TlsConfig tlsConfig = createTlsConfig();
+    SSLFactory sslFactory =
+        
RenewableTlsUtils.createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(tlsConfig,
 () -> true);
+    ensurSslFactoryUseUnsafeTrustManager(sslFactory);
+
+    updateTlsFilesAndWaitForSslFactoryToBeRenewed();
+
+    // after tls file update, the ssl factory should still use 
UnsafeX509ExtendedTrustManager
+    ensurSslFactoryUseUnsafeTrustManager(sslFactory);
+  }
+
+  private void ensurSslFactoryUseNormalTrustManager(SSLFactory sslFactory) {
+    X509ExtendedTrustManager x509ExtendedTrustManager = 
sslFactory.getTrustManager().get();
+    assertTrue(x509ExtendedTrustManager instanceof 
HotSwappableX509ExtendedTrustManager);
+    HotSwappableX509ExtendedTrustManager hotSwappableX509ExtendedTrustManager
+        = (HotSwappableX509ExtendedTrustManager) x509ExtendedTrustManager;
+    assertFalse(hotSwappableX509ExtendedTrustManager.getInnerTrustManager() 
instanceof UnsafeX509ExtendedTrustManager);
+    assertEquals(x509ExtendedTrustManager.getAcceptedIssuers().length, 1);
+  }
+
+  private void ensurSslFactoryUseUnsafeTrustManager(SSLFactory sslFactory) {
+    X509ExtendedTrustManager x509ExtendedTrustManager = 
sslFactory.getTrustManager().get();
+    assertTrue(x509ExtendedTrustManager instanceof 
HotSwappableX509ExtendedTrustManager);
+    HotSwappableX509ExtendedTrustManager hotSwappableX509ExtendedTrustManager
+        = (HotSwappableX509ExtendedTrustManager) x509ExtendedTrustManager;
+    assertTrue(hotSwappableX509ExtendedTrustManager.getInnerTrustManager() 
instanceof UnsafeX509ExtendedTrustManager);
+    assertEquals(x509ExtendedTrustManager.getAcceptedIssuers().length, 0);
+  }
+
+  private TlsConfig createTlsConfig() {
+    TlsConfig tlsConfig = new TlsConfig();
+    tlsConfig.setKeyStoreType(KEYSTORE_TYPE);
+    tlsConfig.setKeyStorePath(TLS_KEYSTORE_FILE_PATH);
+    tlsConfig.setKeyStorePassword(PASSWORD);
+    tlsConfig.setTrustStoreType(TRUSTSTORE_TYPE);
+    tlsConfig.setTrustStorePath(TLS_TRUSTSTORE_FILE_PATH);
+    tlsConfig.setTrustStorePassword(PASSWORD);
+    tlsConfig.setInsecure(false);
+    return tlsConfig;
+  }
+
+  private void updateTlsFilesAndWaitForSslFactoryToBeRenewed()
+      throws IOException, URISyntaxException, InterruptedException {
+    WatchService watchService = FileSystems.getDefault().newWatchService();
+    Map<WatchKey, Set<Path>> watchKeyPathMap = new HashMap<>();
+    RenewableTlsUtils.registerFile(watchService, watchKeyPathMap, 
TLS_KEYSTORE_FILE_PATH);
+    RenewableTlsUtils.registerFile(watchService, watchKeyPathMap, 
TLS_TRUSTSTORE_FILE_PATH);
+
+    // wait for the new thread to start
+    Thread.sleep(100);
+
+    // update tls files
+    copyResourceFilesToTempFolder(
+        ImmutableMap.of(TLS_KEYSTORE_UPDATED_FILE, TLS_KEYSTORE_FILE, 
TLS_TRUSTSTORE_UPDATED_FILE,
+            TLS_TRUSTSTORE_FILE));
+
+    // wait for the file change event to be detected
+    watchService.take();
+    // it will take some time for the thread to be notified and reload the ssl 
factory
+    Thread.sleep(500);
+  }
 }
diff --git 
a/pinot-controller/src/main/java/org/apache/pinot/controller/BaseControllerStarter.java
 
b/pinot-controller/src/main/java/org/apache/pinot/controller/BaseControllerStarter.java
index 9d535ab02a..0f071d0895 100644
--- 
a/pinot-controller/src/main/java/org/apache/pinot/controller/BaseControllerStarter.java
+++ 
b/pinot-controller/src/main/java/org/apache/pinot/controller/BaseControllerStarter.java
@@ -78,6 +78,7 @@ import 
org.apache.pinot.common.utils.helix.LeadControllerUtils;
 import org.apache.pinot.common.utils.log.DummyLogFileServer;
 import org.apache.pinot.common.utils.log.LocalLogFileServer;
 import org.apache.pinot.common.utils.log.LogFileServer;
+import org.apache.pinot.common.utils.tls.PinotInsecureMode;
 import org.apache.pinot.common.utils.tls.TlsUtils;
 import org.apache.pinot.common.version.PinotVersion;
 import org.apache.pinot.controller.api.ControllerAdminApiApplication;
@@ -200,6 +201,10 @@ public abstract class BaseControllerStarter implements 
ServiceStartable {
     _helixClusterName = _config.getHelixClusterName();
     ServiceStartableUtils.applyClusterConfig(_config, _helixZkURL, 
_helixClusterName, ServiceRole.CONTROLLER);
 
+    PinotInsecureMode.setPinotInInsecureMode(
+        
Boolean.valueOf(_config.getProperty(CommonConstants.CONFIG_OF_PINOT_INSECURE_MODE,
+            CommonConstants.DEFAULT_PINOT_INSECURE_MODE)));
+
     setupHelixSystemProperties();
     
HelixHelper.setMinNumCharsInISToTurnOnCompression(_config.getMinNumCharsInISToTurnOnCompression());
     _listenerConfigs = ListenerConfigUtil.buildControllerConfigs(_config);
diff --git 
a/pinot-core/src/main/java/org/apache/pinot/core/transport/grpc/GrpcQueryServer.java
 
b/pinot-core/src/main/java/org/apache/pinot/core/transport/grpc/GrpcQueryServer.java
index 24f952f8c9..bd75b098ac 100644
--- 
a/pinot-core/src/main/java/org/apache/pinot/core/transport/grpc/GrpcQueryServer.java
+++ 
b/pinot-core/src/main/java/org/apache/pinot/core/transport/grpc/GrpcQueryServer.java
@@ -42,6 +42,7 @@ import org.apache.pinot.common.metrics.ServerMetrics;
 import org.apache.pinot.common.proto.PinotQueryServerGrpc;
 import org.apache.pinot.common.proto.Server.ServerRequest;
 import org.apache.pinot.common.proto.Server.ServerResponse;
+import org.apache.pinot.common.utils.tls.PinotInsecureMode;
 import org.apache.pinot.common.utils.tls.RenewableTlsUtils;
 import org.apache.pinot.core.operator.blocks.InstanceResponseBlock;
 import org.apache.pinot.core.operator.streaming.StreamingResponseUtils;
@@ -98,7 +99,9 @@ public class GrpcQueryServer extends 
PinotQueryServerGrpc.PinotQueryServerImplBa
     }
     SslContext sslContext = 
SERVER_SSL_CONTEXTS_CACHE.computeIfAbsent(tlsConfig.hashCode(), 
tlsConfigHashCode -> {
       try {
-        SSLFactory sslFactory = 
RenewableTlsUtils.createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(tlsConfig);
+        SSLFactory sslFactory =
+            
RenewableTlsUtils.createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(
+                tlsConfig, PinotInsecureMode::isPinotInInsecureMode);
         SslContextBuilder sslContextBuilder = 
SslContextBuilder.forServer(sslFactory.getKeyManagerFactory().get())
             .sslProvider(SslProvider.valueOf(tlsConfig.getSslProvider()));
         
sslFactory.getTrustManagerFactory().ifPresent(sslContextBuilder::trustManager);
diff --git 
a/pinot-core/src/main/java/org/apache/pinot/core/util/ListenerConfigUtil.java 
b/pinot-core/src/main/java/org/apache/pinot/core/util/ListenerConfigUtil.java
index e617b0d8a6..9a5969c238 100644
--- 
a/pinot-core/src/main/java/org/apache/pinot/core/util/ListenerConfigUtil.java
+++ 
b/pinot-core/src/main/java/org/apache/pinot/core/util/ListenerConfigUtil.java
@@ -38,6 +38,7 @@ import nl.altindag.ssl.SSLFactory;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.pinot.common.config.TlsConfig;
+import org.apache.pinot.common.utils.tls.PinotInsecureMode;
 import org.apache.pinot.common.utils.tls.RenewableTlsUtils;
 import org.apache.pinot.common.utils.tls.TlsUtils;
 import org.apache.pinot.core.transport.HttpServerThreadPoolConfig;
@@ -264,7 +265,9 @@ public final class ListenerConfigUtil {
   }
 
   private static SSLEngineConfigurator buildSSLEngineConfigurator(TlsConfig 
tlsConfig) {
-    SSLFactory sslFactory = 
RenewableTlsUtils.createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(tlsConfig);
+    SSLFactory sslFactory =
+        
RenewableTlsUtils.createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(
+            tlsConfig, PinotInsecureMode::isPinotInInsecureMode);
     return new 
SSLEngineConfigurator(sslFactory.getSslContext()).setClientMode(false)
         
.setNeedClientAuth(tlsConfig.isClientAuthEnabled()).setEnabledProtocols(new 
String[]{"TLSv1.2"});
   }
diff --git 
a/pinot-minion/src/main/java/org/apache/pinot/minion/BaseMinionStarter.java 
b/pinot-minion/src/main/java/org/apache/pinot/minion/BaseMinionStarter.java
index b82730288b..cc4e17219c 100644
--- a/pinot-minion/src/main/java/org/apache/pinot/minion/BaseMinionStarter.java
+++ b/pinot-minion/src/main/java/org/apache/pinot/minion/BaseMinionStarter.java
@@ -47,6 +47,7 @@ import org.apache.pinot.common.utils.ServiceStartableUtils;
 import org.apache.pinot.common.utils.ServiceStatus;
 import org.apache.pinot.common.utils.fetcher.SegmentFetcherFactory;
 import org.apache.pinot.common.utils.helix.HelixHelper;
+import org.apache.pinot.common.utils.tls.PinotInsecureMode;
 import org.apache.pinot.common.utils.tls.TlsUtils;
 import org.apache.pinot.common.version.PinotVersion;
 import org.apache.pinot.core.transport.ListenerConfig;
@@ -99,6 +100,10 @@ public abstract class BaseMinionStarter implements 
ServiceStartable {
     String helixClusterName = _config.getHelixClusterName();
     ServiceStartableUtils.applyClusterConfig(_config, zkAddress, 
helixClusterName, ServiceRole.MINION);
 
+    PinotInsecureMode.setPinotInInsecureMode(
+        
Boolean.valueOf(_config.getProperty(CommonConstants.CONFIG_OF_PINOT_INSECURE_MODE,
+            CommonConstants.DEFAULT_PINOT_INSECURE_MODE)));
+
     setupHelixSystemProperties();
     _hostname = _config.getHostName();
     _port = _config.getPort();
diff --git 
a/pinot-server/src/main/java/org/apache/pinot/server/starter/helix/BaseServerStarter.java
 
b/pinot-server/src/main/java/org/apache/pinot/server/starter/helix/BaseServerStarter.java
index c30e4286aa..f16b326591 100644
--- 
a/pinot-server/src/main/java/org/apache/pinot/server/starter/helix/BaseServerStarter.java
+++ 
b/pinot-server/src/main/java/org/apache/pinot/server/starter/helix/BaseServerStarter.java
@@ -61,6 +61,7 @@ import org.apache.pinot.common.utils.ServiceStatus.Status;
 import org.apache.pinot.common.utils.config.TagNameUtils;
 import org.apache.pinot.common.utils.fetcher.SegmentFetcherFactory;
 import org.apache.pinot.common.utils.helix.HelixHelper;
+import org.apache.pinot.common.utils.tls.PinotInsecureMode;
 import org.apache.pinot.common.utils.tls.TlsUtils;
 import org.apache.pinot.common.version.PinotVersion;
 import org.apache.pinot.core.common.datatable.DataTableBuilderFactory;
@@ -152,6 +153,10 @@ public abstract class BaseServerStarter implements 
ServiceStartable {
     _helixClusterName = 
_serverConf.getProperty(CommonConstants.Helix.CONFIG_OF_CLUSTER_NAME);
     ServiceStartableUtils.applyClusterConfig(_serverConf, _zkAddress, 
_helixClusterName, ServiceRole.SERVER);
 
+    PinotInsecureMode.setPinotInInsecureMode(
+        
Boolean.valueOf(_serverConf.getProperty(CommonConstants.CONFIG_OF_PINOT_INSECURE_MODE,
+            CommonConstants.DEFAULT_PINOT_INSECURE_MODE)));
+
     setupHelixSystemProperties();
     _listenerConfigs = ListenerConfigUtil.buildServerAdminConfigs(_serverConf);
     _hostname = _serverConf.getProperty(Helix.KEY_OF_SERVER_NETTY_HOST,
diff --git 
a/pinot-spi/src/main/java/org/apache/pinot/spi/utils/CommonConstants.java 
b/pinot-spi/src/main/java/org/apache/pinot/spi/utils/CommonConstants.java
index ba8d5213b5..f0565c402b 100644
--- a/pinot-spi/src/main/java/org/apache/pinot/spi/utils/CommonConstants.java
+++ b/pinot-spi/src/main/java/org/apache/pinot/spi/utils/CommonConstants.java
@@ -54,6 +54,9 @@ public class CommonConstants {
   public static final String CONFIG_OF_SWAGGER_RESOURCES_PATH = 
"META-INF/resources/webjars/swagger-ui/5.1.0/";
   public static final String CONFIG_OF_TIMEZONE = "pinot.timezone";
 
+  public static final String CONFIG_OF_PINOT_INSECURE_MODE = 
"pinot.insecure.mode";
+  public static final String DEFAULT_PINOT_INSECURE_MODE = "false";
+
   /**
    * The state of the consumer for a given segment
    */


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to