bdy 1.23.6-dev → 1.23.7-dev

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 (205) hide show
  1. package/distTs/package.json +10 -2
  2. package/distTs/src/agent/linux.js +53 -3
  3. package/distTs/src/agent/manager.js +3 -6
  4. package/distTs/src/agent/osx.js +51 -3
  5. package/distTs/src/agent/system.js +400 -21
  6. package/distTs/src/agent/windows.js +4 -7
  7. package/distTs/src/command/agent/debug.js +2 -2
  8. package/distTs/src/command/agent/install.js +37 -10
  9. package/distTs/src/command/agent/restart.js +2 -2
  10. package/distTs/src/command/agent/run.js +3 -0
  11. package/distTs/src/command/agent/start.js +2 -2
  12. package/distTs/src/command/agent/status.js +19 -0
  13. package/distTs/src/command/agent/stop.js +2 -2
  14. package/distTs/src/command/agent/uninstall.js +5 -8
  15. package/distTs/src/command/agent/update.js +2 -2
  16. package/distTs/src/command/artifact/publish.js +3 -1
  17. package/distTs/src/command/version.js +13 -5
  18. package/distTs/src/logger.js +40 -4
  19. package/distTs/src/texts.js +35 -19
  20. package/distTs/src/utils.js +98 -3
  21. package/node_modules/asn1/Jenkinsfile +65 -0
  22. package/node_modules/asn1/LICENSE +19 -0
  23. package/node_modules/asn1/README.md +50 -0
  24. package/node_modules/asn1/lib/ber/errors.js +13 -0
  25. package/node_modules/asn1/lib/ber/index.js +27 -0
  26. package/node_modules/asn1/lib/ber/reader.js +262 -0
  27. package/node_modules/asn1/lib/ber/types.js +36 -0
  28. package/node_modules/asn1/lib/ber/writer.js +317 -0
  29. package/node_modules/asn1/lib/index.js +20 -0
  30. package/node_modules/asn1/package.json +31 -0
  31. package/node_modules/bcrypt-pbkdf/CONTRIBUTING.md +13 -0
  32. package/node_modules/bcrypt-pbkdf/LICENSE +66 -0
  33. package/node_modules/bcrypt-pbkdf/README.md +45 -0
  34. package/node_modules/bcrypt-pbkdf/index.js +556 -0
  35. package/node_modules/bcrypt-pbkdf/package.json +15 -0
  36. package/node_modules/safer-buffer/LICENSE +21 -0
  37. package/node_modules/safer-buffer/Porting-Buffer.md +268 -0
  38. package/node_modules/safer-buffer/Readme.md +156 -0
  39. package/node_modules/safer-buffer/dangerous.js +58 -0
  40. package/node_modules/safer-buffer/package.json +34 -0
  41. package/node_modules/safer-buffer/safer.js +77 -0
  42. package/node_modules/safer-buffer/tests.js +406 -0
  43. package/node_modules/ssh2/.eslintignore +4 -0
  44. package/node_modules/ssh2/.eslintrc.js +5 -0
  45. package/node_modules/ssh2/.github/workflows/ci.yml +110 -0
  46. package/node_modules/ssh2/.github/workflows/lint.yml +27 -0
  47. package/node_modules/ssh2/LICENSE +19 -0
  48. package/node_modules/ssh2/README.md +1529 -0
  49. package/node_modules/ssh2/SFTP.md +413 -0
  50. package/node_modules/ssh2/examples/server-chat.js +238 -0
  51. package/node_modules/ssh2/examples/sftp-server-download-only.js +134 -0
  52. package/node_modules/ssh2/install.js +27 -0
  53. package/node_modules/ssh2/lib/Channel.js +295 -0
  54. package/node_modules/ssh2/lib/agent.js +1123 -0
  55. package/node_modules/ssh2/lib/client.js +2176 -0
  56. package/node_modules/ssh2/lib/http-agents.js +84 -0
  57. package/node_modules/ssh2/lib/index.js +44 -0
  58. package/node_modules/ssh2/lib/keygen.js +582 -0
  59. package/node_modules/ssh2/lib/protocol/Protocol.js +2136 -0
  60. package/node_modules/ssh2/lib/protocol/SFTP.js +4052 -0
  61. package/node_modules/ssh2/lib/protocol/constants.js +356 -0
  62. package/node_modules/ssh2/lib/protocol/crypto/binding.gyp +23 -0
  63. package/node_modules/ssh2/lib/protocol/crypto/poly1305.js +43 -0
  64. package/node_modules/ssh2/lib/protocol/crypto/src/binding.cc +2300 -0
  65. package/node_modules/ssh2/lib/protocol/crypto.js +1602 -0
  66. package/node_modules/ssh2/lib/protocol/handlers.js +16 -0
  67. package/node_modules/ssh2/lib/protocol/handlers.misc.js +1285 -0
  68. package/node_modules/ssh2/lib/protocol/kex.js +1908 -0
  69. package/node_modules/ssh2/lib/protocol/keyParser.js +1484 -0
  70. package/node_modules/ssh2/lib/protocol/node-fs-compat.js +115 -0
  71. package/node_modules/ssh2/lib/protocol/utils.js +356 -0
  72. package/node_modules/ssh2/lib/protocol/zlib.js +255 -0
  73. package/node_modules/ssh2/lib/server.js +1380 -0
  74. package/node_modules/ssh2/lib/utils.js +336 -0
  75. package/node_modules/ssh2/package.json +49 -0
  76. package/node_modules/ssh2/test/common.js +316 -0
  77. package/node_modules/ssh2/test/fixtures/bad_rsa_private_key +26 -0
  78. package/node_modules/ssh2/test/fixtures/https_cert.pem +33 -0
  79. package/node_modules/ssh2/test/fixtures/https_key.pem +52 -0
  80. package/node_modules/ssh2/test/fixtures/id_dsa +12 -0
  81. package/node_modules/ssh2/test/fixtures/id_ecdsa +5 -0
  82. package/node_modules/ssh2/test/fixtures/id_rsa +15 -0
  83. package/node_modules/ssh2/test/fixtures/id_rsa.ppk +26 -0
  84. package/node_modules/ssh2/test/fixtures/id_rsa_enc +30 -0
  85. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa +21 -0
  86. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa.pub +1 -0
  87. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa.pub.result +7 -0
  88. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa.result +7 -0
  89. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc +22 -0
  90. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc.pub +1 -0
  91. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc.pub.result +7 -0
  92. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc.result +7 -0
  93. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc_gcm +23 -0
  94. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc_gcm.pub +1 -0
  95. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc_gcm.pub.result +7 -0
  96. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc_gcm.result +7 -0
  97. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa +9 -0
  98. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa.pub +1 -0
  99. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa.pub.result +7 -0
  100. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa.result +7 -0
  101. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc +10 -0
  102. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc.pub +1 -0
  103. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc.pub.result +8 -0
  104. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc.result +7 -0
  105. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc_gcm +10 -0
  106. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc_gcm.pub +1 -0
  107. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc_gcm.pub.result +8 -0
  108. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc_gcm.result +7 -0
  109. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ed25519 +7 -0
  110. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ed25519.pub +1 -0
  111. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ed25519.pub.result +7 -0
  112. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ed25519.result +7 -0
  113. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa +27 -0
  114. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa.pub +1 -0
  115. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa.pub.result +7 -0
  116. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa.result +7 -0
  117. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc +28 -0
  118. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc.pub +1 -0
  119. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc.pub.result +8 -0
  120. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc.result +7 -0
  121. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc_gcm +29 -0
  122. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc_gcm.pub +1 -0
  123. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc_gcm.pub.result +8 -0
  124. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc_gcm.result +7 -0
  125. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa +12 -0
  126. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa.pub +1 -0
  127. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa.pub.result +7 -0
  128. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa.result +7 -0
  129. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa_enc +15 -0
  130. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa_enc.pub +1 -0
  131. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa_enc.pub.result +8 -0
  132. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa_enc.result +7 -0
  133. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa +5 -0
  134. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa.pub +1 -0
  135. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa.pub.result +7 -0
  136. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa.result +7 -0
  137. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa_enc +8 -0
  138. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa_enc.pub +1 -0
  139. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa_enc.pub.result +8 -0
  140. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa_enc.result +7 -0
  141. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa +27 -0
  142. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa.pub +1 -0
  143. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa.pub.result +7 -0
  144. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa.result +7 -0
  145. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc +30 -0
  146. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc.pub +1 -0
  147. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc.pub.result +8 -0
  148. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc.result +7 -0
  149. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc_aes256 +54 -0
  150. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc_aes256.pub +1 -0
  151. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc_aes256.pub.result +6 -0
  152. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc_aes256.result +6 -0
  153. package/node_modules/ssh2/test/fixtures/keyParser/ppk_dsa_enc +17 -0
  154. package/node_modules/ssh2/test/fixtures/keyParser/ppk_dsa_enc.result +7 -0
  155. package/node_modules/ssh2/test/fixtures/keyParser/ppk_rsa +26 -0
  156. package/node_modules/ssh2/test/fixtures/keyParser/ppk_rsa.result +7 -0
  157. package/node_modules/ssh2/test/fixtures/keyParser/ppk_rsa_enc +18 -0
  158. package/node_modules/ssh2/test/fixtures/keyParser/ppk_rsa_enc.result +7 -0
  159. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa.pub +9 -0
  160. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa.pub.result +7 -0
  161. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa2.pub +10 -0
  162. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa2.pub.result +7 -0
  163. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa3.pub +11 -0
  164. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa3.pub.result +7 -0
  165. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa4.pub +11 -0
  166. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa4.pub.result +7 -0
  167. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa5.pub +8 -0
  168. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa5.pub.result +7 -0
  169. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa6.pub +13 -0
  170. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa6.pub.result +7 -0
  171. package/node_modules/ssh2/test/fixtures/openssh_new_rsa +27 -0
  172. package/node_modules/ssh2/test/fixtures/ssh_host_dsa_key +12 -0
  173. package/node_modules/ssh2/test/fixtures/ssh_host_ecdsa_key +5 -0
  174. package/node_modules/ssh2/test/fixtures/ssh_host_rsa_key +15 -0
  175. package/node_modules/ssh2/test/test-exec.js +578 -0
  176. package/node_modules/ssh2/test/test-integration-openssh.js +486 -0
  177. package/node_modules/ssh2/test/test-keygen.js +60 -0
  178. package/node_modules/ssh2/test/test-misc-client-server.js +1460 -0
  179. package/node_modules/ssh2/test/test-openssh.js +261 -0
  180. package/node_modules/ssh2/test/test-protocol-crypto.js +631 -0
  181. package/node_modules/ssh2/test/test-protocol-keyparser.js +177 -0
  182. package/node_modules/ssh2/test/test-server-hostkeys.js +138 -0
  183. package/node_modules/ssh2/test/test-sftp.js +842 -0
  184. package/node_modules/ssh2/test/test-shell.js +109 -0
  185. package/node_modules/ssh2/test/test-userauth-agent-openssh.js +110 -0
  186. package/node_modules/ssh2/test/test-userauth-agent.js +171 -0
  187. package/node_modules/ssh2/test/test-userauth.js +611 -0
  188. package/node_modules/ssh2/test/test-worker-imports.js +25 -0
  189. package/node_modules/ssh2/test/test.js +20 -0
  190. package/node_modules/ssh2/util/build_pagent.bat +2 -0
  191. package/node_modules/ssh2/util/pagent.c +88 -0
  192. package/node_modules/ssh2/util/pagent.exe +0 -0
  193. package/node_modules/tweetnacl/.npmignore +4 -0
  194. package/node_modules/tweetnacl/AUTHORS.md +28 -0
  195. package/node_modules/tweetnacl/CHANGELOG.md +221 -0
  196. package/node_modules/tweetnacl/LICENSE +24 -0
  197. package/node_modules/tweetnacl/PULL_REQUEST_TEMPLATE.md +20 -0
  198. package/node_modules/tweetnacl/README.md +459 -0
  199. package/node_modules/tweetnacl/nacl-fast.js +2388 -0
  200. package/node_modules/tweetnacl/nacl-fast.min.js +2 -0
  201. package/node_modules/tweetnacl/nacl.d.ts +98 -0
  202. package/node_modules/tweetnacl/nacl.js +1175 -0
  203. package/node_modules/tweetnacl/nacl.min.js +1 -0
  204. package/node_modules/tweetnacl/package.json +58 -0
  205. package/package.json +10 -2
