Modular WebSocket engine, added ssh and telnet to quickshell extension
This commit is contained in:
parent
bb2faca479
commit
6c52462c8c
|
@ -1,65 +1,203 @@
|
||||||
<?php
|
<?php
|
||||||
// ______ __ _______ _______ _______
|
/**
|
||||||
// | __ \.---.-.-----.--| |.-----.----.---.-. | ___| | | __|
|
* Quick Shell extension.
|
||||||
// | __/| _ | | _ || _ | _| _ | | ___| |__ |
|
*
|
||||||
// |___| |___._|__|__|_____||_____|__| |___._| |___| |__|_|__|_______|
|
* @category Extension
|
||||||
//
|
* @package Pandora FMS
|
||||||
// ============================================================================
|
* @subpackage QuickShell
|
||||||
// Copyright (c) 2007-2018 Artica Soluciones Tecnologicas, http://www.artica.es
|
* @version 1.0.0
|
||||||
// This code is NOT free software. This code is NOT licenced under GPL2 licence
|
* @license See below
|
||||||
// You cannnot redistribute it without written permission of copyright holder.
|
*
|
||||||
// ============================================================================
|
* ______ ___ _______ _______ ________
|
||||||
require_once 'include/functions.php';
|
* | __ \.-----.--.--.--| |.-----.----.-----. | ___| | | __|
|
||||||
require_once 'include/functions_groupview.php';
|
* | __/| _ | | _ || _ | _| _ | | ___| |__ |
|
||||||
require_once 'include/auth/mysql.php';
|
* |___| |___._|__|__|_____||_____|__| |___._| |___| |__|_|__|_______|
|
||||||
|
*
|
||||||
|
* ============================================================================
|
||||||
|
* Copyright (c) 2005-2019 Artica Soluciones Tecnologicas
|
||||||
|
* Please see http://pandorafms.org for full contribution list
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation for version 2.
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
* ============================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
check_login();
|
// Begin.
|
||||||
|
global $config;
|
||||||
|
|
||||||
if (! check_acl($config['id_user'], 0, 'PM')) {
|
require_once $config['homedir'].'/include/functions_agents.php';
|
||||||
db_pandora_audit(
|
require_once $config['homedir'].'/godmode/wizards/Wizard.main.php';
|
||||||
'ACL Violation',
|
|
||||||
'Trying to access Profile Management'
|
|
||||||
);
|
|
||||||
include 'general/noaccess.php';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function mainWetty()
|
/**
|
||||||
|
* Show Quick Shell interface.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function quickShell()
|
||||||
{
|
{
|
||||||
global $config;
|
global $config;
|
||||||
|
|
||||||
if (!isset($config['wetty_ip'])) {
|
check_login();
|
||||||
config_update_value('wetty_ip', $_SERVER['SERVER_ADDR']);
|
|
||||||
|
if (! check_acl($config['id_user'], 0, 'PM')) {
|
||||||
|
db_pandora_audit(
|
||||||
|
'ACL Violation',
|
||||||
|
'Trying to access Profile Management'
|
||||||
|
);
|
||||||
|
include 'general/noaccess.php';
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($config['wetty_ip'] == '127.0.0.1') {
|
$agent_id = get_parameter('id_agente', 0);
|
||||||
config_update_value('wetty_ip', $_SERVER['SERVER_ADDR']);
|
$username = get_parameter('username', null);
|
||||||
|
$method = get_parameter('method', null);
|
||||||
|
$method_port = get_parameter('port', null);
|
||||||
|
|
||||||
|
// Retrieve main IP Address.
|
||||||
|
$address = agents_get_address($agent_id);
|
||||||
|
|
||||||
|
ui_require_css_file('wizard');
|
||||||
|
ui_require_css_file('discovery');
|
||||||
|
|
||||||
|
// Username. Retrieve from form.
|
||||||
|
if (empty($username) === true) {
|
||||||
|
// No username provided, ask for it.
|
||||||
|
$wiz = new Wizard();
|
||||||
|
$wiz->printForm(
|
||||||
|
[
|
||||||
|
'form' => [
|
||||||
|
'id' => 'pene',
|
||||||
|
'action' => '#',
|
||||||
|
'class' => 'wizard',
|
||||||
|
'method' => 'post',
|
||||||
|
],
|
||||||
|
'inputs' => [
|
||||||
|
[
|
||||||
|
'label' => __('Username'),
|
||||||
|
'arguments' => [
|
||||||
|
'type' => 'text',
|
||||||
|
'name' => 'username',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'label' => __('Port'),
|
||||||
|
'arguments' => [
|
||||||
|
'type' => 'text',
|
||||||
|
'id' => 'port',
|
||||||
|
'name' => 'port',
|
||||||
|
'value' => 22,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'label' => __('Method'),
|
||||||
|
'arguments' => [
|
||||||
|
'type' => 'select',
|
||||||
|
'name' => 'method',
|
||||||
|
'fields' => [
|
||||||
|
'ssh' => __('SSH'),
|
||||||
|
'telnet' => __('Telnet'),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'arguments' => [
|
||||||
|
'type' => 'submit',
|
||||||
|
'label' => __('Connect'),
|
||||||
|
'attributes' => 'class="sub next"',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
false,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isset($config['wetty_port'])) {
|
// WebSocket host, where to connect.
|
||||||
config_update_value('wetty_port', '3000');
|
if (isset($config['ws_host']) === false) {
|
||||||
|
config_update_value('ws_host', $_SERVER['SERVER_ADDR']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$buttons['maps'] = [
|
if (isset($config['ws_port']) === false) {
|
||||||
'active' => false,
|
config_update_value('ws_port', 8080);
|
||||||
'text' => '<a href="index.php?login=1&extension_in_menu=gextensions&sec=gextensions&sec2=extensions/wetty_conf">'.html_print_image('images/setup.png', true, ['title' => __('Wetty settings')]).'</a>',
|
}
|
||||||
];
|
|
||||||
|
|
||||||
ui_print_page_header(__('Wetty'), 'images/extensions.png', false, '', true, $buttons);
|
if (isset($config['gotty_host']) === false) {
|
||||||
|
config_update_value('gotty_host', '127.0.0.1');
|
||||||
|
}
|
||||||
|
|
||||||
$host = '127.0.0.1';
|
if (isset($config['gotty_telnet_port']) === false) {
|
||||||
$port = 8080;
|
config_update_value('gotty_telnet_port', 8082);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($config['gotty_ssh_port']) === false) {
|
||||||
|
config_update_value('gotty_ssh_port', 8081);
|
||||||
|
}
|
||||||
|
|
||||||
|
$host = $config['gotty_host'];
|
||||||
|
if ($method == 'ssh') {
|
||||||
|
// SSH.
|
||||||
|
$port = $config['gotty_ssh_port'];
|
||||||
|
$command_arguments = "var args = '?arg=".$username.'@'.$address;
|
||||||
|
$command_arguments .= '&arg=-p '.$method_port."';";
|
||||||
|
} else if ($method == 'telnet') {
|
||||||
|
// Telnet.
|
||||||
|
$port = $config['gotty_telnet_port'];
|
||||||
|
$command_arguments = "var args = '?arg=-l ".$username;
|
||||||
|
$command_arguments .= '&arg= '.$address;
|
||||||
|
$command_arguments .= '&arg= '.$method_port."';";
|
||||||
|
} else {
|
||||||
|
ui_print_error_message(__('Please use SSH or Telnet.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$r = file_get_contents('http://'.$host.':'.$port.'/js/hterm.js');
|
$r = file_get_contents('http://'.$host.':'.$port.'/js/hterm.js');
|
||||||
$r .= file_get_contents('http://'.$host.':'.$port.'/auth_token.js');
|
|
||||||
|
if (empty($r) === true) {
|
||||||
|
echo 'No hay nadie al volante, peligro constante';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($config['gotty_user'])
|
||||||
|
&& empty($config['gotty_pass'])
|
||||||
|
) {
|
||||||
|
$r .= "var gotty_auth_token = '';";
|
||||||
|
} else {
|
||||||
|
$r .= "var gotty_auth_token = '";
|
||||||
|
$r .= $config['gotty_user'].':'.$gotty_pass."';";
|
||||||
|
}
|
||||||
|
|
||||||
$gotty = file_get_contents('http://'.$host.':'.$port.'/js/gotty.js');
|
$gotty = file_get_contents('http://'.$host.':'.$port.'/js/gotty.js');
|
||||||
|
|
||||||
|
// Set websocket target.
|
||||||
$url = "var url = (httpsEnabled ? 'wss://' : 'ws://') + window.location.host + window.location.pathname + 'ws';";
|
$url = "var url = (httpsEnabled ? 'wss://' : 'ws://') + window.location.host + window.location.pathname + 'ws';";
|
||||||
$new = "var url = (httpsEnabled ? 'wss://' : 'ws://') + window.location.host + ':8081' + window.location.pathname;";
|
if (empty($config['ws_proxy_url']) === true) {
|
||||||
|
$new = "var url = (httpsEnabled ? 'wss://' : 'ws://')";
|
||||||
|
$new .= " + window.location.host + ':";
|
||||||
|
$new .= $config['ws_port'].'/'.$method."';";
|
||||||
|
} else {
|
||||||
|
$new = "var url = (httpsEnabled ? 'wss://' : 'ws://') + ";
|
||||||
|
$new .= 'window.location.host + ';
|
||||||
|
$new .= "'".$config['ws_proxy_url'].'/'.$method."';";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update url.
|
||||||
$gotty = str_replace($url, $new, $gotty);
|
$gotty = str_replace($url, $new, $gotty);
|
||||||
|
|
||||||
|
// Update websocket arguments.
|
||||||
|
$args = 'var args = window.location.search;';
|
||||||
|
$new = $command_arguments;
|
||||||
|
|
||||||
|
// Update arguments.
|
||||||
|
$gotty = str_replace($args, $new, $gotty);
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<style>#terminal {
|
<style>#terminal {
|
||||||
height: 650px;
|
height: 650px;
|
||||||
|
@ -79,31 +217,24 @@ function mainWetty()
|
||||||
<?php echo $gotty; ?>
|
<?php echo $gotty; ?>
|
||||||
</script>
|
</script>
|
||||||
<?php
|
<?php
|
||||||
/*
|
|
||||||
$table->width = '100%';
|
|
||||||
$table->class = 'databox data';
|
|
||||||
$table->data = [];
|
|
||||||
$table->head = [];
|
|
||||||
$table->align = [];
|
|
||||||
// $table->align[3] = 'left';
|
|
||||||
$table->style = [];
|
|
||||||
$table->size = [];
|
|
||||||
// $table->size[3] = '10%';
|
|
||||||
$table->style[0] = 'font-weight: bold';
|
|
||||||
|
|
||||||
$table->head[0] = __('Wetty');
|
|
||||||
|
|
||||||
// $data[0] = '<iframe scrolling="auto" frameborder="0" width="100%" height="600px" src="http://192.168.70.64:3000/"></iframe>';
|
|
||||||
$data[0] = '<iframe scrolling="auto" frameborder="0" width="100%" height="600px" src="http://'.$config['wetty_ip'].':'.$config['wetty_port'].'/"></iframe>';
|
|
||||||
|
|
||||||
// $data[0] .= '<div id="terminal" style="background-color:black;width:100%;height:600px;overflow: hidden;"><div>';
|
|
||||||
array_push($table->data, $data);
|
|
||||||
|
|
||||||
html_print_table($table);
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extensions_add_godmode_menu_option(__('Wetty'), 'AW', 'gextensions', null, 'v1');
|
extensions_add_opemode_tab_agent(
|
||||||
extensions_add_godmode_function('mainWetty');
|
// TabId.
|
||||||
|
'quick_shell',
|
||||||
|
// TabName.
|
||||||
|
__('QuickShell'),
|
||||||
|
// TabIcon.
|
||||||
|
'images/ehorus/terminal.png',
|
||||||
|
// TabFunction.
|
||||||
|
'quickShell',
|
||||||
|
// Version.
|
||||||
|
'N/A',
|
||||||
|
// Acl.
|
||||||
|
'PM'
|
||||||
|
);
|
||||||
|
|
||||||
|
// extensions_add_godmode_menu_option(__('Quick Shell'), 'AW', 'gextensions', null, 'v1');
|
||||||
|
// extensions_add_godmode_function('quickShell');
|
||||||
|
|
|
@ -63,9 +63,20 @@ if (is_ajax()) {
|
||||||
|
|
||||||
$test_address = get_parameter('test_address', '');
|
$test_address = get_parameter('test_address', '');
|
||||||
|
|
||||||
$res = enterprise_hook('send_email_attachment', [$test_address, __('This is an email test sent from Pandora FMS. If you can read this, your configuration works.'), __('Testing Pandora FMS email'), null]);
|
$res = enterprise_hook(
|
||||||
|
'send_email_attachment',
|
||||||
|
[
|
||||||
|
$test_address,
|
||||||
|
__('This is an email test sent from Pandora FMS. If you can read this, your configuration works.'),
|
||||||
|
__('Testing Pandora FMS email'),
|
||||||
|
null,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
echo $res;
|
echo $res;
|
||||||
|
|
||||||
|
// Exit after ajax response.
|
||||||
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
$table = new StdClass();
|
$table = new StdClass();
|
||||||
|
@ -389,6 +400,42 @@ html_print_input_hidden('update_config', 1);
|
||||||
html_print_table($table_mail_conf);
|
html_print_table($table_mail_conf);
|
||||||
|
|
||||||
|
|
||||||
|
echo '</fieldset>';
|
||||||
|
|
||||||
|
echo '<fieldset>';
|
||||||
|
echo '<legend>'.__('WebSocket settings').'</legend>';
|
||||||
|
|
||||||
|
$t = new StdClass();
|
||||||
|
$t->data = [];
|
||||||
|
$t->width = '100%';
|
||||||
|
$t->class = 'databox filters';
|
||||||
|
$t->data = [];
|
||||||
|
$t->style[0] = 'font-weight: bold';
|
||||||
|
|
||||||
|
$t->data[0][0] = __('Bind address');
|
||||||
|
$t->data[0][1] = html_print_input_text(
|
||||||
|
'ws_bind_address',
|
||||||
|
$config['ws_bind_address'],
|
||||||
|
'',
|
||||||
|
30,
|
||||||
|
100,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
$t->data[1][0] = __('Bind port');
|
||||||
|
$t->data[1][2] = html_print_input_text(
|
||||||
|
'ws_port',
|
||||||
|
$config['ws_port'],
|
||||||
|
'',
|
||||||
|
30,
|
||||||
|
100,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
html_print_input_hidden('update_config', 1);
|
||||||
|
html_print_table($t);
|
||||||
|
|
||||||
|
|
||||||
echo '</fieldset>';
|
echo '</fieldset>';
|
||||||
|
|
||||||
echo '<div class="action-buttons" style="width: '.$table->width.'">';
|
echo '<div class="action-buttons" style="width: '.$table->width.'">';
|
||||||
|
|
|
@ -2354,26 +2354,52 @@ class ConsoleSupervisor
|
||||||
public function checkConsoleServerVersions()
|
public function checkConsoleServerVersions()
|
||||||
{
|
{
|
||||||
global $config;
|
global $config;
|
||||||
// List all servers except satellite server
|
// List all servers except satellite server.
|
||||||
$server_version_list = db_get_all_rows_sql(
|
$server_version_list = db_get_all_rows_sql(
|
||||||
'SELECT name, version FROM tserver WHERE server_type != '.SERVER_TYPE_ENTERPRISE_SATELLITE
|
sprintf(
|
||||||
|
'SELECT `name`, `version`
|
||||||
|
FROM tserver
|
||||||
|
WHERE server_type != %d
|
||||||
|
GROUP BY `version`',
|
||||||
|
SERVER_TYPE_ENTERPRISE_SATELLITE
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
foreach ($server_version_list as $server) {
|
$missed = 0;
|
||||||
if (strpos($server['version'], $config['current_package_enterprise']) === false) {
|
|
||||||
$title_ver_misaligned = $server['name'].' version misaligned with Console';
|
|
||||||
$message_ver_misaligned = 'Server '.$server['name'].' and this console have different versions. This might cause several malfunctions. Please, update this server.';
|
|
||||||
|
|
||||||
$this->notify(
|
if (is_array($server_version_list) === true) {
|
||||||
[
|
foreach ($server_version_list as $server) {
|
||||||
'type' => 'NOTIF.SERVER.MISALIGNED',
|
if (strpos(
|
||||||
'title' => __($title_ver_misaligned),
|
$server['version'],
|
||||||
'message' => __($message_ver_misaligned),
|
$config['current_package_enterprise']
|
||||||
'url' => ui_get_full_url('index.php?sec=messages&sec2=godmode/update_manager/update_manager&tab=online'),
|
) === false
|
||||||
]
|
) {
|
||||||
);
|
$missed++;
|
||||||
|
$title_ver_misaligned = __(
|
||||||
|
'%s version misaligned with Console',
|
||||||
|
$server['name']
|
||||||
|
);
|
||||||
|
$message_ver_misaligned = __(
|
||||||
|
'Server %s and this console have different versions. This might cause several malfunctions. Please, update this server.',
|
||||||
|
$server['name']
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->notify(
|
||||||
|
[
|
||||||
|
'type' => 'NOTIF.SERVER.MISALIGNED',
|
||||||
|
'title' => __($title_ver_misaligned),
|
||||||
|
'message' => __($message_ver_misaligned),
|
||||||
|
'url' => ui_get_full_url('index.php?sec=messages&sec2=godmode/update_manager/update_manager&tab=online'),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cleanup notifications if exception is recovered.
|
||||||
|
if ($missed == 0) {
|
||||||
|
$this->cleanNotifications('NOTIF.SERVER.MISALIGNED');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -353,6 +353,14 @@ function config_update_config()
|
||||||
if (!config_update_value('email_password', get_parameter('email_password'))) {
|
if (!config_update_value('email_password', get_parameter('email_password'))) {
|
||||||
$error_update[] = __('Email password');
|
$error_update[] = __('Email password');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!config_update_value('ws_bind_address', get_parameter('ws_bind_address'))) {
|
||||||
|
$error_update[] = __('WebSocket bind address');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!config_update_value('ws_port', get_parameter('ws_port'))) {
|
||||||
|
$error_update[] = __('WebSocket port');
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'enterprise':
|
case 'enterprise':
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* PHP WebSocketServer Proxy.
|
* PHP WebSocketServer Manager.
|
||||||
*
|
*
|
||||||
* Adapted to PandoraFMS by Fco de Borja Sanchez <fborja.sanchez@artica.es>
|
* Adapted to PandoraFMS by Fco de Borja Sanchez <fborja.sanchez@artica.es>
|
||||||
* Compatible with PHP >= 7.0
|
* Compatible with PHP >= 7.0
|
||||||
|
@ -52,7 +52,7 @@ require_once __DIR__.'/../functions.php';
|
||||||
/**
|
/**
|
||||||
* Redirects ws communication between two endpoints.
|
* Redirects ws communication between two endpoints.
|
||||||
*/
|
*/
|
||||||
class WSProxy extends WebSocketServer
|
class WSManager extends WebSocketServer
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -82,14 +82,14 @@ class WSProxy extends WebSocketServer
|
||||||
*
|
*
|
||||||
* @var integer
|
* @var integer
|
||||||
*/
|
*/
|
||||||
protected $maxBufferSize = 1048576;
|
public $maxBufferSize = 1048576;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interactive mode.
|
* Interactive mode.
|
||||||
*
|
*
|
||||||
* @var boolean
|
* @var boolean
|
||||||
*/
|
*/
|
||||||
protected $interative = true;
|
public $interative = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use a timeout of 100 milliseconds to search for messages..
|
* Use a timeout of 100 milliseconds to search for messages..
|
||||||
|
@ -98,37 +98,104 @@ class WSProxy extends WebSocketServer
|
||||||
*/
|
*/
|
||||||
public $timeout = 250;
|
public $timeout = 250;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handlers for connected step:
|
||||||
|
* 'protocol' => 'function';
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public $handlerConnected = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handlers for process step:
|
||||||
|
* 'protocol' => 'function';
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public $handlerProcess = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handlers for processRaw step:
|
||||||
|
* 'protocol' => 'function';
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public $handlerProcessRaw = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handlers for tick step:
|
||||||
|
* 'protocol' => 'function';
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public $handlerTick = [];
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builder.
|
* Builder.
|
||||||
*
|
*
|
||||||
* @param string $listen_addr Target address (external).
|
* @param string $listen_addr Target address (external).
|
||||||
* @param integer $listen_port Target port (external).
|
* @param integer $listen_port Target port (external).
|
||||||
* @param string $to_addr Target address (internal).
|
* @param array $connected Handlers for <connected> step.
|
||||||
* @param integer $to_port Target port (internal).
|
* @param array $process Handlers for <process> step.
|
||||||
* @param integer $to_url Target url (internal).
|
* @param array $processRaw Handlers for <processRaw> step.
|
||||||
|
* @param array $tick Handlers for <tick> step.
|
||||||
* @param integer $bufferLength Max buffer size.
|
* @param integer $bufferLength Max buffer size.
|
||||||
* @param boolean $debug Enable traces.
|
* @param boolean $debug Enable traces.
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
$listen_addr,
|
$listen_addr,
|
||||||
$listen_port,
|
$listen_port,
|
||||||
$to_addr,
|
$connected=[],
|
||||||
$to_port,
|
$process=[],
|
||||||
$to_url='/ws',
|
$processRaw=[],
|
||||||
|
$tick=[],
|
||||||
$bufferLength=1048576,
|
$bufferLength=1048576,
|
||||||
$debug=false
|
$debug=false
|
||||||
) {
|
) {
|
||||||
$this->intHost = $to_addr;
|
|
||||||
$this->intPort = $to_port;
|
|
||||||
$this->intUrl = $to_url;
|
|
||||||
$this->maxBufferSize = $bufferLength;
|
$this->maxBufferSize = $bufferLength;
|
||||||
$this->debug = $debug;
|
$this->debug = $debug;
|
||||||
|
|
||||||
|
// Configure handlers.
|
||||||
|
$this->handlerConnected = $connected;
|
||||||
|
$this->handlerProcess = $process;
|
||||||
|
$this->handlerProcessRaw = $processRaw;
|
||||||
|
$this->handlerTick = $tick;
|
||||||
|
|
||||||
$this->userClass = '\\PandoraFMS\\Websockets\\WebSocketUser';
|
$this->userClass = '\\PandoraFMS\\Websockets\\WebSocketUser';
|
||||||
parent::__construct($listen_addr, $listen_port, $bufferLength);
|
parent::__construct($listen_addr, $listen_port, $bufferLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call a target handler function.
|
||||||
|
*
|
||||||
|
* @param User $user User.
|
||||||
|
* @param array $handler Internal handler.
|
||||||
|
* @param array $arguments Arguments for handler function.
|
||||||
|
*
|
||||||
|
* @return mixed handler return or null.
|
||||||
|
*/
|
||||||
|
public function callHandler($user, $handler, $arguments)
|
||||||
|
{
|
||||||
|
if (isset($user->headers['sec-websocket-protocol'])) {
|
||||||
|
$proto = $user->headers['sec-websocket-protocol'];
|
||||||
|
if (isset($handler[$proto])
|
||||||
|
&& function_exists($handler[$proto])
|
||||||
|
) {
|
||||||
|
// Launch configured handler.
|
||||||
|
$this->stderr('Calling '.$handler[$proto]);
|
||||||
|
return call_user_func_array(
|
||||||
|
$handler[$proto],
|
||||||
|
$arguments
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read from user's socket.
|
* Read from user's socket.
|
||||||
*
|
*
|
||||||
|
@ -136,7 +203,7 @@ class WSProxy extends WebSocketServer
|
||||||
*
|
*
|
||||||
* @return string Buffer.
|
* @return string Buffer.
|
||||||
*/
|
*/
|
||||||
protected function readSocket($user)
|
public function readSocket($user)
|
||||||
{
|
{
|
||||||
$buffer;
|
$buffer;
|
||||||
|
|
||||||
|
@ -171,7 +238,7 @@ class WSProxy extends WebSocketServer
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected function writeSocket($user, $message)
|
public function writeSocket($user, $message)
|
||||||
{
|
{
|
||||||
if (is_resource($user->socket)) {
|
if (is_resource($user->socket)) {
|
||||||
if (!socket_write($user->socket, $message)) {
|
if (!socket_write($user->socket, $message)) {
|
||||||
|
@ -186,53 +253,6 @@ class WSProxy extends WebSocketServer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Connects to internal socket.
|
|
||||||
*
|
|
||||||
* @param array $headers Communication headers.
|
|
||||||
*
|
|
||||||
* @return socket Active socket or null.
|
|
||||||
*/
|
|
||||||
protected function connectInt($headers)
|
|
||||||
{
|
|
||||||
$intSocket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
|
|
||||||
$connect = socket_connect(
|
|
||||||
$intSocket,
|
|
||||||
$this->intHost,
|
|
||||||
$this->intPort
|
|
||||||
);
|
|
||||||
if (!$connect) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$c_str = 'GET '.$this->intUrl." HTTP/1.1\r\n";
|
|
||||||
$c_str .= 'Host: '.$this->intHost."\r\n";
|
|
||||||
$c_str .= "Upgrade: websocket\r\n";
|
|
||||||
$c_str .= "Connection: Upgrade\r\n";
|
|
||||||
$c_str .= 'Origin: http://'.$this->intHost."\r\n";
|
|
||||||
$c_str .= 'Sec-WebSocket-Key: '.$headers['Sec-WebSocket-Key']."\r\n";
|
|
||||||
$c_str .= 'Sec-WebSocket-Version: '.$headers['Sec-WebSocket-Version']."\r\n";
|
|
||||||
if (isset($headers['Sec-WebSocket-Protocol'])) {
|
|
||||||
$c_str .= 'Sec-WebSocket-Protocol: '.$headers['Sec-WebSocket-Protocol']."\r\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
$c_str .= "\r\n";
|
|
||||||
|
|
||||||
// Send.
|
|
||||||
// Register user - internal.
|
|
||||||
$intUser = new $this->userClass('INTERNAL-'.uniqid('u'), $intSocket);
|
|
||||||
|
|
||||||
$intUser->headers = [
|
|
||||||
'get' => $this->intUrl.' HTTP/1.1',
|
|
||||||
'host' => $this->intHost,
|
|
||||||
'origin' => $this->intHost,
|
|
||||||
];
|
|
||||||
$this->writeSocket($intUser, $c_str);
|
|
||||||
|
|
||||||
return $intUser;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User already connected.
|
* User already connected.
|
||||||
*
|
*
|
||||||
|
@ -240,7 +260,7 @@ class WSProxy extends WebSocketServer
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected function connected($user)
|
public function connected($user)
|
||||||
{
|
{
|
||||||
global $config;
|
global $config;
|
||||||
|
|
||||||
|
@ -275,31 +295,15 @@ class WSProxy extends WebSocketServer
|
||||||
// Disconnect previous sessions.
|
// Disconnect previous sessions.
|
||||||
$this->cleanupSocketByCookie($user);
|
$this->cleanupSocketByCookie($user);
|
||||||
|
|
||||||
/*
|
// Launch registered handler.
|
||||||
* $user->intSocket is connected to internal.
|
$this->callHandler(
|
||||||
* $user->socket is connected to external.
|
$user,
|
||||||
*/
|
$this->handlerConnected,
|
||||||
|
[
|
||||||
// Create a new socket connection (internal).
|
$this,
|
||||||
$intUser = $this->connectInt($this->rawHeaders);
|
$user,
|
||||||
if ($intUser === null) {
|
]
|
||||||
$this->disconnect($user->socket);
|
);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Map user.
|
|
||||||
$user->intUser = $intUser;
|
|
||||||
// And socket.
|
|
||||||
$user->intSocket = $intUser->socket;
|
|
||||||
$user->redirect = $intUser;
|
|
||||||
$intUser->redirect = $user;
|
|
||||||
|
|
||||||
// Keep an eye on changes.
|
|
||||||
$this->remoteSockets[$intUser->id] = $intUser->socket;
|
|
||||||
$this->remoteUsers[$intUser->id] = $intUser;
|
|
||||||
|
|
||||||
// Ignore. Cleanup socket.
|
|
||||||
$response = $this->readSocket($user->intUser);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -310,12 +314,34 @@ class WSProxy extends WebSocketServer
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function processProtocol($protocol): string
|
public function processProtocol($protocol): string
|
||||||
{
|
{
|
||||||
return 'Sec-Websocket-Protocol: '.$protocol."\r\n";
|
return 'Sec-Websocket-Protocol: '.$protocol."\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process programattic function
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function tick()
|
||||||
|
{
|
||||||
|
foreach ($this->users as $user) {
|
||||||
|
// Launch registered handler.
|
||||||
|
$this->callHandler(
|
||||||
|
$user,
|
||||||
|
$this->handlerTick,
|
||||||
|
[
|
||||||
|
$this,
|
||||||
|
$user,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process undecoded user message.
|
* Process undecoded user message.
|
||||||
*
|
*
|
||||||
|
@ -324,18 +350,18 @@ class WSProxy extends WebSocketServer
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
protected function processRaw($user, $buffer)
|
public function processRaw($user, $buffer)
|
||||||
{
|
{
|
||||||
if (!isset($user->redirect)) {
|
// Launch registered handler.
|
||||||
$this->disconnect($user->socket);
|
return $this->callHandler(
|
||||||
return false;
|
$user,
|
||||||
}
|
$this->handlerProcessRaw,
|
||||||
|
[
|
||||||
$this->stderr($user->id.' >> '.$user->redirect->id);
|
$this,
|
||||||
$this->stderr($this->dump($buffer));
|
$user,
|
||||||
$this->writeSocket($user->redirect, $buffer);
|
$buffer,
|
||||||
|
]
|
||||||
return true;
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -348,12 +374,24 @@ class WSProxy extends WebSocketServer
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected function process($user, $message, $str_message)
|
public function process($user, $message, $str_message)
|
||||||
{
|
{
|
||||||
if ($str_message === true) {
|
if ($str_message === true) {
|
||||||
$remmitent = $user->address.'('.$user->account->idUser.')';
|
$remmitent = $user->address.'('.$user->account->idUser.')';
|
||||||
$this->stderr($remmitent.': '.$message);
|
$this->stderr($remmitent.': '.$message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Launch registered handler.
|
||||||
|
$this->callHandler(
|
||||||
|
$user,
|
||||||
|
$this->handlerProcess,
|
||||||
|
[
|
||||||
|
$this,
|
||||||
|
$user,
|
||||||
|
$message,
|
||||||
|
$str_message,
|
||||||
|
]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -364,7 +402,7 @@ class WSProxy extends WebSocketServer
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected function closed($user)
|
public function closed($user)
|
||||||
{
|
{
|
||||||
if ($user->account) {
|
if ($user->account) {
|
||||||
$_SERVER['REMOTE_ADDR'] = $user->address;
|
$_SERVER['REMOTE_ADDR'] = $user->address;
|
|
@ -1,89 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* PHP WebSocketUser Proxy.
|
|
||||||
*
|
|
||||||
* Adapted to PandoraFMS by Fco de Borja Sanchez <fborja.sanchez@artica.es>
|
|
||||||
* Compatible with PHP >= 7.0
|
|
||||||
*
|
|
||||||
* @category External library
|
|
||||||
* @package Pandora FMS
|
|
||||||
* @subpackage WebSocketServer
|
|
||||||
* @version 1.0.0
|
|
||||||
* @license See below
|
|
||||||
* @filesource https://github.com/ghedipunk/PHP-Websockets
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* - Redistributions of source code must retain the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer.
|
|
||||||
*
|
|
||||||
* - Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
|
||||||
* and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* - Neither the name of PHP WebSockets nor the names of its contributors may
|
|
||||||
* be used to endorse or promote products derived from this software without
|
|
||||||
* specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
||||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Begin.
|
|
||||||
namespace PandoraFMS\WebSockets;
|
|
||||||
|
|
||||||
use \PandoraFMS\WebSockets\WebSocketUser;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* WebSocket proxy user.
|
|
||||||
*/
|
|
||||||
class WSProxyUser extends WebSocketUser
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Redirection socket.
|
|
||||||
*
|
|
||||||
* @var socket
|
|
||||||
*/
|
|
||||||
public $intSocket;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pair resend packages.
|
|
||||||
*
|
|
||||||
* @var WSProxyUser
|
|
||||||
*/
|
|
||||||
public $redirect;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* User identifier.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
public $myId;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Builder.
|
|
||||||
*
|
|
||||||
* @param string $id Identifier.
|
|
||||||
* @param socket $socket Socket (origin).
|
|
||||||
*/
|
|
||||||
public function __construct($id, $socket)
|
|
||||||
{
|
|
||||||
parent::__construct($id, $socket);
|
|
||||||
$this->myId = $id;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -56,7 +56,7 @@ abstract class WebSocketServer
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $userClass = 'WebSocketUser';
|
public $userClass = 'WebSocketUser';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Redefine this if you want a custom user class. The custom user class
|
* Redefine this if you want a custom user class. The custom user class
|
||||||
|
@ -64,91 +64,91 @@ abstract class WebSocketServer
|
||||||
*
|
*
|
||||||
* @var integer
|
* @var integer
|
||||||
*/
|
*/
|
||||||
protected $maxBufferSize;
|
public $maxBufferSize;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Max. concurrent connections.
|
* Max. concurrent connections.
|
||||||
*
|
*
|
||||||
* @var integer
|
* @var integer
|
||||||
*/
|
*/
|
||||||
protected $maxConnections = 20;
|
public $maxConnections = 20;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Undocumented variable
|
* Undocumented variable
|
||||||
*
|
*
|
||||||
* @var [type]
|
* @var [type]
|
||||||
*/
|
*/
|
||||||
protected $master;
|
public $master;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Incoming sockets.
|
* Incoming sockets.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $sockets = [];
|
public $sockets = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Outgoing sockets.
|
* Outgoing sockets.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $remoteSockets = [];
|
public $remoteSockets = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Client list.
|
* Client list.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $users = [];
|
public $users = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Servers list.
|
* Servers list.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $remoteUsers = [];
|
public $remoteUsers = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Undocumented variable
|
* Undocumented variable
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $heldMessages = [];
|
public $heldMessages = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show output.
|
* Show output.
|
||||||
*
|
*
|
||||||
* @var boolean
|
* @var boolean
|
||||||
*/
|
*/
|
||||||
protected $interactive = true;
|
public $interactive = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Debug.
|
* Debug.
|
||||||
*
|
*
|
||||||
* @var boolean
|
* @var boolean
|
||||||
*/
|
*/
|
||||||
protected $debug = false;
|
public $debug = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Undocumented variable
|
* Undocumented variable
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $headerOriginRequired = false;
|
public $headerOriginRequired = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Undocumented variable
|
* Undocumented variable
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $headerSecWebSocketProtocolRequired = false;
|
public $headerSecWebSocketProtocolRequired = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Undocumented variable
|
* Undocumented variable
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $headerSecWebSocketExtensionsRequired = false;
|
public $headerSecWebSocketExtensionsRequired = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stored raw headers for redirection.
|
* Stored raw headers for redirection.
|
||||||
|
@ -217,7 +217,7 @@ abstract class WebSocketServer
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
abstract protected function process($user, $message, $str_message);
|
abstract public function process($user, $message, $str_message);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -228,7 +228,7 @@ abstract class WebSocketServer
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected function processRaw($user, $buffer)
|
public function processRaw($user, $buffer)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -241,7 +241,7 @@ abstract class WebSocketServer
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
abstract protected function connected($user);
|
abstract public function connected($user);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -251,7 +251,7 @@ abstract class WebSocketServer
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
abstract protected function closed($user);
|
abstract public function closed($user);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -263,7 +263,7 @@ abstract class WebSocketServer
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected function connecting($user)
|
public function connecting($user)
|
||||||
{
|
{
|
||||||
// Optional implementation.
|
// Optional implementation.
|
||||||
}
|
}
|
||||||
|
@ -277,9 +277,8 @@ abstract class WebSocketServer
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected function send($user, $message)
|
public function send($user, $message)
|
||||||
{
|
{
|
||||||
var_dump($user->handshake);
|
|
||||||
if ($user->handshake) {
|
if ($user->handshake) {
|
||||||
$message = $this->frame($message, $user);
|
$message = $this->frame($message, $user);
|
||||||
$result = socket_write($user->socket, $message, strlen($message));
|
$result = socket_write($user->socket, $message, strlen($message));
|
||||||
|
@ -301,7 +300,7 @@ abstract class WebSocketServer
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected function tick()
|
public function tick()
|
||||||
{
|
{
|
||||||
// Optional implementation.
|
// Optional implementation.
|
||||||
}
|
}
|
||||||
|
@ -312,7 +311,7 @@ abstract class WebSocketServer
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected function pTick()
|
public function pTick()
|
||||||
{
|
{
|
||||||
// Core maintenance processes, such as retrying failed messages.
|
// Core maintenance processes, such as retrying failed messages.
|
||||||
foreach ($this->heldMessages as $key => $hm) {
|
foreach ($this->heldMessages as $key => $hm) {
|
||||||
|
@ -532,7 +531,7 @@ abstract class WebSocketServer
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected function connect($socket)
|
public function connect($socket)
|
||||||
{
|
{
|
||||||
$user = new $this->userClass(
|
$user = new $this->userClass(
|
||||||
uniqid('u'),
|
uniqid('u'),
|
||||||
|
@ -553,7 +552,7 @@ abstract class WebSocketServer
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected function disconnect(
|
public function disconnect(
|
||||||
$socket,
|
$socket,
|
||||||
bool $triggerClosed=true,
|
bool $triggerClosed=true,
|
||||||
$sockErrNo=null
|
$sockErrNo=null
|
||||||
|
@ -606,7 +605,7 @@ abstract class WebSocketServer
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected function doHandshake($user, $buffer)
|
public function doHandshake($user, $buffer)
|
||||||
{
|
{
|
||||||
$magicGUID = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
|
$magicGUID = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
|
||||||
$headers = [];
|
$headers = [];
|
||||||
|
@ -742,7 +741,7 @@ abstract class WebSocketServer
|
||||||
*
|
*
|
||||||
* @return boolean Ok or not.
|
* @return boolean Ok or not.
|
||||||
*/
|
*/
|
||||||
protected function checkHost($hostName): bool
|
public function checkHost($hostName): bool
|
||||||
{
|
{
|
||||||
// Override and return false if host is not one that you would expect.
|
// Override and return false if host is not one that you would expect.
|
||||||
// Ex: You only want to accept hosts from the my-domain.com domain,
|
// Ex: You only want to accept hosts from the my-domain.com domain,
|
||||||
|
@ -758,7 +757,7 @@ abstract class WebSocketServer
|
||||||
*
|
*
|
||||||
* @return boolean Allowed or not.
|
* @return boolean Allowed or not.
|
||||||
*/
|
*/
|
||||||
protected function checkOrigin($origin): bool
|
public function checkOrigin($origin): bool
|
||||||
{
|
{
|
||||||
// Override and return false if origin is not one that you would expect.
|
// Override and return false if origin is not one that you would expect.
|
||||||
return true;
|
return true;
|
||||||
|
@ -772,7 +771,7 @@ abstract class WebSocketServer
|
||||||
*
|
*
|
||||||
* @return boolean Expected or not.
|
* @return boolean Expected or not.
|
||||||
*/
|
*/
|
||||||
protected function checkWebsocProtocol($protocol): bool
|
public function checkWebsocProtocol($protocol): bool
|
||||||
{
|
{
|
||||||
// Override and return false if a protocol is not found that you
|
// Override and return false if a protocol is not found that you
|
||||||
// would expect.
|
// would expect.
|
||||||
|
@ -787,7 +786,7 @@ abstract class WebSocketServer
|
||||||
*
|
*
|
||||||
* @return boolean Allowed or not.
|
* @return boolean Allowed or not.
|
||||||
*/
|
*/
|
||||||
protected function checkWebsocExtensions($extensions): bool
|
public function checkWebsocExtensions($extensions): bool
|
||||||
{
|
{
|
||||||
// Override and return false if an extension is not found that you
|
// Override and return false if an extension is not found that you
|
||||||
// would expect.
|
// would expect.
|
||||||
|
@ -810,7 +809,7 @@ abstract class WebSocketServer
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function processProtocol($protocol): string
|
public function processProtocol($protocol): string
|
||||||
{
|
{
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
@ -825,7 +824,7 @@ abstract class WebSocketServer
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function processExtensions($extensions): string
|
public function processExtensions($extensions): string
|
||||||
{
|
{
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
@ -838,7 +837,7 @@ abstract class WebSocketServer
|
||||||
*
|
*
|
||||||
* @return object
|
* @return object
|
||||||
*/
|
*/
|
||||||
protected function getUserBySocket($socket)
|
public function getUserBySocket($socket)
|
||||||
{
|
{
|
||||||
foreach ($this->users as $user) {
|
foreach ($this->users as $user) {
|
||||||
if ($user->socket == $socket) {
|
if ($user->socket == $socket) {
|
||||||
|
@ -863,7 +862,7 @@ abstract class WebSocketServer
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected function cleanupSocketByCookie($user)
|
public function cleanupSocketByCookie($user)
|
||||||
{
|
{
|
||||||
$cookie = $user->headers['cookie'];
|
$cookie = $user->headers['cookie'];
|
||||||
foreach ($this->users as $u) {
|
foreach ($this->users as $u) {
|
||||||
|
@ -884,7 +883,7 @@ abstract class WebSocketServer
|
||||||
*
|
*
|
||||||
* @return object
|
* @return object
|
||||||
*/
|
*/
|
||||||
protected function getIntUserBySocket($socket)
|
public function getIntUserBySocket($socket)
|
||||||
{
|
{
|
||||||
foreach ($this->users as $user) {
|
foreach ($this->users as $user) {
|
||||||
if ($user->intSocket == $socket) {
|
if ($user->intSocket == $socket) {
|
||||||
|
@ -941,7 +940,7 @@ abstract class WebSocketServer
|
||||||
*
|
*
|
||||||
* @return string Framed message.
|
* @return string Framed message.
|
||||||
*/
|
*/
|
||||||
protected function frame(
|
public function frame(
|
||||||
$message,
|
$message,
|
||||||
$user,
|
$user,
|
||||||
$messageType='text',
|
$messageType='text',
|
||||||
|
@ -1046,7 +1045,7 @@ abstract class WebSocketServer
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected function splitPacket(
|
public function splitPacket(
|
||||||
int $length,
|
int $length,
|
||||||
$packet,
|
$packet,
|
||||||
$user
|
$user
|
||||||
|
@ -1106,7 +1105,7 @@ abstract class WebSocketServer
|
||||||
*
|
*
|
||||||
* @return integer Calculated offset.
|
* @return integer Calculated offset.
|
||||||
*/
|
*/
|
||||||
protected function calcOffset(array $headers): int
|
public function calcOffset(array $headers): int
|
||||||
{
|
{
|
||||||
$offset = 2;
|
$offset = 2;
|
||||||
if ($headers['hasmask']) {
|
if ($headers['hasmask']) {
|
||||||
|
@ -1131,7 +1130,7 @@ abstract class WebSocketServer
|
||||||
*
|
*
|
||||||
* @return boolean Process ok or not.
|
* @return boolean Process ok or not.
|
||||||
*/
|
*/
|
||||||
protected function deframe(
|
public function deframe(
|
||||||
$message,
|
$message,
|
||||||
&$user
|
&$user
|
||||||
) {
|
) {
|
||||||
|
@ -1226,7 +1225,7 @@ abstract class WebSocketServer
|
||||||
*
|
*
|
||||||
* @return array Headers.
|
* @return array Headers.
|
||||||
*/
|
*/
|
||||||
protected function extractHeaders($message): array
|
public function extractHeaders($message): array
|
||||||
{
|
{
|
||||||
$header = [
|
$header = [
|
||||||
'fin' => ($message[0] & chr(128)),
|
'fin' => ($message[0] & chr(128)),
|
||||||
|
@ -1304,7 +1303,7 @@ abstract class WebSocketServer
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function extractPayload(
|
public function extractPayload(
|
||||||
$message,
|
$message,
|
||||||
array $headers
|
array $headers
|
||||||
) {
|
) {
|
||||||
|
@ -1331,7 +1330,7 @@ abstract class WebSocketServer
|
||||||
*
|
*
|
||||||
* @return string Xor.
|
* @return string Xor.
|
||||||
*/
|
*/
|
||||||
protected function applyMask(
|
public function applyMask(
|
||||||
array $headers,
|
array $headers,
|
||||||
$payload
|
$payload
|
||||||
) {
|
) {
|
||||||
|
@ -1373,7 +1372,7 @@ abstract class WebSocketServer
|
||||||
*
|
*
|
||||||
* @return boolean OK or not.
|
* @return boolean OK or not.
|
||||||
*/
|
*/
|
||||||
protected function checkRSVBits(
|
public function checkRSVBits(
|
||||||
array $headers,
|
array $headers,
|
||||||
$user
|
$user
|
||||||
): bool {
|
): bool {
|
||||||
|
@ -1400,7 +1399,7 @@ abstract class WebSocketServer
|
||||||
*
|
*
|
||||||
* @return string HEX string.
|
* @return string HEX string.
|
||||||
*/
|
*/
|
||||||
protected function strtohex(
|
public function strtohex(
|
||||||
$str=''
|
$str=''
|
||||||
): string {
|
): string {
|
||||||
$strout = '';
|
$strout = '';
|
||||||
|
@ -1441,7 +1440,7 @@ abstract class WebSocketServer
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected function printHeaders($headers)
|
public function printHeaders($headers)
|
||||||
{
|
{
|
||||||
echo "Array\n(\n";
|
echo "Array\n(\n";
|
||||||
foreach ($headers as $key => $value) {
|
foreach ($headers as $key => $value) {
|
||||||
|
@ -1468,7 +1467,7 @@ abstract class WebSocketServer
|
||||||
// Init.
|
// Init.
|
||||||
$hexi = '';
|
$hexi = '';
|
||||||
$ascii = '';
|
$ascii = '';
|
||||||
$dump = '';
|
$dump = "Hex Message:\n";
|
||||||
$offset = 0;
|
$offset = 0;
|
||||||
$len = strlen($data);
|
$len = strlen($data);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,189 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Extra functionality for PandoraFMS WebSockets.
|
||||||
|
*
|
||||||
|
* Register here your methods to handle different WebSocket steps.
|
||||||
|
* * connected
|
||||||
|
* * process
|
||||||
|
* * disconnect
|
||||||
|
* * tick
|
||||||
|
*
|
||||||
|
* DO NOT FORGET TO REGISTER THEM TO ws.php!!
|
||||||
|
*
|
||||||
|
* @category Websocket
|
||||||
|
* @package Pandora FMS
|
||||||
|
* @subpackage Console
|
||||||
|
* @version 1.0.0
|
||||||
|
* @license See below
|
||||||
|
*
|
||||||
|
* ______ ___ _______ _______ ________
|
||||||
|
* | __ \.-----.--.--.--| |.-----.----.-----. | ___| | | __|
|
||||||
|
* | __/| _ | | _ || _ | _| _ | | ___| |__ |
|
||||||
|
* |___| |___._|__|__|_____||_____|__| |___._| |___| |__|_|__|_______|
|
||||||
|
*
|
||||||
|
* ============================================================================
|
||||||
|
* Copyright (c) 2005-2019 Artica Soluciones Tecnologicas
|
||||||
|
* Please see http://pandorafms.org for full contribution list
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation for version 2.
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
* ============================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ============================================================================
|
||||||
|
* * GOTTY PROTOCOL: PROXY
|
||||||
|
* ============================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connects to internal socket.
|
||||||
|
*
|
||||||
|
* @param WSManager $ws_object Main WebSocket manager object.
|
||||||
|
* @param array $headers Communication headers.
|
||||||
|
* @param string $to_addr Target address (internal).
|
||||||
|
* @param integer $to_port Target port (internal).
|
||||||
|
* @param integer $to_url Target url (internal).
|
||||||
|
*
|
||||||
|
* @return socket Active socket or null.
|
||||||
|
*/
|
||||||
|
function connectInt(
|
||||||
|
$ws_object,
|
||||||
|
$headers,
|
||||||
|
$to_addr,
|
||||||
|
$to_port,
|
||||||
|
$to_url
|
||||||
|
) {
|
||||||
|
$intSocket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
|
||||||
|
$connect = socket_connect(
|
||||||
|
$intSocket,
|
||||||
|
$to_addr,
|
||||||
|
$to_port
|
||||||
|
);
|
||||||
|
if (!$connect) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$c_str = 'GET '.$to_url." HTTP/1.1\r\n";
|
||||||
|
$c_str .= 'Host: '.$to_addr."\r\n";
|
||||||
|
$c_str .= "Upgrade: websocket\r\n";
|
||||||
|
$c_str .= "Connection: Upgrade\r\n";
|
||||||
|
$c_str .= 'Origin: http://'.$to_addr."\r\n";
|
||||||
|
$c_str .= 'Sec-WebSocket-Key: '.$headers['Sec-WebSocket-Key']."\r\n";
|
||||||
|
$c_str .= 'Sec-WebSocket-Version: '.$headers['Sec-WebSocket-Version']."\r\n";
|
||||||
|
if (isset($headers['Sec-WebSocket-Protocol'])) {
|
||||||
|
$c_str .= 'Sec-WebSocket-Protocol: '.$headers['Sec-WebSocket-Protocol']."\r\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$c_str .= "\r\n";
|
||||||
|
|
||||||
|
// Send.
|
||||||
|
// Register user - internal.
|
||||||
|
$intUser = new $ws_object->userClass('INTERNAL-'.uniqid('u'), $intSocket);
|
||||||
|
|
||||||
|
$intUser->headers = [
|
||||||
|
'get' => $to_url.' HTTP/1.1',
|
||||||
|
'host' => $to_addr,
|
||||||
|
'origin' => $to_addr,
|
||||||
|
'sec-websocket-protocol' => 'gotty',
|
||||||
|
];
|
||||||
|
$ws_object->writeSocket($intUser, $c_str);
|
||||||
|
|
||||||
|
return $intUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process a connected step on proxied protocols.
|
||||||
|
*
|
||||||
|
* @param WSManager $ws_object Main WebSocket manager object.
|
||||||
|
* @param User $user WebSocketUser.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function proxyConnected(
|
||||||
|
$ws_object,
|
||||||
|
$user
|
||||||
|
) {
|
||||||
|
global $config;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $user->redirect is connected to internal (reflexive).
|
||||||
|
* $user->socket is connected to external.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Gotty. Based on the command selected, redirect to a target port.
|
||||||
|
if ($user->requestedResource == '/ssh') {
|
||||||
|
$port = $config['gotty_ssh_port'];
|
||||||
|
} else if ($user->requestedResource == '/telnet') {
|
||||||
|
$port = $config['gotty_telnet_port'];
|
||||||
|
} else {
|
||||||
|
$ws_object->disconnect($user->socket);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Switch between ports...
|
||||||
|
// Create a new socket connection (internal).
|
||||||
|
$intUser = connectInt(
|
||||||
|
$ws_object,
|
||||||
|
$ws_object->rawHeaders,
|
||||||
|
$config['gotty_host'],
|
||||||
|
$port,
|
||||||
|
'/ws'
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($intUser === null) {
|
||||||
|
$ws_object->disconnect($user->socket);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map user.
|
||||||
|
$user->intUser = $intUser;
|
||||||
|
// And socket.
|
||||||
|
$user->intSocket = $intUser->socket;
|
||||||
|
$user->redirect = $intUser;
|
||||||
|
$intUser->redirect = $user;
|
||||||
|
|
||||||
|
// Keep an eye on changes.
|
||||||
|
$ws_object->remoteSockets[$intUser->id] = $intUser->socket;
|
||||||
|
$ws_object->remoteUsers[$intUser->id] = $intUser;
|
||||||
|
|
||||||
|
// Ignore. Cleanup socket.
|
||||||
|
$response = $ws_object->readSocket($user->intUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redirects input from user to redirection stabished.
|
||||||
|
*
|
||||||
|
* @param WSManager $ws_object Main WebSocket manager object.
|
||||||
|
* @param WebSocketUser $user WebSocket user.
|
||||||
|
* @param string $buffer Buffer.
|
||||||
|
*
|
||||||
|
* @return boolean Ok or not.
|
||||||
|
*/
|
||||||
|
function proxyProcessRaw($ws_object, $user, $buffer)
|
||||||
|
{
|
||||||
|
if (isset($user->redirect) !== true) {
|
||||||
|
$ws_object->disconnect($user->socket);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$ws_object->stderr($user->id.' >> '.$user->redirect->id);
|
||||||
|
$ws_object->stderr($ws_object->dump($buffer));
|
||||||
|
$ws_object->writeSocket($user->redirect, $buffer);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ============================================================================
|
||||||
|
* * ENDS: GOTTY PROTOCOL: PROXY
|
||||||
|
* ============================================================================
|
||||||
|
*/
|
|
@ -308,8 +308,7 @@ return array(
|
||||||
'Mpdf\\Utils\\PdfDate' => $vendorDir . '/mpdf/mpdf/src/Utils/PdfDate.php',
|
'Mpdf\\Utils\\PdfDate' => $vendorDir . '/mpdf/mpdf/src/Utils/PdfDate.php',
|
||||||
'Mpdf\\Utils\\UtfString' => $vendorDir . '/mpdf/mpdf/src/Utils/UtfString.php',
|
'Mpdf\\Utils\\UtfString' => $vendorDir . '/mpdf/mpdf/src/Utils/UtfString.php',
|
||||||
'PandoraFMS\\User' => $baseDir . '/include/lib/User.php',
|
'PandoraFMS\\User' => $baseDir . '/include/lib/User.php',
|
||||||
'PandoraFMS\\WebSockets\\WSProxy' => $baseDir . '/include/lib/WSProxy.php',
|
'PandoraFMS\\WebSockets\\WSManager' => $baseDir . '/include/lib/WSManager.php',
|
||||||
'PandoraFMS\\WebSockets\\WSProxyUser' => $baseDir . '/include/lib/WSProxyUser.php',
|
|
||||||
'PandoraFMS\\Websockets\\WebSocketServer' => $baseDir . '/include/lib/WebSocketServer.php',
|
'PandoraFMS\\Websockets\\WebSocketServer' => $baseDir . '/include/lib/WebSocketServer.php',
|
||||||
'PandoraFMS\\Websockets\\WebSocketUser' => $baseDir . '/include/lib/WebSocketUser.php',
|
'PandoraFMS\\Websockets\\WebSocketUser' => $baseDir . '/include/lib/WebSocketUser.php',
|
||||||
'Psr\\Log\\AbstractLogger' => $vendorDir . '/psr/log/Psr/Log/AbstractLogger.php',
|
'Psr\\Log\\AbstractLogger' => $vendorDir . '/psr/log/Psr/Log/AbstractLogger.php',
|
||||||
|
|
|
@ -390,8 +390,7 @@ class ComposerStaticInitfdecadadce22e6dde51e9535fe4ad7aa
|
||||||
'Mpdf\\Utils\\PdfDate' => __DIR__ . '/..' . '/mpdf/mpdf/src/Utils/PdfDate.php',
|
'Mpdf\\Utils\\PdfDate' => __DIR__ . '/..' . '/mpdf/mpdf/src/Utils/PdfDate.php',
|
||||||
'Mpdf\\Utils\\UtfString' => __DIR__ . '/..' . '/mpdf/mpdf/src/Utils/UtfString.php',
|
'Mpdf\\Utils\\UtfString' => __DIR__ . '/..' . '/mpdf/mpdf/src/Utils/UtfString.php',
|
||||||
'PandoraFMS\\User' => __DIR__ . '/../..' . '/include/lib/User.php',
|
'PandoraFMS\\User' => __DIR__ . '/../..' . '/include/lib/User.php',
|
||||||
'PandoraFMS\\WebSockets\\WSProxy' => __DIR__ . '/../..' . '/include/lib/WSProxy.php',
|
'PandoraFMS\\WebSockets\\WSManager' => __DIR__ . '/../..' . '/include/lib/WSManager.php',
|
||||||
'PandoraFMS\\WebSockets\\WSProxyUser' => __DIR__ . '/../..' . '/include/lib/WSProxyUser.php',
|
|
||||||
'PandoraFMS\\Websockets\\WebSocketServer' => __DIR__ . '/../..' . '/include/lib/WebSocketServer.php',
|
'PandoraFMS\\Websockets\\WebSocketServer' => __DIR__ . '/../..' . '/include/lib/WebSocketServer.php',
|
||||||
'PandoraFMS\\Websockets\\WebSocketUser' => __DIR__ . '/../..' . '/include/lib/WebSocketUser.php',
|
'PandoraFMS\\Websockets\\WebSocketUser' => __DIR__ . '/../..' . '/include/lib/WebSocketUser.php',
|
||||||
'Psr\\Log\\AbstractLogger' => __DIR__ . '/..' . '/psr/log/Psr/Log/AbstractLogger.php',
|
'Psr\\Log\\AbstractLogger' => __DIR__ . '/..' . '/psr/log/Psr/Log/AbstractLogger.php',
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
|
|
||||||
// Begin.
|
// Begin.
|
||||||
require_once __DIR__.'/vendor/autoload.php';
|
require_once __DIR__.'/vendor/autoload.php';
|
||||||
use \PandoraFMS\WebSockets\WSProxy;
|
use \PandoraFMS\WebSockets\WSManager;
|
||||||
|
|
||||||
// Set to true to get full output.
|
// Set to true to get full output.
|
||||||
$debug = false;
|
$debug = false;
|
||||||
|
@ -48,10 +48,11 @@ $_SERVER['DOCUMENT_ROOT'] = __DIR__.'/../';
|
||||||
|
|
||||||
// Don't start a session before this import.
|
// Don't start a session before this import.
|
||||||
// The session is configured and started inside the config process.
|
// The session is configured and started inside the config process.
|
||||||
require_once 'include/config.php';
|
require_once __DIR__.'/include/config.php';
|
||||||
require_once 'include/functions.php';
|
require_once __DIR__.'/include/functions.php';
|
||||||
require_once 'include/functions_db.php';
|
require_once __DIR__.'/include/functions_db.php';
|
||||||
require_once 'include/auth/mysql.php';
|
require_once __DIR__.'/include/auth/mysql.php';
|
||||||
|
require_once __DIR__.'/include/websocket_registrations.php';
|
||||||
|
|
||||||
// Enterprise support.
|
// Enterprise support.
|
||||||
if (file_exists(ENTERPRISE_DIR.'/load_enterprise.php') === true) {
|
if (file_exists(ENTERPRISE_DIR.'/load_enterprise.php') === true) {
|
||||||
|
@ -67,7 +68,23 @@ if (isset($_SERVER['REMOTE_ADDR']) === true) {
|
||||||
|
|
||||||
|
|
||||||
if (isset($config['ws_port']) === false) {
|
if (isset($config['ws_port']) === false) {
|
||||||
config_update_value('ws_port', 8081);
|
config_update_value('ws_port', 8080);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($config['ws_bind_address']) === false) {
|
||||||
|
config_update_value('ws_bind_address', '0.0.0.0');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($config['gotty_host']) === false) {
|
||||||
|
config_update_value('gotty_host', '127.0.0.1');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($config['gotty_telnet_port']) === false) {
|
||||||
|
config_update_value('gotty_telnet_port', 8082);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($config['gotty_ssh_port']) === false) {
|
||||||
|
config_update_value('gotty_ssh_port', 8081);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($config['gotty']) === false) {
|
if (isset($config['gotty']) === false) {
|
||||||
|
@ -80,25 +97,44 @@ error_reporting(E_ALL);
|
||||||
|
|
||||||
$os = strtolower(PHP_OS);
|
$os = strtolower(PHP_OS);
|
||||||
if (substr($os, 0, 3) !== 'win') {
|
if (substr($os, 0, 3) !== 'win') {
|
||||||
// Launch gotty.
|
// Kill previous gotty running.
|
||||||
$cmd = 'nohup "'.$config['gotty'].'" -a 127.0.0.1 -w /bin/bash';
|
shell_exec('killall "'.$config['gotty'].'" >/dev/null 2>&1');
|
||||||
$cmd .= ' >> '.__DIR__.'/pandora_console.log 2>&1 &';
|
|
||||||
|
// Common.
|
||||||
|
$base_cmd = 'nohup "'.$config['gotty'].'"';
|
||||||
|
$base_cmd .= ' --permit-arguments -a 127.0.0.1 -w ';
|
||||||
|
|
||||||
|
// Launch gotty - SSH.
|
||||||
|
$cmd = $base_cmd.' --port '.$config['gotty_ssh_port'];
|
||||||
|
$cmd .= ' ssh >> '.__DIR__.'/pandora_console.log 2>&1 &';
|
||||||
|
shell_exec($cmd);
|
||||||
|
|
||||||
|
// Launch gotty - telnet.
|
||||||
|
$cmd = $base_cmd.' --port '.$config['gotty_telnet_port'];
|
||||||
|
$cmd .= ' telnet >> '.__DIR__.'/pandora_console.log 2>&1 &';
|
||||||
shell_exec($cmd);
|
shell_exec($cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start Web SocketProxy.
|
// Start Web SocketProxy.
|
||||||
$wsproxy = new WSProxy(
|
$ws = new WSManager(
|
||||||
'0.0.0.0',
|
// Bind address.
|
||||||
|
$config['ws_bind_address'],
|
||||||
|
// Bind port.
|
||||||
$config['ws_port'],
|
$config['ws_port'],
|
||||||
'127.0.0.1',
|
// Connected handlers.
|
||||||
'8080',
|
['gotty' => 'proxyConnected'],
|
||||||
'/ws',
|
// Process handlers.
|
||||||
|
[],
|
||||||
|
// ProcessRaw handlers.
|
||||||
|
['gotty' => 'proxyProcessRaw'],
|
||||||
|
// Tick handlers.
|
||||||
|
[],
|
||||||
$bufferSize,
|
$bufferSize,
|
||||||
$debug
|
$debug
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$wsproxy->run();
|
$ws->run();
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
$wsproxy->stdout($e->getMessage());
|
$ws->stdout($e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue