From 33cea94f6df58394055589c45e43ff498970385a Mon Sep 17 00:00:00 2001 From: b1ek Date: Fri, 5 May 2023 14:36:47 +1000 Subject: [PATCH] add stdin and half-baked su command --- src/emulator/commands/index.js | 5 +- src/emulator/commands/su.js | 31 +++++++++++++ src/emulator/zsh.js | 83 ++++++++++++++++++++++++++++++---- 3 files changed, 109 insertions(+), 10 deletions(-) create mode 100644 src/emulator/commands/su.js diff --git a/src/emulator/commands/index.js b/src/emulator/commands/index.js index d96a03d..83b88e0 100644 --- a/src/emulator/commands/index.js +++ b/src/emulator/commands/index.js @@ -8,7 +8,6 @@ let cmds = { 'wget': require('./wget'), 'export_file': require('./export_file'), 'import_file': require('./import_file'), - 'zsh': require('./zsh'), 'ps': require('./ps'), 'clear': require('./clear'), 'rm': require('./rm'), @@ -16,6 +15,10 @@ let cmds = { 'exit': require('./exit'), 'systemctl': require('./systemctl'), 'set-hostname': require('./set-hostname.js'), + + // funny stuff + 'su': require('./su'), + 'zsh': require('./zsh'), 'guide': require('./guide'), diff --git a/src/emulator/commands/su.js b/src/emulator/commands/su.js new file mode 100644 index 0000000..6c4eabe --- /dev/null +++ b/src/emulator/commands/su.js @@ -0,0 +1,31 @@ +const { Terminal } = require("xterm"); + +/** + * @param {string[]} argv + * @param {Terminal} terminal + */ +module.exports = async (argv, terminal, zsh) => { + if (argv.indexOf('--help') !== -1) { + terminal.writeln( + `Usage: ${argv[0]} [options] []` + '\n' + + 'Change the user ID and group ID to \'s.' + '\n' + + '\n' + + 'If is not giver, root is assumed.' + '\n' + + 'This command is an easter egg. Try to guess the root\'s password!' + ); + return; + } + + const user = argv[1] || 'root'; + const users = Object.freeze(['root', 'daemon', 'bin', 'sys', 'adm', 'nobody', 'lpd', 'lp', 'ipsec', 'user']); + + if (users.indexOf(user) == -1) { + terminal.writeln(`${argv[0]}: user ${user} does not exist or the user entry does not contain all the required fields`); + return 2; + } + + terminal.write('Password: '); + const pass = await zsh.get_stdin({hide: true}); + + terminal.write(pass); +} \ No newline at end of file diff --git a/src/emulator/zsh.js b/src/emulator/zsh.js index f863c38..091a70d 100644 --- a/src/emulator/zsh.js +++ b/src/emulator/zsh.js @@ -23,8 +23,9 @@ const zshapi = { update_prompt, text_prompt, pr_char, + get_stdin, terminal, - dom + dom, }; let prompt = `\x1b[1;32muser@${data.ip} \x1b[36m~ $ \x1b[0m`; @@ -39,17 +40,71 @@ function text_prompt() { return prompt.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, ''); } +let stdin_open = false; + +/** + * + * @param {{hide: boolean}} opt + * @returns + */ +async function get_stdin(opt) { + + if (opt == undefined) opt = {}; + + if (stdin_open) { + return 0; + } + stdin_open = true; + + let input = ''; + + const get_char = function(e) { + if (break_loop) return; + + /** @type {KeyboardEvent} */ + const dom = e.domEvent; + + const startX = terminal.buffer.active.cursorX; + + if ((dom.key.length == 1 && !(dom.ctrlKey || dom.altKey))) { + // non-special key + if (!opt.hide) terminal.write(dom.key); + input += dom.key; + } else { + // special key + switch (dom.keyCode) { + case 8: + if (terminal.buffer.active.cursorX <= startX) return; + terminal.write('\b \b'); + input = input.substring(0, input.length - 1); + case 13: + break_loop = true; + terminal.write('\n'); + break; + case 68: + if (dom.ctrlKey && dom.key.toLowerCase() == 'd') { + terminal.write('\x1b[0m\x1b[49m^D\x1b[0m'); + break_loop = true; + } + } + } + } + let break_loop = false + + terminal.onKey(get_char) + + while (1) { + await sleep(5); + if (break_loop) break; + } + + stdin_open = false; + return input; +} + /** * * @param { string } char -// ZSH api to be used in commands (see references) -const zshapi = { - update_prompt, - text_prompt, - pr_char, - terminal, - dom -}; * @param { KeyboardEvent } dom */ function pr_char(char, dom) { @@ -179,6 +234,13 @@ async function control_char(id, dom) { terminal.write(lastcmd); break; + case 40: + if (cmd == '') break; + lastcmd = cmd; + reprint_prompt(); + cmd = ''; + break; + // Ctrl+c case 67: if (dom.ctrlKey) { @@ -204,6 +266,7 @@ async function control_char(id, dom) { case 68: if (dom.ctrlKey && dom.key.toLowerCase() == 'd') { + alert('you are a moron. zsh runs with PID 1'); terminal.writeln(''); pr_char = () => {}; exec_cmd = pr_char; @@ -231,6 +294,8 @@ async function control_char(id, dom) { } function key(e) { + if (stdin_open) return; + /** @type {KeyboardEvent} */ const dom = e.domEvent; if (dom.key.length == 1 && !(dom.ctrlKey || dom.altKey)) {