[Init] Initial commit - NetMesh terminal manager
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

This commit is contained in:
2026-09-13 18:24:01 +08:00
commit 3c72efcb7f
3255 changed files with 907009 additions and 0 deletions

View File

@@ -0,0 +1,341 @@
"use strict";
const test = require("node:test");
const assert = require("node:assert/strict");
const { EventEmitter } = require("node:events");
const { readFileSync } = require("node:fs");
const { Duplex } = require("node:stream");
const Module = require("node:module");
const keyboardInteractiveHandler = require("./keyboardInteractiveHandler.cjs");
const { resetSshTransportRegistryForTests } = require("./sshConnectionPool.cjs");
function createSender(onSend = () => {}) {
return {
id: 1,
isDestroyed: () => false,
send: onSend,
};
}
function loadBridgeWithMocks(t, { systemAgent = false, chainError = null } = {}) {
const originalLoad = Module._load;
let capturedChainOptions = null;
let capturedConnectOptions = null;
let connectedClient = null;
let capturedSystemAgentOptions = null;
let physicalDialCount = 0;
class MockSshClient extends EventEmitter {
constructor() {
super();
this.socketTimeouts = [];
this._sock = {
setTimeout: (value) => this.socketTimeouts.push(value),
};
}
connect(options) {
physicalDialCount += 1;
this.options = options;
connectedClient = this;
capturedConnectOptions = options;
setImmediate(() => {
this.emit("connect");
this.emit("ready");
});
}
forwardOut(_srcIP, _srcPort, _dstHost, _dstPort, callback) {
callback(null, new Duplex({
read() {},
write(_chunk, _encoding, done) {
done();
},
}));
}
end() {
this.emit("close");
}
}
Module._load = function patchedLoad(request, parent, isMain) {
if (request === "ssh2") {
return {
Client: MockSshClient,
utils: {
parseKey: () => null,
},
};
}
if (request === "./sshBridge.cjs") {
return {
buildAlgorithms: () => ({}),
connectThroughChain: async (_event, options, _jumpHosts, _hostname, _port, sessionId) => {
capturedChainOptions = options;
if (chainError) {
const requestId = keyboardInteractiveHandler.generateRequestId("jump-host");
keyboardInteractiveHandler.storeRequest(
requestId,
() => {},
_event.sender.id,
sessionId,
_event.sender,
);
throw chainError;
}
return {
socket: new Duplex({
read() {},
write(_chunk, _encoding, done) {
done();
},
}),
connections: [],
};
},
};
}
if (request === "./sshAuthHelper.cjs" && systemAgent) {
const helper = originalLoad.call(this, request, parent, isMain);
return {
...helper,
findAllDefaultPrivateKeys: async () => [{
keyName: "id_ed25519",
keyPath: "/home/alice/.ssh/id_ed25519",
privateKey: "PRIVATE KEY",
}],
prepareSystemSshAgentForAuth: async (options) => {
capturedSystemAgentOptions = options;
return {
getIdentities(callback) { callback(null, []); },
sign() {},
};
},
};
}
return originalLoad.call(this, request, parent, isMain);
};
const bridgePath = require.resolve("./portForwardingBridge.cjs");
delete require.cache[bridgePath];
const bridge = require("./portForwardingBridge.cjs");
t.after(() => {
Module._load = originalLoad;
delete require.cache[bridgePath];
});
return {
bridge,
getCapturedChainOptions: () => capturedChainOptions,
getCapturedConnectOptions: () => capturedConnectOptions,
getConnectedClient: () => connectedClient,
getCapturedSystemAgentOptions: () => capturedSystemAgentOptions,
getPhysicalDialCount: () => physicalDialCount,
};
}
test("simultaneous port forwards to one endpoint share one physical SSH dial", async (t) => {
resetSshTransportRegistryForTests({ defaultIdleTtlMs: 0 });
t.after(() => resetSshTransportRegistryForTests({ defaultIdleTtlMs: 0 }));
const { bridge, getPhysicalDialCount } = loadBridgeWithMocks(t);
const payload = {
type: "local",
localPort: 0,
bindAddress: "127.0.0.1",
remoteHost: "127.0.0.1",
remotePort: 3306,
hostname: "db.internal",
hostId: "db-host",
port: 22,
username: "dbuser",
password: "target-password",
authMethod: "password",
verifyHostKeys: false,
useSshAgent: false,
};
const firstEvent = { sender: { ...createSender(), id: 31 } };
const secondEvent = { sender: { ...createSender(), id: 32 } };
try {
const [first, second] = await Promise.all([
bridge.startPortForward(firstEvent, { ...payload, tunnelId: "pf-shared-1", ruleId: "rule-shared-1" }),
bridge.startPortForward(secondEvent, { ...payload, tunnelId: "pf-shared-2", ruleId: "rule-shared-2" }),
]);
assert.equal(first.success, true);
assert.equal(second.success, true);
assert.equal(getPhysicalDialCount(), 1);
} finally {
await bridge.stopPortForward(firstEvent, { tunnelId: "pf-shared-1" });
await bridge.stopPortForward(secondEvent, { tunnelId: "pf-shared-2" });
}
});
test("explicitly dedicated port forwards do not enter shared dial coordination", async (t) => {
resetSshTransportRegistryForTests({ defaultIdleTtlMs: 0 });
t.after(() => resetSshTransportRegistryForTests({ defaultIdleTtlMs: 0 }));
const { bridge, getPhysicalDialCount } = loadBridgeWithMocks(t);
const payload = {
type: "local",
localPort: 0,
bindAddress: "127.0.0.1",
remoteHost: "127.0.0.1",
remotePort: 3306,
hostname: "db.internal",
hostId: "db-host",
port: 22,
username: "dbuser",
password: "target-password",
authMethod: "password",
verifyHostKeys: false,
useSshAgent: false,
reuseTransport: false,
};
const firstEvent = { sender: { ...createSender(), id: 41 } };
const secondEvent = { sender: { ...createSender(), id: 42 } };
try {
const [first, second] = await Promise.all([
bridge.startPortForward(firstEvent, { ...payload, tunnelId: "pf-dedicated-1", ruleId: "rule-dedicated-1" }),
bridge.startPortForward(secondEvent, { ...payload, tunnelId: "pf-dedicated-2", ruleId: "rule-dedicated-2" }),
]);
assert.equal(first.success, true);
assert.equal(second.success, true);
assert.equal(getPhysicalDialCount(), 2);
} finally {
await bridge.stopPortForward(firstEvent, { tunnelId: "pf-dedicated-1" });
await bridge.stopPortForward(secondEvent, { tunnelId: "pf-dedicated-2" });
}
});
test("port forwarding routes jump-host keyboard-interactive prompts through the external scope", async (t) => {
const {
bridge,
getCapturedChainOptions,
getCapturedConnectOptions,
getConnectedClient,
} = loadBridgeWithMocks(t);
const event = { sender: createSender() };
try {
const knownHosts = [{
id: "kh-jump",
hostname: "jump.internal",
port: 22,
keyType: "ssh-ed25519",
fingerprint: "trusted-jump-fingerprint",
}];
const result = await bridge.startPortForward(event, {
tunnelId: "pf-jump-scope",
type: "local",
localPort: 0,
bindAddress: "127.0.0.1",
remoteHost: "127.0.0.1",
remotePort: 3306,
hostname: "db.internal",
port: 22,
username: "dbuser",
password: "target-password",
sshTcpConnectTimeoutMs: 45_000,
sshAuthReadyTimeoutMs: 300_000,
knownHosts,
jumpHosts: [{
hostname: "jump.internal",
port: 22,
username: "jumpuser",
password: "jump-password",
}],
});
assert.equal(result.success, true);
assert.equal(getCapturedChainOptions()?._keyboardInteractiveScope, "external");
assert.equal(getCapturedChainOptions()?.knownHosts, knownHosts);
assert.equal(getCapturedChainOptions()?.sshTcpConnectTimeoutMs, 45_000);
assert.equal(getCapturedChainOptions()?.sshAuthReadyTimeoutMs, 300_000);
assert.equal(getCapturedConnectOptions()?.timeout, 45_000);
assert.equal(getCapturedConnectOptions()?.readyTimeout, 0);
assert.deepEqual(getConnectedClient()?.socketTimeouts, [0]);
} finally {
await bridge.stopPortForward(event, { tunnelId: "pf-jump-scope" });
}
});
test("port forwarding forwards target hostId to keyboard-interactive prompts", () => {
const source = readFileSync(require.resolve("./portForwardingBridge.cjs"), "utf8");
assert.match(source, /hostname,\s*hostId,\s*port = 22,/);
assert.match(
source,
/conn\.on\("keyboard-interactive", createKeyboardInteractiveHandler\(\{\s*sender,\s*sessionId: tunnelId,\s*hostId,/,
);
});
test("jump-host startup failures clear pending keyboard-interactive prompts", async (t) => {
const sent = [];
const { bridge } = loadBridgeWithMocks(t, { chainError: new Error("jump auth timeout") });
const event = { sender: createSender((channel, payload) => sent.push({ channel, payload })) };
await assert.rejects(
bridge.startPortForward(event, {
tunnelId: "pf-jump-failure",
type: "local",
localPort: 0,
bindAddress: "127.0.0.1",
remoteHost: "127.0.0.1",
remotePort: 3306,
hostname: "db.internal",
username: "dbuser",
jumpHosts: [{ hostname: "jump.internal", username: "jumpuser" }],
}),
/jump auth timeout/,
);
assert.equal(
Array.from(keyboardInteractiveHandler.getRequests().values())
.some((request) => request.sessionId === "pf-jump-failure"),
false,
);
assert.equal(
sent.some(({ channel, payload }) =>
channel === "netcatty:keyboard-interactive-cancelled" &&
payload.sessionId === "pf-jump-failure" &&
payload.reason === "connection-ended"),
true,
);
});
test("strict target agent selection keeps default keys available to jump hosts", async (t) => {
const { bridge, getCapturedChainOptions, getCapturedSystemAgentOptions } = loadBridgeWithMocks(t, { systemAgent: true });
const event = { sender: createSender() };
try {
const result = await bridge.startPortForward(event, {
tunnelId: "pf-strict-target",
type: "local",
localPort: 0,
bindAddress: "127.0.0.1",
remoteHost: "127.0.0.1",
remotePort: 3306,
hostname: "db.internal",
port: 2222,
username: "dbuser",
useSshAgent: true,
identitiesOnly: true,
jumpHosts: [{
hostname: "jump.internal",
port: 22,
username: "jumpuser",
}],
});
assert.equal(result.success, true);
assert.deepEqual(getCapturedChainOptions()?._defaultKeys, [{
keyName: "id_ed25519",
keyPath: "/home/alice/.ssh/id_ed25519",
privateKey: "PRIVATE KEY",
}]);
assert.equal(getCapturedSystemAgentOptions()?.port, 2222);
} finally {
await bridge.stopPortForward(event, { tunnelId: "pf-strict-target" });
}
});