Skip to content

Commit

Permalink
secrets/auth: fix bug with aliased backends (#16673)
Browse files Browse the repository at this point in the history
* secrets/auth: fix bug with aliased backends

* add changelog

* update changelog to include affected backends
  • Loading branch information
fairclothjm authored Aug 11, 2022
1 parent 3f45993 commit fd6f904
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 4 deletions.
3 changes: 3 additions & 0 deletions changelog/16673.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
plugin/secrets/auth: Fix a bug with aliased backends such as aws-ec2 or generic
```
4 changes: 2 additions & 2 deletions vault/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -911,12 +911,12 @@ func (c *Core) newCredentialBackend(ctx context.Context, entry *MountEntry, sysV

f, ok := c.credentialBackends[t]
if !ok {
plug, err := c.pluginCatalog.Get(ctx, entry.Type, consts.PluginTypeCredential)
plug, err := c.pluginCatalog.Get(ctx, t, consts.PluginTypeCredential)
if err != nil {
return nil, err
}
if plug == nil {
return nil, fmt.Errorf("%w: %s", ErrPluginNotFound, entry.Type)
return nil, fmt.Errorf("%w: %s", ErrPluginNotFound, t)
}

f = plugin.Factory
Expand Down
59 changes: 59 additions & 0 deletions vault/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,65 @@ func TestCore_EnableCredential(t *testing.T) {
}
}

// TestCore_EnableCredential_aws_ec2 tests that we can successfully mount aws
// auth using the alias "aws-ec2"
func TestCore_EnableCredential_aws_ec2(t *testing.T) {
c, keys, _ := TestCoreUnsealed(t)
c.credentialBackends["aws"] = func(context.Context, *logical.BackendConfig) (logical.Backend, error) {
return &NoopBackend{
BackendType: logical.TypeCredential,
}, nil
}

me := &MountEntry{
Table: credentialTableType,
Path: "foo",
Type: "aws-ec2",
}
err := c.enableCredential(namespace.RootContext(nil), me)
if err != nil {
t.Fatalf("err: %v", err)
}

match := c.router.MatchingMount(namespace.RootContext(nil), "auth/foo/bar")
if match != "auth/foo/" {
t.Fatalf("missing mount, match: %q", match)
}

inmemSink := metrics.NewInmemSink(1000000*time.Hour, 2000000*time.Hour)
conf := &CoreConfig{
Physical: c.physical,
DisableMlock: true,
BuiltinRegistry: NewMockBuiltinRegistry(),
MetricSink: metricsutil.NewClusterMetricSink("test-cluster", inmemSink),
MetricsHelper: metricsutil.NewMetricsHelper(inmemSink, false),
}
c2, err := NewCore(conf)
if err != nil {
t.Fatalf("err: %v", err)
}
defer c2.Shutdown()
c2.credentialBackends["noop"] = func(context.Context, *logical.BackendConfig) (logical.Backend, error) {
return &NoopBackend{
BackendType: logical.TypeCredential,
}, nil
}
for i, key := range keys {
unseal, err := TestCoreUnseal(c2, key)
if err != nil {
t.Fatalf("err: %v", err)
}
if i+1 == len(keys) && !unseal {
t.Fatalf("should be unsealed")
}
}

// Verify matching auth tables
if !reflect.DeepEqual(c.auth, c2.auth) {
t.Fatalf("mismatch: %v %v", c.auth, c2.auth)
}
}

// Test that the local table actually gets populated as expected with local
// entries, and that upon reading the entries from both are recombined
// correctly
Expand Down
4 changes: 2 additions & 2 deletions vault/mount.go
Original file line number Diff line number Diff line change
Expand Up @@ -1419,12 +1419,12 @@ func (c *Core) newLogicalBackend(ctx context.Context, entry *MountEntry, sysView

f, ok := c.logicalBackends[t]
if !ok {
plug, err := c.pluginCatalog.Get(ctx, entry.Type, consts.PluginTypeSecrets)
plug, err := c.pluginCatalog.Get(ctx, t, consts.PluginTypeSecrets)
if err != nil {
return nil, err
}
if plug == nil {
return nil, fmt.Errorf("%w: %s", ErrPluginNotFound, entry.Type)
return nil, fmt.Errorf("%w: %s", ErrPluginNotFound, t)
}

f = plugin.Factory
Expand Down
48 changes: 48 additions & 0 deletions vault/mount_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,54 @@ func TestCore_Mount(t *testing.T) {
}
}

// TestCore_Mount_kv_generic tests that we can successfully mount kv using the
// kv alias "generic"
func TestCore_Mount_kv_generic(t *testing.T) {
c, keys, _ := TestCoreUnsealed(t)
me := &MountEntry{
Table: mountTableType,
Path: "foo",
Type: "generic",
}
err := c.mount(namespace.RootContext(nil), me)
if err != nil {
t.Fatalf("err: %v", err)
}

match := c.router.MatchingMount(namespace.RootContext(nil), "foo/bar")
if match != "foo/" {
t.Fatalf("missing mount")
}

inmemSink := metrics.NewInmemSink(1000000*time.Hour, 2000000*time.Hour)
conf := &CoreConfig{
Physical: c.physical,
DisableMlock: true,
BuiltinRegistry: NewMockBuiltinRegistry(),
MetricSink: metricsutil.NewClusterMetricSink("test-cluster", inmemSink),
MetricsHelper: metricsutil.NewMetricsHelper(inmemSink, false),
}
c2, err := NewCore(conf)
if err != nil {
t.Fatalf("err: %v", err)
}
defer c2.Shutdown()
for i, key := range keys {
unseal, err := TestCoreUnseal(c2, key)
if err != nil {
t.Fatalf("err: %v", err)
}
if i+1 == len(keys) && !unseal {
t.Fatalf("should be unsealed")
}
}

// Verify matching mount tables
if diff := deep.Equal(c.mounts.sortEntriesByPath(), c2.mounts.sortEntriesByPath()); len(diff) > 0 {
t.Fatalf("mismatch: %v", diff)
}
}

// Test that the local table actually gets populated as expected with local
// entries, and that upon reading the entries from both are recombined
// correctly
Expand Down
10 changes: 10 additions & 0 deletions vault/testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -2166,6 +2166,7 @@ func NewMockBuiltinRegistry() *mockBuiltinRegistry {
"mysql-database-plugin": consts.PluginTypeDatabase,
"postgresql-database-plugin": consts.PluginTypeDatabase,
"approle": consts.PluginTypeCredential,
"aws": consts.PluginTypeCredential,
},
}
}
Expand All @@ -2188,6 +2189,15 @@ func (m *mockBuiltinRegistry) Get(name string, pluginType consts.PluginType) (fu
return toFunc(approle.Factory), true
}

if name == "aws" {
return toFunc(func(ctx context.Context, config *logical.BackendConfig) (logical.Backend, error) {
b := new(framework.Backend)
b.Setup(ctx, config)
b.BackendType = logical.TypeCredential
return b, nil
}), true
}

if name == "postgresql-database-plugin" {
return toFunc(func(ctx context.Context, config *logical.BackendConfig) (logical.Backend, error) {
b := new(framework.Backend)
Expand Down

0 comments on commit fd6f904

Please sign in to comment.