Skip to content

Commit

Permalink
Merge pull request #1649 from hashicorp/internal-policy-block
Browse files Browse the repository at this point in the history
Closes #1618
  • Loading branch information
Laura Bennett committed Jul 25, 2016
2 parents 02a9d87 + edc7baa commit 1d0b055
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 15 deletions.
12 changes: 6 additions & 6 deletions http/sys_policy_test.go
Expand Up @@ -17,8 +17,8 @@ func TestSysPolicies(t *testing.T) {

var actual map[string]interface{}
expected := map[string]interface{}{
"policies": []interface{}{"default", "response-wrapping", "root"},
"keys": []interface{}{"default", "response-wrapping", "root"},
"policies": []interface{}{"default", "root"},
"keys": []interface{}{"default", "root"},
}
testResponseStatus(t, resp, 200)
testResponseBody(t, resp, &actual)
Expand Down Expand Up @@ -62,8 +62,8 @@ func TestSysWritePolicy(t *testing.T) {

var actual map[string]interface{}
expected := map[string]interface{}{
"policies": []interface{}{"default", "foo", "response-wrapping", "root"},
"keys": []interface{}{"default", "foo", "response-wrapping", "root"},
"policies": []interface{}{"default", "foo", "root"},
"keys": []interface{}{"default", "foo", "root"},
}
testResponseStatus(t, resp, 200)
testResponseBody(t, resp, &actual)
Expand Down Expand Up @@ -100,8 +100,8 @@ func TestSysDeletePolicy(t *testing.T) {

var actual map[string]interface{}
expected := map[string]interface{}{
"policies": []interface{}{"default", "response-wrapping", "root"},
"keys": []interface{}{"default", "response-wrapping", "root"},
"policies": []interface{}{"default", "root"},
"keys": []interface{}{"default", "root"},
}
testResponseStatus(t, resp, 200)
testResponseBody(t, resp, &actual)
Expand Down
12 changes: 6 additions & 6 deletions vault/logical_system_test.go
Expand Up @@ -614,8 +614,8 @@ func TestSystemBackend_policyList(t *testing.T) {
}

exp := map[string]interface{}{
"keys": []string{"default", "response-wrapping", "root"},
"policies": []string{"default", "response-wrapping", "root"},
"keys": []string{"default", "root"},
"policies": []string{"default", "root"},
}
if !reflect.DeepEqual(resp.Data, exp) {
t.Fatalf("got: %#v expect: %#v", resp.Data, exp)
Expand Down Expand Up @@ -667,8 +667,8 @@ func TestSystemBackend_policyCRUD(t *testing.T) {
}

exp = map[string]interface{}{
"keys": []string{"default", "foo", "response-wrapping", "root"},
"policies": []string{"default", "foo", "response-wrapping", "root"},
"keys": []string{"default", "foo", "root"},
"policies": []string{"default", "foo", "root"},
}
if !reflect.DeepEqual(resp.Data, exp) {
t.Fatalf("got: %#v expect: %#v", resp.Data, exp)
Expand Down Expand Up @@ -702,8 +702,8 @@ func TestSystemBackend_policyCRUD(t *testing.T) {
}

exp = map[string]interface{}{
"keys": []string{"default", "response-wrapping", "root"},
"policies": []string{"default", "response-wrapping", "root"},
"keys": []string{"default", "root"},
"policies": []string{"default", "root"},
}
if !reflect.DeepEqual(resp.Data, exp) {
t.Fatalf("got: %#v expect: %#v", resp.Data, exp)
Expand Down
25 changes: 23 additions & 2 deletions vault/policy_store.go
Expand Up @@ -36,6 +36,9 @@ var (
"root",
cubbyholeResponseWrappingPolicyName,
}
nonAssignablePolicies = []string{
cubbyholeResponseWrappingPolicyName,
}
)

// PolicyStore is used to provide durable storage of policy, and to
Expand Down Expand Up @@ -89,7 +92,7 @@ func (c *Core) setupPolicyStore() error {
// Ensure that the cubbyhole response wrapping policy exists
policy, err = c.policyStore.GetPolicy(cubbyholeResponseWrappingPolicyName)
if err != nil {
return errwrap.Wrapf("error fetching default policy from store: {{err}}", err)
return errwrap.Wrapf("error fetching response-wrapping policy from store: {{err}}", err)
}
if policy == nil || policy.Raw != cubbyholeResponseWrappingPolicy {
err := c.policyStore.createCubbyholeResponseWrappingPolicy()
Expand Down Expand Up @@ -210,7 +213,25 @@ func (ps *PolicyStore) ListPolicies() ([]string, error) {
defer metrics.MeasureSince([]string{"policy", "list_policies"}, time.Now())
// Scan the view, since the policy names are the same as the
// key names.
return CollectKeys(ps.view)
keys, err := CollectKeys(ps.view)

for _, nonAssignable := range nonAssignablePolicies {
deleteIndex := -1
//Find indices of non-assignable policies in keys
for index, key := range keys {
if key == nonAssignable {
// Delete collection outside the loop
deleteIndex = index
break
}
}
// Remove non-assignable policies when found
if deleteIndex != -1 {
keys = append(keys[:deleteIndex], keys[deleteIndex+1:]...)
}
}

return keys, err
}

// DeletePolicy is used to delete the named policy
Expand Down
3 changes: 2 additions & 1 deletion vault/policy_store_test.go
Expand Up @@ -138,7 +138,8 @@ func TestPolicyStore_Predefined(t *testing.T) {
if err != nil {
t.Fatalf("err: %v", err)
}
if len(out) != 2 || out[0] != "default" || out[1] != "response-wrapping" {
// This shouldn't contain response-wrapping since it's non-assignable
if len(out) != 1 || out[0] != "default" {
t.Fatalf("bad: %v", out)
}

Expand Down
7 changes: 7 additions & 0 deletions vault/token_store.go
Expand Up @@ -1193,6 +1193,13 @@ func (ts *TokenStore) handleCreateCommon(
return logical.ErrorResponse(err.Error()), logical.ErrInvalidRequest
}

// Prevent internal policies from being assigned to tokens
for _, policy := range te.Policies {
if strutil.StrListContains(nonAssignablePolicies, policy) {
return logical.ErrorResponse(fmt.Sprintf("cannot assign %s policy", policy)), nil
}
}

// Generate the response
resp.Auth = &logical.Auth{
DisplayName: te.DisplayName,
Expand Down
26 changes: 26 additions & 0 deletions vault/token_store_test.go
Expand Up @@ -503,6 +503,32 @@ func TestTokenStore_RevokeSelf(t *testing.T) {
}
}

func TestTokenStore_HandleRequest_NonAssignable(t *testing.T) {
_, ts, _, root := TestCoreWithTokenStore(t)

req := logical.TestRequest(t, logical.UpdateOperation, "create")
req.ClientToken = root
req.Data["policies"] = []string{"default", "foo"}

resp, err := ts.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v %v", err, resp)
}

req.Data["policies"] = []string{"default", "foo", cubbyholeResponseWrappingPolicyName}

resp, err = ts.HandleRequest(req)
if err != nil {
t.Fatal(err)
}
if resp == nil {
t.Fatal("got a nil response")
}
if !resp.IsError() {
t.Fatalf("expected error; response is %#v", *resp)
}
}

func TestTokenStore_HandleRequest_CreateToken_DisplayName(t *testing.T) {
_, ts, _, root := TestCoreWithTokenStore(t)

Expand Down

0 comments on commit 1d0b055

Please sign in to comment.