package pgconn
import (
"errors"
"fmt"
"github.com/jackc/pgx/v5/pgproto3"
)
type NewGSSFunc func () (GSS , error )
var newGSS NewGSSFunc
func RegisterGSSProvider (newGSSArg NewGSSFunc ) {
newGSS = newGSSArg
}
type GSS interface {
GetInitToken (host string , service string ) ([]byte , error )
GetInitTokenFromSPN (spn string ) ([]byte , error )
Continue (inToken []byte ) (done bool , outToken []byte , err error )
}
func (c *PgConn ) gssAuth () error {
if newGSS == nil {
return errors .New ("kerberos error: no GSSAPI provider registered, see https://github.com/otan/gopgkrb5" )
}
cli , err := newGSS ()
if err != nil {
return err
}
var nextData []byte
if c .config .KerberosSpn != "" {
nextData , err = cli .GetInitTokenFromSPN (c .config .KerberosSpn )
} else {
service := "postgres"
if c .config .KerberosSrvName != "" {
service = c .config .KerberosSrvName
}
nextData , err = cli .GetInitToken (c .config .Host , service )
}
if err != nil {
return err
}
for {
gssResponse := &pgproto3 .GSSResponse {
Data : nextData ,
}
c .frontend .Send (gssResponse )
err = c .flushWithPotentialWriteReadDeadlock ()
if err != nil {
return err
}
resp , err := c .rxGSSContinue ()
if err != nil {
return err
}
var done bool
done , nextData , err = cli .Continue (resp .Data )
if err != nil {
return err
}
if done {
break
}
}
return nil
}
func (c *PgConn ) rxGSSContinue () (*pgproto3 .AuthenticationGSSContinue , error ) {
msg , err := c .receiveMessage ()
if err != nil {
return nil , err
}
switch m := msg .(type ) {
case *pgproto3 .AuthenticationGSSContinue :
return m , nil
case *pgproto3 .ErrorResponse :
return nil , ErrorResponseToPgError (m )
}
return nil , fmt .Errorf ("expected AuthenticationGSSContinue message but received unexpected message %T" , msg )
}
The pages are generated with Golds v0.6.7 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds .