ai-remote 0.1.0

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.
Files changed (114) hide show
  1. package/README.md +50 -0
  2. package/dist/index.js +7 -0
  3. package/dist/index.js.map +7 -0
  4. package/dist/protocols/index.js +35 -0
  5. package/dist/protocols/index.js.map +7 -0
  6. package/dist/protocols/rdp/buffer.js +170 -0
  7. package/dist/protocols/rdp/buffer.js.map +7 -0
  8. package/dist/protocols/rdp/caps.js +260 -0
  9. package/dist/protocols/rdp/caps.js.map +7 -0
  10. package/dist/protocols/rdp/cert.js +135 -0
  11. package/dist/protocols/rdp/cert.js.map +7 -0
  12. package/dist/protocols/rdp/client.js +1068 -0
  13. package/dist/protocols/rdp/client.js.map +7 -0
  14. package/dist/protocols/rdp/cliprdr.js +240 -0
  15. package/dist/protocols/rdp/cliprdr.js.map +7 -0
  16. package/dist/protocols/rdp/credssp.js +254 -0
  17. package/dist/protocols/rdp/credssp.js.map +7 -0
  18. package/dist/protocols/rdp/crypto.js +369 -0
  19. package/dist/protocols/rdp/crypto.js.map +7 -0
  20. package/dist/protocols/rdp/display.js +589 -0
  21. package/dist/protocols/rdp/display.js.map +7 -0
  22. package/dist/protocols/rdp/gcc.js +132 -0
  23. package/dist/protocols/rdp/gcc.js.map +7 -0
  24. package/dist/protocols/rdp/keymap.js +132 -0
  25. package/dist/protocols/rdp/keymap.js.map +7 -0
  26. package/dist/protocols/rdp/mcs.js +223 -0
  27. package/dist/protocols/rdp/mcs.js.map +7 -0
  28. package/dist/protocols/rdp/ntlm.js +305 -0
  29. package/dist/protocols/rdp/ntlm.js.map +7 -0
  30. package/dist/protocols/rdp/pdu.js +444 -0
  31. package/dist/protocols/rdp/pdu.js.map +7 -0
  32. package/dist/protocols/rdp/rail.js +383 -0
  33. package/dist/protocols/rdp/rail.js.map +7 -0
  34. package/dist/protocols/rdp/rle.js +276 -0
  35. package/dist/protocols/rdp/rle.js.map +7 -0
  36. package/dist/protocols/rdp/sec.js +156 -0
  37. package/dist/protocols/rdp/sec.js.map +7 -0
  38. package/dist/protocols/rdp/session.js +307 -0
  39. package/dist/protocols/rdp/session.js.map +7 -0
  40. package/dist/protocols/rdp/tls.js +354 -0
  41. package/dist/protocols/rdp/tls.js.map +7 -0
  42. package/dist/protocols/rdp/vchannel.js +59 -0
  43. package/dist/protocols/rdp/vchannel.js.map +7 -0
  44. package/dist/protocols/rdp/x224.js +110 -0
  45. package/dist/protocols/rdp/x224.js.map +7 -0
  46. package/dist/protocols/ssh/kex.js +177 -0
  47. package/dist/protocols/ssh/kex.js.map +7 -0
  48. package/dist/protocols/ssh/messages.js +55 -0
  49. package/dist/protocols/ssh/messages.js.map +7 -0
  50. package/dist/protocols/ssh/session.js +608 -0
  51. package/dist/protocols/ssh/session.js.map +7 -0
  52. package/dist/protocols/ssh/terminal.js +191 -0
  53. package/dist/protocols/ssh/terminal.js.map +7 -0
  54. package/dist/protocols/ssh/transport.js +611 -0
  55. package/dist/protocols/ssh/transport.js.map +7 -0
  56. package/dist/protocols/ssh/wire.js +189 -0
  57. package/dist/protocols/ssh/wire.js.map +7 -0
  58. package/dist/protocols/types.js +1 -0
  59. package/dist/protocols/types.js.map +7 -0
  60. package/dist/protocols/vnc/input.js +16 -0
  61. package/dist/protocols/vnc/input.js.map +7 -0
  62. package/dist/protocols/vnc/session.js +259 -0
  63. package/dist/protocols/vnc/session.js.map +7 -0
  64. package/dist/shared/connection.js +114 -0
  65. package/dist/shared/connection.js.map +7 -0
  66. package/dist/shared/device.js +1 -0
  67. package/dist/shared/device.js.map +7 -0
  68. package/dist/shared/hosts.js +133 -0
  69. package/dist/shared/hosts.js.map +7 -0
  70. package/dist/shared/icons.js +42 -0
  71. package/dist/shared/icons.js.map +7 -0
  72. package/dist/shared/protocol.js +40 -0
  73. package/dist/shared/protocol.js.map +7 -0
  74. package/dist/shared/signals.js +42 -0
  75. package/dist/shared/signals.js.map +7 -0
  76. package/package.json +82 -0
  77. package/src/index.ts +14 -0
  78. package/src/protocols/index.ts +72 -0
  79. package/src/protocols/rdp/buffer.ts +204 -0
  80. package/src/protocols/rdp/caps.ts +304 -0
  81. package/src/protocols/rdp/cert.ts +190 -0
  82. package/src/protocols/rdp/client.ts +1363 -0
  83. package/src/protocols/rdp/cliprdr.ts +344 -0
  84. package/src/protocols/rdp/credssp.ts +319 -0
  85. package/src/protocols/rdp/crypto.ts +416 -0
  86. package/src/protocols/rdp/display.ts +750 -0
  87. package/src/protocols/rdp/gcc.ts +162 -0
  88. package/src/protocols/rdp/keymap.ts +68 -0
  89. package/src/protocols/rdp/mcs.ts +283 -0
  90. package/src/protocols/rdp/ntlm.ts +380 -0
  91. package/src/protocols/rdp/pdu.ts +497 -0
  92. package/src/protocols/rdp/rail.ts +480 -0
  93. package/src/protocols/rdp/rle.ts +343 -0
  94. package/src/protocols/rdp/sec.ts +184 -0
  95. package/src/protocols/rdp/session.ts +393 -0
  96. package/src/protocols/rdp/tls.ts +452 -0
  97. package/src/protocols/rdp/vchannel.ts +89 -0
  98. package/src/protocols/rdp/x224.ts +139 -0
  99. package/src/protocols/ssh/kex.ts +227 -0
  100. package/src/protocols/ssh/messages.ts +54 -0
  101. package/src/protocols/ssh/session.ts +878 -0
  102. package/src/protocols/ssh/terminal.ts +242 -0
  103. package/src/protocols/ssh/transport.ts +732 -0
  104. package/src/protocols/ssh/wire.ts +220 -0
  105. package/src/protocols/types.ts +146 -0
  106. package/src/protocols/vnc/input.ts +13 -0
  107. package/src/protocols/vnc/novnc.d.ts +75 -0
  108. package/src/protocols/vnc/session.ts +367 -0
  109. package/src/shared/connection.ts +206 -0
  110. package/src/shared/device.ts +28 -0
  111. package/src/shared/hosts.ts +240 -0
  112. package/src/shared/icons.ts +49 -0
  113. package/src/shared/protocol.ts +55 -0
  114. package/src/shared/signals.ts +67 -0
