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 {
|
type Base struct {
|
||||||
IsLineRule bool
|
|
||||||
Comment string
|
Comment string
|
||||||
|
IsLineRule bool
|
||||||
NoNewPrivs bool
|
NoNewPrivs bool
|
||||||
FileInherit bool
|
FileInherit bool
|
||||||
Optional bool
|
Optional bool
|
||||||
|
|
|
@ -118,6 +118,21 @@ func (r *File) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *File) Validate() error {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,6 +275,12 @@ func (r *Link) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Link) Validate() error {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,10 +17,10 @@ const (
|
||||||
func init() {
|
func init() {
|
||||||
requirements[MOUNT] = requirement{
|
requirements[MOUNT] = requirement{
|
||||||
"flags": {
|
"flags": {
|
||||||
"acl", "async", "atime", "ro", "rw", "bind", "rbind", "dev",
|
"ro", "rw", "acl", "async", "atime", "bind", "dev", "diratime",
|
||||||
"diratime", "dirsync", "exec", "iversion", "loud", "mand", "move",
|
"dirsync", "exec", "iversion", "loud", "mand", "move", "noacl",
|
||||||
"noacl", "noatime", "nodev", "nodiratime", "noexec", "noiversion",
|
"noatime", "nodev", "nodiratime", "noexec", "noiversion", "nomand",
|
||||||
"nomand", "norelatime", "nosuid", "nouser", "private", "relatime",
|
"norelatime", "nosuid", "nouser", "private", "rbind", "relatime",
|
||||||
"remount", "rprivate", "rshared", "rslave", "runbindable", "shared",
|
"remount", "rprivate", "rshared", "rslave", "runbindable", "shared",
|
||||||
"silent", "slave", "strictatime", "suid", "sync", "unbindable",
|
"silent", "slave", "strictatime", "suid", "sync", "unbindable",
|
||||||
"user", "verbose",
|
"user", "verbose",
|
||||||
|
|
|
@ -495,9 +495,15 @@ func (r rule) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func isAARE(str string) bool {
|
func isAARE(str string) bool {
|
||||||
return strings.HasPrefix(str, "@") ||
|
if len(str) < 1 {
|
||||||
strings.HasPrefix(str, "/") ||
|
return false
|
||||||
strings.HasPrefix(str, "\"")
|
}
|
||||||
|
switch str[0] {
|
||||||
|
case '@', '/', '"':
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert a slice of internal rules to a slice of ApparmorRule.
|
// Convert a slice of internal rules to a slice of ApparmorRule.
|
||||||
|
@ -652,8 +658,8 @@ done:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse apparmor profile rules by paragraphs
|
// Parse apparmor profile rules by paragraphs
|
||||||
func ParseRules(input string) ([]Rules, []string, error) {
|
func ParseRules(input string) (ParaRules, []string, error) {
|
||||||
paragraphRules := []Rules{}
|
paragraphRules := ParaRules{}
|
||||||
paragraphs := []string{}
|
paragraphs := []string{}
|
||||||
|
|
||||||
for _, match := range regParagraph.FindAllStringSubmatch(input, -1) {
|
for _, match := range regParagraph.FindAllStringSubmatch(input, -1) {
|
||||||
|
|
|
@ -139,16 +139,18 @@ func (p *Profile) GetAttachments() string {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
newLogMap = map[string]func(log map[string]string) Rule{
|
newLogMap = map[string]func(log map[string]string) Rule{
|
||||||
|
// class
|
||||||
"rlimits": newRlimitFromLog,
|
"rlimits": newRlimitFromLog,
|
||||||
"cap": newCapabilityFromLog,
|
|
||||||
"io_uring": newIOUringFromLog,
|
|
||||||
"signal": newSignalFromLog,
|
|
||||||
"ptrace": newPtraceFromLog,
|
|
||||||
"namespace": newUsernsFromLog,
|
"namespace": newUsernsFromLog,
|
||||||
"unix": newUnixFromLog,
|
"cap": newCapabilityFromLog,
|
||||||
"dbus": newDbusFromLog,
|
"net": newNetworkFromLog,
|
||||||
"posix_mqueue": newMqueueFromLog,
|
"posix_mqueue": newMqueueFromLog,
|
||||||
"sysv_mqueue": newMqueueFromLog,
|
"sysv_mqueue": newMqueueFromLog,
|
||||||
|
"signal": newSignalFromLog,
|
||||||
|
"ptrace": newPtraceFromLog,
|
||||||
|
"unix": newUnixFromLog,
|
||||||
|
"io_uring": newIOUringFromLog,
|
||||||
|
"dbus": newDbusFromLog,
|
||||||
"mount": func(log map[string]string) Rule {
|
"mount": func(log map[string]string) Rule {
|
||||||
if strings.Contains(log["flags"], "remount") {
|
if strings.Contains(log["flags"], "remount") {
|
||||||
return newRemountFromLog(log)
|
return newRemountFromLog(log)
|
||||||
|
@ -156,7 +158,6 @@ var (
|
||||||
newRule := newLogMountMap[log["operation"]]
|
newRule := newLogMountMap[log["operation"]]
|
||||||
return newRule(log)
|
return newRule(log)
|
||||||
},
|
},
|
||||||
"net": newNetworkFromLog,
|
|
||||||
"file": func(log map[string]string) Rule {
|
"file": func(log map[string]string) Rule {
|
||||||
if log["operation"] == "change_onexec" {
|
if log["operation"] == "change_onexec" {
|
||||||
return newChangeProfileFromLog(log)
|
return newChangeProfileFromLog(log)
|
||||||
|
@ -164,14 +165,19 @@ var (
|
||||||
return newFileFromLog(log)
|
return newFileFromLog(log)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"exec": newFileFromLog,
|
// operation
|
||||||
"getattr": newFileFromLog,
|
"capable": newCapabilityFromLog,
|
||||||
"mkdir": newFileFromLog,
|
"chmod": newFileFromLog,
|
||||||
"mknod": newFileFromLog,
|
"exec": newFileFromLog,
|
||||||
"open": newFileFromLog,
|
"getattr": newFileFromLog,
|
||||||
"rename_src": newFileFromLog,
|
"link": newFileFromLog,
|
||||||
"truncate": newFileFromLog,
|
"mkdir": newFileFromLog,
|
||||||
"unlink": newFileFromLog,
|
"mknod": newFileFromLog,
|
||||||
|
"open": newFileFromLog,
|
||||||
|
"rename_dest": newFileFromLog,
|
||||||
|
"rename_src": newFileFromLog,
|
||||||
|
"truncate": newFileFromLog,
|
||||||
|
"unlink": newFileFromLog,
|
||||||
}
|
}
|
||||||
newLogMountMap = map[string]func(log map[string]string) Rule{
|
newLogMountMap = map[string]func(log map[string]string) Rule{
|
||||||
"mount": newMountFromLog,
|
"mount": newMountFromLog,
|
||||||
|
@ -213,7 +219,7 @@ func (p *Profile) AddRule(log map[string]string) {
|
||||||
case strings.Contains(log["operation"], "dbus"):
|
case strings.Contains(log["operation"], "dbus"):
|
||||||
p.Rules = append(p.Rules, newDbusFromLog(log))
|
p.Rules = append(p.Rules, newDbusFromLog(log))
|
||||||
default:
|
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 {
|
func (r Rules) DeleteKind(kind Kind) Rules {
|
||||||
res := make(Rules, 0)
|
res := make(Rules, 0, len(r))
|
||||||
for _, rule := range r {
|
for _, rule := range r {
|
||||||
if rule == nil {
|
if rule == nil {
|
||||||
continue
|
continue
|
||||||
|
@ -106,8 +106,8 @@ func (r Rules) DeleteKind(kind Kind) Rules {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r Rules) Filter(filter Kind) Rules {
|
func (r Rules) FilterOut(filter Kind) Rules {
|
||||||
res := make(Rules, 0)
|
res := make(Rules, 0, len(r))
|
||||||
for _, rule := range r {
|
for _, rule := range r {
|
||||||
if rule == nil {
|
if rule == nil {
|
||||||
continue
|
continue
|
||||||
|
@ -119,8 +119,21 @@ func (r Rules) Filter(filter Kind) Rules {
|
||||||
return res
|
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 {
|
func (r Rules) GetVariables() []*Variable {
|
||||||
res := make([]*Variable, 0)
|
res := make([]*Variable, 0, len(r))
|
||||||
for _, rule := range r {
|
for _, rule := range r {
|
||||||
switch rule := rule.(type) {
|
switch rule := rule.(type) {
|
||||||
case *Variable:
|
case *Variable:
|
||||||
|
@ -131,7 +144,7 @@ func (r Rules) GetVariables() []*Variable {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r Rules) GetIncludes() []*Include {
|
func (r Rules) GetIncludes() []*Include {
|
||||||
res := make([]*Include, 0)
|
res := make([]*Include, 0, len(r))
|
||||||
for _, rule := range r {
|
for _, rule := range r {
|
||||||
switch rule := rule.(type) {
|
switch rule := rule.(type) {
|
||||||
case *Include:
|
case *Include:
|
||||||
|
@ -247,3 +260,20 @@ func (r Rules) Format() Rules {
|
||||||
r.setPaddings(paddingsIndex, paddingsMaxLen)
|
r.setPaddings(paddingsIndex, paddingsMaxLen)
|
||||||
return r
|
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
|
// The order AARE should be sorted
|
||||||
stringAlphabet = []byte(
|
stringAlphabet = []byte(
|
||||||
"!\"#$%&'*(){}[]+,-./:;<=>?@\\^_`|~0123456789abcdefghijklmnopqrstuvwxyz",
|
"!\"#$%&'*(){}[]@+,-./:;<=>?\\^_`|~0123456789abcdefghijklmnopqrstuvwxyz",
|
||||||
)
|
)
|
||||||
stringWeights = generateWeights(stringAlphabet)
|
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 {
|
if i == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
return i.(Rule).Kind().String()
|
return i.Kind().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func setindent(i string) string {
|
func setindent(i string) string {
|
||||||
|
|
Loading…
Reference in a new issue