Embedded LDAP server LdapAuth3: support hashed passwords (sha1, sha-256)
Note that none of the currently supported hash are safe against
brute force attacks.
If ldapFilter property does not contain any occurrence of "${password}",
the user DN found via the filter expression will be authenticated
via a regular LDAP bind operation, using the entered password. In this
case, with embedded LDAP server, but probably also with others, hashed
passwords are supported and make sense.
Change-Id: I725832a2faa484623edcebeeeb727b23b6186de2
diff --git a/full/src/main/java/de/ids_mannheim/korap/authentication/LdapAuth3.java b/full/src/main/java/de/ids_mannheim/korap/authentication/LdapAuth3.java
index bdfb2ad..9975fcc 100644
--- a/full/src/main/java/de/ids_mannheim/korap/authentication/LdapAuth3.java
+++ b/full/src/main/java/de/ids_mannheim/korap/authentication/LdapAuth3.java
@@ -83,16 +83,16 @@
}
}
- SearchResult srchRes = search(login, password, ldapConfig);
+ SearchResult srchRes = search(login, password, ldapConfig, !ldapConfig.searchFilter.contains("${password}"));
if (srchRes == null || srchRes.getEntryCount() == 0) {
if (DEBUGLOG) System.out.printf("Finding '%s': no entry found!\n", login);
return LDAP_AUTH_RNAUTH;
}
+
return LDAP_AUTH_ROK;
}
-
- public static SearchResult search(String login, String password, LDAPConfig ldapConfig) throws LDAPException {
+ public static SearchResult search(String login, String password, LDAPConfig ldapConfig, boolean bindWithFoundDN) throws LDAPException {
Map<String, String> valuesMap = new HashMap<>();
valuesMap.put("login", login);
valuesMap.put("password", password);
@@ -174,16 +174,32 @@
if (DEBUGLOG) System.out.printf("Finding '%s': %d entries.\n", login, srchRes.getEntryCount());
} catch (LDAPSearchException e) {
- System.err.printf("Error: login: Search for User failed: '%s'!\n", e);
+ System.err.printf("Error: Search for User failed: '%s'!\n", e);
ldapTerminate(lc);
return null;
}
- if (srchRes.getEntryCount() == 0) {
+ if (srchRes == null || srchRes.getEntryCount() == 0) {
if (DEBUGLOG) System.out.printf("Finding '%s': no entry found!\n", login);
+ ldapTerminate(lc);
return null;
}
+ if (bindWithFoundDN) {
+ String matchedDN = srchRes.getSearchEntries().get(0).getDN();
+ if (DEBUGLOG) System.out.printf("Requested bind for found user %s' failed.\n", matchedDN);
+ try {
+ // bind to server:
+ if (DEBUGLOG) System.out.printf("Binding with '%s' ...\n", matchedDN);
+ lc.bind(matchedDN, password);
+ if (DEBUGLOG) System.out.print("Binding: OK.\n");
+ } catch (LDAPException e) {
+ System.err.printf("Error: login: Binding failed: '%s'!\n", e);
+ ldapTerminate(lc);
+ return null;
+ }
+ }
+
ldapTerminate(lc);
return srchRes;
}
@@ -193,7 +209,7 @@
LDAPConfig ldapConfig = new LDAPConfig(ldapConfigFilename);
final String emailAttribute = ldapConfig.emailAttribute;
- SearchResult searchResult = search(sUserDN, sUserPwd, ldapConfig);
+ SearchResult searchResult = search(sUserDN, sUserPwd, ldapConfig, false);
if (searchResult == null) {
return null;
diff --git a/full/src/main/java/de/ids_mannheim/korap/server/EmbeddedLdapServer.java b/full/src/main/java/de/ids_mannheim/korap/server/EmbeddedLdapServer.java
index 76f6494..88dfe2e 100644
--- a/full/src/main/java/de/ids_mannheim/korap/server/EmbeddedLdapServer.java
+++ b/full/src/main/java/de/ids_mannheim/korap/server/EmbeddedLdapServer.java
@@ -1,9 +1,8 @@
package de.ids_mannheim.korap.server;
-import com.unboundid.ldap.listener.InMemoryDirectoryServer;
-import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;
-import com.unboundid.ldap.listener.InMemoryListenerConfig;
+import com.unboundid.ldap.listener.*;
import com.unboundid.ldap.sdk.LDAPException;
+import com.unboundid.util.CryptoHelper;
import com.unboundid.util.ssl.SSLUtil;
import com.unboundid.util.ssl.TrustAllTrustManager;
import de.ids_mannheim.korap.authentication.LDAPConfig;
@@ -11,6 +10,7 @@
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.GeneralSecurityException;
+import java.security.MessageDigest;
public class EmbeddedLdapServer {
static InMemoryDirectoryServer server;
@@ -21,6 +21,9 @@
}
InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig(ldapConfig.searchBase);
+ final MessageDigest sha1Digest = CryptoHelper.getMessageDigest("SHA1");
+ final MessageDigest sha256Digest = CryptoHelper.getMessageDigest("SHA-256");
+ config.setPasswordEncoders(new ClearInMemoryPasswordEncoder("{CLEAR}", null), new ClearInMemoryPasswordEncoder("{HEX}", HexPasswordEncoderOutputFormatter.getLowercaseInstance()), new ClearInMemoryPasswordEncoder("{BASE64}", Base64PasswordEncoderOutputFormatter.getInstance()), new UnsaltedMessageDigestInMemoryPasswordEncoder("{SHA}", Base64PasswordEncoderOutputFormatter.getInstance(), sha1Digest), new UnsaltedMessageDigestInMemoryPasswordEncoder("{SHA256}", Base64PasswordEncoderOutputFormatter.getInstance(), sha256Digest));
config.addAdditionalBindCredentials(ldapConfig.sLoginDN, ldapConfig.sPwd);
config.setSchema(null);
diff --git a/full/src/main/resources/embedded-ldap-default.conf b/full/src/main/resources/embedded-ldap-default.conf
index becf6e0..00cd2a2 100644
--- a/full/src/main/resources/embedded-ldap-default.conf
+++ b/full/src/main/resources/embedded-ldap-default.conf
@@ -5,6 +5,6 @@
searchBase=dc=example,dc=com
sLoginDN=cn=admin,dc=example,dc=com
pwd=admin
-searchFilter=(&(uid=${login})(userPassword=${password}))
+searchFilter=(uid=${login})
useEmbeddedServer=true
ldifFile=src/main/resources/korap-users.ldif
diff --git a/full/src/main/resources/korap-users.ldif b/full/src/main/resources/korap-users.ldif
index 4a3e69c..8760df9 100644
--- a/full/src/main/resources/korap-users.ldif
+++ b/full/src/main/resources/korap-users.ldif
@@ -12,16 +12,35 @@
cn: user
uid: user
mail: user@example.com
-userPassword: cGFzc3dvcmQ=
+userPassword: {BASE64}cGFzc3dvcmQ=
dn: uid=user1,ou=people,dc=example,dc=com
cn: user1
uid: user1
mail: user1@example.com
-userPassword: password1
+userPassword: {CLEAR}password1
dn: uid=user2,ou=people,dc=example,dc=com
cn: user2
uid: user2
mail: user2@example.com
userPassword: password2
+
+dn: uid=user3,ou=people,dc=example,dc=com
+cn: user3
+uid: user3
+mail: user3@example.com
+userPassword: {SHA}ERnP037iRzV+A0oI2ETuol9v0g8=
+
+dn: uid=user4,ou=people,dc=example,dc=com
+cn: user4
+uid: user4
+mail: user4@example.com
+userPassword: {SHA256}uXhzpA9zq+3Y1oWnzV5fheSpz7g+rCaIZkCggThQEis=
+
+dn: uid=user5,ou=people,dc=example,dc=com
+cn: user5
+uid: user5
+mail: user5@example.com
+userPassword: {PBKDF2-SHA256}26PFrg++/nI8YOiHum5MyAMp0HdqKMNOcLpY5RuO2bY=
+