@dsh-enhanced/assistant-isolation 0.1.65 → 0.1.67
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/README.md +287 -9
- package/lib/audit-archive.d.ts +1 -1
- package/lib/audit-archive.d.ts.map +1 -1
- package/lib/audit-archive.js +31 -13
- package/lib/audit-archive.js.map +1 -1
- package/lib/cli.d.ts +7 -3
- package/lib/cli.d.ts.map +1 -1
- package/lib/cli.js +104 -23
- package/lib/cli.js.map +1 -1
- package/lib/config.d.ts +15 -2
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js +49 -9
- package/lib/config.js.map +1 -1
- package/lib/diagnostics.js +2 -2
- package/lib/diagnostics.js.map +1 -1
- package/lib/index.d.ts +17 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +17 -1
- package/lib/index.js.map +1 -1
- package/lib/ledger.d.ts +19 -2
- package/lib/ledger.d.ts.map +1 -1
- package/lib/ledger.js +371 -44
- package/lib/ledger.js.map +1 -1
- package/lib/linux-cgroups.d.ts +75 -0
- package/lib/linux-cgroups.d.ts.map +1 -0
- package/lib/linux-cgroups.js +517 -0
- package/lib/linux-cgroups.js.map +1 -0
- package/lib/linux-execution-contract.d.ts +123 -0
- package/lib/linux-execution-contract.d.ts.map +1 -0
- package/lib/linux-execution-contract.js +279 -0
- package/lib/linux-execution-contract.js.map +1 -0
- package/lib/linux-execution.d.ts +123 -0
- package/lib/linux-execution.d.ts.map +1 -0
- package/lib/linux-execution.js +1264 -0
- package/lib/linux-execution.js.map +1 -0
- package/lib/linux-job-recovery.d.ts +5 -0
- package/lib/linux-job-recovery.d.ts.map +1 -0
- package/lib/linux-job-recovery.js +63 -0
- package/lib/linux-job-recovery.js.map +1 -0
- package/lib/linux-namespace.d.ts +80 -0
- package/lib/linux-namespace.d.ts.map +1 -0
- package/lib/linux-namespace.js +471 -0
- package/lib/linux-namespace.js.map +1 -0
- package/lib/linux-repository-admission.d.ts +26 -0
- package/lib/linux-repository-admission.d.ts.map +1 -0
- package/lib/linux-repository-admission.js +64 -0
- package/lib/linux-repository-admission.js.map +1 -0
- package/lib/linux-repository-runner.d.ts +54 -0
- package/lib/linux-repository-runner.d.ts.map +1 -0
- package/lib/linux-repository-runner.js +614 -0
- package/lib/linux-repository-runner.js.map +1 -0
- package/lib/linux-runner-state-migration.d.ts +94 -0
- package/lib/linux-runner-state-migration.d.ts.map +1 -0
- package/lib/linux-runner-state-migration.js +463 -0
- package/lib/linux-runner-state-migration.js.map +1 -0
- package/lib/linux-runner-state.d.ts +53 -0
- package/lib/linux-runner-state.d.ts.map +1 -0
- package/lib/linux-runner-state.js +332 -0
- package/lib/linux-runner-state.js.map +1 -0
- package/lib/linux-runtime-source.d.ts +28 -0
- package/lib/linux-runtime-source.d.ts.map +1 -0
- package/lib/linux-runtime-source.js +237 -0
- package/lib/linux-runtime-source.js.map +1 -0
- package/lib/linux-runtime.d.ts +37 -0
- package/lib/linux-runtime.d.ts.map +1 -0
- package/lib/linux-runtime.js +192 -0
- package/lib/linux-runtime.js.map +1 -0
- package/lib/linux-system-snapshot.d.ts +47 -0
- package/lib/linux-system-snapshot.d.ts.map +1 -0
- package/lib/linux-system-snapshot.js +704 -0
- package/lib/linux-system-snapshot.js.map +1 -0
- package/lib/linux-user-namespace.d.ts +79 -0
- package/lib/linux-user-namespace.d.ts.map +1 -0
- package/lib/linux-user-namespace.js +234 -0
- package/lib/linux-user-namespace.js.map +1 -0
- package/lib/linux-verifier-runner.d.ts +27 -0
- package/lib/linux-verifier-runner.d.ts.map +1 -0
- package/lib/linux-verifier-runner.js +346 -0
- package/lib/linux-verifier-runner.js.map +1 -0
- package/lib/native-cgroup-roots.d.ts +20 -0
- package/lib/native-cgroup-roots.d.ts.map +1 -0
- package/lib/native-cgroup-roots.js +121 -0
- package/lib/native-cgroup-roots.js.map +1 -0
- package/lib/native-resources.d.ts +44 -0
- package/lib/native-resources.d.ts.map +1 -0
- package/lib/native-resources.js +354 -0
- package/lib/native-resources.js.map +1 -0
- package/lib/probe.d.ts +10 -0
- package/lib/probe.d.ts.map +1 -1
- package/lib/probe.js +52 -2
- package/lib/probe.js.map +1 -1
- package/lib/service.d.ts +1 -1
- package/lib/service.d.ts.map +1 -1
- package/lib/service.js +122 -9
- package/lib/service.js.map +1 -1
- package/lib/storage.d.ts.map +1 -1
- package/lib/storage.js +36 -6
- package/lib/storage.js.map +1 -1
- package/lib/tools.js +1 -1
- package/lib/tools.js.map +1 -1
- package/lib/types.d.ts +5 -1
- package/lib/types.d.ts.map +1 -1
- package/lib/verifier-runner.d.ts +4 -2
- package/lib/verifier-runner.d.ts.map +1 -1
- package/lib/verifier-runner.js +22 -1
- package/lib/verifier-runner.js.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +15 -10
- package/runtime/linux-candidate-entry.py +82 -0
- package/runtime/linux-namespace-worker.mjs +561 -0
- package/runtime/linux-seccomp-policy.LICENSE +202 -0
- package/runtime/linux-seccomp-policy.json +886 -0
- package/runtime/linux-seccomp.py +106 -0
- package/runtime/linux-userns-launcher.py +149 -0
- package/runtime/linux-userns-proof.py +299 -0
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
3
|
+
import { lstat, mkdir, readFile, realpath, rm, stat } from 'node:fs/promises';
|
|
4
|
+
import { isAbsolute, join, resolve, sep } from 'node:path';
|
|
5
|
+
import { StringDecoder } from 'node:string_decoder';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
const WORKER = fileURLToPath(new URL('../runtime/linux-namespace-worker.mjs', import.meta.url));
|
|
8
|
+
const USERNS_LAUNCHER = fileURLToPath(new URL('../runtime/linux-userns-launcher.py', import.meta.url));
|
|
9
|
+
const CONTROL = /[\p{Cc}]/u;
|
|
10
|
+
const NAMESPACE_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}-[0-9a-f]{32}$/iu;
|
|
11
|
+
const MAX_INPUT_BYTES = 1_048_576;
|
|
12
|
+
// JSON can expand each valid control character to six ASCII bytes. Both the
|
|
13
|
+
// output and total artifacts may independently contain 1 MiB of such text.
|
|
14
|
+
const MAX_PROTOCOL_BYTES = 13 * 1024 * 1024;
|
|
15
|
+
const CLEANUP_TIMEOUT_MS = 5_000;
|
|
16
|
+
export const LINUX_REPOSITORY_INPUT_BYTES = 64 * 1024 ** 2;
|
|
17
|
+
export const LINUX_REPOSITORY_INPUT_MOUNT_BYTES = LINUX_REPOSITORY_INPUT_BYTES + 4096;
|
|
18
|
+
export const LINUX_REPOSITORY_ARTIFACT_BYTES = 32 * 1024 ** 2;
|
|
19
|
+
function fail(message) { throw new Error(`linux namespace: ${message}`); }
|
|
20
|
+
function canonical(path) {
|
|
21
|
+
return isAbsolute(path) && resolve(path) === path
|
|
22
|
+
&& !path.includes('\0') && !path.includes('\r') && !path.includes('\n');
|
|
23
|
+
}
|
|
24
|
+
function integer(value, min, max) { return Number.isSafeInteger(value) && value >= min && value <= max; }
|
|
25
|
+
function safePath(path) {
|
|
26
|
+
return typeof path === 'string' && path.length > 0 && path.length <= 4096
|
|
27
|
+
&& !isAbsolute(path) && !path.includes('\\') && !CONTROL.test(path)
|
|
28
|
+
&& path.split('/').every(part => part.length > 0 && part !== '.' && part !== '..');
|
|
29
|
+
}
|
|
30
|
+
async function privateDirectory(path) {
|
|
31
|
+
if (!canonical(path) || await realpath(path) !== path)
|
|
32
|
+
fail('state root is not canonical');
|
|
33
|
+
const info = await lstat(path);
|
|
34
|
+
if (!info.isDirectory() || info.isSymbolicLink() || info.uid !== process.getuid?.() || (info.mode & 0o077) !== 0) {
|
|
35
|
+
fail('state root must be owner-private');
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
async function validate(input, repository = false) {
|
|
39
|
+
if (process.platform !== 'linux' || process.getuid?.() === 0)
|
|
40
|
+
fail('requires non-root Linux');
|
|
41
|
+
await privateDirectory(input.stateRoot);
|
|
42
|
+
for (const source of ['/usr', '/lib', '/lib64']) {
|
|
43
|
+
const system = await realpath(source).catch(error => {
|
|
44
|
+
if (error.code === 'ENOENT')
|
|
45
|
+
return undefined;
|
|
46
|
+
throw error;
|
|
47
|
+
});
|
|
48
|
+
if (system && (input.stateRoot === system || input.stateRoot.startsWith(system + sep)
|
|
49
|
+
|| system.startsWith(input.stateRoot + sep)))
|
|
50
|
+
fail('state root overlaps exposed system files');
|
|
51
|
+
}
|
|
52
|
+
if (input.namespaceId !== undefined && (typeof input.namespaceId !== 'string' || !NAMESPACE_ID.test(input.namespaceId)))
|
|
53
|
+
fail('invalid namespace id');
|
|
54
|
+
if (input.profile !== 'ordinary' && input.profile !== 'repository')
|
|
55
|
+
fail('invalid profile');
|
|
56
|
+
if (!Array.isArray(input.argv) || input.argv.length < 1 || input.argv.length > 64
|
|
57
|
+
|| !input.argv.every((arg, i) => typeof arg === 'string' && arg.length <= 65_536
|
|
58
|
+
&& !arg.includes('\0') && (i !== 0 || canonical(arg))))
|
|
59
|
+
fail('invalid command');
|
|
60
|
+
if (!integer(input.workspaceBytes, 4096, (repository ? 8 : 4) * 1024 ** 3) || input.workspaceBytes % 4096 !== 0
|
|
61
|
+
|| !integer(input.tmpBytes, 4096, (repository ? 4 : 2) * 1024 ** 3) || input.tmpBytes % 4096 !== 0
|
|
62
|
+
|| !integer(input.workspaceInodes, 16, 1_000_000) || !integer(input.tmpInodes, 16, 1_000_000)
|
|
63
|
+
|| !integer(input.maxArtifactBytes ?? MAX_INPUT_BYTES, 1, (repository ? LINUX_REPOSITORY_ARTIFACT_BYTES : MAX_INPUT_BYTES))
|
|
64
|
+
|| !integer(input.timeoutMs, 1, 1_800_000) || !integer(input.maxOutputBytes, 1, 1_048_576))
|
|
65
|
+
fail('invalid limits');
|
|
66
|
+
if (!Array.isArray(input.files) || input.files.length > 128 || !Array.isArray(input.artifacts ?? [])
|
|
67
|
+
|| (input.artifacts?.length ?? 0) > 128)
|
|
68
|
+
fail('invalid files or artifacts');
|
|
69
|
+
const names = new Set();
|
|
70
|
+
let bytes = 0;
|
|
71
|
+
for (const file of input.files) {
|
|
72
|
+
if (!file || !safePath(file.path) || names.has(file.path) || typeof file.content !== 'string'
|
|
73
|
+
|| !file.content.isWellFormed())
|
|
74
|
+
fail('invalid input file');
|
|
75
|
+
names.add(file.path);
|
|
76
|
+
bytes += Buffer.byteLength(file.content);
|
|
77
|
+
}
|
|
78
|
+
if (bytes > MAX_INPUT_BYTES || [...names].some(name => [...names].some(other => other !== name && other.startsWith(`${name}/`)))) {
|
|
79
|
+
fail('input files exceed bounds or collide');
|
|
80
|
+
}
|
|
81
|
+
if ((input.artifacts ?? []).some(path => !safePath(path))
|
|
82
|
+
|| new Set(input.artifacts ?? []).size !== (input.artifacts ?? []).length)
|
|
83
|
+
fail('invalid artifact path');
|
|
84
|
+
if (!Array.isArray(input.readOnlyRoots ?? []) || (input.readOnlyRoots?.length ?? 0) > 16)
|
|
85
|
+
fail('invalid runtime roots');
|
|
86
|
+
for (const root of input.readOnlyRoots ?? []) {
|
|
87
|
+
if (!canonical(root) || root === '/' || await realpath(root) !== root)
|
|
88
|
+
fail('unsafe runtime root');
|
|
89
|
+
const info = await lstat(root);
|
|
90
|
+
if (!info.isDirectory() || info.isSymbolicLink() || info.uid !== process.getuid?.()
|
|
91
|
+
|| (info.mode & 0o022) !== 0 || root === input.stateRoot || root.startsWith(input.stateRoot + sep)
|
|
92
|
+
|| input.stateRoot.startsWith(root + sep))
|
|
93
|
+
fail('unsafe runtime root');
|
|
94
|
+
}
|
|
95
|
+
if (input.signal.aborted || typeof input.beforeKeeperStart !== 'function' || typeof input.beforeStart !== 'function'
|
|
96
|
+
|| typeof input.afterExit !== 'function' || typeof input.onStop !== 'function')
|
|
97
|
+
fail('missing admission or cleanup');
|
|
98
|
+
}
|
|
99
|
+
async function validateUserNamespace(input) {
|
|
100
|
+
const mapping = input.userNamespace;
|
|
101
|
+
if (!mapping || !input.systemSnapshot || typeof input.onUserNamespaceReady !== 'function'
|
|
102
|
+
|| typeof input.beforeCandidateExec !== 'function')
|
|
103
|
+
fail('dual identity requires snapshot and both gates');
|
|
104
|
+
const keys = (value, names) => Object.keys(value).sort().join() === names;
|
|
105
|
+
if (!keys(mapping, 'candidateGid,candidateUid,helpers,hostNamespace,ownerGid,ownerUid,schemaVersion')
|
|
106
|
+
|| mapping.schemaVersion !== 1 || mapping.ownerUid !== process.getuid?.() || mapping.ownerGid !== process.getgid?.()
|
|
107
|
+
|| !integer(mapping.candidateUid, 1, 4_294_967_294) || !integer(mapping.candidateGid, 1, 4_294_967_294)
|
|
108
|
+
|| mapping.candidateUid === mapping.ownerUid || mapping.candidateGid === mapping.ownerGid
|
|
109
|
+
|| !mapping.hostNamespace || !keys(mapping.hostNamespace, 'dev,ino')
|
|
110
|
+
|| !integer(mapping.hostNamespace.dev, 0, Number.MAX_SAFE_INTEGER) || !integer(mapping.hostNamespace.ino, 1, Number.MAX_SAFE_INTEGER)
|
|
111
|
+
|| !mapping.helpers || !keys(mapping.helpers, 'gid,uid'))
|
|
112
|
+
fail('invalid dual identity mapping');
|
|
113
|
+
const current = await stat('/proc/self/ns/user');
|
|
114
|
+
if (current.dev !== mapping.hostNamespace.dev || current.ino !== mapping.hostNamespace.ino)
|
|
115
|
+
fail('host user namespace differs');
|
|
116
|
+
for (const kind of ['uid', 'gid']) {
|
|
117
|
+
const helper = mapping.helpers[kind], path = `/usr/bin/new${kind}map`;
|
|
118
|
+
if (!helper || !keys(helper, 'path,sha256') || helper.path !== path || !/^[0-9a-f]{64}$/u.test(helper.sha256))
|
|
119
|
+
fail('invalid mapping helper');
|
|
120
|
+
const info = await lstat(path);
|
|
121
|
+
if (!info.isFile() || info.isSymbolicLink() || info.nlink !== 1 || info.uid !== 0 || info.mode & 0o022
|
|
122
|
+
|| !(info.mode & 0o4000) || info.size > MAX_INPUT_BYTES || await realpath(path) !== path
|
|
123
|
+
|| createHash('sha256').update(await readFile(path)).digest('hex') !== helper.sha256)
|
|
124
|
+
fail('unsafe mapping helper');
|
|
125
|
+
}
|
|
126
|
+
// Legacy callers also import this core-only primitive directly as .ts in a
|
|
127
|
+
// fresh Node process. Resolve package helpers only for the new repository mode.
|
|
128
|
+
const { verifyLinuxSystemSnapshot } = await import('./linux-system-snapshot.js');
|
|
129
|
+
await verifyLinuxSystemSnapshot(input.systemSnapshot);
|
|
130
|
+
const root = input.systemSnapshot.root.path;
|
|
131
|
+
if (root === input.stateRoot || root.startsWith(input.stateRoot + sep) || input.stateRoot.startsWith(root + sep))
|
|
132
|
+
fail('snapshot overlaps private state');
|
|
133
|
+
input.signal.throwIfAborted();
|
|
134
|
+
}
|
|
135
|
+
function identity(value) {
|
|
136
|
+
if (!integer(value.pid, 1, Number.MAX_SAFE_INTEGER)
|
|
137
|
+
|| !integer(value.startTicks, 1, Number.MAX_SAFE_INTEGER))
|
|
138
|
+
fail('invalid candidate identity');
|
|
139
|
+
return { pid: value.pid, startTicks: value.startTicks };
|
|
140
|
+
}
|
|
141
|
+
/** A process primitive. The caller's afterExit/onStop implement cgroup proof. */
|
|
142
|
+
export async function runLinuxNamespace(input) {
|
|
143
|
+
const legacy = { ...input };
|
|
144
|
+
delete legacy.userNamespace;
|
|
145
|
+
delete legacy.systemSnapshot;
|
|
146
|
+
delete legacy.onUserNamespaceReady;
|
|
147
|
+
delete legacy.beforeCandidateExec;
|
|
148
|
+
return await runNamespace(legacy);
|
|
149
|
+
}
|
|
150
|
+
export async function runLinuxRepositoryNamespace(input) {
|
|
151
|
+
if (!input.archive || !(input.archive.bytes instanceof Uint8Array)
|
|
152
|
+
|| input.archive.bytes.byteLength < 1 || input.archive.bytes.byteLength > LINUX_REPOSITORY_INPUT_BYTES
|
|
153
|
+
|| !/^[0-9a-f]{64}$/u.test(input.archive.sha256)
|
|
154
|
+
|| createHash('sha256').update(input.archive.bytes).digest('hex') !== input.archive.sha256)
|
|
155
|
+
fail('invalid repository archive');
|
|
156
|
+
// Snapshot the caller-owned view before asynchronous admission or pipe writes.
|
|
157
|
+
const archive = { bytes: Buffer.from(input.archive.bytes), sha256: input.archive.sha256 };
|
|
158
|
+
const dual = input.userNamespace !== undefined || input.systemSnapshot !== undefined
|
|
159
|
+
|| input.onUserNamespaceReady !== undefined || input.beforeCandidateExec !== undefined;
|
|
160
|
+
const deadline = dual ? Date.now() + input.timeoutMs : undefined;
|
|
161
|
+
// Freeze mutable caller metadata before an asynchronous gate can replace it.
|
|
162
|
+
const frozen = dual ? structuredClone({ userNamespace: input.userNamespace, systemSnapshot: input.systemSnapshot }) : undefined;
|
|
163
|
+
const request = { ...input, ...frozen };
|
|
164
|
+
if (dual)
|
|
165
|
+
await validateUserNamespace(request);
|
|
166
|
+
return await runNamespace({ ...request, files: [], profile: 'repository',
|
|
167
|
+
maxArtifactBytes: input.maxArtifactBytes ?? LINUX_REPOSITORY_ARTIFACT_BYTES }, archive, deadline);
|
|
168
|
+
}
|
|
169
|
+
async function runNamespace(input, archive, absoluteDeadline) {
|
|
170
|
+
await validate(input, archive !== undefined);
|
|
171
|
+
const dual = input.userNamespace !== undefined;
|
|
172
|
+
const jobPath = join(input.stateRoot, `namespace-${input.namespaceId ?? randomUUID()}`);
|
|
173
|
+
await mkdir(jobPath, { mode: 0o700 });
|
|
174
|
+
const deadline = absoluteDeadline ?? Date.now() + input.timeoutMs;
|
|
175
|
+
const config = { schemaVersion: dual ? 3 : archive ? 2 : 1, ...(dual ? { userNamespace: input.userNamespace, systemSnapshot: input.systemSnapshot } : {}), ...(archive ? { archive: { size: archive.bytes.length, sha256: archive.sha256 } } : {}), jobPath, argv: input.argv, files: input.files,
|
|
176
|
+
artifacts: input.artifacts ?? [], readOnlyRoots: input.readOnlyRoots ?? [],
|
|
177
|
+
workspaceBytes: input.workspaceBytes, workspaceInodes: input.workspaceInodes,
|
|
178
|
+
tmpBytes: input.tmpBytes, tmpInodes: input.tmpInodes,
|
|
179
|
+
maxOutputBytes: input.maxOutputBytes, maxArtifactBytes: input.maxArtifactBytes ?? MAX_INPUT_BYTES, profile: input.profile, deadline };
|
|
180
|
+
const encoded = JSON.stringify(config);
|
|
181
|
+
if (Buffer.byteLength(encoded) > MAX_INPUT_BYTES + 300_000) {
|
|
182
|
+
await rm(jobPath, { recursive: true, force: true });
|
|
183
|
+
fail('request exceeds bound');
|
|
184
|
+
}
|
|
185
|
+
// The fixed shell owns this PID until exec. No namespace or worker exists
|
|
186
|
+
// until the caller durably admits its exact host identity through fd 3.
|
|
187
|
+
const child = spawn('/bin/sh', ['-c',
|
|
188
|
+
'IFS= read -r gate <&3 || exit 125; [ "$gate" = START ] || exit 125; exec 3<&-; exec "$@"',
|
|
189
|
+
'dsh-keeper-gate', ...(dual ? ['/usr/bin/python3', '-I', '-S', USERNS_LAUNCHER,
|
|
190
|
+
JSON.stringify(input.userNamespace), String(deadline), process.execPath, WORKER]
|
|
191
|
+
: ['/usr/bin/unshare', '--user', '--map-root-user', '--mount', '--fork',
|
|
192
|
+
'--kill-child=SIGKILL', '--net', '--ipc', '--uts', process.execPath, WORKER])], {
|
|
193
|
+
stdio: archive ? ['pipe', 'pipe', 'pipe', 'pipe', 'pipe', 'pipe'] : ['pipe', 'pipe', 'pipe', 'pipe'], shell: false, detached: true,
|
|
194
|
+
env: { PATH: '/usr/bin:/bin', LANG: 'C', LC_ALL: 'C' },
|
|
195
|
+
});
|
|
196
|
+
const messages = [];
|
|
197
|
+
const waiters = [];
|
|
198
|
+
let raw = '';
|
|
199
|
+
let totalBytes = 0;
|
|
200
|
+
let diagnostic = '';
|
|
201
|
+
let stopped = false;
|
|
202
|
+
let completed = false;
|
|
203
|
+
let reason = 'unknown';
|
|
204
|
+
let candidate;
|
|
205
|
+
let cleanup;
|
|
206
|
+
let cleanupError;
|
|
207
|
+
let signalStop = () => { };
|
|
208
|
+
const stopNotice = new Promise(resolveStop => { signalStop = resolveStop; });
|
|
209
|
+
const stop = (why) => {
|
|
210
|
+
if (stopped)
|
|
211
|
+
return;
|
|
212
|
+
// The worker can enforce the shared deadline before the Host timer gets a
|
|
213
|
+
// turn. Classify only the first observed stop; an earlier fault stays unknown.
|
|
214
|
+
reason = why === 'unknown' && Date.now() >= deadline ? 'timed-out' : why;
|
|
215
|
+
stopped = true;
|
|
216
|
+
signalStop();
|
|
217
|
+
cleanup = new Promise(resolveCleanup => {
|
|
218
|
+
let settled = false;
|
|
219
|
+
const finish = (cause) => {
|
|
220
|
+
if (settled)
|
|
221
|
+
return;
|
|
222
|
+
settled = true;
|
|
223
|
+
clearTimeout(cleanupTimer);
|
|
224
|
+
if (cause !== undefined)
|
|
225
|
+
cleanupError = cause instanceof Error ? cause : new Error('cleanup failed');
|
|
226
|
+
resolveCleanup();
|
|
227
|
+
};
|
|
228
|
+
const cleanupTimer = setTimeout(() => finish(new Error('cgroup cleanup exceeded deadline')), CLEANUP_TIMEOUT_MS);
|
|
229
|
+
void Promise.resolve().then(() => input.onStop(candidate)).then(() => finish(), finish);
|
|
230
|
+
});
|
|
231
|
+
if (child.pid !== undefined) {
|
|
232
|
+
try {
|
|
233
|
+
process.kill(-child.pid, 'SIGKILL');
|
|
234
|
+
}
|
|
235
|
+
catch (error) {
|
|
236
|
+
if (error.code !== 'ESRCH')
|
|
237
|
+
throw error;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
child.kill('SIGKILL');
|
|
241
|
+
};
|
|
242
|
+
const archivePipe = child.stdio[4];
|
|
243
|
+
const artifactPipe = child.stdio[5];
|
|
244
|
+
archivePipe?.on('error', () => stop('unknown'));
|
|
245
|
+
let exporting = false;
|
|
246
|
+
let binaryBytes = 0;
|
|
247
|
+
const binaryChunks = [];
|
|
248
|
+
const binaryDone = new Promise(resolveBinary => {
|
|
249
|
+
if (!artifactPipe) {
|
|
250
|
+
resolveBinary();
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
artifactPipe.on('data', (chunk) => {
|
|
254
|
+
binaryBytes += chunk.length;
|
|
255
|
+
if (!exporting || binaryBytes > (input.maxArtifactBytes ?? MAX_INPUT_BYTES)) {
|
|
256
|
+
stop('unknown');
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
binaryChunks.push(chunk);
|
|
260
|
+
});
|
|
261
|
+
artifactPipe.once('end', resolveBinary);
|
|
262
|
+
artifactPipe.once('error', () => { stop('unknown'); resolveBinary(); });
|
|
263
|
+
artifactPipe.once('close', resolveBinary);
|
|
264
|
+
});
|
|
265
|
+
let archiveSent;
|
|
266
|
+
const timer = setTimeout(() => stop('timed-out'), Math.max(1, deadline - Date.now()));
|
|
267
|
+
const assertLive = () => {
|
|
268
|
+
if (Date.now() >= deadline)
|
|
269
|
+
stop('timed-out');
|
|
270
|
+
if (stopped)
|
|
271
|
+
fail('execution stopped');
|
|
272
|
+
};
|
|
273
|
+
// A worker can disappear between protocol observation and write(). Writable
|
|
274
|
+
// errors are independent of ChildProcess 'error' and must revoke the job.
|
|
275
|
+
child.stdin?.on('error', () => stop('unknown'));
|
|
276
|
+
const keeperGate = child.stdio[3];
|
|
277
|
+
keeperGate?.on('error', () => stop('unknown'));
|
|
278
|
+
const abort = () => stop('cancelled');
|
|
279
|
+
input.signal.addEventListener('abort', abort, { once: true });
|
|
280
|
+
if (input.signal.aborted)
|
|
281
|
+
abort();
|
|
282
|
+
const closed = new Promise(resolveDone => {
|
|
283
|
+
child.once('error', error => resolveDone({ code: null, signal: null, error }));
|
|
284
|
+
child.once('close', (code, signal) => { completed = true; resolveDone({ code, signal }); });
|
|
285
|
+
});
|
|
286
|
+
let boundedClosure;
|
|
287
|
+
const waitForClosure = () => boundedClosure ??= new Promise(resolveClosure => {
|
|
288
|
+
const deadline = setTimeout(resolveClosure, CLEANUP_TIMEOUT_MS);
|
|
289
|
+
void closed.then(() => { clearTimeout(deadline); resolveClosure(); });
|
|
290
|
+
});
|
|
291
|
+
const interrupted = () => stopNotice.then(() => fail('execution stopped'));
|
|
292
|
+
const decoder = new StringDecoder('utf8');
|
|
293
|
+
child.stdout?.on('data', (chunk) => {
|
|
294
|
+
totalBytes += chunk.length;
|
|
295
|
+
if (totalBytes > MAX_PROTOCOL_BYTES) {
|
|
296
|
+
stop('unknown');
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
raw += decoder.write(chunk);
|
|
300
|
+
for (;;) {
|
|
301
|
+
const end = raw.indexOf('\n');
|
|
302
|
+
if (end < 0)
|
|
303
|
+
break;
|
|
304
|
+
const line = raw.slice(0, end);
|
|
305
|
+
raw = raw.slice(end + 1);
|
|
306
|
+
let message;
|
|
307
|
+
try {
|
|
308
|
+
message = JSON.parse(line);
|
|
309
|
+
}
|
|
310
|
+
catch {
|
|
311
|
+
stop('unknown');
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
if (!message || typeof message.type !== 'string') {
|
|
315
|
+
stop('unknown');
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
const waiter = waiters.shift();
|
|
319
|
+
if (waiter)
|
|
320
|
+
waiter(message);
|
|
321
|
+
else
|
|
322
|
+
messages.push(message);
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
child.stderr?.on('data', (chunk) => { diagnostic = (diagnostic + chunk.toString('utf8')).slice(-4096); });
|
|
326
|
+
const next = async () => {
|
|
327
|
+
assertLive();
|
|
328
|
+
if (messages.length)
|
|
329
|
+
return messages.shift();
|
|
330
|
+
return await Promise.race([new Promise(resolveNext => waiters.push(resolveNext)),
|
|
331
|
+
closed.then(() => fail('worker exited before protocol completed')), interrupted()]);
|
|
332
|
+
};
|
|
333
|
+
const send = (message) => {
|
|
334
|
+
assertLive();
|
|
335
|
+
child.stdin?.write(message + '\n');
|
|
336
|
+
};
|
|
337
|
+
try {
|
|
338
|
+
send(encoded);
|
|
339
|
+
if (!child.pid)
|
|
340
|
+
fail('keeper gate did not start');
|
|
341
|
+
const stat = await readFile(`/proc/${child.pid}/stat`, 'utf8');
|
|
342
|
+
const keeper = identity({ type: 'KEEPER', pid: child.pid,
|
|
343
|
+
startTicks: Number(stat.slice(stat.lastIndexOf(')') + 2).trim().split(' ')[19]) });
|
|
344
|
+
assertLive();
|
|
345
|
+
await Promise.race([Promise.resolve().then(() => { assertLive(); return input.beforeKeeperStart(keeper); }),
|
|
346
|
+
closed.then(() => fail('keeper exited during admission')), interrupted()]);
|
|
347
|
+
assertLive();
|
|
348
|
+
keeperGate?.end('START\n');
|
|
349
|
+
if (archive && archivePipe) {
|
|
350
|
+
archiveSent = new Promise(resolveSent => {
|
|
351
|
+
// One bounded buffer is queued; the stream owns backpressure until EOF.
|
|
352
|
+
archivePipe.end(archive.bytes, resolveSent);
|
|
353
|
+
archivePipe.once('close', resolveSent);
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
if (dual) {
|
|
357
|
+
const namespace = await next();
|
|
358
|
+
if (namespace.type !== 'NAMESPACE_READY')
|
|
359
|
+
fail(`keeper namespace was not observed: ${String(namespace.reason ?? diagnostic)}`);
|
|
360
|
+
const keeperIdentity = identity(namespace);
|
|
361
|
+
await Promise.race([Promise.resolve().then(() => { assertLive(); return input.onUserNamespaceReady(keeperIdentity); }),
|
|
362
|
+
closed.then(() => fail('keeper exited during namespace binding')), interrupted()]);
|
|
363
|
+
assertLive();
|
|
364
|
+
send('NAMESPACE_ACK');
|
|
365
|
+
}
|
|
366
|
+
const ready = await next();
|
|
367
|
+
if (ready.type !== 'READY')
|
|
368
|
+
fail('worker failed before candidate gate');
|
|
369
|
+
candidate = identity(ready);
|
|
370
|
+
await Promise.race([Promise.resolve().then(() => { assertLive(); return input.beforeStart(candidate); }),
|
|
371
|
+
closed.then(() => fail('worker exited during admission')), interrupted()]);
|
|
372
|
+
assertLive();
|
|
373
|
+
send('START');
|
|
374
|
+
if (dual) {
|
|
375
|
+
const entry = await next();
|
|
376
|
+
if (entry.type !== 'CANDIDATE_READY')
|
|
377
|
+
fail(`candidate privilege gate missing: ${String(entry.reason ?? diagnostic)}`);
|
|
378
|
+
const entryIdentity = identity(entry);
|
|
379
|
+
await Promise.race([Promise.resolve().then(() => { assertLive(); return input.beforeCandidateExec(entryIdentity); }),
|
|
380
|
+
closed.then(() => fail('worker exited during candidate binding')), interrupted()]);
|
|
381
|
+
assertLive();
|
|
382
|
+
send('CANDIDATE_START');
|
|
383
|
+
}
|
|
384
|
+
const exited = await next();
|
|
385
|
+
if (exited.type !== 'EXIT' || exited.pid !== candidate.pid || exited.startTicks !== candidate.startTicks
|
|
386
|
+
|| !(exited.code === null || integer(exited.code, 0, 255))
|
|
387
|
+
|| !(exited.signal === null || typeof exited.signal === 'string')
|
|
388
|
+
|| typeof exited.exceeded !== 'boolean')
|
|
389
|
+
fail('invalid candidate exit');
|
|
390
|
+
await Promise.race([Promise.resolve().then(() => { assertLive(); return input.afterExit(exited); }),
|
|
391
|
+
closed.then(() => fail('worker exited before cgroup proof')), interrupted()]);
|
|
392
|
+
assertLive();
|
|
393
|
+
exporting = true;
|
|
394
|
+
send('EXPORT');
|
|
395
|
+
const result = await next();
|
|
396
|
+
if (result.type !== 'RESULT' || !['succeeded', 'failed'].includes(result.status)
|
|
397
|
+
|| !Array.isArray(result.artifacts) || typeof result.stdout !== 'string' || typeof result.stderr !== 'string'
|
|
398
|
+
|| Buffer.byteLength(result.stdout) + Buffer.byteLength(result.stderr) > input.maxOutputBytes
|
|
399
|
+
|| (archive ? result.status === 'succeeded' && result.artifacts.length !== (input.artifacts?.length ?? 0)
|
|
400
|
+
|| result.status !== 'succeeded' && result.artifacts.length !== 0
|
|
401
|
+
: result.artifacts.length !== (input.artifacts?.length ?? 0))
|
|
402
|
+
|| new Set(result.artifacts.map(file => file?.path)).size !== result.artifacts.length
|
|
403
|
+
|| result.artifacts.some(file => !file || !safePath(file.path) || !(input.artifacts ?? []).includes(file.path)
|
|
404
|
+
|| (archive ? !integer(file.size, 0, input.maxArtifactBytes ?? LINUX_REPOSITORY_ARTIFACT_BYTES)
|
|
405
|
+
|| typeof file.sha256 !== 'string' || !/^[0-9a-f]{64}$/u.test(file.sha256)
|
|
406
|
+
: typeof file.content !== 'string' || !file.content.isWellFormed()))
|
|
407
|
+
|| result.artifacts.reduce((bytes, file) => bytes + (archive ? file.size : Buffer.byteLength(file.content)), 0)
|
|
408
|
+
> (input.maxArtifactBytes ?? MAX_INPUT_BYTES)) {
|
|
409
|
+
fail('worker result violates bounds');
|
|
410
|
+
}
|
|
411
|
+
let artifacts;
|
|
412
|
+
if (archive) {
|
|
413
|
+
await Promise.race([binaryDone, interrupted()]);
|
|
414
|
+
if (!artifactPipe?.readableEnded || binaryBytes !== result.artifacts.reduce((size, file) => size + file.size, 0)) {
|
|
415
|
+
fail('binary artifact length or EOF mismatch');
|
|
416
|
+
}
|
|
417
|
+
const bytes = Buffer.concat(binaryChunks, binaryBytes);
|
|
418
|
+
let offset = 0;
|
|
419
|
+
artifacts = result.artifacts.map(file => {
|
|
420
|
+
const content = bytes.subarray(offset, offset += file.size);
|
|
421
|
+
if (createHash('sha256').update(content).digest('hex') !== file.sha256)
|
|
422
|
+
fail('binary artifact digest mismatch');
|
|
423
|
+
return { path: file.path, bytes: content, sha256: file.sha256 };
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
else
|
|
427
|
+
artifacts = result.artifacts;
|
|
428
|
+
child.stdin?.end();
|
|
429
|
+
const done = await Promise.race([closed, interrupted()]);
|
|
430
|
+
if (done.code !== 0 || stopped || raw !== '')
|
|
431
|
+
fail('worker did not exit cleanly');
|
|
432
|
+
assertLive();
|
|
433
|
+
return { status: result.status, namespaceExited: true,
|
|
434
|
+
...(typeof result.exitCode === 'number' ? { exitCode: result.exitCode } : {}),
|
|
435
|
+
stdout: result.stdout, stderr: result.stderr,
|
|
436
|
+
artifacts,
|
|
437
|
+
...(typeof result.reason === 'string' ? { reason: result.reason } : {}) };
|
|
438
|
+
}
|
|
439
|
+
catch (error) {
|
|
440
|
+
if (!stopped)
|
|
441
|
+
stop('unknown');
|
|
442
|
+
await waitForClosure();
|
|
443
|
+
if (cleanup)
|
|
444
|
+
await cleanup.catch(cause => {
|
|
445
|
+
cleanupError = cause instanceof Error ? cause : new Error('cleanup failed');
|
|
446
|
+
});
|
|
447
|
+
return { status: cleanupError || !completed ? 'unknown' : reason, namespaceExited: completed,
|
|
448
|
+
stdout: '', stderr: '', artifacts: [],
|
|
449
|
+
reason: `${error instanceof Error ? error.message : diagnostic || 'namespace execution failed'}`
|
|
450
|
+
+ (cleanupError ? `; cleanup unproven: ${cleanupError.message}` : '')
|
|
451
|
+
+ (!completed ? '; worker termination unproven' : '') };
|
|
452
|
+
}
|
|
453
|
+
finally {
|
|
454
|
+
clearTimeout(timer);
|
|
455
|
+
input.signal.removeEventListener('abort', abort);
|
|
456
|
+
if (!completed)
|
|
457
|
+
stop('unknown');
|
|
458
|
+
await waitForClosure();
|
|
459
|
+
if (cleanup)
|
|
460
|
+
await cleanup.catch(cause => {
|
|
461
|
+
cleanupError = cause instanceof Error ? cause : new Error('cleanup failed');
|
|
462
|
+
});
|
|
463
|
+
archivePipe?.destroy();
|
|
464
|
+
artifactPipe?.destroy();
|
|
465
|
+
if (archiveSent)
|
|
466
|
+
await archiveSent;
|
|
467
|
+
if (!cleanupError && completed)
|
|
468
|
+
await rm(jobPath, { recursive: true, force: true });
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
//# sourceMappingURL=linux-namespace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linux-namespace.js","sourceRoot":"","sources":["../src/linux-namespace.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { IsolationControllerAuthority } from './ledger.js';
|
|
2
|
+
import type { LinuxRepositoryRunnerRequest } from './linux-repository-runner.js';
|
|
3
|
+
interface LedgerBinding {
|
|
4
|
+
ledger: object;
|
|
5
|
+
key: string;
|
|
6
|
+
requestDigest: string;
|
|
7
|
+
authority: IsolationControllerAuthority;
|
|
8
|
+
}
|
|
9
|
+
export declare function withLinuxLedgerAdmissionAttempt<T>(ledger: object, attempt: object, operation: () => T): T;
|
|
10
|
+
/** Internal: only prepare's explicitly rejected, successfully rolled-back transaction may mark its error. */
|
|
11
|
+
export declare function markLinuxLedgerAdmissionRefusal(error: object, binding: LedgerBinding): void;
|
|
12
|
+
export declare function consumeLinuxLedgerAdmissionRefusal(error: unknown, binding: LedgerBinding & {
|
|
13
|
+
attempt: object;
|
|
14
|
+
}): boolean;
|
|
15
|
+
interface RunnerBinding {
|
|
16
|
+
runner: object;
|
|
17
|
+
key: string;
|
|
18
|
+
request: LinuxRepositoryRunnerRequest;
|
|
19
|
+
current: () => boolean;
|
|
20
|
+
}
|
|
21
|
+
/** Internal: this error is a statement about one completed call, never missing historical state. */
|
|
22
|
+
export declare function linuxRepositoryAdmissionRefusal(cause: unknown, binding: RunnerBinding): Error;
|
|
23
|
+
/** Host-only, single-use proof. JSON, arbitrary errors, another runner/request or a stale controller cannot qualify. */
|
|
24
|
+
export declare function consumeLinuxRepositoryAdmissionRefusal(error: unknown, runner: object, key: string, request: LinuxRepositoryRunnerRequest): boolean;
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=linux-repository-admission.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linux-repository-admission.d.ts","sourceRoot":"","sources":["../src/linux-repository-admission.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAA;AAC/D,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,8BAA8B,CAAA;AAEhF,UAAU,aAAa;IACrB,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,aAAa,EAAE,MAAM,CAAA;IACrB,SAAS,EAAE,4BAA4B,CAAA;CACxC;AAGD,wBAAgB,+BAA+B,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,CAIzG;AAGD,6GAA6G;AAC7G,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,IAAI,CAG3F;AACD,wBAAgB,kCAAkC,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAOxH;AAMD,UAAU,aAAa;IACrB,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,4BAA4B,CAAA;IACrC,OAAO,EAAE,MAAM,OAAO,CAAA;CACvB;AAED,oGAAoG;AACpG,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,GAAG,KAAK,CAI7F;AACD,wHAAwH;AACxH,wBAAgB,sCAAsC,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,4BAA4B,GAAG,OAAO,CAOlJ"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
const ledgerRefusals = new WeakMap();
|
|
2
|
+
const ledgerAttempts = new WeakMap();
|
|
3
|
+
export function withLinuxLedgerAdmissionAttempt(ledger, attempt, operation) {
|
|
4
|
+
const previous = ledgerAttempts.get(ledger);
|
|
5
|
+
ledgerAttempts.set(ledger, attempt);
|
|
6
|
+
try {
|
|
7
|
+
return operation();
|
|
8
|
+
}
|
|
9
|
+
finally {
|
|
10
|
+
if (previous)
|
|
11
|
+
ledgerAttempts.set(ledger, previous);
|
|
12
|
+
else
|
|
13
|
+
ledgerAttempts.delete(ledger);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
const sameAuthority = (a, b) => a.ownerId === b.ownerId && a.fence === b.fence;
|
|
17
|
+
/** Internal: only prepare's explicitly rejected, successfully rolled-back transaction may mark its error. */
|
|
18
|
+
export function markLinuxLedgerAdmissionRefusal(error, binding) {
|
|
19
|
+
const attempt = ledgerAttempts.get(binding.ledger);
|
|
20
|
+
if (attempt)
|
|
21
|
+
ledgerRefusals.set(error, { ...binding, attempt, authority: { ...binding.authority } });
|
|
22
|
+
}
|
|
23
|
+
export function consumeLinuxLedgerAdmissionRefusal(error, binding) {
|
|
24
|
+
if (!error || typeof error !== 'object')
|
|
25
|
+
return false;
|
|
26
|
+
const proof = ledgerRefusals.get(error);
|
|
27
|
+
if (!proof || proof.ledger !== binding.ledger || proof.key !== binding.key || proof.requestDigest !== binding.requestDigest
|
|
28
|
+
|| !sameAuthority(proof.authority, binding.authority) || proof.attempt !== binding.attempt)
|
|
29
|
+
return false;
|
|
30
|
+
ledgerRefusals.delete(error);
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
function canonical(value) {
|
|
34
|
+
if (Array.isArray(value))
|
|
35
|
+
return `[${value.map(canonical).join(',')}]`;
|
|
36
|
+
if (value && typeof value === 'object')
|
|
37
|
+
return `{${Object.keys(value).sort().map(key => `${JSON.stringify(key)}:${canonical(value[key])}`).join(',')}}`;
|
|
38
|
+
return JSON.stringify(value);
|
|
39
|
+
}
|
|
40
|
+
const runnerRefusals = new WeakMap();
|
|
41
|
+
/** Internal: this error is a statement about one completed call, never missing historical state. */
|
|
42
|
+
export function linuxRepositoryAdmissionRefusal(cause, binding) {
|
|
43
|
+
const error = new Error(cause instanceof Error ? cause.message : 'Linux repository admission refused', { cause });
|
|
44
|
+
runnerRefusals.set(error, { ...binding, request: canonical(binding.request) });
|
|
45
|
+
return error;
|
|
46
|
+
}
|
|
47
|
+
/** Host-only, single-use proof. JSON, arbitrary errors, another runner/request or a stale controller cannot qualify. */
|
|
48
|
+
export function consumeLinuxRepositoryAdmissionRefusal(error, runner, key, request) {
|
|
49
|
+
if (!error || typeof error !== 'object')
|
|
50
|
+
return false;
|
|
51
|
+
const proof = runnerRefusals.get(error);
|
|
52
|
+
if (!proof || proof.runner !== runner || proof.key !== key || proof.request !== canonical(request))
|
|
53
|
+
return false;
|
|
54
|
+
try {
|
|
55
|
+
if (!proof.current())
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
runnerRefusals.delete(error);
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=linux-repository-admission.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linux-repository-admission.js","sourceRoot":"","sources":["../src/linux-repository-admission.ts"],"names":[],"mappings":"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"}
|