ASF Bugzilla – Attachment 27699 Details for
Bug 51966
Tomcat does not support ssha hashed passwords in all contexts
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch that implements ssha passwords
ssha1.patch.txt (text/plain), 10.46 KB, created by
Adam Caldwell
on 2011-10-05 18:34:10 UTC
(
hide
)
Description:
Patch that implements ssha passwords
Filename:
MIME Type:
Creator:
Adam Caldwell
Created:
2011-10-05 18:34:10 UTC
Size:
10.46 KB
patch
obsolete
>diff -u --recursive orig/apache-tomcat-6.0.33-src/java/org/apache/catalina/realm/DataSourceRealm.java apache-tomcat-6.0.33-src/java/org/apache/catalina/realm/DataSourceRealm.java >--- orig/apache-tomcat-6.0.33-src/java/org/apache/catalina/realm/DataSourceRealm.java 2011-08-16 07:26:14.000000000 -0500 >+++ apache-tomcat-6.0.33-src/java/org/apache/catalina/realm/DataSourceRealm.java 2011-10-05 11:51:11.000000000 -0500 >@@ -33,6 +33,7 @@ > import org.apache.catalina.LifecycleException; > import org.apache.catalina.ServerFactory; > import org.apache.catalina.core.StandardServer; >+import org.apache.catalina.util.HexUtils; > import org.apache.catalina.util.StringManager; > > /** >@@ -340,10 +341,13 @@ > // Validate the user's credentials > boolean validated = false; > if (hasMessageDigest()) { >- // Hex hashes should be compared case-insensitive >- validated = (digest(credentials).equalsIgnoreCase(dbCredentials)); >+ byte salt[] = null; >+ if (digest.equals("ssha")) { >+ salt = HexUtils.convert(dbCredentials.substring(dbCredentials.length()-8)); // salt is last 4 bytes = 8 characters >+ } >+ validated = dbCredentials.equalsIgnoreCase(digest(credentials,salt)); > } else >- validated = (digest(credentials).equals(dbCredentials)); >+ validated = (digest(credentials,null).equals(dbCredentials)); > > if (validated) { > if (containerLog.isTraceEnabled()) >diff -u --recursive orig/apache-tomcat-6.0.33-src/java/org/apache/catalina/realm/JAASCallbackHandler.java apache-tomcat-6.0.33-src/java/org/apache/catalina/realm/JAASCallbackHandler.java >--- orig/apache-tomcat-6.0.33-src/java/org/apache/catalina/realm/JAASCallbackHandler.java 2011-08-16 07:26:14.000000000 -0500 >+++ apache-tomcat-6.0.33-src/java/org/apache/catalina/realm/JAASCallbackHandler.java 2011-10-05 11:47:39.000000000 -0500 >@@ -69,7 +69,7 @@ > this.username = username; > > if (realm.hasMessageDigest()) { >- this.password = realm.digest(password); >+ this.password = realm.digest(password,null); > } > else { > this.password = password; >diff -u --recursive orig/apache-tomcat-6.0.33-src/java/org/apache/catalina/realm/JDBCRealm.java apache-tomcat-6.0.33-src/java/org/apache/catalina/realm/JDBCRealm.java >--- orig/apache-tomcat-6.0.33-src/java/org/apache/catalina/realm/JDBCRealm.java 2011-08-16 07:26:14.000000000 -0500 >+++ apache-tomcat-6.0.33-src/java/org/apache/catalina/realm/JDBCRealm.java 2011-10-05 11:51:23.000000000 -0500 >@@ -29,6 +29,7 @@ > import java.util.Properties; > > import org.apache.catalina.LifecycleException; >+import org.apache.catalina.util.HexUtils; > import org.apache.catalina.util.StringManager; > > >@@ -416,10 +417,13 @@ > // Validate the user's credentials > boolean validated = false; > if (hasMessageDigest()) { >- // Hex hashes should be compared case-insensitive >- validated = (digest(credentials).equalsIgnoreCase(dbCredentials)); >+ byte[] salt = null; >+ if (digest.equals("ssha")) { >+ salt = HexUtils.convert(dbCredentials.substring(dbCredentials.length()-8)); // salt is last 4 bytes = 8 characters >+ } >+ validated = dbCredentials.equalsIgnoreCase(digest(credentials,salt)); > } else { >- validated = (digest(credentials).equals(dbCredentials)); >+ validated = (digest(credentials,null).equals(dbCredentials)); > } > > if (validated) { >diff -u --recursive orig/apache-tomcat-6.0.33-src/java/org/apache/catalina/realm/JNDIRealm.java apache-tomcat-6.0.33-src/java/org/apache/catalina/realm/JNDIRealm.java >--- orig/apache-tomcat-6.0.33-src/java/org/apache/catalina/realm/JNDIRealm.java 2011-08-16 07:26:14.000000000 -0500 >+++ apache-tomcat-6.0.33-src/java/org/apache/catalina/realm/JNDIRealm.java 2011-10-05 11:46:05.000000000 -0500 >@@ -1520,10 +1520,10 @@ > } // End synchronized(this) block > } else { > // Hex hashes should be compared case-insensitive >- validated = (digest(credentials).equalsIgnoreCase(password)); >+ validated = (digest(credentials,null).equalsIgnoreCase(password)); > } > } else >- validated = (digest(credentials).equals(password)); >+ validated = (digest(credentials,null).equals(password)); > return (validated); > > } >diff -u --recursive orig/apache-tomcat-6.0.33-src/java/org/apache/catalina/realm/MemoryRealm.java apache-tomcat-6.0.33-src/java/org/apache/catalina/realm/MemoryRealm.java >--- orig/apache-tomcat-6.0.33-src/java/org/apache/catalina/realm/MemoryRealm.java 2011-08-16 07:26:14.000000000 -0500 >+++ apache-tomcat-6.0.33-src/java/org/apache/catalina/realm/MemoryRealm.java 2011-10-05 11:51:03.000000000 -0500 >@@ -25,6 +25,7 @@ > import java.util.HashMap; > import java.util.Map; > import org.apache.catalina.LifecycleException; >+import org.apache.catalina.util.HexUtils; > import org.apache.catalina.util.StringManager; > import org.apache.juli.logging.Log; > import org.apache.juli.logging.LogFactory; >@@ -150,12 +151,16 @@ > boolean validated = false; > if (principal != null && credentials != null) { > if (hasMessageDigest()) { >+ String serverCredentials = principal.getPassword(); >+ byte[] salt = null; >+ if (digest.equals("ssha")) { >+ salt = HexUtils.convert(serverCredentials.substring(serverCredentials.length()-8)); // salt is last 4 bytes = 8 characters >+ } >+ validated = serverCredentials.equalsIgnoreCase(digest(credentials,salt)); > // Hex hashes should be compared case-insensitive >- validated = (digest(credentials) >- .equalsIgnoreCase(principal.getPassword())); > } else { > validated = >- (digest(credentials).equals(principal.getPassword())); >+ (digest(credentials,null).equals(principal.getPassword())); > } > } > >diff -u --recursive orig/apache-tomcat-6.0.33-src/java/org/apache/catalina/realm/RealmBase.java apache-tomcat-6.0.33-src/java/org/apache/catalina/realm/RealmBase.java >--- orig/apache-tomcat-6.0.33-src/java/org/apache/catalina/realm/RealmBase.java 2011-08-16 07:26:14.000000000 -0500 >+++ apache-tomcat-6.0.33-src/java/org/apache/catalina/realm/RealmBase.java 2011-10-05 13:16:40.000000000 -0500 >@@ -28,6 +28,7 @@ > import java.security.Principal; > import java.security.cert.X509Certificate; > import java.util.ArrayList; >+import java.util.Random; > > import javax.management.Attribute; > import javax.management.MBeanRegistration; >@@ -311,7 +312,11 @@ > if ( serverCredentials == null ) { > validated = false; > } else if(hasMessageDigest()) { >- validated = serverCredentials.equalsIgnoreCase(digest(credentials)); >+ byte[] salt = null; >+ if (digest.equals("ssha")) { >+ salt = HexUtils.convert(serverCredentials.substring(serverCredentials.length()-8)); // salt is last 4 bytes = 8 characters >+ } >+ validated = serverCredentials.equalsIgnoreCase(digest(credentials,salt)); > } else { > validated = serverCredentials.equals(credentials); > } >@@ -1052,7 +1057,7 @@ > // Create a MessageDigest instance for credentials, if desired > if (digest != null) { > try { >- md = MessageDigest.getInstance(digest); >+ md = MessageDigest.getInstance(digest.equals("ssha") ? "sha1" : digest); > } catch (NoSuchAlgorithmException e) { > throw new LifecycleException > (sm.getString("realmBase.algorithm", digest), e); >@@ -1107,16 +1112,29 @@ > > // ------------------------------------------------------ Protected Methods > >+ /** >+ * Digest the password using the specified algorithm and >+ * convert the result to a corresponding hexadecimal string. >+ * If exception, the plain credentials string is returned. >+ * >+ * @param credentials Password or other credentials to use in >+ * authenticating this username >+ */ >+ protected String digest(String credentials) { >+ return digest(credentials,null); >+ } > > /** > * Digest the password using the specified algorithm and > * convert the result to a corresponding hexadecimal string. > * If exception, the plain credentials string is returned. >+ * If salt is not-null, the message digest is updated with >+ * that salt and it is appended to the string > * > * @param credentials Password or other credentials to use in > * authenticating this username > */ >- protected String digest(String credentials) { >+ protected String digest(String credentials,byte[] salt) { > > // If no MessageDigest instance is specified, return unchanged > if (hasMessageDigest() == false) >@@ -1139,6 +1157,10 @@ > } > } > md.update(bytes); >+ if (salt != null) { >+ md.update(salt); >+ return (HexUtils.convert(md.digest())) + HexUtils.convert(salt); >+ } > > return (HexUtils.convert(md.digest())); > } catch (Exception e) { >@@ -1242,7 +1264,7 @@ > try { > // Obtain a new message digest with "digest" encryption > MessageDigest md = >- (MessageDigest) MessageDigest.getInstance(algorithm).clone(); >+ (MessageDigest) MessageDigest.getInstance(algorithm.equals("ssha") ? "sha1" : algorithm).clone(); > > // encode the credentials > // Should use the digestEncoding, but that's not a static field >@@ -1251,9 +1273,19 @@ > } else { > md.update(credentials.getBytes(encoding)); > } >+ if (algorithm.equals("ssha")) { >+ Random r = new Random(); >+ byte[] salt = new byte[4]; >+ for(int i = 0; i < salt.length; i++) { >+ salt[i] = (byte)r.nextInt(256); >+ } > >- // Digest the credentials and return as hexadecimal >- return (HexUtils.convert(md.digest())); >+ md.update(salt); >+ return (HexUtils.convert(md.digest())) + HexUtils.convert(salt); >+ } else { >+ // Digest the credentials and return as hexadecimal >+ return (HexUtils.convert(md.digest())); >+ } > } catch(Exception ex) { > log.error(ex); > return credentials;
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 51966
:
27699
|
27703