do not log passwords

main
Jörg Prante 2 years ago
parent 7378b91c28
commit 6127f11914

@ -379,7 +379,7 @@ public class Pool implements BagStateListener {
}
/**
* Recycle PoolEntry (add back to the pool)
* Recycle PoolEntry, add back to the pool.
*
* @param poolEntry the PoolEntry to recycle
*/
@ -957,7 +957,7 @@ public class Pool implements BagStateListener {
writeMethod.invoke(target, Class.forName(propValue.toString()).getDeclaredConstructor().newInstance());
} catch (InstantiationException | ClassNotFoundException e) {
logger.log(Level.FINE, () ->
MessageFormat.format("class not found or could not instantiate it (Default constructor): {0}",
MessageFormat.format("class not found or could not instantiate it (default constructor): {0}",
propValue));
writeMethod.invoke(target, propValue);
}

@ -567,11 +567,11 @@ public class PoolConfig {
this.threadFactory = threadFactory;
}
private Class<?> attemptFromContextLoader(final String driverClassName) {
final ClassLoader threadContextClassLoader = Thread.currentThread().getContextClassLoader();
private Class<?> attemptFromContextLoader(String driverClassName) {
ClassLoader threadContextClassLoader = Thread.currentThread().getContextClassLoader();
if (threadContextClassLoader != null) {
try {
final Class<?> driverClass = threadContextClassLoader.loadClass(driverClassName);
Class<?> driverClass = threadContextClassLoader.loadClass(driverClassName);
logger.log(Level.FINE, "Driver class found in Thread context class loader:" +
driverClassName + " " + threadContextClassLoader);
return driverClass;
@ -580,7 +580,6 @@ public class PoolConfig {
driverClassName + " " + threadContextClassLoader + " " + this.getClass().getClassLoader());
}
}
return null;
}
@ -622,7 +621,7 @@ public class PoolConfig {
/**
* @return null if string is null or empty
*/
private static String getNullIfEmpty(final String text) {
private static String getNullIfEmpty(String text) {
return text == null ? null : text.trim().isEmpty() ? null : text.trim();
}

@ -40,7 +40,7 @@ public class PoolEntry implements BagEntry {
private final boolean isAutoCommit;
public PoolEntry(Connection connection, Pool pool, final boolean isReadOnly, final boolean isAutoCommit) {
public PoolEntry(Connection connection, Pool pool, boolean isReadOnly, boolean isAutoCommit) {
this.connection = connection;
this.pool = pool;
this.isReadOnly = isReadOnly;
@ -70,7 +70,7 @@ public class PoolEntry implements BagEntry {
*
* @param lastAccessed last access time-stamp
*/
public void recycle(final long lastAccessed) {
public void recycle(long lastAccessed) {
if (connection != null) {
this.lastAccessed = lastAccessed;
pool.recycle(this);
@ -82,11 +82,11 @@ public class PoolEntry implements BagEntry {
*
* @param endOfLife this PoolEntry/Connection's end of life {@link ScheduledFuture}
*/
public void setFutureEol(final ScheduledFuture<?> endOfLife) {
public void setFutureEol(ScheduledFuture<?> endOfLife) {
this.endOfLife = endOfLife;
}
public Connection createProxyConnection(final ProxyLeakTask leakTask, final long now) {
public Connection createProxyConnection(ProxyLeakTask leakTask, long now) {
return ProxyFactory.getProxyConnection(this, connection, openStatements, leakTask, now, isReadOnly, isAutoCommit);
}
@ -102,7 +102,7 @@ public class PoolEntry implements BagEntry {
this.evict = true;
}
public void evict(final String closureReason) {
public void evict(String closureReason) {
pool.closeConnection(this, closureReason);
}

@ -17,15 +17,15 @@ import java.util.stream.Collectors;
* This is a specialized concurrent bag that achieves superior performance
* to {@link java.util.concurrent.LinkedBlockingQueue} and
* {@link java.util.concurrent.LinkedTransferQueue} for the purposes of a
* connection pool. It uses {@link ThreadLocal} storage when possible to avoid
* connection pool. It uses {@link ThreadLocal} storage when possible to avoid
* locks, but resorts to scanning a common collection if there are no
* available items in the {@link ThreadLocal} list. Not-in-use items in the
* available items in the {@link ThreadLocal} list. Not-in-use items in the
* {@link ThreadLocal} lists can be "stolen" when the borrowing thread has none
* of its own. It is a "lock-less" implementation using a specialized
* of its own. It is a "lock-less" implementation using a specialized
* {@link AbstractQueuedLongSynchronizer} to manage cross-thread signaling.
* Note that items that are "borrowed" from the bag are not actually
* removed from any collection, so garbage collection will not occur
* even if the reference is abandoned. Thus care must be taken to
* even if the reference is abandoned. Thus care must be taken to
* {@link Bag#requite(T)} borrowed objects otherwise a memory leak will result.
* Only the {@link Bag#remove(T)} method can completely remove an object.
*

@ -143,9 +143,15 @@ public interface ClockSource {
return sb.toString();
}
TimeUnit[] TIMEUNITS_DESCENDING = {TimeUnit.DAYS, TimeUnit.HOURS, TimeUnit.MINUTES,
TimeUnit.SECONDS, TimeUnit.MILLISECONDS, TimeUnit.MICROSECONDS,
TimeUnit.NANOSECONDS};
TimeUnit[] TIMEUNITS_DESCENDING = {
TimeUnit.DAYS,
TimeUnit.HOURS,
TimeUnit.MINUTES,
TimeUnit.SECONDS,
TimeUnit.MILLISECONDS,
TimeUnit.MICROSECONDS,
TimeUnit.NANOSECONDS
};
String[] TIMEUNIT_DISPLAY_VALUES = {"ns", "µs", "ms", "s", "m", "h", "d"};

@ -78,16 +78,16 @@ public class DriverDataSource implements DataSource {
}
}
}
final String sanitizedUrl = jdbcUrl.replaceAll("([?&;]password=)[^&#;]*(.*)", "$1<masked>$2");
final String sanitizedUrl = jdbcUrl.replaceAll("([?&;][^&#;=]*[pP]assword=)[^&#;]*", "$1<masked>");
try {
if (driver == null) {
driver = DriverManager.getDriver(jdbcUrl);
logger.fine("Loaded driver with class name for jdbcUrl: " + driver.getClass().getName() + " " + sanitizedUrl);
logger.fine("Loaded driver with class name for jdbcUrl " + driver.getClass().getName() + " " + sanitizedUrl);
} else if (!driver.acceptsURL(jdbcUrl)) {
throw new RuntimeException("Driver " + driverClassName + " claims to not accept jdbcUrl, " + sanitizedUrl);
throw new RuntimeException("Driver " + driverClassName + " claims to not accept jdbcUrl " + sanitizedUrl);
}
} catch (SQLException e) {
throw new RuntimeException("Failed to get driver instance for jdbcUrl=" + sanitizedUrl, e);
throw new RuntimeException("Failed to get driver instance for jdbcUrl " + sanitizedUrl, e);
}
}

@ -0,0 +1,44 @@
package org.xbib.io.pool.jdbc;
import org.junit.jupiter.api.Test;
import org.xbib.jdbc.connection.pool.util.DriverDataSource;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
public class DriverDataSourceTest {
@Test
public void testJdbcUrlLogging() {
List<String> urls = Arrays.asList(
"jdbc:invalid://host/d_dlq?user=USER&password=SECRET",
"jdbc:invalid://host/d_dlq?user=USER&truststorePassword=SECRET",
"jdbc:invalid://host/d_dlq?a=b&password=SECRET&user=USER",
"jdbc:invalid://host/d_dlq?a=b&sslpassword=SECRET&user=USER",
"jdbc:invalid://host/d_dlq?a=b&sslpassword=SECRET&password=SECRET&user=USER",
"jdbc:invalid://host/d_dlq?truststorePassword=SECRET;user=USER&password=SECRET#extra",
"jdbc:invalid://host/d_dlq?sslpassword=SECRET&password=SECRET&trustPassword=SECRET&user=USER",
"jdbc:invalid://host/d_dlq?password=SECRET#user=USER;extra"
);
for (String url : urls) {
testExceptionMessage(url);
}
}
private void testExceptionMessage(String jdbcUrl) {
try {
new DriverDataSource(jdbcUrl, null, new Properties(), null, null);
fail();
} catch (RuntimeException e) {
String msg = e.getMessage();
assertTrue(msg.contains("jdbc:invalid://host/d_dlq"));
assertTrue(msg.contains("user=USER"));
assertFalse(msg.contains("SECRET"));
}
}
}
Loading…
Cancel
Save