Skip to content

Commit

Permalink
implement SASL authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
coder543 committed Apr 1, 2022
1 parent aa66c4f commit 6a80913
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 3 deletions.
59 changes: 59 additions & 0 deletions frontend/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import (
"time"

"github.com/jackc/pgproto3/v2"
"github.com/xdg-go/scram"
"golang.org/x/exp/slices"

"github.com/coder543/roundabout/config"
"github.com/coder543/roundabout/frontend/preambler"
Expand Down Expand Up @@ -160,6 +162,10 @@ func launchConn(wgConn *sync.WaitGroup, dbAddr string, pool *Pool) {
defer GlobalPreambleLock.Unlock()
}
}

// used for SASL authentication
var conversation *scram.ClientConversation

localPreamble := []pgproto3.BackendMessage{}
// drain the ParameterStatus and BackendKeyData messages, looking for RFQ
for {
Expand All @@ -171,12 +177,15 @@ func launchConn(wgConn *sync.WaitGroup, dbAddr string, pool *Pool) {
log.Println("f-receive startup err", err)
return
}

switch fmsg := fmsg.(type) {
case *pgproto3.ErrorResponse:
log.Println(fmsg)
return

case *pgproto3.AuthenticationOk:
continue

case *pgproto3.AuthenticationCleartextPassword:
err := frontend.Send(&pgproto3.PasswordMessage{Password: db.Password})
if err != nil {
Expand All @@ -196,8 +205,58 @@ func launchConn(wgConn *sync.WaitGroup, dbAddr string, pool *Pool) {
log.Println("send pass err", err)
return
}

case *pgproto3.AuthenticationSASL:
if !slices.Contains(fmsg.AuthMechanisms, "SCRAM-SHA-256") {
log.Println("unsupported SASL authentication request: ", fmsg.AuthMechanisms)
return
}

client, err := scram.SHA256.NewClient(db.Username, db.Password, "")
if err != nil {
log.Println("scram client err", err)
return
}
conversation = client.NewConversation()
initalResponse, err := conversation.Step("")
if err != nil {
log.Println("scram initial step err", err)
return
}
err = frontend.Send(&pgproto3.SASLInitialResponse{
AuthMechanism: "SCRAM-SHA-256",
Data: []byte(initalResponse),
})
if err != nil {
log.Println("send initial sasl err", err)
return
}

case *pgproto3.AuthenticationSASLContinue:
resp, err := conversation.Step(string(fmsg.Data))
if err != nil {
log.Println("scram continue step err", err)
return
}

err = frontend.Send(&pgproto3.SASLResponse{
Data: []byte(resp),
})
if err != nil {
log.Println("send continue sasl err", err)
return
}

case *pgproto3.AuthenticationSASLFinal:
_, err := conversation.Step(string(fmsg.Data))
if err != nil {
log.Println("scram final step err", err)
return
}

case *pgproto3.ReadyForQuery:
goto pushConn

case *pgproto3.ParameterStatus:
// we only want to save some server-specific
// preambles that should be constant to the
Expand Down
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,16 @@ go 1.18
require (
github.com/jackc/pgproto3/v2 v2.2.0
github.com/mitchellh/copystructure v1.2.0
github.com/xdg-go/scram v1.1.1
golang.org/x/exp v0.0.0-20220328175248-053ad81199eb
gopkg.in/yaml.v2 v2.4.0
)

require (
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
github.com/jackc/pgio v1.0.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/stringprep v1.0.3 // indirect
golang.org/x/text v0.3.7 // indirect
)
11 changes: 11 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,17 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.1.1 h1:VOMT+81stJgXW3CpHyqHN3AXDYIMsx56mEFrB37Mb/E=
github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
github.com/xdg-go/stringprep v1.0.3 h1:kdwGpVNwPFtjs98xCGkHjQtGKh86rDcRZN17QEMCOIs=
github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
golang.org/x/exp v0.0.0-20220328175248-053ad81199eb h1:pC9Okm6BVmxEw76PUu0XUbOTQ92JX11hfvqTjAV3qxM=
golang.org/x/exp v0.0.0-20220328175248-053ad81199eb/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
Expand Down
4 changes: 1 addition & 3 deletions roundabout.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

# this section sets the behavior of archivist that
# clients will see, as if archivist were any normal
# postgres server.
Expand Down Expand Up @@ -28,7 +27,7 @@ database:
database_name: pg1

# the address of the database
address: "pg1:5432"
address: "localhost:5433"

# database credentials
username: postgres
Expand All @@ -39,4 +38,3 @@ database:

# number of connections to be established
num_conns: 25

0 comments on commit 6a80913

Please sign in to comment.