Repository: activemq-artemis Updated Branches: refs/heads/master b2663b84b -> bf073f19a
ARTEMIS-2010 actively detect unauthenticated LDAP Bind requests Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/53f8bc3d Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/53f8bc3d Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/53f8bc3d Branch: refs/heads/master Commit: 53f8bc3daff9da95aba406c72e706177c28a9012 Parents: b2663b8 Author: Justin Bertram <jbert...@apache.org> Authored: Fri Aug 3 16:39:09 2018 -0500 Committer: Clebert Suconic <clebertsuco...@apache.org> Committed: Thu Aug 9 19:40:30 2018 -0400 ---------------------------------------------------------------------- .../spi/core/security/jaas/LDAPLoginModule.java | 15 ++++-- .../core/security/jaas/LDAPLoginModuleTest.java | 51 ++++++++++++++++++++ 2 files changed, 63 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/53f8bc3d/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/jaas/LDAPLoginModule.java ---------------------------------------------------------------------- diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/jaas/LDAPLoginModule.java b/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/jaas/LDAPLoginModule.java index 7d58a0b..1470040 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/jaas/LDAPLoginModule.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/jaas/LDAPLoginModule.java @@ -167,7 +167,7 @@ public class LDAPLoginModule implements LoginModule { throw (LoginException) new LoginException().initCause(e); } - String password; + String password = null; username = ((NameCallback) callbacks[0]).getName(); if (username == null) @@ -175,8 +175,17 @@ public class LDAPLoginModule implements LoginModule { if (((PasswordCallback) callbacks[1]).getPassword() != null) password = new String(((PasswordCallback) callbacks[1]).getPassword()); - else - password = ""; + + /** + * https://tools.ietf.org/html/rfc4513#section-6.3.1 + * + * Clients that use the results from a simple Bind operation to make + * authorization decisions should actively detect unauthenticated Bind + * requests (by verifying that the supplied password is not empty) and + * react appropriately. + */ + if (password == null || (password != null && password.length() == 0)) + throw new FailedLoginException("Password cannot be null or empty"); // authenticate will throw LoginException // in case of failed authentication http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/53f8bc3d/artemis-server/src/test/java/org/apache/activemq/artemis/core/security/jaas/LDAPLoginModuleTest.java ---------------------------------------------------------------------- diff --git a/artemis-server/src/test/java/org/apache/activemq/artemis/core/security/jaas/LDAPLoginModuleTest.java b/artemis-server/src/test/java/org/apache/activemq/artemis/core/security/jaas/LDAPLoginModuleTest.java index 47bedd9..b52a717 100644 --- a/artemis-server/src/test/java/org/apache/activemq/artemis/core/security/jaas/LDAPLoginModuleTest.java +++ b/artemis-server/src/test/java/org/apache/activemq/artemis/core/security/jaas/LDAPLoginModuleTest.java @@ -27,6 +27,7 @@ import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.NameCallback; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.callback.UnsupportedCallbackException; +import javax.security.auth.login.FailedLoginException; import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; import javax.security.auth.spi.LoginModule; @@ -268,6 +269,56 @@ public class LDAPLoginModuleTest extends AbstractLdapTestUnit { } } + @Test + public void testEmptyPassword() throws Exception { + LoginContext context = new LoginContext("LDAPLogin", new CallbackHandler() { + @Override + public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { + for (int i = 0; i < callbacks.length; i++) { + if (callbacks[i] instanceof NameCallback) { + ((NameCallback) callbacks[i]).setName("first"); + } else if (callbacks[i] instanceof PasswordCallback) { + ((PasswordCallback) callbacks[i]).setPassword("".toCharArray()); + } else { + throw new UnsupportedCallbackException(callbacks[i]); + } + } + } + }); + try { + context.login(); + fail("Should have thrown a FailedLoginException"); + } catch (FailedLoginException fle) { + assertEquals("Password cannot be null or empty", fle.getMessage()); + } + context.logout(); + } + + @Test + public void testNullPassword() throws Exception { + LoginContext context = new LoginContext("LDAPLogin", new CallbackHandler() { + @Override + public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { + for (int i = 0; i < callbacks.length; i++) { + if (callbacks[i] instanceof NameCallback) { + ((NameCallback) callbacks[i]).setName("first"); + } else if (callbacks[i] instanceof PasswordCallback) { + ((PasswordCallback) callbacks[i]).setPassword(null); + } else { + throw new UnsupportedCallbackException(callbacks[i]); + } + } + } + }); + try { + context.login(); + fail("Should have thrown a FailedLoginException"); + } catch (FailedLoginException fle) { + assertEquals("Password cannot be null or empty", fle.getMessage()); + } + context.logout(); + } + private boolean presentInArray(LDAPLoginProperty[] ldapProps, String propertyName) { for (LDAPLoginProperty conf : ldapProps) { if (conf.getPropertyName().equals(propertyName) && (conf.getPropertyValue() != null && !"".equals(conf.getPropertyValue())))