From 31e0dea5a020af9f1bf4d5d3a8e40fc1b2882474 Mon Sep 17 00:00:00 2001 From: Valentin Rothberg Date: Mon, 13 Aug 2018 14:41:10 +0200 Subject: pkg/apparmor: move all linux-code into apparmor_linux* For easier maintenance and clearer structure of the code. Signed-off-by: Valentin Rothberg Closes: #1262 Approved by: mheon --- pkg/apparmor/aaparser.go | 90 ------------------------------------- pkg/apparmor/aaparser_test.go | 78 -------------------------------- pkg/apparmor/apparmor_linux.go | 79 +++++++++++++++++++++++++++++++- pkg/apparmor/apparmor_linux_test.go | 78 ++++++++++++++++++++++++++++++++ 4 files changed, 156 insertions(+), 169 deletions(-) delete mode 100644 pkg/apparmor/aaparser.go delete mode 100644 pkg/apparmor/aaparser_test.go create mode 100644 pkg/apparmor/apparmor_linux_test.go diff --git a/pkg/apparmor/aaparser.go b/pkg/apparmor/aaparser.go deleted file mode 100644 index cec9c4885..000000000 --- a/pkg/apparmor/aaparser.go +++ /dev/null @@ -1,90 +0,0 @@ -// +build linux,apparmor - -package apparmor - -import ( - "fmt" - "os/exec" - "strconv" - "strings" -) - -const ( - binary = "apparmor_parser" -) - -// getVersion returns the major and minor version of apparmor_parser. -func getVersion() (int, error) { - output, err := cmd("", "--version") - if err != nil { - return -1, err - } - - return parseVersion(output) -} - -// loadProfile runs `apparmor_parser -Kr` on a specified apparmor profile to -// replace the profile. The `-K` is necessary to make sure that apparmor_parser -// doesn't try to write to a read-only filesystem. -func loadProfile(profilePath string) error { - _, err := cmd("", "-Kr", profilePath) - return err -} - -// 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, " "), output, err) - } - - return string(output), nil -} - -// parseVersion takes the output from `apparmor_parser --version` and returns -// a representation of the {major, minor, patch} version as a single number of -// the form MMmmPPP {major, minor, patch}. -func parseVersion(output string) (int, error) { - // 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. - - lines := strings.SplitN(output, "\n", 2) - words := strings.Split(lines[0], " ") - version := words[len(words)-1] - - // split by major minor version - v := strings.Split(version, ".") - if len(v) == 0 || len(v) > 3 { - return -1, fmt.Errorf("parsing version failed for output: `%s`", output) - } - - // Default the versions to 0. - var majorVersion, minorVersion, patchLevel int - - majorVersion, err := strconv.Atoi(v[0]) - if err != nil { - return -1, err - } - - if len(v) > 1 { - minorVersion, err = strconv.Atoi(v[1]) - if err != nil { - return -1, err - } - } - if len(v) > 2 { - patchLevel, err = strconv.Atoi(v[2]) - if err != nil { - return -1, err - } - } - - // major*10^5 + minor*10^3 + patch*10^0 - numericVersion := majorVersion*1e5 + minorVersion*1e3 + patchLevel - return numericVersion, nil -} diff --git a/pkg/apparmor/aaparser_test.go b/pkg/apparmor/aaparser_test.go deleted file mode 100644 index 296c101ed..000000000 --- a/pkg/apparmor/aaparser_test.go +++ /dev/null @@ -1,78 +0,0 @@ -// +build linux,apparmor - -package apparmor - -import ( - "testing" -) - -type versionExpected struct { - output string - version int -} - -func TestParseVersion(t *testing.T) { - if !IsEnabled() { - t.Skip("AppArmor disabled: skipping tests") - } - versions := []versionExpected{ - { - output: `AppArmor parser version 2.10 -Copyright (C) 1999-2008 Novell Inc. -Copyright 2009-2012 Canonical Ltd. - -`, - version: 210000, - }, - { - output: `AppArmor parser version 2.8 -Copyright (C) 1999-2008 Novell Inc. -Copyright 2009-2012 Canonical Ltd. - -`, - version: 208000, - }, - { - output: `AppArmor parser version 2.20 -Copyright (C) 1999-2008 Novell Inc. -Copyright 2009-2012 Canonical Ltd. - -`, - version: 220000, - }, - { - output: `AppArmor parser version 2.05 -Copyright (C) 1999-2008 Novell Inc. -Copyright 2009-2012 Canonical Ltd. - -`, - version: 205000, - }, - { - output: `AppArmor parser version 2.9.95 -Copyright (C) 1999-2008 Novell Inc. -Copyright 2009-2012 Canonical Ltd. - -`, - version: 209095, - }, - { - output: `AppArmor parser version 3.14.159 -Copyright (C) 1999-2008 Novell Inc. -Copyright 2009-2012 Canonical Ltd. - -`, - version: 314159, - }, - } - - for _, v := range versions { - version, err := parseVersion(v.output) - if err != nil { - t.Fatalf("expected error to be nil for %#v, got: %v", v, err) - } - if version != v.version { - t.Fatalf("expected version to be %d, was %d, for: %#v\n", v.version, version, v) - } - } -} diff --git a/pkg/apparmor/apparmor_linux.go b/pkg/apparmor/apparmor_linux.go index a09c5fc44..4cc95a107 100644 --- a/pkg/apparmor/apparmor_linux.go +++ b/pkg/apparmor/apparmor_linux.go @@ -4,10 +4,13 @@ package apparmor import ( "bufio" + "fmt" "io" "io/ioutil" "os" + "os/exec" "path" + "strconv" "strings" "text/template" @@ -48,7 +51,7 @@ func (p *profileData) generateDefault(out io.Writer) error { p.InnerImports = append(p.InnerImports, "#include ") } - ver, err := getVersion() + ver, err := getAAParserVersion() if err != nil { return err } @@ -115,3 +118,77 @@ func IsLoaded(name string) (bool, error) { return false, nil } + +// execAAParser runs `apparmor_parser` with the passed arguments. +func execAAParser(dir string, args ...string) (string, error) { + c := exec.Command("apparmor_parser", args...) + 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, " "), output, err) + } + + return string(output), nil +} + +// loadProfile runs `apparmor_parser -Kr` on a specified apparmor profile to +// replace the profile. The `-K` is necessary to make sure that apparmor_parser +// doesn't try to write to a read-only filesystem. +func loadProfile(profilePath string) error { + _, err := execAAParser("", "-Kr", profilePath) + return err +} + +// getAAParserVersion returns the major and minor version of apparmor_parser. +func getAAParserVersion() (int, error) { + output, err := execAAParser("", "--version") + if err != nil { + return -1, err + } + return parseAAParserVersion(output) +} + +// parseAAParserVersion parses the given `apparmor_parser --version` output and +// returns the major and minor version number as an integer. +func parseAAParserVersion(output string) (int, error) { + // 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. + lines := strings.SplitN(output, "\n", 2) + words := strings.Split(lines[0], " ") + version := words[len(words)-1] + + // split by major minor version + v := strings.Split(version, ".") + if len(v) == 0 || len(v) > 3 { + return -1, fmt.Errorf("parsing version failed for output: `%s`", output) + } + + // Default the versions to 0. + var majorVersion, minorVersion, patchLevel int + + majorVersion, err := strconv.Atoi(v[0]) + if err != nil { + return -1, err + } + + if len(v) > 1 { + minorVersion, err = strconv.Atoi(v[1]) + if err != nil { + return -1, err + } + } + if len(v) > 2 { + patchLevel, err = strconv.Atoi(v[2]) + if err != nil { + return -1, err + } + } + + // major*10^5 + minor*10^3 + patch*10^0 + numericVersion := majorVersion*1e5 + minorVersion*1e3 + patchLevel + return numericVersion, nil + +} diff --git a/pkg/apparmor/apparmor_linux_test.go b/pkg/apparmor/apparmor_linux_test.go new file mode 100644 index 000000000..4aa3753d9 --- /dev/null +++ b/pkg/apparmor/apparmor_linux_test.go @@ -0,0 +1,78 @@ +// +build linux,apparmor + +package apparmor + +import ( + "testing" +) + +type versionExpected struct { + output string + version int +} + +func TestParseAAParserVersion(t *testing.T) { + if !IsEnabled() { + t.Skip("AppArmor disabled: skipping tests") + } + versions := []versionExpected{ + { + output: `AppArmor parser version 2.10 +Copyright (C) 1999-2008 Novell Inc. +Copyright 2009-2012 Canonical Ltd. + +`, + version: 210000, + }, + { + output: `AppArmor parser version 2.8 +Copyright (C) 1999-2008 Novell Inc. +Copyright 2009-2012 Canonical Ltd. + +`, + version: 208000, + }, + { + output: `AppArmor parser version 2.20 +Copyright (C) 1999-2008 Novell Inc. +Copyright 2009-2012 Canonical Ltd. + +`, + version: 220000, + }, + { + output: `AppArmor parser version 2.05 +Copyright (C) 1999-2008 Novell Inc. +Copyright 2009-2012 Canonical Ltd. + +`, + version: 205000, + }, + { + output: `AppArmor parser version 2.9.95 +Copyright (C) 1999-2008 Novell Inc. +Copyright 2009-2012 Canonical Ltd. + +`, + version: 209095, + }, + { + output: `AppArmor parser version 3.14.159 +Copyright (C) 1999-2008 Novell Inc. +Copyright 2009-2012 Canonical Ltd. + +`, + version: 314159, + }, + } + + for _, v := range versions { + version, err := parseAAParserVersion(v.output) + if err != nil { + t.Fatalf("expected error to be nil for %#v, got: %v", v, err) + } + if version != v.version { + t.Fatalf("expected version to be %d, was %d, for: %#v\n", v.version, version, v) + } + } +} -- cgit v1.2.3-54-g00ecf