Skip to content

Commit

Permalink
Merge pull request #1 from ChaseLEngel/permissions
Browse files Browse the repository at this point in the history
created structure for permissions and modified parsePaths in policy.g…
  • Loading branch information
Mwoolsey committed Oct 14, 2016
2 parents 956fa43 + e8cc6a0 commit a433f41
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 22 deletions.
55 changes: 42 additions & 13 deletions vault/acl.go
Expand Up @@ -47,24 +47,27 @@ func NewACL(policies []*Policy) (*ACL, error) {
// Check for an existing policy
raw, ok := tree.Get(pc.Prefix)
if !ok {
tree.Insert(pc.Prefix, pc.CapabilitiesBitmap)
tree.Insert(pc.Prefix, pc.Permissions)
continue
}
existing := raw.(uint32)
perm := raw.(Permissions)
existing := perm.CapabilitiesBitmap

switch {
case existing&DenyCapabilityInt > 0:
// If we are explicitly denied in the existing capability set,
// don't save anything else

case pc.CapabilitiesBitmap&DenyCapabilityInt > 0:
case pc.Permissions.CapabilitiesBitmap&DenyCapabilityInt > 0:
// If this new policy explicitly denies, only save the deny value
tree.Insert(pc.Prefix, DenyCapabilityInt)
pc.Permissions.CapabilitesBitmap = DenyCapabilityInt
tree.Insert(pc.Prefix, pc.Permissions)

default:
// Insert the capabilities in this new policy into the existing
// value
tree.Insert(pc.Prefix, existing|pc.CapabilitiesBitmap)
pc.Permissions.CapabilitesBitmap = existing | pc.Permissions.CapabilitesBitmap
tree.Insert(pc.Prefix, pc.Permissions)
}
}
}
Expand All @@ -80,8 +83,10 @@ func (a *ACL) Capabilities(path string) (pathCapabilities []string) {
// 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)
perm := raw.(Permissions)
capbilities := perm.CapabilitiesBitmap
goto CHECK
}

Expand All @@ -90,7 +95,8 @@ func (a *ACL) Capabilities(path string) (pathCapabilities []string) {
if !ok {
return []string{DenyCapability}
} else {
capabilities = raw.(uint32)
perm := raw.(Permissions)
capbilities := perm.CapabilitiesBitmap
}

CHECK:
Expand Down Expand Up @@ -124,12 +130,22 @@ CHECK:
// AllowOperation is used to check if the given operation is permitted. The
// first bool indicates if an op is allowed, the second whether sudo priviliges
// exist for that op and path.

// change arguments to hold a full request that holds the operation, path, and parameter
// that is to be modified.
//func (a *ACL) AllowOperation(req Request) (allowed bool, sudo bool) {
func (a *ACL) AllowOperation(op logical.Operation, path string) (allowed bool, sudo bool) {
// Fast-path root
if a.root {
return true, true
}

///////////////////////////////////////////////////////////////////////////////////
// Parse Request and set variables to check on
///////////////////////////////////////////////////////////////////////////////////
op := req.Operation
path := req.Path

// Help is always allowed
if op == logical.HelpOperation {
return true, false
Expand All @@ -156,24 +172,37 @@ CHECK:
// If "deny" has been explicitly set, only deny will be in the map, so we
// only need to check for the existence of other values
sudo = capabilities&SudoCapabilityInt > 0
operationAllowed := false
switch op {
case logical.ReadOperation:
allowed = capabilities&ReadCapabilityInt > 0
operationAllowed = capabilities&ReadCapabilityInt > 0
case logical.ListOperation:
allowed = capabilities&ListCapabilityInt > 0
operationAllowed = capabilities&ListCapabilityInt > 0
case logical.UpdateOperation:
allowed = capabilities&UpdateCapabilityInt > 0
operationAllowed = capabilities&UpdateCapabilityInt > 0
case logical.DeleteOperation:
allowed = capabilities&DeleteCapabilityInt > 0
operationAllowed = capabilities&DeleteCapabilityInt > 0
case logical.CreateOperation:
allowed = capabilities&CreateCapabilityInt > 0
operationAllowed = capabilities&CreateCapabilityInt > 0

// These three re-use UpdateCapabilityInt since that's the most appropriate capability/operation mapping
case logical.RevokeOperation, logical.RenewOperation, logical.RollbackOperation:
allowed = capabilities&UpdateCapabilityInt > 0
operationAllowed = capabilities&UpdateCapabilityInt > 0

default:
return false, false
}

if !operationAllowed {
return false, sudo
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
// need to know how to access parameter/parameters. If only one it is trivial to look it up,
// if there are many, have to loop through and check each one.
///////////////////////////////////////////////////////////////////////////////////////////////////////
//check whether parameter change is allowed

//if raw.AllowOperation[param_trying_to_be_set]

return
}
39 changes: 30 additions & 9 deletions vault/policy.go
Expand Up @@ -56,13 +56,22 @@ type Policy struct {
Raw string
}

type Permissions struct {
CapabilitiesBitmap uint32 `hcl:"-"`
AllowedParams map[string]bool
DisallowedParams map[string]bool
}

/*
*/
// PathCapabilities represents a policy for a path in the namespace.
type PathCapabilities struct {
Prefix string
Policy string
Capabilities []string
CapabilitiesBitmap uint32 `hcl:"-"`
Glob bool
Prefix string
Policy string
Capabilities []string
//CapabilitiesBitmap uint32 `hcl:"-"`
AclCapabilites *Permissions
Glob bool
}

// Parse is used to parse the specified ACL rules into an
Expand Down Expand Up @@ -107,16 +116,19 @@ func Parse(rules string) (*Policy, error) {
}

func parsePaths(result *Policy, list *ast.ObjectList) error {
// specifically how can we access the key value pairs for
// permissions
paths := make([]*PathCapabilities, 0, len(list.Items))
for _, item := range list.Items {
key := "path"
if len(item.Keys) > 0 {
key = item.Keys[0].Token.Value().(string)
key = item.Keys[0].Token.Value().(string) // "secret/foo"
}

valid := []string{
"policy",
"capabilities",
"permissions", // added here to validate
}
if err := checkHCLKeys(item.Val, valid); err != nil {
return multierror.Prefix(err, fmt.Sprintf("path %q:", key))
Expand Down Expand Up @@ -156,21 +168,30 @@ func parsePaths(result *Policy, list *ast.ObjectList) error {
}

// Initialize the map
pc.CapabilitiesBitmap = 0
pc.Permissions.CapabilitiesBitmap = 0
for _, cap := range pc.Capabilities {
switch cap {
// If it's deny, don't include any other capability
case DenyCapability:
pc.Capabilities = []string{DenyCapability}
pc.CapabilitiesBitmap = DenyCapabilityInt
pc.Permissions.CapabilitiesBitmap = DenyCapabilityInt
goto PathFinished
case CreateCapability, ReadCapability, UpdateCapability, DeleteCapability, ListCapability, SudoCapability:
pc.CapabilitiesBitmap |= cap2Int[cap]
pc.Permissions.CapabilitiesBitmap |= cap2Int[cap]
default:
return fmt.Errorf("path %q: invalid capability '%s'", key, cap)
}
}

//////////////////////////////////////////////////////////////////////////////

// filter out permissions from list object
// if p := item.Filter("permissions"); len(p.Whatever) > 0 {
// }

// go through p and initialize pc.Permissions.Allowed/Disallowed

//////////////////////////////////////////////////////////////////////////////
PathFinished:

paths = append(paths, &pc)
Expand Down

0 comments on commit a433f41

Please sign in to comment.