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

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

commit 9513405020b413cd182d8b819572bb050223984a
Author: Timothy Bish <tabish...@gmail.com>
AuthorDate: Thu May 13 14:33:35 2021 -0400

    ARTEMIS-2813 Update MiniKDC and fix Kerberos tests on JDK 11+
    
    Updates the MiniKDC dependency and adds another now needed dep in order
    to get the Kerberos tests working on JDK 11+ builds.
---
 tests/integration-tests/pom.xml                    |  11 ++-
 .../tests/integration/amqp/JMSSaslGssapiTest.java  | 110 ++++++++++++++++-----
 .../src/test/resources/minikdc-krb5-template.conf  |  30 ++++++
 3 files changed, 121 insertions(+), 30 deletions(-)

diff --git a/tests/integration-tests/pom.xml b/tests/integration-tests/pom.xml
index 65140fa..66eaaa2 100644
--- a/tests/integration-tests/pom.xml
+++ b/tests/integration-tests/pom.xml
@@ -390,7 +390,13 @@
       <dependency>
          <groupId>org.apache.hadoop</groupId>
          <artifactId>hadoop-minikdc</artifactId>
-         <version>2.8.1</version>
+         <version>3.3.0</version>
+         <scope>test</scope>
+      </dependency>
+      <dependency>
+         <groupId>org.apache.directory.server</groupId>
+         <artifactId>apacheds-interceptor-kerberos</artifactId>
+         <version>${directory-version}</version>
          <scope>test</scope>
       </dependency>
       <dependency>
@@ -554,8 +560,7 @@
                      <artifactId>maven-surefire-plugin</artifactId>
                      <configuration>
                         <excludes combine.children="append">
-                           <!-- These fail, likely due to due to isues with 
the old Kerberos test harness bits -->
-                           <exclude>**/JMSSaslGssapiTest.java</exclude>
+                           <!-- This fails, likely due to due to issues of 
compatibility with newer KDC updates -->
                            <exclude>**/SaslKrb5LDAPSecurityTest.java</exclude>
 
                            <!-- This is no longer possible on JDK11 because 
the old KRB5 cipher suites it requires were
diff --git 
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSSaslGssapiTest.java
 
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSSaslGssapiTest.java
index 7b6e220..99c4ae8 100644
--- 
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSSaslGssapiTest.java
+++ 
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSSaslGssapiTest.java
@@ -16,24 +16,37 @@
  */
 package org.apache.activemq.artemis.tests.integration.amqp;
 
-import javax.jms.Connection;
-import javax.jms.JMSSecurityException;
-import javax.jms.MessageConsumer;
-import javax.jms.MessageProducer;
-import javax.jms.Session;
-import javax.jms.TextMessage;
+import java.io.BufferedReader;
 import java.io.File;
+import java.io.FileReader;
+import java.io.OutputStream;
 import java.net.URI;
 import java.net.URL;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.WritableByteChannel;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Optional;
+import java.util.Properties;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 
+import javax.jms.Connection;
+import javax.jms.JMSSecurityException;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Queue;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+
 import org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnector;
 import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants;
 import org.apache.activemq.artemis.core.security.Role;
@@ -47,21 +60,25 @@ import 
org.apache.activemq.artemis.protocol.amqp.proton.handler.ProtonHandler;
 import org.apache.activemq.artemis.protocol.amqp.sasl.ClientSASL;
 import org.apache.activemq.artemis.protocol.amqp.sasl.ClientSASLFactory;
 import 
org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager;
-import org.apache.activemq.artemis.tests.util.JavaVersionUtil;
 import org.apache.activemq.artemis.tests.util.Wait;
 import org.apache.activemq.artemis.utils.RandomUtil;
 import org.apache.hadoop.minikdc.MiniKdc;
+import org.apache.kerby.kerberos.kerb.keytab.Keytab;
+import org.apache.kerby.kerberos.kerb.keytab.KeytabEntry;
+import org.apache.kerby.kerberos.kerb.type.base.PrincipalName;
 import org.apache.qpid.jms.JmsConnectionFactory;
 import org.apache.qpid.jms.sasl.GssapiMechanism;
 import org.apache.qpid.proton.amqp.Symbol;
