acl: do not resolve local tokens from remote dcs (#8068)

This commit is contained in:
Hans Hasselberg 2020-06-09 21:13:09 +02:00 committed by hashicorp-ci
parent 9e6718ad0f
commit a678b47c73
4 changed files with 53 additions and 2 deletions

View File

@ -417,6 +417,9 @@ func (r *ACLResolver) fetchAndCacheIdentityFromToken(token string, cached *struc
if resp.Token == nil {
r.cache.PutIdentity(cacheID, nil)
return nil, acl.ErrNotFound
} else if resp.Token.Local && r.config.Datacenter != resp.SourceDatacenter {
r.cache.PutIdentity(cacheID, nil)
return nil, acl.PermissionDeniedError{Cause: fmt.Sprintf("This is a local token in datacenter %q", resp.SourceDatacenter)}
} else {
r.cache.PutIdentity(cacheID, resp.Token)
return resp.Token, nil

View File

@ -260,6 +260,7 @@ func (a *ACL) TokenRead(args *structs.ACLTokenGetRequest, reply *structs.ACLToke
}
reply.Index, reply.Token = index, token
reply.SourceDatacenter = args.Datacenter
return nil
})
}

View File

@ -3703,3 +3703,49 @@ func TestDedupeServiceIdentities(t *testing.T) {
})
}
}
func TestACL_LocalToken(t *testing.T) {
t.Run("local token in same dc", func(t *testing.T) {
d := &ACLResolverTestDelegate{
datacenter: "dc1",
tokenReadFn: func(_ *structs.ACLTokenGetRequest, reply *structs.ACLTokenResponse) error {
reply.Token = &structs.ACLToken{Local: true}
// different dc
reply.SourceDatacenter = "dc1"
return nil
},
}
r := newTestACLResolver(t, d, nil)
_, err := r.fetchAndCacheIdentityFromToken("", nil)
require.NoError(t, err)
})
t.Run("non local token in remote dc", func(t *testing.T) {
d := &ACLResolverTestDelegate{
datacenter: "dc1",
tokenReadFn: func(_ *structs.ACLTokenGetRequest, reply *structs.ACLTokenResponse) error {
reply.Token = &structs.ACLToken{Local: false}
// different dc
reply.SourceDatacenter = "remote"
return nil
},
}
r := newTestACLResolver(t, d, nil)
_, err := r.fetchAndCacheIdentityFromToken("", nil)
require.NoError(t, err)
})
t.Run("local token in remote dc", func(t *testing.T) {
d := &ACLResolverTestDelegate{
datacenter: "dc1",
tokenReadFn: func(_ *structs.ACLTokenGetRequest, reply *structs.ACLTokenResponse) error {
reply.Token = &structs.ACLToken{Local: true}
// different dc
reply.SourceDatacenter = "remote"
return nil
},
}
r := newTestACLResolver(t, d, nil)
_, err := r.fetchAndCacheIdentityFromToken("", nil)
require.Equal(t, acl.PermissionDeniedError{Cause: "This is a local token in datacenter \"remote\""}, err)
})
}

View File

@ -1258,8 +1258,9 @@ type ACLTokenBootstrapRequest struct {
// ACLTokenResponse returns a single Token + metadata
type ACLTokenResponse struct {
Token *ACLToken
Redacted bool // whether the token's secret was redacted
Token *ACLToken
Redacted bool // whether the token's secret was redacted
SourceDatacenter string
QueryMeta
}