Index: org/postgresql/Driver.java.in =================================================================== RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/Driver.java.in,v retrieving revision 1.48 diff -c -r1.48 Driver.java.in *** org/postgresql/Driver.java.in 10 Oct 2004 15:39:30 -0000 1.48 --- org/postgresql/Driver.java.in 15 Oct 2004 03:03:04 -0000 *************** *** 189,194 **** --- 189,198 ---- "Force use of a particular protocol version when connecting; if set, disables protocol version fallback.", }, { "ssl", Boolean.FALSE, "Control use of SSL; any nonnull value causes SSL to be required." }, + { "sslfactory", Boolean.FALSE, + "Provide a SSLSocketFactory class when using SSL." }, + { "sslfactoryargs", Boolean.FALSE, + "Arguments forwarded to constructor of SSLSocketFactory class;in addition to url." }, { "logLevel", Boolean.FALSE, "Control the driver's log verbosity: 0 is off, 1 is INFO, 2 is DEBUG.", new String[] { "0", "1", "2" } }, *************** *** 413,418 **** --- 417,425 ---- } } + //needed for a custom SSLSocketFactory in ConnectionFactoryImpl + urlProps.put("&urlServer&",l_urlServer); + return urlProps; } *************** *** 524,533 **** } ! public static void makeSSL(org.postgresql.core.PGStream p_stream) throws IOException { @SSL@ if (logDebug) @SSL@ debug("converting regular socket connection to ssl"); ! @SSL@ javax.net.ssl.SSLSocketFactory factory = (javax.net.ssl.SSLSocketFactory) javax.net.ssl.SSLSocketFactory.getDefault(); @SSL@ java.net.Socket newConnection = factory.createSocket(p_stream.getSocket(), p_stream.getHost(), p_stream.getPort(), true); @SSL@ p_stream.changeSocket(newConnection); } --- 531,540 ---- } ! public static void makeSSL(org.postgresql.core.PGStream p_stream, Object factory_o) throws IOException { @SSL@ if (logDebug) @SSL@ debug("converting regular socket connection to ssl"); ! @SSL@ javax.net.ssl.SSLSocketFactory factory = (javax.net.ssl.SSLSocketFactory) factory_o; @SSL@ java.net.Socket newConnection = factory.createSocket(p_stream.getSocket(), p_stream.getHost(), p_stream.getPort(), true); @SSL@ p_stream.changeSocket(newConnection); } Index: org/postgresql/core/v2/ConnectionFactoryImpl.java =================================================================== RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/core/v2/ConnectionFactoryImpl.java,v retrieving revision 1.3 diff -c -r1.3 ConnectionFactoryImpl.java *** org/postgresql/core/v2/ConnectionFactoryImpl.java 10 Oct 2004 15:39:35 -0000 1.3 --- org/postgresql/core/v2/ConnectionFactoryImpl.java 15 Oct 2004 03:03:04 -0000 *************** *** 68,74 **** // Construct and send an ssl startup packet if requested. if (trySSL) ! newStream = enableSSL(newStream, requireSSL); // Construct and send a startup packet. sendStartupPacket(newStream, user, database); --- 68,74 ---- // Construct and send an ssl startup packet if requested. if (trySSL) ! newStream = enableSSL(newStream, requireSSL, info); // Construct and send a startup packet. sendStartupPacket(newStream, user, database); *************** *** 107,113 **** } } ! private PGStream enableSSL(PGStream pgStream, boolean requireSSL) throws IOException, SQLException { if (Driver.logDebug) Driver.debug(" FE=> SSLRequest"); --- 107,113 ---- } } ! private PGStream enableSSL(PGStream pgStream, boolean requireSSL, Properties info) throws IOException, SQLException { if (Driver.logDebug) Driver.debug(" FE=> SSLRequest"); *************** *** 147,153 **** Driver.debug(" <=BE SSLOk"); // Server supports ssl ! Driver.makeSSL(pgStream); return pgStream; default: --- 147,153 ---- Driver.debug(" <=BE SSLOk"); // Server supports ssl ! Driver.makeSSL(pgStream,getSSLSocketFactory(info)); return pgStream; default: *************** *** 155,160 **** --- 155,186 ---- } } + private javax.net.ssl.SSLSocketFactory getSSLSocketFactory(Properties info) throws SQLException { + // If the url contains no class, return the default factory + String classname = info.getProperty("sslfactory"); + if (classname==null) + return (javax.net.ssl.SSLSocketFactory)javax.net.ssl.SSLSocketFactory.getDefault();; + + // those are passed to the provided class if a fitting constructor is found + Object[] args = { info.getProperty("&urlServer&"), info.getProperty("sslfactoryargs") }; + java.lang.reflect.Constructor ctor; + Class factory_class; + + // get the (String,String) constructor and use () if that fails + try { + factory_class = Class.forName(classname); + try { + ctor = factory_class.getConstructor(new Class[] { String.class, String.class}); + } catch (NoSuchMethodException e) { + ctor = factory_class.getConstructor(null); + args = null; + } + return (javax.net.ssl.SSLSocketFactory)ctor.newInstance(args); + } catch (Exception e) { + throw new PSQLException(GT.tr("The SSLSocketFactory class provided in the connection URL could not be instantiated"), PSQLState.CONNECTION_FAILURE,e); + } + } + private void sendStartupPacket(PGStream pgStream, String user, String database) throws IOException { // 4: total size including self // 2: protocol major Index: org/postgresql/core/v3/ConnectionFactoryImpl.java =================================================================== RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/core/v3/ConnectionFactoryImpl.java,v retrieving revision 1.3 diff -c -r1.3 ConnectionFactoryImpl.java *** org/postgresql/core/v3/ConnectionFactoryImpl.java 10 Oct 2004 15:39:37 -0000 1.3 --- org/postgresql/core/v3/ConnectionFactoryImpl.java 15 Oct 2004 03:03:05 -0000 *************** *** 78,84 **** // Construct and send an ssl startup packet if requested. if (trySSL) ! newStream = enableSSL(newStream, requireSSL); // Construct and send a startup packet. String[][] params = { --- 78,84 ---- // Construct and send an ssl startup packet if requested. if (trySSL) ! newStream = enableSSL(newStream, requireSSL, info); // Construct and send a startup packet. String[][] params = { *************** *** 126,132 **** } } ! private PGStream enableSSL(PGStream pgStream, boolean requireSSL) throws IOException, SQLException { if (Driver.logDebug) Driver.debug(" FE=> SSLRequest"); --- 126,132 ---- } } ! private PGStream enableSSL(PGStream pgStream, boolean requireSSL, Properties info) throws IOException, SQLException { if (Driver.logDebug) Driver.debug(" FE=> SSLRequest"); *************** *** 166,172 **** Driver.debug(" <=BE SSLOk"); // Server supports ssl ! Driver.makeSSL(pgStream); return pgStream; default: --- 166,172 ---- Driver.debug(" <=BE SSLOk"); // Server supports ssl ! Driver.makeSSL(pgStream,getSSLSocketFactory(info)); return pgStream; default: *************** *** 174,179 **** --- 174,205 ---- } } + private javax.net.ssl.SSLSocketFactory getSSLSocketFactory(Properties info) throws SQLException { + // If the url contains no class, return the default factory + String classname = info.getProperty("sslfactory"); + if (classname==null) + return (javax.net.ssl.SSLSocketFactory)javax.net.ssl.SSLSocketFactory.getDefault();; + + // those are passed to the provided class if a fitting constructor is found + Object[] args = { info.getProperty("&urlServer&"), info.getProperty("sslfactoryargs") }; + java.lang.reflect.Constructor ctor; + Class factory_class; + + // get the (String,String) constructor and use () if that fails + try { + factory_class = Class.forName(classname); + try { + ctor = factory_class.getConstructor(new Class[] { String.class, String.class}); + } catch (NoSuchMethodException e) { + ctor = factory_class.getConstructor(null); + args = null; + } + return (javax.net.ssl.SSLSocketFactory)ctor.newInstance(args); + } catch (Exception e) { + throw new PSQLException(GT.tr("The SSLSocketFactory class provided in the connection URL could not be instantiated"), PSQLState.CONNECTION_FAILURE,e); + } + } + private void sendStartupPacket(PGStream pgStream, String[][] params) throws IOException { if (Driver.logDebug) { String details = "";