mirror of
https://github.com/roddhjav/apparmor.d.git
synced 2024-12-26 06:58:00 +01:00
feat(aa-log): minor improvment in rule generation & formatting.
This commit is contained in:
parent
fbdf9cea64
commit
83bc7d3ade
7 changed files with 97 additions and 34 deletions
|
@ -9,8 +9,8 @@ import (
|
|||
)
|
||||
|
||||
type Base struct {
|
||||
IsLineRule bool
|
||||
Comment string
|
||||
IsLineRule bool
|
||||
NoNewPrivs bool
|
||||
FileInherit bool
|
||||
Optional bool
|
||||
|
|
|
@ -118,6 +118,21 @@ func (r *File) String() string {
|
|||
}
|
||||
|
||||
func (r *File) Validate() error {
|
||||
if !isAARE(r.Path) {
|
||||
return fmt.Errorf("'%s' is not a valid AARE", r.Path)
|
||||
}
|
||||
for _, v := range r.Access {
|
||||
if v == "" {
|
||||
continue
|
||||
}
|
||||
if !slices.Contains(requirements[r.Kind()]["access"], v) ||
|
||||
!slices.Contains(requirements[r.Kind()]["transition"], v) {
|
||||
return fmt.Errorf("invalid mode '%s'", v)
|
||||
}
|
||||
}
|
||||
if r.Target != "" && !isAARE(r.Target) {
|
||||
return fmt.Errorf("'%s' is not a valid AARE", r.Target)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -260,6 +275,12 @@ func (r *Link) String() string {
|
|||
}
|
||||
|
||||
func (r *Link) Validate() error {
|
||||
if !isAARE(r.Path) {
|
||||
return fmt.Errorf("'%s' is not a valid AARE", r.Path)
|
||||
}
|
||||
if !isAARE(r.Target) {
|
||||
return fmt.Errorf("'%s' is not a valid AARE", r.Target)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -17,10 +17,10 @@ const (
|
|||
func init() {
|
||||
requirements[MOUNT] = requirement{
|
||||
"flags": {
|
||||
"acl", "async", "atime", "ro", "rw", "bind", "rbind", "dev",
|
||||
"diratime", "dirsync", "exec", "iversion", "loud", "mand", "move",
|
||||
"noacl", "noatime", "nodev", "nodiratime", "noexec", "noiversion",
|
||||
"nomand", "norelatime", "nosuid", "nouser", "private", "relatime",
|
||||
"ro", "rw", "acl", "async", "atime", "bind", "dev", "diratime",
|
||||
"dirsync", "exec", "iversion", "loud", "mand", "move", "noacl",
|
||||
"noatime", "nodev", "nodiratime", "noexec", "noiversion", "nomand",
|
||||
"norelatime", "nosuid", "nouser", "private", "rbind", "relatime",
|
||||
"remount", "rprivate", "rshared", "rslave", "runbindable", "shared",
|
||||
"silent", "slave", "strictatime", "suid", "sync", "unbindable",
|
||||
"user", "verbose",
|
||||
|
|
|
@ -495,9 +495,15 @@ func (r rule) String() string {
|
|||
}
|
||||
|
||||
func isAARE(str string) bool {
|
||||
return strings.HasPrefix(str, "@") ||
|
||||
strings.HasPrefix(str, "/") ||
|
||||
strings.HasPrefix(str, "\"")
|
||||
if len(str) < 1 {
|
||||
return false
|
||||
}
|
||||
switch str[0] {
|
||||
case '@', '/', '"':
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Convert a slice of internal rules to a slice of ApparmorRule.
|
||||
|
@ -652,8 +658,8 @@ done:
|
|||
}
|
||||
|
||||
// Parse apparmor profile rules by paragraphs
|
||||
func ParseRules(input string) ([]Rules, []string, error) {
|
||||
paragraphRules := []Rules{}
|
||||
func ParseRules(input string) (ParaRules, []string, error) {
|
||||
paragraphRules := ParaRules{}
|
||||
paragraphs := []string{}
|
||||
|
||||
for _, match := range regParagraph.FindAllStringSubmatch(input, -1) {
|
||||
|
|
|
@ -139,16 +139,18 @@ func (p *Profile) GetAttachments() string {
|
|||
|
||||
var (
|
||||
newLogMap = map[string]func(log map[string]string) Rule{
|
||||
// class
|
||||
"rlimits": newRlimitFromLog,
|
||||
"cap": newCapabilityFromLog,
|
||||
"io_uring": newIOUringFromLog,
|
||||
"signal": newSignalFromLog,
|
||||
"ptrace": newPtraceFromLog,
|
||||
"namespace": newUsernsFromLog,
|
||||
"unix": newUnixFromLog,
|
||||
"dbus": newDbusFromLog,
|
||||
"cap": newCapabilityFromLog,
|
||||
"net": newNetworkFromLog,
|
||||
"posix_mqueue": newMqueueFromLog,
|
||||
"sysv_mqueue": newMqueueFromLog,
|
||||
"signal": newSignalFromLog,
|
||||
"ptrace": newPtraceFromLog,
|
||||
"unix": newUnixFromLog,
|
||||
"io_uring": newIOUringFromLog,
|
||||
"dbus": newDbusFromLog,
|
||||
"mount": func(log map[string]string) Rule {
|
||||
if strings.Contains(log["flags"], "remount") {
|
||||
return newRemountFromLog(log)
|
||||
|
@ -156,7 +158,6 @@ var (
|
|||
newRule := newLogMountMap[log["operation"]]
|
||||
return newRule(log)
|
||||
},
|
||||
"net": newNetworkFromLog,
|
||||
"file": func(log map[string]string) Rule {
|
||||
if log["operation"] == "change_onexec" {
|
||||
return newChangeProfileFromLog(log)
|
||||
|
@ -164,11 +165,16 @@ var (
|
|||
return newFileFromLog(log)
|
||||
}
|
||||
},
|
||||
// operation
|
||||
"capable": newCapabilityFromLog,
|
||||
"chmod": newFileFromLog,
|
||||
"exec": newFileFromLog,
|
||||
"getattr": newFileFromLog,
|
||||
"link": newFileFromLog,
|
||||
"mkdir": newFileFromLog,
|
||||
"mknod": newFileFromLog,
|
||||
"open": newFileFromLog,
|
||||
"rename_dest": newFileFromLog,
|
||||
"rename_src": newFileFromLog,
|
||||
"truncate": newFileFromLog,
|
||||
"unlink": newFileFromLog,
|
||||
|
@ -213,7 +219,7 @@ func (p *Profile) AddRule(log map[string]string) {
|
|||
case strings.Contains(log["operation"], "dbus"):
|
||||
p.Rules = append(p.Rules, newDbusFromLog(log))
|
||||
default:
|
||||
fmt.Printf("unknown log type: %s", log["operation"])
|
||||
fmt.Printf("unknown log type: %s\n", log["operation"])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ func (r Rules) Delete(i int) Rules {
|
|||
}
|
||||
|
||||
func (r Rules) DeleteKind(kind Kind) Rules {
|
||||
res := make(Rules, 0)
|
||||
res := make(Rules, 0, len(r))
|
||||
for _, rule := range r {
|
||||
if rule == nil {
|
||||
continue
|
||||
|
@ -106,8 +106,8 @@ func (r Rules) DeleteKind(kind Kind) Rules {
|
|||
return res
|
||||
}
|
||||
|
||||
func (r Rules) Filter(filter Kind) Rules {
|
||||
res := make(Rules, 0)
|
||||
func (r Rules) FilterOut(filter Kind) Rules {
|
||||
res := make(Rules, 0, len(r))
|
||||
for _, rule := range r {
|
||||
if rule == nil {
|
||||
continue
|
||||
|
@ -119,8 +119,21 @@ func (r Rules) Filter(filter Kind) Rules {
|
|||
return res
|
||||
}
|
||||
|
||||
func (r Rules) Filter(filter Kind) Rules {
|
||||
res := make(Rules, 0, len(r))
|
||||
for _, rule := range r {
|
||||
if rule == nil {
|
||||
continue
|
||||
}
|
||||
if rule.Kind() == filter {
|
||||
res = append(res, rule)
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (r Rules) GetVariables() []*Variable {
|
||||
res := make([]*Variable, 0)
|
||||
res := make([]*Variable, 0, len(r))
|
||||
for _, rule := range r {
|
||||
switch rule := rule.(type) {
|
||||
case *Variable:
|
||||
|
@ -131,7 +144,7 @@ func (r Rules) GetVariables() []*Variable {
|
|||
}
|
||||
|
||||
func (r Rules) GetIncludes() []*Include {
|
||||
res := make([]*Include, 0)
|
||||
res := make([]*Include, 0, len(r))
|
||||
for _, rule := range r {
|
||||
switch rule := rule.(type) {
|
||||
case *Include:
|
||||
|
@ -247,3 +260,20 @@ func (r Rules) Format() Rules {
|
|||
r.setPaddings(paddingsIndex, paddingsMaxLen)
|
||||
return r
|
||||
}
|
||||
|
||||
// ParaRules is a slice of Rules grouped by paragraph
|
||||
type ParaRules []Rules
|
||||
|
||||
func (r ParaRules) Flatten() Rules {
|
||||
totalLen := 0
|
||||
for i := range r {
|
||||
totalLen += len(r[i])
|
||||
}
|
||||
|
||||
res := make(Rules, 0, totalLen)
|
||||
for i := range r {
|
||||
res = append(res, r[i]...)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
|
|
@ -138,7 +138,7 @@ var (
|
|||
|
||||
// The order AARE should be sorted
|
||||
stringAlphabet = []byte(
|
||||
"!\"#$%&'*(){}[]+,-./:;<=>?@\\^_`|~0123456789abcdefghijklmnopqrstuvwxyz",
|
||||
"!\"#$%&'*(){}[]@+,-./:;<=>?\\^_`|~0123456789abcdefghijklmnopqrstuvwxyz",
|
||||
)
|
||||
stringWeights = generateWeights(stringAlphabet)
|
||||
|
||||
|
@ -232,11 +232,11 @@ func cjoin(i any) string {
|
|||
}
|
||||
}
|
||||
|
||||
func kindOf(i any) string {
|
||||
func kindOf(i Rule) string {
|
||||
if i == nil {
|
||||
return ""
|
||||
}
|
||||
return i.(Rule).Kind().String()
|
||||
return i.Kind().String()
|
||||
}
|
||||
|
||||
func setindent(i string) string {
|
||||
|
|
Loading…
Reference in a new issue