Skip to content

Commit

Permalink
fix #4504: ensure acl default rule matches all for unmarshalled json …
Browse files Browse the repository at this point in the history
…and yaml acls
  • Loading branch information
fbuetler committed Apr 17, 2024
1 parent f9c9639 commit e5b1f72
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 4 deletions.
21 changes: 17 additions & 4 deletions private/path/pathpol/acl.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ type ACL struct {

// NewACL creates a new entry and checks for the presence of a default action
func NewACL(entries ...*ACLEntry) (*ACL, error) {
if len(entries) == 0 || !entries[len(entries)-1].Rule.matchesAll() {
return nil, ErrNoDefault
if err := validateACL(entries); err != nil {
return nil, err
}
return &ACL{Entries: entries}, nil
}
Expand All @@ -61,15 +61,21 @@ func (a *ACL) MarshalJSON() ([]byte, error) {
}

func (a *ACL) UnmarshalJSON(b []byte) error {
return json.Unmarshal(b, &a.Entries)
if err := json.Unmarshal(b, &a.Entries); err != nil {
return err
}
return validateACL(a.Entries)
}

func (a *ACL) MarshalYAML() (interface{}, error) {
return a.Entries, nil
}

func (a *ACL) UnmarshalYAML(unmarshal func(interface{}) error) error {
return unmarshal(&a.Entries)
if err := unmarshal(&a.Entries); err != nil {
return err
}
return validateACL(a.Entries)
}

func (a *ACL) evalPath(pm *snet.PathMetadata) ACLAction {
Expand All @@ -90,6 +96,13 @@ func (a *ACL) evalInterface(iface snet.PathInterface, ingress bool) ACLAction {
panic("Default ACL action missing")
}

func validateACL(entries []*ACLEntry) error {
if len(entries) == 0 || !entries[len(entries)-1].Rule.matchesAll() {
return ErrNoDefault
}
return nil
}

type ACLEntry struct {
Action ACLAction
Rule *HopPredicate
Expand Down
29 changes: 29 additions & 0 deletions private/path/pathpol/acl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,35 @@ func TestNewACL(t *testing.T) {
}
}

func TestUnmarshalJSON(t *testing.T) {
tests := map[string]struct {
Input string
ExpectedErr error
}{
"No entry": {
Input: `[]`,
ExpectedErr: ErrNoDefault,
},
"No default entry": {
Input: `["+ 42"]`,
ExpectedErr: ErrNoDefault,
},
"Entry without rule": {
Input: `["+"]`,
},
"Entry with hop predicates": {
Input: `["+ 42", "-"]`,
},
}
for name, test := range tests {
t.Run(name, func(t *testing.T) {
var acl ACL
err := acl.UnmarshalJSON([]byte(test.Input))
assert.ErrorIs(t, err, test.ExpectedErr)
})
}
}

func TestACLEntryLoadFromString(t *testing.T) {
tests := map[string]struct {
String string
Expand Down

0 comments on commit e5b1f72

Please sign in to comment.