typescript-virtual-container 1.4.4 → 1.4.6
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/README.md +1 -1
- package/builds/self-standalone.js +321 -272
- package/builds/self-standalone.js.map +4 -4
- package/builds/standalone-wo-sftp.js +262 -212
- package/builds/standalone-wo-sftp.js.map +4 -4
- package/builds/standalone.cjs +491 -0
- package/builds/standalone.cjs.map +7 -0
- package/builds/standalone.js +266 -216
- package/builds/standalone.js.map +4 -4
- package/builds/web-full-api.min.js +5 -5
- package/builds/web-full-api.min.js.map +3 -3
- package/builds/web.min.js +5 -5
- package/builds/web.min.js.map +3 -3
- package/bun.lock +97 -0
- package/dist/Honeypot/index.d.ts.map +1 -0
- package/dist/Honeypot/index.js +299 -0
- package/dist/Honeypot/index.js.map +1 -0
- package/dist/SSHClient/index.d.ts.map +1 -0
- package/dist/SSHClient/index.js +238 -0
- package/dist/SSHClient/index.js.map +1 -0
- package/dist/SSHMimic/exec.d.ts.map +1 -0
- package/dist/SSHMimic/exec.js +28 -0
- package/dist/SSHMimic/exec.js.map +1 -0
- package/dist/SSHMimic/executor.d.ts.map +1 -0
- package/dist/SSHMimic/executor.js +161 -0
- package/dist/SSHMimic/executor.js.map +1 -0
- package/dist/SSHMimic/hostKey.d.ts.map +1 -0
- package/dist/SSHMimic/hostKey.js +18 -0
- package/dist/SSHMimic/hostKey.js.map +1 -0
- package/dist/SSHMimic/index.d.ts.map +1 -0
- package/dist/SSHMimic/index.js +250 -0
- package/dist/SSHMimic/index.js.map +1 -0
- package/dist/SSHMimic/loginBanner.d.ts.map +1 -0
- package/dist/SSHMimic/loginBanner.js +23 -0
- package/dist/SSHMimic/loginBanner.js.map +1 -0
- package/dist/SSHMimic/loginFormat.d.ts.map +1 -0
- package/dist/SSHMimic/loginFormat.js +11 -0
- package/dist/SSHMimic/loginFormat.js.map +1 -0
- package/dist/SSHMimic/prompt.d.ts.map +1 -0
- package/dist/SSHMimic/prompt.js +10 -0
- package/dist/SSHMimic/prompt.js.map +1 -0
- package/dist/SSHMimic/sftp.d.ts.map +1 -0
- package/dist/SSHMimic/sftp.js +620 -0
- package/dist/SSHMimic/sftp.js.map +1 -0
- package/dist/VirtualFileSystem/binaryPack.d.ts.map +1 -0
- package/dist/VirtualFileSystem/binaryPack.js +217 -0
- package/dist/VirtualFileSystem/binaryPack.js.map +1 -0
- package/dist/VirtualFileSystem/index.d.ts.map +1 -0
- package/dist/VirtualFileSystem/index.js +690 -0
- package/dist/VirtualFileSystem/index.js.map +1 -0
- package/dist/VirtualFileSystem/internalTypes.d.ts.map +1 -0
- package/dist/VirtualFileSystem/internalTypes.js +1 -0
- package/dist/VirtualFileSystem/internalTypes.js.map +1 -0
- package/dist/VirtualFileSystem/path.d.ts.map +1 -0
- package/dist/VirtualFileSystem/path.js +50 -0
- package/dist/VirtualFileSystem/path.js.map +1 -0
- package/dist/VirtualPackageManager/index.d.ts.map +1 -0
- package/dist/VirtualPackageManager/index.js +854 -0
- package/dist/VirtualPackageManager/index.js.map +1 -0
- package/dist/VirtualShell/index.d.ts.map +1 -0
- package/dist/VirtualShell/index.js +285 -0
- package/dist/VirtualShell/index.js.map +1 -0
- package/dist/VirtualShell/shell.d.ts.map +1 -0
- package/dist/VirtualShell/shell.js +503 -0
- package/dist/VirtualShell/shell.js.map +1 -0
- package/dist/VirtualShell/shellParser.d.ts.map +1 -0
- package/dist/VirtualShell/shellParser.js +266 -0
- package/dist/VirtualShell/shellParser.js.map +1 -0
- package/dist/VirtualUserManager/index.d.ts.map +1 -0
- package/dist/VirtualUserManager/index.js +608 -0
- package/dist/VirtualUserManager/index.js.map +1 -0
- package/dist/commands/adduser.d.ts.map +1 -0
- package/dist/commands/adduser.js +90 -0
- package/dist/commands/adduser.js.map +1 -0
- package/dist/commands/alias.d.ts.map +1 -0
- package/dist/commands/alias.js +69 -0
- package/dist/commands/alias.js.map +1 -0
- package/dist/commands/apt.d.ts.map +1 -0
- package/dist/commands/apt.js +211 -0
- package/dist/commands/apt.js.map +1 -0
- package/dist/commands/awk.d.ts.map +1 -0
- package/dist/commands/awk.js +170 -0
- package/dist/commands/awk.js.map +1 -0
- package/dist/commands/base64.d.ts.map +1 -0
- package/dist/commands/base64.js +29 -0
- package/dist/commands/base64.js.map +1 -0
- package/dist/commands/cat.d.ts.map +1 -0
- package/dist/commands/cat.js +45 -0
- package/dist/commands/cat.js.map +1 -0
- package/dist/commands/cd.d.ts.map +1 -0
- package/dist/commands/cd.js +22 -0
- package/dist/commands/cd.js.map +1 -0
- package/dist/commands/chmod.d.ts.map +1 -0
- package/dist/commands/chmod.js +88 -0
- package/dist/commands/chmod.js.map +1 -0
- package/dist/commands/clear.d.ts.map +1 -0
- package/dist/commands/clear.js +14 -0
- package/dist/commands/clear.js.map +1 -0
- package/dist/commands/command-helpers.d.ts.map +1 -0
- package/dist/commands/command-helpers.js +222 -0
- package/dist/commands/command-helpers.js.map +1 -0
- package/dist/commands/cp.d.ts.map +1 -0
- package/dist/commands/cp.js +76 -0
- package/dist/commands/cp.js.map +1 -0
- package/dist/commands/curl.d.ts.map +1 -0
- package/dist/commands/curl.js +128 -0
- package/dist/commands/curl.js.map +1 -0
- package/dist/commands/cut.d.ts.map +1 -0
- package/dist/commands/cut.js +35 -0
- package/dist/commands/cut.js.map +1 -0
- package/dist/commands/date.d.ts.map +1 -0
- package/dist/commands/date.js +29 -0
- package/dist/commands/date.js.map +1 -0
- package/dist/commands/declare.d.ts.map +1 -0
- package/dist/commands/declare.js +45 -0
- package/dist/commands/declare.js.map +1 -0
- package/dist/commands/deluser.d.ts.map +1 -0
- package/dist/commands/deluser.js +84 -0
- package/dist/commands/deluser.js.map +1 -0
- package/dist/commands/df.d.ts.map +1 -0
- package/dist/commands/df.js +22 -0
- package/dist/commands/df.js.map +1 -0
- package/dist/commands/diff.d.ts.map +1 -0
- package/dist/commands/diff.js +46 -0
- package/dist/commands/diff.js.map +1 -0
- package/dist/commands/dpkg.d.ts.map +1 -0
- package/dist/commands/dpkg.js +162 -0
- package/dist/commands/dpkg.js.map +1 -0
- package/dist/commands/du.d.ts.map +1 -0
- package/dist/commands/du.js +51 -0
- package/dist/commands/du.js.map +1 -0
- package/dist/commands/echo.d.ts.map +1 -0
- package/dist/commands/echo.js +46 -0
- package/dist/commands/echo.js.map +1 -0
- package/dist/commands/env.d.ts.map +1 -0
- package/dist/commands/env.js +21 -0
- package/dist/commands/env.js.map +1 -0
- package/dist/commands/exit.d.ts.map +1 -0
- package/dist/commands/exit.js +17 -0
- package/dist/commands/exit.js.map +1 -0
- package/dist/commands/export.d.ts.map +1 -0
- package/dist/commands/export.js +34 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/find.d.ts.map +1 -0
- package/dist/commands/find.js +56 -0
- package/dist/commands/find.js.map +1 -0
- package/dist/commands/free.d.ts.map +1 -0
- package/dist/commands/free.js +44 -0
- package/dist/commands/free.js.map +1 -0
- package/dist/commands/grep.d.ts.map +1 -0
- package/dist/commands/grep.js +121 -0
- package/dist/commands/grep.js.map +1 -0
- package/dist/commands/groups.d.ts.map +1 -0
- package/dist/commands/groups.js +18 -0
- package/dist/commands/groups.js.map +1 -0
- package/dist/commands/gzip.d.ts.map +1 -0
- package/dist/commands/gzip.js +83 -0
- package/dist/commands/gzip.js.map +1 -0
- package/dist/commands/head.d.ts.map +1 -0
- package/dist/commands/head.js +47 -0
- package/dist/commands/head.js.map +1 -0
- package/dist/commands/help.d.ts.map +1 -0
- package/dist/commands/help.js +124 -0
- package/dist/commands/help.js.map +1 -0
- package/dist/commands/helpers.d.ts.map +1 -0
- package/dist/commands/helpers.js +167 -0
- package/dist/commands/helpers.js.map +1 -0
- package/dist/commands/history.d.ts.map +1 -0
- package/dist/commands/history.js +27 -0
- package/dist/commands/history.js.map +1 -0
- package/dist/commands/hostname.d.ts.map +1 -0
- package/dist/commands/hostname.js +13 -0
- package/dist/commands/hostname.js.map +1 -0
- package/dist/commands/htop.d.ts.map +1 -0
- package/dist/commands/htop.js +18 -0
- package/dist/commands/htop.js.map +1 -0
- package/dist/commands/id.d.ts.map +1 -0
- package/dist/commands/id.js +18 -0
- package/dist/commands/id.js.map +1 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +3 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/kill.d.ts.map +1 -0
- package/dist/commands/kill.js +19 -0
- package/dist/commands/kill.js.map +1 -0
- package/dist/commands/ln.d.ts.map +1 -0
- package/dist/commands/ln.js +67 -0
- package/dist/commands/ln.js.map +1 -0
- package/dist/commands/ls.d.ts.map +1 -0
- package/dist/commands/ls.js +201 -0
- package/dist/commands/ls.js.map +1 -0
- package/dist/commands/lsb-release.d.ts.map +1 -0
- package/dist/commands/lsb-release.js +62 -0
- package/dist/commands/lsb-release.js.map +1 -0
- package/dist/commands/man.d.ts.map +1 -0
- package/dist/commands/man.js +50 -0
- package/dist/commands/man.js.map +1 -0
- package/dist/commands/mkdir.d.ts.map +1 -0
- package/dist/commands/mkdir.js +29 -0
- package/dist/commands/mkdir.js.map +1 -0
- package/dist/commands/mv.d.ts.map +1 -0
- package/dist/commands/mv.js +43 -0
- package/dist/commands/mv.js.map +1 -0
- package/dist/commands/nano.d.ts.map +1 -0
- package/dist/commands/nano.js +35 -0
- package/dist/commands/nano.js.map +1 -0
- package/dist/commands/neofetch.d.ts.map +1 -0
- package/dist/commands/neofetch.js +49 -0
- package/dist/commands/neofetch.js.map +1 -0
- package/dist/commands/node.d.ts.map +1 -0
- package/dist/commands/node.js +317 -0
- package/dist/commands/node.js.map +1 -0
- package/dist/commands/npm.d.ts.map +1 -0
- package/dist/commands/npm.js +110 -0
- package/dist/commands/npm.js.map +1 -0
- package/dist/commands/passwd.d.ts.map +1 -0
- package/dist/commands/passwd.js +45 -0
- package/dist/commands/passwd.js.map +1 -0
- package/dist/commands/ping.d.ts.map +1 -0
- package/dist/commands/ping.js +29 -0
- package/dist/commands/ping.js.map +1 -0
- package/dist/commands/printf.d.ts.map +1 -0
- package/dist/commands/printf.js +145 -0
- package/dist/commands/printf.js.map +1 -0
- package/dist/commands/ps.d.ts.map +1 -0
- package/dist/commands/ps.js +47 -0
- package/dist/commands/ps.js.map +1 -0
- package/dist/commands/pwd.d.ts.map +1 -0
- package/dist/commands/pwd.js +8 -0
- package/dist/commands/pwd.js.map +1 -0
- package/dist/commands/python.d.ts.map +1 -0
- package/dist/commands/python.js +2059 -0
- package/dist/commands/python.js.map +1 -0
- package/dist/commands/read.d.ts.map +1 -0
- package/dist/commands/read.js +40 -0
- package/dist/commands/read.js.map +1 -0
- package/dist/commands/registry.d.ts.map +1 -0
- package/dist/commands/registry.js +235 -0
- package/dist/commands/registry.js.map +1 -0
- package/dist/commands/rm.d.ts.map +1 -0
- package/dist/commands/rm.js +37 -0
- package/dist/commands/rm.js.map +1 -0
- package/dist/commands/runtime.d.ts.map +1 -0
- package/dist/commands/runtime.js +286 -0
- package/dist/commands/runtime.js.map +1 -0
- package/dist/commands/sed.d.ts.map +1 -0
- package/dist/commands/sed.js +61 -0
- package/dist/commands/sed.js.map +1 -0
- package/dist/commands/seq.d.ts.map +1 -0
- package/dist/commands/seq.js +51 -0
- package/dist/commands/seq.js.map +1 -0
- package/dist/commands/set.d.ts.map +1 -0
- package/dist/commands/set.js +27 -0
- package/dist/commands/set.js.map +1 -0
- package/dist/commands/sh.d.ts.map +1 -0
- package/dist/commands/sh.js +432 -0
- package/dist/commands/sh.js.map +1 -0
- package/dist/commands/shift.d.ts.map +1 -0
- package/dist/commands/shift.js +63 -0
- package/dist/commands/shift.js.map +1 -0
- package/dist/commands/sleep.d.ts.map +1 -0
- package/dist/commands/sleep.js +19 -0
- package/dist/commands/sleep.js.map +1 -0
- package/dist/commands/sort.d.ts.map +1 -0
- package/dist/commands/sort.js +45 -0
- package/dist/commands/sort.js.map +1 -0
- package/dist/commands/source.d.ts.map +1 -0
- package/dist/commands/source.js +40 -0
- package/dist/commands/source.js.map +1 -0
- package/dist/commands/stat.d.ts.map +1 -0
- package/dist/commands/stat.js +57 -0
- package/dist/commands/stat.js.map +1 -0
- package/dist/commands/su.d.ts.map +1 -0
- package/dist/commands/su.js +58 -0
- package/dist/commands/su.js.map +1 -0
- package/dist/commands/sudo.d.ts.map +1 -0
- package/dist/commands/sudo.js +55 -0
- package/dist/commands/sudo.js.map +1 -0
- package/dist/commands/tail.d.ts.map +1 -0
- package/dist/commands/tail.js +48 -0
- package/dist/commands/tail.js.map +1 -0
- package/dist/commands/tar.d.ts.map +1 -0
- package/dist/commands/tar.js +103 -0
- package/dist/commands/tar.js.map +1 -0
- package/dist/commands/tee.d.ts.map +1 -0
- package/dist/commands/tee.js +37 -0
- package/dist/commands/tee.js.map +1 -0
- package/dist/commands/test.d.ts.map +1 -0
- package/dist/commands/test.js +115 -0
- package/dist/commands/test.js.map +1 -0
- package/dist/commands/touch.d.ts.map +1 -0
- package/dist/commands/touch.js +26 -0
- package/dist/commands/touch.js.map +1 -0
- package/dist/commands/tr.d.ts.map +1 -0
- package/dist/commands/tr.js +62 -0
- package/dist/commands/tr.js.map +1 -0
- package/dist/commands/tree.d.ts.map +1 -0
- package/dist/commands/tree.js +19 -0
- package/dist/commands/tree.js.map +1 -0
- package/dist/commands/true.d.ts.map +1 -0
- package/dist/commands/true.js +25 -0
- package/dist/commands/true.js.map +1 -0
- package/dist/commands/type.d.ts.map +1 -0
- package/dist/commands/type.js +40 -0
- package/dist/commands/type.js.map +1 -0
- package/dist/commands/uname.d.ts.map +1 -0
- package/dist/commands/uname.js +30 -0
- package/dist/commands/uname.js.map +1 -0
- package/dist/commands/uniq.d.ts.map +1 -0
- package/dist/commands/uniq.js +39 -0
- package/dist/commands/uniq.js.map +1 -0
- package/dist/commands/unset.d.ts.map +1 -0
- package/dist/commands/unset.js +17 -0
- package/dist/commands/unset.js.map +1 -0
- package/dist/commands/uptime.d.ts.map +1 -0
- package/dist/commands/uptime.js +49 -0
- package/dist/commands/uptime.js.map +1 -0
- package/dist/commands/wc.d.ts.map +1 -0
- package/dist/commands/wc.js +56 -0
- package/dist/commands/wc.js.map +1 -0
- package/dist/commands/wget.d.ts.map +1 -0
- package/dist/commands/wget.js +127 -0
- package/dist/commands/wget.js.map +1 -0
- package/dist/commands/which.d.ts.map +1 -0
- package/dist/commands/which.js +33 -0
- package/dist/commands/which.js.map +1 -0
- package/dist/commands/who.d.ts.map +1 -0
- package/dist/commands/who.js +23 -0
- package/dist/commands/who.js.map +1 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/commands/whoami.js +13 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/commands/xargs.d.ts.map +1 -0
- package/dist/commands/xargs.js +22 -0
- package/dist/commands/xargs.js.map +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/modules/linuxRootfs.d.ts.map +1 -0
- package/dist/modules/linuxRootfs.js +620 -0
- package/dist/modules/linuxRootfs.js.map +1 -0
- package/dist/modules/neofetch.d.ts.map +1 -0
- package/dist/modules/neofetch.js +285 -0
- package/dist/modules/neofetch.js.map +1 -0
- package/dist/modules/shellInteractive.d.ts.map +1 -0
- package/dist/modules/shellInteractive.js +27 -0
- package/dist/modules/shellInteractive.js.map +1 -0
- package/dist/modules/shellRuntime.d.ts.map +1 -0
- package/dist/modules/shellRuntime.js +53 -0
- package/dist/modules/shellRuntime.js.map +1 -0
- package/dist/self-standalone.d.ts.map +1 -0
- package/dist/self-standalone.js +420 -0
- package/dist/self-standalone.js.map +1 -0
- package/dist/standalone-wo-sftp.d.ts.map +1 -0
- package/dist/standalone-wo-sftp.js +31 -0
- package/dist/standalone-wo-sftp.js.map +1 -0
- package/dist/standalone.d.ts.map +1 -0
- package/dist/standalone.js +40 -0
- package/dist/standalone.js.map +1 -0
- package/dist/types/commands.d.ts.map +1 -0
- package/dist/types/commands.js +1 -0
- package/dist/types/commands.js.map +1 -0
- package/dist/types/pipeline.d.ts.map +1 -0
- package/dist/types/pipeline.js +1 -0
- package/dist/types/pipeline.js.map +1 -0
- package/dist/types/streams.d.ts.map +1 -0
- package/dist/types/streams.js +1 -0
- package/dist/types/streams.js.map +1 -0
- package/dist/types/vfs.d.ts.map +1 -0
- package/dist/types/vfs.js +1 -0
- package/dist/types/vfs.js.map +1 -0
- package/dist/utils/expand.d.ts.map +1 -0
- package/dist/utils/expand.js +477 -0
- package/dist/utils/expand.js.map +1 -0
- package/dist/utils/perfLogger.d.ts.map +1 -0
- package/dist/utils/perfLogger.js +50 -0
- package/dist/utils/perfLogger.js.map +1 -0
- package/dist/utils/tokenize.d.ts.map +1 -0
- package/dist/utils/tokenize.js +115 -0
- package/dist/utils/tokenize.js.map +1 -0
- package/dist/utils/vfsDiff.d.ts.map +1 -0
- package/dist/utils/vfsDiff.js +178 -0
- package/dist/utils/vfsDiff.js.map +1 -0
- package/dist/web-api.d.ts.map +1 -0
- package/dist/web-api.js +47 -0
- package/dist/web-api.js.map +1 -0
- package/dist/web-full.d.ts.map +1 -0
- package/dist/web-full.js +9 -0
- package/dist/web-full.js.map +1 -0
- package/dist/web.d.ts.map +1 -0
- package/dist/web.js +774 -0
- package/dist/web.js.map +1 -0
- package/docs/.nojekyll +1 -0
- package/docs/assets/hierarchy.js +1 -0
- package/docs/assets/highlight.css +162 -0
- package/docs/assets/icons.js +18 -0
- package/docs/assets/icons.svg +1 -0
- package/docs/assets/main.js +60 -0
- package/docs/assets/navigation.js +1 -0
- package/docs/assets/search.js +1 -0
- package/docs/assets/style.css +1633 -0
- package/docs/classes/HoneyPot.html +31 -0
- package/docs/classes/SshClient.html +66 -0
- package/docs/classes/VirtualFileSystem.html +262 -0
- package/docs/classes/VirtualPackageManager.html +63 -0
- package/docs/classes/VirtualSftpServer.html +169 -0
- package/docs/classes/VirtualShell.html +265 -0
- package/docs/classes/VirtualSshServer.html +177 -0
- package/docs/classes/VirtualUserManager.html +276 -0
- package/docs/functions/assertDiff.html +6 -0
- package/docs/functions/diffSnapshots.html +7 -0
- package/docs/functions/formatDiff.html +6 -0
- package/docs/functions/getArg.html +13 -0
- package/docs/functions/getFlag.html +15 -0
- package/docs/functions/ifFlag.html +11 -0
- package/docs/hierarchy.html +1 -0
- package/docs/index.html +1842 -0
- package/docs/interfaces/AuditLogEntry.html +6 -0
- package/docs/interfaces/CommandContext.html +22 -0
- package/docs/interfaces/CommandResult.html +26 -0
- package/docs/interfaces/ExecStream.html +11 -0
- package/docs/interfaces/HoneyPotStats.html +14 -0
- package/docs/interfaces/InstalledPackage.html +20 -0
- package/docs/interfaces/NanoEditorSession.html +8 -0
- package/docs/interfaces/PackageDefinition.html +30 -0
- package/docs/interfaces/PackageFile.html +8 -0
- package/docs/interfaces/RemoveOptions.html +4 -0
- package/docs/interfaces/ShellEnv.html +6 -0
- package/docs/interfaces/ShellModule.html +14 -0
- package/docs/interfaces/ShellProperties.html +14 -0
- package/docs/interfaces/ShellStream.html +11 -0
- package/docs/interfaces/SudoChallenge.html +24 -0
- package/docs/interfaces/VfsBaseNode.html +12 -0
- package/docs/interfaces/VfsDiff.html +10 -0
- package/docs/interfaces/VfsDiffEntry.html +6 -0
- package/docs/interfaces/VfsDiffModified.html +10 -0
- package/docs/interfaces/VfsDirectoryNode.html +15 -0
- package/docs/interfaces/VfsFileNode.html +17 -0
- package/docs/interfaces/VfsOptions.html +12 -0
- package/docs/interfaces/VfsSnapshot.html +3 -0
- package/docs/interfaces/VfsSnapshotBaseNode.html +8 -0
- package/docs/interfaces/VfsSnapshotDirectoryNode.html +10 -0
- package/docs/interfaces/VfsSnapshotFileNode.html +12 -0
- package/docs/interfaces/WriteFileOptions.html +6 -0
- package/docs/media/LICENSE +21 -0
- package/docs/modules.html +1 -0
- package/docs/types/CommandMode.html +2 -0
- package/docs/types/CommandOutcome.html +2 -0
- package/docs/types/VfsNodeStats.html +2 -0
- package/docs/types/VfsNodeType.html +2 -0
- package/docs/types/VfsPersistenceMode.html +5 -0
- package/docs/types/VfsSnapshotNode.html +2 -0
- package/examples/web.min.js +5 -5
- package/package.json +6 -4
- package/src/commands/man.ts +1 -1
- package/src/self-standalone.ts +1 -1
- package/src/standalone.ts +8 -3
- package/tsconfig.json +7 -2
- package/src/Honeypot/index.d.ts.map +0 -1
- package/src/Honeypot/index.js +0 -298
- package/src/SSHClient/index.d.ts.map +0 -1
- package/src/SSHClient/index.js +0 -237
- package/src/SSHMimic/exec.d.ts.map +0 -1
- package/src/SSHMimic/exec.js +0 -27
- package/src/SSHMimic/executor.d.ts.map +0 -1
- package/src/SSHMimic/executor.js +0 -160
- package/src/SSHMimic/hostKey.d.ts.map +0 -1
- package/src/SSHMimic/hostKey.js +0 -17
- package/src/SSHMimic/index.d.ts.map +0 -1
- package/src/SSHMimic/index.js +0 -249
- package/src/SSHMimic/loginBanner.d.ts.map +0 -1
- package/src/SSHMimic/loginBanner.js +0 -22
- package/src/SSHMimic/loginFormat.d.ts.map +0 -1
- package/src/SSHMimic/loginFormat.js +0 -10
- package/src/SSHMimic/prompt.d.ts.map +0 -1
- package/src/SSHMimic/prompt.js +0 -9
- package/src/SSHMimic/sftp.d.ts.map +0 -1
- package/src/SSHMimic/sftp.js +0 -619
- package/src/VirtualFileSystem/binaryPack.d.ts.map +0 -1
- package/src/VirtualFileSystem/binaryPack.js +0 -216
- package/src/VirtualFileSystem/index.d.ts.map +0 -1
- package/src/VirtualFileSystem/index.js +0 -689
- package/src/VirtualFileSystem/internalTypes.d.ts.map +0 -1
- package/src/VirtualFileSystem/internalTypes.js +0 -0
- package/src/VirtualFileSystem/path.d.ts.map +0 -1
- package/src/VirtualFileSystem/path.js +0 -49
- package/src/VirtualPackageManager/index.d.ts.map +0 -1
- package/src/VirtualPackageManager/index.js +0 -853
- package/src/VirtualShell/index.d.ts.map +0 -1
- package/src/VirtualShell/index.js +0 -284
- package/src/VirtualShell/shell.d.ts.map +0 -1
- package/src/VirtualShell/shell.js +0 -502
- package/src/VirtualShell/shellParser.d.ts.map +0 -1
- package/src/VirtualShell/shellParser.js +0 -265
- package/src/VirtualUserManager/index.d.ts.map +0 -1
- package/src/VirtualUserManager/index.js +0 -607
- package/src/commands/adduser.d.ts.map +0 -1
- package/src/commands/adduser.js +0 -89
- package/src/commands/alias.d.ts.map +0 -1
- package/src/commands/alias.js +0 -68
- package/src/commands/apt.d.ts.map +0 -1
- package/src/commands/apt.js +0 -210
- package/src/commands/awk.d.ts.map +0 -1
- package/src/commands/awk.js +0 -169
- package/src/commands/base64.d.ts.map +0 -1
- package/src/commands/base64.js +0 -28
- package/src/commands/cat.d.ts.map +0 -1
- package/src/commands/cat.js +0 -44
- package/src/commands/cd.d.ts.map +0 -1
- package/src/commands/cd.js +0 -21
- package/src/commands/chmod.d.ts.map +0 -1
- package/src/commands/chmod.js +0 -87
- package/src/commands/clear.d.ts.map +0 -1
- package/src/commands/clear.js +0 -13
- package/src/commands/command-helpers.d.ts.map +0 -1
- package/src/commands/command-helpers.js +0 -221
- package/src/commands/cp.d.ts.map +0 -1
- package/src/commands/cp.js +0 -75
- package/src/commands/curl.d.ts.map +0 -1
- package/src/commands/curl.js +0 -127
- package/src/commands/cut.d.ts.map +0 -1
- package/src/commands/cut.js +0 -34
- package/src/commands/date.d.ts.map +0 -1
- package/src/commands/date.js +0 -28
- package/src/commands/declare.d.ts.map +0 -1
- package/src/commands/declare.js +0 -44
- package/src/commands/deluser.d.ts.map +0 -1
- package/src/commands/deluser.js +0 -83
- package/src/commands/df.d.ts.map +0 -1
- package/src/commands/df.js +0 -21
- package/src/commands/diff.d.ts.map +0 -1
- package/src/commands/diff.js +0 -45
- package/src/commands/dpkg.d.ts.map +0 -1
- package/src/commands/dpkg.js +0 -161
- package/src/commands/du.d.ts.map +0 -1
- package/src/commands/du.js +0 -50
- package/src/commands/echo.d.ts.map +0 -1
- package/src/commands/echo.js +0 -45
- package/src/commands/env.d.ts.map +0 -1
- package/src/commands/env.js +0 -20
- package/src/commands/exit.d.ts.map +0 -1
- package/src/commands/exit.js +0 -16
- package/src/commands/export.d.ts.map +0 -1
- package/src/commands/export.js +0 -33
- package/src/commands/find.d.ts.map +0 -1
- package/src/commands/find.js +0 -55
- package/src/commands/free.d.ts.map +0 -1
- package/src/commands/free.js +0 -43
- package/src/commands/grep.d.ts.map +0 -1
- package/src/commands/grep.js +0 -120
- package/src/commands/groups.d.ts.map +0 -1
- package/src/commands/groups.js +0 -17
- package/src/commands/gzip.d.ts.map +0 -1
- package/src/commands/gzip.js +0 -82
- package/src/commands/head.d.ts.map +0 -1
- package/src/commands/head.js +0 -46
- package/src/commands/help.d.ts.map +0 -1
- package/src/commands/help.js +0 -123
- package/src/commands/helpers.d.ts.map +0 -1
- package/src/commands/helpers.js +0 -166
- package/src/commands/history.d.ts.map +0 -1
- package/src/commands/history.js +0 -26
- package/src/commands/hostname.d.ts.map +0 -1
- package/src/commands/hostname.js +0 -12
- package/src/commands/htop.d.ts.map +0 -1
- package/src/commands/htop.js +0 -17
- package/src/commands/id.d.ts.map +0 -1
- package/src/commands/id.js +0 -17
- package/src/commands/index.d.ts.map +0 -1
- package/src/commands/index.js +0 -2
- package/src/commands/kill.d.ts.map +0 -1
- package/src/commands/kill.js +0 -18
- package/src/commands/ln.d.ts.map +0 -1
- package/src/commands/ln.js +0 -66
- package/src/commands/ls.d.ts.map +0 -1
- package/src/commands/ls.js +0 -200
- package/src/commands/lsb-release.d.ts.map +0 -1
- package/src/commands/lsb-release.js +0 -61
- package/src/commands/man.d.ts.map +0 -1
- package/src/commands/man.js +0 -49
- package/src/commands/mkdir.d.ts.map +0 -1
- package/src/commands/mkdir.js +0 -28
- package/src/commands/mv.d.ts.map +0 -1
- package/src/commands/mv.js +0 -42
- package/src/commands/nano.d.ts.map +0 -1
- package/src/commands/nano.js +0 -34
- package/src/commands/neofetch.d.ts.map +0 -1
- package/src/commands/neofetch.js +0 -48
- package/src/commands/node.d.ts.map +0 -1
- package/src/commands/node.js +0 -316
- package/src/commands/npm.d.ts.map +0 -1
- package/src/commands/npm.js +0 -109
- package/src/commands/passwd.d.ts.map +0 -1
- package/src/commands/passwd.js +0 -44
- package/src/commands/ping.d.ts.map +0 -1
- package/src/commands/ping.js +0 -28
- package/src/commands/printf.d.ts.map +0 -1
- package/src/commands/printf.js +0 -144
- package/src/commands/ps.d.ts.map +0 -1
- package/src/commands/ps.js +0 -46
- package/src/commands/pwd.d.ts.map +0 -1
- package/src/commands/pwd.js +0 -7
- package/src/commands/python.d.ts.map +0 -1
- package/src/commands/python.js +0 -2058
- package/src/commands/read.d.ts.map +0 -1
- package/src/commands/read.js +0 -39
- package/src/commands/registry.d.ts.map +0 -1
- package/src/commands/registry.js +0 -234
- package/src/commands/rm.d.ts.map +0 -1
- package/src/commands/rm.js +0 -36
- package/src/commands/runtime.d.ts.map +0 -1
- package/src/commands/runtime.js +0 -285
- package/src/commands/sed.d.ts.map +0 -1
- package/src/commands/sed.js +0 -60
- package/src/commands/seq.d.ts.map +0 -1
- package/src/commands/seq.js +0 -50
- package/src/commands/set.d.ts.map +0 -1
- package/src/commands/set.js +0 -26
- package/src/commands/sh.d.ts.map +0 -1
- package/src/commands/sh.js +0 -431
- package/src/commands/shift.d.ts.map +0 -1
- package/src/commands/shift.js +0 -62
- package/src/commands/sleep.d.ts.map +0 -1
- package/src/commands/sleep.js +0 -18
- package/src/commands/sort.d.ts.map +0 -1
- package/src/commands/sort.js +0 -44
- package/src/commands/source.d.ts.map +0 -1
- package/src/commands/source.js +0 -39
- package/src/commands/stat.d.ts.map +0 -1
- package/src/commands/stat.js +0 -56
- package/src/commands/su.d.ts.map +0 -1
- package/src/commands/su.js +0 -57
- package/src/commands/sudo.d.ts.map +0 -1
- package/src/commands/sudo.js +0 -54
- package/src/commands/tail.d.ts.map +0 -1
- package/src/commands/tail.js +0 -47
- package/src/commands/tar.d.ts.map +0 -1
- package/src/commands/tar.js +0 -102
- package/src/commands/tee.d.ts.map +0 -1
- package/src/commands/tee.js +0 -36
- package/src/commands/test.d.ts.map +0 -1
- package/src/commands/test.js +0 -114
- package/src/commands/touch.d.ts.map +0 -1
- package/src/commands/touch.js +0 -25
- package/src/commands/tr.d.ts.map +0 -1
- package/src/commands/tr.js +0 -61
- package/src/commands/tree.d.ts.map +0 -1
- package/src/commands/tree.js +0 -18
- package/src/commands/true.d.ts.map +0 -1
- package/src/commands/true.js +0 -24
- package/src/commands/type.d.ts.map +0 -1
- package/src/commands/type.js +0 -39
- package/src/commands/uname.d.ts.map +0 -1
- package/src/commands/uname.js +0 -29
- package/src/commands/uniq.d.ts.map +0 -1
- package/src/commands/uniq.js +0 -38
- package/src/commands/unset.d.ts.map +0 -1
- package/src/commands/unset.js +0 -16
- package/src/commands/uptime.d.ts.map +0 -1
- package/src/commands/uptime.js +0 -48
- package/src/commands/wc.d.ts.map +0 -1
- package/src/commands/wc.js +0 -55
- package/src/commands/wget.d.ts.map +0 -1
- package/src/commands/wget.js +0 -126
- package/src/commands/which.d.ts.map +0 -1
- package/src/commands/which.js +0 -32
- package/src/commands/who.d.ts.map +0 -1
- package/src/commands/who.js +0 -22
- package/src/commands/whoami.d.ts.map +0 -1
- package/src/commands/whoami.js +0 -12
- package/src/commands/xargs.d.ts.map +0 -1
- package/src/commands/xargs.js +0 -21
- package/src/index.d.ts.map +0 -1
- package/src/index.js +0 -9
- package/src/modules/linuxRootfs.d.ts.map +0 -1
- package/src/modules/linuxRootfs.js +0 -619
- package/src/modules/neofetch.d.ts.map +0 -1
- package/src/modules/neofetch.js +0 -284
- package/src/modules/shellInteractive.d.ts.map +0 -1
- package/src/modules/shellInteractive.js +0 -26
- package/src/modules/shellRuntime.d.ts.map +0 -1
- package/src/modules/shellRuntime.js +0 -52
- package/src/self-standalone.d.ts.map +0 -1
- package/src/self-standalone.js +0 -418
- package/src/standalone-wo-sftp.d.ts.map +0 -1
- package/src/standalone-wo-sftp.js +0 -30
- package/src/standalone.d.ts.map +0 -1
- package/src/standalone.js +0 -35
- package/src/types/commands.d.ts.map +0 -1
- package/src/types/commands.js +0 -0
- package/src/types/pipeline.d.ts.map +0 -1
- package/src/types/pipeline.js +0 -0
- package/src/types/streams.d.ts.map +0 -1
- package/src/types/streams.js +0 -0
- package/src/types/vfs.d.ts.map +0 -1
- package/src/types/vfs.js +0 -0
- package/src/utils/expand.d.ts.map +0 -1
- package/src/utils/expand.js +0 -476
- package/src/utils/perfLogger.d.ts.map +0 -1
- package/src/utils/perfLogger.js +0 -49
- package/src/utils/tokenize.d.ts.map +0 -1
- package/src/utils/tokenize.js +0 -114
- package/src/utils/vfsDiff.d.ts.map +0 -1
- package/src/utils/vfsDiff.js +0 -177
- package/src/web-api.d.ts.map +0 -1
- package/src/web-api.js +0 -46
- package/src/web-full.d.ts.map +0 -1
- package/src/web-full.js +0 -8
- package/src/web.d.ts.map +0 -1
- package/src/web.js +0 -773
- package/tests/command-helpers.test.d.ts +0 -2
- package/tests/command-helpers.test.d.ts.map +0 -1
- package/tests/command-helpers.test.js +0 -92
- package/tests/commands-admin-net.test.d.ts +0 -2
- package/tests/commands-admin-net.test.d.ts.map +0 -1
- package/tests/commands-admin-net.test.js +0 -353
- package/tests/commands-advanced.test.d.ts +0 -2
- package/tests/commands-advanced.test.d.ts.map +0 -1
- package/tests/commands-advanced.test.js +0 -378
- package/tests/commands-core.test.d.ts +0 -2
- package/tests/commands-core.test.d.ts.map +0 -1
- package/tests/commands-core.test.js +0 -477
- package/tests/commands-missing.test.d.ts +0 -2
- package/tests/commands-missing.test.d.ts.map +0 -1
- package/tests/commands-missing.test.js +0 -470
- package/tests/commands-specific-units.test.d.ts +0 -2
- package/tests/commands-specific-units.test.d.ts.map +0 -1
- package/tests/commands-specific-units.test.js +0 -264
- package/tests/commands-text-sys.test.d.ts +0 -2
- package/tests/commands-text-sys.test.d.ts.map +0 -1
- package/tests/commands-text-sys.test.js +0 -366
- package/tests/expand.test.d.ts +0 -2
- package/tests/expand.test.d.ts.map +0 -1
- package/tests/expand.test.js +0 -138
- package/tests/helpers.test.d.ts +0 -2
- package/tests/helpers.test.d.ts.map +0 -1
- package/tests/helpers.test.js +0 -52
- package/tests/new-features.test.d.ts +0 -2
- package/tests/new-features.test.d.ts.map +0 -1
- package/tests/new-features.test.js +0 -850
- package/tests/parser-executor.test.d.ts +0 -2
- package/tests/parser-executor.test.d.ts.map +0 -1
- package/tests/parser-executor.test.js +0 -25
- package/tests/sftp.test.d.ts +0 -2
- package/tests/sftp.test.d.ts.map +0 -1
- package/tests/sftp.test.js +0 -246
- package/tests/ssh-exec.test.d.ts +0 -2
- package/tests/ssh-exec.test.d.ts.map +0 -1
- package/tests/ssh-exec.test.js +0 -39
- package/tests/test-helper.d.ts +0 -56
- package/tests/test-helper.d.ts.map +0 -1
- package/tests/test-helper.js +0 -71
- package/tests/users.test.d.ts +0 -2
- package/tests/users.test.d.ts.map +0 -1
- package/tests/users.test.js +0 -71
- package/tests/web.test.d.ts +0 -2
- package/tests/web.test.d.ts.map +0 -1
- package/tests/web.test.js +0 -149
- /package/{src → dist}/Honeypot/index.d.ts +0 -0
- /package/{src → dist}/SSHClient/index.d.ts +0 -0
- /package/{src → dist}/SSHMimic/exec.d.ts +0 -0
- /package/{src → dist}/SSHMimic/executor.d.ts +0 -0
- /package/{src → dist}/SSHMimic/hostKey.d.ts +0 -0
- /package/{src → dist}/SSHMimic/index.d.ts +0 -0
- /package/{src → dist}/SSHMimic/loginBanner.d.ts +0 -0
- /package/{src → dist}/SSHMimic/loginFormat.d.ts +0 -0
- /package/{src → dist}/SSHMimic/prompt.d.ts +0 -0
- /package/{src → dist}/SSHMimic/sftp.d.ts +0 -0
- /package/{src → dist}/VirtualFileSystem/binaryPack.d.ts +0 -0
- /package/{src → dist}/VirtualFileSystem/index.d.ts +0 -0
- /package/{src → dist}/VirtualFileSystem/internalTypes.d.ts +0 -0
- /package/{src → dist}/VirtualFileSystem/path.d.ts +0 -0
- /package/{src → dist}/VirtualPackageManager/index.d.ts +0 -0
- /package/{src → dist}/VirtualShell/index.d.ts +0 -0
- /package/{src → dist}/VirtualShell/shell.d.ts +0 -0
- /package/{src → dist}/VirtualShell/shellParser.d.ts +0 -0
- /package/{src → dist}/VirtualUserManager/index.d.ts +0 -0
- /package/{src → dist}/commands/adduser.d.ts +0 -0
- /package/{src → dist}/commands/alias.d.ts +0 -0
- /package/{src → dist}/commands/apt.d.ts +0 -0
- /package/{src → dist}/commands/awk.d.ts +0 -0
- /package/{src → dist}/commands/base64.d.ts +0 -0
- /package/{src → dist}/commands/cat.d.ts +0 -0
- /package/{src → dist}/commands/cd.d.ts +0 -0
- /package/{src → dist}/commands/chmod.d.ts +0 -0
- /package/{src → dist}/commands/clear.d.ts +0 -0
- /package/{src → dist}/commands/command-helpers.d.ts +0 -0
- /package/{src → dist}/commands/cp.d.ts +0 -0
- /package/{src → dist}/commands/curl.d.ts +0 -0
- /package/{src → dist}/commands/cut.d.ts +0 -0
- /package/{src → dist}/commands/date.d.ts +0 -0
- /package/{src → dist}/commands/declare.d.ts +0 -0
- /package/{src → dist}/commands/deluser.d.ts +0 -0
- /package/{src → dist}/commands/df.d.ts +0 -0
- /package/{src → dist}/commands/diff.d.ts +0 -0
- /package/{src → dist}/commands/dpkg.d.ts +0 -0
- /package/{src → dist}/commands/du.d.ts +0 -0
- /package/{src → dist}/commands/echo.d.ts +0 -0
- /package/{src → dist}/commands/env.d.ts +0 -0
- /package/{src → dist}/commands/exit.d.ts +0 -0
- /package/{src → dist}/commands/export.d.ts +0 -0
- /package/{src → dist}/commands/find.d.ts +0 -0
- /package/{src → dist}/commands/free.d.ts +0 -0
- /package/{src → dist}/commands/grep.d.ts +0 -0
- /package/{src → dist}/commands/groups.d.ts +0 -0
- /package/{src → dist}/commands/gzip.d.ts +0 -0
- /package/{src → dist}/commands/head.d.ts +0 -0
- /package/{src → dist}/commands/help.d.ts +0 -0
- /package/{src → dist}/commands/helpers.d.ts +0 -0
- /package/{src → dist}/commands/history.d.ts +0 -0
- /package/{src → dist}/commands/hostname.d.ts +0 -0
- /package/{src → dist}/commands/htop.d.ts +0 -0
- /package/{src → dist}/commands/id.d.ts +0 -0
- /package/{src → dist}/commands/index.d.ts +0 -0
- /package/{src → dist}/commands/kill.d.ts +0 -0
- /package/{src → dist}/commands/ln.d.ts +0 -0
- /package/{src → dist}/commands/ls.d.ts +0 -0
- /package/{src → dist}/commands/lsb-release.d.ts +0 -0
- /package/{src → dist}/commands/man.d.ts +0 -0
- /package/{src → dist}/commands/mkdir.d.ts +0 -0
- /package/{src → dist}/commands/mv.d.ts +0 -0
- /package/{src → dist}/commands/nano.d.ts +0 -0
- /package/{src → dist}/commands/neofetch.d.ts +0 -0
- /package/{src → dist}/commands/node.d.ts +0 -0
- /package/{src → dist}/commands/npm.d.ts +0 -0
- /package/{src → dist}/commands/passwd.d.ts +0 -0
- /package/{src → dist}/commands/ping.d.ts +0 -0
- /package/{src → dist}/commands/printf.d.ts +0 -0
- /package/{src → dist}/commands/ps.d.ts +0 -0
- /package/{src → dist}/commands/pwd.d.ts +0 -0
- /package/{src → dist}/commands/python.d.ts +0 -0
- /package/{src → dist}/commands/read.d.ts +0 -0
- /package/{src → dist}/commands/registry.d.ts +0 -0
- /package/{src → dist}/commands/rm.d.ts +0 -0
- /package/{src → dist}/commands/runtime.d.ts +0 -0
- /package/{src → dist}/commands/sed.d.ts +0 -0
- /package/{src → dist}/commands/seq.d.ts +0 -0
- /package/{src → dist}/commands/set.d.ts +0 -0
- /package/{src → dist}/commands/sh.d.ts +0 -0
- /package/{src → dist}/commands/shift.d.ts +0 -0
- /package/{src → dist}/commands/sleep.d.ts +0 -0
- /package/{src → dist}/commands/sort.d.ts +0 -0
- /package/{src → dist}/commands/source.d.ts +0 -0
- /package/{src → dist}/commands/stat.d.ts +0 -0
- /package/{src → dist}/commands/su.d.ts +0 -0
- /package/{src → dist}/commands/sudo.d.ts +0 -0
- /package/{src → dist}/commands/tail.d.ts +0 -0
- /package/{src → dist}/commands/tar.d.ts +0 -0
- /package/{src → dist}/commands/tee.d.ts +0 -0
- /package/{src → dist}/commands/test.d.ts +0 -0
- /package/{src → dist}/commands/touch.d.ts +0 -0
- /package/{src → dist}/commands/tr.d.ts +0 -0
- /package/{src → dist}/commands/tree.d.ts +0 -0
- /package/{src → dist}/commands/true.d.ts +0 -0
- /package/{src → dist}/commands/type.d.ts +0 -0
- /package/{src → dist}/commands/uname.d.ts +0 -0
- /package/{src → dist}/commands/uniq.d.ts +0 -0
- /package/{src → dist}/commands/unset.d.ts +0 -0
- /package/{src → dist}/commands/uptime.d.ts +0 -0
- /package/{src → dist}/commands/wc.d.ts +0 -0
- /package/{src → dist}/commands/wget.d.ts +0 -0
- /package/{src → dist}/commands/which.d.ts +0 -0
- /package/{src → dist}/commands/who.d.ts +0 -0
- /package/{src → dist}/commands/whoami.d.ts +0 -0
- /package/{src → dist}/commands/xargs.d.ts +0 -0
- /package/{src → dist}/index.d.ts +0 -0
- /package/{src → dist}/modules/linuxRootfs.d.ts +0 -0
- /package/{src → dist}/modules/neofetch.d.ts +0 -0
- /package/{src → dist}/modules/shellInteractive.d.ts +0 -0
- /package/{src → dist}/modules/shellRuntime.d.ts +0 -0
- /package/{src → dist}/self-standalone.d.ts +0 -0
- /package/{src → dist}/standalone-wo-sftp.d.ts +0 -0
- /package/{src → dist}/standalone.d.ts +0 -0
- /package/{src → dist}/types/commands.d.ts +0 -0
- /package/{src → dist}/types/pipeline.d.ts +0 -0
- /package/{src → dist}/types/streams.d.ts +0 -0
- /package/{src → dist}/types/vfs.d.ts +0 -0
- /package/{src → dist}/utils/expand.d.ts +0 -0
- /package/{src → dist}/utils/perfLogger.d.ts +0 -0
- /package/{src → dist}/utils/tokenize.d.ts +0 -0
- /package/{src → dist}/utils/vfsDiff.d.ts +0 -0
- /package/{src → dist}/web-api.d.ts +0 -0
- /package/{src → dist}/web-full.d.ts +0 -0
- /package/{src → dist}/web.d.ts +0 -0
|
@@ -1,607 +0,0 @@
|
|
|
1
|
-
import { createHash, randomBytes, randomUUID, scryptSync, timingSafeEqual } from "node:crypto";
|
|
2
|
-
import { EventEmitter } from "node:events";
|
|
3
|
-
import * as path from "node:path";
|
|
4
|
-
import { createPerfLogger } from "../utils/perfLogger";
|
|
5
|
-
function resolveFastPasswordHash() {
|
|
6
|
-
const configured = process.env.SSH_MIMIC_FAST_PASSWORD_HASH;
|
|
7
|
-
return (!!configured &&
|
|
8
|
-
!["0", "false", "no", "off"].includes(configured.toLowerCase()));
|
|
9
|
-
}
|
|
10
|
-
const perf = createPerfLogger("VirtualUserManager");
|
|
11
|
-
/**
|
|
12
|
-
* Persistent user, sudoers, and active-session manager for the shell runtime.
|
|
13
|
-
*
|
|
14
|
-
* Passwords are hashed with scrypt by default and stored in the backing virtual filesystem.
|
|
15
|
-
*/
|
|
16
|
-
export class VirtualUserManager extends EventEmitter {
|
|
17
|
-
vfs;
|
|
18
|
-
autoSudoForNewUsers;
|
|
19
|
-
static recordCache = new Map();
|
|
20
|
-
static fastPasswordHash = resolveFastPasswordHash();
|
|
21
|
-
usersPath = "/etc/htpasswd";
|
|
22
|
-
sudoersPath = "/etc/sudoers";
|
|
23
|
-
quotasPath = "/etc/quotas";
|
|
24
|
-
authDirPath = "/.virtual-env-js/.auth";
|
|
25
|
-
users = new Map();
|
|
26
|
-
sudoers = new Set();
|
|
27
|
-
quotas = new Map();
|
|
28
|
-
activeSessions = new Map();
|
|
29
|
-
nextTty = 0;
|
|
30
|
-
/**
|
|
31
|
-
* Creates a user manager instance backed by a virtual filesystem.
|
|
32
|
-
*
|
|
33
|
-
* @param vfs Backing virtual filesystem used for persistence.
|
|
34
|
-
* @param defaultRootPassword Initial root password used when root is created.
|
|
35
|
-
* @param autoSudoForNewUsers Whether newly created users are added to sudoers.
|
|
36
|
-
*/
|
|
37
|
-
constructor(vfs,
|
|
38
|
-
// private readonly defaultRootPassword: string = process.env
|
|
39
|
-
// .SSH_MIMIC_ROOT_PASSWORD || "root",
|
|
40
|
-
autoSudoForNewUsers = true) {
|
|
41
|
-
super();
|
|
42
|
-
this.vfs = vfs;
|
|
43
|
-
this.autoSudoForNewUsers = autoSudoForNewUsers;
|
|
44
|
-
perf.mark("constructor");
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Loads users/sudoers from disk and ensures root account exists.
|
|
48
|
-
* Also creates the current system user if not already present.
|
|
49
|
-
*/
|
|
50
|
-
async initialize() {
|
|
51
|
-
perf.mark("initialize");
|
|
52
|
-
this.loadFromVfs();
|
|
53
|
-
this.loadSudoersFromVfs();
|
|
54
|
-
this.loadQuotasFromVfs();
|
|
55
|
-
let changed = false;
|
|
56
|
-
if (!this.users.has("root")) {
|
|
57
|
-
this.users.set("root", this.createRecord("root", ""));
|
|
58
|
-
changed = true;
|
|
59
|
-
}
|
|
60
|
-
this.sudoers.add("root");
|
|
61
|
-
// Auto-create current system user for easier authentication
|
|
62
|
-
// const currentUser = process.env.USER || process.env.USERNAME;
|
|
63
|
-
// if (currentUser && currentUser !== "root" && !this.users.has(currentUser)) {
|
|
64
|
-
// const userPassword = this.defaultRootPassword;
|
|
65
|
-
// this.users.set(currentUser, this.createRecord(currentUser, userPassword));
|
|
66
|
-
// this.sudoers.add(currentUser);
|
|
67
|
-
// changed = true;
|
|
68
|
-
// }
|
|
69
|
-
// const homePath = `/home/root`;
|
|
70
|
-
// if (!this.vfs.exists(homePath)) {
|
|
71
|
-
// this.vfs.mkdir(homePath, 0o755);
|
|
72
|
-
// this.vfs.writeFile(
|
|
73
|
-
// `${homePath}/README.txt`,
|
|
74
|
-
// `Welcome to the virtual environment, root`,
|
|
75
|
-
// );
|
|
76
|
-
// }
|
|
77
|
-
if (changed) {
|
|
78
|
-
await this.persist();
|
|
79
|
-
}
|
|
80
|
-
this.emit("initialized");
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Sets max allowed bytes under /home/<username>.
|
|
84
|
-
*
|
|
85
|
-
* @param username Target username.
|
|
86
|
-
* @param maxBytes Quota ceiling in bytes.
|
|
87
|
-
*/
|
|
88
|
-
async setQuotaBytes(username, maxBytes) {
|
|
89
|
-
perf.mark("setQuotaBytes");
|
|
90
|
-
this.validateUsername(username);
|
|
91
|
-
if (!this.users.has(username)) {
|
|
92
|
-
throw new Error(`quota: user '${username}' does not exist`);
|
|
93
|
-
}
|
|
94
|
-
if (!Number.isFinite(maxBytes) || maxBytes < 0) {
|
|
95
|
-
throw new Error("quota: maxBytes must be a non-negative number");
|
|
96
|
-
}
|
|
97
|
-
this.quotas.set(username, Math.floor(maxBytes));
|
|
98
|
-
await this.persist();
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Removes quota for a user.
|
|
102
|
-
*
|
|
103
|
-
* @param username Target username.
|
|
104
|
-
*/
|
|
105
|
-
async clearQuota(username) {
|
|
106
|
-
perf.mark("clearQuota");
|
|
107
|
-
this.validateUsername(username);
|
|
108
|
-
this.quotas.delete(username);
|
|
109
|
-
await this.persist();
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Gets configured quota in bytes for a user.
|
|
113
|
-
*
|
|
114
|
-
* @param username Target username.
|
|
115
|
-
* @returns Quota in bytes, or null when unlimited.
|
|
116
|
-
*/
|
|
117
|
-
getQuotaBytes(username) {
|
|
118
|
-
perf.mark("getQuotaBytes");
|
|
119
|
-
return this.quotas.get(username) ?? null;
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* Computes current usage under /home/<username>.
|
|
123
|
-
*
|
|
124
|
-
* @param username Target username.
|
|
125
|
-
* @returns Current usage in bytes.
|
|
126
|
-
*/
|
|
127
|
-
getUsageBytes(username) {
|
|
128
|
-
perf.mark("getUsageBytes");
|
|
129
|
-
const homePath = `/home/${username}`;
|
|
130
|
-
if (!this.vfs.exists(homePath)) {
|
|
131
|
-
return 0;
|
|
132
|
-
}
|
|
133
|
-
return this.vfs.getUsageBytes(homePath);
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* Validates that writing file content would not exceed user quota.
|
|
137
|
-
*
|
|
138
|
-
* Quotas are enforced only for writes inside /home/<username>.
|
|
139
|
-
*
|
|
140
|
-
* @param username Authenticated user.
|
|
141
|
-
* @param targetPath Target file path.
|
|
142
|
-
* @param nextContent New file content.
|
|
143
|
-
*/
|
|
144
|
-
assertWriteWithinQuota(username, targetPath, nextContent) {
|
|
145
|
-
perf.mark("assertWriteWithinQuota");
|
|
146
|
-
const quota = this.quotas.get(username);
|
|
147
|
-
if (quota === undefined) {
|
|
148
|
-
return;
|
|
149
|
-
}
|
|
150
|
-
const normalizedPath = normalizeVfsPath(targetPath);
|
|
151
|
-
const homePath = normalizeVfsPath(`/home/${username}`);
|
|
152
|
-
const inUserHome = normalizedPath === homePath || normalizedPath.startsWith(`${homePath}/`);
|
|
153
|
-
if (!inUserHome) {
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
const currentUsage = this.getUsageBytes(username);
|
|
157
|
-
let existingSize = 0;
|
|
158
|
-
if (this.vfs.exists(normalizedPath)) {
|
|
159
|
-
const existing = this.vfs.stat(normalizedPath);
|
|
160
|
-
if (existing.type === "file") {
|
|
161
|
-
existingSize = existing.size;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
const incomingSize = Buffer.isBuffer(nextContent)
|
|
165
|
-
? nextContent.length
|
|
166
|
-
: Buffer.byteLength(nextContent, "utf8");
|
|
167
|
-
const projectedUsage = currentUsage - existingSize + incomingSize;
|
|
168
|
-
if (projectedUsage > quota) {
|
|
169
|
-
throw new Error(`quota exceeded for '${username}': ${projectedUsage}/${quota} bytes`);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
/**
|
|
173
|
-
* Verifies plaintext password against stored record.
|
|
174
|
-
*
|
|
175
|
-
* @param username User login name.
|
|
176
|
-
* @param password Plaintext password candidate.
|
|
177
|
-
* @returns True when credentials are valid.
|
|
178
|
-
*/
|
|
179
|
-
verifyPassword(username, password) {
|
|
180
|
-
perf.mark("verifyPassword");
|
|
181
|
-
const record = this.users.get(username);
|
|
182
|
-
if (!record) {
|
|
183
|
-
// Perform a dummy hash to avoid timing leakage on unknown usernames
|
|
184
|
-
this.hashPassword(password, "");
|
|
185
|
-
return false;
|
|
186
|
-
}
|
|
187
|
-
const computed = this.hashPassword(password, record.salt);
|
|
188
|
-
const expected = record.passwordHash;
|
|
189
|
-
// timingSafeEqual prevents timing-based password oracle attacks
|
|
190
|
-
try {
|
|
191
|
-
const a = Buffer.from(computed, "hex");
|
|
192
|
-
const b = Buffer.from(expected, "hex");
|
|
193
|
-
if (a.length !== b.length)
|
|
194
|
-
return false;
|
|
195
|
-
return timingSafeEqual(a, b);
|
|
196
|
-
}
|
|
197
|
-
catch {
|
|
198
|
-
return computed === expected;
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
/**
|
|
202
|
-
* Creates user, home directory, and sudo access entry.
|
|
203
|
-
*
|
|
204
|
-
* @param username New username.
|
|
205
|
-
* @param password Initial plaintext password.
|
|
206
|
-
*/
|
|
207
|
-
async addUser(username, password) {
|
|
208
|
-
perf.mark("addUser");
|
|
209
|
-
this.validateUsername(username);
|
|
210
|
-
this.validatePassword(password);
|
|
211
|
-
if (this.users.has(username)) {
|
|
212
|
-
return;
|
|
213
|
-
// throw new Error(`adduser: user '${username}' already exists`);
|
|
214
|
-
}
|
|
215
|
-
this.users.set(username, this.createRecord(username, password));
|
|
216
|
-
if (this.autoSudoForNewUsers) {
|
|
217
|
-
this.sudoers.add(username);
|
|
218
|
-
}
|
|
219
|
-
const homePath = `/home/${username}`;
|
|
220
|
-
if (!this.vfs.exists(homePath)) {
|
|
221
|
-
this.vfs.mkdir(homePath, 0o755);
|
|
222
|
-
this.vfs.writeFile(`${homePath}/README.txt`, `Welcome to the virtual environment, ${username}`);
|
|
223
|
-
}
|
|
224
|
-
await this.persist();
|
|
225
|
-
this.emit("user:add", { username });
|
|
226
|
-
}
|
|
227
|
-
/**
|
|
228
|
-
* Retrieves stored password hash for a user, or null if user does not exist.
|
|
229
|
-
*
|
|
230
|
-
* @param username Target username.
|
|
231
|
-
* @returns Password hash in hex encoding, or null when user is not found.
|
|
232
|
-
*/
|
|
233
|
-
getPasswordHash(username) {
|
|
234
|
-
perf.mark("getPasswordHash");
|
|
235
|
-
const record = this.users.get(username);
|
|
236
|
-
return record ? record.passwordHash : null;
|
|
237
|
-
}
|
|
238
|
-
/**
|
|
239
|
-
* Updates the password for an existing user account.
|
|
240
|
-
*
|
|
241
|
-
* @param username Username to update.
|
|
242
|
-
* @param password New plaintext password (must be non-empty).
|
|
243
|
-
* @throws When the user does not exist or the password is empty.
|
|
244
|
-
*/
|
|
245
|
-
async setPassword(username, password) {
|
|
246
|
-
perf.mark("setPassword");
|
|
247
|
-
this.validateUsername(username);
|
|
248
|
-
this.validatePassword(password);
|
|
249
|
-
if (!this.users.has(username)) {
|
|
250
|
-
throw new Error(`passwd: user '${username}' does not exist`);
|
|
251
|
-
}
|
|
252
|
-
this.users.set(username, this.createRecord(username, password));
|
|
253
|
-
await this.persist();
|
|
254
|
-
}
|
|
255
|
-
/**
|
|
256
|
-
* Deletes an existing non-root user account and revokes sudo access.
|
|
257
|
-
*
|
|
258
|
-
* @param username Username to remove.
|
|
259
|
-
* @throws When `username` is `"root"` or the user does not exist.
|
|
260
|
-
*/
|
|
261
|
-
async deleteUser(username) {
|
|
262
|
-
perf.mark("deleteUser");
|
|
263
|
-
this.validateUsername(username);
|
|
264
|
-
if (username === "root") {
|
|
265
|
-
throw new Error("deluser: cannot delete root");
|
|
266
|
-
}
|
|
267
|
-
if (!this.users.delete(username)) {
|
|
268
|
-
throw new Error(`deluser: user '${username}' does not exist`);
|
|
269
|
-
}
|
|
270
|
-
this.sudoers.delete(username);
|
|
271
|
-
this.emit("user:delete", { username });
|
|
272
|
-
await this.persist();
|
|
273
|
-
}
|
|
274
|
-
/**
|
|
275
|
-
* Checks whether user is member of sudoers set.
|
|
276
|
-
*
|
|
277
|
-
* @param username Username to test.
|
|
278
|
-
* @returns True when user can run sudo.
|
|
279
|
-
*/
|
|
280
|
-
isSudoer(username) {
|
|
281
|
-
perf.mark("isSudoer");
|
|
282
|
-
return this.sudoers.has(username);
|
|
283
|
-
}
|
|
284
|
-
/**
|
|
285
|
-
* Grants sudo privileges to an existing user.
|
|
286
|
-
*
|
|
287
|
-
* @param username Username to promote.
|
|
288
|
-
* @throws When the user does not exist.
|
|
289
|
-
*/
|
|
290
|
-
async addSudoer(username) {
|
|
291
|
-
perf.mark("addSudoer");
|
|
292
|
-
this.validateUsername(username);
|
|
293
|
-
if (!this.users.has(username)) {
|
|
294
|
-
throw new Error(`sudoers: user '${username}' does not exist`);
|
|
295
|
-
}
|
|
296
|
-
this.sudoers.add(username);
|
|
297
|
-
await this.persist();
|
|
298
|
-
}
|
|
299
|
-
/**
|
|
300
|
-
* Revokes sudo privileges from a user. Root cannot be demoted.
|
|
301
|
-
*
|
|
302
|
-
* @param username Username to demote.
|
|
303
|
-
* @throws When `username` is `"root"`.
|
|
304
|
-
*/
|
|
305
|
-
async removeSudoer(username) {
|
|
306
|
-
perf.mark("removeSudoer");
|
|
307
|
-
this.validateUsername(username);
|
|
308
|
-
if (username === "root") {
|
|
309
|
-
throw new Error("sudoers: cannot remove root");
|
|
310
|
-
}
|
|
311
|
-
this.sudoers.delete(username);
|
|
312
|
-
await this.persist();
|
|
313
|
-
}
|
|
314
|
-
/**
|
|
315
|
-
* Registers a new active session and allocates a virtual TTY identifier.
|
|
316
|
-
*
|
|
317
|
-
* Called by the SSH server when a client is authenticated. The returned
|
|
318
|
-
* descriptor is visible in `who` output and `listActiveSessions()`.
|
|
319
|
-
*
|
|
320
|
-
* @param username Authenticated username bound to the session.
|
|
321
|
-
* @param remoteAddress IP address or hostname of the connecting client.
|
|
322
|
-
* @returns The newly created `VirtualActiveSession` descriptor.
|
|
323
|
-
*/
|
|
324
|
-
registerSession(username, remoteAddress) {
|
|
325
|
-
perf.mark("registerSession");
|
|
326
|
-
const session = {
|
|
327
|
-
id: randomUUID(),
|
|
328
|
-
username,
|
|
329
|
-
tty: `pts/${this.nextTty++}`,
|
|
330
|
-
remoteAddress,
|
|
331
|
-
startedAt: new Date().toISOString(),
|
|
332
|
-
};
|
|
333
|
-
this.activeSessions.set(session.id, session);
|
|
334
|
-
this.emit("session:register", {
|
|
335
|
-
sessionId: session.id,
|
|
336
|
-
username,
|
|
337
|
-
remoteAddress,
|
|
338
|
-
});
|
|
339
|
-
return session;
|
|
340
|
-
}
|
|
341
|
-
/**
|
|
342
|
-
* Removes an active session record when the connection closes.
|
|
343
|
-
*
|
|
344
|
-
* Safe to call with a `null` or `undefined` session ID — it will be a no-op.
|
|
345
|
-
*
|
|
346
|
-
* @param sessionId Session UUID returned by `registerSession()`, or nullish.
|
|
347
|
-
*/
|
|
348
|
-
unregisterSession(sessionId) {
|
|
349
|
-
perf.mark("unregisterSession");
|
|
350
|
-
if (!sessionId) {
|
|
351
|
-
return;
|
|
352
|
-
}
|
|
353
|
-
const session = this.activeSessions.get(sessionId);
|
|
354
|
-
this.activeSessions.delete(sessionId);
|
|
355
|
-
if (session) {
|
|
356
|
-
this.emit("session:unregister", {
|
|
357
|
-
sessionId,
|
|
358
|
-
username: session.username,
|
|
359
|
-
});
|
|
360
|
-
}
|
|
361
|
-
this.activeSessions.delete(sessionId);
|
|
362
|
-
}
|
|
363
|
-
/**
|
|
364
|
-
* Updates the username and remote address metadata for an active session.
|
|
365
|
-
*
|
|
366
|
-
* Called internally by `su` and `sudo` when the effective user changes
|
|
367
|
-
* within a session. Silently ignored when the session ID is nullish or
|
|
368
|
-
* unknown.
|
|
369
|
-
*
|
|
370
|
-
* @param sessionId Session UUID to update, or nullish for no-op.
|
|
371
|
-
* @param username New effective username.
|
|
372
|
-
* @param remoteAddress New remote address (usually unchanged).
|
|
373
|
-
*/
|
|
374
|
-
updateSession(sessionId, username, remoteAddress) {
|
|
375
|
-
perf.mark("updateSession");
|
|
376
|
-
if (!sessionId) {
|
|
377
|
-
return;
|
|
378
|
-
}
|
|
379
|
-
const session = this.activeSessions.get(sessionId);
|
|
380
|
-
if (!session) {
|
|
381
|
-
return;
|
|
382
|
-
}
|
|
383
|
-
this.activeSessions.set(sessionId, {
|
|
384
|
-
...session,
|
|
385
|
-
username,
|
|
386
|
-
remoteAddress,
|
|
387
|
-
});
|
|
388
|
-
}
|
|
389
|
-
/**
|
|
390
|
-
* Returns a snapshot of all currently active sessions, sorted by start time.
|
|
391
|
-
*
|
|
392
|
-
* Used by `who`, `ps`, `uptime`, and the `HoneyPot` auditor.
|
|
393
|
-
*
|
|
394
|
-
* @returns Array of `VirtualActiveSession` descriptors.
|
|
395
|
-
*/
|
|
396
|
-
listActiveSessions() {
|
|
397
|
-
perf.mark("listActiveSessions");
|
|
398
|
-
return Array.from(this.activeSessions.values()).sort((left, right) => left.startedAt.localeCompare(right.startedAt));
|
|
399
|
-
}
|
|
400
|
-
/**
|
|
401
|
-
* Returns a sorted list of all registered usernames.
|
|
402
|
-
*
|
|
403
|
-
* @returns Array of username strings sorted alphabetically.
|
|
404
|
-
*/
|
|
405
|
-
listUsers() {
|
|
406
|
-
return Array.from(this.users.keys()).sort();
|
|
407
|
-
}
|
|
408
|
-
loadFromVfs() {
|
|
409
|
-
this.users.clear();
|
|
410
|
-
if (!this.vfs.exists(this.usersPath)) {
|
|
411
|
-
return;
|
|
412
|
-
}
|
|
413
|
-
const raw = this.vfs.readFile(this.usersPath);
|
|
414
|
-
for (const line of raw.split("\n")) {
|
|
415
|
-
const trimmed = line.trim();
|
|
416
|
-
if (trimmed.length === 0) {
|
|
417
|
-
continue;
|
|
418
|
-
}
|
|
419
|
-
const parts = trimmed.split(":");
|
|
420
|
-
if (parts.length < 3) {
|
|
421
|
-
continue;
|
|
422
|
-
}
|
|
423
|
-
const [username, salt, passwordHash] = parts;
|
|
424
|
-
if (!username || !salt || !passwordHash) {
|
|
425
|
-
continue;
|
|
426
|
-
}
|
|
427
|
-
this.users.set(username, { username, salt, passwordHash });
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
loadSudoersFromVfs() {
|
|
431
|
-
this.sudoers.clear();
|
|
432
|
-
if (!this.vfs.exists(this.sudoersPath)) {
|
|
433
|
-
return;
|
|
434
|
-
}
|
|
435
|
-
const raw = this.vfs.readFile(this.sudoersPath);
|
|
436
|
-
for (const line of raw.split("\n")) {
|
|
437
|
-
const username = line.trim();
|
|
438
|
-
if (username.length > 0) {
|
|
439
|
-
this.sudoers.add(username);
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
loadQuotasFromVfs() {
|
|
444
|
-
this.quotas.clear();
|
|
445
|
-
if (!this.vfs.exists(this.quotasPath)) {
|
|
446
|
-
return;
|
|
447
|
-
}
|
|
448
|
-
const raw = this.vfs.readFile(this.quotasPath);
|
|
449
|
-
for (const line of raw.split("\n")) {
|
|
450
|
-
const trimmed = line.trim();
|
|
451
|
-
if (trimmed.length === 0) {
|
|
452
|
-
continue;
|
|
453
|
-
}
|
|
454
|
-
const [username, value] = trimmed.split(":");
|
|
455
|
-
const bytes = Number.parseInt(value ?? "", 10);
|
|
456
|
-
if (!username || !Number.isFinite(bytes) || bytes < 0) {
|
|
457
|
-
continue;
|
|
458
|
-
}
|
|
459
|
-
this.quotas.set(username, bytes);
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
async persist() {
|
|
463
|
-
if (!this.vfs.exists(this.authDirPath)) {
|
|
464
|
-
this.vfs.mkdir(this.authDirPath, 0o700);
|
|
465
|
-
}
|
|
466
|
-
const authContent = Array.from(this.users.values())
|
|
467
|
-
.sort((left, right) => left.username.localeCompare(right.username))
|
|
468
|
-
.map((record) => [record.username, record.salt, record.passwordHash].join(":"))
|
|
469
|
-
.join("\n");
|
|
470
|
-
const sudoersContent = Array.from(this.sudoers.values()).sort().join("\n");
|
|
471
|
-
const quotasContent = Array.from(this.quotas.entries())
|
|
472
|
-
.sort(([left], [right]) => left.localeCompare(right))
|
|
473
|
-
.map(([username, maxBytes]) => `${username}:${maxBytes}`)
|
|
474
|
-
.join("\n");
|
|
475
|
-
let changed = false;
|
|
476
|
-
changed =
|
|
477
|
-
this.writeIfChanged(this.usersPath, authContent.length > 0 ? `${authContent}\n` : "", 0o600) || changed;
|
|
478
|
-
changed =
|
|
479
|
-
this.writeIfChanged(this.sudoersPath, sudoersContent.length > 0 ? `${sudoersContent}\n` : "", 0o600) || changed;
|
|
480
|
-
changed =
|
|
481
|
-
this.writeIfChanged(this.quotasPath, quotasContent.length > 0 ? `${quotasContent}\n` : "", 0o600) || changed;
|
|
482
|
-
if (changed) {
|
|
483
|
-
await this.vfs.flushMirror();
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
writeIfChanged(targetPath, content, mode) {
|
|
487
|
-
if (this.vfs.exists(targetPath)) {
|
|
488
|
-
const existing = this.vfs.readFile(targetPath);
|
|
489
|
-
if (existing === content) {
|
|
490
|
-
this.vfs.chmod(targetPath, mode);
|
|
491
|
-
return false;
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
this.vfs.writeFile(targetPath, content, { mode });
|
|
495
|
-
return true;
|
|
496
|
-
}
|
|
497
|
-
createRecord(username, password) {
|
|
498
|
-
// Cache key is a hash of the inputs — never store plaintext password in memory
|
|
499
|
-
const cacheKey = createHash("sha256").update(username).update(":").update(password).digest("hex");
|
|
500
|
-
const cached = VirtualUserManager.recordCache.get(cacheKey);
|
|
501
|
-
if (cached) {
|
|
502
|
-
return cached;
|
|
503
|
-
}
|
|
504
|
-
const salt = randomBytes(16).toString("hex");
|
|
505
|
-
const record = {
|
|
506
|
-
username,
|
|
507
|
-
salt,
|
|
508
|
-
// Hash uses the generated salt — verifyPassword must use record.salt
|
|
509
|
-
passwordHash: this.hashPassword(password, salt),
|
|
510
|
-
};
|
|
511
|
-
VirtualUserManager.recordCache.set(cacheKey, record);
|
|
512
|
-
return record;
|
|
513
|
-
}
|
|
514
|
-
/**
|
|
515
|
-
* Returns `true` when the user has a non-empty password set.
|
|
516
|
-
*
|
|
517
|
-
* A user with no password (or whose password hash matches the empty-string
|
|
518
|
-
* hash) is allowed to authenticate without a credential check.
|
|
519
|
-
*
|
|
520
|
-
* @param username Target username.
|
|
521
|
-
*/
|
|
522
|
-
hasPassword(username) {
|
|
523
|
-
perf.mark("hasPassword");
|
|
524
|
-
const record = this.users.get(username);
|
|
525
|
-
if (!record)
|
|
526
|
-
return false;
|
|
527
|
-
// Empty password hash computed with the record's own salt
|
|
528
|
-
const emptyHash = this.hashPassword("", record.salt);
|
|
529
|
-
if (record.passwordHash === emptyHash)
|
|
530
|
-
return false;
|
|
531
|
-
return !!record.passwordHash;
|
|
532
|
-
}
|
|
533
|
-
/**
|
|
534
|
-
* Hashes a plaintext password using scrypt (or SHA-256 in fast-hash mode).
|
|
535
|
-
*
|
|
536
|
-
* Set `SSH_MIMIC_FAST_PASSWORD_HASH=1` to switch to SHA-256 for test
|
|
537
|
-
* environments where scrypt latency is undesirable.
|
|
538
|
-
*
|
|
539
|
-
* @param password Plaintext password string.
|
|
540
|
-
* @returns Hex-encoded hash string.
|
|
541
|
-
*/
|
|
542
|
-
/**
|
|
543
|
-
* Hash a password with an optional salt.
|
|
544
|
-
* When salt is provided (verify path), the same salt is used for a
|
|
545
|
-
* deterministic hash. When omitted (create path), an empty salt is used
|
|
546
|
-
* for backward compat — callers should pass the stored salt on verify.
|
|
547
|
-
*/
|
|
548
|
-
hashPassword(password, salt = "") {
|
|
549
|
-
if (VirtualUserManager.fastPasswordHash) {
|
|
550
|
-
return createHash("sha256")
|
|
551
|
-
.update(salt)
|
|
552
|
-
.update(password)
|
|
553
|
-
.digest("hex");
|
|
554
|
-
}
|
|
555
|
-
return scryptSync(password, salt || "", 32).toString("hex");
|
|
556
|
-
}
|
|
557
|
-
validateUsername(username) {
|
|
558
|
-
if (!username || username.trim() === "") {
|
|
559
|
-
throw new Error("invalid username");
|
|
560
|
-
}
|
|
561
|
-
if (!/^[a-z_][a-z0-9_-]{0,31}$/i.test(username)) {
|
|
562
|
-
throw new Error("invalid username");
|
|
563
|
-
}
|
|
564
|
-
}
|
|
565
|
-
validatePassword(password) {
|
|
566
|
-
if (!password || password.trim() === "") {
|
|
567
|
-
throw new Error("invalid password");
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
authorizedKeys = new Map();
|
|
571
|
-
/**
|
|
572
|
-
* Adds an SSH public key for a user, enabling public-key authentication.
|
|
573
|
-
*
|
|
574
|
-
* @param username Target user.
|
|
575
|
-
* @param algo Key algorithm (e.g. "ssh-rsa", "ssh-ed25519").
|
|
576
|
-
* @param data Raw key data as a Buffer (the base64-decoded key bytes).
|
|
577
|
-
*/
|
|
578
|
-
addAuthorizedKey(username, algo, data) {
|
|
579
|
-
perf.mark("addAuthorizedKey");
|
|
580
|
-
const keys = this.authorizedKeys.get(username) ?? [];
|
|
581
|
-
keys.push({ algo, data });
|
|
582
|
-
this.authorizedKeys.set(username, keys);
|
|
583
|
-
this.emit("key:add", { username, algo });
|
|
584
|
-
}
|
|
585
|
-
/**
|
|
586
|
-
* Removes all authorized keys for a user.
|
|
587
|
-
*
|
|
588
|
-
* @param username Target user.
|
|
589
|
-
*/
|
|
590
|
-
removeAuthorizedKeys(username) {
|
|
591
|
-
this.authorizedKeys.delete(username);
|
|
592
|
-
this.emit("key:remove", { username });
|
|
593
|
-
}
|
|
594
|
-
/**
|
|
595
|
-
* Returns the list of authorized keys for a user.
|
|
596
|
-
* Returns an empty array when no keys are registered.
|
|
597
|
-
*
|
|
598
|
-
* @param username Target user.
|
|
599
|
-
*/
|
|
600
|
-
getAuthorizedKeys(username) {
|
|
601
|
-
return this.authorizedKeys.get(username) ?? [];
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
function normalizeVfsPath(targetPath) {
|
|
605
|
-
const normalized = path.posix.normalize(targetPath);
|
|
606
|
-
return normalized.startsWith("/") ? normalized : `/${normalized}`;
|
|
607
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"adduser.d.ts","sourceRoot":"","sources":["adduser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGpE;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,cAAc,EAAE,WAuF5B,CAAC"}
|
package/src/commands/adduser.js
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Add a new user interactively.
|
|
3
|
-
*
|
|
4
|
-
* Usage: `adduser <username>`
|
|
5
|
-
*
|
|
6
|
-
* Prompts for:
|
|
7
|
-
* New password: ****
|
|
8
|
-
* Retype new password: ****
|
|
9
|
-
*
|
|
10
|
-
* Mirrors the real `adduser` behaviour — password is never passed on the
|
|
11
|
-
* command line. Root-only.
|
|
12
|
-
*/
|
|
13
|
-
export const adduserCommand = {
|
|
14
|
-
name: "adduser",
|
|
15
|
-
description: "Add a new user",
|
|
16
|
-
category: "users",
|
|
17
|
-
params: ["<username>"],
|
|
18
|
-
run: ({ authUser, shell, args }) => {
|
|
19
|
-
if (authUser !== "root") {
|
|
20
|
-
return { stderr: "adduser: permission denied\n", exitCode: 1 };
|
|
21
|
-
}
|
|
22
|
-
const username = args[0];
|
|
23
|
-
if (!username) {
|
|
24
|
-
return {
|
|
25
|
-
stderr: "Usage: adduser <username>\n",
|
|
26
|
-
exitCode: 1,
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
// Reject if user already exists
|
|
30
|
-
if (shell.users.listUsers().includes(username)) {
|
|
31
|
-
return {
|
|
32
|
-
stderr: `adduser: user '${username}' already exists\n`,
|
|
33
|
-
exitCode: 1,
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
let newPassword = "";
|
|
37
|
-
let step = "new";
|
|
38
|
-
const onPassword = async (input, sh) => {
|
|
39
|
-
if (step === "new") {
|
|
40
|
-
if (input.length < 1) {
|
|
41
|
-
return {
|
|
42
|
-
result: {
|
|
43
|
-
stderr: "adduser: password cannot be empty\n",
|
|
44
|
-
exitCode: 1,
|
|
45
|
-
},
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
newPassword = input;
|
|
49
|
-
step = "retype";
|
|
50
|
-
return { result: null, nextPrompt: "Retype new password: " };
|
|
51
|
-
}
|
|
52
|
-
// step === "retype"
|
|
53
|
-
if (input !== newPassword) {
|
|
54
|
-
return {
|
|
55
|
-
result: {
|
|
56
|
-
stderr: "adduser: passwords do not match — user not created\n",
|
|
57
|
-
exitCode: 1,
|
|
58
|
-
},
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
await sh.users.addUser(username, newPassword);
|
|
62
|
-
return {
|
|
63
|
-
result: {
|
|
64
|
-
stdout: `${[
|
|
65
|
-
`Adding user '${username}' ...`,
|
|
66
|
-
`Adding new group '${username}' (1001) ...`,
|
|
67
|
-
`Adding new user '${username}' (1001) with group '${username}' ...`,
|
|
68
|
-
`Creating home directory '/home/${username}' ...`,
|
|
69
|
-
`passwd: password set for '${username}'`,
|
|
70
|
-
`adduser: done.`,
|
|
71
|
-
].join("\n")}\n`,
|
|
72
|
-
exitCode: 0,
|
|
73
|
-
},
|
|
74
|
-
};
|
|
75
|
-
};
|
|
76
|
-
return {
|
|
77
|
-
sudoChallenge: {
|
|
78
|
-
username,
|
|
79
|
-
targetUser: username,
|
|
80
|
-
commandLine: null,
|
|
81
|
-
loginShell: false,
|
|
82
|
-
prompt: "New password: ",
|
|
83
|
-
mode: "passwd",
|
|
84
|
-
onPassword,
|
|
85
|
-
},
|
|
86
|
-
exitCode: 0,
|
|
87
|
-
};
|
|
88
|
-
},
|
|
89
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"alias.d.ts","sourceRoot":"","sources":["alias.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD;;;;GAIG;AACH,eAAO,MAAM,YAAY,EAAE,WAkC1B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,WAoB5B,CAAC"}
|