@inhuman.tools/policy 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/authorize.scm +4 -0
- package/dist/acknowledge.d.ts +70 -0
- package/dist/acknowledge.d.ts.map +1 -0
- package/dist/acknowledge.js +162 -0
- package/dist/acknowledge.js.map +1 -0
- package/dist/authorize.d.ts +8 -0
- package/dist/authorize.d.ts.map +1 -0
- package/dist/authorize.js +39 -0
- package/dist/authorize.js.map +1 -0
- package/dist/bind.d.ts +6 -0
- package/dist/bind.d.ts.map +1 -0
- package/dist/bind.js +45 -0
- package/dist/bind.js.map +1 -0
- package/dist/check.d.ts +30 -0
- package/dist/check.d.ts.map +1 -0
- package/dist/check.js +389 -0
- package/dist/check.js.map +1 -0
- package/dist/classes.d.ts +23 -0
- package/dist/classes.d.ts.map +1 -0
- package/dist/classes.js +139 -0
- package/dist/classes.js.map +1 -0
- package/dist/compile.d.ts +40 -0
- package/dist/compile.d.ts.map +1 -0
- package/dist/compile.js +311 -0
- package/dist/compile.js.map +1 -0
- package/dist/deadline.d.ts +5 -0
- package/dist/deadline.d.ts.map +1 -0
- package/dist/deadline.js +17 -0
- package/dist/deadline.js.map +1 -0
- package/dist/decide.d.ts +64 -0
- package/dist/decide.d.ts.map +1 -0
- package/dist/decide.js +482 -0
- package/dist/decide.js.map +1 -0
- package/dist/error-with-invariant.d.ts +9 -0
- package/dist/error-with-invariant.d.ts.map +1 -0
- package/dist/error-with-invariant.js +12 -0
- package/dist/error-with-invariant.js.map +1 -0
- package/dist/floor.d.ts +9 -0
- package/dist/floor.d.ts.map +1 -0
- package/dist/floor.js +9 -0
- package/dist/floor.js.map +1 -0
- package/dist/glob-expand.d.ts +10 -0
- package/dist/glob-expand.d.ts.map +1 -0
- package/dist/glob-expand.js +132 -0
- package/dist/glob-expand.js.map +1 -0
- package/dist/guards.d.ts +26 -0
- package/dist/guards.d.ts.map +1 -0
- package/dist/guards.js +419 -0
- package/dist/guards.js.map +1 -0
- package/dist/identity.d.ts +11 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +23 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/license-law.d.ts +43 -0
- package/dist/license-law.d.ts.map +1 -0
- package/dist/license-law.js +129 -0
- package/dist/license-law.js.map +1 -0
- package/dist/license.d.ts +3 -0
- package/dist/license.d.ts.map +1 -0
- package/dist/license.js +2 -0
- package/dist/license.js.map +1 -0
- package/dist/lift.d.ts +4 -0
- package/dist/lift.d.ts.map +1 -0
- package/dist/lift.js +14 -0
- package/dist/lift.js.map +1 -0
- package/dist/path-policy.d.ts +53 -0
- package/dist/path-policy.d.ts.map +1 -0
- package/dist/path-policy.js +248 -0
- package/dist/path-policy.js.map +1 -0
- package/dist/peel-cwd.d.ts +8 -0
- package/dist/peel-cwd.d.ts.map +1 -0
- package/dist/peel-cwd.js +120 -0
- package/dist/peel-cwd.js.map +1 -0
- package/dist/prep.d.ts +58 -0
- package/dist/prep.d.ts.map +1 -0
- package/dist/prep.js +690 -0
- package/dist/prep.js.map +1 -0
- package/dist/processor.d.ts +71 -0
- package/dist/processor.d.ts.map +1 -0
- package/dist/processor.js +132 -0
- package/dist/processor.js.map +1 -0
- package/dist/reasonable-defaults.d.ts +1448 -0
- package/dist/reasonable-defaults.d.ts.map +1 -0
- package/dist/reasonable-defaults.js +6 -0
- package/dist/reasonable-defaults.js.map +1 -0
- package/dist/reasonable-defaults.json +1662 -0
- package/dist/run-authorization.d.ts +8 -0
- package/dist/run-authorization.d.ts.map +1 -0
- package/dist/run-authorization.js +16 -0
- package/dist/run-authorization.js.map +1 -0
- package/dist/schemas/tirith.d.ts +58 -0
- package/dist/schemas/tirith.d.ts.map +1 -0
- package/dist/schemas/tirith.js +23 -0
- package/dist/schemas/tirith.js.map +1 -0
- package/dist/tirith-units.d.ts +2 -0
- package/dist/tirith-units.d.ts.map +1 -0
- package/dist/tirith-units.js +227 -0
- package/dist/tirith-units.js.map +1 -0
- package/dist/tirith.d.ts +24 -0
- package/dist/tirith.d.ts.map +1 -0
- package/dist/tirith.js +311 -0
- package/dist/tirith.js.map +1 -0
- package/dist/tool-path.d.ts +8 -0
- package/dist/tool-path.d.ts.map +1 -0
- package/dist/tool-path.js +38 -0
- package/dist/tool-path.js.map +1 -0
- package/dist/types.d.ts +87 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +14 -0
- package/dist/types.js.map +1 -0
- package/dist/verdict.d.ts +15 -0
- package/dist/verdict.d.ts.map +1 -0
- package/dist/verdict.js +55 -0
- package/dist/verdict.js.map +1 -0
- package/package.json +62 -3
- package/src/acknowledge.ts +206 -0
- package/src/authorize.ts +38 -0
- package/src/bind.ts +58 -0
- package/src/check.ts +552 -0
- package/src/classes.ts +156 -0
- package/src/compile.ts +370 -0
- package/src/deadline.ts +15 -0
- package/src/floor.ts +16 -0
- package/src/glob-expand.ts +137 -0
- package/src/guards.ts +428 -0
- package/src/identity.ts +26 -0
- package/src/index.ts +24 -0
- package/src/lift.ts +15 -0
- package/src/path-policy.ts +280 -0
- package/src/processor.ts +187 -0
- package/src/reasonable-defaults.json +1662 -0
- package/src/reasonable-defaults.ts +8 -0
- package/src/run-authorization.ts +23 -0
- package/src/tool-path.ts +43 -0
- package/src/types.ts +102 -0
- package/src/verdict.ts +63 -0
- package/README.md +0 -3
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lexical brace expansion (`.e{nv,x}`, `a{1..3}`, `{a,b}{c,d}`), the way bash does it before
|
|
3
|
+
* globbing. Used to judge a shell word as every word it could become. Bounded: past `limit`
|
|
4
|
+
* words the caller falls back to a wildcard superset.
|
|
5
|
+
*/
|
|
6
|
+
const DEFAULT_LIMIT = 256;
|
|
7
|
+
export function expandBraces(word, limit = DEFAULT_LIMIT) {
|
|
8
|
+
const done = [];
|
|
9
|
+
const work = [word];
|
|
10
|
+
while (work.length > 0) {
|
|
11
|
+
const next = work.pop();
|
|
12
|
+
const group = firstGroup(next);
|
|
13
|
+
if (group === undefined) {
|
|
14
|
+
done.push(next);
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
const head = next.slice(0, group.start);
|
|
18
|
+
const tail = next.slice(group.end + 1);
|
|
19
|
+
for (const item of group.items)
|
|
20
|
+
work.push(`${head}${item}${tail}`);
|
|
21
|
+
}
|
|
22
|
+
if (done.length + work.length > limit)
|
|
23
|
+
return { words: [], overflow: true };
|
|
24
|
+
}
|
|
25
|
+
return { words: done.toReversed(), overflow: false };
|
|
26
|
+
}
|
|
27
|
+
/** The first top-level `{...}` that bash would expand (a comma list or a range), or undefined. */
|
|
28
|
+
function firstGroup(text) {
|
|
29
|
+
for (let start = 0; start < text.length; start += 1) {
|
|
30
|
+
if (text[start] === "\\") {
|
|
31
|
+
start += 1;
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (text[start] !== "{")
|
|
35
|
+
continue;
|
|
36
|
+
const end = matchingBrace(text, start);
|
|
37
|
+
if (end === undefined)
|
|
38
|
+
continue;
|
|
39
|
+
const body = text.slice(start + 1, end);
|
|
40
|
+
const items = commaItems(body) ?? rangeItems(body);
|
|
41
|
+
if (items !== undefined)
|
|
42
|
+
return { start, end, items };
|
|
43
|
+
}
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
function matchingBrace(text, start) {
|
|
47
|
+
let depth = 0;
|
|
48
|
+
for (let i = start; i < text.length; i += 1) {
|
|
49
|
+
const ch = text[i];
|
|
50
|
+
switch (ch) {
|
|
51
|
+
case "\\": {
|
|
52
|
+
i += 1;
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
case "{": {
|
|
56
|
+
depth += 1;
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
case "}": {
|
|
60
|
+
depth -= 1;
|
|
61
|
+
if (depth === 0)
|
|
62
|
+
return i;
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
// No default
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
/** Items of a top-level comma list. Undefined when there is no top-level comma. */
|
|
71
|
+
function commaItems(body) {
|
|
72
|
+
const items = [];
|
|
73
|
+
let depth = 0;
|
|
74
|
+
let from = 0;
|
|
75
|
+
for (let i = 0; i < body.length; i += 1) {
|
|
76
|
+
const ch = body[i];
|
|
77
|
+
switch (ch) {
|
|
78
|
+
case "\\": {
|
|
79
|
+
i += 1;
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
case "{": {
|
|
83
|
+
depth += 1;
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
case "}": {
|
|
87
|
+
depth -= 1;
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
default:
|
|
91
|
+
if (ch === "," && depth === 0) {
|
|
92
|
+
items.push(body.slice(from, i));
|
|
93
|
+
from = i + 1;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (items.length === 0)
|
|
98
|
+
return undefined;
|
|
99
|
+
items.push(body.slice(from));
|
|
100
|
+
return items;
|
|
101
|
+
}
|
|
102
|
+
const RANGE = /^(-?\d+|[A-Z])\.\.(-?\d+|[A-Z])(?:\.\.(-?\d+))?$/i;
|
|
103
|
+
const MAX_RANGE = 1024;
|
|
104
|
+
function rangeItems(body) {
|
|
105
|
+
const match = RANGE.exec(body);
|
|
106
|
+
if (match === null)
|
|
107
|
+
return undefined;
|
|
108
|
+
const [, a, b, stepText] = match;
|
|
109
|
+
const step = Math.max(1, Math.abs(Number(stepText ?? "1")) || 1);
|
|
110
|
+
const out = [];
|
|
111
|
+
if (/^-?\d+$/.test(a) && /^-?\d+$/.test(b)) {
|
|
112
|
+
const from = Number(a);
|
|
113
|
+
const to = Number(b);
|
|
114
|
+
const width = /^-?0\d/.test(a) || /^-?0\d/.test(b) ? Math.max(a.replace("-", "").length, b.replace("-", "").length) : 0;
|
|
115
|
+
if (Math.abs(to - from) / step > MAX_RANGE)
|
|
116
|
+
return Array.from({ length: MAX_RANGE + 1 }, (_, i) => String(i));
|
|
117
|
+
for (let n = from; from <= to ? n <= to : n >= to; n += from <= to ? step : -step) {
|
|
118
|
+
const text = String(Math.abs(n)).padStart(width, "0");
|
|
119
|
+
out.push(n < 0 ? `-${text}` : text);
|
|
120
|
+
}
|
|
121
|
+
return out;
|
|
122
|
+
}
|
|
123
|
+
if (a.length === 1 && b.length === 1 && !/\d/.test(a + b)) {
|
|
124
|
+
const from = a.codePointAt(0);
|
|
125
|
+
const to = b.codePointAt(0);
|
|
126
|
+
for (let c = from; from <= to ? c <= to : c >= to; c += from <= to ? step : -step)
|
|
127
|
+
out.push(String.fromCodePoint(c));
|
|
128
|
+
return out;
|
|
129
|
+
}
|
|
130
|
+
return undefined;
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=glob-expand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glob-expand.js","sourceRoot":"","sources":["../src/glob-expand.ts"],"names":[],"mappings":"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"}
|
package/dist/guards.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Argument guards: what an option table cannot say. A guard sees the command
|
|
3
|
+
* node's positionals and flag bag and returns extra votes that join the node's
|
|
4
|
+
* own vote on the strict lattice, so a guard can tighten a verdict, never lift it.
|
|
5
|
+
*
|
|
6
|
+
* `flag_paths` (option values typed as paths, glued short values included) is
|
|
7
|
+
* a guard that every node gets for free.
|
|
8
|
+
*/
|
|
9
|
+
import { type PathTerm } from "./path-policy.js";
|
|
10
|
+
import type { ArgType, CommandNode, FloorVerdict } from "./types.js";
|
|
11
|
+
export type GuardPaths = {
|
|
12
|
+
readonly read?: PathTerm;
|
|
13
|
+
readonly write?: PathTerm;
|
|
14
|
+
/** The shell would expand this question's words: judge braces and globs as what they could become. */
|
|
15
|
+
readonly expand?: boolean;
|
|
16
|
+
/** `dotglob` is set somewhere in the command: `*` may match a leading dot. */
|
|
17
|
+
readonly dotglob?: boolean;
|
|
18
|
+
};
|
|
19
|
+
type Flags = Readonly<Record<string, readonly string[]>>;
|
|
20
|
+
export declare function guardVotes(node: CommandNode, toks: readonly string[], flags: Flags, paths: GuardPaths): FloorVerdict[];
|
|
21
|
+
export declare function pathVote(kind: ArgType, path: string, paths: GuardPaths): FloorVerdict;
|
|
22
|
+
/** Conservative sed parser: true only for scripts it fully understands and finds inert. */
|
|
23
|
+
export declare function sedScriptIsPlain(script: string): boolean;
|
|
24
|
+
export declare const GUARDS: ReadonlySet<string>;
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=guards.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guards.d.ts","sourceRoot":"","sources":["../src/guards.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,EAAiC,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAChF,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAe,YAAY,EAAE,MAAM,YAAY,CAAC;AAGlF,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC;IAC1B,sGAAsG;IACtG,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,8EAA8E;IAC9E,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B,CAAC;AAEF,KAAK,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAAC;AAIzD,wBAAgB,UAAU,CACxB,IAAI,EAAE,WAAW,EACjB,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,UAAU,GAChB,YAAY,EAAE,CAMhB;AAMD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,YAAY,CAMrF;AAwKD,2FAA2F;AAC3F,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CA2GxD;AAoGD,eAAO,MAAM,MAAM,EAAE,WAAW,CAAC,MAAM,CAAqC,CAAC"}
|
package/dist/guards.js
ADDED
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Argument guards: what an option table cannot say. A guard sees the command
|
|
3
|
+
* node's positionals and flag bag and returns extra votes that join the node's
|
|
4
|
+
* own vote on the strict lattice, so a guard can tighten a verdict, never lift it.
|
|
5
|
+
*
|
|
6
|
+
* `flag_paths` (option values typed as paths, glued short values included) is
|
|
7
|
+
* a guard that every node gets for free.
|
|
8
|
+
*/
|
|
9
|
+
import { posix } from "node:path";
|
|
10
|
+
import { explainPath, explainShellPath } from "./path-policy.js";
|
|
11
|
+
import { cast } from "./verdict.js";
|
|
12
|
+
export function guardVotes(node, toks, flags, paths) {
|
|
13
|
+
const positionals = toks.filter((tok) => tok !== "--");
|
|
14
|
+
return [
|
|
15
|
+
...flagPathVotes(node.flagPaths, flags, paths),
|
|
16
|
+
...node.guards.flatMap((name) => (GUARD_TABLE[name] ?? unknownGuard)(positionals, flags, paths)),
|
|
17
|
+
];
|
|
18
|
+
}
|
|
19
|
+
function unknownGuard() {
|
|
20
|
+
return [cast("ask", "unmodelled", "guard:unknown")];
|
|
21
|
+
}
|
|
22
|
+
export function pathVote(kind, path, paths) {
|
|
23
|
+
const cluster = kind === "read_path" ? paths.read : paths.write;
|
|
24
|
+
if (cluster === undefined)
|
|
25
|
+
return cast("ask", "unmodelled", `${kind === "read_path" ? "read" : "write"}:no-policy`);
|
|
26
|
+
return paths.expand === true
|
|
27
|
+
? explainShellPath(cluster, path, { dotglob: paths.dotglob })
|
|
28
|
+
: explainPath(cluster, path);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* `--output=F`, `--output F`, `-o F`, and glued `-oF`. An empty value (an
|
|
32
|
+
* option that lost its operand, or a letter cluster such as `-ofile`) is an
|
|
33
|
+
* unresolvable path and asks.
|
|
34
|
+
*/
|
|
35
|
+
function flagPathVotes(flagPaths, flags, paths) {
|
|
36
|
+
const votes = [];
|
|
37
|
+
for (const [name, kind] of Object.entries(flagPaths)) {
|
|
38
|
+
for (const value of flags[name] ?? [])
|
|
39
|
+
votes.push(pathVote(kind, value, paths));
|
|
40
|
+
if (name.startsWith("--") || name.length !== 2)
|
|
41
|
+
continue;
|
|
42
|
+
for (const key of Object.keys(flags)) {
|
|
43
|
+
if (key.startsWith(name) && key.length > 2 && !key.startsWith("--")) {
|
|
44
|
+
votes.push(pathVote(kind, key.slice(2), paths));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return votes;
|
|
49
|
+
}
|
|
50
|
+
/** True when `key` is `full` or an unambiguous long-option prefix of it (`--out` of `--output`). */
|
|
51
|
+
function isOption(key, full) {
|
|
52
|
+
return key === full || (key.startsWith("--") && key.length >= 3 && full.startsWith(key));
|
|
53
|
+
}
|
|
54
|
+
const GIT_CONFIG_DENY = [
|
|
55
|
+
/^alias\./,
|
|
56
|
+
/^include(if)?\./,
|
|
57
|
+
/^core\.(hookspath|fsmonitor|sshcommand|pager|editor|askpass|gitproxy|attributesfile|excludesfile)$/,
|
|
58
|
+
/^diff\..*(external|textconv|command)$/,
|
|
59
|
+
/^(pager|credential|filter|merge|mergetool|difftool|man|web|browser|sequence|gpg|url|protocol|uploadpack|receivepack|safe|http|remote|submodule)\./,
|
|
60
|
+
];
|
|
61
|
+
/** Keys whose value no git code path turns into a program, a file read, or a file write. */
|
|
62
|
+
const GIT_CONFIG_INERT = new Set([
|
|
63
|
+
"color.ui",
|
|
64
|
+
"color.diff",
|
|
65
|
+
"color.status",
|
|
66
|
+
"color.branch",
|
|
67
|
+
"color.log",
|
|
68
|
+
"core.quotepath",
|
|
69
|
+
"core.abbrev",
|
|
70
|
+
"core.precomposeunicode",
|
|
71
|
+
"core.filemode",
|
|
72
|
+
"core.whitespace",
|
|
73
|
+
"diff.renames",
|
|
74
|
+
"diff.context",
|
|
75
|
+
"diff.algorithm",
|
|
76
|
+
"log.date",
|
|
77
|
+
"log.abbrevcommit",
|
|
78
|
+
"status.showuntrackedfiles",
|
|
79
|
+
"status.branch",
|
|
80
|
+
"status.short",
|
|
81
|
+
"advice.statushints",
|
|
82
|
+
"user.name",
|
|
83
|
+
"user.email",
|
|
84
|
+
]);
|
|
85
|
+
/**
|
|
86
|
+
* `-c key=value` allowlist (case-insensitive: git folds the section and key).
|
|
87
|
+
* Exec/include keys deny, anything unknown asks. `--config-env` always asks.
|
|
88
|
+
*/
|
|
89
|
+
function gitConfig(_toks, flags) {
|
|
90
|
+
const votes = [];
|
|
91
|
+
for (const raw of flags["-c"] ?? []) {
|
|
92
|
+
const key = raw.split("=", 1)[0].trim().toLowerCase();
|
|
93
|
+
if (GIT_CONFIG_DENY.some((rule) => rule.test(key)))
|
|
94
|
+
votes.push(cast("deny", "exec-unknown", "guard:git-config"));
|
|
95
|
+
else if (!GIT_CONFIG_INERT.has(key))
|
|
96
|
+
votes.push(cast("ask", "unmodelled", "guard:git-config"));
|
|
97
|
+
}
|
|
98
|
+
if (Object.keys(flags).includes("--config-env"))
|
|
99
|
+
votes.push(cast("ask", "exec-unknown", "guard:git-config-env"));
|
|
100
|
+
return votes;
|
|
101
|
+
}
|
|
102
|
+
const REV_SYNTAX = /[~^@{}]/;
|
|
103
|
+
/**
|
|
104
|
+
* diff/log/show operands are revisions or paths. `--no-index` makes every
|
|
105
|
+
* operand a file git reads; otherwise a `rev:path` or bare operand that is
|
|
106
|
+
* not revision syntax is read as a path too (`git diff -- .env`, `git show HEAD:.env`).
|
|
107
|
+
*/
|
|
108
|
+
function gitReads(toks, flags, paths) {
|
|
109
|
+
const noIndex = Object.keys(flags).some((key) => isOption(key, "--no-index"));
|
|
110
|
+
if (noIndex)
|
|
111
|
+
return toks.map((tok) => pathVote("read_path", tok, paths));
|
|
112
|
+
const votes = [];
|
|
113
|
+
for (const tok of toks) {
|
|
114
|
+
for (const part of tok.split(/\.{2,3}/)) {
|
|
115
|
+
const target = part.includes(":") ? part.slice(part.indexOf(":") + 1) : part;
|
|
116
|
+
if (target === "" || REV_SYNTAX.test(target))
|
|
117
|
+
continue;
|
|
118
|
+
votes.push(pathVote("read_path", target, paths));
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return votes;
|
|
122
|
+
}
|
|
123
|
+
const SED_SAFE_FLAGS = [
|
|
124
|
+
"--quiet",
|
|
125
|
+
"--silent",
|
|
126
|
+
"--regexp-extended",
|
|
127
|
+
"--separate",
|
|
128
|
+
"--unbuffered",
|
|
129
|
+
"--null-data",
|
|
130
|
+
"--posix",
|
|
131
|
+
"--sandbox",
|
|
132
|
+
"--debug",
|
|
133
|
+
"--follow-symlinks",
|
|
134
|
+
"--expression",
|
|
135
|
+
];
|
|
136
|
+
const SED_OTHER_LONG = ["--file", "--in-place", "--line-length", "--help", "--version", "--binary"];
|
|
137
|
+
const SED_SAFE_SHORT = new Set(["-n", "-E", "-r", "-s", "-u", "-z", "-e"]);
|
|
138
|
+
function sedFlagVote(key) {
|
|
139
|
+
if (isOption(key, "--in-place"))
|
|
140
|
+
return "deny";
|
|
141
|
+
if (key.startsWith("--")) {
|
|
142
|
+
const safe = SED_SAFE_FLAGS.some((full) => isOption(key, full));
|
|
143
|
+
const other = SED_OTHER_LONG.some((full) => isOption(key, full));
|
|
144
|
+
return safe && !other ? undefined : "ask";
|
|
145
|
+
}
|
|
146
|
+
if (key.startsWith("-i") || key.startsWith("-I"))
|
|
147
|
+
return "deny";
|
|
148
|
+
if (key.startsWith("-e") && key.length > 2)
|
|
149
|
+
return undefined; // glued script, validated below
|
|
150
|
+
return SED_SAFE_SHORT.has(key) ? undefined : "ask";
|
|
151
|
+
}
|
|
152
|
+
function sedIsBoolean(key) {
|
|
153
|
+
if (key.startsWith("--"))
|
|
154
|
+
return sedFlagVote(key) === undefined && !isOption(key, "--expression");
|
|
155
|
+
return SED_SAFE_SHORT.has(key) && key !== "-e";
|
|
156
|
+
}
|
|
157
|
+
function sedScripts(toks, flags) {
|
|
158
|
+
const scripts = [];
|
|
159
|
+
for (const [key, values] of Object.entries(flags)) {
|
|
160
|
+
if (key === "-e" || isOption(key, "--expression"))
|
|
161
|
+
scripts.push(...values.filter((value) => value !== ""));
|
|
162
|
+
else if (key.startsWith("-e") && !key.startsWith("--") && key.length > 2)
|
|
163
|
+
scripts.push(key.slice(2));
|
|
164
|
+
}
|
|
165
|
+
if (scripts.length > 0)
|
|
166
|
+
return { scripts, files: toks };
|
|
167
|
+
return { scripts: toks.slice(0, 1), files: toks.slice(1) };
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* sed: in-place edits deny; a script that is anything but plain addressed
|
|
171
|
+
* `s`/`y`/`p`/`d`/`q`/`n`-style commands with benign `s` flags asks. That drops the file
|
|
172
|
+
* writers (`w`, `W`, `s///w`) and the program runners (`e`, `s///e`), and `r`/`R` file reads.
|
|
173
|
+
* File operands are reads.
|
|
174
|
+
*/
|
|
175
|
+
function sed(toks, flags, paths) {
|
|
176
|
+
const votes = Object.keys(flags).flatMap((key) => {
|
|
177
|
+
const vote = sedFlagVote(key);
|
|
178
|
+
if (vote === undefined)
|
|
179
|
+
return [];
|
|
180
|
+
return [
|
|
181
|
+
vote === "deny"
|
|
182
|
+
? cast("deny", "workspace-write", "guard:sed-in-place")
|
|
183
|
+
: cast("ask", "exec-unknown", "guard:sed-flag"),
|
|
184
|
+
];
|
|
185
|
+
});
|
|
186
|
+
// `-n SCRIPT` also parses as `-n` taking SCRIPT as a value. The other reading (boolean flag, SCRIPT a
|
|
187
|
+
// positional) is enumerated and judged on its own, so this one has no script or files to inspect.
|
|
188
|
+
const swallowed = Object.entries(flags).some(([key, values]) => sedIsBoolean(key) && values.some((v) => v !== ""));
|
|
189
|
+
if (swallowed)
|
|
190
|
+
return votes;
|
|
191
|
+
const { scripts, files } = sedScripts(toks, flags);
|
|
192
|
+
if (scripts.length === 0 || !scripts.every((script) => sedScriptIsPlain(script))) {
|
|
193
|
+
votes.push(cast("ask", "exec-unknown", "guard:sed-script"));
|
|
194
|
+
}
|
|
195
|
+
for (const file of files)
|
|
196
|
+
votes.push(pathVote("read_path", file, paths));
|
|
197
|
+
return votes;
|
|
198
|
+
}
|
|
199
|
+
const SED_SIMPLE = new Set(["p", "P", "d", "D", "g", "G", "h", "H", "x", "n", "N", "=", "l", "q", "Q", "z"]);
|
|
200
|
+
/** Conservative sed parser: true only for scripts it fully understands and finds inert. */
|
|
201
|
+
export function sedScriptIsPlain(script) {
|
|
202
|
+
let i = 0;
|
|
203
|
+
let depth = 0;
|
|
204
|
+
const n = script.length;
|
|
205
|
+
const blank = (c) => c === " " || c === "\t";
|
|
206
|
+
const digit = (c) => c !== undefined && c >= "0" && c <= "9";
|
|
207
|
+
const space = () => {
|
|
208
|
+
while (i < n && blank(script[i]))
|
|
209
|
+
i += 1;
|
|
210
|
+
};
|
|
211
|
+
/** Consume up to the unescaped delimiter. Returns false when unterminated. */
|
|
212
|
+
const delimited = (delim) => {
|
|
213
|
+
while (i < n) {
|
|
214
|
+
const c = script[i];
|
|
215
|
+
i += 1;
|
|
216
|
+
if (c === "\\") {
|
|
217
|
+
i += 1;
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
if (c === delim)
|
|
221
|
+
return true;
|
|
222
|
+
}
|
|
223
|
+
return false;
|
|
224
|
+
};
|
|
225
|
+
const address = () => {
|
|
226
|
+
const c = script[i];
|
|
227
|
+
if (c === "$") {
|
|
228
|
+
i += 1;
|
|
229
|
+
return true;
|
|
230
|
+
}
|
|
231
|
+
if (digit(c)) {
|
|
232
|
+
while (digit(script[i]))
|
|
233
|
+
i += 1;
|
|
234
|
+
if (script[i] === "~") {
|
|
235
|
+
i += 1;
|
|
236
|
+
while (digit(script[i]))
|
|
237
|
+
i += 1;
|
|
238
|
+
}
|
|
239
|
+
return true;
|
|
240
|
+
}
|
|
241
|
+
if (c === "/" || c === "\\") {
|
|
242
|
+
let delim = "/";
|
|
243
|
+
if (c === "\\") {
|
|
244
|
+
i += 1;
|
|
245
|
+
delim = script[i] ?? "";
|
|
246
|
+
if (delim === "" || delim === "\\" || delim === "\n")
|
|
247
|
+
return false;
|
|
248
|
+
}
|
|
249
|
+
i += 1;
|
|
250
|
+
if (!delimited(delim))
|
|
251
|
+
return false;
|
|
252
|
+
while (script[i] === "I" || script[i] === "M")
|
|
253
|
+
i += 1;
|
|
254
|
+
return true;
|
|
255
|
+
}
|
|
256
|
+
return false;
|
|
257
|
+
};
|
|
258
|
+
const ending = () => {
|
|
259
|
+
space();
|
|
260
|
+
const c = script[i];
|
|
261
|
+
return c === undefined || c === ";" || c === "\n" || c === "}";
|
|
262
|
+
};
|
|
263
|
+
while (i < n) {
|
|
264
|
+
while (i < n && (blank(script[i]) || script[i] === ";" || script[i] === "\n"))
|
|
265
|
+
i += 1;
|
|
266
|
+
if (i >= n)
|
|
267
|
+
break;
|
|
268
|
+
if (script[i] === "}") {
|
|
269
|
+
depth -= 1;
|
|
270
|
+
if (depth < 0)
|
|
271
|
+
return false;
|
|
272
|
+
i += 1;
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
if (address()) {
|
|
276
|
+
space();
|
|
277
|
+
if (script[i] === ",") {
|
|
278
|
+
i += 1;
|
|
279
|
+
space();
|
|
280
|
+
if (script[i] === "+" || script[i] === "~")
|
|
281
|
+
i += 1;
|
|
282
|
+
if (!address())
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
space();
|
|
287
|
+
while (script[i] === "!") {
|
|
288
|
+
i += 1;
|
|
289
|
+
space();
|
|
290
|
+
}
|
|
291
|
+
const cmd = script[i];
|
|
292
|
+
if (cmd === undefined)
|
|
293
|
+
return false;
|
|
294
|
+
i += 1;
|
|
295
|
+
if (cmd === "{") {
|
|
296
|
+
depth += 1;
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
if (cmd === "s" || cmd === "y") {
|
|
300
|
+
const delim = script[i];
|
|
301
|
+
if (delim === undefined || delim === "\\" || delim === "\n" || blank(delim))
|
|
302
|
+
return false;
|
|
303
|
+
i += 1;
|
|
304
|
+
if (!delimited(delim) || !delimited(delim))
|
|
305
|
+
return false;
|
|
306
|
+
if (cmd === "s") {
|
|
307
|
+
while (i < n && "gpiImM0123456789".includes(script[i]))
|
|
308
|
+
i += 1;
|
|
309
|
+
}
|
|
310
|
+
if (!ending())
|
|
311
|
+
return false;
|
|
312
|
+
continue;
|
|
313
|
+
}
|
|
314
|
+
if (SED_SIMPLE.has(cmd)) {
|
|
315
|
+
if (cmd === "q" || cmd === "Q" || cmd === "l") {
|
|
316
|
+
space();
|
|
317
|
+
while (digit(script[i]))
|
|
318
|
+
i += 1;
|
|
319
|
+
}
|
|
320
|
+
if (!ending())
|
|
321
|
+
return false;
|
|
322
|
+
continue;
|
|
323
|
+
}
|
|
324
|
+
return false;
|
|
325
|
+
}
|
|
326
|
+
return depth === 0;
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Catastrophic shapes: the few commands whose one run cannot be undone, so no mode may
|
|
330
|
+
* lift them (`block`, not `deny`). A guard only tightens, so the node keeps its soft vote
|
|
331
|
+
* for every other form and these arms add the hard one.
|
|
332
|
+
*
|
|
333
|
+
* Operands are read from positionals and from flag values alike: `rm -r /` parses both as
|
|
334
|
+
* a boolean `-r` plus operand `/` and as `-r` taking `/`, and either reading must see it.
|
|
335
|
+
*/
|
|
336
|
+
const ROOT_LIKE = new Set([
|
|
337
|
+
"/",
|
|
338
|
+
"/*",
|
|
339
|
+
"/.",
|
|
340
|
+
"~",
|
|
341
|
+
"~/",
|
|
342
|
+
"~/*",
|
|
343
|
+
"~/.",
|
|
344
|
+
"$HOME",
|
|
345
|
+
"$HOME/",
|
|
346
|
+
"$HOME/*",
|
|
347
|
+
"$HOME/.",
|
|
348
|
+
"${HOME}",
|
|
349
|
+
"${HOME}/",
|
|
350
|
+
"${HOME}/*",
|
|
351
|
+
"${HOME}/.",
|
|
352
|
+
]);
|
|
353
|
+
/** `/`, `/*`, `~`, `~/`, `$HOME` and their `//`, `/.` spellings. Not `/tmp/x`, not `./`. */
|
|
354
|
+
function isRootLike(word) {
|
|
355
|
+
const squeezed = word.replaceAll(/\/{2,}/g, "/");
|
|
356
|
+
if (ROOT_LIKE.has(squeezed))
|
|
357
|
+
return true;
|
|
358
|
+
// `/.`, `/./`, `~/.`: no-op segments after the head.
|
|
359
|
+
const plain = squeezed.replaceAll(/(?<=.)\/\.(?=\/|$)/g, "");
|
|
360
|
+
return plain !== squeezed && ROOT_LIKE.has(plain);
|
|
361
|
+
}
|
|
362
|
+
function operands(toks, flags) {
|
|
363
|
+
return [...toks, ...Object.values(flags).flat()];
|
|
364
|
+
}
|
|
365
|
+
/** `-R`, `--recursive`, or a short cluster that carries `r`/`R` (`-rf`, `-fR`). */
|
|
366
|
+
function isRecursive(flags) {
|
|
367
|
+
return Object.keys(flags).some((key) => isOption(key, "--recursive") || (/^-[A-Z]+$/i.test(key) && /r/i.test(key)));
|
|
368
|
+
}
|
|
369
|
+
function hasOption(flags, full) {
|
|
370
|
+
return Object.keys(flags).some((key) => isOption(key, full));
|
|
371
|
+
}
|
|
372
|
+
/** rm/chmod/chown: `--no-preserve-root`, or recursion over the filesystem root or the home directory. */
|
|
373
|
+
function recursiveRoot(toks, flags) {
|
|
374
|
+
if (hasOption(flags, "--no-preserve-root"))
|
|
375
|
+
return [catastrophe("guard:no-preserve-root")];
|
|
376
|
+
return isRecursive(flags) && operands(toks, flags).some(isRootLike) ? [catastrophe("guard:recursive-root")] : [];
|
|
377
|
+
}
|
|
378
|
+
function catastrophe(ruleId) {
|
|
379
|
+
return cast("block", "destroy-catastrophic", ruleId);
|
|
380
|
+
}
|
|
381
|
+
/** Device nodes dd may write without harm. Everything else under /dev is a disk, a tty, or memory. */
|
|
382
|
+
const DD_HARMLESS_DEVICES = new Set(["/dev/null", "/dev/zero", "/dev/full", "/dev/stdout", "/dev/stderr", "/dev/tty"]);
|
|
383
|
+
/** dd: `of=` a device node. */
|
|
384
|
+
function ddDevice(toks, flags) {
|
|
385
|
+
const hit = operands(toks, flags).some((word) => {
|
|
386
|
+
if (!word.startsWith("of="))
|
|
387
|
+
return false;
|
|
388
|
+
const target = posix.normalize(word.slice(3));
|
|
389
|
+
if (!target.startsWith("/dev/"))
|
|
390
|
+
return false;
|
|
391
|
+
return !DD_HARMLESS_DEVICES.has(target) && !target.startsWith("/dev/fd/");
|
|
392
|
+
});
|
|
393
|
+
return hit ? [catastrophe("guard:dd-device")] : [];
|
|
394
|
+
}
|
|
395
|
+
const PARTED_READS = new Set(["print", "p", "free", "all", "list", "devices"]);
|
|
396
|
+
/**
|
|
397
|
+
* Partition editors. The listing forms read; every other invocation (including the
|
|
398
|
+
* interactive ones, whose commands arrive on stdin) can rewrite the table.
|
|
399
|
+
*/
|
|
400
|
+
function diskWrite(toks, flags) {
|
|
401
|
+
const readOnly = ["--list", "--show-size", "--version", "--help"].some((full) => hasOption(flags, full)) ||
|
|
402
|
+
["-l", "-s", "-V", "-h"].some((short) => Object.hasOwn(flags, short));
|
|
403
|
+
if (readOnly)
|
|
404
|
+
return [];
|
|
405
|
+
// parted names the device, then commands: only the printing ones are a read.
|
|
406
|
+
const commands = toks.filter((tok) => !tok.startsWith("/dev/"));
|
|
407
|
+
const printing = commands.length > 0 && commands.every((tok) => PARTED_READS.has(tok));
|
|
408
|
+
return printing ? [] : [catastrophe("guard:disk-write")];
|
|
409
|
+
}
|
|
410
|
+
const GUARD_TABLE = {
|
|
411
|
+
"git-config": gitConfig,
|
|
412
|
+
"git-reads": gitReads,
|
|
413
|
+
sed,
|
|
414
|
+
"recursive-root": recursiveRoot,
|
|
415
|
+
"dd-device": ddDevice,
|
|
416
|
+
"disk-write": diskWrite,
|
|
417
|
+
};
|
|
418
|
+
export const GUARDS = new Set(Object.keys(GUARD_TABLE));
|
|
419
|
+
//# sourceMappingURL=guards.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guards.js","sourceRoot":"","sources":["../src/guards.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Executable identity for the floor. Path-form argv0 is the named command
|
|
3
|
+
* iff `which` returns the same path; otherwise it stays a path.
|
|
4
|
+
* No process-lifetime cache — PATH/cwd are part of identity.
|
|
5
|
+
*/
|
|
6
|
+
import { type Which } from "@inhuman.tools/policy-bash-disassembler";
|
|
7
|
+
export declare function whichOnPath(name: string): string | undefined;
|
|
8
|
+
/** Path-form argv0 rewritten to the known name, or the original token. */
|
|
9
|
+
export declare function identityName(raw: string, known: ReadonlySet<string>, which: Which | undefined): string;
|
|
10
|
+
export { type Which } from "@inhuman.tools/policy-bash-disassembler";
|
|
11
|
+
//# sourceMappingURL=identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAgB,KAAK,KAAK,EAAE,MAAM,yCAAyC,CAAC;AAEnF,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAQ5D;AAED,0EAA0E;AAC1E,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,SAAS,GAAG,MAAM,CAEtG;AAED,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,yCAAyC,CAAC"}
|
package/dist/identity.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Executable identity for the floor. Path-form argv0 is the named command
|
|
3
|
+
* iff `which` returns the same path; otherwise it stays a path.
|
|
4
|
+
* No process-lifetime cache — PATH/cwd are part of identity.
|
|
5
|
+
*/
|
|
6
|
+
import { execFileSync } from "node:child_process";
|
|
7
|
+
import { resolveKnown } from "@inhuman.tools/policy-bash-disassembler";
|
|
8
|
+
export function whichOnPath(name) {
|
|
9
|
+
if (name === "" || name.includes("/") || name.includes("\0"))
|
|
10
|
+
return undefined;
|
|
11
|
+
try {
|
|
12
|
+
const out = execFileSync("which", [name], { encoding: "utf8", timeout: 1000 }).trim();
|
|
13
|
+
return out === "" ? undefined : out.split("\n")[0];
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/** Path-form argv0 rewritten to the known name, or the original token. */
|
|
20
|
+
export function identityName(raw, known, which) {
|
|
21
|
+
return resolveKnown(raw, known, which) ?? raw;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,YAAY,EAAc,MAAM,yCAAyC,CAAC;AAEnF,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,IAAI,IAAI,KAAK,EAAE,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IAC/E,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACtF,OAAO,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,KAA0B,EAAE,KAAwB;IAC5F,OAAO,YAAY,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,GAAG,CAAC;AAChD,CAAC"}
|