Return-Path: Mailing-List: contact tomcat-dev-help@jakarta.apache.org; run by ezmlm Delivered-To: mailing list tomcat-dev@jakarta.apache.org Delivered-To: moderator for tomcat-dev@jakarta.apache.org Received: (qmail 44378 invoked from network); 9 Feb 2001 21:54:36 -0000 Received: from aulne.infini.fr (212.208.100.11) by h31.sny.collab.net with SMTP; 9 Feb 2001 21:54:36 -0000 Received: (from uucp@localhost) by aulne.infini.fr (8.9.3/8.9.3/R&D&B-990119) with UUCP id WAA20487 for tomcat-dev@jakarta.apache.org; Fri, 9 Feb 2001 22:54:11 +0100 Received: from iroise.net (herberts@localhost [127.0.0.1]) by glop.infini.fr (8.9.3/8.9.3/Debian 8.9.3-21) with ESMTP id WAA05522 for ; Fri, 9 Feb 2001 22:53:50 +0100 X-Authentication-Warning: glop.infini.fr: Host herberts@localhost [127.0.0.1] claimed to be iroise.net Sender: herberts@iroise.net Message-ID: <3A8466ED.8152401F@iroise.net> Date: Fri, 09 Feb 2001 22:53:49 +0100 From: Mathias Herberts X-Mailer: Mozilla 4.7 [en] (X11; U; Linux 2.2.17 i686) X-Accept-Language: en MIME-Version: 1.0 To: tomcat-dev@jakarta.apache.org Subject: [PATCH] encryption support in SimpleRealm.java Content-Type: multipart/mixed; boundary="------------664DB158F86A508221DC0E84" X-Spam-Rating: h31.sny.collab.net 1.6.2 0/1000/N --------------664DB158F86A508221DC0E84 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Hi, I've been playing around with Tomcat 3.2.1 as we have several production servers using it and was concerned by the way the passwords were stored in tomcat-users.xml. The included patch modifies SimplesRealm.java (org.apache.tomcat.request.SimpleRealm) so it can correctly manage a tomcat-users.xml file whose passwords are encrypted. The method used to handle encryption is java.security.MessageDigest, therefore all algorithms known by this class (without the use of an external Provider) can be used, mainly MD5 and SHA. All passwords in tomcat-users.xml must be encrypted using the same algorithm (or no algorithm if so choosen). The algorithm of choice is specified in the declaration of the SimpleRealm RequestInterceptor as follows: The SimpleRealm request interceptor then expects all tomcat-users.xml passwords to be encrypted using the specified algorithm, comparison is case insensitive (for the encrypted part). If you choose not to use encryption, simply omit the crypt attribute in the RequestInterceptor element. As I am not a subscriber of the tomcat-dev mailing list please CC me when replying to my message. Any comment welcome about this patch. Best regards, Mathias Herberts. --------------664DB158F86A508221DC0E84 Content-Type: text/plain; charset=us-ascii; name="tomcat-SimpleRealm.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="tomcat-SimpleRealm.patch" --- org/apache/tomcat/request/SimpleRealm.java.orig Fri Feb 9 21:42:02 2001 +++ org/apache/tomcat/request/SimpleRealm.java Fri Feb 9 22:36:49 2001 @@ -66,6 +66,7 @@ import java.io.*; import java.net.*; import java.util.*; +import java.security.*; import org.xml.sax.*; /** @@ -84,6 +85,9 @@ ContextManager cm; int reqRolesNote; + // MessageDigest algorithm + String crypt; + public SimpleRealm() { } @@ -112,6 +116,7 @@ memoryRealm = new MemoryRealm(ctx); try { memoryRealm.readMemoryRealm(ctx); + memoryRealm.crypt = crypt; } catch(Exception ex ) { ex.printStackTrace(); memoryRealm=null; @@ -166,6 +171,10 @@ if( debug > 0 ) log( "UnAuthorized " + roles[0] ); return 401; } + + public void setCrypt( String c ) { + crypt = c; + } } class MemoryRealm { @@ -177,6 +186,9 @@ Hashtable userRoles= new Hashtable(); Context ctx; int debug=0; + + // MessageDigest used to encrypt the passwords + String crypt; MemoryRealm(Context ctx) { this.ctx=ctx; @@ -218,7 +230,45 @@ public boolean checkPassword( String user, String pass ) { if( user==null ) return false; if( debug > 0 ) ctx.log( "check " + user+ " " + pass + " " + passwords.get( user )); - return pass.equals( (String)passwords.get( user ) ); + if( crypt==null ) { + return pass.equals( (String)passwords.get( user ) ); + } else { + return checkMDPassword( user, pass ); + } + } + + public boolean checkMDPassword( String user, String pass ) { + MessageDigest md; + + if( crypt==null ) { + if( debug > 0 ) ctx.log( "MessageDigest algorithm not set" ); + return false; + } + + try { + md = MessageDigest.getInstance( crypt ); + } catch( NoSuchAlgorithmException e ) { + if( debug > 0 ) ctx.log( "Unknown MessageDigest algorithm " + crypt ); + return false; + } + + if( md!=null ) { + String s = ""; + byte a[] = md.digest (pass.getBytes()); + + for( int i = 0; i < a.length; i++ ) { + s = s.concat( Integer.toHexString( (0x100 | a[i]) & 0x1ff ).toUpperCase().substring( 1 ) ); + } + + if( ((String)passwords.get( user )).toUpperCase().compareTo( s )== 0) { + return true; + } else { + return false; + } + } else { + if( debug > 0 ) ctx.log( "Failed to create MessageDigest" ); + return false; + } } public String[] getUserRoles( String user ) { --------------664DB158F86A508221DC0E84--