@ai-ecoverse/slicc-kernel 1.125.1 → 1.125.3

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.
@@ -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 names = asked === void 0 ? [] : await namesOf(this.root, asked);
532
- if (real !== at) names.push(...await namesOf(this.root, at));
533
- const name2 = names.findLast((p) => isProtected(this.prefixes, p));
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 names = meta.fresh ? [...META_OPS, "fresh"] : META_OPS;
1122
- const ops = Object.fromEntries(names.map((op) => [op, guarded2(op)]));
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 [names, op] of [
2481
+ for (const [names2, op] of [
2482
2482
  [READS, "read"],
2483
2483
  [WRITES, "write"]
2484
2484
  ]) {
2485
- for (const name2 of names) {
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 names = chain(path);
3498
+ const names2 = chain(path);
3499
3499
  const perms = await ancestryOf(this.fs, path);
3500
- for (let i = 0; i < names.length; i++) {
3500
+ for (let i = 0; i < names2.length; i++) {
3501
3501
  const perm = perms[i];
3502
- this.known.set(names[i], perm);
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, names) {
5735
- return names.map((g) => {
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.1" : "0.0.0-dev";
6635
+ var KERNEL_VERSION = true ? "1.125.3" : "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 names = await fs.readdir(modules).catch(() => []);
6790
+ const names2 = await fs.readdir(modules).catch(() => []);
6791
6791
  const packageNames = [];
6792
- for (const name2 of names) {
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 = (names) => names.filter((name2) => name2 !== UNLINKED_DIR);
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 names = await this.fs.readdir(dir).catch(() => void 0);
7805
- if (!names) return;
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 names) {
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 names = await fs.readdir(SPOOL_DIR).catch((err) => {
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 names.sort()) {
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, names, userDir = async () => void 0, owners = false, targetOf2 = async () => void 0) {
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 names()];
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 names()).has(name2) ? owned4(synthetic(false, path)) : void 0;
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 names();
9152
+ const now = await names2();
9122
9153
  if (now !== generation) {
9123
9154
  generation = now;
9124
9155
  targets.clear();
@@ -9627,22 +9658,22 @@ 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 created3 = [];
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 (created3.length > 0 || !await fs.exists(ancestor)) created3.push(ancestor);
9666
+ if (created4.length > 0 || !await fs.exists(ancestor)) created4.push(ancestor);
9636
9667
  }
9637
9668
  }
9638
- const fresh2 = !options?.recursive || !(this.covers(path) && await fs.exists(path));
9669
+ const fresh2 = !options?.recursive || this.typed.size > 0 && !await fs.exists(path);
9639
9670
  let done4 = false;
9640
9671
  try {
9641
9672
  await fs.mkdir(path, options);
9642
9673
  done4 = true;
9643
9674
  } finally {
9644
- this.report([...created3, path]);
9645
- if (done4) this.emit("rename", fresh2 ? [...created3, path] : created3);
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 names = chain(normalizePath(path));
11620
- const first = names.findIndex((name2) => this.at(name2));
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, names[first - 1]);
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 names.slice(first)) {
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 created3 = (mode & HOLD_CREATED) !== 0 && entry.created?.take(path) === true;
12115
- if (g && want !== 0 && !created3) {
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 names = await entry.fs.readdir(path).catch(() => void 0);
12322
- if (!names) return refused3;
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 names) {
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(JSON.stringify({ errno: result.errno, message: result.message }))
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(names) {
15010
- const parts2 = names.map((name2) => new TextEncoder().encode(name2));
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 controlsOf(o, session, protocol) {
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 ? {} : { hostnameMatches: checked || !session.nameMismatch }
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: session.peerChain(),
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, created3) {
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: created3, ...linksOf(opts) } } : {},
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 created3 = new Created();
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
- created3
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: created3,
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, ...names] = raw.replace(/#.*/, "").trim().split(/\s+/);
21555
- if (!address || names.length === 0) continue;
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 names) {
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 created2(ino, kind, mode, from, owner) {
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) => created2(++inodes, 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 names = parts2(path);
23934
- const name2 = names.pop();
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(`/${names.join("/")}`);
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 names = await this.o.fs.readdir(SUDOERS_D).catch(() => []);
24417
- if (names.length > 0 && !await this.trusted(SUDOERS_D)) {
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 [...names].sort()) {
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 untrusted = await this.untrusted(path, cwd, word);
24502
- if (untrusted) return untrusted;
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 names = chain(path);
24782
- for (const [i, at] of names.entries()) {
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 === names.length - 1 && !dir ? st?.isFile : st?.isDirectory;
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 names = env.SLICC_WASM_BACKTRACE === "1" ? await this.names(target.wasm, module) : void 0;
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
- ...names ? { names } : {},
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 names = await this.base.readdir(real).catch(() => void 0);
26722
+ const names2 = await this.base.readdir(real).catch(() => void 0);
26585
26723
  let removed = 0;
26586
- let left = names === void 0 ? 1 : 0;
26587
- for (const name2 of names ?? []) {
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 names = this.named.get(commands);
26866
- if (!names) {
26867
- names = new Set(commands.keys());
26868
- this.named.set(commands, names);
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 names;
27008
+ return names2;
26871
27009
  }
26872
27010
  async entryTarget(path) {
26873
27011
  const system = COMMAND2.exec(path)?.[1];