From 2c69b92117f0d60d35062fc7bd93aeef53ce4d3b Mon Sep 17 00:00:00 2001 From: Andrew Ayer Date: Fri, 29 May 2020 14:39:01 -0400 Subject: [PATCH 1/3] Move Kerberos implementation to its own module Henceforth to use Kerberos authentication, you must add this import statement somewhere in your program: import _ "github.com/lib/pq/auth/kerberos" Moving Kerberos to its own module reduces the number of dependencies for those users who don't need Kerberos. Closes: #971 --- auth/kerberos/go.mod | 11 +++++ auth/kerberos/go.sum | 49 +++++++++++++++++++ auth/kerberos/krb.go | 29 +++++++++++ krb_unix.go => auth/kerberos/krb_unix.go | 9 +++- .../kerberos/krb_windows.go | 9 +++- conn.go | 5 +- go.mod | 11 ----- krb.go | 48 ++++++------------ 8 files changed, 123 insertions(+), 48 deletions(-) create mode 100644 auth/kerberos/go.mod create mode 100644 auth/kerberos/go.sum create mode 100644 auth/kerberos/krb.go rename krb_unix.go => auth/kerberos/krb_unix.go (95%) rename krb_windows.go => auth/kerberos/krb_windows.go (89%) diff --git a/auth/kerberos/go.mod b/auth/kerberos/go.mod new file mode 100644 index 00000000..bf0dc359 --- /dev/null +++ b/auth/kerberos/go.mod @@ -0,0 +1,11 @@ +module github.com/lib/pq/auth/kerberos + +go 1.13 + +replace github.com/lib/pq => ../.. + +require ( + github.com/alexbrainman/sspi v0.0.0-20180613141037-e580b900e9f5 + github.com/jcmturner/gokrb5/v8 v8.2.0 + github.com/lib/pq v1.6.0 +) diff --git a/auth/kerberos/go.sum b/auth/kerberos/go.sum new file mode 100644 index 00000000..a5aa8639 --- /dev/null +++ b/auth/kerberos/go.sum @@ -0,0 +1,49 @@ +github.com/alexbrainman/sspi v0.0.0-20180613141037-e580b900e9f5 h1:P5U+E4x5OkVEKQDklVPmzs71WM56RTTRqV4OrDC//Y4= +github.com/alexbrainman/sspi v0.0.0-20180613141037-e580b900e9f5/go.mod h1:976q2ETgjT2snVCf2ZaBnyBbVoPERGjUz+0sofzEfro= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= +github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= +github.com/gorilla/sessions v1.2.0 h1:S7P+1Hm5V/AT9cjEcUD5uDaQSX0OE577aCXgoaKpYbQ= +github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= +github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8= +github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= +github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo= +github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= +github.com/jcmturner/gofork v1.0.0 h1:J7uCkflzTEhUZ64xqKnkDxq3kzc96ajM1Gli5ktUem8= +github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= +github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o= +github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= +github.com/jcmturner/gokrb5/v8 v8.2.0 h1:lzPl/30ZLkTveYsYZPKMcgXc8MbnE6RsTd4F9KgiLtk= +github.com/jcmturner/gokrb5/v8 v8.2.0/go.mod h1:T1hnNppQsBtxW0tCHMHTkAt8n/sABdzZgZdoFrZaZNM= +github.com/jcmturner/rpc/v2 v2.0.2 h1:gMB4IwRXYsWw4Bc6o/az2HJgFUA1ffSh90i26ZJ6Xl0= +github.com/jcmturner/rpc/v2 v2.0.2/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= +github.com/lib/pq v1.6.0 h1:I5DPxhYJChW9KYc66se+oKFFQX6VuQrKiprsX6ivRZc= +github.com/lib/pq v1.6.0/go.mod h1:4vXEAYvW1fRQ2/FhZ78H73A60MHw1geSm145z2mdY1g= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +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= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200117160349-530e935923ad h1:Jh8cai0fqIK+f6nG0UgPW5wFk8wmiMhM3AyciDBdtQg= +golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4 h1:QmwruyY+bKbDDL0BaglrbZABEali68eoMFhTZpCjYVA= +golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa h1:F+8P+gmewFQYRk6JoLQLwjBCTu3mcIURZfNkVweuRKA= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +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/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= +gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= +gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4= +gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= +gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/auth/kerberos/krb.go b/auth/kerberos/krb.go new file mode 100644 index 00000000..451a7ee1 --- /dev/null +++ b/auth/kerberos/krb.go @@ -0,0 +1,29 @@ +package kerberos + +import ( + "net" + "strings" +) + +/* + * Find the A record associated with a hostname + * In general, hostnames supplied to the driver should be + * canonicalized because the KDC usually only has one + * principal and not one per potential alias of a host. + */ +func canonicalizeHostname(host string) (string, error) { + canon := host + + name, err := net.LookupCNAME(host) + if err != nil { + return "", err + } + + name = strings.TrimSuffix(name, ".") + + if name != "" { + canon = name + } + + return canon, nil +} diff --git a/krb_unix.go b/auth/kerberos/krb_unix.go similarity index 95% rename from krb_unix.go rename to auth/kerberos/krb_unix.go index b5483663..166b30b0 100644 --- a/krb_unix.go +++ b/auth/kerberos/krb_unix.go @@ -1,6 +1,6 @@ // +build !windows -package pq +package kerberos import ( "fmt" @@ -12,6 +12,7 @@ import ( "github.com/jcmturner/gokrb5/v8/config" "github.com/jcmturner/gokrb5/v8/credentials" "github.com/jcmturner/gokrb5/v8/spnego" + "github.com/lib/pq" ) /* @@ -24,7 +25,7 @@ type gss struct { cli *client.Client } -func NewGSS() (Gss, error) { +func NewGSS() (pq.Gss, error) { g := &gss{} err := g.init() @@ -121,3 +122,7 @@ func (g *gss) Continue(inToken []byte) (done bool, outToken []byte, err error) { return true, nil, nil } + +func init() { + pq.RegisterNewGSSFunc(NewGSS) +} diff --git a/krb_windows.go b/auth/kerberos/krb_windows.go similarity index 89% rename from krb_windows.go rename to auth/kerberos/krb_windows.go index 71e328ea..c9ec7541 100644 --- a/krb_windows.go +++ b/auth/kerberos/krb_windows.go @@ -1,10 +1,11 @@ // +build windows -package pq +package kerberos import ( "github.com/alexbrainman/sspi" "github.com/alexbrainman/sspi/negotiate" + "github.com/lib/pq" ) type gss struct { @@ -12,7 +13,7 @@ type gss struct { ctx *negotiate.ClientContext } -func NewGSS() (Gss, error) { +func NewGSS() (pq.Gss, error) { g := &gss{} err := g.init() @@ -59,3 +60,7 @@ func (g *gss) GetInitTokenFromSpn(spn string) ([]byte, error) { func (g *gss) Continue(inToken []byte) (done bool, outToken []byte, err error) { return g.ctx.Update(inToken) } + +func init() { + pq.RegisterNewGSSFunc(NewGSS) +} diff --git a/conn.go b/conn.go index d95fb888..31b4eb71 100644 --- a/conn.go +++ b/conn.go @@ -1158,7 +1158,10 @@ func (cn *conn) auth(r *readBuf, o values) { errorf("unexpected authentication response: %q", t) } case 7: // GSSAPI, startup - cli, err := NewGSS() + if newGss == nil { + errorf("kerberos error: no GSSAPI provider registered (import github.com/lib/pq/auth/kerberos if you need Kerberos support)") + } + cli, err := newGss() if err != nil { errorf("kerberos error: %s", err.Error()) } diff --git a/go.mod b/go.mod index a33cf4c4..b5a5639a 100644 --- a/go.mod +++ b/go.mod @@ -1,14 +1,3 @@ module github.com/lib/pq go 1.13 - -require ( - github.com/alexbrainman/sspi v0.0.0-20180613141037-e580b900e9f5 // indirect - github.com/jcmturner/gokrb5/v8 v8.2.0 - golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4 // indirect - gopkg.in/jcmturner/aescts.v1 v1.0.1 // indirect - gopkg.in/jcmturner/dnsutils.v1 v1.0.1 // indirect - gopkg.in/jcmturner/goidentity.v3 v3.0.0 // indirect - gopkg.in/jcmturner/gokrb5.v7 v7.5.0 - gopkg.in/jcmturner/rpc.v1 v1.1.0 // indirect -) diff --git a/krb.go b/krb.go index e98432f0..e4a2a179 100644 --- a/krb.go +++ b/krb.go @@ -1,40 +1,24 @@ package pq -import ( - "net" - "strings" -) - -/* - * Basic GSSAPI interface to abstract Windows (SSPI) from Unix - * APIs within the driver - */ +// A function that creates a GSS authentication provider. You +// only need to care about this type if you are writing a GSS +// authentication provider. +type NewGSSFunc func() (Gss, error) + +var newGss NewGSSFunc + +// Register the function for creating a GSS authentication provider. +// You only need to care about this function if you are writing a +// GSS authentication provider. +func RegisterNewGSSFunc(newGssArg NewGSSFunc) { + newGss = newGssArg +} +// An interface for providing GSSAPI authentication (e.g. Kerberos). +// You only need to care about this interface if you are writing a +// GSS authentication provider. type Gss interface { GetInitToken(host string, service string) ([]byte, error) GetInitTokenFromSpn(spn string) ([]byte, error) Continue(inToken []byte) (done bool, outToken []byte, err error) } - -/* - * Find the A record associated with a hostname - * In general, hostnames supplied to the driver should be - * canonicalized because the KDC usually only has one - * principal and not one per potential alias of a host. - */ -func canonicalizeHostname(host string) (string, error) { - canon := host - - name, err := net.LookupCNAME(host) - if err != nil { - return "", err - } - - name = strings.TrimSuffix(name, ".") - - if name != "" { - canon = name - } - - return canon, nil -} From e4e4fd48e8777c09cc694378e4f77e6862aa3f41 Mon Sep 17 00:00:00 2001 From: Andrew Ayer Date: Fri, 29 May 2020 14:57:26 -0400 Subject: [PATCH 2/3] Update documentation for optional Kerberos support --- README.md | 5 ++++- doc.go | 12 ++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c972a86a..db4448e6 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,10 @@ * Unix socket support * Notifications: `LISTEN`/`NOTIFY` * pgpass support -* GSS (Kerberos) auth + +## Optional Features + +* GSS (Kerberos) auth (to use, import `github.com/lib/pq/auth/kerberos`) ## Tests diff --git a/doc.go b/doc.go index 16695979..b7a506ab 100644 --- a/doc.go +++ b/doc.go @@ -243,5 +243,17 @@ bytes by the PostgreSQL server. You can find a complete, working example of Listener usage at https://godoc.org/github.com/lib/pq/example/listen. + +Kerberos Support + + +If you need support for Kerberos authentication, add the following import +statement to your program: + +import _ "github.com/lib/pq/auth/kerberos" + +This package is in a separate module so that users who don't need Kerberos +don't have to download unnecessary dependencies. + */ package pq From 83d7d7f83f6e9392c38f2cd582f10fdbb5c5b2f6 Mon Sep 17 00:00:00 2001 From: Andrew Ayer Date: Tue, 2 Jun 2020 11:00:49 -0400 Subject: [PATCH 3/3] Remove automatic registration of GSS provider This removes the dependency from the kerberos module to the pq module, which would have complicated releases. --- README.md | 2 +- auth/kerberos/go.mod | 3 --- auth/kerberos/go.sum | 9 --------- auth/kerberos/krb_unix.go | 21 ++++++++------------- auth/kerberos/krb_windows.go | 20 ++++++++------------ doc.go | 10 +++++++--- krb.go | 17 +++++++++++------ 7 files changed, 35 insertions(+), 47 deletions(-) diff --git a/README.md b/README.md index db4448e6..ecd01939 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ ## Optional Features -* GSS (Kerberos) auth (to use, import `github.com/lib/pq/auth/kerberos`) +* GSS (Kerberos) auth (to use, see GoDoc) ## Tests diff --git a/auth/kerberos/go.mod b/auth/kerberos/go.mod index bf0dc359..d58d6df4 100644 --- a/auth/kerberos/go.mod +++ b/auth/kerberos/go.mod @@ -2,10 +2,7 @@ module github.com/lib/pq/auth/kerberos go 1.13 -replace github.com/lib/pq => ../.. - require ( github.com/alexbrainman/sspi v0.0.0-20180613141037-e580b900e9f5 github.com/jcmturner/gokrb5/v8 v8.2.0 - github.com/lib/pq v1.6.0 ) diff --git a/auth/kerberos/go.sum b/auth/kerberos/go.sum index a5aa8639..138e36f1 100644 --- a/auth/kerberos/go.sum +++ b/auth/kerberos/go.sum @@ -20,8 +20,6 @@ github.com/jcmturner/gokrb5/v8 v8.2.0 h1:lzPl/30ZLkTveYsYZPKMcgXc8MbnE6RsTd4F9Kg github.com/jcmturner/gokrb5/v8 v8.2.0/go.mod h1:T1hnNppQsBtxW0tCHMHTkAt8n/sABdzZgZdoFrZaZNM= github.com/jcmturner/rpc/v2 v2.0.2 h1:gMB4IwRXYsWw4Bc6o/az2HJgFUA1ffSh90i26ZJ6Xl0= github.com/jcmturner/rpc/v2 v2.0.2/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= -github.com/lib/pq v1.6.0 h1:I5DPxhYJChW9KYc66se+oKFFQX6VuQrKiprsX6ivRZc= -github.com/lib/pq v1.6.0/go.mod h1:4vXEAYvW1fRQ2/FhZ78H73A60MHw1geSm145z2mdY1g= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -30,8 +28,6 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200117160349-530e935923ad h1:Jh8cai0fqIK+f6nG0UgPW5wFk8wmiMhM3AyciDBdtQg= golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4 h1:QmwruyY+bKbDDL0BaglrbZABEali68eoMFhTZpCjYVA= -golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa h1:F+8P+gmewFQYRk6JoLQLwjBCTu3mcIURZfNkVweuRKA= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -40,10 +36,5 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 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/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= -gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= -gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4= -gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= -gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/auth/kerberos/krb_unix.go b/auth/kerberos/krb_unix.go index 166b30b0..e2760576 100644 --- a/auth/kerberos/krb_unix.go +++ b/auth/kerberos/krb_unix.go @@ -12,7 +12,6 @@ import ( "github.com/jcmturner/gokrb5/v8/config" "github.com/jcmturner/gokrb5/v8/credentials" "github.com/jcmturner/gokrb5/v8/spnego" - "github.com/lib/pq" ) /* @@ -20,13 +19,13 @@ import ( * implementation */ -// Implements the Gss interface -type gss struct { +// Implements the pq.Gss interface +type Gss struct { cli *client.Client } -func NewGSS() (pq.Gss, error) { - g := &gss{} +func NewGSS() (*Gss, error) { + g := &Gss{} err := g.init() if err != nil { @@ -36,7 +35,7 @@ func NewGSS() (pq.Gss, error) { return g, nil } -func (g *gss) init() error { +func (g *Gss) init() error { cfgPath, ok := os.LookupEnv("KRB5_CONFIG") if !ok { cfgPath = "/etc/krb5.conf" @@ -76,7 +75,7 @@ func (g *gss) init() error { return nil } -func (g *gss) GetInitToken(host string, service string) ([]byte, error) { +func (g *Gss) GetInitToken(host string, service string) ([]byte, error) { // Resolve the hostname down to an 'A' record, if required (usually, it is) if g.cli.Config.LibDefaults.DNSCanonicalizeHostname { @@ -92,7 +91,7 @@ func (g *gss) GetInitToken(host string, service string) ([]byte, error) { return g.GetInitTokenFromSpn(spn) } -func (g *gss) GetInitTokenFromSpn(spn string) ([]byte, error) { +func (g *Gss) GetInitTokenFromSpn(spn string) ([]byte, error) { s := spnego.SPNEGOClient(g.cli, spn) st, err := s.InitSecContext() @@ -108,7 +107,7 @@ func (g *gss) GetInitTokenFromSpn(spn string) ([]byte, error) { return b, nil } -func (g *gss) Continue(inToken []byte) (done bool, outToken []byte, err error) { +func (g *Gss) Continue(inToken []byte) (done bool, outToken []byte, err error) { t := &spnego.SPNEGOToken{} err = t.Unmarshal(inToken) if err != nil { @@ -122,7 +121,3 @@ func (g *gss) Continue(inToken []byte) (done bool, outToken []byte, err error) { return true, nil, nil } - -func init() { - pq.RegisterNewGSSFunc(NewGSS) -} diff --git a/auth/kerberos/krb_windows.go b/auth/kerberos/krb_windows.go index c9ec7541..614442db 100644 --- a/auth/kerberos/krb_windows.go +++ b/auth/kerberos/krb_windows.go @@ -5,16 +5,16 @@ package kerberos import ( "github.com/alexbrainman/sspi" "github.com/alexbrainman/sspi/negotiate" - "github.com/lib/pq" ) -type gss struct { +// Implements the pq.Gss interface +type Gss struct { creds *sspi.Credentials ctx *negotiate.ClientContext } -func NewGSS() (pq.Gss, error) { - g := &gss{} +func NewGSS() (*Gss, error) { + g := &Gss{} err := g.init() if err != nil { @@ -24,7 +24,7 @@ func NewGSS() (pq.Gss, error) { return g, nil } -func (g *gss) init() error { +func (g *Gss) init() error { creds, err := negotiate.AcquireCurrentUserCredentials() if err != nil { return err @@ -34,7 +34,7 @@ func (g *gss) init() error { return nil } -func (g *gss) GetInitToken(host string, service string) ([]byte, error) { +func (g *Gss) GetInitToken(host string, service string) ([]byte, error) { host, err := canonicalizeHostname(host) if err != nil { @@ -46,7 +46,7 @@ func (g *gss) GetInitToken(host string, service string) ([]byte, error) { return g.GetInitTokenFromSpn(spn) } -func (g *gss) GetInitTokenFromSpn(spn string) ([]byte, error) { +func (g *Gss) GetInitTokenFromSpn(spn string) ([]byte, error) { ctx, token, err := negotiate.NewClientContext(g.creds, spn) if err != nil { return nil, err @@ -57,10 +57,6 @@ func (g *gss) GetInitTokenFromSpn(spn string) ([]byte, error) { return token, nil } -func (g *gss) Continue(inToken []byte) (done bool, outToken []byte, err error) { +func (g *Gss) Continue(inToken []byte) (done bool, outToken []byte, err error) { return g.ctx.Update(inToken) } - -func init() { - pq.RegisterNewGSSFunc(NewGSS) -} diff --git a/doc.go b/doc.go index b7a506ab..78c670b1 100644 --- a/doc.go +++ b/doc.go @@ -247,10 +247,14 @@ https://godoc.org/github.com/lib/pq/example/listen. Kerberos Support -If you need support for Kerberos authentication, add the following import -statement to your program: +If you need support for Kerberos authentication, add the following to your main +package: -import _ "github.com/lib/pq/auth/kerberos" + import "github.com/lib/pq/auth/kerberos" + + func init() { + pq.RegisterGSSProvider(func() (pq.Gss, error) { return kerberos.NewGSS() }) + } This package is in a separate module so that users who don't need Kerberos don't have to download unnecessary dependencies. diff --git a/krb.go b/krb.go index e4a2a179..690f1d40 100644 --- a/krb.go +++ b/krb.go @@ -1,16 +1,21 @@ package pq -// A function that creates a GSS authentication provider. You -// only need to care about this type if you are writing a GSS -// authentication provider. +// A function that creates a GSS authentication provider, +// for use with RegisterGSSProvider. type NewGSSFunc func() (Gss, error) var newGss NewGSSFunc // Register the function for creating a GSS authentication provider. -// You only need to care about this function if you are writing a -// GSS authentication provider. -func RegisterNewGSSFunc(newGssArg NewGSSFunc) { +// For example, if you need to use Kerberos to authenticate with your server, +// add this to your main package: +// +// import "github.com/lib/pq/auth/kerberos" +// +// func init() { +// pq.RegisterGSSProvider(func() (pq.Gss, error) { return kerberos.NewGSS() }) +// } +func RegisterGSSProvider(newGssArg NewGSSFunc) { newGss = newGssArg }