feat(build): add new filter directives.
This commit is contained in:
parent
2ca62215bc
commit
83691bbb1f
2 changed files with 207 additions and 0 deletions
75
pkg/prebuild/directive/filter.go
Normal file
75
pkg/prebuild/directive/filter.go
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
// apparmor.d - Full set of apparmor profiles
|
||||
// Copyright (C) 2021-2024 Alexandre Pujol <alexandre@pujol.io>
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
package directive
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
oss "github.com/roddhjav/apparmor.d/pkg/os"
|
||||
"golang.org/x/exp/maps"
|
||||
)
|
||||
|
||||
type FilterOnly struct {
|
||||
DirectiveBase
|
||||
}
|
||||
|
||||
type FilterExclude struct {
|
||||
DirectiveBase
|
||||
}
|
||||
|
||||
func init() {
|
||||
Directives["only"] = &FilterOnly{
|
||||
DirectiveBase: DirectiveBase{
|
||||
message: "Only directive applied",
|
||||
usage: `#aa:only <dist or familly>`,
|
||||
},
|
||||
}
|
||||
Directives["exclude"] = &FilterExclude{
|
||||
DirectiveBase: DirectiveBase{
|
||||
message: "Exclude directive applied",
|
||||
usage: `#aa:exclude <dist or familly>`,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func filterRuleForUs(opt *Option) bool {
|
||||
return slices.Contains(maps.Keys(opt.Args), oss.Distribution) || slices.Contains(maps.Keys(opt.Args), oss.Family)
|
||||
}
|
||||
|
||||
func filter(only bool, opt *Option, profile string) string {
|
||||
if only && filterRuleForUs(opt) {
|
||||
return profile
|
||||
}
|
||||
if !only && !filterRuleForUs(opt) {
|
||||
return profile
|
||||
}
|
||||
|
||||
inline := true
|
||||
tmp := strings.Split(opt.Raw, Keyword)
|
||||
if len(tmp) >= 1 {
|
||||
left := strings.TrimSpace(tmp[0])
|
||||
if len(left) == 0 {
|
||||
inline = false
|
||||
}
|
||||
}
|
||||
|
||||
if inline {
|
||||
profile = strings.Replace(profile, opt.Raw, "", -1)
|
||||
} else {
|
||||
regRemoveParagraph := regexp.MustCompile(`(?s)` + opt.Raw + `\n.*?\n\n`)
|
||||
profile = regRemoveParagraph.ReplaceAllString(profile, "")
|
||||
}
|
||||
return profile
|
||||
}
|
||||
|
||||
func (d FilterOnly) Apply(opt *Option, profile string) string {
|
||||
return filter(true, opt, profile)
|
||||
}
|
||||
|
||||
func (d FilterExclude) Apply(opt *Option, profile string) string {
|
||||
return filter(false, opt, profile)
|
||||
}
|
||||
132
pkg/prebuild/directive/filter_test.go
Normal file
132
pkg/prebuild/directive/filter_test.go
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
// apparmor.d - Full set of apparmor profiles
|
||||
// Copyright (C) 2021-2024 Alexandre Pujol <alexandre@pujol.io>
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
package directive
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
oss "github.com/roddhjav/apparmor.d/pkg/os"
|
||||
)
|
||||
|
||||
func TestFilterOnly_Apply(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
dist string
|
||||
family string
|
||||
opt *Option
|
||||
profile string
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "inline",
|
||||
dist: "debian",
|
||||
family: "apt",
|
||||
opt: &Option{
|
||||
Name: "only",
|
||||
Args: map[string]string{"apt": ""},
|
||||
File: nil,
|
||||
Raw: " @{bin}/arch-audit rPx, #aa:only apt",
|
||||
},
|
||||
profile: " @{bin}/arch-audit rPx, #aa:only apt",
|
||||
want: " @{bin}/arch-audit rPx, #aa:only apt",
|
||||
},
|
||||
{
|
||||
name: "paragraph",
|
||||
dist: "arch",
|
||||
family: "pacman",
|
||||
opt: &Option{
|
||||
Name: "only",
|
||||
Args: map[string]string{"zypper": ""},
|
||||
File: nil,
|
||||
Raw: " #aa:only zypper",
|
||||
},
|
||||
profile: `
|
||||
/tmp/apt-changelog-@{rand6}/ w,
|
||||
/tmp/apt-changelog-@{rand6}/*.changelog rw,
|
||||
owner /tmp/alpm_*/{,**} rw,
|
||||
owner /tmp/apt-changelog-@{rand6}/.apt-acquire-privs-test.@{rand6} rw,
|
||||
owner /tmp/packagekit* rw,
|
||||
|
||||
@{run}/systemd/inhibit/*.ref rw,
|
||||
owner @{run}/systemd/users/@{uid} r,
|
||||
|
||||
#aa:only zypper
|
||||
@{run}/zypp.pid rwk,
|
||||
owner @{run}/zypp-rpm.pid rwk,
|
||||
owner @{run}/zypp/packages/ r,
|
||||
|
||||
owner /dev/shm/AP_0x@{rand6}/{,**} rw,
|
||||
owner /dev/shm/ r,`,
|
||||
want: `
|
||||
/tmp/apt-changelog-@{rand6}/ w,
|
||||
/tmp/apt-changelog-@{rand6}/*.changelog rw,
|
||||
owner /tmp/alpm_*/{,**} rw,
|
||||
owner /tmp/apt-changelog-@{rand6}/.apt-acquire-privs-test.@{rand6} rw,
|
||||
owner /tmp/packagekit* rw,
|
||||
|
||||
@{run}/systemd/inhibit/*.ref rw,
|
||||
owner @{run}/systemd/users/@{uid} r,
|
||||
|
||||
owner /dev/shm/AP_0x@{rand6}/{,**} rw,
|
||||
owner /dev/shm/ r,`,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
oss.Distribution = tt.dist
|
||||
oss.Family = tt.family
|
||||
if got := Directives["only"].Apply(tt.opt, tt.profile); got != tt.want {
|
||||
t.Errorf("FilterOnly.Apply() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterExclude_Apply(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
dist string
|
||||
family string
|
||||
opt *Option
|
||||
profile string
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "inline",
|
||||
dist: "debian",
|
||||
family: "apt",
|
||||
opt: &Option{
|
||||
Name: "exclude",
|
||||
Args: map[string]string{"debian": ""},
|
||||
File: nil,
|
||||
Raw: " @{bin}/dpkg rPx -> child-dpkg, #aa:exclude debian",
|
||||
},
|
||||
profile: " @{bin}/dpkg rPx -> child-dpkg, #aa:exclude debian",
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
name: "inline-keep",
|
||||
dist: "whonix",
|
||||
family: "apt",
|
||||
opt: &Option{
|
||||
Name: "exclude",
|
||||
Args: map[string]string{"debian": ""},
|
||||
File: nil,
|
||||
Raw: " @{bin}/dpkg rPx -> child-dpkg, #aa:exclude debian",
|
||||
},
|
||||
profile: " @{bin}/dpkg rPx -> child-dpkg, #aa:exclude debian",
|
||||
want: " @{bin}/dpkg rPx -> child-dpkg, #aa:exclude debian",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
oss.Distribution = tt.dist
|
||||
oss.Family = tt.family
|
||||
if got := Directives["exclude"].Apply(tt.opt, tt.profile); got != tt.want {
|
||||
t.Errorf("FilterExclude.Apply() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue