From 1a7cf8ccc49f53b6cb6607ee95bda1268784e8bb Mon Sep 17 00:00:00 2001 From: Jack Christensen Date: Thu, 11 Apr 2013 21:39:44 -0500 Subject: [PATCH] Added connect with md5 password --- README.md | 10 +++++++++- conn.go | 12 ++++++++++++ conn_test.go | 14 +++++++++++++- test_setup.sql | 2 ++ 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6f6cf226..e2c2b303 100644 --- a/README.md +++ b/README.md @@ -6,4 +6,12 @@ Experimental PostgreSQL client library for Go Testing ------- -To setup the test environment run the test_setup.sql script as a user that can create users and databases. +To setup the test environment run the test_setup.sql script as a user that can +create users and databases. To successfully run the connection tests for various +means of authentication you must include the following in your pg_hba.conf. + + local pgx_test pgx_none trust + local pgx_test pgx_pw password + local pgx_test pgx_md5 md5 + + diff --git a/conn.go b/conn.go index 91abbd83..b60a783c 100644 --- a/conn.go +++ b/conn.go @@ -1,7 +1,9 @@ package pqx import ( + "crypto/md5" "encoding/binary" + "encoding/hex" "errors" "fmt" "io" @@ -189,6 +191,10 @@ func (c *conn) rxAuthenticationX(r *messageReader) (err error) { case 0: // AuthenticationOk case 3: // AuthenticationCleartextPassword c.txPasswordMessage(c.options["password"]) + case 5: // AuthenticationMD5Password + salt := r.readByteString(4) + digestedPassword := "md5" + hexMD5(hexMD5(c.options["password"]+c.options["user"])+salt) + c.txPasswordMessage(digestedPassword) default: err = errors.New("Received unknown authentication message") } @@ -196,6 +202,12 @@ func (c *conn) rxAuthenticationX(r *messageReader) (err error) { return } +func hexMD5(s string) string { + hash := md5.New() + io.WriteString(hash, s) + return hex.EncodeToString(hash.Sum(nil)) +} + func (c *conn) rxParameterStatus(r *messageReader) { key := r.readString() value := r.readString() diff --git a/conn_test.go b/conn_test.go index bbbcc710..59788fcf 100644 --- a/conn_test.go +++ b/conn_test.go @@ -47,7 +47,7 @@ func TestConnectWithInvalidUser(t *testing.T) { } } -func TestConnectWithPassword(t *testing.T) { +func TestConnectWithPlainTextPassword(t *testing.T) { conn, err := Connect(map[string]string{"socket": "/private/tmp/.s.PGSQL.5432", "user": "pgx_pw", "password": "secret", "database": "pgx_test"}) if err != nil { t.Fatal("Unable to establish connection: " + err.Error()) @@ -59,6 +59,18 @@ func TestConnectWithPassword(t *testing.T) { } } +func TestConnectWithMD5Password(t *testing.T) { + conn, err := Connect(map[string]string{"socket": "/private/tmp/.s.PGSQL.5432", "user": "pgx_md5", "password": "secret", "database": "pgx_test"}) + if err != nil { + t.Fatal("Unable to establish connection: " + err.Error()) + } + + err = conn.Close() + if err != nil { + t.Fatal("Unable to close connection") + } +} + func TestQuery(t *testing.T) { conn, err := Connect(map[string]string{"socket": "/private/tmp/.s.PGSQL.5432", "user": "pgx_none", "database": "pgx_test"}) if err != nil { diff --git a/test_setup.sql b/test_setup.sql index 15af361c..c5c73614 100644 --- a/test_setup.sql +++ b/test_setup.sql @@ -1,7 +1,9 @@ drop database if exists pgx_test; drop user if exists pgx_none; drop user if exists pgx_pw; +drop user if exists pgx_md5; create user pgx_none; create user pgx_pw password 'secret'; +create user pgx_md5 password 'secret'; create database pgx_test;