build: update directives with the new interface.

This commit is contained in:
Alexandre Pujol 2024-03-25 22:40:25 +00:00
parent 38e9e5f08e
commit 08d4110c2a
No known key found for this signature in database
GPG key ID: C5469996F0DF68EC
9 changed files with 63 additions and 89 deletions

View file

@ -10,36 +10,25 @@ import (
"strings" "strings"
"github.com/arduino/go-paths-helper" "github.com/arduino/go-paths-helper"
"github.com/roddhjav/apparmor.d/pkg/prebuild/cfg"
) )
// Define the directive keyword globally // Define the directive keyword globally
const Keyword = "#aa:" const Keyword = "#aa:"
var (
// Build the profiles with the following directive applied // Build the profiles with the following directive applied
var Directives = map[string]Directive{} Directives = map[string]Directive{}
var regDirective = regexp.MustCompile(`(?m).*` + Keyword + `([a-z]*) (.*)`) regDirective = regexp.MustCompile(`(?m).*` + Keyword + `([a-z]*) (.*)`)
)
// Main directive interface // Main directive interface
type Directive interface { type Directive interface {
Usage() string cfg.BaseInterface
Message() string
Apply(opt *Option, profile string) string Apply(opt *Option, profile string) string
} }
type DirectiveBase struct {
message string
usage string
}
func (d *DirectiveBase) Usage() string {
return d.usage
}
func (d *DirectiveBase) Message() string {
return d.message
}
// Directive options // Directive options
type Option struct { type Option struct {
Name string Name string
@ -72,6 +61,10 @@ func NewOption(file *paths.Path, match []string) *Option {
} }
} }
func RegisterDirective(d Directive) {
Directives[d.Name()] = d
}
func Run(file *paths.Path, profile string) string { func Run(file *paths.Path, profile string) string {
for _, match := range regDirective.FindAllStringSubmatch(profile, -1) { for _, match := range regDirective.FindAllStringSubmatch(profile, -1) {
opt := NewOption(file, match) opt := NewOption(file, match)

View file

@ -11,32 +11,6 @@ import (
"github.com/arduino/go-paths-helper" "github.com/arduino/go-paths-helper"
) )
func TestDirective_Usage(t *testing.T) {
tests := []struct {
name string
d Directive
wantMessage string
wantUsage string
}{
{
name: "empty",
d: Directives["stack"],
wantMessage: "Stack directive applied",
wantUsage: `#aa:stack profiles_name...`,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := tt.d.Usage(); got != tt.wantUsage {
t.Errorf("Directive.Usage() = %v, want %v", got, tt.wantUsage)
}
if got := tt.d.Message(); got != tt.wantMessage {
t.Errorf("Directive.Usage() = %v, want %v", got, tt.wantMessage)
}
})
}
}
func TestNewOption(t *testing.T) { func TestNewOption(t *testing.T) {
tests := []struct { tests := []struct {
name string name string

View file

@ -18,6 +18,7 @@ import (
"strings" "strings"
"github.com/roddhjav/apparmor.d/pkg/aa" "github.com/roddhjav/apparmor.d/pkg/aa"
"github.com/roddhjav/apparmor.d/pkg/prebuild/cfg"
) )
var defaultInterfaces = []string{ var defaultInterfaces = []string{
@ -26,17 +27,18 @@ var defaultInterfaces = []string{
} }
type Dbus struct { type Dbus struct {
DirectiveBase cfg.Base
} }
func init() { func init() {
Directives["dbus"] = &Dbus{ RegisterDirective(&Dbus{
DirectiveBase: DirectiveBase{ Base: cfg.Base{
message: "Dbus directive applied", Keyword: "dbus",
usage: `#aa:dbus own bus=(system | session) name=<interface> Msg: "Dbus directive applied",
#aa:dbus talk bus=(system | session) name=<interface> label=<profile_name>`, Help: `#aa:dbus own bus=<bus> name=<name> [interface=AARE] [path=AARE]
#aa:dbus talk bus=<bus> name=<name> label=<profile> [interface=AARE] [path=AARE]`,
}, },
} })
} }
func setInterfaces(rules map[string]string) []string { func setInterfaces(rules map[string]string) []string {

View file

@ -8,20 +8,22 @@ import (
"strings" "strings"
"github.com/roddhjav/apparmor.d/pkg/aa" "github.com/roddhjav/apparmor.d/pkg/aa"
"github.com/roddhjav/apparmor.d/pkg/prebuild/cfg"
"golang.org/x/exp/slices" "golang.org/x/exp/slices"
) )
type Exec struct { type Exec struct {
DirectiveBase cfg.Base
} }
func init() { func init() {
Directives["exec"] = &Exec{ RegisterDirective(&Exec{
DirectiveBase: DirectiveBase{ Base: cfg.Base{
message: "Exec directive applied", Keyword: "exec",
usage: `#aa:exec [P|U|p|u|PU|pu|] profiles_name...`, Msg: "Exec directive applied",
Help: `#aa:exec [P|U|p|u|PU|pu|] profiles...`,
}, },
} })
} }
func (d Exec) Apply(opt *Option, profile string) string { func (d Exec) Apply(opt *Option, profile string) string {
@ -35,7 +37,7 @@ func (d Exec) Apply(opt *Option, profile string) string {
p := &aa.AppArmorProfile{} p := &aa.AppArmorProfile{}
for name := range opt.ArgMap { for name := range opt.ArgMap {
content, err := rootApparmord.Join(name).ReadFile() content, err := cfg.RootApparmord.Join(name).ReadFile()
if err != nil { if err != nil {
panic(err) panic(err)
} }

View file

@ -8,6 +8,7 @@ import (
"testing" "testing"
"github.com/arduino/go-paths-helper" "github.com/arduino/go-paths-helper"
"github.com/roddhjav/apparmor.d/pkg/prebuild/cfg"
) )
func TestExec_Apply(t *testing.T) { func TestExec_Apply(t *testing.T) {
@ -49,7 +50,7 @@ func TestExec_Apply(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
rootApparmord = tt.rootApparmord cfg.RootApparmord = tt.rootApparmord
if got := Directives["exec"].Apply(tt.opt, tt.profile); got != tt.want { if got := Directives["exec"].Apply(tt.opt, tt.profile); got != tt.want {
t.Errorf("Exec.Apply() = %v, want %v", got, tt.want) t.Errorf("Exec.Apply() = %v, want %v", got, tt.want)
} }

View file

@ -8,35 +8,37 @@ import (
"regexp" "regexp"
"strings" "strings"
oss "github.com/roddhjav/apparmor.d/pkg/os" "github.com/roddhjav/apparmor.d/pkg/prebuild/cfg"
"golang.org/x/exp/slices" "golang.org/x/exp/slices"
) )
type FilterOnly struct { type FilterOnly struct {
DirectiveBase cfg.Base
} }
type FilterExclude struct { type FilterExclude struct {
DirectiveBase cfg.Base
} }
func init() { func init() {
Directives["only"] = &FilterOnly{ RegisterDirective(&FilterOnly{
DirectiveBase: DirectiveBase{ Base: cfg.Base{
message: "Only directive applied", Keyword: "only",
usage: `#aa:only <dist or familly>`, Msg: "Only directive applied",
Help: `#aa:only filters...`,
}, },
} })
Directives["exclude"] = &FilterExclude{ RegisterDirective(&FilterExclude{
DirectiveBase: DirectiveBase{ Base: cfg.Base{
message: "Exclude directive applied", Keyword: "exclude",
usage: `#aa:exclude <dist or familly>`, Msg: "Exclude directive applied",
Help: `#aa:exclude filters...`,
}, },
} })
} }
func filterRuleForUs(opt *Option) bool { func filterRuleForUs(opt *Option) bool {
return slices.Contains(opt.ArgList, oss.Distribution) || slices.Contains(opt.ArgList, oss.Family) return slices.Contains(opt.ArgList, cfg.Distribution) || slices.Contains(opt.ArgList, cfg.Family)
} }
func filter(only bool, opt *Option, profile string) string { func filter(only bool, opt *Option, profile string) string {

View file

@ -7,7 +7,7 @@ package directive
import ( import (
"testing" "testing"
oss "github.com/roddhjav/apparmor.d/pkg/os" "github.com/roddhjav/apparmor.d/pkg/prebuild/cfg"
) )
func TestFilterOnly_Apply(t *testing.T) { func TestFilterOnly_Apply(t *testing.T) {
@ -77,8 +77,8 @@ func TestFilterOnly_Apply(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
oss.Distribution = tt.dist cfg.Distribution = tt.dist
oss.Family = tt.family cfg.Family = tt.family
if got := Directives["only"].Apply(tt.opt, tt.profile); got != tt.want { if got := Directives["only"].Apply(tt.opt, tt.profile); got != tt.want {
t.Errorf("FilterOnly.Apply() = %v, want %v", got, tt.want) t.Errorf("FilterOnly.Apply() = %v, want %v", got, tt.want)
} }
@ -126,8 +126,8 @@ func TestFilterExclude_Apply(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
oss.Distribution = tt.dist cfg.Distribution = tt.dist
oss.Family = tt.family cfg.Family = tt.family
if got := Directives["exclude"].Apply(tt.opt, tt.profile); got != tt.want { if got := Directives["exclude"].Apply(tt.opt, tt.profile); got != tt.want {
t.Errorf("FilterExclude.Apply() = %v, want %v", got, tt.want) t.Errorf("FilterExclude.Apply() = %v, want %v", got, tt.want)
} }

View file

@ -9,12 +9,10 @@ import (
"regexp" "regexp"
"strings" "strings"
"github.com/arduino/go-paths-helper" "github.com/roddhjav/apparmor.d/pkg/prebuild/cfg"
"github.com/roddhjav/apparmor.d/pkg/util" "github.com/roddhjav/apparmor.d/pkg/util"
) )
var rootApparmord = paths.New(".build/apparmor.d")
var ( var (
regRules = regexp.MustCompile(`(?m)^profile.*{$((.|\n)*)}`) regRules = regexp.MustCompile(`(?m)^profile.*{$((.|\n)*)}`)
regEndOfRules = regexp.MustCompile(`(?m)([\t ]*include if exists <.*>\n)+}`) regEndOfRules = regexp.MustCompile(`(?m)([\t ]*include if exists <.*>\n)+}`)
@ -27,22 +25,23 @@ var (
) )
type Stack struct { type Stack struct {
DirectiveBase cfg.Base
} }
func init() { func init() {
Directives["stack"] = &Stack{ RegisterDirective(&Stack{
DirectiveBase: DirectiveBase{ Base: cfg.Base{
message: "Stack directive applied", Keyword: "stack",
usage: `#aa:stack profiles_name...`, Msg: "Stack directive applied",
Help: `#aa:stack profiles...`,
}, },
} })
} }
func (s Stack) Apply(opt *Option, profile string) string { func (s Stack) Apply(opt *Option, profile string) string {
res := "" res := ""
for name := range opt.ArgMap { for name := range opt.ArgMap {
tmp, err := rootApparmord.Join(name).ReadFile() tmp, err := cfg.RootApparmord.Join(name).ReadFile()
if err != nil { if err != nil {
panic(err) panic(err)
} }

View file

@ -8,6 +8,7 @@ import (
"testing" "testing"
"github.com/arduino/go-paths-helper" "github.com/arduino/go-paths-helper"
"github.com/roddhjav/apparmor.d/pkg/prebuild/cfg"
) )
func TestStack_Apply(t *testing.T) { func TestStack_Apply(t *testing.T) {
@ -66,7 +67,7 @@ profile parent @{exec_path} {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
rootApparmord = tt.rootApparmord cfg.RootApparmord = tt.rootApparmord
if got := Directives["stack"].Apply(tt.opt, tt.profile); got != tt.want { if got := Directives["stack"].Apply(tt.opt, tt.profile); got != tt.want {
t.Errorf("Stack.Apply() = %v, want %v", got, tt.want) t.Errorf("Stack.Apply() = %v, want %v", got, tt.want)
} }