mirror of
https://github.com/postgres/postgres.git
synced 2025-06-16 06:01:02 +03:00
Commit to support MD5 passwords as per the backend for 7.2. This patch was submitted by Jeremy Wohl jeremyw-pgjdbc@igmus.org
This commit is contained in:
@ -11,7 +11,7 @@ import org.postgresql.util.*;
|
|||||||
import org.postgresql.core.*;
|
import org.postgresql.core.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* $Id: Connection.java,v 1.34 2001/11/01 01:08:36 barry Exp $
|
* $Id: Connection.java,v 1.35 2001/11/12 19:11:56 barry Exp $
|
||||||
*
|
*
|
||||||
* This abstract class is used by org.postgresql.Driver to open either the JDBC1 or
|
* This abstract class is used by org.postgresql.Driver to open either the JDBC1 or
|
||||||
* JDBC2 versions of the Connection class.
|
* JDBC2 versions of the Connection class.
|
||||||
@ -63,6 +63,7 @@ public abstract class Connection
|
|||||||
private static final int AUTH_REQ_KRB5 = 2;
|
private static final int AUTH_REQ_KRB5 = 2;
|
||||||
private static final int AUTH_REQ_PASSWORD = 3;
|
private static final int AUTH_REQ_PASSWORD = 3;
|
||||||
private static final int AUTH_REQ_CRYPT = 4;
|
private static final int AUTH_REQ_CRYPT = 4;
|
||||||
|
private static final int AUTH_REQ_MD5 = 5;
|
||||||
|
|
||||||
// New for 6.3, salt value for crypt authorisation
|
// New for 6.3, salt value for crypt authorisation
|
||||||
private String salt;
|
private String salt;
|
||||||
@ -180,21 +181,33 @@ public abstract class Connection
|
|||||||
// Get the type of request
|
// Get the type of request
|
||||||
areq = pg_stream.ReceiveIntegerR(4);
|
areq = pg_stream.ReceiveIntegerR(4);
|
||||||
|
|
||||||
// Get the password salt if there is one
|
// Get the crypt password salt if there is one
|
||||||
if (areq == AUTH_REQ_CRYPT)
|
if (areq == AUTH_REQ_CRYPT)
|
||||||
{
|
{
|
||||||
byte[] rst = new byte[2];
|
byte[] rst = new byte[2];
|
||||||
rst[0] = (byte)pg_stream.ReceiveChar();
|
rst[0] = (byte)pg_stream.ReceiveChar();
|
||||||
rst[1] = (byte)pg_stream.ReceiveChar();
|
rst[1] = (byte)pg_stream.ReceiveChar();
|
||||||
salt = new String(rst, 0, 2);
|
salt = new String(rst, 0, 2);
|
||||||
DriverManager.println("Salt=" + salt);
|
DriverManager.println("Crypt salt=" + salt);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Or get the md5 password salt if there is one
|
||||||
|
if (areq == AUTH_REQ_MD5)
|
||||||
|
{
|
||||||
|
byte[] rst = new byte[4];
|
||||||
|
rst[0] = (byte)pg_stream.ReceiveChar();
|
||||||
|
rst[1] = (byte)pg_stream.ReceiveChar();
|
||||||
|
rst[2] = (byte)pg_stream.ReceiveChar();
|
||||||
|
rst[3] = (byte)pg_stream.ReceiveChar();
|
||||||
|
salt = new String(rst, 0, 4);
|
||||||
|
DriverManager.println("MD5 salt=" + salt);
|
||||||
}
|
}
|
||||||
|
|
||||||
// now send the auth packet
|
// now send the auth packet
|
||||||
switch (areq)
|
switch (areq)
|
||||||
{
|
{
|
||||||
case AUTH_REQ_OK:
|
case AUTH_REQ_OK:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AUTH_REQ_KRB4:
|
case AUTH_REQ_KRB4:
|
||||||
DriverManager.println("postgresql: KRB4");
|
DriverManager.println("postgresql: KRB4");
|
||||||
@ -221,6 +234,15 @@ public abstract class Connection
|
|||||||
pg_stream.flush();
|
pg_stream.flush();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case AUTH_REQ_MD5:
|
||||||
|
DriverManager.println("postgresql: MD5");
|
||||||
|
byte[] digest = MD5Digest.encode(PG_USER, PG_PASSWORD, salt);
|
||||||
|
pg_stream.SendInteger(5 + digest.length, 4);
|
||||||
|
pg_stream.Send(digest);
|
||||||
|
pg_stream.SendInteger(0, 1);
|
||||||
|
pg_stream.flush();
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new PSQLException("postgresql.con.auth", new Integer(areq));
|
throw new PSQLException("postgresql.con.auth", new Integer(areq));
|
||||||
}
|
}
|
||||||
|
73
src/interfaces/jdbc/org/postgresql/util/MD5Digest.java
Normal file
73
src/interfaces/jdbc/org/postgresql/util/MD5Digest.java
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
package org.postgresql.util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MD5-based utility function to obfuscate passwords before network transmission
|
||||||
|
*
|
||||||
|
* @author Jeremy Wohl
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.security.*;
|
||||||
|
|
||||||
|
public class MD5Digest
|
||||||
|
{
|
||||||
|
private MD5Digest() {}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes user/password/salt information in the following way:
|
||||||
|
* MD5(MD5(password + user) + salt)
|
||||||
|
*
|
||||||
|
* @param user The connecting user.
|
||||||
|
* @param password The connecting user's password.
|
||||||
|
* @param salt A four-character string sent by the server.
|
||||||
|
*
|
||||||
|
* @return A 35-byte array, comprising the string "md5", followed by an MD5 digest.
|
||||||
|
*/
|
||||||
|
public static byte[] encode(String user, String password, String salt)
|
||||||
|
{
|
||||||
|
MessageDigest md;
|
||||||
|
byte[] temp_digest, pass_digest;
|
||||||
|
byte[] hex_digest = new byte[35];
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
md = MessageDigest.getInstance("MD5");
|
||||||
|
|
||||||
|
md.update(password.getBytes());
|
||||||
|
md.update(user.getBytes());
|
||||||
|
temp_digest = md.digest();
|
||||||
|
|
||||||
|
bytesToHex(temp_digest, hex_digest, 0);
|
||||||
|
md.update(hex_digest, 0, 32);
|
||||||
|
md.update(salt.getBytes());
|
||||||
|
pass_digest = md.digest();
|
||||||
|
|
||||||
|
bytesToHex(pass_digest, hex_digest, 3);
|
||||||
|
hex_digest[0] = (byte) 'm'; hex_digest[1] = (byte) 'd'; hex_digest[2] = (byte) '5';
|
||||||
|
} catch (Exception e) {
|
||||||
|
; // "MessageDigest failure; " + e
|
||||||
|
}
|
||||||
|
|
||||||
|
return hex_digest;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turn 16-byte stream into a human-readable 32-byte hex string
|
||||||
|
*/
|
||||||
|
private static void bytesToHex(byte[] bytes, byte[] hex, int offset)
|
||||||
|
{
|
||||||
|
final char lookup[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
||||||
|
'a', 'b', 'c', 'd', 'e', 'f' };
|
||||||
|
|
||||||
|
int i, c, j, pos = offset;
|
||||||
|
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
c = bytes[i] & 0xFF; j = c >> 4;
|
||||||
|
hex[pos++] = (byte) lookup[j];
|
||||||
|
j = (c & 0xF);
|
||||||
|
hex[pos++] = (byte) lookup[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user