Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 1cc5516

Browse files
author
Barry Lind
committed
Added support for SSL in the jdbc driver
Modified Files: jdbc/build.xml jdbc/org/postgresql/Driver.java.in jdbc/org/postgresql/PG_Stream.java jdbc/org/postgresql/errors.properties jdbc/org/postgresql/jdbc1/AbstractJdbc1Connection.java jdbc/org/postgresql/util/PSQLException.java
1 parent 9ff872a commit 1cc5516

File tree

6 files changed

+159
-40
lines changed

6 files changed

+159
-40
lines changed

src/interfaces/jdbc/build.xml

+20-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
77
This file now requires Ant 1.4.1. 2002-04-18
88
9-
$Header: /cvsroot/pgsql/src/interfaces/jdbc/Attic/build.xml,v 1.31 2002/12/11 12:27:47 davec Exp $
9+
$Header: /cvsroot/pgsql/src/interfaces/jdbc/Attic/build.xml,v 1.32 2003/02/27 05:45:43 barry Exp $
1010
1111
-->
1212

@@ -22,6 +22,7 @@
2222
<property name="builddir" value="build" />
2323
<property name="package" value="org/postgresql" />
2424
<property name="debug" value="on" />
25+
<property name="ssl" value="false" />
2526

2627
<property file="build.properties"/>
2728

@@ -47,6 +48,7 @@
4748
<equals arg1="${ant.java.version}" arg2="1.4"/>
4849
</condition>
4950
<available property="datasource" classname="javax.sql.DataSource"/>
51+
<available property="ssl" classname="javax.net.ssl.SSLSocketFactory"/>
5052
<available property="junit" classname="junit.framework.Test" />
5153
<condition property="jdbc2tests">
5254
<and>
@@ -160,12 +162,27 @@
160162
<equals arg1="${jdbc3}" arg2="true"/>
161163
</condition>
162164

165+
<!-- determine the ssl status -->
166+
<condition property="ssl_config" value="">
167+
<equals arg1="${ssl}" arg2="true"/>
168+
</condition>
169+
<condition property="ssl_config" value="//">
170+
<equals arg1="${ssl}" arg2="false"/>
171+
</condition>
172+
<condition property="ssl_edition" value="SSL">
173+
<equals arg1="${ssl}" arg2="true"/>
174+
</condition>
175+
<condition property="ssl_edition" value="NO SSL">
176+
<equals arg1="${ssl}" arg2="false"/>
177+
</condition>
178+
163179
<!-- Some defaults -->
164180
<filter token="MAJORVERSION" value="${major}" />
165181
<filter token="MINORVERSION" value="${minor}" />
166-
<filter token="VERSION" value="PostgreSQL ${fullversion} ${edition}" />
182+
<filter token="VERSION" value="PostgreSQL ${fullversion} ${edition} with ${ssl_edition}" />
167183
<filter token="JDBCCONNECTCLASS" value="${connectclass}" />
168184
<filter token="DEF_PGPORT" value="${def_pgport}" />
185+
<filter token="SSL" value="${ssl_config}" />
169186

170187
<fail unless="major" message="'major' undefined. Please follow the directions in README."/>
171188
<fail unless="minor" message="'minor' undefined. Please follow the directions in README."/>
@@ -181,7 +198,7 @@
181198
tofile="${package}/Driver.java"
182199
filtering="yes" />
183200

184-
<echo message="Configured build for the ${edition} edition driver" />
201+
<echo message="Configured build for the ${edition} edition driver with ${ssl_edition}" />
185202
</target>
186203

187204

src/interfaces/jdbc/org/postgresql/Driver.java.in

+60-29
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.postgresql;
22

3+
import java.io.*;
34
import java.sql.*;
45
import java.util.*;
56

