From 5c8bd44a7fe27d85b5e8cab381c45a0e3909fa57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ira=20=28=E3=83=84=29?= <45-lambdaclan@users.noreply.gitlab.archlinux.org> Date: Thu, 4 Feb 2021 16:17:26 +0900 Subject: [PATCH] Add password validation prior to hash generation --- .../mailpass/rest/MailPassResource.java | 31 ++++++++++++++++--- .../mailpass/rest/MailPassRestResource.java | 10 +++++- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/roles/keycloak/files/providers/keycloak-mailpass-rest/src/main/java/org/archlinux/keycloak/mailpass/rest/MailPassResource.java b/roles/keycloak/files/providers/keycloak-mailpass-rest/src/main/java/org/archlinux/keycloak/mailpass/rest/MailPassResource.java index edd3e6b33..5ad552a3d 100644 --- a/roles/keycloak/files/providers/keycloak-mailpass-rest/src/main/java/org/archlinux/keycloak/mailpass/rest/MailPassResource.java +++ b/roles/keycloak/files/providers/keycloak-mailpass-rest/src/main/java/org/archlinux/keycloak/mailpass/rest/MailPassResource.java @@ -13,17 +13,21 @@ import javax.ws.rs.core.Response; import org.bouncycastle.crypto.generators.OpenBSDBCrypt; import org.jboss.resteasy.annotations.cache.NoCache; import org.keycloak.models.KeycloakSession; +import org.keycloak.policy.PasswordPolicyManagerProvider; +import org.keycloak.policy.PolicyError; /** - * A custom REST endpoint to trigger functionality on the Keycloak server, which is not available - * through the default set of built-in Keycloak REST endpoints. This is to be used during the - * storage of a custom attribute on the Account Management Console for the mail password. The data - * stored will be a Bcrypt hash instead of the plain text password. + * A custom REST endpoint to trigger functionality on the Keycloak server, which + * is not available through the default set of built-in Keycloak REST endpoints. + * This is to be used during the storage of a custom attribute on the Account + * Management Console for the mail password. The data stored will be a Bcrypt + * hash instead of the plain text password. */ public class MailPassResource { @SuppressWarnings("unused") private final KeycloakSession session; + private final String userName; private static final int SALT_LENGTH = 16; private static final int COST = 12; @@ -37,8 +41,21 @@ public class MailPassResource { return salt; } - public MailPassResource(KeycloakSession session) { + private boolean validatePassword(String pass) { + PasswordPolicyManagerProvider policy = session.getProvider(PasswordPolicyManagerProvider.class); + + PolicyError error = policy.validate(this.userName, pass); + + if (error != null) { + return false; + } + + return true; + } + + public MailPassResource(KeycloakSession session, String userName) { this.session = session; + this.userName = userName; } /** @@ -64,6 +81,10 @@ public class MailPassResource { throw new BadRequestException("password object not detected in provided JSON body"); } + if (!validatePassword(password)) { + throw new BadRequestException("password policy error(length(8) and notUsername)"); + } + byte[] salt = generateSalt(); String hash = OpenBSDBCrypt.generate(VARIANT, password.toCharArray(), salt, COST); diff --git a/roles/keycloak/files/providers/keycloak-mailpass-rest/src/main/java/org/archlinux/keycloak/mailpass/rest/MailPassRestResource.java b/roles/keycloak/files/providers/keycloak-mailpass-rest/src/main/java/org/archlinux/keycloak/mailpass/rest/MailPassRestResource.java index c3d856eff..daf788737 100644 --- a/roles/keycloak/files/providers/keycloak-mailpass-rest/src/main/java/org/archlinux/keycloak/mailpass/rest/MailPassRestResource.java +++ b/roles/keycloak/files/providers/keycloak-mailpass-rest/src/main/java/org/archlinux/keycloak/mailpass/rest/MailPassRestResource.java @@ -18,6 +18,7 @@ public class MailPassRestResource { private final KeycloakSession session; private final String realmName; private final String realmRole; + private final String userName; private final AuthenticationManager.AuthResult auth; /** @@ -30,6 +31,13 @@ public class MailPassRestResource { public MailPassRestResource(KeycloakSession session, String realmName, String realmRole) { this.session = session; this.auth = new AppAuthManager.BearerTokenAuthenticator(session).authenticate(); + + if (auth != null) { + this.userName = this.auth.getUser().getUsername(); + } else { + this.userName = ""; + } + this.realmName = realmName; this.realmRole = realmRole; } @@ -43,7 +51,7 @@ public class MailPassRestResource { public MailPassResource getMailPassResourceAuthenticated() { checkRealm(); checkRealmAdmin(); - return new MailPassResource(session); + return new MailPassResource(session, userName); } private void checkRealm() { -- GitLab