@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/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 names = chain(path);
400
+ const names2 = chain(path);
401
401
  const perms = await ancestryOf(this.fs, path);
402
- for (let i = 0; i < names.length; i++) {
402
+ for (let i = 0; i < names2.length; i++) {
403
403
  const perm = perms[i];
404
- this.known.set(names[i], perm);
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, names) {
2856
- return names.map((g) => {
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 names = asked === void 0 ? [] : await namesOf(this.root, asked);
3808
- if (real !== at) names.push(...await namesOf(this.root, at));
3809
- const name2 = names.findLast((p) => isProtected(this.prefixes, p));
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 names = meta.fresh ? [...META_OPS, "fresh"] : META_OPS;
4385
- const ops = Object.fromEntries(names.map((op) => [op, guarded3(op)]));
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 [names, op] of [
5740
+ for (const [names2, op] of [
5741
5741
  [READS, "read"],
5742
5742
  [WRITES, "write"]
5743
5743
  ]) {
5744
- for (const name2 of names) {
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 = (names) => names.filter((name2) => name2 !== UNLINKED_DIR);
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 names = await this.fs.readdir(dir).catch(() => void 0);
6116
- if (!names) return;
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 names) {
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.0" : "0.0.0-dev";
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 names = await fs.readdir(modules).catch(() => []);
7244
+ const names2 = await fs.readdir(modules).catch(() => []);
7245
7245
  const packageNames = [];
7246
- for (const name2 of names) {
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 names = await fs.readdir(SPOOL_DIR).catch((err) => {
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 names.sort()) {
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, names, userDir = async () => void 0, owners = false, targetOf2 = async () => void 0) {
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 names()];
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 names()).has(name2) ? owned4(synthetic(false, path)) : void 0;
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 names();
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 created3 = [];
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 (created3.length > 0 || !await fs.exists(ancestor)) created3.push(ancestor);
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([...created3, path]);
9740
- if (done4) this.emit("rename", fresh2 ? [...created3, path] : created3);
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 names = chain(normalizePath(path));
11715
- const first = names.findIndex((name2) => this.at(name2));
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, names[first - 1]);
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 names.slice(first)) {
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 created3 = (mode & HOLD_CREATED) !== 0 && entry.created?.take(path) === true;
12210
- if (g && want !== 0 && !created3) {
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 names = await entry.fs.readdir(path).catch(() => void 0);
12417
- if (!names) return refused3;
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 names) {
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(JSON.stringify({ errno: result.errno, message: result.message }))
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(names) {
15061
- const parts2 = names.map((name2) => new TextEncoder().encode(name2));
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 controlsOf(o, session, protocol) {
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 ? {} : { hostnameMatches: checked || !session.nameMismatch }
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: session.peerChain(),
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, created3) {
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: created3, ...linksOf(opts) } } : {},
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 created3 = new Created();
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
- created3
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: created3,
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, ...names] = raw.replace(/#.*/, "").trim().split(/\s+/);
21492
- if (!address || names.length === 0) continue;
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 names) {
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 created2(ino, kind, mode, from, owner) {
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) => created2(++inodes, 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 names = parts2(path);
23943
- const name2 = names.pop();
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(`/${names.join("/")}`);
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 names = await this.o.fs.readdir(SUDOERS_D).catch(() => []);
24426
- if (names.length > 0 && !await this.trusted(SUDOERS_D)) {
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 [...names].sort()) {
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 untrusted = await this.untrusted(path, cwd, word);
24511
- if (untrusted) return untrusted;
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 names = chain(path);
24787
- for (const [i, at] of names.entries()) {
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 === names.length - 1 && !dir ? st?.isFile : st?.isDirectory;
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 names = env.SLICC_WASM_BACKTRACE === "1" ? await this.names(target.wasm, module) : void 0;
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
- ...names ? { names } : {},
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 names = await this.base.readdir(real).catch(() => void 0);
26727
+ const names2 = await this.base.readdir(real).catch(() => void 0);
26590
26728
  let removed = 0;
26591
- let left = names === void 0 ? 1 : 0;
26592
- for (const name2 of names ?? []) {
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 names = this.named.get(commands);
26871
- if (!names) {
26872
- names = new Set(commands.keys());
26873
- this.named.set(commands, names);
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 names;
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 names = [];
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
- names.unshift(at.name);
27508
+ names2.unshift(at.name);
27371
27509
  }
27372
- return names;
27510
+ return names2;
27373
27511
  }
27374
27512
  remove() {
27375
27513
  this.removed = true;