check.bend
bend-osdev-apparmor@0.1.0.0 · 181 lines · 13 definitions
1import Base
2import bend-osdev-bytes@0.1.0.0/bytes.bend as B
3import bend-osdev-apparmor@0.1.0.0/text.bend as X
4import bend-osdev-apparmor@0.1.0.0/glob.bend as G
5import bend-osdev-apparmor@0.1.0.0/perm.bend as P
6import bend-osdev-apparmor@0.1.0.0/error.bend as E
7import bend-osdev-apparmor@0.1.0.0/options.bend as O
8import bend-osdev-apparmor@0.1.0.0/profile.bend as PR
9import bend-osdev-apparmor@0.1.0.0/eval.bend as V
10import bend-osdev-apparmor@0.1.0.0/transitions.bend as TR
11import bend-osdev-apparmor@0.1.0.0/rule_file.bend as F
12import bend-osdev-apparmor@0.1.0.0/rule_mount.bend as RM
13import bend-osdev-apparmor@0.1.0.0/rule_dbus.bend as RD
14import bend-osdev-apparmor@0.1.0.0/example.bend as EX
15import bend-osdev-apparmor@0.1.0.0/apparmor.bend as A
16
17def o(s: String) -> B.Octets:
18 B.Octets.of_string(s)
19
20def l(s: String) -> List<&2, U32>:
21 X.AaText.of_string(s)
22
23def show.d(m: Maybe<&2, V.AaDecision>) -> String:
24 match m:
25 case None{}:
26 "no profile"
27 case Some{d}:
28 V.AaDecision.show(d)
29
30def show.load(r: Result<&2, &2, E.AaError, PR.AaPolicy>) -> String:
31 match r:
32 case Fail{+e}:
33 "error " ++ E.AaError.name(e) ++ " at line " ++ U32.show(E.AaError.line(e))
34 case Done{p}:
35 "ok, " ++ Nat.show(List.length(&2, PR.AaProfile, PR.AaPolicy.profiles(p))) ++ " profiles"
36
37
38def load1(t: String) -> String:
39 show.load(A.Aa.load_default([EX.AaExample.source("p", t)], o("p")))
40
41def g(+p: String, +s: String) -> String:
42 p ++ " ~ " ++ s ++ ": " ++ Bool.show(G.AaGlob.match_text(l(p), l(s)))
43
44def pol() -> PR.AaPolicy:
45 EX.AaExample.pol()
46
47
48
49def big.rules(n: Nat, +i: U32, acc: String) -> String:
50 match n:
51 case 0n:
52 acc
53 case 1n+k:
54 big.rules(k, U32.add(i, 1), acc ++ " /data/d" ++ U32.show(i) ++ "/** r,\n deny /data/d" ++ U32.show(i) ++ "/secret w,\n")
55
56def big.text(n: Nat) -> String:
57 "profile big {\n" ++ big.rules(n, 0, "") ++ "}\n"
58
59def big.path.go(n: Nat, acc: String) -> String:
60 match n:
61 case 0n:
62 acc
63 case 1n+k:
64 big.path.go(k, acc ++ "/abcdefghij")
65
66def big.path(n: Nat) -> String:
67 "/data/d299" ++ big.path.go(n, "") ++ "/file"
68
69def big.query(+r: Result<&2, &2, E.AaError, PR.AaPolicy>, path: String, perms: String) -> String:
70 match r:
71 case Fail{e}:
72 "no policy"
73 case Done{p}:
74 show.d(A.Aa.file(O.AaOptions.default(), p, o("big"), o(path), False{}, F.AaFile.perms(perms)))
75
76def main() -> IO(Unit):
77 +big = A.Aa.load_default([EX.AaExample.source("big", big.text(300n))], o("big"))
78 do IO<Unit>:
79 IO.print("example: " ++ show.load(EX.AaExample.loaded()))
80 IO.print(show.d(EX.AaExample.file("/usr/bin/foo", "/etc/ld.so.cache", "r")))
81 IO.print(show.d(EX.AaExample.file("/usr/bin/foo", "/etc/ld.so.cache", "w")))
82 IO.print(show.d(EX.AaExample.file("/usr/bin/foo", "/lib/x86_64/libc.so.6", "mr")))
83 IO.print(show.d(EX.AaExample.file("/usr/bin/foo", "/home/bob/.foo_file", "rw")))
84 IO.print(show.d(EX.AaExample.file("/usr/bin/foo", "/etc/shadow", "r")))
85 IO.print(show.d(EX.AaExample.file("/usr/bin/foo", "/var/log/foo", "w")))
86 IO.print(show.d(EX.AaExample.file("/usr/bin/foo", "/tmp/foo.1", "l")))
87 IO.print(show.d(A.Aa.file(O.AaOptions.default(), pol(), o("/usr/bin/foo"), o("/proc/42/stat"), True{}, F.AaFile.perms("r"))))
88 IO.print(show.d(EX.AaExample.file("/usr/bin/foo", "/proc/42/stat", "r")))
89 IO.print(show.d(EX.AaExample.file("/usr/bin/foo//hat", "/var/spool/q", "rw")))
90 IO.print(show.d(EX.AaExample.file("bar", "/etc/anything", "r")))
91 IO.print(show.d(EX.AaExample.file("bar", "/etc/secret", "r")))
92 IO.print(show.d(A.Aa.file(O.AaOptions.with_complain_deny(O.AaOptions.default(), False{}), pol(), o("bar"), o("/etc/secret"), False{}, F.AaFile.perms("r"))))
93 IO.print(show.d(A.Aa.capability(O.AaOptions.default(), pol(), o("/usr/bin/foo"), 7)))
94 IO.print(show.d(A.Aa.capability(O.AaOptions.default(), pol(), o("/usr/bin/foo"), 21)))
95 IO.print(show.d(A.Aa.network(O.AaOptions.default(), pol(), o("/usr/bin/foo"), o("inet"), o("stream"), o("tcp"))))
96 IO.print(show.d(A.Aa.network(O.AaOptions.default(), pol(), o("/usr/bin/foo"), o("inet6"), o("stream"), o("tcp"))))
97 IO.print(show.d(A.Aa.signal(O.AaOptions.default(), pol(), o("/usr/bin/foo"), P.AaPerms.bit(0n), o("term"), o("/usr/bin/bar"))))
98 IO.print(show.d(A.Aa.signal(O.AaOptions.default(), pol(), o("/usr/bin/foo"), P.AaPerms.bit(1n), o("term"), o("/usr/bin/bar"))))
99 IO.print(EX.AaExample.exec("/usr/bin/foo", "/bin/mount"))
100 IO.print(EX.AaExample.exec("/usr/bin/foo", "/usr/bin/baz"))
101 IO.print(EX.AaExample.exec("/usr/bin/foo", "/usr/bin/bar"))
102 IO.print(EX.AaExample.exec("/usr/bin/foo", "/usr/bin/zzz"))
103 IO.print(EX.AaExample.exec("/usr/bin/foo", "/bin/sh"))
104 IO.print(EX.AaExample.exec("/usr/bin/foo//baz", "/bin/bash"))
105 IO.print(TR.AaExecResult.show(A.Aa.exec_unconfined(pol(), o("/usr/bin/bar"))))
106 IO.print(TR.AaExecResult.show(A.Aa.exec_unconfined(pol(), o("/usr/bin/other"))))
107 IO.print(load1("profile e { /x wa, }"))
108 IO.print(load1("profile e {\n /x r,\n /y ix px,\n}"))
109 IO.print(load1("profile e { capability bogus, }"))
110 IO.print(load1("profile e { @{NOPE}/x r, }"))
111 IO.print(load1("@{A} = /x\n@{A} = /y\nprofile e { }"))
112 IO.print(load1("profile e { /x ix, /x px, }"))
113 IO.print(load1("profile e { unix, }"))
114 IO.print(load1("profile e { include <missing> }"))
115 IO.print(load1("profile e { include if exists <missing> }"))
116 IO.print(load1("profile e { /x/{a} r, }"))
117 IO.print(load1("profile e flags=(complain,kill) { }"))
118 IO.print(load1("profile e { } profile e { }"))
119 IO.print(load1("profile e { /x r }"))
120 IO.print(g("/tmp/*", "/tmp/"))
121 IO.print(g("/tmp/**", "/tmp/a/b"))
122 IO.print(g("/a/{b,c{d,e}}/*", "/a/cd/x"))
123 IO.print(g("/a/[^b]c", "/a//c"))
124 IO.print(g("/a/**/b/**/c/**/d/**/e*", "/a/1/2/b/3/c/4/5/d/6/7/8/f/9/x/y/z/w/v/u/t/s/r/q/p/o/n/m/l"))
125 IO.print("big: " ++ show.load(big))
126 IO.print(big.query(big, "/data/d150/x", "r"))
127 IO.print(big.query(big, "/data/d150/secret", "w"))
128 IO.print(big.query(big, "/data/d300/x", "r"))
129 IO.print(big.query(big, big.path(200n), "r"))
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181