@ai-ecoverse/slicc-kernel 1.125.1 → 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 +11 -2
- package/dist/kernel-worker.js +219 -81
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-process-worker.js +97 -46
- 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 +97 -46
- 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/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 +6 -1
- package/dist/types/realm/sync-sab-bridge.d.ts +1 -0
- package/package.json +1 -1
package/dist/kernel-worker.js
CHANGED
|
@@ -528,9 +528,9 @@ var Integrity = class {
|
|
|
528
528
|
const at = normalizePath(path);
|
|
529
529
|
const real = known ?? await this.root.realpath?.(at, true).catch(() => void 0) ?? at;
|
|
530
530
|
if (isProtected(this.prefixes, real)) return { real, name: real };
|
|
531
|
-
const
|
|
532
|
-
if (real !== at)
|
|
533
|
-
const name2 =
|
|
531
|
+
const names2 = asked === void 0 ? [] : await namesOf(this.root, asked);
|
|
532
|
+
if (real !== at) names2.push(...await namesOf(this.root, at));
|
|
533
|
+
const name2 = names2.findLast((p) => isProtected(this.prefixes, p));
|
|
534
534
|
return name2 === void 0 ? void 0 : { real, name: name2 };
|
|
535
535
|
}
|
|
536
536
|
async key(path, asked) {
|
|
@@ -1118,8 +1118,8 @@ function sidecar(meta) {
|
|
|
1118
1118
|
const guarded2 = (op) => (...args) => meta[op].apply(meta, args).catch((err) => {
|
|
1119
1119
|
throw translate(err, pathOf(args), "sidecar", false);
|
|
1120
1120
|
});
|
|
1121
|
-
const
|
|
1122
|
-
const ops = Object.fromEntries(
|
|
1121
|
+
const names2 = meta.fresh ? [...META_OPS, "fresh"] : META_OPS;
|
|
1122
|
+
const ops = Object.fromEntries(names2.map((op) => [op, guarded2(op)]));
|
|
1123
1123
|
const { updateMany } = meta;
|
|
1124
1124
|
ops.updateMany = updateMany ? (changes) => updateMany.call(meta, changes).catch((err) => {
|
|
1125
1125
|
throw translate(err, changes[0]?.path ?? "/", "sidecar", false);
|
|
@@ -2478,11 +2478,11 @@ var WRITES = [
|
|
|
2478
2478
|
"lutimes",
|
|
2479
2479
|
"chown"
|
|
2480
2480
|
];
|
|
2481
|
-
for (const [
|
|
2481
|
+
for (const [names2, op] of [
|
|
2482
2482
|
[READS, "read"],
|
|
2483
2483
|
[WRITES, "write"]
|
|
2484
2484
|
]) {
|
|
2485
|
-
for (const name2 of
|
|
2485
|
+
for (const name2 of names2) {
|
|
2486
2486
|
const proto = OpfsFs.prototype;
|
|
2487
2487
|
const inner = proto[name2];
|
|
2488
2488
|
proto[name2] = async function(...args) {
|
|
@@ -3495,11 +3495,11 @@ var Perms = class {
|
|
|
3495
3495
|
this.fs = fs;
|
|
3496
3496
|
}
|
|
3497
3497
|
async learn(path) {
|
|
3498
|
-
const
|
|
3498
|
+
const names2 = chain(path);
|
|
3499
3499
|
const perms = await ancestryOf(this.fs, path);
|
|
3500
|
-
for (let i = 0; i <
|
|
3500
|
+
for (let i = 0; i < names2.length; i++) {
|
|
3501
3501
|
const perm = perms[i];
|
|
3502
|
-
this.known.set(
|
|
3502
|
+
this.known.set(names2[i], perm);
|
|
3503
3503
|
if (perm === void 0 || perm.link !== void 0) break;
|
|
3504
3504
|
}
|
|
3505
3505
|
}
|
|
@@ -5731,8 +5731,8 @@ function userEnv(account, system) {
|
|
|
5731
5731
|
PATH: `${pnpm}/bin:/usr/local/bin:/usr/bin:/bin`
|
|
5732
5732
|
};
|
|
5733
5733
|
}
|
|
5734
|
-
function groupsOf(groups,
|
|
5735
|
-
return
|
|
5734
|
+
function groupsOf(groups, names2) {
|
|
5735
|
+
return names2.map((g) => {
|
|
5736
5736
|
const row = groups.find((r) => r.name === g);
|
|
5737
5737
|
if (!row) throw fsError("ENOENT", `no group ${g}`);
|
|
5738
5738
|
return row;
|
|
@@ -6632,7 +6632,7 @@ function satisfies(version, range2) {
|
|
|
6632
6632
|
}
|
|
6633
6633
|
|
|
6634
6634
|
// src/version.ts
|
|
6635
|
-
var KERNEL_VERSION = true ? "1.125.
|
|
6635
|
+
var KERNEL_VERSION = true ? "1.125.2" : "0.0.0-dev";
|
|
6636
6636
|
var OS_RELEASE = "6.0.0-slicc";
|
|
6637
6637
|
function procVersion() {
|
|
6638
6638
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -6787,9 +6787,9 @@ async function withPackagePaths(fs, pkg, command) {
|
|
|
6787
6787
|
return { ...command, env };
|
|
6788
6788
|
}
|
|
6789
6789
|
async function packages(fs, modules) {
|
|
6790
|
-
const
|
|
6790
|
+
const names2 = await fs.readdir(modules).catch(() => []);
|
|
6791
6791
|
const packageNames = [];
|
|
6792
|
-
for (const name2 of
|
|
6792
|
+
for (const name2 of names2) {
|
|
6793
6793
|
if (name2.startsWith(".")) continue;
|
|
6794
6794
|
if (!name2.startsWith("@")) {
|
|
6795
6795
|
packageNames.push(name2);
|
|
@@ -7582,7 +7582,7 @@ var UnlinkedKeeper = class {
|
|
|
7582
7582
|
[name2]: (path, ...rest2) => unreplaced(path, () => call.call(fs, path, ...rest2))
|
|
7583
7583
|
};
|
|
7584
7584
|
};
|
|
7585
|
-
const visible = (
|
|
7585
|
+
const visible = (names2) => names2.filter((name2) => name2 !== UNLINKED_DIR);
|
|
7586
7586
|
const counted2 = (st) => {
|
|
7587
7587
|
const hidden = keeper.links.get(`${st.dev ?? 0}:${st.ino}`) ?? 0;
|
|
7588
7588
|
return hidden === 0 || st.nlink === void 0 ? st : { ...st, nlink: Math.max(0, st.nlink - hidden) };
|
|
@@ -7801,10 +7801,10 @@ var UnlinkedKeeper = class {
|
|
|
7801
7801
|
if (!query && !owner) return Promise.resolve();
|
|
7802
7802
|
return this.serial(async () => {
|
|
7803
7803
|
const dir = dirOf(root);
|
|
7804
|
-
const
|
|
7805
|
-
if (!
|
|
7804
|
+
const names2 = await this.fs.readdir(dir).catch(() => void 0);
|
|
7805
|
+
if (!names2) return;
|
|
7806
7806
|
const held = query && new Set(((await query()).held ?? []).map((lock) => lock.name));
|
|
7807
|
-
for (const name2 of
|
|
7807
|
+
for (const name2 of names2) {
|
|
7808
7808
|
const id2 = name2.slice(0, name2.lastIndexOf("."));
|
|
7809
7809
|
const at = id2.indexOf("~");
|
|
7810
7810
|
const dead = id2 !== this.instance && (at < 0 ? held !== void 0 && !held.has(lockName(id2)) : owner?.alive(id2.slice(0, at)) === false);
|
|
@@ -8007,11 +8007,11 @@ var CronService = class {
|
|
|
8007
8007
|
const account = await this.host.lookup(job.user);
|
|
8008
8008
|
if (account) out.push({ source: "system", account, job });
|
|
8009
8009
|
}
|
|
8010
|
-
const
|
|
8010
|
+
const names2 = await fs.readdir(SPOOL_DIR).catch((err) => {
|
|
8011
8011
|
if (err?.code === "ENOENT") return [];
|
|
8012
8012
|
throw err;
|
|
8013
8013
|
});
|
|
8014
|
-
for (const name2 of
|
|
8014
|
+
for (const name2 of names2.sort()) {
|
|
8015
8015
|
if (name2.startsWith(".") || name2.endsWith("~")) continue;
|
|
8016
8016
|
const path = `${SPOOL_DIR}/${name2}`;
|
|
8017
8017
|
const account = await this.host.lookup(name2);
|
|
@@ -9036,6 +9036,37 @@ var FileChanges = class {
|
|
|
9036
9036
|
}
|
|
9037
9037
|
}
|
|
9038
9038
|
};
|
|
9039
|
+
var ChangeView = class {
|
|
9040
|
+
view;
|
|
9041
|
+
constructor(sab) {
|
|
9042
|
+
this.view = new Int32Array(sab);
|
|
9043
|
+
}
|
|
9044
|
+
now() {
|
|
9045
|
+
return Atomics.load(this.view, GEN);
|
|
9046
|
+
}
|
|
9047
|
+
clean() {
|
|
9048
|
+
return this.view.length > DIRTY && Atomics.load(this.view, DIRTY) === 0;
|
|
9049
|
+
}
|
|
9050
|
+
foreign() {
|
|
9051
|
+
return this.view.length > FOREIGN && Atomics.load(this.view, FOREIGN) === 1;
|
|
9052
|
+
}
|
|
9053
|
+
changedSince(seen, path) {
|
|
9054
|
+
const now = Atomics.load(this.view, GEN);
|
|
9055
|
+
const distance = now - seen >>> 0;
|
|
9056
|
+
if (distance === 0) return { now, changed: false };
|
|
9057
|
+
if (distance > RING_SIZE) return { now, changed: true };
|
|
9058
|
+
const hash = changeHash(normal(path));
|
|
9059
|
+
for (let i = 1; i <= distance; i++) {
|
|
9060
|
+
const g = seen + i | 0;
|
|
9061
|
+
const at = RING + (g & RING_SIZE - 1) * SLOT;
|
|
9062
|
+
if (Atomics.load(this.view, at) !== g) return { now, changed: true };
|
|
9063
|
+
const hit = Atomics.load(this.view, at + 1) === hash;
|
|
9064
|
+
if (Atomics.load(this.view, at) !== g) return { now, changed: true };
|
|
9065
|
+
if (hit) return { now, changed: true };
|
|
9066
|
+
}
|
|
9067
|
+
return { now, changed: false };
|
|
9068
|
+
}
|
|
9069
|
+
};
|
|
9039
9070
|
|
|
9040
9071
|
// src/fs/commands.ts
|
|
9041
9072
|
var S_IFDIR2 = 16384;
|
|
@@ -9083,7 +9114,7 @@ async function shownTarget(fs, target) {
|
|
|
9083
9114
|
const st = await quiet(fs.stat(target));
|
|
9084
9115
|
return st?.isFile && await readsAs2(fs, NOBODY, target) ? st : void 0;
|
|
9085
9116
|
}
|
|
9086
|
-
function withCommandDirs(fs,
|
|
9117
|
+
function withCommandDirs(fs, names2, userDir = async () => void 0, owners = false, targetOf2 = async () => void 0) {
|
|
9087
9118
|
async function nearest(path) {
|
|
9088
9119
|
const st = await fs.stat(path).catch(() => void 0);
|
|
9089
9120
|
if (st || path === "/") return st ?? {};
|
|
@@ -9097,7 +9128,7 @@ function withCommandDirs(fs, names, userDir = async () => void 0, owners = false
|
|
|
9097
9128
|
async function children2(path) {
|
|
9098
9129
|
if (path === "/") return ["bin", "usr"];
|
|
9099
9130
|
if (path === "/usr") return ["bin"];
|
|
9100
|
-
if (path === "/bin" || path === "/usr/bin") return [...await
|
|
9131
|
+
if (path === "/bin" || path === "/usr/bin") return [...await names2()];
|
|
9101
9132
|
const own = await userDir(path);
|
|
9102
9133
|
return own?.size ? [...own] : void 0;
|
|
9103
9134
|
}
|
|
@@ -9107,7 +9138,7 @@ function withCommandDirs(fs, names, userDir = async () => void 0, owners = false
|
|
|
9107
9138
|
}
|
|
9108
9139
|
const name2 = COMMAND.exec(path)?.[1];
|
|
9109
9140
|
if (name2 !== void 0) {
|
|
9110
|
-
return (await
|
|
9141
|
+
return (await names2()).has(name2) ? owned4(synthetic(false, path)) : void 0;
|
|
9111
9142
|
}
|
|
9112
9143
|
if ((await userDir(path))?.size) return owned4(synthetic(true, path), path);
|
|
9113
9144
|
const slash = path.lastIndexOf("/");
|
|
@@ -9118,7 +9149,7 @@ function withCommandDirs(fs, names, userDir = async () => void 0, owners = false
|
|
|
9118
9149
|
let generation;
|
|
9119
9150
|
const targets = /* @__PURE__ */ new Map();
|
|
9120
9151
|
async function targetStat(target) {
|
|
9121
|
-
const now = await
|
|
9152
|
+
const now = await names2();
|
|
9122
9153
|
if (now !== generation) {
|
|
9123
9154
|
generation = now;
|
|
9124
9155
|
targets.clear();
|
|
@@ -9627,12 +9658,12 @@ var FsWatchers = class {
|
|
|
9627
9658
|
writeFile: content(fs.writeFile.bind(fs), written2),
|
|
9628
9659
|
...fs.createExclusive ? { createExclusive: content(fs.createExclusive.bind(fs), () => ["rename"]) } : {},
|
|
9629
9660
|
mkdir: async (path, options) => {
|
|
9630
|
-
const
|
|
9661
|
+
const created4 = [];
|
|
9631
9662
|
if (options?.recursive) {
|
|
9632
9663
|
const parts2 = normalizePath(path).split("/").filter(Boolean);
|
|
9633
9664
|
for (let at = 1; at < parts2.length; at++) {
|
|
9634
9665
|
const ancestor = `/${parts2.slice(0, at).join("/")}`;
|
|
9635
|
-
if (
|
|
9666
|
+
if (created4.length > 0 || !await fs.exists(ancestor)) created4.push(ancestor);
|
|
9636
9667
|
}
|
|
9637
9668
|
}
|
|
9638
9669
|
const fresh2 = !options?.recursive || !(this.covers(path) && await fs.exists(path));
|
|
@@ -9641,8 +9672,8 @@ var FsWatchers = class {
|
|
|
9641
9672
|
await fs.mkdir(path, options);
|
|
9642
9673
|
done4 = true;
|
|
9643
9674
|
} finally {
|
|
9644
|
-
this.report([...
|
|
9645
|
-
if (done4) this.emit("rename", fresh2 ? [...
|
|
9675
|
+
this.report([...created4, path]);
|
|
9676
|
+
if (done4) this.emit("rename", fresh2 ? [...created4, path] : created4);
|
|
9646
9677
|
}
|
|
9647
9678
|
},
|
|
9648
9679
|
rm: reshaping(after(fs.rm.bind(fs), (path) => [path], "rename")),
|
|
@@ -11616,12 +11647,12 @@ var MountFs = class _MountFs {
|
|
|
11616
11647
|
return await this.base.hasOwner?.(path) ?? true;
|
|
11617
11648
|
}
|
|
11618
11649
|
async ancestry(path) {
|
|
11619
|
-
const
|
|
11620
|
-
const first =
|
|
11650
|
+
const names2 = chain(normalizePath(path));
|
|
11651
|
+
const first = names2.findIndex((name2) => this.at(name2));
|
|
11621
11652
|
if (first < 0) return ancestryOf(this.base, path);
|
|
11622
|
-
const out = first === 0 ? [] : await ancestryOf(this.base,
|
|
11653
|
+
const out = first === 0 ? [] : await ancestryOf(this.base, names2[first - 1]);
|
|
11623
11654
|
if (out.length < first || out.some((perm) => perm?.link !== void 0)) return out;
|
|
11624
|
-
for (const name2 of
|
|
11655
|
+
for (const name2 of names2.slice(first)) {
|
|
11625
11656
|
const st = await this.lstat(name2).catch(() => void 0);
|
|
11626
11657
|
if (!st) break;
|
|
11627
11658
|
out.push(permOf(st, st.isSymbolicLink ? await this.readlink(name2) : void 0));
|
|
@@ -12111,8 +12142,8 @@ async function guard(g, path, req, cwd) {
|
|
|
12111
12142
|
async function opening(entry, path, mode) {
|
|
12112
12143
|
const g = guardOf(entry);
|
|
12113
12144
|
const want = (mode & HOLD_READ ? R_OK : 0) | (mode & HOLD_WRITE ? W_OK : 0);
|
|
12114
|
-
const
|
|
12115
|
-
if (g && want !== 0 && !
|
|
12145
|
+
const created4 = (mode & HOLD_CREATED) !== 0 && entry.created?.take(path) === true;
|
|
12146
|
+
if (g && want !== 0 && !created4) {
|
|
12116
12147
|
await need(g, "open", path, want, { directory: false });
|
|
12117
12148
|
}
|
|
12118
12149
|
}
|
|
@@ -12294,6 +12325,7 @@ async function dispatchSyncFs(req) {
|
|
|
12294
12325
|
served++;
|
|
12295
12326
|
const entry = resolveSyncFsToken(req.token);
|
|
12296
12327
|
if (!entry) return { ok: false, errno: "EACCES", message: "sync-fs: unknown or revoked token" };
|
|
12328
|
+
if (req.identity && req.op === "create") return created2(entry, req);
|
|
12297
12329
|
if (!req.identity || !IDENTITY_OPS.has(req.op)) return dispatchOne(entry, req);
|
|
12298
12330
|
const { fs, cwd } = entry;
|
|
12299
12331
|
const path = fs.resolvePath(cwd, req.path);
|
|
@@ -12312,16 +12344,24 @@ async function dispatchSyncFs(req) {
|
|
|
12312
12344
|
return toErrno(err);
|
|
12313
12345
|
}
|
|
12314
12346
|
}
|
|
12347
|
+
async function created2(entry, req) {
|
|
12348
|
+
const result = await dispatchOne(entry, req);
|
|
12349
|
+
if (!result.ok) return result;
|
|
12350
|
+
const seen = entry.changes?.now();
|
|
12351
|
+
const looked = await dispatchOne(entry, { ...req, op: "stat" });
|
|
12352
|
+
if (!looked.ok || looked.kind !== "json") return json2(null);
|
|
12353
|
+
return seen === void 0 ? looked : json2({ ...looked.json, seen });
|
|
12354
|
+
}
|
|
12315
12355
|
var DENIED = /* @__PURE__ */ new Set(["EACCES", "EPERM"]);
|
|
12316
12356
|
async function rmPermitted(entry, path, req, refused3) {
|
|
12317
12357
|
const st = await entry.fs.lstat(path).catch(() => void 0);
|
|
12318
12358
|
if (!st?.isDirectory) return refused3;
|
|
12319
12359
|
const unlisted = await guarded(entry, path, { ...req, op: "readdir" });
|
|
12320
12360
|
if ("refused" in unlisted) return unlisted.refused;
|
|
12321
|
-
const
|
|
12322
|
-
if (!
|
|
12361
|
+
const names2 = await entry.fs.readdir(path).catch(() => void 0);
|
|
12362
|
+
if (!names2) return refused3;
|
|
12323
12363
|
let first;
|
|
12324
|
-
for (const name2 of
|
|
12364
|
+
for (const name2 of names2) {
|
|
12325
12365
|
const child = await dispatchOne(entry, {
|
|
12326
12366
|
...req,
|
|
12327
12367
|
path: joinName(path, name2)
|
|
@@ -12379,7 +12419,27 @@ async function newDevName(entry, path, req) {
|
|
|
12379
12419
|
if (there) return void 0;
|
|
12380
12420
|
return { ok: false, errno: refused3, message: `${target}: no new names in /dev or /proc` };
|
|
12381
12421
|
}
|
|
12422
|
+
var MISS_OPS = /* @__PURE__ */ new Set(["stat", "lstat"]);
|
|
12423
|
+
async function linkFree(fs, path) {
|
|
12424
|
+
for (let at = path.indexOf("/", 1); ; at = path.indexOf("/", at + 1)) {
|
|
12425
|
+
let st;
|
|
12426
|
+
try {
|
|
12427
|
+
st = await fs.lstat(at === -1 ? path : path.slice(0, at));
|
|
12428
|
+
} catch (err) {
|
|
12429
|
+
return err.code === "ENOENT";
|
|
12430
|
+
}
|
|
12431
|
+
if (st.isSymbolicLink || at === -1) return false;
|
|
12432
|
+
}
|
|
12433
|
+
}
|
|
12382
12434
|
async function dispatchOne(entry, req) {
|
|
12435
|
+
const result = await dispatchPath(entry, req);
|
|
12436
|
+
if (result.ok || result.errno !== "ENOENT" || !req.direct || !MISS_OPS.has(req.op) || req.handle !== void 0) {
|
|
12437
|
+
return result;
|
|
12438
|
+
}
|
|
12439
|
+
const path = entry.fs.resolvePath(entry.cwd, req.path);
|
|
12440
|
+
return await linkFree(entry.fs, path) ? { ...result, direct: true } : result;
|
|
12441
|
+
}
|
|
12442
|
+
async function dispatchPath(entry, req) {
|
|
12383
12443
|
const { fs, cwd } = entry;
|
|
12384
12444
|
try {
|
|
12385
12445
|
const path = fs.resolvePath(cwd, req.path);
|
|
@@ -12466,7 +12526,13 @@ function encodeSabResult(result) {
|
|
|
12466
12526
|
if (!result.ok) {
|
|
12467
12527
|
return {
|
|
12468
12528
|
status: SAB_STATUS_ERRNO,
|
|
12469
|
-
payload: encoder3.encode(
|
|
12529
|
+
payload: encoder3.encode(
|
|
12530
|
+
JSON.stringify({
|
|
12531
|
+
errno: result.errno,
|
|
12532
|
+
message: result.message,
|
|
12533
|
+
...result.direct ? { direct: true } : {}
|
|
12534
|
+
})
|
|
12535
|
+
)
|
|
12470
12536
|
};
|
|
12471
12537
|
}
|
|
12472
12538
|
switch (result.kind) {
|
|
@@ -15006,8 +15072,8 @@ var TlsEngine = class {
|
|
|
15006
15072
|
return n < 0 ? `${text}\u2026` : text;
|
|
15007
15073
|
}
|
|
15008
15074
|
};
|
|
15009
|
-
function alpnWire(
|
|
15010
|
-
const parts2 =
|
|
15075
|
+
function alpnWire(names2) {
|
|
15076
|
+
const parts2 = names2.map((name2) => new TextEncoder().encode(name2));
|
|
15011
15077
|
const out = new Uint8Array(parts2.reduce((n, p) => n + p.length + 1, 0));
|
|
15012
15078
|
let at = 0;
|
|
15013
15079
|
for (const part of parts2) {
|
|
@@ -15141,6 +15207,10 @@ var TlsSession = class {
|
|
|
15141
15207
|
get ciphersuite() {
|
|
15142
15208
|
return this.m._tls_ciphersuite(this.ptr);
|
|
15143
15209
|
}
|
|
15210
|
+
get lastAlert() {
|
|
15211
|
+
const last = this.m._tls_last_alert;
|
|
15212
|
+
return last ? last(this.ptr) : -1;
|
|
15213
|
+
}
|
|
15144
15214
|
get nameMismatch() {
|
|
15145
15215
|
return this.m._tls_name_mismatch(this.ptr) === 1;
|
|
15146
15216
|
}
|
|
@@ -17192,6 +17262,62 @@ function encodeReceived(got) {
|
|
|
17192
17262
|
return out;
|
|
17193
17263
|
}
|
|
17194
17264
|
|
|
17265
|
+
// src/kernel/net/tls-chain.ts
|
|
17266
|
+
var CN_MISMATCH = 4;
|
|
17267
|
+
var NOT_TRUSTED = 8;
|
|
17268
|
+
function tlv2(der, at) {
|
|
17269
|
+
if (at + 2 > der.length) return void 0;
|
|
17270
|
+
const first = der[at + 1];
|
|
17271
|
+
let body = at + 2;
|
|
17272
|
+
let length2 = first;
|
|
17273
|
+
if (first & 128) {
|
|
17274
|
+
const n = first & 127;
|
|
17275
|
+
if (n === 0 || n > 4 || body + n > der.length) return void 0;
|
|
17276
|
+
length2 = 0;
|
|
17277
|
+
for (let i = 0; i < n; i++) length2 = length2 * 256 + der[body + i];
|
|
17278
|
+
body += n;
|
|
17279
|
+
}
|
|
17280
|
+
const end = body + length2;
|
|
17281
|
+
return end > der.length ? void 0 : { start: at, body, end };
|
|
17282
|
+
}
|
|
17283
|
+
function names(der) {
|
|
17284
|
+
const cert = tlv2(der, 0);
|
|
17285
|
+
const tbs = cert && tlv2(der, cert.body);
|
|
17286
|
+
if (!tbs) return void 0;
|
|
17287
|
+
const fields = [];
|
|
17288
|
+
for (let at = tbs.body; at < tbs.end && fields.length < 6; ) {
|
|
17289
|
+
const field4 = tlv2(der, at);
|
|
17290
|
+
if (!field4) return void 0;
|
|
17291
|
+
if (fields.length > 0 || der[at] !== 160) fields.push(field4);
|
|
17292
|
+
at = field4.end;
|
|
17293
|
+
}
|
|
17294
|
+
const [, , issuer, , subject] = fields;
|
|
17295
|
+
if (!issuer || !subject) return void 0;
|
|
17296
|
+
return [der.subarray(issuer.start, issuer.end), der.subarray(subject.start, subject.end)];
|
|
17297
|
+
}
|
|
17298
|
+
function selfIssued(der) {
|
|
17299
|
+
const pair = der && names(der);
|
|
17300
|
+
if (!pair) return false;
|
|
17301
|
+
const [issuer, subject] = pair;
|
|
17302
|
+
return issuer.length === subject.length && issuer.every((b, i) => b === subject[i]);
|
|
17303
|
+
}
|
|
17304
|
+
function untrusted(chain2) {
|
|
17305
|
+
if (chain2.length === 1) {
|
|
17306
|
+
return selfIssued(chain2[0]) ? "DEPTH_ZERO_SELF_SIGNED_CERT" : "UNABLE_TO_VERIFY_LEAF_SIGNATURE";
|
|
17307
|
+
}
|
|
17308
|
+
return selfIssued(chain2.at(-1)) ? "SELF_SIGNED_CERT_IN_CHAIN" : "UNABLE_TO_GET_ISSUER_CERT_LOCALLY";
|
|
17309
|
+
}
|
|
17310
|
+
function chainError(flags2, chain2) {
|
|
17311
|
+
if (flags2 === -1) return "UNABLE_TO_VERIFY_LEAF_SIGNATURE";
|
|
17312
|
+
const rest2 = flags2 & ~CN_MISMATCH;
|
|
17313
|
+
if (rest2 === 0) return void 0;
|
|
17314
|
+
if (rest2 & NOT_TRUSTED) return untrusted(chain2);
|
|
17315
|
+
return verifyCode(rest2);
|
|
17316
|
+
}
|
|
17317
|
+
function nameMatches(flags2) {
|
|
17318
|
+
return flags2 !== -1 && (flags2 & CN_MISMATCH) === 0;
|
|
17319
|
+
}
|
|
17320
|
+
|
|
17195
17321
|
// src/kernel/net/tls-ciphers.ts
|
|
17196
17322
|
var SUITES = [
|
|
17197
17323
|
[4865, "TLS_AES_128_GCM_SHA256", "TLS_AES_128_GCM_SHA256", "TLSv1.3"],
|
|
@@ -17309,7 +17435,11 @@ function refused2(engine, session, err) {
|
|
|
17309
17435
|
if (code && flags2 !== -1)
|
|
17310
17436
|
return new KernelError("EPROTO", `${code}: ${engine.verifyInfo(flags2).trim()}`);
|
|
17311
17437
|
const text = err instanceof TlsError ? err.message : String(err);
|
|
17312
|
-
return new KernelError("EPROTO", `ERR_SSL_HANDSHAKE_FAILURE: ${text}`);
|
|
17438
|
+
return new KernelError("EPROTO", `ERR_SSL_HANDSHAKE_FAILURE: ${text}${alertOf(session)}`);
|
|
17439
|
+
}
|
|
17440
|
+
function alertOf(session) {
|
|
17441
|
+
const alert = session.lastAlert;
|
|
17442
|
+
return alert >= 0 ? ` (alert ${alert})` : "";
|
|
17313
17443
|
}
|
|
17314
17444
|
async function handshake(conn, o, session, inbox) {
|
|
17315
17445
|
for (; ; ) {
|
|
@@ -17330,7 +17460,12 @@ async function handshake(conn, o, session, inbox) {
|
|
|
17330
17460
|
}
|
|
17331
17461
|
}
|
|
17332
17462
|
}
|
|
17333
|
-
function
|
|
17463
|
+
function insecureOf(session, chain2) {
|
|
17464
|
+
const flags2 = session.verifyResult;
|
|
17465
|
+
const error = chainError(flags2, chain2);
|
|
17466
|
+
return { hostnameMatches: nameMatches(flags2), ...error ? { chainError: error } : {} };
|
|
17467
|
+
}
|
|
17468
|
+
function controlsOf(o, session, protocol, chain2) {
|
|
17334
17469
|
if (!o.engine.sessionControls) return {};
|
|
17335
17470
|
const checked = o.checkHostname !== false && !o.insecure;
|
|
17336
17471
|
return {
|
|
@@ -17338,28 +17473,29 @@ function controlsOf(o, session, protocol) {
|
|
|
17338
17473
|
clientCertificate: o.clientCertificate === true,
|
|
17339
17474
|
sni: o.sni !== false && !isIP(o.servername),
|
|
17340
17475
|
hostnameChecked: checked,
|
|
17341
|
-
...o.insecure ?
|
|
17476
|
+
...o.insecure ? insecureOf(session, chain2) : { hostnameMatches: checked || !session.nameMismatch }
|
|
17342
17477
|
};
|
|
17343
17478
|
}
|
|
17344
17479
|
function infoOf(o, session) {
|
|
17345
17480
|
const flags2 = session.verifyResult;
|
|
17346
17481
|
const code = verifyCode(flags2);
|
|
17347
17482
|
const protocol = session.version === 772 ? "TLSv1.3" : "TLSv1.2";
|
|
17483
|
+
const chain2 = session.peerChain();
|
|
17348
17484
|
return {
|
|
17349
17485
|
protocol,
|
|
17350
17486
|
alpnProtocol: session.alpn ?? false,
|
|
17351
17487
|
authorized: code === void 0,
|
|
17352
17488
|
...code ? { authorizationError: code, authorizationText: o.engine.verifyInfo(flags2).trim() } : {},
|
|
17353
|
-
peerCertificates:
|
|
17354
|
-
...controlsOf(o, session, protocol)
|
|
17489
|
+
peerCertificates: chain2,
|
|
17490
|
+
...controlsOf(o, session, protocol, chain2)
|
|
17355
17491
|
};
|
|
17356
17492
|
}
|
|
17357
17493
|
var FATAL_ALERT = -30592;
|
|
17358
|
-
function alerted(err) {
|
|
17494
|
+
function alerted(err, session) {
|
|
17359
17495
|
if (err.code === FATAL_ALERT)
|
|
17360
17496
|
return new KernelError(
|
|
17361
17497
|
"EPROTO",
|
|
17362
|
-
`ERR_SSL_FATAL_ALERT: the server ended the session: ${err.message}`
|
|
17498
|
+
`ERR_SSL_FATAL_ALERT: the server ended the session: ${err.message}${alertOf(session)}`
|
|
17363
17499
|
);
|
|
17364
17500
|
return new KernelError("EPROTO", `ERR_SSL_PROTOCOL_ERROR: ${err.message}`);
|
|
17365
17501
|
}
|
|
@@ -17381,7 +17517,7 @@ function plaintext(conn, session, inbox) {
|
|
|
17381
17517
|
try {
|
|
17382
17518
|
got = session.read();
|
|
17383
17519
|
} catch (err) {
|
|
17384
|
-
throw alerted(err);
|
|
17520
|
+
throw alerted(err, session);
|
|
17385
17521
|
}
|
|
17386
17522
|
await send(conn, session);
|
|
17387
17523
|
if (got instanceof Uint8Array) return got;
|
|
@@ -17487,7 +17623,8 @@ function controls(info) {
|
|
|
17487
17623
|
clientCertificate: info.clientCertificate === true,
|
|
17488
17624
|
sni: info.sni !== false,
|
|
17489
17625
|
hostnameChecked: info.hostnameChecked === true,
|
|
17490
|
-
...info.hostnameMatches === void 0 ? {} : { hostnameMatches: info.hostnameMatches }
|
|
17626
|
+
...info.hostnameMatches === void 0 ? {} : { hostnameMatches: info.hostnameMatches },
|
|
17627
|
+
...info.chainError ? { chainError: info.chainError } : {}
|
|
17491
17628
|
};
|
|
17492
17629
|
}
|
|
17493
17630
|
var KEY_ERRORS = [
|
|
@@ -20724,6 +20861,7 @@ function holdingToken(opts, holds2, caller) {
|
|
|
20724
20861
|
...opts.fresh ? { fresh: (path) => opts.fresh?.(path, caller.umask()) } : {},
|
|
20725
20862
|
...opts.source ? { source: opts.source } : {},
|
|
20726
20863
|
...opts.replacements ? { replacements: opts.replacements } : {},
|
|
20864
|
+
...opts.changes ? { changes: new ChangeView(opts.changes) } : {},
|
|
20727
20865
|
fs: opts.fs,
|
|
20728
20866
|
noLinks: opts.noLinks,
|
|
20729
20867
|
cwd: opts.cwd,
|
|
@@ -20743,7 +20881,7 @@ function linksOf(opts) {
|
|
|
20743
20881
|
function clipboardName(opts) {
|
|
20744
20882
|
return opts.program.abi === "js" ? {} : { clipboardName: opts.argv0 };
|
|
20745
20883
|
}
|
|
20746
|
-
function processOptions(opts, header3, hooks,
|
|
20884
|
+
function processOptions(opts, header3, hooks, created4) {
|
|
20747
20885
|
return {
|
|
20748
20886
|
...inherited(opts),
|
|
20749
20887
|
...opts.owners ? { owners: true } : {},
|
|
@@ -20753,7 +20891,7 @@ function processOptions(opts, header3, hooks, created3) {
|
|
|
20753
20891
|
...opts.readonlyAt ? { readonlyAt: opts.readonlyAt } : {},
|
|
20754
20892
|
...opts.source ? { source: opts.source } : {},
|
|
20755
20893
|
noLinks: opts.noLinks,
|
|
20756
|
-
...opts.dac ? { guard: { dac: opts.dac, fs: opts.fs, created:
|
|
20894
|
+
...opts.dac ? { guard: { dac: opts.dac, fs: opts.fs, created: created4, ...linksOf(opts) } } : {},
|
|
20757
20895
|
...opts.identity ? { identity: opts.identity } : {},
|
|
20758
20896
|
...opts.onSyscall ? { onSyscall: opts.onSyscall } : {},
|
|
20759
20897
|
...opts.settling ? { settling: opts.settling } : {},
|
|
@@ -20836,7 +20974,7 @@ function spawnWasmProcess(opts) {
|
|
|
20836
20974
|
const blocked2 = opts.fork?.wasi?.blocked ?? opts.blocked;
|
|
20837
20975
|
if (blocked2 && anyBlocked(blocked2) && opts.program.abi === "wasi") storeBlocked(header3, blocked2);
|
|
20838
20976
|
const threadSignals = /* @__PURE__ */ new Map();
|
|
20839
|
-
const
|
|
20977
|
+
const created4 = new Created();
|
|
20840
20978
|
const process = new WasmProcess(
|
|
20841
20979
|
opts.pid,
|
|
20842
20980
|
opts.fds,
|
|
@@ -20852,7 +20990,7 @@ function spawnWasmProcess(opts) {
|
|
|
20852
20990
|
exitSignal: (sig) => queueMicrotask(() => finish(128 + sig, sig))
|
|
20853
20991
|
} : { exitSignal: (sig) => terminate(128 + sig, sig) }
|
|
20854
20992
|
},
|
|
20855
|
-
|
|
20993
|
+
created4
|
|
20856
20994
|
)
|
|
20857
20995
|
);
|
|
20858
20996
|
publishStops(process, header3);
|
|
@@ -20861,7 +20999,7 @@ function spawnWasmProcess(opts) {
|
|
|
20861
20999
|
const token = holdingToken(opts, holds2, {
|
|
20862
21000
|
cred: () => process.cred,
|
|
20863
21001
|
umask: () => process.umask,
|
|
20864
|
-
created:
|
|
21002
|
+
created: created4,
|
|
20865
21003
|
holdsKept: async (path) => path.includes(`/${UNLINKED_DIR}/`) && (holds2.keeps(path) || await process.holds(path))
|
|
20866
21004
|
});
|
|
20867
21005
|
heldBy(process, holds2, opts.replacements);
|
|
@@ -21551,10 +21689,10 @@ var HOSTS_PATH = "/etc/hosts";
|
|
|
21551
21689
|
function parseHosts(text) {
|
|
21552
21690
|
const table = /* @__PURE__ */ new Map();
|
|
21553
21691
|
for (const raw of text.split("\n")) {
|
|
21554
|
-
const [address, ...
|
|
21555
|
-
if (!address ||
|
|
21692
|
+
const [address, ...names2] = raw.replace(/#.*/, "").trim().split(/\s+/);
|
|
21693
|
+
if (!address || names2.length === 0) continue;
|
|
21556
21694
|
if (ipv4Bytes(address) === void 0 && ipv6Groups(address) === void 0) continue;
|
|
21557
|
-
for (const name2 of
|
|
21695
|
+
for (const name2 of names2) {
|
|
21558
21696
|
const key = name2.toLowerCase().replace(/\.$/, "");
|
|
21559
21697
|
const known = table.get(key) ?? [];
|
|
21560
21698
|
if (!known.includes(address)) known.push(address);
|
|
@@ -23875,7 +24013,7 @@ var ChunkedBytes = class {
|
|
|
23875
24013
|
function idOption2(value2) {
|
|
23876
24014
|
return value2 !== void 0 && /^\d+$/.test(value2) ? Number(value2) : 0;
|
|
23877
24015
|
}
|
|
23878
|
-
function
|
|
24016
|
+
function created3(ino, kind, mode, from, owner) {
|
|
23879
24017
|
const now = Date.now();
|
|
23880
24018
|
return {
|
|
23881
24019
|
kind,
|
|
@@ -23910,7 +24048,7 @@ function attr(node) {
|
|
|
23910
24048
|
}
|
|
23911
24049
|
function tmpfs() {
|
|
23912
24050
|
let inodes = 0;
|
|
23913
|
-
const make = (kind, mode, from, owner) =>
|
|
24051
|
+
const make = (kind, mode, from, owner) => created3(++inodes, kind, mode, from, owner);
|
|
23914
24052
|
const root = make("directory", 16877);
|
|
23915
24053
|
const handles = /* @__PURE__ */ new Map();
|
|
23916
24054
|
let nextFh = 0;
|
|
@@ -23930,10 +24068,10 @@ function tmpfs() {
|
|
|
23930
24068
|
return node;
|
|
23931
24069
|
}
|
|
23932
24070
|
function parent(path) {
|
|
23933
|
-
const
|
|
23934
|
-
const name2 =
|
|
24071
|
+
const names2 = parts2(path);
|
|
24072
|
+
const name2 = names2.pop();
|
|
23935
24073
|
if (name2 === void 0) throw fsError2("EBUSY", "the root of a mount");
|
|
23936
|
-
const dir = find(`/${
|
|
24074
|
+
const dir = find(`/${names2.join("/")}`);
|
|
23937
24075
|
if (dir.kind !== "directory") throw fsError2("ENOTDIR", path);
|
|
23938
24076
|
return { dir, name: name2 };
|
|
23939
24077
|
}
|
|
@@ -24413,12 +24551,12 @@ var Sudo = class {
|
|
|
24413
24551
|
}
|
|
24414
24552
|
async policy() {
|
|
24415
24553
|
const rules = await this.policyFile(SUDOERS);
|
|
24416
|
-
const
|
|
24417
|
-
if (
|
|
24554
|
+
const names2 = await this.o.fs.readdir(SUDOERS_D).catch(() => []);
|
|
24555
|
+
if (names2.length > 0 && !await this.trusted(SUDOERS_D)) {
|
|
24418
24556
|
this.warn(`sudo: ${SUDOERS_D} skipped: it must be root's and writable by root only`);
|
|
24419
24557
|
return rules;
|
|
24420
24558
|
}
|
|
24421
|
-
for (const name2 of [...
|
|
24559
|
+
for (const name2 of [...names2].sort()) {
|
|
24422
24560
|
if (name2.startsWith(".") || name2.endsWith("~")) continue;
|
|
24423
24561
|
rules.push(...await this.policyFile(`${SUDOERS_D}/${name2}`));
|
|
24424
24562
|
}
|
|
@@ -24498,8 +24636,8 @@ var Sudo = class {
|
|
|
24498
24636
|
}
|
|
24499
24637
|
const path = await this.locate(word, cwd);
|
|
24500
24638
|
if (!path) return failed2("ENOENT", `sudo: ${word}: command not found`);
|
|
24501
|
-
const
|
|
24502
|
-
if (
|
|
24639
|
+
const untrusted2 = await this.untrusted(path, cwd, word);
|
|
24640
|
+
if (untrusted2) return untrusted2;
|
|
24503
24641
|
const argv = [path, ...args];
|
|
24504
24642
|
const matching = rules.filter(
|
|
24505
24643
|
(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]))
|
|
@@ -24778,10 +24916,10 @@ function shebang(head) {
|
|
|
24778
24916
|
return new TextDecoder().decode(head.subarray(0, SHEBANG_MAX)).slice(2).split("\n")[0].trim().split(/[ \t]+/);
|
|
24779
24917
|
}
|
|
24780
24918
|
async function rootOnly(fs, path, dir = false) {
|
|
24781
|
-
const
|
|
24782
|
-
for (const [i, at] of
|
|
24919
|
+
const names2 = chain(path);
|
|
24920
|
+
for (const [i, at] of names2.entries()) {
|
|
24783
24921
|
const st = await fs.lstat(at).catch(() => void 0);
|
|
24784
|
-
const kind = i ===
|
|
24922
|
+
const kind = i === names2.length - 1 && !dir ? st?.isFile : st?.isDirectory;
|
|
24785
24923
|
if (!kind || st?.uid !== 0 || (st.mode & 18) !== 0) return false;
|
|
24786
24924
|
}
|
|
24787
24925
|
return true;
|
|
@@ -25790,7 +25928,7 @@ var Launcher = class {
|
|
|
25790
25928
|
return { glue, module: module2 };
|
|
25791
25929
|
}
|
|
25792
25930
|
const { module, memory, foreign } = await this.module(target.wasm, caller, asked);
|
|
25793
|
-
const
|
|
25931
|
+
const names2 = env.SLICC_WASM_BACKTRACE === "1" ? await this.names(target.wasm, module) : void 0;
|
|
25794
25932
|
const imports = target.imports ? await this.text(target.imports, caller) : void 0;
|
|
25795
25933
|
return {
|
|
25796
25934
|
abi: "wasi",
|
|
@@ -25799,7 +25937,7 @@ var Launcher = class {
|
|
|
25799
25937
|
...memory ? { memory } : {},
|
|
25800
25938
|
foreign,
|
|
25801
25939
|
path: target.wasm,
|
|
25802
|
-
...
|
|
25940
|
+
...names2 ? { names: names2 } : {},
|
|
25803
25941
|
...imports !== void 0 ? { imports } : {},
|
|
25804
25942
|
...target.preopenRoot ? { preopenRoot: true } : {}
|
|
25805
25943
|
};
|
|
@@ -26581,10 +26719,10 @@ var Launcher = class {
|
|
|
26581
26719
|
const real = await this.realLayoutPath("/tmp");
|
|
26582
26720
|
const st = real === void 0 ? void 0 : await this.base.lstat(real).catch(() => void 0);
|
|
26583
26721
|
if (real !== void 0 && st?.isDirectory && this.base.hasOwner && !await this.base.hasOwner(real)) {
|
|
26584
|
-
const
|
|
26722
|
+
const names2 = await this.base.readdir(real).catch(() => void 0);
|
|
26585
26723
|
let removed = 0;
|
|
26586
|
-
let left =
|
|
26587
|
-
for (const name2 of
|
|
26724
|
+
let left = names2 === void 0 ? 1 : 0;
|
|
26725
|
+
for (const name2 of names2 ?? []) {
|
|
26588
26726
|
const path = joinName(real, name2);
|
|
26589
26727
|
if (await this.base.hasOwner(path)) continue;
|
|
26590
26728
|
const failed3 = this.inUse(path) ? "busy" : await this.base.rm(path, { recursive: true, force: true }).catch(String);
|
|
@@ -26862,12 +27000,12 @@ var Launcher = class {
|
|
|
26862
27000
|
}
|
|
26863
27001
|
named = /* @__PURE__ */ new WeakMap();
|
|
26864
27002
|
commandNames(commands) {
|
|
26865
|
-
let
|
|
26866
|
-
if (!
|
|
26867
|
-
|
|
26868
|
-
this.named.set(commands,
|
|
27003
|
+
let names2 = this.named.get(commands);
|
|
27004
|
+
if (!names2) {
|
|
27005
|
+
names2 = new Set(commands.keys());
|
|
27006
|
+
this.named.set(commands, names2);
|
|
26869
27007
|
}
|
|
26870
|
-
return
|
|
27008
|
+
return names2;
|
|
26871
27009
|
}
|
|
26872
27010
|
async entryTarget(path) {
|
|
26873
27011
|
const system = COMMAND2.exec(path)?.[1];
|