github.com/Prakhar-Agarwal-byte/moby@v0.0.0-20231027092010-a14e3e8ab87e/pkg/aaparser/aaparser.go (about) 1 // Package aaparser is a convenience package interacting with `apparmor_parser`. 2 package aaparser // import "github.com/Prakhar-Agarwal-byte/moby/pkg/aaparser" 3 4 import ( 5 "fmt" 6 "os/exec" 7 "strconv" 8 "strings" 9 ) 10 11 const ( 12 binary = "apparmor_parser" 13 ) 14 15 // GetVersion returns the major and minor version of apparmor_parser. 16 // 17 // Deprecated: no longer used, and will be removed in the next release. 18 func GetVersion() (int, error) { 19 output, err := cmd("", "--version") 20 if err != nil { 21 return -1, err 22 } 23 24 return parseVersion(output) 25 } 26 27 // LoadProfile runs `apparmor_parser -Kr` on a specified apparmor profile to 28 // replace the profile. The `-K` is necessary to make sure that apparmor_parser 29 // doesn't try to write to a read-only filesystem. 30 func LoadProfile(profilePath string) error { 31 _, err := cmd("", "-Kr", profilePath) 32 return err 33 } 34 35 // cmd runs `apparmor_parser` with the passed arguments. 36 func cmd(dir string, arg ...string) (string, error) { 37 c := exec.Command(binary, arg...) 38 c.Dir = dir 39 40 output, err := c.CombinedOutput() 41 if err != nil { 42 return "", fmt.Errorf("running `%s %s` failed with output: %s\nerror: %v", c.Path, strings.Join(c.Args, " "), output, err) 43 } 44 45 return string(output), nil 46 } 47 48 // parseVersion takes the output from `apparmor_parser --version` and returns 49 // a representation of the {major, minor, patch} version as a single number of 50 // the form MMmmPPP {major, minor, patch}. 51 func parseVersion(output string) (int, error) { 52 // output is in the form of the following: 53 // AppArmor parser version 2.9.1 54 // Copyright (C) 1999-2008 Novell Inc. 55 // Copyright 2009-2012 Canonical Ltd. 56 57 lines := strings.SplitN(output, "\n", 2) 58 words := strings.Split(lines[0], " ") 59 version := words[len(words)-1] 60 61 // trim "-beta1" suffix from version="3.0.0-beta1" if exists 62 version = strings.SplitN(version, "-", 2)[0] 63 // also trim "~..." suffix used historically (https://gitlab.com/apparmor/apparmor/-/commit/bca67d3d27d219d11ce8c9cc70612bd637f88c10) 64 version = strings.SplitN(version, "~", 2)[0] 65 66 // split by major minor version 67 v := strings.Split(version, ".") 68 if len(v) == 0 || len(v) > 3 { 69 return -1, fmt.Errorf("parsing version failed for output: `%s`", output) 70 } 71 72 // Default the versions to 0. 73 var majorVersion, minorVersion, patchLevel int 74 75 majorVersion, err := strconv.Atoi(v[0]) 76 if err != nil { 77 return -1, err 78 } 79 80 if len(v) > 1 { 81 minorVersion, err = strconv.Atoi(v[1]) 82 if err != nil { 83 return -1, err 84 } 85 } 86 if len(v) > 2 { 87 patchLevel, err = strconv.Atoi(v[2]) 88 if err != nil { 89 return -1, err 90 } 91 } 92 93 // major*10^5 + minor*10^3 + patch*10^0 94 numericVersion := majorVersion*1e5 + minorVersion*1e3 + patchLevel 95 return numericVersion, nil 96 }