You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by cl...@apache.org on 2023/01/30 20:26:05 UTC

[activemq-artemis] branch main updated: ARTEMIS-4149 - add watch to login.config dir to trigger periodic update to jass reloadable properties status in the absence of login attempts

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

clebertsuconic pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/activemq-artemis.git


The following commit(s) were added to refs/heads/main by this push:
     new b5ae95c376 ARTEMIS-4149 - add watch to login.config dir to trigger periodic update to jass reloadable properties status in the absence of login attempts
b5ae95c376 is described below

commit b5ae95c3765734421f5fe0fb7996d41ba4ba4239
Author: Gary Tully <ga...@gmail.com>
AuthorDate: Mon Jan 30 17:53:19 2023 +0000

    ARTEMIS-4149 - add watch to login.config dir to trigger periodic update to jass reloadable properties status in the absence of login attempts
---
 .../core/server/impl/ActiveMQServerImpl.java       | 10 +++
 .../spi/core/security/jaas/PropertiesLoader.java   | 26 +++++-
 .../artemis/core/security/jaas/StatusTest.java     | 94 ++++++++++++++++++++++
 3 files changed, 127 insertions(+), 3 deletions(-)

diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
index 2a313ce4a2..d2f5657011 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
@@ -195,6 +195,7 @@ import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection;
 import org.apache.activemq.artemis.spi.core.protocol.SessionCallback;
 import org.apache.activemq.artemis.spi.core.security.ActiveMQBasicSecurityManager;
 import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager;
+import org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoader;
 import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
 import org.apache.activemq.artemis.utils.ActiveMQThreadPoolExecutor;
 import org.apache.activemq.artemis.utils.CompositeAddress;
@@ -3324,6 +3325,15 @@ public class ActiveMQServerImpl implements ActiveMQServer {
                }
             }
          }
+
+         // watch login.config dir for mods to trigger reload, otherwise reloadable properties
+         // only appear in status on a relevant login attempt which may never happen
+         File optionalJaasConfigBaseDir = PropertiesLoader.FileNameKey.parentDirOfLoginConfigSystemProperty();
+         if (optionalJaasConfigBaseDir != null) {
+            reloadManager.addCallback(optionalJaasConfigBaseDir.toURI().toURL(), (uri) -> {
+               PropertiesLoader.reload();
+            });
+         }
       }
 
       if (hasBrokerPlugins()) {
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/jaas/PropertiesLoader.java b/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/jaas/PropertiesLoader.java
index 6adf4dca41..ae62b7a494 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/jaas/PropertiesLoader.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/jaas/PropertiesLoader.java
@@ -17,6 +17,8 @@
 package org.apache.activemq.artemis.spi.core.security.jaas;
 
 import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -28,6 +30,7 @@ public class PropertiesLoader {
 
    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
+   public static String LOGIN_CONFIG_SYS_PROP_NAME = "java.security.auth.login.config";
    static final Map<FileNameKey, ReloadableProperties> staticCache = new HashMap<>();
    protected boolean debug;
 
@@ -109,9 +112,7 @@ public class PropertiesLoader {
          if (options.get("baseDir") != null) {
             baseDir = new File((String) options.get("baseDir"));
          } else {
-            if (System.getProperty("java.security.auth.login.config") != null) {
-               baseDir = new File(System.getProperty("java.security.auth.login.config")).getParentFile();
-            }
+            baseDir = parentDirOfLoginConfigSystemProperty();
          }
          if (debug) {
             logger.debug("Using basedir={}", (baseDir == null ? null : baseDir.getAbsolutePath()));
@@ -119,6 +120,14 @@ public class PropertiesLoader {
          return baseDir;
       }
 
+      public static File parentDirOfLoginConfigSystemProperty() {
+         String path = System.getProperty(LOGIN_CONFIG_SYS_PROP_NAME);
+         if (path != null) {
+            return new File(path).getParentFile();
+         }
+         return null;
+      }
+
       @Override
       public String toString() {
          return "PropsFile=" + absPath;
@@ -133,6 +142,17 @@ public class PropertiesLoader {
       }
    }
 
+   public static void reload() {
+      logger.debug("reLoad");
+      Collection<ReloadableProperties> currentSnapshot;
+      synchronized (staticCache) {
+         currentSnapshot = new ArrayList<>(staticCache.values());
+      }
+      for (ReloadableProperties reloadableProperties : currentSnapshot) {
+         reloadableProperties.obtained();
+      }
+   }
+
    /**
     * For test-usage only.
     */
diff --git a/artemis-server/src/test/java/org/apache/activemq/artemis/core/security/jaas/StatusTest.java b/artemis-server/src/test/java/org/apache/activemq/artemis/core/security/jaas/StatusTest.java
new file mode 100644
index 0000000000..873a410117
--- /dev/null
+++ b/artemis-server/src/test/java/org/apache/activemq/artemis/core/security/jaas/StatusTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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.activemq.artemis.core.security.jaas;
+
+import javax.security.auth.Subject;
+import java.io.File;
+import java.util.HashMap;
+
+import org.apache.activemq.artemis.core.server.ActiveMQServer;
+import org.apache.activemq.artemis.core.server.impl.ServerStatus;
+import org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModule;
+import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
+import org.apache.activemq.artemis.utils.Wait;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoader.LOGIN_CONFIG_SYS_PROP_NAME;
+
+public class StatusTest extends ActiveMQTestBase {
+
+   private String existingPath = null;
+
+   @Before
+   public void trackSystemProp() throws Exception {
+      existingPath = System.getProperty(LOGIN_CONFIG_SYS_PROP_NAME);
+   }
+
+   @After
+   public void revertExisting() throws Exception {
+      setOrClearLoginConfigSystemProperty(existingPath);
+   }
+
+   @Test
+   public void testStatusOfLoginConfigSystemProperty() throws Exception {
+
+      File parentDir = new File(temporaryFolder.getRoot(), "sub");
+      parentDir.mkdirs();
+
+      File fileToReferenceViaLoginSystemPropAndFromPropertiesLoginModule = new File(parentDir, "someFileInTempDir.txt");
+      fileToReferenceViaLoginSystemPropAndFromPropertiesLoginModule.createNewFile();
+
+      setOrClearLoginConfigSystemProperty(fileToReferenceViaLoginSystemPropAndFromPropertiesLoginModule.getAbsolutePath());
+
+      ActiveMQServer server = createServer(false);
+      server.getConfiguration().setConfigurationFileRefreshPeriod(1);
+      server.start();
+
+      PropertiesLoginModule propertiesLoginModule = new PropertiesLoginModule();
+      final HashMap<String, String> options = new HashMap<>();
+      options.put("reload", "true");
+      options.put(PropertiesLoginModule.USER_FILE_PROP_NAME, fileToReferenceViaLoginSystemPropAndFromPropertiesLoginModule.getName());
+      options.put(PropertiesLoginModule.ROLE_FILE_PROP_NAME, fileToReferenceViaLoginSystemPropAndFromPropertiesLoginModule.getName());
+
+      propertiesLoginModule.initialize(new Subject(), null, null, options);
+      assertTrue("contains", ServerStatus.getInstance().asJson().contains(fileToReferenceViaLoginSystemPropAndFromPropertiesLoginModule.getName()));
+
+      // reset current status reloadTime time, to verify reload
+      final String UNKNOWN = "UNKNOWN";
+      ServerStatus.getInstance().update(ServerStatus.SERVER_COMPONENT, "{\"jaas\":{\"properties\":{\"" + fileToReferenceViaLoginSystemPropAndFromPropertiesLoginModule.getName() + "\": {\"reloadTime\":\"" + UNKNOWN + "\"}}}}");
+
+      // updating referenced file won't kick in till login
+      fileToReferenceViaLoginSystemPropAndFromPropertiesLoginModule.setLastModified(System.currentTimeMillis());
+
+      assertTrue("contains", ServerStatus.getInstance().asJson().contains(UNKNOWN));
+
+      // mod of login.config dir - trigger a reload
+      parentDir.setLastModified(System.currentTimeMillis());
+
+      Wait.assertFalse(() -> ServerStatus.getInstance().asJson().contains(UNKNOWN));
+   }
+
+   private static void setOrClearLoginConfigSystemProperty(String path) throws Exception {
+      if (path != null) {
+         System.setProperty(LOGIN_CONFIG_SYS_PROP_NAME, path);
+      } else {
+         System.clearProperty(LOGIN_CONFIG_SYS_PROP_NAME);
+      }
+   }
+}
\ No newline at end of file