From: James Moger Date: Wed, 25 Apr 2012 20:35:40 +0000 (-0400) Subject: Merge jcrygier's LDAP injection defense and displayname/email retrieval X-Git-Tag: v1.0.0~67 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=d2426e1eb5d07664b5c26c4247fae3325282d60d;p=gitblit.git Merge jcrygier's LDAP injection defense and displayname/email retrieval Add LDAP logic to retrieve display name & email address Add code / test to defend against LDAP injection attacks. --- d2426e1eb5d07664b5c26c4247fae3325282d60d diff --cc src/com/gitblit/LdapUserService.java index ec84c956,674e2a0d..80a966dd --- a/src/com/gitblit/LdapUserService.java +++ b/src/com/gitblit/LdapUserService.java @@@ -135,9 -135,9 +135,9 @@@ public class LdapUserService extends Gi LDAPConnection ldapConnection = getLdapConnection(); if (ldapConnection != null) { // Find the logging in user's DN - String accountBase = settings.getString(Keys.realm.ldap_accountBase, ""); - String accountPattern = settings.getString(Keys.realm.ldap_accountPattern, "(&(objectClass=person)(sAMAccountName=${username}))"); + String accountBase = settings.getString(Keys.realm.ldap.accountBase, ""); + String accountPattern = settings.getString(Keys.realm.ldap.accountPattern, "(&(objectClass=person)(sAMAccountName=${username}))"); - accountPattern = StringUtils.replace(accountPattern, "${username}", simpleUsername); + accountPattern = StringUtils.replace(accountPattern, "${username}", escapeLDAPSearchFilter(simpleUsername)); SearchResult result = doSearch(ldapConnection, accountBase, accountPattern); if (result != null && result.getEntryCount() == 1) { @@@ -186,16 -186,47 +186,47 @@@ user.canAdmin = true; } } + + private void setUserAttributes(UserModel user, SearchResultEntry userEntry) { + // Is this user an admin? + setAdminAttribute(user); + + // Don't want visibility into the real password, make up a dummy + user.password = "StoredInLDAP"; + + // Get Attributes for full name / email - String displayName = settings.getString(Keys.realm.ldap_displayName, "displayName"); - String email = settings.getString(Keys.realm.ldap_email, "email"); ++ String displayName = settings.getString(Keys.realm.ldap.displayName, "displayName"); ++ String email = settings.getString(Keys.realm.ldap.email, "email"); + + // Replace embedded ${} with attributes + if (displayName.contains("${")) { + for (Attribute userAttribute : userEntry.getAttributes()) + displayName = StringUtils.replace(displayName, "${" + userAttribute.getName() + "}", userAttribute.getValue()); + + user.displayName = displayName; + } else { + user.displayName = userEntry.getAttribute(displayName).getValue(); + } + + if (email.contains("${")) { + for (Attribute userAttribute : userEntry.getAttributes()) + email = StringUtils.replace(email, "${" + userAttribute.getName() + "}", userAttribute.getValue()); + + user.emailAddress = email; + } else { + user.emailAddress = userEntry.getAttribute(email).getValue(); + } + } private void getTeamsFromLdap(LDAPConnection ldapConnection, String simpleUsername, SearchResultEntry loggingInUser, UserModel user) { String loggingInUserDN = loggingInUser.getDN(); user.teams.clear(); // Clear the users team memberships - we're going to get them from LDAP - String groupBase = settings.getString(Keys.realm.ldap_groupBase, ""); - String groupMemberPattern = settings.getString(Keys.realm.ldap_groupMemberPattern, "(&(objectClass=group)(member=${dn}))"); + String groupBase = settings.getString(Keys.realm.ldap.groupBase, ""); + String groupMemberPattern = settings.getString(Keys.realm.ldap.groupMemberPattern, "(&(objectClass=group)(member=${dn}))"); - groupMemberPattern = StringUtils.replace(groupMemberPattern, "${dn}", loggingInUserDN); - groupMemberPattern = StringUtils.replace(groupMemberPattern, "${username}", simpleUsername); + groupMemberPattern = StringUtils.replace(groupMemberPattern, "${dn}", escapeLDAPSearchFilter(loggingInUserDN)); + groupMemberPattern = StringUtils.replace(groupMemberPattern, "${username}", escapeLDAPSearchFilter(simpleUsername)); // Fill in attributes into groupMemberPattern for (Attribute userAttribute : loggingInUser.getAttributes()) diff --cc src/com/gitblit/models/UserModel.java index ecb97cfc,925edf91..b0e57fd2 --- a/src/com/gitblit/models/UserModel.java +++ b/src/com/gitblit/models/UserModel.java @@@ -112,6 -114,6 +114,13 @@@ public class UserModel implements Princ public String getName() { return username; } ++ ++ public String getDisplayName() { ++ if (StringUtils.isEmpty(displayName)) { ++ return username; ++ } ++ return displayName; ++ } @Override public String toString() { diff --cc tests/com/gitblit/tests/LdapUserServiceTest.java index 48c97416,c7e95c36..390fa001 --- a/tests/com/gitblit/tests/LdapUserServiceTest.java +++ b/tests/com/gitblit/tests/LdapUserServiceTest.java @@@ -45,13 -47,11 +47,13 @@@ public class LdapUserServiceTest private LdapUserService ldapUserService; - int ldapPort = 1389; ++ static int ldapPort = 1389; + - @Before - public void createInMemoryLdapServer() throws Exception { + @BeforeClass + public static void createInMemoryLdapServer() throws Exception { InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig("dc=MyDomain"); config.addAdditionalBindCredentials("cn=Directory Manager", "password"); - config.setListenerConfigs(InMemoryListenerConfig.createLDAPConfig("default", 389)); + config.setListenerConfigs(InMemoryListenerConfig.createLDAPConfig("default", ldapPort)); config.setSchema(null); InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config); @@@ -61,8 -61,13 +63,13 @@@ @Before public void createLdapUserService() { + ldapUserService = new LdapUserService(); + ldapUserService.setup(getSettings()); + } + + private MemorySettings getSettings() { Map backingMap = new HashMap(); - backingMap.put("realm.ldap.server", "ldap://localhost:389"); + backingMap.put("realm.ldap.server", "ldap://localhost:" + ldapPort); backingMap.put("realm.ldap.domain", ""); backingMap.put("realm.ldap.username", "cn=Directory Manager"); backingMap.put("realm.ldap.password", "password");