@honeybbq/teamspeak 0.0.1 → 1.0.0-beta.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +726 -2
- package/dist/client/abort.d.ts +5 -0
- package/dist/client/abort.d.ts.map +1 -0
- package/dist/client/abort.js +23 -0
- package/dist/client/abort.js.map +1 -0
- package/dist/client/address.d.ts +17 -0
- package/dist/client/address.d.ts.map +1 -0
- package/dist/client/address.js +66 -0
- package/dist/client/address.js.map +1 -0
- package/dist/client/api/voice.d.ts +24 -0
- package/dist/client/api/voice.d.ts.map +1 -0
- package/dist/client/api/voice.js +33 -0
- package/dist/client/api/voice.js.map +1 -0
- package/dist/client/capabilities.d.ts +68 -0
- package/dist/client/capabilities.d.ts.map +1 -0
- package/dist/client/capabilities.js +59 -0
- package/dist/client/capabilities.js.map +1 -0
- package/dist/client/client.d.ts +196 -0
- package/dist/client/client.d.ts.map +1 -0
- package/dist/client/client.js +1523 -0
- package/dist/client/client.js.map +1 -0
- package/dist/client/commands.d.ts +66 -0
- package/dist/client/commands.d.ts.map +1 -0
- package/dist/client/commands.js +162 -0
- package/dist/client/commands.js.map +1 -0
- package/dist/client/crypto/crypt-ops.d.ts +7 -0
- package/dist/client/crypto/crypt-ops.d.ts.map +1 -0
- package/dist/client/crypto/crypt-ops.js +2 -0
- package/dist/client/crypto/crypt-ops.js.map +1 -0
- package/dist/client/crypto/crypt.d.ts +37 -0
- package/dist/client/crypto/crypt.d.ts.map +1 -0
- package/dist/client/crypto/crypt.js +203 -0
- package/dist/client/crypto/crypt.js.map +1 -0
- package/dist/client/crypto/eax.d.ts +12 -0
- package/dist/client/crypto/eax.d.ts.map +1 -0
- package/dist/client/crypto/eax.js +118 -0
- package/dist/client/crypto/eax.js.map +1 -0
- package/dist/client/crypto/identity.d.ts +97 -0
- package/dist/client/crypto/identity.d.ts.map +1 -0
- package/dist/client/crypto/identity.js +412 -0
- package/dist/client/crypto/identity.js.map +1 -0
- package/dist/client/crypto/index.d.ts +7 -0
- package/dist/client/crypto/index.d.ts.map +1 -0
- package/dist/client/crypto/index.js +5 -0
- package/dist/client/crypto/index.js.map +1 -0
- package/dist/client/crypto/primitives.d.ts +43 -0
- package/dist/client/crypto/primitives.d.ts.map +1 -0
- package/dist/client/crypto/primitives.js +116 -0
- package/dist/client/crypto/primitives.js.map +1 -0
- package/dist/client/diagnostics.d.ts +45 -0
- package/dist/client/diagnostics.d.ts.map +1 -0
- package/dist/client/diagnostics.js +30 -0
- package/dist/client/diagnostics.js.map +1 -0
- package/dist/client/discovery/index.d.ts +2 -0
- package/dist/client/discovery/index.d.ts.map +1 -0
- package/dist/client/discovery/index.js +2 -0
- package/dist/client/discovery/index.js.map +1 -0
- package/dist/client/discovery/resolver.d.ts +26 -0
- package/dist/client/discovery/resolver.d.ts.map +1 -0
- package/dist/client/discovery/resolver.js +275 -0
- package/dist/client/discovery/resolver.js.map +1 -0
- package/dist/client/errors.d.ts +82 -0
- package/dist/client/errors.d.ts.map +1 -0
- package/dist/client/errors.js +201 -0
- package/dist/client/errors.js.map +1 -0
- package/dist/client/events.d.ts +3 -0
- package/dist/client/events.d.ts.map +1 -0
- package/dist/client/events.js +8 -0
- package/dist/client/events.js.map +1 -0
- package/dist/client/handshake/crypt-handshake.d.ts +17 -0
- package/dist/client/handshake/crypt-handshake.d.ts.map +1 -0
- package/dist/client/handshake/crypt-handshake.js +128 -0
- package/dist/client/handshake/crypt-handshake.js.map +1 -0
- package/dist/client/handshake/crypt-init2.d.ts +7 -0
- package/dist/client/handshake/crypt-init2.d.ts.map +1 -0
- package/dist/client/handshake/crypt-init2.js +37 -0
- package/dist/client/handshake/crypt-init2.js.map +1 -0
- package/dist/client/handshake/index.d.ts +4 -0
- package/dist/client/handshake/index.d.ts.map +1 -0
- package/dist/client/handshake/index.js +4 -0
- package/dist/client/handshake/index.js.map +1 -0
- package/dist/client/handshake/license.d.ts +35 -0
- package/dist/client/handshake/license.d.ts.map +1 -0
- package/dist/client/handshake/license.js +169 -0
- package/dist/client/handshake/license.js.map +1 -0
- package/dist/client/handshake.d.ts +27 -0
- package/dist/client/handshake.d.ts.map +1 -0
- package/dist/client/handshake.js +126 -0
- package/dist/client/handshake.js.map +1 -0
- package/dist/client/helpers.d.ts +6 -0
- package/dist/client/helpers.d.ts.map +1 -0
- package/dist/client/helpers.js +13 -0
- package/dist/client/helpers.js.map +1 -0
- package/dist/client/hooks.d.ts +7 -0
- package/dist/client/hooks.d.ts.map +1 -0
- package/dist/client/hooks.js +28 -0
- package/dist/client/hooks.js.map +1 -0
- package/dist/client/index.d.ts +26 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +28 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/reconnect.d.ts +12 -0
- package/dist/client/reconnect.d.ts.map +1 -0
- package/dist/client/reconnect.js +44 -0
- package/dist/client/reconnect.js.map +1 -0
- package/dist/client/throttle.d.ts +20 -0
- package/dist/client/throttle.d.ts.map +1 -0
- package/dist/client/throttle.js +83 -0
- package/dist/client/throttle.js.map +1 -0
- package/dist/client/trace.d.ts +223 -0
- package/dist/client/trace.d.ts.map +1 -0
- package/dist/client/trace.js +13 -0
- package/dist/client/trace.js.map +1 -0
- package/dist/client/transfer.d.ts +111 -0
- package/dist/client/transfer.d.ts.map +1 -0
- package/dist/client/transfer.js +243 -0
- package/dist/client/transfer.js.map +1 -0
- package/dist/client/transport/generation-window.d.ts +30 -0
- package/dist/client/transport/generation-window.d.ts.map +1 -0
- package/dist/client/transport/generation-window.js +97 -0
- package/dist/client/transport/generation-window.js.map +1 -0
- package/dist/client/transport/handler.d.ts +61 -0
- package/dist/client/transport/handler.d.ts.map +1 -0
- package/dist/client/transport/handler.js +793 -0
- package/dist/client/transport/handler.js.map +1 -0
- package/dist/client/transport/index.d.ts +6 -0
- package/dist/client/transport/index.d.ts.map +1 -0
- package/dist/client/transport/index.js +5 -0
- package/dist/client/transport/index.js.map +1 -0
- package/dist/client/transport/packet.d.ts +36 -0
- package/dist/client/transport/packet.d.ts.map +1 -0
- package/dist/client/transport/packet.js +55 -0
- package/dist/client/transport/packet.js.map +1 -0
- package/dist/client/transport/quicklz.d.ts +24 -0
- package/dist/client/transport/quicklz.d.ts.map +1 -0
- package/dist/client/transport/quicklz.js +179 -0
- package/dist/client/transport/quicklz.js.map +1 -0
- package/dist/client/types.d.ts +226 -0
- package/dist/client/types.d.ts.map +1 -0
- package/dist/client/types.js +39 -0
- package/dist/client/types.js.map +1 -0
- package/dist/core/api/channels.d.ts +182 -0
- package/dist/core/api/channels.d.ts.map +1 -0
- package/dist/core/api/channels.js +155 -0
- package/dist/core/api/channels.js.map +1 -0
- package/dist/core/api/clients.d.ts +304 -0
- package/dist/core/api/clients.d.ts.map +1 -0
- package/dist/core/api/clients.js +260 -0
- package/dist/core/api/clients.js.map +1 -0
- package/dist/core/api/command.d.ts +305 -0
- package/dist/core/api/command.d.ts.map +1 -0
- package/dist/core/api/command.js +363 -0
- package/dist/core/api/command.js.map +1 -0
- package/dist/core/api/files.d.ts +153 -0
- package/dist/core/api/files.d.ts.map +1 -0
- package/dist/core/api/files.js +181 -0
- package/dist/core/api/files.js.map +1 -0
- package/dist/core/api/groups.d.ts +248 -0
- package/dist/core/api/groups.d.ts.map +1 -0
- package/dist/core/api/groups.js +271 -0
- package/dist/core/api/groups.js.map +1 -0
- package/dist/core/api/moderation.d.ts +205 -0
- package/dist/core/api/moderation.d.ts.map +1 -0
- package/dist/core/api/moderation.js +209 -0
- package/dist/core/api/moderation.js.map +1 -0
- package/dist/core/api/parse.d.ts +16 -0
- package/dist/core/api/parse.d.ts.map +1 -0
- package/dist/core/api/parse.js +40 -0
- package/dist/core/api/parse.js.map +1 -0
- package/dist/core/api/server.d.ts +310 -0
- package/dist/core/api/server.d.ts.map +1 -0
- package/dist/core/api/server.js +290 -0
- package/dist/core/api/server.js.map +1 -0
- package/dist/core/command/command.d.ts +20 -0
- package/dist/core/command/command.d.ts.map +1 -0
- package/dist/core/command/command.js +112 -0
- package/dist/core/command/command.js.map +1 -0
- package/dist/core/command/ids.d.ts +125 -0
- package/dist/core/command/ids.d.ts.map +1 -0
- package/dist/core/command/ids.js +85 -0
- package/dist/core/command/ids.js.map +1 -0
- package/dist/core/command/parser.d.ts +17 -0
- package/dist/core/command/parser.d.ts.map +1 -0
- package/dist/core/command/parser.js +65 -0
- package/dist/core/command/parser.js.map +1 -0
- package/dist/core/command/request.d.ts +61 -0
- package/dist/core/command/request.d.ts.map +1 -0
- package/dist/core/command/request.js +64 -0
- package/dist/core/command/request.js.map +1 -0
- package/dist/core/command/responses.d.ts +59 -0
- package/dist/core/command/responses.d.ts.map +1 -0
- package/dist/core/command/responses.js +74 -0
- package/dist/core/command/responses.js.map +1 -0
- package/dist/core/command-name.d.ts +333 -0
- package/dist/core/command-name.d.ts.map +1 -0
- package/dist/core/command-name.js +331 -0
- package/dist/core/command-name.js.map +1 -0
- package/dist/core/enums.d.ts +146 -0
- package/dist/core/enums.d.ts.map +1 -0
- package/dist/core/enums.js +132 -0
- package/dist/core/enums.js.map +1 -0
- package/dist/core/errorcode.d.ts +413 -0
- package/dist/core/errorcode.d.ts.map +1 -0
- package/dist/core/errorcode.js +410 -0
- package/dist/core/errorcode.js.map +1 -0
- package/dist/core/errors.d.ts +111 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +233 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/events.d.ts +207 -0
- package/dist/core/events.d.ts.map +1 -0
- package/dist/core/events.js +6 -0
- package/dist/core/events.js.map +1 -0
- package/dist/core/helpers.d.ts +42 -0
- package/dist/core/helpers.d.ts.map +1 -0
- package/dist/core/helpers.js +156 -0
- package/dist/core/helpers.js.map +1 -0
- package/dist/core/index.d.ts +35 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +34 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/internal.d.ts +23 -0
- package/dist/core/internal.d.ts.map +1 -0
- package/dist/core/internal.js +20 -0
- package/dist/core/internal.js.map +1 -0
- package/dist/core/middleware.d.ts +14 -0
- package/dist/core/middleware.d.ts.map +1 -0
- package/dist/core/middleware.js +18 -0
- package/dist/core/middleware.js.map +1 -0
- package/dist/core/notification-name.d.ts +154 -0
- package/dist/core/notification-name.d.ts.map +1 -0
- package/dist/core/notification-name.js +152 -0
- package/dist/core/notification-name.js.map +1 -0
- package/dist/core/notifications.d.ts +43 -0
- package/dist/core/notifications.d.ts.map +1 -0
- package/dist/core/notifications.js +116 -0
- package/dist/core/notifications.js.map +1 -0
- package/dist/core/permission-name.d.ts +533 -0
- package/dist/core/permission-name.d.ts.map +1 -0
- package/dist/core/permission-name.js +531 -0
- package/dist/core/permission-name.js.map +1 -0
- package/dist/core/permission.d.ts +31 -0
- package/dist/core/permission.d.ts.map +1 -0
- package/dist/core/permission.js +20 -0
- package/dist/core/permission.js.map +1 -0
- package/dist/core/property-name.d.ts +403 -0
- package/dist/core/property-name.d.ts.map +1 -0
- package/dist/core/property-name.js +405 -0
- package/dist/core/property-name.js.map +1 -0
- package/dist/core/reason.d.ts +39 -0
- package/dist/core/reason.d.ts.map +1 -0
- package/dist/core/reason.js +36 -0
- package/dist/core/reason.js.map +1 -0
- package/dist/core/reconnect.d.ts +59 -0
- package/dist/core/reconnect.d.ts.map +1 -0
- package/dist/core/reconnect.js +55 -0
- package/dist/core/reconnect.js.map +1 -0
- package/dist/core/types.d.ts +110 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +27 -0
- package/dist/core/types.js.map +1 -0
- package/dist/query/client.d.ts +194 -0
- package/dist/query/client.d.ts.map +1 -0
- package/dist/query/client.js +967 -0
- package/dist/query/client.js.map +1 -0
- package/dist/query/errors.d.ts +61 -0
- package/dist/query/errors.d.ts.map +1 -0
- package/dist/query/errors.js +100 -0
- package/dist/query/errors.js.map +1 -0
- package/dist/query/index.d.ts +36 -0
- package/dist/query/index.d.ts.map +1 -0
- package/dist/query/index.js +34 -0
- package/dist/query/index.js.map +1 -0
- package/dist/query/knownhosts.d.ts +61 -0
- package/dist/query/knownhosts.d.ts.map +1 -0
- package/dist/query/knownhosts.js +223 -0
- package/dist/query/knownhosts.js.map +1 -0
- package/dist/query/lines.d.ts +14 -0
- package/dist/query/lines.d.ts.map +1 -0
- package/dist/query/lines.js +29 -0
- package/dist/query/lines.js.map +1 -0
- package/dist/query/options.d.ts +187 -0
- package/dist/query/options.d.ts.map +1 -0
- package/dist/query/options.js +213 -0
- package/dist/query/options.js.map +1 -0
- package/dist/query/reconnect.d.ts +29 -0
- package/dist/query/reconnect.d.ts.map +1 -0
- package/dist/query/reconnect.js +87 -0
- package/dist/query/reconnect.js.map +1 -0
- package/dist/query/ssh.d.ts +345 -0
- package/dist/query/ssh.d.ts.map +1 -0
- package/dist/query/ssh.js +241 -0
- package/dist/query/ssh.js.map +1 -0
- package/dist/query/stream.d.ts +38 -0
- package/dist/query/stream.d.ts.map +1 -0
- package/dist/query/stream.js +70 -0
- package/dist/query/stream.js.map +1 -0
- package/dist/query/tcp.d.ts +38 -0
- package/dist/query/tcp.d.ts.map +1 -0
- package/dist/query/tcp.js +53 -0
- package/dist/query/tcp.js.map +1 -0
- package/dist/query/transport.d.ts +36 -0
- package/dist/query/transport.d.ts.map +1 -0
- package/dist/query/transport.js +2 -0
- package/dist/query/transport.js.map +1 -0
- package/dist/query/web.d.ts +54 -0
- package/dist/query/web.d.ts.map +1 -0
- package/dist/query/web.js +146 -0
- package/dist/query/web.js.map +1 -0
- package/dist/versions/index.d.ts +3094 -0
- package/dist/versions/index.d.ts.map +1 -0
- package/dist/versions/index.js +9237 -0
- package/dist/versions/index.js.map +1 -0
- package/package.json +118 -4
- package/src/client/abort.ts +24 -0
- package/src/client/address.ts +74 -0
- package/src/client/api/voice.ts +61 -0
- package/src/client/capabilities.ts +106 -0
- package/src/client/client.ts +1809 -0
- package/src/client/commands.ts +193 -0
- package/src/client/crypto/crypt-ops.ts +6 -0
- package/src/client/crypto/crypt.ts +275 -0
- package/src/client/crypto/eax.ts +152 -0
- package/src/client/crypto/identity.ts +484 -0
- package/src/client/crypto/index.ts +21 -0
- package/src/client/crypto/primitives.ts +141 -0
- package/src/client/diagnostics.ts +58 -0
- package/src/client/discovery/index.ts +1 -0
- package/src/client/discovery/resolver.ts +325 -0
- package/src/client/errors.ts +217 -0
- package/src/client/events.ts +12 -0
- package/src/client/handshake/crypt-handshake.ts +157 -0
- package/src/client/handshake/crypt-init2.ts +48 -0
- package/src/client/handshake/index.ts +3 -0
- package/src/client/handshake/license.ts +208 -0
- package/src/client/handshake.ts +150 -0
- package/src/client/helpers.ts +10 -0
- package/src/client/hooks.ts +30 -0
- package/src/client/index.ts +93 -0
- package/src/client/reconnect.ts +43 -0
- package/src/client/throttle.ts +92 -0
- package/src/client/trace.ts +237 -0
- package/src/client/transfer.ts +436 -0
- package/src/client/transport/generation-window.ts +108 -0
- package/src/client/transport/handler.ts +926 -0
- package/src/client/transport/index.ts +14 -0
- package/src/client/transport/packet.ts +69 -0
- package/src/client/transport/quicklz.ts +209 -0
- package/src/client/types.ts +268 -0
- package/src/core/api/channels.ts +396 -0
- package/src/core/api/clients.ts +654 -0
- package/src/core/api/command.ts +563 -0
- package/src/core/api/files.ts +405 -0
- package/src/core/api/groups.ts +622 -0
- package/src/core/api/moderation.ts +525 -0
- package/src/core/api/parse.ts +52 -0
- package/src/core/api/server.ts +709 -0
- package/src/core/command/command.ts +125 -0
- package/src/core/command/ids.ts +149 -0
- package/src/core/command/parser.ts +68 -0
- package/src/core/command/request.ts +119 -0
- package/src/core/command/responses.ts +114 -0
- package/src/core/command-name.ts +334 -0
- package/src/core/enums.ts +167 -0
- package/src/core/errorcode.ts +412 -0
- package/src/core/errors.ts +258 -0
- package/src/core/events.ts +219 -0
- package/src/core/helpers.ts +161 -0
- package/src/core/index.ts +126 -0
- package/src/core/internal.ts +23 -0
- package/src/core/middleware.ts +24 -0
- package/src/core/notification-name.ts +155 -0
- package/src/core/notifications.ts +157 -0
- package/src/core/permission-name.ts +538 -0
- package/src/core/permission.ts +34 -0
- package/src/core/property-name.ts +411 -0
- package/src/core/reason.ts +38 -0
- package/src/core/reconnect.ts +98 -0
- package/src/core/types.ts +138 -0
- package/src/query/client.ts +1132 -0
- package/src/query/errors.ts +108 -0
- package/src/query/index.ts +65 -0
- package/src/query/knownhosts.ts +257 -0
- package/src/query/lines.ts +28 -0
- package/src/query/options.ts +388 -0
- package/src/query/reconnect.ts +84 -0
- package/src/query/ssh.ts +614 -0
- package/src/query/stream.ts +91 -0
- package/src/query/tcp.ts +85 -0
- package/src/query/transport.ts +35 -0
- package/src/query/web.ts +195 -0
- package/src/versions/index.ts +10774 -0
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
import { StreamTransport } from "./stream.js";
|
|
2
|
+
import type { QueryStream } from "./stream.js";
|
|
3
|
+
/**
|
|
4
|
+
* The part of an SSH client this transport uses: `ssh2`'s `Client` is one, and
|
|
5
|
+
* so is anything else with these methods.
|
|
6
|
+
*
|
|
7
|
+
* Declared here rather than imported from `@types/ssh2`, which a caller
|
|
8
|
+
* without the optional peer dependency does not have: the types are a
|
|
9
|
+
* devDependency and are not published with the package. A later release may
|
|
10
|
+
* widen this, and every new member will be optional, so an implementation
|
|
11
|
+
* written today keeps compiling.
|
|
12
|
+
*/
|
|
13
|
+
export interface SshClient {
|
|
14
|
+
/**
|
|
15
|
+
* Begin the connection; `ready` is emitted once the handshake is done.
|
|
16
|
+
*
|
|
17
|
+
* `hostVerifier` is asked about the server's key before anything is
|
|
18
|
+
* authenticated, so before the password is sent. It is given the key's wire
|
|
19
|
+
* encoding and returns whether to go on: a client must end the connection
|
|
20
|
+
* when it returns `false`, and must not treat a missing answer as a yes.
|
|
21
|
+
*/
|
|
22
|
+
connect(config: {
|
|
23
|
+
host: string;
|
|
24
|
+
port: number;
|
|
25
|
+
username: string;
|
|
26
|
+
password: string;
|
|
27
|
+
readyTimeout: number;
|
|
28
|
+
hostVerifier: (key: Uint8Array) => boolean;
|
|
29
|
+
}): void;
|
|
30
|
+
/** Open a shell channel, or report why it could not be opened. */
|
|
31
|
+
shell(pty: false, callback: (error: Error | undefined, channel: SshChannel) => void): void;
|
|
32
|
+
/** End the connection. */
|
|
33
|
+
end(): void;
|
|
34
|
+
/** Listen for the handshake completing, once. */
|
|
35
|
+
once(event: "ready", listener: () => void): unknown;
|
|
36
|
+
/** Listen for the next failure, once. */
|
|
37
|
+
once(event: "error", listener: (error: Error) => void): unknown;
|
|
38
|
+
/** Listen for each failure. */
|
|
39
|
+
on(event: "error", listener: (error: Error) => void): unknown;
|
|
40
|
+
/** Stop listening for failures. */
|
|
41
|
+
off(event: "error", listener: (error: Error) => void): unknown;
|
|
42
|
+
}
|
|
43
|
+
/** The channel an SSH client's shell opens: a byte stream, and the errors on it. */
|
|
44
|
+
export interface SshChannel extends QueryStream {
|
|
45
|
+
/** Report a failure on the stream, as a socket would: the transport reads it. */
|
|
46
|
+
emit(event: "error", error: Error): unknown;
|
|
47
|
+
/** Listen for the stream closing, once. */
|
|
48
|
+
once(event: "close", listener: () => void): unknown;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* An SSH client this transport uses instead of loading `ssh2` itself: either
|
|
52
|
+
* one that is connected already, or a factory that makes one.
|
|
53
|
+
*
|
|
54
|
+
* A caller that holds its own connected client — authenticated through an
|
|
55
|
+
* agent, a jump host or a key file this transport knows nothing about — hands
|
|
56
|
+
* it over. A factory is asked for one per connection attempt, which a
|
|
57
|
+
* reconnection needs.
|
|
58
|
+
*/
|
|
59
|
+
export type SshConnection = SshClient | (() => Promise<SshClient>);
|
|
60
|
+
/**
|
|
61
|
+
* The key an SSH server presented, as the check a caller supplies sees it.
|
|
62
|
+
*
|
|
63
|
+
* A type of this package's own rather than the SSH library's, so a policy can
|
|
64
|
+
* be written without importing that library.
|
|
65
|
+
*
|
|
66
|
+
* @experimental Part of the `@honeybbq/teamspeak/query` entry, which may
|
|
67
|
+
* change in a minor release.
|
|
68
|
+
*/
|
|
69
|
+
export interface SshHostKey {
|
|
70
|
+
/** The host that was dialled, as it was given. */
|
|
71
|
+
readonly host: string;
|
|
72
|
+
/** The port that was dialled. */
|
|
73
|
+
readonly port: number;
|
|
74
|
+
/** The key's algorithm, such as `ssh-ed25519`, as its own encoding names it. */
|
|
75
|
+
readonly keyType: string;
|
|
76
|
+
/** The key's wire encoding: the blob a `known_hosts` line carries in base64. */
|
|
77
|
+
readonly key: Uint8Array;
|
|
78
|
+
/**
|
|
79
|
+
* The key's SHA-256 fingerprint in OpenSSH form, such as `SHA256:HR5y2ZQ…`.
|
|
80
|
+
* It is what `ssh-keygen -lf` and `ssh-keyscan` print, so it can be compared
|
|
81
|
+
* with the one the server's operator published.
|
|
82
|
+
*/
|
|
83
|
+
readonly fingerprint: string;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* A caller's check of an SSH server's host key: returns to accept the key and
|
|
87
|
+
* throws to refuse it.
|
|
88
|
+
*
|
|
89
|
+
* Throwing is how a callback with no error channel says no, and the error it
|
|
90
|
+
* throws is kept as the `cause` of the {@link SshHostKeyError} the connection
|
|
91
|
+
* fails with. It runs before the login is sent, and it has to be synchronous
|
|
92
|
+
* and return nothing: a return value, a `false` included, is not an answer this
|
|
93
|
+
* can read, so it refuses the key rather than guess, as does a promise, whose
|
|
94
|
+
* rejection would arrive too late to stop anything.
|
|
95
|
+
*
|
|
96
|
+
* @experimental Part of the `@honeybbq/teamspeak/query` entry, which may
|
|
97
|
+
* change in a minor release.
|
|
98
|
+
*/
|
|
99
|
+
export type SshHostKeyVerifier = (key: SshHostKey) => void;
|
|
100
|
+
/**
|
|
101
|
+
* Your own check of the server's host key. Use it when the key you trust does
|
|
102
|
+
* not live in a `known_hosts` file: a fingerprint from configuration, a pinned
|
|
103
|
+
* key, a lookup somewhere else.
|
|
104
|
+
*
|
|
105
|
+
* One of the three arms of {@link SshHostKeyPolicy}: giving it excludes the
|
|
106
|
+
* other two.
|
|
107
|
+
*
|
|
108
|
+
* @experimental Part of the `@honeybbq/teamspeak/query` entry, which may
|
|
109
|
+
* change in a minor release.
|
|
110
|
+
*/
|
|
111
|
+
export interface SshHostKeyCallbackPolicy {
|
|
112
|
+
/**
|
|
113
|
+
* The check; see {@link SshHostKeyVerifier}. Called once per connection
|
|
114
|
+
* attempt, before the login is sent.
|
|
115
|
+
*/
|
|
116
|
+
readonly hostKey: SshHostKeyVerifier;
|
|
117
|
+
/** Left out: `hostKey` is the policy, and a second one would not say which decides. */
|
|
118
|
+
readonly knownHosts?: never;
|
|
119
|
+
/** Left out: `hostKey` is the policy, and a second one would not say which decides. */
|
|
120
|
+
readonly insecureIgnoreHostKey?: never;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Accept whatever key the server presents. Use it for a test or a throwaway
|
|
124
|
+
* server on a network that is already trusted, and for nothing else.
|
|
125
|
+
*
|
|
126
|
+
* One of the three arms of {@link SshHostKeyPolicy}: giving it excludes the
|
|
127
|
+
* other two.
|
|
128
|
+
*
|
|
129
|
+
* @experimental Part of the `@honeybbq/teamspeak/query` entry, which may
|
|
130
|
+
* change in a minor release.
|
|
131
|
+
*/
|
|
132
|
+
export interface SshInsecureHostKeyPolicy {
|
|
133
|
+
/**
|
|
134
|
+
* Only `true` is a value: this is not a switch to be left `false`, but a
|
|
135
|
+
* decision a call site makes out loud.
|
|
136
|
+
*
|
|
137
|
+
* It gives up the one thing the host key is for. Anyone who can answer the
|
|
138
|
+
* port, on the path or at the address, receives the query login and its
|
|
139
|
+
* password and is indistinguishable from the server. Use
|
|
140
|
+
* {@link SshKnownHostsPolicy.knownHosts} otherwise.
|
|
141
|
+
*/
|
|
142
|
+
readonly insecureIgnoreHostKey: true;
|
|
143
|
+
/** Left out: accepting any key leaves nothing for a second policy to decide. */
|
|
144
|
+
readonly hostKey?: never;
|
|
145
|
+
/** Left out: accepting any key leaves nothing for a second policy to decide. */
|
|
146
|
+
readonly knownHosts?: never;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Check the server against an OpenSSH `known_hosts` file. Use it for a server
|
|
150
|
+
* whose key you have recorded with `ssh-keyscan`, or already trust through
|
|
151
|
+
* `ssh`.
|
|
152
|
+
*
|
|
153
|
+
* One of the three arms of {@link SshHostKeyPolicy}: giving it excludes the
|
|
154
|
+
* other two.
|
|
155
|
+
*
|
|
156
|
+
* @experimental Part of the `@honeybbq/teamspeak/query` entry, which may
|
|
157
|
+
* change in a minor release.
|
|
158
|
+
*/
|
|
159
|
+
export interface SshKnownHostsPolicy {
|
|
160
|
+
/**
|
|
161
|
+
* A path to the `known_hosts` file, in the format `ssh-keyscan` writes and
|
|
162
|
+
* `ssh-keygen -H` hashes.
|
|
163
|
+
*
|
|
164
|
+
* Read when each connection is attempted, so a reconnection sees the file as
|
|
165
|
+
* it is then, and only from the path given: `~/.ssh/known_hosts` is never
|
|
166
|
+
* assumed, because a library reading the home directory on its own is a
|
|
167
|
+
* surprise. The check is what `ssh` does with `StrictHostKeyChecking=yes`: a
|
|
168
|
+
* host the file does not mention is refused, so is one recorded with another
|
|
169
|
+
* key, and so is a key a `@revoked` line names. Plain, `[host]:port` and
|
|
170
|
+
* hashed entries are read; a line that cannot be read fails the connection
|
|
171
|
+
* rather than being skipped.
|
|
172
|
+
*
|
|
173
|
+
* A port other than 22 is recorded as `[host]:port`, which is what
|
|
174
|
+
* `ssh-keyscan -p` writes: an entry for port 22 does not vouch for the query
|
|
175
|
+
* port.
|
|
176
|
+
*/
|
|
177
|
+
readonly knownHosts: string;
|
|
178
|
+
/** Left out: `knownHosts` is the policy, and a second one would not say which decides. */
|
|
179
|
+
readonly hostKey?: never;
|
|
180
|
+
/** Left out: `knownHosts` is the policy, and a second one would not say which decides. */
|
|
181
|
+
readonly insecureIgnoreHostKey?: never;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* How the server's host key is checked: exactly one of `hostKey`, `knownHosts`
|
|
185
|
+
* and `insecureIgnoreHostKey`.
|
|
186
|
+
*
|
|
187
|
+
* There is no default, and a missing or doubled choice does not compile. The
|
|
188
|
+
* query login is a credential, normally `serveradmin`'s, and a client that
|
|
189
|
+
* accepts any key hands it to whatever answers the port. The same rule is
|
|
190
|
+
* checked when the program runs, for callers that are not type checked.
|
|
191
|
+
*
|
|
192
|
+
* @experimental Part of the `@honeybbq/teamspeak/query` entry, which may
|
|
193
|
+
* change in a minor release.
|
|
194
|
+
*/
|
|
195
|
+
export type SshHostKeyPolicy = SshHostKeyCallbackPolicy | SshKnownHostsPolicy | SshInsecureHostKeyPolicy;
|
|
196
|
+
/**
|
|
197
|
+
* The address and the login of a server this transport dials itself: the part
|
|
198
|
+
* of {@link SshDialOptions} that is not the host key policy.
|
|
199
|
+
*
|
|
200
|
+
* @experimental Part of the `@honeybbq/teamspeak/query` entry, which may
|
|
201
|
+
* change in a minor release.
|
|
202
|
+
*/
|
|
203
|
+
export interface SshDialTarget {
|
|
204
|
+
/** The server's host. */
|
|
205
|
+
readonly host: string;
|
|
206
|
+
/** The SSH query port; 10022 by default. */
|
|
207
|
+
readonly port?: number | undefined;
|
|
208
|
+
/** The query login name, such as `serveradmin`. */
|
|
209
|
+
readonly username: string;
|
|
210
|
+
/** The query login's password. */
|
|
211
|
+
readonly password: string;
|
|
212
|
+
/** Left out: a connection of your own is {@link SshSuppliedConnectionOptions}. */
|
|
213
|
+
readonly connection?: never;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Connect to a server this transport dials itself: with a login, and with a
|
|
217
|
+
* host key policy. The usual way, and the one to use unless you already hold a
|
|
218
|
+
* connected SSH client.
|
|
219
|
+
*
|
|
220
|
+
* It is {@link SshHostKeyPolicy} together with the address and the login, so
|
|
221
|
+
* leaving the policy out is a type error that names the three ways to give one.
|
|
222
|
+
*
|
|
223
|
+
* @experimental Part of the `@honeybbq/teamspeak/query` entry, which may
|
|
224
|
+
* change in a minor release.
|
|
225
|
+
*/
|
|
226
|
+
export type SshDialOptions = SshDialTarget & SshHostKeyPolicy;
|
|
227
|
+
/**
|
|
228
|
+
* Use an SSH client you made and connected yourself, or a factory for one:
|
|
229
|
+
* authenticated through an agent, a jump host or a key file this transport
|
|
230
|
+
* knows nothing about.
|
|
231
|
+
*
|
|
232
|
+
* Only a shell is opened on it, so no login and no host key policy are taken:
|
|
233
|
+
* the client you supply has done both already, and an option nothing would
|
|
234
|
+
* read is a type error rather than something that could suggest the key was
|
|
235
|
+
* verified here. The host and port are the server's identity, for messages.
|
|
236
|
+
*
|
|
237
|
+
* @experimental Part of the `@honeybbq/teamspeak/query` entry, which may
|
|
238
|
+
* change in a minor release.
|
|
239
|
+
*/
|
|
240
|
+
export interface SshSuppliedConnectionOptions {
|
|
241
|
+
/** The server's host, for identity and messages: nothing is dialled. */
|
|
242
|
+
readonly host: string;
|
|
243
|
+
/** The server's SSH query port, for identity and messages; 10022 by default. */
|
|
244
|
+
readonly port?: number | undefined;
|
|
245
|
+
/**
|
|
246
|
+
* The SSH client to use, or a factory for one. A client that is already
|
|
247
|
+
* connected skips the handshake; a factory is asked for one per connection
|
|
248
|
+
* attempt, which a reconnection needs.
|
|
249
|
+
*
|
|
250
|
+
* Deliberately narrow, so a later release can widen it without breaking an
|
|
251
|
+
* implementation written today. Its host key is checked by whoever made it.
|
|
252
|
+
*/
|
|
253
|
+
readonly connection: SshConnection;
|
|
254
|
+
/** Left out: the supplied client is authenticated already. */
|
|
255
|
+
readonly username?: never;
|
|
256
|
+
/** Left out: the supplied client is authenticated already. */
|
|
257
|
+
readonly password?: never;
|
|
258
|
+
/** Left out: the supplied client's host key is checked by whoever made it. */
|
|
259
|
+
readonly hostKey?: never;
|
|
260
|
+
/** Left out: the supplied client's host key is checked by whoever made it. */
|
|
261
|
+
readonly knownHosts?: never;
|
|
262
|
+
/** Left out: the supplied client's host key is checked by whoever made it. */
|
|
263
|
+
readonly insecureIgnoreHostKey?: never;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* How a ServerQuery over SSH is reached, without the cancellation: one of
|
|
267
|
+
* {@link SshDialOptions} and {@link SshSuppliedConnectionOptions}.
|
|
268
|
+
*
|
|
269
|
+
* What a `QueryClient`'s `ssh` transport is built from, so that the two cannot
|
|
270
|
+
* drift apart.
|
|
271
|
+
*
|
|
272
|
+
* @experimental Part of the `@honeybbq/teamspeak/query` entry, which may
|
|
273
|
+
* change in a minor release.
|
|
274
|
+
*/
|
|
275
|
+
export type SshConnectOptions = SshDialOptions | SshSuppliedConnectionOptions;
|
|
276
|
+
/**
|
|
277
|
+
* Where a ServerQuery over SSH listens, who logs in, and how the server's host
|
|
278
|
+
* key is checked.
|
|
279
|
+
*
|
|
280
|
+
* One of two shapes. The usual one, {@link SshDialOptions}, takes the host, the
|
|
281
|
+
* login and exactly one of `hostKey`, `knownHosts` and `insecureIgnoreHostKey`:
|
|
282
|
+
* there is no default, because the login is a credential and a client that
|
|
283
|
+
* accepts any key hands it to whatever answers the port. The other,
|
|
284
|
+
* {@link SshSuppliedConnectionOptions}, takes an SSH client you connected
|
|
285
|
+
* yourself, and no login or policy.
|
|
286
|
+
*
|
|
287
|
+
* @experimental Part of the `@honeybbq/teamspeak/query` entry, which may
|
|
288
|
+
* change in a minor release.
|
|
289
|
+
*/
|
|
290
|
+
export type SshOptions = SshConnectOptions & {
|
|
291
|
+
/** Abandons the connection attempt. */
|
|
292
|
+
readonly signal?: AbortSignal | undefined;
|
|
293
|
+
};
|
|
294
|
+
/** How the host key is to be decided, once the options have been read. */
|
|
295
|
+
export type HostKeyDecision = {
|
|
296
|
+
readonly kind: "verifier";
|
|
297
|
+
readonly verify: SshHostKeyVerifier;
|
|
298
|
+
} | {
|
|
299
|
+
readonly kind: "knownHosts";
|
|
300
|
+
readonly path: string;
|
|
301
|
+
} | {
|
|
302
|
+
readonly kind: "insecure";
|
|
303
|
+
}
|
|
304
|
+
/** The caller supplied the connection, so the key was theirs to check. */
|
|
305
|
+
| {
|
|
306
|
+
readonly kind: "connection";
|
|
307
|
+
};
|
|
308
|
+
/**
|
|
309
|
+
* What the decision reads. Every member is `unknown`: the types of
|
|
310
|
+
* {@link SshOptions} already make a wrong combination a compile error, and this
|
|
311
|
+
* is for the callers they do not reach, a JavaScript program or an `as` cast.
|
|
312
|
+
*/
|
|
313
|
+
export interface SshChoice {
|
|
314
|
+
readonly hostKey?: unknown;
|
|
315
|
+
readonly knownHosts?: unknown;
|
|
316
|
+
readonly insecureIgnoreHostKey?: unknown;
|
|
317
|
+
readonly connection?: unknown;
|
|
318
|
+
readonly username?: unknown;
|
|
319
|
+
readonly password?: unknown;
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Read the trust decision out of the options, or refuse them.
|
|
323
|
+
*
|
|
324
|
+
* Fails closed: with none of the three there is no policy, and this throws
|
|
325
|
+
* rather than choose one. Two is a `TypeError`, since a caller who passed both
|
|
326
|
+
* has not decided which is authoritative. Runs when a client is built as well
|
|
327
|
+
* as when it connects, so a missing decision is heard about before the first
|
|
328
|
+
* attempt.
|
|
329
|
+
*
|
|
330
|
+
* The same rule as the types state, for the callers they do not reach.
|
|
331
|
+
*/
|
|
332
|
+
export declare function hostKeyDecision(options: SshChoice): HostKeyDecision;
|
|
333
|
+
/**
|
|
334
|
+
* Open a ServerQuery over SSH.
|
|
335
|
+
*
|
|
336
|
+
* SSH logs in itself, so there is no `login` command to send afterwards: the
|
|
337
|
+
* session is already the query account, and only `use` is left.
|
|
338
|
+
*
|
|
339
|
+
* The server's host key is checked first, by whichever of `hostKey`,
|
|
340
|
+
* `knownHosts` and `insecureIgnoreHostKey` was given, and the password is sent
|
|
341
|
+
* only to a server whose key was accepted. With none of them, or with two,
|
|
342
|
+
* this rejects before anything is opened or dialled.
|
|
343
|
+
*/
|
|
344
|
+
export declare function connectSsh(options: SshOptions): Promise<StreamTransport>;
|
|
345
|
+
//# sourceMappingURL=ssh.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssh.d.ts","sourceRoot":"","sources":["../../src/query/ssh.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { MissingDependencyError, QueryAuthError, SshHostKeyError } from "./errors.js";
|
|
3
|
+
import { KnownHosts, fingerprintOf, keyTypeOf } from "./knownhosts.js";
|
|
4
|
+
import { StreamTransport } from "./stream.js";
|
|
5
|
+
/**
|
|
6
|
+
* Read the trust decision out of the options, or refuse them.
|
|
7
|
+
*
|
|
8
|
+
* Fails closed: with none of the three there is no policy, and this throws
|
|
9
|
+
* rather than choose one. Two is a `TypeError`, since a caller who passed both
|
|
10
|
+
* has not decided which is authoritative. Runs when a client is built as well
|
|
11
|
+
* as when it connects, so a missing decision is heard about before the first
|
|
12
|
+
* attempt.
|
|
13
|
+
*
|
|
14
|
+
* The same rule as the types state, for the callers they do not reach.
|
|
15
|
+
*/
|
|
16
|
+
export function hostKeyDecision(options) {
|
|
17
|
+
const { hostKey, knownHosts, insecureIgnoreHostKey, connection, username, password } = options;
|
|
18
|
+
if (hostKey !== undefined && typeof hostKey !== "function") {
|
|
19
|
+
throw new TypeError("hostKey is a function that throws to refuse a host key");
|
|
20
|
+
}
|
|
21
|
+
if (knownHosts !== undefined && (typeof knownHosts !== "string" || knownHosts === "")) {
|
|
22
|
+
throw new TypeError("knownHosts is the path of a known_hosts file");
|
|
23
|
+
}
|
|
24
|
+
if (insecureIgnoreHostKey !== undefined && insecureIgnoreHostKey !== true) {
|
|
25
|
+
throw new TypeError("insecureIgnoreHostKey is `true` or left out: it is a decision, not a switch to set to false");
|
|
26
|
+
}
|
|
27
|
+
const given = [];
|
|
28
|
+
if (hostKey !== undefined)
|
|
29
|
+
given.push("hostKey");
|
|
30
|
+
if (knownHosts !== undefined)
|
|
31
|
+
given.push("knownHosts");
|
|
32
|
+
if (insecureIgnoreHostKey !== undefined)
|
|
33
|
+
given.push("insecureIgnoreHostKey");
|
|
34
|
+
if (given.length > 1) {
|
|
35
|
+
throw new TypeError(`${given.join(", ")} were given together; exactly one of hostKey, knownHosts and insecureIgnoreHostKey decides whether the host key is accepted`);
|
|
36
|
+
}
|
|
37
|
+
if (connection !== undefined) {
|
|
38
|
+
if (given.length > 0) {
|
|
39
|
+
throw new TypeError(`${given[0]} has no effect with connection, which makes the connection itself: its host key is checked by whoever made it`);
|
|
40
|
+
}
|
|
41
|
+
if (username !== undefined || password !== undefined) {
|
|
42
|
+
throw new TypeError("username and password have no effect with connection, which is authenticated already: nothing would send them");
|
|
43
|
+
}
|
|
44
|
+
return { kind: "connection" };
|
|
45
|
+
}
|
|
46
|
+
if (hostKey !== undefined)
|
|
47
|
+
return { kind: "verifier", verify: hostKey };
|
|
48
|
+
if (knownHosts !== undefined)
|
|
49
|
+
return { kind: "knownHosts", path: knownHosts };
|
|
50
|
+
if (insecureIgnoreHostKey !== undefined)
|
|
51
|
+
return { kind: "insecure" };
|
|
52
|
+
throw new Error("the SSH host key has to be checked, and none of hostKey, knownHosts or insecureIgnoreHostKey was given: a query login is a credential, normally serveradmin's, and this client will not send it to a host it has not verified");
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* `ssh2`, or a `MissingDependencyError` naming it. Loaded on demand: it is an
|
|
56
|
+
* optional peer dependency, so importing it at the top of this module would
|
|
57
|
+
* make it a requirement of the whole entry point — including the TCP and
|
|
58
|
+
* WebQuery transports, which need nothing but Node.
|
|
59
|
+
*/
|
|
60
|
+
async function loadSsh2() {
|
|
61
|
+
try {
|
|
62
|
+
return await import("ssh2");
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
if (typeof error === "object" &&
|
|
66
|
+
error !== null &&
|
|
67
|
+
error.code === "ERR_MODULE_NOT_FOUND") {
|
|
68
|
+
throw new MissingDependencyError();
|
|
69
|
+
}
|
|
70
|
+
throw error;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Open a ServerQuery over SSH.
|
|
75
|
+
*
|
|
76
|
+
* SSH logs in itself, so there is no `login` command to send afterwards: the
|
|
77
|
+
* session is already the query account, and only `use` is left.
|
|
78
|
+
*
|
|
79
|
+
* The server's host key is checked first, by whichever of `hostKey`,
|
|
80
|
+
* `knownHosts` and `insecureIgnoreHostKey` was given, and the password is sent
|
|
81
|
+
* only to a server whose key was accepted. With none of them, or with two,
|
|
82
|
+
* this rejects before anything is opened or dialled.
|
|
83
|
+
*/
|
|
84
|
+
export async function connectSsh(options) {
|
|
85
|
+
const { host, port = 10022, signal, connection } = options;
|
|
86
|
+
const decision = hostKeyDecision(options);
|
|
87
|
+
// The login is read only where this module dials: a supplied client is
|
|
88
|
+
// authenticated already. Checked here, so a missing one fails before ssh2 is
|
|
89
|
+
// loaded or anything is opened.
|
|
90
|
+
const login = connection === undefined
|
|
91
|
+
? {
|
|
92
|
+
username: nonEmptyString(options.username, "username"),
|
|
93
|
+
password: nonEmptyString(options.password, "password"),
|
|
94
|
+
}
|
|
95
|
+
: undefined;
|
|
96
|
+
signal?.throwIfAborted();
|
|
97
|
+
const verify = await verifierFor(decision, host, port);
|
|
98
|
+
const ssh = await clientFor(connection);
|
|
99
|
+
signal?.throwIfAborted();
|
|
100
|
+
// What the caller's check said, so that the failure ssh2 reports for a
|
|
101
|
+
// refused key can be told from any other and carry the reason.
|
|
102
|
+
let refusal;
|
|
103
|
+
return new Promise((resolve, reject) => {
|
|
104
|
+
let settled = false;
|
|
105
|
+
const failed = (error) => {
|
|
106
|
+
if (settled)
|
|
107
|
+
return;
|
|
108
|
+
settled = true;
|
|
109
|
+
signal?.removeEventListener("abort", onAbort);
|
|
110
|
+
reject(error);
|
|
111
|
+
};
|
|
112
|
+
const onAbort = () => {
|
|
113
|
+
ssh.end();
|
|
114
|
+
failed(signal.reason);
|
|
115
|
+
};
|
|
116
|
+
const onAuthError = (error) => {
|
|
117
|
+
if (refusal !== undefined) {
|
|
118
|
+
failed(new SshHostKeyError(host, port, `the SSH host key of ${host}:${port} was not accepted, so no login was sent: ${refusal.message}`, { cause: refusal }));
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
// ssh2 reports a refused credential through `level`, which its types do
|
|
122
|
+
// not name; a wrong password is the one that leaves the client unable to
|
|
123
|
+
// authenticate rather than unable to reach the server.
|
|
124
|
+
const level = error.level;
|
|
125
|
+
failed(level === "client-authentication"
|
|
126
|
+
? new QueryAuthError(login.username, `SSH authentication failed for ${login.username}`, { cause: error })
|
|
127
|
+
: error);
|
|
128
|
+
};
|
|
129
|
+
const openShell = () => {
|
|
130
|
+
ssh.shell(false, (error, channel) => {
|
|
131
|
+
if (error) {
|
|
132
|
+
ssh.end();
|
|
133
|
+
failed(error);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
ssh.off("error", onAuthError);
|
|
137
|
+
settled = true;
|
|
138
|
+
signal?.removeEventListener("abort", onAbort);
|
|
139
|
+
// `ssh2` reports a failure after the handshake on the connection, and the
|
|
140
|
+
// stream closes with it.
|
|
141
|
+
ssh.on("error", (failure) => channel.emit("error", failure));
|
|
142
|
+
channel.once("close", () => ssh.end());
|
|
143
|
+
resolve(new StreamTransport(channel, () => ssh.end()));
|
|
144
|
+
});
|
|
145
|
+
};
|
|
146
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
147
|
+
if (connection !== undefined) {
|
|
148
|
+
// A client the caller handed over is one they say is connected, and one
|
|
149
|
+
// from their own factory is dialled on their terms: neither is connected
|
|
150
|
+
// here, and neither can be a wrong credential this module knows of.
|
|
151
|
+
openShell();
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
ssh.once("error", onAuthError);
|
|
155
|
+
ssh.once("ready", openShell);
|
|
156
|
+
ssh.connect({
|
|
157
|
+
host,
|
|
158
|
+
port,
|
|
159
|
+
// Set exactly when `connection` is not, and this is the dial path.
|
|
160
|
+
username: login.username,
|
|
161
|
+
password: login.password,
|
|
162
|
+
readyTimeout: 10_000,
|
|
163
|
+
hostVerifier: (blob) => {
|
|
164
|
+
const outcome = decide(verify, host, port, blob);
|
|
165
|
+
if (outcome !== undefined)
|
|
166
|
+
refusal = outcome;
|
|
167
|
+
return outcome === undefined;
|
|
168
|
+
},
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
function nonEmptyString(value, name) {
|
|
173
|
+
if (typeof value !== "string" || value === "")
|
|
174
|
+
throw new TypeError(`${name} is a non-empty string`);
|
|
175
|
+
return value;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* The check the options chose, ready to run: the caller's own, one over the
|
|
179
|
+
* `known_hosts` file read now, or the one that accepts anything.
|
|
180
|
+
*
|
|
181
|
+
* A file that cannot be read or parsed is a failure to verify, and ends the
|
|
182
|
+
* connection as a refused key does.
|
|
183
|
+
*/
|
|
184
|
+
async function verifierFor(policy, host, port) {
|
|
185
|
+
if (policy.kind === "verifier")
|
|
186
|
+
return policy.verify;
|
|
187
|
+
// `connection` never reaches a handshake of ours, so for it this is not asked.
|
|
188
|
+
if (policy.kind !== "knownHosts")
|
|
189
|
+
return () => { };
|
|
190
|
+
let hosts;
|
|
191
|
+
try {
|
|
192
|
+
hosts = KnownHosts.parse(await readFile(policy.path, "utf8"), policy.path);
|
|
193
|
+
}
|
|
194
|
+
catch (error) {
|
|
195
|
+
throw new SshHostKeyError(host, port, `the host key of ${host}:${port} cannot be checked: ${error.message}`, { cause: error });
|
|
196
|
+
}
|
|
197
|
+
return (key) => hosts.verify(key);
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Run the check on the key ssh2 found, returning why it was refused, or
|
|
201
|
+
* `undefined` for a key it accepted.
|
|
202
|
+
*
|
|
203
|
+
* Everything that is not a plain return counts as a refusal: a throw, naturally,
|
|
204
|
+
* but also an answer. A check that returns `false` was written in ssh2's
|
|
205
|
+
* convention and means no; one that returns `true` means yes in that
|
|
206
|
+
* convention, and a promise means whatever it later settles to. None of those
|
|
207
|
+
* is the contract, and acting on a guess at which was meant is how a refused key
|
|
208
|
+
* gets through, so each fails closed and says what to write instead.
|
|
209
|
+
*/
|
|
210
|
+
function decide(verify, host, port, blob) {
|
|
211
|
+
try {
|
|
212
|
+
const key = new Uint8Array(blob);
|
|
213
|
+
const answer = verify({
|
|
214
|
+
host,
|
|
215
|
+
port,
|
|
216
|
+
keyType: keyTypeOf(key),
|
|
217
|
+
key,
|
|
218
|
+
fingerprint: fingerprintOf(key),
|
|
219
|
+
});
|
|
220
|
+
if (answer === undefined)
|
|
221
|
+
return undefined;
|
|
222
|
+
// A rejection nobody awaits would otherwise surface as an unhandled one.
|
|
223
|
+
if (typeof answer.then === "function") {
|
|
224
|
+
void Promise.resolve(answer).catch(() => { });
|
|
225
|
+
}
|
|
226
|
+
return new TypeError("the hostKey check returned a value; it has to return nothing to accept the key and throw to refuse it, and be synchronous");
|
|
227
|
+
}
|
|
228
|
+
catch (error) {
|
|
229
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
/** The client to talk over: the caller's, their factory's, or a fresh `ssh2`. */
|
|
233
|
+
async function clientFor(connection) {
|
|
234
|
+
if (typeof connection === "function")
|
|
235
|
+
return connection();
|
|
236
|
+
if (connection !== undefined)
|
|
237
|
+
return connection;
|
|
238
|
+
const { Client } = await loadSsh2();
|
|
239
|
+
return new Client();
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=ssh.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssh.js","sourceRoot":"","sources":["../../src/query/ssh.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { QueryTransport } from "./transport.js";
|
|
2
|
+
/**
|
|
3
|
+
* The part of a duplex byte stream a line transport uses. A `node:net` socket
|
|
4
|
+
* is one; so is an SSH shell channel, or a test double.
|
|
5
|
+
*/
|
|
6
|
+
export interface QueryStream {
|
|
7
|
+
/** Write bytes to the peer; `callback` runs once they are flushed, with the failure if any. */
|
|
8
|
+
write(data: string, callback: (error?: Error | null) => void): unknown;
|
|
9
|
+
/** Close the stream. */
|
|
10
|
+
end(): unknown;
|
|
11
|
+
/** Listen for each chunk received. */
|
|
12
|
+
on(event: "data", listener: (chunk: Uint8Array) => void): unknown;
|
|
13
|
+
/** Listen for a failure, which ends the connection. */
|
|
14
|
+
on(event: "error", listener: (error: Error) => void): unknown;
|
|
15
|
+
/** Listen for the stream closing. */
|
|
16
|
+
on(event: "close", listener: () => void): unknown;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* A {@link QueryTransport} over a byte stream: raw TCP, or an SSH shell.
|
|
20
|
+
*
|
|
21
|
+
* Both greet with a two-line banner, `TS3` and a welcome sentence, before any
|
|
22
|
+
* answer. It is skipped, so the client sees only answers and notifications.
|
|
23
|
+
*/
|
|
24
|
+
export declare class StreamTransport implements QueryTransport {
|
|
25
|
+
#private;
|
|
26
|
+
/** A raw TCP connection and an SSH session both carry pushed notifications. */
|
|
27
|
+
readonly supportsNotifications = true;
|
|
28
|
+
onLine: ((line: string) => void) | null;
|
|
29
|
+
onClose: ((error: Error | undefined) => void) | null;
|
|
30
|
+
/**
|
|
31
|
+
* `onEnd` runs once the stream is closed, to release what the stream sits
|
|
32
|
+
* on: an SSH session's connection, say.
|
|
33
|
+
*/
|
|
34
|
+
constructor(stream: QueryStream, onEnd?: () => void);
|
|
35
|
+
send(line: string): Promise<void>;
|
|
36
|
+
close(): Promise<void>;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=stream.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/query/stream.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,+FAA+F;IAC/F,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC;IACvE,wBAAwB;IACxB,GAAG,IAAI,OAAO,CAAC;IACf,sCAAsC;IACtC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,GAAG,OAAO,CAAC;IAClE,uDAAuD;IACvD,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,OAAO,CAAC;IAC9D,qCAAqC;IACrC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC;CACnD;AAED;;;;;GAKG;AACH,qBAAa,eAAgB,YAAW,cAAc;;IACpD,+EAA+E;IAC/E,QAAQ,CAAC,qBAAqB,QAAQ;IACtC,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,CAAQ;IAC/C,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,KAAK,IAAI,CAAC,GAAG,IAAI,CAAQ;IAW5D;;;OAGG;IACH,YAAY,MAAM,EAAE,WAAW,EAAE,KAAK,CAAC,EAAE,MAAM,IAAI,EAQlD;IAED,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKhC;IAED,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAUrB;CAkBF"}
|