@@ -0,0 +1,486 @@
1
+ // TODO: add more rekey tests that at least include switching from no
2
+ // compression to compression and vice versa
3
+ 'use strict';
4
+
5
+ const assert = require('assert');
6
+ const { spawn, spawnSync } = require('child_process');
7
+ const { chmodSync, readdirSync } = require('fs');
8
+ const { join } = require('path');
9
+ const readline = require('readline');
10
+
11
+ const Server = require('../lib/server.js');
12
+
13
+ const {
14
+ fixture,
15
+ fixtureKey,
16
+ FIXTURES_DIR,
17
+ mustCall,
18
+ mustCallAtLeast,
19
+ } = require('./common.js');
20
+
21
+ const SPAWN_OPTS = { windowsHide: true };
22
+ const CLIENT_TIMEOUT = 5000;
23
+
24
+ const debug = false;
25
+ const opensshPath = 'ssh';
26
+ let opensshVer;
27
+
28
+ // TODO: figure out why this test is failing on Windows
29
+ if (process.platform === 'win32') {
30
+ console.log('Skipping OpenSSH integration tests on Windows');
31
+ process.exit(0);
32
+ }
33
+
34
+ // Fix file modes to avoid OpenSSH client complaints about keys' permissions
35
+ for (const file of readdirSync(FIXTURES_DIR, { withFileTypes: true })) {
36
+ if (file.isFile())
37
+ chmodSync(join(FIXTURES_DIR, file.name), 0o600);
38
+ }
39
+
40
+ {
41
+ // Get OpenSSH client version first
42
+ const {
43
+ error, stderr, stdout
44
+ } = spawnSync(opensshPath, ['-V'], SPAWN_OPTS);
45
+
46
+ if (error) {
47
+ console.error('OpenSSH client is required for these tests');
48
+ process.exitCode = 5;
49
+ return;
50
+ }
51
+
52
+ const re = /^OpenSSH_([\d.]+)/;
53
+ let m = re.exec(stdout.toString());
54
+ if (!m || !m[1]) {
55
+ m = re.exec(stderr.toString());
56
+ if (!m || !m[1]) {
57
+ console.error('OpenSSH client is required for these tests');
58
+ process.exitCode = 5;
59
+ return;
60
+ }
61
+ }
62
+
63
+ opensshVer = m[1];
64
+ console.log(`Testing with OpenSSH version: ${opensshVer}`);
65
+ }
66
+
67
+
68
+ // Key-based authentication
69
+ [
70
+ { desc: 'RSA user key (old OpenSSH)',
71
+ clientKey: fixtureKey('id_rsa') },
72
+ { desc: 'RSA user key (new OpenSSH)',
73
+ clientKey: fixtureKey('openssh_new_rsa') },
74
+ { desc: 'DSA user key',
75
+ clientKey: fixtureKey('id_dsa') },
76
+ { desc: 'ECDSA user key',
77
+ clientKey: fixtureKey('id_ecdsa') },
78
+ ].forEach((test) => {
79
+ const { desc, clientKey } = test;
80
+ const username = 'KeyUser';
81
+ const { server } = setup(
82
+ desc,
83
+ {
84
+ client: {
85
+ username,
86
+ privateKeyPath: clientKey.fullPath,
87
+ },
88
+ server: { hostKeys: [ fixture('ssh_host_rsa_key') ] },
89
+ debug,
90
+ }
91
+ );
92
+
93
+ server.on('connection', mustCall((conn) => {
94
+ let authAttempt = 0;
95
+ conn.on('authentication', mustCallAtLeast((ctx) => {
96
+ assert(ctx.username === username,
97
+ `Wrong username: ${ctx.username}`);
98
+ switch (++authAttempt) {
99
+ case 1:
100
+ assert(ctx.method === 'none',
101
+ `Wrong auth method: ${ctx.method}`);
102
+ return ctx.reject();
103
+ case 2:
104
+ case 3:
105
+ if (authAttempt === 3)
106
+ assert(ctx.signature, 'Missing publickey signature');
107
+ assert(ctx.method === 'publickey',
108
+ `Wrong auth method: ${ctx.method}`);
109
+ assert(ctx.key.algo === clientKey.key.type,
110
+ `Wrong key algo: ${ctx.key.algo}`);
111
+ assert.deepStrictEqual(clientKey.key.getPublicSSH(),
112
+ ctx.key.data,
113
+ 'Public key mismatch');
114
+ break;
115
+ default:
116
+ assert(false, 'Unexpected number of auth attempts');
117
+ }
118
+ if (ctx.signature) {
119
+ const result =
120
+ clientKey.key.verify(ctx.blob, ctx.signature, ctx.hashAlgo);
121
+ assert(result === true, 'Could not verify publickey signature');
122
+ // We should not expect any further auth attempts after we verify a
123
+ // signature
124
+ authAttempt = Infinity;
125
+ }
126
+ ctx.accept();
127
+ }, 2)).on('ready', mustCall(() => {
128
+ conn.on('session', mustCall((accept, reject) => {
129
+ accept().on('exec', mustCall((accept, reject) => {
130
+ const stream = accept();
131
+ stream.exit(0);
132
+ stream.end();
133
+ }));
134
+ }));
135
+ }));
136
+ }));
137
+ });
138
+
139
+
140
+ // Different host key types
141
+ [
142
+ { desc: 'RSA host key (old OpenSSH)',
143
+ hostKey: fixture('id_rsa') },
144
+ { desc: 'RSA host key (new OpenSSH)',
145
+ hostKey: fixture('openssh_new_rsa') },
146
+ { desc: 'DSA host key',
147
+ hostKey: fixture('ssh_host_dsa_key') },
148
+ { desc: 'ECDSA host key',
149
+ hostKey: fixture('ssh_host_ecdsa_key') },
150
+ { desc: 'PPK',
151
+ hostKey: fixture('id_rsa.ppk') },
152
+ ].forEach((test) => {
153
+ const { desc, hostKey } = test;
154
+ const clientKey = fixtureKey('openssh_new_rsa');
155
+ const username = 'KeyUser';
156
+ const { server } = setup(
157
+ desc,
158
+ {
159
+ client: {
160
+ username,
161
+ privateKeyPath: clientKey.fullPath,
162
+ },
163
+ server: { hostKeys: [ hostKey ] },
164
+ debug,
165
+ }
166
+ );
167
+
168
+ server.on('connection', mustCall((conn) => {
169
+ let authAttempt = 0;
170
+ conn.on('authentication', mustCallAtLeast((ctx) => {
171
+ assert(ctx.username === username,
172
+ `Wrong username: ${ctx.username}`);
173
+ switch (++authAttempt) {
174
+ case 1:
175
+ assert(ctx.method === 'none',
176
+ `Wrong auth method: ${ctx.method}`);
177
+ return ctx.reject();
178
+ case 2:
179
+ case 3:
180
+ if (authAttempt === 3)
181
+ assert(ctx.signature, 'Missing publickey signature');
182
+ assert(ctx.method === 'publickey',
183
+ `Wrong auth method: ${ctx.method}`);
184
+ assert(ctx.key.algo === clientKey.key.type,
185
+ `Wrong key algo: ${ctx.key.algo}`);
186
+ assert.deepStrictEqual(clientKey.key.getPublicSSH(),
187
+ ctx.key.data,
188
+ 'Public key mismatch');
189
+ break;
190
+ default:
191
+ assert(false, 'Unexpected number of auth attempts');
192
+ }
193
+ if (ctx.signature) {
194
+ const result =
195
+ clientKey.key.verify(ctx.blob, ctx.signature, ctx.hashAlgo);
196
+ assert(result === true, 'Could not verify publickey signature');
197
+ // We should not expect any further auth attempts after we verify a
198
+ // signature
199
+ authAttempt = Infinity;
200
+ }
201
+ ctx.accept();
202
+ }, 2)).on('ready', mustCall(() => {
203
+ conn.on('session', mustCall((accept, reject) => {
204
+ accept().on('exec', mustCall((accept, reject) => {
205
+ const stream = accept();
206
+ stream.exit(0);
207
+ stream.end();
208
+ }));
209
+ }));
210
+ }));
211
+ }));
212
+ });
213
+
214
+
215
+ // Various edge cases
216
+ {
217
+ const clientKey = fixtureKey('openssh_new_rsa');
218
+ const username = 'KeyUser';
219
+ const { server } = setup(
220
+ 'Server closes stdin too early',
221
+ {
222
+ client: {
223
+ username,
224
+ privateKeyPath: clientKey.fullPath,
225
+ },
226
+ server: { hostKeys: [ fixture('ssh_host_rsa_key') ] },
227
+ debug,
228
+ }
229
+ );
230
+
231
+ server.on('_child', mustCall((childProc) => {
232
+ childProc.stderr.once('data', mustCall((data) => {
233
+ childProc.stdin.end();
234
+ }));
235
+ childProc.stdin.write('ping');
236
+ })).on('connection', mustCall((conn) => {
237
+ let authAttempt = 0;
238
+ conn.on('authentication', mustCallAtLeast((ctx) => {
239
+ assert(ctx.username === username,
240
+ `Wrong username: ${ctx.username}`);
241
+ switch (++authAttempt) {
242
+ case 1:
243
+ assert(ctx.method === 'none',
244
+ `Wrong auth method: ${ctx.method}`);
245
+ return ctx.reject();
246
+ case 2:
247
+ case 3:
248
+ if (authAttempt === 3)
249
+ assert(ctx.signature, 'Missing publickey signature');
250
+ assert(ctx.method === 'publickey',
251
+ `Wrong auth method: ${ctx.method}`);
252
+ assert(ctx.key.algo === clientKey.key.type,
253
+ `Wrong key algo: ${ctx.key.algo}`);
254
+ assert.deepStrictEqual(clientKey.key.getPublicSSH(),
255
+ ctx.key.data,
256
+ 'Public key mismatch');
257
+ break;
258
+ default:
259
+ assert(false, 'Unexpected number of auth attempts');
260
+ }
261
+ if (ctx.signature) {
262
+ const result =
263
+ clientKey.key.verify(ctx.blob, ctx.signature, ctx.hashAlgo);
264
+ assert(result === true, 'Could not verify publickey signature');
265
+ // We should not expect any further auth attempts after we verify a
266
+ // signature
267
+ authAttempt = Infinity;
268
+ }
269
+ ctx.accept();
270
+ }, 2)).on('ready', mustCall(() => {
271
+ conn.on('session', mustCall((accept, reject) => {
272
+ accept().on('exec', mustCall((accept, reject) => {
273
+ const stream = accept();
274
+ stream.stdin.on('data', mustCallAtLeast((data) => {
275
+ stream.stdout.write('pong on stdout');
276
+ stream.stderr.write('pong on stderr');
277
+ })).on('end', mustCall(() => {
278
+ stream.stdout.write('pong on stdout');
279
+ stream.stderr.write('pong on stderr');
280
+ stream.exit(0);
281
+ stream.close();
282
+ }));
283
+ }));
284
+ }));
285
+ }));
286
+ }));
287
+ }
288
+ {
289
+ const clientKey = fixtureKey('openssh_new_rsa');
290
+ const username = 'KeyUser';
291
+ const { server } = setup(
292
+ 'Rekey',
293
+ {
294
+ client: {
295
+ username,
296
+ privateKeyPath: clientKey.fullPath,
297
+ },
298
+ server: { hostKeys: [ fixture('ssh_host_rsa_key') ] },
299
+ debug,
300
+ }
301
+ );
302
+
303
+ server.on('connection', mustCall((conn) => {
304
+ let authAttempt = 0;
305
+ conn.on('authentication', mustCallAtLeast((ctx) => {
306
+ assert(ctx.username === username,
307
+ `Wrong username: ${ctx.username}`);
308
+ switch (++authAttempt) {
309
+ case 1:
310
+ assert(ctx.method === 'none',
311
+ `Wrong auth method: ${ctx.method}`);
312
+ return ctx.reject();
313
+ case 2:
314
+ case 3:
315
+ if (authAttempt === 3)
316
+ assert(ctx.signature, 'Missing publickey signature');
317
+ assert(ctx.method === 'publickey',
318
+ `Wrong auth method: ${ctx.method}`);
319
+ assert(ctx.key.algo === clientKey.key.type,
320
+ `Wrong key algo: ${ctx.key.algo}`);
321
+ assert.deepStrictEqual(clientKey.key.getPublicSSH(),
322
+ ctx.key.data,
323
+ 'Public key mismatch');
324
+ break;
325
+ default:
326
+ assert(false, 'Unexpected number of auth attempts');
327
+ }
328
+ if (ctx.signature) {
329
+ const result =
330
+ clientKey.key.verify(ctx.blob, ctx.signature, ctx.hashAlgo);
331
+ assert(result === true, 'Could not verify publickey signature');
332
+ // We should not expect any further auth attempts after we verify a
333
+ // signature
334
+ authAttempt = Infinity;
335
+ }
336
+ ctx.accept();
337
+ }, 2)).on('ready', mustCall(() => {
338
+ conn.on('session', mustCall((accept, reject) => {
339
+ const session = accept();
340
+ conn.rekey();
341
+ session.on('exec', mustCall((accept, reject) => {
342
+ const stream = accept();
343
+ stream.exit(0);
344
+ stream.end();
345
+ }));
346
+ }));
347
+ }));
348
+ }));
349
+ }
350
+
351
+
352
+ function setup(title, configs) {
353
+ const {
354
+ client: clientCfg,
355
+ server: serverCfg,
356
+ allReady: allReady_,
357
+ timeout: timeout_,
358
+ debug,
359
+ noForceServerReady,
360
+ } = configs;
361
+ let clientClose = false;
362
+ let serverClose = false;
363
+ let serverReady = false;
364
+ let client;
365
+ const msg = (text) => {
366
+ return `${title}: ${text}`;
367
+ };
368
+
369
+ const timeout = (typeof timeout_ === 'number'
370
+ ? timeout_
371
+ : CLIENT_TIMEOUT);
372
+
373
+ const allReady = (typeof allReady_ === 'function' ? allReady_ : undefined);
374
+
375
+ if (debug) {
376
+ serverCfg.debug = (...args) => {
377
+ console.log(`[${title}][SERVER]`, ...args);
378
+ };
379
+ }
380
+
381
+ const serverReadyFn = (noForceServerReady ? onReady : mustCall(onReady));
382
+ const server = new Server(serverCfg);
383
+
384
+ server.on('error', onError)
385
+ .on('connection', mustCall((conn) => {
386
+ conn.on('error', onError)
387
+ .on('ready', serverReadyFn);
388
+ server.close();
389
+ }))
390
+ .on('close', mustCall(onClose));
391
+
392
+ function onError(err) {
393
+ const which = (arguments.length >= 3 ? 'client' : 'server');
394
+ assert(false, msg(`Unexpected ${which} error: ${err}`));
395
+ }
396
+
397
+ function onReady() {
398
+ assert(!serverReady, msg('Received multiple ready events for server'));
399
+ serverReady = true;
400
+ allReady && allReady();
401
+ }
402
+
403
+ function onClose() {
404
+ if (arguments.length >= 3) {
405
+ assert(!clientClose, msg('Received multiple close events for client'));
406
+ clientClose = true;
407
+ } else {
408
+ assert(!serverClose, msg('Received multiple close events for server'));
409
+ serverClose = true;
410
+ }
411
+ }
412
+
413
+ process.nextTick(mustCall(() => {
414
+ server.listen(0, 'localhost', mustCall(() => {
415
+ const args = [
416
+ '-o', 'UserKnownHostsFile=/dev/null',
417
+ '-o', 'StrictHostKeyChecking=no',
418
+ '-o', 'CheckHostIP=no',
419
+ '-o', 'ConnectTimeout=3',
420
+ '-o', 'GlobalKnownHostsFile=/dev/null',
421
+ '-o', 'GSSAPIAuthentication=no',
422
+ '-o', 'IdentitiesOnly=yes',
423
+ '-o', 'BatchMode=yes',
424
+ '-o', 'VerifyHostKeyDNS=no',
425
+
426
+ '-vvvvvv',
427
+ '-T',
428
+ '-o', 'KbdInteractiveAuthentication=no',
429
+ '-o', 'HostbasedAuthentication=no',
430
+ '-o', 'PasswordAuthentication=no',
431
+ '-o', 'PubkeyAuthentication=yes',
432
+ '-o', 'PreferredAuthentications=publickey'
433
+ ];
434
+
435
+ if (clientCfg.privateKeyPath)
436
+ args.push('-o', `IdentityFile=${clientCfg.privateKeyPath}`);
437
+
438
+ if (!/^[0-6]\./.test(opensshVer)) {
439
+ // OpenSSH 7.0+ disables DSS/DSA host (and user) key support by
440
+ // default, so we explicitly enable it here
441
+ args.push('-o', 'HostKeyAlgorithms=+ssh-dss');
442
+ args.push('-o', 'PubkeyAcceptedKeyTypes=+ssh-dss');
443
+ args.push('-o', 'PubkeyAcceptedAlgorithms=+ssh-dss');
444
+ }
445
+
446
+ args.push('-p', server.address().port.toString(),
447
+ '-l', clientCfg.username,
448
+ 'localhost',
449
+ 'uptime');
450
+
451
+ client = spawn(opensshPath, args, SPAWN_OPTS);
452
+ server.emit('_child', client);
453
+
454
+ if (debug) {
455
+ readline.createInterface({
456
+ input: client.stdout
457
+ }).on('line', (line) => {
458
+ console.log(`[${title}][CLIENT][STDOUT]`, line);
459
+ });
460
+ readline.createInterface({
461
+ input: client.stderr
462
+ }).on('line', (line) => {
463
+ console.error(`[${title}][CLIENT][STDERR]`, line);
464
+ });
465
+ } else {
466
+ client.stdout.resume();
467
+ client.stderr.resume();
468
+ }
469
+
470
+ client.on('error', (err) => {
471
+ onError(err, null, null);
472
+ }).on('exit', (code) => {
473
+ clearTimeout(client.timer);
474
+ if (code !== 0)
475
+ return onError(new Error(`Non-zero exit code ${code}`), null, null);
476
+ onClose(null, null, null);
477
+ });
478
+
479
+ client.timer = setTimeout(() => {
480
+ assert(false, msg('Client timeout'));
481
+ }, timeout);
482
+ }));
483
+ }));
484
+
485
+ return { server };
486
+ }
@@ -0,0 +1,60 @@
1
+ 'use strict';
2
+
3
+ const assert = require('assert');
4
+
5
+ const {
6
+ utils: {
7
+ generateKeyPair,
8
+ generateKeyPairSync,
9
+ parseKey,
10
+ },
11
+ } = require('..');
12
+
13
+ const { mustCall } = require('./common.js');
14
+
15
+ const nodeMajor = +/(?<=^v)\d+/.exec(process.version)[0];
16
+
17
+ function tryParse(...args) {
18
+ const ret = parseKey(...args);
19
+ if (ret instanceof Error)
20
+ throw ret;
21
+ return ret;
22
+ }
23
+
24
+ const inputs = [
25
+ { args: ['rsa', { bits: 2048 }], sshType: 'ssh-rsa' },
26
+ { args: ['ecdsa', { bits: 256 }], sshType: 'ecdsa-sha2-nistp256' },
27
+ { args: ['ecdsa', { bits: 521 }], sshType: 'ecdsa-sha2-nistp521' },
28
+ { args: ['ed25519'], sshType: 'ssh-ed25519' },
29
+ { args: ['rsa', { bits: 2048, passphrase: 'foo', cipher: 'aes256-cbc' }],
30
+ sshType: 'ssh-rsa' },
31
+ { args: ['rsa', { bits: 2048, comment: 'foobarbaz' }], sshType: 'ssh-rsa' },
32
+ ];
33
+ (function next() {
34
+ if (inputs.length === 0)
35
+ return;
36
+ const { args, sshType } = inputs.shift();
37
+ if (args[0] === 'ed25519' && nodeMajor < 12) {
38
+ console.log('Skipping ed25519 on node < 12');
39
+ return;
40
+ }
41
+ const passphrase = (args[1] && args[1].passphrase);
42
+ const comment = ((args[1] && args[1].comment) || '');
43
+ const check = (keys) => {
44
+ let parsed = tryParse(keys.private, passphrase);
45
+ assert.strictEqual(parsed.type, sshType);
46
+ assert.strictEqual(parsed.comment, comment);
47
+
48
+ parsed = tryParse(keys.public);
49
+ assert.strictEqual(parsed.type, sshType);
50
+ assert.strictEqual(parsed.comment, comment);
51
+ };
52
+ console.log(`Testing generateKeyPairSync(${JSON.stringify(args)}) ...`);
53
+ check(generateKeyPairSync(...args));
54
+ console.log(`Testing generateKeyPair(${JSON.stringify(args)}) ...`);
55
+ generateKeyPair(...args, mustCall((err, keys) => {
56
+ assert.ifError(err);
57
+ check(keys);
58
+ next();
59
+ }));
60
+ })();