KEYCLOAK-13285 Enable check identity for email

This commit is contained in:
stianst 2020-03-11 09:48:08 +01:00 committed by Stian Thorgersen
parent d3a4bef9a4
commit 97b5654690
2 changed files with 62 additions and 1 deletions

View file

@ -35,6 +35,7 @@ import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMultipart;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import java.io.UnsupportedEncodingException;
import java.security.KeyManagementException;
@ -48,6 +49,8 @@ import java.util.Properties;
*/
public class DefaultEmailSenderProvider implements EmailSenderProvider {
private static final String SUPPORTED_SSL_PROTOCOLS = getSupportedSslProtocols();
private static final Logger logger = Logger.getLogger(DefaultEmailSenderProvider.class);
private final KeycloakSession session;
@ -89,6 +92,8 @@ public class DefaultEmailSenderProvider implements EmailSenderProvider {
}
if (ssl || starttls) {
props.put("mail.smtp.ssl.protocols", SUPPORTED_SSL_PROTOCOLS);
setupTruststore(props);
}
@ -171,7 +176,8 @@ public class DefaultEmailSenderProvider implements EmailSenderProvider {
return user.getEmail();
}
private void setupTruststore(Properties props) throws NoSuchAlgorithmException, KeyManagementException {
private void setupTruststore(Properties props) {
boolean checkServerIdentity = true;
JSSETruststoreConfigurator configurator = new JSSETruststoreConfigurator(session);
@ -180,12 +186,30 @@ public class DefaultEmailSenderProvider implements EmailSenderProvider {
props.put("mail.smtp.ssl.socketFactory", factory);
if (configurator.getProvider().getPolicy() == HostnameVerificationPolicy.ANY) {
props.setProperty("mail.smtp.ssl.trust", "*");
checkServerIdentity = false;
}
}
if (checkServerIdentity) {
props.put("mail.smtp.ssl.checkserveridentity", "true");
}
}
@Override
public void close() {
}
private static String getSupportedSslProtocols() {
try {
String[] protocols = SSLContext.getDefault().getSupportedSSLParameters().getProtocols();
if (protocols != null) {
return String.join(" ", protocols);
}
} catch (Exception e) {
logger.warn("Failed to get list of supported SSL protocols", e);
}
return null;
}
}

View file

@ -40,6 +40,9 @@ import org.keycloak.testsuite.util.SslMailServer;
import static org.junit.Assert.assertEquals;
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer;
import java.util.Map;
import static org.keycloak.testsuite.util.MailAssert.assertEmailAndGetUrl;
import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith;
@ -164,4 +167,38 @@ public class TrustStoreEmailTest extends AbstractTestRealmKeycloakTest {
assertEquals("You need to verify your email address to activate your account.",
testRealmVerifyEmailPage.feedbackMessage().getText());
}
@Test
public void verifyEmailWithSslWrongHostname() throws Exception {
UserRepresentation user = ApiUtil.findUserByUsername(testRealm(), "test-user@localhost");
RealmRepresentation realmRep = testRealm().toRepresentation();
realmRep.getSmtpServer().put("host", "localhost.localdomain");
testRealm().update(realmRep);
try {
SslMailServer.startWithSsl(this.getClass().getClassLoader().getResource(SslMailServer.PRIVATE_KEY).getFile());
accountManagement.navigateTo();
loginPage.form().login(user.getUsername(), "password");
events.expectRequiredAction(EventType.SEND_VERIFY_EMAIL_ERROR)
.error(Errors.EMAIL_SEND_FAILED)
.user(user.getId())
.client("account")
.detail(Details.USERNAME, "test-user@localhost")
.detail(Details.EMAIL, "test-user@localhost")
.removeDetail(Details.REDIRECT_URI)
.assertEvent();
// Email wasn't send
Assert.assertNull(SslMailServer.getLastReceivedMessage());
// Email wasn't send, but we won't notify end user about that. Admin is aware due to the error in the logs and the SEND_VERIFY_EMAIL_ERROR event.
assertEquals("You need to verify your email address to activate your account.",
testRealmVerifyEmailPage.feedbackMessage().getText());
} finally {
realmRep.getSmtpServer().put("host", "localhost");
testRealm().update(realmRep);
}
}
}