Repository: activemq-artemis
Updated Branches:
  refs/heads/2.6.x db818b13e -> da1eeacc0


ARTEMIS-2107 clarify identity for authn failures in notification

(cherry picked from commit b86cf69e6a268e08b43f857656f3b849e06e0ea4)


Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/da1eeacc
Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/da1eeacc
Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/da1eeacc

Branch: refs/heads/2.6.x
Commit: da1eeacc0d8b963cae9e61a1b5b9c207a1af4cac
Parents: db818b1
Author: Justin Bertram <[email protected]>
Authored: Wed Oct 3 13:03:18 2018 -0500
Committer: Justin Bertram <[email protected]>
Committed: Thu Oct 11 16:55:06 2018 -0500

----------------------------------------------------------------------
 .../api/core/management/ManagementHelper.java   |   2 +
 .../core/security/impl/SecurityStoreImpl.java   |  15 +-
 docs/user-manual/en/management.md               |   2 +-
 .../management/SSLSecurityNotificationTest.java | 181 +++++++++++++++++++
 .../management/SecurityNotificationTest.java    |   3 +
 .../src/test/resources/cert-roles.properties    |   1 +
 6 files changed, 197 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/da1eeacc/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/ManagementHelper.java
----------------------------------------------------------------------
diff --git 
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/ManagementHelper.java
 
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/ManagementHelper.java
index a682eba..7b6d3ff 100644
--- 
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/ManagementHelper.java
+++ 
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/ManagementHelper.java
@@ -62,6 +62,8 @@ public final class ManagementHelper {
 
    public static final SimpleString HDR_USER = new SimpleString("_AMQ_User");
 
+   public static final SimpleString HDR_CERT_SUBJECT_DN = new 
SimpleString("_AMQ_CertSubjectDN");
+
    public static final SimpleString HDR_CHECK_TYPE = new 
SimpleString("_AMQ_CheckType");
 
    public static final SimpleString HDR_SESSION_NAME = new 
SimpleString("_AMQ_SessionName");

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/da1eeacc/artemis-server/src/main/java/org/apache/activemq/artemis/core/security/impl/SecurityStoreImpl.java
----------------------------------------------------------------------
diff --git 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/security/impl/SecurityStoreImpl.java
 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/security/impl/SecurityStoreImpl.java
index a690954..761a20b 100644
--- 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/security/impl/SecurityStoreImpl.java
+++ 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/security/impl/SecurityStoreImpl.java
@@ -140,20 +140,23 @@ public class SecurityStoreImpl implements SecurityStore, 
HierarchicalRepositoryC
          }
 
          if (!userIsValid && validatedUser == null) {
+            String certSubjectDN = "unavailable";
+            X509Certificate[] certs = 
CertificateUtil.getCertsFromConnection(connection);
+            if (certs != null && certs.length > 0 && certs[0] != null) {
+               certSubjectDN = certs[0].getSubjectDN().getName();
+            }
+
             if (notificationService != null) {
                TypedProperties props = new TypedProperties();
+               props.putSimpleStringProperty(ManagementHelper.HDR_USER, 
SimpleString.toSimpleString(user));
+               
props.putSimpleStringProperty(ManagementHelper.HDR_CERT_SUBJECT_DN, 
SimpleString.toSimpleString(certSubjectDN));
+               
props.putSimpleStringProperty(ManagementHelper.HDR_REMOTE_ADDRESS, 
SimpleString.toSimpleString(connection.getRemoteAddress()));
 
                Notification notification = new Notification(null, 
CoreNotificationType.SECURITY_AUTHENTICATION_VIOLATION, props);
 
                notificationService.sendNotification(notification);
             }
 
-            String certSubjectDN = "unavailable";
-            X509Certificate[] certs = 
CertificateUtil.getCertsFromConnection(connection);
-            if (certs != null && certs.length > 0 && certs[0] != null) {
-               certSubjectDN = certs[0].getSubjectDN().getName();
-            }
-
             throw 
ActiveMQMessageBundle.BUNDLE.unableToValidateUser(connection.getRemoteAddress(),
 user, certSubjectDN);
          }
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/da1eeacc/docs/user-manual/en/management.md
----------------------------------------------------------------------
diff --git a/docs/user-manual/en/management.md 
b/docs/user-manual/en/management.md
index d415e98..350f7e6 100644
--- a/docs/user-manual/en/management.md
+++ b/docs/user-manual/en/management.md
@@ -746,7 +746,7 @@ un-formatted result of a call to 
`java.lang.System.currentTimeMillis()`.
 
 - `SECURITY_AUTHENTICATION_VIOLATION` (6)
 
