Merge pull request #5 from ChaseLEngel/permissions-chase

Permissions chase
This commit is contained in:
Chase L Engel 2016-10-24 11:43:52 -07:00 committed by GitHub
commit c9545c2afd
4 changed files with 58 additions and 25 deletions

View File

@ -50,7 +50,7 @@ func NewACL(policies []*Policy) (*ACL, error) {
tree.Insert(pc.Prefix, pc.Permissions)
continue
}
permissions := raw.(Permissions)
permissions := raw.(*Permissions)
existing := permissions.CapabilitiesBitmap
switch {
@ -109,7 +109,7 @@ func (a *ACL) Capabilities(path string) (pathCapabilities []string) {
raw, ok := a.exactRules.Get(path)
if ok {
perm := raw.(Permissions)
perm := raw.(*Permissions)
capabilities = perm.CapabilitiesBitmap
goto CHECK
}
@ -119,7 +119,7 @@ func (a *ACL) Capabilities(path string) (pathCapabilities []string) {
if !ok {
return []string{DenyCapability}
} else {
perm := raw.(Permissions)
perm := raw.(*Permissions)
capabilities = perm.CapabilitiesBitmap
}
@ -163,9 +163,6 @@ func (a *ACL) AllowOperation(req *logical.Request) (allowed bool, sudo bool) {
return true, true
}
///////////////////////////////////////////////////////////////////////////////////
// Parse Request and set variables to check on
///////////////////////////////////////////////////////////////////////////////////
op := req.Operation
path := req.Path
@ -174,11 +171,14 @@ func (a *ACL) AllowOperation(req *logical.Request) (allowed bool, sudo bool) {
return true, false
}
var permissions *Permissions
// Find an exact matching rule, look for glob if no match
var capabilities uint32
raw, ok := a.exactRules.Get(path)
if ok {
capabilities = raw.(uint32)
permissions = raw.(*Permissions)
capabilities = permissions.CapabilitiesBitmap
goto CHECK
}
@ -187,7 +187,8 @@ func (a *ACL) AllowOperation(req *logical.Request) (allowed bool, sudo bool) {
if !ok {
return false, false
} else {
capabilities = raw.(uint32)
permissions = raw.(*Permissions)
capabilities = permissions.CapabilitiesBitmap
}
CHECK:
@ -219,11 +220,29 @@ CHECK:
if !operationAllowed {
return false, sudo
}
//check whether parameter change is allowed
if op == logical.UpdateOperation || op == logical.CreateOperation || op == logical.DeleteOperation {
// Only check parameter permissions for operations that can modify parameters.
if op == logical.UpdateOperation || op == logical.DeleteOperation || op == logical.CreateOperation {
// Check if all parameters have been denied
if _, ok := permissions.DeniedParameters["*"]; ok {
return false, sudo
}
//if raw.AllowOperation[param_trying_to_be_set]
return
for parameter, _ := range req.Data {
// Check if parameter has explictly denied
if _, ok := permissions.DeniedParameters[parameter]; ok {
return false, sudo
}
// Specfic parameters have been allowed
if len(permissions.AllowedParameters) > 0 {
// Requested parameter is not in allowed list
if _, ok := permissions.AllowedParameters[parameter]; !ok {
return false, sudo
}
}
}
return true, sudo
}
return operationAllowed, sudo
}

View File

@ -59,7 +59,10 @@ func TestACL_Root(t *testing.T) {
t.Fatalf("err: %v", err)
}
allowed, rootPrivs := acl.AllowOperation(logical.UpdateOperation, "sys/mount/foo")
request := new(logical.Request)
request.Operation = logical.UpdateOperation
request.Path = "sys/mount/foo"
allowed, rootPrivs := acl.AllowOperation(request)
if !rootPrivs {
t.Fatalf("expected root")
}
@ -81,7 +84,10 @@ func TestACL_Single(t *testing.T) {
// Type of operation is not important here as we only care about checking
// sudo/root
_, rootPrivs := acl.AllowOperation(logical.ReadOperation, "sys/mount/foo")
request := new(logical.Request)
request.Operation = logical.ReadOperation
request.Path = "sys/mount/foo"
_, rootPrivs := acl.AllowOperation(request)
if rootPrivs {
t.Fatalf("unexpected root")
}
@ -117,7 +123,10 @@ func TestACL_Single(t *testing.T) {
}
for _, tc := range tcases {
allowed, rootPrivs := acl.AllowOperation(tc.op, tc.path)
request := new(logical.Request)
request.Operation = tc.op
request.Path = tc.path
allowed, rootPrivs := acl.AllowOperation(request)
if allowed != tc.allowed {
t.Fatalf("bad: case %#v: %v, %v", tc, allowed, rootPrivs)
}
@ -148,7 +157,10 @@ func TestACL_Layered(t *testing.T) {
func testLayeredACL(t *testing.T, acl *ACL) {
// Type of operation is not important here as we only care about checking
// sudo/root
_, rootPrivs := acl.AllowOperation(logical.ReadOperation, "sys/mount/foo")
request := new(logical.Request)
request.Operation = logical.ReadOperation
request.Path = "sys/mount/foo"
_, rootPrivs := acl.AllowOperation(request)
if rootPrivs {
t.Fatalf("unexpected root")
}
@ -189,7 +201,10 @@ func testLayeredACL(t *testing.T, acl *ACL) {
}
for _, tc := range tcases {
allowed, rootPrivs := acl.AllowOperation(tc.op, tc.path)
request := new(logical.Request)
request.Operation = tc.op
request.Path = tc.path
allowed, rootPrivs := acl.AllowOperation(request)
if allowed != tc.allowed {
t.Fatalf("bad: case %#v: %v, %v", tc, allowed, rootPrivs)
}

View File

@ -184,7 +184,6 @@ func parsePaths(result *Policy, list *ast.ObjectList) error {
return fmt.Errorf("path %q: invalid capability '%s'", key, cap)
}
}
fmt.Println(pc.Permissions)
PathFinished:

View File

@ -52,7 +52,7 @@ func TestPolicy_Parse(t *testing.T) {
&PathCapabilities{"", "deny",
[]string{
"deny",
}, DenyCapabilityInt, true},
}, &Permissions{CapabilitiesBitmap: DenyCapabilityInt}, true},
&PathCapabilities{"stage/", "sudo",
[]string{
"create",
@ -61,23 +61,23 @@ func TestPolicy_Parse(t *testing.T) {
"delete",
"list",
"sudo",
}, CreateCapabilityInt | ReadCapabilityInt | UpdateCapabilityInt |
DeleteCapabilityInt | ListCapabilityInt | SudoCapabilityInt, true},
}, &Permissions{CapabilitiesBitmap: (CreateCapabilityInt | ReadCapabilityInt | UpdateCapabilityInt |
DeleteCapabilityInt | ListCapabilityInt | SudoCapabilityInt)}, true},
&PathCapabilities{"prod/version", "read",
[]string{
"read",
"list",
}, ReadCapabilityInt | ListCapabilityInt, false},
}, &Permissions{CapabilitiesBitmap: (ReadCapabilityInt | ListCapabilityInt)}, false},
&PathCapabilities{"foo/bar", "read",
[]string{
"read",
"list",
}, ReadCapabilityInt | ListCapabilityInt, false},
}, &Permissions{CapabilitiesBitmap: (ReadCapabilityInt | ListCapabilityInt)}, false},
&PathCapabilities{"foo/bar", "",
[]string{
"create",
"sudo",
}, CreateCapabilityInt | SudoCapabilityInt, false},
}, &Permissions{CapabilitiesBitmap: (CreateCapabilityInt | SudoCapabilityInt)}, false},
}
if !reflect.DeepEqual(p.Paths, expect) {
t.Errorf("expected \n\n%#v\n\n to be \n\n%#v\n\n", p.Paths, expect)