You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kafka.apache.org by ma...@apache.org on 2023/02/14 06:26:18 UTC

[kafka] branch trunk updated: MINOR: Few cleanups to JaasContext/Utils classes

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

manikumar pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/kafka.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 1ed61e40903 MINOR: Few cleanups to JaasContext/Utils classes
1ed61e40903 is described below

commit 1ed61e4090353bc9e4802ee09366f512dc60884f
Author: Manikumar Reddy <ma...@gmail.com>
AuthorDate: Fri Jan 13 23:18:02 2023 +0530

    MINOR: Few cleanups to JaasContext/Utils classes
    
    Reviewers: Rajini Sivaram <ra...@googlemail.com>
---
 .../apache/kafka/common/security/JaasContext.java  | 22 ++++++++++
 .../apache/kafka/common/security/JaasUtils.java    |  3 +-
 .../kafka/common/security/JaasContextTest.java     | 48 ++++++++++++++++++++++
 3 files changed, 72 insertions(+), 1 deletion(-)

diff --git a/clients/src/main/java/org/apache/kafka/common/security/JaasContext.java b/clients/src/main/java/org/apache/kafka/common/security/JaasContext.java
index 48216a8a90c..34f2952bff6 100644
--- a/clients/src/main/java/org/apache/kafka/common/security/JaasContext.java
+++ b/clients/src/main/java/org/apache/kafka/common/security/JaasContext.java
@@ -30,6 +30,11 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.apache.kafka.common.security.JaasUtils.DISALLOWED_LOGIN_MODULES_CONFIG;
+import static org.apache.kafka.common.security.JaasUtils.DISALLOWED_LOGIN_MODULES_DEFAULT;
 
 public class JaasContext {
 
@@ -91,11 +96,25 @@ public class JaasContext {
                 throw new IllegalArgumentException("JAAS config property does not contain any login modules");
             else if (contextModules.length != 1)
                 throw new IllegalArgumentException("JAAS config property contains " + contextModules.length + " login modules, should be 1 module");
+
+            throwIfLoginModuleIsNotAllowed(contextModules[0]);
             return new JaasContext(globalContextName, contextType, jaasConfig, dynamicJaasConfig);
         } else
             return defaultContext(contextType, listenerContextName, globalContextName);
     }
 
+    private static void throwIfLoginModuleIsNotAllowed(AppConfigurationEntry appConfigurationEntry) {
+        Set<String> disallowedLoginModuleList = Arrays.stream(
+                System.getProperty(DISALLOWED_LOGIN_MODULES_CONFIG, DISALLOWED_LOGIN_MODULES_DEFAULT).split(","))
+                .map(String::trim)
+                .collect(Collectors.toSet());
+        String loginModuleName = appConfigurationEntry.getLoginModuleName().trim();
+        if (disallowedLoginModuleList.contains(loginModuleName)) {
+            throw new IllegalArgumentException(loginModuleName + " is not allowed. Update System property '"
+                    + DISALLOWED_LOGIN_MODULES_CONFIG + "' to allow " + loginModuleName);
+        }
+    }
+
     private static JaasContext defaultContext(JaasContext.Type contextType, String listenerContextName,
                                               String globalContextName) {
         String jaasConfigFile = System.getProperty(JaasUtils.JAVA_LOGIN_CONFIG_PARAM);
@@ -131,6 +150,9 @@ public class JaasContext {
             throw new IllegalArgumentException(errorMessage);
         }
 
+        for (AppConfigurationEntry appConfigurationEntry : configEntries) {
+            throwIfLoginModuleIsNotAllowed(appConfigurationEntry);
+        }
         return new JaasContext(contextName, contextType, jaasConfig, null);
     }
 
