From 829453f805590486ca3a608226ad40e36ed51772 Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Mon, 26 Jun 2017 22:36:09 -0500 Subject: [PATCH 1/9] [Security] Address critical flaw in console rendering that allowed arbitrary command execution --- CHANGELOG.md | 7 + README.md | 4 +- public/themes/pterodactyl/css/pterodactyl.css | 87 +++++ .../themes/pterodactyl/js/frontend/console.js | 101 ++++-- .../themes/pterodactyl/vendor/ansi/ansi_up.js | 335 ++++++++++++++++++ .../vendor/terminal/jquery.terminal.css | 17 - .../vendor/terminal/jquery.terminal.min.js | 39 -- .../vendor/terminal/keyboard.polyfill.js | 121 ------- .../vendor/terminal/unix_formatting.js | 318 ----------------- .../pterodactyl/server/console.blade.php | 22 +- .../themes/pterodactyl/server/index.blade.php | 12 +- 11 files changed, 515 insertions(+), 548 deletions(-) create mode 100644 public/themes/pterodactyl/vendor/ansi/ansi_up.js delete mode 100755 public/themes/pterodactyl/vendor/terminal/jquery.terminal.css delete mode 100644 public/themes/pterodactyl/vendor/terminal/jquery.terminal.min.js delete mode 100644 public/themes/pterodactyl/vendor/terminal/keyboard.polyfill.js delete mode 100755 public/themes/pterodactyl/vendor/terminal/unix_formatting.js diff --git a/CHANGELOG.md b/CHANGELOG.md index a776bb872..5acdc17d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,13 @@ This file is a running track of new features and fixes to each version of the pa This project follows [Semantic Versioning](http://semver.org) guidelines. +## v0.6.3 (Courageous Carniadactylus) +### Fixed +* **[Security]** — Addresses an oversight in how the terminal rendered information sent from the server feed which allowed a malicious user to execute arbitrary commands on the game-server process itself by using a specifically crafted in-game command. + +### Changed +* Removed `jquery.terminal` and replaced it with an in-house developed terminal with less potential for security issues. + ## v0.6.2 (Courageous Carniadactylus) ### Fixed * Fixes a few typos throughout the panel, there are more don't worry. diff --git a/README.md b/README.md index c47e6f101..393dff90c 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,8 @@ AdminLTE - [license](https://github.com/almasaeed2010/AdminLTE/blob/master/LICEN Animate.css - [license](https://github.com/daneden/animate.css/blob/master/LICENSE) - [homepage](http://daneden.github.io/animate.css/) +AnsiUp - [license](https://github.com/drudru/ansi_up/blob/master/Readme.md#license) - [homepage](https://github.com/drudru/ansi_up) + Async.js - [license](https://github.com/caolan/async/blob/master/LICENSE) - [homepage](https://github.com/caolan/async/) Bootstrap - [license](https://github.com/twbs/bootstrap/blob/master/LICENSE) - [homepage](http://getbootstrap.com) @@ -53,8 +55,6 @@ FontAwesome Animations - [license](https://github.com/l-lin/font-awesome-animati jQuery - [license](https://github.com/jquery/jquery/blob/master/LICENSE.txt) - [homepage](http://jquery.com) -jQuery Terminal - [license](https://github.com/jcubic/jquery.terminal/blob/master/LICENSE) - [homepage](http://terminal.jcubic.pl) - Laravel Framework - [license](https://github.com/laravel/framework/blob/5.4/LICENSE.md) - [homepage](https://laravel.com) Lodash - [license](https://github.com/lodash/lodash/blob/master/LICENSE) - [homepage](https://lodash.com/) diff --git a/public/themes/pterodactyl/css/pterodactyl.css b/public/themes/pterodactyl/css/pterodactyl.css index afc0377c3..ff6966b1a 100644 --- a/public/themes/pterodactyl/css/pterodactyl.css +++ b/public/themes/pterodactyl/css/pterodactyl.css @@ -311,3 +311,90 @@ input.form-autocomplete-stop[readonly] { background: white; box-shadow: none !important; } + +#terminal { + font-family: monospace; + color: #aaa; + background: #000; + font-size: 12px; + line-height: 14px; + padding: 10px 10px 0; + box-sizing: border-box; + min-height: 30px; + max-height: 500px; + overflow-y: auto; + overflow-x: hidden; + border-radius: 5px 5px 0 0; +} + +#terminal > .cmd { + padding: 1px 0; +} + +@keyframes blinky { + 0% { + background: transparent; + } + 100% { + background: rgba(170, 170, 170, 0.9); + } +} + +@-webkit-keyframes blinky { + 0% { + background: transparent; + } + 100% { + background: rgba(170, 170, 170, 0.9); + } +} + +#terminal_input { + width: 100%; + background: #000; + border-radius: 0 0 5px 5px; + padding: 5px 10px; +} + +.terminal_input--input { + height: 0; + width: 0; + position: absolute; + top: -20px; +} + +.terminal_input--text, .terminal_input--prompt { + line-height: 14px; + width: 100%; + vertical-align: middle; + font-size: 12px; + font-family: monospace; + margin-bottom: 0; + background: transparent; + color: #aaa; +} + +.terminal_input--text:before, .terminal_input--text:after { + content: ""; + display: inline-block; + width: 7px; + height: 14px; + margin: 0 0 -12px -6px; + vertical-align: middle; +} + +.terminal_input--text:after { + position: relative; + bottom: 8px; + left: 8px; + background: #ff00; + animation: blinky 0.6s linear infinite alternate; + -webkit-animation: blinky 0.6s linear infinite alternate; +} + +.terminal_input--input { + color: transparent; + background-color: transparent; + border: 0; + outline: none; +} diff --git a/public/themes/pterodactyl/js/frontend/console.js b/public/themes/pterodactyl/js/frontend/console.js index b0cd9755b..c77576f26 100644 --- a/public/themes/pterodactyl/js/frontend/console.js +++ b/public/themes/pterodactyl/js/frontend/console.js @@ -20,39 +20,56 @@ var CONSOLE_PUSH_COUNT = Pterodactyl.config.console_count || 10; var CONSOLE_PUSH_FREQ = Pterodactyl.config.console_freq || 200; var CONSOLE_OUTPUT_LIMIT = Pterodactyl.config.console_limit || 2000; + var InitialLogSent = false; +var AnsiUp = new AnsiUp; + +var $terminal = $('#terminal'); +var $ghostInput = $('.terminal_input--input'); +var $visibleInput = $('.terminal_input--text'); +var $scrollNotify = $('#terminalNotify'); + +$(document).ready(function () { + $ghostInput.focus(); + $('.terminal_input--text, #terminal_input, #terminal, #terminalNotify').on('click', function () { + $ghostInput.focus(); + }); + + $ghostInput.on('input', function () { + $visibleInput.html($(this).val()); + }); + + $ghostInput.on('keyup', function (e) { + if (e.which === 13) { + Socket.emit((ConsoleServerStatus !== 0) ? 'send command' : 'set status', $(this).val()); + + $(this).val(''); + $visibleInput.html(''); + } + }); +}); + +$terminal.on('scroll', function () { + if ($(this).scrollTop() + $(this).innerHeight() < $(this)[0].scrollHeight) { + $scrollNotify.removeClass('hidden'); + } else { + $scrollNotify.addClass('hidden'); + } +}); + +window.scrollToBottom = function () { + $terminal.scrollTop($terminal[0].scrollHeight); +}; (function initConsole() { window.TerminalQueue = []; window.ConsoleServerStatus = 0; - window.Terminal = $('#terminal').terminal(function (command, term) { - Socket.emit((ConsoleServerStatus !== 0) ? 'send command' : 'set status', command); - }, { - greetings: '', - name: Pterodactyl.server.uuid, - height: 450, - exit: false, - echoCommand: false, - outputLimit: CONSOLE_OUTPUT_LIMIT, - prompt: Pterodactyl.server.username + ':~$ ', - scrollOnEcho: false, - scrollBottomOffset: 5, - onBlur: function (terminal) { - return false; - } + window.ConsoleElements = 0; + + $scrollNotify.on('click', function () { + window.scrollToBottom(); + $scrollNotify.addClass('hidden'); }); - - window.TerminalNotifyElement = $('#terminalNotify'); - TerminalNotifyElement.on('click', function () { - Terminal.scroll_to_bottom(); - TerminalNotifyElement.addClass('hidden'); - }) - - Terminal.on('scroll', function () { - if (Terminal.is_bottom()) { - TerminalNotifyElement.addClass('hidden'); - } - }) })(); (function pushOutputQueue() { @@ -62,16 +79,22 @@ var InitialLogSent = false; if (TerminalQueue.length > 0) { for (var i = 0; i < CONSOLE_PUSH_COUNT && TerminalQueue.length > 0; i++) { - Terminal.echo(TerminalQueue[0], { flush: false }); + $terminal.append( + '
' + AnsiUp.ansi_to_html(TerminalQueue[0] + '\u001b[0m') + '
' + ); + + if (! $scrollNotify.is(':visible')) { + window.scrollToBottom(); + } + + window.ConsoleElements++; TerminalQueue.shift(); } - // Flush after looping through all. - Terminal.flush(); - - // Show Warning - if (! Terminal.is_bottom()) { - TerminalNotifyElement.removeClass('hidden'); + var removeElements = window.ConsoleElements - CONSOLE_OUTPUT_LIMIT; + if (removeElements > 0) { + $('#terminal').find('.cmd').slice(0, removeElements).remove(); + window.ConsoleElements = window.ConsoleElements - removeElements; } } @@ -99,14 +122,18 @@ var InitialLogSent = false; Socket.on('server log', function (data) { if (! InitialLogSent) { - Terminal.clear(); - TerminalQueue.push(data); + $('#terminal').html(''); + data.split(/\n/g).forEach(function (item) { + TerminalQueue.push(item); + }); InitialLogSent = true; } }); Socket.on('console', function (data) { - TerminalQueue.push(data.line); + data.line.split(/\n/g).forEach(function (item) { + TerminalQueue.push(item); + }); }); })(); diff --git a/public/themes/pterodactyl/vendor/ansi/ansi_up.js b/public/themes/pterodactyl/vendor/ansi/ansi_up.js new file mode 100644 index 000000000..c17c9d566 --- /dev/null +++ b/public/themes/pterodactyl/vendor/ansi/ansi_up.js @@ -0,0 +1,335 @@ +/* ansi_up.js + * author : Dru Nelson + * license : MIT + * http://github.com/drudru/ansi_up + */ +(function (factory) { + var v; + if (typeof module === "object" && typeof module.exports === "object") { + v = factory(require, exports); + if ("undefined" !== typeof v) module.exports = v; + } + else if ("function" === typeof define && define.amd) { + define(["require", "exports"], factory); + } + else { + var req, exp = {}; + v = factory(req, exp); + window.AnsiUp = exp.default; + } +})(function (require, exports) { + + "use strict"; + function rgx(tmplObj) { + var subst = []; + for (var _i = 1; _i < arguments.length; _i++) { + subst[_i - 1] = arguments[_i]; + } + var regexText = tmplObj.raw[0]; + var wsrgx = /^\s+|\s+\n|\s+#[\s\S]+?\n/gm; + var txt2 = regexText.replace(wsrgx, ''); + return new RegExp(txt2, 'm'); + } + var AnsiUp = (function () { + function AnsiUp() { + this.VERSION = "2.0.1"; + this.ansi_colors = [ + [ + { rgb: [0, 0, 0], class_name: "ansi-black" }, + { rgb: [187, 0, 0], class_name: "ansi-red" }, + { rgb: [0, 187, 0], class_name: "ansi-green" }, + { rgb: [187, 187, 0], class_name: "ansi-yellow" }, + { rgb: [0, 0, 187], class_name: "ansi-blue" }, + { rgb: [187, 0, 187], class_name: "ansi-magenta" }, + { rgb: [0, 187, 187], class_name: "ansi-cyan" }, + { rgb: [255, 255, 255], class_name: "ansi-white" } + ], + [ + { rgb: [85, 85, 85], class_name: "ansi-bright-black" }, + { rgb: [255, 85, 85], class_name: "ansi-bright-red" }, + { rgb: [0, 255, 0], class_name: "ansi-bright-green" }, + { rgb: [255, 255, 85], class_name: "ansi-bright-yellow" }, + { rgb: [85, 85, 255], class_name: "ansi-bright-blue" }, + { rgb: [255, 85, 255], class_name: "ansi-bright-magenta" }, + { rgb: [85, 255, 255], class_name: "ansi-bright-cyan" }, + { rgb: [255, 255, 255], class_name: "ansi-bright-white" } + ] + ]; + this.htmlFormatter = { + transform: function (fragment, instance) { + var txt = fragment.text; + if (txt.length === 0) + return txt; + if (instance._escape_for_html) + txt = instance.old_escape_for_html(txt); + if (!fragment.bright && fragment.fg === null && fragment.bg === null) + return txt; + var styles = []; + var classes = []; + var fg = fragment.fg; + var bg = fragment.bg; + if (fg === null && fragment.bright) + fg = instance.ansi_colors[1][7]; + if (!instance._use_classes) { + if (fg) + styles.push("color:rgb(" + fg.rgb.join(',') + ")"); + if (bg) + styles.push("background-color:rgb(" + bg.rgb + ")"); + } + else { + if (fg) { + if (fg.class_name !== 'truecolor') { + classes.push(fg.class_name + "-fg"); + } + else { + styles.push("color:rgb(" + fg.rgb.join(',') + ")"); + } + } + if (bg) { + if (bg.class_name !== 'truecolor') { + classes.push(bg.class_name + "-bg"); + } + else { + styles.push("background-color:rgb(" + bg.rgb.join(',') + ")"); + } + } + } + var class_string = ''; + var style_string = ''; + if (classes.length) + class_string = " class=\"" + classes.join(' ') + "\""; + if (styles.length) + style_string = " style=\"" + styles.join(';') + "\""; + return "" + txt + ""; + }, + compose: function (segments, instance) { + return segments.join(""); + } + }; + this.textFormatter = { + transform: function (fragment, instance) { + return fragment.text; + }, + compose: function (segments, instance) { + return segments.join(""); + } + }; + this.setup_256_palette(); + this._use_classes = false; + this._escape_for_html = true; + this.bright = false; + this.fg = this.bg = null; + this._buffer = ''; + } + Object.defineProperty(AnsiUp.prototype, "use_classes", { + get: function () { + return this._use_classes; + }, + set: function (arg) { + this._use_classes = arg; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(AnsiUp.prototype, "escape_for_html", { + get: function () { + return this._escape_for_html; + }, + set: function (arg) { + this._escape_for_html = arg; + }, + enumerable: true, + configurable: true + }); + AnsiUp.prototype.setup_256_palette = function () { + var _this = this; + this.palette_256 = []; + this.ansi_colors.forEach(function (palette) { + palette.forEach(function (rec) { + _this.palette_256.push(rec); + }); + }); + var levels = [0, 95, 135, 175, 215, 255]; + for (var r = 0; r < 6; ++r) { + for (var g = 0; g < 6; ++g) { + for (var b = 0; b < 6; ++b) { + var col = { rgb: [levels[r], levels[g], levels[b]], class_name: 'truecolor' }; + this.palette_256.push(col); + } + } + } + var grey_level = 8; + for (var i = 0; i < 24; ++i, grey_level += 10) { + var gry = { rgb: [grey_level, grey_level, grey_level], class_name: 'truecolor' }; + this.palette_256.push(gry); + } + }; + AnsiUp.prototype.old_escape_for_html = function (txt) { + return txt.replace(/[&<>]/gm, function (str) { + if (str === "&") + return "&"; + if (str === "<") + return "<"; + if (str === ">") + return ">"; + }); + }; + AnsiUp.prototype.old_linkify = function (txt) { + return txt.replace(/(https?:\/\/[^\s]+)/gm, function (str) { + return "" + str + ""; + }); + }; + AnsiUp.prototype.detect_incomplete_ansi = function (txt) { + return !(/.*?[\x40-\x7e]/.test(txt)); + }; + AnsiUp.prototype.detect_incomplete_link = function (txt) { + var found = false; + for (var i = txt.length - 1; i > 0; i--) { + if (/\s|\x1B/.test(txt[i])) { + found = true; + break; + } + } + if (!found) { + if (/(https?:\/\/[^\s]+)/.test(txt)) + return 0; + else + return -1; + } + var prefix = txt.substr(i + 1, 4); + if (prefix.length === 0) + return -1; + if ("http".indexOf(prefix) === 0) + return (i + 1); + }; + AnsiUp.prototype.ansi_to = function (txt, formatter) { + var pkt = this._buffer + txt; + this._buffer = ''; + var raw_text_pkts = pkt.split(/\x1B\[/); + if (raw_text_pkts.length === 1) + raw_text_pkts.push(''); + this.handle_incomplete_sequences(raw_text_pkts); + var first_chunk = this.with_state(raw_text_pkts.shift()); + var blocks = new Array(raw_text_pkts.length); + for (var i = 0, len = raw_text_pkts.length; i < len; ++i) { + blocks[i] = (formatter.transform(this.process_ansi(raw_text_pkts[i]), this)); + } + if (first_chunk.text.length > 0) + blocks.unshift(formatter.transform(first_chunk, this)); + return formatter.compose(blocks, this); + }; + AnsiUp.prototype.ansi_to_html = function (txt) { + return this.ansi_to(txt, this.htmlFormatter); + }; + AnsiUp.prototype.ansi_to_text = function (txt) { + return this.ansi_to(txt, this.textFormatter); + }; + AnsiUp.prototype.with_state = function (text) { + return { bright: this.bright, fg: this.fg, bg: this.bg, text: text }; + }; + AnsiUp.prototype.handle_incomplete_sequences = function (chunks) { + var last_chunk = chunks[chunks.length - 1]; + if ((last_chunk.length > 0) && this.detect_incomplete_ansi(last_chunk)) { + this._buffer = "\x1B[" + last_chunk; + chunks.pop(); + chunks.push(''); + } + else { + if (last_chunk.slice(-1) === "\x1B") { + this._buffer = "\x1B"; + console.log("raw", chunks); + chunks.pop(); + chunks.push(last_chunk.substr(0, last_chunk.length - 1)); + console.log(chunks); + console.log(last_chunk); + } + if (chunks.length === 2 && + chunks[1] === "" && + chunks[0].slice(-1) === "\x1B") { + this._buffer = "\x1B"; + last_chunk = chunks.shift(); + chunks.unshift(last_chunk.substr(0, last_chunk.length - 1)); + } + } + }; + AnsiUp.prototype.process_ansi = function (block) { + if (!this._sgr_regex) { + this._sgr_regex = (_a = ["\n ^ # beginning of line\n ([!<-?]?) # a private-mode char (!, <, =, >, ?)\n ([d;]*) # any digits or semicolons\n ([ -/]? # an intermediate modifier\n [@-~]) # the command\n ([sS]*) # any text following this CSI sequence\n "], _a.raw = ["\n ^ # beginning of line\n ([!\\x3c-\\x3f]?) # a private-mode char (!, <, =, >, ?)\n ([\\d;]*) # any digits or semicolons\n ([\\x20-\\x2f]? # an intermediate modifier\n [\\x40-\\x7e]) # the command\n ([\\s\\S]*) # any text following this CSI sequence\n "], rgx(_a)); + } + var matches = block.match(this._sgr_regex); + if (!matches) { + return this.with_state(block); + } + var orig_txt = matches[4]; + if (matches[1] !== '' || matches[3] !== 'm') { + return this.with_state(orig_txt); + } + var sgr_cmds = matches[2].split(';'); + while (sgr_cmds.length > 0) { + var sgr_cmd_str = sgr_cmds.shift(); + var num = parseInt(sgr_cmd_str, 10); + if (isNaN(num) || num === 0) { + this.fg = this.bg = null; + this.bright = false; + } + else if (num === 1) { + this.bright = true; + } + else if (num === 22) { + this.bright = false; + } + else if (num === 39) { + this.fg = null; + } + else if (num === 49) { + this.bg = null; + } + else if ((num >= 30) && (num < 38)) { + var bidx = this.bright ? 1 : 0; + this.fg = this.ansi_colors[bidx][(num - 30)]; + } + else if ((num >= 90) && (num < 98)) { + this.fg = this.ansi_colors[1][(num - 90)]; + } + else if ((num >= 40) && (num < 48)) { + this.bg = this.ansi_colors[0][(num - 40)]; + } + else if ((num >= 100) && (num < 108)) { + this.bg = this.ansi_colors[1][(num - 100)]; + } + else if (num === 38 || num === 48) { + if (sgr_cmds.length > 0) { + var is_foreground = (num === 38); + var mode_cmd = sgr_cmds.shift(); + if (mode_cmd === '5' && sgr_cmds.length > 0) { + var palette_index = parseInt(sgr_cmds.shift(), 10); + if (palette_index >= 0 && palette_index <= 255) { + if (is_foreground) + this.fg = this.palette_256[palette_index]; + else + this.bg = this.palette_256[palette_index]; + } + } + if (mode_cmd === '2' && sgr_cmds.length > 2) { + var r = parseInt(sgr_cmds.shift(), 10); + var g = parseInt(sgr_cmds.shift(), 10); + var b = parseInt(sgr_cmds.shift(), 10); + if ((r >= 0 && r <= 255) && (g >= 0 && g <= 255) && (b >= 0 && b <= 255)) { + var c = { rgb: [r, g, b], class_name: 'truecolor' }; + if (is_foreground) + this.fg = c; + else + this.bg = c; + } + } + } + } + } + return this.with_state(orig_txt); + var _a; + }; + return AnsiUp; + }()); + Object.defineProperty(exports, "__esModule", { value: true }); + exports.default = AnsiUp; +}); diff --git a/public/themes/pterodactyl/vendor/terminal/jquery.terminal.css b/public/themes/pterodactyl/vendor/terminal/jquery.terminal.css deleted file mode 100755 index 0d9305d8b..000000000 --- a/public/themes/pterodactyl/vendor/terminal/jquery.terminal.css +++ /dev/null @@ -1,17 +0,0 @@ -/*! - * __ _____ ________ __ - * / // _ /__ __ _____ ___ __ _/__ ___/__ ___ ______ __ __ __ ___ / / - * __ / // // // // // _ // _// // / / // _ // _// // // \/ // _ \/ / - * / / // // // // // ___// / / // / / // ___// / / / / // // /\ // // / /__ - * \___//____ \\___//____//_/ _\_ / /_//____//_/ /_/ /_//_//_/ /_/ \__\_\___/ - * \/ /____/ version DEV - * http://terminal.jcubic.pl - * - * This file is part of jQuery Terminal. - * - * Copyright (c) 2011-2017 Jakub Jankiewicz - * Released under the MIT license - * - * Date: Tue, 11 Apr 2017 16:39:22 +0000 - */ - .cmd .format,.cmd .prompt,.cmd .prompt div,.terminal .terminal-output .format,.terminal .terminal-output div div{display:inline-block}.cmd,.terminal h1,.terminal h2,.terminal h3,.terminal h4,.terminal h5,.terminal h6,.terminal pre{margin:0}.terminal h1,.terminal h2,.terminal h3,.terminal h4,.terminal h5,.terminal h6{line-height:1.2em}.cmd .clipboard{position:absolute;left:-16px;top:0;width:20px;height:16px;background:transparent;border:none;color:transparent;outline:none;padding:0;resize:none;z-index:0;overflow:hidden}.terminal .error{color:red}.terminal{position:relative;overflow-y:auto;overflow-x:hidden}.terminal>div{height:100%}.cmd{padding:0;height:1.3em;position:relative}.cmd .inverted,.terminal .inverted{background-color:#aaa;color:#000}.cmd .cursor{border-bottom:3px solid transparent;margin-bottom:-3px;background-clip:content-box}.cmd .cursor.blink{-webkit-animation:a 1s infinite step-start;animation:a 1s infinite step-start;border-left:1px solid transparent;margin-left:-1px}.bar.cmd .inverted,.bar.terminal .inverted{border-left-color:#aaa}@-webkit-keyframes a{0%,to{background-color:#000;color:#aaa}50%{background-color:#bbb;color:#000}}@keyframes a{0%,to{background-color:#000;color:#aaa}50%{background-color:#bbb;color:#000}}.cmd .prompt,.terminal .terminal-output div div{display:block;line-height:14px;height:auto}.cmd .prompt{float:left}.cmd,.terminal{font-family:monospace;color:#aaa;background-color:#000;font-size:12px;line-height:14px;box-sizing:border-box}.cmd div{float:left}.cmd div,.cmd div+span{clear:both}.cmd .prompt+div{clear:right}.terminal-output>div{min-height:14px}.terminal-output>div>div *{overflow-wrap:break-word;word-wrap:break-word}.terminal .terminal-output div span{display:inline-block}.cmd span{float:left}.cmd div,.cmd span,.terminal-output a,.terminal-output span,.terminal h1,.terminal h2,.terminal h3,.terminal h4,.terminal h5,.terminal h6,.terminal pre,.terminal td{-webkit-touch-callout:initial;-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text}.terminal,.terminal-output,.terminal-output div{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}@-moz-document url-prefix(){.terminal,.terminal-output,.terminal-output div{-webkit-touch-callout:initial;-webkit-user-select:initial;-moz-user-select:initial;-ms-user-select:initial;user-select:auto}}.terminal table{border-collapse:collapse}.terminal td{border:1px solid #aaa}.cmd .prompt span::-moz-selection,.cmd>div::-moz-selection,.cmd>div span::-moz-selection,.cmd>span::-moz-selection,.cmd>span span::-moz-selection,.cmd div::-moz-selection,.terminal .terminal-output div div::-moz-selection,.terminal .terminal-output div div a::-moz-selection,.terminal .terminal-output div span::-moz-selection,.terminal h1::-moz-selection,.terminal h2::-moz-selection,.terminal h3::-moz-selection,.terminal h4::-moz-selection,.terminal h5::-moz-selection,.terminal h6::-moz-selection,.terminal pre::-moz-selection,.terminal td::-moz-selection{background-color:#aaa;color:#000}.cmd .prompt span::selection,.cmd>div::selection,.cmd>div span::selection,.cmd>span::selection,.cmd>span span::selection,.cmd div::selection,.terminal .terminal-output div div::selection,.terminal .terminal-output div div a::selection,.terminal .terminal-output div span::selection,.terminal h1::selection,.terminal h2::selection,.terminal h3::selection,.terminal h4::selection,.terminal h5::selection,.terminal h6::selection,.terminal pre::selection,.terminal td::selection{background-color:hsla(0,0%,67%,.99);color:#000}.terminal .terminal-output div.error,.terminal .terminal-output div.error div{color:red}.tilda{position:fixed;top:0;left:0;width:100%;z-index:1}.clear{clear:both}.terminal a{color:#0f60ff}.terminal a:hover{color:red}.terminal iframe{position:absolute;left:0;top:-100%;width:100%;height:100%;margin:1px 0 0;border:none;opacity:0;pointer-events:none;box-sizing:border-box}.terminal,.terminal iframe{padding:10px}@supports (--css:variables){.cmd,.terminal{color:var(--color,#aaa);background-color:var(--background,#000)}.cmd,.cmd .prompt,.terminal,.terminal .terminal-output div div{font-size:calc(var(--size, 1) * 12px);line-height:calc(var(--size, 1) * 14px)}.cmd .inverted,.terminal .inverted{background-color:var(--color,#aaa);color:var(--background,#000)}.cmd .cursor.blink{-webkit-animation:var(--animation,a) 1s infinite step-start;animation:var(--animation,a) 1s infinite step-start;color:var(--color,#aaa);background-color:var(--background,#000);margin-bottom:-3px}.cmd .prompt span::-moz-selection,.cmd>div::-moz-selection,.cmd>div span::-moz-selection,.cmd>span::-moz-selection,.cmd>span span::-moz-selection,.cmd div::-moz-selection,.terminal .terminal-output div div::-moz-selection,.terminal .terminal-output div div a::-moz-selection,.terminal .terminal-output div span::-moz-selection,.terminal h1::-moz-selection,.terminal h2::-moz-selection,.terminal h3::-moz-selection,.terminal h4::-moz-selection,.terminal h5::-moz-selection,.terminal h6::-moz-selection,.terminal pre::-moz-selection,.terminal td::-moz-selection{background-color:var(--color,#aaa);color:var(--background,#000)}.cmd .prompt span::selection,.cmd>div::selection,.cmd>div span::selection,.cmd>span::selection,.cmd>span span::selection,.cmd div::selection,.terminal .terminal-output div div::selection,.terminal .terminal-output div div a::selection,.terminal .terminal-output div span::selection,.terminal h1::selection,.terminal h2::selection,.terminal h3::selection,.terminal h4::selection,.terminal h5::selection,.terminal h6::selection,.terminal pre::selection,.terminal td::selection{background-color:var(--color,hsla(0,0%,67%,.99));color:var(--background,#000)}@-webkit-keyframes a{0%,to{background-color:var(--background,#000);color:var(--color,#aaa)}50%{background-color:var(--color,#aaa);color:var(--background,#000)}}@keyframes a{0%,to{background-color:var(--background,#000);color:var(--color,#aaa)}50%{background-color:var(--color,#aaa);color:var(--background,#000)}}} diff --git a/public/themes/pterodactyl/vendor/terminal/jquery.terminal.min.js b/public/themes/pterodactyl/vendor/terminal/jquery.terminal.min.js deleted file mode 100644 index c6d4f84b3..000000000 --- a/public/themes/pterodactyl/vendor/terminal/jquery.terminal.min.js +++ /dev/null @@ -1,39 +0,0 @@ -/**@license - * __ _____ ________ __ - * / // _ /__ __ _____ ___ __ _/__ ___/__ ___ ______ __ __ __ ___ / / - * __ / // // // // // _ // _// // / / // _ // _// // // \/ // _ \/ / - * / / // // // // // ___// / / // / / // ___// / / / / // // /\ // // / /__ - * \___//____ \\___//____//_/ _\_ / /_//____//_/ /_/ /_//_//_/ /_/ \__\_\___/ - * \/ /____/ version 1.1.2 - * - * This file is part of jQuery Terminal. http://terminal.jcubic.pl - * - * Copyright (c) 2010-2017 Jakub Jankiewicz - * Released under the MIT license - * - * Contains: - * - * Storage plugin Distributed under the MIT License - * Copyright (c) 2010 Dave Schindler - * - * jQuery Timers licenced with the WTFPL - * - * - * Cross-Browser Split 1.1.1 - * Copyright 2007-2012 Steven Levithan - * Available under the MIT License - * - * jQuery Caret - * Copyright (c) 2009, Gideon Sireling - * 3 clause BSD License - * - * sprintf.js - * Copyright (c) 2007-2013 Alexandru Marasteanu - * licensed under 3 clause BSD license - * - * Date: Tue, 11 Apr 2017 16:39:20 +0000 - */ -(function(e){var n=function(){if(!n.cache.hasOwnProperty(arguments[0])){n.cache[arguments[0]]=n.parse(arguments[0])}return n.format.call(null,n.cache[arguments[0]],arguments)};n.format=function(e,r){var o=1,a=e.length,s="",l,f=[],c,u,p,m,h,d;for(c=0;c>>0;break;case"x":l=l.toString(16);break;case"X":l=l.toString(16).toUpperCase();break}l=/[def]/.test(p[8])&&p[3]&&l>=0?" +"+l:l;h=p[4]?p[4]==="0"?"0":p[4].charAt(1):" ";d=p[6]-String(l).length;m=p[6]?i(h,d):"";f.push(p[5]?l+m:m+l)}}return f.join("")};n.cache={};n.parse=function(e){var n=e,r=[],t=[],i=0;while(n){if((r=/^[^\x25]+/.exec(n))!==null){t.push(r[0])}else if((r=/^\x25{2}/.exec(n))!==null){t.push("%")}else if((r=/^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(n))!==null){if(r[2]){i|=1;var o=[],a=r[2],s=[];if((s=/^([a-z_][a-z_\d]*)/i.exec(a))!==null){o.push(s[1]);while((a=a.substring(s[0].length))!==""){if((s=/^\.([a-z_][a-z_\d]*)/i.exec(a))!==null){o.push(s[1])}else if((s=/^\[(\d+)\]/.exec(a))!==null){o.push(s[1])}else{throw"[sprintf] huh?"}}}else{throw"[sprintf] huh?"}r[2]=o}else{i|=2}if(i===3){throw"[sprintf] mixing positional and named placeholders is not (yet) supported"}t.push(r)}else{throw"[sprintf] huh?"}n=n.substring(r[0].length)}return t};var r=function(e,r,t){t=r.slice(0);t.splice(0,0,e);return n.apply(null,t)};function t(e){return Object.prototype.toString.call(e).slice(8,-1).toLowerCase()}function i(e,n){for(var r=[];n>0;r[--n]=e){}return r.join("")}e.sprintf=n;e.vsprintf=r})(typeof global!=="undefined"?global:window);(function(e,n){"use strict";e.omap=function(n,r){var t={};e.each(n,function(e,i){t[e]=r.call(n,e,i)});return t};var r={clone_object:function(n){var r={};if(typeof n==="object"){if(e.isArray(n)){return this.clone_array(n)}else if(n===null){return n}else{for(var t in n){if(e.isArray(n[t])){r[t]=this.clone_array(n[t])}else if(typeof n[t]==="object"){r[t]=this.clone_object(n[t])}else{r[t]=n[t]}}}}return r},clone_array:function(n){if(!e.isFunction(Array.prototype.map)){throw new Error("Your browser don't support ES5 array map "+"use es5-shim")}return n.slice(0).map(function(e){if(typeof e==="object"){return this.clone_object(e)}else{return e}}.bind(this))}};var t=function(e){return r.clone_object(e)};var i=function(){var e="test",n=window.localStorage;try{n.setItem(e,"1");n.removeItem(e);return true}catch(r){return false}};var o=i();function a(e,n){var r;if(typeof e==="string"&&typeof n==="string"){localStorage[e]=n;return true}else if(typeof e==="object"&&typeof n==="undefined"){for(r in e){if(e.hasOwnProperty(r)){localStorage[r]=e[r]}}return true}return false}function s(e,n){var r,t,i;r=new Date;r.setTime(r.getTime()+31536e6);t="; expires="+r.toGMTString();if(typeof e==="string"&&typeof n==="string"){document.cookie=e+"="+n+t+"; path=/";return true}else if(typeof e==="object"&&typeof n==="undefined"){for(i in e){if(e.hasOwnProperty(i)){document.cookie=i+"="+e[i]+t+"; path=/"}}return true}return false}function l(e){return localStorage[e]}function f(e){var n,r,t,i;n=e+"=";r=document.cookie.split(";");for(t=0;ti&&i!==0||t.call(e,a)===false){p.timer.remove(e,r,t)}s.inProgress=false};s.$timerID=t.$timerID;if(!e.$timers[r][t.$timerID]){e.$timers[r][t.$timerID]=window.setInterval(s,n)}if(!this.global[r]){this.global[r]=[]}this.global[r].push(e)},remove:function(e,n,r){var t=e.$timers,i;if(t){if(!n){for(var o in t){if(t.hasOwnProperty(o)){this.remove(e,o,r)}}}else if(t[n]){if(r){if(r.$timerID){window.clearInterval(t[n][r.$timerID]);delete t[n][r.$timerID]}}else{for(var a in t[n]){if(t[n].hasOwnProperty(a)){window.clearInterval(t[n][a]);delete t[n][a]}}}for(i in t[n]){if(t[n].hasOwnProperty(i)){break}}if(!i){i=null;delete t[n]}}for(i in t){if(t.hasOwnProperty(i)){break}}if(!i){e.$timers=null}}}}});if(/(msie) ([\w.]+)/.exec(navigator.userAgent.toLowerCase())){p(window).one("unload",function(){var e=p.timer.global;for(var n in e){if(e.hasOwnProperty(n)){var r=e[n],t=r.length;while(--t){p.timer.remove(r[t],n)}}}})}(function(e){if(!String.prototype.split.toString().match(/\[native/)){return}var n=String.prototype.split,r=/()??/.exec("")[1]===e,t;t=function(t,i,o){if(Object.prototype.toString.call(i)!=="[object RegExp]"){return n.call(t,i,o)}var a=[],s=(i.ignoreCase?"i":"")+(i.multiline?"m":"")+(i.extended?"x":"")+(i.sticky?"y":""),l=0,f,c,u,p;i=new RegExp(i.source,s+"g");t+="";if(!r){f=new RegExp("^"+i.source+"$(?!\\s)",s)}o=o===e?-1>>>0:o>>>0;while(c=i.exec(t)){u=c.index+c[0].length;if(u>l){a.push(t.slice(l,c.index));if(!r&&c.length>1){c[0].replace(f,function(){for(var n=1;n1&&c.index=o){break}}if(i.lastIndex===c.index){i.lastIndex++}}if(l===t.length){if(p||!i.test("")){a.push("")}}else{a.push(t.slice(l))}return a.length>o?a.slice(0,o):a};String.prototype.split=function(e,n){return t(this,e,n)};return t})();e.fn.caret=function(e){var n=this[0];var r=n.contentEditable==="true";if(arguments.length===0){if(window.getSelection){if(r){n.focus();var t=window.getSelection().getRangeAt(0),i=t.cloneRange();i.selectNodeContents(n);i.setEnd(t.endContainer,t.endOffset);return i.toString().length}return n.selectionStart}if(document.selection){n.focus();if(r){var t=document.selection.createRange(),i=document.body.createTextRange();i.moveToElementText(n);i.setEndPoint("EndToEnd",t);return i.text.length}var e=0,o=n.createTextRange(),i=document.selection.createRange().duplicate(),a=i.getBookmark();o.moveToBookmark(a);while(o.moveStart("character",-1)!==0)e++;return e}return 0}if(e===-1)e=this[r?"text":"val"]().length;if(window.getSelection){if(r){n.focus();window.getSelection().collapse(n.firstChild,e)}else n.setSelectionRange(e,e)}else if(document.body.createTextRange){var o=document.body.createTextRange();o.moveToElementText(n);o.moveStart("character",e);o.collapse(true);o.select()}if(!r)n.focus();return e};function m(e,n){var r=[];var t=e.length;if(tr.length){if(n){break}e=0;n=true}}return r[e]}},append:function(e){r.push(e)}})}function d(n){var r=n instanceof Array?n:n?[n]:[];e.extend(this,{data:function(){return r},map:function(n){return e.map(r,n)},size:function(){return r.length},pop:function(){if(r.length===0){return null}else{var e=r[r.length-1];r=r.slice(0,r.length-1);return e}},push:function(e){r=r.concat([e]);return e},top:function(){return r.length>0?r[r.length-1]:null},clone:function(){return new d(r.slice(0))}})}function g(n,r,t){var i=true;var o="";if(typeof n==="string"&&n!==""){o=n+"_"}o+="commands";var a;if(t){a=[]}else{a=e.Storage.get(o);a=a?e.parseJSON(a):[]}var s=a.length-1;e.extend(this,{append:function(n){if(i){if(a[a.length-1]!==n){a.push(n);if(r&&a.length>r){a=a.slice(-r)}s=a.length-1;if(!t){e.Storage.set(o,JSON.stringify(a))}}}},set:function(n){if(n instanceof Array){a=n;if(!t){e.Storage.set(o,JSON.stringify(a))}}},data:function(){return a},reset:function(){s=a.length-1},last:function(){return a[a.length-1]},end:function(){return s===a.length-1},position:function(){return s},current:function(){return a[s]},next:function(){if(s0){--s}if(e!==-1){return a[s]}},clear:function(){a=[];this.purge()},enabled:function(){return i},enable:function(){i=true},purge:function(){if(!t){e.Storage.remove(o)}},disable:function(){i=false}})}var v=0;e.fn.cmd=function(r){var t=this;var i=t.data("cmd");if(i){return i}var o=v++;t.addClass("cmd");t.append(''+' ');var a=e("