Init Repo
This commit is contained in:
228
resources/library/terminal/terminal.php
Normal file
228
resources/library/terminal/terminal.php
Normal file
@@ -0,0 +1,228 @@
|
||||
<?php
|
||||
define('PICONTROL', true);
|
||||
|
||||
(include_once realpath(dirname(__FILE__)).'/../../init.php') or die('Error: 0x0000');
|
||||
(include_once LIBRARY_PATH.'main/tpl.class.php') or die('Error: 0x0001');
|
||||
(include_once LIBRARY_PATH.'main/main.function.php') or die('Error: 0x0002');
|
||||
|
||||
$host = '127.0.0.1';
|
||||
$port = (isset($_GET['port'])) ? $_GET['port'] : 0;
|
||||
$null = NULL;
|
||||
|
||||
$tpl = new PiTpl;
|
||||
$tpl->setTpl($tpl);
|
||||
|
||||
$termial = getConfig('terminal:port_'.$port, array());
|
||||
|
||||
if (is_array($termial) && $port > 9000 && $port < 9006 && ((empty($termial) || $termial['pid'] == getmypid())))
|
||||
setConfig('terminal:port_'.$port.'.pid', getmypid());
|
||||
else
|
||||
exit();
|
||||
|
||||
set_time_limit(0);
|
||||
|
||||
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
|
||||
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
|
||||
socket_bind($socket, 0, $port);
|
||||
socket_listen($socket);
|
||||
|
||||
$clients = array($socket);
|
||||
$ssh = NULL;
|
||||
$stdio = NULL;
|
||||
$lastLine = '';
|
||||
$i = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
$changed = $clients;
|
||||
|
||||
socket_select($changed, $null, $null, 0, 10);
|
||||
|
||||
if (in_array($socket, $changed))
|
||||
{
|
||||
$newSocket = socket_accept($socket);
|
||||
$header = socket_read($newSocket, 1024);
|
||||
perform_handshaking($header, $newSocket, $host, $port);
|
||||
|
||||
if (substr($header, 6, 16) == substr($_COOKIE['_pi-control_login'], 0, 16))
|
||||
{
|
||||
$clients[] = $newSocket;
|
||||
|
||||
$diff = array_diff($clients, array($socket, $newSocket));
|
||||
|
||||
foreach ($diff as $client)
|
||||
{
|
||||
$response = mask(json_encode(array('type'=>'system', 'message'=> 'newSession')));
|
||||
@socket_write($client, $response, strlen($response));
|
||||
@socket_write($client, 'ping', strlen('ping'));
|
||||
}
|
||||
|
||||
$clients = array($socket, $newSocket);
|
||||
|
||||
socket_getpeername($newSocket, $ip);
|
||||
|
||||
$found_socket = array_search($socket, $changed);
|
||||
unset($changed[$found_socket]);
|
||||
|
||||
$response = mask(json_encode(array('type'=> 'system', 'message' => 'connected')));
|
||||
send_message($response);
|
||||
$response_text = mask(json_encode(array('type' => 'console', 'message' => $lastLine)));
|
||||
send_message($response_text);
|
||||
}
|
||||
else
|
||||
{
|
||||
$response = mask(json_encode(array('type'=> 'system', 'message' => 'denied')));
|
||||
@socket_write($newSocket, $response, strlen($response));
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($changed as $changedSocket)
|
||||
{
|
||||
if (@socket_recv($changedSocket, $buf, 1024, 0) === 0)
|
||||
{
|
||||
$found_socket = array_search($changedSocket, $clients);
|
||||
socket_getpeername($changedSocket, $ip);
|
||||
unset($clients[$found_socket]);
|
||||
}
|
||||
else
|
||||
{
|
||||
$received_text = unmask($buf);
|
||||
$tst_msg = json_decode($received_text);
|
||||
|
||||
if (isset($tst_msg->message))
|
||||
{
|
||||
$user_message = $tst_msg->message;
|
||||
|
||||
if ($user_message == '^PI')
|
||||
{
|
||||
removeConfig('terminal:port_'.$port);
|
||||
socket_close($socket);
|
||||
exec('kill -9 '.getmypid());
|
||||
break 2;
|
||||
}
|
||||
|
||||
if ($user_message != '^C')
|
||||
$ssh->write($user_message."\n");
|
||||
else
|
||||
$ssh->write(chr(3));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count($clients) == 2 && $ssh === NULL)
|
||||
{
|
||||
if (($ssh = $tpl->getSSHResource()) === false)
|
||||
exit('Login Failed');
|
||||
|
||||
$ssh->setTimeout(1);
|
||||
stream_set_timeout($ssh->fsock, 999999);
|
||||
}
|
||||
|
||||
if ($ssh !== NULL)
|
||||
{
|
||||
if ($output = $ssh->read())
|
||||
{
|
||||
$ansi = new File_ANSI();
|
||||
$ansi->appendString($output);
|
||||
|
||||
$lastLine = $ansi->getScreen();
|
||||
$response_text = mask(json_encode(array('type' => 'console', 'message' => $ansi->getScreen())));
|
||||
send_message($response_text);
|
||||
|
||||
$response = mask(json_encode(array('type' => 'system', 'message' => 'connected')));
|
||||
send_message($response);
|
||||
}
|
||||
}
|
||||
|
||||
$i += 1;
|
||||
if ($i == 60)
|
||||
{
|
||||
$termial = getConfig('terminal:port_'.$port, array());
|
||||
|
||||
if (!is_array($termial) || empty($termial) || $termial['pid'] != getmypid())
|
||||
{
|
||||
socket_close($socket);
|
||||
exec('kill -9 '.getmypid());
|
||||
break;
|
||||
}
|
||||
|
||||
$i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
socket_close($socket);
|
||||
|
||||
function send_message($msg)
|
||||
{
|
||||
global $clients;
|
||||
|
||||
foreach ($clients as $client)
|
||||
@socket_write($client, $msg, strlen($msg));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function unmask($text)
|
||||
{
|
||||
$length = ord($text[1]) & 127;
|
||||
if ($length == 126)
|
||||
{
|
||||
$masks = substr($text, 4, 4);
|
||||
$data = substr($text, 8);
|
||||
}
|
||||
elseif ($length == 127)
|
||||
{
|
||||
$masks = substr($text, 10, 4);
|
||||
$data = substr($text, 14);
|
||||
}
|
||||
else
|
||||
{
|
||||
$masks = substr($text, 2, 4);
|
||||
$data = substr($text, 6);
|
||||
}
|
||||
|
||||
$text = "";
|
||||
for ($i = 0; $i < strlen($data); ++$i)
|
||||
$text .= $data[$i] ^ $masks[$i%4];
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
function mask($text)
|
||||
{
|
||||
$b1 = 0x80 | (0x1 & 0x0f);
|
||||
$length = strlen($text);
|
||||
|
||||
if ($length <= 125)
|
||||
$header = pack('CC', $b1, $length);
|
||||
elseif ($length > 125 && $length < 65536)
|
||||
$header = pack('CCn', $b1, 126, $length);
|
||||
elseif ($length >= 65536)
|
||||
$header = pack('CCNN', $b1, 127, $length);
|
||||
return $header.$text;
|
||||
}
|
||||
|
||||
function perform_handshaking($receved_header, $client_conn, $host, $port)
|
||||
{
|
||||
$headers = array();
|
||||
$lines = preg_split("/\r\n/", $receved_header);
|
||||
foreach($lines as $line)
|
||||
{
|
||||
$line = chop($line);
|
||||
if (preg_match('/\A(\S+): (.*)\z/', $line, $matches))
|
||||
$headers[$matches[1]] = $matches[2];
|
||||
}
|
||||
|
||||
$secKey = $headers['Sec-WebSocket-Key'];
|
||||
$secAccept = base64_encode(pack('H*', sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));
|
||||
$upgrade = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .
|
||||
"Upgrade: websocket\r\n" .
|
||||
"Connection: Upgrade\r\n" .
|
||||
"WebSocket-Origin: $host\r\n" .
|
||||
"WebSocket-Location: ws://$host:$port/demo/shout.php\r\n".
|
||||
"Sec-WebSocket-Accept:$secAccept\r\n\r\n";
|
||||
socket_write($client_conn,$upgrade,strlen($upgrade));
|
||||
}
|
||||
|
||||
exit();
|
||||
?>
|
||||
Reference in New Issue
Block a user