让liferay 支持 LDAP SSHA加密方式

最近公司的邮件服务器改成了ZIMBRA,ZIMBRA的LDAP使用了SSHA 加密方式,但是LIFERAY不支持,看了一下LIFERAY的代码,我写了一个patch。

ssha.patch

--- LDAPAuth.java 2007-03-01 23:42:18.000000000 +0800
+++ /liferay/portal-ejb/src/com/liferay/portal/security/auth/LDAPAuth.java 2007-03-01 23:11:33.000000000 +0800
@@ -28,6 +28,7 @@
import com.liferay.portal.kernel.log.LogUtil;
import com.liferay.portal.kernel.util.StackTraceUtil;
import com.liferay.portal.kernel.util.StringPool;
+import com.liferay.portal.kernel.util.Base64;
import com.liferay.portal.model.User;
import com.liferay.portal.security.ldap.LDAPImportUtil;
import com.liferay.portal.service.UserLocalServiceUtil;
@@ -54,6 +55,10 @@
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;

+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import sun.misc.BASE64Encoder;
+
/**
* View Source
*
@@ -261,23 +266,11 @@
if (userPassword != null) {
String ldapPassword = new String((byte[])userPassword.get());

- String encryptedPassword = password;
-
- String algorithm = PrefsPropsUtil.getString(
- companyId,
- PropsUtil.AUTH_IMPL_LDAP_PASSWORD_ENCRYPTION_ALGORITHM);
-
- if (Validator.isNotNull(algorithm)) {
- encryptedPassword =
- "{" + algorithm + "}" +
- Encryptor.digest(algorithm, password);
- }
-
- if (!ldapPassword.equals(encryptedPassword)) {
+ if (!verifyPassword(ldapPassword,password)) {
_log.error(
"LDAP password " + ldapPassword +
" does not match with given password " +
- encryptedPassword + " for user id " + userId);
+ password + " for user id " + userId);

return false;
}
@@ -381,6 +374,98 @@
locationId, sendEmail, true, true);
}

+ /**
+ * Splits a byte array into two.
+ *
+ * @param src byte array to split
+ * @param n location to split the array
+ * @return a two dimensional array of the split
+ */
+ private static byte[][] split(byte[] src, int n) {
+ byte[] l;
+ byte[] r;
+
+ if (src.length <= n) {
+ l = src;
+ r = new byte[0];
+
+ } else {
+ l = new byte[n];
+ r = new byte[src.length - n];
+ System.arraycopy(src, 0, l, 0, n);
+ System.arraycopy(src, n, r, 0, r.length);
+
+ }
+
+ byte[][] lr = { l, r };
+
+ return lr;
+
+ }
+
+
+ /**
+ * Validates if a plaintext password matches a
+ * hashed version.
+ *
+ * @param digest digested version
+ * @param password plaintext password
+ * @return if the two match
+ */
+ public static boolean verifyPassword(String digest, String password) {
+ String alg = null;
+ int size = 0;
+
+ if (digest.regionMatches(true, 0, "{SHA}", 0, 5)) {
+ digest = digest.substring(5);
+ alg = "SHA-1";
+ size = 20;
+
+ } else if (digest.regionMatches(true, 0, "{SSHA}", 0, 6)) {
+ digest = digest.substring(6);
+ alg = "SHA-1";
+ size = 20;
+
+ } else if (digest.regionMatches(true, 0, "{MD5}", 0, 5)) {
+ digest = digest.substring(5);
+ alg = "MD5";
+ size = 16;
+
+ } else if (digest.regionMatches(true, 0, "{SMD5}", 0, 6)) {
+ digest = digest.substring(6);
+ alg = "MD5";
+ size = 16;
+
+ }
+
+ try {
+ MessageDigest mDigest = MessageDigest.getInstance(alg);
+
+ if (mDigest == null) {
+ return false;
+
+ }
+
+ byte[][] hs = split(Base64.decode(digest), size);
+ byte[] hash = hs[0];
+ byte[] salt = hs[1];
+ mDigest.reset();
+ mDigest.update(password.getBytes());
+ mDigest.update(salt);
+
+ byte[] pwhash = mDigest.digest();
+
+ return MessageDigest.isEqual(hash, pwhash);
+
+ } catch (NoSuchAlgorithmException nsae) {
+ _log.error(StackTraceUtil.getStackTrace(nsae));
+ return false;
+ }
+
+ }
+
+
+
private static Log _log = LogFactoryUtil.getLog(LDAPAuth.class);

-}
\ No newline at end of file
+}

你可能感兴趣的:(Security,ejb,sun)