feat(aa): add rule constructors from internal parser.
This commit is contained in:
parent
ac9d6d859f
commit
163c5be61c
19 changed files with 456 additions and 75 deletions
|
|
@ -12,6 +12,10 @@ type All struct {
|
||||||
RuleBase
|
RuleBase
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newAll(q Qualifier, rule rule) (Rule, error) {
|
||||||
|
return &All{RuleBase: newBase(rule)}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *All) Validate() error {
|
func (r *All) Validate() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,17 +18,19 @@ type RuleBase struct {
|
||||||
Optional bool
|
Optional bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRule(rule []string) RuleBase {
|
func newBase(rule rule) RuleBase {
|
||||||
comment := ""
|
comment := ""
|
||||||
fileInherit, noNewPrivs, optional := false, false, false
|
fileInherit, noNewPrivs, optional := false, false, false
|
||||||
|
|
||||||
idx := 0
|
if len(rule) > 0 {
|
||||||
for idx < len(rule) {
|
if len(rule.Get(0)) > 0 && rule.Get(0)[0] == '#' {
|
||||||
if rule[idx] == COMMENT.Tok() {
|
// Line rule is a comment
|
||||||
comment = " " + strings.Join(rule[idx+1:], " ")
|
rule = rule[1:]
|
||||||
break
|
comment = rule.GetString()
|
||||||
|
} else {
|
||||||
|
// Comma rule, with comment at the end
|
||||||
|
comment = rule[len(rule)-1].comment
|
||||||
}
|
}
|
||||||
idx++
|
|
||||||
}
|
}
|
||||||
switch {
|
switch {
|
||||||
case strings.Contains(comment, "file_inherit"):
|
case strings.Contains(comment, "file_inherit"):
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,18 @@ type Capability struct {
|
||||||
Names []string
|
Names []string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newCapability(q Qualifier, rule rule) (Rule, error) {
|
||||||
|
names, err := toValues(CAPABILITY, "name", rule.GetString())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Capability{
|
||||||
|
RuleBase: newBase(rule),
|
||||||
|
Qualifier: q,
|
||||||
|
Names: names,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func newCapabilityFromLog(log map[string]string) Rule {
|
func newCapabilityFromLog(log map[string]string) Rule {
|
||||||
return &Capability{
|
return &Capability{
|
||||||
RuleBase: newBaseFromLog(log),
|
RuleBase: newBaseFromLog(log),
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,10 @@
|
||||||
|
|
||||||
package aa
|
package aa
|
||||||
|
|
||||||
import "fmt"
|
import (
|
||||||
|
"fmt"
|
||||||
|
"slices"
|
||||||
|
)
|
||||||
|
|
||||||
const CHANGEPROFILE Kind = "change_profile"
|
const CHANGEPROFILE Kind = "change_profile"
|
||||||
|
|
||||||
|
|
@ -22,6 +25,38 @@ type ChangeProfile struct {
|
||||||
ProfileName string
|
ProfileName string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newChangeProfile(q Qualifier, rule rule) (Rule, error) {
|
||||||
|
mode, exec, target := "", "", ""
|
||||||
|
if len(rule) > 0 {
|
||||||
|
if slices.Contains(requirements[CHANGEPROFILE]["mode"], rule.Get(0)) {
|
||||||
|
mode = rule.Get(0)
|
||||||
|
rule = rule[1:]
|
||||||
|
}
|
||||||
|
if len(rule) > 0 {
|
||||||
|
if rule.Get(0) != tokARROW {
|
||||||
|
exec = rule.Get(0)
|
||||||
|
if len(rule) > 2 {
|
||||||
|
if rule.Get(1) != tokARROW {
|
||||||
|
return nil, fmt.Errorf("missing '%s' in rule: %s", tokARROW, rule)
|
||||||
|
}
|
||||||
|
target = rule.Get(2)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if len(rule) > 1 {
|
||||||
|
target = rule.Get(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &ChangeProfile{
|
||||||
|
RuleBase: newBase(rule),
|
||||||
|
Qualifier: q,
|
||||||
|
ExecMode: mode,
|
||||||
|
Exec: exec,
|
||||||
|
ProfileName: target,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func newChangeProfileFromLog(log map[string]string) Rule {
|
func newChangeProfileFromLog(log map[string]string) Rule {
|
||||||
return &ChangeProfile{
|
return &ChangeProfile{
|
||||||
RuleBase: newBaseFromLog(log),
|
RuleBase: newBaseFromLog(log),
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,25 @@ type Dbus struct {
|
||||||
PeerLabel string
|
PeerLabel string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newDbus(q Qualifier, rule rule) (Rule, error) {
|
||||||
|
accesses, err := toAccess(DBUS, rule.GetString())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Dbus{
|
||||||
|
RuleBase: newBase(rule),
|
||||||
|
Qualifier: q,
|
||||||
|
Access: accesses,
|
||||||
|
Bus: rule.GetValuesAsString("bus"),
|
||||||
|
Name: rule.GetValuesAsString("name"),
|
||||||
|
Path: rule.GetValuesAsString("path"),
|
||||||
|
Interface: rule.GetValuesAsString("interface"),
|
||||||
|
Member: rule.GetValuesAsString("member"),
|
||||||
|
PeerName: rule.GetValues("peer").GetValuesAsString("name"),
|
||||||
|
PeerLabel: rule.GetValues("peer").GetValuesAsString("label"),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func newDbusFromLog(log map[string]string) Rule {
|
func newDbusFromLog(log map[string]string) Rule {
|
||||||
name := ""
|
name := ""
|
||||||
peerName := ""
|
peerName := ""
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,45 @@ type File struct {
|
||||||
Target string
|
Target string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newFile(q Qualifier, rule rule) (Rule, error) {
|
||||||
|
path, access, target, owner := "", "", "", false
|
||||||
|
if len(rule) > 0 {
|
||||||
|
if rule.Get(0) == tokOWNER {
|
||||||
|
owner = true
|
||||||
|
rule = rule[1:]
|
||||||
|
}
|
||||||
|
if rule.Get(0) == FILE.Tok() {
|
||||||
|
rule = rule[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
r := rule.GetSlice()
|
||||||
|
size := len(r)
|
||||||
|
if size < 2 {
|
||||||
|
return nil, fmt.Errorf("missing file or access in rule: %s", rule)
|
||||||
|
}
|
||||||
|
|
||||||
|
path, access = r[0], r[1]
|
||||||
|
if size > 2 {
|
||||||
|
if r[2] != tokARROW {
|
||||||
|
return nil, fmt.Errorf("missing '%s' in rule: %s", tokARROW, rule)
|
||||||
|
}
|
||||||
|
target = r[3]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
accesses, err := toAccess(FILE, access)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &File{
|
||||||
|
RuleBase: newBase(rule),
|
||||||
|
Qualifier: q,
|
||||||
|
Owner: owner,
|
||||||
|
Path: path,
|
||||||
|
Access: accesses,
|
||||||
|
Target: target,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func newFileFromLog(log map[string]string) Rule {
|
func newFileFromLog(log map[string]string) Rule {
|
||||||
accesses, err := toAccess("file-log", log["requested_mask"])
|
accesses, err := toAccess("file-log", log["requested_mask"])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -112,6 +151,40 @@ type Link struct {
|
||||||
Target string
|
Target string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newLink(q Qualifier, rule rule) (Rule, error) {
|
||||||
|
owner, subset, path, target := false, false, "", ""
|
||||||
|
if len(rule) > 0 {
|
||||||
|
if rule.Get(0) == tokOWNER {
|
||||||
|
owner = true
|
||||||
|
rule = rule[1:]
|
||||||
|
}
|
||||||
|
if len(rule) > 0 && rule.Get(0) == tokSUBSET {
|
||||||
|
subset = true
|
||||||
|
rule = rule[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
r := rule.GetSlice()
|
||||||
|
size := len(r)
|
||||||
|
if size > 0 {
|
||||||
|
path = r[0]
|
||||||
|
}
|
||||||
|
if size > 2 {
|
||||||
|
if r[1] != tokARROW {
|
||||||
|
return nil, fmt.Errorf("missing '%s' in rule: %s", tokARROW, rule)
|
||||||
|
}
|
||||||
|
target = r[2]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &Link{
|
||||||
|
RuleBase: newBase(rule),
|
||||||
|
Qualifier: q,
|
||||||
|
Owner: owner,
|
||||||
|
Subset: subset,
|
||||||
|
Path: path,
|
||||||
|
Target: target,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func newLinkFromLog(log map[string]string) Rule {
|
func newLinkFromLog(log map[string]string) Rule {
|
||||||
return &Link{
|
return &Link{
|
||||||
RuleBase: newBaseFromLog(log),
|
RuleBase: newBaseFromLog(log),
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,19 @@ type IOUring struct {
|
||||||
Label string
|
Label string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newIOUring(q Qualifier, rule rule) (Rule, error) {
|
||||||
|
accesses, err := toAccess(IOURING, rule.GetString())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &IOUring{
|
||||||
|
RuleBase: newBase(rule),
|
||||||
|
Qualifier: q,
|
||||||
|
Access: accesses,
|
||||||
|
Label: rule.GetValuesAsString("label"),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func newIOUringFromLog(log map[string]string) Rule {
|
func newIOUringFromLog(log map[string]string) Rule {
|
||||||
return &IOUring{
|
return &IOUring{
|
||||||
RuleBase: newBaseFromLog(log),
|
RuleBase: newBaseFromLog(log),
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,17 @@ type MountConditions struct {
|
||||||
Options []string
|
Options []string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newMountConditions(rule rule) (MountConditions, error) {
|
||||||
|
options, err := toValues(MOUNT, "flags", rule.GetValuesAsString("options"))
|
||||||
|
if err != nil {
|
||||||
|
return MountConditions{}, err
|
||||||
|
}
|
||||||
|
return MountConditions{
|
||||||
|
FsType: rule.GetValuesAsString("fstype"),
|
||||||
|
Options: options,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func newMountConditionsFromLog(log map[string]string) MountConditions {
|
func newMountConditionsFromLog(log map[string]string) MountConditions {
|
||||||
if _, present := log["flags"]; present {
|
if _, present := log["flags"]; present {
|
||||||
return MountConditions{
|
return MountConditions{
|
||||||
|
|
@ -62,6 +73,35 @@ type Mount struct {
|
||||||
MountPoint string
|
MountPoint string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newMount(q Qualifier, rule rule) (Rule, error) {
|
||||||
|
mount, src := "", ""
|
||||||
|
r := rule.GetSlice()
|
||||||
|
if len(r) > 0 {
|
||||||
|
if r[0] != tokARROW {
|
||||||
|
src = r[0]
|
||||||
|
r = r[1:]
|
||||||
|
}
|
||||||
|
if len(r) == 2 {
|
||||||
|
if r[0] != tokARROW {
|
||||||
|
return nil, fmt.Errorf("missing '%s' in rule: %s", tokARROW, rule)
|
||||||
|
}
|
||||||
|
mount = r[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
conditions, err := newMountConditions(rule)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Mount{
|
||||||
|
RuleBase: newBase(rule),
|
||||||
|
Qualifier: q,
|
||||||
|
MountConditions: conditions,
|
||||||
|
Source: src,
|
||||||
|
MountPoint: mount,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func newMountFromLog(log map[string]string) Rule {
|
func newMountFromLog(log map[string]string) Rule {
|
||||||
return &Mount{
|
return &Mount{
|
||||||
RuleBase: newBaseFromLog(log),
|
RuleBase: newBaseFromLog(log),
|
||||||
|
|
@ -112,6 +152,24 @@ type Umount struct {
|
||||||
MountPoint string
|
MountPoint string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newUmount(q Qualifier, rule rule) (Rule, error) {
|
||||||
|
mount := ""
|
||||||
|
r := rule.GetSlice()
|
||||||
|
if len(r) > 0 {
|
||||||
|
mount = r[0]
|
||||||
|
}
|
||||||
|
conditions, err := newMountConditions(rule)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Umount{
|
||||||
|
RuleBase: newBase(rule),
|
||||||
|
Qualifier: q,
|
||||||
|
MountConditions: conditions,
|
||||||
|
MountPoint: mount,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func newUmountFromLog(log map[string]string) Rule {
|
func newUmountFromLog(log map[string]string) Rule {
|
||||||
return &Umount{
|
return &Umount{
|
||||||
RuleBase: newBaseFromLog(log),
|
RuleBase: newBaseFromLog(log),
|
||||||
|
|
@ -158,6 +216,25 @@ type Remount struct {
|
||||||
MountPoint string
|
MountPoint string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newRemount(q Qualifier, rule rule) (Rule, error) {
|
||||||
|
mount := ""
|
||||||
|
r := rule.GetSlice()
|
||||||
|
if len(r) > 0 {
|
||||||
|
mount = r[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
conditions, err := newMountConditions(rule)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Remount{
|
||||||
|
RuleBase: newBase(rule),
|
||||||
|
Qualifier: q,
|
||||||
|
MountConditions: conditions,
|
||||||
|
MountPoint: mount,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func newRemountFromLog(log map[string]string) Rule {
|
func newRemountFromLog(log map[string]string) Rule {
|
||||||
return &Remount{
|
return &Remount{
|
||||||
RuleBase: newBaseFromLog(log),
|
RuleBase: newBaseFromLog(log),
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,31 @@ type Mqueue struct {
|
||||||
Name string
|
Name string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newMqueue(q Qualifier, rule rule) (Rule, error) {
|
||||||
|
access, name := "", ""
|
||||||
|
r := rule.GetSlice()
|
||||||
|
size := len(r)
|
||||||
|
if size > 0 {
|
||||||
|
access = strings.Join(r[:size-1], " ")
|
||||||
|
name = r[size-1]
|
||||||
|
if slices.Contains(requirements[MQUEUE]["access"], name) {
|
||||||
|
access += " " + name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
accesses, err := toAccess(MQUEUE, access)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Mqueue{
|
||||||
|
RuleBase: newBase(rule),
|
||||||
|
Qualifier: q,
|
||||||
|
Access: accesses,
|
||||||
|
Type: rule.GetValuesAsString("type"),
|
||||||
|
Label: rule.GetValuesAsString("label"),
|
||||||
|
Name: name,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func newMqueueFromLog(log map[string]string) Rule {
|
func newMqueueFromLog(log map[string]string) Rule {
|
||||||
mqueueType := "posix"
|
mqueueType := "posix"
|
||||||
if strings.Contains(log["class"], "posix") {
|
if strings.Contains(log["class"], "posix") {
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ package aa
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
const NETWORK Kind = "network"
|
const NETWORK Kind = "network"
|
||||||
|
|
@ -70,6 +71,28 @@ type Network struct {
|
||||||
Protocol string
|
Protocol string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newNetwork(q Qualifier, rule rule) (Rule, error) {
|
||||||
|
nType, protocol, domain := "", "", ""
|
||||||
|
r := rule.GetSlice()
|
||||||
|
if len(r) > 0 {
|
||||||
|
domain = r[0]
|
||||||
|
}
|
||||||
|
if len(r) >= 2 {
|
||||||
|
if slices.Contains(requirements[NETWORK]["type"], r[1]) {
|
||||||
|
nType = r[1]
|
||||||
|
} else if slices.Contains(requirements[NETWORK]["protocol"], r[1]) {
|
||||||
|
protocol = r[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &Network{
|
||||||
|
RuleBase: newBase(rule),
|
||||||
|
Qualifier: q,
|
||||||
|
Domain: domain,
|
||||||
|
Type: nType,
|
||||||
|
Protocol: protocol,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func newNetworkFromLog(log map[string]string) Rule {
|
func newNetworkFromLog(log map[string]string) Rule {
|
||||||
return &Network{
|
return &Network{
|
||||||
RuleBase: newBaseFromLog(log),
|
RuleBase: newBaseFromLog(log),
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,26 @@ const (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
newRuleMap = map[string]func(q Qualifier, r rule) (Rule, error){
|
newRuleMap = map[string]func(q Qualifier, r rule) (Rule, error){
|
||||||
|
ABI.Tok(): newAbi,
|
||||||
|
ALIAS.Tok(): newAlias,
|
||||||
|
ALL.Tok(): newAll,
|
||||||
|
"set": newRlimit,
|
||||||
|
USERNS.Tok(): newUserns,
|
||||||
|
CAPABILITY.Tok(): newCapability,
|
||||||
|
NETWORK.Tok(): newNetwork,
|
||||||
|
MOUNT.Tok(): newMount,
|
||||||
|
UMOUNT.Tok(): newUmount,
|
||||||
|
REMOUNT.Tok(): newRemount,
|
||||||
|
MQUEUE.Tok(): newMqueue,
|
||||||
|
IOURING.Tok(): newIOUring,
|
||||||
|
PIVOTROOT.Tok(): newPivotRoot,
|
||||||
|
CHANGEPROFILE.Tok(): newChangeProfile,
|
||||||
|
SIGNAL.Tok(): newSignal,
|
||||||
|
PTRACE.Tok(): newPtrace,
|
||||||
|
UNIX.Tok(): newUnix,
|
||||||
|
DBUS.Tok(): newDbus,
|
||||||
|
FILE.Tok(): newFile,
|
||||||
|
LINK.Tok(): newLink,
|
||||||
}
|
}
|
||||||
|
|
||||||
tok = map[Kind]string{
|
tok = map[Kind]string{
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
package aa
|
package aa
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
const PIVOTROOT Kind = "pivot_root"
|
const PIVOTROOT Kind = "pivot_root"
|
||||||
|
|
||||||
type PivotRoot struct {
|
type PivotRoot struct {
|
||||||
|
|
@ -14,6 +16,30 @@ type PivotRoot struct {
|
||||||
TargetProfile string
|
TargetProfile string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newPivotRoot(q Qualifier, rule rule) (Rule, error) {
|
||||||
|
newroot, target := "", ""
|
||||||
|
r := rule.GetSlice()
|
||||||
|
if len(r) > 0 {
|
||||||
|
if r[0] != tokARROW {
|
||||||
|
newroot = r[0]
|
||||||
|
r = r[1:]
|
||||||
|
}
|
||||||
|
if len(r) == 2 {
|
||||||
|
if r[0] != tokARROW {
|
||||||
|
return nil, fmt.Errorf("missing '%s' in rule: %s", tokARROW, rule)
|
||||||
|
}
|
||||||
|
target = r[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &PivotRoot{
|
||||||
|
RuleBase: newBase(rule),
|
||||||
|
Qualifier: q,
|
||||||
|
OldRoot: rule.GetValuesAsString("oldroot"),
|
||||||
|
NewRoot: newroot,
|
||||||
|
TargetProfile: target,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func newPivotRootFromLog(log map[string]string) Rule {
|
func newPivotRootFromLog(log map[string]string) Rule {
|
||||||
return &PivotRoot{
|
return &PivotRoot{
|
||||||
RuleBase: newBaseFromLog(log),
|
RuleBase: newBaseFromLog(log),
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,8 @@ type Comment struct {
|
||||||
RuleBase
|
RuleBase
|
||||||
}
|
}
|
||||||
|
|
||||||
func newComment(rule []string) (Rule, error) {
|
func newComment(rule rule) (Rule, error) {
|
||||||
base := newRule(rule)
|
base := newBase(rule)
|
||||||
base.IsLineRule = true
|
base.IsLineRule = true
|
||||||
return &Comment{RuleBase: base}, nil
|
return &Comment{RuleBase: base}, nil
|
||||||
}
|
}
|
||||||
|
|
@ -41,10 +41,6 @@ func (r *Comment) String() string {
|
||||||
return renderTemplate(r.Kind(), r)
|
return renderTemplate(r.Kind(), r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Comment) IsPreamble() bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Comment) Constraint() constraint {
|
func (r *Comment) Constraint() constraint {
|
||||||
return anyKind
|
return anyKind
|
||||||
}
|
}
|
||||||
|
|
@ -59,16 +55,13 @@ type Abi struct {
|
||||||
IsMagic bool
|
IsMagic bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func newAbi(rule []string) (Rule, error) {
|
func newAbi(q Qualifier, rule rule) (Rule, error) {
|
||||||
var magic bool
|
var magic bool
|
||||||
if len(rule) > 0 && rule[0] == ABI.Tok() {
|
|
||||||
rule = rule[1:]
|
|
||||||
}
|
|
||||||
if len(rule) != 1 {
|
if len(rule) != 1 {
|
||||||
return nil, fmt.Errorf("invalid abi format: %s", rule)
|
return nil, fmt.Errorf("invalid abi format: %s", rule)
|
||||||
}
|
}
|
||||||
|
|
||||||
path := rule[0]
|
path := rule.Get(0)
|
||||||
switch {
|
switch {
|
||||||
case path[0] == '"':
|
case path[0] == '"':
|
||||||
magic = false
|
magic = false
|
||||||
|
|
@ -78,7 +71,7 @@ func newAbi(rule []string) (Rule, error) {
|
||||||
return nil, fmt.Errorf("invalid path %s in rule: %s", path, rule)
|
return nil, fmt.Errorf("invalid path %s in rule: %s", path, rule)
|
||||||
}
|
}
|
||||||
return &Abi{
|
return &Abi{
|
||||||
RuleBase: newRule(rule),
|
RuleBase: newBase(rule),
|
||||||
Path: strings.Trim(path, "\"<>"),
|
Path: strings.Trim(path, "\"<>"),
|
||||||
IsMagic: magic,
|
IsMagic: magic,
|
||||||
}, nil
|
}, nil
|
||||||
|
|
@ -114,20 +107,17 @@ type Alias struct {
|
||||||
RewrittenPath string
|
RewrittenPath string
|
||||||
}
|
}
|
||||||
|
|
||||||
func newAlias(rule []string) (Rule, error) {
|
func newAlias(q Qualifier, rule rule) (Rule, error) {
|
||||||
if len(rule) > 0 && rule[0] == ALIAS.Tok() {
|
|
||||||
rule = rule[1:]
|
|
||||||
}
|
|
||||||
if len(rule) != 3 {
|
if len(rule) != 3 {
|
||||||
return nil, fmt.Errorf("invalid alias format: %s", rule)
|
return nil, fmt.Errorf("invalid alias format: %s", rule)
|
||||||
}
|
}
|
||||||
if rule[1] != tokARROW {
|
if rule.Get(1) != tokARROW {
|
||||||
return nil, fmt.Errorf("invalid alias format, missing %s in: %s", tokARROW, rule)
|
return nil, fmt.Errorf("invalid alias format, missing %s in: %s", tokARROW, rule)
|
||||||
}
|
}
|
||||||
return &Alias{
|
return &Alias{
|
||||||
RuleBase: newRule(rule),
|
RuleBase: newBase(rule),
|
||||||
Path: rule[0],
|
Path: rule.Get(0),
|
||||||
RewrittenPath: rule[2],
|
RewrittenPath: rule.Get(2),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -162,25 +152,22 @@ type Include struct {
|
||||||
IsMagic bool
|
IsMagic bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func newInclude(rule []string) (Rule, error) {
|
func newInclude(rule rule) (Rule, error) {
|
||||||
var magic bool
|
var magic bool
|
||||||
var ifexists bool
|
var ifexists bool
|
||||||
|
|
||||||
if len(rule) > 0 && rule[0] == INCLUDE.Tok() {
|
|
||||||
rule = rule[1:]
|
|
||||||
}
|
|
||||||
|
|
||||||
size := len(rule)
|
size := len(rule)
|
||||||
if size == 0 {
|
if size == 0 {
|
||||||
return nil, fmt.Errorf("invalid include format: %v", rule)
|
return nil, fmt.Errorf("invalid include format: %v", rule)
|
||||||
}
|
}
|
||||||
|
|
||||||
if size >= 3 && strings.Join(rule[:2], " ") == tokIFEXISTS {
|
r := rule.GetSlice()
|
||||||
|
if size >= 3 && strings.Join(r[:2], " ") == tokIFEXISTS {
|
||||||
ifexists = true
|
ifexists = true
|
||||||
rule = rule[2:]
|
r = r[2:]
|
||||||
}
|
}
|
||||||
|
|
||||||
path := rule[0]
|
path := r[0]
|
||||||
switch {
|
switch {
|
||||||
case path[0] == '"':
|
case path[0] == '"':
|
||||||
magic = false
|
magic = false
|
||||||
|
|
@ -190,7 +177,7 @@ func newInclude(rule []string) (Rule, error) {
|
||||||
return nil, fmt.Errorf("invalid path format: %v", path)
|
return nil, fmt.Errorf("invalid path format: %v", path)
|
||||||
}
|
}
|
||||||
return &Include{
|
return &Include{
|
||||||
RuleBase: newRule(rule),
|
RuleBase: newBase(rule),
|
||||||
IfExists: ifexists,
|
IfExists: ifexists,
|
||||||
Path: strings.Trim(path, "\"<>"),
|
Path: strings.Trim(path, "\"<>"),
|
||||||
IsMagic: magic,
|
IsMagic: magic,
|
||||||
|
|
@ -238,29 +225,27 @@ type Variable struct {
|
||||||
Define bool
|
Define bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func newVariable(rule []string) (Rule, error) {
|
func newVariableFromRule(rule rule) (Rule, error) {
|
||||||
var define bool
|
var define bool
|
||||||
var values []string
|
var values []string
|
||||||
if len(rule) < 3 {
|
if len(rule) < 3 {
|
||||||
return nil, fmt.Errorf("invalid variable format: %v", rule)
|
return nil, fmt.Errorf("invalid variable format: %v", rule)
|
||||||
}
|
}
|
||||||
|
|
||||||
name := strings.Trim(rule[0], VARIABLE.Tok()+"}")
|
r := rule.GetSlice()
|
||||||
switch rule[1] {
|
name := strings.Trim(rule.Get(0), VARIABLE.Tok()+"}")
|
||||||
|
switch rule.Get(1) {
|
||||||
case tokEQUAL:
|
case tokEQUAL:
|
||||||
define = true
|
define = true
|
||||||
values = tokensStripComment(rule[2:])
|
values = r[2:]
|
||||||
case tokPLUS:
|
case tokPLUS + tokEQUAL:
|
||||||
if rule[2] != tokEQUAL {
|
|
||||||
return nil, fmt.Errorf("invalid operator in variable: %v", rule)
|
|
||||||
}
|
|
||||||
define = false
|
define = false
|
||||||
values = tokensStripComment(rule[3:])
|
values = r[2:]
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("invalid operator in variable: %v", rule)
|
return nil, fmt.Errorf("invalid operator in variable: %v", rule)
|
||||||
}
|
}
|
||||||
return &Variable{
|
return &Variable{
|
||||||
RuleBase: newRule(rule),
|
RuleBase: newBase(rule),
|
||||||
Name: name,
|
Name: name,
|
||||||
Values: values,
|
Values: values,
|
||||||
Define: define,
|
Define: define,
|
||||||
|
|
|
||||||
|
|
@ -43,48 +43,29 @@ type Header struct {
|
||||||
Flags []string
|
Flags []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func newHeader(rule []string) (Header, error) {
|
func newHeader(rule rule) (Header, error) {
|
||||||
if len(rule) == 0 {
|
if len(rule) == 0 {
|
||||||
return Header{}, nil
|
return Header{}, nil
|
||||||
}
|
}
|
||||||
if rule[len(rule)-1] == "{" {
|
if rule.Get(0) == PROFILE.Tok() {
|
||||||
rule = rule[:len(rule)-1]
|
|
||||||
}
|
|
||||||
if rule[0] == PROFILE.Tok() {
|
|
||||||
rule = rule[1:]
|
rule = rule[1:]
|
||||||
}
|
}
|
||||||
|
|
||||||
delete := []int{}
|
|
||||||
flags := []string{}
|
|
||||||
attributes := make(map[string]string)
|
|
||||||
for idx, token := range rule {
|
|
||||||
if item, ok := strings.CutPrefix(token, tokFLAGS+"="); ok {
|
|
||||||
flags = tokenToSlice(item)
|
|
||||||
delete = append(delete, idx)
|
|
||||||
} else if item, ok := strings.CutPrefix(token, tokATTRIBUTES+"="); ok {
|
|
||||||
for _, m := range tokenToSlice(item) {
|
|
||||||
kv := strings.SplitN(m, "=", 2)
|
|
||||||
attributes[kv[0]] = kv[1]
|
|
||||||
}
|
|
||||||
delete = append(delete, idx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for i := len(delete) - 1; i >= 0; i-- {
|
|
||||||
rule = slices.Delete(rule, delete[i], delete[i]+1)
|
|
||||||
}
|
|
||||||
|
|
||||||
name, attachments := "", []string{}
|
name, attachments := "", []string{}
|
||||||
if len(rule) >= 1 {
|
if len(rule) >= 1 {
|
||||||
name = rule[0]
|
name = rule.Get(0)
|
||||||
if len(rule) > 1 {
|
if len(rule) > 1 {
|
||||||
attachments = rule[1:]
|
attachments = rule[1:].GetSlice()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
attributes := make(map[string]string)
|
||||||
|
for k, v := range rule.GetValues(tokATTRIBUTES).GetAsMap() {
|
||||||
|
attributes[k] = strings.Join(v, "")
|
||||||
|
}
|
||||||
return Header{
|
return Header{
|
||||||
Name: name,
|
Name: name,
|
||||||
Attachments: attachments,
|
Attachments: attachments,
|
||||||
Attributes: attributes,
|
Attributes: attributes,
|
||||||
Flags: flags,
|
Flags: rule.GetValuesAsSlice(tokFLAGS),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,19 @@ type Ptrace struct {
|
||||||
Peer string
|
Peer string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newPtrace(q Qualifier, rule rule) (Rule, error) {
|
||||||
|
accesses, err := toAccess(PTRACE, rule.GetString())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Ptrace{
|
||||||
|
RuleBase: newBase(rule),
|
||||||
|
Qualifier: q,
|
||||||
|
Access: accesses,
|
||||||
|
Peer: rule.GetValuesAsString("peer"),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func newPtraceFromLog(log map[string]string) Rule {
|
func newPtraceFromLog(log map[string]string) Rule {
|
||||||
return &Ptrace{
|
return &Ptrace{
|
||||||
RuleBase: newBaseFromLog(log),
|
RuleBase: newBaseFromLog(log),
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,21 @@ type Rlimit struct {
|
||||||
Value string
|
Value string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newRlimit(q Qualifier, rule rule) (Rule, error) {
|
||||||
|
if len(rule) != 4 {
|
||||||
|
return nil, fmt.Errorf("invalid set format: %s", rule)
|
||||||
|
}
|
||||||
|
if rule.Get(0) != RLIMIT.Tok() {
|
||||||
|
return nil, fmt.Errorf("invalid rlimit format: %s", rule)
|
||||||
|
}
|
||||||
|
return &Rlimit{
|
||||||
|
RuleBase: newBase(rule),
|
||||||
|
Key: rule.Get(1),
|
||||||
|
Op: rule.Get(2),
|
||||||
|
Value: rule.Get(3),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func newRlimitFromLog(log map[string]string) Rule {
|
func newRlimitFromLog(log map[string]string) Rule {
|
||||||
return &Rlimit{
|
return &Rlimit{
|
||||||
RuleBase: newBaseFromLog(log),
|
RuleBase: newBaseFromLog(log),
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,24 @@ type Signal struct {
|
||||||
Peer string
|
Peer string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newSignal(q Qualifier, rule rule) (Rule, error) {
|
||||||
|
accesses, err := toAccess(SIGNAL, rule.GetString())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
set, err := toValues(SIGNAL, "set", rule.GetValuesAsString("set"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Signal{
|
||||||
|
RuleBase: newBase(rule),
|
||||||
|
Qualifier: q,
|
||||||
|
Access: accesses,
|
||||||
|
Set: set,
|
||||||
|
Peer: rule.GetValuesAsString("peer"),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func newSignalFromLog(log map[string]string) Rule {
|
func newSignalFromLog(log map[string]string) Rule {
|
||||||
return &Signal{
|
return &Signal{
|
||||||
RuleBase: newBaseFromLog(log),
|
RuleBase: newBaseFromLog(log),
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,26 @@ type Unix struct {
|
||||||
PeerAddr string
|
PeerAddr string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newUnix(q Qualifier, rule rule) (Rule, error) {
|
||||||
|
accesses, err := toAccess(UNIX, rule.GetString())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Unix{
|
||||||
|
RuleBase: newBase(rule),
|
||||||
|
Qualifier: q,
|
||||||
|
Access: accesses,
|
||||||
|
Type: rule.GetValuesAsString("type"),
|
||||||
|
Protocol: rule.GetValuesAsString("protocol"),
|
||||||
|
Address: rule.GetValuesAsString("addr"),
|
||||||
|
Label: rule.GetValuesAsString("label"),
|
||||||
|
Attr: rule.GetValuesAsString("attr"),
|
||||||
|
Opt: rule.GetValuesAsString("opt"),
|
||||||
|
PeerLabel: rule.GetValues("peer").GetValuesAsString("label"),
|
||||||
|
PeerAddr: rule.GetValues("peer").GetValuesAsString("addr"),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func newUnixFromLog(log map[string]string) Rule {
|
func newUnixFromLog(log map[string]string) Rule {
|
||||||
return &Unix{
|
return &Unix{
|
||||||
RuleBase: newBaseFromLog(log),
|
RuleBase: newBaseFromLog(log),
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,26 @@ type Userns struct {
|
||||||
Create bool
|
Create bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newUserns(q Qualifier, rule rule) (Rule, error) {
|
||||||
|
var create bool
|
||||||
|
switch len(rule) {
|
||||||
|
case 0:
|
||||||
|
create = true
|
||||||
|
case 1:
|
||||||
|
if rule.Get(0) != "create" {
|
||||||
|
return nil, fmt.Errorf("invalid userns format: %s", rule)
|
||||||
|
}
|
||||||
|
create = true
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("invalid userns format: %s", rule)
|
||||||
|
}
|
||||||
|
return &Userns{
|
||||||
|
RuleBase: newBase(rule),
|
||||||
|
Qualifier: q,
|
||||||
|
Create: create,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func newUsernsFromLog(log map[string]string) Rule {
|
func newUsernsFromLog(log map[string]string) Rule {
|
||||||
return &Userns{
|
return &Userns{
|
||||||
RuleBase: newBaseFromLog(log),
|
RuleBase: newBaseFromLog(log),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue