@ai-ecoverse/slicc-kernel 1.125.0 → 1.125.2
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 +12 -3
- package/dist/kernel-worker.js +219 -81
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-process-worker.js +130 -66
- package/dist/node-process-worker.js.map +3 -3
- package/dist/node.js +222 -84
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +130 -66
- package/dist/process-worker.js.map +3 -3
- package/dist/types/kernel/net/tls-chain.d.ts +2 -0
- package/dist/types/kernel/net/tls-client.d.ts +1 -0
- package/dist/types/kernel/net/tls-engine.d.ts +2 -1
- package/dist/types/kernel/net/tls-uplink.d.ts +1 -0
- package/dist/types/process/js/js-net.d.ts +1 -0
- package/dist/types/process/js/js-sync.d.ts +2 -1
- package/dist/types/process/wasi/wasi-fds.d.ts +3 -0
- package/dist/types/realm/sync-fs-token-registry.d.ts +3 -0
- package/dist/types/realm/sync-fs-wire.d.ts +7 -1
- package/dist/types/realm/sync-sab-bridge.d.ts +1 -0
- package/package.json +2 -2
package/dist/node.js
CHANGED
|
@@ -397,11 +397,11 @@ var Perms = class {
|
|
|
397
397
|
this.fs = fs;
|
|
398
398
|
}
|
|
399
399
|
async learn(path) {
|
|
400
|
-
const
|
|
400
|
+
const names2 = chain(path);
|
|
401
401
|
const perms = await ancestryOf(this.fs, path);
|
|
402
|
-
for (let i = 0; i <
|
|
402
|
+
for (let i = 0; i < names2.length; i++) {
|
|
403
403
|
const perm = perms[i];
|
|
404
|
-
this.known.set(
|
|
404
|
+
this.known.set(names2[i], perm);
|
|
405
405
|
if (perm === void 0 || perm.link !== void 0) break;
|
|
406
406
|
}
|
|
407
407
|
}
|
|
@@ -2852,8 +2852,8 @@ function userEnv(account, system) {
|
|
|
2852
2852
|
PATH: `${pnpm}/bin:/usr/local/bin:/usr/bin:/bin`
|
|
2853
2853
|
};
|
|
2854
2854
|
}
|
|
2855
|
-
function groupsOf(groups,
|
|
2856
|
-
return
|
|
2855
|
+
function groupsOf(groups, names2) {
|
|
2856
|
+
return names2.map((g) => {
|
|
2857
2857
|
const row = groups.find((r) => r.name === g);
|
|
2858
2858
|
if (!row) throw fsError("ENOENT", `no group ${g}`);
|
|
2859
2859
|
return row;
|
|
@@ -3804,9 +3804,9 @@ var Integrity = class {
|
|
|
3804
3804
|
const at = normalizePath(path);
|
|
3805
3805
|
const real = known ?? await this.root.realpath?.(at, true).catch(() => void 0) ?? at;
|
|
3806
3806
|
if (isProtected(this.prefixes, real)) return { real, name: real };
|
|
3807
|
-
const
|
|
3808
|
-
if (real !== at)
|
|
3809
|
-
const name2 =
|
|
3807
|
+
const names2 = asked === void 0 ? [] : await namesOf(this.root, asked);
|
|
3808
|
+
if (real !== at) names2.push(...await namesOf(this.root, at));
|
|
3809
|
+
const name2 = names2.findLast((p) => isProtected(this.prefixes, p));
|
|
3810
3810
|
return name2 === void 0 ? void 0 : { real, name: name2 };
|
|
3811
3811
|
}
|
|
3812
3812
|
async key(path, asked) {
|
|
@@ -4381,8 +4381,8 @@ function sidecar(meta) {
|
|
|
4381
4381
|
const guarded3 = (op) => (...args) => meta[op].apply(meta, args).catch((err) => {
|
|
4382
4382
|
throw translate(err, pathOf(args), "sidecar", false);
|
|
4383
4383
|
});
|
|
4384
|
-
const
|
|
4385
|
-
const ops = Object.fromEntries(
|
|
4384
|
+
const names2 = meta.fresh ? [...META_OPS, "fresh"] : META_OPS;
|
|
4385
|
+
const ops = Object.fromEntries(names2.map((op) => [op, guarded3(op)]));
|
|
4386
4386
|
const { updateMany } = meta;
|
|
4387
4387
|
ops.updateMany = updateMany ? (changes) => updateMany.call(meta, changes).catch((err) => {
|
|
4388
4388
|
throw translate(err, changes[0]?.path ?? "/", "sidecar", false);
|
|
@@ -5737,11 +5737,11 @@ var WRITES = [
|
|
|
5737
5737
|
"lutimes",
|
|
5738
5738
|
"chown"
|
|
5739
5739
|
];
|
|
5740
|
-
for (const [
|
|
5740
|
+
for (const [names2, op] of [
|
|
5741
5741
|
[READS, "read"],
|
|
5742
5742
|
[WRITES, "write"]
|
|
5743
5743
|
]) {
|
|
5744
|
-
for (const name2 of
|
|
5744
|
+
for (const name2 of names2) {
|
|
5745
5745
|
const proto = OpfsFs.prototype;
|
|
5746
5746
|
const inner = proto[name2];
|
|
5747
5747
|
proto[name2] = async function(...args) {
|
|
@@ -5893,7 +5893,7 @@ var UnlinkedKeeper = class {
|
|
|
5893
5893
|
[name2]: (path, ...rest2) => unreplaced(path, () => call.call(fs, path, ...rest2))
|
|
5894
5894
|
};
|
|
5895
5895
|
};
|
|
5896
|
-
const visible = (
|
|
5896
|
+
const visible = (names2) => names2.filter((name2) => name2 !== UNLINKED_DIR);
|
|
5897
5897
|
const counted3 = (st) => {
|
|
5898
5898
|
const hidden = keeper.links.get(`${st.dev ?? 0}:${st.ino}`) ?? 0;
|
|
5899
5899
|
return hidden === 0 || st.nlink === void 0 ? st : { ...st, nlink: Math.max(0, st.nlink - hidden) };
|
|
@@ -6112,10 +6112,10 @@ var UnlinkedKeeper = class {
|
|
|
6112
6112
|
if (!query && !owner) return Promise.resolve();
|
|
6113
6113
|
return this.serial(async () => {
|
|
6114
6114
|
const dir = dirOf(root);
|
|
6115
|
-
const
|
|
6116
|
-
if (!
|
|
6115
|
+
const names2 = await this.fs.readdir(dir).catch(() => void 0);
|
|
6116
|
+
if (!names2) return;
|
|
6117
6117
|
const held = query && new Set(((await query()).held ?? []).map((lock) => lock.name));
|
|
6118
|
-
for (const name2 of
|
|
6118
|
+
for (const name2 of names2) {
|
|
6119
6119
|
const id2 = name2.slice(0, name2.lastIndexOf("."));
|
|
6120
6120
|
const at = id2.indexOf("~");
|
|
6121
6121
|
const dead = id2 !== this.instance && (at < 0 ? held !== void 0 && !held.has(lockName(id2)) : owner?.alive(id2.slice(0, at)) === false);
|
|
@@ -7086,7 +7086,7 @@ function satisfies(version, range2) {
|
|
|
7086
7086
|
}
|
|
7087
7087
|
|
|
7088
7088
|
// src/version.ts
|
|
7089
|
-
var KERNEL_VERSION = true ? "1.125.
|
|
7089
|
+
var KERNEL_VERSION = true ? "1.125.2" : "0.0.0-dev";
|
|
7090
7090
|
var OS_RELEASE = "6.0.0-slicc";
|
|
7091
7091
|
function procVersion() {
|
|
7092
7092
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -7241,9 +7241,9 @@ async function withPackagePaths(fs, pkg, command) {
|
|
|
7241
7241
|
return { ...command, env };
|
|
7242
7242
|
}
|
|
7243
7243
|
async function packages(fs, modules) {
|
|
7244
|
-
const
|
|
7244
|
+
const names2 = await fs.readdir(modules).catch(() => []);
|
|
7245
7245
|
const packageNames = [];
|
|
7246
|
-
for (const name2 of
|
|
7246
|
+
for (const name2 of names2) {
|
|
7247
7247
|
if (name2.startsWith(".")) continue;
|
|
7248
7248
|
if (!name2.startsWith("@")) {
|
|
7249
7249
|
packageNames.push(name2);
|
|
@@ -8102,11 +8102,11 @@ var CronService = class {
|
|
|
8102
8102
|
const account = await this.host.lookup(job.user);
|
|
8103
8103
|
if (account) out.push({ source: "system", account, job });
|
|
8104
8104
|
}
|
|
8105
|
-
const
|
|
8105
|
+
const names2 = await fs.readdir(SPOOL_DIR).catch((err) => {
|
|
8106
8106
|
if (err?.code === "ENOENT") return [];
|
|
8107
8107
|
throw err;
|
|
8108
8108
|
});
|
|
8109
|
-
for (const name2 of
|
|
8109
|
+
for (const name2 of names2.sort()) {
|
|
8110
8110
|
if (name2.startsWith(".") || name2.endsWith("~")) continue;
|
|
8111
8111
|
const path = `${SPOOL_DIR}/${name2}`;
|
|
8112
8112
|
const account = await this.host.lookup(name2);
|
|
@@ -9131,6 +9131,37 @@ var FileChanges = class {
|
|
|
9131
9131
|
}
|
|
9132
9132
|
}
|
|
9133
9133
|
};
|
|
9134
|
+
var ChangeView = class {
|
|
9135
|
+
view;
|
|
9136
|
+
constructor(sab) {
|
|
9137
|
+
this.view = new Int32Array(sab);
|
|
9138
|
+
}
|
|
9139
|
+
now() {
|
|
9140
|
+
return Atomics.load(this.view, GEN);
|
|
9141
|
+
}
|
|
9142
|
+
clean() {
|
|
9143
|
+
return this.view.length > DIRTY && Atomics.load(this.view, DIRTY) === 0;
|
|
9144
|
+
}
|
|
9145
|
+
foreign() {
|
|
9146
|
+
return this.view.length > FOREIGN && Atomics.load(this.view, FOREIGN) === 1;
|
|
9147
|
+
}
|
|
9148
|
+
changedSince(seen, path) {
|
|
9149
|
+
const now = Atomics.load(this.view, GEN);
|
|
9150
|
+
const distance = now - seen >>> 0;
|
|
9151
|
+
if (distance === 0) return { now, changed: false };
|
|
9152
|
+
if (distance > RING_SIZE) return { now, changed: true };
|
|
9153
|
+
const hash = changeHash(normal(path));
|
|
9154
|
+
for (let i = 1; i <= distance; i++) {
|
|
9155
|
+
const g = seen + i | 0;
|
|
9156
|
+
const at = RING + (g & RING_SIZE - 1) * SLOT;
|
|
9157
|
+
if (Atomics.load(this.view, at) !== g) return { now, changed: true };
|
|
9158
|
+
const hit = Atomics.load(this.view, at + 1) === hash;
|
|
9159
|
+
if (Atomics.load(this.view, at) !== g) return { now, changed: true };
|
|
9160
|
+
if (hit) return { now, changed: true };
|
|
9161
|
+
}
|
|
9162
|
+
return { now, changed: false };
|
|
9163
|
+
}
|
|
9164
|
+
};
|
|
9134
9165
|
|
|
9135
9166
|
// src/fs/commands.ts
|
|
9136
9167
|
var S_IFDIR2 = 16384;
|
|
@@ -9178,7 +9209,7 @@ async function shownTarget(fs, target) {
|
|
|
9178
9209
|
const st = await quiet2(fs.stat(target));
|
|
9179
9210
|
return st?.isFile && await readsAs2(fs, NOBODY, target) ? st : void 0;
|
|
9180
9211
|
}
|
|
9181
|
-
function withCommandDirs(fs,
|
|
9212
|
+
function withCommandDirs(fs, names2, userDir = async () => void 0, owners = false, targetOf2 = async () => void 0) {
|
|
9182
9213
|
async function nearest(path) {
|
|
9183
9214
|
const st = await fs.stat(path).catch(() => void 0);
|
|
9184
9215
|
if (st || path === "/") return st ?? {};
|
|
@@ -9192,7 +9223,7 @@ function withCommandDirs(fs, names, userDir = async () => void 0, owners = false
|
|
|
9192
9223
|
async function children2(path) {
|
|
9193
9224
|
if (path === "/") return ["bin", "usr"];
|
|
9194
9225
|
if (path === "/usr") return ["bin"];
|
|
9195
|
-
if (path === "/bin" || path === "/usr/bin") return [...await
|
|
9226
|
+
if (path === "/bin" || path === "/usr/bin") return [...await names2()];
|
|
9196
9227
|
const own = await userDir(path);
|
|
9197
9228
|
return own?.size ? [...own] : void 0;
|
|
9198
9229
|
}
|
|
@@ -9202,7 +9233,7 @@ function withCommandDirs(fs, names, userDir = async () => void 0, owners = false
|
|
|
9202
9233
|
}
|
|
9203
9234
|
const name2 = COMMAND.exec(path)?.[1];
|
|
9204
9235
|
if (name2 !== void 0) {
|
|
9205
|
-
return (await
|
|
9236
|
+
return (await names2()).has(name2) ? owned4(synthetic(false, path)) : void 0;
|
|
9206
9237
|
}
|
|
9207
9238
|
if ((await userDir(path))?.size) return owned4(synthetic(true, path), path);
|
|
9208
9239
|
const slash = path.lastIndexOf("/");
|
|
@@ -9213,7 +9244,7 @@ function withCommandDirs(fs, names, userDir = async () => void 0, owners = false
|
|
|
9213
9244
|
let generation;
|
|
9214
9245
|
const targets = /* @__PURE__ */ new Map();
|
|
9215
9246
|
async function targetStat(target) {
|
|
9216
|
-
const now = await
|
|
9247
|
+
const now = await names2();
|
|
9217
9248
|
if (now !== generation) {
|
|
9218
9249
|
generation = now;
|
|
9219
9250
|
targets.clear();
|
|
@@ -9722,12 +9753,12 @@ var FsWatchers = class {
|
|
|
9722
9753
|
writeFile: content(fs.writeFile.bind(fs), written2),
|
|
9723
9754
|
...fs.createExclusive ? { createExclusive: content(fs.createExclusive.bind(fs), () => ["rename"]) } : {},
|
|
9724
9755
|
mkdir: async (path, options) => {
|
|
9725
|
-
const
|
|
9756
|
+
const created4 = [];
|
|
9726
9757
|
if (options?.recursive) {
|
|
9727
9758
|
const parts2 = normalizePath(path).split("/").filter(Boolean);
|
|
9728
9759
|
for (let at = 1; at < parts2.length; at++) {
|
|
9729
9760
|
const ancestor = `/${parts2.slice(0, at).join("/")}`;
|
|
9730
|
-
if (
|
|
9761
|
+
if (created4.length > 0 || !await fs.exists(ancestor)) created4.push(ancestor);
|
|
9731
9762
|
}
|
|
9732
9763
|
}
|
|
9733
9764
|
const fresh2 = !options?.recursive || !(this.covers(path) && await fs.exists(path));
|
|
@@ -9736,8 +9767,8 @@ var FsWatchers = class {
|
|
|
9736
9767
|
await fs.mkdir(path, options);
|
|
9737
9768
|
done4 = true;
|
|
9738
9769
|
} finally {
|
|
9739
|
-
this.report([...
|
|
9740
|
-
if (done4) this.emit("rename", fresh2 ? [...
|
|
9770
|
+
this.report([...created4, path]);
|
|
9771
|
+
if (done4) this.emit("rename", fresh2 ? [...created4, path] : created4);
|
|
9741
9772
|
}
|
|
9742
9773
|
},
|
|
9743
9774
|
rm: reshaping(after(fs.rm.bind(fs), (path) => [path], "rename")),
|
|
@@ -11711,12 +11742,12 @@ var MountFs = class _MountFs {
|
|
|
11711
11742
|
return await this.base.hasOwner?.(path) ?? true;
|
|
11712
11743
|
}
|
|
11713
11744
|
async ancestry(path) {
|
|
11714
|
-
const
|
|
11715
|
-
const first =
|
|
11745
|
+
const names2 = chain(normalizePath(path));
|
|
11746
|
+
const first = names2.findIndex((name2) => this.at(name2));
|
|
11716
11747
|
if (first < 0) return ancestryOf(this.base, path);
|
|
11717
|
-
const out = first === 0 ? [] : await ancestryOf(this.base,
|
|
11748
|
+
const out = first === 0 ? [] : await ancestryOf(this.base, names2[first - 1]);
|
|
11718
11749
|
if (out.length < first || out.some((perm) => perm?.link !== void 0)) return out;
|
|
11719
|
-
for (const name2 of
|
|
11750
|
+
for (const name2 of names2.slice(first)) {
|
|
11720
11751
|
const st = await this.lstat(name2).catch(() => void 0);
|
|
11721
11752
|
if (!st) break;
|
|
11722
11753
|
out.push(permOf(st, st.isSymbolicLink ? await this.readlink(name2) : void 0));
|
|
@@ -12206,8 +12237,8 @@ async function guard(g, path, req, cwd) {
|
|
|
12206
12237
|
async function opening(entry, path, mode) {
|
|
12207
12238
|
const g = guardOf(entry);
|
|
12208
12239
|
const want = (mode & HOLD_READ ? R_OK : 0) | (mode & HOLD_WRITE ? W_OK : 0);
|
|
12209
|
-
const
|
|
12210
|
-
if (g && want !== 0 && !
|
|
12240
|
+
const created4 = (mode & HOLD_CREATED) !== 0 && entry.created?.take(path) === true;
|
|
12241
|
+
if (g && want !== 0 && !created4) {
|
|
12211
12242
|
await need(g, "open", path, want, { directory: false });
|
|
12212
12243
|
}
|
|
12213
12244
|
}
|
|
@@ -12389,6 +12420,7 @@ async function dispatchSyncFs(req) {
|
|
|
12389
12420
|
served++;
|
|
12390
12421
|
const entry = resolveSyncFsToken(req.token);
|
|
12391
12422
|
if (!entry) return { ok: false, errno: "EACCES", message: "sync-fs: unknown or revoked token" };
|
|
12423
|
+
if (req.identity && req.op === "create") return created2(entry, req);
|
|
12392
12424
|
if (!req.identity || !IDENTITY_OPS.has(req.op)) return dispatchOne(entry, req);
|
|
12393
12425
|
const { fs, cwd } = entry;
|
|
12394
12426
|
const path = fs.resolvePath(cwd, req.path);
|
|
@@ -12407,16 +12439,24 @@ async function dispatchSyncFs(req) {
|
|
|
12407
12439
|
return toErrno(err);
|
|
12408
12440
|
}
|
|
12409
12441
|
}
|
|
12442
|
+
async function created2(entry, req) {
|
|
12443
|
+
const result = await dispatchOne(entry, req);
|
|
12444
|
+
if (!result.ok) return result;
|
|
12445
|
+
const seen = entry.changes?.now();
|
|
12446
|
+
const looked = await dispatchOne(entry, { ...req, op: "stat" });
|
|
12447
|
+
if (!looked.ok || looked.kind !== "json") return json2(null);
|
|
12448
|
+
return seen === void 0 ? looked : json2({ ...looked.json, seen });
|
|
12449
|
+
}
|
|
12410
12450
|
var DENIED = /* @__PURE__ */ new Set(["EACCES", "EPERM"]);
|
|
12411
12451
|
async function rmPermitted(entry, path, req, refused3) {
|
|
12412
12452
|
const st = await entry.fs.lstat(path).catch(() => void 0);
|
|
12413
12453
|
if (!st?.isDirectory) return refused3;
|
|
12414
12454
|
const unlisted = await guarded(entry, path, { ...req, op: "readdir" });
|
|
12415
12455
|
if ("refused" in unlisted) return unlisted.refused;
|
|
12416
|
-
const
|
|
12417
|
-
if (!
|
|
12456
|
+
const names2 = await entry.fs.readdir(path).catch(() => void 0);
|
|
12457
|
+
if (!names2) return refused3;
|
|
12418
12458
|
let first;
|
|
12419
|
-
for (const name2 of
|
|
12459
|
+
for (const name2 of names2) {
|
|
12420
12460
|
const child = await dispatchOne(entry, {
|
|
12421
12461
|
...req,
|
|
12422
12462
|
path: joinName(path, name2)
|
|
@@ -12474,7 +12514,27 @@ async function newDevName(entry, path, req) {
|
|
|
12474
12514
|
if (there) return void 0;
|
|
12475
12515
|
return { ok: false, errno: refused3, message: `${target}: no new names in /dev or /proc` };
|
|
12476
12516
|
}
|
|
12517
|
+
var MISS_OPS = /* @__PURE__ */ new Set(["stat", "lstat"]);
|
|
12518
|
+
async function linkFree(fs, path) {
|
|
12519
|
+
for (let at = path.indexOf("/", 1); ; at = path.indexOf("/", at + 1)) {
|
|
12520
|
+
let st;
|
|
12521
|
+
try {
|
|
12522
|
+
st = await fs.lstat(at === -1 ? path : path.slice(0, at));
|
|
12523
|
+
} catch (err) {
|
|
12524
|
+
return err.code === "ENOENT";
|
|
12525
|
+
}
|
|
12526
|
+
if (st.isSymbolicLink || at === -1) return false;
|
|
12527
|
+
}
|
|
12528
|
+
}
|
|
12477
12529
|
async function dispatchOne(entry, req) {
|
|
12530
|
+
const result = await dispatchPath(entry, req);
|
|
12531
|
+
if (result.ok || result.errno !== "ENOENT" || !req.direct || !MISS_OPS.has(req.op) || req.handle !== void 0) {
|
|
12532
|
+
return result;
|
|
12533
|
+
}
|
|
12534
|
+
const path = entry.fs.resolvePath(entry.cwd, req.path);
|
|
12535
|
+
return await linkFree(entry.fs, path) ? { ...result, direct: true } : result;
|
|
12536
|
+
}
|
|
12537
|
+
async function dispatchPath(entry, req) {
|
|
12478
12538
|
const { fs, cwd } = entry;
|
|
12479
12539
|
try {
|
|
12480
12540
|
const path = fs.resolvePath(cwd, req.path);
|
|
@@ -12561,7 +12621,13 @@ function encodeSabResult(result) {
|
|
|
12561
12621
|
if (!result.ok) {
|
|
12562
12622
|
return {
|
|
12563
12623
|
status: SAB_STATUS_ERRNO,
|
|
12564
|
-
payload: encoder3.encode(
|
|
12624
|
+
payload: encoder3.encode(
|
|
12625
|
+
JSON.stringify({
|
|
12626
|
+
errno: result.errno,
|
|
12627
|
+
message: result.message,
|
|
12628
|
+
...result.direct ? { direct: true } : {}
|
|
12629
|
+
})
|
|
12630
|
+
)
|
|
12565
12631
|
};
|
|
12566
12632
|
}
|
|
12567
12633
|
switch (result.kind) {
|
|
@@ -15057,8 +15123,8 @@ var TlsEngine = class {
|
|
|
15057
15123
|
return n < 0 ? `${text}\u2026` : text;
|
|
15058
15124
|
}
|
|
15059
15125
|
};
|
|
15060
|
-
function alpnWire(
|
|
15061
|
-
const parts2 =
|
|
15126
|
+
function alpnWire(names2) {
|
|
15127
|
+
const parts2 = names2.map((name2) => new TextEncoder().encode(name2));
|
|
15062
15128
|
const out = new Uint8Array(parts2.reduce((n, p) => n + p.length + 1, 0));
|
|
15063
15129
|
let at = 0;
|
|
15064
15130
|
for (const part of parts2) {
|
|
@@ -15192,6 +15258,10 @@ var TlsSession = class {
|
|
|
15192
15258
|
get ciphersuite() {
|
|
15193
15259
|
return this.m._tls_ciphersuite(this.ptr);
|
|
15194
15260
|
}
|
|
15261
|
+
get lastAlert() {
|
|
15262
|
+
const last = this.m._tls_last_alert;
|
|
15263
|
+
return last ? last(this.ptr) : -1;
|
|
15264
|
+
}
|
|
15195
15265
|
get nameMismatch() {
|
|
15196
15266
|
return this.m._tls_name_mismatch(this.ptr) === 1;
|
|
15197
15267
|
}
|
|
@@ -17129,6 +17199,62 @@ function encodeReceived(got) {
|
|
|
17129
17199
|
return out;
|
|
17130
17200
|
}
|
|
17131
17201
|
|
|
17202
|
+
// src/kernel/net/tls-chain.ts
|
|
17203
|
+
var CN_MISMATCH = 4;
|
|
17204
|
+
var NOT_TRUSTED = 8;
|
|
17205
|
+
function tlv2(der, at) {
|
|
17206
|
+
if (at + 2 > der.length) return void 0;
|
|
17207
|
+
const first = der[at + 1];
|
|
17208
|
+
let body = at + 2;
|
|
17209
|
+
let length2 = first;
|
|
17210
|
+
if (first & 128) {
|
|
17211
|
+
const n = first & 127;
|
|
17212
|
+
if (n === 0 || n > 4 || body + n > der.length) return void 0;
|
|
17213
|
+
length2 = 0;
|
|
17214
|
+
for (let i = 0; i < n; i++) length2 = length2 * 256 + der[body + i];
|
|
17215
|
+
body += n;
|
|
17216
|
+
}
|
|
17217
|
+
const end = body + length2;
|
|
17218
|
+
return end > der.length ? void 0 : { start: at, body, end };
|
|
17219
|
+
}
|
|
17220
|
+
function names(der) {
|
|
17221
|
+
const cert = tlv2(der, 0);
|
|
17222
|
+
const tbs = cert && tlv2(der, cert.body);
|
|
17223
|
+
if (!tbs) return void 0;
|
|
17224
|
+
const fields = [];
|
|
17225
|
+
for (let at = tbs.body; at < tbs.end && fields.length < 6; ) {
|
|
17226
|
+
const field4 = tlv2(der, at);
|
|
17227
|
+
if (!field4) return void 0;
|
|
17228
|
+
if (fields.length > 0 || der[at] !== 160) fields.push(field4);
|
|
17229
|
+
at = field4.end;
|
|
17230
|
+
}
|
|
17231
|
+
const [, , issuer, , subject] = fields;
|
|
17232
|
+
if (!issuer || !subject) return void 0;
|
|
17233
|
+
return [der.subarray(issuer.start, issuer.end), der.subarray(subject.start, subject.end)];
|
|
17234
|
+
}
|
|
17235
|
+
function selfIssued(der) {
|
|
17236
|
+
const pair = der && names(der);
|
|
17237
|
+
if (!pair) return false;
|
|
17238
|
+
const [issuer, subject] = pair;
|
|
17239
|
+
return issuer.length === subject.length && issuer.every((b, i) => b === subject[i]);
|
|
17240
|
+
}
|
|
17241
|
+
function untrusted(chain2) {
|
|
17242
|
+
if (chain2.length === 1) {
|
|
17243
|
+
return selfIssued(chain2[0]) ? "DEPTH_ZERO_SELF_SIGNED_CERT" : "UNABLE_TO_VERIFY_LEAF_SIGNATURE";
|
|
17244
|
+
}
|
|
17245
|
+
return selfIssued(chain2.at(-1)) ? "SELF_SIGNED_CERT_IN_CHAIN" : "UNABLE_TO_GET_ISSUER_CERT_LOCALLY";
|
|
17246
|
+
}
|
|
17247
|
+
function chainError(flags2, chain2) {
|
|
17248
|
+
if (flags2 === -1) return "UNABLE_TO_VERIFY_LEAF_SIGNATURE";
|
|
17249
|
+
const rest2 = flags2 & ~CN_MISMATCH;
|
|
17250
|
+
if (rest2 === 0) return void 0;
|
|
17251
|
+
if (rest2 & NOT_TRUSTED) return untrusted(chain2);
|
|
17252
|
+
return verifyCode(rest2);
|
|
17253
|
+
}
|
|
17254
|
+
function nameMatches(flags2) {
|
|
17255
|
+
return flags2 !== -1 && (flags2 & CN_MISMATCH) === 0;
|
|
17256
|
+
}
|
|
17257
|
+
|
|
17132
17258
|
// src/kernel/net/tls-ciphers.ts
|
|
17133
17259
|
var SUITES = [
|
|
17134
17260
|
[4865, "TLS_AES_128_GCM_SHA256", "TLS_AES_128_GCM_SHA256", "TLSv1.3"],
|
|
@@ -17246,7 +17372,11 @@ function refused2(engine, session, err) {
|
|
|
17246
17372
|
if (code && flags2 !== -1)
|
|
17247
17373
|
return new KernelError("EPROTO", `${code}: ${engine.verifyInfo(flags2).trim()}`);
|
|
17248
17374
|
const text = err instanceof TlsError ? err.message : String(err);
|
|
17249
|
-
return new KernelError("EPROTO", `ERR_SSL_HANDSHAKE_FAILURE: ${text}`);
|
|
17375
|
+
return new KernelError("EPROTO", `ERR_SSL_HANDSHAKE_FAILURE: ${text}${alertOf(session)}`);
|
|
17376
|
+
}
|
|
17377
|
+
function alertOf(session) {
|
|
17378
|
+
const alert = session.lastAlert;
|
|
17379
|
+
return alert >= 0 ? ` (alert ${alert})` : "";
|
|
17250
17380
|
}
|
|
17251
17381
|
async function handshake(conn, o, session, inbox) {
|
|
17252
17382
|
for (; ; ) {
|
|
@@ -17267,7 +17397,12 @@ async function handshake(conn, o, session, inbox) {
|
|
|
17267
17397
|
}
|
|
17268
17398
|
}
|
|
17269
17399
|
}
|
|
17270
|
-
function
|
|
17400
|
+
function insecureOf(session, chain2) {
|
|
17401
|
+
const flags2 = session.verifyResult;
|
|
17402
|
+
const error = chainError(flags2, chain2);
|
|
17403
|
+
return { hostnameMatches: nameMatches(flags2), ...error ? { chainError: error } : {} };
|
|
17404
|
+
}
|
|
17405
|
+
function controlsOf(o, session, protocol, chain2) {
|
|
17271
17406
|
if (!o.engine.sessionControls) return {};
|
|
17272
17407
|
const checked = o.checkHostname !== false && !o.insecure;
|
|
17273
17408
|
return {
|
|
@@ -17275,28 +17410,29 @@ function controlsOf(o, session, protocol) {
|
|
|
17275
17410
|
clientCertificate: o.clientCertificate === true,
|
|
17276
17411
|
sni: o.sni !== false && !isIP(o.servername),
|
|
17277
17412
|
hostnameChecked: checked,
|
|
17278
|
-
...o.insecure ?
|
|
17413
|
+
...o.insecure ? insecureOf(session, chain2) : { hostnameMatches: checked || !session.nameMismatch }
|
|
17279
17414
|
};
|
|
17280
17415
|
}
|
|
17281
17416
|
function infoOf(o, session) {
|
|
17282
17417
|
const flags2 = session.verifyResult;
|
|
17283
17418
|
const code = verifyCode(flags2);
|
|
17284
17419
|
const protocol = session.version === 772 ? "TLSv1.3" : "TLSv1.2";
|
|
17420
|
+
const chain2 = session.peerChain();
|
|
17285
17421
|
return {
|
|
17286
17422
|
protocol,
|
|
17287
17423
|
alpnProtocol: session.alpn ?? false,
|
|
17288
17424
|
authorized: code === void 0,
|
|
17289
17425
|
...code ? { authorizationError: code, authorizationText: o.engine.verifyInfo(flags2).trim() } : {},
|
|
17290
|
-
peerCertificates:
|
|
17291
|
-
...controlsOf(o, session, protocol)
|
|
17426
|
+
peerCertificates: chain2,
|
|
17427
|
+
...controlsOf(o, session, protocol, chain2)
|
|
17292
17428
|
};
|
|
17293
17429
|
}
|
|
17294
17430
|
var FATAL_ALERT = -30592;
|
|
17295
|
-
function alerted(err) {
|
|
17431
|
+
function alerted(err, session) {
|
|
17296
17432
|
if (err.code === FATAL_ALERT)
|
|
17297
17433
|
return new KernelError(
|
|
17298
17434
|
"EPROTO",
|
|
17299
|
-
`ERR_SSL_FATAL_ALERT: the server ended the session: ${err.message}`
|
|
17435
|
+
`ERR_SSL_FATAL_ALERT: the server ended the session: ${err.message}${alertOf(session)}`
|
|
17300
17436
|
);
|
|
17301
17437
|
return new KernelError("EPROTO", `ERR_SSL_PROTOCOL_ERROR: ${err.message}`);
|
|
17302
17438
|
}
|
|
@@ -17318,7 +17454,7 @@ function plaintext(conn, session, inbox) {
|
|
|
17318
17454
|
try {
|
|
17319
17455
|
got = session.read();
|
|
17320
17456
|
} catch (err) {
|
|
17321
|
-
throw alerted(err);
|
|
17457
|
+
throw alerted(err, session);
|
|
17322
17458
|
}
|
|
17323
17459
|
await send(conn, session);
|
|
17324
17460
|
if (got instanceof Uint8Array) return got;
|
|
@@ -17424,7 +17560,8 @@ function controls(info) {
|
|
|
17424
17560
|
clientCertificate: info.clientCertificate === true,
|
|
17425
17561
|
sni: info.sni !== false,
|
|
17426
17562
|
hostnameChecked: info.hostnameChecked === true,
|
|
17427
|
-
...info.hostnameMatches === void 0 ? {} : { hostnameMatches: info.hostnameMatches }
|
|
17563
|
+
...info.hostnameMatches === void 0 ? {} : { hostnameMatches: info.hostnameMatches },
|
|
17564
|
+
...info.chainError ? { chainError: info.chainError } : {}
|
|
17428
17565
|
};
|
|
17429
17566
|
}
|
|
17430
17567
|
var KEY_ERRORS = [
|
|
@@ -20661,6 +20798,7 @@ function holdingToken(opts, holds2, caller) {
|
|
|
20661
20798
|
...opts.fresh ? { fresh: (path) => opts.fresh?.(path, caller.umask()) } : {},
|
|
20662
20799
|
...opts.source ? { source: opts.source } : {},
|
|
20663
20800
|
...opts.replacements ? { replacements: opts.replacements } : {},
|
|
20801
|
+
...opts.changes ? { changes: new ChangeView(opts.changes) } : {},
|
|
20664
20802
|
fs: opts.fs,
|
|
20665
20803
|
noLinks: opts.noLinks,
|
|
20666
20804
|
cwd: opts.cwd,
|
|
@@ -20680,7 +20818,7 @@ function linksOf(opts) {
|
|
|
20680
20818
|
function clipboardName(opts) {
|
|
20681
20819
|
return opts.program.abi === "js" ? {} : { clipboardName: opts.argv0 };
|
|
20682
20820
|
}
|
|
20683
|
-
function processOptions(opts, header4, hooks,
|
|
20821
|
+
function processOptions(opts, header4, hooks, created4) {
|
|
20684
20822
|
return {
|
|
20685
20823
|
...inherited(opts),
|
|
20686
20824
|
...opts.owners ? { owners: true } : {},
|
|
@@ -20690,7 +20828,7 @@ function processOptions(opts, header4, hooks, created3) {
|
|
|
20690
20828
|
...opts.readonlyAt ? { readonlyAt: opts.readonlyAt } : {},
|
|
20691
20829
|
...opts.source ? { source: opts.source } : {},
|
|
20692
20830
|
noLinks: opts.noLinks,
|
|
20693
|
-
...opts.dac ? { guard: { dac: opts.dac, fs: opts.fs, created:
|
|
20831
|
+
...opts.dac ? { guard: { dac: opts.dac, fs: opts.fs, created: created4, ...linksOf(opts) } } : {},
|
|
20694
20832
|
...opts.identity ? { identity: opts.identity } : {},
|
|
20695
20833
|
...opts.onSyscall ? { onSyscall: opts.onSyscall } : {},
|
|
20696
20834
|
...opts.settling ? { settling: opts.settling } : {},
|
|
@@ -20773,7 +20911,7 @@ function spawnWasmProcess(opts) {
|
|
|
20773
20911
|
const blocked2 = opts.fork?.wasi?.blocked ?? opts.blocked;
|
|
20774
20912
|
if (blocked2 && anyBlocked(blocked2) && opts.program.abi === "wasi") storeBlocked(header4, blocked2);
|
|
20775
20913
|
const threadSignals = /* @__PURE__ */ new Map();
|
|
20776
|
-
const
|
|
20914
|
+
const created4 = new Created();
|
|
20777
20915
|
const process2 = new WasmProcess(
|
|
20778
20916
|
opts.pid,
|
|
20779
20917
|
opts.fds,
|
|
@@ -20789,7 +20927,7 @@ function spawnWasmProcess(opts) {
|
|
|
20789
20927
|
exitSignal: (sig) => queueMicrotask(() => finish(128 + sig, sig))
|
|
20790
20928
|
} : { exitSignal: (sig) => terminate(128 + sig, sig) }
|
|
20791
20929
|
},
|
|
20792
|
-
|
|
20930
|
+
created4
|
|
20793
20931
|
)
|
|
20794
20932
|
);
|
|
20795
20933
|
publishStops(process2, header4);
|
|
@@ -20798,7 +20936,7 @@ function spawnWasmProcess(opts) {
|
|
|
20798
20936
|
const token = holdingToken(opts, holds2, {
|
|
20799
20937
|
cred: () => process2.cred,
|
|
20800
20938
|
umask: () => process2.umask,
|
|
20801
|
-
created:
|
|
20939
|
+
created: created4,
|
|
20802
20940
|
holdsKept: async (path) => path.includes(`/${UNLINKED_DIR}/`) && (holds2.keeps(path) || await process2.holds(path))
|
|
20803
20941
|
});
|
|
20804
20942
|
heldBy(process2, holds2, opts.replacements);
|
|
@@ -21488,10 +21626,10 @@ var HOSTS_PATH = "/etc/hosts";
|
|
|
21488
21626
|
function parseHosts(text) {
|
|
21489
21627
|
const table = /* @__PURE__ */ new Map();
|
|
21490
21628
|
for (const raw of text.split("\n")) {
|
|
21491
|
-
const [address, ...
|
|
21492
|
-
if (!address ||
|
|
21629
|
+
const [address, ...names2] = raw.replace(/#.*/, "").trim().split(/\s+/);
|
|
21630
|
+
if (!address || names2.length === 0) continue;
|
|
21493
21631
|
if (ipv4Bytes(address) === void 0 && ipv6Groups(address) === void 0) continue;
|
|
21494
|
-
for (const name2 of
|
|
21632
|
+
for (const name2 of names2) {
|
|
21495
21633
|
const key = name2.toLowerCase().replace(/\.$/, "");
|
|
21496
21634
|
const known = table.get(key) ?? [];
|
|
21497
21635
|
if (!known.includes(address)) known.push(address);
|
|
@@ -23884,7 +24022,7 @@ var ChunkedBytes = class {
|
|
|
23884
24022
|
function idOption2(value2) {
|
|
23885
24023
|
return value2 !== void 0 && /^\d+$/.test(value2) ? Number(value2) : 0;
|
|
23886
24024
|
}
|
|
23887
|
-
function
|
|
24025
|
+
function created3(ino, kind, mode, from, owner) {
|
|
23888
24026
|
const now = Date.now();
|
|
23889
24027
|
return {
|
|
23890
24028
|
kind,
|
|
@@ -23919,7 +24057,7 @@ function attr(node) {
|
|
|
23919
24057
|
}
|
|
23920
24058
|
function tmpfs() {
|
|
23921
24059
|
let inodes = 0;
|
|
23922
|
-
const make = (kind, mode, from, owner) =>
|
|
24060
|
+
const make = (kind, mode, from, owner) => created3(++inodes, kind, mode, from, owner);
|
|
23923
24061
|
const root = make("directory", 16877);
|
|
23924
24062
|
const handles = /* @__PURE__ */ new Map();
|
|
23925
24063
|
let nextFh = 0;
|
|
@@ -23939,10 +24077,10 @@ function tmpfs() {
|
|
|
23939
24077
|
return node;
|
|
23940
24078
|
}
|
|
23941
24079
|
function parent(path) {
|
|
23942
|
-
const
|
|
23943
|
-
const name2 =
|
|
24080
|
+
const names2 = parts2(path);
|
|
24081
|
+
const name2 = names2.pop();
|
|
23944
24082
|
if (name2 === void 0) throw fsError2("EBUSY", "the root of a mount");
|
|
23945
|
-
const dir = find(`/${
|
|
24083
|
+
const dir = find(`/${names2.join("/")}`);
|
|
23946
24084
|
if (dir.kind !== "directory") throw fsError2("ENOTDIR", path);
|
|
23947
24085
|
return { dir, name: name2 };
|
|
23948
24086
|
}
|
|
@@ -24422,12 +24560,12 @@ var Sudo = class {
|
|
|
24422
24560
|
}
|
|
24423
24561
|
async policy() {
|
|
24424
24562
|
const rules = await this.policyFile(SUDOERS);
|
|
24425
|
-
const
|
|
24426
|
-
if (
|
|
24563
|
+
const names2 = await this.o.fs.readdir(SUDOERS_D).catch(() => []);
|
|
24564
|
+
if (names2.length > 0 && !await this.trusted(SUDOERS_D)) {
|
|
24427
24565
|
this.warn(`sudo: ${SUDOERS_D} skipped: it must be root's and writable by root only`);
|
|
24428
24566
|
return rules;
|
|
24429
24567
|
}
|
|
24430
|
-
for (const name2 of [...
|
|
24568
|
+
for (const name2 of [...names2].sort()) {
|
|
24431
24569
|
if (name2.startsWith(".") || name2.endsWith("~")) continue;
|
|
24432
24570
|
rules.push(...await this.policyFile(`${SUDOERS_D}/${name2}`));
|
|
24433
24571
|
}
|
|
@@ -24507,8 +24645,8 @@ var Sudo = class {
|
|
|
24507
24645
|
}
|
|
24508
24646
|
const path = await this.locate(word, cwd);
|
|
24509
24647
|
if (!path) return failed2("ENOENT", `sudo: ${word}: command not found`);
|
|
24510
|
-
const
|
|
24511
|
-
if (
|
|
24648
|
+
const untrusted2 = await this.untrusted(path, cwd, word);
|
|
24649
|
+
if (untrusted2) return untrusted2;
|
|
24512
24650
|
const argv = [path, ...args];
|
|
24513
24651
|
const matching = rules.filter(
|
|
24514
24652
|
(rule) => applies(rule) && (rule.target === "ALL" || rule.target === target.name) && (rule.cwd === void 0 || rule.cwd === cwd) && (rule.cmnd === "*" || rule.cmnd.length === argv.length && rule.cmnd.every((w, i) => w === argv[i]))
|
|
@@ -24783,10 +24921,10 @@ function shebang(head) {
|
|
|
24783
24921
|
return new TextDecoder().decode(head.subarray(0, SHEBANG_MAX)).slice(2).split("\n")[0].trim().split(/[ \t]+/);
|
|
24784
24922
|
}
|
|
24785
24923
|
async function rootOnly(fs, path, dir = false) {
|
|
24786
|
-
const
|
|
24787
|
-
for (const [i, at] of
|
|
24924
|
+
const names2 = chain(path);
|
|
24925
|
+
for (const [i, at] of names2.entries()) {
|
|
24788
24926
|
const st = await fs.lstat(at).catch(() => void 0);
|
|
24789
|
-
const kind = i ===
|
|
24927
|
+
const kind = i === names2.length - 1 && !dir ? st?.isFile : st?.isDirectory;
|
|
24790
24928
|
if (!kind || st?.uid !== 0 || (st.mode & 18) !== 0) return false;
|
|
24791
24929
|
}
|
|
24792
24930
|
return true;
|
|
@@ -25795,7 +25933,7 @@ var Launcher = class {
|
|
|
25795
25933
|
return { glue, module: module2 };
|
|
25796
25934
|
}
|
|
25797
25935
|
const { module, memory, foreign } = await this.module(target.wasm, caller, asked);
|
|
25798
|
-
const
|
|
25936
|
+
const names2 = env.SLICC_WASM_BACKTRACE === "1" ? await this.names(target.wasm, module) : void 0;
|
|
25799
25937
|
const imports = target.imports ? await this.text(target.imports, caller) : void 0;
|
|
25800
25938
|
return {
|
|
25801
25939
|
abi: "wasi",
|
|
@@ -25804,7 +25942,7 @@ var Launcher = class {
|
|
|
25804
25942
|
...memory ? { memory } : {},
|
|
25805
25943
|
foreign,
|
|
25806
25944
|
path: target.wasm,
|
|
25807
|
-
...
|
|
25945
|
+
...names2 ? { names: names2 } : {},
|
|
25808
25946
|
...imports !== void 0 ? { imports } : {},
|
|
25809
25947
|
...target.preopenRoot ? { preopenRoot: true } : {}
|
|
25810
25948
|
};
|
|
@@ -26586,10 +26724,10 @@ var Launcher = class {
|
|
|
26586
26724
|
const real = await this.realLayoutPath("/tmp");
|
|
26587
26725
|
const st = real === void 0 ? void 0 : await this.base.lstat(real).catch(() => void 0);
|
|
26588
26726
|
if (real !== void 0 && st?.isDirectory && this.base.hasOwner && !await this.base.hasOwner(real)) {
|
|
26589
|
-
const
|
|
26727
|
+
const names2 = await this.base.readdir(real).catch(() => void 0);
|
|
26590
26728
|
let removed = 0;
|
|
26591
|
-
let left =
|
|
26592
|
-
for (const name2 of
|
|
26729
|
+
let left = names2 === void 0 ? 1 : 0;
|
|
26730
|
+
for (const name2 of names2 ?? []) {
|
|
26593
26731
|
const path = joinName(real, name2);
|
|
26594
26732
|
if (await this.base.hasOwner(path)) continue;
|
|
26595
26733
|
const failed3 = this.inUse(path) ? "busy" : await this.base.rm(path, { recursive: true, force: true }).catch(String);
|
|
@@ -26867,12 +27005,12 @@ var Launcher = class {
|
|
|
26867
27005
|
}
|
|
26868
27006
|
named = /* @__PURE__ */ new WeakMap();
|
|
26869
27007
|
commandNames(commands) {
|
|
26870
|
-
let
|
|
26871
|
-
if (!
|
|
26872
|
-
|
|
26873
|
-
this.named.set(commands,
|
|
27008
|
+
let names2 = this.named.get(commands);
|
|
27009
|
+
if (!names2) {
|
|
27010
|
+
names2 = new Set(commands.keys());
|
|
27011
|
+
this.named.set(commands, names2);
|
|
26874
27012
|
}
|
|
26875
|
-
return
|
|
27013
|
+
return names2;
|
|
26876
27014
|
}
|
|
26877
27015
|
async entryTarget(path) {
|
|
26878
27016
|
const system = COMMAND2.exec(path)?.[1];
|
|
@@ -27364,12 +27502,12 @@ var MemoryDirectory = class _MemoryDirectory {
|
|
|
27364
27502
|
if (found.kind === "directory") found.remove();
|
|
27365
27503
|
}
|
|
27366
27504
|
async resolve(handle) {
|
|
27367
|
-
const
|
|
27505
|
+
const names2 = [];
|
|
27368
27506
|
for (let at = handle; at !== this; at = at.parent) {
|
|
27369
27507
|
if (!at || at.kind === "directory" && at.removed) return null;
|
|
27370
|
-
|
|
27508
|
+
names2.unshift(at.name);
|
|
27371
27509
|
}
|
|
27372
|
-
return
|
|
27510
|
+
return names2;
|
|
27373
27511
|
}
|
|
27374
27512
|
remove() {
|
|
27375
27513
|
this.removed = true;
|