views:

3393

answers:

5

The resource definition in tomcat's server.xml looks something like this...

<Resource
name="jdbc/tox"
scope="Shareable"
type="javax.sql.DataSource"
url="jdbc:oracle:thin:@yourDBserver.yourCompany.com:1521:yourDBsid"
driverClassName="oracle.jdbc.pool.OracleDataSource"
username="tox"
password="toxbaby"
maxIdle="3"
maxActive="10"
removeAbandoned="true"
removeAbandonedTimeout="60"
testOnBorrow="true"
validationQuery="select * from dual"
logAbandoned="true"
debug="99"/>

The password is in the clear. How to avoid this?

A: 

This question has also come up a few times on tomcat-user, where server.xml has the problem (JNDI DataSource configuration requires plain text database password).

AFAIK, prior to Tomcat 6.0, the only option is to develop your own custom JNDI Resource that does the crpto or obfuscates the database password in code and work directly with dbcp to set up the connections. Key management will be a pain. Unless you want a human to have to enter a password to "unlock" the crypto key at startup time, the encryption key has to be stored somewhere.

In Tomcat 6.0 you can see the documentation about Digested Passwords [1] . Not sure about if that also applies to Datasources.

[1]: http://tomcat.apache.org/tomcat-6.0-doc/realm-howto.html#Digested Passwords

Guido
The Digested Passwords reference there has nothing to do with datasource passwords.
Sindri Traustason
A: 

We use C#'s SHA1CryptoServiceProvider

print(SHA1CryptoServiceProvider sHA1Hasher = new SHA1CryptoServiceProvider();
        ASCIIEncoding enc = new ASCIIEncoding();

        byte[] arrbytHashValue = sHA1Hasher.ComputeHash(enc.GetBytes(clearTextPW));
        string HashData = System.BitConverter.ToString(arrbytHashValue);
        HashData = HashData.Replace("-", "");
        if (HashData == databaseHashedPassWO)
        {
            return true;
        }
        else
        {
            return false;
        });

)

Brad8118
Not sure what this has to do with tomcat config files.
dacracot
+2  A: 

Tomcat needs to know how to connect to the database, so it needs access to the plain text password. If the password in encrypted, Tomcat needs to know how to decrypt it, so you are only moving the problem somewhere else.

The real problem is: who can access server.xml except for Tomcat? A solution is to give read access to server.xml only to root user, requiring that Tomcat is started with root privileges: if a malicious user gains root privileges on the system, losing a database password is probably a minor concern.

Otherwise you should type the password manually at every startup, but this is seldom a viable option.

gameame
+4  A: 

As said before encrypting passwords is just moving the problem somewhere else.

Anyway, it's quite simple. Just write a class with static fields for your secret key and so on, and static methods to encrypt, decrypt your passwords. Encrypt your password in Tomcat's configuration file (server.xml or yourapp.xml...) using this class.

And to decrypt the password "on the fly" in Tomcat, extend the DBCP's BasicDataSourceFactory and use this factory in your resource.

It will look like:

    <Resource
     name="jdbc/myDataSource"
     auth="Container"
     type="javax.sql.DataSource"
     username="user"
     password="encryptedpassword"
     driverClassName="driverClass"
     factory="mypackage.MyCustomBasicDataSourceFactory"
     url="jdbc:blabla://..."/>

And for the custom factory:

package mypackage;

....

public class MyCustomBasicDataSourceFactory extends org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory {

@Override
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) throws Exception {
 Object o = super.getObjectInstance(obj, name, nameCtx, environment);
 if (o != null) {
  BasicDataSource ds = (BasicDataSource) o;
  if (ds.getPassword() != null && ds.getPassword().length() > 0) {
   String pwd = MyPasswordUtilClass.unscramblePassword(ds.getPassword());
   ds.setPassword(pwd);
  }
  return ds;
 } else {
  return null;
 }
}

Hope this helps.

Jerome Delattre
A: 

I agree with Jerome Delattre, that a solution. I used that with success. It is the same aproach of : http://java.sys-con.com/node/393364