-  `_AMQ_User`
+  `_AMQ_User`, `_AMQ_CertSubjectDN`, `_AMQ_RemoteAddress`
 
 - `SECURITY_PERMISSION_VIOLATION` (7)
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/da1eeacc/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/SSLSecurityNotificationTest.java
----------------------------------------------------------------------
diff --git 
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/SSLSecurityNotificationTest.java
 
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/SSLSecurityNotificationTest.java
new file mode 100644
index 0000000..26e0cca
--- /dev/null
+++ 
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/SSLSecurityNotificationTest.java
@@ -0,0 +1,181 @@
+/*
+ * 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.management;
+
+import java.lang.management.ManagementFactory;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration;
+import org.apache.activemq.artemis.api.core.ActiveMQException;
+import org.apache.activemq.artemis.api.core.SimpleString;
+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.ClientConsumer;
+import org.apache.activemq.artemis.api.core.client.ClientMessage;
+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.api.core.management.ManagementHelper;
+import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants;
+import org.apache.activemq.artemis.core.security.Role;
+import org.apache.activemq.artemis.core.server.ActiveMQServer;
+import org.apache.activemq.artemis.core.server.ActiveMQServers;
+import 
org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager;
+import org.apache.activemq.artemis.tests.integration.security.SecurityTest;
+import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
+import org.apache.activemq.artemis.utils.RandomUtil;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static 
org.apache.activemq.artemis.api.core.management.CoreNotificationType.SECURITY_AUTHENTICATION_VIOLATION;
+
+public class SSLSecurityNotificationTest extends ActiveMQTestBase {
+
+   static {
+      String path = System.getProperty("java.security.auth.login.config");
+      if (path == null) {
+         URL resource = 
SecurityTest.class.getClassLoader().getResource("login.config");
+         if (resource != null) {
+            path = resource.getFile();
+            System.setProperty("java.security.auth.login.config", path);
+         }
+      }
+   }
+
+   private ActiveMQServer server;
+
+   private ClientSession adminSession;
+
+   private ClientConsumer notifConsumer;
+
+   private SimpleString notifQueue;
+
+   @Test
+   public void testSECURITY_AUTHENTICATION_VIOLATION() throws Exception {
+      SSLSecurityNotificationTest.flush(notifConsumer);
+
+      TransportConfiguration tc = new 
TransportConfiguration(NETTY_CONNECTOR_FACTORY);
+      tc.getParams().put(TransportConstants.SSL_ENABLED_PROP_NAME, true);
+      tc.getParams().put(TransportConstants.TRUSTSTORE_PATH_PROP_NAME, 
"client-side-truststore.jks");
+      tc.getParams().put(TransportConstants.TRUSTSTORE_PASSWORD_PROP_NAME, 
"secureexample");
+      tc.getParams().put(TransportConstants.KEYSTORE_PATH_PROP_NAME, 
"bad-client-side-keystore.jks");
+      tc.getParams().put(TransportConstants.KEYSTORE_PASSWORD_PROP_NAME, 
"secureexample");
+
+      ServerLocator locator = 
addServerLocator(ActiveMQClient.createServerLocatorWithoutHA(tc));
+      ClientSessionFactory sf = 
addSessionFactory(createSessionFactory(locator));
+
+      try {
+         sf.createSession();
+         Assert.fail("authentication must fail and a notification of security 
violation must be sent");
+      } catch (Exception e) {
+      }
+
+      ClientMessage[] notifications = 
SSLSecurityNotificationTest.consumeMessages(1, notifConsumer);
+      Assert.assertEquals(SECURITY_AUTHENTICATION_VIOLATION.toString(), 
notifications[0].getObjectProperty(ManagementHelper.HDR_NOTIFICATION_TYPE).toString());
+      Assert.assertEquals(null, 
notifications[0].getObjectProperty(ManagementHelper.HDR_USER));
+      Assert.assertEquals("CN=Bad Client, OU=Artemis, O=ActiveMQ, L=AMQ, 
ST=AMQ, C=AMQ", 
notifications[0].getObjectProperty(ManagementHelper.HDR_CERT_SUBJECT_DN).toString());
+      
Assert.assertTrue(notifications[0].getObjectProperty(ManagementHelper.HDR_REMOTE_ADDRESS).toString().startsWith("/127.0.0.1"));
+   }
+
+   @Override
+   @Before
+   public void setUp() throws Exception {
+      super.setUp();
+      ActiveMQJAASSecurityManager securityManager = new 
ActiveMQJAASSecurityManager("CertLogin");
+      server = 
addServer(ActiveMQServers.newActiveMQServer(createDefaultInVMConfig().setSecurityEnabled(true),
 ManagementFactory.getPlatformMBeanServer(), securityManager, false));
+
+      Map<String, Object> params = new HashMap<>();
+      params.put(TransportConstants.SSL_ENABLED_PROP_NAME, true);
+      params.put(TransportConstants.KEYSTORE_PATH_PROP_NAME, 
"server-side-keystore.jks");
+      params.put(TransportConstants.KEYSTORE_PASSWORD_PROP_NAME, 
"secureexample");
+      params.put(TransportConstants.TRUSTSTORE_PATH_PROP_NAME, 
"server-side-truststore.jks");
+      params.put(TransportConstants.TRUSTSTORE_PASSWORD_PROP_NAME, 
"secureexample");
+      params.put(TransportConstants.NEED_CLIENT_AUTH_PROP_NAME, true);
+
+      server.getConfiguration().addAcceptorConfiguration(new 
TransportConfiguration(NETTY_ACCEPTOR_FACTORY, params));
+
+      server.start();
+
+      notifQueue = RandomUtil.randomSimpleString();
+
+      Role role = new Role("notif", true, true, true, true, true, true, true, 
true, true, true);
+      Set<Role> roles = new HashSet<>();
+      roles.add(role);
+      
server.getSecurityRepository().addMatch(ActiveMQDefaultConfiguration.getDefaultManagementNotificationAddress().toString(),
 roles);
+
+      TransportConfiguration tc = new 
TransportConfiguration(NETTY_CONNECTOR_FACTORY);
+      tc.getParams().put(TransportConstants.SSL_ENABLED_PROP_NAME, true);
+      tc.getParams().put(TransportConstants.TRUSTSTORE_PATH_PROP_NAME, 
"client-side-truststore.jks");
+      tc.getParams().put(TransportConstants.TRUSTSTORE_PASSWORD_PROP_NAME, 
"secureexample");
+      tc.getParams().put(TransportConstants.KEYSTORE_PATH_PROP_NAME, 
"client-side-keystore.jks");
+      tc.getParams().put(TransportConstants.KEYSTORE_PASSWORD_PROP_NAME, 
"secureexample");
+
+      ServerLocator locator = 
addServerLocator(ActiveMQClient.createServerLocatorWithoutHA(tc));
+      ClientSessionFactory sf = 
addSessionFactory(createSessionFactory(locator));
+      adminSession = sf.createSession(true, true, 1);
+      adminSession.start();
+
+      
adminSession.createTemporaryQueue(ActiveMQDefaultConfiguration.getDefaultManagementNotificationAddress(),
 notifQueue);
+
+      notifConsumer = adminSession.createConsumer(notifQueue);
+   }
+
+   // Private -------------------------------------------------------
+
+   private static void flush(final ClientConsumer notifConsumer) throws 
ActiveMQException {
+      ClientMessage message = null;
+      do {
+         message = notifConsumer.receive(500);
+      }
+      while (message != null);
+   }
+
+   protected static ClientMessage[] consumeMessages(final int expected,
+                                                    final ClientConsumer 
consumer) throws Exception {
+      ClientMessage[] messages = new ClientMessage[expected];
+
+      ClientMessage m = null;
+      for (int i = 0; i < expected; i++) {
+         m = consumer.receive(500);
+         if (m != null) {
+            for (SimpleString key : m.getPropertyNames()) {
+               System.out.println(key + "=" + m.getObjectProperty(key));
+            }
+         }
+         Assert.assertNotNull("expected to received " + expected + " messages, 
got only " + i, m);
+         messages[i] = m;
+         m.acknowledge();
+      }
+      m = consumer.receiveImmediate();
+      if (m != null) {
+         for (SimpleString key : m.getPropertyNames()) {
+            System.out.println(key + "=" + m.getObjectProperty(key));
+         }
+      }
+      Assert.assertNull("received one more message than expected (" + expected 
+ ")", m);
+
+      return messages;
+   }
+
+   // Inner classes -------------------------------------------------
+
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/da1eeacc/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/SecurityNotificationTest.java
----------------------------------------------------------------------
diff --git 
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/SecurityNotificationTest.java
 
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/SecurityNotificationTest.java
index 13208fc..579811a 100644
--- 
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/SecurityNotificationTest.java
+++ 
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/SecurityNotificationTest.java
@@ -80,6 +80,9 @@ public class SecurityNotificationTest extends 
ActiveMQTestBase {
 
       ClientMessage[] notifications = 
SecurityNotificationTest.consumeMessages(1, notifConsumer);
       Assert.assertEquals(SECURITY_AUTHENTICATION_VIOLATION.toString(), 
notifications[0].getObjectProperty(ManagementHelper.HDR_NOTIFICATION_TYPE).toString());
+      Assert.assertEquals(unknownUser, 
notifications[0].getObjectProperty(ManagementHelper.HDR_USER).toString());
+      Assert.assertEquals("unavailable", 
notifications[0].getObjectProperty(ManagementHelper.HDR_CERT_SUBJECT_DN).toString());
+      Assert.assertEquals("invm:0", 
notifications[0].getObjectProperty(ManagementHelper.HDR_REMOTE_ADDRESS).toString());
    }
 
    @Test

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/da1eeacc/tests/integration-tests/src/test/resources/cert-roles.properties
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/resources/cert-roles.properties 
b/tests/integration-tests/src/test/resources/cert-roles.properties
index 5f860fc..6ca5d99 100644
--- a/tests/integration-tests/src/test/resources/cert-roles.properties
+++ b/tests/integration-tests/src/test/resources/cert-roles.properties
@@ -17,3 +17,4 @@
 
 programmers=first
 widgets=second
+notif=first

Reply via email to