diff --git a/clients/src/main/java/org/apache/kafka/common/security/JaasUtils.java b/clients/src/main/java/org/apache/kafka/common/security/JaasUtils.java
index baff5633a3f..38a8b06de45 100644
--- a/clients/src/main/java/org/apache/kafka/common/security/JaasUtils.java
+++ b/clients/src/main/java/org/apache/kafka/common/security/JaasUtils.java
@@ -25,7 +25,8 @@ import javax.security.auth.login.Configuration;
 public final class JaasUtils {
     private static final Logger LOG = LoggerFactory.getLogger(JaasUtils.class);
     public static final String JAVA_LOGIN_CONFIG_PARAM = "java.security.auth.login.config";
-
+    public static final String DISALLOWED_LOGIN_MODULES_CONFIG = "org.apache.kafka.disallowed.login.modules";
+    public static final String DISALLOWED_LOGIN_MODULES_DEFAULT = "com.sun.security.auth.module.JndiLoginModule";
     public static final String SERVICE_NAME = "serviceName";
 
     public static final String ZK_SASL_CLIENT = "zookeeper.sasl.client";
diff --git a/clients/src/test/java/org/apache/kafka/common/security/JaasContextTest.java b/clients/src/test/java/org/apache/kafka/common/security/JaasContextTest.java
index e4f70222d13..ade3aa12319 100644
--- a/clients/src/test/java/org/apache/kafka/common/security/JaasContextTest.java
+++ b/clients/src/test/java/org/apache/kafka/common/security/JaasContextTest.java
@@ -30,6 +30,7 @@ import javax.security.auth.login.AppConfigurationEntry;
 import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag;
 import javax.security.auth.login.Configuration;
 
+import static org.apache.kafka.common.security.JaasUtils.DISALLOWED_LOGIN_MODULES_CONFIG;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -61,6 +62,7 @@ public class JaasContextTest {
     @AfterEach
     public void tearDown() throws Exception {
         Files.delete(jaasConfigFile.toPath());
+        System.clearProperty(DISALLOWED_LOGIN_MODULES_CONFIG);
     }
 
     @Test
@@ -180,6 +182,52 @@ public class JaasContextTest {
         checkInvalidConfiguration("test.testInvalidControlFlag { option1=3;");
     }
 
+    @Test
+    public void testDisallowedLoginModulesSystemProperty() throws Exception {
+        //test JndiLoginModule is not allowed by default
+        String jaasConfigProp1 = "com.sun.security.auth.module.JndiLoginModule required;";
+        assertThrows(IllegalArgumentException.class, () -> configurationEntry(JaasContext.Type.CLIENT, jaasConfigProp1));
+
+        //test ListenerName Override
+        writeConfiguration(Arrays.asList(
+                "KafkaServer { test.LoginModuleDefault required; };",
+                "plaintext.KafkaServer { com.sun.security.auth.module.JndiLoginModule requisite; };"
+        ));
+        assertThrows(IllegalArgumentException.class, () -> JaasContext.loadServerContext(new ListenerName("plaintext"),
+                "SOME-MECHANISM", Collections.emptyMap()));
+
+        //test org.apache.kafka.disallowed.login.modules system property with multiple modules
+        System.setProperty(DISALLOWED_LOGIN_MODULES_CONFIG, " com.ibm.security.auth.module.LdapLoginModule , com.ibm.security.auth.module.Krb5LoginModule ");
+
+        String jaasConfigProp2 = "com.ibm.security.auth.module.LdapLoginModule required;";
+        assertThrows(IllegalArgumentException.class, () ->  configurationEntry(JaasContext.Type.CLIENT, jaasConfigProp2));
+
+        //test ListenerName Override
+        writeConfiguration(Arrays.asList(
+                "KafkaServer { test.LoginModuleDefault required; };",
+                "plaintext.KafkaServer { com.ibm.security.auth.module.Krb5LoginModule requisite; };"
+        ));
+        assertThrows(IllegalArgumentException.class, () -> JaasContext.loadServerContext(new ListenerName("plaintext"),
+                "SOME-MECHANISM", Collections.emptyMap()));
+
+
+        //Remove default value for org.apache.kafka.disallowed.login.modules
+        System.setProperty(DISALLOWED_LOGIN_MODULES_CONFIG, "");
+
+        checkConfiguration("com.sun.security.auth.module.JndiLoginModule", LoginModuleControlFlag.REQUIRED, new HashMap<>());
+
+        //test ListenerName Override
+        writeConfiguration(Arrays.asList(
+                "KafkaServer { com.ibm.security.auth.module.LdapLoginModule required; };",
+                "plaintext.KafkaServer { com.sun.security.auth.module.JndiLoginModule requisite; };"
+        ));
+        JaasContext context = JaasContext.loadServerContext(new ListenerName("plaintext"),
+                "SOME-MECHANISM", Collections.emptyMap());
+        assertEquals(1, context.configurationEntries().size());
+        checkEntry(context.configurationEntries().get(0), "com.sun.security.auth.module.JndiLoginModule",
+                LoginModuleControlFlag.REQUISITE, Collections.emptyMap());
+    }
+
     @Test
     public void testNumericOptionWithQuotes() throws Exception {
         Map<String, Object> options = new HashMap<>();