ai-remote 0.5.0 → 0.5.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/dist/{cli-chunk-F2TSY3YW.mjs → cli-chunk-DGYNADUR.mjs} +1 -1
- package/dist/{cli-chunk-Q33YGIDO.mjs → cli-chunk-M5GGPPAC.mjs} +1 -1
- package/dist/{cli-chunk-OZG2CODR.mjs → cli-chunk-WBOYG4KJ.mjs} +1 -1
- package/dist/{cli-chunk-S2TWL5LF.mjs → cli-chunk-X2JMVOWL.mjs} +77 -20
- package/dist/{cli-copy-BOF44DWQ.mjs → cli-copy-ZBTICP7N.mjs} +1 -1
- package/dist/{cli-daemon-3BBFQCML.mjs → cli-daemon-M3KM2YHW.mjs} +233 -80
- package/dist/{cli-identities-ZILT4XCR.mjs → cli-identities-GBQWYF2O.mjs} +4 -4
- package/dist/{cli-shell-45XRTE7O.mjs → cli-shell-22PZYNSJ.mjs} +2 -2
- package/dist/{cli-window-ZKAXEHQV.mjs → cli-window-WLRFUKSW.mjs} +2 -2
- package/dist/cli.mjs +26 -22
- package/dist/protocols.d.ts +149 -15
- package/dist/protocols.js +16 -16
- package/package.json +1 -1
|
@@ -175,7 +175,9 @@ async function createKexClient(algorithmName) {
|
|
|
175
175
|
}
|
|
176
176
|
};
|
|
177
177
|
}
|
|
178
|
-
|
|
178
|
+
if (!algorithm.curve) throw new Error(`SSH: ${algorithmName} names no curve to exchange over`);
|
|
179
|
+
const curve = algorithm.curve;
|
|
180
|
+
const pair = await subtle.generateKey({ name: "ECDH", namedCurve: curve }, false, ["deriveBits"]);
|
|
179
181
|
const publicKey = new Uint8Array(await subtle.exportKey("raw", pair.publicKey));
|
|
180
182
|
return {
|
|
181
183
|
hash: algorithm.hash,
|
|
@@ -184,7 +186,7 @@ async function createKexClient(algorithmName) {
|
|
|
184
186
|
const peer = await subtle.importKey(
|
|
185
187
|
"raw",
|
|
186
188
|
serverPublicKey,
|
|
187
|
-
{ name: "ECDH", namedCurve:
|
|
189
|
+
{ name: "ECDH", namedCurve: curve },
|
|
188
190
|
false,
|
|
189
191
|
[]
|
|
190
192
|
);
|
|
@@ -244,7 +246,9 @@ function signatureBytes(algorithmName, signatureBlob) {
|
|
|
244
246
|
return concatBytes(padStart(r, 32), padStart(s, 32));
|
|
245
247
|
}
|
|
246
248
|
async function verifyHostKeySignature({ algorithm, keyBlob, signatureBlob, exchangeHash: exchangeHash2 }) {
|
|
247
|
-
const
|
|
249
|
+
const named = HOST_KEY_ALGORITHMS[algorithm];
|
|
250
|
+
if (!named) throw new Error(`SSH: unsupported host key algorithm ${algorithm}`);
|
|
251
|
+
const { kind, hash } = named;
|
|
248
252
|
const key = await importHostKey(algorithm, keyBlob);
|
|
249
253
|
const signature = signatureBytes(algorithm, signatureBlob);
|
|
250
254
|
const parameters = kind === "ecdsa" ? { name: "ECDSA", hash } : kind === "rsa" ? { name: "RSASSA-PKCS1-v1_5" } : { name: "Ed25519" };
|
|
@@ -356,6 +360,7 @@ var SshTransport = class extends EventTarget {
|
|
|
356
360
|
releaseNewKeys;
|
|
357
361
|
pendingServerKexInit;
|
|
358
362
|
established;
|
|
363
|
+
drainChain;
|
|
359
364
|
/**
|
|
360
365
|
* @param {string} url gateway WebSocket URL
|
|
361
366
|
* @param {object} options
|
|
@@ -387,10 +392,11 @@ var SshTransport = class extends EventTarget {
|
|
|
387
392
|
}
|
|
388
393
|
// --- connection ----------------------------------------------------------
|
|
389
394
|
connect() {
|
|
390
|
-
|
|
391
|
-
this.socket
|
|
392
|
-
|
|
393
|
-
|
|
395
|
+
const socket = this.openTransport ? this.openTransport(this.url) : new WebSocket(this.url);
|
|
396
|
+
this.socket = socket;
|
|
397
|
+
socket.binaryType = "arraybuffer";
|
|
398
|
+
socket.addEventListener("open", () => {
|
|
399
|
+
socket.send(GATEWAY_READY_SIGNAL);
|
|
394
400
|
this.#write(encodeUtf8(`${CLIENT_VERSION}\r
|
|
395
401
|
`));
|
|
396
402
|
this.keepaliveTimer = setInterval(() => {
|
|
@@ -404,18 +410,18 @@ var SshTransport = class extends EventTarget {
|
|
|
404
410
|
}
|
|
405
411
|
}, KEEPALIVE_INTERVAL_MS);
|
|
406
412
|
});
|
|
407
|
-
|
|
413
|
+
socket.addEventListener("message", (event) => {
|
|
408
414
|
if (typeof event.data === "string") return;
|
|
409
415
|
this.#receive(new Uint8Array(event.data));
|
|
410
416
|
});
|
|
411
|
-
|
|
417
|
+
socket.addEventListener("close", (event) => {
|
|
412
418
|
this.#finish({
|
|
413
419
|
clean: event.code === 1e3,
|
|
414
420
|
code: event.code,
|
|
415
421
|
message: event.reason || (event.code === 1006 ? "The gateway rejected or could not reach this SSH target. Confirm that SSH is published for this host." : "")
|
|
416
422
|
});
|
|
417
423
|
});
|
|
418
|
-
|
|
424
|
+
socket.addEventListener("error", () => {
|
|
419
425
|
this.log("The SSH gateway WebSocket reported a transport error; waiting for its close reason.");
|
|
420
426
|
});
|
|
421
427
|
}
|
|
@@ -792,11 +798,16 @@ var SshTransport = class extends EventTarget {
|
|
|
792
798
|
exchangeHash: hash,
|
|
793
799
|
sessionId: this.sessionId
|
|
794
800
|
};
|
|
801
|
+
const toServerCipher = CIPHERS[cipherToServer];
|
|
802
|
+
const toClientCipher = CIPHERS[cipherToClient];
|
|
803
|
+
if (!toServerCipher || !toClientCipher) {
|
|
804
|
+
throw new Error(`SSH: negotiated a cipher this client does not implement (${cipherToServer}, ${cipherToClient})`);
|
|
805
|
+
}
|
|
795
806
|
const [ivToServer, ivToClient, keyToServer, keyToClient] = await Promise.all([
|
|
796
807
|
deriveKey({ ...parameters, letter: "A", length: GCM_IV_BYTES }),
|
|
797
808
|
deriveKey({ ...parameters, letter: "B", length: GCM_IV_BYTES }),
|
|
798
|
-
deriveKey({ ...parameters, letter: "C", length:
|
|
799
|
-
deriveKey({ ...parameters, letter: "D", length:
|
|
809
|
+
deriveKey({ ...parameters, letter: "C", length: toServerCipher.keyLength }),
|
|
810
|
+
deriveKey({ ...parameters, letter: "D", length: toClientCipher.keyLength })
|
|
800
811
|
]);
|
|
801
812
|
this.outgoing = await GcmCipher.create(keyToServer, ivToServer);
|
|
802
813
|
this.incoming = await GcmCipher.create(keyToClient, ivToClient);
|
|
@@ -956,6 +967,52 @@ function releaseDisplayFilter(session) {
|
|
|
956
967
|
}));
|
|
957
968
|
}
|
|
958
969
|
var SshSession = class extends EventTarget {
|
|
970
|
+
options;
|
|
971
|
+
username;
|
|
972
|
+
password;
|
|
973
|
+
/**
|
|
974
|
+
* Keys to sign in with, if any. A function rather than a list is allowed
|
|
975
|
+
* because reading keys off a disk -- or asking an agent for them -- is work
|
|
976
|
+
* a session that never needs them should not do.
|
|
977
|
+
*/
|
|
978
|
+
/** Replaced with the resolved list the first time it is read. */
|
|
979
|
+
identities;
|
|
980
|
+
requestInput;
|
|
981
|
+
/** Whether there is anybody to ask; see the constructor. */
|
|
982
|
+
canAsk;
|
|
983
|
+
columns;
|
|
984
|
+
rows;
|
|
985
|
+
/** A subsystem to run instead of a shell, e.g. 'sftp'. */
|
|
986
|
+
subsystem;
|
|
987
|
+
channelId;
|
|
988
|
+
remoteChannelId;
|
|
989
|
+
remoteWindow;
|
|
990
|
+
remoteMaxPacket;
|
|
991
|
+
localWindow;
|
|
992
|
+
pendingWrites;
|
|
993
|
+
shellOpen;
|
|
994
|
+
commandInFlight;
|
|
995
|
+
/** Set while a tool command runs, to keep its framing off the screen. */
|
|
996
|
+
displayFilter;
|
|
997
|
+
/** True only after the requested interactive shell is ready for commands. */
|
|
998
|
+
readySignaled;
|
|
999
|
+
powerShellAttempted;
|
|
1000
|
+
powerShellTimer;
|
|
1001
|
+
/** '', 'posix', 'cmd' or 'powershell'; learned from the prompt. */
|
|
1002
|
+
shellFamily;
|
|
1003
|
+
promptTail;
|
|
1004
|
+
exitStatus;
|
|
1005
|
+
exitSignal;
|
|
1006
|
+
authMethods;
|
|
1007
|
+
/** Which keys were offered and refused, for the message if nothing works. */
|
|
1008
|
+
triedKeys;
|
|
1009
|
+
/** Set once the host has said no to the stored password. */
|
|
1010
|
+
passwordRejected;
|
|
1011
|
+
closed;
|
|
1012
|
+
waiters;
|
|
1013
|
+
transport;
|
|
1014
|
+
fingerprint;
|
|
1015
|
+
lastMessage;
|
|
959
1016
|
/**
|
|
960
1017
|
* @param {string} url gateway WebSocket URL
|
|
961
1018
|
* @param {object} options
|
|
@@ -1033,7 +1090,7 @@ var SshSession = class extends EventTarget {
|
|
|
1033
1090
|
this.transport.addEventListener("close", (event) => {
|
|
1034
1091
|
if (this.closed) return;
|
|
1035
1092
|
this.closed = true;
|
|
1036
|
-
clearTimeout(this.powerShellTimer);
|
|
1093
|
+
clearTimeout(this.powerShellTimer ?? void 0);
|
|
1037
1094
|
this.#abandonWaiters(event.detail.message || "The SSH connection closed.");
|
|
1038
1095
|
this.dispatchEvent(new CustomEvent("close", {
|
|
1039
1096
|
detail: {
|
|
@@ -1050,7 +1107,7 @@ var SshSession = class extends EventTarget {
|
|
|
1050
1107
|
}
|
|
1051
1108
|
disconnect() {
|
|
1052
1109
|
if (this.closed) return;
|
|
1053
|
-
clearTimeout(this.powerShellTimer);
|
|
1110
|
+
clearTimeout(this.powerShellTimer ?? void 0);
|
|
1054
1111
|
if (this.shellOpen && this.remoteChannelId !== null) {
|
|
1055
1112
|
this.transport.send(new SshWriter(8).u8(MSG.CHANNEL_CLOSE).u32(this.remoteChannelId).take());
|
|
1056
1113
|
}
|
|
@@ -1111,9 +1168,9 @@ var SshSession = class extends EventTarget {
|
|
|
1111
1168
|
return new Promise((resolve, reject) => {
|
|
1112
1169
|
let transcript = "";
|
|
1113
1170
|
let started = false;
|
|
1114
|
-
let startTimer
|
|
1115
|
-
let idleTimer
|
|
1116
|
-
let maxTimer
|
|
1171
|
+
let startTimer;
|
|
1172
|
+
let idleTimer;
|
|
1173
|
+
let maxTimer;
|
|
1117
1174
|
const finish = (settle) => {
|
|
1118
1175
|
clearTimeout(startTimer);
|
|
1119
1176
|
clearTimeout(idleTimer);
|
|
@@ -1149,7 +1206,7 @@ var SshSession = class extends EventTarget {
|
|
|
1149
1206
|
timedOut: false,
|
|
1150
1207
|
started,
|
|
1151
1208
|
durationMs: Date.now() - startedAt,
|
|
1152
|
-
error: error.message
|
|
1209
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1153
1210
|
}
|
|
1154
1211
|
}));
|
|
1155
1212
|
reject(error);
|
|
@@ -1174,7 +1231,7 @@ var SshSession = class extends EventTarget {
|
|
|
1174
1231
|
if (!started && transcript.indexOf(begin) !== -1) {
|
|
1175
1232
|
started = true;
|
|
1176
1233
|
clearTimeout(startTimer);
|
|
1177
|
-
startTimer =
|
|
1234
|
+
startTimer = void 0;
|
|
1178
1235
|
}
|
|
1179
1236
|
if (started) {
|
|
1180
1237
|
clearTimeout(idleTimer);
|
|
@@ -1333,7 +1390,7 @@ var SshSession = class extends EventTarget {
|
|
|
1333
1390
|
}, 2e3);
|
|
1334
1391
|
}
|
|
1335
1392
|
#markReady(message = "Connected.") {
|
|
1336
|
-
clearTimeout(this.powerShellTimer);
|
|
1393
|
+
clearTimeout(this.powerShellTimer ?? void 0);
|
|
1337
1394
|
this.powerShellTimer = null;
|
|
1338
1395
|
this.readySignaled = true;
|
|
1339
1396
|
this.#status("ready", message);
|