Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
metafeather committed May 3, 2024
1 parent 05da02e commit 286eae4
Showing 1 changed file with 59 additions and 9 deletions.
68 changes: 59 additions & 9 deletions modules/l4postgres/matcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,18 @@
// limitations under the License.

// Package l4postgres allows the L4 multiplexing of Postgres connections
// optionally matching on Users and their Databases
//
// Example matcher config:
//
// {
// "postgres": {
// "users": {
// "*": ["public_db"]
// "alice": ["planets_db", "stars_db"]
// }
// }
// }
//
// With thanks to docs and code published at these links:
// ref: https://github.com/mholt/caddy-l4/blob/master/modules/l4ssh/matcher.go
Expand All @@ -26,10 +38,13 @@ package l4postgres
import (
"encoding/binary"
"errors"
"fmt"
"io"
"slices"

"github.com/caddyserver/caddy/v2"
"github.com/mholt/caddy-l4/layer4"
"go.uber.org/zap"
)

func init() {
Expand Down Expand Up @@ -77,12 +92,10 @@ type startupMessage struct {
Parameters map[string]string
}

// MatchPostgres is able to match Postgres connections, optionally further
// matching on the User or Database being requested
// MatchPostgres is able to match Postgres connections
type MatchPostgres struct {
Users []string
Databases []string
startup *startupMessage
Users map[string][]string
startup *startupMessage
}

// CaddyModule returns the Caddy module information.
Expand All @@ -108,11 +121,12 @@ func (m MatchPostgres) Match(cx *layer4.Connection) (bool, error) {
}

b := newMessageFromBytes(data)
isConn := false

// Check if it is a SSLRequest
code := b.ReadUint32()
if code == sslRequestCode {
return true, nil
isConn = true
}

// Check supported protocol
Expand All @@ -127,11 +141,47 @@ func (m MatchPostgres) Match(cx *layer4.Connection) (bool, error) {
if k == "" {
break
}
startup.Parameters[k] = b.ReadString()
m.startup.Parameters[k] = b.ReadString()
}
if len(m.startup.Parameters) > 0 {
isConn = true
}

cx.Logger.Debug("postgres",
zap.String("match.config", fmt.Sprintf("%v", m.Users)),
zap.String("startup.Parameters?", fmt.Sprintf("%v", m.startup.Parameters)),
)

// Finish if no more matchers are configured
if len(m.Users) == 0 {
return isConn, nil
}

// Is there a user to check?
user, ok := m.startup.Parameters["user"]
if !ok {
// Are there public databases to check?
if databases, ok := m.Users["*"]; ok {
if db, ok := m.startup.Parameters["database"]; ok {
return slices.Contains(databases, db), nil
}
}
return false, nil
}

databases, ok := m.Users[user]
if !ok {
return false, nil
}

// Are there a databases to check?
if len(databases) > 0 {
if db, ok := m.startup.Parameters["database"]; ok {
return slices.Contains(databases, db), nil
}
}
// TODO(metafeather): match on param values: user, database, options, etc

return len(startup.Parameters) > 0, nil
return true, nil
}

// Interface guard
Expand Down

0 comments on commit 286eae4

Please sign in to comment.