geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From vamsic...@apache.org
Subject svn commit: r478545 - in /geronimo/server/trunk: applications/console/geronimo-console-standard/src/main/webapp/WEB-INF/classes/ applications/console/geronimo-console-standard/src/main/webapp/WEB-INF/view/realmwizard/ modules/geronimo-security/src/main...
Date Thu, 23 Nov 2006 12:20:41 GMT
Author: vamsic007
Date: Thu Nov 23 04:20:40 2006
New Revision: 478545

URL: http://svn.apache.org/viewvc?view=rev&rev=478545
Log:
GERONIMO-1880 To Allow configurable password digests during REALM Deployment
  o Introduced a "digest" option in PropertiesFileLoginModule and SQLLoginModule

Modified:
    geronimo/server/trunk/applications/console/geronimo-console-standard/src/main/webapp/WEB-INF/classes/login-modules.properties
    geronimo/server/trunk/applications/console/geronimo-console-standard/src/main/webapp/WEB-INF/view/realmwizard/_sql.jsp
    geronimo/server/trunk/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/PropertiesFileLoginModule.java
    geronimo/server/trunk/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/SQLLoginModule.java

Modified: geronimo/server/trunk/applications/console/geronimo-console-standard/src/main/webapp/WEB-INF/classes/login-modules.properties
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/applications/console/geronimo-console-standard/src/main/webapp/WEB-INF/classes/login-modules.properties?view=diff&rev=478545&r1=478544&r2=478545
==============================================================================
--- geronimo/server/trunk/applications/console/geronimo-console-standard/src/main/webapp/WEB-INF/classes/login-modules.properties
(original)
+++ geronimo/server/trunk/applications/console/geronimo-console-standard/src/main/webapp/WEB-INF/classes/login-modules.properties
Thu Nov 23 04:20:40 2006
@@ -28,6 +28,11 @@
 module.props.field.groupsURI.displayName=Groups File URI
 module.props.field.groupsURI.description=The location of a properties file (relative to the
Geronimo home dir) holding group information.  The format of each line should be <tt>group=user,user,...</tt>.
 module.props.field.groupsURI.length=50
+module.props.field.digest.displayOrder=3
+module.props.field.digest.displayName=Digest Algorithm
+module.props.field.digest.description=Message Digest algorithm (e.g. MD5, SHA1, etc.) used
on the passwords.  Leave this field empty if no digest algorithm is used.
+module.props.field.digest.length=10
+module.props.field.digest.blankAllowed=true
 # LDAP
 module.ldap.name=LDAP Realm
 module.ldap.class=org.apache.geronimo.security.realm.providers.LDAPLoginModule

Modified: geronimo/server/trunk/applications/console/geronimo-console-standard/src/main/webapp/WEB-INF/view/realmwizard/_sql.jsp
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/applications/console/geronimo-console-standard/src/main/webapp/WEB-INF/view/realmwizard/_sql.jsp?view=diff&rev=478545&r1=478544&r2=478545
==============================================================================
--- geronimo/server/trunk/applications/console/geronimo-console-standard/src/main/webapp/WEB-INF/view/realmwizard/_sql.jsp
(original)
+++ geronimo/server/trunk/applications/console/geronimo-console-standard/src/main/webapp/WEB-INF/view/realmwizard/_sql.jsp
Thu Nov 23 04:20:40 2006
@@ -62,6 +62,17 @@
       </tr>
 
       <tr>
+        <th><div align="right">Digest Algorithm:</div></th>
+        <td><input name="option-digest" type="text"
+                   size="10" value="${realm.options['digest']}"></td>
+      </tr>
+      <tr>
+        <td></td>
+        <td>Message Digest algorithm (e.g. MD5, SHA1, etc.) used on the passwords.
 Leave this field empty if no digest
+          algorithm is used.</td>
+      </tr>
+
+      <tr>
         <td></td>
         <td><i>A SQL security realm must either have a database pool or JDBC
connectivity settings to
           connect to the database.  Please select EITHER the database pool, OR the rest of
the JDBC

