*** Connection.java.old Wed Nov 7 11:19:11 2001 --- Connection.java Wed Nov 7 10:12:51 2001 *************** *** 4,9 **** --- 4,10 ---- import java.net.*; import java.sql.*; import java.util.*; + import java.security.*; import org.postgresql.Field; import org.postgresql.fastpath.*; import org.postgresql.largeobject.*; *************** *** 63,68 **** --- 64,70 ---- private static final int AUTH_REQ_KRB5 = 2; private static final int AUTH_REQ_PASSWORD = 3; 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 private String salt; *************** *** 180,201 **** // Get the type of request areq = pg_stream.ReceiveIntegerR(4); ! // Get the password salt if there is one if (areq == AUTH_REQ_CRYPT) { byte[] rst = new byte[2]; rst[0] = (byte)pg_stream.ReceiveChar(); rst[1] = (byte)pg_stream.ReceiveChar(); salt = new String(rst, 0, 2); ! DriverManager.println("Salt=" + salt); } // now send the auth packet switch (areq) { case AUTH_REQ_OK: ! break; ! case AUTH_REQ_KRB4: DriverManager.println("postgresql: KRB4"); throw new PSQLException("postgresql.con.kerb4"); --- 182,215 ---- // Get the type of request areq = pg_stream.ReceiveIntegerR(4); ! // Get the crypt password salt if there is one if (areq == AUTH_REQ_CRYPT) { byte[] rst = new byte[2]; rst[0] = (byte)pg_stream.ReceiveChar(); rst[1] = (byte)pg_stream.ReceiveChar(); salt = new String(rst, 0, 2); ! 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 switch (areq) { case AUTH_REQ_OK: ! break; ! case AUTH_REQ_KRB4: DriverManager.println("postgresql: KRB4"); throw new PSQLException("postgresql.con.kerb4"); *************** *** 221,226 **** --- 235,269 ---- pg_stream.flush(); break; + case AUTH_REQ_MD5: + try { + MessageDigest md = MessageDigest.getInstance("MD5"); + byte[] temp_digest, pass_digest; + byte[] hex_digest = new byte[35]; + + DriverManager.println("postgresql: MD5"); + + md.update(PG_PASSWORD.getBytes()); + md.update(PG_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] = 'm'; hex_digest[1] = 'd'; hex_digest[2] = '5'; + + pg_stream.SendInteger(5 + hex_digest.length, 4); + pg_stream.Send(hex_digest); + pg_stream.SendInteger(0, 1); + pg_stream.flush(); + } catch (Exception e) { + ; // "MessageDigest failure; " + e + } + break; + default: throw new PSQLException("postgresql.con.auth", new Integer(areq)); } *************** *** 308,313 **** --- 351,371 ---- firstWarning = null; PG_STATUS = CONNECTION_OK; } + + 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]; + } + } // These methods used to be in the main Connection implementation. As they // are common to all implementations (JDBC1 or 2), they are placed here.