@@ -66,15 +67,17 @@ public class Driver implements java.sql.Driver
6667
*
6768
* user - (optional) The user to connect as
6869
* password - (optional) The password for the user
70+
* ssl - (optional) Use SSL when connecting to the server
6971
* charSet - (optional) The character set to be used for converting
7072
* to/from the database to unicode. If multibyte is enabled on the
7173
* server then the character set of the database is used as the default,
7274
* otherwise the jvm character encoding is used as the default.
73-
* loglevel - (optional) Enable logging of messages from the driver.
74-
* The value is an integer from 1 to 2 where:
75-
* INFO = 1, DEBUG = 2
76-
* The output is sent to DriverManager.getPrintWriter() if set,
77-
* otherwise it is sent to System.out.
75+
* This value is only used when connecting to a 7.2 or older server.
76+
* loglevel - (optional) Enable logging of messages from the driver.
77+
* The value is an integer from 1 to 2 where:
78+
* INFO = 1, DEBUG = 2
79+
* The output is sent to DriverManager.getPrintWriter() if set,
80+
* otherwise it is sent to System.out.
7881
* compatible - (optional) This is used to toggle
7982
* between different functionality as it changes across different releases
8083
* of the jdbc driver code. The values here are versions of the jdbc
@@ -136,8 +139,9 @@ public class Driver implements java.sql.Driver
136139
}
137140
catch (Exception ex2)
138141
{
139-
if (Driver.logDebug)
142+
if (Driver.logDebug) {
140143
Driver.debug("error", ex2);
144+
}
141145
throw new PSQLException("postgresql.unusual", ex2);
142146
}
143147
}
@@ -211,7 +215,7 @@ public class Driver implements java.sql.Driver
211215
*/
212216
public static String getVersion()
213217
{
214-
return "@VERSION@ jdbc driver build " + m_buildNumber;
218+
return "@VERSION@ (build " + m_buildNumber + ")";
215219
}
216220

