example.bend

bend-osdev-apparmor@0.1.0.0 · 71 lines · 16 definitions

1# bend-osdev-apparmor: examples, for the laws' witnesses, check.bend and
2# users: a profile built directly from the types, and a small policy in
3# the profile language (the example of apparmor.d(5), cut down, with an
4# abstraction and a tunable in a file map).
5import Base
6import bend-osdev-bytes@0.1.0.0/bytes.bend as B
7import bend-osdev-apparmor@0.1.0.0/text.bend as X
8import bend-osdev-apparmor@0.1.0.0/glob.bend as G
9import bend-osdev-apparmor@0.1.0.0/perm.bend as P
10import bend-osdev-apparmor@0.1.0.0/options.bend as O
11import bend-osdev-apparmor@0.1.0.0/profile.bend as PR
12import bend-osdev-apparmor@0.1.0.0/rule_file.bend as F
13import bend-osdev-apparmor@0.1.0.0/error.bend as E
14import bend-osdev-apparmor@0.1.0.0/eval.bend as V
15import bend-osdev-apparmor@0.1.0.0/transitions.bend as TR
16import bend-osdev-apparmor@0.1.0.0/apparmor.bend as A
17
18def AaExample.qual(audit: Bool, deny: Bool) -> P.AaQual:
19  P.AaQual{audit, deny, False{}}
20
21# a file rule on a literal path
22def AaExample.rule(+path: String, q: P.AaQual, perms: String) -> F.AaFileRule:
23  F.AaFileRule{q, X.AaText.of_string(path), G.AaGlob.literal(X.AaText.of_string(path)), F.AaFile.perms(perms), None{}, None{}}
24
25# profile ex: /etc/x rw, deny /etc/x w, audit /var/log/x w, /lib/** (built
26# as a literal-free pattern) r; no x rule anywhere
27def AaExample.rules() -> PR.AaRules:
28  PR.AaRules.with_files(PR.AaRules.empty(), [AaExample.rule("/etc/x", AaExample.qual(False{}, False{}), "rw"), AaExample.rule("/etc/x", AaExample.qual(False{}, True{}), "w"), AaExample.rule("/var/log/x", AaExample.qual(True{}, False{}), "w"), F.AaFileRule{AaExample.qual(False{}, False{}), X.AaText.of_string("/lib/**"), G.AaGlob{[[G.AaGChar{47}, G.AaGChar{108}, G.AaGChar{105}, G.AaGChar{98}, G.AaGChar{47}, G.AaGAny{}, G.AaGStar2{}]], False{}}, F.AaFile.perms("r"), None{}, None{}}])
29
30def AaExample.profile(m: PR.AaMode) -> PR.AaProfile:
31  PR.AaProfile.include(PR.AaProfile.new(X.AaText.of_string("ex"), None{}, PR.AaFlags{m, False{}}), AaExample.rules())
32
33def AaExample.policy() -> PR.AaPolicy:
34  PR.AaPolicy{[AaExample.profile(PR.AaModeEnforce{})]}
35
36def AaExample.query(+path: String, perms: String) -> F.AaFileQuery:
37  F.AaFileQuery{X.AaText.of_string(path), False{}, F.AaFile.perms(perms)}
38
39# The policy text
40
41def AaExample.source(n: String, t: String) -> A.AaSource:
42  A.AaSource{B.Octets.of_string(n), B.Octets.of_string(t)}
43
44def AaExample.files() -> List<&2, A.AaSource>:
45  [AaExample.source("tunables/home", "@{HOMEDIRS} = /home/\n@{HOME} = @{HOMEDIRS}/*/ /root/\n"), AaExample.source("abstractions/base", "/etc/ld.so.cache r,\n/{usr/,}lib{,32,64}/** mr,\n"), AaExample.source("main", "include <tunables/home>\n# a cut-down version of the example in apparmor.d(5)\n/usr/bin/foo {\n  include <abstractions/base>\n  include <abstractions/base>\n  /bin/mount ux,\n  /dev/{,u}random r,\n  /etc/foo/* r,\n  /tmp/foo.* lrw,\n  @{HOME}/.foo_file rw,\n  deny /etc/shadow rw,\n  audit /var/log/foo w,\n  owner /proc/[0-9]*/stat r,\n  /usr/bin/baz Cx -> baz,\n  /usr/bin/bar px,\n  /usr/bin/** pix,\n  capability setuid,\n  network inet stream,\n  signal (send) set=(term, kill) peer=/usr/bin/bar,\n  ^hat {\n    /var/spool/* rwl,\n  }\n  profile baz {\n    /bin/bash ixr,\n  }\n}\nprofile bar /usr/bin/bar flags=(complain) {\n  /etc/bar r,\n  deny /etc/secret r,\n}\n")]
46
47def AaExample.loaded() -> Result<&2, &2, E.AaError, PR.AaPolicy>:
48  A.Aa.load(O.AaOptions.default(), AaExample.files(), B.Octets.of_string("main"))
49
50def AaExample.pol() -> PR.AaPolicy:
51  Result.default(&2, &2, E.AaError, PR.AaPolicy, AaExample.loaded(), PR.AaPolicy{Nil{}})
52
53def AaExample.file(prof: String, path: String, perms: String) -> Maybe<&2, V.AaDecision>:
54  A.Aa.file(O.AaOptions.default(), AaExample.pol(), B.Octets.of_string(prof), B.Octets.of_string(path), False{}, F.AaFile.perms(perms))
55
56def AaExample.exec(prof: String, path: String) -> String:
57  TR.AaExecResult.show(A.Aa.exec(O.AaOptions.default(), AaExample.pol(), B.Octets.of_string(prof), B.Octets.of_string(path), False{}))
58
59# A smaller policy, for the laws' vectors (the checker's kernel evaluates
60# them, so they are kept short)
61def AaExample.small_files() -> List<&2, A.AaSource>:
62  [AaExample.source("t", "@{H} = /home/*/ /root/\n"), AaExample.source("a", "/lib/** mr,\n"), AaExample.source("m", "include <t>\n/usr/bin/foo {\n  include <a>\n  include <a>\n  deny /etc/shadow r,\n  @{H}/f rw,\n  /bin/x px,\n}\nprofile bar /bin/x flags=(complain) {\n}\n")]
63
64def AaExample.small() -> PR.AaPolicy:
65  Result.default(&2, &2, E.AaError, PR.AaPolicy, A.Aa.load(O.AaOptions.default(), AaExample.small_files(), B.Octets.of_string("m")), PR.AaPolicy{Nil{}})
66
67def AaExample.small_file(prof: String, path: String, perms: String) -> Maybe<&2, V.AaDecision>:
68  A.Aa.file(O.AaOptions.default(), AaExample.small(), B.Octets.of_string(prof), B.Octets.of_string(path), False{}, F.AaFile.perms(perms))
69
70def AaExample.small_exec(prof: String, path: String) -> String:
71  TR.AaExecResult.show(A.Aa.exec(O.AaOptions.default(), AaExample.small(), B.Octets.of_string(prof), B.Octets.of_string(path), False{}))