summaryrefslogtreecommitdiffstats
path: root/admin/WebConsole/rest/ogagent.php
diff options
context:
space:
mode:
Diffstat (limited to 'admin/WebConsole/rest/ogagent.php')
-rw-r--r--admin/WebConsole/rest/ogagent.php272
1 files changed, 272 insertions, 0 deletions
diff --git a/admin/WebConsole/rest/ogagent.php b/admin/WebConsole/rest/ogagent.php
new file mode 100644
index 00000000..65c6cf64
--- /dev/null
+++ b/admin/WebConsole/rest/ogagent.php
@@ -0,0 +1,272 @@
+<?php
+/**
+ * @file ogagent.php
+ * @brief OpenGnsys REST routes for OGAgent communications.
+ * @warning All input and output messages are formatted in JSON.
+ * @note Some ideas are based on article "How to create REST API for Android app using PHP, Slim and MySQL" by Ravi Tamada, thanx.
+ * @license GNU GPLv3+
+ * @author Ramón M. Gómez, ETSII Univ. Sevilla
+ * @version 1.1.0 - First version
+ * @date 2016-10-03
+ */
+
+
+// OGAgent sessions log file.
+define('LOG_FILE', '/opt/opengnsys/log/ogagent.log');
+
+// Function to write a line into log file.
+function writeLog($message = "") {
+ file_put_contents(LOG_FILE, date(DATE_ISO8601).": $message\n", FILE_APPEND);
+}
+
+/**
+ * @brief OGAgent notifies that its service is started on a client.
+ * @note Route: /ogagent/started, Method: POST, Format: JSON
+ * @param string ip IP address
+ * @param string mac MAC (Ethernet) address
+ * @param string ostype OS type (Linux, Windows, macOS)
+ * @param string osversion OS version
+ * @param string secret random secret key to access client's REST API
+ * @return Null string if OK, else error message.
+ */
+$app->post('/ogagent/started',
+ function() use ($app) {
+ global $cmd;
+ $osType = $osVersion = "none";
+ try {
+ // Reading POST parameters in JSON format.
+ $input = json_decode($app->request()->getBody());
+ $ip = htmlspecialchars($input->ip);
+ $mac = htmlspecialchars($input->mac);
+ if (isset($input->ostype)) $osType = htmlspecialchars($input->ostype);
+ if (isset($input->osversion)) $osVersion = str_replace(",", ";", htmlspecialchars($input->osversion));
+ // Check sender agent type and IP address consistency (same as parameter value).
+ if (empty(preg_match('/^python-requests\//', $_SERVER['HTTP_USER_AGENT'])) or $ip !== $_SERVER['REMOTE_ADDR']) {
+ throw new Exception("Bad OGAgent: ip=$ip, sender=".$_SERVER['REMOTE_ADDR'].", agent=".$_SERVER['HTTP_USER_AGENT']);
+ }
+ // Client secret key for secure communications.
+ if (isset($input->secret)) {
+ // Check if secret key is valid (32 alphanumeric characters).
+ if (! ctype_alnum($input->secret) or strlen($input->secret) !== 32) {
+ throw new Exception("Bad secret key: ip=$ip, mac=$mac, os=$osType:$osVersion.");
+ }
+ // Store secret key in DB.
+ if (isset($input->secret)) $secret = htmlspecialchars($input->secret);
+ $cmd->texto = <<<EOD
+UPDATE ordenadores
+ SET agentkey='$secret'
+ WHERE ip='$ip' AND mac=UPPER(REPLACE('$mac', ':', ''))
+ LIMIT 1;
+EOD;
+ if ($cmd->Ejecutar() !== true or mysql_affected_rows() !== 1) {
+ // DB access error or not updated.
+ throw new Exception("Cannot store new secret key: ip=$ip, mac=$mac, os=$osType:$osVersion.");
+ }
+ } else {
+ // Insecure agent exception.
+ throw new Exception("Insecure OGAgent started: ip=$ip, mac=$mac, os=$osType:$osVersion.");
+ }
+ // Default processing: log activity.
+ writeLog("OGAgent started: ip=$ip, mac=$mac, os=$osType:$osVersion.");
+ // Response.
+ $response = "";
+ jsonResponse(200, $response);
+ } catch (Exception $e) {
+ // Communication error.
+ $response["message"] = $e->getMessage();
+ writeLog($app->request()->getResourceUri().": ERROR: ".$response["message"]);
+ jsonResponse(400, $response);
+ }
+ }
+);
+
+/**
+ * @brief OGAgent notifies that its service is stopped on client.
+ * @note Route: /ogagent/stopped, Method: POST, Format: JSON
+ * @param string ip IP address
+ * @param string mac MAC (Ethernet) address
+ * @param string ostype OS type (Linux, Windows, macOS)
+ * @param string osversion OS version
+ * @return Null string if OK, else error message.
+ */
+$app->post('/ogagent/stopped',
+ function() use ($app) {
+ $osType = $osVersion = "none";
+ try {
+ // Reading POST parameters in JSON format.
+ $input = json_decode($app->request()->getBody());
+ $ip = htmlspecialchars($input->ip);
+ $mac = htmlspecialchars($input->mac);
+ if (isset($input->ostype)) $osType = htmlspecialchars($input->ostype);
+ if (isset($input->osversion)) $osVersion = str_replace(",", ";", htmlspecialchars($input->osversion));
+ // Check sender agent type and IP address consistency (same as parameter value).
+ if (empty(preg_match('/^python-requests\//', $_SERVER['HTTP_USER_AGENT'])) or $ip !== $_SERVER['REMOTE_ADDR']) {
+ throw new Exception("Bad OGAgent: ip=$ip, sender=".$_SERVER['REMOTE_ADDR'].", agent=".$_SERVER['HTTP_USER_AGENT']);
+ }
+ // May check if client is included in the server database?
+ // Default processing: log activity.
+ writeLog("OGAgent stopped: ip=$ip, mac=$mac, os=$osType:$osVersion.");
+ // Response.
+ $response = "";
+ jsonResponse(200, $response);
+ } catch (Exception $e) {
+ // Communication error.
+ $response["message"] = $e->getMessage();
+ writeLog($app->request()->getResourceUri().": ERROR: ".$response["message"]);
+ jsonResponse(400, $response);
+ }
+ }
+);
+
+/**
+ * @brief OGAgent notifies that an user logs in.
+ * @note Route: /ogagent/loggedin, Method: POST, Format: JSON
+ * @param string ip IP address
+ * @param string user username
+ * @param string language session language
+ * @param string ostype OS type (Linux, Windows, macOS)
+ * @param string osversion OS version
+ * @return Null string if OK, else error message.
+ */
+$app->post('/ogagent/loggedin',
+ function() use ($app) {
+ global $cmd;
+ $redirto = Array();
+ $result = Array();
+
+ try {
+ // Reading POST parameters in JSON format.
+ $input = json_decode($app->request()->getBody());
+ $ip = htmlspecialchars($input->ip);
+ $user = htmlspecialchars($input->user);
+ $language = isset($input->language) ? substr($input->language, 0, strpos($input->language, "_")) : "";
+ if (isset($input->ostype)) $osType = htmlspecialchars($input->ostype);
+ if (isset($input->osversion)) $osVersion = str_replace(",", ";", htmlspecialchars($input->osversion));
+ // Check sender IP address consistency (same as parameter value).
+ if (empty(preg_match('/^python-requests\//', $_SERVER['HTTP_USER_AGENT'])) or $ip !== $_SERVER['REMOTE_ADDR']) {
+ throw new Exception("Bad OGAgent: ip=$ip, sender=".$_SERVER['REMOTE_ADDR'].", agent=".$_SERVER['HTTP_USER_AGENT']);
+ }
+ // Check if client is included in the server database.
+ $cmd->CreaParametro("@ip", $ip, 0);
+ $cmd->texto = <<<EOD
+SELECT ordenadores.idordenador, ordenadores.nombreordenador, remotepc.urllogin,
+ remotepc.reserved > NOW() AS reserved
+ FROM remotepc
+ RIGHT JOIN ordenadores ON remotepc.id=ordenadores.idordenador
+ WHERE ordenadores.ip=@ip
+ LIMIT 1;
+EOD;
+ $rs=new Recordset;
+ $rs->Comando=&$cmd;
+ if ($rs->Abrir()) {
+ // Read query data.
+ $rs->Primero();
+ $id = $rs->campos['idordenador'];
+ $redirto[0]['url'] = $rs->campos['urllogin'];
+ $reserved = $rs->campos['reserved'];
+ $rs->Cerrar();
+ if (!is_null($id)) {
+ // Log activity, respond to client and continue processing.
+ writeLog("User logged in: ip=$ip, user=$user, lang=$language, os=$osType:$osVersion.");
+ $response = "";
+ jsonResponseNow(200, $response);
+ } else {
+ throw new Exception("Client is not in the database: ip=$ip, user=$user");
+ }
+ // Redirect notification to UDS server, if needed.
+ if ($reserved == 1 and !is_null($redirto[0]['url'])) {
+ $redirto[0]['get'] = $app->request()->getBody();
+ $result = multiRequest($redirto);
+ // ... (check response)
+ //if ($result[0]['code'] != 200) {
+ // ...
+ // Updating user's session language for messages.
+ $cmd->texto = <<<EOD
+UPDATE remotepc
+ SET language = '$language'
+ WHERE id = '$id';
+EOD;
+ $cmd->Ejecutar();
+ }
+ } else {
+ throw new Exception("Database error");
+ }
+ } catch (Exception $e) {
+ // Communication error.
+ $response["message"] = $e->getMessage();
+ writeLog($app->request()->getResourceUri().": ERROR: ".$response["message"]);
+ jsonResponse(400, $response);
+ }
+ }
+);
+
+/**
+ * @brief OGAgent notifies that an user logs out.
+ * @note Route: /ogagent/loggedout, Method: POST, Format: JSON
+ * @param string ip IP address
+ * @param string user username
+ * @return Null string if OK, else error message.
+ */
+$app->post('/ogagent/loggedout',
+ function() use ($app) {
+ global $cmd;
+ $redirto = Array();
+ $result = Array();
+
+ try {
+ // Reading POST parameters in JSON format.
+ $input = json_decode($app->request()->getBody());
+ $ip = htmlspecialchars($input->ip);
+ $user = htmlspecialchars($input->user);
+ // Check sender agent type and IP address consistency (same as parameter value).
+ if (empty(preg_match('/^python-requests\//', $_SERVER['HTTP_USER_AGENT'])) or $ip !== $_SERVER['REMOTE_ADDR']) {
+ throw new Exception("Bad OGAgent: ip=$ip, sender=".$_SERVER['REMOTE_ADDR'].", agent=".$_SERVER['HTTP_USER_AGENT']);
+ }
+ // Check if client is included in the server database.
+ $cmd->CreaParametro("@ip", $ip, 0);
+ $cmd->texto = <<<EOD
+SELECT ordenadores.idordenador, ordenadores.nombreordenador, remotepc.urllogout,
+ remotepc.reserved > NOW() AS reserved
+ FROM remotepc
+ RIGHT JOIN ordenadores ON remotepc.id=ordenadores.idordenador
+ WHERE ordenadores.ip=@ip
+ LIMIT 1;
+EOD;
+ $rs=new Recordset;
+ $rs->Comando=&$cmd;
+ if ($rs->Abrir()) {
+ // Read query data.
+ $rs->Primero();
+ $id = $rs->campos['idordenador'];
+ $redirto[0]['url'] = $rs->campos['urllogout'];
+ $reserved = $rs->campos['reserved'];
+ $rs->Cerrar();
+ if (!is_null($id)) {
+ // Log activity, respond to client and continue processing.
+ writeLog("User logged out: ip=$ip, user=$user.");
+ $response = "";
+ jsonResponseNow(200, $response);
+ } else {
+ throw new Exception("Client is not in the database: ip=$ip, user=$user");
+ }
+ // Redirect notification to UDS server, if needed.
+ if ($reserved == 1 and !is_null($redirto[0]['url'])) {
+ $redirto[0]['get'] = $app->request()->getBody();
+ $result = multiRequest($redirto);
+ // ... (check response)
+ //if ($result[0]['code'] != 200) {
+ // ...
+ }
+ } else {
+ throw new Exception("Database error");
+ }
+ } catch (Exception $e) {
+ // Communication error.
+ $response["message"] = $e->getMessage();
+ writeLog($app->request()->getResourceUri().": ERROR: ".$response["message"]);
+ jsonResponse(400, $response);
+ }
+ }
+);
+
+?>