From 1a3e5a5bb861f59cbcdede94a82f0984e97ea002 Mon Sep 17 00:00:00 2001 From: Guillaume Mazoyer Date: Thu, 29 May 2014 14:28:48 +0200 Subject: Apache 2.4 configuration to avoid to access the config.php file. First import of the whole source code (quite monolithic for now). Update configuration example. --- .htaccess | 3 ++ config.php.example | 2 + execute.php | 99 ++++++++++++++++++++++++++++++++++++++ includes/style.css | 63 ++++++++++++++++++++++++ includes/utils.js | 41 ++++++++++++++++ index.php | 111 ++++++++++++++++++++++++++++++++++++++++++ router.php | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 458 insertions(+) create mode 100644 .htaccess create mode 100644 execute.php create mode 100644 includes/style.css create mode 100644 includes/utils.js create mode 100644 index.php create mode 100644 router.php diff --git a/.htaccess b/.htaccess new file mode 100644 index 0000000..149477a --- /dev/null +++ b/.htaccess @@ -0,0 +1,3 @@ + + Require all denied + diff --git a/config.php.example b/config.php.example index 7666cb3..7355e92 100644 --- a/config.php.example +++ b/config.php.example @@ -6,6 +6,8 @@ $config['contact']['mail'] = 'support@example.com'; // Frontpage configuration +// CSS to use +$config['frontpage']['css'] = 'includes/style.css'; // Title of the page $config['frontpage']['title'] = 'Looking Glass'; // Logo to display diff --git a/execute.php b/execute.php new file mode 100644 index 0000000..e3774f0 --- /dev/null +++ b/execute.php @@ -0,0 +1,99 @@ +connect(); + $data = $router->send_command($query, $parameters); + $router->disconnect(); + + // Process the output line by line + foreach (preg_split("/((\r?\n)|(\r\n?))/", $data) as $line) { + // Get rid of empty lines + if (empty($line)) { + continue; + } + + $valid = true; + + foreach ($config['filters'] as $filter) { + // Line has been marked as invalid + if (!$valid) { + break; + } + + // Filter line based on the configuration + if (preg_match($filter, $line) === 1) { + $valid = false; + break; + } + } + + // The line is valid, print it + if ($valid) { + $return .= $line."\n"; + } + } + + // Display the result of the command + echo $return; + } +} + +// End of execute.php diff --git a/includes/style.css b/includes/style.css new file mode 100644 index 0000000..caf7a34 --- /dev/null +++ b/includes/style.css @@ -0,0 +1,63 @@ +body { + font-size: 1em; + background-color: #FFFFFF; +} +.header_bar { + color: #000000; + text-align: center; + margin-bottom: 1em; +} +.footer_bar { + color: #000000; + font-size: 1.2em; + text-align: center; + margin-top: 1em; + width: 50%; + margin-left: auto; + margin-right: auto; +} +.logo { + text-align: center; + padding: 1%; +} +.content { + color: #000000; + font-size: 1.1em; + text-align: center; + width: 50%; + display: block; + margin-left: auto; + margin-right: auto; +} +.confirm { + width: 50%; + margin-left: auto; + margin-right: auto; +} +.loading { + margin-top: 1em; + width: 50%; + margin-left: auto; + margin-right: auto; +} +.reset { + width: 25%; + margin-left: auto; + margin-right: auto; +} +pre { + color: #FFFFFF; + background-color: #000000; + text-decoration: none; + width: 70%; + margin-left: auto; + margin-right: auto; +} +a { + color: #000000; + text-decoration: none; +} +a:hover { + color: #000000; + text-decoration: none; +} diff --git a/includes/utils.js b/includes/utils.js new file mode 100644 index 0000000..3bcde51 --- /dev/null +++ b/includes/utils.js @@ -0,0 +1,41 @@ +$(function() { + // hide the optional parameters field + $('.result').hide(); + $('.loading').hide(); + + // show and hide loading bar + $(document).ajaxStart(function() { + $('.loading').show(); + }); + $(document).ajaxStop(function() { + $('.loading').hide(); + }); + + // validate the parameters field + $('#input-params').on('input', function() { + var cmd = $('#query').val(); + }); + + // reset the view to the default one + $('#backhome').click(function() { + $('.content').slideDown(); + $('.result').slideUp(); + }); + + // send an ajax request that will get the info on the router + $('form').on('submit', function(e) { + e.preventDefault(); + + $.ajax({ + type: 'post', + url: 'execute.php', + data: $('form').serialize() + }).done(function(response, state, xhr) { + $('#output').text(response); + $('.content').slideUp(); + $('.result').slideDown(); + }).fail(function(xhr, state, error) { + alert('The following error occured: ' + state, error); + }); + }); +}); diff --git a/index.php b/index.php new file mode 100644 index 0000000..76774d0 --- /dev/null +++ b/index.php @@ -0,0 +1,111 @@ + + + + + + + + + <?php echo $config['frontpage']['title']; ?> + + + + + + +
+


