github.com/hustcat/docker@v1.3.3-0.20160314103604-901c67a8eeab/profiles/apparmor/apparmor.go (about) 1 // +build linux 2 3 package apparmor 4 5 import ( 6 "bufio" 7 "io" 8 "os" 9 "path" 10 "strings" 11 12 "github.com/docker/docker/pkg/aaparser" 13 "github.com/docker/docker/utils/templates" 14 ) 15 16 var ( 17 // profileDirectory is the file store for apparmor profiles and macros. 18 profileDirectory = "/etc/apparmor.d" 19 // defaultProfilePath is the default path for the apparmor profile to be saved. 20 defaultProfilePath = path.Join(profileDirectory, "docker") 21 ) 22 23 // profileData holds information about the given profile for generation. 24 type profileData struct { 25 // Name is profile name. 26 Name string 27 // ExecPath is the path to the docker binary. 28 ExecPath string 29 // Imports defines the apparmor functions to import, before defining the profile. 30 Imports []string 31 // InnerImports defines the apparmor functions to import in the profile. 32 InnerImports []string 33 // Version is the {major, minor, patch} version of apparmor_parser as a single number. 34 Version int 35 } 36 37 // generateDefault creates an apparmor profile from ProfileData. 38 func (p *profileData) generateDefault(out io.Writer) error { 39 compiled, err := templates.NewParse("apparmor_profile", baseTemplate) 40 if err != nil { 41 return err 42 } 43 if macroExists("tunables/global") { 44 p.Imports = append(p.Imports, "#include <tunables/global>") 45 } else { 46 p.Imports = append(p.Imports, "@{PROC}=/proc/") 47 } 48 if macroExists("abstractions/base") { 49 p.InnerImports = append(p.InnerImports, "#include <abstractions/base>") 50 } 51 if err := compiled.Execute(out, p); err != nil { 52 return err 53 } 54 return nil 55 } 56 57 // macrosExists checks if the passed macro exists. 58 func macroExists(m string) bool { 59 _, err := os.Stat(path.Join(profileDirectory, m)) 60 return err == nil 61 } 62 63 // InstallDefault generates a default profile and installs it in the 64 // ProfileDirectory with `apparmor_parser`. 65 func InstallDefault(name string) error { 66 // Make sure the path where they want to save the profile exists 67 if err := os.MkdirAll(profileDirectory, 0755); err != nil { 68 return err 69 } 70 71 p := profileData{ 72 Name: name, 73 } 74 75 f, err := os.OpenFile(defaultProfilePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) 76 if err != nil { 77 return err 78 } 79 if err := p.generateDefault(f); err != nil { 80 f.Close() 81 return err 82 } 83 f.Close() 84 85 if err := aaparser.LoadProfile(defaultProfilePath); err != nil { 86 return err 87 } 88 89 return nil 90 } 91 92 // IsLoaded checks if a passed profile has been loaded into the kernel. 93 func IsLoaded(name string) error { 94 file, err := os.Open("/sys/kernel/security/apparmor/profiles") 95 if err != nil { 96 return err 97 } 98 r := bufio.NewReader(file) 99 for { 100 p, err := r.ReadString('\n') 101 if err != nil { 102 return err 103 } 104 if strings.HasPrefix(p, name+" ") { 105 return nil 106 } 107 } 108 }