--- activemq-5.6.0/activemq-jaas/src/main/java/org/apache/activemq/jaas/LDAPLoginModule.java 2012-09-11 01:12:25.000000000 +0200
+++ activemq-5.6.0/activemq-jaas/src/main/java/org/apache/activemq/jaas/LDAPLoginModule.java.CVE-2015-6524 2015-01-15 08:57:10.000000000 +0100
@@ -17,22 +17,13 @@
package org.apache.activemq.jaas;
import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.security.Principal;
import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.naming.AuthenticationException;
-import javax.naming.CommunicationException;
-import javax.naming.Context;
-import javax.naming.Name;
-import javax.naming.NameParser;
-import javax.naming.NamingEnumeration;
-import javax.naming.NamingException;
+import java.util.*;
+
+import javax.naming.*;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
@@ -71,6 +62,8 @@
private static final String ROLE_SEARCH_MATCHING = "roleSearchMatching";
private static final String ROLE_SEARCH_SUBTREE = "roleSearchSubtree";
private static final String USER_ROLE_NAME = "userRoleName";
+ private static final String EXPAND_ROLES = "expandRoles";
+ private static final String EXPAND_ROLES_MATCHING = "expandRolesMatching";
private static Logger log = LoggerFactory.getLogger(LDAPLoginModule.class);
@@ -102,7 +95,10 @@
new LDAPLoginProperty (ROLE_SEARCH_MATCHING, (String)options.get(ROLE_SEARCH_MATCHING)),
new LDAPLoginProperty (ROLE_SEARCH_SUBTREE, (String)options.get(ROLE_SEARCH_SUBTREE)),
new LDAPLoginProperty (USER_ROLE_NAME, (String)options.get(USER_ROLE_NAME)),
- };
+ new LDAPLoginProperty (EXPAND_ROLES, (String) options.get(EXPAND_ROLES)),
+ new LDAPLoginProperty (EXPAND_ROLES_MATCHING, (String) options.get(EXPAND_ROLES_MATCHING)),
+
+ };
}
@Override
@@ -194,7 +190,7 @@
try {
String filter = userSearchMatchingFormat.format(new String[] {
- username
+ doRFC2254Encoding(username)
});
SearchControls constraints = new SearchControls();
if (userSearchSubtreeBool) {
@@ -231,13 +227,43 @@
if (results.hasMore()) {
// ignore for now
}
- NameParser parser = context.getNameParser("");
- Name contextName = parser.parse(context.getNameInNamespace());
- Name baseName = parser.parse(getLDAPPropertyValue(USER_BASE));
- Name entryName = parser.parse(result.getName());
- Name name = contextName.addAll(baseName);
- name = name.addAll(entryName);
- String dn = name.toString();
+
+ String dn;
+ if (result.isRelative()) {
+ log.debug("LDAP returned a relative name: {}", result.getName());
+
+ NameParser parser = context.getNameParser("");
+ Name contextName = parser.parse(context.getNameInNamespace());
+ Name baseName = parser.parse(getLDAPPropertyValue(USER_BASE));
+ Name entryName = parser.parse(result.getName());
+ Name name = contextName.addAll(baseName);
+ name = name.addAll(entryName);
+ dn = name.toString();
+ } else {
+ log.debug("LDAP returned an absolute name: {}", result.getName());
+
+ try {
+ URI uri = new URI(result.getName());
+ String path = uri.getPath();
+
+ if (path.startsWith("/")) {
+ dn = path.substring(1);
+ } else {
+ dn = path;
+ }
+ } catch (URISyntaxException e) {
+ if (context != null) {
+ close(context);
+ }
+ FailedLoginException ex = new FailedLoginException("Error parsing absolute name as URI.");
+ ex.initCause(e);
+ throw ex;
+ }
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug("Using DN [" + dn + "] for binding.");
+ }
Attributes attrs = result.getAttributes();
if (attrs == null) {
@@ -281,8 +307,10 @@
List<String> list = currentRoles;
MessageFormat roleSearchMatchingFormat;
boolean roleSearchSubtreeBool;
+ boolean expandRolesBool;
roleSearchMatchingFormat = new MessageFormat(getLDAPPropertyValue(ROLE_SEARCH_MATCHING));
roleSearchSubtreeBool = Boolean.valueOf(getLDAPPropertyValue(ROLE_SEARCH_SUBTREE)).booleanValue();
+ expandRolesBool = Boolean.valueOf(getLDAPPropertyValue(EXPAND_ROLES)).booleanValue();
if (list == null) {
list = new ArrayList<String>();
@@ -291,7 +319,7 @@
return list;
}
String filter = roleSearchMatchingFormat.format(new String[] {
- doRFC2254Encoding(dn), username
+ doRFC2254Encoding(dn), doRFC2254Encoding(username)
});
SearchControls constraints = new SearchControls();
@@ -306,17 +334,40 @@
log.debug(" base DN: " + getLDAPPropertyValue(ROLE_BASE));
log.debug(" filter: " + filter);
}
+ HashSet<String> haveSeenNames = new HashSet<String>();
+ Queue<String> pendingNameExpansion = new LinkedList<String>();
NamingEnumeration<SearchResult> results = context.search(getLDAPPropertyValue(ROLE_BASE), filter, constraints);
while (results.hasMore()) {
SearchResult result = results.next();
Attributes attrs = result.getAttributes();
+ if (expandRolesBool) {
+ haveSeenNames.add(result.getNameInNamespace());
+ pendingNameExpansion.add(result.getNameInNamespace());
+ }
if (attrs == null) {
continue;
}
list = addAttributeValues(getLDAPPropertyValue(ROLE_NAME), attrs, list);
}
+ if (expandRolesBool) {
+ MessageFormat expandRolesMatchingFormat = new MessageFormat(getLDAPPropertyValue(EXPAND_ROLES_MATCHING));
+ while (!pendingNameExpansion.isEmpty()) {
+ String name = pendingNameExpansion.remove();
+ filter = expandRolesMatchingFormat.format(new String[]{name});
+ results = context.search(getLDAPPropertyValue(ROLE_BASE), filter, constraints);
+ while (results.hasMore()) {
+ SearchResult result = results.next();
+ name = result.getNameInNamespace();
+ if (!haveSeenNames.contains(name)) {
+ Attributes attrs = result.getAttributes();
+ list = addAttributeValues(getLDAPPropertyValue(ROLE_NAME), attrs, list);
+ haveSeenNames.add(name);
+ pendingNameExpansion.add(name);
+ }
+ }
+ }
+ }
return list;
-
}
protected String doRFC2254Encoding(String inputString) {
@@ -408,9 +459,14 @@
env.put(Context.INITIAL_CONTEXT_FACTORY, getLDAPPropertyValue(INITIAL_CONTEXT_FACTORY));
if (isLoginPropertySet(CONNECTION_USERNAME)) {
env.put(Context.SECURITY_PRINCIPAL, getLDAPPropertyValue(CONNECTION_USERNAME));
+ } else {
+ throw new NamingException("Empty username is not allowed");
}
+
if (isLoginPropertySet(CONNECTION_PASSWORD)) {
env.put(Context.SECURITY_CREDENTIALS, getLDAPPropertyValue(CONNECTION_PASSWORD));
+ } else {
+ throw new NamingException("Empty password is not allowed");
}
env.put(Context.SECURITY_PROTOCOL, getLDAPPropertyValue(CONNECTION_PROTOCOL));
env.put(Context.PROVIDER_URL, getLDAPPropertyValue(CONNECTION_URL));
@@ -433,7 +489,7 @@
private boolean isLoginPropertySet(String propertyName) {
for (int i=0; i < config.length; i++ ) {
- if (config[i].getPropertyName() == propertyName && config[i].getPropertyValue() != null)
+ if (config[i].getPropertyName() == propertyName && (config[i].getPropertyValue() != null && !"".equals(config[i].getPropertyValue())))
return true;
}
return false;