@ai-ecoverse/slicc-kernel 1.124.12 → 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 +29 -8
- package/dist/index.js.map +2 -2
- package/dist/kernel-worker.js +304 -53
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-process-worker.js +4419 -4337
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +309 -58
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +7087 -7005
- 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
|
|
@@ -14824,6 +14834,8 @@ function realmCa(owner, store) {
|
|
|
14824
14834
|
|
|
14825
14835
|
// src/kernel/net/tls-engine.ts
|
|
14826
14836
|
var TLS_CLIENT_INSECURE_SKIP_VERIFY = 1;
|
|
14837
|
+
var TLS_CLIENT_NO_SNI = 2;
|
|
14838
|
+
var TLS_CLIENT_VERIFY_CHAIN_ONLY = 4;
|
|
14827
14839
|
var SCRATCH = 64 * 1024;
|
|
14828
14840
|
var EOF = -1;
|
|
14829
14841
|
var TlsError = class extends Error {
|
|
@@ -14880,10 +14892,22 @@ var TlsEngine = class {
|
|
|
14880
14892
|
this.m._free(ptr);
|
|
14881
14893
|
}
|
|
14882
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
|
+
}
|
|
14883
14904
|
intoScratch(fn) {
|
|
14884
14905
|
const n = fn(this.scratch, SCRATCH);
|
|
14885
14906
|
return n > 0 ? this.taken(n) : n;
|
|
14886
14907
|
}
|
|
14908
|
+
get sessionControls() {
|
|
14909
|
+
return typeof this.m._tls_client_cert === "function";
|
|
14910
|
+
}
|
|
14887
14911
|
get client() {
|
|
14888
14912
|
return typeof this.m._tls_client_new === "function" ? this.m : void 0;
|
|
14889
14913
|
}
|
|
@@ -15036,6 +15060,27 @@ var TlsSession = class {
|
|
|
15036
15060
|
const out = this.engine.intoScratch((p, max) => this.c._tls_alpn(this.ptr, p, max));
|
|
15037
15061
|
return out instanceof Uint8Array ? new TextDecoder().decode(out) : void 0;
|
|
15038
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
|
+
}
|
|
15039
15084
|
peerChain() {
|
|
15040
15085
|
const chain2 = [];
|
|
15041
15086
|
const count2 = this.c._tls_peer_count(this.ptr);
|
|
@@ -16340,11 +16385,11 @@ async function runChild(req, deps) {
|
|
|
16340
16385
|
if (pid !== 0) kill();
|
|
16341
16386
|
decided.resolve();
|
|
16342
16387
|
};
|
|
16343
|
-
const
|
|
16388
|
+
const controls2 = [];
|
|
16344
16389
|
const capture = () => {
|
|
16345
16390
|
const { promise, resolve: resolve2 } = Promise.withResolvers();
|
|
16346
16391
|
const control = { shut: false, ended: resolve2, eof: promise };
|
|
16347
|
-
|
|
16392
|
+
controls2.push(control);
|
|
16348
16393
|
return { capture: true, max, overflow: () => stop("ENOBUFS"), control };
|
|
16349
16394
|
};
|
|
16350
16395
|
const decided = Promise.withResolvers();
|
|
@@ -16378,11 +16423,11 @@ async function runChild(req, deps) {
|
|
|
16378
16423
|
let status;
|
|
16379
16424
|
try {
|
|
16380
16425
|
status = await reaped(deps, pid);
|
|
16381
|
-
const open =
|
|
16426
|
+
const open = controls2.filter((c) => c.opened);
|
|
16382
16427
|
await Promise.race([Promise.all(open.map((c) => c.eof)), decided.promise]);
|
|
16383
16428
|
} finally {
|
|
16384
16429
|
cancel?.();
|
|
16385
|
-
for (const control of
|
|
16430
|
+
for (const control of controls2) control.shut = true;
|
|
16386
16431
|
}
|
|
16387
16432
|
const out = deps.children.captured(pid, 1);
|
|
16388
16433
|
const err = deps.children.captured(pid, 2);
|
|
@@ -16964,6 +17009,47 @@ function encodeReceived(got) {
|
|
|
16964
17009
|
return out;
|
|
16965
17010
|
}
|
|
16966
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
|
+
|
|
16967
17053
|
// src/kernel/net/tls-client.ts
|
|
16968
17054
|
var WRITE_CHUNK = 16 * 1024;
|
|
16969
17055
|
var BADCERT = [
|
|
@@ -16980,6 +17066,15 @@ function verifyCode(flags2) {
|
|
|
16980
17066
|
if (flags2 === -1) return "UNABLE_TO_VERIFY_LEAF_SIGNATURE";
|
|
16981
17067
|
return BADCERT.find(([bit]) => (flags2 & bit) !== 0)?.[1] ?? "UNABLE_TO_VERIFY_LEAF_SIGNATURE";
|
|
16982
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
|
+
}
|
|
16983
17078
|
var Ciphertext = class {
|
|
16984
17079
|
queue = [];
|
|
16985
17080
|
ended = false;
|
|
@@ -17052,17 +17147,39 @@ async function handshake(conn, o, session, inbox) {
|
|
|
17052
17147
|
}
|
|
17053
17148
|
}
|
|
17054
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
|
+
}
|
|
17055
17161
|
function infoOf(o, session) {
|
|
17056
17162
|
const flags2 = session.verifyResult;
|
|
17057
17163
|
const code = verifyCode(flags2);
|
|
17164
|
+
const protocol = session.version === 772 ? "TLSv1.3" : "TLSv1.2";
|
|
17058
17165
|
return {
|
|
17059
|
-
protocol
|
|
17166
|
+
protocol,
|
|
17060
17167
|
alpnProtocol: session.alpn ?? false,
|
|
17061
17168
|
authorized: code === void 0,
|
|
17062
17169
|
...code ? { authorizationError: code, authorizationText: o.engine.verifyInfo(flags2).trim() } : {},
|
|
17063
|
-
peerCertificates: session.peerChain()
|
|
17170
|
+
peerCertificates: session.peerChain(),
|
|
17171
|
+
...controlsOf(o, session, protocol)
|
|
17064
17172
|
};
|
|
17065
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
|
+
}
|
|
17066
17183
|
function plaintext(conn, session, inbox) {
|
|
17067
17184
|
let freed = false;
|
|
17068
17185
|
let writeClosed = false;
|
|
@@ -17077,7 +17194,12 @@ function plaintext(conn, session, inbox) {
|
|
|
17077
17194
|
async read() {
|
|
17078
17195
|
for (; ; ) {
|
|
17079
17196
|
if (freed) return null;
|
|
17080
|
-
|
|
17197
|
+
let got;
|
|
17198
|
+
try {
|
|
17199
|
+
got = session.read();
|
|
17200
|
+
} catch (err) {
|
|
17201
|
+
throw alerted(err);
|
|
17202
|
+
}
|
|
17081
17203
|
await send(conn, session);
|
|
17082
17204
|
if (got instanceof Uint8Array) return got;
|
|
17083
17205
|
if (got === "eof") return null;
|
|
@@ -17105,8 +17227,7 @@ function plaintext(conn, session, inbox) {
|
|
|
17105
17227
|
};
|
|
17106
17228
|
}
|
|
17107
17229
|
async function tlsClient(conn, o, taken = new Uint8Array(0)) {
|
|
17108
|
-
const
|
|
17109
|
-
const session = o.engine.clientSession(o.store, o.servername, o.alpn, flags2);
|
|
17230
|
+
const session = o.session ?? openSession(o);
|
|
17110
17231
|
const inbox = new Ciphertext(conn, session);
|
|
17111
17232
|
inbox.hand(taken);
|
|
17112
17233
|
try {
|
|
@@ -17119,10 +17240,10 @@ async function tlsClient(conn, o, taken = new Uint8Array(0)) {
|
|
|
17119
17240
|
}
|
|
17120
17241
|
|
|
17121
17242
|
// src/kernel/net/tls-uplink.ts
|
|
17122
|
-
var
|
|
17243
|
+
var isIP2 = (text) => ipv4Bytes(text) !== void 0 || text.includes(":") && ipv6Groups(text) !== void 0;
|
|
17123
17244
|
var LABEL2 = /^(?!-)[A-Za-z0-9-]{1,63}(?<!-)$/;
|
|
17124
17245
|
function serverName(name2) {
|
|
17125
|
-
if (
|
|
17246
|
+
if (isIP2(name2.replace(/^\[|\]$/g, ""))) return name2.replace(/^\[|\]$/g, "");
|
|
17126
17247
|
const bare = name2.endsWith(".") ? name2.slice(0, -1) : name2;
|
|
17127
17248
|
if (bare.length === 0 || bare.length > 253 || !bare.split(".").every((l) => LABEL2.test(l))) {
|
|
17128
17249
|
throw new KernelError(
|
|
@@ -17172,9 +17293,66 @@ function sessionOf(info, servername) {
|
|
|
17172
17293
|
authorizationText: info.authorizationText
|
|
17173
17294
|
} : {},
|
|
17174
17295
|
servername,
|
|
17175
|
-
peerCertificates: info.peerCertificates.map(encode)
|
|
17296
|
+
peerCertificates: info.peerCertificates.map(encode),
|
|
17297
|
+
...controls(info)
|
|
17176
17298
|
};
|
|
17177
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
|
+
}
|
|
17178
17356
|
async function setUp(support, req) {
|
|
17179
17357
|
const engine = await support.engine();
|
|
17180
17358
|
if (!engine.client)
|
|
@@ -17192,21 +17370,66 @@ async function setUp(support, req) {
|
|
|
17192
17370
|
}
|
|
17193
17371
|
return { engine, store: own, own };
|
|
17194
17372
|
}
|
|
17195
|
-
function
|
|
17196
|
-
|
|
17197
|
-
|
|
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;
|
|
17198
17421
|
try {
|
|
17199
|
-
return await tlsClient(raw,
|
|
17200
|
-
engine,
|
|
17201
|
-
store,
|
|
17202
|
-
servername,
|
|
17203
|
-
alpn: req.alpn ?? [],
|
|
17204
|
-
insecure: req.insecure === true
|
|
17205
|
-
});
|
|
17422
|
+
return await tlsClient(raw, prepared.options);
|
|
17206
17423
|
} finally {
|
|
17207
|
-
own?.release();
|
|
17424
|
+
prepared.own?.release();
|
|
17208
17425
|
}
|
|
17209
17426
|
};
|
|
17427
|
+
const abandon = () => {
|
|
17428
|
+
if (ran) return;
|
|
17429
|
+
prepared.options.session.free();
|
|
17430
|
+
prepared.own?.release();
|
|
17431
|
+
};
|
|
17432
|
+
return { make, abandon };
|
|
17210
17433
|
}
|
|
17211
17434
|
function supportOf(net) {
|
|
17212
17435
|
const support = net.tlsClient;
|
|
@@ -17215,7 +17438,7 @@ function supportOf(net) {
|
|
|
17215
17438
|
}
|
|
17216
17439
|
async function uplinkAddress(proc, host) {
|
|
17217
17440
|
const bare = host.replace(/^\[|\]$/g, "");
|
|
17218
|
-
if (
|
|
17441
|
+
if (isIP2(bare)) return bare;
|
|
17219
17442
|
const [first] = await proc.resolve(host, 0, () => proc.blocking());
|
|
17220
17443
|
if (!first) throw new KernelError("ENOENT", `ENOTFOUND: ${host}`);
|
|
17221
17444
|
return first;
|
|
@@ -17229,18 +17452,26 @@ async function connectSecure(proc, socket, host, port, req) {
|
|
|
17229
17452
|
throw new KernelError("ENOTSUP", "TLS in the kernel needs a destination the uplink routes");
|
|
17230
17453
|
const support = supportOf(proc.net);
|
|
17231
17454
|
let info;
|
|
17232
|
-
const make = secure(support, req, servername);
|
|
17233
|
-
|
|
17234
|
-
|
|
17235
|
-
|
|
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
|
+
}
|
|
17236
17463
|
return sessionOf(info, servername);
|
|
17237
17464
|
}
|
|
17238
17465
|
async function upgradeSecure(proc, socket, req) {
|
|
17239
17466
|
const peer = socket.peer;
|
|
17240
17467
|
const host = req.servername || (peer?.family === "inet" ? peer.host : "");
|
|
17241
17468
|
const servername = serverName(host);
|
|
17242
|
-
const
|
|
17243
|
-
|
|
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
|
+
}
|
|
17244
17475
|
}
|
|
17245
17476
|
|
|
17246
17477
|
// src/kernel/unix-dgram.ts
|
|
@@ -17602,17 +17833,23 @@ var NOT_HTTP_PORTS = /* @__PURE__ */ new Set([
|
|
|
17602
17833
|
8883
|
|
17603
17834
|
]);
|
|
17604
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
|
+
}
|
|
17605
17839
|
function wantsKernel(req) {
|
|
17606
17840
|
if (req.path === "kernel") return true;
|
|
17607
17841
|
if (req.path === "transport") return false;
|
|
17608
|
-
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);
|
|
17609
17843
|
}
|
|
17610
17844
|
async function secureConnect(req, proc) {
|
|
17611
17845
|
if (!Number.isInteger(req.port) || req.port < 1 || req.port > 65535)
|
|
17612
17846
|
throw new KernelError("EINVAL");
|
|
17613
17847
|
const kernelPath = wantsKernel(req) && await uplinked(proc, req.host);
|
|
17614
17848
|
if (!kernelPath) {
|
|
17615
|
-
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
|
+
}
|
|
17616
17853
|
return { ...tlsOverTransport(req, proc), path: "transport", substitutes: true };
|
|
17617
17854
|
}
|
|
17618
17855
|
const socket = proc.net.socket("inet");
|
|
@@ -17746,13 +17983,17 @@ var VfsNode = class {
|
|
|
17746
17983
|
const ranged2 = await this.prepare();
|
|
17747
17984
|
await ranged2?.pin();
|
|
17748
17985
|
}
|
|
17986
|
+
moving = /* @__PURE__ */ new Set();
|
|
17749
17987
|
async load() {
|
|
17750
17988
|
if (this.revoked) throw new KernelError("EIO");
|
|
17751
|
-
|
|
17989
|
+
while (!this.data) {
|
|
17990
|
+
const at = this.path;
|
|
17752
17991
|
try {
|
|
17753
|
-
this.data = await this.fs.readFileBuffer(
|
|
17992
|
+
this.data = await this.fs.readFileBuffer(at);
|
|
17754
17993
|
} catch (err) {
|
|
17755
17994
|
if (!isMissing(err)) throw err;
|
|
17995
|
+
while (this.moving.size > 0) await Promise.all(this.moving);
|
|
17996
|
+
if (this.path !== at) continue;
|
|
17756
17997
|
this.data = new Uint8Array(0);
|
|
17757
17998
|
this.missing = true;
|
|
17758
17999
|
}
|
|
@@ -18106,6 +18347,16 @@ var VfsNodes = class {
|
|
|
18106
18347
|
this.byPath.set(file.hidden, node);
|
|
18107
18348
|
this.kept.set(node, file);
|
|
18108
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
|
+
}
|
|
18109
18360
|
unkeep(path, file) {
|
|
18110
18361
|
const node = this.byPath.get(file.hidden);
|
|
18111
18362
|
if (!node) return;
|
|
@@ -21393,7 +21644,7 @@ function register(automaton, sources, ids, bytes, source) {
|
|
|
21393
21644
|
}
|
|
21394
21645
|
sources[id2].push(source);
|
|
21395
21646
|
}
|
|
21396
|
-
function
|
|
21647
|
+
function prepare2(secrets) {
|
|
21397
21648
|
const main = new Automaton();
|
|
21398
21649
|
const wrap = new Automaton();
|
|
21399
21650
|
const sources = [];
|
|
@@ -21544,7 +21795,7 @@ function merge(into, from) {
|
|
|
21544
21795
|
}
|
|
21545
21796
|
}
|
|
21546
21797
|
function compile(secrets, options = {}) {
|
|
21547
|
-
const c =
|
|
21798
|
+
const c = prepare2(secrets.map((secret) => ({ ...secret })));
|
|
21548
21799
|
const decoder4 = new TextDecoder();
|
|
21549
21800
|
const idleMs = options.idleMs ?? 250;
|
|
21550
21801
|
const scrubBytes = (input) => {
|
|
@@ -26549,7 +26800,7 @@ function cronLocks() {
|
|
|
26549
26800
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
26550
26801
|
import { subscribe } from "node:diagnostics_channel";
|
|
26551
26802
|
import { lookup as lookup2 } from "node:dns/promises";
|
|
26552
|
-
import { isIP as
|
|
26803
|
+
import { isIP as isIP3 } from "node:net";
|
|
26553
26804
|
var DEVTOOLS_PORTS = [9222, 9223, 9224, 9225, 9226, 9227, 9228, 9229];
|
|
26554
26805
|
var METADATA_V6 = [64768, 3778, 0, 0, 0, 0, 0, 596].join(":");
|
|
26555
26806
|
var resolveHost = async (host) => (await lookup2(host, { all: true, verbatim: true })).map((a) => a.address);
|
|
@@ -26561,7 +26812,7 @@ function ipv4Place(address) {
|
|
|
26561
26812
|
}
|
|
26562
26813
|
function placeOf(address) {
|
|
26563
26814
|
const plain2 = address.replace(/^\[(.*)\]$/, "$1").toLowerCase();
|
|
26564
|
-
const kind =
|
|
26815
|
+
const kind = isIP3(plain2);
|
|
26565
26816
|
if (kind === 4) return ipv4Place(plain2);
|
|
26566
26817
|
if (kind !== 6) return void 0;
|
|
26567
26818
|
const words2 = hextets2(plain2);
|
|
@@ -26614,7 +26865,7 @@ function connectRefusal(address, port, place) {
|
|
|
26614
26865
|
}
|
|
26615
26866
|
async function addressesOf(host, resolve2) {
|
|
26616
26867
|
const plain2 = host.replace(/^\[(.*)\]$/, "$1");
|
|
26617
|
-
if (
|
|
26868
|
+
if (isIP3(plain2)) return [plain2];
|
|
26618
26869
|
if (loopbackName2(plain2)) return ["127.0.0.1"];
|
|
26619
26870
|
return resolve2(plain2).catch(() => []);
|
|
26620
26871
|
}
|
|
@@ -26949,7 +27200,7 @@ function isMemoryRoot(handle) {
|
|
|
26949
27200
|
|
|
26950
27201
|
// src/node/ws-diagnose.ts
|
|
26951
27202
|
import { lookup as lookup3 } from "node:dns/promises";
|
|
26952
|
-
import { isIP as
|
|
27203
|
+
import { isIP as isIP4, connect as tcp } from "node:net";
|
|
26953
27204
|
import { connect as tls } from "node:tls";
|
|
26954
27205
|
var PROBE_MS = 3e3;
|
|
26955
27206
|
var PASSED = /* @__PURE__ */ new Set(["ECONNREFUSED", "EHOSTUNREACH", "ENETUNREACH", "ETIMEDOUT", "ECONNRESET"]);
|
|
@@ -26971,7 +27222,7 @@ function abortable(work, signal) {
|
|
|
26971
27222
|
}
|
|
26972
27223
|
function probe(secure2, host, port, ms, signal) {
|
|
26973
27224
|
return new Promise((resolve2) => {
|
|
26974
|
-
const socket = secure2 ? tls({ host, port, ...
|
|
27225
|
+
const socket = secure2 ? tls({ host, port, ...isIP4(host) ? {} : { servername: host } }) : tcp({ host, port });
|
|
26975
27226
|
const stop = () => done4("ABORTED");
|
|
26976
27227
|
const done4 = (code) => {
|
|
26977
27228
|
clearTimeout(timer);
|