make token create case insensitive [VAULT-1021] (#10743)

* make token create case insensitive

* changelog

* comment update
This commit is contained in:
Hridoy Roy 2021-01-27 09:56:54 -08:00 committed by GitHub
parent 4518d8a82f
commit 537189cab8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 104 additions and 2 deletions

3
changelog/10743.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:bug
core: Turn off case sensitivity for allowed entity alias check during token create operation.
```

View File

@ -2334,9 +2334,14 @@ func (ts *TokenStore) handleCreateCommon(ctx context.Context, req *logical.Reque
return logical.ErrorResponse("'entity_alias' is only allowed in combination with token role"), logical.ErrInvalidRequest return logical.ErrorResponse("'entity_alias' is only allowed in combination with token role"), logical.ErrInvalidRequest
} }
// Convert entity alias to lowercase to match the fact that role.AllowedEntityAliases
// has also been lowercased. An entity alias will keep its case formatting, but be
// treated as lowercase during any value cheek anywhere.
entityAlias := strings.ToLower(data.EntityAlias)
// Check if there is a concrete match // Check if there is a concrete match
if !strutil.StrListContains(role.AllowedEntityAliases, data.EntityAlias) && if !strutil.StrListContains(role.AllowedEntityAliases, entityAlias) &&
!strutil.StrListContainsGlob(role.AllowedEntityAliases, data.EntityAlias) { !strutil.StrListContainsGlob(role.AllowedEntityAliases, entityAlias) {
return logical.ErrorResponse("invalid 'entity_alias' value"), logical.ErrInvalidRequest return logical.ErrorResponse("invalid 'entity_alias' value"), logical.ErrInvalidRequest
} }

View File

@ -2704,6 +2704,99 @@ func TestTokenStore_HandleRequest_CreateToken_ExistingEntityAlias(t *testing.T)
} }
} }
func TestTokenStore_HandleRequest_CreateToken_ExistingEntityAliasMixedCase(t *testing.T) {
core, _, root := TestCoreUnsealed(t)
i := core.identityStore
ctx := namespace.RootContext(nil)
testPolicyName := "testpolicy"
entityAliasName := "tEStEntityAliaS"
entityAliasNameLower := "testentityalias"
testRoleName := "test"
// Create manually an entity
resp, err := i.HandleRequest(ctx, &logical.Request{
Path: "entity",
Operation: logical.UpdateOperation,
Data: map[string]interface{}{
"name": "testentity",
"policies": []string{testPolicyName},
},
})
if err != nil || (resp != nil && resp.IsError()) {
t.Fatalf("err: %v\nresp: %#v", err, resp)
}
entityID := resp.Data["id"].(string)
// Find mount accessor
resp, err = core.systemBackend.HandleRequest(namespace.RootContext(nil), &logical.Request{
Path: "auth",
Operation: logical.ReadOperation,
})
if err != nil || (resp != nil && resp.IsError()) {
t.Fatalf("bad: resp: %#v\nerr: %v", resp, err)
}
tokenMountAccessor := resp.Data["token/"].(map[string]interface{})["accessor"].(string)
// Create manually an entity alias
resp, err = i.HandleRequest(ctx, &logical.Request{
Path: "entity-alias",
Operation: logical.UpdateOperation,
Data: map[string]interface{}{
"name": entityAliasName,
"canonical_id": entityID,
"mount_accessor": tokenMountAccessor,
},
})
if err != nil {
t.Fatalf("error handling request: %v", err)
}
// Create token role
resp, err = core.HandleRequest(ctx, &logical.Request{
Path: "auth/token/roles/" + testRoleName,
ClientToken: root,
Operation: logical.CreateOperation,
Data: map[string]interface{}{
"orphan": true,
"period": "72h",
"path_suffix": "happenin",
"bound_cidrs": []string{"0.0.0.0/0"},
"allowed_entity_aliases": []string{"test1", "test2", entityAliasName},
},
})
if err != nil || (resp != nil && resp.IsError()) {
t.Fatalf("err: %v\nresp: %#v", err, resp)
}
respMixedCase, err := core.HandleRequest(ctx, &logical.Request{
Path: "auth/token/create/" + testRoleName,
Operation: logical.UpdateOperation,
ClientToken: root,
Data: map[string]interface{}{
"entity_alias": entityAliasName,
},
})
if respMixedCase.Auth.EntityID != entityID {
t.Fatalf("expected '%s' got '%s'", entityID, respMixedCase.Auth.EntityID)
}
// lowercase entity alias should match a mixed case alias
respLowerCase, err := core.HandleRequest(ctx, &logical.Request{
Path: "auth/token/create/" + testRoleName,
Operation: logical.UpdateOperation,
ClientToken: root,
Data: map[string]interface{}{
"entity_alias": entityAliasNameLower,
},
})
// A token created with the mixed case alias should return the same entity
// id as the normal case response.
if respLowerCase.Auth.EntityID != entityID {
t.Fatalf("expected '%s' got '%s'", entityID, respLowerCase.Auth.EntityID)
}
}
func TestTokenStore_HandleRequest_CreateToken_NonExistingEntityAlias(t *testing.T) { func TestTokenStore_HandleRequest_CreateToken_NonExistingEntityAlias(t *testing.T) {
core, _, root := TestCoreUnsealed(t) core, _, root := TestCoreUnsealed(t)
i := core.identityStore i := core.identityStore

View File

@ -709,6 +709,7 @@ tokens created against a role to be revoked using the
- `allowed_entity_aliases` `(string: "", or list: [])` - String or JSON list - `allowed_entity_aliases` `(string: "", or list: [])` - String or JSON list
of allowed entity aliases. If set, specifies the entity aliases which are of allowed entity aliases. If set, specifies the entity aliases which are
allowed to be used during token generation. This field supports globbing. allowed to be used during token generation. This field supports globbing.
Note that `allowed_entity_aliases` is not case sensitive.
@include 'tokenstorefields.mdx' @include 'tokenstorefields.mdx'