2016-01-12 13:01:04 -05:00
|
|
|
// Package aaparser is a convenience package interacting with `apparmor_parser`.
|
2015-11-23 18:41:18 -05:00
|
|
|
package aaparser
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"os/exec"
|
2016-01-12 13:01:04 -05:00
|
|
|
"path/filepath"
|
2015-11-23 18:41:18 -05:00
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
2016-01-12 13:01:04 -05:00
|
|
|
const (
|
|
|
|
binary = "apparmor_parser"
|
|
|
|
)
|
|
|
|
|
|
|
|
// GetVersion returns the major and minor version of apparmor_parser.
|
2015-11-23 18:41:18 -05:00
|
|
|
func GetVersion() (int, int, error) {
|
2016-01-12 13:01:04 -05:00
|
|
|
output, err := cmd("", "--version")
|
|
|
|
if err != nil {
|
|
|
|
return -1, -1, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return parseVersion(string(output))
|
|
|
|
}
|
2015-11-23 18:41:18 -05:00
|
|
|
|
2016-01-12 13:01:04 -05:00
|
|
|
// LoadProfile runs `apparmor_parser -r -W` on a specified apparmor profile to
|
|
|
|
// replace and write it to disk.
|
|
|
|
func LoadProfile(profilePath string) error {
|
|
|
|
_, err := cmd(filepath.Dir(profilePath), "-r", "-W", filepath.Base(profilePath))
|
2015-11-23 18:41:18 -05:00
|
|
|
if err != nil {
|
2016-01-12 13:01:04 -05:00
|
|
|
return err
|
2015-11-23 18:41:18 -05:00
|
|
|
}
|
2016-01-12 13:01:04 -05:00
|
|
|
return nil
|
|
|
|
}
|
2015-11-23 18:41:18 -05:00
|
|
|
|
2016-01-12 13:01:04 -05:00
|
|
|
// cmd runs `apparmor_parser` with the passed arguments.
|
|
|
|
func cmd(dir string, arg ...string) (string, error) {
|
|
|
|
c := exec.Command(binary, arg...)
|
|
|
|
c.Dir = dir
|
|
|
|
|
|
|
|
output, err := c.CombinedOutput()
|
|
|
|
if err != nil {
|
|
|
|
return "", fmt.Errorf("running `%s %s` failed with output: %s\nerror: %v", c.Path, strings.Join(c.Args, " "), string(output), err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return string(output), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// parseVersion takes the output from `apparmor_parser --version` and returns
|
|
|
|
// the major and minor version for `apparor_parser`.
|
|
|
|
func parseVersion(output string) (int, int, error) {
|
2015-11-23 18:41:18 -05:00
|
|
|
// output is in the form of the following:
|
|
|
|
// AppArmor parser version 2.9.1
|
|
|
|
// Copyright (C) 1999-2008 Novell Inc.
|
|
|
|
// Copyright 2009-2012 Canonical Ltd.
|
2016-01-12 13:01:04 -05:00
|
|
|
lines := strings.SplitN(output, "\n", 2)
|
2015-11-23 18:41:18 -05:00
|
|
|
words := strings.Split(lines[0], " ")
|
|
|
|
version := words[len(words)-1]
|
2016-01-12 13:01:04 -05:00
|
|
|
|
2015-11-23 18:41:18 -05:00
|
|
|
// split by major minor version
|
|
|
|
v := strings.Split(version, ".")
|
|
|
|
if len(v) < 2 {
|
2016-01-12 13:01:04 -05:00
|
|
|
return -1, -1, fmt.Errorf("parsing major minor version failed for output: `%s`", output)
|
2015-11-23 18:41:18 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
majorVersion, err := strconv.Atoi(v[0])
|
|
|
|
if err != nil {
|
|
|
|
return -1, -1, err
|
|
|
|
}
|
|
|
|
minorVersion, err := strconv.Atoi(v[1])
|
|
|
|
if err != nil {
|
|
|
|
return -1, -1, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return majorVersion, minorVersion, nil
|
|
|
|
}
|