tomee-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jlmonte...@apache.org
Subject svn commit: r818889 - in /openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc: BasicDataSource.java BasicManagedDataSource.java PasswordCodec.java PlainTextPasswordCodec.java StaticDESPasswordCodec.java
Date Fri, 25 Sep 2009 15:50:59 GMT
Author: jlmonteiro
Date: Fri Sep 25 15:50:58 2009
New Revision: 818889

URL: http://svn.apache.org/viewvc?rev=818889&view=rev
Log:
OPENEJB-1076 Allow end users to use ciphered passwords in datasource configuration (openejb.xml)

Added:
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/PasswordCodec.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/PlainTextPasswordCodec.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/StaticDESPasswordCodec.java
Modified:
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/BasicDataSource.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/BasicManagedDataSource.java

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/BasicDataSource.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/BasicDataSource.java?rev=818889&r1=818888&r2=818889&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/BasicDataSource.java
(original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/BasicDataSource.java
Fri Sep 25 15:50:58 2009
@@ -17,16 +17,48 @@
  */
 package org.apache.openejb.resource.jdbc;
 
-import org.apache.openejb.loader.SystemInstance;
-
-import javax.sql.DataSource;
+import java.io.File;
 import java.sql.SQLException;
 import java.util.Properties;
-import java.util.Map;
-import java.util.HashMap;
-import java.io.File;
+
+import javax.sql.DataSource;
+
+import org.apache.commons.dbcp.SQLNestedException;
+import org.apache.openejb.loader.SystemInstance;
 
 public class BasicDataSource extends org.apache.commons.dbcp.BasicDataSource {
+    
+    /**
+     * The password codec to be used to retrieve the plain text password from a
+     * ciphered value.
+     * 
+     * <em>The default is no codec.</em>. In other words, it means password is
+     * not ciphered. The {@link PlainTextPasswordCodec} can also be used.
+     */
+    private String passwordCodecClass = null;
+
+    /**
+     * Returns the password codec class name to use to retrieve plain text
+     * password.
+     * 
+     * @return the password codec class
+     */
+    public synchronized String getPasswordCodecClass() {
+        return this.passwordCodecClass;
+    }
+
+    /**
+     * <p>
+     * Sets the {@link #passwordCodecClass}.
+     * </p>
+     * 
+     * @param passwordCodecClass
+     *            password codec value
+     */
+    public synchronized void setPasswordCodecClass(String passwordCodecClass) {
+        this.passwordCodecClass = passwordCodecClass;
+    }
+    
 
     public synchronized String getUserName() {
         return super.getUsername();
@@ -35,7 +67,7 @@
     public synchronized void setUserName(String string) {
         super.setUsername(string);
     }
-
+    
     public synchronized String getJdbcDriver() {
         return super.getDriverClassName();
     }
@@ -62,6 +94,15 @@
         if (dataSource != null) {
             return dataSource;
         }
+        
+        // check password codec if available
+        if (null != passwordCodecClass) {
+            PasswordCodec codec = getPasswordCodec();
+            String plainPwd = codec.decode(password.toCharArray());
+
+            // override previous password value
+            super.setPassword(plainPwd);
+        }
 
         // get the plugin
         DataSourcePlugin helper = BasicDataSourceUtil.getDataSourcePlugin(getUrl());
@@ -89,4 +130,45 @@
             }
         }
     }