217221
/*
@@ -248,7 +252,17 @@ public class Driver implements java.sql.Driver
248252
String key = "";
249253
String value = "";
250254

251-
StringTokenizer st = new StringTokenizer(url, ":/;=&?", true);
255+
String l_urlServer = url;
256+
String l_urlArgs = "";
257+
258+
int l_qPos = url.indexOf('?');
259+
if (l_qPos != -1) {
260+
l_urlServer = url.substring(0,l_qPos);
261+
l_urlArgs = url.substring(l_qPos+1);
262+
}
263+
264+
//parse the server part of the url
265+
StringTokenizer st = new StringTokenizer(l_urlServer, ":/", true);
252266
for (int count = 0; (st.hasMoreTokens()); count++)
253267
{
254268
String token = st.nextToken();
@@ -318,25 +332,19 @@ public class Driver implements java.sql.Driver
318332
urlProps.put("PGDBNAME", token);
319333
state = -2;
320334
}
321-
else if (state <= -2 && (count % 2) == 1)
322-
{
323-
// PM Aug 2 1997 - added tests for ? and &
324-
if (token.equals(";") || token.equals("?") || token.equals("&") )
325-
state = -3;
326-
else if (token.equals("="))
327-
state = -5;
328-
}
329-
else if (state <= -2 && (count % 2) == 0)
330-
{
331-
if (state == -3)
332-
key = token;
333-
else if (state == -5)
334-
{
335-
value = token;
336-
urlProps.put(key, value);
337-
state = -2;
338-
}
339-
}
335+
}
336+
}
337+
338+
//parse the args part of the url
339+
StringTokenizer qst = new StringTokenizer(l_urlArgs, "&");
340+
for (int count = 0; (qst.hasMoreTokens()); count++)
341+
{
342+
String token = qst.nextToken();
343+
int l_pos = token.indexOf('=');
344+
if (l_pos == -1) {
345+
urlProps.put(token, "");
346+
} else {
347+
urlProps.put(token.substring(0,l_pos), token.substring(l_pos+1));
340348
}
341349
}
342350

@@ -419,7 +427,10 @@ public class Driver implements java.sql.Driver
419427
{
420428
if (logDebug)
421429
{
422-
DriverManager.println(msg + ex != null ? ex.getMessage() : "null Exception");
430+
DriverManager.println(msg);
431+
if(ex != null) {
432+
DriverManager.println(ex.toString());
433+
}
423434
}
424435
}
425436
/*
@@ -441,10 +452,30 @@ public class Driver implements java.sql.Driver
441452
{
442453
if (logInfo)
443454
{
444-
DriverManager.println(msg + ex != null ? ex.getMessage() : "null Exception");
455+
DriverManager.println(msg);
456+
if(ex != null) {
457+
DriverManager.println(ex.toString());
458+
}
445459
}
446460
}
447461

462+
463+
public static void makeSSL(PG_Stream p_stream) throws IOException {
464+
@SSL@ if (logDebug)
465+
@SSL@ debug("converting regular socket connection to ssl");
466+
@SSL@ javax.net.ssl.SSLSocketFactory factory = (javax.net.ssl.SSLSocketFactory) javax.net.ssl.SSLSocketFactory.getDefault();
467+
@SSL@ p_stream.connection = (javax.net.ssl.SSLSocket) factory.createSocket(p_stream.connection,p_stream.host,p_stream.port,true);
468+
@SSL@ p_stream.pg_input = new BufferedInputStream(p_stream.connection.getInputStream(), 8192);
469+
@SSL@ p_stream.pg_output = new BufferedOutputStream(p_stream.connection.getOutputStream(), 8192);
470+
}
471+
472+
public static boolean sslEnabled() {
473+
boolean l_return = false;
474+
@SSL@ l_return = true;
475+
return l_return;
476+
}
477+
478+
448479
//The build number should be incremented for every new build
449480
private static int m_buildNumber = 201;
450481

src/interfaces/jdbc/org/postgresql/PG_Stream.java

+9-5
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import org.postgresql.util.*;
1111

1212
/*
13-
* $Id: PG_Stream.java,v 1.17 2002/08/20 04:26:02 barry Exp $
13+
* $Id: PG_Stream.java,v 1.18 2003/02/27 05:45:44 barry Exp $
1414
*
1515
* This class is used by Connection & PGlobj for communicating with the
1616
* backend.
@@ -20,9 +20,11 @@
2020
// This class handles all the Streamed I/O for a org.postgresql connection
2121
public class PG_Stream
2222
{
23-
private Socket connection;
24-
private InputStream pg_input;
25-
private BufferedOutputStream pg_output;
23+
public String host;
24+
public int port;
25+
public Socket connection;
26+
public InputStream pg_input;
27+
public BufferedOutputStream pg_output;
2628
private byte[] byte_buf = new byte[8*1024];
2729

2830
/*
@@ -33,8 +35,10 @@ public class PG_Stream
3335
* @param port the port number that the postmaster is sitting on
3436
* @exception IOException if an IOException occurs below it.
3537
*/
36-
public PG_Stream(String host, int port) throws IOException
38+
public PG_Stream(String p_host, int p_port) throws IOException
3739
{
40+
host = p_host;
41+
port = p_port;
3842
connection = new Socket(host, port);
3943

4044
// Submitted by Jason Venner <jason@idiom.com> adds a 10x speed

src/interfaces/jdbc/org/postgresql/errors.properties

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ postgresql.con.multres:Cannot handle multiple result groups.
1919
postgresql.con.pass:The password property is missing. It is mandatory.
2020
postgresql.con.refused:Connection refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
2121
postgresql.con.setup:Protocol error. Session setup failed.
22+
postgresql.con.sslfail:An error occured while getting setting up the SSL connection.
23+
postgresql.con.sslnotsupported:The server does not support SSL
2224
postgresql.con.strobj:The object could not be stored. Check that any tables required have already been created in the database.
2325
postgresql.con.strobjex:Failed to store object - {0}
2426
postgresql.con.toolong:The SQL Statement is too long - {0}

src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Connection.java

+67-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
import org.postgresql.util.*;
1515

1616

17-
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Connection.java,v 1.15 2003/02/05 11:12:39 davec Exp $
17+
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Connection.java,v 1.16 2003/02/27 05:45:44 barry Exp $
1818
* This class defines methods of the jdbc1 specification. This class is
1919
* extended by org.postgresql.jdbc2.AbstractJdbc2Connection which adds the jdbc2
2020
* methods. The real Connection class (for jdbc1) is org.postgresql.jdbc1.Jdbc1Connection
@@ -34,6 +34,7 @@ public PG_Stream getPGStream() {
3434
protected String PG_DATABASE;
3535
protected boolean PG_STATUS;
3636
protected String compatible;
37+
protected boolean useSSL;
3738

3839
// The PID an cancellation key we get from the backend process
3940
protected int pid;
@@ -100,7 +101,7 @@ public PG_Stream getPGStream() {
100101
* @exception SQLException if a database access error occurs
101102
*/
102103
public void openConnection(String host, int port, Properties info, String database, String url, org.postgresql.Driver d) throws SQLException
103-
{
104+
{
104105
firstWarning = null;
105106

106107
// Throw an exception if the user or password properties are missing
@@ -121,6 +122,15 @@ public void openConnection(String host, int port, Properties info, String databa
121122
PG_HOST = host;
122123
PG_STATUS = CONNECTION_BAD;
123124

125+
if (info.getProperty("ssl") != null && this_driver.sslEnabled())
126+
{
127+
useSSL = true;
128+
}
129+
else
130+
{
131+
useSSL = false;
132+
}
133+
124134
if (info.getProperty("compatible") == null)
125135
{
126136
compatible = d.getMajorVersion() + "." + d.getMinorVersion();
@@ -156,6 +166,11 @@ public void openConnection(String host, int port, Properties info, String databa
156166
//Print out the driver version number
157167
if (org.postgresql.Driver.logInfo)
158168
org.postgresql.Driver.info(org.postgresql.Driver.getVersion());
169+
if (org.postgresql.Driver.logDebug) {
170+
org.postgresql.Driver.debug(" ssl = " + useSSL);
171+
org.postgresql.Driver.debug(" compatible = " + compatible);
172+
org.postgresql.Driver.debug(" loglevel = " + l_logLevel);
173+
}
159174

160175
// Now make the initial connection
161176
try
@@ -174,6 +189,56 @@ public void openConnection(String host, int port, Properties info, String databa
174189
throw new PSQLException ("postgresql.con.failed", e);
175190
}
176191

192+
// Now we need to construct and send an ssl startup packet
193+
try
194+
{
195+
if (useSSL) {
196+
if (org.postgresql.Driver.logDebug)
197+
org.postgresql.Driver.debug("Asking server if it supports ssl");
198+
pg_stream.SendInteger(8,4);
199+
pg_stream.SendInteger(80877103,4);
200+
201+
// now flush the ssl packets to the backend
202+
pg_stream.flush();
203+
204+
// Now get the response from the backend, either an error message
205+
// or an authentication request
206+
int beresp = pg_stream.ReceiveChar();
207+
if (org.postgresql.Driver.logDebug)
208+
org.postgresql.Driver.debug("Server response was (S=Yes,N=No): "+(char)beresp);
209+
switch (beresp)
210+
{
211+
case 'E':
212+
// An error occured, so pass the error message to the
213+
// user.
214+
//
215+
// The most common one to be thrown here is:
216+
// "User authentication failed"
217+
//
218+
throw new PSQLException("postgresql.con.misc", pg_stream.ReceiveString(encoding));
219+
220+
case 'N':
221+
// Server does not support ssl
222+
throw new PSQLException("postgresql.con.sslnotsupported");
223+
224+
case 'S':
225+
// Server supports ssl
226+
if (org.postgresql.Driver.logDebug)
227+
org.postgresql.Driver.debug("server does support ssl");
228+
org.postgresql.Driver.makeSSL(pg_stream);
229+
break;
230+
231+
default:
232+
throw new PSQLException("postgresql.con.sslfail");
233+
}
234+
}
235+
}
236+
catch (IOException e)
237+
{
238+
throw new PSQLException("postgresql.con.failed", e);
239+
}
240+
241+
177242
// Now we need to construct and send a startup packet
178243
try
179244
{

src/interfaces/jdbc/org/postgresql/util/PSQLException.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public PSQLException(String error)
2727
*/
2828
public PSQLException(String error, Object[] args)
2929
{
30-
//super();
30+
super();
3131
translate(error, args);
3232
}
3333

0 commit comments

Comments
 (0)