dsh-remote 0.8.46 → 0.8.47

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 (391) hide show
  1. package/LICENSE +21 -21
  2. package/README.en.md +361 -361
  3. package/README.md +368 -368
  4. package/cordis.patch.yml +9 -9
  5. package/lib/binding.js +172 -172
  6. package/lib/client.js +3637 -3637
  7. package/lib/credential.js +177 -177
  8. package/lib/deploy-tasks.js +142 -142
  9. package/lib/errors.js +87 -87
  10. package/lib/file-reference.js +457 -457
  11. package/lib/forwards.js +258 -258
  12. package/lib/hostkey.js +108 -108
  13. package/lib/http-transport.js +196 -196
  14. package/lib/ignore.js +156 -156
  15. package/lib/index.js +3771 -3747
  16. package/lib/openssh.js +838 -838
  17. package/lib/paths.js +225 -225
  18. package/lib/pool.js +757 -757
  19. package/lib/registry.js +95 -95
  20. package/lib/remote-fs.js +148 -143
  21. package/lib/routes-fs.js +233 -233
  22. package/lib/search.js +230 -230
  23. package/lib/sftp-surface.js +76 -76
  24. package/lib/sshconfig.js +454 -454
  25. package/lib/sync.js +275 -275
  26. package/lib/tasks.js +95 -95
  27. package/lib/telemetry.js +213 -213
  28. package/lib/update.js +472 -472
  29. package/lib/web-attach.js +850 -850
  30. package/lib/web-deploy-skill.js +205 -205
  31. package/lib/web-deploy.js +694 -694
  32. package/node_modules/asn1/Jenkinsfile +65 -0
  33. package/node_modules/asn1/LICENSE +19 -0
  34. package/node_modules/asn1/README.md +50 -0
  35. package/node_modules/asn1/lib/ber/errors.js +13 -0
  36. package/node_modules/asn1/lib/ber/index.js +27 -0
  37. package/node_modules/asn1/lib/ber/reader.js +262 -0
  38. package/node_modules/asn1/lib/ber/types.js +36 -0
  39. package/node_modules/asn1/lib/ber/writer.js +317 -0
  40. package/node_modules/asn1/lib/index.js +20 -0
  41. package/node_modules/asn1/package.json +31 -0
  42. package/node_modules/bcrypt-pbkdf/CONTRIBUTING.md +13 -0
  43. package/node_modules/bcrypt-pbkdf/LICENSE +66 -0
  44. package/node_modules/bcrypt-pbkdf/README.md +45 -0
  45. package/node_modules/bcrypt-pbkdf/index.js +556 -0
  46. package/node_modules/bcrypt-pbkdf/package.json +15 -0
  47. package/node_modules/buildcheck/.eslintrc.js +5 -0
  48. package/node_modules/buildcheck/.github/workflows/ci.yml +88 -0
  49. package/node_modules/buildcheck/.github/workflows/lint.yml +27 -0
  50. package/node_modules/buildcheck/.npmignore +3 -0
  51. package/node_modules/buildcheck/LICENSE +19 -0
  52. package/node_modules/buildcheck/README.md +106 -0
  53. package/node_modules/buildcheck/deps/Find-VisualStudio.cs +250 -0
  54. package/node_modules/buildcheck/lib/findvs.js +361 -0
  55. package/node_modules/buildcheck/lib/index.js +738 -0
  56. package/node_modules/buildcheck/package.json +36 -0
  57. package/node_modules/buildcheck/test/test.js +8 -0
  58. package/node_modules/cpu-features/.eslintrc.js +5 -0
  59. package/node_modules/cpu-features/.github/workflows/ci.yml +74 -0
  60. package/node_modules/cpu-features/.github/workflows/lint.yml +27 -0
  61. package/node_modules/cpu-features/LICENSE +19 -0
  62. package/node_modules/cpu-features/README.md +59 -0
  63. package/node_modules/cpu-features/binding.gyp +16 -0
  64. package/node_modules/cpu-features/buildcheck.js +32 -0
  65. package/node_modules/cpu-features/deps/cpu_features/.clang-format +4 -0
  66. package/node_modules/cpu-features/deps/cpu_features/.dockerignore +31 -0
  67. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/Dockerfile +5 -0
  68. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/aarch64_linux_cmake.yml +30 -0
  69. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/amd64_freebsd_cmake.yml +22 -0
  70. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/amd64_linux_bazel.yml +26 -0
  71. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/amd64_linux_cmake.yml +31 -0
  72. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/amd64_macos_cmake.yml +43 -0
  73. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/amd64_windows_cmake.yml +25 -0
  74. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/arm_linux_cmake.yml +31 -0
  75. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/clang_format.yml +24 -0
  76. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/mips_linux_cmake.yml +30 -0
  77. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/power_linux_cmake.yml +29 -0
  78. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/riscv_linux_cmake.yml +28 -0
  79. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/s390x_linux_cmake.yml +27 -0
  80. package/node_modules/cpu-features/deps/cpu_features/.grenrc.yml +21 -0
  81. package/node_modules/cpu-features/deps/cpu_features/BUILD.bazel +329 -0
  82. package/node_modules/cpu-features/deps/cpu_features/CMakeLists.txt +261 -0
  83. package/node_modules/cpu-features/deps/cpu_features/CONTRIBUTING.md +23 -0
  84. package/node_modules/cpu-features/deps/cpu_features/LICENSE +230 -0
  85. package/node_modules/cpu-features/deps/cpu_features/README.md +272 -0
  86. package/node_modules/cpu-features/deps/cpu_features/WORKSPACE +19 -0
  87. package/node_modules/cpu-features/deps/cpu_features/bazel/ci/README.md +5 -0
  88. package/node_modules/cpu-features/deps/cpu_features/bazel/platforms.bzl +11 -0
  89. package/node_modules/cpu-features/deps/cpu_features/cmake/CpuFeaturesConfig.cmake.in +3 -0
  90. package/node_modules/cpu-features/deps/cpu_features/cmake/CpuFeaturesNdkCompatConfig.cmake.in +3 -0
  91. package/node_modules/cpu-features/deps/cpu_features/cmake/README.md +30 -0
  92. package/node_modules/cpu-features/deps/cpu_features/cmake/ci/Makefile +252 -0
  93. package/node_modules/cpu-features/deps/cpu_features/cmake/ci/README.md +40 -0
  94. package/node_modules/cpu-features/deps/cpu_features/cmake/ci/doc/docker.dot +64 -0
  95. package/node_modules/cpu-features/deps/cpu_features/cmake/ci/doc/docker.svg +312 -0
  96. package/node_modules/cpu-features/deps/cpu_features/cmake/ci/doc/generate_image.sh +7 -0
  97. package/node_modules/cpu-features/deps/cpu_features/cmake/ci/docker/amd64/Dockerfile +48 -0
  98. package/node_modules/cpu-features/deps/cpu_features/cmake/ci/docker/toolchain/Dockerfile +34 -0
  99. package/node_modules/cpu-features/deps/cpu_features/cmake/ci/sample/CMakeLists.txt +22 -0
  100. package/node_modules/cpu-features/deps/cpu_features/cmake/ci/sample/main.cpp +11 -0
  101. package/node_modules/cpu-features/deps/cpu_features/cmake/ci/vagrant/freebsd/Vagrantfile +107 -0
  102. package/node_modules/cpu-features/deps/cpu_features/cmake/googletest.CMakeLists.txt.in +15 -0
  103. package/node_modules/cpu-features/deps/cpu_features/cpu_features.gyp +105 -0
  104. package/node_modules/cpu-features/deps/cpu_features/include/cpu_features_cache_info.h +54 -0
  105. package/node_modules/cpu-features/deps/cpu_features/include/cpu_features_macros.h +384 -0
  106. package/node_modules/cpu-features/deps/cpu_features/include/cpuinfo_aarch64.h +259 -0
  107. package/node_modules/cpu-features/deps/cpu_features/include/cpuinfo_arm.h +121 -0
  108. package/node_modules/cpu-features/deps/cpu_features/include/cpuinfo_mips.h +74 -0
  109. package/node_modules/cpu-features/deps/cpu_features/include/cpuinfo_ppc.h +149 -0
  110. package/node_modules/cpu-features/deps/cpu_features/include/cpuinfo_riscv.h +72 -0
  111. package/node_modules/cpu-features/deps/cpu_features/include/cpuinfo_s390x.h +108 -0
  112. package/node_modules/cpu-features/deps/cpu_features/include/cpuinfo_x86.h +288 -0
  113. package/node_modules/cpu-features/deps/cpu_features/include/internal/bit_utils.h +40 -0
  114. package/node_modules/cpu-features/deps/cpu_features/include/internal/cpuid_x86.h +37 -0
  115. package/node_modules/cpu-features/deps/cpu_features/include/internal/filesystem.h +39 -0
  116. package/node_modules/cpu-features/deps/cpu_features/include/internal/hwcaps.h +240 -0
  117. package/node_modules/cpu-features/deps/cpu_features/include/internal/stack_line_reader.h +49 -0
  118. package/node_modules/cpu-features/deps/cpu_features/include/internal/string_view.h +110 -0
  119. package/node_modules/cpu-features/deps/cpu_features/include/internal/windows_utils.h +70 -0
  120. package/node_modules/cpu-features/deps/cpu_features/ndk_compat/CMakeLists.txt +60 -0
  121. package/node_modules/cpu-features/deps/cpu_features/ndk_compat/README.md +4 -0
  122. package/node_modules/cpu-features/deps/cpu_features/ndk_compat/cpu-features.c +205 -0
  123. package/node_modules/cpu-features/deps/cpu_features/ndk_compat/cpu-features.h +320 -0
  124. package/node_modules/cpu-features/deps/cpu_features/ndk_compat/ndk-compat-test.c +12 -0
  125. package/node_modules/cpu-features/deps/cpu_features/patches/0001-Add-Apple-Silicon-Support.patch +456 -0
  126. package/node_modules/cpu-features/deps/cpu_features/scripts/generate_badges.d +165 -0
  127. package/node_modules/cpu-features/deps/cpu_features/scripts/make_release.sh +75 -0
  128. package/node_modules/cpu-features/deps/cpu_features/scripts/run_integration.sh +490 -0
  129. package/node_modules/cpu-features/deps/cpu_features/scripts/test_integration.sh +79 -0
  130. package/node_modules/cpu-features/deps/cpu_features/src/copy.inl +19 -0
  131. package/node_modules/cpu-features/deps/cpu_features/src/define_introspection.inl +86 -0
  132. package/node_modules/cpu-features/deps/cpu_features/src/define_introspection_and_hwcaps.inl +26 -0
  133. package/node_modules/cpu-features/deps/cpu_features/src/equals.inl +22 -0
  134. package/node_modules/cpu-features/deps/cpu_features/src/filesystem.c +62 -0
  135. package/node_modules/cpu-features/deps/cpu_features/src/hwcaps.c +169 -0
  136. package/node_modules/cpu-features/deps/cpu_features/src/impl_aarch64__base_implementation.inl +88 -0
  137. package/node_modules/cpu-features/deps/cpu_features/src/impl_aarch64_linux_or_android.c +79 -0
  138. package/node_modules/cpu-features/deps/cpu_features/src/impl_aarch64_macos_or_iphone.c +82 -0
  139. package/node_modules/cpu-features/deps/cpu_features/src/impl_aarch64_windows.c +138 -0
  140. package/node_modules/cpu-features/deps/cpu_features/src/impl_arm_linux_or_android.c +212 -0
  141. package/node_modules/cpu-features/deps/cpu_features/src/impl_mips_linux_or_android.c +93 -0
  142. package/node_modules/cpu-features/deps/cpu_features/src/impl_ppc_linux.c +163 -0
  143. package/node_modules/cpu-features/deps/cpu_features/src/impl_riscv_linux.c +111 -0
  144. package/node_modules/cpu-features/deps/cpu_features/src/impl_s390x_linux.c +120 -0
  145. package/node_modules/cpu-features/deps/cpu_features/src/impl_x86__base_implementation.inl +2055 -0
  146. package/node_modules/cpu-features/deps/cpu_features/src/impl_x86_freebsd.c +68 -0
  147. package/node_modules/cpu-features/deps/cpu_features/src/impl_x86_linux_or_android.c +58 -0
  148. package/node_modules/cpu-features/deps/cpu_features/src/impl_x86_macos.c +57 -0
  149. package/node_modules/cpu-features/deps/cpu_features/src/impl_x86_windows.c +58 -0
  150. package/node_modules/cpu-features/deps/cpu_features/src/stack_line_reader.c +132 -0
  151. package/node_modules/cpu-features/deps/cpu_features/src/string_view.c +192 -0
  152. package/node_modules/cpu-features/deps/cpu_features/src/utils/list_cpu_features.c +461 -0
  153. package/node_modules/cpu-features/deps/cpu_features/test/CMakeLists.txt +114 -0
  154. package/node_modules/cpu-features/deps/cpu_features/test/bit_utils_test.cc +53 -0
  155. package/node_modules/cpu-features/deps/cpu_features/test/cpuinfo_aarch64_test.cc +396 -0
  156. package/node_modules/cpu-features/deps/cpu_features/test/cpuinfo_arm_test.cc +384 -0
  157. package/node_modules/cpu-features/deps/cpu_features/test/cpuinfo_mips_test.cc +176 -0
  158. package/node_modules/cpu-features/deps/cpu_features/test/cpuinfo_ppc_test.cc +131 -0
  159. package/node_modules/cpu-features/deps/cpu_features/test/cpuinfo_riscv_test.cc +180 -0
  160. package/node_modules/cpu-features/deps/cpu_features/test/cpuinfo_s390x_test.cc +82 -0
  161. package/node_modules/cpu-features/deps/cpu_features/test/cpuinfo_x86_test.cc +1729 -0
  162. package/node_modules/cpu-features/deps/cpu_features/test/filesystem_for_testing.cc +103 -0
  163. package/node_modules/cpu-features/deps/cpu_features/test/filesystem_for_testing.h +61 -0
  164. package/node_modules/cpu-features/deps/cpu_features/test/hwcaps_for_testing.cc +52 -0
  165. package/node_modules/cpu-features/deps/cpu_features/test/hwcaps_for_testing.h +31 -0
  166. package/node_modules/cpu-features/deps/cpu_features/test/stack_line_reader_test.cc +132 -0
  167. package/node_modules/cpu-features/deps/cpu_features/test/string_view_test.cc +202 -0
  168. package/node_modules/cpu-features/lib/index.js +5 -0
  169. package/node_modules/cpu-features/package.json +40 -0
  170. package/node_modules/cpu-features/src/binding.cc +151 -0
  171. package/node_modules/cpu-features/test/test.js +12 -0
  172. package/node_modules/nan/.github/workflows/ci.yml +46 -0
  173. package/node_modules/nan/.pre-commit-config.yaml +8 -0
  174. package/node_modules/nan/CHANGELOG.md +605 -0
  175. package/node_modules/nan/CMakeLists.txt +138 -0
  176. package/node_modules/nan/LICENSE.md +9 -0
  177. package/node_modules/nan/README.md +457 -0
  178. package/node_modules/nan/doc/asyncworker.md +146 -0
  179. package/node_modules/nan/doc/buffers.md +54 -0
  180. package/node_modules/nan/doc/callback.md +76 -0
  181. package/node_modules/nan/doc/converters.md +41 -0
  182. package/node_modules/nan/doc/errors.md +226 -0
  183. package/node_modules/nan/doc/json.md +62 -0
  184. package/node_modules/nan/doc/maybe_types.md +583 -0
  185. package/node_modules/nan/doc/methods.md +689 -0
  186. package/node_modules/nan/doc/new.md +147 -0
  187. package/node_modules/nan/doc/node_misc.md +123 -0
  188. package/node_modules/nan/doc/object_wrappers.md +263 -0
  189. package/node_modules/nan/doc/persistent.md +296 -0
  190. package/node_modules/nan/doc/scopes.md +73 -0
  191. package/node_modules/nan/doc/script.md +58 -0
  192. package/node_modules/nan/doc/string_bytes.md +81 -0
  193. package/node_modules/nan/doc/v8_internals.md +211 -0
  194. package/node_modules/nan/doc/v8_misc.md +85 -0
  195. package/node_modules/nan/include_dirs.js +1 -0
  196. package/node_modules/nan/nan.h +3202 -0
  197. package/node_modules/nan/nan_callbacks.h +141 -0
  198. package/node_modules/nan/nan_callbacks_12_inl.h +730 -0
  199. package/node_modules/nan/nan_callbacks_pre_12_inl.h +528 -0
  200. package/node_modules/nan/nan_converters.h +72 -0
  201. package/node_modules/nan/nan_converters_43_inl.h +68 -0
  202. package/node_modules/nan/nan_converters_pre_43_inl.h +42 -0
  203. package/node_modules/nan/nan_define_own_property_helper.h +29 -0
  204. package/node_modules/nan/nan_implementation_12_inl.h +446 -0
  205. package/node_modules/nan/nan_implementation_pre_12_inl.h +263 -0
  206. package/node_modules/nan/nan_json.h +166 -0
  207. package/node_modules/nan/nan_maybe_43_inl.h +360 -0
  208. package/node_modules/nan/nan_maybe_pre_43_inl.h +268 -0
  209. package/node_modules/nan/nan_new.h +340 -0
  210. package/node_modules/nan/nan_object_wrap.h +156 -0
  211. package/node_modules/nan/nan_persistent_12_inl.h +132 -0
  212. package/node_modules/nan/nan_persistent_pre_12_inl.h +242 -0
  213. package/node_modules/nan/nan_private.h +73 -0
  214. package/node_modules/nan/nan_scriptorigin.h +97 -0
  215. package/node_modules/nan/nan_string_bytes.h +305 -0
  216. package/node_modules/nan/nan_typedarray_contents.h +96 -0
  217. package/node_modules/nan/nan_weak.h +453 -0
  218. package/node_modules/nan/package.json +38 -0
  219. package/node_modules/nan/tools/1to2.js +412 -0
  220. package/node_modules/nan/tools/README.md +14 -0
  221. package/node_modules/nan/tools/package.json +19 -0
  222. package/node_modules/safer-buffer/LICENSE +21 -0
  223. package/node_modules/safer-buffer/Porting-Buffer.md +268 -0
  224. package/node_modules/safer-buffer/Readme.md +156 -0
  225. package/node_modules/safer-buffer/dangerous.js +58 -0
  226. package/node_modules/safer-buffer/package.json +34 -0
  227. package/node_modules/safer-buffer/safer.js +77 -0
  228. package/node_modules/safer-buffer/tests.js +406 -0
  229. package/node_modules/ssh2/.eslintignore +4 -0
  230. package/node_modules/ssh2/.eslintrc.js +5 -0
  231. package/node_modules/ssh2/.github/workflows/ci.yml +110 -0
  232. package/node_modules/ssh2/.github/workflows/lint.yml +27 -0
  233. package/node_modules/ssh2/LICENSE +19 -0
  234. package/node_modules/ssh2/README.md +1529 -0
  235. package/node_modules/ssh2/SFTP.md +413 -0
  236. package/node_modules/ssh2/examples/server-chat.js +238 -0
  237. package/node_modules/ssh2/examples/sftp-server-download-only.js +134 -0
  238. package/node_modules/ssh2/install.js +27 -0
  239. package/node_modules/ssh2/lib/Channel.js +295 -0
  240. package/node_modules/ssh2/lib/agent.js +1123 -0
  241. package/node_modules/ssh2/lib/client.js +2176 -0
  242. package/node_modules/ssh2/lib/http-agents.js +84 -0
  243. package/node_modules/ssh2/lib/index.js +44 -0
  244. package/node_modules/ssh2/lib/keygen.js +582 -0
  245. package/node_modules/ssh2/lib/protocol/Protocol.js +2136 -0
  246. package/node_modules/ssh2/lib/protocol/SFTP.js +4052 -0
  247. package/node_modules/ssh2/lib/protocol/constants.js +356 -0
  248. package/node_modules/ssh2/lib/protocol/crypto/binding.gyp +23 -0
  249. package/node_modules/ssh2/lib/protocol/crypto/poly1305.js +43 -0
  250. package/node_modules/ssh2/lib/protocol/crypto/src/binding.cc +2300 -0
  251. package/node_modules/ssh2/lib/protocol/crypto.js +1602 -0
  252. package/node_modules/ssh2/lib/protocol/handlers.js +16 -0
  253. package/node_modules/ssh2/lib/protocol/handlers.misc.js +1285 -0
  254. package/node_modules/ssh2/lib/protocol/kex.js +1908 -0
  255. package/node_modules/ssh2/lib/protocol/keyParser.js +1484 -0
  256. package/node_modules/ssh2/lib/protocol/node-fs-compat.js +115 -0
  257. package/node_modules/ssh2/lib/protocol/utils.js +356 -0
  258. package/node_modules/ssh2/lib/protocol/zlib.js +255 -0
  259. package/node_modules/ssh2/lib/server.js +1380 -0
  260. package/node_modules/ssh2/lib/utils.js +336 -0
  261. package/node_modules/ssh2/package.json +49 -0
  262. package/node_modules/ssh2/test/common.js +316 -0
  263. package/node_modules/ssh2/test/fixtures/bad_rsa_private_key +26 -0
  264. package/node_modules/ssh2/test/fixtures/https_cert.pem +33 -0
  265. package/node_modules/ssh2/test/fixtures/https_key.pem +52 -0
  266. package/node_modules/ssh2/test/fixtures/id_dsa +12 -0
  267. package/node_modules/ssh2/test/fixtures/id_ecdsa +5 -0
  268. package/node_modules/ssh2/test/fixtures/id_rsa +15 -0
  269. package/node_modules/ssh2/test/fixtures/id_rsa.ppk +26 -0
  270. package/node_modules/ssh2/test/fixtures/id_rsa_enc +30 -0
  271. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa +21 -0
  272. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa.pub +1 -0
  273. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa.pub.result +7 -0
  274. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa.result +7 -0
  275. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc +22 -0
  276. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc.pub +1 -0
  277. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc.pub.result +7 -0
  278. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc.result +7 -0
  279. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc_gcm +23 -0
  280. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc_gcm.pub +1 -0
  281. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc_gcm.pub.result +7 -0
  282. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc_gcm.result +7 -0
  283. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa +9 -0
  284. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa.pub +1 -0
  285. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa.pub.result +7 -0
  286. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa.result +7 -0
  287. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc +10 -0
  288. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc.pub +1 -0
  289. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc.pub.result +8 -0
  290. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc.result +7 -0
  291. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc_gcm +10 -0
  292. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc_gcm.pub +1 -0
  293. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc_gcm.pub.result +8 -0
  294. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc_gcm.result +7 -0
  295. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ed25519 +7 -0
  296. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ed25519.pub +1 -0
  297. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ed25519.pub.result +7 -0
  298. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ed25519.result +7 -0
  299. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa +27 -0
  300. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa.pub +1 -0
  301. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa.pub.result +7 -0
  302. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa.result +7 -0
  303. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc +28 -0
  304. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc.pub +1 -0
  305. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc.pub.result +8 -0
  306. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc.result +7 -0
  307. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc_gcm +29 -0
  308. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc_gcm.pub +1 -0
  309. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc_gcm.pub.result +8 -0
  310. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc_gcm.result +7 -0
  311. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa +12 -0
  312. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa.pub +1 -0
  313. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa.pub.result +7 -0
  314. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa.result +7 -0
  315. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa_enc +15 -0
  316. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa_enc.pub +1 -0
  317. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa_enc.pub.result +8 -0
  318. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa_enc.result +7 -0
  319. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa +5 -0
  320. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa.pub +1 -0
  321. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa.pub.result +7 -0
  322. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa.result +7 -0
  323. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa_enc +8 -0
  324. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa_enc.pub +1 -0
  325. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa_enc.pub.result +8 -0
  326. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa_enc.result +7 -0
  327. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa +27 -0
  328. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa.pub +1 -0
  329. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa.pub.result +7 -0
  330. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa.result +7 -0
  331. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc +30 -0
  332. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc.pub +1 -0
  333. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc.pub.result +8 -0
  334. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc.result +7 -0
  335. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc_aes256 +54 -0
  336. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc_aes256.pub +1 -0
  337. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc_aes256.pub.result +6 -0
  338. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc_aes256.result +6 -0
  339. package/node_modules/ssh2/test/fixtures/keyParser/ppk_dsa_enc +17 -0
  340. package/node_modules/ssh2/test/fixtures/keyParser/ppk_dsa_enc.result +7 -0
  341. package/node_modules/ssh2/test/fixtures/keyParser/ppk_rsa +26 -0
  342. package/node_modules/ssh2/test/fixtures/keyParser/ppk_rsa.result +7 -0
  343. package/node_modules/ssh2/test/fixtures/keyParser/ppk_rsa_enc +18 -0
  344. package/node_modules/ssh2/test/fixtures/keyParser/ppk_rsa_enc.result +7 -0
  345. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa.pub +9 -0
  346. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa.pub.result +7 -0
  347. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa2.pub +10 -0
  348. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa2.pub.result +7 -0
  349. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa3.pub +11 -0
  350. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa3.pub.result +7 -0
  351. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa4.pub +11 -0
  352. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa4.pub.result +7 -0
  353. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa5.pub +8 -0
  354. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa5.pub.result +7 -0
  355. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa6.pub +13 -0
  356. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa6.pub.result +7 -0
  357. package/node_modules/ssh2/test/fixtures/openssh_new_rsa +27 -0
  358. package/node_modules/ssh2/test/fixtures/ssh_host_dsa_key +12 -0
  359. package/node_modules/ssh2/test/fixtures/ssh_host_ecdsa_key +5 -0
  360. package/node_modules/ssh2/test/fixtures/ssh_host_rsa_key +15 -0
  361. package/node_modules/ssh2/test/test-exec.js +578 -0
  362. package/node_modules/ssh2/test/test-integration-openssh.js +486 -0
  363. package/node_modules/ssh2/test/test-keygen.js +60 -0
  364. package/node_modules/ssh2/test/test-misc-client-server.js +1460 -0
  365. package/node_modules/ssh2/test/test-openssh.js +261 -0
  366. package/node_modules/ssh2/test/test-protocol-crypto.js +631 -0
  367. package/node_modules/ssh2/test/test-protocol-keyparser.js +177 -0
  368. package/node_modules/ssh2/test/test-server-hostkeys.js +138 -0
  369. package/node_modules/ssh2/test/test-sftp.js +842 -0
  370. package/node_modules/ssh2/test/test-shell.js +109 -0
  371. package/node_modules/ssh2/test/test-userauth-agent-openssh.js +110 -0
  372. package/node_modules/ssh2/test/test-userauth-agent.js +171 -0
  373. package/node_modules/ssh2/test/test-userauth.js +611 -0
  374. package/node_modules/ssh2/test/test-worker-imports.js +25 -0
  375. package/node_modules/ssh2/test/test.js +20 -0
  376. package/node_modules/ssh2/util/build_pagent.bat +2 -0
  377. package/node_modules/ssh2/util/pagent.c +88 -0
  378. package/node_modules/ssh2/util/pagent.exe +0 -0
  379. package/node_modules/tweetnacl/.npmignore +4 -0
  380. package/node_modules/tweetnacl/AUTHORS.md +28 -0
  381. package/node_modules/tweetnacl/CHANGELOG.md +221 -0
  382. package/node_modules/tweetnacl/LICENSE +24 -0
  383. package/node_modules/tweetnacl/PULL_REQUEST_TEMPLATE.md +20 -0
  384. package/node_modules/tweetnacl/README.md +459 -0
  385. package/node_modules/tweetnacl/nacl-fast.js +2388 -0
  386. package/node_modules/tweetnacl/nacl-fast.min.js +2 -0
  387. package/node_modules/tweetnacl/nacl.d.ts +98 -0
  388. package/node_modules/tweetnacl/nacl.js +1175 -0
  389. package/node_modules/tweetnacl/nacl.min.js +1 -0
  390. package/node_modules/tweetnacl/package.json +58 -0
  391. package/package.json +95 -89
@@ -0,0 +1,1460 @@
1
+ 'use strict';
2
+
3
+ const assert = require('assert');
4
+ const { createHash } = require('crypto');
5
+ const http = require('http');
6
+ const https = require('https');
7
+ const net = require('net');
8
+ const { Transform } = require('stream');
9
+ const { inspect } = require('util');
10
+
11
+ const Client = require('../lib/client.js');
12
+ const {
13
+ SSHTTPAgent: HTTPAgent,
14
+ SSHTTPSAgent: HTTPSAgent,
15
+ } = require('../lib/http-agents.js');
16
+ const Server = require('../lib/server.js');
17
+ const { KexInit } = require('../lib/protocol/kex.js');
18
+
19
+ const {
20
+ fixture,
21
+ mustCall,
22
+ mustCallAtLeast,
23
+ mustNotCall,
24
+ setup: setup_,
25
+ setupSimple,
26
+ } = require('./common.js');
27
+
28
+ const KEY_RSA_BAD = fixture('bad_rsa_private_key');
29
+ const HOST_RSA_MD5 = '64254520742d3d0792e918f3ce945a64';
30
+ const clientCfg = { username: 'foo', password: 'bar' };
31
+ const serverCfg = { hostKeys: [ fixture('ssh_host_rsa_key') ] };
32
+
33
+ const debug = false;
34
+
35
+ const setup = setupSimple.bind(undefined, debug);
36
+
37
+
38
+ {
39
+ const { server } = setup_(
40
+ 'Verify host fingerprint (sync success, hostHash set)',
41
+ {
42
+ client: {
43
+ ...clientCfg,
44
+ hostHash: 'md5',
45
+ hostVerifier: mustCall((hash) => {
46
+ assert(hash === HOST_RSA_MD5, 'Host fingerprint mismatch');
47
+ return true;
48
+ }),
49
+ },
50
+ server: serverCfg,
51
+ },
52
+ );
53
+
54
+ server.on('connection', mustCall((conn) => {
55
+ conn.on('authentication', mustCall((ctx) => {
56
+ ctx.accept();
57
+ })).on('ready', mustCall(() => {
58
+ conn.end();
59
+ }));
60
+ }));
61
+ }
62
+
63
+ {
64
+ const { server } = setup_(
65
+ 'Verify host fingerprint (sync success, hostHash not set)',
66
+ {
67
+ client: {
68
+ ...clientCfg,
69
+ hostVerifier: mustCall((key) => {
70
+ assert(Buffer.isBuffer(key), 'Expected buffer');
71
+ let hash = createHash('md5');
72
+ hash.update(key);
73
+ hash = hash.digest('hex');
74
+ assert(hash === HOST_RSA_MD5, 'Host fingerprint mismatch');
75
+ return true;
76
+ }),
77
+ },
78
+ server: serverCfg,
79
+ }
80
+ );
81
+
82
+ server.on('connection', mustCall((conn) => {
83
+ conn.on('authentication', mustCall((ctx) => {
84
+ ctx.accept();
85
+ })).on('ready', mustCall(() => {
86
+ conn.end();
87
+ }));
88
+ }));
89
+ }
90
+
91
+ {
92
+ const { server } = setup_(
93
+ 'Verify host fingerprint (async success)',
94
+ {
95
+ client: {
96
+ ...clientCfg,
97
+ hostVerifier: mustCall((key, cb) => {
98
+ assert(Buffer.isBuffer(key), 'Expected buffer');
99
+ let hash = createHash('md5');
100
+ hash.update(key);
101
+ hash = hash.digest('hex');
102
+ assert(hash === HOST_RSA_MD5, 'Host fingerprint mismatch');
103
+ process.nextTick(cb, true);
104
+ }),
105
+ },
106
+ server: serverCfg,
107
+ }
108
+ );
109
+
110
+ server.on('connection', mustCall((conn) => {
111
+ conn.on('authentication', mustCall((ctx) => {
112
+ ctx.accept();
113
+ })).on('ready', mustCall(() => {
114
+ conn.end();
115
+ }));
116
+ }));
117
+ }
118
+
119
+ {
120
+ const { client, server } = setup_(
121
+ 'Verify host fingerprint (sync failure)',
122
+ {
123
+ client: {
124
+ ...clientCfg,
125
+ hostVerifier: mustCall((key) => {
126
+ return false;
127
+ }),
128
+ },
129
+ server: serverCfg,
130
+
131
+ noForceClientReady: true,
132
+ noForceServerReady: true,
133
+ },
134
+ );
135
+
136
+ client.removeAllListeners('error');
137
+ client.on('ready', mustNotCall())
138
+ .on('error', mustCall((err) => {
139
+ assert(/verification failed/.test(err.message),
140
+ 'Wrong client error message');
141
+ }));
142
+
143
+ server.on('connection', mustCall((conn) => {
144
+ conn.removeAllListeners('error');
145
+
146
+ conn.on('authentication', mustNotCall())
147
+ .on('ready', mustNotCall())
148
+ .on('error', mustCall((err) => {
149
+ assert(/KEY_EXCHANGE_FAILED/.test(err.message),
150
+ 'Wrong server error message');
151
+ }));
152
+ }));
153
+ }
154
+
155
+ {
156
+ // connect() on connected client
157
+
158
+ const clientCfg_ = { ...clientCfg };
159
+ const client = new Client();
160
+ const server = new Server(serverCfg);
161
+
162
+ server.listen(0, 'localhost', mustCall(() => {
163
+ clientCfg_.host = 'localhost';
164
+ clientCfg_.port = server.address().port;
165
+ client.connect(clientCfg_);
166
+ }));
167
+
168
+ let connections = 0;
169
+ server.on('connection', mustCall((conn) => {
170
+ if (++connections === 2)
171
+ server.close();
172
+ conn.on('authentication', mustCall((ctx) => {
173
+ ctx.accept();
174
+ })).on('ready', mustCall(() => {}));
175
+ }, 2)).on('close', mustCall(() => {}));
176
+
177
+ let reconnect = false;
178
+ client.on('ready', mustCall(() => {
179
+ if (reconnect) {
180
+ client.end();
181
+ } else {
182
+ reconnect = true;
183
+ client.connect(clientCfg_);
184
+ }
185
+ }, 2)).on('close', mustCall(() => {}, 2));
186
+ }
187
+
188
+ {
189
+ // Throw when not connected
190
+
191
+ const client = new Client({
192
+ username: 'foo',
193
+ password: 'bar',
194
+ });
195
+
196
+ assert.throws(mustCall(() => {
197
+ client.exec('uptime', mustNotCall());
198
+ }));
199
+ }
200
+
201
+ {
202
+ const { client, server } = setup(
203
+ 'Outstanding callbacks called on disconnect'
204
+ );
205
+
206
+ server.on('connection', mustCall((conn) => {
207
+ conn.on('session', mustCall(() => {}, 3));
208
+ }));
209
+
210
+ client.on('ready', mustCall(() => {
211
+ function callback(err, stream) {
212
+ assert(err, 'Expected error');
213
+ assert(err.message === 'No response from server',
214
+ `Wrong error message: ${err.message}`);
215
+ }
216
+ client.exec('uptime', mustCall(callback));
217
+ client.shell(mustCall(callback));
218
+ client.sftp(mustCall(callback));
219
+ client.end();
220
+ }));
221
+ }
222
+
223
+ {
224
+ const { client, server } = setup('Pipelined requests');
225
+
226
+ server.on('connection', mustCall((conn) => {
227
+ conn.on('ready', mustCall(() => {
228
+ conn.on('session', mustCall((accept, reject) => {
229
+ const session = accept();
230
+ session.on('exec', mustCall((accept, reject, info) => {
231
+ const stream = accept();
232
+ stream.exit(0);
233
+ stream.end();
234
+ }));
235
+ }, 3));
236
+ }));
237
+ }));
238
+
239
+ client.on('ready', mustCall(() => {
240
+ let calledBack = 0;
241
+ function callback(err, stream) {
242
+ assert(!err, `Unexpected error: ${err}`);
243
+ stream.resume();
244
+ if (++calledBack === 3)
245
+ client.end();
246
+ }
247
+ client.exec('foo', mustCall(callback));
248
+ client.exec('bar', mustCall(callback));
249
+ client.exec('baz', mustCall(callback));
250
+ }));
251
+ }
252
+
253
+ {
254
+ const { client, server } = setup(
255
+ 'Pipelined requests with intermediate rekeying'
256
+ );
257
+
258
+ server.on('connection', mustCall((conn) => {
259
+ conn.on('ready', mustCall(() => {
260
+ const reqs = [];
261
+ conn.on('session', mustCall((accept, reject) => {
262
+ if (reqs.length === 0) {
263
+ conn.rekey(mustCall((err) => {
264
+ assert(!err, `Unexpected rekey error: ${err}`);
265
+ reqs.forEach((accept) => {
266
+ const session = accept();
267
+ session.on('exec', mustCall((accept, reject, info) => {
268
+ const stream = accept();
269
+ stream.exit(0);
270
+ stream.end();
271
+ }));
272
+ });
273
+ }));
274
+ }
275
+ reqs.push(accept);
276
+ }, 3));
277
+ }));
278
+ }));
279
+
280
+ client.on('ready', mustCall(() => {
281
+ let calledBack = 0;
282
+ function callback(err, stream) {
283
+ assert(!err, `Unexpected error: ${err}`);
284
+ stream.resume();
285
+ if (++calledBack === 3)
286
+ client.end();
287
+ }
288
+ client.exec('foo', mustCall(callback));
289
+ client.exec('bar', mustCall(callback));
290
+ client.exec('baz', mustCall(callback));
291
+ }));
292
+ }
293
+
294
+ {
295
+ const { client, server } = setup('Ignore outgoing after stream close');
296
+
297
+ server.on('connection', mustCall((conn) => {
298
+ conn.on('ready', mustCall(() => {
299
+ conn.on('session', mustCall((accept, reject) => {
300
+ const session = accept();
301
+ session.on('exec', mustCall((accept, reject, info) => {
302
+ const stream = accept();
303
+ stream.exit(0);
304
+ stream.end();
305
+ }));
306
+ }));
307
+ }));
308
+ }));
309
+
310
+ client.on('ready', mustCall(() => {
311
+ client.exec('foo', mustCall((err, stream) => {
312
+ assert(!err, `Unexpected error: ${err}`);
313
+ stream.on('exit', mustCall((code, signal) => {
314
+ client.end();
315
+ }));
316
+ }));
317
+ }));
318
+ }
319
+
320
+ {
321
+ const { client, server } = setup_(
322
+ 'Double pipe on unconnected, passed in net.Socket',
323
+ {
324
+ client: {
325
+ ...clientCfg,
326
+ sock: new net.Socket(),
327
+ },
328
+ server: serverCfg,
329
+ },
330
+ );
331
+
332
+ server.on('connection', mustCall((conn) => {
333
+ conn.on('authentication', mustCall((ctx) => {
334
+ ctx.accept();
335
+ })).on('ready', mustCall(() => {}));
336
+ }));
337
+ client.on('ready', mustCall(() => {
338
+ client.end();
339
+ }));
340
+ }
341
+
342
+ {
343
+ const { client, server } = setup(
344
+ 'Client auto-rejects inbound connections to unknown bound address'
345
+ );
346
+
347
+ const assignedPort = 31337;
348
+
349
+ server.on('connection', mustCall((conn) => {
350
+ conn.on('ready', mustCall(() => {
351
+ conn.on('request', mustCall((accept, reject, name, info) => {
352
+ assert(name === 'tcpip-forward', 'Wrong request name');
353
+ assert.deepStrictEqual(
354
+ info,
355
+ { bindAddr: 'good', bindPort: 0 },
356
+ 'Wrong request info'
357
+ );
358
+ accept(assignedPort);
359
+ conn.forwardOut(info.bindAddr,
360
+ assignedPort,
361
+ 'remote',
362
+ 12345,
363
+ mustCall((err, ch) => {
364
+ assert(!err, `Unexpected error: ${err}`);
365
+ conn.forwardOut('bad',
366
+ assignedPort,
367
+ 'remote',
368
+ 12345,
369
+ mustCall((err, ch) => {
370
+ assert(err, 'Should receive error');
371
+ client.end();
372
+ }));
373
+ }));
374
+ }));
375
+ }));
376
+ }));
377
+
378
+ client.on('ready', mustCall(() => {
379
+ // request forwarding
380
+ client.forwardIn('good', 0, mustCall((err, port) => {
381
+ assert(!err, `Unexpected error: ${err}`);
382
+ assert(port === assignedPort, 'Wrong assigned port');
383
+ }));
384
+ })).on('tcp connection', mustCall((details, accept, reject) => {
385
+ assert.deepStrictEqual(
386
+ details,
387
+ { destIP: 'good',
388
+ destPort: assignedPort,
389
+ srcIP: 'remote',
390
+ srcPort: 12345
391
+ },
392
+ 'Wrong connection details'
393
+ );
394
+ accept();
395
+ }));
396
+ }
397
+
398
+ {
399
+ const { client, server } = setup(
400
+ 'Client auto-rejects inbound connections to unknown bound port'
401
+ );
402
+
403
+ const assignedPort = 31337;
404
+
405
+ server.on('connection', mustCall((conn) => {
406
+ conn.on('ready', mustCall(() => {
407
+ conn.on('request', mustCall((accept, reject, name, info) => {
408
+ assert(name === 'tcpip-forward', 'Wrong request name');
409
+ assert.deepStrictEqual(
410
+ info,
411
+ { bindAddr: 'good', bindPort: 0 },
412
+ 'Wrong request info'
413
+ );
414
+ accept(assignedPort);
415
+ conn.forwardOut(info.bindAddr,
416
+ assignedPort,
417
+ 'remote',
418
+ 12345,
419
+ mustCall((err, ch) => {
420
+ assert(!err, `Unexpected error: ${err}`);
421
+ conn.forwardOut(info.bindAddr,
422
+ 99999,
423
+ 'remote',
424
+ 12345,
425
+ mustCall((err, ch) => {
426
+ assert(err, 'Should receive error');
427
+ client.end();
428
+ }));
429
+ }));
430
+ }));
431
+ }));
432
+ }));
433
+
434
+ client.on('ready', mustCall(() => {
435
+ // request forwarding
436
+ client.forwardIn('good', 0, mustCall((err, port) => {
437
+ assert(!err, `Unexpected error: ${err}`);
438
+ assert(port === assignedPort, 'Wrong assigned port');
439
+ }));
440
+ })).on('tcp connection', mustCall((details, accept, reject) => {
441
+ assert.deepStrictEqual(
442
+ details,
443
+ { destIP: 'good',
444
+ destPort: assignedPort,
445
+ srcIP: 'remote',
446
+ srcPort: 12345
447
+ },
448
+ 'Wrong connection details'
449
+ );
450
+ accept();
451
+ }));
452
+ }
453
+
454
+ {
455
+ const GREETING = 'Hello world!';
456
+
457
+ const { client, server } = setup_(
458
+ 'Server greeting',
459
+ {
460
+ client: {
461
+ ...clientCfg,
462
+ ident: 'node.js rules',
463
+ },
464
+ server: {
465
+ ...serverCfg,
466
+ greeting: GREETING,
467
+ }
468
+ },
469
+ );
470
+
471
+ let sawGreeting = false;
472
+
473
+ server.on('connection', mustCall((conn, info) => {
474
+ assert.deepStrictEqual(info.header, {
475
+ identRaw: 'SSH-2.0-node.js rules',
476
+ greeting: '',
477
+ versions: {
478
+ protocol: '2.0',
479
+ software: 'node.js'
480
+ },
481
+ comments: 'rules'
482
+ });
483
+ conn.on('handshake', mustCall((details) => {
484
+ assert(sawGreeting, 'Client did not see greeting before handshake');
485
+ })).on('authentication', mustCall((ctx) => {
486
+ ctx.accept();
487
+ })).on('ready', mustCall(() => {
488
+ conn.end();
489
+ }));
490
+ }));
491
+
492
+ client.on('greeting', mustCall((greeting) => {
493
+ assert.strictEqual(greeting, `${GREETING}\r\n`);
494
+ sawGreeting = true;
495
+ })).on('banner', mustNotCall());
496
+ }
497
+
498
+ {
499
+ const { client, server } = setup_(
500
+ 'Correct ident parsing',
501
+ {
502
+ client: {
503
+ ...clientCfg,
504
+ ident: 'node.js rules\n',
505
+ },
506
+ server: serverCfg,
507
+
508
+ noServerError: true,
509
+ noClientError: true,
510
+ noForceServerReady: true,
511
+ noForceClientReady: true,
512
+ },
513
+ );
514
+
515
+ server.on('connection', mustCall((conn, info) => {
516
+ assert.deepStrictEqual(info.header, {
517
+ identRaw: 'SSH-2.0-node.js rules',
518
+ greeting: '',
519
+ versions: {
520
+ protocol: '2.0',
521
+ software: 'node.js'
522
+ },
523
+ comments: 'rules'
524
+ });
525
+ conn.once('error', mustCall((err) => {
526
+ assert(/bad packet length/i.test(err.message), 'Wrong error message');
527
+ }));
528
+ conn.on('handshake', mustNotCall())
529
+ .on('authentication', mustNotCall())
530
+ .on('ready', mustNotCall());
531
+ }));
532
+
533
+ client.on('greeting', mustNotCall())
534
+ .on('banner', mustNotCall())
535
+ .on('ready', mustNotCall());
536
+ }
537
+
538
+ {
539
+ const BANNER = 'Hello world!';
540
+
541
+ let authCb;
542
+ const { client, server } = setup_(
543
+ 'Server banner',
544
+ {
545
+ client: {
546
+ ...clientCfg,
547
+ // This test uses a custom auth handler to avoid a race condition where
548
+ // we don't get the complete banner packet before the default auth
549
+ // handler immediately sends the initial auth method
550
+ authHandler: (authsLeft, partialSuccess, cb) => {
551
+ authCb = cb;
552
+ },
553
+ },
554
+ server: {
555
+ ...serverCfg,
556
+ banner: BANNER,
557
+ }
558
+ },
559
+ );
560
+
561
+ let sawBanner = false;
562
+
563
+ server.on('connection', mustCall((conn) => {
564
+ conn.on('handshake', mustCall((details) => {
565
+ assert(!sawBanner, 'Client saw banner too early');
566
+ })).on('authentication', mustCall((ctx) => {
567
+ assert(sawBanner, 'Client did not see banner before auth');
568
+ ctx.accept();
569
+ })).on('ready', mustCall(() => {
570
+ conn.end();
571
+ }));
572
+ }));
573
+
574
+ client.on('greeting', mustNotCall())
575
+ .on('banner', mustCall((message) => {
576
+ assert.strictEqual(message, 'Hello world!\r\n');
577
+ sawBanner = true;
578
+ authCb('password');
579
+ }));
580
+ }
581
+
582
+ {
583
+ const { client, server } = setup(
584
+ 'Server responds to global requests in the right order'
585
+ );
586
+
587
+ function sendAcceptLater(accept) {
588
+ if (fastRejectSent)
589
+ accept();
590
+ else
591
+ setImmediate(sendAcceptLater, accept);
592
+ }
593
+
594
+ let fastRejectSent = false;
595
+
596
+ server.on('connection', mustCall((conn) => {
597
+ conn.on('ready', mustCall(() => {
598
+ conn.on('request', mustCall((accept, reject, name, info) => {
599
+ if (info.bindAddr === 'fastReject') {
600
+ // Will call reject on 'fastReject' soon ...
601
+ reject();
602
+ fastRejectSent = true;
603
+ } else {
604
+ // ... but accept on 'slowAccept' later
605
+ sendAcceptLater(accept);
606
+ }
607
+ }, 2));
608
+ }));
609
+ }));
610
+
611
+ client.on('ready', mustCall(() => {
612
+ let replyCnt = 0;
613
+
614
+ client.forwardIn('slowAccept', 0, mustCall((err) => {
615
+ assert(!err, `Unexpected error: ${err}`);
616
+ if (++replyCnt === 2)
617
+ client.end();
618
+ }));
619
+
620
+ client.forwardIn('fastReject', 0, mustCall((err) => {
621
+ assert(err, 'Expected error');
622
+ if (++replyCnt === 2)
623
+ client.end();
624
+ }));
625
+ }));
626
+ }
627
+
628
+ {
629
+ const { client, server } = setup(
630
+ 'Cleanup outstanding channel requests on channel close'
631
+ );
632
+
633
+ server.on('connection', mustCall((conn) => {
634
+ conn.on('ready', mustCall(() => {
635
+ conn.on('session', mustCall((accept, reject) => {
636
+ const session = accept();
637
+ session.on('subsystem', mustCall((accept, reject, info) => {
638
+ assert(info.name === 'netconf', `Wrong subsystem name: ${info.name}`);
639
+
640
+ // XXX: hack to prevent success reply from being sent
641
+ conn._protocol.channelSuccess = () => {};
642
+
643
+ accept().close();
644
+ }));
645
+ }));
646
+ }));
647
+ }));
648
+
649
+ client.on('ready', mustCall(() => {
650
+ client.subsys('netconf', mustCall((err, stream) => {
651
+ assert(err, 'Expected error');
652
+ client.end();
653
+ }));
654
+ }));
655
+ }
656
+
657
+ {
658
+ const { client, server } = setup_(
659
+ 'Handshake errors are emitted',
660
+ {
661
+ client: {
662
+ ...clientCfg,
663
+ algorithms: { cipher: [ 'aes128-cbc' ] },
664
+ },
665
+ server: {
666
+ ...serverCfg,
667
+ algorithms: { cipher: [ 'aes128-ctr' ] },
668
+ },
669
+
670
+ noForceClientReady: true,
671
+ noForceServerReady: true,
672
+ },
673
+ );
674
+
675
+ client.removeAllListeners('error');
676
+
677
+ function onError(err) {
678
+ assert.strictEqual(err.level, 'handshake');
679
+ assert(/handshake failed/i.test(err.message), 'Wrong error message');
680
+ }
681
+
682
+ server.on('connection', mustCall((conn) => {
683
+ conn.removeAllListeners('error');
684
+
685
+ conn.on('authentication', mustNotCall())
686
+ .on('ready', mustNotCall())
687
+ .on('handshake', mustNotCall())
688
+ .on('error', mustCall(onError))
689
+ .on('close', mustCall(() => {}));
690
+ }));
691
+
692
+ client.on('ready', mustNotCall())
693
+ .on('error', mustCall(onError))
694
+ .on('close', mustCall(() => {}));
695
+ }
696
+
697
+ {
698
+ const { client, server } = setup_(
699
+ 'Client signing errors are caught and emitted',
700
+ {
701
+ client: {
702
+ username: 'foo',
703
+ privateKey: KEY_RSA_BAD,
704
+ },
705
+ server: serverCfg,
706
+
707
+ noForceClientReady: true,
708
+ noForceServerReady: true,
709
+ },
710
+ );
711
+
712
+ client.removeAllListeners('error');
713
+
714
+ server.on('connection', mustCall((conn) => {
715
+ let authAttempt = 0;
716
+ conn.on('authentication', mustCall((ctx) => {
717
+ assert(!ctx.signature, 'Unexpected signature');
718
+ switch (++authAttempt) {
719
+ case 1:
720
+ assert(ctx.method === 'none', `Wrong auth method: ${ctx.method}`);
721
+ return ctx.reject();
722
+ case 2:
723
+ assert(ctx.method === 'publickey',
724
+ `Wrong auth method: ${ctx.method}`);
725
+ ctx.accept();
726
+ break;
727
+ }
728
+ }, 2)).on('ready', mustNotCall()).on('close', mustCall(() => {}));
729
+ }));
730
+
731
+ let cliError;
732
+ client.on('ready', mustNotCall()).on('error', mustCall((err) => {
733
+ if (cliError) {
734
+ assert(/all configured/i.test(err.message), 'Wrong error message');
735
+ } else {
736
+ cliError = err;
737
+ assert(/signing/i.test(err.message), 'Wrong error message');
738
+ }
739
+ }, 2)).on('close', mustCall(() => {}));
740
+ }
741
+
742
+ {
743
+ const { client, server } = setup_(
744
+ 'Server signing errors are caught and emitted',
745
+ {
746
+ client: clientCfg,
747
+ server: { hostKeys: [KEY_RSA_BAD] },
748
+
749
+ noForceClientReady: true,
750
+ noForceServerReady: true,
751
+ },
752
+ );
753
+
754
+ client.removeAllListeners('error');
755
+
756
+ server.on('connection', mustCall((conn) => {
757
+ conn.removeAllListeners('error');
758
+
759
+ conn.on('error', mustCall((err) => {
760
+ assert(/signature generation failed/i.test(err.message),
761
+ 'Wrong error message');
762
+ })).on('authentication', mustNotCall())
763
+ .on('ready', mustNotCall())
764
+ .on('close', mustCall(() => {}));
765
+ }));
766
+
767
+ client.on('ready', mustNotCall()).on('error', mustCall((err) => {
768
+ assert(/KEY_EXCHANGE_FAILED/.test(err.message), 'Wrong error message');
769
+ })).on('close', mustCall(() => {}));
770
+ }
771
+
772
+ {
773
+ const { client, server } = setup_(
774
+ 'Rekeying with AES-GCM',
775
+ {
776
+ client: {
777
+ ...clientCfg,
778
+ algorithms: { cipher: [ 'aes128-gcm@openssh.com' ] },
779
+ },
780
+ server: {
781
+ ...serverCfg,
782
+ algorithms: { cipher: [ 'aes128-gcm@openssh.com' ] },
783
+ },
784
+ },
785
+ );
786
+
787
+ server.on('connection', mustCall((conn) => {
788
+ conn.on('authentication', mustCall((ctx) => {
789
+ ctx.accept();
790
+ })).on('ready', mustCall(() => {
791
+ const reqs = [];
792
+ conn.on('session', mustCall((accept, reject) => {
793
+ if (reqs.length === 0) {
794
+ conn.rekey(mustCall((err) => {
795
+ assert(!err, `Unexpected rekey error: ${err}`);
796
+ reqs.forEach((accept) => {
797
+ const session = accept();
798
+ session.on('exec', mustCall((accept, reject, info) => {
799
+ const stream = accept();
800
+ stream.exit(0);
801
+ stream.end();
802
+ }));
803
+ });
804
+ }));
805
+ }
806
+ reqs.push(accept);
807
+ }, 3));
808
+ }));
809
+ }));
810
+
811
+ client.on('ready', mustCall(() => {
812
+ let calledBack = 0;
813
+ function callback(err, stream) {
814
+ assert(!err, `Unexpected error: ${err}`);
815
+ stream.resume();
816
+ if (++calledBack === 3)
817
+ client.end();
818
+ }
819
+ client.exec('foo', mustCall(callback));
820
+ client.exec('bar', mustCall(callback));
821
+ client.exec('baz', mustCall(callback));
822
+ }));
823
+ }
824
+
825
+ {
826
+ const { client, server } = setup_(
827
+ 'Switch from no compression to compression',
828
+ {
829
+ client: {
830
+ ...clientCfg,
831
+ algorithms: { compress: [ 'none' ] },
832
+ },
833
+ server: {
834
+ ...serverCfg,
835
+ algorithms: { compress: [ 'none', 'zlib@openssh.com' ] },
836
+ },
837
+ },
838
+ );
839
+
840
+ server.on('connection', mustCall((conn) => {
841
+ conn.on('authentication', mustCall((ctx) => {
842
+ ctx.accept();
843
+ })).on('ready', mustCall(() => {
844
+ const reqs = [];
845
+ conn.on('session', mustCall((accept, reject) => {
846
+ if (reqs.length === 0) {
847
+ // XXX: hack to change algorithms after initial handshake
848
+ client._protocol._offer = new KexInit({
849
+ kex: [ 'ecdh-sha2-nistp256' ],
850
+ serverHostKey: [ 'rsa-sha2-256' ],
851
+ cs: {
852
+ cipher: [ 'aes128-gcm@openssh.com' ],
853
+ mac: [],
854
+ compress: [ 'zlib@openssh.com' ],
855
+ lang: [],
856
+ },
857
+ sc: {
858
+ cipher: [ 'aes128-gcm@openssh.com' ],
859
+ mac: [],
860
+ compress: [ 'zlib@openssh.com' ],
861
+ lang: [],
862
+ },
863
+ });
864
+
865
+ conn.rekey(mustCall((err) => {
866
+ assert(!err, `Unexpected rekey error: ${err}`);
867
+ reqs.forEach((accept) => {
868
+ const session = accept();
869
+ session.on('exec', mustCall((accept, reject, info) => {
870
+ const stream = accept();
871
+ stream.exit(0);
872
+ stream.end();
873
+ }));
874
+ });
875
+ }));
876
+ }
877
+ reqs.push(accept);
878
+ }, 3));
879
+ }));
880
+ }));
881
+
882
+ let handshakes = 0;
883
+ client.on('handshake', mustCall((info) => {
884
+ switch (++handshakes) {
885
+ case 1:
886
+ assert(info.cs.compress === 'none', 'wrong compress value');
887
+ assert(info.sc.compress === 'none', 'wrong compress value');
888
+ break;
889
+ case 2:
890
+ assert(info.cs.compress === 'zlib@openssh.com',
891
+ 'wrong compress value');
892
+ assert(info.sc.compress === 'zlib@openssh.com',
893
+ 'wrong compress value');
894
+ break;
895
+ }
896
+ }, 2)).on('ready', mustCall(() => {
897
+ let calledBack = 0;
898
+ function callback(err, stream) {
899
+ assert(!err, `Unexpected error: ${err}`);
900
+ stream.resume();
901
+ if (++calledBack === 3)
902
+ client.end();
903
+ }
904
+ client.exec('foo', mustCall(callback));
905
+ client.exec('bar', mustCall(callback));
906
+ client.exec('baz', mustCall(callback));
907
+ }));
908
+ }
909
+
910
+ {
911
+ const { client, server } = setup_(
912
+ 'Switch from compression to no compression',
913
+ {
914
+ client: {
915
+ ...clientCfg,
916
+ algorithms: { compress: [ 'zlib' ] },
917
+ },
918
+ server: {
919
+ ...serverCfg,
920
+ algorithms: { compress: [ 'zlib', 'none' ] },
921
+ }
922
+ },
923
+ );
924
+
925
+ server.on('connection', mustCall((conn) => {
926
+ conn.on('authentication', mustCall((ctx) => {
927
+ ctx.accept();
928
+ })).on('ready', mustCall(() => {
929
+ const reqs = [];
930
+ conn.on('session', mustCall((accept, reject) => {
931
+ if (reqs.length === 0) {
932
+ // XXX: hack to change algorithms after initial handshake
933
+ client._protocol._offer = new KexInit({
934
+ kex: [ 'ecdh-sha2-nistp256' ],
935
+ serverHostKey: [ 'rsa-sha2-256' ],
936
+ cs: {
937
+ cipher: [ 'aes128-gcm@openssh.com' ],
938
+ mac: [],
939
+ compress: [ 'none' ],
940
+ lang: [],
941
+ },
942
+ sc: {
943
+ cipher: [ 'aes128-gcm@openssh.com' ],
944
+ mac: [],
945
+ compress: [ 'none' ],
946
+ lang: [],
947
+ },
948
+ });
949
+
950
+ conn.rekey(mustCall((err) => {
951
+ assert(!err, `Unexpected rekey error: ${err}`);
952
+ reqs.forEach((accept) => {
953
+ const session = accept();
954
+ session.on('exec', mustCall((accept, reject, info) => {
955
+ const stream = accept();
956
+ stream.exit(0);
957
+ stream.end();
958
+ }));
959
+ });
960
+ }));
961
+ }
962
+ reqs.push(accept);
963
+ }, 3));
964
+ }));
965
+ }));
966
+
967
+ let handshakes = 0;
968
+ client.on('handshake', mustCall((info) => {
969
+ switch (++handshakes) {
970
+ case 1:
971
+ assert(info.cs.compress === 'zlib', 'wrong compress value');
972
+ assert(info.sc.compress === 'zlib', 'wrong compress value');
973
+ break;
974
+ case 2:
975
+ assert(info.cs.compress === 'none', 'wrong compress value');
976
+ assert(info.sc.compress === 'none', 'wrong compress value');
977
+ break;
978
+ }
979
+ }, 2)).on('ready', mustCall(() => {
980
+ let calledBack = 0;
981
+ function callback(err, stream) {
982
+ assert(!err, `Unexpected error: ${err}`);
983
+ stream.resume();
984
+ if (++calledBack === 3)
985
+ client.end();
986
+ }
987
+ client.exec('foo', mustCall(callback));
988
+ client.exec('bar', mustCall(callback));
989
+ client.exec('baz', mustCall(callback));
990
+ }));
991
+ }
992
+
993
+ {
994
+ const { client, server } = setup_(
995
+ 'Large data compression',
996
+ {
997
+ client: {
998
+ ...clientCfg,
999
+ algorithms: { compress: [ 'zlib' ] },
1000
+ },
1001
+ server: {
1002
+ ...serverCfg,
1003
+ algorithms: { compress: [ 'zlib' ] },
1004
+ }
1005
+ },
1006
+ );
1007
+
1008
+ const chunk = Buffer.alloc(1024 * 1024, 'a');
1009
+ const chunkCount = 10;
1010
+
1011
+ server.on('connection', mustCall((conn) => {
1012
+ conn.on('authentication', mustCall((ctx) => {
1013
+ ctx.accept();
1014
+ })).on('ready', mustCall(() => {
1015
+ conn.on('session', mustCall((accept, reject) => {
1016
+ accept().on('exec', mustCall((accept, reject, info) => {
1017
+ const stream = accept();
1018
+ for (let i = 0; i < chunkCount; ++i)
1019
+ stream.write(chunk);
1020
+ stream.exit(0);
1021
+ stream.end();
1022
+ }));
1023
+ }));
1024
+ }));
1025
+ }));
1026
+
1027
+ client.on('ready', mustCall(() => {
1028
+ client.exec('foo', mustCall((err, stream) => {
1029
+ assert(!err, `Unexpected exec error: ${err}`);
1030
+ let nb = 0;
1031
+ stream.on('data', mustCallAtLeast((data) => {
1032
+ nb += data.length;
1033
+ })).on('end', mustCall(() => {
1034
+ assert(nb === (chunkCount * chunk.length),
1035
+ `Wrong stream byte count: ${nb}`);
1036
+ client.end();
1037
+ }));
1038
+ }));
1039
+ }));
1040
+ }
1041
+
1042
+ {
1043
+ const { client, server } = setup_(
1044
+ 'Debug output',
1045
+ {
1046
+ client: {
1047
+ ...clientCfg,
1048
+ debug: mustCallAtLeast((msg) => {
1049
+ assert(typeof msg === 'string',
1050
+ `Wrong debug argument type: ${typeof msg}`);
1051
+ assert(msg.length > 0, 'Unexpected empty debug message');
1052
+ }),
1053
+ },
1054
+ server: {
1055
+ ...serverCfg,
1056
+ debug: mustCallAtLeast((msg) => {
1057
+ assert(typeof msg === 'string',
1058
+ `Wrong debug argument type: ${typeof msg}`);
1059
+ assert(msg.length > 0, 'Unexpected empty debug message');
1060
+ }),
1061
+ },
1062
+ },
1063
+ );
1064
+
1065
+ server.on('connection', mustCall((conn) => {
1066
+ conn.on('authentication', mustCall((ctx) => {
1067
+ ctx.accept();
1068
+ })).on('ready', mustCall(() => {
1069
+ conn.on('session', mustCall((accept, reject) => {
1070
+ accept().on('exec', mustCall((accept, reject, info) => {
1071
+ assert(info.command === 'foo --bar',
1072
+ `Wrong exec command: ${info.command}`);
1073
+ const stream = accept();
1074
+ stream.exit(100);
1075
+ stream.end();
1076
+ conn.end();
1077
+ }));
1078
+ }));
1079
+ }));
1080
+ }));
1081
+
1082
+ client.on('ready', mustCall(() => {
1083
+ client.exec('foo --bar', mustCall((err, stream) => {
1084
+ assert(!err, `Unexpected exec error: ${err}`);
1085
+ stream.resume();
1086
+ }));
1087
+ }));
1088
+ }
1089
+
1090
+ {
1091
+ const { server } = setup_(
1092
+ 'HTTP agent',
1093
+ {
1094
+ // No automatic client, the agent will create one
1095
+
1096
+ server: serverCfg,
1097
+
1098
+ debug,
1099
+ },
1100
+ );
1101
+
1102
+ let httpServer;
1103
+ server.on('listening', () => {
1104
+ httpServer = http.createServer((req, res) => {
1105
+ httpServer.close();
1106
+ res.end('hello world!');
1107
+ });
1108
+ httpServer.listen(0, 'localhost', () => {
1109
+ const agent = new HTTPAgent({
1110
+ host: 'localhost',
1111
+ port: server.address().port,
1112
+ username: 'foo',
1113
+ password: 'bar',
1114
+ });
1115
+ http.get({
1116
+ host: 'localhost',
1117
+ port: httpServer.address().port,
1118
+ agent,
1119
+ headers: { Connection: 'close' },
1120
+ }, (res) => {
1121
+ assert(res.statusCode === 200,
1122
+ `Wrong http status code: ${res.statusCode}`);
1123
+ let buf = '';
1124
+ res.on('data', mustCallAtLeast((chunk) => {
1125
+ buf += chunk;
1126
+ })).on('end', mustCall(() => {
1127
+ assert(buf === 'hello world!',
1128
+ `Wrong http response body: ${inspect(buf)}`);
1129
+ }));
1130
+ });
1131
+ });
1132
+ });
1133
+
1134
+ server.on('connection', mustCall((conn) => {
1135
+ conn.on('authentication', mustCall((ctx) => {
1136
+ ctx.accept();
1137
+ })).on('ready', mustCall(() => {
1138
+ conn.on('tcpip', mustCall((accept, reject, info) => {
1139
+ assert(info.destIP === 'localhost', `Wrong destIP: ${info.destIP}`);
1140
+ assert(info.destPort === httpServer.address().port,
1141
+ `Wrong destPort: ${info.destPort}`);
1142
+ assert(info.srcIP === 'localhost', `Wrong srcIP: ${info.srcIP}`);
1143
+
1144
+ const stream = accept();
1145
+ const tcp = new net.Socket();
1146
+ tcp.pipe(stream).pipe(tcp);
1147
+ tcp.connect(httpServer.address().port, 'localhost');
1148
+ }));
1149
+ }));
1150
+ }));
1151
+ }
1152
+
1153
+ {
1154
+ const { server } = setup_(
1155
+ 'HTTPS agent',
1156
+ {
1157
+ // No automatic client, the agent will create one
1158
+
1159
+ server: serverCfg,
1160
+
1161
+ debug,
1162
+ },
1163
+ );
1164
+
1165
+ let httpsServer;
1166
+ server.on('listening', () => {
1167
+ httpsServer = https.createServer({
1168
+ key: fixture('https_key.pem'),
1169
+ cert: fixture('https_cert.pem'),
1170
+ }, (req, res) => {
1171
+ httpsServer.close();
1172
+ res.end('hello world!');
1173
+ });
1174
+ httpsServer.listen(0, 'localhost', () => {
1175
+ const agent = new HTTPSAgent({
1176
+ host: 'localhost',
1177
+ port: server.address().port,
1178
+ username: 'foo',
1179
+ password: 'bar',
1180
+ });
1181
+ https.get({
1182
+ host: 'localhost',
1183
+ port: httpsServer.address().port,
1184
+ agent,
1185
+ headers: { Connection: 'close' },
1186
+ ca: fixture('https_cert.pem'),
1187
+ }, (res) => {
1188
+ assert(res.statusCode === 200,
1189
+ `Wrong http status code: ${res.statusCode}`);
1190
+ let buf = '';
1191
+ res.on('data', mustCallAtLeast((chunk) => {
1192
+ buf += chunk;
1193
+ })).on('end', mustCall(() => {
1194
+ assert(buf === 'hello world!',
1195
+ `Wrong http response body: ${inspect(buf)}`);
1196
+ }));
1197
+ }).on('error', (err) => {
1198
+ // This workaround is necessary for some reason on node < v14.x
1199
+ if (!/write after end/i.test(err.message))
1200
+ throw err;
1201
+ });
1202
+ });
1203
+ });
1204
+
1205
+ server.on('connection', mustCall((conn) => {
1206
+ conn.on('authentication', mustCall((ctx) => {
1207
+ ctx.accept();
1208
+ })).on('ready', mustCall(() => {
1209
+ conn.on('tcpip', mustCall((accept, reject, info) => {
1210
+ assert(info.destIP === 'localhost', `Wrong destIP: ${info.destIP}`);
1211
+ assert(info.destPort === httpsServer.address().port,
1212
+ `Wrong destPort: ${info.destPort}`);
1213
+ assert(info.srcIP === 'localhost', `Wrong srcIP: ${info.srcIP}`);
1214
+
1215
+ const stream = accept();
1216
+ const tcp = new net.Socket();
1217
+ tcp.pipe(stream).pipe(tcp);
1218
+ tcp.connect(httpsServer.address().port, 'localhost');
1219
+ }));
1220
+ }));
1221
+ }));
1222
+ }
1223
+
1224
+ [
1225
+ { desc: 'remove/append/prepend (regexps)',
1226
+ config: {
1227
+ remove: /.*/,
1228
+ append: /gcm/,
1229
+ prepend: /ctr/,
1230
+ },
1231
+ expected: [
1232
+ 'aes128-ctr',
1233
+ 'aes192-ctr',
1234
+ 'aes256-ctr',
1235
+ 'aes128-gcm@openssh.com',
1236
+ 'aes256-gcm@openssh.com',
1237
+ 'aes128-gcm',
1238
+ 'aes256-gcm',
1239
+ ],
1240
+ },
1241
+ { desc: 'remove/append/prepend (strings)',
1242
+ config: {
1243
+ remove: /.*/,
1244
+ append: 'aes256-ctr',
1245
+ prepend: [ 'aes256-gcm@openssh.com', 'aes128-gcm@openssh.com' ],
1246
+ },
1247
+ expected: [
1248
+ 'aes256-gcm@openssh.com',
1249
+ 'aes128-gcm@openssh.com',
1250
+ 'aes256-ctr',
1251
+ ],
1252
+ },
1253
+ ].forEach((info) => {
1254
+ const { client, server } = setup_(
1255
+ `Client algorithms option (${info.desc})`,
1256
+ {
1257
+ client: {
1258
+ ...clientCfg,
1259
+ algorithms: { cipher: info.config },
1260
+ },
1261
+ server: serverCfg,
1262
+
1263
+ debug,
1264
+ },
1265
+ );
1266
+
1267
+ server.on('connection', mustCall((conn) => {
1268
+ conn.on('authentication', mustCall((ctx) => {
1269
+ ctx.accept();
1270
+ })).on('ready', mustCall(() => {
1271
+ conn.end();
1272
+ }));
1273
+ }));
1274
+ client.on('ready', mustCall(() => {
1275
+ // XXX: hack to easily verify computed offer
1276
+ const offer = client._protocol._offer.lists;
1277
+ assert.deepStrictEqual(
1278
+ offer.cs.cipher.array,
1279
+ info.expected,
1280
+ `Wrong algorithm list: ${offer.cs.cipher.array}`
1281
+ );
1282
+ }));
1283
+ });
1284
+
1285
+ {
1286
+ const { client } = setup_(
1287
+ `Safely end() from Client 'error' event handler`,
1288
+ {
1289
+ client: clientCfg,
1290
+ noClientError: true,
1291
+ noForceClientReady: true,
1292
+ },
1293
+ );
1294
+
1295
+ const badServer = net.createServer((s) => {});
1296
+ badServer.listen(0, 'localhost', mustCall(() => {
1297
+ badServer.unref();
1298
+
1299
+ client.on('error', mustCallAtLeast((err) => {
1300
+ client.end();
1301
+ })).on('ready', mustNotCall()).on('close', mustCall(() => {}));
1302
+ client.connect({
1303
+ host: 'localhost',
1304
+ port: badServer.address().port,
1305
+ user: 'foo',
1306
+ password: 'bar',
1307
+ readyTimeout: 1,
1308
+ });
1309
+ }));
1310
+ }
1311
+
1312
+ {
1313
+ const { client } = setup_(
1314
+ 'Client error should be emitted on bad/nonexistent greeting',
1315
+ {
1316
+ client: clientCfg,
1317
+ noClientError: true,
1318
+ noForceClientReady: true,
1319
+ },
1320
+ );
1321
+
1322
+ const badServer = net.createServer(mustCall((s) => {
1323
+ badServer.close();
1324
+ s.end();
1325
+ })).listen(0, 'localhost', mustCall(() => {
1326
+ client.on('error', mustCall((err) => {
1327
+ client.end();
1328
+ })).on('ready', mustNotCall()).on('close', mustCall(() => {}));
1329
+ client.connect({
1330
+ host: 'localhost',
1331
+ port: badServer.address().port,
1332
+ user: 'foo',
1333
+ password: 'bar',
1334
+ });
1335
+ }));
1336
+ }
1337
+
1338
+ {
1339
+ const { client } = setup_(
1340
+ 'Only one client error on connection failure',
1341
+ {
1342
+ client: clientCfg,
1343
+ noClientError: true,
1344
+ noForceClientReady: true,
1345
+ },
1346
+ );
1347
+
1348
+ client.on('error', mustCall((err) => {
1349
+ assert.strictEqual(err.syscall, 'getaddrinfo');
1350
+ }));
1351
+ client.connect({
1352
+ host: 'blerbblubblubblerb',
1353
+ port: 9999,
1354
+ user: 'foo',
1355
+ password: 'bar'
1356
+ });
1357
+ }
1358
+
1359
+ {
1360
+ const { client, server } = setup(
1361
+ 'Client should remove reserved channels on incoming channel rejection'
1362
+ );
1363
+
1364
+ const assignedPort = 31337;
1365
+
1366
+ server.on('connection', mustCall((conn) => {
1367
+ conn.on('ready', mustCall(() => {
1368
+ conn.on('request', mustCall((accept, reject, name, info) => {
1369
+ assert(name === 'tcpip-forward', 'Wrong request name');
1370
+ assert.deepStrictEqual(
1371
+ info,
1372
+ { bindAddr: 'good', bindPort: 0 },
1373
+ 'Wrong request info'
1374
+ );
1375
+ accept(assignedPort);
1376
+ conn.forwardOut(info.bindAddr,
1377
+ assignedPort,
1378
+ 'remote',
1379
+ 12345,
1380
+ mustCall((err, ch) => {
1381
+ assert(err, 'Should receive error');
1382
+ client.end();
1383
+ }));
1384
+ }));
1385
+ }));
1386
+ }));
1387
+
1388
+ client.on('ready', mustCall(() => {
1389
+ // request forwarding
1390
+ client.forwardIn('good', 0, mustCall((err, port) => {
1391
+ assert(!err, `Unexpected error: ${err}`);
1392
+ assert(port === assignedPort, 'Wrong assigned port');
1393
+ }));
1394
+ })).on('tcp connection', mustCall((details, accept, reject) => {
1395
+ assert.deepStrictEqual(
1396
+ details,
1397
+ { destIP: 'good',
1398
+ destPort: assignedPort,
1399
+ srcIP: 'remote',
1400
+ srcPort: 12345
1401
+ },
1402
+ 'Wrong connection details'
1403
+ );
1404
+ assert.strictEqual(Object.keys(client._chanMgr._channels).length, 1);
1405
+ assert.strictEqual(client._chanMgr._count, 1);
1406
+ reject();
1407
+ assert.strictEqual(Object.keys(client._chanMgr._channels).length, 0);
1408
+ assert.strictEqual(client._chanMgr._count, 0);
1409
+ }));
1410
+ }
1411
+
1412
+ {
1413
+ // Allow injected sockets
1414
+
1415
+ const socket = new Transform({
1416
+ emitClose: true,
1417
+ autoDestroy: true,
1418
+ transform: (chunk, encoding, cb) => {
1419
+ cb();
1420
+ },
1421
+ });
1422
+ socket.remoteAddress = '127.0.0.1';
1423
+ socket.remotePort = '12345';
1424
+ socket.remoteFamily = 'IPv4';
1425
+ socket.push(Buffer.from('SSH-2.0-foo\r\n'));
1426
+
1427
+ const server = new Server(serverCfg);
1428
+ server.on('connection', mustCall((conn, info) => {
1429
+ assert.strictEqual(info.header.versions.software, 'foo');
1430
+ assert.strictEqual(info.ip, '127.0.0.1');
1431
+ assert.strictEqual(info.port, '12345');
1432
+ assert.strictEqual(info.family, 'IPv4');
1433
+ conn.on('ready', mustNotCall());
1434
+ conn.on('close', mustCall());
1435
+ socket.end();
1436
+ }));
1437
+ server.injectSocket(socket);
1438
+ }
1439
+
1440
+ {
1441
+ const { client, server } = setup(
1442
+ 'Server should not error when cleaning up client bare session channels'
1443
+ );
1444
+
1445
+ server.on('connection', mustCall((conn) => {
1446
+ conn.on('session', mustCall((accept, reject) => {
1447
+ accept().on('exec', mustCall((accept, reject, info) => {
1448
+ assert(info.command === 'uptime',
1449
+ `Wrong exec command: ${info.command}`);
1450
+ client.end();
1451
+ }));
1452
+ }));
1453
+ }));
1454
+
1455
+ client.on('ready', mustCall(() => {
1456
+ client.exec('uptime', mustCall((err) => {
1457
+ assert(err instanceof Error);
1458
+ }));
1459
+ }));
1460
+ }