@ai-ecoverse/slicc-kernel 1.124.11 → 1.124.13
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 +30 -9
- package/dist/index.js.map +2 -2
- package/dist/kernel-worker.js +308 -53
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-process-worker.js +4424 -4329
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +313 -58
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +7111 -7016
- package/dist/process-worker.js.map +4 -4
- package/dist/types/fs/unlinked.d.ts +1 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/kernel/net/tls-ciphers.d.ts +6 -0
- package/dist/types/kernel/net/tls-client.d.ts +13 -1
- package/dist/types/kernel/net/tls-engine.d.ts +10 -0
- package/dist/types/kernel/net/tls-uplink.d.ts +14 -1
- package/dist/types/kernel/net/uplink-socket.d.ts +1 -1
- package/dist/types/kernel/socket-syscalls.d.ts +7 -0
- package/dist/types/kernel/vfs-file.d.ts +2 -0
- package/dist/types/process/js/js-dev.d.ts +1 -0
- package/dist/types/process/js/js-net.d.ts +16 -0
- package/dist/types/process/process-fds.d.ts +1 -1
- package/dist/types/process/wasi/wasi-host.d.ts +1 -0
- package/package.json +3 -3
package/dist/node.js
CHANGED
|
@@ -1557,8 +1557,8 @@ function uplinkLink(conn, onReset) {
|
|
|
1557
1557
|
open = false;
|
|
1558
1558
|
conn.close();
|
|
1559
1559
|
};
|
|
1560
|
-
void inbound(conn, rx).catch(() => {
|
|
1561
|
-
onReset();
|
|
1560
|
+
void inbound(conn, rx).catch((err) => {
|
|
1561
|
+
onReset(err);
|
|
1562
1562
|
close();
|
|
1563
1563
|
tx.closeRead();
|
|
1564
1564
|
}).finally(() => rx.closeWrite());
|
|
@@ -1649,7 +1649,7 @@ var KernelSocket = class _KernelSocket {
|
|
|
1649
1649
|
state = "open";
|
|
1650
1650
|
dialing;
|
|
1651
1651
|
failed;
|
|
1652
|
-
reset
|
|
1652
|
+
reset;
|
|
1653
1653
|
local;
|
|
1654
1654
|
peer;
|
|
1655
1655
|
peerCred;
|
|
@@ -1688,19 +1688,20 @@ var KernelSocket = class _KernelSocket {
|
|
|
1688
1688
|
const { rx } = this.connection();
|
|
1689
1689
|
if (this.readShut || max <= 0) return new Uint8Array(0);
|
|
1690
1690
|
const bytes = await pipeCall(() => rx.read(max, signal));
|
|
1691
|
-
if (bytes.length === 0 && this.reset) throw
|
|
1691
|
+
if (bytes.length === 0 && this.reset) throw this.reset;
|
|
1692
1692
|
return bytes;
|
|
1693
1693
|
}
|
|
1694
1694
|
async peek(max, signal) {
|
|
1695
1695
|
const { rx } = this.connection();
|
|
1696
1696
|
if (this.readShut || max <= 0) return new Uint8Array(0);
|
|
1697
1697
|
const bytes = await pipeCall(() => rx.peek(max, signal));
|
|
1698
|
-
if (bytes.length === 0 && this.reset) throw
|
|
1698
|
+
if (bytes.length === 0 && this.reset) throw this.reset;
|
|
1699
1699
|
return bytes;
|
|
1700
1700
|
}
|
|
1701
1701
|
async write(bytes, signal) {
|
|
1702
1702
|
const { tx } = this.connection();
|
|
1703
1703
|
if (this.writeShut) throw new KernelError("EPIPE");
|
|
1704
|
+
if (this.reset?.code === "EPROTO") throw this.reset;
|
|
1704
1705
|
return pipeCall(() => tx.write(bytes, signal));
|
|
1705
1706
|
}
|
|
1706
1707
|
poll() {
|
|
@@ -1885,8 +1886,8 @@ var KernelSocket = class _KernelSocket {
|
|
|
1885
1886
|
this.dialing = void 0;
|
|
1886
1887
|
this.switch = conn;
|
|
1887
1888
|
this.attach(
|
|
1888
|
-
uplinkLink(conn, () => {
|
|
1889
|
-
this.reset =
|
|
1889
|
+
uplinkLink(conn, (err) => {
|
|
1890
|
+
this.reset = err instanceof KernelError && err.code === "EPROTO" ? err : new KernelError("ECONNRESET");
|
|
1890
1891
|
this.changes.wake();
|
|
1891
1892
|
})
|
|
1892
1893
|
);
|
|
@@ -5993,16 +5994,24 @@ var UnlinkedKeeper = class {
|
|
|
5993
5994
|
gated();
|
|
5994
5995
|
const held = /* @__PURE__ */ new Map();
|
|
5995
5996
|
const hidden = /* @__PURE__ */ new Map();
|
|
5996
|
-
|
|
5997
|
-
|
|
5998
|
-
|
|
5999
|
-
|
|
6000
|
-
|
|
6001
|
-
|
|
6002
|
-
|
|
6003
|
-
const
|
|
6004
|
-
|
|
5997
|
+
const moved2 = [];
|
|
5998
|
+
try {
|
|
5999
|
+
for (; ; ) {
|
|
6000
|
+
await take();
|
|
6001
|
+
const now = this.heldWithin(target);
|
|
6002
|
+
const next3 = paths.filter((path) => now.has(path) && !held.has(path));
|
|
6003
|
+
if (next3.length === 0) break;
|
|
6004
|
+
for (const path of next3) {
|
|
6005
|
+
const holders = now.get(path);
|
|
6006
|
+
held.set(path, holders);
|
|
6007
|
+
for (const holder of holders) moved2.push(holder.moving?.(path) ?? (() => void 0));
|
|
6008
|
+
const at = await this.hide(path);
|
|
6009
|
+
if (at !== void 0) hidden.set(path, at);
|
|
6010
|
+
}
|
|
6005
6011
|
}
|
|
6012
|
+
} catch (err) {
|
|
6013
|
+
for (const settle of moved2) settle();
|
|
6014
|
+
throw err;
|
|
6006
6015
|
}
|
|
6007
6016
|
sealed();
|
|
6008
6017
|
const done4 = () => {
|
|
@@ -6015,6 +6024,7 @@ var UnlinkedKeeper = class {
|
|
|
6015
6024
|
files.set(path, file);
|
|
6016
6025
|
for (const holder of holders) holder.keep(path, file);
|
|
6017
6026
|
}
|
|
6027
|
+
for (const settle of moved2) settle();
|
|
6018
6028
|
return {
|
|
6019
6029
|
moved: new Set(hidden.keys()),
|
|
6020
6030
|
commit: () => {
|
|
@@ -7070,7 +7080,7 @@ function satisfies(version, range2) {
|
|
|
7070
7080
|
}
|
|
7071
7081
|
|
|
7072
7082
|
// src/version.ts
|
|
7073
|
-
var KERNEL_VERSION = true ? "1.124.
|
|
7083
|
+
var KERNEL_VERSION = true ? "1.124.13" : "0.0.0-dev";
|
|
7074
7084
|
var OS_RELEASE = "6.0.0-slicc";
|
|
7075
7085
|
function procVersion() {
|
|
7076
7086
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -12489,6 +12499,10 @@ function attachSyncSabResponder(port, sab, token, opts) {
|
|
|
12489
12499
|
Atomics.add(header4, SAB_I_PUB, 1);
|
|
12490
12500
|
Atomics.notify(header4, SAB_I_PUB);
|
|
12491
12501
|
if (offset + chunk2 >= entry.payload.byteLength) drop(id2);
|
|
12502
|
+
else if (entry.timer) {
|
|
12503
|
+
clearTimeout(entry.timer);
|
|
12504
|
+
entry.timer = setTimeout(() => drop(id2), PENDING_TTL_MS);
|
|
12505
|
+
}
|
|
12492
12506
|
}
|
|
12493
12507
|
function settle(id2, result) {
|
|
12494
12508
|
if (disposed) return;
|
|
@@ -14820,6 +14834,8 @@ function realmCa(owner, store) {
|
|
|
14820
14834
|
|
|
14821
14835
|
// src/kernel/net/tls-engine.ts
|
|
14822
14836
|
var TLS_CLIENT_INSECURE_SKIP_VERIFY = 1;
|
|
14837
|
+
var TLS_CLIENT_NO_SNI = 2;
|
|
14838
|
+
var TLS_CLIENT_VERIFY_CHAIN_ONLY = 4;
|
|
14823
14839
|
var SCRATCH = 64 * 1024;
|
|
14824
14840
|
var EOF = -1;
|
|
14825
14841
|
var TlsError = class extends Error {
|
|
@@ -14876,10 +14892,22 @@ var TlsEngine = class {
|
|
|
14876
14892
|
this.m._free(ptr);
|
|
14877
14893
|
}
|
|
14878
14894
|
}
|
|
14895
|
+
withSecret(bytes, fn) {
|
|
14896
|
+
const ptr = this.put(bytes);
|
|
14897
|
+
try {
|
|
14898
|
+
return fn(ptr);
|
|
14899
|
+
} finally {
|
|
14900
|
+
this.m.HEAPU8.fill(0, ptr, ptr + bytes.length + 1);
|
|
14901
|
+
this.m._free(ptr);
|
|
14902
|
+
}
|
|
14903
|
+
}
|
|
14879
14904
|
intoScratch(fn) {
|
|
14880
14905
|
const n = fn(this.scratch, SCRATCH);
|
|
14881
14906
|
return n > 0 ? this.taken(n) : n;
|
|
14882
14907
|
}
|
|
14908
|
+
get sessionControls() {
|
|
14909
|
+
return typeof this.m._tls_client_cert === "function";
|
|
14910
|
+
}
|
|
14883
14911
|
get client() {
|
|
14884
14912
|
return typeof this.m._tls_client_new === "function" ? this.m : void 0;
|
|
14885
14913
|
}
|
|
@@ -15032,6 +15060,27 @@ var TlsSession = class {
|
|
|
15032
15060
|
const out = this.engine.intoScratch((p, max) => this.c._tls_alpn(this.ptr, p, max));
|
|
15033
15061
|
return out instanceof Uint8Array ? new TextDecoder().decode(out) : void 0;
|
|
15034
15062
|
}
|
|
15063
|
+
ownCert(chain2, key, pass2) {
|
|
15064
|
+
const set3 = this.m._tls_client_cert;
|
|
15065
|
+
const keyLen = key[0] === 45 ? key.length + 1 : key.length;
|
|
15066
|
+
const ret = this.engine.withBytes(
|
|
15067
|
+
chain2,
|
|
15068
|
+
(c) => this.engine.withSecret(
|
|
15069
|
+
key,
|
|
15070
|
+
(k) => this.engine.withSecret(
|
|
15071
|
+
pass2,
|
|
15072
|
+
(p) => set3(this.ptr, c, chain2.length, k, keyLen, pass2.length > 0 ? p : 0, pass2.length)
|
|
15073
|
+
)
|
|
15074
|
+
)
|
|
15075
|
+
);
|
|
15076
|
+
if (ret !== 0) throw this.engine.error(ret, "client certificate");
|
|
15077
|
+
}
|
|
15078
|
+
get ciphersuite() {
|
|
15079
|
+
return this.m._tls_ciphersuite(this.ptr);
|
|
15080
|
+
}
|
|
15081
|
+
get nameMismatch() {
|
|
15082
|
+
return this.m._tls_name_mismatch(this.ptr) === 1;
|
|
15083
|
+
}
|
|
15035
15084
|
peerChain() {
|
|
15036
15085
|
const chain2 = [];
|
|
15037
15086
|
const count2 = this.c._tls_peer_count(this.ptr);
|
|
@@ -16336,11 +16385,11 @@ async function runChild(req, deps) {
|
|
|
16336
16385
|
if (pid !== 0) kill();
|
|
16337
16386
|
decided.resolve();
|
|
16338
16387
|
};
|
|
16339
|
-
const
|
|
16388
|
+
const controls2 = [];
|
|
16340
16389
|
const capture = () => {
|
|
16341
16390
|
const { promise, resolve: resolve2 } = Promise.withResolvers();
|
|
16342
16391
|
const control = { shut: false, ended: resolve2, eof: promise };
|
|
16343
|
-
|
|
16392
|
+
controls2.push(control);
|
|
16344
16393
|
return { capture: true, max, overflow: () => stop("ENOBUFS"), control };
|
|
16345
16394
|
};
|
|
16346
16395
|
const decided = Promise.withResolvers();
|
|
@@ -16374,11 +16423,11 @@ async function runChild(req, deps) {
|
|
|
16374
16423
|
let status;
|
|
16375
16424
|
try {
|
|
16376
16425
|
status = await reaped(deps, pid);
|
|
16377
|
-
const open =
|
|
16426
|
+
const open = controls2.filter((c) => c.opened);
|
|
16378
16427
|
await Promise.race([Promise.all(open.map((c) => c.eof)), decided.promise]);
|
|
16379
16428
|
} finally {
|
|
16380
16429
|
cancel?.();
|
|
16381
|
-
for (const control of
|
|
16430
|
+
for (const control of controls2) control.shut = true;
|
|
16382
16431
|
}
|
|
16383
16432
|
const out = deps.children.captured(pid, 1);
|
|
16384
16433
|
const err = deps.children.captured(pid, 2);
|
|
@@ -16960,6 +17009,47 @@ function encodeReceived(got) {
|
|
|
16960
17009
|
return out;
|
|
16961
17010
|
}
|
|
16962
17011
|
|
|
17012
|
+
// src/kernel/net/tls-ciphers.ts
|
|
17013
|
+
var SUITES = [
|
|
17014
|
+
[4865, "TLS_AES_128_GCM_SHA256", "TLS_AES_128_GCM_SHA256", "TLSv1.3"],
|
|
17015
|
+
[4866, "TLS_AES_256_GCM_SHA384", "TLS_AES_256_GCM_SHA384", "TLSv1.3"],
|
|
17016
|
+
[4867, "TLS_CHACHA20_POLY1305_SHA256", "TLS_CHACHA20_POLY1305_SHA256", "TLSv1.3"],
|
|
17017
|
+
[4868, "TLS_AES_128_CCM_SHA256", "TLS_AES_128_CCM_SHA256", "TLSv1.3"],
|
|
17018
|
+
[4869, "TLS_AES_128_CCM_8_SHA256", "TLS_AES_128_CCM_8_SHA256", "TLSv1.3"],
|
|
17019
|
+
[49195, "ECDHE-ECDSA-AES128-GCM-SHA256", "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLSv1.2"],
|
|
17020
|
+
[49196, "ECDHE-ECDSA-AES256-GCM-SHA384", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "TLSv1.2"],
|
|
17021
|
+
[49199, "ECDHE-RSA-AES128-GCM-SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLSv1.2"],
|
|
17022
|
+
[49200, "ECDHE-RSA-AES256-GCM-SHA384", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLSv1.2"],
|
|
17023
|
+
[52392, "ECDHE-RSA-CHACHA20-POLY1305", "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", "TLSv1.2"],
|
|
17024
|
+
[
|
|
17025
|
+
52393,
|
|
17026
|
+
"ECDHE-ECDSA-CHACHA20-POLY1305",
|
|
17027
|
+
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
|
|
17028
|
+
"TLSv1.2"
|
|
17029
|
+
],
|
|
17030
|
+
[49187, "ECDHE-ECDSA-AES128-SHA256", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", "TLSv1.2"],
|
|
17031
|
+
[49188, "ECDHE-ECDSA-AES256-SHA384", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", "TLSv1.2"],
|
|
17032
|
+
[49191, "ECDHE-RSA-AES128-SHA256", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "TLSv1.2"],
|
|
17033
|
+
[49192, "ECDHE-RSA-AES256-SHA384", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", "TLSv1.2"],
|
|
17034
|
+
[49161, "ECDHE-ECDSA-AES128-SHA", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", "TLSv1.0"],
|
|
17035
|
+
[49162, "ECDHE-ECDSA-AES256-SHA", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", "TLSv1.0"],
|
|
17036
|
+
[49171, "ECDHE-RSA-AES128-SHA", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "TLSv1.0"],
|
|
17037
|
+
[49172, "ECDHE-RSA-AES256-SHA", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "TLSv1.0"],
|
|
17038
|
+
[156, "AES128-GCM-SHA256", "TLS_RSA_WITH_AES_128_GCM_SHA256", "TLSv1.2"],
|
|
17039
|
+
[157, "AES256-GCM-SHA384", "TLS_RSA_WITH_AES_256_GCM_SHA384", "TLSv1.2"],
|
|
17040
|
+
[158, "DHE-RSA-AES128-GCM-SHA256", "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", "TLSv1.2"],
|
|
17041
|
+
[159, "DHE-RSA-AES256-GCM-SHA384", "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", "TLSv1.2"]
|
|
17042
|
+
];
|
|
17043
|
+
function cipherOf(id2, protocol) {
|
|
17044
|
+
const known = SUITES.find(([n]) => n === id2);
|
|
17045
|
+
const hex3 = `0x${id2.toString(16).padStart(4, "0").toUpperCase()}`;
|
|
17046
|
+
return {
|
|
17047
|
+
name: known?.[1] ?? hex3,
|
|
17048
|
+
standardName: known?.[2] ?? hex3,
|
|
17049
|
+
version: known?.[3] ?? protocol
|
|
17050
|
+
};
|
|
17051
|
+
}
|
|
17052
|
+
|
|
16963
17053
|
// src/kernel/net/tls-client.ts
|
|
16964
17054
|
var WRITE_CHUNK = 16 * 1024;
|
|
16965
17055
|
var BADCERT = [
|
|
@@ -16976,6 +17066,15 @@ function verifyCode(flags2) {
|
|
|
16976
17066
|
if (flags2 === -1) return "UNABLE_TO_VERIFY_LEAF_SIGNATURE";
|
|
16977
17067
|
return BADCERT.find(([bit]) => (flags2 & bit) !== 0)?.[1] ?? "UNABLE_TO_VERIFY_LEAF_SIGNATURE";
|
|
16978
17068
|
}
|
|
17069
|
+
function isIP(name2) {
|
|
17070
|
+
return ipv4Bytes(name2) !== void 0 || name2.includes(":") && ipv6Groups(name2) !== void 0;
|
|
17071
|
+
}
|
|
17072
|
+
function clientFlags(o) {
|
|
17073
|
+
return (o.insecure ? TLS_CLIENT_INSECURE_SKIP_VERIFY : 0) | (o.sni === false ? TLS_CLIENT_NO_SNI : 0) | (o.checkHostname === false ? TLS_CLIENT_VERIFY_CHAIN_ONLY : 0);
|
|
17074
|
+
}
|
|
17075
|
+
function openSession(o) {
|
|
17076
|
+
return o.engine.clientSession(o.store, o.servername, o.alpn, clientFlags(o));
|
|
17077
|
+
}
|
|
16979
17078
|
var Ciphertext = class {
|
|
16980
17079
|
queue = [];
|
|
16981
17080
|
ended = false;
|
|
@@ -17048,17 +17147,39 @@ async function handshake(conn, o, session, inbox) {
|
|
|
17048
17147
|
}
|
|
17049
17148
|
}
|
|
17050
17149
|
}
|
|
17150
|
+
function controlsOf(o, session, protocol) {
|
|
17151
|
+
if (!o.engine.sessionControls) return {};
|
|
17152
|
+
const checked = o.checkHostname !== false && !o.insecure;
|
|
17153
|
+
return {
|
|
17154
|
+
cipher: cipherOf(session.ciphersuite, protocol),
|
|
17155
|
+
clientCertificate: o.clientCertificate === true,
|
|
17156
|
+
sni: o.sni !== false && !isIP(o.servername),
|
|
17157
|
+
hostnameChecked: checked,
|
|
17158
|
+
...o.insecure ? {} : { hostnameMatches: checked || !session.nameMismatch }
|
|
17159
|
+
};
|
|
17160
|
+
}
|
|
17051
17161
|
function infoOf(o, session) {
|
|
17052
17162
|
const flags2 = session.verifyResult;
|
|
17053
17163
|
const code = verifyCode(flags2);
|
|
17164
|
+
const protocol = session.version === 772 ? "TLSv1.3" : "TLSv1.2";
|
|
17054
17165
|
return {
|
|
17055
|
-
protocol
|
|
17166
|
+
protocol,
|
|
17056
17167
|
alpnProtocol: session.alpn ?? false,
|
|
17057
17168
|
authorized: code === void 0,
|
|
17058
17169
|
...code ? { authorizationError: code, authorizationText: o.engine.verifyInfo(flags2).trim() } : {},
|
|
17059
|
-
peerCertificates: session.peerChain()
|
|
17170
|
+
peerCertificates: session.peerChain(),
|
|
17171
|
+
...controlsOf(o, session, protocol)
|
|
17060
17172
|
};
|
|
17061
17173
|
}
|
|
17174
|
+
var FATAL_ALERT = -30592;
|
|
17175
|
+
function alerted(err) {
|
|
17176
|
+
if (err.code === FATAL_ALERT)
|
|
17177
|
+
return new KernelError(
|
|
17178
|
+
"EPROTO",
|
|
17179
|
+
`ERR_SSL_FATAL_ALERT: the server ended the session: ${err.message}`
|
|
17180
|
+
);
|
|
17181
|
+
return new KernelError("EPROTO", `ERR_SSL_PROTOCOL_ERROR: ${err.message}`);
|
|
17182
|
+
}
|
|
17062
17183
|
function plaintext(conn, session, inbox) {
|
|
17063
17184
|
let freed = false;
|
|
17064
17185
|
let writeClosed = false;
|
|
@@ -17073,7 +17194,12 @@ function plaintext(conn, session, inbox) {
|
|
|
17073
17194
|
async read() {
|
|
17074
17195
|
for (; ; ) {
|
|
17075
17196
|
if (freed) return null;
|
|
17076
|
-
|
|
17197
|
+
let got;
|
|
17198
|
+
try {
|
|
17199
|
+
got = session.read();
|
|
17200
|
+
} catch (err) {
|
|
17201
|
+
throw alerted(err);
|
|
17202
|
+
}
|
|
17077
17203
|
await send(conn, session);
|
|
17078
17204
|
if (got instanceof Uint8Array) return got;
|
|
17079
17205
|
if (got === "eof") return null;
|
|
@@ -17101,8 +17227,7 @@ function plaintext(conn, session, inbox) {
|
|
|
17101
17227
|
};
|
|
17102
17228
|
}
|
|
17103
17229
|
async function tlsClient(conn, o, taken = new Uint8Array(0)) {
|
|
17104
|
-
const
|
|
17105
|
-
const session = o.engine.clientSession(o.store, o.servername, o.alpn, flags2);
|
|
17230
|
+
const session = o.session ?? openSession(o);
|
|
17106
17231
|
const inbox = new Ciphertext(conn, session);
|
|
17107
17232
|
inbox.hand(taken);
|
|
17108
17233
|
try {
|
|
@@ -17115,10 +17240,10 @@ async function tlsClient(conn, o, taken = new Uint8Array(0)) {
|
|
|
17115
17240
|
}
|
|
17116
17241
|
|
|
17117
17242
|
// src/kernel/net/tls-uplink.ts
|
|
17118
|
-
var
|
|
17243
|
+
var isIP2 = (text) => ipv4Bytes(text) !== void 0 || text.includes(":") && ipv6Groups(text) !== void 0;
|
|
17119
17244
|
var LABEL2 = /^(?!-)[A-Za-z0-9-]{1,63}(?<!-)$/;
|
|
17120
17245
|
function serverName(name2) {
|
|
17121
|
-
if (
|
|
17246
|
+
if (isIP2(name2.replace(/^\[|\]$/g, ""))) return name2.replace(/^\[|\]$/g, "");
|
|
17122
17247
|
const bare = name2.endsWith(".") ? name2.slice(0, -1) : name2;
|
|
17123
17248
|
if (bare.length === 0 || bare.length > 253 || !bare.split(".").every((l) => LABEL2.test(l))) {
|
|
17124
17249
|
throw new KernelError(
|
|
@@ -17168,9 +17293,66 @@ function sessionOf(info, servername) {
|
|
|
17168
17293
|
authorizationText: info.authorizationText
|
|
17169
17294
|
} : {},
|
|
17170
17295
|
servername,
|
|
17171
|
-
peerCertificates: info.peerCertificates.map(encode)
|
|
17296
|
+
peerCertificates: info.peerCertificates.map(encode),
|
|
17297
|
+
...controls(info)
|
|
17172
17298
|
};
|
|
17173
17299
|
}
|
|
17300
|
+
function controls(info) {
|
|
17301
|
+
if (!info.cipher) return {};
|
|
17302
|
+
return {
|
|
17303
|
+
cipher: info.cipher,
|
|
17304
|
+
clientCertificate: info.clientCertificate === true,
|
|
17305
|
+
sni: info.sni !== false,
|
|
17306
|
+
hostnameChecked: info.hostnameChecked === true,
|
|
17307
|
+
...info.hostnameMatches === void 0 ? {} : { hostnameMatches: info.hostnameMatches }
|
|
17308
|
+
};
|
|
17309
|
+
}
|
|
17310
|
+
var KEY_ERRORS = [
|
|
17311
|
+
[-3, "ERR_OSSL_X509_KEY_VALUES_MISMATCH"],
|
|
17312
|
+
[-15232, "ERR_OSSL_BAD_DECRYPT"],
|
|
17313
|
+
[-15360, "ERR_OSSL_CRYPTO_INTERRUPTED_OR_CANCELLED"]
|
|
17314
|
+
];
|
|
17315
|
+
function keyRefused(err) {
|
|
17316
|
+
const code = err instanceof TlsError ? err.code : 0;
|
|
17317
|
+
const name2 = KEY_ERRORS.find(([n]) => n === code)?.[1] ?? "ERR_OSSL_UNSUPPORTED";
|
|
17318
|
+
const text = code === -3 ? "the key does not match the certificate" : err.message;
|
|
17319
|
+
return new KernelError("EPROTO", `${name2}: ${text}`);
|
|
17320
|
+
}
|
|
17321
|
+
function takeCert(req) {
|
|
17322
|
+
const cert = req.clientCert;
|
|
17323
|
+
if (!cert) return void 0;
|
|
17324
|
+
delete req.clientCert;
|
|
17325
|
+
if (!Array.isArray(cert.chain) || cert.chain.length === 0 || typeof cert.key !== "string")
|
|
17326
|
+
throw new KernelError("EINVAL", "ERR_INVALID_ARG_VALUE: cert and key go together");
|
|
17327
|
+
let ders;
|
|
17328
|
+
let key;
|
|
17329
|
+
try {
|
|
17330
|
+
ders = cert.chain.map(base64Der);
|
|
17331
|
+
key = base64Der(cert.key);
|
|
17332
|
+
} catch {
|
|
17333
|
+
throw new KernelError("EINVAL", "ERR_INVALID_ARG_VALUE: cert or key is not base64");
|
|
17334
|
+
}
|
|
17335
|
+
const chain2 = new Uint8Array(ders.reduce((n, d) => n + d.length, 0));
|
|
17336
|
+
let at = 0;
|
|
17337
|
+
for (const der of ders) {
|
|
17338
|
+
chain2.set(der, at);
|
|
17339
|
+
at += der.length;
|
|
17340
|
+
}
|
|
17341
|
+
const pass2 = new TextEncoder().encode(cert.passphrase ?? "");
|
|
17342
|
+
return { chain: chain2, key, pass: pass2 };
|
|
17343
|
+
}
|
|
17344
|
+
function withCert(session, cert) {
|
|
17345
|
+
if (!cert) return;
|
|
17346
|
+
try {
|
|
17347
|
+
session.ownCert(cert.chain, cert.key, cert.pass);
|
|
17348
|
+
} catch (err) {
|
|
17349
|
+
throw keyRefused(err);
|
|
17350
|
+
}
|
|
17351
|
+
}
|
|
17352
|
+
function wipe(cert) {
|
|
17353
|
+
cert?.key.fill(0);
|
|
17354
|
+
cert?.pass.fill(0);
|
|
17355
|
+
}
|
|
17174
17356
|
async function setUp(support, req) {
|
|
17175
17357
|
const engine = await support.engine();
|
|
17176
17358
|
if (!engine.client)
|
|
@@ -17188,21 +17370,66 @@ async function setUp(support, req) {
|
|
|
17188
17370
|
}
|
|
17189
17371
|
return { engine, store: own, own };
|
|
17190
17372
|
}
|
|
17191
|
-
function
|
|
17192
|
-
|
|
17193
|
-
|
|
17373
|
+
async function prepare(support, req, servername) {
|
|
17374
|
+
const cert = takeCert(req);
|
|
17375
|
+
try {
|
|
17376
|
+
return await prepareWith(support, req, servername, cert);
|
|
17377
|
+
} catch (err) {
|
|
17378
|
+
if (err instanceof KernelError) throw err;
|
|
17379
|
+
throw new KernelError("ENOTSUP", err instanceof Error ? err.message : String(err));
|
|
17380
|
+
} finally {
|
|
17381
|
+
wipe(cert);
|
|
17382
|
+
}
|
|
17383
|
+
}
|
|
17384
|
+
async function prepareWith(support, req, servername, cert) {
|
|
17385
|
+
if (req.checkHostname === false && req.insecure === true) {
|
|
17386
|
+
throw new KernelError(
|
|
17387
|
+
"EINVAL",
|
|
17388
|
+
"ERR_INVALID_ARG_VALUE: checkHostname: false needs rejectUnauthorized"
|
|
17389
|
+
);
|
|
17390
|
+
}
|
|
17391
|
+
const { engine, store, own } = await setUp(support, req);
|
|
17392
|
+
const options = {
|
|
17393
|
+
engine,
|
|
17394
|
+
store,
|
|
17395
|
+
servername,
|
|
17396
|
+
alpn: req.alpn ?? [],
|
|
17397
|
+
insecure: req.insecure === true,
|
|
17398
|
+
...req.sni === false ? { sni: false } : {},
|
|
17399
|
+
...req.checkHostname === false ? { checkHostname: false } : {},
|
|
17400
|
+
clientCertificate: cert !== void 0
|
|
17401
|
+
};
|
|
17402
|
+
let session;
|
|
17403
|
+
try {
|
|
17404
|
+
const controls2 = req.sni === false || req.checkHostname === false || cert !== void 0;
|
|
17405
|
+
if (controls2 && !engine.sessionControls) {
|
|
17406
|
+
throw new KernelError("ENOTSUP", "the installed tls engine has no client certificates");
|
|
17407
|
+
}
|
|
17408
|
+
session = openSession(options);
|
|
17409
|
+
withCert(session, cert);
|
|
17410
|
+
return { options: { ...options, session }, own };
|
|
17411
|
+
} catch (err) {
|
|
17412
|
+
session?.free();
|
|
17413
|
+
own?.release();
|
|
17414
|
+
throw err;
|
|
17415
|
+
}
|
|
17416
|
+
}
|
|
17417
|
+
function secure(prepared) {
|
|
17418
|
+
let ran = false;
|
|
17419
|
+
const make = async (raw) => {
|
|
17420
|
+
ran = true;
|
|
17194
17421
|
try {
|
|
17195
|
-
return await tlsClient(raw,
|
|
17196
|
-
engine,
|
|
17197
|
-
store,
|
|
17198
|
-
servername,
|
|
17199
|
-
alpn: req.alpn ?? [],
|
|
17200
|
-
insecure: req.insecure === true
|
|
17201
|
-
});
|
|
17422
|
+
return await tlsClient(raw, prepared.options);
|
|
17202
17423
|
} finally {
|
|
17203
|
-
own?.release();
|
|
17424
|
+
prepared.own?.release();
|
|
17204
17425
|
}
|
|
17205
17426
|
};
|
|
17427
|
+
const abandon = () => {
|
|
17428
|
+
if (ran) return;
|
|
17429
|
+
prepared.options.session.free();
|
|
17430
|
+
prepared.own?.release();
|
|
17431
|
+
};
|
|
17432
|
+
return { make, abandon };
|
|
17206
17433
|
}
|
|
17207
17434
|
function supportOf(net) {
|
|
17208
17435
|
const support = net.tlsClient;
|
|
@@ -17211,7 +17438,7 @@ function supportOf(net) {
|
|
|
17211
17438
|
}
|
|
17212
17439
|
async function uplinkAddress(proc, host) {
|
|
17213
17440
|
const bare = host.replace(/^\[|\]$/g, "");
|
|
17214
|
-
if (
|
|
17441
|
+
if (isIP2(bare)) return bare;
|
|
17215
17442
|
const [first] = await proc.resolve(host, 0, () => proc.blocking());
|
|
17216
17443
|
if (!first) throw new KernelError("ENOENT", `ENOTFOUND: ${host}`);
|
|
17217
17444
|
return first;
|
|
@@ -17225,18 +17452,26 @@ async function connectSecure(proc, socket, host, port, req) {
|
|
|
17225
17452
|
throw new KernelError("ENOTSUP", "TLS in the kernel needs a destination the uplink routes");
|
|
17226
17453
|
const support = supportOf(proc.net);
|
|
17227
17454
|
let info;
|
|
17228
|
-
const make = secure(support, req, servername);
|
|
17229
|
-
|
|
17230
|
-
|
|
17231
|
-
|
|
17455
|
+
const { make, abandon } = secure(await prepare(support, req, servername));
|
|
17456
|
+
try {
|
|
17457
|
+
await socket.connectSecure({ family: "inet", host: address, port }, route, async (conn) => {
|
|
17458
|
+
info = await conn.upgrade(make);
|
|
17459
|
+
});
|
|
17460
|
+
} finally {
|
|
17461
|
+
abandon();
|
|
17462
|
+
}
|
|
17232
17463
|
return sessionOf(info, servername);
|
|
17233
17464
|
}
|
|
17234
17465
|
async function upgradeSecure(proc, socket, req) {
|
|
17235
17466
|
const peer = socket.peer;
|
|
17236
17467
|
const host = req.servername || (peer?.family === "inet" ? peer.host : "");
|
|
17237
17468
|
const servername = serverName(host);
|
|
17238
|
-
const
|
|
17239
|
-
|
|
17469
|
+
const { make, abandon } = secure(await prepare(supportOf(proc.net), req, servername));
|
|
17470
|
+
try {
|
|
17471
|
+
return sessionOf(await socket.upgradeSecure(make), servername);
|
|
17472
|
+
} finally {
|
|
17473
|
+
abandon();
|
|
17474
|
+
}
|
|
17240
17475
|
}
|
|
17241
17476
|
|
|
17242
17477
|
// src/kernel/unix-dgram.ts
|
|
@@ -17598,17 +17833,23 @@ var NOT_HTTP_PORTS = /* @__PURE__ */ new Set([
|
|
|
17598
17833
|
8883
|
|
17599
17834
|
]);
|
|
17600
17835
|
var HOST_NAME = /^[A-Za-z0-9.-]+$|^\[?[0-9A-Fa-f:.]+\]?$/;
|
|
17836
|
+
function sessionControls(req) {
|
|
17837
|
+
return req.sni === false || req.checkHostname === false || req.clientCert !== void 0;
|
|
17838
|
+
}
|
|
17601
17839
|
function wantsKernel(req) {
|
|
17602
17840
|
if (req.path === "kernel") return true;
|
|
17603
17841
|
if (req.path === "transport") return false;
|
|
17604
|
-
return Array.isArray(req.ca) || req.alpn !== void 0 && req.alpn.length > 0 && !req.alpn.includes("http/1.1") || NOT_HTTP_PORTS.has(req.port);
|
|
17842
|
+
return Array.isArray(req.ca) || sessionControls(req) || req.alpn !== void 0 && req.alpn.length > 0 && !req.alpn.includes("http/1.1") || NOT_HTTP_PORTS.has(req.port);
|
|
17605
17843
|
}
|
|
17606
17844
|
async function secureConnect(req, proc) {
|
|
17607
17845
|
if (!Number.isInteger(req.port) || req.port < 1 || req.port > 65535)
|
|
17608
17846
|
throw new KernelError("EINVAL");
|
|
17609
17847
|
const kernelPath = wantsKernel(req) && await uplinked(proc, req.host);
|
|
17610
17848
|
if (!kernelPath) {
|
|
17611
|
-
if (req.path === "kernel" || Array.isArray(req.ca)
|
|
17849
|
+
if (req.path === "kernel" || Array.isArray(req.ca) || sessionControls(req)) {
|
|
17850
|
+
delete req.clientCert;
|
|
17851
|
+
throw new KernelError("ENOTSUP");
|
|
17852
|
+
}
|
|
17612
17853
|
return { ...tlsOverTransport(req, proc), path: "transport", substitutes: true };
|
|
17613
17854
|
}
|
|
17614
17855
|
const socket = proc.net.socket("inet");
|
|
@@ -17742,13 +17983,17 @@ var VfsNode = class {
|
|
|
17742
17983
|
const ranged2 = await this.prepare();
|
|
17743
17984
|
await ranged2?.pin();
|
|
17744
17985
|
}
|
|
17986
|
+
moving = /* @__PURE__ */ new Set();
|
|
17745
17987
|
async load() {
|
|
17746
17988
|
if (this.revoked) throw new KernelError("EIO");
|
|
17747
|
-
|
|
17989
|
+
while (!this.data) {
|
|
17990
|
+
const at = this.path;
|
|
17748
17991
|
try {
|
|
17749
|
-
this.data = await this.fs.readFileBuffer(
|
|
17992
|
+
this.data = await this.fs.readFileBuffer(at);
|
|
17750
17993
|
} catch (err) {
|
|
17751
17994
|
if (!isMissing(err)) throw err;
|
|
17995
|
+
while (this.moving.size > 0) await Promise.all(this.moving);
|
|
17996
|
+
if (this.path !== at) continue;
|
|
17752
17997
|
this.data = new Uint8Array(0);
|
|
17753
17998
|
this.missing = true;
|
|
17754
17999
|
}
|
|
@@ -18102,6 +18347,16 @@ var VfsNodes = class {
|
|
|
18102
18347
|
this.byPath.set(file.hidden, node);
|
|
18103
18348
|
this.kept.set(node, file);
|
|
18104
18349
|
}
|
|
18350
|
+
moving(path) {
|
|
18351
|
+
const node = this.byPath.get(path);
|
|
18352
|
+
if (!node) return () => void 0;
|
|
18353
|
+
const { promise, resolve: resolve2 } = Promise.withResolvers();
|
|
18354
|
+
node.moving.add(promise);
|
|
18355
|
+
return () => {
|
|
18356
|
+
node.moving.delete(promise);
|
|
18357
|
+
resolve2();
|
|
18358
|
+
};
|
|
18359
|
+
}
|
|
18105
18360
|
unkeep(path, file) {
|
|
18106
18361
|
const node = this.byPath.get(file.hidden);
|
|
18107
18362
|
if (!node) return;
|
|
@@ -21389,7 +21644,7 @@ function register(automaton, sources, ids, bytes, source) {
|
|
|
21389
21644
|
}
|
|
21390
21645
|
sources[id2].push(source);
|
|
21391
21646
|
}
|
|
21392
|
-
function
|
|
21647
|
+
function prepare2(secrets) {
|
|
21393
21648
|
const main = new Automaton();
|
|
21394
21649
|
const wrap = new Automaton();
|
|
21395
21650
|
const sources = [];
|
|
@@ -21540,7 +21795,7 @@ function merge(into, from) {
|
|
|
21540
21795
|
}
|
|
21541
21796
|
}
|
|
21542
21797
|
function compile(secrets, options = {}) {
|
|
21543
|
-
const c =
|
|
21798
|
+
const c = prepare2(secrets.map((secret) => ({ ...secret })));
|
|
21544
21799
|
const decoder4 = new TextDecoder();
|
|
21545
21800
|
const idleMs = options.idleMs ?? 250;
|
|
21546
21801
|
const scrubBytes = (input) => {
|
|
@@ -26545,7 +26800,7 @@ function cronLocks() {
|
|
|
26545
26800
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
26546
26801
|
import { subscribe } from "node:diagnostics_channel";
|
|
26547
26802
|
import { lookup as lookup2 } from "node:dns/promises";
|
|
26548
|
-
import { isIP as
|
|
26803
|
+
import { isIP as isIP3 } from "node:net";
|
|
26549
26804
|
var DEVTOOLS_PORTS = [9222, 9223, 9224, 9225, 9226, 9227, 9228, 9229];
|
|
26550
26805
|
var METADATA_V6 = [64768, 3778, 0, 0, 0, 0, 0, 596].join(":");
|
|
26551
26806
|
var resolveHost = async (host) => (await lookup2(host, { all: true, verbatim: true })).map((a) => a.address);
|
|
@@ -26557,7 +26812,7 @@ function ipv4Place(address) {
|
|
|
26557
26812
|
}
|
|
26558
26813
|
function placeOf(address) {
|
|
26559
26814
|
const plain2 = address.replace(/^\[(.*)\]$/, "$1").toLowerCase();
|
|
26560
|
-
const kind =
|
|
26815
|
+
const kind = isIP3(plain2);
|
|
26561
26816
|
if (kind === 4) return ipv4Place(plain2);
|
|
26562
26817
|
if (kind !== 6) return void 0;
|
|
26563
26818
|
const words2 = hextets2(plain2);
|
|
@@ -26610,7 +26865,7 @@ function connectRefusal(address, port, place) {
|
|
|
26610
26865
|
}
|
|
26611
26866
|
async function addressesOf(host, resolve2) {
|
|
26612
26867
|
const plain2 = host.replace(/^\[(.*)\]$/, "$1");
|
|
26613
|
-
if (
|
|
26868
|
+
if (isIP3(plain2)) return [plain2];
|
|
26614
26869
|
if (loopbackName2(plain2)) return ["127.0.0.1"];
|
|
26615
26870
|
return resolve2(plain2).catch(() => []);
|
|
26616
26871
|
}
|
|
@@ -26945,7 +27200,7 @@ function isMemoryRoot(handle) {
|
|
|
26945
27200
|
|
|
26946
27201
|
// src/node/ws-diagnose.ts
|
|
26947
27202
|
import { lookup as lookup3 } from "node:dns/promises";
|
|
26948
|
-
import { isIP as
|
|
27203
|
+
import { isIP as isIP4, connect as tcp } from "node:net";
|
|
26949
27204
|
import { connect as tls } from "node:tls";
|
|
26950
27205
|
var PROBE_MS = 3e3;
|
|
26951
27206
|
var PASSED = /* @__PURE__ */ new Set(["ECONNREFUSED", "EHOSTUNREACH", "ENETUNREACH", "ETIMEDOUT", "ECONNRESET"]);
|
|
@@ -26967,7 +27222,7 @@ function abortable(work, signal) {
|
|
|
26967
27222
|
}
|
|
26968
27223
|
function probe(secure2, host, port, ms, signal) {
|
|
26969
27224
|
return new Promise((resolve2) => {
|
|
26970
|
-
const socket = secure2 ? tls({ host, port, ...
|
|
27225
|
+
const socket = secure2 ? tls({ host, port, ...isIP4(host) ? {} : { servername: host } }) : tcp({ host, port });
|
|
26971
27226
|
const stop = () => done4("ABORTED");
|
|
26972
27227
|
const done4 = (code) => {
|
|
26973
27228
|
clearTimeout(timer);
|