Files
NetMesh/electron/bridges/x11Forwarding.test.cjs
zhaolei 3c72efcb7f
Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
[Init] Initial commit - NetMesh terminal manager
2026-09-13 18:24:01 +08:00

236 lines
7.3 KiB
JavaScript

const test = require("node:test");
const assert = require("node:assert/strict");
const { Duplex } = require("node:stream");
const { EventEmitter } = require("node:events");
const {
attachX11Forwarding,
readLocalX11AuthCookie,
rewriteX11AuthSetupPacket,
resolveX11DisplaySpec,
} = require("./x11Forwarding.cjs");
const buildX11SetupPacket = ({ cookie, endian = "l" }) => {
const protocol = Buffer.from("MIT-MAGIC-COOKIE-1", "ascii");
const cookieBytes = Buffer.from(cookie, "hex");
const protocolPad = (4 - (protocol.length % 4)) % 4;
const cookiePad = (4 - (cookieBytes.length % 4)) % 4;
const packet = Buffer.alloc(12 + protocol.length + protocolPad + cookieBytes.length + cookiePad);
packet[0] = endian.charCodeAt(0);
const writeUInt16 = endian === "l"
? packet.writeUInt16LE.bind(packet)
: packet.writeUInt16BE.bind(packet);
writeUInt16(11, 2);
writeUInt16(0, 4);
writeUInt16(protocol.length, 6);
writeUInt16(cookieBytes.length, 8);
protocol.copy(packet, 12);
cookieBytes.copy(packet, 12 + protocol.length + protocolPad);
return packet;
};
test("resolveX11DisplaySpec maps unix display to the X11 socket path", () => {
assert.deepEqual(
resolveX11DisplaySpec(":2", { platform: "linux" }),
{ path: "/tmp/.X11-unix/X2" },
);
});
test("resolveX11DisplaySpec treats a bare colon as display zero", () => {
assert.deepEqual(
resolveX11DisplaySpec(":", { platform: "darwin" }),
{ path: "/tmp/.X11-unix/X0" },
);
});
test("resolveX11DisplaySpec maps tcp display numbers to X11 ports", () => {
assert.deepEqual(
resolveX11DisplaySpec("localhost:1", { platform: "win32" }),
{ host: "localhost", port: 6001 },
);
});
test("resolveX11DisplaySpec accepts explicit unix socket paths", () => {
assert.deepEqual(
resolveX11DisplaySpec("/private/tmp/com.apple.launchd.test/org.xquartz:0", { platform: "darwin" }),
{ path: "/private/tmp/com.apple.launchd.test/org.xquartz:0" },
);
});
test("resolveX11DisplaySpec maps unix-prefixed displays to local X11 sockets", () => {
assert.deepEqual(
resolveX11DisplaySpec("unix:1", { platform: "linux" }),
{ path: "/tmp/.X11-unix/X1" },
);
});
test("rewriteX11AuthSetupPacket replaces the SSH fake cookie with the local X11 cookie", () => {
const fakeCookie = "11111111111111111111111111111111";
const realCookie = "22222222222222222222222222222222";
const rewritten = rewriteX11AuthSetupPacket(buildX11SetupPacket({ cookie: fakeCookie }), {
fakeCookie,
realCookie: Buffer.from(realCookie, "hex"),
});
assert.equal(rewritten.complete, true);
assert.equal(rewritten.rewritten, true);
assert.match(rewritten.buffer.toString("hex"), new RegExp(realCookie));
assert.doesNotMatch(rewritten.buffer.toString("hex"), new RegExp(fakeCookie));
});
test("readLocalX11AuthCookie selects the cookie for the requested display", () => {
const cookie0 = "00000000000000000000000000000000";
const cookie10 = "10101010101010101010101010101010";
const cookie = readLocalX11AuthCookie({
display: ":0",
readXauthOutput: () => [
`host/unix:10 MIT-MAGIC-COOKIE-1 ${cookie10}`,
`host/unix:0 MIT-MAGIC-COOKIE-1 ${cookie0}`,
].join("\n"),
});
assert.equal(cookie.toString("hex"), cookie0);
});
test("readLocalX11AuthCookie matches explicit unix socket display paths", () => {
const cookie0 = "00000000000000000000000000000000";
const cookie1 = "11111111111111111111111111111111";
const cookie = readLocalX11AuthCookie({
display: "/tmp/.X11-unix/X1",
readXauthOutput: () => [
`host/unix:0 MIT-MAGIC-COOKIE-1 ${cookie0}`,
`host/unix:1 MIT-MAGIC-COOKIE-1 ${cookie1}`,
].join("\n"),
});
assert.equal(cookie.toString("hex"), cookie1);
});
test("attachX11Forwarding reuses a session-level local X11 cookie", async () => {
const conn = new EventEmitter();
const localSockets = [];
const acceptedChannels = [];
const cookieReads = [];
const makeDuplex = () => new Duplex({
read() {},
write(_chunk, _encoding, callback) {
callback();
},
});
attachX11Forwarding(conn, {
display: ":0",
fakeCookie: "11111111111111111111111111111111",
readLocalAuthCookie: () => {
cookieReads.push(Date.now());
return Buffer.from("22222222222222222222222222222222", "hex");
},
createSocket: () => {
const socket = makeDuplex();
socket.connect = () => {
queueMicrotask(() => socket.emit("connect"));
return socket;
};
localSockets.push(socket);
return socket;
},
sendMessage: () => {},
platform: "linux",
});
for (let i = 0; i < 2; i++) {
conn.emit("x11", { srcIP: "127.0.0.1", srcPort: 1234 + i }, () => {
const channel = makeDuplex();
acceptedChannels.push(channel);
return channel;
}, () => {
throw new Error("unexpected reject");
});
await new Promise((resolve) => setImmediate(resolve));
}
assert.equal(localSockets.length, 2);
assert.equal(acceptedChannels.length, 2);
assert.equal(cookieReads.length, 1);
});
test("attachX11Forwarding pipes accepted X11 channels to the local display socket", async () => {
const conn = new EventEmitter();
const localSocket = new Duplex({
read() {},
write(chunk, _encoding, callback) {
localSocket.written = Buffer.concat([localSocket.written ?? Buffer.alloc(0), Buffer.from(chunk)]);
callback();
},
});
const acceptedChannel = new Duplex({
read() {},
write(chunk, _encoding, callback) {
acceptedChannel.written = Buffer.concat([acceptedChannel.written ?? Buffer.alloc(0), Buffer.from(chunk)]);
callback();
},
});
localSocket.connect = () => {
queueMicrotask(() => localSocket.emit("connect"));
return localSocket;
};
let accepted = false;
const messages = [];
attachX11Forwarding(conn, {
display: ":0",
createSocket: () => localSocket,
sendMessage: (message) => messages.push(message),
platform: "linux",
});
conn.emit("x11", { srcIP: "127.0.0.1", srcPort: 1234 }, () => {
accepted = true;
return acceptedChannel;
}, () => {
throw new Error("unexpected reject");
});
await new Promise((resolve) => setImmediate(resolve));
acceptedChannel.push("remote");
localSocket.push("local");
await new Promise((resolve) => setImmediate(resolve));
assert.equal(accepted, true);
assert.equal(localSocket.written.toString(), "remote");
assert.equal(acceptedChannel.written.toString(), "local");
assert.deepEqual(messages, []);
});
test("attachX11Forwarding rejects the remote channel and explains local display failures", async () => {
const conn = new EventEmitter();
const localSocket = new EventEmitter();
localSocket.connect = () => {
queueMicrotask(() => localSocket.emit("error", new Error("ECONNREFUSED")));
return localSocket;
};
localSocket.destroy = () => {};
let rejected = false;
const messages = [];
attachX11Forwarding(conn, {
display: "localhost:0",
createSocket: () => localSocket,
sendMessage: (message) => messages.push(message),
platform: "win32",
});
conn.emit("x11", { srcIP: "127.0.0.1", srcPort: 1234 }, () => {
throw new Error("unexpected accept");
}, () => {
rejected = true;
});
await new Promise((resolve) => setImmediate(resolve));
assert.equal(rejected, true);
assert.match(messages.join("\n"), /Could not connect to the local X11 server/);
assert.match(messages.join("\n"), /VcXsrv/);
});