diff --git a/pkg/aa/apparmor.go b/pkg/aa/apparmor.go index 36ed44c8..139ff234 100644 --- a/pkg/aa/apparmor.go +++ b/pkg/aa/apparmor.go @@ -19,19 +19,10 @@ type AppArmorProfileFiles map[string]*AppArmorProfileFile // - Some rules are not supported yet (subprofile, hat...) // - The structure is simplified as it only aims at writing profile, not parsing it. type AppArmorProfileFile struct { - Preamble + Preamble Rules Profiles []*Profile } -// Preamble section of a profile file, -type Preamble struct { - Abi []*Abi - Includes []*Include - Aliases []*Alias - Variables []*Variable - Comments []*RuleBase -} - func NewAppArmorProfile() *AppArmorProfileFile { return &AppArmorProfileFile{} } diff --git a/pkg/aa/apparmor_test.go b/pkg/aa/apparmor_test.go index 00d99d4f..dd0a9fe3 100644 --- a/pkg/aa/apparmor_test.go +++ b/pkg/aa/apparmor_test.go @@ -31,15 +31,16 @@ func TestAppArmorProfileFile_String(t *testing.T) { { name: "foo", f: &AppArmorProfileFile{ - Preamble: Preamble{ - Abi: []*Abi{{IsMagic: true, Path: "abi/4.0"}}, - Includes: []*Include{{IsMagic: true, Path: "tunables/global"}}, - Aliases: []*Alias{{Path: "/mnt/usr", RewrittenPath: "/usr"}}, - Variables: []*Variable{{ + Preamble: Rules{ + &Comment{RuleBase: RuleBase{Comment: " Simple test profile for the AppArmorProfileFile.String() method", IsLineRule: true}}, + nil, + &Abi{IsMagic: true, Path: "abi/4.0"}, + &Alias{Path: "/mnt/usr", RewrittenPath: "/usr"}, + &Include{IsMagic: true, Path: "tunables/global"}, + &Variable{ Name: "exec_path", Define: true, Values: []string{"@{bin}/foo", "@{lib}/foo"}, - }}, - Comments: []*RuleBase{{Comment: "Simple test profile for the AppArmorProfileFile.String() method", IsLineRule: true}}, + }, }, Profiles: []*Profile{{ Header: Header{ @@ -192,17 +193,16 @@ func TestAppArmorProfileFile_Integration(t *testing.T) { { name: "aa-status", f: &AppArmorProfileFile{ - Preamble: Preamble{ - Abi: []*Abi{{IsMagic: true, Path: "abi/3.0"}}, - Includes: []*Include{{IsMagic: true, Path: "tunables/global"}}, - Variables: []*Variable{{ + Preamble: Rules{ + &Comment{RuleBase: RuleBase{Comment: " apparmor.d - Full set of apparmor profiles", IsLineRule: true}}, + &Comment{RuleBase: RuleBase{Comment: " Copyright (C) 2021-2024 Alexandre Pujol ", IsLineRule: true}}, + &Comment{RuleBase: RuleBase{Comment: " SPDX-License-Identifier: GPL-2.0-only", IsLineRule: true}}, + nil, + &Abi{IsMagic: true, Path: "abi/3.0"}, + &Include{IsMagic: true, Path: "tunables/global"}, + &Variable{ Name: "exec_path", Define: true, Values: []string{"@{bin}/aa-status", "@{bin}/apparmor_status"}, - }}, - Comments: []*RuleBase{ - {Comment: "apparmor.d - Full set of apparmor profiles", IsLineRule: true}, - {Comment: "Copyright (C) 2021-2024 Alexandre Pujol ", IsLineRule: true}, - {Comment: "SPDX-License-Identifier: GPL-2.0-only", IsLineRule: true}, }, }, Profiles: []*Profile{{ diff --git a/pkg/aa/preamble.go b/pkg/aa/preamble.go index 6970bee5..8459099a 100644 --- a/pkg/aa/preamble.go +++ b/pkg/aa/preamble.go @@ -14,6 +14,40 @@ const ( tokIFEXISTS = "if exists" ) +type Comment struct { + RuleBase +} + +func newCommentFromRule(rule rule) (Rule, error) { + base := newRuleFromRule(rule) + base.IsLineRule = true + return &Comment{RuleBase: base}, nil +} + +func (r *Comment) Less(other any) bool { + return false +} + +func (r *Comment) Equals(other any) bool { + return false +} + +func (r *Comment) String() string { + return renderTemplate("comment", r) +} + +func (r *Comment) IsPreamble() bool { + return true +} + +func (r *Comment) Constraint() RuleConstraint { + return anyKind +} + +func (r *Comment) Kind() string { + return tokCOMMENT +} + type Abi struct { RuleBase Path string diff --git a/pkg/aa/template.go b/pkg/aa/template.go index 7cd78d53..8ee6d756 100644 --- a/pkg/aa/template.go +++ b/pkg/aa/template.go @@ -175,6 +175,9 @@ func cjoin(i any) string { } func typeOf(i any) string { + if i == nil { + return "" + } return strings.TrimPrefix(reflect.TypeOf(i).String(), "*aa.") } diff --git a/pkg/aa/templates/apparmor.j2 b/pkg/aa/templates/apparmor.j2 index 1686a7de..75a0026f 100644 --- a/pkg/aa/templates/apparmor.j2 +++ b/pkg/aa/templates/apparmor.j2 @@ -4,42 +4,7 @@ {{- define "apparmor" -}} - {{- with .Comments -}} - {{- range . -}} - {{- template "comment" . -}} - {{- "\n" -}} - {{- end -}} - {{- "\n" -}} - {{- end -}} - - {{- with .Abi -}} - {{- range . -}} - {{- template "abi" . -}} - {{- "\n" -}} - {{- end -}} - {{- "\n" -}} - {{- end -}} - - {{- with .Aliases -}} - {{- range . -}} - {{- template "alias" . -}} - {{- "\n" -}} - {{- end -}} - {{- "\n" -}} - {{- end -}} - - {{- with .Includes -}} - {{- range . -}} - {{- template "include" . -}} - {{- "\n" -}} - {{- end -}} - {{- "\n" -}} - {{- end -}} - - {{- range .Variables -}} - {{- template "variable" . -}} - {{- "\n" -}} - {{- end -}} + {{- template "rules" .Preamble -}} {{- range .Profiles -}} {{- template "profile" . -}} diff --git a/pkg/aa/templates/rule/comment.j2 b/pkg/aa/templates/rule/comment.j2 index 2a752288..abe41963 100644 --- a/pkg/aa/templates/rule/comment.j2 +++ b/pkg/aa/templates/rule/comment.j2 @@ -19,7 +19,7 @@ {{- " optional:" -}} {{- end -}} {{- with .Comment -}} - {{ " " }}{{ . }} + {{ . }} {{- end -}} {{- end -}} {{- end -}} diff --git a/pkg/aa/templates/rules.j2 b/pkg/aa/templates/rules.j2 index 8ab9bfb3..f2099334 100644 --- a/pkg/aa/templates/rules.j2 +++ b/pkg/aa/templates/rules.j2 @@ -7,7 +7,11 @@ {{- $oldtype := "" -}} {{- range . -}} {{- $type := typeof . -}} - {{- if eq $type "RuleBase" -}} + {{- if eq $type "" -}} + {{- "\n" -}} + {{- continue -}} + {{- end -}} + {{- if eq $type "Comment" -}} {{- template "comment" . -}} {{- "\n" -}} {{- continue -}} @@ -18,10 +22,22 @@ {{- end -}} {{- indent "" -}} + {{- if eq $type "Abi" -}} + {{- template "abi" . -}} + {{- end -}} + + {{- if eq $type "Alias" -}} + {{- template "alias" . -}} + {{- end -}} + {{- if eq $type "Include" -}} {{- template "include" . -}} {{- end -}} + {{- if eq $type "Variable" -}} + {{- template "variable" . -}} + {{- end -}} + {{- if eq $type "All" -}} {{- template "all" . -}} {{- end -}} diff --git a/pkg/aa/variables_test.go b/pkg/aa/variables_test.go index 778b3380..8f8f55fa 100644 --- a/pkg/aa/variables_test.go +++ b/pkg/aa/variables_test.go @@ -21,16 +21,14 @@ func TestDefaultTunables(t *testing.T) { { name: "aa", want: &AppArmorProfileFile{ - Preamble: Preamble{ - Variables: []*Variable{ - {Name: "bin", Values: []string{"/{,usr/}{,s}bin"}}, - {Name: "lib", Values: []string{"/{,usr/}lib{,exec,32,64}"}}, - {Name: "multiarch", Values: []string{"*-linux-gnu*"}}, - {Name: "HOME", Values: []string{"/home/*"}}, - {Name: "user_share_dirs", Values: []string{"/home/*/.local/share"}}, - {Name: "etc_ro", Values: []string{"/{,usr/}etc/"}}, - {Name: "int", Values: []string{"[0-9]{[0-9],}{[0-9],}{[0-9],}{[0-9],}{[0-9],}{[0-9],}{[0-9],}{[0-9],}{[0-9],}"}}, - }, + Preamble: Rules{ + &Variable{Name: "bin", Values: []string{"/{,usr/}{,s}bin"}}, + &Variable{Name: "lib", Values: []string{"/{,usr/}lib{,exec,32,64}"}}, + &Variable{Name: "multiarch", Values: []string{"*-linux-gnu*"}}, + &Variable{Name: "HOME", Values: []string{"/home/*"}}, + &Variable{Name: "user_share_dirs", Values: []string{"/home/*/.local/share"}}, + &Variable{Name: "etc_ro", Values: []string{"/{,usr/}etc/"}}, + &Variable{Name: "int", Values: []string{"[0-9]{[0-9],}{[0-9],}{[0-9],}{[0-9],}{[0-9],}{[0-9],}{[0-9],}{[0-9],}{[0-9],}"}}, }, }, },