+ '; + } + ?> +
+ +
+
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+
+
+
+
+ +
+

+    
+ +
+
+ + + + + + + + + + diff --git a/router.php b/router.php new file mode 100644 index 0000000..c1fb3c4 --- /dev/null +++ b/router.php @@ -0,0 +1,139 @@ +id = $id; + $this->host = $config['routers'][$id]['host']; + $this->type = $config['routers'][$id]['type']; + $this->auth = $config['routers'][$id]['auth']; + $this->requester = $requester; + } + + private function log_command($command) { + include 'config.php'; + + file_put_contents($config['misc']['logs'], $command, + FILE_APPEND | LOCK_EX); + } + + public function connect() { + include 'config.php'; + + switch ($this->auth) { + case 'ssh-password': + $this->connection = ssh2_connect($this->host, 22); + if (!$this->connection) { + throw new Exception('Cannot connect to router'); + } + + $user = $config['routers'][$this->id]['user']; + $pass = $config['routers'][$this->id]['pass']; + + if (!ssh2_auth_password($this->connection, $user, $pass)) { + throw new Exception('Bad login/password.'); + } + + break; + + default: + echo 'Unknown protocol for connection.'; + } + } + + public function execute_command($command) { + if ($this->connection == null) { + $this->connect(); + } + + if (!($stream = ssh2_exec($this->connection, $command))) { + throw new Exception('SSH command failed'); + } + + stream_set_blocking($stream, true); + + $data = ''; + while ($buf = fread($stream, 4096)) { + $data .= $buf; + } + fclose($stream); + + return $data; + } + + public function send_command($command, $parameters) { + switch ($command) { + case 'bgp': + if (($parameters != null) && (strlen($parameters) > 0)) { + $complete_command = 'show route '.$parameters.' | no-more'; + } else { + return 'An IP address (and only one) is required as destination.'; + } + break; + + case 'as-path-regex': + if (($parameters != null) && (strlen($parameters) > 0)) { + $complete_command = 'show route aspath-regex '.$parameters.' | no-more'; + } else { + return 'An AS-Path regex is required like ".*XXXX YYYY.*".'; + } + break; + + case 'as': + if (($parameters != null) && (strlen($parameters) > 0)) { + $complete_command = 'show route aspath-regex .*'.$parameters.'.* | no-more'; + } else { + return 'An AS number is required like XXXX.'; + } + break; + + case 'ping': + if (($parameters != null) && (strlen($parameters) > 0)) { + $complete_command = 'ping count 10 '.$parameters.' rapid'; + } else { + return 'An IP address (and only one) is required to ping a host.'; + } + break; + + case 'traceroute': + if (($parameters != null) && (strlen($parameters) > 0)) { + if (match_ipv4($parameters)) { + $complete_command = 'traceroute '.$parameters.' as-number-lookup'; + } else { + $complete_command = 'traceroute '.$parameters; + } + } else { + return 'An IP address is required to traceroute a host.'; + } + break; + + default: + return 'Command not supported.'; + } + + $this->log_command('['.date("Y-m-d H:i:s").'] [client: '. + $this->requester.'] '.$this->host.'> '.$complete_command."\n"); + return $this->execute_command($complete_command); + } + + public function disconnect() { + $this->execute_command('exit'); + $this->connection = null; + } + + public function __destruct() { + $this->disconnect(); + } +} + +// End of router.php -- cgit v1.2.3