apparmor.d/pkg/aa/profile.go
2023-09-01 19:26:52 +01:00

90 lines
2.5 KiB
Go

// apparmor.d - Full set of apparmor profiles
// Copyright (C) 2023 Alexandre Pujol <alexandre@pujol.io>
// SPDX-License-Identifier: GPL-2.0-only
package aa
import (
"bytes"
"strings"
"golang.org/x/exp/slices"
)
// AppArmorProfiles represents a full set of apparmor profiles
type AppArmorProfiles map[string]*AppArmorProfile
// ApparmorProfile represents a full apparmor profile.
// Warning: close to the BNF grammar of apparmor profile but not exactly the same (yet):
// - Some rules are not supported yet (subprofile, hat...)
// - The structure is simplified as it only aims at writing profile, not parsing it.
type AppArmorProfile struct {
Preamble
Profile
}
func NewAppArmorProfile() *AppArmorProfile {
return &AppArmorProfile{}
}
// String returns the formatted representation of a profile as a string
func (p *AppArmorProfile) String() string {
var res bytes.Buffer
err := tmplAppArmorProfile.Execute(&res, p)
if err != nil {
return err.Error()
}
return res.String()
}
// AddRule adds a new rule to the profile from a log map
func (p *AppArmorProfile) AddRule(log map[string]string) {
noNewPrivs := false
fileInherit := false
if log["operation"] == "file_inherit" {
fileInherit = true
}
switch log["error"] {
case "-1":
noNewPrivs = true
case "-2":
if !slices.Contains(p.Flags, "mediate_deleted") {
p.Flags = append(p.Flags, "mediate_deleted")
}
case "-13":
if !slices.Contains(p.Flags, "attach_disconnected") {
p.Flags = append(p.Flags, "attach_disconnected")
}
default:
}
switch log["class"] {
case "cap":
p.Capability = append(p.Capability, NewCapability(log, noNewPrivs, fileInherit))
case "file":
p.File = append(p.File, NewFile(log, noNewPrivs, fileInherit))
case "net":
if log["family"] == "unix" {
p.Unix = append(p.Unix, NewUnix(log, noNewPrivs, fileInherit))
} else {
p.Network = append(p.Network, NewNetwork(log, noNewPrivs, fileInherit))
}
case "signal":
p.Signal = append(p.Signal, NewSignal(log, noNewPrivs, fileInherit))
case "ptrace":
p.Ptrace = append(p.Ptrace, NewPtrace(log, noNewPrivs, fileInherit))
case "unix":
p.Unix = append(p.Unix, NewUnix(log, noNewPrivs, fileInherit))
case "mount":
p.Mount = append(p.Mount, NewMount(log, noNewPrivs, fileInherit))
default:
if strings.Contains(log["operation"], "dbus") {
p.Dbus = append(p.Dbus, NewDbus(log, noNewPrivs, fileInherit))
} else if log["family"] == "unix" {
p.Unix = append(p.Unix, NewUnix(log, noNewPrivs, fileInherit))
}
}
}