+    
+    /**
+     * Create a {@link PasswordCodec} instance from the
+     * {@link #passwordCodecClass}.
+     * 
+     * @return the password codec from the {@link #passwordCodecClass}
+     *         optionally set.
+     * @throws SQLException
+     *             if the driver can not be found.
+     */
+    private PasswordCodec getPasswordCodec() throws SQLException {
+        // Load the password codec class
+        Class pwdCodec = null;
+        try {
+            try {
+                pwdCodec = Class.forName(passwordCodecClass);
+
+            } catch (ClassNotFoundException cnfe) {
+                pwdCodec = Thread.currentThread().getContextClassLoader().loadClass(passwordCodecClass);
+            }
+        } catch (Throwable t) {
+            String message = "Cannot load password codec class '" + passwordCodecClass +
"'";
+            logWriter.println(message);
+            t.printStackTrace(logWriter);
+            throw new SQLNestedException(message, t);
+        }
+
+        // Create an instance
+        PasswordCodec codec = null;
+        try {
+            codec = (PasswordCodec) pwdCodec.newInstance();
+
+        } catch (Throwable t) {
+            String message = "Cannot create password codec instance";
+            logWriter.println(message);
+            t.printStackTrace(logWriter);
+            throw new SQLNestedException(message, t);
+        }
+
+        return codec;
+    }
 }

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/BasicManagedDataSource.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/BasicManagedDataSource.java?rev=818889&r1=818888&r2=818889&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/BasicManagedDataSource.java
(original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/BasicManagedDataSource.java
Fri Sep 25 15:50:58 2009
@@ -23,9 +23,42 @@
 
 import javax.sql.DataSource;
 
+import org.apache.commons.dbcp.SQLNestedException;
 import org.apache.openejb.loader.SystemInstance;
 
 public class BasicManagedDataSource extends org.apache.commons.dbcp.managed.BasicManagedDataSource
{
+    
+    /**
+     * The password codec to be used to retrieve the plain text password from a
+     * ciphered value.
+     * 
+     * <em>The default is no codec.</em>. In other words, it means password is
+     * not ciphered. The {@link PlainTextPasswordCodec} can also be used.
+     */
+    private String passwordCodecClass = null;
+
+    /**
+     * Returns the password codec class name to use to retrieve plain text
+     * password.
+     * 
+     * @return the password codec class
+     */
+    public synchronized String getPasswordCodecClass() {
+        return this.passwordCodecClass;
+    }
+
+    /**
+     * <p>
+     * Sets the {@link #passwordCodecClass}.
+     * </p>
+     * 
+     * @param passwordCodecClass
+     *            password codec value
+     */
+    public synchronized void setPasswordCodecClass(String passwordCodecClass) {
+        this.passwordCodecClass = passwordCodecClass;
+    }
+    
     public synchronized String getUserName() {
         return super.getUsername();
     }
@@ -60,6 +93,15 @@
         if (dataSource != null) {
             return dataSource;
         }
+        
+        // check password codec if available
+        if (null != passwordCodecClass) {
+            PasswordCodec codec = getPasswordCodec();
+            String plainPwd = codec.decode(password.toCharArray());
+
+            // override previous password value
+            super.setPassword(plainPwd);
+        }
 
         // get the plugin
         DataSourcePlugin helper = BasicDataSourceUtil.getDataSourcePlugin(getUrl());
@@ -91,5 +133,46 @@
 
     protected void wrapTransactionManager() {
     }
+    
+    /**
+     * Create a {@link PasswordCodec} instance from the
+     * {@link #passwordCodecClass}.
+     * 
+     * @return the password codec from the {@link #passwordCodecClass}
+     *         optionally set.
+     * @throws SQLException
+     *             if the driver can not be found.
+     */
+    private PasswordCodec getPasswordCodec() throws SQLException {
+        // Load the password codec class
+        Class pwdCodec = null;
+        try {
+            try {
+                pwdCodec = Class.forName(passwordCodecClass);
+
+            } catch (ClassNotFoundException cnfe) {
+                pwdCodec = Thread.currentThread().getContextClassLoader().loadClass(passwordCodecClass);
+            }
+        } catch (Throwable t) {
+            String message = "Cannot load password codec class '" + passwordCodecClass +
"'";
+            logWriter.println(message);
+            t.printStackTrace(logWriter);
+            throw new SQLNestedException(message, t);
+        }
+
+        // Create an instance
+        PasswordCodec codec = null;
+        try {
+            codec = (PasswordCodec) pwdCodec.newInstance();
+
+        } catch (Throwable t) {
+            String message = "Cannot create password codec instance";
+            logWriter.println(message);
+            t.printStackTrace(logWriter);
+            throw new SQLNestedException(message, t);
+        }
+
+        return codec;
+    }
 
 }

Added: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/PasswordCodec.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/PasswordCodec.java?rev=818889&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/PasswordCodec.java
(added)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/PasswordCodec.java
Fri Sep 25 15:50:58 2009
@@ -0,0 +1,53 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openejb.resource.jdbc;
+
+/**
+ * Implementations of {@link PasswordCodec} allow to encode and decode passwords
+ * used to connect to a database.
+ * <p/>
+ * Several implementations may exist, as several encryption algorithms may be
+ * supported. One-way encryption algorithm (hash) can't be used as we need to
+ * give a plain password to the database. {@link #encode(String)} method is not
+ * mandatory as we don't need to encode a password, but it's useful to get the
+ * encrypted value for a given plain text password. In the case you have
+ * implemented both methods, you can use the PasswordCodec command line tool to
+ * encode/decode a password.
+ */
+public interface PasswordCodec {
+
+    /**
+     * Encodes a given plain text password and returns the encoded password.
+     * 
+     * @param plainPassword
+     *            The password to encode. May not be <code>null</code>, nor empty.
+     * @return The encoded password.
+     */
+    public char[] encode(String plainPassword);
+
+    /**
+     * Decodes an encoded password and returns a plain text password.
+     * 
+     * @param encodedPassword
+     *            The ciphered password to decode. May not be <code>null</code>,
+     *            nor empty.
+     * @return The plain text password.
+     */
+    public String decode(char[] encodedPassword);
+
+}

Added: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/PlainTextPasswordCodec.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/PlainTextPasswordCodec.java?rev=818889&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/PlainTextPasswordCodec.java
(added)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/PlainTextPasswordCodec.java
Fri Sep 25 15:50:58 2009
@@ -0,0 +1,58 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openejb.resource.jdbc;
+
+/**
+ * This {@link PlainTextPasswordCodec} is an {@link PasswordCodec}
+ * implementation that does not use any encryption/decryption algorithm at all.
+ */
+public class PlainTextPasswordCodec implements PasswordCodec {
+
+    /**
+     * Returns the <code>encodedPassword</code> as plain text string.
+     * 
+     * @param encodedPassword
+     *            the encoded password
+     * @return String the decoded password
+     * 
+     * @see PasswordCodec#decode(char[])
+     */
+    public String decode(char[] encodedPassword) {
+        if (null == encodedPassword) {
+            throw new IllegalArgumentException("encodedPassword cannot be null.");
+        }
+        return new String(encodedPassword);
+    }
+
+    /**
+     * Returns the <code>plainPassword</code> as plain text character array.
+     * 
+     * @param plainPassword
+     *            the plain-text password
+     * @return the plain-text password as character array
+     * 
+     * @see PasswordCodec#encode(java.lang.String)
+     */
+    public char[] encode(String plainPassword) {
+        if (null == plainPassword) {
+            throw new IllegalArgumentException("plainPassword cannot be null.");
+        }
+        return plainPassword.toCharArray();
+    }
+
+}

Added: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/StaticDESPasswordCodec.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/StaticDESPasswordCodec.java?rev=818889&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/StaticDESPasswordCodec.java
(added)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/StaticDESPasswordCodec.java
Fri Sep 25 15:50:58 2009
@@ -0,0 +1,99 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openejb.resource.jdbc;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.apache.openejb.util.Base64;
+
+/**
+ * This {@link PasswordCodec} implementation uses a the Triple-DES encryption
+ * algorithm.
+ */
+public class StaticDESPasswordCodec implements PasswordCodec {
+
+    private static final byte[] _3desData = { 
+            (byte) 0x76, (byte) 0x6F, (byte) 0xBA, (byte) 0x39, (byte) 0x31, 
+            (byte) 0x2F, (byte) 0x0D, (byte) 0x4A, (byte) 0xA3, (byte) 0x90, 
+            (byte) 0x55, (byte) 0xFE, (byte) 0x55, (byte) 0x65, (byte) 0x61, 
+            (byte) 0x13, (byte) 0x34, (byte) 0x82, (byte) 0x12, (byte) 0x17, 
+            (byte) 0xAC, (byte) 0x77, (byte) 0x39, (byte) 0x19 };
+
+    private static final SecretKeySpec KEY = new SecretKeySpec(_3desData, "DESede");
+
+    /**
+     * The name of the transformation defines Triple-DES encryption
+     */
+    private static final String TRANSFORMATION = new String("DESede");
+
+    /**
+     * @see PasswordCodec#encode(java.lang.String)
+     * @throws RuntimeException
+     *             in any case of error.
+     */
+    public char[] encode(String plainPassword) {
+        if ((null == plainPassword) || plainPassword.length() == 0) {
+            throw new IllegalArgumentException("plainPassword cannot be null nor empty.");
+        }
+
+        byte[] plaintext = plainPassword.getBytes();
+        try {
+            // Get a 3DES Cipher object
+            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
+            // Set it into encryption mode
+            cipher.init(Cipher.ENCRYPT_MODE, KEY);
+
+            // Encrypt data
+            byte[] cipherText = cipher.doFinal(plaintext);
+            return new String(Base64.encodeBase64(cipherText)).toCharArray();
+
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * @see PasswordCodec#decode(char[])
+     * @throws RuntimeException
+     *             in any case of error.
+     */
+    public String decode(char[] encodedPassword) {
+        if ((null == encodedPassword) || encodedPassword.length == 0) {
+            throw new IllegalArgumentException("encodedPassword cannot be null nor empty.");
+        }
+
+        try {
+            byte[] cipherText = Base64.decodeBase64(
+                    String.valueOf(encodedPassword).getBytes());
+
+            // Get a 3DES Cipher object
+            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
+            // Set it into decryption mode
+            cipher.init(Cipher.DECRYPT_MODE, KEY);
+
+            // Decrypt data
+            String plainText = new String(cipher.doFinal(cipherText));
+            return plainText;
+
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+}



Mime
View raw message