build: prepare new structure for directives.

This commit is contained in:
Alexandre Pujol 2024-03-21 20:36:41 +00:00
parent e1d1d0be3d
commit 2ca62215bc
No known key found for this signature in database
GPG Key ID: C5469996F0DF68EC
4 changed files with 159 additions and 3 deletions

View File

@ -12,11 +12,13 @@ import (
"github.com/roddhjav/apparmor.d/pkg/logging"
oss "github.com/roddhjav/apparmor.d/pkg/os"
"github.com/roddhjav/apparmor.d/pkg/prebuild"
"github.com/roddhjav/apparmor.d/pkg/prebuild/directive"
)
const usage = `prebuild [-h] [--full] [--complain | --enforce]
const usage = `prebuild [-h] [--full] [--complain | --enforce] [profiles...]
Prebuild apparmor.d profiles for a given distribution.
Prebuild apparmor.d profiles for a given distribution and apply
internal built-in directives.
Options:
-h, --help Show this help message and exit.
@ -24,6 +26,8 @@ Options:
-c, --complain Set complain flag on all profiles.
-e, --enforce Set enforce flag on all profiles.
--abi4 Convert the profiles to Apparmor abi/4.0.
Directives:
`
var (
@ -73,7 +77,13 @@ func aaPrebuild() error {
}
func main() {
flag.Usage = func() { fmt.Print(usage) }
flag.Usage = func() {
res := usage
for _, d := range directive.Directives {
res += ` ` + d.Usage() + "\n"
}
fmt.Print(res)
}
flag.Parse()
if help {
flag.Usage()

View File

@ -0,0 +1,82 @@
// 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 (
"fmt"
"regexp"
"strings"
"github.com/arduino/go-paths-helper"
)
// Define the directive keyword globally
const Keyword = "#aa:"
// Build the profiles with the following directive applied
var Directives = map[string]Directive{}
var regDirective = regexp.MustCompile(`(?m).*` + Keyword + `([a-z]*) (.*)`)
// Main directive interface
type Directive interface {
Usage() string
Message() 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
type Option struct {
Name string
Args map[string]string
File *paths.Path
Raw string
}
func NewOption(file *paths.Path, match []string) *Option {
if len(match) != 3 {
panic(fmt.Sprintf("Invalid directive: %v", match))
}
args := map[string]string{}
for _, t := range strings.Fields(match[2]) {
tmp := strings.Split(t, "=")
if len(tmp) < 2 {
args[tmp[0]] = ""
} else {
args[tmp[0]] = tmp[1]
}
}
return &Option{
Name: match[1],
Args: args,
File: file,
Raw: match[0],
}
}
func Run(file *paths.Path, profile string) string {
for _, match := range regDirective.FindAllStringSubmatch(profile, -1) {
opt := NewOption(file, match)
drtv, ok := Directives[opt.Name]
if !ok {
panic(fmt.Sprintf("Unknown directive: %s", opt.Name))
}
profile = drtv.Apply(opt, profile)
}
return profile
}

View File

@ -0,0 +1,63 @@
// 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 (
"reflect"
"testing"
"github.com/arduino/go-paths-helper"
)
func TestNewOption(t *testing.T) {
tests := []struct {
name string
file *paths.Path
match []string
want *Option
}{
{
name: "dbus",
file: nil,
match: []string{
" #aa:dbus own bus=system name=org.gnome.DisplayManager",
"dbus",
"own bus=system name=org.gnome.DisplayManager",
},
want: &Option{
Name: "dbus",
Args: map[string]string{
"bus": "system",
"name": "org.gnome.DisplayManager",
"own": "",
},
File: paths.New(""),
Raw: " #aa:dbus own bus=system name=org.gnome.DisplayManager",
},
},
{
name: "only",
file: nil,
match: []string{
" #aa:only opensuse",
"only",
"opensuse",
},
want: &Option{
Name: "only",
Args: map[string]string{"opensuse": ""},
File: paths.New(""),
Raw: " #aa:only opensuse",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := NewOption(tt.file, tt.match); !reflect.DeepEqual(got, tt.want) {
t.Errorf("NewOption() = %v, want %v", got, tt.want)
}
})
}
}

View File

@ -89,6 +89,7 @@ func Build() error {
for _, fct := range Directives {
profile = fct(file, profile)
}
profile = directive.Run(file, profile)
if err := file.WriteFile([]byte(profile)); err != nil {
return err
}