Fix entropy sourcing on Vault Enterprise (#20684)
Note the three overlapping scenarios discussed in the comments. In the future, when this interface is more broadly supported, we should likely add the interface directly to SystemView and implement it over the GRPC interface, removing this nasty layering of already complex SystemView implementations. Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
This commit is contained in:
parent
f551f4e5ba
commit
9d2af72bde
|
@ -13,34 +13,103 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/hashicorp/vault/sdk/logical"
|
||||
|
||||
"github.com/hashicorp/go-kms-wrapping/entropy/v2"
|
||||
)
|
||||
|
||||
// See comment in command/format.go
|
||||
const hopeDelim = "♨"
|
||||
|
||||
type acmeBillingSystemViewImpl struct {
|
||||
extendedSystemView
|
||||
logical.ManagedKeySystemView
|
||||
|
||||
// acmeBillingImpl is the (single) implementation of the actual client
|
||||
// counting interface. It needs a reference to core (as per discussions
|
||||
// with Mike, in the future the activityLog reference will no longer be
|
||||
// static but may be replaced throughout the lifecycle of a core instance)
|
||||
// and a reference to the mount that is being counted.
|
||||
type acmeBillingImpl struct {
|
||||
core *Core
|
||||
entry *MountEntry
|
||||
}
|
||||
|
||||
var _ logical.ACMEBillingSystemView = (*acmeBillingSystemViewImpl)(nil)
|
||||
var _ logical.ACMEBillingSystemView = (*acmeBillingImpl)(nil)
|
||||
|
||||
func (c *Core) NewAcmeBillingSystemView(sysView interface{}, managed logical.ManagedKeySystemView) *acmeBillingSystemViewImpl {
|
||||
// Due to unfortunate layering of system view interfaces, there are three
|
||||
// possible sets of interfaces we need to layer with this ACME interface:
|
||||
//
|
||||
// 1. Everything: a managed key system view, an entropy sourcer, and an
|
||||
// extended system view.
|
||||
// 2. Managed keys without an entropy sourcer.
|
||||
// 3. Just extended system view.
|
||||
//
|
||||
// Unfortunately, just using acmeBillingSystemViewImpl is not sufficient:
|
||||
// because of the embedded interfaces, even when these are nil, the
|
||||
// implementation will claim to support these interfaces, (thus, their cast
|
||||
// being accepted by the toolchain), but when the caller goes to use the new
|
||||
// value, they are hit with a nil panic.
|
||||
//
|
||||
// This is unfortunate.
|
||||
//
|
||||
// To avoid this, we create three possible implementations and use the lowest
|
||||
// common denominator of the caller of NewAcmeBillingSystemView(...) to assume
|
||||
// it is _just_ an extendedSystemView implementation.
|
||||
|
||||
// Scenario 1 above.
|
||||
type acmeBillingSystemViewImpl struct {
|
||||
extendedSystemView
|
||||
logical.ManagedKeySystemView
|
||||
entropy.Sourcer
|
||||
acmeBillingImpl
|
||||
}
|
||||
|
||||
var (
|
||||
_ logical.ACMEBillingSystemView = (*acmeBillingSystemViewImpl)(nil)
|
||||
_ extendedSystemView = (*acmeBillingSystemViewImpl)(nil)
|
||||
_ logical.ManagedKeySystemView = (*acmeBillingSystemViewImpl)(nil)
|
||||
_ entropy.Sourcer = (*acmeBillingSystemViewImpl)(nil)
|
||||
)
|
||||
|
||||
// Scenario 2 above.
|
||||
type acmeBillingSystemViewImplNoSourcer struct {
|
||||
extendedSystemView
|
||||
logical.ManagedKeySystemView
|
||||
acmeBillingImpl
|
||||
}
|
||||
|
||||
var (
|
||||
_ logical.ACMEBillingSystemView = (*acmeBillingSystemViewImplNoSourcer)(nil)
|
||||
_ extendedSystemView = (*acmeBillingSystemViewImplNoSourcer)(nil)
|
||||
_ logical.ManagedKeySystemView = (*acmeBillingSystemViewImplNoSourcer)(nil)
|
||||
)
|
||||
|
||||
// Scenario 3 above.
|
||||
type acmeBillingSystemViewImplNoManagedKeys struct {
|
||||
extendedSystemView
|
||||
acmeBillingImpl
|
||||
}
|
||||
|
||||
var (
|
||||
_ logical.ACMEBillingSystemView = (*acmeBillingSystemViewImplNoManagedKeys)(nil)
|
||||
_ extendedSystemView = (*acmeBillingSystemViewImplNoManagedKeys)(nil)
|
||||
)
|
||||
|
||||
// NewAcmeBillingSystemView creates the appropriate implementation based on
|
||||
// the passed arguments, mapping them to the above scenarios. We further
|
||||
// restrict sysView to have a dynamicSystemView implementation, to get the
|
||||
// mount entry out of.
|
||||
func (c *Core) NewAcmeBillingSystemView(sysView interface{}) extendedSystemView {
|
||||
es := sysView.(extendedSystemViewImpl)
|
||||
des := es.dynamicSystemView
|
||||
|
||||
return &acmeBillingSystemViewImpl{
|
||||
extendedSystemView: es,
|
||||
ManagedKeySystemView: managed,
|
||||
core: c,
|
||||
entry: des.mountEntry,
|
||||
// Scenario 3.
|
||||
return &acmeBillingSystemViewImplNoManagedKeys{
|
||||
extendedSystemView: es,
|
||||
acmeBillingImpl: acmeBillingImpl{
|
||||
core: c,
|
||||
entry: des.mountEntry,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (a *acmeBillingSystemViewImpl) CreateActivityCountEventForIdentifiers(ctx context.Context, identifiers []string) error {
|
||||
func (a *acmeBillingImpl) CreateActivityCountEventForIdentifiers(ctx context.Context, identifiers []string) error {
|
||||
// Fake our clientID from the identifiers, but ensure it is
|
||||
// independent of ordering.
|
||||
//
|
||||
|
|
|
@ -64,5 +64,10 @@ func (c *Core) mountEntrySysView(entry *MountEntry) extendedSystemView {
|
|||
},
|
||||
}
|
||||
|
||||
return c.NewAcmeBillingSystemView(esi, nil /* managed keys system view */)
|
||||
// Due to complexity in the ACME interface, only return it when we
|
||||
// are a PKI plugin that needs it.
|
||||
if entry.Type != "pki" {
|
||||
return esi
|
||||
}
|
||||
return c.NewAcmeBillingSystemView(esi)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue