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,1285 @@
1
+ 'use strict';
2
+
3
+ const {
4
+ bufferSlice,
5
+ bufferParser,
6
+ doFatalError,
7
+ sigSSHToASN1,
8
+ writeUInt32BE,
9
+ } = require('./utils.js');
10
+
11
+ const {
12
+ CHANNEL_OPEN_FAILURE,
13
+ COMPAT,
14
+ MESSAGE,
15
+ TERMINAL_MODE,
16
+ } = require('./constants.js');
17
+
18
+ const {
19
+ parseKey,
20
+ } = require('./keyParser.js');
21
+
22
+ const TERMINAL_MODE_BY_VALUE =
23
+ Array.from(Object.entries(TERMINAL_MODE))
24
+ .reduce((obj, [key, value]) => ({ ...obj, [key]: value }), {});
25
+
26
+ module.exports = {
27
+ // Transport layer protocol ==================================================
28
+ [MESSAGE.DISCONNECT]: (self, payload) => {
29
+ /*
30
+ byte SSH_MSG_DISCONNECT
31
+ uint32 reason code
32
+ string description in ISO-10646 UTF-8 encoding
33
+ string language tag
34
+ */
35
+ bufferParser.init(payload, 1);
36
+ const reason = bufferParser.readUInt32BE();
37
+ const desc = bufferParser.readString(true);
38
+ const lang = bufferParser.readString();
39
+ bufferParser.clear();
40
+
41
+ if (lang === undefined) {
42
+ return doFatalError(
43
+ self,
44
+ 'Inbound: Malformed DISCONNECT packet'
45
+ );
46
+ }
47
+
48
+ self._debug && self._debug(
49
+ `Inbound: Received DISCONNECT (${reason}, "${desc}")`
50
+ );
51
+
52
+ const handler = self._handlers.DISCONNECT;
53
+ handler && handler(self, reason, desc);
54
+ },
55
+ [MESSAGE.IGNORE]: (self, payload) => {
56
+ /*
57
+ byte SSH_MSG_IGNORE
58
+ string data
59
+ */
60
+ self._debug && self._debug('Inbound: Received IGNORE');
61
+ },
62
+ [MESSAGE.UNIMPLEMENTED]: (self, payload) => {
63
+ /*
64
+ byte SSH_MSG_UNIMPLEMENTED
65
+ uint32 packet sequence number of rejected message
66
+ */
67
+ bufferParser.init(payload, 1);
68
+ const seqno = bufferParser.readUInt32BE();
69
+ bufferParser.clear();
70
+
71
+ if (seqno === undefined) {
72
+ return doFatalError(
73
+ self,
74
+ 'Inbound: Malformed UNIMPLEMENTED packet'
75
+ );
76
+ }
77
+
78
+ self._debug
79
+ && self._debug(`Inbound: Received UNIMPLEMENTED (seqno ${seqno})`);
80
+ },
81
+ [MESSAGE.DEBUG]: (self, payload) => {
82
+ /*
83
+ byte SSH_MSG_DEBUG
84
+ boolean always_display
85
+ string message in ISO-10646 UTF-8 encoding [RFC3629]
86
+ string language tag [RFC3066]
87
+ */
88
+ bufferParser.init(payload, 1);
89
+ const display = bufferParser.readBool();
90
+ const msg = bufferParser.readString(true);
91
+ const lang = bufferParser.readString();
92
+ bufferParser.clear();
93
+
94
+ if (lang === undefined) {
95
+ return doFatalError(
96
+ self,
97
+ 'Inbound: Malformed DEBUG packet'
98
+ );
99
+ }
100
+
101
+ self._debug && self._debug('Inbound: Received DEBUG');
102
+
103
+ const handler = self._handlers.DEBUG;
104
+ handler && handler(self, display, msg);
105
+ },
106
+ [MESSAGE.SERVICE_REQUEST]: (self, payload) => {
107
+ /*
108
+ byte SSH_MSG_SERVICE_REQUEST
109
+ string service name
110
+ */
111
+ bufferParser.init(payload, 1);
112
+ const name = bufferParser.readString(true);
113
+ bufferParser.clear();
114
+
115
+ if (name === undefined) {
116
+ return doFatalError(
117
+ self,
118
+ 'Inbound: Malformed SERVICE_REQUEST packet'
119
+ );
120
+ }
121
+
122
+ self._debug && self._debug(`Inbound: Received SERVICE_REQUEST (${name})`);
123
+
124
+ const handler = self._handlers.SERVICE_REQUEST;
125
+ handler && handler(self, name);
126
+ },
127
+ [MESSAGE.SERVICE_ACCEPT]: (self, payload) => {
128
+ // S->C
129
+ /*
130
+ byte SSH_MSG_SERVICE_ACCEPT
131
+ string service name
132
+ */
133
+ bufferParser.init(payload, 1);
134
+ const name = bufferParser.readString(true);
135
+ bufferParser.clear();
136
+
137
+ if (name === undefined) {
138
+ return doFatalError(
139
+ self,
140
+ 'Inbound: Malformed SERVICE_ACCEPT packet'
141
+ );
142
+ }
143
+
144
+ self._debug && self._debug(`Inbound: Received SERVICE_ACCEPT (${name})`);
145
+
146
+ const handler = self._handlers.SERVICE_ACCEPT;
147
+ handler && handler(self, name);
148
+ },
149
+ [MESSAGE.EXT_INFO]: (self, payload) => {
150
+ /*
151
+ byte SSH_MSG_EXT_INFO
152
+ uint32 nr-extensions
153
+ repeat the following 2 fields "nr-extensions" times:
154
+ string extension-name
155
+ string extension-value (binary)
156
+ */
157
+ bufferParser.init(payload, 1);
158
+ const numExts = bufferParser.readUInt32BE();
159
+ let exts;
160
+ if (numExts !== undefined) {
161
+ exts = [];
162
+ for (let i = 0; i < numExts; ++i) {
163
+ const name = bufferParser.readString(true);
164
+ const data = bufferParser.readString();
165
+ if (data !== undefined) {
166
+ switch (name) {
167
+ case 'server-sig-algs': {
168
+ const algs = data.latin1Slice(0, data.length).split(',');
169
+ exts.push({ name, algs });
170
+ continue;
171
+ }
172
+ default:
173
+ continue;
174
+ }
175
+ }
176
+ // Malformed
177
+ exts = undefined;
178
+ break;
179
+ }
180
+ }
181
+ bufferParser.clear();
182
+
183
+ if (exts === undefined)
184
+ return doFatalError(self, 'Inbound: Malformed EXT_INFO packet');
185
+
186
+ self._debug && self._debug('Inbound: Received EXT_INFO');
187
+
188
+ const handler = self._handlers.EXT_INFO;
189
+ handler && handler(self, exts);
190
+ },
191
+
192
+ // User auth protocol -- generic =============================================
193
+ [MESSAGE.USERAUTH_REQUEST]: (self, payload) => {
194
+ /*
195
+ byte SSH_MSG_USERAUTH_REQUEST
196
+ string user name in ISO-10646 UTF-8 encoding [RFC3629]
197
+ string service name in US-ASCII
198
+ string method name in US-ASCII
199
+ .... method specific fields
200
+ */
201
+ bufferParser.init(payload, 1);
202
+ const user = bufferParser.readString(true);
203
+ const service = bufferParser.readString(true);
204
+ const method = bufferParser.readString(true);
205
+ let methodData;
206
+ let methodDesc;
207
+ switch (method) {
208
+ case 'none':
209
+ methodData = null;
210
+ break;
211
+ case 'password': {
212
+ /*
213
+ boolean <new password follows (old) plaintext password?>
214
+ string plaintext password in ISO-10646 UTF-8 encoding [RFC3629]
215
+ [string new password]
216
+ */
217
+ const isChange = bufferParser.readBool();
218
+ if (isChange !== undefined) {
219
+ methodData = bufferParser.readString(true);
220
+ if (methodData !== undefined && isChange) {
221
+ const newPassword = bufferParser.readString(true);
222
+ if (newPassword !== undefined)
223
+ methodData = { oldPassword: methodData, newPassword };
224
+ else
225
+ methodData = undefined;
226
+ }
227
+ }
228
+ break;
229
+ }
230
+ case 'publickey': {
231
+ /*
232
+ boolean <signature follows public key blob?>
233
+ string public key algorithm name
234
+ string public key blob
235
+ [string signature]
236
+ */
237
+ const hasSig = bufferParser.readBool();
238
+ if (hasSig !== undefined) {
239
+ const keyAlgo = bufferParser.readString(true);
240
+ let realKeyAlgo = keyAlgo;
241
+ const key = bufferParser.readString();
242
+
243
+ let hashAlgo;
244
+ switch (keyAlgo) {
245
+ case 'rsa-sha2-256':
246
+ realKeyAlgo = 'ssh-rsa';
247
+ hashAlgo = 'sha256';
248
+ break;
249
+ case 'rsa-sha2-512':
250
+ realKeyAlgo = 'ssh-rsa';
251
+ hashAlgo = 'sha512';
252
+ break;
253
+ }
254
+
255
+ if (hasSig) {
256
+ const blobEnd = bufferParser.pos();
257
+ let signature = bufferParser.readString();
258
+ if (signature !== undefined) {
259
+ if (signature.length > (4 + keyAlgo.length + 4)
260
+ && signature.utf8Slice(4, 4 + keyAlgo.length) === keyAlgo) {
261
+ // Skip algoLen + algo + sigLen
262
+ signature = bufferSlice(signature, 4 + keyAlgo.length + 4);
263
+ }
264
+
265
+ signature = sigSSHToASN1(signature, realKeyAlgo);
266
+ if (signature) {
267
+ const sessionID = self._kex.sessionID;
268
+ const blob = Buffer.allocUnsafe(4 + sessionID.length + blobEnd);
269
+ writeUInt32BE(blob, sessionID.length, 0);
270
+ blob.set(sessionID, 4);
271
+ blob.set(
272
+ new Uint8Array(payload.buffer, payload.byteOffset, blobEnd),
273
+ 4 + sessionID.length
274
+ );
275
+ methodData = {
276
+ keyAlgo: realKeyAlgo,
277
+ key,
278
+ signature,
279
+ blob,
280
+ hashAlgo,
281
+ };
282
+ }
283
+ }
284
+ } else {
285
+ methodData = { keyAlgo: realKeyAlgo, key, hashAlgo };
286
+ methodDesc = 'publickey -- check';
287
+ }
288
+ }
289
+ break;
290
+ }
291
+ case 'hostbased': {
292
+ /*
293
+ string public key algorithm for host key
294
+ string public host key and certificates for client host
295
+ string client host name expressed as the FQDN in US-ASCII
296
+ string user name on the client host in ISO-10646 UTF-8 encoding
297
+ [RFC3629]
298
+ string signature
299
+ */
300
+ const keyAlgo = bufferParser.readString(true);
301
+ let realKeyAlgo = keyAlgo;
302
+ const key = bufferParser.readString();
303
+ const localHostname = bufferParser.readString(true);
304
+ const localUsername = bufferParser.readString(true);
305
+
306
+ let hashAlgo;
307
+ switch (keyAlgo) {
308
+ case 'rsa-sha2-256':
309
+ realKeyAlgo = 'ssh-rsa';
310
+ hashAlgo = 'sha256';
311
+ break;
312
+ case 'rsa-sha2-512':
313
+ realKeyAlgo = 'ssh-rsa';
314
+ hashAlgo = 'sha512';
315
+ break;
316
+ }
317
+
318
+ const blobEnd = bufferParser.pos();
319
+ let signature = bufferParser.readString();
320
+ if (signature !== undefined) {
321
+ if (signature.length > (4 + keyAlgo.length + 4)
322
+ && signature.utf8Slice(4, 4 + keyAlgo.length) === keyAlgo) {
323
+ // Skip algoLen + algo + sigLen
324
+ signature = bufferSlice(signature, 4 + keyAlgo.length + 4);
325
+ }
326
+
327
+ signature = sigSSHToASN1(signature, realKeyAlgo);
328
+ if (signature !== undefined) {
329
+ const sessionID = self._kex.sessionID;
330
+ const blob = Buffer.allocUnsafe(4 + sessionID.length + blobEnd);
331
+ writeUInt32BE(blob, sessionID.length, 0);
332
+ blob.set(sessionID, 4);
333
+ blob.set(
334
+ new Uint8Array(payload.buffer, payload.byteOffset, blobEnd),
335
+ 4 + sessionID.length
336
+ );
337
+ methodData = {
338
+ keyAlgo: realKeyAlgo,
339
+ key,
340
+ signature,
341
+ blob,
342
+ localHostname,
343
+ localUsername,
344
+ hashAlgo
345
+ };
346
+ }
347
+ }
348
+ break;
349
+ }
350
+ case 'keyboard-interactive':
351
+ /*
352
+ string language tag (as defined in [RFC-3066])
353
+ string submethods (ISO-10646 UTF-8)
354
+ */
355
+ // Skip/ignore language field -- it's deprecated in RFC 4256
356
+ bufferParser.skipString();
357
+
358
+ methodData = bufferParser.readList();
359
+ break;
360
+ default:
361
+ if (method !== undefined)
362
+ methodData = bufferParser.readRaw();
363
+ }
364
+ bufferParser.clear();
365
+
366
+ if (methodData === undefined) {
367
+ return doFatalError(
368
+ self,
369
+ 'Inbound: Malformed USERAUTH_REQUEST packet'
370
+ );
371
+ }
372
+
373
+ if (methodDesc === undefined)
374
+ methodDesc = method;
375
+
376
+ self._authsQueue.push(method);
377
+
378
+ self._debug
379
+ && self._debug(`Inbound: Received USERAUTH_REQUEST (${methodDesc})`);
380
+
381
+ const handler = self._handlers.USERAUTH_REQUEST;
382
+ handler && handler(self, user, service, method, methodData);
383
+ },
384
+ [MESSAGE.USERAUTH_FAILURE]: (self, payload) => {
385
+ // S->C
386
+ /*
387
+ byte SSH_MSG_USERAUTH_FAILURE
388
+ name-list authentications that can continue
389
+ boolean partial success
390
+ */
391
+ bufferParser.init(payload, 1);
392
+ const authMethods = bufferParser.readList();
393
+ const partialSuccess = bufferParser.readBool();
394
+ bufferParser.clear();
395
+
396
+ if (partialSuccess === undefined) {
397
+ return doFatalError(
398
+ self,
399
+ 'Inbound: Malformed USERAUTH_FAILURE packet'
400
+ );
401
+ }
402
+
403
+ self._debug
404
+ && self._debug(`Inbound: Received USERAUTH_FAILURE (${authMethods})`);
405
+
406
+ self._authsQueue.shift();
407
+ const handler = self._handlers.USERAUTH_FAILURE;
408
+ handler && handler(self, authMethods, partialSuccess);
409
+ },
410
+ [MESSAGE.USERAUTH_SUCCESS]: (self, payload) => {
411
+ // S->C
412
+ /*
413
+ byte SSH_MSG_USERAUTH_SUCCESS
414
+ */
415
+ self._debug && self._debug('Inbound: Received USERAUTH_SUCCESS');
416
+
417
+ self._authsQueue.shift();
418
+ const handler = self._handlers.USERAUTH_SUCCESS;
419
+ handler && handler(self);
420
+ },
421
+ [MESSAGE.USERAUTH_BANNER]: (self, payload) => {
422
+ // S->C
423
+ /*
424
+ byte SSH_MSG_USERAUTH_BANNER
425
+ string message in ISO-10646 UTF-8 encoding [RFC3629]
426
+ string language tag [RFC3066]
427
+ */
428
+ bufferParser.init(payload, 1);
429
+ const msg = bufferParser.readString(true);
430
+ const lang = bufferParser.readString();
431
+ bufferParser.clear();
432
+
433
+ if (lang === undefined) {
434
+ return doFatalError(
435
+ self,
436
+ 'Inbound: Malformed USERAUTH_BANNER packet'
437
+ );
438
+ }
439
+
440
+ self._debug && self._debug('Inbound: Received USERAUTH_BANNER');
441
+
442
+ const handler = self._handlers.USERAUTH_BANNER;
443
+ handler && handler(self, msg);
444
+ },
445
+
446
+ // User auth protocol -- method-specific =====================================
447
+ 60: (self, payload) => {
448
+ if (!self._authsQueue.length) {
449
+ self._debug
450
+ && self._debug('Inbound: Received payload type 60 without auth');
451
+ return;
452
+ }
453
+
454
+ switch (self._authsQueue[0]) {
455
+ case 'password': {
456
+ // S->C
457
+ /*
458
+ byte SSH_MSG_USERAUTH_PASSWD_CHANGEREQ
459
+ string prompt in ISO-10646 UTF-8 encoding [RFC3629]
460
+ string language tag [RFC3066]
461
+ */
462
+ bufferParser.init(payload, 1);
463
+ const prompt = bufferParser.readString(true);
464
+ const lang = bufferParser.readString();
465
+ bufferParser.clear();
466
+
467
+ if (lang === undefined) {
468
+ return doFatalError(
469
+ self,
470
+ 'Inbound: Malformed USERAUTH_PASSWD_CHANGEREQ packet'
471
+ );
472
+ }
473
+
474
+ self._debug
475
+ && self._debug('Inbound: Received USERAUTH_PASSWD_CHANGEREQ');
476
+
477
+ const handler = self._handlers.USERAUTH_PASSWD_CHANGEREQ;
478
+ handler && handler(self, prompt);
479
+ break;
480
+ }
481
+ case 'publickey': {
482
+ // S->C
483
+ /*
484
+ byte SSH_MSG_USERAUTH_PK_OK
485
+ string public key algorithm name from the request
486
+ string public key blob from the request
487
+ */
488
+ bufferParser.init(payload, 1);
489
+ const keyAlgo = bufferParser.readString(true);
490
+ const key = bufferParser.readString();
491
+ bufferParser.clear();
492
+
493
+ if (key === undefined) {
494
+ return doFatalError(
495
+ self,
496
+ 'Inbound: Malformed USERAUTH_PK_OK packet'
497
+ );
498
+ }
499
+
500
+ self._debug && self._debug('Inbound: Received USERAUTH_PK_OK');
501
+
502
+ self._authsQueue.shift();
503
+ const handler = self._handlers.USERAUTH_PK_OK;
504
+ handler && handler(self, keyAlgo, key);
505
+ break;
506
+ }
507
+ case 'keyboard-interactive': {
508
+ // S->C
509
+ /*
510
+ byte SSH_MSG_USERAUTH_INFO_REQUEST
511
+ string name (ISO-10646 UTF-8)
512
+ string instruction (ISO-10646 UTF-8)
513
+ string language tag (as defined in [RFC-3066])
514
+ int num-prompts
515
+ string prompt[1] (ISO-10646 UTF-8)
516
+ boolean echo[1]
517
+ ...
518
+ string prompt[num-prompts] (ISO-10646 UTF-8)
519
+ boolean echo[num-prompts]
520
+ */
521
+ bufferParser.init(payload, 1);
522
+ const name = bufferParser.readString(true);
523
+ const instructions = bufferParser.readString(true);
524
+ bufferParser.readString(); // skip lang
525
+ const numPrompts = bufferParser.readUInt32BE();
526
+ let prompts;
527
+ if (numPrompts !== undefined) {
528
+ prompts = new Array(numPrompts);
529
+ let i;
530
+ for (i = 0; i < numPrompts; ++i) {
531
+ const prompt = bufferParser.readString(true);
532
+ const echo = bufferParser.readBool();
533
+ if (echo === undefined)
534
+ break;
535
+ prompts[i] = { prompt, echo };
536
+ }
537
+ if (i !== numPrompts)
538
+ prompts = undefined;
539
+ }
540
+ bufferParser.clear();
541
+
542
+ if (prompts === undefined) {
543
+ return doFatalError(
544
+ self,
545
+ 'Inbound: Malformed USERAUTH_INFO_REQUEST packet'
546
+ );
547
+ }
548
+
549
+ self._debug && self._debug('Inbound: Received USERAUTH_INFO_REQUEST');
550
+
551
+ const handler = self._handlers.USERAUTH_INFO_REQUEST;
552
+ handler && handler(self, name, instructions, prompts);
553
+ break;
554
+ }
555
+ default:
556
+ self._debug
557
+ && self._debug('Inbound: Received unexpected payload type 60');
558
+ }
559
+ },
560
+ 61: (self, payload) => {
561
+ if (!self._authsQueue.length) {
562
+ self._debug
563
+ && self._debug('Inbound: Received payload type 61 without auth');
564
+ return;
565
+ }
566
+ /*
567
+ byte SSH_MSG_USERAUTH_INFO_RESPONSE
568
+ int num-responses
569
+ string response[1] (ISO-10646 UTF-8)
570
+ ...
571
+ string response[num-responses] (ISO-10646 UTF-8)
572
+ */
573
+ if (self._authsQueue[0] !== 'keyboard-interactive') {
574
+ return doFatalError(
575
+ self,
576
+ 'Inbound: Received unexpected payload type 61'
577
+ );
578
+ }
579
+ bufferParser.init(payload, 1);
580
+ const numResponses = bufferParser.readUInt32BE();
581
+ let responses;
582
+ if (numResponses !== undefined) {
583
+ responses = new Array(numResponses);
584
+ let i;
585
+ for (i = 0; i < numResponses; ++i) {
586
+ const response = bufferParser.readString(true);
587
+ if (response === undefined)
588
+ break;
589
+ responses[i] = response;
590
+ }
591
+ if (i !== numResponses)
592
+ responses = undefined;
593
+ }
594
+ bufferParser.clear();
595
+
596
+ if (responses === undefined) {
597
+ return doFatalError(
598
+ self,
599
+ 'Inbound: Malformed USERAUTH_INFO_RESPONSE packet'
600
+ );
601
+ }
602
+
603
+ self._debug && self._debug('Inbound: Received USERAUTH_INFO_RESPONSE');
604
+
605
+ const handler = self._handlers.USERAUTH_INFO_RESPONSE;
606
+ handler && handler(self, responses);
607
+ },
608
+
609
+ // Connection protocol -- generic ============================================
610
+ [MESSAGE.GLOBAL_REQUEST]: (self, payload) => {
611
+ /*
612
+ byte SSH_MSG_GLOBAL_REQUEST
613
+ string request name in US-ASCII only
614
+ boolean want reply
615
+ .... request-specific data follows
616
+ */
617
+ bufferParser.init(payload, 1);
618
+ const name = bufferParser.readString(true);
619
+ const wantReply = bufferParser.readBool();
620
+ let data;
621
+ if (wantReply !== undefined) {
622
+ switch (name) {
623
+ case 'tcpip-forward':
624
+ case 'cancel-tcpip-forward': {
625
+ /*
626
+ string address to bind (e.g., "0.0.0.0")
627
+ uint32 port number to bind
628
+ */
629
+ const bindAddr = bufferParser.readString(true);
630
+ const bindPort = bufferParser.readUInt32BE();
631
+ if (bindPort !== undefined)
632
+ data = { bindAddr, bindPort };
633
+ break;
634
+ }
635
+ case 'streamlocal-forward@openssh.com':
636
+ case 'cancel-streamlocal-forward@openssh.com': {
637
+ /*
638
+ string socket path
639
+ */
640
+ const socketPath = bufferParser.readString(true);
641
+ if (socketPath !== undefined)
642
+ data = { socketPath };
643
+ break;
644
+ }
645
+ case 'no-more-sessions@openssh.com':
646
+ data = null;
647
+ break;
648
+ case 'hostkeys-00@openssh.com': {
649
+ data = [];
650
+ while (bufferParser.avail() > 0) {
651
+ const keyRaw = bufferParser.readString();
652
+ if (keyRaw === undefined) {
653
+ data = undefined;
654
+ break;
655
+ }
656
+ const key = parseKey(keyRaw);
657
+ if (!(key instanceof Error))
658
+ data.push(key);
659
+ }
660
+ break;
661
+ }
662
+ default:
663
+ data = bufferParser.readRaw();
664
+ }
665
+ }
666
+ bufferParser.clear();
667
+
668
+ if (data === undefined) {
669
+ return doFatalError(
670
+ self,
671
+ 'Inbound: Malformed GLOBAL_REQUEST packet'
672
+ );
673
+ }
674
+
675
+ self._debug && self._debug(`Inbound: GLOBAL_REQUEST (${name})`);
676
+
677
+ const handler = self._handlers.GLOBAL_REQUEST;
678
+ if (handler)
679
+ handler(self, name, wantReply, data);
680
+ else
681
+ self.requestFailure(); // Auto reject
682
+ },
683
+ [MESSAGE.REQUEST_SUCCESS]: (self, payload) => {
684
+ /*
685
+ byte SSH_MSG_REQUEST_SUCCESS
686
+ .... response specific data
687
+ */
688
+ const data = (payload.length > 1 ? bufferSlice(payload, 1) : null);
689
+
690
+ self._debug && self._debug('Inbound: REQUEST_SUCCESS');
691
+
692
+ const handler = self._handlers.REQUEST_SUCCESS;
693
+ handler && handler(self, data);
694
+ },
695
+ [MESSAGE.REQUEST_FAILURE]: (self, payload) => {
696
+ /*
697
+ byte SSH_MSG_REQUEST_FAILURE
698
+ */
699
+ self._debug && self._debug('Inbound: Received REQUEST_FAILURE');
700
+
701
+ const handler = self._handlers.REQUEST_FAILURE;
702
+ handler && handler(self);
703
+ },
704
+
705
+ // Connection protocol -- channel-related ====================================
706
+ [MESSAGE.CHANNEL_OPEN]: (self, payload) => {
707
+ /*
708
+ byte SSH_MSG_CHANNEL_OPEN
709
+ string channel type in US-ASCII only
710
+ uint32 sender channel
711
+ uint32 initial window size
712
+ uint32 maximum packet size
713
+ .... channel type specific data follows
714
+ */
715
+ bufferParser.init(payload, 1);
716
+ const type = bufferParser.readString(true);
717
+ const sender = bufferParser.readUInt32BE();
718
+ const window = bufferParser.readUInt32BE();
719
+ const packetSize = bufferParser.readUInt32BE();
720
+ let channelInfo;
721
+
722
+ switch (type) {
723
+ case 'forwarded-tcpip': // S->C
724
+ case 'direct-tcpip': { // C->S
725
+ /*
726
+ string address that was connected / host to connect
727
+ uint32 port that was connected / port to connect
728
+ string originator IP address
729
+ uint32 originator port
730
+ */
731
+ const destIP = bufferParser.readString(true);
732
+ const destPort = bufferParser.readUInt32BE();
733
+ const srcIP = bufferParser.readString(true);
734
+ const srcPort = bufferParser.readUInt32BE();
735
+ if (srcPort !== undefined) {
736
+ channelInfo = {
737
+ type,
738
+ sender,
739
+ window,
740
+ packetSize,
741
+ data: { destIP, destPort, srcIP, srcPort }
742
+ };
743
+ }
744
+ break;
745
+ }
746
+ case 'forwarded-streamlocal@openssh.com': // S->C
747
+ case 'direct-streamlocal@openssh.com': { // C->S
748
+ /*
749
+ string socket path
750
+ string reserved for future use
751
+
752
+ (direct-streamlocal@openssh.com additionally has:)
753
+ uint32 reserved
754
+ */
755
+ const socketPath = bufferParser.readString(true);
756
+ if (socketPath !== undefined) {
757
+ channelInfo = {
758
+ type,
759
+ sender,
760
+ window,
761
+ packetSize,
762
+ data: { socketPath }
763
+ };
764
+ }
765
+ break;
766
+ }
767
+ case 'x11': { // S->C
768
+ /*
769
+ string originator address (e.g., "192.168.7.38")
770
+ uint32 originator port
771
+ */
772
+ const srcIP = bufferParser.readString(true);
773
+ const srcPort = bufferParser.readUInt32BE();
774
+ if (srcPort !== undefined) {
775
+ channelInfo = {
776
+ type,
777
+ sender,
778
+ window,
779
+ packetSize,
780
+ data: { srcIP, srcPort }
781
+ };
782
+ }
783
+ break;
784
+ }
785
+ default:
786
+ // Includes:
787
+ // 'session' (C->S)
788
+ // 'auth-agent@openssh.com' (S->C)
789
+ channelInfo = {
790
+ type,
791
+ sender,
792
+ window,
793
+ packetSize,
794
+ data: {}
795
+ };
796
+ }
797
+ bufferParser.clear();
798
+
799
+ if (channelInfo === undefined) {
800
+ return doFatalError(
801
+ self,
802
+ 'Inbound: Malformed CHANNEL_OPEN packet'
803
+ );
804
+ }
805
+
806
+ self._debug && self._debug(`Inbound: CHANNEL_OPEN (s:${sender}, ${type})`);
807
+
808
+ const handler = self._handlers.CHANNEL_OPEN;
809
+ if (handler) {
810
+ handler(self, channelInfo);
811
+ } else {
812
+ self.channelOpenFail(
813
+ channelInfo.sender,
814
+ CHANNEL_OPEN_FAILURE.ADMINISTRATIVELY_PROHIBITED,
815
+ '',
816
+ ''
817
+ );
818
+ }
819
+ },
820
+ [MESSAGE.CHANNEL_OPEN_CONFIRMATION]: (self, payload) => {
821
+ /*
822
+ byte SSH_MSG_CHANNEL_OPEN_CONFIRMATION
823
+ uint32 recipient channel
824
+ uint32 sender channel
825
+ uint32 initial window size
826
+ uint32 maximum packet size
827
+ .... channel type specific data follows
828
+ */
829
+ // "The 'recipient channel' is the channel number given in the
830
+ // original open request, and 'sender channel' is the channel number
831
+ // allocated by the other side."
832
+ bufferParser.init(payload, 1);
833
+ const recipient = bufferParser.readUInt32BE();
834
+ const sender = bufferParser.readUInt32BE();
835
+ const window = bufferParser.readUInt32BE();
836
+ const packetSize = bufferParser.readUInt32BE();
837
+ const data = (bufferParser.avail() ? bufferParser.readRaw() : undefined);
838
+ bufferParser.clear();
839
+
840
+ if (packetSize === undefined) {
841
+ return doFatalError(
842
+ self,
843
+ 'Inbound: Malformed CHANNEL_OPEN_CONFIRMATION packet'
844
+ );
845
+ }
846
+
847
+ self._debug && self._debug(
848
+ `Inbound: CHANNEL_OPEN_CONFIRMATION (r:${recipient}, s:${sender})`
849
+ );
850
+
851
+ const handler = self._handlers.CHANNEL_OPEN_CONFIRMATION;
852
+ if (handler)
853
+ handler(self, { recipient, sender, window, packetSize, data });
854
+ },
855
+ [MESSAGE.CHANNEL_OPEN_FAILURE]: (self, payload) => {
856
+ /*
857
+ byte SSH_MSG_CHANNEL_OPEN_FAILURE
858
+ uint32 recipient channel
859
+ uint32 reason code
860
+ string description in ISO-10646 UTF-8 encoding [RFC3629]
861
+ string language tag [RFC3066]
862
+ */
863
+ bufferParser.init(payload, 1);
864
+ const recipient = bufferParser.readUInt32BE();
865
+ const reason = bufferParser.readUInt32BE();
866
+ const description = bufferParser.readString(true);
867
+ const lang = bufferParser.readString();
868
+ bufferParser.clear();
869
+
870
+ if (lang === undefined) {
871
+ return doFatalError(
872
+ self,
873
+ 'Inbound: Malformed CHANNEL_OPEN_FAILURE packet'
874
+ );
875
+ }
876
+
877
+ self._debug
878
+ && self._debug(`Inbound: CHANNEL_OPEN_FAILURE (r:${recipient})`);
879
+
880
+ const handler = self._handlers.CHANNEL_OPEN_FAILURE;
881
+ handler && handler(self, recipient, reason, description);
882
+ },
883
+ [MESSAGE.CHANNEL_WINDOW_ADJUST]: (self, payload) => {
884
+ /*
885
+ byte SSH_MSG_CHANNEL_WINDOW_ADJUST
886
+ uint32 recipient channel
887
+ uint32 bytes to add
888
+ */
889
+ bufferParser.init(payload, 1);
890
+ const recipient = bufferParser.readUInt32BE();
891
+ const bytesToAdd = bufferParser.readUInt32BE();
892
+ bufferParser.clear();
893
+
894
+ if (bytesToAdd === undefined) {
895
+ return doFatalError(
896
+ self,
897
+ 'Inbound: Malformed CHANNEL_WINDOW_ADJUST packet'
898
+ );
899
+ }
900
+
901
+ self._debug && self._debug(
902
+ `Inbound: CHANNEL_WINDOW_ADJUST (r:${recipient}, ${bytesToAdd})`
903
+ );
904
+
905
+ const handler = self._handlers.CHANNEL_WINDOW_ADJUST;
906
+ handler && handler(self, recipient, bytesToAdd);
907
+ },
908
+ [MESSAGE.CHANNEL_DATA]: (self, payload) => {
909
+ /*
910
+ byte SSH_MSG_CHANNEL_DATA
911
+ uint32 recipient channel
912
+ string data
913
+ */
914
+ bufferParser.init(payload, 1);
915
+ const recipient = bufferParser.readUInt32BE();
916
+ const data = bufferParser.readString();
917
+ bufferParser.clear();
918
+
919
+ if (data === undefined) {
920
+ return doFatalError(
921
+ self,
922
+ 'Inbound: Malformed CHANNEL_DATA packet'
923
+ );
924
+ }
925
+
926
+ self._debug
927
+ && self._debug(`Inbound: CHANNEL_DATA (r:${recipient}, ${data.length})`);
928
+
929
+ const handler = self._handlers.CHANNEL_DATA;
930
+ handler && handler(self, recipient, data);
931
+ },
932
+ [MESSAGE.CHANNEL_EXTENDED_DATA]: (self, payload) => {
933
+ /*
934
+ byte SSH_MSG_CHANNEL_EXTENDED_DATA
935
+ uint32 recipient channel
936
+ uint32 data_type_code
937
+ string data
938
+ */
939
+ bufferParser.init(payload, 1);
940
+ const recipient = bufferParser.readUInt32BE();
941
+ const type = bufferParser.readUInt32BE();
942
+ const data = bufferParser.readString();
943
+ bufferParser.clear();
944
+
945
+ if (data === undefined) {
946
+ return doFatalError(
947
+ self,
948
+ 'Inbound: Malformed CHANNEL_EXTENDED_DATA packet'
949
+ );
950
+ }
951
+
952
+ self._debug && self._debug(
953
+ `Inbound: CHANNEL_EXTENDED_DATA (r:${recipient}, ${data.length})`
954
+ );
955
+
956
+ const handler = self._handlers.CHANNEL_EXTENDED_DATA;
957
+ handler && handler(self, recipient, data, type);
958
+ },
959
+ [MESSAGE.CHANNEL_EOF]: (self, payload) => {
960
+ /*
961
+ byte SSH_MSG_CHANNEL_EOF
962
+ uint32 recipient channel
963
+ */
964
+ bufferParser.init(payload, 1);
965
+ const recipient = bufferParser.readUInt32BE();
966
+ bufferParser.clear();
967
+
968
+ if (recipient === undefined) {
969
+ return doFatalError(
970
+ self,
971
+ 'Inbound: Malformed CHANNEL_EOF packet'
972
+ );
973
+ }
974
+
975
+ self._debug && self._debug(`Inbound: CHANNEL_EOF (r:${recipient})`);
976
+
977
+ const handler = self._handlers.CHANNEL_EOF;
978
+ handler && handler(self, recipient);
979
+ },
980
+ [MESSAGE.CHANNEL_CLOSE]: (self, payload) => {
981
+ /*
982
+ byte SSH_MSG_CHANNEL_CLOSE
983
+ uint32 recipient channel
984
+ */
985
+ bufferParser.init(payload, 1);
986
+ const recipient = bufferParser.readUInt32BE();
987
+ bufferParser.clear();
988
+
989
+ if (recipient === undefined) {
990
+ return doFatalError(
991
+ self,
992
+ 'Inbound: Malformed CHANNEL_CLOSE packet'
993
+ );
994
+ }
995
+
996
+ self._debug && self._debug(`Inbound: CHANNEL_CLOSE (r:${recipient})`);
997
+
998
+ const handler = self._handlers.CHANNEL_CLOSE;
999
+ handler && handler(self, recipient);
1000
+ },
1001
+ [MESSAGE.CHANNEL_REQUEST]: (self, payload) => {
1002
+ /*
1003
+ byte SSH_MSG_CHANNEL_REQUEST
1004
+ uint32 recipient channel
1005
+ string request type in US-ASCII characters only
1006
+ boolean want reply
1007
+ .... type-specific data follows
1008
+ */
1009
+ bufferParser.init(payload, 1);
1010
+ const recipient = bufferParser.readUInt32BE();
1011
+ const type = bufferParser.readString(true);
1012
+ const wantReply = bufferParser.readBool();
1013
+ let data;
1014
+ if (wantReply !== undefined) {
1015
+ switch (type) {
1016
+ case 'exit-status': // S->C
1017
+ /*
1018
+ uint32 exit_status
1019
+ */
1020
+ data = bufferParser.readUInt32BE();
1021
+ self._debug && self._debug(
1022
+ `Inbound: CHANNEL_REQUEST (r:${recipient}, ${type}: ${data})`
1023
+ );
1024
+ break;
1025
+ case 'exit-signal': { // S->C
1026
+ /*
1027
+ string signal name (without the "SIG" prefix)
1028
+ boolean core dumped
1029
+ string error message in ISO-10646 UTF-8 encoding
1030
+ string language tag
1031
+ */
1032
+ let signal;
1033
+ let coreDumped;
1034
+ if (self._compatFlags & COMPAT.OLD_EXIT) {
1035
+ /*
1036
+ Instead of `signal name` and `core dumped`, we have just:
1037
+ uint32 signal number
1038
+ */
1039
+ const num = bufferParser.readUInt32BE();
1040
+ switch (num) {
1041
+ case 1:
1042
+ signal = 'HUP';
1043
+ break;
1044
+ case 2:
1045
+ signal = 'INT';
1046
+ break;
1047
+ case 3:
1048
+ signal = 'QUIT';
1049
+ break;
1050
+ case 6:
1051
+ signal = 'ABRT';
1052
+ break;
1053
+ case 9:
1054
+ signal = 'KILL';
1055
+ break;
1056
+ case 14:
1057
+ signal = 'ALRM';
1058
+ break;
1059
+ case 15:
1060
+ signal = 'TERM';
1061
+ break;
1062
+ default:
1063
+ if (num !== undefined) {
1064
+ // Unknown or OS-specific
1065
+ signal = `UNKNOWN (${num})`;
1066
+ }
1067
+ }
1068
+ coreDumped = false;
1069
+ } else {
1070
+ signal = bufferParser.readString(true);
1071
+ coreDumped = bufferParser.readBool();
1072
+ if (coreDumped === undefined)
1073
+ signal = undefined;
1074
+ }
1075
+ const errorMessage = bufferParser.readString(true);
1076
+ if (bufferParser.skipString() !== undefined)
1077
+ data = { signal, coreDumped, errorMessage };
1078
+ self._debug && self._debug(
1079
+ `Inbound: CHANNEL_REQUEST (r:${recipient}, ${type}: ${signal})`
1080
+ );
1081
+ break;
1082
+ }
1083
+ case 'pty-req': { // C->S
1084
+ /*
1085
+ string TERM environment variable value (e.g., vt100)
1086
+ uint32 terminal width, characters (e.g., 80)
1087
+ uint32 terminal height, rows (e.g., 24)
1088
+ uint32 terminal width, pixels (e.g., 640)
1089
+ uint32 terminal height, pixels (e.g., 480)
1090
+ string encoded terminal modes
1091
+ */
1092
+ const term = bufferParser.readString(true);
1093
+ const cols = bufferParser.readUInt32BE();
1094
+ const rows = bufferParser.readUInt32BE();
1095
+ const width = bufferParser.readUInt32BE();
1096
+ const height = bufferParser.readUInt32BE();
1097
+ const modesBinary = bufferParser.readString();
1098
+ if (modesBinary !== undefined) {
1099
+ bufferParser.init(modesBinary, 1);
1100
+ let modes = {};
1101
+ while (bufferParser.avail()) {
1102
+ const opcode = bufferParser.readByte();
1103
+ if (opcode === TERMINAL_MODE.TTY_OP_END)
1104
+ break;
1105
+ const name = TERMINAL_MODE_BY_VALUE[opcode];
1106
+ const value = bufferParser.readUInt32BE();
1107
+ if (opcode === undefined
1108
+ || name === undefined
1109
+ || value === undefined) {
1110
+ modes = undefined;
1111
+ break;
1112
+ }
1113
+ modes[name] = value;
1114
+ }
1115
+ if (modes !== undefined)
1116
+ data = { term, cols, rows, width, height, modes };
1117
+ }
1118
+ self._debug && self._debug(
1119
+ `Inbound: CHANNEL_REQUEST (r:${recipient}, ${type})`
1120
+ );
1121
+ break;
1122
+ }
1123
+ case 'window-change': { // C->S
1124
+ /*
1125
+ uint32 terminal width, columns
1126
+ uint32 terminal height, rows
1127
+ uint32 terminal width, pixels
1128
+ uint32 terminal height, pixels
1129
+ */
1130
+ const cols = bufferParser.readUInt32BE();
1131
+ const rows = bufferParser.readUInt32BE();
1132
+ const width = bufferParser.readUInt32BE();
1133
+ const height = bufferParser.readUInt32BE();
1134
+ if (height !== undefined)
1135
+ data = { cols, rows, width, height };
1136
+ self._debug && self._debug(
1137
+ `Inbound: CHANNEL_REQUEST (r:${recipient}, ${type})`
1138
+ );
1139
+ break;
1140
+ }
1141
+ case 'x11-req': { // C->S
1142
+ /*
1143
+ boolean single connection
1144
+ string x11 authentication protocol
1145
+ string x11 authentication cookie
1146
+ uint32 x11 screen number
1147
+ */
1148
+ const single = bufferParser.readBool();
1149
+ const protocol = bufferParser.readString(true);
1150
+ const cookie = bufferParser.readString();
1151
+ const screen = bufferParser.readUInt32BE();
1152
+ if (screen !== undefined)
1153
+ data = { single, protocol, cookie, screen };
1154
+ self._debug && self._debug(
1155
+ `Inbound: CHANNEL_REQUEST (r:${recipient}, ${type})`
1156
+ );
1157
+ break;
1158
+ }
1159
+ case 'env': { // C->S
1160
+ /*
1161
+ string variable name
1162
+ string variable value
1163
+ */
1164
+ const name = bufferParser.readString(true);
1165
+ const value = bufferParser.readString(true);
1166
+ if (value !== undefined)
1167
+ data = { name, value };
1168
+ if (self._debug) {
1169
+ self._debug(
1170
+ `Inbound: CHANNEL_REQUEST (r:${recipient}, ${type}: `
1171
+ + `${name}=${value})`
1172
+ );
1173
+ }
1174
+ break;
1175
+ }
1176
+ case 'shell': // C->S
1177
+ data = null; // No extra data
1178
+ self._debug && self._debug(
1179
+ `Inbound: CHANNEL_REQUEST (r:${recipient}, ${type})`
1180
+ );
1181
+ break;
1182
+ case 'exec': // C->S
1183
+ /*
1184
+ string command
1185
+ */
1186
+ data = bufferParser.readString(true);
1187
+ self._debug && self._debug(
1188
+ `Inbound: CHANNEL_REQUEST (r:${recipient}, ${type}: ${data})`
1189
+ );
1190
+ break;
1191
+ case 'subsystem': // C->S
1192
+ /*
1193
+ string subsystem name
1194
+ */
1195
+ data = bufferParser.readString(true);
1196
+ self._debug && self._debug(
1197
+ `Inbound: CHANNEL_REQUEST (r:${recipient}, ${type}: ${data})`
1198
+ );
1199
+ break;
1200
+ case 'signal': // C->S
1201
+ /*
1202
+ string signal name (without the "SIG" prefix)
1203
+ */
1204
+ data = bufferParser.readString(true);
1205
+ self._debug && self._debug(
1206
+ `Inbound: CHANNEL_REQUEST (r:${recipient}, ${type}: ${data})`
1207
+ );
1208
+ break;
1209
+ case 'xon-xoff': // C->S
1210
+ /*
1211
+ boolean client can do
1212
+ */
1213
+ data = bufferParser.readBool();
1214
+ self._debug && self._debug(
1215
+ `Inbound: CHANNEL_REQUEST (r:${recipient}, ${type}: ${data})`
1216
+ );
1217
+ break;
1218
+ case 'auth-agent-req@openssh.com': // C-S
1219
+ data = null; // No extra data
1220
+ self._debug && self._debug(
1221
+ `Inbound: CHANNEL_REQUEST (r:${recipient}, ${type})`
1222
+ );
1223
+ break;
1224
+ default:
1225
+ data = (bufferParser.avail() ? bufferParser.readRaw() : null);
1226
+ self._debug && self._debug(
1227
+ `Inbound: CHANNEL_REQUEST (r:${recipient}, ${type})`
1228
+ );
1229
+ }
1230
+ }
1231
+ bufferParser.clear();
1232
+
1233
+ if (data === undefined) {
1234
+ return doFatalError(
1235
+ self,
1236
+ 'Inbound: Malformed CHANNEL_REQUEST packet'
1237
+ );
1238
+ }
1239
+
1240
+ const handler = self._handlers.CHANNEL_REQUEST;
1241
+ handler && handler(self, recipient, type, wantReply, data);
1242
+ },
1243
+ [MESSAGE.CHANNEL_SUCCESS]: (self, payload) => {
1244
+ /*
1245
+ byte SSH_MSG_CHANNEL_SUCCESS
1246
+ uint32 recipient channel
1247
+ */
1248
+ bufferParser.init(payload, 1);
1249
+ const recipient = bufferParser.readUInt32BE();
1250
+ bufferParser.clear();
1251
+
1252
+ if (recipient === undefined) {
1253
+ return doFatalError(
1254
+ self,
1255
+ 'Inbound: Malformed CHANNEL_SUCCESS packet'
1256
+ );
1257
+ }
1258
+
1259
+ self._debug && self._debug(`Inbound: CHANNEL_SUCCESS (r:${recipient})`);
1260
+
1261
+ const handler = self._handlers.CHANNEL_SUCCESS;
1262
+ handler && handler(self, recipient);
1263
+ },
1264
+ [MESSAGE.CHANNEL_FAILURE]: (self, payload) => {
1265
+ /*
1266
+ byte SSH_MSG_CHANNEL_FAILURE
1267
+ uint32 recipient channel
1268
+ */
1269
+ bufferParser.init(payload, 1);
1270
+ const recipient = bufferParser.readUInt32BE();
1271
+ bufferParser.clear();
1272
+
1273
+ if (recipient === undefined) {
1274
+ return doFatalError(
1275
+ self,
1276
+ 'Inbound: Malformed CHANNEL_FAILURE packet'
1277
+ );
1278
+ }
1279
+
1280
+ self._debug && self._debug(`Inbound: CHANNEL_FAILURE (r:${recipient})`);
1281
+
1282
+ const handler = self._handlers.CHANNEL_FAILURE;
1283
+ handler && handler(self, recipient);
1284
+ },
1285
+ };