-import org.junit.After;
-import org.junit.Assume;
-import org.junit.Before;
+import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class JMSSaslGssapiTest extends JMSClientTestSupport {
 
+   private static final Logger LOG = 
LoggerFactory.getLogger(JMSSaslGssapiTest.class);
+
    static {
       String path = System.getProperty("java.security.auth.login.config");
       if (path == null) {
@@ -72,25 +89,48 @@ public class JMSSaslGssapiTest extends JMSClientTestSupport 
{
          }
       }
    }
-   MiniKdc kdc = null;
-   private final boolean debug = false;
+
+   private static final String KRB5_TCP_PORT_TEMPLATE = "MINI_KDC_PORT";
+   private static final String KRB5_CONFIG_TEMPLATE = 
"minikdc-krb5-template.conf";
+   private static final String KRB5_DEFAULT_KEYTAB = "target/test.krb5.keytab";
+
+   private static MiniKdc kdc;
+   private static final boolean debug = false;
 
    @BeforeClass
-   public static void checkAssumptions() throws Exception {
-      Assume.assumeTrue("Test only runs on JDK 8", JavaVersionUtil.isJava8());
-   }
+   public static void setUpKerberos() throws Exception {
+      Properties kdcConf = MiniKdc.createConf();
+      kdcConf.setProperty("debug", Boolean.toString(debug));
 
-   @Before
-   public void setUpKerberos() throws Exception {
-      kdc = new MiniKdc(MiniKdc.createConf(), 
temporaryFolder.newFolder("kdc"));
+      // Creates a single server for the tests as there were failures when 
spawning and killing one per unit test.
+      kdc = new MiniKdc(kdcConf, new File("target/"));
       kdc.start();
 
       // hard coded match, default_keytab_name in minikdc-krb5.conf template
-      File userKeyTab = new File("target/test.krb5.keytab");
+      File userKeyTab = new File(KRB5_DEFAULT_KEYTAB);
       kdc.createPrincipal(userKeyTab, "client", "amqp/localhost");
 
+      // We need to hard code the default keyTab into the Krb5 configuration 
file which is not possible
+      // with this version of MiniKDC so we use a template file and replace 
the port with the value from
+      // the MiniKDC instance we just started.
+      rewriteKrbConfFile(kdc);
+
       if (debug) {
-         for (java.util.logging.Logger logger : new java.util.logging.Logger[] 
{java.util.logging.Logger.getLogger("javax.security.sasl"), 
java.util.logging.Logger.getLogger("org.apache.qpid.proton")}) {
+         LOG.debug("java.security.krb5.conf='{}'", 
System.getProperty("java.security.krb5.conf"));
+         try (BufferedReader br = new BufferedReader(new 
FileReader(System.getProperty("java.security.krb5.conf")))) {
+            br.lines().forEach(line -> LOG.debug(line));
+         }
+
+         Keytab kt = Keytab.loadKeytab(userKeyTab);
+         for (PrincipalName name : kt.getPrincipals()) {
+            for (KeytabEntry entry : kt.getKeytabEntries(name)) {
+               LOG.info("KeyTab Entry: PrincipalName:" + entry.getPrincipal() 
+ " ; KeyInfo:" + entry.getKey().getKeyType());
+            }
+         }
+
+         for (java.util.logging.Logger logger : new java.util.logging.Logger[] 
{java.util.logging.Logger.getLogger("logincontext"),
+                                                                               
 java.util.logging.Logger.getLogger("javax.security.sasl"),
+                                                                               
 java.util.logging.Logger.getLogger("org.apache.qpid.proton")}) {
             logger.setLevel(java.util.logging.Level.FINEST);
             logger.addHandler(new java.util.logging.ConsoleHandler());
             for (java.util.logging.Handler handler : logger.getHandlers()) {
@@ -100,8 +140,8 @@ public class JMSSaslGssapiTest extends JMSClientTestSupport 
{
       }
    }
 
-   @After
-   public void stopKerberos() throws Exception {
+   @AfterClass
+   public static void stopKerberos() throws Exception {
       if (kdc != null) {
          kdc.stop();
       }
@@ -125,6 +165,10 @@ public class JMSSaslGssapiTest extends 
JMSClientTestSupport {
       roles.add(role);
       server.getSecurityRepository().addMatch(getQueueName().toString(), 
roles);
 
+      if (debug) {
+         // The default produces so much log spam that debugging the exchanges 
becomes impossible.
+         server.getConfiguration().setMessageExpiryScanPeriod(30_000);
+      }
    }
 
    @Override
@@ -134,7 +178,6 @@ public class JMSSaslGssapiTest extends JMSClientTestSupport 
{
 
    @Override
    protected URI getBrokerQpidJMSConnectionURI() {
-
       try {
          int port = AMQP_PORT;
 
@@ -164,7 +207,7 @@ public class JMSSaslGssapiTest extends JMSClientTestSupport 
{
 
       try {
          Session session = connection.createSession(false, 
Session.AUTO_ACKNOWLEDGE);
-         javax.jms.Queue queue = session.createQueue(getQueueName());
+         Queue queue = session.createQueue(getQueueName());
          MessageConsumer consumer = session.createConsumer(queue);
          MessageProducer producer = session.createProducer(queue);
 
@@ -174,7 +217,6 @@ public class JMSSaslGssapiTest extends JMSClientTestSupport 
{
          TextMessage m = (TextMessage) consumer.receive(1000);
          assertNotNull(m);
          assertEquals(text, m.getText());
-
       } finally {
          connection.close();
       }
@@ -182,7 +224,6 @@ public class JMSSaslGssapiTest extends JMSClientTestSupport 
{
 
    @Test(timeout = 600000)
    public void testSaslPlainConnectionDenied() throws Exception {
-
       JmsConnectionFactory factory = new JmsConnectionFactory(new 
URI("amqp://localhost:" + AMQP_PORT + "?amqp.saslMechanisms=PLAIN"));
       try {
          factory.createConnection("plain", "secret");
@@ -192,7 +233,7 @@ public class JMSSaslGssapiTest extends JMSClientTestSupport 
{
       }
    }
 
-   @Test
+   @Test(timeout = 900000)
    public void testOutboundWithSlowMech() throws Exception {
       final Map<String, Object> config = new LinkedHashMap<>(); 
config.put(TransportConstants.HOST_PROP_NAME, "localhost");
       config.put(TransportConstants.PORT_PROP_NAME, String.valueOf(AMQP_PORT));
@@ -270,4 +311,19 @@ public class JMSSaslGssapiTest extends 
JMSClientTestSupport {
          lifeCycleListener.stop();
       }
    }
+
+   private static void rewriteKrbConfFile(MiniKdc server) throws Exception {
+      final Path template = 
Paths.get(JMSSaslGssapiTest.class.getClassLoader().getResource(KRB5_CONFIG_TEMPLATE).toURI());
+      final String krb5confTemplate = new String(Files.readAllBytes(template), 
StandardCharsets.UTF_8);
+      final String replacementPort = Integer.toString(server.getPort());
+
+      // Replace the port template with the current actual port of the MiniKDC 
Server instance.
+      final String krb5confUpdated = 
krb5confTemplate.replaceAll(KRB5_TCP_PORT_TEMPLATE, replacementPort);
+
+      try (OutputStream outputStream = 
Files.newOutputStream(server.getKrb5conf().toPath());
+           WritableByteChannel channel = Channels.newChannel(outputStream)) {
+
+         
channel.write(ByteBuffer.wrap(krb5confUpdated.getBytes(StandardCharsets.UTF_8)));
+      }
+   }
 }
diff --git 
a/tests/integration-tests/src/test/resources/minikdc-krb5-template.conf 
b/tests/integration-tests/src/test/resources/minikdc-krb5-template.conf
new file mode 100644
index 0000000..1d08811
--- /dev/null
+++ b/tests/integration-tests/src/test/resources/minikdc-krb5-template.conf
@@ -0,0 +1,30 @@
+#
+# 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.
+#
+
+[libdefaults]
+    kdc_realm = EXAMPLE.COM
+    default_realm = EXAMPLE.COM
+    udp_preference_limit = 1
+    kdc_tcp_port = MINI_KDC_PORT
+    default_keytab_name = FILE:target/test.krb5.keytab
+
+[realms]
+    EXAMPLE.COM = {
+        kdc = localhost:MINI_KDC_PORT
+    }
+

Reply via email to