@@ -2,6 +2,7 @@ package server_v1
22
33import (
44 "context"
5+ "crypto/tls"
56 "errors"
67
78 "github.com/couchbase/gocbcorex"
@@ -10,7 +11,9 @@ import (
1011 "github.com/couchbase/stellar-gateway/gateway/auth"
1112 "github.com/couchbase/stellar-gateway/utils/authhdr"
1213 "go.uber.org/zap"
14+ "google.golang.org/grpc/credentials"
1315 "google.golang.org/grpc/metadata"
16+ "google.golang.org/grpc/peer"
1417 "google.golang.org/grpc/status"
1518)
1619
@@ -45,16 +48,57 @@ func (a AuthHandler) MaybeGetUserPassFromContext(ctx context.Context) (string, s
4548 return username , password , nil
4649}
4750
51+ func (a AuthHandler ) MaybeGetConnStateFromContext (ctx context.Context ) (* tls.ConnectionState , * status.Status ) {
52+ p , ok := peer .FromContext (ctx )
53+ if ! ok {
54+ return nil , nil
55+ }
56+
57+ tlsInfo , ok := p .AuthInfo .(credentials.TLSInfo )
58+ if ! ok {
59+ a .Logger .Debug ("unexpected auth type" , zap .String ("authType" , p .AuthInfo .AuthType ()))
60+ return nil , a .ErrorHandler .NewUnexpectedAuthTypeStatus ()
61+ }
62+
63+ return & tlsInfo .State , nil
64+ }
65+
4866func (a AuthHandler ) MaybeGetOboUserFromContext (ctx context.Context ) (string , string , * status.Status ) {
4967 username , password , errSt := a .MaybeGetUserPassFromContext (ctx )
5068 if errSt != nil {
5169 return "" , "" , errSt
5270 }
5371
54- if username == "" && password == "" {
72+ connState , errSt := a .MaybeGetConnStateFromContext (ctx )
73+ if errSt != nil {
74+ return "" , "" , errSt
75+ }
76+
77+ credsFound := username != "" && password != ""
78+ certFound := connState != nil && len (connState .PeerCertificates ) != 0
79+
80+ if credsFound && certFound {
81+ return "" , "" , a .ErrorHandler .NewCredentialsAndCertStatus ()
82+ }
83+
84+ if ! credsFound && ! certFound {
5585 return "" , "" , nil
5686 }
5787
88+ if certFound {
89+ oboUser , oboDomain , err := a .Authenticator .ValidateConnStateForObo (ctx , connState )
90+ if err != nil {
91+ if errors .Is (err , auth .ErrInvalidCertificate ) {
92+ return "" , "" , a .ErrorHandler .NewInvalidCertificateStatus ()
93+ }
94+
95+ a .Logger .Error ("received an unexpected cert authentication error" , zap .Error (err ))
96+ return "" , "" , a .ErrorHandler .NewInternalStatus ()
97+ }
98+
99+ return oboUser , oboDomain , nil
100+ }
101+
58102 oboUser , oboDomain , err := a .Authenticator .ValidateUserForObo (ctx , username , password )
59103 if err != nil {
60104 if errors .Is (err , auth .ErrInvalidCredentials ) {
0 commit comments