This is an automated email from the ASF dual-hosted git repository.
brusdev 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 a79685e0b8 ARTEMIS-5683 properly convert wildcards in
LegacyLDAPSecuritySettingPlugin
a79685e0b8 is described below
commit a79685e0b88fe0faa702856a4af43d7ee89dc423
Author: Justin Bertram <[email protected]>
AuthorDate: Thu Oct 2 10:47:47 2025 -0500
ARTEMIS-5683 properly convert wildcards in LegacyLDAPSecuritySettingPlugin
---
.../impl/LegacyLDAPSecuritySettingPlugin.java | 69 ++++-
.../impl/LegacyLDAPSecuritySettingPluginTest.java | 119 +++++++++
docs/user-manual/security.adoc | 15 ++
...egacyLDAPSecuritySettingPluginWildcardTest.java | 291 +++++++++++++++++++++
.../src/test/resources/AMQauthWildcard.ldif | 148 +++++++++++
5 files changed, 641 insertions(+), 1 deletion(-)
diff --git
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/LegacyLDAPSecuritySettingPlugin.java
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/LegacyLDAPSecuritySettingPlugin.java
index e9942c48ec..b361a98397 100644
---
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/LegacyLDAPSecuritySettingPlugin.java
+++
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/LegacyLDAPSecuritySettingPlugin.java
@@ -40,6 +40,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+import org.apache.activemq.artemis.core.config.WildcardConfiguration;
import org.apache.activemq.artemis.core.security.Role;
import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
import org.apache.activemq.artemis.core.server.SecuritySettingPlugin;
@@ -52,10 +53,14 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
+import static
org.apache.activemq.artemis.core.config.WildcardConfiguration.DEFAULT_WILDCARD_CONFIGURATION;
+
public class LegacyLDAPSecuritySettingPlugin implements SecuritySettingPlugin {
private static final Logger logger =
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+ private static final WildcardConfiguration OPENWIRE_WILDCARD = new
WildcardConfiguration().setDelimiter('.').setAnyWords('>').setSingleWord('*');
+
private static final long serialVersionUID = 4793109879399750045L;
public static final String INITIAL_CONTEXT_FACTORY =
"initialContextFactory";
@@ -74,6 +79,9 @@ public class LegacyLDAPSecuritySettingPlugin implements
SecuritySettingPlugin {
public static final String REFRESH_INTERVAL = "refreshInterval";
public static final String MAP_ADMIN_TO_MANAGE = "mapAdminToManage";
public static final String ALLOW_QUEUE_ADMIN_ON_READ =
"allowQueueAdminOnRead";
+ public static final String ANY_WORDS_WILDCARD_CONVERSION =
"anyWordsWildcardConversion";
+ public static final String SINGLE_WORD_WILDCARD_CONVERSION =
"singleWordWildcardConversion";
+ public static final String DELIMITER_WILDCARD_CONVERSION =
"delimiterWildcardConversion";
private String initialContextFactory = "com.sun.jndi.ldap.LdapCtxFactory";
private String connectionURL = "ldap://localhost:1024";
@@ -91,6 +99,10 @@ public class LegacyLDAPSecuritySettingPlugin implements
SecuritySettingPlugin {
private int refreshInterval = 0;
private boolean mapAdminToManage = false;
private boolean allowQueueAdminOnRead = false;
+ private WildcardConfiguration wildcardConfiguration = new
WildcardConfiguration()
+ .setAnyWords(DEFAULT_WILDCARD_CONFIGURATION.getAnyWords())
+ .setSingleWord(DEFAULT_WILDCARD_CONFIGURATION.getSingleWord())
+ .setDelimiter(DEFAULT_WILDCARD_CONFIGURATION.getDelimiter());
private DirContext context;
private EventDirContext eventContext;
@@ -118,6 +130,9 @@ public class LegacyLDAPSecuritySettingPlugin implements
SecuritySettingPlugin {
refreshInterval = Integer.parseInt(getOption(options,
REFRESH_INTERVAL, Integer.valueOf(refreshInterval).toString()));
mapAdminToManage = getOption(options, MAP_ADMIN_TO_MANAGE,
Boolean.FALSE.toString()).equalsIgnoreCase(Boolean.TRUE.toString());
allowQueueAdminOnRead = getOption(options, ALLOW_QUEUE_ADMIN_ON_READ,
Boolean.FALSE.toString()).equalsIgnoreCase(Boolean.TRUE.toString());
+ wildcardConfiguration.setAnyWords(getCharOption(options,
ANY_WORDS_WILDCARD_CONVERSION,
String.valueOf(DEFAULT_WILDCARD_CONFIGURATION.getAnyWords())));
+ wildcardConfiguration.setSingleWord(getCharOption(options,
SINGLE_WORD_WILDCARD_CONVERSION,
String.valueOf(DEFAULT_WILDCARD_CONFIGURATION.getSingleWord())));
+ wildcardConfiguration.setDelimiter(getCharOption(options,
DELIMITER_WILDCARD_CONVERSION,
String.valueOf(DEFAULT_WILDCARD_CONFIGURATION.getDelimiter())));
}
if (refreshInterval > 0) {
@@ -138,6 +153,14 @@ public class LegacyLDAPSecuritySettingPlugin implements
SecuritySettingPlugin {
return this;
}
+ private char getCharOption(Map<String, String> options, String key, String
defaultValue) {
+ String result = getOption(options, key, defaultValue);
+ if (result.length() != 1) {
+ throw new IllegalArgumentException("Value for " + key + " is longer
than 1 character: " + result);
+ }
+ return result.charAt(0);
+ }
+
private String getOption(Map<String, String> options, String key, String
defaultValue) {
String result = options.get(key);
if (result == null) {
@@ -264,6 +287,15 @@ public class LegacyLDAPSecuritySettingPlugin implements
SecuritySettingPlugin {
return this;
}
+ public int getRefreshInterval() {
+ return refreshInterval;
+ }
+
+ public LegacyLDAPSecuritySettingPlugin setRefreshInterval(int
refreshInterval) {
+ this.refreshInterval = refreshInterval;
+ return this;
+ }
+
public boolean isMapAdminToManage() {
return mapAdminToManage;
}
@@ -282,6 +314,33 @@ public class LegacyLDAPSecuritySettingPlugin implements
SecuritySettingPlugin {
return this;
}
+ public char getAnyWordsWildcardConversion() {
+ return this.wildcardConfiguration.getAnyWords();
+ }
+
+ public LegacyLDAPSecuritySettingPlugin setAnyWordsWildcardConversion(char
anyWordsWildcardConversion) {
+ this.wildcardConfiguration.setAnyWords(anyWordsWildcardConversion);
+ return this;
+ }
+
+ public char getSingleWordWildcardConversion() {
+ return this.wildcardConfiguration.getSingleWord();
+ }
+
+ public LegacyLDAPSecuritySettingPlugin setSingleWordWildcardConversion(char
singleWordWildcardConversion) {
+ this.wildcardConfiguration.setSingleWord(singleWordWildcardConversion);
+ return this;
+ }
+
+ public char getDelimiterWildcardConversion() {
+ return this.wildcardConfiguration.getDelimiter();
+ }
+
+ public LegacyLDAPSecuritySettingPlugin setDelimiterWildcardConversion(char
delimiterWildcardConversion) {
+ this.wildcardConfiguration.setDelimiter(delimiterWildcardConversion);
+ return this;
+ }
+
protected boolean isContextAlive() {
boolean alive = false;
if (context != null) {
@@ -415,7 +474,7 @@ public class LegacyLDAPSecuritySettingPlugin implements
SecuritySettingPlugin {
if (prepareDebugLog) {
logMessage.append("\n\tDestination name: ").append(rdn.getValue());
}
- String destination = rdn.getValue().toString();
+ String destination =
convertDestinationWildcards(rdn.getValue().toString());
rdn = rdns.get(rdns.size() - 1);
if (prepareDebugLog) {
@@ -482,6 +541,14 @@ public class LegacyLDAPSecuritySettingPlugin implements
SecuritySettingPlugin {
}
}
+ private String convertDestinationWildcards(String destination) {
+ // Convert the OpenWire wildcard syntax to the corresponding Artemis
syntax
+ destination = OPENWIRE_WILDCARD.convert(destination,
wildcardConfiguration);
+ // The '$' character was used previously in LDAP entries to represent
the '>' character
+ destination = destination.replace('$',
wildcardConfiguration.getAnyWords());
+ return destination;
+ }
+
@Override
public SecuritySettingPlugin stop() {
if (scheduledFuture != null) {
diff --git
a/artemis-server/src/test/java/org/apache/activemq/artemis/core/server/impl/LegacyLDAPSecuritySettingPluginTest.java
b/artemis-server/src/test/java/org/apache/activemq/artemis/core/server/impl/LegacyLDAPSecuritySettingPluginTest.java
new file mode 100644
index 0000000000..14a0440c50
--- /dev/null
+++
b/artemis-server/src/test/java/org/apache/activemq/artemis/core/server/impl/LegacyLDAPSecuritySettingPluginTest.java
@@ -0,0 +1,119 @@
+/*
+ * 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.server.impl;
+
+import java.util.Map;
+
+import org.apache.activemq.artemis.utils.RandomUtil;
+import org.junit.Test;
+
+import static java.util.Map.entry;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+public class LegacyLDAPSecuritySettingPluginTest {
+
+ @Test
+ public void testBlankParameterMap() throws Exception {
+ new LegacyLDAPSecuritySettingPlugin().init(Map.of());
+ }
+
+ @Test
+ public void testFullParameterMap() throws Exception {
+ final String initialContextFactoryValue = RandomUtil.randomUUIDString();
+ final String connectionURLValue = RandomUtil.randomUUIDString();
+ final String connectionUsernameValue = RandomUtil.randomUUIDString();
+ final String connectionPasswordValue = RandomUtil.randomUUIDString();
+ final String connectionProtocolValue = RandomUtil.randomUUIDString();
+ final String authenticationValue = RandomUtil.randomUUIDString();
+ final String roleAttributeValue = RandomUtil.randomUUIDString();
+ final String filterValue = RandomUtil.randomUUIDString();
+ final String destinationBaseValue = RandomUtil.randomUUIDString();
+ final String adminPermissionValueValue = RandomUtil.randomUUIDString();
+ final String readPermissionValueValue = RandomUtil.randomUUIDString();
+ final String writePermissionValueValue = RandomUtil.randomUUIDString();
+ final String enableListenerValue =
String.valueOf(RandomUtil.randomBoolean());
+ final String refreshIntervalValue =
String.valueOf(RandomUtil.randomInt());
+ final String mapAdminToManageValue =
String.valueOf(RandomUtil.randomBoolean());
+ final String allowQueueAdminOnReadValue =
String.valueOf(RandomUtil.randomBoolean());
+ final String anyWordsWildcardConversionValue =
String.valueOf(RandomUtil.randomChar());
+ final String singleWordWildcardConversionValue =
String.valueOf(RandomUtil.randomChar());
+ final String delimiterWildcardConversionValue =
String.valueOf(RandomUtil.randomChar());
+
+ LegacyLDAPSecuritySettingPlugin plugin = new
LegacyLDAPSecuritySettingPlugin().init(Map.ofEntries(
+ entry("initialContextFactory", initialContextFactoryValue),
+ entry("connectionURL", connectionURLValue),
+ entry("connectionUsername", connectionUsernameValue),
+ entry("connectionPassword", connectionPasswordValue),
+ entry("connectionProtocol", connectionProtocolValue),
+ entry("authentication", authenticationValue),
+ entry("roleAttribute", roleAttributeValue),
+ entry("filter", filterValue),
+ entry("destinationBase", destinationBaseValue),
+ entry("adminPermissionValue", adminPermissionValueValue),
+ entry("readPermissionValue", readPermissionValueValue),
+ entry("writePermissionValue", writePermissionValueValue),
+ entry("enableListener", enableListenerValue),
+ entry("refreshInterval", refreshIntervalValue),
+ entry("mapAdminToManage", mapAdminToManageValue),
+ entry("allowQueueAdminOnRead", allowQueueAdminOnReadValue),
+ entry("anyWordsWildcardConversion", anyWordsWildcardConversionValue),
+ entry("singleWordWildcardConversion",
singleWordWildcardConversionValue),
+ entry("delimiterWildcardConversion", delimiterWildcardConversionValue)
+ ));
+ assertEquals(initialContextFactoryValue,
plugin.getInitialContextFactory());
+ assertEquals(connectionURLValue, plugin.getConnectionURL());
+ assertEquals(connectionUsernameValue, plugin.getConnectionUsername());
+ assertEquals(connectionPasswordValue, plugin.getConnectionPassword());
+ assertEquals(connectionProtocolValue, plugin.getConnectionProtocol());
+ assertEquals(authenticationValue, plugin.getAuthentication());
+ assertEquals(roleAttributeValue, plugin.getRoleAttribute());
+ assertEquals(filterValue, plugin.getFilter());
+ assertEquals(destinationBaseValue, plugin.getDestinationBase());
+ assertEquals(adminPermissionValueValue,
plugin.getAdminPermissionValue());
+ assertEquals(readPermissionValueValue, plugin.getReadPermissionValue());
+ assertEquals(writePermissionValueValue,
plugin.getWritePermissionValue());
+ assertEquals(enableListenerValue,
String.valueOf(plugin.isEnableListener()));
+ assertEquals(refreshIntervalValue,
String.valueOf(plugin.getRefreshInterval()));
+ assertEquals(mapAdminToManageValue,
String.valueOf(plugin.isMapAdminToManage()));
+ assertEquals(allowQueueAdminOnReadValue,
String.valueOf(plugin.isAllowQueueAdminOnRead()));
+ assertEquals(anyWordsWildcardConversionValue,
String.valueOf(plugin.getAnyWordsWildcardConversion()));
+ assertEquals(singleWordWildcardConversionValue,
String.valueOf(plugin.getSingleWordWildcardConversion()));
+ assertEquals(delimiterWildcardConversionValue,
String.valueOf(plugin.getDelimiterWildcardConversion()));
+ }
+
+ @Test
+ public void testLongAnyWords() throws Exception {
+ assertThrows(IllegalArgumentException.class, () -> {
+ new
LegacyLDAPSecuritySettingPlugin().init(Map.of(LegacyLDAPSecuritySettingPlugin.ANY_WORDS_WILDCARD_CONVERSION,
"xxx"));
+ });
+ }
+
+ @Test
+ public void testLongSingleWord() throws Exception {
+ assertThrows(IllegalArgumentException.class, () -> {
+ new
LegacyLDAPSecuritySettingPlugin().init(Map.of(LegacyLDAPSecuritySettingPlugin.SINGLE_WORD_WILDCARD_CONVERSION,
"xxx"));
+ });
+ }
+
+ @Test
+ public void testLongDelimiter() throws Exception {
+ assertThrows(IllegalArgumentException.class, () -> {
+ new
LegacyLDAPSecuritySettingPlugin().init(Map.of(LegacyLDAPSecuritySettingPlugin.DELIMITER_WILDCARD_CONVERSION,
"xxx"));
+ });
+ }
+}
diff --git a/docs/user-manual/security.adoc b/docs/user-manual/security.adoc
index 281f18640e..2298c7994c 100644
--- a/docs/user-manual/security.adoc
+++ b/docs/user-manual/security.adoc
@@ -349,6 +349,21 @@ Whether or not to map the legacy `read` permission to the
`createDurableQueue`,
This was allowed in ActiveMQ Classic.
The default value is `false`.
+anyWordsWildcardConversion::
+This is a 1-character value that should match the `any-words`
xref:wildcard-syntax.adoc#customizing-the-syntax[wildcard syntax] setting
defined for the broker.
+The plugin will translate any `<` or `$` character to this value in an LDAP
entry defining a destination name.
+The default value is `#`.
+
+singleWordWildcardConversion::
+This is a 1-character value that should match the `single-word`
xref:wildcard-syntax.adoc#customizing-the-syntax[wildcard syntax] setting
defined for the broker.
+The plugin will translate any `\*` character to this value in an LDAP entry
defining a destination name.
+The default value is `*`.
+
+delimiterWildcardConversion::
+This is a 1-character value that should match the `delimiter`
xref:wildcard-syntax.adoc#customizing-the-syntax[wildcard syntax] setting
defined for the broker.
+The plugin will translate any `.` character to this value in an LDAP entry
defining a destination name.
+The default value is `.`.
+
The name of the queue or topic defined in LDAP will serve as the "match" for
the security-setting, the permission value will be mapped from the ActiveMQ
Classic type to the Artemis type, and the role will be mapped as-is.
ActiveMQ Classic only has 3 permission types - `read`, `write`, and `admin`.
diff --git
a/tests/integration-tests-isolated/src/test/java/org/apache/activemq/artemis/tests/integration/isolated/security/LegacyLDAPSecuritySettingPluginWildcardTest.java
b/tests/integration-tests-isolated/src/test/java/org/apache/activemq/artemis/tests/integration/isolated/security/LegacyLDAPSecuritySettingPluginWildcardTest.java
new file mode 100644
index 0000000000..0c1c1722af
--- /dev/null
+++
b/tests/integration-tests-isolated/src/test/java/org/apache/activemq/artemis/tests/integration/isolated/security/LegacyLDAPSecuritySettingPluginWildcardTest.java
@@ -0,0 +1,291 @@
+/*
+ * 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.tests.integration.isolated.security;
+
+import javax.naming.Context;
+import javax.naming.NameClassPair;
+import javax.naming.NamingEnumeration;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.InitialDirContext;
+import java.io.File;
+import java.lang.management.ManagementFactory;
+import java.net.URL;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Set;
+
+import org.apache.activemq.artemis.api.core.ActiveMQException;
+import org.apache.activemq.artemis.api.core.QueueConfiguration;
+import org.apache.activemq.artemis.api.core.TransportConfiguration;
+import org.apache.activemq.artemis.api.core.client.ActiveMQClient;
+import org.apache.activemq.artemis.api.core.client.ClientProducer;
+import org.apache.activemq.artemis.api.core.client.ClientSession;
+import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
+import org.apache.activemq.artemis.api.core.client.ServerLocator;
+import org.apache.activemq.artemis.core.config.Configuration;
+import org.apache.activemq.artemis.core.config.WildcardConfiguration;
+import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl;
+import org.apache.activemq.artemis.core.remoting.impl.invm.InVMAcceptorFactory;
+import
org.apache.activemq.artemis.core.remoting.impl.invm.InVMConnectorFactory;
+import org.apache.activemq.artemis.core.server.ActiveMQServer;
+import org.apache.activemq.artemis.core.server.ActiveMQServers;
+import
org.apache.activemq.artemis.core.server.impl.LegacyLDAPSecuritySettingPlugin;
+import
org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager;
+import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
+import org.apache.directory.server.annotations.CreateLdapServer;
+import org.apache.directory.server.annotations.CreateTransport;
+import org.apache.directory.server.core.annotations.ApplyLdifFiles;
+import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
+import org.apache.directory.server.core.integ.FrameworkRunner;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.junit.runner.RunWith;
+
+import static
org.apache.activemq.artemis.core.config.WildcardConfiguration.DEFAULT_WILDCARD_CONFIGURATION;
+
+@RunWith(FrameworkRunner.class)
+@CreateLdapServer(transports = {@CreateTransport(protocol = "LDAP", port =
1024)})
+@ApplyLdifFiles("AMQauthWildcard.ldif")
+public class LegacyLDAPSecuritySettingPluginWildcardTest extends
AbstractLdapTestUnit {
+
+ static {
+ String path = System.getProperty("java.security.auth.login.config");
+ if (path == null) {
+ URL resource =
LegacyLDAPSecuritySettingPluginWildcardTest.class.getClassLoader().getResource("login.config");
+ if (resource != null) {
+ path = resource.getFile();
+ System.setProperty("java.security.auth.login.config", path);
+ }
+ }
+ }
+
+ ActiveMQServer server;
+ ActiveMQJAASSecurityManager securityManager;
+ Configuration configuration;
+ private ServerLocator locator;
+
+ public static final String TARGET_TMP = "./target/tmp";
+ private static final String PRINCIPAL = "uid=admin,ou=system";
+ private static final String CREDENTIALS = "secret";
+
+ // defined in LDIF
+ private static final String AUTHORIZED_USER = "authorizedUser";
+ private static final String UNAUTHORIZED_USER = "unauthorizedUser";
+
+ public LegacyLDAPSecuritySettingPluginWildcardTest() {
+ File parent = new File(TARGET_TMP);
+ parent.mkdirs();
+ temporaryFolder = new TemporaryFolder(parent);
+ }
+
+ @Rule
+ public TemporaryFolder temporaryFolder;
+ private String testDir;
+
+ @Before
+ public void setUp() throws Exception {
+ locator = ActiveMQClient.createServerLocatorWithoutHA(new
TransportConfiguration(InVMConnectorFactory.class.getCanonicalName()));
+ testDir = temporaryFolder.getRoot().getAbsolutePath();
+
+ LegacyLDAPSecuritySettingPlugin legacyLDAPSecuritySettingPlugin = new
LegacyLDAPSecuritySettingPlugin()
+ .setInitialContextFactory("com.sun.jndi.ldap.LdapCtxFactory")
+ .setConnectionURL("ldap://localhost:1024")
+ .setConnectionUsername("uid=admin,ou=system")
+ .setConnectionPassword("secret")
+ .setConnectionProtocol("s")
+ .setAuthentication("simple");
+
+ securityManager = new ActiveMQJAASSecurityManager("LDAPLogin");
+ configuration = new ConfigurationImpl()
+ .setSecurityEnabled(true)
+ .setPersistenceEnabled(false)
+ .addAcceptorConfiguration(new
TransportConfiguration(InVMAcceptorFactory.class.getCanonicalName()))
+ .setJournalDirectory(ActiveMQTestBase.getJournalDir(testDir, 0,
false))
+ .setBindingsDirectory(ActiveMQTestBase.getBindingsDir(testDir, 0,
false))
+ .setPagingDirectory(ActiveMQTestBase.getPageDir(testDir, 0, false))
+
.setLargeMessagesDirectory(ActiveMQTestBase.getLargeMessagesDir(testDir, 0,
false))
+ .addSecuritySettingPlugin(legacyLDAPSecuritySettingPlugin);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ locator.close();
+ if (server != null) {
+ server.stop();
+ }
+ }
+
+ @Test
+ public void testRunning() throws Exception {
+ Hashtable<String, String> env = new Hashtable<>();
+ env.put(Context.PROVIDER_URL, "ldap://localhost:1024");
+ env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
+ env.put(Context.SECURITY_AUTHENTICATION, "simple");
+ env.put(Context.SECURITY_PRINCIPAL, PRINCIPAL);
+ env.put(Context.SECURITY_CREDENTIALS, CREDENTIALS);
+ DirContext ctx = new InitialDirContext(env);
+
+ Set<String> set = new HashSet<>();
+
+ NamingEnumeration<NameClassPair> list = ctx.list("ou=system");
+
+ while (list.hasMore()) {
+ NameClassPair ncp = list.next();
+ set.add(ncp.getName());
+ }
+
+ Assert.assertTrue(set.contains("uid=admin"));
+ Assert.assertTrue(set.contains("ou=users"));
+ Assert.assertTrue(set.contains("ou=groups"));
+ Assert.assertTrue(set.contains("ou=configuration"));
+ Assert.assertTrue(set.contains("prefNodeName=sysPrefRoot"));
+ }
+
+ @Test
+ public void
testBasicPluginAuthorizationRightAngleBracketWithDefaultAnywords() throws
Exception {
+ testBasicPluginAuthorization("A.A", DEFAULT_WILDCARD_CONFIGURATION,
AUTHORIZED_USER);
+ }
+
+ @Test
+ public void
testBasicPluginAuthorizationRightAngleBracketWithDefaultAnywordsNegative()
throws Exception {
+ testBasicPluginAuthorization("A.A", DEFAULT_WILDCARD_CONFIGURATION,
UNAUTHORIZED_USER);
+ }
+
+ @Test
+ public void
testBasicPluginAuthorizationRightAngleBracketWithCustomAnywords() throws
Exception {
+ testBasicPluginAuthorization("A.A", new
WildcardConfiguration().setAnyWords('%'), AUTHORIZED_USER);
+ }
+
+ @Test
+ public void
testBasicPluginAuthorizationRightAngleBracketWithCustomAnywordsNegative()
throws Exception {
+ testBasicPluginAuthorization("A.A", new
WildcardConfiguration().setAnyWords('%'), UNAUTHORIZED_USER);
+ }
+
+ @Test
+ public void
testBasicPluginAuthorizationRightAngleBracketWithCustomDelimiter() throws
Exception {
+ testBasicPluginAuthorization("A_A", new
WildcardConfiguration().setDelimiter('_'), AUTHORIZED_USER);
+ }
+
+ @Test
+ public void
testBasicPluginAuthorizationRightAngleBracketWithCustomDelimiterNegative()
throws Exception {
+ testBasicPluginAuthorization("A_A", new
WildcardConfiguration().setDelimiter('_'), UNAUTHORIZED_USER);
+ }
+
+ @Test
+ public void testBasicPluginAuthorizationDollarWithDefaultAnywords() throws
Exception {
+ testBasicPluginAuthorization("B.B", DEFAULT_WILDCARD_CONFIGURATION,
AUTHORIZED_USER);
+ }
+
+ @Test
+ public void testBasicPluginAuthorizationDollarWithDefaultAnywordsNegative()
throws Exception {
+ testBasicPluginAuthorization("B.B", DEFAULT_WILDCARD_CONFIGURATION,
UNAUTHORIZED_USER);
+ }
+
+ @Test
+ public void testBasicPluginAuthorizationDollarWithCustomAnywords() throws
Exception {
+ testBasicPluginAuthorization("B.B", new
WildcardConfiguration().setAnyWords('%'), AUTHORIZED_USER);
+ }
+
+ @Test
+ public void testBasicPluginAuthorizationDollarWithCustomAnywordsNegative()
throws Exception {
+ testBasicPluginAuthorization("B.B", new
WildcardConfiguration().setAnyWords('%'), UNAUTHORIZED_USER);
+ }
+
+ @Test
+ public void testBasicPluginAuthorizationDollarWithCustomDelimiter() throws
Exception {
+ testBasicPluginAuthorization("B_B", new
WildcardConfiguration().setDelimiter('_'), AUTHORIZED_USER);
+ }
+
+ @Test
+ public void testBasicPluginAuthorizationDollarWithCustomDelimiterNegative()
throws Exception {
+ testBasicPluginAuthorization("B_B", new
WildcardConfiguration().setDelimiter('_'), UNAUTHORIZED_USER);
+ }
+
+ @Test
+ public void testBasicPluginAuthorizationWithDefaultSingleWord() throws
Exception {
+ testBasicPluginAuthorization("C.C.C", DEFAULT_WILDCARD_CONFIGURATION,
AUTHORIZED_USER);
+ }
+
+ @Test
+ public void testBasicPluginAuthorizationWithDefaultSingleWordNegative()
throws Exception {
+ testBasicPluginAuthorization("C.C.C", DEFAULT_WILDCARD_CONFIGURATION,
UNAUTHORIZED_USER);
+ }
+
+ @Test
+ public void testBasicPluginAuthorizationCustomSingleWord() throws Exception
{
+ testBasicPluginAuthorization("C.C.C", new
WildcardConfiguration().setSingleWord('%'), AUTHORIZED_USER);
+ }
+
+ @Test
+ public void testBasicPluginAuthorizationCustomSingleWordNegative() throws
Exception {
+ testBasicPluginAuthorization("C.C.C", new
WildcardConfiguration().setSingleWord('%'), UNAUTHORIZED_USER);
+ }
+
+ private void testBasicPluginAuthorization(String name,
WildcardConfiguration wildcardConfiguration, String username) throws Exception {
+ if (!wildcardConfiguration.equals(DEFAULT_WILDCARD_CONFIGURATION)) {
+ LegacyLDAPSecuritySettingPlugin plugin =
(LegacyLDAPSecuritySettingPlugin)
configuration.getSecuritySettingPlugins().iterator().next();
+
plugin.setAnyWordsWildcardConversion(wildcardConfiguration.getAnyWords());
+
plugin.setSingleWordWildcardConversion(wildcardConfiguration.getSingleWord());
+
plugin.setDelimiterWildcardConversion(wildcardConfiguration.getDelimiter());
+ configuration.setWildCardConfiguration(wildcardConfiguration);
+ }
+ server = ActiveMQServers.newActiveMQServer(configuration,
ManagementFactory.getPlatformMBeanServer(), securityManager, false);
+ server.start();
+
+ ClientSessionFactory cf = locator.createSessionFactory();
+
+ try {
+ ClientSession session = cf.createSession(username, "secret", false,
true, true, false, 0);
+ session.createQueue(QueueConfiguration.of(name));
+ if (!username.equals(AUTHORIZED_USER)) {
+ Assert.fail("should throw exception here");
+ }
+ ClientProducer producer = session.createProducer();
+ producer.send(name, session.createMessage(false));
+ session.close();
+ } catch (ActiveMQException e) {
+ if (username.equals(AUTHORIZED_USER)) {
+ Assert.fail("should not throw exception");
+ }
+ }
+
+ cf.close();
+ }
+
+ @Test
+ public void testBasicPluginAuthorizationWithBadMatch() throws Exception {
+ final String name = "X.X";
+ server = ActiveMQServers.newActiveMQServer(configuration,
ManagementFactory.getPlatformMBeanServer(), securityManager, false);
+ server.start();
+
+ ClientSessionFactory cf = locator.createSessionFactory();
+
+ try {
+ ClientSession session = cf.createSession(AUTHORIZED_USER, "secret",
false, true, true, false, 0);
+ session.createQueue(QueueConfiguration.of(name));
+ Assert.fail("should throw exception here");
+ } catch (ActiveMQException e) {
+ // ignore
+ }
+
+ cf.close();
+ }
+}
diff --git
a/tests/integration-tests-isolated/src/test/resources/AMQauthWildcard.ldif
b/tests/integration-tests-isolated/src/test/resources/AMQauthWildcard.ldif
new file mode 100755
index 0000000000..097292292a
--- /dev/null
+++ b/tests/integration-tests-isolated/src/test/resources/AMQauthWildcard.ldif
@@ -0,0 +1,148 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+##########################
+## Define basic objects ##
+##########################
+
+dn: o=ActiveMQ,ou=system
+objectclass: organization
+objectclass: top
+o: ActiveMQ
+
+###################
+## Define roles ##
+###################
+
+dn: cn=role1,ou=system
+cn: role1
+member: uid=authorizedUser,ou=system
+objectClass: groupOfNames
+objectClass: top
+
+dn: cn=unauthorizedRole,ou=system
+cn: unauthorizedRole
+member: uid=unauthorizedUser,ou=system
+objectClass: groupOfNames
+objectClass: top
+
+##################
+## Define users ##
+##################
+
+dn: uid=authorizedUser,ou=system
+uid: authorizedUser
+userPassword: secret
+objectClass: account
+objectClass: simpleSecurityObject
+objectClass: top
+
+dn: uid=unauthorizedUser,ou=system
+uid: unauthorizedUser
+userPassword: secret
+objectClass: account
+objectClass: simpleSecurityObject
+objectClass: top
+
+#########################
+## Define destinations ##
+#########################
+
+dn: ou=destinations,o=ActiveMQ,ou=system
+objectclass: organizationalUnit
+objectclass: top
+ou: destinations
+
+dn: ou=queues,ou=destinations,o=ActiveMQ,ou=system
+objectclass: organizationalUnit
+objectclass: top
+ou: queues
+
+## A.>
+
+dn: cn=A.>,ou=queues,ou=destinations,o=ActiveMQ,ou=system
+objectClass: applicationProcess
+objectClass: top
+cn: A.>
+
+dn: cn=admin,cn=A.>,ou=queues,ou=destinations,o=ActiveMQ,ou=system
+objectclass: groupOfUniqueNames
+objectclass: top
+cn: admin
+uniquemember: cn=role1
+
+dn: cn=read,cn=A.>,ou=queues,ou=destinations,o=ActiveMQ,ou=system
+objectclass: groupOfUniqueNames
+objectclass: top
+cn: read
+uniquemember: cn=role1
+
+dn: cn=write,cn=A.>,ou=queues,ou=destinations,o=ActiveMQ,ou=system
+objectclass: groupOfUniqueNames
+objectclass: top
+cn: write
+uniquemember: cn=role1
+
+## B.$
+
+dn: cn=B.$,ou=queues,ou=destinations,o=ActiveMQ,ou=system
+objectClass: applicationProcess
+objectClass: top
+cn: B.$
+
+dn: cn=admin,cn=B.$,ou=queues,ou=destinations,o=ActiveMQ,ou=system
+objectclass: groupOfUniqueNames
+objectclass: top
+cn: admin
+uniquemember: cn=role1
+
+dn: cn=read,cn=B.$,ou=queues,ou=destinations,o=ActiveMQ,ou=system
+objectclass: groupOfUniqueNames
+objectclass: top
+cn: read
+uniquemember: cn=role1
+
+dn: cn=write,cn=B.$,ou=queues,ou=destinations,o=ActiveMQ,ou=system
+objectclass: groupOfUniqueNames
+objectclass: top
+cn: write
+uniquemember: cn=role1
+
+## C.*.C
+
+dn: cn=C.*.C,ou=queues,ou=destinations,o=ActiveMQ,ou=system
+objectClass: applicationProcess
+objectClass: top
+cn: C.*.C
+
+dn: cn=admin,cn=C.*.C,ou=queues,ou=destinations,o=ActiveMQ,ou=system
+objectclass: groupOfUniqueNames
+objectclass: top
+cn: admin
+uniquemember: cn=role1
+
+dn: cn=read,cn=C.*.C,ou=queues,ou=destinations,o=ActiveMQ,ou=system
+objectclass: groupOfUniqueNames
+objectclass: top
+cn: read
+uniquemember: cn=role1
+
+dn: cn=write,cn=C.*.C,ou=queues,ou=destinations,o=ActiveMQ,ou=system
+objectclass: groupOfUniqueNames
+objectclass: top
+cn: write
+uniquemember: cn=role1
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
For further information, visit: https://activemq.apache.org/contact