@@ -0,0 +1,177 @@
1
+ import { SshReader, SshWriter, concatBytes, padStart, toBase64, toBase64Url } from "./wire";
2
+ const subtle = globalThis.crypto?.subtle;
3
+ const KEX_ALGORITHMS = {
4
+ "curve25519-sha256": { type: "x25519", hash: "SHA-256" },
5
+ "curve25519-sha256@libssh.org": { type: "x25519", hash: "SHA-256" },
6
+ "ecdh-sha2-nistp256": { type: "ecdh", curve: "P-256", hash: "SHA-256" }
7
+ };
8
+ const HOST_KEY_ALGORITHMS = {
9
+ "ssh-ed25519": { keyType: "ssh-ed25519", kind: "ed25519" },
10
+ "rsa-sha2-512": { keyType: "ssh-rsa", kind: "rsa", hash: "SHA-512" },
11
+ "rsa-sha2-256": { keyType: "ssh-rsa", kind: "rsa", hash: "SHA-256" },
12
+ "ecdsa-sha2-nistp256": { keyType: "ecdsa-sha2-nistp256", kind: "ecdsa", curve: "P-256", hash: "SHA-256" }
13
+ };
14
+ async function supports(algorithm, usages) {
15
+ if (!subtle) return false;
16
+ try {
17
+ await subtle.generateKey(algorithm, false, usages);
18
+ return true;
19
+ } catch {
20
+ return false;
21
+ }
22
+ }
23
+ let cachedOffer = null;
24
+ async function negotiableAlgorithms() {
25
+ if (cachedOffer) return cachedOffer;
26
+ const [x25519, ed25519] = await Promise.all([
27
+ supports({ name: "X25519" }, ["deriveBits"]),
28
+ supports({ name: "Ed25519" }, ["sign", "verify"])
29
+ ]);
30
+ const kex = [];
31
+ if (x25519) kex.push("curve25519-sha256", "curve25519-sha256@libssh.org");
32
+ kex.push("ecdh-sha2-nistp256");
33
+ const hostKey = [];
34
+ if (ed25519) hostKey.push("ssh-ed25519");
35
+ hostKey.push("rsa-sha2-512", "rsa-sha2-256", "ecdsa-sha2-nistp256");
36
+ cachedOffer = { kex, hostKey, x25519, ed25519 };
37
+ return cachedOffer;
38
+ }
39
+ async function createKexClient(algorithmName) {
40
+ const algorithm = KEX_ALGORITHMS[algorithmName];
41
+ if (!algorithm) throw new Error(`SSH: unsupported key exchange ${algorithmName}`);
42
+ if (algorithm.type === "x25519") {
43
+ const pair2 = await subtle.generateKey({ name: "X25519" }, false, ["deriveBits"]);
44
+ const publicKey2 = new Uint8Array(await subtle.exportKey("raw", pair2.publicKey));
45
+ return {
46
+ hash: algorithm.hash,
47
+ publicKey: publicKey2,
48
+ async sharedSecret(serverPublicKey) {
49
+ if (serverPublicKey.length !== 32) throw new Error("SSH: the host sent a malformed X25519 key.");
50
+ const peer = await subtle.importKey("raw", serverPublicKey, { name: "X25519" }, false, []);
51
+ const secret = new Uint8Array(await subtle.deriveBits({ name: "X25519", public: peer }, pair2.privateKey, 256));
52
+ if (secret.every((byte) => byte === 0)) {
53
+ throw new Error("SSH: the host sent a degenerate X25519 key.");
54
+ }
55
+ return secret;
56
+ }
57
+ };
58
+ }
59
+ const pair = await subtle.generateKey({ name: "ECDH", namedCurve: algorithm.curve }, false, ["deriveBits"]);
60
+ const publicKey = new Uint8Array(await subtle.exportKey("raw", pair.publicKey));
61
+ return {
62
+ hash: algorithm.hash,
63
+ publicKey,
64
+ async sharedSecret(serverPublicKey) {
65
+ const peer = await subtle.importKey(
66
+ "raw",
67
+ serverPublicKey,
68
+ { name: "ECDH", namedCurve: algorithm.curve },
69
+ false,
70
+ []
71
+ );
72
+ return new Uint8Array(await subtle.deriveBits({ name: "ECDH", public: peer }, pair.privateKey, 256));
73
+ }
74
+ };
75
+ }
76
+ function hostKeyType(keyBlob) {
77
+ return new SshReader(keyBlob).string();
78
+ }
79
+ async function hostKeyFingerprint(keyBlob) {
80
+ const digest = new Uint8Array(await subtle.digest("SHA-256", keyBlob));
81
+ return `SHA256:${toBase64(digest).replace(/=+$/, "")}`;
82
+ }
83
+ async function importHostKey(algorithmName, keyBlob) {
84
+ const algorithm = HOST_KEY_ALGORITHMS[algorithmName];
85
+ if (!algorithm) throw new Error(`SSH: unsupported host key algorithm ${algorithmName}`);
86
+ const reader = new SshReader(keyBlob);
87
+ const keyType = reader.string();
88
+ if (keyType !== algorithm.keyType) {
89
+ throw new Error(`SSH: the host key is a ${keyType} but was announced as ${algorithmName}.`);
90
+ }
91
+ if (algorithm.kind === "ed25519") {
92
+ return subtle.importKey("raw", reader.stringBytes(), { name: "Ed25519" }, false, ["verify"]);
93
+ }
94
+ if (algorithm.kind === "rsa") {
95
+ const exponent = reader.mpint();
96
+ const modulus = reader.mpint();
97
+ return subtle.importKey(
98
+ "jwk",
99
+ { kty: "RSA", n: toBase64Url(modulus), e: toBase64Url(exponent), ext: true },
100
+ { name: "RSASSA-PKCS1-v1_5", hash: algorithm.hash },
101
+ false,
102
+ ["verify"]
103
+ );
104
+ }
105
+ reader.string();
106
+ return subtle.importKey(
107
+ "raw",
108
+ reader.stringBytes(),
109
+ { name: "ECDSA", namedCurve: algorithm.curve },
110
+ false,
111
+ ["verify"]
112
+ );
113
+ }
114
+ function signatureBytes(algorithmName, signatureBlob) {
115
+ const reader = new SshReader(signatureBlob);
116
+ const named = reader.string();
117
+ if (named !== algorithmName) {
118
+ throw new Error(`SSH: the host signed with ${named} after agreeing on ${algorithmName}.`);
119
+ }
120
+ const raw = reader.stringBytes();
121
+ if (HOST_KEY_ALGORITHMS[algorithmName]?.kind !== "ecdsa") return raw;
122
+ const parts = new SshReader(raw);
123
+ const r = parts.mpint();
124
+ const s = parts.mpint();
125
+ return concatBytes(padStart(r, 32), padStart(s, 32));
126
+ }
127
+ async function verifyHostKeySignature({ algorithm, keyBlob, signatureBlob, exchangeHash: exchangeHash2 }) {
128
+ const { kind, hash } = HOST_KEY_ALGORITHMS[algorithm];
129
+ const key = await importHostKey(algorithm, keyBlob);
130
+ const signature = signatureBytes(algorithm, signatureBlob);
131
+ const parameters = kind === "ecdsa" ? { name: "ECDSA", hash } : kind === "rsa" ? { name: "RSASSA-PKCS1-v1_5" } : { name: "Ed25519" };
132
+ return subtle.verify(parameters, key, signature, exchangeHash2);
133
+ }
134
+ async function exchangeHash({
135
+ hash,
136
+ clientVersion,
137
+ serverVersion,
138
+ clientKexInit,
139
+ serverKexInit,
140
+ hostKeyBlob,
141
+ clientPublicKey,
142
+ serverPublicKey,
143
+ sharedSecret
144
+ }) {
145
+ const writer = new SshWriter(1024);
146
+ writer.string(clientVersion);
147
+ writer.string(serverVersion);
148
+ writer.string(clientKexInit);
149
+ writer.string(serverKexInit);
150
+ writer.string(hostKeyBlob);
151
+ writer.string(clientPublicKey);
152
+ writer.string(serverPublicKey);
153
+ writer.mpint(sharedSecret);
154
+ return new Uint8Array(await subtle.digest(hash, writer.take()));
155
+ }
156
+ async function deriveKey({ hash, sharedSecret, exchangeHash: h, letter, sessionId, length }) {
157
+ const prefix = new SshWriter(64 + h.length).mpint(sharedSecret).take();
158
+ const seed = concatBytes(prefix, h, new Uint8Array([letter.charCodeAt(0)]), sessionId);
159
+ let material = new Uint8Array(await subtle.digest(hash, seed));
160
+ while (material.length < length) {
161
+ const extension = new Uint8Array(await subtle.digest(hash, concatBytes(prefix, h, material)));
162
+ material = concatBytes(material, extension);
163
+ }
164
+ return material.subarray(0, length);
165
+ }
166
+ export {
167
+ HOST_KEY_ALGORITHMS,
168
+ KEX_ALGORITHMS,
169
+ createKexClient,
170
+ deriveKey,
171
+ exchangeHash,
172
+ hostKeyFingerprint,
173
+ hostKeyType,
174
+ negotiableAlgorithms,
175
+ verifyHostKeySignature
176
+ };
177
+ //# sourceMappingURL=kex.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/protocols/ssh/kex.ts"],
4
+ "sourcesContent": ["// Key exchange and host-key verification.\n//\n// Every algorithm here is one the Web Crypto API implements, because the whole\n// SSH client runs in the browser: X25519 and NIST P-256 for the exchange, and\n// Ed25519, RSA or ECDSA to check the host's signature over it. Nothing is\n// hand-rolled, and nothing that cannot be verified is offered.\n\nimport { SshReader, SshWriter, concatBytes, padStart, toBase64, toBase64Url } from './wire';\n\nconst subtle = globalThis.crypto?.subtle;\n\n/** Key exchange methods, best first. All of them hash with SHA-256. */\nexport const KEX_ALGORITHMS = {\n 'curve25519-sha256': { type: 'x25519', hash: 'SHA-256' },\n 'curve25519-sha256@libssh.org': { type: 'x25519', hash: 'SHA-256' },\n 'ecdh-sha2-nistp256': { type: 'ecdh', curve: 'P-256', hash: 'SHA-256' },\n};\n\n/**\n * Host key signature algorithms. `keyType` is what appears inside the key blob;\n * a modern RSA key is signed with SHA-256 or SHA-512 but still calls itself\n * ssh-rsa, so the two names differ there.\n */\nexport const HOST_KEY_ALGORITHMS = {\n 'ssh-ed25519': { keyType: 'ssh-ed25519', kind: 'ed25519' },\n 'rsa-sha2-512': { keyType: 'ssh-rsa', kind: 'rsa', hash: 'SHA-512' },\n 'rsa-sha2-256': { keyType: 'ssh-rsa', kind: 'rsa', hash: 'SHA-256' },\n 'ecdsa-sha2-nistp256': { keyType: 'ecdsa-sha2-nistp256', kind: 'ecdsa', curve: 'P-256', hash: 'SHA-256' },\n};\n\nasync function supports(algorithm, usages) {\n if (!subtle) return false;\n try {\n await subtle.generateKey(algorithm, false, usages);\n return true;\n } catch {\n return false;\n }\n}\n\nlet cachedOffer = null;\n\n/**\n * What this browser can actually do. X25519 and Ed25519 are recent additions to\n * Web Crypto, so they are probed rather than assumed; the NIST curve and RSA\n * have been there all along and always keep the session possible.\n */\nexport async function negotiableAlgorithms() {\n if (cachedOffer) return cachedOffer;\n\n const [x25519, ed25519] = await Promise.all([\n supports({ name: 'X25519' }, ['deriveBits']),\n supports({ name: 'Ed25519' }, ['sign', 'verify']),\n ]);\n\n const kex = [];\n if (x25519) kex.push('curve25519-sha256', 'curve25519-sha256@libssh.org');\n kex.push('ecdh-sha2-nistp256');\n\n const hostKey = [];\n if (ed25519) hostKey.push('ssh-ed25519');\n hostKey.push('rsa-sha2-512', 'rsa-sha2-256', 'ecdsa-sha2-nistp256');\n\n cachedOffer = { kex, hostKey, x25519, ed25519 };\n return cachedOffer;\n}\n\n/** The client half of one key exchange. */\nexport async function createKexClient(algorithmName: string) {\n const algorithm = KEX_ALGORITHMS[algorithmName];\n if (!algorithm) throw new Error(`SSH: unsupported key exchange ${algorithmName}`);\n\n if (algorithm.type === 'x25519') {\n const pair = await subtle.generateKey({ name: 'X25519' }, false, ['deriveBits']);\n const publicKey = new Uint8Array(await subtle.exportKey('raw', pair.publicKey));\n return {\n hash: algorithm.hash,\n publicKey,\n async sharedSecret(serverPublicKey) {\n if (serverPublicKey.length !== 32) throw new Error('SSH: the host sent a malformed X25519 key.');\n const peer = await subtle.importKey('raw', serverPublicKey, { name: 'X25519' }, false, []);\n const secret = new Uint8Array(await subtle.deriveBits({ name: 'X25519', public: peer }, pair.privateKey, 256));\n if (secret.every((byte) => byte === 0)) {\n throw new Error('SSH: the host sent a degenerate X25519 key.');\n }\n return secret;\n },\n };\n }\n\n const pair = await subtle.generateKey({ name: 'ECDH', namedCurve: algorithm.curve }, false, ['deriveBits']);\n const publicKey = new Uint8Array(await subtle.exportKey('raw', pair.publicKey));\n return {\n hash: algorithm.hash,\n publicKey,\n async sharedSecret(serverPublicKey) {\n const peer = await subtle.importKey(\n 'raw', serverPublicKey, { name: 'ECDH', namedCurve: algorithm.curve }, false, []\n );\n return new Uint8Array(await subtle.deriveBits({ name: 'ECDH', public: peer }, pair.privateKey, 256));\n },\n };\n}\n\n/** The key type named inside a host key blob, which the algorithm must match. */\nexport function hostKeyType(keyBlob: Uint8Array) {\n return new SshReader(keyBlob).string();\n}\n\n/** The SHA256:\u2026 fingerprint OpenSSH prints, so a user can compare it. */\nexport async function hostKeyFingerprint(keyBlob: Uint8Array) {\n const digest = new Uint8Array(await subtle.digest('SHA-256', keyBlob));\n return `SHA256:${toBase64(digest).replace(/=+$/, '')}`;\n}\n\nasync function importHostKey(algorithmName: string, keyBlob: Uint8Array) {\n const algorithm = HOST_KEY_ALGORITHMS[algorithmName];\n if (!algorithm) throw new Error(`SSH: unsupported host key algorithm ${algorithmName}`);\n\n const reader = new SshReader(keyBlob);\n const keyType = reader.string();\n if (keyType !== algorithm.keyType) {\n throw new Error(`SSH: the host key is a ${keyType} but was announced as ${algorithmName}.`);\n }\n\n if (algorithm.kind === 'ed25519') {\n return subtle.importKey('raw', reader.stringBytes(), { name: 'Ed25519' }, false, ['verify']);\n }\n\n if (algorithm.kind === 'rsa') {\n const exponent = reader.mpint();\n const modulus = reader.mpint();\n return subtle.importKey(\n 'jwk',\n { kty: 'RSA', n: toBase64Url(modulus), e: toBase64Url(exponent), ext: true },\n { name: 'RSASSA-PKCS1-v1_5', hash: algorithm.hash },\n false,\n ['verify']\n );\n }\n\n reader.string(); // curve name, already implied by the algorithm\n return subtle.importKey(\n 'raw', reader.stringBytes(), { name: 'ECDSA', namedCurve: algorithm.curve }, false, ['verify']\n );\n}\n\n/** Unwrap the signature blob, which names its own algorithm again. */\nfunction signatureBytes(algorithmName: string, signatureBlob: Uint8Array) {\n const reader = new SshReader(signatureBlob);\n const named = reader.string();\n if (named !== algorithmName) {\n throw new Error(`SSH: the host signed with ${named} after agreeing on ${algorithmName}.`);\n }\n\n const raw = reader.stringBytes();\n if (HOST_KEY_ALGORITHMS[algorithmName]?.kind !== 'ecdsa') return raw;\n\n // ECDSA signatures arrive as two mpints and Web Crypto wants them as a fixed\n // width pair.\n const parts = new SshReader(raw);\n const r = parts.mpint();\n const s = parts.mpint();\n return concatBytes(padStart(r, 32), padStart(s, 32));\n}\n\n/**\n * Check that the host owns the key it presented, by verifying its signature\n * over the exchange hash. A failure here is fatal: it is what stands between\n * the session and a machine in the middle of it.\n */\nexport async function verifyHostKeySignature({ algorithm, keyBlob, signatureBlob, exchangeHash }) {\n const { kind, hash } = HOST_KEY_ALGORITHMS[algorithm];\n const key = await importHostKey(algorithm, keyBlob);\n const signature = signatureBytes(algorithm, signatureBlob);\n\n // Only ECDSA needs the digest named at verification time; the other two\n // carry it on the key itself.\n const parameters = kind === 'ecdsa'\n ? { name: 'ECDSA', hash }\n : kind === 'rsa' ? { name: 'RSASSA-PKCS1-v1_5' } : { name: 'Ed25519' };\n\n return subtle.verify(parameters, key, signature, exchangeHash);\n}\n\n/**\n * The exchange hash H (RFC 4253 section 8), which both sides compute from the\n * same inputs and the host signs.\n */\nexport async function exchangeHash({\n hash,\n clientVersion,\n serverVersion,\n clientKexInit,\n serverKexInit,\n hostKeyBlob,\n clientPublicKey,\n serverPublicKey,\n sharedSecret,\n}) {\n const writer = new SshWriter(1024);\n writer.string(clientVersion);\n writer.string(serverVersion);\n writer.string(clientKexInit);\n writer.string(serverKexInit);\n writer.string(hostKeyBlob);\n writer.string(clientPublicKey);\n writer.string(serverPublicKey);\n writer.mpint(sharedSecret);\n return new Uint8Array(await subtle.digest(hash, writer.take()));\n}\n\n/**\n * Derive one key from the exchange (RFC 4253 section 7.2), extending it with\n * further hash rounds when the cipher wants more bytes than one digest.\n */\nexport async function deriveKey({ hash, sharedSecret, exchangeHash: h, letter, sessionId, length }) {\n const prefix = new SshWriter(64 + h.length).mpint(sharedSecret).take();\n const seed = concatBytes(prefix, h, new Uint8Array([letter.charCodeAt(0)]), sessionId);\n\n let material = new Uint8Array(await subtle.digest(hash, seed));\n while (material.length < length) {\n const extension = new Uint8Array(await subtle.digest(hash, concatBytes(prefix, h, material)));\n material = concatBytes(material, extension);\n }\n return material.subarray(0, length);\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["pair", "publicKey", "exchangeHash"]
7
+ }
@@ -0,0 +1,55 @@
1
+ const MSG = {
2
+ DISCONNECT: 1,
3
+ IGNORE: 2,
4
+ UNIMPLEMENTED: 3,
5
+ DEBUG: 4,
6
+ SERVICE_REQUEST: 5,
7
+ SERVICE_ACCEPT: 6,
8
+ EXT_INFO: 7,
9
+ KEXINIT: 20,
10
+ NEWKEYS: 21,
11
+ KEX_ECDH_INIT: 30,
12
+ KEX_ECDH_REPLY: 31,
13
+ USERAUTH_REQUEST: 50,
14
+ USERAUTH_FAILURE: 51,
15
+ USERAUTH_SUCCESS: 52,
16
+ USERAUTH_BANNER: 53,
17
+ USERAUTH_INFO_REQUEST: 60,
18
+ USERAUTH_INFO_RESPONSE: 61,
19
+ GLOBAL_REQUEST: 80,
20
+ REQUEST_SUCCESS: 81,
21
+ REQUEST_FAILURE: 82,
22
+ CHANNEL_OPEN: 90,
23
+ CHANNEL_OPEN_CONFIRMATION: 91,
24
+ CHANNEL_OPEN_FAILURE: 92,
25
+ CHANNEL_WINDOW_ADJUST: 93,
26
+ CHANNEL_DATA: 94,
27
+ CHANNEL_EXTENDED_DATA: 95,
28
+ CHANNEL_EOF: 96,
29
+ CHANNEL_CLOSE: 97,
30
+ CHANNEL_REQUEST: 98,
31
+ CHANNEL_SUCCESS: 99,
32
+ CHANNEL_FAILURE: 100
33
+ };
34
+ const EXTENDED_DATA_STDERR = 1;
35
+ const DISCONNECT_REASON = {
36
+ 1: "the host reported a protocol error",
37
+ 2: "the host could not agree on a key exchange method",
38
+ 3: "the key exchange failed",
39
+ 5: "the host ran out of resources",
40
+ 6: "the connection was lost below SSH",
41
+ 7: "the host application ended the connection",
42
+ 8: "too many connections",
43
+ 9: "authentication was cancelled by the user",
44
+ 10: "no more authentication methods are available",
45
+ 11: "the host closed the connection",
46
+ 12: "authentication was cancelled by the host",
47
+ 14: "the host refused the authentication attempt",
48
+ 15: "the host closed the connection while authenticating"
49
+ };
50
+ export {
51
+ DISCONNECT_REASON,
52
+ EXTENDED_DATA_STDERR,
53
+ MSG
54
+ };
55
+ //# sourceMappingURL=messages.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/protocols/ssh/messages.ts"],
4
+ "sourcesContent": ["// SSH message numbers and the human wording for a disconnect (RFC 4250, 4253).\n\nexport const MSG = {\n DISCONNECT: 1,\n IGNORE: 2,\n UNIMPLEMENTED: 3,\n DEBUG: 4,\n SERVICE_REQUEST: 5,\n SERVICE_ACCEPT: 6,\n EXT_INFO: 7,\n KEXINIT: 20,\n NEWKEYS: 21,\n KEX_ECDH_INIT: 30,\n KEX_ECDH_REPLY: 31,\n USERAUTH_REQUEST: 50,\n USERAUTH_FAILURE: 51,\n USERAUTH_SUCCESS: 52,\n USERAUTH_BANNER: 53,\n USERAUTH_INFO_REQUEST: 60,\n USERAUTH_INFO_RESPONSE: 61,\n GLOBAL_REQUEST: 80,\n REQUEST_SUCCESS: 81,\n REQUEST_FAILURE: 82,\n CHANNEL_OPEN: 90,\n CHANNEL_OPEN_CONFIRMATION: 91,\n CHANNEL_OPEN_FAILURE: 92,\n CHANNEL_WINDOW_ADJUST: 93,\n CHANNEL_DATA: 94,\n CHANNEL_EXTENDED_DATA: 95,\n CHANNEL_EOF: 96,\n CHANNEL_CLOSE: 97,\n CHANNEL_REQUEST: 98,\n CHANNEL_SUCCESS: 99,\n CHANNEL_FAILURE: 100,\n};\n\n/** SSH_EXTENDED_DATA_STDERR. */\nexport const EXTENDED_DATA_STDERR = 1;\n\nexport const DISCONNECT_REASON = {\n 1: 'the host reported a protocol error',\n 2: 'the host could not agree on a key exchange method',\n 3: 'the key exchange failed',\n 5: 'the host ran out of resources',\n 6: 'the connection was lost below SSH',\n 7: 'the host application ended the connection',\n 8: 'too many connections',\n 9: 'authentication was cancelled by the user',\n 10: 'no more authentication methods are available',\n 11: 'the host closed the connection',\n 12: 'authentication was cancelled by the host',\n 14: 'the host refused the authentication attempt',\n 15: 'the host closed the connection while authenticating',\n};\n"],
5
+ "mappings": "AAEO,MAAM,MAAM;AAAA,EACjB,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,eAAe;AAAA,EACf,OAAO;AAAA,EACP,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,UAAU;AAAA,EACV,SAAS;AAAA,EACT,SAAS;AAAA,EACT,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,uBAAuB;AAAA,EACvB,wBAAwB;AAAA,EACxB,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,cAAc;AAAA,EACd,2BAA2B;AAAA,EAC3B,sBAAsB;AAAA,EACtB,uBAAuB;AAAA,EACvB,cAAc;AAAA,EACd,uBAAuB;AAAA,EACvB,aAAa;AAAA,EACb,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,iBAAiB;AACnB;AAGO,MAAM,uBAAuB;AAE7B,MAAM,oBAAoB;AAAA,EAC/B,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;",
6
+ "names": []
7
+ }