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.
- package/distTs/package.json +10 -2
- package/distTs/src/agent/linux.js +53 -3
- package/distTs/src/agent/manager.js +3 -6
- package/distTs/src/agent/osx.js +51 -3
- package/distTs/src/agent/system.js +400 -21
- package/distTs/src/agent/windows.js +4 -7
- package/distTs/src/command/agent/debug.js +2 -2
- package/distTs/src/command/agent/install.js +37 -10
- package/distTs/src/command/agent/restart.js +2 -2
- package/distTs/src/command/agent/run.js +3 -0
- package/distTs/src/command/agent/start.js +2 -2
- package/distTs/src/command/agent/status.js +19 -0
- package/distTs/src/command/agent/stop.js +2 -2
- package/distTs/src/command/agent/uninstall.js +5 -8
- package/distTs/src/command/agent/update.js +2 -2
- package/distTs/src/command/artifact/publish.js +3 -1
- package/distTs/src/command/version.js +13 -5
- package/distTs/src/logger.js +40 -4
- package/distTs/src/texts.js +35 -19
- package/distTs/src/utils.js +98 -3
- package/node_modules/asn1/Jenkinsfile +65 -0
- package/node_modules/asn1/LICENSE +19 -0
- package/node_modules/asn1/README.md +50 -0
- package/node_modules/asn1/lib/ber/errors.js +13 -0
- package/node_modules/asn1/lib/ber/index.js +27 -0
- package/node_modules/asn1/lib/ber/reader.js +262 -0
- package/node_modules/asn1/lib/ber/types.js +36 -0
- package/node_modules/asn1/lib/ber/writer.js +317 -0
- package/node_modules/asn1/lib/index.js +20 -0
- package/node_modules/asn1/package.json +31 -0
- package/node_modules/bcrypt-pbkdf/CONTRIBUTING.md +13 -0
- package/node_modules/bcrypt-pbkdf/LICENSE +66 -0
- package/node_modules/bcrypt-pbkdf/README.md +45 -0
- package/node_modules/bcrypt-pbkdf/index.js +556 -0
- package/node_modules/bcrypt-pbkdf/package.json +15 -0
- package/node_modules/safer-buffer/LICENSE +21 -0
- package/node_modules/safer-buffer/Porting-Buffer.md +268 -0
- package/node_modules/safer-buffer/Readme.md +156 -0
- package/node_modules/safer-buffer/dangerous.js +58 -0
- package/node_modules/safer-buffer/package.json +34 -0
- package/node_modules/safer-buffer/safer.js +77 -0
- package/node_modules/safer-buffer/tests.js +406 -0
- package/node_modules/ssh2/.eslintignore +4 -0
- package/node_modules/ssh2/.eslintrc.js +5 -0
- package/node_modules/ssh2/.github/workflows/ci.yml +110 -0
- package/node_modules/ssh2/.github/workflows/lint.yml +27 -0
- package/node_modules/ssh2/LICENSE +19 -0
- package/node_modules/ssh2/README.md +1529 -0
- package/node_modules/ssh2/SFTP.md +413 -0
- package/node_modules/ssh2/examples/server-chat.js +238 -0
- package/node_modules/ssh2/examples/sftp-server-download-only.js +134 -0
- package/node_modules/ssh2/install.js +27 -0
- package/node_modules/ssh2/lib/Channel.js +295 -0
- package/node_modules/ssh2/lib/agent.js +1123 -0
- package/node_modules/ssh2/lib/client.js +2176 -0
- package/node_modules/ssh2/lib/http-agents.js +84 -0
- package/node_modules/ssh2/lib/index.js +44 -0
- package/node_modules/ssh2/lib/keygen.js +582 -0
- package/node_modules/ssh2/lib/protocol/Protocol.js +2136 -0
- package/node_modules/ssh2/lib/protocol/SFTP.js +4052 -0
- package/node_modules/ssh2/lib/protocol/constants.js +356 -0
- package/node_modules/ssh2/lib/protocol/crypto/binding.gyp +23 -0
- package/node_modules/ssh2/lib/protocol/crypto/poly1305.js +43 -0
- package/node_modules/ssh2/lib/protocol/crypto/src/binding.cc +2300 -0
- package/node_modules/ssh2/lib/protocol/crypto.js +1602 -0
- package/node_modules/ssh2/lib/protocol/handlers.js +16 -0
- package/node_modules/ssh2/lib/protocol/handlers.misc.js +1285 -0
- package/node_modules/ssh2/lib/protocol/kex.js +1908 -0
- package/node_modules/ssh2/lib/protocol/keyParser.js +1484 -0
- package/node_modules/ssh2/lib/protocol/node-fs-compat.js +115 -0
- package/node_modules/ssh2/lib/protocol/utils.js +356 -0
- package/node_modules/ssh2/lib/protocol/zlib.js +255 -0
- package/node_modules/ssh2/lib/server.js +1380 -0
- package/node_modules/ssh2/lib/utils.js +336 -0
- package/node_modules/ssh2/package.json +49 -0
- package/node_modules/ssh2/test/common.js +316 -0
- package/node_modules/ssh2/test/fixtures/bad_rsa_private_key +26 -0
- package/node_modules/ssh2/test/fixtures/https_cert.pem +33 -0
- package/node_modules/ssh2/test/fixtures/https_key.pem +52 -0
- package/node_modules/ssh2/test/fixtures/id_dsa +12 -0
- package/node_modules/ssh2/test/fixtures/id_ecdsa +5 -0
- package/node_modules/ssh2/test/fixtures/id_rsa +15 -0
- package/node_modules/ssh2/test/fixtures/id_rsa.ppk +26 -0
- package/node_modules/ssh2/test/fixtures/id_rsa_enc +30 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa +21 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa.pub +1 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa.pub.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc +22 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc.pub +1 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc.pub.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc_gcm +23 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc_gcm.pub +1 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc_gcm.pub.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc_gcm.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa +9 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa.pub +1 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa.pub.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc +10 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc.pub +1 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc.pub.result +8 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc_gcm +10 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc_gcm.pub +1 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc_gcm.pub.result +8 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc_gcm.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ed25519 +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ed25519.pub +1 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ed25519.pub.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ed25519.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa +27 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa.pub +1 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa.pub.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc +28 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc.pub +1 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc.pub.result +8 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc_gcm +29 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc_gcm.pub +1 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc_gcm.pub.result +8 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc_gcm.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa +12 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa.pub +1 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa.pub.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa_enc +15 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa_enc.pub +1 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa_enc.pub.result +8 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa_enc.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa +5 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa.pub +1 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa.pub.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa_enc +8 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa_enc.pub +1 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa_enc.pub.result +8 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa_enc.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa +27 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa.pub +1 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa.pub.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc +30 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc.pub +1 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc.pub.result +8 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc_aes256 +54 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc_aes256.pub +1 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc_aes256.pub.result +6 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc_aes256.result +6 -0
- package/node_modules/ssh2/test/fixtures/keyParser/ppk_dsa_enc +17 -0
- package/node_modules/ssh2/test/fixtures/keyParser/ppk_dsa_enc.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/ppk_rsa +26 -0
- package/node_modules/ssh2/test/fixtures/keyParser/ppk_rsa.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/ppk_rsa_enc +18 -0
- package/node_modules/ssh2/test/fixtures/keyParser/ppk_rsa_enc.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa.pub +9 -0
- package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa.pub.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa2.pub +10 -0
- package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa2.pub.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa3.pub +11 -0
- package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa3.pub.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa4.pub +11 -0
- package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa4.pub.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa5.pub +8 -0
- package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa5.pub.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa6.pub +13 -0
- package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa6.pub.result +7 -0
- package/node_modules/ssh2/test/fixtures/openssh_new_rsa +27 -0
- package/node_modules/ssh2/test/fixtures/ssh_host_dsa_key +12 -0
- package/node_modules/ssh2/test/fixtures/ssh_host_ecdsa_key +5 -0
- package/node_modules/ssh2/test/fixtures/ssh_host_rsa_key +15 -0
- package/node_modules/ssh2/test/test-exec.js +578 -0
- package/node_modules/ssh2/test/test-integration-openssh.js +486 -0
- package/node_modules/ssh2/test/test-keygen.js +60 -0
- package/node_modules/ssh2/test/test-misc-client-server.js +1460 -0
- package/node_modules/ssh2/test/test-openssh.js +261 -0
- package/node_modules/ssh2/test/test-protocol-crypto.js +631 -0
- package/node_modules/ssh2/test/test-protocol-keyparser.js +177 -0
- package/node_modules/ssh2/test/test-server-hostkeys.js +138 -0
- package/node_modules/ssh2/test/test-sftp.js +842 -0
- package/node_modules/ssh2/test/test-shell.js +109 -0
- package/node_modules/ssh2/test/test-userauth-agent-openssh.js +110 -0
- package/node_modules/ssh2/test/test-userauth-agent.js +171 -0
- package/node_modules/ssh2/test/test-userauth.js +611 -0
- package/node_modules/ssh2/test/test-worker-imports.js +25 -0
- package/node_modules/ssh2/test/test.js +20 -0
- package/node_modules/ssh2/util/build_pagent.bat +2 -0
- package/node_modules/ssh2/util/pagent.c +88 -0
- package/node_modules/ssh2/util/pagent.exe +0 -0
- package/node_modules/tweetnacl/.npmignore +4 -0
- package/node_modules/tweetnacl/AUTHORS.md +28 -0
- package/node_modules/tweetnacl/CHANGELOG.md +221 -0
- package/node_modules/tweetnacl/LICENSE +24 -0
- package/node_modules/tweetnacl/PULL_REQUEST_TEMPLATE.md +20 -0
- package/node_modules/tweetnacl/README.md +459 -0
- package/node_modules/tweetnacl/nacl-fast.js +2388 -0
- package/node_modules/tweetnacl/nacl-fast.min.js +2 -0
- package/node_modules/tweetnacl/nacl.d.ts +98 -0
- package/node_modules/tweetnacl/nacl.js +1175 -0
- package/node_modules/tweetnacl/nacl.min.js +1 -0
- package/node_modules/tweetnacl/package.json +58 -0
- package/package.json +10 -2
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { SFTP } = require('./protocol/SFTP.js');
|
|
4
|
+
|
|
5
|
+
const MAX_CHANNEL = 2 ** 32 - 1;
|
|
6
|
+
|
|
7
|
+
function onChannelOpenFailure(self, recipient, info, cb) {
|
|
8
|
+
self._chanMgr.remove(recipient);
|
|
9
|
+
if (typeof cb !== 'function')
|
|
10
|
+
return;
|
|
11
|
+
|
|
12
|
+
let err;
|
|
13
|
+
if (info instanceof Error) {
|
|
14
|
+
err = info;
|
|
15
|
+
} else if (typeof info === 'object' && info !== null) {
|
|
16
|
+
err = new Error(`(SSH) Channel open failure: ${info.description}`);
|
|
17
|
+
err.reason = info.reason;
|
|
18
|
+
} else {
|
|
19
|
+
err = new Error(
|
|
20
|
+
'(SSH) Channel open failure: server closed channel unexpectedly'
|
|
21
|
+
);
|
|
22
|
+
err.reason = '';
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
cb(err);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function onCHANNEL_CLOSE(self, recipient, channel, err, dead) {
|
|
29
|
+
if (typeof channel === 'function') {
|
|
30
|
+
// We got CHANNEL_CLOSE instead of CHANNEL_OPEN_FAILURE when
|
|
31
|
+
// requesting to open a channel
|
|
32
|
+
onChannelOpenFailure(self, recipient, err, channel);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (typeof channel !== 'object' || channel === null)
|
|
37
|
+
return;
|
|
38
|
+
|
|
39
|
+
if (channel.incoming && channel.incoming.state === 'closed')
|
|
40
|
+
return;
|
|
41
|
+
|
|
42
|
+
self._chanMgr.remove(recipient);
|
|
43
|
+
|
|
44
|
+
if (channel.server && channel.constructor.name === 'Session')
|
|
45
|
+
return;
|
|
46
|
+
|
|
47
|
+
channel.incoming.state = 'closed';
|
|
48
|
+
|
|
49
|
+
if (channel.readable)
|
|
50
|
+
channel.push(null);
|
|
51
|
+
if (channel.server) {
|
|
52
|
+
if (channel.stderr.writable)
|
|
53
|
+
channel.stderr.end();
|
|
54
|
+
} else if (channel.stderr.readable) {
|
|
55
|
+
channel.stderr.push(null);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (channel.constructor !== SFTP
|
|
59
|
+
&& (channel.outgoing.state === 'open'
|
|
60
|
+
|| channel.outgoing.state === 'eof')
|
|
61
|
+
&& !dead) {
|
|
62
|
+
channel.close();
|
|
63
|
+
}
|
|
64
|
+
if (channel.outgoing.state === 'closing')
|
|
65
|
+
channel.outgoing.state = 'closed';
|
|
66
|
+
|
|
67
|
+
const readState = channel._readableState;
|
|
68
|
+
const writeState = channel._writableState;
|
|
69
|
+
if (writeState && !writeState.ending && !writeState.finished && !dead)
|
|
70
|
+
channel.end();
|
|
71
|
+
|
|
72
|
+
// Take care of any outstanding channel requests
|
|
73
|
+
const chanCallbacks = channel._callbacks;
|
|
74
|
+
channel._callbacks = [];
|
|
75
|
+
for (let i = 0; i < chanCallbacks.length; ++i)
|
|
76
|
+
chanCallbacks[i](true);
|
|
77
|
+
|
|
78
|
+
if (channel.server) {
|
|
79
|
+
if (!channel.readable
|
|
80
|
+
|| channel.destroyed
|
|
81
|
+
|| (readState && readState.endEmitted)) {
|
|
82
|
+
channel.emit('close');
|
|
83
|
+
} else {
|
|
84
|
+
channel.once('end', () => channel.emit('close'));
|
|
85
|
+
}
|
|
86
|
+
} else {
|
|
87
|
+
let doClose;
|
|
88
|
+
switch (channel.type) {
|
|
89
|
+
case 'direct-streamlocal@openssh.com':
|
|
90
|
+
case 'direct-tcpip':
|
|
91
|
+
doClose = () => channel.emit('close');
|
|
92
|
+
break;
|
|
93
|
+
default: {
|
|
94
|
+
// Align more with node child processes, where the close event gets
|
|
95
|
+
// the same arguments as the exit event
|
|
96
|
+
const exit = channel._exit;
|
|
97
|
+
doClose = () => {
|
|
98
|
+
if (exit.code === null)
|
|
99
|
+
channel.emit('close', exit.code, exit.signal, exit.dump, exit.desc);
|
|
100
|
+
else
|
|
101
|
+
channel.emit('close', exit.code);
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (!channel.readable
|
|
106
|
+
|| channel.destroyed
|
|
107
|
+
|| (readState && readState.endEmitted)) {
|
|
108
|
+
doClose();
|
|
109
|
+
} else {
|
|
110
|
+
channel.once('end', doClose);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const errReadState = channel.stderr._readableState;
|
|
114
|
+
if (!channel.stderr.readable
|
|
115
|
+
|| channel.stderr.destroyed
|
|
116
|
+
|| (errReadState && errReadState.endEmitted)) {
|
|
117
|
+
channel.stderr.emit('close');
|
|
118
|
+
} else {
|
|
119
|
+
channel.stderr.once('end', () => channel.stderr.emit('close'));
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
class ChannelManager {
|
|
125
|
+
constructor(client) {
|
|
126
|
+
this._client = client;
|
|
127
|
+
this._channels = {};
|
|
128
|
+
this._cur = -1;
|
|
129
|
+
this._count = 0;
|
|
130
|
+
}
|
|
131
|
+
add(val) {
|
|
132
|
+
// Attempt to reserve an id
|
|
133
|
+
|
|
134
|
+
let id;
|
|
135
|
+
// Optimized paths
|
|
136
|
+
if (this._cur < MAX_CHANNEL) {
|
|
137
|
+
id = ++this._cur;
|
|
138
|
+
} else if (this._count === 0) {
|
|
139
|
+
// Revert and reset back to fast path once we no longer have any channels
|
|
140
|
+
// open
|
|
141
|
+
this._cur = 0;
|
|
142
|
+
id = 0;
|
|
143
|
+
} else {
|
|
144
|
+
// Slower lookup path
|
|
145
|
+
|
|
146
|
+
// This path is triggered we have opened at least MAX_CHANNEL channels
|
|
147
|
+
// while having at least one channel open at any given time, so we have
|
|
148
|
+
// to search for a free id.
|
|
149
|
+
const channels = this._channels;
|
|
150
|
+
for (let i = 0; i < MAX_CHANNEL; ++i) {
|
|
151
|
+
if (channels[i] === undefined) {
|
|
152
|
+
id = i;
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (id === undefined)
|
|
159
|
+
return -1;
|
|
160
|
+
|
|
161
|
+
this._channels[id] = (val || true);
|
|
162
|
+
++this._count;
|
|
163
|
+
|
|
164
|
+
return id;
|
|
165
|
+
}
|
|
166
|
+
update(id, val) {
|
|
167
|
+
if (typeof id !== 'number' || id < 0 || id >= MAX_CHANNEL || !isFinite(id))
|
|
168
|
+
throw new Error(`Invalid channel id: ${id}`);
|
|
169
|
+
|
|
170
|
+
if (val && this._channels[id])
|
|
171
|
+
this._channels[id] = val;
|
|
172
|
+
}
|
|
173
|
+
get(id) {
|
|
174
|
+
if (typeof id !== 'number' || id < 0 || id >= MAX_CHANNEL || !isFinite(id))
|
|
175
|
+
throw new Error(`Invalid channel id: ${id}`);
|
|
176
|
+
|
|
177
|
+
return this._channels[id];
|
|
178
|
+
}
|
|
179
|
+
remove(id) {
|
|
180
|
+
if (typeof id !== 'number' || id < 0 || id >= MAX_CHANNEL || !isFinite(id))
|
|
181
|
+
throw new Error(`Invalid channel id: ${id}`);
|
|
182
|
+
|
|
183
|
+
if (this._channels[id]) {
|
|
184
|
+
delete this._channels[id];
|
|
185
|
+
if (this._count)
|
|
186
|
+
--this._count;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
cleanup(err) {
|
|
190
|
+
const channels = this._channels;
|
|
191
|
+
this._channels = {};
|
|
192
|
+
this._cur = -1;
|
|
193
|
+
this._count = 0;
|
|
194
|
+
|
|
195
|
+
const chanIDs = Object.keys(channels);
|
|
196
|
+
const client = this._client;
|
|
197
|
+
for (let i = 0; i < chanIDs.length; ++i) {
|
|
198
|
+
const id = +chanIDs[i];
|
|
199
|
+
const channel = channels[id];
|
|
200
|
+
onCHANNEL_CLOSE(client, id, channel._channel || channel, err, true);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const isRegExp = (() => {
|
|
206
|
+
const toString = Object.prototype.toString;
|
|
207
|
+
return (val) => toString.call(val) === '[object RegExp]';
|
|
208
|
+
})();
|
|
209
|
+
|
|
210
|
+
function generateAlgorithmList(algoList, defaultList, supportedList) {
|
|
211
|
+
if (Array.isArray(algoList) && algoList.length > 0) {
|
|
212
|
+
// Exact list
|
|
213
|
+
for (let i = 0; i < algoList.length; ++i) {
|
|
214
|
+
if (supportedList.indexOf(algoList[i]) === -1)
|
|
215
|
+
throw new Error(`Unsupported algorithm: ${algoList[i]}`);
|
|
216
|
+
}
|
|
217
|
+
return algoList;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (typeof algoList === 'object' && algoList !== null) {
|
|
221
|
+
// Operations based on the default list
|
|
222
|
+
const keys = Object.keys(algoList);
|
|
223
|
+
let list = defaultList;
|
|
224
|
+
for (let i = 0; i < keys.length; ++i) {
|
|
225
|
+
const key = keys[i];
|
|
226
|
+
let val = algoList[key];
|
|
227
|
+
switch (key) {
|
|
228
|
+
case 'append':
|
|
229
|
+
if (!Array.isArray(val))
|
|
230
|
+
val = [val];
|
|
231
|
+
if (Array.isArray(val)) {
|
|
232
|
+
for (let j = 0; j < val.length; ++j) {
|
|
233
|
+
const append = val[j];
|
|
234
|
+
if (typeof append === 'string') {
|
|
235
|
+
if (!append || list.indexOf(append) !== -1)
|
|
236
|
+
continue;
|
|
237
|
+
if (supportedList.indexOf(append) === -1)
|
|
238
|
+
throw new Error(`Unsupported algorithm: ${append}`);
|
|
239
|
+
if (list === defaultList)
|
|
240
|
+
list = list.slice();
|
|
241
|
+
list.push(append);
|
|
242
|
+
} else if (isRegExp(append)) {
|
|
243
|
+
for (let k = 0; k < supportedList.length; ++k) {
|
|
244
|
+
const algo = supportedList[k];
|
|
245
|
+
if (append.test(algo)) {
|
|
246
|
+
if (list.indexOf(algo) !== -1)
|
|
247
|
+
continue;
|
|
248
|
+
if (list === defaultList)
|
|
249
|
+
list = list.slice();
|
|
250
|
+
list.push(algo);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
break;
|
|
257
|
+
case 'prepend':
|
|
258
|
+
if (!Array.isArray(val))
|
|
259
|
+
val = [val];
|
|
260
|
+
if (Array.isArray(val)) {
|
|
261
|
+
for (let j = val.length; j >= 0; --j) {
|
|
262
|
+
const prepend = val[j];
|
|
263
|
+
if (typeof prepend === 'string') {
|
|
264
|
+
if (!prepend || list.indexOf(prepend) !== -1)
|
|
265
|
+
continue;
|
|
266
|
+
if (supportedList.indexOf(prepend) === -1)
|
|
267
|
+
throw new Error(`Unsupported algorithm: ${prepend}`);
|
|
268
|
+
if (list === defaultList)
|
|
269
|
+
list = list.slice();
|
|
270
|
+
list.unshift(prepend);
|
|
271
|
+
} else if (isRegExp(prepend)) {
|
|
272
|
+
for (let k = supportedList.length; k >= 0; --k) {
|
|
273
|
+
const algo = supportedList[k];
|
|
274
|
+
if (prepend.test(algo)) {
|
|
275
|
+
if (list.indexOf(algo) !== -1)
|
|
276
|
+
continue;
|
|
277
|
+
if (list === defaultList)
|
|
278
|
+
list = list.slice();
|
|
279
|
+
list.unshift(algo);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
break;
|
|
286
|
+
case 'remove':
|
|
287
|
+
if (!Array.isArray(val))
|
|
288
|
+
val = [val];
|
|
289
|
+
if (Array.isArray(val)) {
|
|
290
|
+
for (let j = 0; j < val.length; ++j) {
|
|
291
|
+
const search = val[j];
|
|
292
|
+
if (typeof search === 'string') {
|
|
293
|
+
if (!search)
|
|
294
|
+
continue;
|
|
295
|
+
const idx = list.indexOf(search);
|
|
296
|
+
if (idx === -1)
|
|
297
|
+
continue;
|
|
298
|
+
if (list === defaultList)
|
|
299
|
+
list = list.slice();
|
|
300
|
+
list.splice(idx, 1);
|
|
301
|
+
} else if (isRegExp(search)) {
|
|
302
|
+
for (let k = 0; k < list.length; ++k) {
|
|
303
|
+
if (search.test(list[k])) {
|
|
304
|
+
if (list === defaultList)
|
|
305
|
+
list = list.slice();
|
|
306
|
+
list.splice(k, 1);
|
|
307
|
+
--k;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
break;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
return list;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
return defaultList;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
module.exports = {
|
|
324
|
+
ChannelManager,
|
|
325
|
+
generateAlgorithmList,
|
|
326
|
+
onChannelOpenFailure,
|
|
327
|
+
onCHANNEL_CLOSE,
|
|
328
|
+
isWritable: (stream) => {
|
|
329
|
+
// XXX: hack to workaround regression in node
|
|
330
|
+
// See: https://github.com/nodejs/node/issues/36029
|
|
331
|
+
return (stream
|
|
332
|
+
&& stream.writable
|
|
333
|
+
&& stream._readableState
|
|
334
|
+
&& stream._readableState.ended === false);
|
|
335
|
+
},
|
|
336
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ssh2",
|
|
3
|
+
"version": "1.17.0",
|
|
4
|
+
"author": "Brian White <mscdex@mscdex.net>",
|
|
5
|
+
"description": "SSH2 client and server modules written in pure JavaScript for node.js",
|
|
6
|
+
"main": "./lib/index.js",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=10.16.0"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"asn1": "^0.2.6",
|
|
12
|
+
"bcrypt-pbkdf": "^1.0.2"
|
|
13
|
+
},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"@mscdex/eslint-config": "^1.1.0",
|
|
16
|
+
"eslint": "^7.32.0"
|
|
17
|
+
},
|
|
18
|
+
"optionalDependencies": {
|
|
19
|
+
"cpu-features": "~0.0.10",
|
|
20
|
+
"nan": "^2.23.0"
|
|
21
|
+
},
|
|
22
|
+
"scripts": {
|
|
23
|
+
"install": "node install.js",
|
|
24
|
+
"rebuild": "node install.js",
|
|
25
|
+
"test": "node test/test.js",
|
|
26
|
+
"lint": "eslint --cache --report-unused-disable-directives --ext=.js .eslintrc.js examples lib test",
|
|
27
|
+
"lint:fix": "npm run lint -- --fix"
|
|
28
|
+
},
|
|
29
|
+
"keywords": [
|
|
30
|
+
"ssh",
|
|
31
|
+
"ssh2",
|
|
32
|
+
"sftp",
|
|
33
|
+
"secure",
|
|
34
|
+
"shell",
|
|
35
|
+
"exec",
|
|
36
|
+
"remote",
|
|
37
|
+
"client"
|
|
38
|
+
],
|
|
39
|
+
"licenses": [
|
|
40
|
+
{
|
|
41
|
+
"type": "MIT",
|
|
42
|
+
"url": "http://github.com/mscdex/ssh2/raw/master/LICENSE"
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
"repository": {
|
|
46
|
+
"type": "git",
|
|
47
|
+
"url": "http://github.com/mscdex/ssh2.git"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const assert = require('assert');
|
|
4
|
+
const { readFileSync } = require('fs');
|
|
5
|
+
const { join } = require('path');
|
|
6
|
+
const { inspect } = require('util');
|
|
7
|
+
|
|
8
|
+
const Client = require('../lib/client.js');
|
|
9
|
+
const Server = require('../lib/server.js');
|
|
10
|
+
const { parseKey } = require('../lib/protocol/keyParser.js');
|
|
11
|
+
|
|
12
|
+
const mustCallChecks = [];
|
|
13
|
+
|
|
14
|
+
const DEFAULT_TEST_TIMEOUT = 30 * 1000;
|
|
15
|
+
|
|
16
|
+
function noop() {}
|
|
17
|
+
|
|
18
|
+
function runCallChecks(exitCode) {
|
|
19
|
+
if (exitCode !== 0) return;
|
|
20
|
+
|
|
21
|
+
const failed = mustCallChecks.filter((context) => {
|
|
22
|
+
if ('minimum' in context) {
|
|
23
|
+
context.messageSegment = `at least ${context.minimum}`;
|
|
24
|
+
return context.actual < context.minimum;
|
|
25
|
+
}
|
|
26
|
+
context.messageSegment = `exactly ${context.exact}`;
|
|
27
|
+
return context.actual !== context.exact;
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
failed.forEach((context) => {
|
|
31
|
+
console.error('Mismatched %s function calls. Expected %s, actual %d.',
|
|
32
|
+
context.name,
|
|
33
|
+
context.messageSegment,
|
|
34
|
+
context.actual);
|
|
35
|
+
console.error(context.stack.split('\n').slice(2).join('\n'));
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
if (failed.length)
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function mustCall(fn, exact) {
|
|
43
|
+
return _mustCallInner(fn, exact, 'exact');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function mustCallAtLeast(fn, minimum) {
|
|
47
|
+
return _mustCallInner(fn, minimum, 'minimum');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function _mustCallInner(fn, criteria = 1, field) {
|
|
51
|
+
if (process._exiting)
|
|
52
|
+
throw new Error('Cannot use common.mustCall*() in process exit handler');
|
|
53
|
+
|
|
54
|
+
if (typeof fn === 'number') {
|
|
55
|
+
criteria = fn;
|
|
56
|
+
fn = noop;
|
|
57
|
+
} else if (fn === undefined) {
|
|
58
|
+
fn = noop;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (typeof criteria !== 'number')
|
|
62
|
+
throw new TypeError(`Invalid ${field} value: ${criteria}`);
|
|
63
|
+
|
|
64
|
+
const context = {
|
|
65
|
+
[field]: criteria,
|
|
66
|
+
actual: 0,
|
|
67
|
+
stack: inspect(new Error()),
|
|
68
|
+
name: fn.name || '<anonymous>'
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
// Add the exit listener only once to avoid listener leak warnings
|
|
72
|
+
if (mustCallChecks.length === 0)
|
|
73
|
+
process.on('exit', runCallChecks);
|
|
74
|
+
|
|
75
|
+
mustCallChecks.push(context);
|
|
76
|
+
|
|
77
|
+
function wrapped(...args) {
|
|
78
|
+
++context.actual;
|
|
79
|
+
return fn.call(this, ...args);
|
|
80
|
+
}
|
|
81
|
+
// TODO: remove origFn?
|
|
82
|
+
wrapped.origFn = fn;
|
|
83
|
+
|
|
84
|
+
return wrapped;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function getCallSite(top) {
|
|
88
|
+
const originalStackFormatter = Error.prepareStackTrace;
|
|
89
|
+
Error.prepareStackTrace = (err, stack) =>
|
|
90
|
+
`${stack[0].getFileName()}:${stack[0].getLineNumber()}`;
|
|
91
|
+
const err = new Error();
|
|
92
|
+
Error.captureStackTrace(err, top);
|
|
93
|
+
// With the V8 Error API, the stack is not formatted until it is accessed
|
|
94
|
+
// eslint-disable-next-line no-unused-expressions
|
|
95
|
+
err.stack;
|
|
96
|
+
Error.prepareStackTrace = originalStackFormatter;
|
|
97
|
+
return err.stack;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function mustNotCall(msg) {
|
|
101
|
+
const callSite = getCallSite(mustNotCall);
|
|
102
|
+
return function mustNotCall(...args) {
|
|
103
|
+
args = args.map(inspect).join(', ');
|
|
104
|
+
const argsInfo = (args.length > 0
|
|
105
|
+
? `\ncalled with arguments: ${args}`
|
|
106
|
+
: '');
|
|
107
|
+
assert.fail(
|
|
108
|
+
`${msg || 'function should not have been called'} at ${callSite}`
|
|
109
|
+
+ argsInfo);
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function setup(title, configs) {
|
|
114
|
+
const {
|
|
115
|
+
client: clientCfg_,
|
|
116
|
+
server: serverCfg_,
|
|
117
|
+
allReady: allReady_,
|
|
118
|
+
timeout: timeout_,
|
|
119
|
+
debug,
|
|
120
|
+
noForceClientReady,
|
|
121
|
+
noForceServerReady,
|
|
122
|
+
noClientError,
|
|
123
|
+
noServerError,
|
|
124
|
+
} = configs;
|
|
125
|
+
|
|
126
|
+
// Make shallow copies of client/server configs to avoid mutating them when
|
|
127
|
+
// multiple tests share the same config object reference
|
|
128
|
+
let clientCfg;
|
|
129
|
+
if (clientCfg_)
|
|
130
|
+
clientCfg = { ...clientCfg_ };
|
|
131
|
+
let serverCfg;
|
|
132
|
+
if (serverCfg_)
|
|
133
|
+
serverCfg = { ...serverCfg_ };
|
|
134
|
+
|
|
135
|
+
let clientClose = false;
|
|
136
|
+
let clientReady = false;
|
|
137
|
+
let serverClose = false;
|
|
138
|
+
let serverReady = false;
|
|
139
|
+
const msg = (text) => {
|
|
140
|
+
return `${title}: ${text}`;
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
const timeout = (typeof timeout_ === 'number'
|
|
144
|
+
? timeout_
|
|
145
|
+
: DEFAULT_TEST_TIMEOUT);
|
|
146
|
+
|
|
147
|
+
const allReady = (typeof allReady_ === 'function' ? allReady_ : undefined);
|
|
148
|
+
|
|
149
|
+
if (debug) {
|
|
150
|
+
if (clientCfg) {
|
|
151
|
+
clientCfg.debug = (...args) => {
|
|
152
|
+
console.log(`[${title}][CLIENT]`, ...args);
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
if (serverCfg) {
|
|
156
|
+
serverCfg.debug = (...args) => {
|
|
157
|
+
console.log(`[${title}][SERVER]`, ...args);
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
let timer;
|
|
163
|
+
let client;
|
|
164
|
+
let clientReadyFn;
|
|
165
|
+
let server;
|
|
166
|
+
let serverReadyFn;
|
|
167
|
+
if (clientCfg) {
|
|
168
|
+
client = new Client();
|
|
169
|
+
if (!noClientError)
|
|
170
|
+
client.on('error', onError);
|
|
171
|
+
clientReadyFn = (noForceClientReady ? onReady : mustCall(onReady));
|
|
172
|
+
client.on('ready', clientReadyFn)
|
|
173
|
+
.on('close', mustCall(onClose));
|
|
174
|
+
} else {
|
|
175
|
+
clientReady = clientClose = true;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (serverCfg) {
|
|
179
|
+
server = new Server(serverCfg);
|
|
180
|
+
if (!noServerError)
|
|
181
|
+
server.on('error', onError);
|
|
182
|
+
serverReadyFn = (noForceServerReady ? onReady : mustCall(onReady));
|
|
183
|
+
server.on('connection', mustCall((conn) => {
|
|
184
|
+
if (!noServerError)
|
|
185
|
+
conn.on('error', onError);
|
|
186
|
+
conn.on('ready', serverReadyFn);
|
|
187
|
+
server.close();
|
|
188
|
+
})).on('close', mustCall(onClose));
|
|
189
|
+
} else {
|
|
190
|
+
serverReady = serverClose = true;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function onError(err) {
|
|
194
|
+
const which = (this === client ? 'client' : 'server');
|
|
195
|
+
assert(false, msg(`Unexpected ${which} error: ${err.stack}\n`));
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function onReady() {
|
|
199
|
+
if (this === client) {
|
|
200
|
+
assert(!clientReady,
|
|
201
|
+
msg('Received multiple ready events for client'));
|
|
202
|
+
clientReady = true;
|
|
203
|
+
} else {
|
|
204
|
+
assert(!serverReady,
|
|
205
|
+
msg('Received multiple ready events for server'));
|
|
206
|
+
serverReady = true;
|
|
207
|
+
}
|
|
208
|
+
clientReady && serverReady && allReady && allReady();
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function onClose() {
|
|
212
|
+
if (this === client) {
|
|
213
|
+
assert(!clientClose,
|
|
214
|
+
msg('Received multiple close events for client'));
|
|
215
|
+
clientClose = true;
|
|
216
|
+
} else {
|
|
217
|
+
assert(!serverClose,
|
|
218
|
+
msg('Received multiple close events for server'));
|
|
219
|
+
serverClose = true;
|
|
220
|
+
}
|
|
221
|
+
if (clientClose && serverClose)
|
|
222
|
+
clearTimeout(timer);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
process.nextTick(mustCall(() => {
|
|
226
|
+
function connectClient() {
|
|
227
|
+
if (clientCfg.sock) {
|
|
228
|
+
clientCfg.sock.connect(server.address().port, 'localhost');
|
|
229
|
+
} else {
|
|
230
|
+
clientCfg.host = 'localhost';
|
|
231
|
+
clientCfg.port = server.address().port;
|
|
232
|
+
}
|
|
233
|
+
try {
|
|
234
|
+
client.connect(clientCfg);
|
|
235
|
+
} catch (ex) {
|
|
236
|
+
ex.message = msg(ex.message);
|
|
237
|
+
throw ex;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
if (server) {
|
|
242
|
+
server.listen(0, 'localhost', mustCall(() => {
|
|
243
|
+
if (timeout >= 0) {
|
|
244
|
+
timer = setTimeout(() => {
|
|
245
|
+
assert(false, msg('Test timed out'));
|
|
246
|
+
}, timeout);
|
|
247
|
+
}
|
|
248
|
+
if (client)
|
|
249
|
+
connectClient();
|
|
250
|
+
}));
|
|
251
|
+
}
|
|
252
|
+
}));
|
|
253
|
+
|
|
254
|
+
return { client, server };
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const FIXTURES_DIR = join(__dirname, 'fixtures');
|
|
258
|
+
const fixture = (() => {
|
|
259
|
+
const cache = new Map();
|
|
260
|
+
return (file) => {
|
|
261
|
+
const existing = cache.get(file);
|
|
262
|
+
if (existing !== undefined)
|
|
263
|
+
return existing;
|
|
264
|
+
|
|
265
|
+
const result = readFileSync(join(FIXTURES_DIR, file));
|
|
266
|
+
cache.set(file, result);
|
|
267
|
+
return result;
|
|
268
|
+
};
|
|
269
|
+
})();
|
|
270
|
+
const fixtureKey = (() => {
|
|
271
|
+
const cache = new Map();
|
|
272
|
+
return (file, passphrase, bypass) => {
|
|
273
|
+
if (typeof passphrase === 'boolean') {
|
|
274
|
+
bypass = passphrase;
|
|
275
|
+
passphrase = undefined;
|
|
276
|
+
}
|
|
277
|
+
if (typeof bypass !== 'boolean' || !bypass) {
|
|
278
|
+
const existing = cache.get(file);
|
|
279
|
+
if (existing !== undefined)
|
|
280
|
+
return existing;
|
|
281
|
+
}
|
|
282
|
+
const fullPath = join(FIXTURES_DIR, file);
|
|
283
|
+
const raw = fixture(file);
|
|
284
|
+
let key = parseKey(raw, passphrase);
|
|
285
|
+
if (Array.isArray(key))
|
|
286
|
+
key = key[0];
|
|
287
|
+
const result = { key, raw, fullPath };
|
|
288
|
+
cache.set(file, result);
|
|
289
|
+
return result;
|
|
290
|
+
};
|
|
291
|
+
})();
|
|
292
|
+
|
|
293
|
+
function setupSimple(debug, title) {
|
|
294
|
+
const { client, server } = setup(title, {
|
|
295
|
+
client: { username: 'Password User', password: '12345' },
|
|
296
|
+
server: { hostKeys: [ fixtureKey('ssh_host_rsa_key').raw ] },
|
|
297
|
+
debug,
|
|
298
|
+
});
|
|
299
|
+
server.on('connection', mustCall((conn) => {
|
|
300
|
+
conn.on('authentication', mustCall((ctx) => {
|
|
301
|
+
ctx.accept();
|
|
302
|
+
}));
|
|
303
|
+
}));
|
|
304
|
+
return { client, server };
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
module.exports = {
|
|
308
|
+
fixture,
|
|
309
|
+
fixtureKey,
|
|
310
|
+
FIXTURES_DIR,
|
|
311
|
+
mustCall,
|
|
312
|
+
mustCallAtLeast,
|
|
313
|
+
mustNotCall,
|
|
314
|
+
setup,
|
|
315
|
+
setupSimple,
|
|
316
|
+
};
|