mirror of
https://github.com/icecoder/ICEcoder.git
synced 2026-03-03 07:13:59 +01:00
Overhauled terminal XHR response and tweaked the UI a little
This commit is contained in:
@@ -30,7 +30,7 @@ html, body {width: 100%; height: 100%}
|
||||
.output {position: absolute; display: block; top: 0; padding: 15px 18px 8px 13px; width: 100%; min-height: 100%; border: 0; background: rgba(0,0,0,0.92); color: #ccc}
|
||||
.commandLine {width: 100%; padding: 8px 2px 8px 0; color: #fff}
|
||||
.commandLine .user {display: inline-block; height: 24px; margin-top: -4px; margin-left: -13px; padding: 5px 5px 5px 0; margin-bottom: 5px; background: #b58901; color: #000}
|
||||
.commandLine .path {display: inline-block; height: 24px; margin-top: -4px; padding: 5px 5px 5px 0; margin-bottom: 5px; background: #278bd2; color: #fff}
|
||||
.commandLine .cwd {display: inline-block; height: 24px; margin-top: -4px; padding: 5px 5px 5px 0; margin-bottom: 5px; background: #278bd2; color: #fff}
|
||||
.commandLine .promptVLine {display: inline-block; width: 1px; height: 12px; margin-top: -5px; margin-left: 3px; background: #b58901}
|
||||
.commandLine .promptHLine {display: inline-block; color: #b58901}
|
||||
.commandLine .promptArrow {display: inline-block; margin-left:-1px}
|
||||
|
||||
@@ -1,67 +1,95 @@
|
||||
<?php
|
||||
include(dirname(__FILE__)."/headers.php");
|
||||
include(dirname(__FILE__)."/settings.php");
|
||||
|
||||
|
||||
function proc_open_enabled() {
|
||||
$disabled = explode(',', ini_get('disable_functions'));
|
||||
return !in_array('proc_open', $disabled);
|
||||
}
|
||||
|
||||
if(!proc_open_enabled()) {
|
||||
exit("<span style=\"color: #fff\">Sorry but you can't use this terminal if your proc_open is disabled</span>\n\n");
|
||||
}
|
||||
include dirname(__FILE__) . "/headers.php";
|
||||
include dirname(__FILE__) . "/settings.php";
|
||||
|
||||
// Set some common aliases
|
||||
$aliases = array(
|
||||
'la' => 'ls -la',
|
||||
'll' => 'ls -lvhF',
|
||||
'la' => 'ls -la',
|
||||
'll' => 'ls -lvhF',
|
||||
);
|
||||
|
||||
// Get current working dir
|
||||
$user = str_replace("\n","",shell_exec("whoami"));
|
||||
$cwd = getcwd();
|
||||
// If we have a current working dir in session, change to that dir
|
||||
if (true === isset($_SESSION['cwd'])) {
|
||||
chdir($_SESSION['cwd']);
|
||||
}
|
||||
|
||||
// If we have a command
|
||||
if(!empty($_REQUEST['command'])) {
|
||||
// Strip any slashes from it
|
||||
if(get_magic_quotes_gpc()) {
|
||||
$_REQUEST['command'] = stripslashes($_REQUEST['command']);
|
||||
}
|
||||
// Get current user and cwd
|
||||
$user = str_replace("\n", "", shell_exec("whoami"));
|
||||
$cwd = str_replace("\n", "", shell_exec("pwd"));
|
||||
|
||||
// Begin output with prompt and user command
|
||||
$output = '<div class="commandLine"><div class="user"> '.$user.' </div>'.
|
||||
'<div class="path"> '.$cwd.' </div> : '.date("H:m:s").
|
||||
'<br>'.
|
||||
'<div class="promptVLine"></div><div class="promptHLine">─<div class="promptArrow">▶</div></div> '.$_REQUEST['command'].'</div><br><br>';
|
||||
// Check if we have proc_open_enabled
|
||||
// (Used later to handle commands)
|
||||
function proc_open_enabled() {
|
||||
$disabled = explode(',', ini_get('disable_functions'));
|
||||
return false === in_array('proc_open', $disabled);
|
||||
}
|
||||
|
||||
// Return HTML prompt plus the command the user provided last
|
||||
function returnHTMLPromptCommand($cmd) {
|
||||
global $user, $cwd;
|
||||
// Begin output with prompt and user command
|
||||
return '<div class="commandLine"><div class="user"> ' . $user . ' </div>'.
|
||||
'<div class="cwd"> ' . $cwd . ' </div> : ' . date("H:m:s") .
|
||||
'<br>' .
|
||||
'<div class="promptVLine"></div><div class="promptHLine">─<div class="promptArrow">▶</div></div> ' . $cmd . '</div></div><br>';
|
||||
}
|
||||
|
||||
// If proc_open isn't enabled, display prompt, command and a message re needing this enabled
|
||||
if (false === proc_open_enabled()) {
|
||||
echo json_encode([
|
||||
"output" => returnHTMLPromptCommand($_REQUEST['command'] . "<br><br>Sorry but you can't use this terminal if your proc_open is disabled"),
|
||||
"user" => $user,
|
||||
"cwd" => $cwd
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// If in demo mode, display message and go no further
|
||||
if ($demoMode) {
|
||||
$output .= "Sorry, shell usage not enabled in demo mode\n\n";
|
||||
echo $output;
|
||||
exit;
|
||||
if (true === $demoMode) {
|
||||
echo json_encode([
|
||||
"output" => returnHTMLPromptCommand($_REQUEST['command'] . "<br><br>Sorry, shell usage not enabled in demo mode"),
|
||||
"user" => $user,
|
||||
"cwd" => $cwd
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// If in demo mode, display message and go no further
|
||||
if (false === isset($_REQUEST['command'])) {
|
||||
echo json_encode([
|
||||
"output" => returnHTMLPromptCommand($_REQUEST['command'] . "<br><br>Sorry, no command received"),
|
||||
"user" => $user,
|
||||
"cwd" => $cwd
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Strip any slashes from command
|
||||
$_REQUEST['command'] = stripslashes($_REQUEST['command']);
|
||||
|
||||
// Start output with the prompt and command they provided last
|
||||
$output = returnHTMLPromptCommand($_REQUEST['command']);
|
||||
|
||||
// If command contains cd but no dir
|
||||
if (preg_match('/^[[:blank:]]*cd[[:blank:]]*$/', @$_REQUEST['command'])) {
|
||||
$_SESSION['cwd'] = getcwd(); //dirname(__FILE__);
|
||||
if (preg_match('/^[[:blank:]]*cd[[:blank:]]*$/', $_REQUEST['command'])) {
|
||||
$_SESSION['cwd'] = $cwd;
|
||||
$output .= returnHTMLPromptCommand("cd");
|
||||
// Else cd to a dir
|
||||
} elseif (preg_match('/^[[:blank:]]*cd[[:blank:]]+([^;]+)$/', @$_REQUEST['command'], $regs)) {
|
||||
} elseif (preg_match('/^[[:blank:]]*cd[[:blank:]]+([^;]+)$/', $_REQUEST['command'], $regs)) {
|
||||
// The current command is 'cd', which we have to handle as an internal shell command
|
||||
// Absolute/relative path ?
|
||||
($regs[1][0] == '/') ? $newDir = $regs[1] : $newDir = $_SESSION['cwd'].'/'.$regs[1];
|
||||
$newDir = "/" === $regs[1][0] ? $regs[1] : $_SESSION['cwd'] . "/" . $regs[1];
|
||||
|
||||
// Tidy up appearance on /./
|
||||
while (strpos($newDir, '/./') !== false) {
|
||||
while (false !== strpos($newDir, '/./')) {
|
||||
$newDir = str_replace('/./', '/', $newDir);
|
||||
}
|
||||
// Tidy up appearance on //
|
||||
while (strpos($newDir, '//') !== false) {
|
||||
while (false !== strpos($newDir, '//')) {
|
||||
$newDir = str_replace('//', '/', $newDir);
|
||||
}
|
||||
// Tidy up appearance on other variations
|
||||
while (preg_match('|/\.\.(?!\.)|', $newDir)) {
|
||||
$newDir = preg_replace('|/?[^/]+/\.\.(?!\.)|', '', $newDir);
|
||||
while (preg_match('/\/\.\.(?!\.)/', $newDir)) {
|
||||
$newDir = preg_replace('/\/?[^\/]+\/\.\.(?!\.)/', '', $newDir);
|
||||
}
|
||||
|
||||
// Empty dir
|
||||
@@ -70,36 +98,35 @@ if (preg_match('/^[[:blank:]]*cd[[:blank:]]*$/', @$_REQUEST['command'])) {
|
||||
}
|
||||
|
||||
// Test if we could change to that dir, else display error
|
||||
(@chdir($newDir)) ? $_SESSION['cwd'] = $newDir : $output .= "\n\nCould not change to: $newDir\n\n";
|
||||
(@chdir($newDir)) ? $_SESSION['cwd'] = $newDir : $output .= "Could not change to: $newDir\n\n";
|
||||
} else {
|
||||
// The command is not a 'cd' command, so we execute it after
|
||||
// changing the directory and save the output.
|
||||
chdir($_SESSION['cwd']);
|
||||
// The command is not a 'cd' command
|
||||
|
||||
// Alias expansion
|
||||
$length = strcspn(@$_REQUEST['command'], " \t");
|
||||
$token = substr(@$_REQUEST['command'], 0, $length);
|
||||
if (isset($aliases[$token])) {
|
||||
$_REQUEST['command'] = $aliases[$token].substr($_REQUEST['command'], $length);
|
||||
$length = strcspn($_REQUEST['command'], " \t");
|
||||
$token = substr($_REQUEST['command'], 0, $length);
|
||||
if (true === isset($aliases[$token])) {
|
||||
$_REQUEST['command'] = $aliases[$token] . substr($_REQUEST['command'], $length);
|
||||
}
|
||||
|
||||
// Open a proc with array and $io return
|
||||
$p = proc_open(
|
||||
@$_REQUEST['command'],
|
||||
$_REQUEST['command'],
|
||||
array(
|
||||
1 => array('pipe', 'w'),
|
||||
2 => array('pipe', 'w')
|
||||
),
|
||||
$io
|
||||
);
|
||||
|
||||
|
||||
// Read output sent to stdout
|
||||
while (!feof($io[1])) { /// this will return always false ... and will loop forever until "fork: retry: no child processes" will show if proc_open is disabled;
|
||||
$output .= htmlspecialchars(fgets($io[1]),ENT_COMPAT, 'UTF-8');
|
||||
while (false === feof($io[1])) {
|
||||
// this will return always false ... and will loop forever until "fork: retry: no child processes" will show if proc_open is disabled;
|
||||
$output .= htmlspecialchars(fgets($io[1]), ENT_COMPAT, 'UTF-8');
|
||||
}
|
||||
// Read output sent to stderr
|
||||
while (!feof($io[2])) {
|
||||
$output .= htmlspecialchars(fgets($io[2]),ENT_COMPAT, 'UTF-8');
|
||||
while (false === feof($io[2])) {
|
||||
$output .= htmlspecialchars(fgets($io[2]), ENT_COMPAT, 'UTF-8');
|
||||
}
|
||||
$output .= "\n";
|
||||
|
||||
@@ -109,6 +136,16 @@ if (preg_match('/^[[:blank:]]*cd[[:blank:]]*$/', @$_REQUEST['command'])) {
|
||||
proc_close($p);
|
||||
}
|
||||
|
||||
// Finally, output our string
|
||||
echo $output;
|
||||
// Change to the cwd in session
|
||||
chdir($_SESSION['cwd']);
|
||||
// and again ask for current user and working dir
|
||||
$user = str_replace("\n","",shell_exec("whoami"));
|
||||
$cwd = str_replace("\n","",shell_exec("pwd"));
|
||||
|
||||
// Finally, output our JSON data
|
||||
echo json_encode([
|
||||
"output" => $output,
|
||||
"user" => $user,
|
||||
"cwd" => $cwd
|
||||
]);
|
||||
|
||||
|
||||
17
terminal.php
17
terminal.php
@@ -60,10 +60,15 @@ sendCmd = function(command) {
|
||||
if (xhr.status==200) {
|
||||
// Set the output to also include our response and scroll down to bottom
|
||||
var newOutput = document.createElement("DIV");
|
||||
newOutput.innerHTML = xhr.responseText;
|
||||
responseText = xhr.responseText;
|
||||
responseJSON = JSON.parse(responseText);
|
||||
newOutput.innerHTML = responseJSON.output;
|
||||
document.getElementById("user").innerHTML = "  " + responseJSON.user + " ";
|
||||
document.getElementById("user").innerHTML = "  " + responseJSON.user + " ";
|
||||
document.getElementById("cwd").innerHTML = " " + responseJSON.cwd + " ";
|
||||
var cmdElem = document.getElementById("commandLine");
|
||||
cmdElem.parentNode.insertBefore(newOutput, cmdElem);
|
||||
document.getElementById("terminal").contentWindow.document.documentElement.scrollTop = document.getElementById('output').scrollHeight;
|
||||
parent.document.getElementById("terminal").contentWindow.document.documentElement.scrollTop = document.getElementById('output').scrollHeight;
|
||||
|
||||
// Add command onto end of history array or set as last item in array
|
||||
if (currentLine == 0 || commandHistory[commandHistory.length-1].indexOf("[[ICEcoder]]:") !== 0) {
|
||||
@@ -86,10 +91,11 @@ sendCmd = function(command) {
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<body onclick="document.getElementById('command').focus()">
|
||||
<?php
|
||||
chdir($_SESSION['cwd']);
|
||||
$user = str_replace("\n","",shell_exec("whoami"));
|
||||
$cwd = getcwd();
|
||||
$cwd = str_replace("\n","",shell_exec("pwd"));
|
||||
?>
|
||||
|
||||
<form name="shell" onsubmit="sendCmd(document.getElementById('command').value); return false" method="POST">
|
||||
@@ -97,8 +103,7 @@ $cwd = getcwd();
|
||||
This is a full powered terminal, but will have the permissions of the '<?php echo $user;?>' user.
|
||||
The more access rights you give that user, the more this terminal has.
|
||||
|
||||
<div class="commandLine" id="commandLine"><div class="user"> <?php echo $user;?> </div><div class="path"> <?php echo $cwd;?> </div>
|
||||
<div class="promptVLine"></div><div class="promptHLine">─<div class="promptArrow">▶</div></div> <input type="text" class="command" id="command" onkeyup="key(event)" tabindex="1" autocomplete="off"></div></pre>
|
||||
<div class="commandLine" id="commandLine"><div class="user" id="user"> <?php echo $user;?> </div><div class="cwd" id="cwd"> <?php echo $cwd;?> </div> : <?php echo date("H:m:s");?><br><div class="promptVLine"></div><div class="promptHLine">─<div class="promptArrow">▶</div></div> <input type="text" class="command" id="command" onkeyup="key(event)" tabindex="1" autocomplete="off"></div></pre>
|
||||
</form>
|
||||
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user