fix databroker requiring signed jwt (#1538)

* add test, explicitly call RequireSignedJWT instead of using interceptor to handle combined gRPC server

* register handler, handle config changes

* fix nil error in tests

* unexport constructor
This commit is contained in:
Caleb Doxsey 2020-10-20 10:29:22 -06:00 committed by GitHub
parent a375f707f8
commit 1763f02620
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 184 additions and 22 deletions

10
cache/cache.go vendored
View file

@ -28,7 +28,7 @@ import (
// Cache represents the cache service. The cache service is a simple interface
// for storing keyed blobs (bytes) of unstructured data.
type Cache struct {
dataBrokerServer *DataBrokerServer
dataBrokerServer *dataBrokerServer
manager *manager.Manager
localListener net.Listener
@ -52,10 +52,7 @@ func New(cfg *config.Config) (*Cache, error) {
// No metrics handler because we have one in the control plane. Add one
// if we no longer register with that grpc Server
localGRPCServer := grpc.NewServer(
grpc.StreamInterceptor(grpcutil.StreamRequireSignedJWT(cfg.Options.SharedKey)),
grpc.UnaryInterceptor(grpcutil.UnaryRequireSignedJWT(cfg.Options.SharedKey)),
)
localGRPCServer := grpc.NewServer()
clientStatsHandler := telemetry.NewGRPCClientStatsHandler(cfg.Options.Services)
clientDialOptions := []grpc.DialOption{
@ -74,7 +71,7 @@ func New(cfg *config.Config) (*Cache, error) {
return nil, err
}
dataBrokerServer := NewDataBrokerServer(localGRPCServer, cfg)
dataBrokerServer := newDataBrokerServer(cfg)
c := &Cache{
dataBrokerServer: dataBrokerServer,
@ -84,6 +81,7 @@ func New(cfg *config.Config) (*Cache, error) {
deprecatedCacheClusterDomain: cfg.Options.GetDataBrokerURL().Hostname(),
dataBrokerStorageType: cfg.Options.DataBrokerStorageType,
}
c.Register(c.localGRPCServer)
err = c.update(cfg)
if err != nil {

95
cache/databroker.go vendored
View file

@ -1,32 +1,39 @@
package cache
import (
"google.golang.org/grpc"
"context"
"encoding/base64"
"sync/atomic"
"github.com/golang/protobuf/ptypes/empty"
"github.com/pomerium/pomerium/config"
"github.com/pomerium/pomerium/internal/databroker"
databrokerpb "github.com/pomerium/pomerium/pkg/grpc/databroker"
"github.com/pomerium/pomerium/pkg/grpcutil"
)
// A DataBrokerServer implements the data broker service interface.
type DataBrokerServer struct {
*databroker.Server
// A dataBrokerServer implements the data broker service interface.
type dataBrokerServer struct {
server *databroker.Server
sharedKey atomic.Value
}
// NewDataBrokerServer creates a new databroker service server.
func NewDataBrokerServer(grpcServer *grpc.Server, cfg *config.Config) *DataBrokerServer {
srv := &DataBrokerServer{}
srv.Server = databroker.New(srv.getOptions(cfg)...)
databrokerpb.RegisterDataBrokerServiceServer(grpcServer, srv)
// newDataBrokerServer creates a new databroker service server.
func newDataBrokerServer(cfg *config.Config) *dataBrokerServer {
srv := &dataBrokerServer{}
srv.server = databroker.New(srv.getOptions(cfg)...)
srv.setKey(cfg)
return srv
}
// OnConfigChange updates the underlying databroker server whenever configuration is changed.
func (srv *DataBrokerServer) OnConfigChange(cfg *config.Config) {
srv.UpdateConfig(srv.getOptions(cfg)...)
func (srv *dataBrokerServer) OnConfigChange(cfg *config.Config) {
srv.server.UpdateConfig(srv.getOptions(cfg)...)
srv.setKey(cfg)
}
func (srv *DataBrokerServer) getOptions(cfg *config.Config) []databroker.ServerOption {
func (srv *dataBrokerServer) getOptions(cfg *config.Config) []databroker.ServerOption {
return []databroker.ServerOption{
databroker.WithSharedKey(cfg.Options.SharedKey),
databroker.WithStorageType(cfg.Options.DataBrokerStorageType),
@ -36,3 +43,67 @@ func (srv *DataBrokerServer) getOptions(cfg *config.Config) []databroker.ServerO
databroker.WithStorageCertSkipVerify(cfg.Options.DataBrokerStorageCertSkipVerify),
}
}
func (srv *dataBrokerServer) setKey(cfg *config.Config) {
bs, _ := base64.StdEncoding.DecodeString(cfg.Options.SharedKey)
if bs == nil {
bs = make([]byte, 0)
}
srv.sharedKey.Store(bs)
}
func (srv *dataBrokerServer) Delete(ctx context.Context, req *databrokerpb.DeleteRequest) (*empty.Empty, error) {
if err := grpcutil.RequireSignedJWT(ctx, srv.sharedKey.Load().([]byte)); err != nil {
return nil, err
}
return srv.server.Delete(ctx, req)
}
func (srv *dataBrokerServer) Get(ctx context.Context, req *databrokerpb.GetRequest) (*databrokerpb.GetResponse, error) {
if err := grpcutil.RequireSignedJWT(ctx, srv.sharedKey.Load().([]byte)); err != nil {
return nil, err
}
return srv.server.Get(ctx, req)
}
func (srv *dataBrokerServer) GetAll(ctx context.Context, req *databrokerpb.GetAllRequest) (*databrokerpb.GetAllResponse, error) {
if err := grpcutil.RequireSignedJWT(ctx, srv.sharedKey.Load().([]byte)); err != nil {
return nil, err
}
return srv.server.GetAll(ctx, req)
}
func (srv *dataBrokerServer) Query(ctx context.Context, req *databrokerpb.QueryRequest) (*databrokerpb.QueryResponse, error) {
if err := grpcutil.RequireSignedJWT(ctx, srv.sharedKey.Load().([]byte)); err != nil {
return nil, err
}
return srv.server.Query(ctx, req)
}
func (srv *dataBrokerServer) Set(ctx context.Context, req *databrokerpb.SetRequest) (*databrokerpb.SetResponse, error) {
if err := grpcutil.RequireSignedJWT(ctx, srv.sharedKey.Load().([]byte)); err != nil {
return nil, err
}
return srv.server.Set(ctx, req)
}
func (srv *dataBrokerServer) Sync(req *databrokerpb.SyncRequest, stream databrokerpb.DataBrokerService_SyncServer) error {
if err := grpcutil.RequireSignedJWT(stream.Context(), srv.sharedKey.Load().([]byte)); err != nil {
return err
}
return srv.server.Sync(req, stream)
}
func (srv *dataBrokerServer) GetTypes(ctx context.Context, req *empty.Empty) (*databrokerpb.GetTypesResponse, error) {
if err := grpcutil.RequireSignedJWT(ctx, srv.sharedKey.Load().([]byte)); err != nil {
return nil, err
}
return srv.server.GetTypes(ctx, req)
}
func (srv *dataBrokerServer) SyncTypes(req *empty.Empty, stream databrokerpb.DataBrokerService_SyncTypesServer) error {
if err := grpcutil.RequireSignedJWT(stream.Context(), srv.sharedKey.Load().([]byte)); err != nil {
return err
}
return srv.server.SyncTypes(req, stream)
}

View file

@ -27,7 +27,8 @@ func init() {
lis = bufconn.Listen(bufSize)
s := grpc.NewServer()
internalSrv := internal_databroker.New()
srv := &DataBrokerServer{Server: internalSrv}
srv := &dataBrokerServer{server: internalSrv}
srv.sharedKey.Store([]byte{})
databroker.RegisterDataBrokerServiceServer(s, srv)
go func() {