Connection to PgSQL does not use SSL with JDBC driver 9.4 if the parameter is passed through Properties rather than URL

From: Matthieu SANCHEZ <msanchez(at)magellanset(dot)com>
To: "pgsql-jdbc(at)postgresql(dot)org" <pgsql-jdbc(at)postgresql(dot)org>
Subject: Connection to PgSQL does not use SSL with JDBC driver 9.4 if the parameter is passed through Properties rather than URL
Date: 2016-01-15 10:18:36
Message-ID: VI1PR06MB147240A60DDC3F6C5BF4485ED3CD0@VI1PR06MB1472.eurprd06.prod.outlook.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-jdbc

Greetings,

I found an issue with JDBC driver postgresql-9.4.1207.jre7 involving SSL connections.

First the context. In order to enforce TLSv1.2 connection, i extend the PostgreSQL driver in order to set properties by default :

public class SecurePostgresqlDriver extends Driver {
@Override
public Connection connect(String url, Properties info) throws SQLException {
info.setProperty(PGProperty.SSL.getName(), "true");
info.setProperty(PGProperty.SSL_FACTORY.getName(), SecurePostgresqlSocketFactory.class.getCanonicalName());
return super.connect(url, info);
}
}

But this leads me to an exception:

org.postgresql.util.PSQLException: FATAL: no pg_hba.conf entry for host "127.0.0.1", user "xxx", database "xxx", SSL off
at org.postgresql.core.v3.ConnectionFactoryImpl.doAuthentication(ConnectionFactoryImpl.java:427)
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:203)
at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:65)
at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:159)
at org.postgresql.Driver.makeConnection(Driver.java:415)
at org.postgresql.Driver.connect(Driver.java:283)
at SecurePostgresqlDriver.connect(SecurePostgresqlDriver.java:21)

For the note, using the default org.postgresql.Driver class and adding "?ssl=true&sslfactory=SecurePostgresqlSocketFactory" at the end of the URL works.

I did a little debbuging, and this is what i found.

- org.postgresql.Driver.connect(String, Properties) calls the parseURL(String, Properties) method at line 264, which creates a new Properties instance with the paramater one as default (Driver :537)

- This new instance overrides the original one on this same line. So from now on my SSL and SSL_FACTORY are default properties of the current one. If the parameters were passed through URL, they would be actual properties rather than default ones.

- This instance is passed to the PgConnection, which passes it to the ConnectionFactory, which passes it to the ConnectionFactoryImpl.

- org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(HostSpec[], String, String, Properties, Logger) checks the SSL property at line 74 by calling PGProperty.isPresent(Properties)

- org.postgresql.PGProperty.isPresent(Properties) calls the getSetString(Properties) method at line 468, but this method does not check default properties.

- My SSL and SSL_FACTORY properties are ignored since they are default ones, and thus a non-SSL connection is opened.

Hence i have two questions :

- Do SSL and SSL_FACTORY properties have to be passed through URL ?

- If not, can you please patch this ? :)

Best regards,
Matthieu SANCHEZ

Responses

Browse pgsql-jdbc by date

  From Date Subject
Next Message Vladimir Sitnikov 2016-01-15 10:24:30 Re: Connection to PgSQL does not use SSL with JDBC driver 9.4 if the parameter is passed through Properties rather than URL
Previous Message Sehrope Sarkuni 2016-01-14 23:34:14 Re: Maven Artifact JDK Suffix