From 4fcac9d2cbdafb51e3ee9ca3b3da64fd86103174 Mon Sep 17 00:00:00 2001 From: James Moger <james.moger@gitblit.com> Date: Tue, 26 Nov 2013 15:58:15 -0500 Subject: [PATCH] Remove artifact setting from manager dialog --- src/main/java/com/gitblit/LdapUserService.java | 167 +++++++++++++++++++++++++++++++++---------------------- 1 files changed, 100 insertions(+), 67 deletions(-) diff --git a/src/main/java/com/gitblit/LdapUserService.java b/src/main/java/com/gitblit/LdapUserService.java index 2867b88..888d13c 100644 --- a/src/main/java/com/gitblit/LdapUserService.java +++ b/src/main/java/com/gitblit/LdapUserService.java @@ -20,6 +20,7 @@ import java.net.URI; import java.net.URISyntaxException; import java.security.GeneralSecurityException; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -35,21 +36,24 @@ import com.gitblit.utils.ArrayUtils; import com.gitblit.utils.StringUtils; import com.unboundid.ldap.sdk.Attribute; +import com.unboundid.ldap.sdk.DereferencePolicy; import com.unboundid.ldap.sdk.ExtendedResult; import com.unboundid.ldap.sdk.LDAPConnection; import com.unboundid.ldap.sdk.LDAPException; import com.unboundid.ldap.sdk.LDAPSearchException; import com.unboundid.ldap.sdk.ResultCode; +import com.unboundid.ldap.sdk.SearchRequest; import com.unboundid.ldap.sdk.SearchResult; import com.unboundid.ldap.sdk.SearchResultEntry; import com.unboundid.ldap.sdk.SearchScope; +import com.unboundid.ldap.sdk.SimpleBindRequest; import com.unboundid.ldap.sdk.extensions.StartTLSExtendedRequest; import com.unboundid.util.ssl.SSLUtil; import com.unboundid.util.ssl.TrustAllTrustManager; /** * Implementation of an LDAP user service. - * + * * @author John Crygier */ public class LdapUserService extends GitblitUserService { @@ -58,7 +62,7 @@ private IStoredSettings settings; private AtomicLong lastLdapUserSync = new AtomicLong(0L); - + public LdapUserService() { super(); } @@ -74,19 +78,19 @@ throw new IllegalArgumentException(Keys.realm.ldap.ldapCachePeriod + " must have format '<long> <TimeUnit>' where <TimeUnit> is one of 'MILLISECONDS', 'SECONDS', 'MINUTES', 'HOURS', 'DAYS'"); } } - + @Override public void setup(IStoredSettings settings) { this.settings = settings; String file = settings.getString(Keys.realm.ldap.backingUserService, "${baseFolder}/users.conf"); File realmFile = GitBlit.getFileOrFolder(file); - + serviceImpl = createUserService(realmFile); logger.info("LDAP User Service backed by " + serviceImpl.toString()); - + synchronizeLdapUsers(); } - + protected synchronized void synchronizeLdapUsers() { final boolean enabled = settings.getBoolean(Keys.realm.ldap.synchronizeUsers.enable, false); if (enabled) { @@ -129,7 +133,7 @@ logger.debug("detecting removed LDAP users..."); for (UserModel userModel : super.getAllUsers()) { - if (ExternalAccount.equals(userModel.password)) { + if (Constants.EXTERNAL_ACCOUNT.equals(userModel.password)) { if (! ldapUsers.containsKey(userModel.username)) { logger.info("deleting removed LDAP user " + userModel.username + " from backing user service"); super.deleteUser(userModel.username); @@ -150,7 +154,7 @@ updateTeamModels(userTeams.values()); } } - lastLdapUserSync.set(System.currentTimeMillis()); + lastLdapUserSync.set(System.currentTimeMillis()); } finally { ldapConnection.close(); } @@ -158,38 +162,45 @@ } } } - + private LDAPConnection getLdapConnection() { try { + URI ldapUrl = new URI(settings.getRequiredString(Keys.realm.ldap.server)); + String ldapHost = ldapUrl.getHost(); + int ldapPort = ldapUrl.getPort(); String bindUserName = settings.getString(Keys.realm.ldap.username, ""); String bindPassword = settings.getString(Keys.realm.ldap.password, ""); - int ldapPort = ldapUrl.getPort(); + + LDAPConnection conn; if (ldapUrl.getScheme().equalsIgnoreCase("ldaps")) { // SSL - if (ldapPort == -1) // Default Port - ldapPort = 636; - - SSLUtil sslUtil = new SSLUtil(new TrustAllTrustManager()); - return new LDAPConnection(sslUtil.createSSLSocketFactory(), ldapUrl.getHost(), ldapPort, bindUserName, bindPassword); + SSLUtil sslUtil = new SSLUtil(new TrustAllTrustManager()); + conn = new LDAPConnection(sslUtil.createSSLSocketFactory()); + } else if (ldapUrl.getScheme().equalsIgnoreCase("ldap") || ldapUrl.getScheme().equalsIgnoreCase("ldap+tls")) { // no encryption or StartTLS + conn = new LDAPConnection(); } else { - if (ldapPort == -1) // Default Port - ldapPort = 389; - - LDAPConnection conn = new LDAPConnection(ldapUrl.getHost(), ldapPort, bindUserName, bindPassword); - - if (ldapUrl.getScheme().equalsIgnoreCase("ldap+tls")) { - SSLUtil sslUtil = new SSLUtil(new TrustAllTrustManager()); - - ExtendedResult extendedResult = conn.processExtendedOperation( - new StartTLSExtendedRequest(sslUtil.createSSLContext())); - - if (extendedResult.getResultCode() != ResultCode.SUCCESS) { - throw new LDAPException(extendedResult.getResultCode()); - } - } - return conn; + logger.error("Unsupported LDAP URL scheme: " + ldapUrl.getScheme()); + return null; } + + conn.connect(ldapHost, ldapPort); + + if (ldapUrl.getScheme().equalsIgnoreCase("ldap+tls")) { + SSLUtil sslUtil = new SSLUtil(new TrustAllTrustManager()); + ExtendedResult extendedResult = conn.processExtendedOperation( + new StartTLSExtendedRequest(sslUtil.createSSLContext())); + if (extendedResult.getResultCode() != ResultCode.SUCCESS) { + throw new LDAPException(extendedResult.getResultCode()); + } + } + + if ( ! StringUtils.isEmpty(bindUserName) || ! StringUtils.isEmpty(bindPassword)) { + conn.bind(new SimpleBindRequest(bindUserName, bindPassword)); + } + + return conn; + } catch (URISyntaxException e) { logger.error("Bad LDAP URL, should be in the form: ldap(s|+tls)://<server>:<port>", e); } catch (GeneralSecurityException e) { @@ -197,10 +208,10 @@ } catch (LDAPException e) { logger.error("Error Connecting to LDAP", e); } - + return null; } - + /** * Credentials are defined in the LDAP server and can not be manipulated * from Gitblit. @@ -212,7 +223,7 @@ public boolean supportsCredentialChanges() { return false; } - + /** * If no displayName pattern is defined then Gitblit can manage the display name. * @@ -223,7 +234,7 @@ public boolean supportsDisplayNameChanges() { return StringUtils.isEmpty(settings.getString(Keys.realm.ldap.displayName, "")); } - + /** * If no email pattern is defined then Gitblit can manage the email address. * @@ -235,19 +246,20 @@ return StringUtils.isEmpty(settings.getString(Keys.realm.ldap.email, "")); } - + /** * If the LDAP server will maintain team memberships then LdapUserService * will not allow team membership changes. In this scenario all team * changes must be made on the LDAP server by the LDAP administrator. - * + * * @return true or false * @since 1.0.0 - */ + */ + @Override public boolean supportsTeamMembershipChanges() { return !settings.getBoolean(Keys.realm.ldap.maintainTeams, false); } - + @Override protected AccountType getAccountType() { return AccountType.LDAP; @@ -259,9 +271,9 @@ // local account, bypass LDAP authentication return super.authenticate(username, password); } - + String simpleUsername = getSimpleUsername(username); - + LDAPConnection ldapConnection = getLdapConnection(); if (ldapConnection != null) { try { @@ -302,7 +314,7 @@ updateTeamModel(userTeam); } } - + return user; } } @@ -310,14 +322,14 @@ ldapConnection.close(); } } - return null; + return null; } /** * Set the admin attribute from team memberships retrieved from LDAP. * If we are not storing teams in LDAP and/or we have not defined any * administrator teams, then do not change the admin flag. - * + * * @param user */ private void setAdminAttribute(UserModel user) { @@ -338,17 +350,17 @@ } } } - + 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 = ExternalAccount; + user.password = Constants.EXTERNAL_ACCOUNT; user.accountType = getAccountType(); - + // Get full name Attribute - String displayName = settings.getString(Keys.realm.ldap.displayName, ""); + String displayName = settings.getString(Keys.realm.ldap.displayName, ""); if (!StringUtils.isEmpty(displayName)) { // Replace embedded ${} with attributes if (displayName.contains("${")) { @@ -363,7 +375,7 @@ } } } - + // Get email address Attribute String email = settings.getString(Keys.realm.ldap.email, ""); if (!StringUtils.isEmpty(email)) { @@ -383,39 +395,39 @@ 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}))"); - + groupMemberPattern = StringUtils.replace(groupMemberPattern, "${dn}", escapeLDAPSearchFilter(loggingInUserDN)); groupMemberPattern = StringUtils.replace(groupMemberPattern, "${username}", escapeLDAPSearchFilter(simpleUsername)); - + // Fill in attributes into groupMemberPattern for (Attribute userAttribute : loggingInUser.getAttributes()) groupMemberPattern = StringUtils.replace(groupMemberPattern, "${" + userAttribute.getName() + "}", escapeLDAPSearchFilter(userAttribute.getValue())); - - SearchResult teamMembershipResult = doSearch(ldapConnection, groupBase, groupMemberPattern); + + SearchResult teamMembershipResult = doSearch(ldapConnection, groupBase, true, groupMemberPattern, Arrays.asList("cn")); if (teamMembershipResult != null && teamMembershipResult.getEntryCount() > 0) { for (int i = 0; i < teamMembershipResult.getEntryCount(); i++) { SearchResultEntry teamEntry = teamMembershipResult.getSearchEntries().get(i); String teamName = teamEntry.getAttribute("cn").getValue(); - + TeamModel teamModel = getTeamModel(teamName); if (teamModel == null) teamModel = createTeamFromLdap(teamEntry); - + user.teams.add(teamModel); teamModel.addUser(user.getName()); } } } - + private TeamModel createTeamFromLdap(SearchResultEntry teamEntry) { TeamModel answer = new TeamModel(teamEntry.getAttributeValue("cn")); // potentially retrieve other attributes here in the future - - return answer; + + return answer; } private SearchResult doSearch(LDAPConnection ldapConnection, String base, String filter) { @@ -423,7 +435,28 @@ return ldapConnection.search(base, SearchScope.SUB, filter); } catch (LDAPSearchException e) { logger.error("Problem Searching LDAP", e); - + + return null; + } + } + + private SearchResult doSearch(LDAPConnection ldapConnection, String base, boolean dereferenceAliases, String filter, List<String> attributes) { + try { + SearchRequest searchRequest = new SearchRequest(base, SearchScope.SUB, filter); + if ( dereferenceAliases ) { + searchRequest.setDerefPolicy(DereferencePolicy.SEARCHING); + } + if (attributes != null) { + searchRequest.setAttributes(attributes); + } + return ldapConnection.search(searchRequest); + + } catch (LDAPSearchException e) { + logger.error("Problem Searching LDAP", e); + + return null; + } catch (LDAPException e) { + logger.error("Problem creating LDAP search", e); return null; } } @@ -450,10 +483,10 @@ synchronizeLdapUsers(); return super.getAllUsers(); } - + /** * Returns a simple username without any domain prefixes. - * + * * @param username * @return a simple username */ @@ -462,10 +495,10 @@ if (lastSlash > -1) { username = username.substring(lastSlash + 1); } - + return username; } - + // From: https://www.owasp.org/index.php/Preventing_LDAP_Injection_in_Java public static final String escapeLDAPSearchFilter(String filter) { StringBuilder sb = new StringBuilder(); @@ -484,8 +517,8 @@ case ')': sb.append("\\29"); break; - case '\u0000': - sb.append("\\00"); + case '\u0000': + sb.append("\\00"); break; default: sb.append(curChar); -- Gitblit v1.9.1