Modified: geronimo/server/trunk/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/PropertiesFileLoginModule.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/PropertiesFileLoginModule.java?view=diff&rev=478545&r1=478544&r2=478545
==============================================================================
--- geronimo/server/trunk/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/PropertiesFileLoginModule.java
(original)
+++ geronimo/server/trunk/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/PropertiesFileLoginModule.java
Thu Nov 23 04:20:40 2006
@@ -22,6 +22,7 @@
 import org.apache.geronimo.common.GeronimoSecurityException;
 import org.apache.geronimo.security.jaas.JaasLoginModuleUse;
 import org.apache.geronimo.system.serverinfo.ServerInfo;
+import org.apache.geronimo.util.encoders.HexTranslator;
 
 import javax.security.auth.Subject;
 import javax.security.auth.callback.Callback;
@@ -35,6 +36,8 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URI;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -54,9 +57,11 @@
 public class PropertiesFileLoginModule implements LoginModule {
     public final static String USERS_URI = "usersURI";
     public final static String GROUPS_URI = "groupsURI";
+    public final static String DIGEST = "digest";
     private static Log log = LogFactory.getLog(PropertiesFileLoginModule.class);
     final Properties users = new Properties();
     final Map groups = new HashMap();
+    private String digest;
 
     Subject subject;
     CallbackHandler handler;
@@ -70,6 +75,16 @@
             ServerInfo serverInfo = (ServerInfo) options.get(JaasLoginModuleUse.SERVERINFO_LM_OPTION);
             final String users = (String)options.get(USERS_URI);
             final String groups = (String)options.get(GROUPS_URI);
+            digest = (String) options.get(DIGEST);
+            if(digest != null && !digest.equals("")) {
+                // Check if the digest algorithm is available
+                try {
+                    MessageDigest.getInstance(digest);
+                } catch(NoSuchAlgorithmException e) {
+                    log.error("Initialization failed. Digest algorithm "+digest+" is not
available.", e);
+                    throw new IllegalArgumentException("Unable to configure properties file
login module: "+e.getMessage());
+                }
+            }
             if(users == null || groups == null) {
                 throw new IllegalArgumentException("Both "+USERS_URI+" and "+GROUPS_URI+"
must be provided!");
             }
@@ -139,7 +154,7 @@
         char[] entered = ((PasswordCallback) callbacks[1]).getPassword();
         password = entered == null ? null : new String(entered);
         boolean result = (realPassword == null && password == null) ||
-                (realPassword != null && password != null && realPassword.equals(password));
+                (realPassword != null && password != null && checkPassword(realPassword,
password));
         if(!result) {
             throw new FailedLoginException();
         }
@@ -204,5 +219,33 @@
             throw new IllegalArgumentException("No such principal class "+className);
         }
         return (String[]) s.toArray(new String[s.size()]);
+    }
+
+    /**
+     * This method checks if the provided password is correct.  The original password may
have been digested.
+     * @param real      Original password in digested form if applicable
+     * @param provided  User provided password in clear text
+     * @return true     If the password is correct
+     */
+    private boolean checkPassword(String real, String provided){
+        if(digest == null || digest.equals("")) {
+            // No digest algorithm is used
+            return real.equals(provided);
+        }
+        try {
+            // Digest the user provided password
+            MessageDigest md = MessageDigest.getInstance(digest);
+            byte[] data = md.digest(provided.getBytes());
+            // Convert bytes to hex digits
+            byte[] hexData = new byte[data.length * 2];
+            HexTranslator ht = new HexTranslator();
+            ht.encode(data, 0, data.length, hexData, 0);
+            // Compare the digested provided password with the actual one
+            return real.equalsIgnoreCase(new String(hexData));
+        } catch (NoSuchAlgorithmException e) {
+            // Should not occur.  Availability of algorithm has been checked at initialization
+            log.error("Should not occur.  Availability of algorithm has been checked at initialization.",
e);
+        }
+        return false;
     }
 }

Modified: geronimo/server/trunk/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/SQLLoginModule.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/SQLLoginModule.java?view=diff&rev=478545&r1=478544&r2=478545
==============================================================================
--- geronimo/server/trunk/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/SQLLoginModule.java
(original)
+++ geronimo/server/trunk/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/SQLLoginModule.java
Thu Nov 23 04:20:40 2006
@@ -18,6 +18,8 @@
 package org.apache.geronimo.security.realm.providers;
 
 import java.io.IOException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
 import java.sql.Connection;
 import java.sql.Driver;
 import java.sql.PreparedStatement;
@@ -39,6 +41,8 @@
 import javax.security.auth.spi.LoginModule;
 import javax.sql.DataSource;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.apache.geronimo.gbean.AbstractName;
 import org.apache.geronimo.gbean.AbstractNameQuery;
 import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
@@ -47,6 +51,7 @@
 import org.apache.geronimo.kernel.KernelRegistry;
 import org.apache.geronimo.management.geronimo.JCAManagedConnectionFactory;
 import org.apache.geronimo.security.jaas.JaasLoginModuleUse;
+import org.apache.geronimo.util.encoders.HexTranslator;
 
 
 /**
@@ -71,6 +76,7 @@
  * @version $Rev$ $Date$
  */
 public class SQLLoginModule implements LoginModule {
+    private static Log log = LogFactory.getLog(SQLLoginModule.class);
     public final static String USER_SELECT = "userSelect";
     public final static String GROUP_SELECT = "groupSelect";
     public final static String CONNECTION_URL = "jdbcURL";
@@ -79,12 +85,14 @@
     public final static String DRIVER = "jdbcDriver";
     public final static String DATABASE_POOL_NAME = "dataSourceName";
     public final static String DATABASE_POOL_APP_NAME = "dataSourceApplication";
+    public final static String DIGEST = "digest";
     private String connectionURL;
     private Properties properties;
     private Driver driver;
     private JCAManagedConnectionFactory factory;
     private String userSelect;
     private String groupSelect;
+    private String digest;
 
     private Subject subject;
     private CallbackHandler handler;
@@ -98,6 +106,17 @@
         userSelect = (String) options.get(USER_SELECT);
         groupSelect = (String) options.get(GROUP_SELECT);
 
+        digest = (String) options.get(DIGEST);
+        if(digest != null && !digest.equals("")) {
+            // Check if the digest algorithm is available
+            try {
+                MessageDigest.getInstance(digest);
+            } catch(NoSuchAlgorithmException e) {
+                log.error("Initialization failed. Digest algorithm "+digest+" is not available.",
e);
+                throw new IllegalArgumentException("Unable to configure SQL login module:
"+e.getMessage());
+            }
+        }
+
         String dataSourceName = (String) options.get(DATABASE_POOL_NAME);
         if(dataSourceName != null) {
             dataSourceName = dataSourceName.trim();
@@ -193,7 +212,7 @@
 
                             if (cbUsername.equals(userName)) {
                                 found = (cbPassword == null && userPassword == null)
||
-                                        (cbPassword != null && userPassword != null
&& cbPassword.equals(userPassword));
+                                        (cbPassword != null && userPassword != null
&& checkPassword(userPassword, cbPassword));
                                 break;
                             }
                         }
@@ -273,5 +292,33 @@
             ++count;
         }
         return count;
+    }
+
+    /**
+     * This method checks if the provided password is correct.  The original password may
have been digested.
+     * @param real      Original password in digested form if applicable
+     * @param provided  User provided password in clear text
+     * @return true     If the password is correct
+     */
+    private boolean checkPassword(String real, String provided){
+        if(digest == null || digest.equals("")) {
+            // No digest algorithm is used
+            return real.equals(provided);
+        }
+        try {
+            // Digest the user provided password
+            MessageDigest md = MessageDigest.getInstance(digest);
+            byte[] data = md.digest(provided.getBytes());
+            // Convert bytes to hex digits
+            byte[] hexData = new byte[data.length * 2];
+            HexTranslator ht = new HexTranslator();
+            ht.encode(data, 0, data.length, hexData, 0);
+            // Compare the digested provided password with the actual one
+            return real.equalsIgnoreCase(new String(hexData));
+        } catch (NoSuchAlgorithmException e) {
+            // Should not occur.  Availability of algorithm has been checked at initialization
+            log.error("Should not occur.  Availability of algorithm has been checked at initialization.",
e);
+        }
+        return false;
     }
 }



Mime
View raw message