Monday, April 26, 2010

Encrypting your jndi data source in Tomcat

I was shocked to discover at my new gig that the database password that Tomcat loaded up into JNDI were not encrypted on the live site.  I was even more shocked that Tomcat does not provide a quick fix for this.

So here's mine.  Encode the password in your text file, and figure out where the below goes in your code:


    /**
     * Get a DataSource for the given JNDI name (with caching of lookups)
     *
     * @param dataSourceJNDIName The DataSource name
     * @return A DataSource for JNDI name 'dataSourceJNDIName', or null if the
     * lookup fails.
     */
    public static DataSource getDataSource(String dataSourceJNDIName)
    {
        DataSource dataSource = null;
        if (null != dataSourceJNDIName) {
            dataSource = (DataSource)dataSourceCache.get(dataSourceJNDIName);
            if (null == dataSource) {
                try {
                    dataSource = (DataSource) jndiContext.lookup(JNDI_PREFIX + dataSourceJNDIName);
                    //cast the datasource to the Apache BasicDataSource class
                    BasicDataSource bds=(BasicDataSource)dataSource;
                    //decrypt the password
                    bds.setPassword(EncryptionHelper.decode(bds.getPassword()));

                    Logs.debug(JNDI_PREFIX + dataSourceJNDIName + " returns " + dataSource);
                    if (null != dataSource) {
                        dataSourceCache.put(dataSourceJNDIName, dataSource);
                    }
                } catch (NamingException name) {
                    Logs.error("Naming exception (" + name + ") on lookup of '"
                        + dataSourceJNDIName + "'.");
                }
            }
        }
        return dataSource;
    }