This is an automated email from the ASF dual-hosted git repository. quantranhong1999 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
commit f9b60bfdee7d32e06dad35ac8383b8d962adbf5a Author: Quan Tran <[email protected]> AuthorDate: Fri Jul 24 16:49:13 2026 +0700 JAMES-4215 Test GSSAPI authentication through IMAP and SMTP Start a memory James server backed by an embedded Kerberos KDC and load the GSSAPI mechanism through the extension factory. Cover IMAP and SMTP authentication, STARTTLS availability, exchanges without an initial response, invalid tokens, and unauthorized identities. --- .../sasl/kerberos/KerberosTestExtension.java | 137 ++++++++ server/apps/memory-app/pom.xml | 27 ++ .../apache/james/SaslGssapiIntegrationTest.java | 368 +++++++++++++++++++++ .../src/test/resources/imapserver-gssapi.xml | 45 +++ .../src/test/resources/smtpserver-gssapi.xml | 53 +++ 5 files changed, 630 insertions(+) diff --git a/protocols/sasl-kerberos/src/test/java/org/apache/james/protocols/sasl/kerberos/KerberosTestExtension.java b/protocols/sasl-kerberos/src/test/java/org/apache/james/protocols/sasl/kerberos/KerberosTestExtension.java new file mode 100644 index 0000000000..be76ca116d --- /dev/null +++ b/protocols/sasl-kerberos/src/test/java/org/apache/james/protocols/sasl/kerberos/KerberosTestExtension.java @@ -0,0 +1,137 @@ +/**************************************************************** + * 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.james.protocols.sasl.kerberos; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.extension.AfterAllCallback; +import org.junit.jupiter.api.extension.BeforeAllCallback; +import org.junit.jupiter.api.extension.ExtensionContext; + +import com.google.common.collect.ImmutableMap; + +/** + * Runs an embedded Apache Kerby KDC and provisions principals and keytabs for Kerberos tests. + */ +public class KerberosTestExtension implements BeforeAllCallback, AfterAllCallback { + public static final String SERVER_NAME = "localhost"; + + public static String principalProperty(String serviceName) { + return "james.test.kerberos." + serviceName + ".principal"; + } + + public static String keyTabProperty(String serviceName) { + return "james.test.kerberos." + serviceName + ".keytab"; + } + + private static boolean isNested(ExtensionContext context) { + return context.getTestClass() + .map(testClass -> testClass.isAnnotationPresent(Nested.class)) + .orElse(false); + } + + private final String[] serviceNames; + private final Map<String, String> previousProperties; + private KerberosTestFixture fixture; + private Map<String, KerberosTestFixture.Service> services; + + public KerberosTestExtension(String... serviceNames) { + this.serviceNames = Arrays.copyOf(serviceNames, serviceNames.length); + this.previousProperties = new HashMap<>(); + this.services = ImmutableMap.of(); + } + + @Override + public void beforeAll(ExtensionContext context) throws Exception { + if (isNested(context)) { + return; + } + + Path workDirectory = Files.createTempDirectory("james-kerberos-"); + fixture = new KerberosTestFixture(workDirectory); + + try { + ImmutableMap.Builder<String, KerberosTestFixture.Service> provisionedServices = ImmutableMap.builder(); + for (String serviceName : serviceNames) { + KerberosTestFixture.Service service = fixture.provisionService(serviceName, SERVER_NAME); + provisionedServices.put(serviceName, service); + setProperty(principalProperty(serviceName), service.principal()); + setProperty(keyTabProperty(serviceName), service.keyTab().toString()); + } + services = provisionedServices.build(); + } catch (Exception e) { + afterAll(context); + throw e; + } + } + + @Override + public void afterAll(ExtensionContext context) throws Exception { + if (isNested(context)) { + return; + } + + try { + if (fixture != null) { + KerberosTestFixture fixtureToClose = fixture; + fixture = null; + fixtureToClose.close(); + } + } finally { + previousProperties.forEach((property, previousValue) -> { + if (previousValue == null) { + System.clearProperty(property); + } else { + System.setProperty(property, previousValue); + } + }); + previousProperties.clear(); + } + } + + public KerberosTestFixture.Service service(String serviceName) { + KerberosTestFixture.Service service = services.get(serviceName); + if (service == null) { + throw new IllegalArgumentException("Kerberos service was not provisioned: " + serviceName); + } + return service; + } + + public GssapiTestClient client(String serviceName) throws Exception { + return fixture.client(service(serviceName)); + } + + public GssapiTestClient client(String serviceName, Optional<String> authorizationId) throws Exception { + return fixture.client(service(serviceName), authorizationId); + } + + private void setProperty(String property, String value) { + if (!previousProperties.containsKey(property)) { + previousProperties.put(property, System.getProperty(property)); + } + System.setProperty(property, value); + } +} diff --git a/server/apps/memory-app/pom.xml b/server/apps/memory-app/pom.xml index d553a31ea1..76f748f5ef 100644 --- a/server/apps/memory-app/pom.xml +++ b/server/apps/memory-app/pom.xml @@ -208,15 +208,42 @@ <artifactId>testing-base</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>${james.protocols.groupId}</groupId> + <artifactId>protocols-api</artifactId> + <type>test-jar</type> + <scope>test</scope> + </dependency> + <dependency> + <groupId>${james.protocols.groupId}</groupId> + <artifactId>protocols-sasl-kerberos</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>${james.protocols.groupId}</groupId> + <artifactId>protocols-sasl-kerberos</artifactId> + <type>test-jar</type> + <scope>test</scope> + </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> </dependency> + <dependency> + <groupId>commons-net</groupId> + <artifactId>commons-net</artifactId> + <scope>test</scope> + </dependency> <dependency> <groupId>io.rest-assured</groupId> <artifactId>rest-assured</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>org.apache.kerby</groupId> + <artifactId>kerb-simplekdc</artifactId> + <scope>test</scope> + </dependency> <dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> diff --git a/server/apps/memory-app/src/test/java/org/apache/james/SaslGssapiIntegrationTest.java b/server/apps/memory-app/src/test/java/org/apache/james/SaslGssapiIntegrationTest.java new file mode 100644 index 0000000000..9613431b93 --- /dev/null +++ b/server/apps/memory-app/src/test/java/org/apache/james/SaslGssapiIntegrationTest.java @@ -0,0 +1,368 @@ +/**************************************************************** + * 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.james; + +import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT; +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Base64; +import java.util.Optional; + +import org.apache.commons.net.imap.AuthenticatingIMAPClient; +import org.apache.commons.net.imap.IMAPReply; +import org.apache.commons.net.smtp.SMTPSClient; +import org.apache.james.modules.protocols.ImapGuiceProbe; +import org.apache.james.modules.protocols.SmtpGuiceProbe; +import org.apache.james.protocols.api.utils.BogusSslContextFactory; +import org.apache.james.protocols.api.utils.BogusTrustManagerFactory; +import org.apache.james.protocols.sasl.kerberos.GssapiTestClient; +import org.apache.james.protocols.sasl.kerberos.KerberosTestExtension; +import org.apache.james.protocols.sasl.kerberos.KerberosTestFixture; +import org.apache.james.utils.DataProbeImpl; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.api.parallel.ResourceLock; + +// The embedded KDC temporarily replaces the JVM-wide Kerberos configuration. +@ResourceLock(KerberosTestFixture.KRB5_CONFIGURATION_RESOURCE) +class SaslGssapiIntegrationTest { + private static final String DELEGATION_TARGET = "bob@" + KerberosTestFixture.REALM; + private static final String HOST = "127.0.0.1"; + private static final int MAX_SASL_ROUNDS = 10; + private static final int SMTP_AUTH_CONTINUE = 334; + private static final int SMTP_AUTH_FAILURE = 535; + private static final int SMTP_AUTH_SUCCESS = 235; + private static final int SMTP_OK = 250; + private static final byte[] INVALID_GSSAPI_TOKEN = {1, 2, 3}; + + // Provision Kerberos credentials before James resolves them from its server configuration. + @Order(1) + @RegisterExtension + static KerberosTestExtension kerberos = new KerberosTestExtension("imap", "smtp"); + + @Order(2) + @RegisterExtension + static JamesServerExtension jamesServerExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir -> { + TemporaryJamesServer temporaryJamesServer = new TemporaryJamesServer(tmpDir); + temporaryJamesServer.copyResources("imapserver-gssapi.xml", "imapserver.xml"); + temporaryJamesServer.copyResources("smtpserver-gssapi.xml", "smtpserver.xml"); + return MemoryJamesConfiguration.builder() + .workingDirectory(tmpDir) + .usersRepository(DEFAULT) + .build(); + }) + .server(MemoryJamesServerMain::createServer) + .lifeCycle(JamesServerExtension.Lifecycle.PER_ENCLOSING_CLASS) + .build(); + + @BeforeAll + static void provisionKerberosUser(GuiceJamesServer server) throws Exception { + server.getProbe(DataProbeImpl.class).fluent() + .addDomain(KerberosTestFixture.REALM) + .addUser(KerberosTestFixture.USER_PRINCIPAL, "unused-password") + .addUser(DELEGATION_TARGET, "unused-password"); + } + + private static AuthenticatingIMAPClient connectedImapClient(int port) throws Exception { + AuthenticatingIMAPClient client = new AuthenticatingIMAPClient(false, BogusSslContextFactory.getClientContext()); + client.setTrustManager(BogusTrustManagerFactory.getTrustManagers()[0]); + client.connect(HOST, port); + return client; + } + + private static AuthenticatingIMAPClient imapClient(int port) throws Exception { + AuthenticatingIMAPClient client = connectedImapClient(port); + assertThat(client.execTLS()).isTrue(); + return client; + } + + private static SMTPSClient connectedSmtpClient(int port) throws Exception { + SMTPSClient client = new SMTPSClient(false, BogusSslContextFactory.getClientContext()); + client.setTrustManager(BogusTrustManagerFactory.getTrustManagers()[0]); + client.connect(HOST, port); + return client; + } + + private static SMTPSClient smtpClient(int port) throws Exception { + SMTPSClient client = connectedSmtpClient(port); + assertThat(client.execTLS()).isTrue(); + return client; + } + + private static byte[] imapChallenge(String reply) { + String challenge = reply.trim().substring(1).trim(); + return challenge.isEmpty() ? new byte[0] : Base64.getDecoder().decode(challenge); + } + + private static byte[] smtpChallenge(String reply) { + String challenge = reply.trim().substring(3).trim(); + return challenge.isEmpty() ? new byte[0] : Base64.getDecoder().decode(challenge); + } + + private static String encode(byte[] token) { + return Base64.getEncoder().encodeToString(token); + } + + private static int completeImapExchange(AuthenticatingIMAPClient imapClient, GssapiTestClient gssapiClient, int replyCode) throws Exception { + // Relay each server challenge through the JDK GSSAPI client until SASL completes. + for (int round = 0; round < MAX_SASL_ROUNDS && IMAPReply.isContinuation(replyCode); round++) { + replyCode = imapClient.sendData(encode(gssapiClient.evaluate(imapChallenge(imapClient.getReplyString())))); + } + return replyCode; + } + + private static int completeSmtpExchange(SMTPSClient smtpClient, GssapiTestClient gssapiClient, int replyCode) throws Exception { + // Relay each server challenge through the JDK GSSAPI client until SASL completes. + for (int round = 0; round < MAX_SASL_ROUNDS && replyCode == SMTP_AUTH_CONTINUE; round++) { + replyCode = smtpClient.sendCommand(encode(gssapiClient.evaluate(smtpChallenge(smtpClient.getReplyString())))); + } + return replyCode; + } + + @Nested + class Imap { + @Test + void shouldLoadConfiguredGssapiFactoryAndAuthenticate(GuiceJamesServer server) throws Exception { + // Connect to IMAP over TLS, as required by the configured GSSAPI mechanism. + int port = server.getProbe(ImapGuiceProbe.class).getImapStartTLSPort(); + AuthenticatingIMAPClient imapClient = imapClient(port); + + try (GssapiTestClient gssapiClient = kerberos.client("imap")) { + // Verify James loaded and advertised the configured GSSAPI plugin. + imapClient.capability(); + assertThat(imapClient.getReplyString()).contains("AUTH=GSSAPI"); + + // Complete the Kerberos token exchange with an initial client response. + int replyCode = completeImapExchange(imapClient, gssapiClient, + imapClient.sendCommand("AUTHENTICATE GSSAPI " + encode(gssapiClient.initialResponse()))); + + // Verify authentication succeeded and the IMAP session remains usable. + assertThat(replyCode) + .withFailMessage("Unexpected IMAP authentication reply: %s", imapClient.getReplyString()) + .isEqualTo(IMAPReply.OK); + assertThat(gssapiClient.isComplete()).isTrue(); + assertThat(imapClient.getReplyString()).contains("OK AUTHENTICATE completed."); + assertThat(imapClient.sendCommand("NOOP")).isEqualTo(IMAPReply.OK); + } finally { + imapClient.disconnect(); + } + } + + @Test + void shouldOnlyAdvertiseGssapiAfterStartTls(GuiceJamesServer server) throws Exception { + // Connect without TLS to inspect the initial IMAP capabilities. + int port = server.getProbe(ImapGuiceProbe.class).getImapStartTLSPort(); + AuthenticatingIMAPClient imapClient = connectedImapClient(port); + + try { + // Verify GSSAPI is hidden while the connection is clear text. + imapClient.capability(); + assertThat(imapClient.getReplyString()).doesNotContain("AUTH=GSSAPI"); + + // Start TLS and verify GSSAPI becomes available. + assertThat(imapClient.execTLS()).isTrue(); + imapClient.capability(); + assertThat(imapClient.getReplyString()).contains("AUTH=GSSAPI"); + } finally { + imapClient.disconnect(); + } + } + + @Test + void shouldAuthenticateWithExplicitSelfAuthorizationIdentity(GuiceJamesServer server) throws Exception { + // Connect over TLS and create a client requesting its own James identity. + int port = server.getProbe(ImapGuiceProbe.class).getImapStartTLSPort(); + AuthenticatingIMAPClient imapClient = imapClient(port); + + try (GssapiTestClient gssapiClient = kerberos.client("imap", Optional.of(KerberosTestFixture.USER_PRINCIPAL))) { + // Authenticate with an explicit authorization identity matching the Kerberos principal. + int replyCode = completeImapExchange(imapClient, gssapiClient, + imapClient.sendCommand("AUTHENTICATE GSSAPI " + encode(gssapiClient.initialResponse()))); + + // Verify self-authorization is accepted. + assertThat(replyCode).isEqualTo(IMAPReply.OK); + assertThat(gssapiClient.isComplete()).isTrue(); + } finally { + imapClient.disconnect(); + } + } + + @Test + void shouldAuthenticateWithoutInitialResponse(GuiceJamesServer server) throws Exception { + // Connect to IMAP over TLS without preparing an inline authentication token. + int port = server.getProbe(ImapGuiceProbe.class).getImapStartTLSPort(); + AuthenticatingIMAPClient imapClient = imapClient(port); + + try (GssapiTestClient gssapiClient = kerberos.client("imap")) { + // Start authentication without a token and verify the server requests one. + int replyCode = imapClient.sendCommand("AUTHENTICATE GSSAPI"); + assertThat(replyCode).isEqualTo(IMAPReply.CONT); + assertThat(imapChallenge(imapClient.getReplyString())).isEmpty(); + + // Send the initial token and complete the remaining Kerberos exchange. + replyCode = completeImapExchange(imapClient, gssapiClient, + imapClient.sendData(encode(gssapiClient.initialResponse()))); + + // Verify authentication succeeds without an inline initial response. + assertThat(replyCode).isEqualTo(IMAPReply.OK); + assertThat(gssapiClient.isComplete()).isTrue(); + } finally { + imapClient.disconnect(); + } + } + + @Test + void shouldRejectInvalidTokenAndKeepConnectionUsable(GuiceJamesServer server) throws Exception { + // Connect to IMAP over TLS before submitting a malformed GSSAPI token. + int port = server.getProbe(ImapGuiceProbe.class).getImapStartTLSPort(); + AuthenticatingIMAPClient imapClient = imapClient(port); + + try { + // Attempt authentication with data that is not a valid Kerberos token. + int replyCode = imapClient.sendCommand("AUTHENTICATE GSSAPI " + encode(INVALID_GSSAPI_TOKEN)); + + // Verify authentication fails without closing or corrupting the IMAP session. + assertThat(replyCode).isEqualTo(IMAPReply.NO); + assertThat(imapClient.getReplyString()).contains("NO AUTHENTICATE failed."); + assertThat(imapClient.sendCommand("NOOP")).isEqualTo(IMAPReply.OK); + } finally { + imapClient.disconnect(); + } + } + + @Test + void shouldRejectUnauthorizedIdentity(GuiceJamesServer server) throws Exception { + // Connect over TLS and request a James identity different from the Kerberos principal. + int port = server.getProbe(ImapGuiceProbe.class).getImapStartTLSPort(); + AuthenticatingIMAPClient imapClient = imapClient(port); + + try (GssapiTestClient gssapiClient = kerberos.client("imap", Optional.of(DELEGATION_TARGET))) { + // Complete Kerberos authentication while requesting the unauthorized target identity. + int replyCode = completeImapExchange(imapClient, gssapiClient, + imapClient.sendCommand("AUTHENTICATE GSSAPI " + encode(gssapiClient.initialResponse()))); + + // Verify James rejects delegation while keeping the IMAP session usable. + assertThat(replyCode).isEqualTo(IMAPReply.NO); + assertThat(imapClient.getReplyString()).contains("Delegation is forbidden."); + assertThat(imapClient.sendCommand("NOOP")).isEqualTo(IMAPReply.OK); + } finally { + imapClient.disconnect(); + } + } + } + + @Nested + class Smtp { + @Test + void shouldLoadConfiguredGssapiFactoryAndAuthenticate(GuiceJamesServer server) throws Exception { + // Connect to SMTP over TLS, as required by the configured GSSAPI mechanism. + int port = server.getProbe(SmtpGuiceProbe.class).getSmtpStartTlsPort().getValue(); + SMTPSClient smtpClient = smtpClient(port); + + try (GssapiTestClient gssapiClient = kerberos.client("smtp")) { + // Verify James loaded and advertised the configured GSSAPI plugin. + smtpClient.sendCommand("EHLO localhost"); + assertThat(smtpClient.getReplyString()).contains("AUTH GSSAPI"); + + // Complete the Kerberos token exchange with an initial client response. + int replyCode = completeSmtpExchange(smtpClient, gssapiClient, + smtpClient.sendCommand("AUTH GSSAPI " + encode(gssapiClient.initialResponse()))); + + // Verify authentication succeeded and the SMTP session remains usable. + assertThat(replyCode).isEqualTo(SMTP_AUTH_SUCCESS); + assertThat(gssapiClient.isComplete()).isTrue(); + assertThat(smtpClient.getReplyString()).contains("Authentication Successful"); + assertThat(smtpClient.noop()).isEqualTo(SMTP_OK); + } finally { + smtpClient.disconnect(); + } + } + + @Test + void shouldOnlyAdvertiseGssapiAfterStartTls(GuiceJamesServer server) throws Exception { + // Connect without TLS to inspect the initial SMTP extensions. + int port = server.getProbe(SmtpGuiceProbe.class).getSmtpStartTlsPort().getValue(); + SMTPSClient smtpClient = connectedSmtpClient(port); + + try { + // Verify GSSAPI is hidden while the connection is clear text. + smtpClient.sendCommand("EHLO localhost"); + assertThat(smtpClient.getReplyString()).doesNotContain("AUTH GSSAPI"); + + // Start TLS and verify GSSAPI becomes available. + assertThat(smtpClient.execTLS()).isTrue(); + smtpClient.sendCommand("EHLO localhost"); + assertThat(smtpClient.getReplyString()).contains("AUTH GSSAPI"); + } finally { + smtpClient.disconnect(); + } + } + + @Test + void shouldAuthenticateWithoutInitialResponse(GuiceJamesServer server) throws Exception { + // Connect to SMTP over TLS without preparing an inline authentication token. + int port = server.getProbe(SmtpGuiceProbe.class).getSmtpStartTlsPort().getValue(); + SMTPSClient smtpClient = smtpClient(port); + + try (GssapiTestClient gssapiClient = kerberos.client("smtp")) { + smtpClient.sendCommand("EHLO localhost"); + + // Start authentication without a token and verify the server requests one. + int replyCode = smtpClient.sendCommand("AUTH GSSAPI"); + assertThat(replyCode).isEqualTo(SMTP_AUTH_CONTINUE); + assertThat(smtpChallenge(smtpClient.getReplyString())).isEmpty(); + + // Send the initial token and complete the remaining Kerberos exchange. + replyCode = completeSmtpExchange(smtpClient, gssapiClient, + smtpClient.sendCommand(encode(gssapiClient.initialResponse()))); + + // Verify authentication succeeds without an inline initial response. + assertThat(replyCode).isEqualTo(SMTP_AUTH_SUCCESS); + assertThat(gssapiClient.isComplete()).isTrue(); + } finally { + smtpClient.disconnect(); + } + } + + @Test + void shouldRejectInvalidTokenAndKeepConnectionUsable(GuiceJamesServer server) throws Exception { + // Connect to SMTP over TLS before submitting a malformed GSSAPI token. + int port = server.getProbe(SmtpGuiceProbe.class).getSmtpStartTlsPort().getValue(); + SMTPSClient smtpClient = smtpClient(port); + + try { + smtpClient.sendCommand("EHLO localhost"); + + // Attempt authentication with data that is not a valid Kerberos token. + int replyCode = smtpClient.sendCommand("AUTH GSSAPI " + encode(INVALID_GSSAPI_TOKEN)); + + // Verify authentication fails without closing or corrupting the SMTP session. + assertThat(replyCode).isEqualTo(SMTP_AUTH_FAILURE); + assertThat(smtpClient.getReplyString()).contains("535 Authentication Failed"); + assertThat(smtpClient.noop()).isEqualTo(SMTP_OK); + } finally { + smtpClient.disconnect(); + } + } + } +} diff --git a/server/apps/memory-app/src/test/resources/imapserver-gssapi.xml b/server/apps/memory-app/src/test/resources/imapserver-gssapi.xml new file mode 100644 index 0000000000..61951eb011 --- /dev/null +++ b/server/apps/memory-app/src/test/resources/imapserver-gssapi.xml @@ -0,0 +1,45 @@ +<?xml version="1.0"?> + +<!-- +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. +--> + +<imapservers> + <imapserver enabled="true"> + <jmxName>imapserver-gssapi</jmxName> + <bind>127.0.0.1:0</bind> + <tls socketTLS="false" startTLS="true"> + <keystore>classpath://keystore</keystore> + <secret>james72laBalle</secret> + <provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider> + </tls> + <auth> + <requireSSL>true</requireSSL> + <saslMechanisms>org.apache.james.protocols.sasl.kerberos.GssapiSaslMechanismFactory</saslMechanisms> + <gssapi> + <serviceName>imap</serviceName> + <serverName>localhost</serverName> + <principal>${sys:james.test.kerberos.imap.principal}</principal> + <keyTab>${sys:james.test.kerberos.imap.keytab}</keyTab> + </gssapi> + </auth> + <connectionLimit>0</connectionLimit> + <connectionLimitPerIP>0</connectionLimitPerIP> + <gracefulShutdown>false</gracefulShutdown> + </imapserver> +</imapservers> diff --git a/server/apps/memory-app/src/test/resources/smtpserver-gssapi.xml b/server/apps/memory-app/src/test/resources/smtpserver-gssapi.xml new file mode 100644 index 0000000000..07fc0d8af9 --- /dev/null +++ b/server/apps/memory-app/src/test/resources/smtpserver-gssapi.xml @@ -0,0 +1,53 @@ +<?xml version="1.0"?> + +<!-- +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. +--> + +<smtpservers> + <smtpserver enabled="true"> + <jmxName>smtpserver-gssapi</jmxName> + <bind>127.0.0.1:0</bind> + <tls socketTLS="false" startTLS="true"> + <keystore>classpath://keystore</keystore> + <secret>james72laBalle</secret> + <provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider> + <algorithm>SunX509</algorithm> + </tls> + <auth> + <announce>always</announce> + <requireSSL>true</requireSSL> + <saslMechanisms>org.apache.james.protocols.sasl.kerberos.GssapiSaslMechanismFactory</saslMechanisms> + <gssapi> + <serviceName>smtp</serviceName> + <serverName>localhost</serverName> + <principal>${sys:james.test.kerberos.smtp.principal}</principal> + <keyTab>${sys:james.test.kerberos.smtp.keytab}</keyTab> + </gssapi> + </auth> + <verifyIdentity>false</verifyIdentity> + <maxmessagesize>0</maxmessagesize> + <maxLineLength>65536</maxLineLength> + <addressBracketsEnforcement>true</addressBracketsEnforcement> + <smtpGreeting>Apache JAMES GSSAPI Test Server</smtpGreeting> + <handlerchain> + <handler class="org.apache.james.smtpserver.CoreCmdHandlerLoader"/> + </handlerchain> + <gracefulShutdown>false</gracefulShutdown> + </smtpserver> +</smtpservers> --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
