rule_change_profile.bend
bend-osdev-apparmor@0.1.0.0 · 210 lines · 24 definitions
1
2
3
4
5
6
7import Base
8import bend-osdev-apparmor@0.1.0.0/text.bend as X
9import bend-osdev-apparmor@0.1.0.0/glob.bend as G
10import bend-osdev-apparmor@0.1.0.0/perm.bend as P
11import bend-osdev-apparmor@0.1.0.0/token.bend as T
12import bend-osdev-apparmor@0.1.0.0/error.bend as E
13import bend-osdev-apparmor@0.1.0.0/rule.bend as R
14
15
16type AaChangeRule is Data:
17 AaChangeRule{qual: P.AaQual, exec: Maybe<&2, G.AaGlob>, safe: Bool, target: Maybe<&2, G.AaGlob>}
18
19
20
21type AaChangeQuery is Data:
22 AaChangeQuery{exec: Maybe<&2, List<&2, U32>>, target: List<&2, U32>}
23
24
25
26type AaChB is Data:
27 AaChB{mode: Nat, exec: Maybe<&2, G.AaGlob>, arrow: Bool, target: Maybe<&2, G.AaGlob>}
28
29def AaChange.is_path(t: T.AaTerm) -> Bool:
30 match t:
31 case T.AaTmWord{+w}:
32 Bool.or(U32.is_eq(X.AaText.head(w), 47), U32.is_eq(X.AaText.head(w), 123))
33 case T.AaTmQuoted{q}:
34 True{}
35 case _:
36 False{}
37
38def AaChB.set_target(b: AaChB, g: G.AaGlob, src: E.AaSrc) -> Result<&2, &2, E.AaError, AaChB>:
39 match b:
40 case AaChB{m, e, ar, tg}:
41 match ar:
42 case False{}:
43 Fail{E.AaSrc.syntax(src)}
44 case True{}:
45 match tg:
46 case None{}:
47 Done{AaChB{m, e, True{}, Some{g}}}
48 case Some{h}:
49 Fail{E.AaSrc.syntax(src)}
50
51def AaChB.set_exec(b: AaChB, g: G.AaGlob, src: E.AaSrc) -> Result<&2, &2, E.AaError, AaChB>:
52 match b:
53 case AaChB{m, e, ar, tg}:
54 match e:
55 case None{}:
56 match ar:
57 case False{}:
58 Done{AaChB{m, Some{g}, False{}, tg}}
59 case True{}:
60 Fail{E.AaSrc.syntax(src)}
61 case Some{h}:
62 Fail{E.AaSrc.syntax(src)}
63
64
65def AaChB.glob(b: AaChB, g: G.AaGlob, src: E.AaSrc) -> Result<&2, &2, E.AaError, AaChB>:
66 match b:
67 case AaChB{m, e, +ar, tg}:
68 match ar:
69 case True{}:
70 AaChB.set_target(AaChB{m, e, ar, tg}, g, src)
71 case False{}:
72 AaChB.set_exec(AaChB{m, e, ar, tg}, g, src)
73
74def AaChB.arrow(b: AaChB, src: E.AaSrc) -> Result<&2, &2, E.AaError, AaChB>:
75 match b:
76 case AaChB{m, e, ar, tg}:
77 match ar:
78 case True{}:
79 Fail{E.AaSrc.syntax(src)}
80 case False{}:
81 Done{AaChB{m, e, True{}, tg}}
82
83
84def AaChB.mode(b: AaChB, n: Nat, src: E.AaSrc) -> Result<&2, &2, E.AaError, AaChB>:
85 match b:
86 case AaChB{m, e, ar, tg}:
87 match m:
88 case 0n:
89 match e:
90 case None{}:
91 match ar:
92 case False{}:
93 Done{AaChB{n, None{}, False{}, tg}}
94 case True{}:
95 Fail{E.AaSrc.syntax(src)}
96 case Some{h}:
97 Fail{E.AaSrc.syntax(src)}
98 case 1n+k:
99 Fail{E.AaSrc.syntax(src)}
100
101def AaChB.term.glob(r: Result<&2, &2, E.AaError, G.AaGlob>, b: AaChB, src: E.AaSrc) -> Result<&2, &2, E.AaError, AaChB>:
102 match r:
103 case Fail{e}:
104 Fail{e}
105 case Done{g}:
106 AaChB.glob(b, g, src)
107
108def AaChB.step(t: T.AaTerm, +b: AaChB, +src: E.AaSrc) -> Result<&2, &2, E.AaError, AaChB>:
109 match t:
110 case T.AaTmWord{+w}:
111 Bool.pick(Result<&2, &2, E.AaError, AaChB>, X.AaText.is(w, "safe"), AaChB.mode(b, 1n, src), Bool.pick(Result<&2, &2, E.AaError, AaChB>, X.AaText.is(w, "unsafe"), AaChB.mode(b, 2n, src), AaChB.term.glob(R.AaRule.glob_text(w, src), b, src)))
112 case T.AaTmQuoted{q}:
113 AaChB.term.glob(R.AaRule.glob_text(q, src), b, src)
114 case T.AaTmArrow{}:
115 AaChB.arrow(b, src)
116 case _:
117 Fail{E.AaSrc.syntax(src)}
118
119def AaChB.run(ts: List<&2, T.AaTerm>, b: AaChB, +src: E.AaSrc) -> Result<&2, &2, E.AaError, AaChB>:
120 match ts:
121 case Nil{}:
122 Done{b}
123 case Con{t, rest}:
124 do Result<&2, &2, E.AaError, AaChB>:
125 b2 : AaChB <- AaChB.step(t, b, src)
126 AaChB.run(rest, b2, src)
127
128def AaChange.is_some(m: Maybe<&2, G.AaGlob>) -> Bool:
129 match m:
130 case None{}:
131 False{}
132 case Some{g}:
133 True{}
134
135
136def AaChB.finish(q: P.AaQual, b: AaChB, src: E.AaSrc) -> Result<&2, &2, E.AaError, AaChangeRule>:
137 match b:
138 case AaChB{+m, +e, ar, +tg}:
139 +bad = Bool.or(Bool.and(Nat.is_gt(m, 0n), Bool.not(AaChange.is_some(e))), Bool.and(ar, Bool.not(AaChange.is_some(tg))))
140 Bool.pick(Result<&2, &2, E.AaError, AaChangeRule>, bad, Fail{E.AaSrc.syntax(src)}, Done{AaChangeRule{q, e, Bool.not(Nat.is_eq(m, 2n)), tg}})
141
142def AaChange.parse.q(r: Result<&2, &2, E.AaError, P.AaQual>, ts: List<&2, T.AaTerm>, +src: E.AaSrc) -> Result<&2, &2, E.AaError, AaChangeRule>:
143 match r:
144 case Fail{e}:
145 Fail{e}
146 case Done{q}:
147 do Result<&2, &2, E.AaError, AaChangeRule>:
148 b : AaChB <- AaChB.run(ts, AaChB{0n, None{}, False{}, None{}}, src)
149 AaChB.finish(q, b, src)
150
151
152def AaChange.parse(ts: List<&2, T.AaTerm>, q: P.AaQual, +src: E.AaSrc) -> Result<&2, &2, E.AaError, AaChangeRule>:
153 AaChange.parse.q(R.AaRule.no_owner(q, src), ts, src)
154
155
156
157
158def AaChange.exec_ok(m: Maybe<&2, G.AaGlob>, x: Maybe<&2, List<&2, U32>>) -> Bool:
159 match m:
160 case None{}:
161 True{}
162 case Some{g}:
163 match x:
164 case None{}:
165 False{}
166 case Some{p}:
167 G.AaGlob.matches(g, p)
168
169def AaChangeRule.matches(r: AaChangeRule, q: AaChangeQuery) -> Bool:
170 match r:
171 case AaChangeRule{qu, e, s, tg}:
172 match q:
173 case AaChangeQuery{qe, qt}:
174 Bool.and(AaChange.exec_ok(e, qe), R.AaRule.opt_match(tg, qt))
175
176def AaChangeRule.matching.go(hit: Bool, r: AaChangeRule, rest: List<&2, AaChangeRule>) -> List<&2, AaChangeRule>:
177 match hit:
178 case True{}:
179 Con{r, rest}
180 case False{}:
181 rest
182
183def AaChangeRule.matching(rs: List<&2, AaChangeRule>, +q: AaChangeQuery) -> List<&2, AaChangeRule>:
184 match rs:
185 case Nil{}:
186 Nil{}
187 case Con{+r, t}:
188 AaChangeRule.matching.go(AaChangeRule.matches(r, q), r, AaChangeRule.matching(t, q))
189
190def AaChangeRule.grants.of(rs: List<&2, AaChangeRule>) -> List<&2, P.AaGrant>:
191 match rs:
192 case Nil{}:
193 Nil{}
194 case Con{r, t}:
195 match r:
196 case AaChangeRule{qu, e, s, tg}:
197 Con{P.AaGrant.of(qu, P.AaPerms.bit(0n)), AaChangeRule.grants.of(t)}
198
199def AaChangeRule.grants(rs: List<&2, AaChangeRule>, +q: AaChangeQuery) -> List<&2, P.AaGrant>:
200 AaChangeRule.grants.of(AaChangeRule.matching(rs, q))
201
202def AaChangeRule.append(xs: List<&2, AaChangeRule>, ys: List<&2, AaChangeRule>) -> List<&2, AaChangeRule>:
203 match xs:
204 case Nil{}:
205 ys
206 case Con{h, t}:
207 Con{h, AaChangeRule.append(t, ys)}
208
209def AaChangeQuery.req() -> P.AaPerms:
210 P.AaPerms.bit(0n)