-
Notifications
You must be signed in to change notification settings - Fork 601
/
Copy pathapparmor.go
117 lines (104 loc) · 2.96 KB
/
apparmor.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// -*- Mode: Go; indent-tabs-mode: t -*-
/*
* Copyright (C) 2014-2015 Canonical Ltd
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package release
import (
"fmt"
"os"
"path/filepath"
"strings"
)
// ApparmorLevelType encodes the kind of support for apparmor
// found on this system.
type AppArmorLevelType int
const (
// NoAppArmor indicates that apparmor is not enabled.
NoAppArmor AppArmorLevelType = iota
// PartialAppArmor indicates that apparmor is enabled but some
// features are missing.
PartialAppArmor
// FullAppArmor indicates that all features are supported.
FullAppArmor
)
var (
appArmorLevel AppArmorLevelType
appArmorSummary string
)
func init() {
appArmorLevel, appArmorSummary = probeAppArmor()
}
// AppArmorLevel quantifies how well apparmor is supported on the
// current kernel.
func AppArmorLevel() AppArmorLevelType {
return appArmorLevel
}
// AppArmorSummary describes how well apparmor is supported on the
// current kernel.
func AppArmorSummary() string {
return appArmorSummary
}
// MockAppArmorSupportLevel makes the system believe it has certain
// level of apparmor support.
func MockAppArmorLevel(level AppArmorLevelType) (restore func()) {
oldAppArmorLevel := appArmorLevel
oldAppArmorSummary := appArmorSummary
appArmorLevel = level
appArmorSummary = fmt.Sprintf("mocked apparmor level: %v", level)
return func() {
appArmorLevel = oldAppArmorLevel
appArmorSummary = oldAppArmorSummary
}
}
// probe related code
var (
appArmorFeaturesSysPath = "/sys/kernel/security/apparmor/features"
requiredAppArmorFeatures = []string{
"caps",
"dbus",
"domain",
"file",
"mount",
"namespaces",
"network",
"ptrace",
"signal",
}
)
// isDirectoy is like osutil.IsDirectory but we cannot import this
// because of import cycles
func isDirectory(path string) bool {
stat, err := os.Stat(path)
if err != nil {
return false
}
return stat.IsDir()
}
func probeAppArmor() (AppArmorLevelType, string) {
if !isDirectory(appArmorFeaturesSysPath) {
return NoAppArmor, "apparmor not enabled"
}
var missing []string
for _, feature := range requiredAppArmorFeatures {
if !isDirectory(filepath.Join(appArmorFeaturesSysPath, feature)) {
missing = append(missing, feature)
}
}
if len(missing) > 0 {
return PartialAppArmor, fmt.Sprintf("apparmor is enabled but some features are missing: %s", strings.Join(missing, ", "))
}
return FullAppArmor, "apparmor is enabled and all features are available"
}