@ai-ecoverse/slicc-kernel 1.148.1 → 1.149.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -2
- package/dist/index.js +4 -1
- package/dist/index.js.map +2 -2
- package/dist/kernel-worker.js +299 -13
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-process-worker.js +209 -75
- package/dist/node-process-worker.js.map +3 -3
- package/dist/node.js +299 -13
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +209 -75
- package/dist/process-worker.js.map +3 -3
- package/dist/types/kernel/net/tls-client.d.ts +12 -0
- package/dist/types/kernel/net/tls-engine.d.ts +7 -1
- package/dist/types/kernel/net/tls-server.d.ts +34 -0
- package/dist/types/kernel/net/tls-uplink.d.ts +11 -1
- package/dist/types/kernel/socket-syscalls.d.ts +11 -0
- package/dist/types/kernel/socket.d.ts +9 -0
- package/dist/types/process/js/js-net.d.ts +16 -0
- package/package.json +3 -3
package/dist/kernel-worker.js
CHANGED
|
@@ -5954,6 +5954,9 @@ function link(a, b) {
|
|
|
5954
5954
|
a.attach({ rx: ba, tx: ab });
|
|
5955
5955
|
b.attach({ rx: ab, tx: ba });
|
|
5956
5956
|
}
|
|
5957
|
+
var SERVE_CHUNK = 64 * 1024;
|
|
5958
|
+
var NEVER_ABORTED = new AbortController().signal;
|
|
5959
|
+
var EMPTY = new Uint8Array(0);
|
|
5957
5960
|
var KernelSocket = class _KernelSocket {
|
|
5958
5961
|
net;
|
|
5959
5962
|
domain;
|
|
@@ -6151,6 +6154,54 @@ var KernelSocket = class _KernelSocket {
|
|
|
6151
6154
|
if (this.state !== "open") throw new KernelError("EISCONN");
|
|
6152
6155
|
return this.dial(addr, route2, secure2);
|
|
6153
6156
|
}
|
|
6157
|
+
serving;
|
|
6158
|
+
served = false;
|
|
6159
|
+
get loopbackLinked() {
|
|
6160
|
+
return this.state === "connected" && !this.switch;
|
|
6161
|
+
}
|
|
6162
|
+
async secureLink(make, signal = NEVER_ABORTED) {
|
|
6163
|
+
const raw2 = this.connection();
|
|
6164
|
+
if (this.switch || this.served || this.writeShut || this.readShut)
|
|
6165
|
+
throw new KernelError("EINVAL");
|
|
6166
|
+
signal.throwIfAborted();
|
|
6167
|
+
this.served = true;
|
|
6168
|
+
let handshaking = true;
|
|
6169
|
+
const view2 = {
|
|
6170
|
+
localAddr: "",
|
|
6171
|
+
remoteAddr: "",
|
|
6172
|
+
read: async () => {
|
|
6173
|
+
const bytes = await raw2.rx.read(SERVE_CHUNK, handshaking ? signal : void 0).catch(() => EMPTY);
|
|
6174
|
+
return bytes.length > 0 ? bytes : null;
|
|
6175
|
+
},
|
|
6176
|
+
write: (bytes) => raw2.tx.write(bytes),
|
|
6177
|
+
closeWrite: () => raw2.tx.closeWrite(),
|
|
6178
|
+
close: () => {
|
|
6179
|
+
raw2.rx.closeRead();
|
|
6180
|
+
raw2.tx.closeWrite();
|
|
6181
|
+
}
|
|
6182
|
+
};
|
|
6183
|
+
let made2;
|
|
6184
|
+
const abandon = () => view2.close();
|
|
6185
|
+
signal.addEventListener("abort", abandon, { once: true });
|
|
6186
|
+
try {
|
|
6187
|
+
made2 = await make(view2);
|
|
6188
|
+
} catch (err) {
|
|
6189
|
+
view2.close();
|
|
6190
|
+
this.readShut = true;
|
|
6191
|
+
this.writeShut = true;
|
|
6192
|
+
this.changes.wake();
|
|
6193
|
+
throw signal.aborted ? signal.reason : err;
|
|
6194
|
+
} finally {
|
|
6195
|
+
handshaking = false;
|
|
6196
|
+
signal.removeEventListener("abort", abandon);
|
|
6197
|
+
}
|
|
6198
|
+
this.link = uplinkLink(made2.conn, (err) => {
|
|
6199
|
+
this.reset = err instanceof KernelError && err.code === "EPROTO" ? err : new KernelError("ECONNRESET");
|
|
6200
|
+
this.changes.wake();
|
|
6201
|
+
});
|
|
6202
|
+
this.changes.wake();
|
|
6203
|
+
return made2.info;
|
|
6204
|
+
}
|
|
6154
6205
|
upgradeSecure(make) {
|
|
6155
6206
|
if (this.state !== "connected") throw new KernelError("ENOTCONN");
|
|
6156
6207
|
if (!this.switch) throw new KernelError("EOPNOTSUPP");
|
|
@@ -6282,6 +6333,8 @@ var KernelSocket = class _KernelSocket {
|
|
|
6282
6333
|
}
|
|
6283
6334
|
if (this.boundAt) this.net.release(this.boundAt, this, this.named);
|
|
6284
6335
|
this.boundAt = void 0;
|
|
6336
|
+
this.serving?.release();
|
|
6337
|
+
this.serving = void 0;
|
|
6285
6338
|
this.changes.wake();
|
|
6286
6339
|
}
|
|
6287
6340
|
static pair(net, domain, cred) {
|
|
@@ -6784,6 +6837,7 @@ function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS2 } = {})
|
|
|
6784
6837
|
const flow = {
|
|
6785
6838
|
inflight: 0,
|
|
6786
6839
|
closing: false,
|
|
6840
|
+
dropped: false,
|
|
6787
6841
|
deadline: () => AbortSignal.timeout(closeWaitMs).addEventListener("abort", late, { once: true })
|
|
6788
6842
|
};
|
|
6789
6843
|
credit.set(nid, flow);
|
|
@@ -6795,7 +6849,7 @@ function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS2 } = {})
|
|
|
6795
6849
|
const next3 = await Promise.race([messages.next(), unanswered]);
|
|
6796
6850
|
if (next3 === "late" || next3.done) break;
|
|
6797
6851
|
const data = next3.value;
|
|
6798
|
-
if (flow.
|
|
6852
|
+
if (flow.dropped) continue;
|
|
6799
6853
|
if (payloadSize(data) > MESSAGE_LIMIT) {
|
|
6800
6854
|
oversize = true;
|
|
6801
6855
|
break;
|
|
@@ -6849,6 +6903,8 @@ function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS2 } = {})
|
|
|
6849
6903
|
};
|
|
6850
6904
|
const drop = (nid) => {
|
|
6851
6905
|
sockets.get(nid)?.close(1e3, "cancelled");
|
|
6906
|
+
const flow = credit.get(nid);
|
|
6907
|
+
if (flow) flow.dropped = true;
|
|
6852
6908
|
refill(nid, 0, true);
|
|
6853
6909
|
const entry = open2.get(nid);
|
|
6854
6910
|
open2.delete(nid);
|
|
@@ -7855,7 +7911,7 @@ function satisfies(version, range2) {
|
|
|
7855
7911
|
}
|
|
7856
7912
|
|
|
7857
7913
|
// src/version.ts
|
|
7858
|
-
var KERNEL_VERSION = true ? "1.
|
|
7914
|
+
var KERNEL_VERSION = true ? "1.149.1" : "0.0.0-dev";
|
|
7859
7915
|
var OS_RELEASE = "6.0.0-slicc";
|
|
7860
7916
|
function procVersion() {
|
|
7861
7917
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -10354,7 +10410,7 @@ async function followLinks(fs, path) {
|
|
|
10354
10410
|
return current;
|
|
10355
10411
|
}
|
|
10356
10412
|
var NOBODY = { ruid: -1, euid: -1, suid: -1, rgid: -1, egid: -1, sgid: -1, groups: [] };
|
|
10357
|
-
var
|
|
10413
|
+
var EMPTY2 = new Uint8Array(0);
|
|
10358
10414
|
function quiet(promise) {
|
|
10359
10415
|
return promise.catch(() => void 0);
|
|
10360
10416
|
}
|
|
@@ -10437,13 +10493,13 @@ function withCommandDirs(fs, names2, userDir = async () => void 0, owners = fals
|
|
|
10437
10493
|
return target?.path;
|
|
10438
10494
|
}
|
|
10439
10495
|
const absent2 = (err) => {
|
|
10440
|
-
if (missing3(err)) return
|
|
10496
|
+
if (missing3(err)) return EMPTY2;
|
|
10441
10497
|
throw err;
|
|
10442
10498
|
};
|
|
10443
10499
|
async function content(path, err) {
|
|
10444
10500
|
if (!missing3(err) || !(await linked2(path))?.isFile) throw err;
|
|
10445
10501
|
const target = await redirected2(path);
|
|
10446
|
-
return target === void 0 ?
|
|
10502
|
+
return target === void 0 ? EMPTY2 : fs.readFileBuffer(target).catch(absent2);
|
|
10447
10503
|
}
|
|
10448
10504
|
const ranged2 = rangedOps(fs);
|
|
10449
10505
|
async function stat(path, real) {
|
|
@@ -16717,6 +16773,8 @@ function realmCa(owner, store) {
|
|
|
16717
16773
|
var TLS_CLIENT_INSECURE_SKIP_VERIFY = 1;
|
|
16718
16774
|
var TLS_CLIENT_NO_SNI = 2;
|
|
16719
16775
|
var TLS_CLIENT_VERIFY_CHAIN_ONLY = 4;
|
|
16776
|
+
var TLS_SERVER_REQUEST_CERT = 1;
|
|
16777
|
+
var TLS_SERVER_REQUIRE_CERT = 2;
|
|
16720
16778
|
var SCRATCH = 64 * 1024;
|
|
16721
16779
|
var EOF = -1;
|
|
16722
16780
|
var TlsError = class extends Error {
|
|
@@ -16765,6 +16823,35 @@ var TlsEngine = class {
|
|
|
16765
16823
|
this.m._free(name2);
|
|
16766
16824
|
}
|
|
16767
16825
|
}
|
|
16826
|
+
get serverSessions() {
|
|
16827
|
+
return typeof this.m._tls_server_new === "function";
|
|
16828
|
+
}
|
|
16829
|
+
importLeaf(chain2, key, pass2) {
|
|
16830
|
+
const leafImport = this.m._tls_leaf_import;
|
|
16831
|
+
const keyLen = key[0] === 45 ? key.length + 1 : key.length;
|
|
16832
|
+
const ptr = this.withBytes(
|
|
16833
|
+
chain2,
|
|
16834
|
+
(c) => this.withSecret(
|
|
16835
|
+
key,
|
|
16836
|
+
(k) => this.withSecret(
|
|
16837
|
+
pass2,
|
|
16838
|
+
(p) => leafImport(c, chain2.length, k, keyLen, pass2.length > 0 ? p : 0, pass2.length)
|
|
16839
|
+
)
|
|
16840
|
+
)
|
|
16841
|
+
);
|
|
16842
|
+
if (!ptr) throw this.error(this.m._tls_last_error(), "server certificate");
|
|
16843
|
+
return new TlsLeaf(this, this.m, ptr);
|
|
16844
|
+
}
|
|
16845
|
+
serverSession(leaf, alpn, clientCa, flags2) {
|
|
16846
|
+
const open2 = this.m._tls_server_new;
|
|
16847
|
+
const wire = alpnWire(alpn);
|
|
16848
|
+
const ptr = this.withBytes(
|
|
16849
|
+
wire,
|
|
16850
|
+
(p) => open2(leaf.ptr, wire.length > 0 ? p : 0, wire.length, clientCa?.ptr ?? 0, flags2)
|
|
16851
|
+
);
|
|
16852
|
+
if (!ptr) throw this.error(this.m._tls_last_error(), "tls server");
|
|
16853
|
+
return new TlsSession(this, this.m, ptr);
|
|
16854
|
+
}
|
|
16768
16855
|
withBytes(bytes, fn) {
|
|
16769
16856
|
const ptr = this.put(bytes);
|
|
16770
16857
|
try {
|
|
@@ -16969,6 +17056,12 @@ var TlsSession = class {
|
|
|
16969
17056
|
get version() {
|
|
16970
17057
|
return this.c._tls_version(this.ptr);
|
|
16971
17058
|
}
|
|
17059
|
+
get sni() {
|
|
17060
|
+
const out = this.engine.intoScratch(
|
|
17061
|
+
(p, max) => this.m._tls_sni(this.ptr, p, max)
|
|
17062
|
+
);
|
|
17063
|
+
return out instanceof Uint8Array ? new TextDecoder().decode(out) : "";
|
|
17064
|
+
}
|
|
16972
17065
|
get alpn() {
|
|
16973
17066
|
const out = this.engine.intoScratch((p, max) => this.c._tls_alpn(this.ptr, p, max));
|
|
16974
17067
|
return out instanceof Uint8Array ? new TextDecoder().decode(out) : void 0;
|
|
@@ -17471,7 +17564,7 @@ var Upload = class {
|
|
|
17471
17564
|
}
|
|
17472
17565
|
}
|
|
17473
17566
|
};
|
|
17474
|
-
var
|
|
17567
|
+
var EMPTY3 = new Uint8Array(0);
|
|
17475
17568
|
function message2(e) {
|
|
17476
17569
|
return e instanceof Error ? e.message : String(e);
|
|
17477
17570
|
}
|
|
@@ -17546,8 +17639,8 @@ var HttpHandles = class {
|
|
|
17546
17639
|
const entry = {
|
|
17547
17640
|
abort,
|
|
17548
17641
|
head: Promise.resolve({ ok: true, kind: "void" }),
|
|
17549
|
-
body: once(
|
|
17550
|
-
left:
|
|
17642
|
+
body: once(EMPTY3),
|
|
17643
|
+
left: EMPTY3,
|
|
17551
17644
|
done: false,
|
|
17552
17645
|
reading: Promise.resolve(),
|
|
17553
17646
|
cancel: async () => void 0,
|
|
@@ -18785,6 +18878,46 @@ async function tlsClient(conn, o, taken = new Uint8Array(0)) {
|
|
|
18785
18878
|
throw err;
|
|
18786
18879
|
}
|
|
18787
18880
|
}
|
|
18881
|
+
async function serverHandshake(conn, session, inbox) {
|
|
18882
|
+
for (; ; ) {
|
|
18883
|
+
let done5;
|
|
18884
|
+
try {
|
|
18885
|
+
done5 = session.handshake();
|
|
18886
|
+
} catch (err) {
|
|
18887
|
+
await send(conn, session).catch(() => void 0);
|
|
18888
|
+
const text = err instanceof TlsError ? err.message : String(err);
|
|
18889
|
+
throw new KernelError("EPROTO", `ERR_SSL_HANDSHAKE_FAILURE: ${text}${alertOf(session)}`);
|
|
18890
|
+
}
|
|
18891
|
+
await send(conn, session);
|
|
18892
|
+
if (done5) return;
|
|
18893
|
+
if (!await inbox.more()) {
|
|
18894
|
+
throw new KernelError(
|
|
18895
|
+
"ECONNRESET",
|
|
18896
|
+
"the client closed the connection during the TLS handshake"
|
|
18897
|
+
);
|
|
18898
|
+
}
|
|
18899
|
+
}
|
|
18900
|
+
}
|
|
18901
|
+
async function tlsServer(conn, session, clientCerts) {
|
|
18902
|
+
const inbox = new Ciphertext(conn, session);
|
|
18903
|
+
try {
|
|
18904
|
+
await serverHandshake(conn, session, inbox);
|
|
18905
|
+
const chain2 = session.peerChain();
|
|
18906
|
+
const code = clientCerts ? verifyCode(session.verifyResult) : void 0;
|
|
18907
|
+
const info = {
|
|
18908
|
+
protocol: session.version === 772 ? "TLSv1.3" : "TLSv1.2",
|
|
18909
|
+
alpnProtocol: session.alpn ?? false,
|
|
18910
|
+
servername: session.sni,
|
|
18911
|
+
authorized: clientCerts && chain2.length > 0 && code === void 0,
|
|
18912
|
+
...clientCerts && chain2.length > 0 && code ? { authorizationError: code } : {},
|
|
18913
|
+
peerCertificates: chain2
|
|
18914
|
+
};
|
|
18915
|
+
return { conn: plaintext(conn, session, inbox), info };
|
|
18916
|
+
} catch (err) {
|
|
18917
|
+
session.free();
|
|
18918
|
+
throw err;
|
|
18919
|
+
}
|
|
18920
|
+
}
|
|
18788
18921
|
|
|
18789
18922
|
// src/kernel/net/tls-chain.ts
|
|
18790
18923
|
var CN_MISMATCH = 4;
|
|
@@ -19237,7 +19370,7 @@ var RANK = {
|
|
|
19237
19370
|
};
|
|
19238
19371
|
var CR2 = 13;
|
|
19239
19372
|
var LF2 = 10;
|
|
19240
|
-
var
|
|
19373
|
+
var EMPTY4 = new Uint8Array(0);
|
|
19241
19374
|
function register(automaton, sources, ids, bytes, source) {
|
|
19242
19375
|
const key = Array.from(bytes).join(",");
|
|
19243
19376
|
let id2 = ids.get(key);
|
|
@@ -19417,12 +19550,12 @@ function compile(secrets, options = {}) {
|
|
|
19417
19550
|
return { text: decoder4.decode(bytes), hits };
|
|
19418
19551
|
},
|
|
19419
19552
|
stream() {
|
|
19420
|
-
let pending =
|
|
19553
|
+
let pending = EMPTY4;
|
|
19421
19554
|
const hits = /* @__PURE__ */ new Map();
|
|
19422
19555
|
const run2 = (final) => {
|
|
19423
19556
|
if (c.secrets.length === 0 || pending.length === 0) {
|
|
19424
19557
|
const out = pending;
|
|
19425
|
-
pending =
|
|
19558
|
+
pending = EMPTY4;
|
|
19426
19559
|
return out;
|
|
19427
19560
|
}
|
|
19428
19561
|
const result = pass(c, pending, final);
|
|
@@ -19436,7 +19569,7 @@ function compile(secrets, options = {}) {
|
|
|
19436
19569
|
return run2(false);
|
|
19437
19570
|
},
|
|
19438
19571
|
idle() {
|
|
19439
|
-
return pending.length < FRAGMENT ? run2(true) :
|
|
19572
|
+
return pending.length < FRAGMENT ? run2(true) : EMPTY4;
|
|
19440
19573
|
},
|
|
19441
19574
|
end() {
|
|
19442
19575
|
return run2(true);
|
|
@@ -21598,6 +21731,7 @@ function sealedConn(conn, s) {
|
|
|
21598
21731
|
}
|
|
21599
21732
|
|
|
21600
21733
|
// src/kernel/net/tls-uplink.ts
|
|
21734
|
+
var handshakeAbort = (proc) => proc.cancelled ?? proc.blocking();
|
|
21601
21735
|
var isIP2 = (text) => ipv4Bytes(text) !== void 0 || text.includes(":") && ipv6Groups(text) !== void 0;
|
|
21602
21736
|
var LABEL2 = /^(?!-)[A-Za-z0-9-]{1,63}(?<!-)$/;
|
|
21603
21737
|
function serverName(name2) {
|
|
@@ -21718,6 +21852,9 @@ function takeCert(req) {
|
|
|
21718
21852
|
const cert = req.clientCert;
|
|
21719
21853
|
if (!cert) return void 0;
|
|
21720
21854
|
delete req.clientCert;
|
|
21855
|
+
return certBytes(cert);
|
|
21856
|
+
}
|
|
21857
|
+
function certBytes(cert) {
|
|
21721
21858
|
if (!Array.isArray(cert.chain) || cert.chain.length === 0 || typeof cert.key !== "string")
|
|
21722
21859
|
throw new KernelError("EINVAL", "ERR_INVALID_ARG_VALUE: cert and key go together");
|
|
21723
21860
|
let ders;
|
|
@@ -21893,8 +22030,32 @@ async function connectSecure(proc, socket, host, port, req) {
|
|
|
21893
22030
|
}
|
|
21894
22031
|
return sessionOf(info, servername);
|
|
21895
22032
|
}
|
|
22033
|
+
async function loopbackSecure(proc, socket, servername, req) {
|
|
22034
|
+
const prepared = await prepare2(supportOf(proc.net), req, servername);
|
|
22035
|
+
let ran = false;
|
|
22036
|
+
try {
|
|
22037
|
+
const info = await socket.secureLink(async (raw2) => {
|
|
22038
|
+
ran = true;
|
|
22039
|
+
try {
|
|
22040
|
+
return await tlsClient(raw2, prepared.options);
|
|
22041
|
+
} finally {
|
|
22042
|
+
prepared.own?.release();
|
|
22043
|
+
}
|
|
22044
|
+
}, handshakeAbort(proc));
|
|
22045
|
+
return sessionOf({ ...info, substitutes: false }, servername);
|
|
22046
|
+
} finally {
|
|
22047
|
+
if (!ran) {
|
|
22048
|
+
prepared.options.session.free();
|
|
22049
|
+
prepared.own?.release();
|
|
22050
|
+
}
|
|
22051
|
+
}
|
|
22052
|
+
}
|
|
21896
22053
|
async function upgradeSecure(proc, socket, req) {
|
|
21897
22054
|
const peer = socket.peer;
|
|
22055
|
+
if (socket.loopbackLinked) {
|
|
22056
|
+
const host2 = req.servername || (peer?.family === "inet" ? peer.host : "localhost");
|
|
22057
|
+
return loopbackSecure(proc, socket, serverName(host2), req);
|
|
22058
|
+
}
|
|
21898
22059
|
const host = req.servername || (peer?.family === "inet" ? peer.host : "");
|
|
21899
22060
|
const servername = serverName(host);
|
|
21900
22061
|
const port = peer?.family === "inet" ? peer.port : 0;
|
|
@@ -21909,6 +22070,120 @@ async function upgradeSecure(proc, socket, req) {
|
|
|
21909
22070
|
}
|
|
21910
22071
|
}
|
|
21911
22072
|
|
|
22073
|
+
// src/kernel/net/tls-server.ts
|
|
22074
|
+
var HANDSHAKE_TIMEOUT_MS = 12e4;
|
|
22075
|
+
function leafOf(engine, cert) {
|
|
22076
|
+
try {
|
|
22077
|
+
return engine.importLeaf(cert.chain, cert.key, cert.pass);
|
|
22078
|
+
} catch (err) {
|
|
22079
|
+
throw keyRefused(err, cert.pass.length > 0 && encryptedKey(cert.key));
|
|
22080
|
+
} finally {
|
|
22081
|
+
wipe(cert);
|
|
22082
|
+
}
|
|
22083
|
+
}
|
|
22084
|
+
function storeOf(engine, ca) {
|
|
22085
|
+
const store = engine.store();
|
|
22086
|
+
try {
|
|
22087
|
+
for (const der2 of ca) store.add(base64Der(der2));
|
|
22088
|
+
return store;
|
|
22089
|
+
} catch (err) {
|
|
22090
|
+
store.release();
|
|
22091
|
+
throw new KernelError("EINVAL", `ERR_INVALID_ARG_VALUE: ca: ${err.message}`);
|
|
22092
|
+
}
|
|
22093
|
+
}
|
|
22094
|
+
function flagsOf(req, store) {
|
|
22095
|
+
if (!req.requestCert) return 0;
|
|
22096
|
+
if (!store) throw new KernelError("EINVAL", "ERR_INVALID_ARG_VALUE: requestCert needs a ca");
|
|
22097
|
+
return req.rejectUnauthorized === false ? TLS_SERVER_REQUEST_CERT : TLS_SERVER_REQUIRE_CERT;
|
|
22098
|
+
}
|
|
22099
|
+
function timeoutOf(req) {
|
|
22100
|
+
const ms = req.handshakeTimeout ?? HANDSHAKE_TIMEOUT_MS;
|
|
22101
|
+
if (!Number.isInteger(ms) || ms <= 0)
|
|
22102
|
+
throw new KernelError(
|
|
22103
|
+
"EINVAL",
|
|
22104
|
+
"ERR_OUT_OF_RANGE: handshakeTimeout must be a positive integer"
|
|
22105
|
+
);
|
|
22106
|
+
return ms;
|
|
22107
|
+
}
|
|
22108
|
+
function handshakeSignal(proc, ms) {
|
|
22109
|
+
const timer = new AbortController();
|
|
22110
|
+
const id2 = setTimeout(
|
|
22111
|
+
() => timer.abort(new KernelError("EPROTO", "ERR_TLS_HANDSHAKE_TIMEOUT: TLS handshake timeout")),
|
|
22112
|
+
ms
|
|
22113
|
+
);
|
|
22114
|
+
return {
|
|
22115
|
+
signal: AbortSignal.any([handshakeAbort(proc), timer.signal]),
|
|
22116
|
+
done: () => clearTimeout(id2)
|
|
22117
|
+
};
|
|
22118
|
+
}
|
|
22119
|
+
async function serverOf(proc, req) {
|
|
22120
|
+
const own = req.cert;
|
|
22121
|
+
delete req.cert;
|
|
22122
|
+
if (!own) throw new KernelError("EINVAL", "ERR_INVALID_ARG_VALUE: a server needs cert and key");
|
|
22123
|
+
const cert = certBytes(own);
|
|
22124
|
+
let engine;
|
|
22125
|
+
try {
|
|
22126
|
+
engine = await supportOf(proc.net).engine();
|
|
22127
|
+
if (!engine.serverSessions)
|
|
22128
|
+
throw new KernelError("ENOTSUP", "the installed tls engine has no server sessions");
|
|
22129
|
+
} catch (err) {
|
|
22130
|
+
wipe(cert);
|
|
22131
|
+
throw err;
|
|
22132
|
+
}
|
|
22133
|
+
const leaf = leafOf(engine, cert);
|
|
22134
|
+
let store;
|
|
22135
|
+
try {
|
|
22136
|
+
store = req.ca && req.ca.length > 0 ? storeOf(engine, req.ca) : void 0;
|
|
22137
|
+
const flags2 = flagsOf(req, store);
|
|
22138
|
+
return {
|
|
22139
|
+
engine,
|
|
22140
|
+
leaf,
|
|
22141
|
+
store,
|
|
22142
|
+
alpn: req.alpn ?? [],
|
|
22143
|
+
flags: flags2,
|
|
22144
|
+
timeoutMs: timeoutOf(req),
|
|
22145
|
+
release() {
|
|
22146
|
+
leaf.release();
|
|
22147
|
+
store?.release();
|
|
22148
|
+
}
|
|
22149
|
+
};
|
|
22150
|
+
} catch (err) {
|
|
22151
|
+
leaf.release();
|
|
22152
|
+
store?.release();
|
|
22153
|
+
throw err;
|
|
22154
|
+
}
|
|
22155
|
+
}
|
|
22156
|
+
async function listenSecure(proc, socket, req) {
|
|
22157
|
+
if (!socket.listening) throw new KernelError("EINVAL", "not a listening socket");
|
|
22158
|
+
const server = await serverOf(proc, req);
|
|
22159
|
+
socket.serving?.release();
|
|
22160
|
+
socket.serving = server;
|
|
22161
|
+
}
|
|
22162
|
+
async function serveSecure(proc, socket, req) {
|
|
22163
|
+
const shared = req.listener?.serving;
|
|
22164
|
+
if (req.listener && !shared) throw new KernelError("EINVAL", "the listener has no tls");
|
|
22165
|
+
const server = shared ?? await serverOf(proc, req);
|
|
22166
|
+
try {
|
|
22167
|
+
const { engine, leaf, alpn, store, flags: flags2 } = server;
|
|
22168
|
+
const limit = handshakeSignal(proc, server.timeoutMs);
|
|
22169
|
+
const info = await socket.secureLink(
|
|
22170
|
+
(raw2) => tlsServer(raw2, engine.serverSession(leaf, alpn, store, flags2), flags2 !== 0),
|
|
22171
|
+
limit.signal
|
|
22172
|
+
).finally(limit.done);
|
|
22173
|
+
return {
|
|
22174
|
+
path: "kernel",
|
|
22175
|
+
protocol: info.protocol,
|
|
22176
|
+
alpnProtocol: info.alpnProtocol,
|
|
22177
|
+
servername: info.servername,
|
|
22178
|
+
authorized: info.authorized,
|
|
22179
|
+
...info.authorizationError ? { authorizationError: info.authorizationError } : {},
|
|
22180
|
+
peerCertificates: info.peerCertificates.map(encode)
|
|
22181
|
+
};
|
|
22182
|
+
} finally {
|
|
22183
|
+
if (!shared) server.release();
|
|
22184
|
+
}
|
|
22185
|
+
}
|
|
22186
|
+
|
|
21912
22187
|
// src/kernel/unix-dgram.ts
|
|
21913
22188
|
var SOL_SOCKET3 = 1;
|
|
21914
22189
|
var SO_TYPE3 = 3;
|
|
@@ -22071,7 +22346,9 @@ var SOCKET_OPS = [
|
|
|
22071
22346
|
"sock-sendto",
|
|
22072
22347
|
"sock-recvfrom",
|
|
22073
22348
|
"sock-tls",
|
|
22074
|
-
"sock-tls-upgrade"
|
|
22349
|
+
"sock-tls-upgrade",
|
|
22350
|
+
"sock-tls-serve",
|
|
22351
|
+
"sock-tls-listen"
|
|
22075
22352
|
];
|
|
22076
22353
|
function socketAt(fds, fd) {
|
|
22077
22354
|
const file = anySocketAt(fds, fd);
|
|
@@ -22147,6 +22424,14 @@ async function socketSyscall(req, proc) {
|
|
|
22147
22424
|
return ok3(await secureConnect(req, proc));
|
|
22148
22425
|
case "sock-tls-upgrade":
|
|
22149
22426
|
return ok3(await upgradeSecure(proc, socketAt(fds, req.fd), req));
|
|
22427
|
+
case "sock-tls-serve": {
|
|
22428
|
+
const { from, ...rest2 } = req;
|
|
22429
|
+
const listener = from === void 0 ? {} : { listener: socketAt(fds, from) };
|
|
22430
|
+
return ok3(await serveSecure(proc, socketAt(fds, req.fd), { ...rest2, ...listener }));
|
|
22431
|
+
}
|
|
22432
|
+
case "sock-tls-listen":
|
|
22433
|
+
await listenSecure(proc, socketAt(fds, req.fd), req);
|
|
22434
|
+
return ok3({});
|
|
22150
22435
|
default:
|
|
22151
22436
|
return datagram(req, proc);
|
|
22152
22437
|
}
|
|
@@ -24578,6 +24863,7 @@ var WasmProcess = class {
|
|
|
24578
24863
|
fds: this.fds,
|
|
24579
24864
|
net: this.net,
|
|
24580
24865
|
blocking: () => this.blockingSignal(cancelled),
|
|
24866
|
+
cancelled,
|
|
24581
24867
|
resolve: (name2, family, blocking) => resolver.resolve(name2, family, blocking),
|
|
24582
24868
|
cred: () => ({ pid: this.pid, uid: this.cred.euid, gid: this.cred.egid }),
|
|
24583
24869
|
stamp: () => this.connectorStamp(),
|