typescript-virtual-container 1.2.9 → 1.3.0
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/.vscode/settings.json +0 -1
- package/README.md +141 -50
- package/biome.json +7 -0
- package/dist/SSHMimic/exec.d.ts.map +1 -1
- package/dist/SSHMimic/executor.d.ts.map +1 -1
- package/dist/SSHMimic/executor.js +32 -16
- package/dist/SSHMimic/index.d.ts.map +1 -1
- package/dist/SSHMimic/index.js +20 -6
- package/dist/VirtualFileSystem/binaryPack.d.ts.map +1 -1
- package/dist/VirtualFileSystem/binaryPack.js +29 -6
- package/dist/VirtualFileSystem/index.d.ts.map +1 -1
- package/dist/VirtualFileSystem/index.js +36 -13
- package/dist/VirtualPackageManager/index.d.ts.map +1 -1
- package/dist/VirtualPackageManager/index.js +192 -43
- package/dist/VirtualShell/index.d.ts +10 -4
- package/dist/VirtualShell/index.d.ts.map +1 -1
- package/dist/VirtualShell/index.js +18 -7
- package/dist/VirtualShell/shell.d.ts.map +1 -1
- package/dist/VirtualShell/shell.js +3 -1
- package/dist/VirtualShell/shellParser.d.ts.map +1 -1
- package/dist/VirtualUserManager/index.d.ts.map +1 -1
- package/dist/commands/adduser.d.ts +6 -0
- package/dist/commands/adduser.d.ts.map +1 -1
- package/dist/commands/adduser.js +6 -0
- package/dist/commands/alias.d.ts +5 -0
- package/dist/commands/alias.d.ts.map +1 -1
- package/dist/commands/alias.js +5 -0
- package/dist/commands/apt.d.ts +5 -0
- package/dist/commands/apt.d.ts.map +1 -1
- package/dist/commands/apt.js +32 -9
- package/dist/commands/awk.d.ts +11 -0
- package/dist/commands/awk.d.ts.map +1 -1
- package/dist/commands/awk.js +15 -2
- package/dist/commands/base64.d.ts +5 -0
- package/dist/commands/base64.d.ts.map +1 -1
- package/dist/commands/base64.js +9 -1
- package/dist/commands/cat.d.ts +5 -0
- package/dist/commands/cat.d.ts.map +1 -1
- package/dist/commands/cat.js +10 -2
- package/dist/commands/cd.d.ts +5 -0
- package/dist/commands/cd.d.ts.map +1 -1
- package/dist/commands/cd.js +5 -0
- package/dist/commands/chmod.d.ts +5 -0
- package/dist/commands/chmod.d.ts.map +1 -1
- package/dist/commands/chmod.js +5 -0
- package/dist/commands/cp.d.ts +5 -0
- package/dist/commands/cp.d.ts.map +1 -1
- package/dist/commands/cp.js +5 -0
- package/dist/commands/curl.d.ts +5 -0
- package/dist/commands/curl.d.ts.map +1 -1
- package/dist/commands/curl.js +34 -6
- package/dist/commands/cut.d.ts +5 -0
- package/dist/commands/cut.d.ts.map +1 -1
- package/dist/commands/cut.js +8 -1
- package/dist/commands/date.d.ts +5 -0
- package/dist/commands/date.d.ts.map +1 -1
- package/dist/commands/date.js +7 -1
- package/dist/commands/declare.d.ts +3 -0
- package/dist/commands/declare.d.ts.map +1 -0
- package/dist/commands/declare.js +39 -0
- package/dist/commands/diff.d.ts +5 -0
- package/dist/commands/diff.d.ts.map +1 -1
- package/dist/commands/diff.js +5 -0
- package/dist/commands/dpkg.d.ts +5 -0
- package/dist/commands/dpkg.d.ts.map +1 -1
- package/dist/commands/dpkg.js +24 -7
- package/dist/commands/du.d.ts.map +1 -1
- package/dist/commands/du.js +8 -2
- package/dist/commands/echo.d.ts +5 -0
- package/dist/commands/echo.d.ts.map +1 -1
- package/dist/commands/echo.js +13 -4
- package/dist/commands/env.d.ts +5 -0
- package/dist/commands/env.d.ts.map +1 -1
- package/dist/commands/env.js +11 -1
- package/dist/commands/exit.d.ts +5 -0
- package/dist/commands/exit.d.ts.map +1 -1
- package/dist/commands/exit.js +12 -2
- package/dist/commands/export.d.ts.map +1 -1
- package/dist/commands/export.js +3 -1
- package/dist/commands/find.d.ts +5 -0
- package/dist/commands/find.d.ts.map +1 -1
- package/dist/commands/find.js +5 -0
- package/dist/commands/free.d.ts +5 -0
- package/dist/commands/free.d.ts.map +1 -1
- package/dist/commands/free.js +5 -0
- package/dist/commands/grep.d.ts +5 -0
- package/dist/commands/grep.d.ts.map +1 -1
- package/dist/commands/grep.js +12 -2
- package/dist/commands/gzip.d.ts +5 -0
- package/dist/commands/gzip.d.ts.map +1 -1
- package/dist/commands/gzip.js +18 -2
- package/dist/commands/head.d.ts +5 -0
- package/dist/commands/head.d.ts.map +1 -1
- package/dist/commands/head.js +5 -0
- package/dist/commands/help.d.ts.map +1 -1
- package/dist/commands/help.js +98 -45
- package/dist/commands/history.d.ts +5 -0
- package/dist/commands/history.d.ts.map +1 -1
- package/dist/commands/history.js +5 -0
- package/dist/commands/hostname.d.ts +5 -0
- package/dist/commands/hostname.d.ts.map +1 -1
- package/dist/commands/hostname.js +5 -0
- package/dist/commands/id.d.ts.map +1 -1
- package/dist/commands/id.js +4 -1
- package/dist/commands/index.d.ts +2 -17
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +2 -340
- package/dist/commands/ls.d.ts.map +1 -1
- package/dist/commands/ls.js +3 -1
- package/dist/commands/lsb-release.d.ts.map +1 -1
- package/dist/commands/lsb-release.js +8 -2
- package/dist/commands/nano.js +1 -1
- package/dist/commands/neofetch.js +1 -1
- package/dist/commands/node.d.ts +9 -0
- package/dist/commands/node.d.ts.map +1 -0
- package/dist/commands/node.js +316 -0
- package/dist/commands/npm.d.ts +19 -0
- package/dist/commands/npm.d.ts.map +1 -0
- package/dist/commands/npm.js +109 -0
- package/dist/commands/ping.d.ts.map +1 -1
- package/dist/commands/ping.js +3 -1
- package/dist/commands/printf.d.ts +3 -0
- package/dist/commands/printf.d.ts.map +1 -0
- package/dist/commands/printf.js +113 -0
- package/dist/commands/ps.d.ts.map +1 -1
- package/dist/commands/ps.js +4 -1
- package/dist/commands/python.d.ts +30 -0
- package/dist/commands/python.d.ts.map +1 -0
- package/dist/commands/python.js +2058 -0
- package/dist/commands/read.d.ts +3 -0
- package/dist/commands/read.d.ts.map +1 -0
- package/dist/commands/read.js +34 -0
- package/dist/commands/registry.d.ts +8 -0
- package/dist/commands/registry.d.ts.map +1 -0
- package/dist/commands/registry.js +229 -0
- package/dist/commands/runtime.d.ts +6 -0
- package/dist/commands/runtime.d.ts.map +1 -0
- package/dist/commands/runtime.js +280 -0
- package/dist/commands/sed.d.ts.map +1 -1
- package/dist/commands/sed.js +11 -3
- package/dist/commands/set.d.ts.map +1 -1
- package/dist/commands/set.js +9 -3
- package/dist/commands/sh.d.ts.map +1 -1
- package/dist/commands/sh.js +57 -36
- package/dist/commands/shift.d.ts +5 -0
- package/dist/commands/shift.d.ts.map +1 -0
- package/dist/commands/shift.js +52 -0
- package/dist/commands/sleep.d.ts.map +1 -1
- package/dist/commands/sort.d.ts.map +1 -1
- package/dist/commands/sort.js +4 -2
- package/dist/commands/source.d.ts.map +1 -1
- package/dist/commands/source.js +5 -2
- package/dist/commands/sudo.js +1 -1
- package/dist/commands/tar.d.ts.map +1 -1
- package/dist/commands/tar.js +11 -3
- package/dist/commands/tee.d.ts.map +1 -1
- package/dist/commands/tee.js +8 -6
- package/dist/commands/test.d.ts.map +1 -1
- package/dist/commands/test.js +46 -24
- package/dist/commands/tr.d.ts.map +1 -1
- package/dist/commands/tr.js +3 -1
- package/dist/commands/true.d.ts +4 -0
- package/dist/commands/true.d.ts.map +1 -0
- package/dist/commands/true.js +14 -0
- package/dist/commands/type.d.ts.map +1 -1
- package/dist/commands/type.js +1 -1
- package/dist/commands/uname.d.ts.map +1 -1
- package/dist/commands/uname.js +4 -1
- package/dist/commands/uniq.d.ts.map +1 -1
- package/dist/commands/uptime.d.ts.map +1 -1
- package/dist/commands/uptime.js +4 -1
- package/dist/commands/wget.d.ts.map +1 -1
- package/dist/commands/wget.js +32 -7
- package/dist/commands/which.d.ts.map +1 -1
- package/dist/commands/xargs.d.ts.map +1 -1
- package/dist/commands/xargs.js +1 -1
- package/dist/index.d.ts +15 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -9
- package/dist/modules/linuxRootfs.d.ts +18 -1
- package/dist/modules/linuxRootfs.d.ts.map +1 -1
- package/dist/modules/linuxRootfs.js +160 -17
- package/dist/standalone-wo-sftp.d.ts +2 -0
- package/dist/standalone-wo-sftp.d.ts.map +1 -0
- package/dist/standalone-wo-sftp.js +30 -0
- package/dist/utils/expand.d.ts +50 -0
- package/dist/utils/expand.d.ts.map +1 -0
- package/dist/utils/expand.js +183 -0
- package/dist/utils/vfsDiff.d.ts +90 -0
- package/dist/utils/vfsDiff.d.ts.map +1 -0
- package/dist/utils/vfsDiff.js +177 -0
- package/package.json +2 -1
- package/src/SSHMimic/exec.ts +10 -1
- package/src/SSHMimic/executor.ts +104 -18
- package/src/SSHMimic/index.ts +49 -15
- package/src/VirtualFileSystem/binaryPack.ts +35 -8
- package/src/VirtualFileSystem/index.ts +78 -28
- package/src/VirtualPackageManager/index.ts +208 -49
- package/src/VirtualShell/index.ts +35 -7
- package/src/VirtualShell/shell.ts +23 -3
- package/src/VirtualShell/shellParser.ts +134 -36
- package/src/VirtualUserManager/index.ts +7 -2
- package/src/commands/adduser.ts +6 -0
- package/src/commands/alias.ts +5 -1
- package/src/commands/apt.ts +47 -17
- package/src/commands/awk.ts +20 -6
- package/src/commands/base64.ts +13 -2
- package/src/commands/cat.ts +13 -5
- package/src/commands/cd.ts +5 -0
- package/src/commands/chmod.ts +5 -0
- package/src/commands/cp.ts +5 -0
- package/src/commands/curl.ts +56 -12
- package/src/commands/cut.ts +8 -1
- package/src/commands/date.ts +7 -1
- package/src/commands/declare.ts +44 -0
- package/src/commands/diff.ts +17 -3
- package/src/commands/dpkg.ts +33 -11
- package/src/commands/du.ts +17 -5
- package/src/commands/echo.ts +22 -9
- package/src/commands/env.ts +11 -1
- package/src/commands/exit.ts +12 -2
- package/src/commands/export.ts +3 -1
- package/src/commands/find.ts +5 -0
- package/src/commands/free.ts +9 -2
- package/src/commands/grep.ts +12 -2
- package/src/commands/gzip.ts +28 -4
- package/src/commands/head.ts +5 -0
- package/src/commands/help.ts +121 -47
- package/src/commands/history.ts +7 -2
- package/src/commands/hostname.ts +5 -0
- package/src/commands/id.ts +4 -1
- package/src/commands/index.ts +9 -360
- package/src/commands/ls.ts +5 -3
- package/src/commands/lsb-release.ts +8 -2
- package/src/commands/nano.ts +1 -1
- package/src/commands/neofetch.ts +1 -1
- package/src/commands/node.ts +341 -0
- package/src/commands/npm.ts +132 -0
- package/src/commands/ping.ts +6 -2
- package/src/commands/printf.ts +112 -0
- package/src/commands/ps.ts +21 -9
- package/src/commands/python.ts +2229 -0
- package/src/commands/read.ts +41 -0
- package/src/commands/registry.ts +244 -0
- package/src/commands/runtime.ts +353 -0
- package/src/commands/sed.ts +27 -9
- package/src/commands/set.ts +9 -3
- package/src/commands/sh.ts +159 -55
- package/src/commands/shift.ts +53 -0
- package/src/commands/sleep.ts +2 -1
- package/src/commands/sort.ts +10 -6
- package/src/commands/source.ts +15 -3
- package/src/commands/sudo.ts +1 -1
- package/src/commands/tar.ts +28 -7
- package/src/commands/tee.ts +7 -1
- package/src/commands/test.ts +61 -26
- package/src/commands/tr.ts +3 -1
- package/src/commands/true.ts +17 -0
- package/src/commands/type.ts +6 -3
- package/src/commands/uname.ts +5 -1
- package/src/commands/uniq.ts +8 -2
- package/src/commands/uptime.ts +4 -1
- package/src/commands/wget.ts +51 -12
- package/src/commands/which.ts +5 -2
- package/src/commands/xargs.ts +11 -2
- package/src/index.ts +23 -24
- package/src/modules/linuxRootfs.ts +233 -30
- package/src/standalone-wo-sftp.ts +38 -0
- package/src/utils/expand.ts +238 -0
- package/src/utils/vfsDiff.ts +275 -0
- package/standalone-wo-sftp.js +507 -0
- package/standalone-wo-sftp.js.map +7 -0
- package/standalone.js +253 -191
- package/standalone.js.map +4 -4
- package/tests/bun-test-shim.ts +9 -1
- package/tests/command-helpers.test.ts +1 -5
- package/tests/new-features.test.ts +415 -5
- package/tests/parser-executor.test.ts +27 -27
- package/tests/sftp.test.ts +122 -42
- package/tests/users.test.ts +23 -5
- package/CHANGELOG.md +0 -150
package/.vscode/settings.json
CHANGED
package/README.md
CHANGED
|
@@ -2,26 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
> Pure in-memory SSH/SFTP server with a realistic Linux rootfs, a virtual package manager, a real shell interpreter, and a typed programmatic API for testing, automation, honeypots, and interactive shell scripting in TypeScript/JavaScript.
|
|
4
4
|
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
> **Release notes — what changed in this drop**
|
|
8
|
-
>
|
|
9
|
-
> **Linux rootfs** — full `/etc`, `/proc`, `/sys`, `/dev`, `/usr`, `/var` hierarchy bootstrapped at init. `neofetch` now shows real uptime and package count. `/proc/meminfo`, `/proc/cpuinfo`, `/proc/version` populated from live system data. `/etc/passwd`, `/etc/group`, `/etc/shadow` synced from `VirtualUserManager`.
|
|
10
|
-
>
|
|
11
|
-
> **Virtual package manager** — `apt install vim git nodejs python3` works. 25 packages in the built-in registry. Dependency resolution, file installation into VFS, `/var/lib/dpkg/status` persistence, `dpkg -l|-s|-L`, `apt-cache search|show|policy`. `neofetch` reflects installed count.
|
|
12
|
-
>
|
|
13
|
-
> **`curl` / `wget` — pure `fetch()`** — host binary no longer spawned. Full flag support (`-o`, `-X`, `-d`, `-H`, `-s`, `-I`, `-L`, `-v` for curl; `-O`, `-P`, `-q` for wget). Zero host filesystem access.
|
|
14
|
-
>
|
|
15
|
-
> **New commands** — `which`, `type`, `man` (with built-in pages), `uptime`, `free`, `lsb_release`, `alias`, `unalias`.
|
|
16
|
-
>
|
|
17
|
-
> **`$(cmd)` command substitution** — `echo $(whoami)`, `mkdir /tmp/$(date +%s)`, nested subs, all work.
|
|
18
|
-
>
|
|
19
|
-
> **Alias expansion** — `alias ll='ls -la'` then `ll /etc` resolves transparently in the dispatcher.
|
|
20
|
-
>
|
|
21
|
-
> *— written by Claude because explaining every change manually is a waste of everyone's time*
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
5
|
[](https://www.npmjs.com/package/typescript-virtual-container)
|
|
26
6
|
[](https://opensource.org/licenses/MIT)
|
|
27
7
|
[](https://www.typescriptlang.org/)
|
|
@@ -82,7 +62,7 @@
|
|
|
82
62
|
- **Security Auditing**: Built-in `HoneyPot` utility for comprehensive activity logging, event tracking, statistics collection, and anomaly detection across all components.
|
|
83
63
|
- **Linux rootfs on boot**: Realistic `/etc`, `/proc`, `/sys`, `/dev`, `/usr`, `/var` hierarchy populated at startup — `os-release`, `passwd`, `hosts`, `resolv.conf`, `/proc/meminfo`, `/proc/cpuinfo`, and more.
|
|
84
64
|
- **Virtual package manager**: `apt install`, `apt remove`, `apt search`, `dpkg -l`, `dpkg -s` — 25 packages in the built-in registry (vim, git, nodejs, python3, curl, openssh, gcc…). Writes files into VFS, tracks state in `/var/lib/dpkg/status`.
|
|
85
|
-
- **
|
|
65
|
+
- **87 Built-in Commands**: Full navigation, text processing, archiving, system info, package management, and user management commands — grouped and documented in the interactive `help` system.
|
|
86
66
|
- **`$(cmd)` command substitution**: Nested command execution in any argument position.
|
|
87
67
|
- **Alias support**: `alias`, `unalias` — persisted in session environment.
|
|
88
68
|
- **Full TypeScript Support**: Complete JSDoc coverage, exported types, and first-class async/await for all operations.
|
|
@@ -804,6 +784,77 @@ interface InstalledPackage {
|
|
|
804
784
|
|
|
805
785
|
---
|
|
806
786
|
|
|
787
|
+
### Snapshot Diff Tooling
|
|
788
|
+
|
|
789
|
+
Three utility functions for comparing VFS snapshots in tests and deployment verification.
|
|
790
|
+
|
|
791
|
+
```typescript
|
|
792
|
+
import {
|
|
793
|
+
diffSnapshots,
|
|
794
|
+
formatDiff,
|
|
795
|
+
assertDiff,
|
|
796
|
+
} from "typescript-virtual-container";
|
|
797
|
+
```
|
|
798
|
+
|
|
799
|
+
#### `diffSnapshots(before, after, options?): VfsDiff`
|
|
800
|
+
|
|
801
|
+
Compares two snapshots and returns structured diff results.
|
|
802
|
+
|
|
803
|
+
```ts
|
|
804
|
+
const before = shell.vfs.toSnapshot();
|
|
805
|
+
await client.exec("apt install vim && mkdir -p /app");
|
|
806
|
+
const after = shell.vfs.toSnapshot();
|
|
807
|
+
|
|
808
|
+
const diff = diffSnapshots(before, after, {
|
|
809
|
+
ignore: ["/proc", "/var/log"], // skip volatile paths
|
|
810
|
+
});
|
|
811
|
+
|
|
812
|
+
diff.clean; // false
|
|
813
|
+
diff.added; // [{ path: "/usr/bin/vim", type: "file" }, ...]
|
|
814
|
+
diff.removed; // []
|
|
815
|
+
diff.modified; // [{ path: "/var/lib/dpkg/status", before: "...", after: "..." }]
|
|
816
|
+
```
|
|
817
|
+
|
|
818
|
+
#### `formatDiff(diff, options?): string`
|
|
819
|
+
|
|
820
|
+
Human-readable output similar to `git diff --stat`.
|
|
821
|
+
|
|
822
|
+
```ts
|
|
823
|
+
console.log(formatDiff(diff));
|
|
824
|
+
// + /app [directory]
|
|
825
|
+
// + /usr/bin/vim [file]
|
|
826
|
+
// ~ /var/lib/dpkg/status [modified]
|
|
827
|
+
//
|
|
828
|
+
// 2 added, 1 modified
|
|
829
|
+
|
|
830
|
+
console.log(formatDiff(diff, { showContent: true, maxContentChars: 80 }));
|
|
831
|
+
```
|
|
832
|
+
|
|
833
|
+
#### `assertDiff(diff, expected): void`
|
|
834
|
+
|
|
835
|
+
Throws on mismatch — designed for test suites.
|
|
836
|
+
|
|
837
|
+
```ts
|
|
838
|
+
assertDiff(diff, {
|
|
839
|
+
added: ["/app", "/usr/bin/vim"],
|
|
840
|
+
modified: ["/var/lib/dpkg/status"],
|
|
841
|
+
});
|
|
842
|
+
// throws if any expected path is not in the diff
|
|
843
|
+
```
|
|
844
|
+
|
|
845
|
+
#### Types
|
|
846
|
+
|
|
847
|
+
```ts
|
|
848
|
+
interface VfsDiff {
|
|
849
|
+
added: VfsDiffEntry[]; // { path, type }
|
|
850
|
+
removed: VfsDiffEntry[]; // { path, type }
|
|
851
|
+
modified: VfsDiffModified[]; // { path, type, before, after }
|
|
852
|
+
clean: boolean;
|
|
853
|
+
}
|
|
854
|
+
```
|
|
855
|
+
|
|
856
|
+
---
|
|
857
|
+
|
|
807
858
|
### `HoneyPot`
|
|
808
859
|
|
|
809
860
|
Comprehensive security auditing and event tracking utility. Attaches listeners to all core components to log activity, track statistics, and detect anomalies.
|
|
@@ -1475,6 +1526,9 @@ On every `VirtualShell` init, a realistic Linux directory hierarchy is bootstrap
|
|
|
1475
1526
|
│ ├── resolv.conf 1.1.1.1 + 8.8.8.8
|
|
1476
1527
|
│ └── shadow (mode 0o640)
|
|
1477
1528
|
├── proc/
|
|
1529
|
+
│ ├── 1/ init process (cmdline, status, comm, environ, fd/)
|
|
1530
|
+
│ ├── <pid>/ one entry per active session (based on pts/* TTY)
|
|
1531
|
+
│ ├── self/ mirrors the most recent session's /proc/<pid>/
|
|
1478
1532
|
│ ├── cpuinfo real host CPU info
|
|
1479
1533
|
│ ├── loadavg
|
|
1480
1534
|
│ ├── meminfo real host memory
|
|
@@ -1617,6 +1671,7 @@ All commands are available in SSH shell mode and via `SshClient.exec()`. Type `h
|
|
|
1617
1671
|
| `mkdir <path>` | `-p` | Create directory |
|
|
1618
1672
|
| `mv <src> <dest>` | | Move or rename |
|
|
1619
1673
|
| `rm <path>` | `-r` | Remove file or directory |
|
|
1674
|
+
| `nano <path>` | | Interactive text editor |
|
|
1620
1675
|
| `touch <path>` | | Create or update file |
|
|
1621
1676
|
|
|
1622
1677
|
### Text Processing
|
|
@@ -1661,6 +1716,8 @@ All commands are available in SSH shell mode and via `SshClient.exec()`. Type `h
|
|
|
1661
1716
|
| `free` | `-h` `-m` `-g` | Display free and used memory |
|
|
1662
1717
|
| `lsb_release` | `-a` `-i` `-d` `-r` `-c` | Print distribution information |
|
|
1663
1718
|
| `neofetch` | | System info display (shows real packages/uptime) |
|
|
1719
|
+
| `node` | `--version` `-e` `-p` | JavaScript runtime (virtual REPL — evaluates expressions and VFS `.js` files) |
|
|
1720
|
+
| `python3` | `--version` `-c` `-V` | Python 3 interpreter (virtual REPL — evaluates expressions and VFS `.py` files); alias `python` |
|
|
1664
1721
|
| `uptime` | `-p` `-s` | Tell how long the system has been running |
|
|
1665
1722
|
| `ping [-c <n>] <host>` | | Send ICMP ECHO_REQUEST (mock) |
|
|
1666
1723
|
| `ps` | `-a` `-u` `-x` `aux` | Report process status; `-u` / `aux` shows USER/PID/%CPU/%MEM columns |
|
|
@@ -1682,20 +1739,31 @@ All commands are available in SSH shell mode and via `SshClient.exec()`. Type `h
|
|
|
1682
1739
|
|---------|-------|-------------|
|
|
1683
1740
|
| `alias [name=value]` | | Define or display aliases |
|
|
1684
1741
|
| `clear` | | Clear terminal screen (full ANSI reset) |
|
|
1685
|
-
| `
|
|
1742
|
+
| `declare [name=value]` | `-i` `-r` `-x` | Declare variables with attributes; aliases `local`, `typeset` |
|
|
1743
|
+
| `echo <text>` | `-n` `-e` | Display text; `-n` suppresses newline, `-e` interprets `\n` `\t` `\r` `\\` |
|
|
1686
1744
|
| `env` | | Print session environment variables |
|
|
1687
|
-
| `exit [code]` | | Exit session |
|
|
1745
|
+
| `exit [code]` | | Exit session with optional exit code |
|
|
1688
1746
|
| `export NAME=VALUE` | | Set shell variable in current session |
|
|
1689
|
-
| `help [command]` | | List commands
|
|
1690
|
-
| `set [VAR=val]` | | Display or set shell variables |
|
|
1691
|
-
| `sh` | `-c <script>` `[file]` | Execute shell script (supports if/for/while/do/done); `$(cmd)` substitution inside single-quoted args is preserved |
|
|
1747
|
+
| `help [command]` | | List commands grouped by category, or show usage for a specific command |
|
|
1692
1748
|
| `history [n]` | | Display command history (last N entries) |
|
|
1693
|
-
| `
|
|
1749
|
+
| `man <command>` | | Display command reference manual |
|
|
1750
|
+
| `printf <fmt> [args...]` | | Format and print data (`%s` `%d` `%f` `%x` `\n` `\t`) |
|
|
1751
|
+
| `read [-r] <var...>` | `-r` `-p` | Read a line from stdin into variable(s) |
|
|
1752
|
+
| `return [n]` | | Return from a shell function with optional exit code |
|
|
1753
|
+
| `set [VAR=val]` | | Display or set shell variables |
|
|
1754
|
+
| `sh` | `-c <script>` `[file]` | Execute shell script — supports `if`/`for`/`while`/`case`/functions, bare `VAR=val` assignments, `$((expr))` arithmetic; single-quoted args are never expanded |
|
|
1755
|
+
| `shift [n]` | | Shift positional parameters left by n (default 1) |
|
|
1756
|
+
| `source <file>` | | Execute file in current shell environment; aliases and exports persist |
|
|
1694
1757
|
| `. <file>` | | Alias for `source` |
|
|
1695
|
-
| `test <expr>` | | Evaluate conditional expression |
|
|
1696
|
-
| `[ <expr> ]` | | Alias for `test
|
|
1758
|
+
| `test <expr>` | | Evaluate POSIX conditional expression |
|
|
1759
|
+
| `[ <expr> ]` | | Alias for `test`; supports `-f` `-d` `-e` `-z` `-n` `-x` `-s` `=` `!=` `-eq` `-lt` `-gt` `-le` `-ge` `!` `-a` `-o` |
|
|
1760
|
+
| `trap [action] [signal]` | | Register handler for shell signals; supports `EXIT` |
|
|
1761
|
+
| `true` | | Return success exit code (0) |
|
|
1762
|
+
| `false` | | Return failure exit code (1) |
|
|
1763
|
+
| `type <command>` | | Describe how a command would be interpreted (builtin vs PATH) |
|
|
1697
1764
|
| `unalias <name>` | `-a` | Remove alias definitions |
|
|
1698
1765
|
| `unset <VAR>` | | Remove shell variable |
|
|
1766
|
+
| `which <command>` | | Locate a command in the session PATH |
|
|
1699
1767
|
|
|
1700
1768
|
### Package Management
|
|
1701
1769
|
|
|
@@ -1707,15 +1775,6 @@ All commands are available in SSH shell mode and via `SshClient.exec()`. Type `h
|
|
|
1707
1775
|
| `dpkg` | `-l` `-s` `-L` `-r` `-P` | Debian package manager low-level tool |
|
|
1708
1776
|
| `dpkg-query` | `-W` `-l` | Show information about installed packages |
|
|
1709
1777
|
|
|
1710
|
-
### Shell (extended)
|
|
1711
|
-
|
|
1712
|
-
| Command | Flags | Description |
|
|
1713
|
-
|---------|-------|-------------|
|
|
1714
|
-
| `alias [name=value]` | | Define or display aliases |
|
|
1715
|
-
| `man <command>` | | Display command manual page |
|
|
1716
|
-
| `type <command>` | | Describe how command is interpreted |
|
|
1717
|
-
| `unalias <name>` | `-a` | Remove alias definitions |
|
|
1718
|
-
| `which <command>` | | Locate command in PATH |
|
|
1719
1778
|
|
|
1720
1779
|
### Users & Permissions
|
|
1721
1780
|
|
|
@@ -1723,7 +1782,6 @@ All commands are available in SSH shell mode and via `SshClient.exec()`. Type `h
|
|
|
1723
1782
|
|---------|-------|-------------|
|
|
1724
1783
|
| `adduser <name> <pass>` | | Create user (root only) |
|
|
1725
1784
|
| `deluser <name>` | | Delete user (root only) |
|
|
1726
|
-
| `nano <path>` | | Interactive text editor |
|
|
1727
1785
|
| `passwd [user]` | | Change password |
|
|
1728
1786
|
| `su [user]` | | Switch user |
|
|
1729
1787
|
| `sudo <cmd>` | `-i` | Run as root |
|
|
@@ -1758,11 +1816,34 @@ cat /tmp/out.txt >> /tmp/log.txt
|
|
|
1758
1816
|
```bash
|
|
1759
1817
|
export NAME=world
|
|
1760
1818
|
echo "Hello $NAME" # Hello world
|
|
1819
|
+
echo "${NAME}" # world (braced form)
|
|
1761
1820
|
echo "${NAME:-fallback}" # world (or fallback if unset)
|
|
1762
|
-
echo "${UNSET:-default}" # default
|
|
1763
|
-
echo "
|
|
1821
|
+
echo "${UNSET:-default}" # default (assign-on-read: use ${UNSET:=default})
|
|
1822
|
+
echo "${NAME:+alternate}" # alternate (only if NAME is set)
|
|
1823
|
+
echo "${#NAME}" # 5 (string length)
|
|
1824
|
+
echo "$?" # last exit code
|
|
1825
|
+
echo "~" # /home/<user> (tilde expansion)
|
|
1826
|
+
```
|
|
1827
|
+
|
|
1828
|
+
### Arithmetic Expansion
|
|
1829
|
+
|
|
1830
|
+
```bash
|
|
1831
|
+
echo $((2 + 3)) # 5
|
|
1832
|
+
echo $((10 % 3)) # 1
|
|
1833
|
+
X=4; echo $((X * 2)) # 8
|
|
1834
|
+
i=0; i=$((i + 1)); echo $i # 1
|
|
1835
|
+
|
|
1836
|
+
# In loops (via sh):
|
|
1837
|
+
sh -c 'i=0
|
|
1838
|
+
while [ $i -lt 5 ]; do
|
|
1839
|
+
echo $i
|
|
1840
|
+
i=$((i + 1))
|
|
1841
|
+
done'
|
|
1764
1842
|
```
|
|
1765
1843
|
|
|
1844
|
+
> **Single-quote isolation** — variable and arithmetic expansion never occurs inside single quotes.
|
|
1845
|
+
> `echo '$NAME'` always outputs the literal string `$NAME`.
|
|
1846
|
+
|
|
1766
1847
|
### Conditionals
|
|
1767
1848
|
|
|
1768
1849
|
```bash
|
|
@@ -2115,13 +2196,23 @@ MIT — see [LICENSE](./LICENSE).
|
|
|
2115
2196
|
- [x] `>>` append redirect fixed — was broken because `echo` lacked terminal newline
|
|
2116
2197
|
- [x] `export A=1 && echo $A` — env vars visible to subsequent commands in same pipeline
|
|
2117
2198
|
- [x] `echo` uses session `env.vars` (not stale global store)
|
|
2118
|
-
- [
|
|
2199
|
+
- [x] `printf` — format string with `%s` `%d` `%f` `%x` `\n` `\t`
|
|
2200
|
+
- [x] `read` — read stdin into variables (supports multiple vars, splits on whitespace)
|
|
2201
|
+
- [x] `declare` / `local` / `typeset` — variable declaration with `-i` integer, `-r` readonly, `-x` export
|
|
2202
|
+
- [x] `shift [n]` — shift positional parameters
|
|
2203
|
+
- [x] `trap [action] [signal]` — signal handlers with `EXIT` support
|
|
2204
|
+
- [x] `return [n]` — return from shell functions
|
|
2205
|
+
- [x] `exit [code]` — optional exit code
|
|
2206
|
+
- [x] `help` rewrite — Package Management category, aliases shown inline, `help <cmd>` shows category
|
|
2207
|
+
- [x] Category corrections — `neofetch`→system, `nano`→files, `apt`/`dpkg`→package
|
|
2208
|
+
- [x] `src/utils/expand.ts` — centralised expansion module used by `runCommand`, `echo`, and `sh.ts`
|
|
2209
|
+
- [x] `${#VAR}` string length, `$((expr))` arithmetic, `~` tilde expansion
|
|
2210
|
+
- [x] `${VAR:=assign}` assign-on-read, `${VAR:+alternate}` alternate-if-set
|
|
2211
|
+
- [x] Single-quote isolation in expansion — `$VAR` never expanded inside `'...'`
|
|
2212
|
+
- [x] `true` / `false` builtins
|
|
2213
|
+
- [x] Bare `VAR=val` assignments in `sh` scripts (`i=0`, `i=$((i+1))`)
|
|
2214
|
+
- [x] `$?` reflects last command exit code correctly across `&&` / `;` chains
|
|
2215
|
+
- [x] `node` / `python3` virtual REPL stubs — `node -e`, `node <file>`, `python3 -c`, `python3 <file>`, `--version` flags
|
|
2216
|
+
- [x] `/proc/self` and `/proc/<pid>` per-session process entries — `comm`, `status`, `cmdline`, `environ`, `cwd`, `exe`, `fd/`
|
|
2217
|
+
- [x] Snapshot diff tooling — `diffSnapshots()`, `formatDiff()`, `assertDiff()` exported from `typescript-virtual-container`
|
|
2119
2218
|
- [ ] WebSocket-based remote shell client (experimental)
|
|
2120
|
-
- [ ] Package stubs that simulate REPL behavior (node, python3)
|
|
2121
|
-
- [ ] `/proc/self` and `/proc/<pid>` per-session process entries
|
|
2122
|
-
|
|
2123
|
-
---
|
|
2124
|
-
|
|
2125
|
-
## Changelog
|
|
2126
|
-
|
|
2127
|
-
See [CHANGELOG.md](./CHANGELOG.md).
|
package/biome.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../../src/SSHMimic/exec.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AASpD,wBAAgB,OAAO,CACtB,MAAM,EAAE,UAAU,EAClB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,YAAY,GACjB,IAAI,
|
|
1
|
+
{"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../../src/SSHMimic/exec.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AASpD,wBAAgB,OAAO,CACtB,MAAM,EAAE,UAAU,EAClB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,YAAY,GACjB,IAAI,CAgCN"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/SSHMimic/executor.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC9E,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/SSHMimic/executor.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC9E,OAAO,KAAK,EACX,QAAQ,EAER,MAAM,EACN,SAAS,EACT,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAIpD,wBAAsB,aAAa,CAClC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,WAAW,EACjB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,YAAY,EACnB,GAAG,EAAE,QAAQ,GACX,OAAO,CAAC,aAAa,CAAC,CA8BxB;AAED,8CAA8C;AAC9C,wBAAsB,iBAAiB,CACtC,UAAU,EAAE,SAAS,EAAE,EACvB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,WAAW,EACjB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,YAAY,EACnB,GAAG,EAAE,QAAQ,GACX,OAAO,CAAC,aAAa,CAAC,CAoCxB;AAID,wBAAsB,eAAe,CACpC,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,WAAW,EACjB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,YAAY,EACnB,GAAG,CAAC,EAAE,QAAQ,GACZ,OAAO,CAAC,aAAa,CAAC,CA4BxB"}
|
|
@@ -10,7 +10,9 @@ export async function executeScript(script, authUser, hostname, mode, cwd, shell
|
|
|
10
10
|
lastResult = await executePipeline(stmt.pipeline, authUser, hostname, mode, cwd, shell, env);
|
|
11
11
|
env.lastExitCode = lastResult.exitCode ?? 0;
|
|
12
12
|
// Propagate session-control signals
|
|
13
|
-
if (lastResult.closeSession ||
|
|
13
|
+
if (lastResult.closeSession ||
|
|
14
|
+
lastResult.switchUser ||
|
|
15
|
+
lastResult.nextCwd) {
|
|
14
16
|
break;
|
|
15
17
|
}
|
|
16
18
|
}
|
|
@@ -68,7 +70,10 @@ async function executeSingleCommandWithRedirections(cmd, authUser, hostname, mod
|
|
|
68
70
|
stdin = shell.vfs.readFile(inputPath);
|
|
69
71
|
}
|
|
70
72
|
catch {
|
|
71
|
-
return {
|
|
73
|
+
return {
|
|
74
|
+
stderr: `${cmd.inputFile}: No such file or directory`,
|
|
75
|
+
exitCode: 1,
|
|
76
|
+
};
|
|
72
77
|
}
|
|
73
78
|
}
|
|
74
79
|
const result = await runCommandDirect(cmd.name, cmd.args, authUser, hostname, mode, cwd, shell, stdin, env);
|
|
@@ -77,12 +82,14 @@ async function executeSingleCommandWithRedirections(cmd, authUser, hostname, mod
|
|
|
77
82
|
const output = result.stdout || "";
|
|
78
83
|
try {
|
|
79
84
|
if (cmd.appendOutput) {
|
|
80
|
-
const existing = (() => {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
85
|
+
const existing = (() => {
|
|
86
|
+
try {
|
|
87
|
+
return shell.vfs.readFile(outputPath);
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return "";
|
|
91
|
+
}
|
|
92
|
+
})();
|
|
86
93
|
shell.writeFileAsUser(authUser, outputPath, existing + output);
|
|
87
94
|
}
|
|
88
95
|
else {
|
|
@@ -91,7 +98,11 @@ async function executeSingleCommandWithRedirections(cmd, authUser, hostname, mod
|
|
|
91
98
|
return { ...result, stdout: "" };
|
|
92
99
|
}
|
|
93
100
|
catch {
|
|
94
|
-
return {
|
|
101
|
+
return {
|
|
102
|
+
...result,
|
|
103
|
+
stderr: `Failed to write to ${cmd.outputFile}`,
|
|
104
|
+
exitCode: 1,
|
|
105
|
+
};
|
|
95
106
|
}
|
|
96
107
|
}
|
|
97
108
|
return result;
|
|
@@ -107,7 +118,10 @@ async function executePipelineChain(commands, authUser, hostname, mode, cwd, she
|
|
|
107
118
|
currentOutput = shell.vfs.readFile(inputPath);
|
|
108
119
|
}
|
|
109
120
|
catch {
|
|
110
|
-
return {
|
|
121
|
+
return {
|
|
122
|
+
stderr: `${cmd.inputFile}: No such file or directory`,
|
|
123
|
+
exitCode: 1,
|
|
124
|
+
};
|
|
111
125
|
}
|
|
112
126
|
}
|
|
113
127
|
const result = await runCommandDirect(cmd.name, cmd.args, authUser, hostname, mode, cwd, shell, currentOutput, env);
|
|
@@ -117,12 +131,14 @@ async function executePipelineChain(commands, authUser, hostname, mode, cwd, she
|
|
|
117
131
|
const output = result.stdout || "";
|
|
118
132
|
try {
|
|
119
133
|
if (cmd.appendOutput) {
|
|
120
|
-
const existing = (() => {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
134
|
+
const existing = (() => {
|
|
135
|
+
try {
|
|
136
|
+
return shell.vfs.readFile(outputPath);
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
return "";
|
|
140
|
+
}
|
|
141
|
+
})();
|
|
126
142
|
shell.writeFileAsUser(authUser, outputPath, existing + output);
|
|
127
143
|
}
|
|
128
144
|
else {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/SSHMimic/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AA0B/C,cAAM,QAAS,SAAQ,YAAY;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,KAAK,CAAe;IAE5B,mEAAmE;IACnE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,2DAA2D;IAC3D,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqC;IAElE;;;;;;;;OAQG;gBACS,EACX,IAAI,EACJ,QAA0B,EAC1B,KAAkC,EAClC,eAAmB,EACnB,iBAA0B,GAC1B,EAAE;QACF,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,YAAY,CAAC;QACrB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC3B;IAYD,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,aAAa;IAcrB;;;;OAIG;IACU,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/SSHMimic/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AA0B/C,cAAM,QAAS,SAAQ,YAAY;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,KAAK,CAAe;IAE5B,mEAAmE;IACnE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,2DAA2D;IAC3D,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqC;IAElE;;;;;;;;OAQG;gBACS,EACX,IAAI,EACJ,QAA0B,EAC1B,KAAkC,EAClC,eAAmB,EACnB,iBAA0B,GAC1B,EAAE;QACF,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,YAAY,CAAC;QACrB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC3B;IAYD,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,aAAa;IAcrB;;;;OAIG;IACU,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IA6LrC;;OAEG;IACI,IAAI,IAAI,IAAI;IAUnB;;;OAGG;IACI,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;CAGrC;AAED,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EAAE,QAAQ,EAAE,CAAC"}
|
package/dist/SSHMimic/index.js
CHANGED
|
@@ -103,7 +103,11 @@ class SshMimic extends EventEmitter {
|
|
|
103
103
|
remoteAddress = ctx.ip ?? remoteAddress;
|
|
104
104
|
// Rate-limit check
|
|
105
105
|
if (this.isLockedOut(remoteAddress)) {
|
|
106
|
-
this.emit("auth:failure", {
|
|
106
|
+
this.emit("auth:failure", {
|
|
107
|
+
username: candidateUser,
|
|
108
|
+
remoteAddress,
|
|
109
|
+
reason: "lockout",
|
|
110
|
+
});
|
|
107
111
|
ctx.reject();
|
|
108
112
|
return;
|
|
109
113
|
}
|
|
@@ -123,7 +127,10 @@ class SshMimic extends EventEmitter {
|
|
|
123
127
|
ctx.password === "" ||
|
|
124
128
|
!shell.users.verifyPassword(candidateUser, ctx.password)) {
|
|
125
129
|
this.recordFailure(remoteAddress);
|
|
126
|
-
this.emit("auth:failure", {
|
|
130
|
+
this.emit("auth:failure", {
|
|
131
|
+
username: candidateUser,
|
|
132
|
+
remoteAddress,
|
|
133
|
+
});
|
|
127
134
|
ctx.reject();
|
|
128
135
|
return;
|
|
129
136
|
}
|
|
@@ -144,11 +151,14 @@ class SshMimic extends EventEmitter {
|
|
|
144
151
|
return;
|
|
145
152
|
}
|
|
146
153
|
const incomingKey = ctx.key;
|
|
147
|
-
const keyMatches = authorizedKeys.some((k) => k.algo === incomingKey.algo &&
|
|
148
|
-
k.data.equals(incomingKey.data));
|
|
154
|
+
const keyMatches = authorizedKeys.some((k) => k.algo === incomingKey.algo && k.data.equals(incomingKey.data));
|
|
149
155
|
if (!keyMatches) {
|
|
150
156
|
this.recordFailure(remoteAddress);
|
|
151
|
-
this.emit("auth:failure", {
|
|
157
|
+
this.emit("auth:failure", {
|
|
158
|
+
username: candidateUser,
|
|
159
|
+
remoteAddress,
|
|
160
|
+
method: "publickey",
|
|
161
|
+
});
|
|
152
162
|
ctx.reject();
|
|
153
163
|
return;
|
|
154
164
|
}
|
|
@@ -157,7 +167,11 @@ class SshMimic extends EventEmitter {
|
|
|
157
167
|
authUser = candidateUser;
|
|
158
168
|
sessionId = shell.users.registerSession(authUser, remoteAddress).id;
|
|
159
169
|
this.recordSuccess(remoteAddress);
|
|
160
|
-
this.emit("auth:success", {
|
|
170
|
+
this.emit("auth:success", {
|
|
171
|
+
username: authUser,
|
|
172
|
+
remoteAddress,
|
|
173
|
+
method: "publickey",
|
|
174
|
+
});
|
|
161
175
|
this.ensureHomeDir(authUser);
|
|
162
176
|
ctx.accept();
|
|
163
177
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"binaryPack.d.ts","sourceRoot":"","sources":["../../src/VirtualFileSystem/binaryPack.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"binaryPack.d.ts","sourceRoot":"","sources":["../../src/VirtualFileSystem/binaryPack.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,EACX,qBAAqB,EAGrB,MAAM,iBAAiB,CAAC;AA+EzB;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,qBAAqB,GAAG,MAAM,CAM7D;AA0FD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,qBAAqB,CAiB5D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAErD"}
|
|
@@ -37,7 +37,9 @@ const TYPE_DIR = 0x02;
|
|
|
37
37
|
// ── Encoder ───────────────────────────────────────────────────────────────────
|
|
38
38
|
class Encoder {
|
|
39
39
|
chunks = [];
|
|
40
|
-
write(buf) {
|
|
40
|
+
write(buf) {
|
|
41
|
+
this.chunks.push(buf);
|
|
42
|
+
}
|
|
41
43
|
writeUint8(n) {
|
|
42
44
|
const b = Buffer.allocUnsafe(1);
|
|
43
45
|
b.writeUInt8(n, 0);
|
|
@@ -67,7 +69,9 @@ class Encoder {
|
|
|
67
69
|
this.writeUint32(bytes.length);
|
|
68
70
|
this.chunks.push(bytes);
|
|
69
71
|
}
|
|
70
|
-
toBuffer() {
|
|
72
|
+
toBuffer() {
|
|
73
|
+
return Buffer.concat(this.chunks);
|
|
74
|
+
}
|
|
71
75
|
}
|
|
72
76
|
function encodeNode(enc, node) {
|
|
73
77
|
if (node.type === "file") {
|
|
@@ -111,7 +115,9 @@ class Decoder {
|
|
|
111
115
|
constructor(buf) {
|
|
112
116
|
this.buf = buf;
|
|
113
117
|
}
|
|
114
|
-
readUint8() {
|
|
118
|
+
readUint8() {
|
|
119
|
+
return this.buf.readUInt8(this.pos++);
|
|
120
|
+
}
|
|
115
121
|
readUint16() {
|
|
116
122
|
const v = this.buf.readUInt16LE(this.pos);
|
|
117
123
|
this.pos += 2;
|
|
@@ -139,7 +145,9 @@ class Decoder {
|
|
|
139
145
|
this.pos += len;
|
|
140
146
|
return b;
|
|
141
147
|
}
|
|
142
|
-
remaining() {
|
|
148
|
+
remaining() {
|
|
149
|
+
return this.buf.length - this.pos;
|
|
150
|
+
}
|
|
143
151
|
}
|
|
144
152
|
function decodeNode(dec) {
|
|
145
153
|
const type = dec.readUint8();
|
|
@@ -150,7 +158,15 @@ function decodeNode(dec) {
|
|
|
150
158
|
if (type === TYPE_FILE) {
|
|
151
159
|
const compressed = dec.readUint8() === 0x01;
|
|
152
160
|
const content = dec.readBytes();
|
|
153
|
-
return {
|
|
161
|
+
return {
|
|
162
|
+
type: "file",
|
|
163
|
+
name,
|
|
164
|
+
mode,
|
|
165
|
+
createdAt,
|
|
166
|
+
updatedAt,
|
|
167
|
+
compressed,
|
|
168
|
+
content,
|
|
169
|
+
};
|
|
154
170
|
}
|
|
155
171
|
if (type === TYPE_DIR) {
|
|
156
172
|
const count = dec.readUint32();
|
|
@@ -159,7 +175,14 @@ function decodeNode(dec) {
|
|
|
159
175
|
const child = decodeNode(dec);
|
|
160
176
|
children.set(child.name, child);
|
|
161
177
|
}
|
|
162
|
-
return {
|
|
178
|
+
return {
|
|
179
|
+
type: "directory",
|
|
180
|
+
name,
|
|
181
|
+
mode,
|
|
182
|
+
createdAt,
|
|
183
|
+
updatedAt,
|
|
184
|
+
children,
|
|
185
|
+
};
|
|
163
186
|
}
|
|
164
187
|
throw new Error(`[VFS binary] Unknown node type: 0x${type.toString(16)}`);
|
|
165
188
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/VirtualFileSystem/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAW3C,OAAO,KAAK,EACX,aAAa,EACb,YAAY,EACZ,WAAW,EAIX,gBAAgB,EAChB,MAAM,cAAc,CAAC;AAItB;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,IAAI,CAAC;AAEjD,MAAM,WAAW,UAAU;IAC1B;;;;;OAKG;IACH,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAC1B;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAID;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,cAAM,iBAAkB,SAAQ,YAAY;IAC3C,OAAO,CAAC,IAAI,CAAwB;IACpC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAqB;IAC1C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAgB;gBAEjC,OAAO,GAAE,UAAe;IAqBpC,OAAO,CAAC,OAAO;IAYf,OAAO,CAAC,QAAQ;IAkBhB,OAAO,CAAC,cAAc;IAwBtB;;;;;;OAMG;IACU,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/VirtualFileSystem/index.ts"],"names":[],"mappings":"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"}
|