From b50513a9466eb3591dc973000a225fc07821a5f2 Mon Sep 17 00:00:00 2001 From: fkiss Date: Mon, 16 May 2016 22:31:23 +0200 Subject: [PATCH] KEYCLOAK-2283 added email truststore test --- pom.xml | 7 + .../servers/auth-server/jboss/pom.xml | 84 +++++++++- .../integration-arquillian/tests/base/pom.xml | 5 + .../auth/page/login/VerifyEmail.java | 10 +- .../util/MailServerConfiguration.java | 2 + .../util/MessageHandlerFactoryImpl.java | 86 ++++++++++ .../testsuite/util/MessageHandlerImpl.java | 37 +++++ .../account/TrustStoreEmailTest.java | 115 +++++++++++++ .../keycloak/testsuite/util/MailAssert.java | 10 +- .../testsuite/util/SslMailServer.java | 151 ++++++++++++++++++ .../resources/META-INF/keycloak-server.json | 4 +- .../test/resources/keystore/email_invalid.jks | Bin 0 -> 2179 bytes .../src/test/resources/keystore/keycloak.jks | Bin 0 -> 2233 bytes .../resources/keystore/keycloak.truststore | Bin 0 -> 1857 bytes .../integration-arquillian/tests/pom.xml | 10 ++ 15 files changed, 512 insertions(+), 9 deletions(-) create mode 100644 testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/MessageHandlerFactoryImpl.java create mode 100644 testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/MessageHandlerImpl.java create mode 100644 testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/TrustStoreEmailTest.java create mode 100644 testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/SslMailServer.java create mode 100644 testsuite/integration-arquillian/tests/base/src/test/resources/keystore/email_invalid.jks create mode 100644 testsuite/integration-arquillian/tests/base/src/test/resources/keystore/keycloak.jks create mode 100644 testsuite/integration-arquillian/tests/base/src/test/resources/keystore/keycloak.truststore diff --git a/pom.xml b/pom.xml index 38efdcffa9..80d281b897 100755 --- a/pom.xml +++ b/pom.xml @@ -99,6 +99,7 @@ 2.7.0.Final 2.35.0 1.4.01 + 3.1.7 0.1.12 @@ -419,6 +420,12 @@ ${greenmail.version} test + + org.subethamail + subethasmtp + ${subethasmtp.version} + test + diff --git a/testsuite/integration-arquillian/servers/auth-server/jboss/pom.xml b/testsuite/integration-arquillian/servers/auth-server/jboss/pom.xml index ef8a64d230..8a773966d9 100644 --- a/testsuite/integration-arquillian/servers/auth-server/jboss/pom.xml +++ b/testsuite/integration-arquillian/servers/auth-server/jboss/pom.xml @@ -277,6 +277,84 @@ + + maven-resources-plugin + + + copy-keystore + process-resources + + copy-resources + + + ${auth.server.home}/standalone/configuration + + + ${common.resources}/keystore + + keycloak.jks + keycloak.truststore + + + + + + + + + org.apache.maven.plugins + maven-antrun-plugin + 1.8 + + + inject-truststore-into-keycloak-server-json + process-resources + + run + + + + + + + + + + + + + ant-contrib + ant-contrib + 1.0b3 + + + ant + ant + + + + + org.apache.ant + ant-apache-bsf + 1.9.3 + + + org.apache.bsf + bsf-api + 3.1 + + + rhino + js + 1.7R2 + + + org.keycloak + keycloak-core + ${project.version} + + + @@ -615,12 +693,12 @@ 1 1 1 - + simple - + @@ -723,7 +801,7 @@ - + admin diff --git a/testsuite/integration-arquillian/tests/base/pom.xml b/testsuite/integration-arquillian/tests/base/pom.xml index ee6ad1beb7..11cf4d692e 100644 --- a/testsuite/integration-arquillian/tests/base/pom.xml +++ b/testsuite/integration-arquillian/tests/base/pom.xml @@ -67,6 +67,11 @@ junit compile + + org.subethamail + subethasmtp + compile + com.icegreen greenmail diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/VerifyEmail.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/VerifyEmail.java index e566b41bf6..848a9fa37d 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/VerifyEmail.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/VerifyEmail.java @@ -28,9 +28,17 @@ public class VerifyEmail extends Authenticate { @FindBy(xpath = "//div[@id='kc-form-wrapper']/p") private WebElement instruction; - + + @FindBy(id = "kc-error-message") + private WebElement error; + public String getInstructionMessage() { waitUntilElement(instruction).is().present(); return instruction.getText(); } + + public String getErrorMessage() { + waitUntilElement(error).is().present(); + return error.getText(); + } } diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/MailServerConfiguration.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/MailServerConfiguration.java index 5110e4ca26..50c8ed3123 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/MailServerConfiguration.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/MailServerConfiguration.java @@ -25,4 +25,6 @@ public class MailServerConfiguration { public static final String FROM = "server@mail.test"; public static final String HOST = "localhost"; public static final String PORT = "3025"; + public static final String PORT_SSL = "3465"; + public static final String STARTTLS = "true"; } diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/MessageHandlerFactoryImpl.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/MessageHandlerFactoryImpl.java new file mode 100644 index 0000000000..67a2e43872 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/MessageHandlerFactoryImpl.java @@ -0,0 +1,86 @@ +package org.keycloak.testsuite.util; + +import org.subethamail.smtp.MessageContext; +import org.subethamail.smtp.MessageHandler; +import org.subethamail.smtp.MessageHandlerFactory; +import org.subethamail.smtp.RejectException; + +import javax.mail.MessagingException; +import javax.mail.Session; +import javax.mail.internet.MimeMessage; +import java.io.*; +import java.util.Properties; + + +public class MessageHandlerFactoryImpl implements MessageHandlerFactory { + + MimeMessage message; + + public MessageHandler create(MessageContext ctx) { + return new Handler(ctx); + } + + class Handler implements MessageHandler { + MessageContext ctx; + + + + public Handler(MessageContext ctx) { + this.ctx = ctx; + } + + public void from(String from) throws RejectException { + System.out.println("FROM:" + from); + } + + public void recipient(String recipient) throws RejectException { + System.out.println("RECIPIENT:" + recipient); + } + + public void data(InputStream data) throws IOException { + String rawMail = this.convertStreamToString(data); + + Session session = Session.getDefaultInstance(new Properties()); + InputStream is = new ByteArrayInputStream(rawMail.getBytes()); + try + { + message = new MimeMessage(session, is); + setMessage(message); + } + catch (MessagingException e) + { + e.printStackTrace(); + } + } + + public void done() { + System.out.println("Finished"); + } + + public String convertStreamToString(InputStream is) { + BufferedReader reader = new BufferedReader(new InputStreamReader(is)); + StringBuilder sb = new StringBuilder(); + + String line = null; + try { + while ((line = reader.readLine()) != null) { + sb.append(line + "\n"); + } + } catch (IOException e) { + e.printStackTrace(); + } + return sb.toString(); + } + + + + } + + public MimeMessage getMessage(){ + return message; + } + + public void setMessage(MimeMessage msg){ + this.message = msg; + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/MessageHandlerImpl.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/MessageHandlerImpl.java new file mode 100644 index 0000000000..ec6d430276 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/MessageHandlerImpl.java @@ -0,0 +1,37 @@ +package org.keycloak.testsuite.util; + +import org.jboss.logging.Logger; +import org.subethamail.smtp.MessageContext; +import org.subethamail.smtp.MessageHandler; + +import java.io.InputStream; + +public class MessageHandlerImpl implements MessageHandler { + MessageContext context; + + private static final Logger log = Logger.getLogger(MessageHandlerImpl.class); + + MessageHandlerImpl(MessageContext context) { + this.context = context; + } + + @Override + public void from(String from) { + log.info("FROM: ${from}"); + } + + @Override + public void recipient(String recipient) { + log.info("RECIPIENT: ${recipient}"); + } + + @Override + public void data(InputStream data) { + log.info("DATA"); + } + + @Override + public void done() { + log.info("DONE"); + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/TrustStoreEmailTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/TrustStoreEmailTest.java new file mode 100644 index 0000000000..499e387741 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/TrustStoreEmailTest.java @@ -0,0 +1,115 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed 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.keycloak.testsuite.account; + +import org.jboss.arquillian.graphene.page.Page; +import org.junit.After; +import org.junit.Test; +import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.representations.idm.UserRepresentation; + +import org.keycloak.testsuite.TestRealmKeycloakTest; +import org.keycloak.testsuite.auth.page.AuthRealm; +import org.keycloak.testsuite.auth.page.account.AccountManagement; +import org.keycloak.testsuite.auth.page.login.OIDCLogin; +import org.keycloak.testsuite.auth.page.login.VerifyEmail; +import org.keycloak.testsuite.util.*; + + +import static org.junit.Assert.assertEquals; +import static org.keycloak.testsuite.util.MailAssert.assertEmailAndGetUrl; +import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith; + + +/** + * + * @author fkiss + */ +public class TrustStoreEmailTest extends TestRealmKeycloakTest { + + @Page + protected OIDCLogin testRealmLoginPage; + + @Page + protected AuthRealm testRealmPage; + + @Page + protected AccountManagement accountManagement; + + @Page + private VerifyEmail testRealmVerifyEmailPage; + + private UserRepresentation user; + + @Override + public void configureTestRealm(RealmRepresentation testRealm) { + log.info("enable verify email and configure smtp server to run with ssl in test realm"); + + user = findUserInRealmRep(testRealm, "test-user@localhost"); + testRealm.setSmtpServer(SslMailServer.getServerConfiguration()); + testRealm.setVerifyEmail(true); + } + + + @Override + public void setDefaultPageUriParameters() { + super.setDefaultPageUriParameters(); + testRealmPage.setAuthRealm("test"); + testRealmVerifyEmailPage.setAuthRealm(testRealmPage); + accountManagement.setAuthRealm(testRealmPage); + testRealmLoginPage.setAuthRealm(testRealmPage); + } + + @After + public void afterTrustStoreEmailTest() { + SslMailServer.stop(); + } + + + @Test + public void verifyEmailWithSslEnabled() { + SslMailServer.startWithSsl(this.getClass().getClassLoader().getResource(SslMailServer.PRIVATE_KEY).getFile()); + accountManagement.navigateTo(); + testRealmLoginPage.form().login(user.getUsername(), "password"); + + assertEquals("You need to verify your email address to activate your account.", + testRealmVerifyEmailPage.getFeedbackText()); + + String verifyEmailUrl = assertEmailAndGetUrl(MailServerConfiguration.FROM, user.getEmail(), + "Someone has created a Test account with this email address.", true); + + log.info("navigating to url from email: " + verifyEmailUrl); + + driver.navigate().to(verifyEmailUrl); + + assertCurrentUrlStartsWith(accountManagement); + accountManagement.signOut(); + testRealmLoginPage.form().login(user); + assertCurrentUrlStartsWith(accountManagement); + } + + @Test + public void verifyEmailWithSslWrongCertificate() { + SslMailServer.startWithSsl(this.getClass().getClassLoader().getResource(SslMailServer.INVALID_KEY).getFile()); + accountManagement.navigateTo(); + loginPage.form().login(user); + + assertEquals("Failed to send email, please try again later.\n" + + "« Back to Application", + testRealmVerifyEmailPage.getErrorMessage()); + } +} \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/MailAssert.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/MailAssert.java index 93ae0cc4f2..ac90ea8418 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/MailAssert.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/MailAssert.java @@ -30,11 +30,15 @@ public class MailAssert { private static final Logger log = Logger.getLogger(MailAssert.class); - public static String assertEmailAndGetUrl(String from, String recipient, String content) { + public static String assertEmailAndGetUrl(String from, String recipient, String content, Boolean sslEnabled) { try { - MimeMessage message = MailServer.getLastReceivedMessage(); - assertNotNull("There is no received email.", message); + MimeMessage message; + if (sslEnabled){ + message= SslMailServer.getLastReceivedMessage(); + } else { + message = MailServer.getLastReceivedMessage(); + } assertNotNull("There is no received email.", message); assertEquals(recipient, message.getRecipients(RecipientType.TO)[0].toString()); assertEquals(from, message.getFrom()[0].toString()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/SslMailServer.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/SslMailServer.java new file mode 100644 index 0000000000..0088e42070 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/SslMailServer.java @@ -0,0 +1,151 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed 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.keycloak.testsuite.util; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.*; +import java.security.*; +import java.security.cert.CertificateException; +import java.util.HashMap; +import java.util.Map; + +import javax.mail.internet.MimeMessage; +import javax.net.ssl.*; + +import org.jboss.logging.Logger; +import org.subethamail.smtp.server.SMTPServer; + +import static org.keycloak.testsuite.util.MailServerConfiguration.*; +import static org.keycloak.testsuite.util.MailServerConfiguration.PORT_SSL; +import static org.keycloak.testsuite.util.MailServerConfiguration.STARTTLS; + +public class SslMailServer { + + private static final Logger log = Logger.getLogger(MailServer.class); + + public static final String PRIVATE_KEY = "keystore/keycloak.jks"; + + public static final String TRUSTED_CERTIFICATE = "keystore/keycloak.truststore"; + + //private key tested with invalid certificate + public static final String INVALID_KEY = "keystore/email_invalid.jks"; + + private static MessageHandlerFactoryImpl messageHandlerFactory = new MessageHandlerFactoryImpl(); + + private static SMTPServer smtpServer; + + private static Map serverConfiguration = new HashMap<>(); + + + public static void start() { + smtpServer = new SMTPServer(messageHandlerFactory); + smtpServer.setHostName(HOST); + smtpServer.setPort(Integer.parseInt(PORT)); + smtpServer.start(); + + log.info("Started mail server (" + smtpServer.getHostName() + ":" + smtpServer.getPort() + ")"); + } + + public static void stop() { + if (smtpServer != null) { + log.info("Stopping mail server (" + smtpServer.getHostName() + ":" + smtpServer.getPort() + ")"); + // Suppress error from SubEthaSmtp on shutdown + Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { + @Override + public void uncaughtException(Thread t, Throwable e) { + if (!(e.getCause() instanceof SocketException && e.getStackTrace()[0].getClassName() + .equals("org.subethamail.smtp.server.Session"))) { + log.error("Exception in thread \"" + t.getName() + "\" "); + log.error(e.getMessage(), e); + } + } + }); + smtpServer.stop(); + } + } + + public static void startWithSsl(String privateKey){ + InputStream keyStoreIS = null; + try { + keyStoreIS = new FileInputStream(privateKey); + char[] keyStorePassphrase = "secret".toCharArray(); + KeyStore ksKeys = null; + ksKeys = KeyStore.getInstance("JKS"); + ksKeys.load(keyStoreIS, keyStorePassphrase); + + // KeyManager decides which key material to use. + KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); + kmf.init(ksKeys, keyStorePassphrase); + + // Trust store for client authentication. + InputStream trustStoreIS = new FileInputStream(String.valueOf(MailServer.class.getClassLoader().getResource(TRUSTED_CERTIFICATE).getFile())); + char[] trustStorePassphrase = "secret".toCharArray(); + KeyStore ksTrust = KeyStore.getInstance("JKS"); + ksTrust.load(trustStoreIS, trustStorePassphrase); + + // TrustManager decides which certificate authorities to use. + TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); + tmf.init(ksTrust); + + final SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + + smtpServer = new SMTPServer(messageHandlerFactory) { + @Override + public SSLSocket createSSLSocket(Socket socket) throws IOException { + InetSocketAddress remoteAddress = + (InetSocketAddress) socket.getRemoteSocketAddress(); + SSLSocketFactory sf = sslContext.getSocketFactory(); + SSLSocket s = (SSLSocket) (sf.createSocket( + socket, remoteAddress.getHostName(), socket.getPort(), true)); + + // we are a server + s.setUseClientMode(false); + + // select protocols and cipher suites + s.setEnabledProtocols(s.getSupportedProtocols()); + s.setEnabledCipherSuites(s.getSupportedCipherSuites()); + return s; + } + }; + } catch (KeyStoreException | IOException | NoSuchAlgorithmException | UnrecoverableKeyException | KeyManagementException | CertificateException e) { + throw new RuntimeException(e); + } + + smtpServer.setHostName(HOST); + smtpServer.setPort(Integer.parseInt(PORT_SSL)); + smtpServer.setEnableTLS(true); + smtpServer.start(); + + log.info("Started mail server (" + smtpServer.getHostName() + ":" + smtpServer.getPort() + ")"); + } + + public static Map getServerConfiguration() { + serverConfiguration.put("from", FROM); + serverConfiguration.put("host", HOST); + serverConfiguration.put("port", PORT_SSL); + serverConfiguration.put("starttls", STARTTLS); + return serverConfiguration; + } + + public static MimeMessage getLastReceivedMessage() throws InterruptedException { + return messageHandlerFactory.getMessage(); + } +} \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/META-INF/keycloak-server.json b/testsuite/integration-arquillian/tests/base/src/test/resources/META-INF/keycloak-server.json index 9208927bc5..a356e6fe58 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/META-INF/keycloak-server.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/META-INF/keycloak-server.json @@ -117,10 +117,10 @@ "truststore": { "file": { - "file": "${keycloak.truststore.file:src/main/keystore/keycloak.truststore}", + "file": "${keycloak.truststore.file:src/test/resources/keystore/keycloak.truststore}", "password": "${keycloak.truststore.password:secret}", "hostname-verification-policy": "${keycloak.truststore.policy:WILDCARD}", - "disabled": "${keycloak.truststore.disabled:true}" + "disabled": "${keycloak.truststore.disabled:false}" } } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/keystore/email_invalid.jks b/testsuite/integration-arquillian/tests/base/src/test/resources/keystore/email_invalid.jks new file mode 100644 index 0000000000000000000000000000000000000000..e940f190cf2519f2357398d9b70699a9332228ab GIT binary patch literal 2179 zcmcgt`8U*!8lT;seGP-?T1wx+Ob8+S{$h;m#=eYc7+Z)YMj>R2n!J|c#iiaXL(wP_ z4PCD6vQ=JT$Qs7W)qCze=brlq+#f#YJfF|=%kzBBb3V@z>xcycfgmRU{{=AWq;hT< zjBo{k;81`9I|fc6xYZC~7+4h|2nNGJFbZrXBSN~gXIyGx*Yf8DWf z>ZXIL{*F79Y1gQ#9m`%Cs1}PIBh}T-2uTqR+!~FsbnZMfc5jv?U_~CM|fEbs*8=IAsiRb?(UkCWFif zY#ku18z!Rf_}YzgRNwe*-H;V4$|&@g$%l?NJDWPudXV&DW<||lvJHgy_KVtp;WaU4 z+4k(7b7B@?GiynvwM>*RCj~o!&DwLa<9+=1XfkddumR*ttnLzqDu8_S_t59B1L(h- zXYcyupv-tmg;?wcueB8CdG*8vBP|{5(wGaq1ncOlcf?2Q{b5q^^8O1|Bx=oIgm!uK z%d|-!@|o0#j*uqdI5qH`BLq#ks2s*cXdPf4GRqNY#taB9p5cuVC^IU7++Xr`8(ts*^m zi*S8dW7_2P)6e#YVjnd`9}<`KCGH2CIdxa%G)7yCBT3DRkKucN*bRD`h2FUI)Ded{ zQdch8l&)9zOg+AIrolp!EC&kV=%K{C-mA5eBDq2rI4GljHxgzMix;1irGC>|iw~EB zE33{({V8+0CACwaF1y()T=& zzxXl0F#2|`L!^Qmx(lke-38vantOodix+W}bz4bwT6RD784$!xFISG3SxC4wC@r3S zv5-HC@N}fSR)LHws#u<{7rp-Z5uK~NYp{J`ZpFw^QqU=GliAr*c#B3I;+#MD`b(Pa zyHkZ8@7?R_W?x9oAcM>j4>TMpjzX+$ceMIg{R0$qJ&7zOF}om5saQLH#7B zeCW=@_0K?(+#hD&-x6u4R8Q&UMu}}%>k`;iPP9Yx?k79%?W_IVu1zlPFCFaLB?9gF z0~mU1@QuReK>jvZ(qxa|DBOV}Rd-3h_H4m-v|V&=q2C^9L;?W%@J?STgAN&p(V4=v z(#S<(dSiZFxh-VhOt8=MHpkDkkL^d4%K*y0@cwoL+VGqok2F%QdD+JBcT&pnYgcy*^vm z5)*BFy7H)zb3nh6N#nWqc7xbM;5^%&br6zp6joZ z@1vLO;uTNZWtg0ks~%!YURaXJtr(w`nJ_-3?fXsnSmz2U8sAd}UP9%}7naT?%j z12#m%C9kS)x1E~L$=OeD371mih`H3$?Ul1T_I#{M?;Q!SU*;#^8NYlB;P(a zN*at9Hfp`>>gbqAIbkXgsZxJD&!{#~@HJ=zq`S#33-K z=UwCvwyd_$)T>Gf$@eFptfZDv=t)5zNg1c8RoD}FOjTyb^+ zcy%yyeWU^0f97yzGW8$t@kJ?E5s&w9XCdJ+<9qk#EkTX(?Xr-5&XQgcNcy%pyLIZ< ztxKB}F~g#Ayw9!0ht&klB8-}LXX0LGMhN|0x?u6*v`HK(7f)=GhT)=@0!0*A9v7yQ z66)$b!nBe%P~Gy<&n$bnI!ywu-)RpTQ2rB+=PcxL$XjEfQB3kX_K{*2dpR77_!eum zmX}r~!6jn(f&5wE8pCKJ|3Q(ew#%C*z|I_hW#QA$Q?^yFx8SWuj?|#V#+u78@sJr; TjH~2)_Ti#y34ycYi390hwerCQ literal 0 HcmV?d00001 diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/keystore/keycloak.jks b/testsuite/integration-arquillian/tests/base/src/test/resources/keystore/keycloak.jks new file mode 100644 index 0000000000000000000000000000000000000000..81570ab52922e70c047bf56442ccce582af55539 GIT binary patch literal 2233 zcmcgt`8(7L7oYE#jHMaI2&Kq!%ZzQTS;`(`OR}WFwPeXUN*YU2GuKE$t{A1P$x>t) zJ0U}gVQiVJ?E5}OE+Ss{KJR_r`xm@Foaa2Bb3Q+u=X1{UIr}U7DFvr!R?Q~ z?&g03AAI|;V(s_A9}fZ@0bz)cJq(VOqMcdl=AA29 znPJu}^_f1kNDY?gG+0WsamWy5&em}uPzeb}bQpfzVN7WG?)Q4Ce>D`M0qVBs1Izj3yYo{4iZ{k+ ze3S`AU6&YaUn~8d!LAiitH0CyXwVO#=6e1%hw|DTsX|qwWb~z>*oh+Q>lT80QJ$Q; z%5;r!b8>z5RG6k_Z+XO?GQsy_2)V4R#of5A&!fpcT*Gm!V`SS5O|)Oc^0`Lb`7Ez4 z`Sx*Bhr!9S1E2HR{JjcI^)PB$F9lWMNE?G}e3B>#;cxwUupszl$C~il7YbTrF}wWz z{-nZz*)u7cT-r@!Ef655tDS$zYLI8M-E?7TR7=7oC>XA+9#jg+2 z@{apwP3x(*f0s(*gW~Ih)@+frD^M3p*T-ZQV<^V7AcSlt*R#4P#QB^=3MxfY+USqrnWrSTB#981sqle!Hx}zb2isk-B zkKc*Md9}J*FHQ_MB4e_{J z zn*)6#OuoVGV#(NJeM9#VPb=jNV%<N+=JTL7LTVZ*idY+o?Gi$J?2h@6u=!b$(Hn;NrY~&2Pk=k&=d`d(mz&d`W(&cX1r z_ow%?Z`~%)*@7Z37~ZRqiR_ph|YHWba3h3jF-- zP5IqS%_}GuC#d+uj0e*Mlqo20Z>UyP^%n5dvAFk18SLIP5U@+w3?p7QI#>tH)W64`E0N_0|OfMx~3^yl-9fT7JwzK&Ma3R5# z`br24-(MXllIyBx@NEMAmWLAmp}QWIc#zO5o*t*MZnys-@glj*J;Sd1&n-|5>?2Uw+@<0h|vg~vfRR4f%xy!9L)N?jSx(S^L7XI$>l%&1TD zc>}pPuoN_aTROIOJ+|zfQ~XeNNi^2?7aSnXfwB{*dJsHmEL&*N-MFODlH+f@1?B)i zK&}Kv9CPY$ho|5WA&B7ROhi~JN*foOR8N&{De;i3)9U=Uh=+G{C?WvjNc^Ew9y-1M z;-z3U!Ky%Z)#{mp2=xItK{K;Vdl(gHf0P<1Y8=QaqOqfAl*3e!u;iZ zqn+r({M{6uUi$JxNakbH$&keRjb@c+ReA+R`Ro(>U+}bS6l2ajd-NwcM!MkMHlk@H8W4_LHnT8m&Fogw@|!Tij3-^a(24 zxS>4i;cs@HcH8_*%IE9ah3cCew{CaLFt^eX*I#(vlzYZ~#}B!TZPKMP5B0A8S79P0 zYrOhInU0UA*R##KSyv|aPRzPi@8jH1Uc5u^_%-Vft$&(iLtlN&IB=xKB_y`(W9Xub zjGBj^E2i(#=aHJeBk-#5xywcFGn5P%)o!M~s`~vzYUaoMPeFBpU#))>D;(~exz3P7 z`!C0{`zzP|OMe-((NeALrS`Pzb5_OQ;w?6M@lyQC4vmk}a;7`C&tJLjq4O2qKW)*6 zXIc6@7B!2FXJTe#U|g(dAa5WGj6zvH7BLo)FUuHABUY@FT*999?~z={<7W-mB#;9U zn2Lab$jIPcmbaJLw7lu;(A@;P(=-?N{B zKh9n4n;4ug%(47H=^2ZE5@`%Kr7Wt?-mUZsaa|W)@V{)5&FSsS?_61}5o=ZUd^2X`h;i+|kZX3@n30%2Qu2X-{lW8kT_B{!n9GZAOX>+hL=hl7g zDXVmLAKB3K;ppUbS1sMywK?bW9P->E=+Mn+W_rEiZxxfmPmdq-T#S4^_D<7TQ2%`X z-5<-(y5CxRHkF0(@XvX7`u0>Tyq)j#-ey61qG0t;sV4QsZ679V@zhM+@a0IPgiNf@ z%s`2`3)ee_Zn^Sd!|4a^%i{RD**_cm>S=QCW@ebaYaa9yiMmTDBE3bSUY(6+|nM{e3Hea`KDZEj@x%^88TqL zVC6JT>!{9&ySHc`T$iG>%jz^*Is#`%=Kf!Hn<}3Cn=@Brd%6D#?RWk&BP6yoGWA)` z-)MbHGcSy1OP;h_-iK93KD9nIsx%SiogA(ZTv5j`XHS(&_uDgHi~cmLOx^VE`k8yS zf%aXot3N1eMn`LXN-_L#WB(ZwjbrHtnjdr<*|2SB+OW;`Jg@wLdr!O8NYyqg-kbPZ z;;7Ke8Cw{|W8YpYnjiciZ&Re|xy@b&T&^E^UMIM(e7Cf0P4lP67X;OPnl9-xZO6Ih7^bG<^O+sfvUc1({JQodpT)7J%o~$D z`DSmJD^)tb$MaEXf5Tp{t?I@Xh3@f(^ + + org.subethamail + subethasmtp + + + org.slf4j + slf4j-api + + +