Bug 32938 - SSHA passwords in JNDIRealm
Summary: SSHA passwords in JNDIRealm
Status: RESOLVED FIXED
Alias: None
Product: Tomcat 5
Classification: Unclassified
Component: Catalina (show other bugs)
Version: 5.5.4
Hardware: All All
: P2 enhancement with 1 vote (vote)
Target Milestone: ---
Assignee: Tomcat Developers Mailing List
URL:
Keywords: PatchAvailable
Depends on:
Blocks:
 
Reported: 2005-01-04 17:52 UTC by Andrey Polozov
Modified: 2005-03-23 07:18 UTC (History)
0 users



Attachments
The patch to make it work. (2.63 KB, patch)
2005-01-04 17:53 UTC, Andrey Polozov
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Andrey Polozov 2005-01-04 17:52:04 UTC
Current implementation of JNDIRealm does not support "Salted" SHA passwords.
So, if the password was set by iPlaned Admin server - it can't be verified by
JNDIRealm.
Here is the patch to make it work.

*** orig/catalina/src/share/org/apache/catalina/realm/JNDIRealm.java	Tue Jan  4
11:34:07 2005
---
jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/realm/JNDIRealm.java
Tue Jan  4 11:16:54 2005
*************** import javax.naming.directory.SearchCont
*** 43,48 ****
--- 43,50 ----
  import javax.naming.directory.SearchResult;
  import org.apache.catalina.LifecycleException;
  import org.apache.catalina.util.Base64;
+ import org.apache.tomcat.util.buf.ByteChunk;
+ import org.apache.tomcat.util.buf.CharChunk;
  
  
  /**
*************** public class JNDIRealm extends RealmBase
*** 1191,1196 ****
--- 1193,1231 ----
                          new String(Base64.encode(md.digest()));
                      validated = password.equals(digestedPassword);
                  }
+             } else if (password.startsWith("{SSHA}")) {
+                 /* sync since super.digest() does this same thing */
+                 synchronized (this) {
+                     password = password.substring(6);
+ 
+                     md.reset();
+                     md.update(credentials.getBytes());
+ 					//Decode stored password.
+                     ByteChunk pwbc = new ByteChunk(password.length());
+                     try {
+                         pwbc.append(password.getBytes(), 0, password.length());
+                     } catch (java.io.IOException e) {
+                         e.printStackTrace(); //Hopefully will never happen.
+                     }
+                     CharChunk decoded = new CharChunk();
+                     Base64.decode(pwbc, decoded);
+                     char[] pwarray = decoded.getBuffer();
+                     // Split decoded password into hash and salt.
+                     final int saltpos = 20;
+                     byte[] hash = new byte[saltpos];
+                     for (int i=0; i< hash.length; i++)
+                         hash[i] = (byte)pwarray[i];
+ 
+                     byte[] salt = new byte[pwarray.length - saltpos];
+                     for (int i=0; i< salt.length; i++)
+                         salt[i] = (byte)pwarray[i+saltpos];
+ 
+                     md.update(salt);
+                     
+                     byte[] dp = md.digest();
+ 
+                     validated = java.util.Arrays.equals(dp, hash);
+                 }
              } else {
                  // Hex hashes should be compared case-insensitive
                  validated = (digest(credentials).equalsIgnoreCase(password));
*************** public class JNDIRealm extends RealmBase
*** 1202,1208 ****
      }
  
  
- 
      /**
       * Check credentials by binding to the directory as the user
       *
--- 1237,1242 ----
Comment 1 Andrey Polozov 2005-01-04 17:53:08 UTC
Created attachment 13885 [details]
The patch to make it work.
Comment 2 Yoav Shapira 2005-03-23 16:18:05 UTC
Done for 5.5.9.  Thanks for the contribution.

What would really be great is if you wanted to amend the realm-howto doc page to
include the new feature you sent us.  If you do this, please open a separate
bugzilla issue for the doc enhancement, don't reopen this one.  Thanks!