source: admin/WebConsole/rest/ogagent.php @ 9f1274e

918-git-images-111dconfigfileconfigure-oglivegit-imageslgromero-new-oglivemainmaint-cronmount-efivarfsmultivmmultivm-ogboot-installerogClonningEngineogboot-installer-jenkinsoglive-ipv6test-python-scriptsticket-301ticket-50ticket-50-oldticket-577ticket-585ticket-611ticket-612ticket-693ticket-700ubu24tplunification2use-local-agent-oglivevarios-instalacionwebconsole3
Last change on this file since 9f1274e was e7d4fbb7, checked in by ramon <ramongomez@…>, 7 years ago

#730: Cambios menores:

  • Correcciones en comentarios.
  • Corrección al actualizar la BD.
  • Incluir curl en lista de paquetes a instalar en ogLive.
  • Volver a activar Wake-On-Lan al arrancar clientes.

git-svn-id: https://opengnsys.es/svn/branches/version1.1@5601 a21b9725-9963-47de-94b9-378ad31fedc9

  • Property mode set to 100644
File size: 10.0 KB
RevLine 
[b1735a7]1<?php
[8f3c218]2/**
3 * @file    ogagent.php
4 * @brief   OpenGnsys REST routes for OGAgent communications.
5 * @warning All input and output messages are formatted in JSON.
6 * @note    Some ideas are based on article "How to create REST API for Android app using PHP, Slim and MySQL" by Ravi Tamada, thanx.
7 * @license GNU GPLv3+
8 * @author  Ramón M. Gómez, ETSII Univ. Sevilla
9 * @version 1.1.0 - First version
10 * @date    2016-10-03
11 */
[b1735a7]12
13
14// OGAgent sessions log file.
15define('LOG_FILE', '/opt/opengnsys/log/ogagent.log');
16
[8f3c218]17// Function to write a line into log file.
18function writeLog($message = "") {
19        file_put_contents(LOG_FILE, date(DATE_ISO8601).": $message\n", FILE_APPEND);
20}
21
[a9140b0]22/**
23 * @brief    OGAgent notifies that its service is started on a client.
[21e5ee3]24 * @note     Route: /ogagent/started, Method: POST, Format: JSON
[a9140b0]25 * @param    string ip         IP address
26 * @param    string mac        MAC (Ethernet) address
[e7d4fbb7]27 * @param    string ostype     OS type (Linux, Windows, macOS)
[21e5ee3]28 * @param    string osversion  OS version
[a9140b0]29 * @param    string secret     random secret key to access client's REST API
30 * @return   Null string if OK, else error message.
31 */
[b1735a7]32$app->post('/ogagent/started',
33    function() use ($app) {
[2913439]34        global $cmd;
35        $osType = $osVersion = "none";
[b1735a7]36        try {
37                // Reading POST parameters in JSON format.
38                $input = json_decode($app->request()->getBody());
39                $ip = htmlspecialchars($input->ip);
40                $mac = htmlspecialchars($input->mac);
[31970a0]41                if (isset($input->ostype))  $osType = htmlspecialchars($input->ostype);
42                if (isset($input->osversion))  $osVersion = str_replace(",", ";", htmlspecialchars($input->osversion));
[21e5ee3]43                // Check sender agent type and IP address consistency (same as parameter value).
44                if (empty(preg_match('/^python-requests\//', $_SERVER['HTTP_USER_AGENT'])) or $ip !== $_SERVER['REMOTE_ADDR']) {
45                    throw new Exception("Bad OGAgent: ip=$ip, sender=".$_SERVER['REMOTE_ADDR'].", agent=".$_SERVER['HTTP_USER_AGENT']);
[a9140b0]46                }
[210ee85]47                // Client secret key for secure communications.
48                if (isset($input->secret)) {
[a9140b0]49                    // Check if secret key is valid (32 alphanumeric characters).
50                    if (! ctype_alnum($input->secret) or strlen($input->secret) !== 32) {
51                        throw new Exception("Bad secret key: ip=$ip, mac=$mac, os=$osType:$osVersion.");
52                    }
[210ee85]53                    // Store secret key in DB.
[f6045a5]54                    if (isset($input->secret))  $secret = htmlspecialchars($input->secret);
[8ba8712]55                    $cmd->texto = <<<EOD
56UPDATE ordenadores
57   SET agentkey='$secret'
58 WHERE ip='$ip' AND mac=UPPER(REPLACE('$mac', ':', ''))
59 LIMIT 1;
60EOD;
[a9140b0]61                    if ($cmd->Ejecutar() !== true or mysql_affected_rows() !== 1) {
62                        // DB access error or not updated.
63                        throw new Exception("Cannot store new secret key: ip=$ip, mac=$mac, os=$osType:$osVersion.");
[2913439]64                    }
[210ee85]65                } else {
66                    // Insecure agent exception.
[31970a0]67                    throw new Exception("Insecure OGAgent started: ip=$ip, mac=$mac, os=$osType:$osVersion.");
[210ee85]68                }
[b1735a7]69                // Default processing: log activity.
[8f3c218]70                writeLog("OGAgent started: ip=$ip, mac=$mac, os=$osType:$osVersion.");
[b1735a7]71                // Response.
[d98bc86]72                $response = "";
[b1735a7]73                jsonResponse(200, $response);
74        } catch (Exception $e) {
[8ba8712]75                // Communication error.
[b1735a7]76                $response["message"] = $e->getMessage();
[8f3c218]77                writeLog($app->request()->getResourceUri().": ERROR: ".$response["message"]);
[b1735a7]78                jsonResponse(400, $response);
79        }
80    }
81);
82
[21e5ee3]83/**
84 * @brief    OGAgent notifies that its service is stopped on client.
85 * @note     Route: /ogagent/stopped, Method: POST, Format: JSON
86 * @param    string ip         IP address
87 * @param    string mac        MAC (Ethernet) address
[e7d4fbb7]88 * @param    string ostype     OS type (Linux, Windows, macOS)
[21e5ee3]89 * @param    string osversion  OS version
90 * @return   Null string if OK, else error message.
91 */
[b1735a7]92$app->post('/ogagent/stopped',
93    function() use ($app) {
[2913439]94        $osType = $osVersion = "none";
[b1735a7]95        try {
96                // Reading POST parameters in JSON format.
97                $input = json_decode($app->request()->getBody());
98                $ip = htmlspecialchars($input->ip);
99                $mac = htmlspecialchars($input->mac);
[31970a0]100                if (isset($input->ostype))  $osType = htmlspecialchars($input->ostype);
101                if (isset($input->osversion))  $osVersion = str_replace(",", ";", htmlspecialchars($input->osversion));
[21e5ee3]102                // Check sender agent type and IP address consistency (same as parameter value).
103                if (empty(preg_match('/^python-requests\//', $_SERVER['HTTP_USER_AGENT'])) or $ip !== $_SERVER['REMOTE_ADDR']) {
104                    throw new Exception("Bad OGAgent: ip=$ip, sender=".$_SERVER['REMOTE_ADDR'].", agent=".$_SERVER['HTTP_USER_AGENT']);
[a9140b0]105                }
106                // May check if client is included in the server database?
[b1735a7]107                // Default processing: log activity.
[8f3c218]108                writeLog("OGAgent stopped: ip=$ip, mac=$mac, os=$osType:$osVersion.");
[b1735a7]109                // Response.
[d98bc86]110                $response = "";
[b1735a7]111                jsonResponse(200, $response);
112        } catch (Exception $e) {
[8ba8712]113                // Communication error.
[b1735a7]114                $response["message"] = $e->getMessage();
[8f3c218]115                writeLog($app->request()->getResourceUri().": ERROR: ".$response["message"]);
[b1735a7]116                jsonResponse(400, $response);
117        }
118    }
119);
120
[21e5ee3]121/**
122 * @brief    OGAgent notifies that an user logs in.
123 * @note     Route: /ogagent/loggedin, Method: POST, Format: JSON
124 * @param    string ip         IP address
125 * @param    string user       username
[e7d4fbb7]126 * @param    string language   session language
127 * @param    string ostype     OS type (Linux, Windows, macOS)
128 * @param    string osversion  OS version
[21e5ee3]129 * @return   Null string if OK, else error message.
130 */
[b1735a7]131$app->post('/ogagent/loggedin',
132    function() use ($app) {
[8f3c218]133        global $cmd;
134        $redirto = Array();
135        $result = Array();
136
[b1735a7]137        try {
138                // Reading POST parameters in JSON format.
139                $input = json_decode($app->request()->getBody());
140                $ip = htmlspecialchars($input->ip);
141                $user = htmlspecialchars($input->user);
[b46042c]142                $language = isset($input->language) ? substr($input->language, 0, strpos($input->language, "_")) : "";
143                if (isset($input->ostype))  $osType = htmlspecialchars($input->ostype);
144                if (isset($input->osversion))  $osVersion = str_replace(",", ";", htmlspecialchars($input->osversion));
[a9140b0]145                // Check sender IP address consistency (same as parameter value).
[21e5ee3]146                if (empty(preg_match('/^python-requests\//', $_SERVER['HTTP_USER_AGENT'])) or $ip !== $_SERVER['REMOTE_ADDR']) {
147                    throw new Exception("Bad OGAgent: ip=$ip, sender=".$_SERVER['REMOTE_ADDR'].", agent=".$_SERVER['HTTP_USER_AGENT']);
[a9140b0]148                }
[8f3c218]149                // Check if client is included in the server database.
[8ba8712]150                $cmd->CreaParametro("@ip", $ip, 0);
[8f3c218]151                $cmd->texto = <<<EOD
[9551d71]152SELECT ordenadores.idordenador, ordenadores.nombreordenador, remotepc.urllogin,
[8ba8712]153       remotepc.reserved > NOW() AS reserved
[8f3c218]154  FROM remotepc
155 RIGHT JOIN ordenadores ON remotepc.id=ordenadores.idordenador
[8ba8712]156 WHERE ordenadores.ip=@ip
[8f3c218]157 LIMIT 1;
158EOD;
159                $rs=new Recordset;
160                $rs->Comando=&$cmd;
161                if ($rs->Abrir()) {
162                        // Read query data.
163                        $rs->Primero();
[8ba8712]164                        $id = $rs->campos['idordenador'];
[8f3c218]165                        $redirto[0]['url'] = $rs->campos['urllogin'];
[8ba8712]166                        $reserved = $rs->campos['reserved'];
[8f3c218]167                        $rs->Cerrar();
[8ba8712]168                        if (!is_null($id)) {
169                                // Log activity, respond to client and continue processing.
[b46042c]170                                writeLog("User logged in: ip=$ip, user=$user, lang=$language, os=$osType:$osVersion.");
[8ba8712]171                                $response = "";
172                                jsonResponseNow(200, $response);
173                        } else {
174                                throw new Exception("Client is not in the database: ip=$ip, user=$user");
175                        }
176                        // Redirect notification to UDS server, if needed.
177                        if ($reserved == 1 and !is_null($redirto[0]['url'])) {
[030ee20]178                                $redirto[0]['get'] = $app->request()->getBody();
[8f3c218]179                                $result = multiRequest($redirto);
[b942930]180                                // ... (check response)
181                                //if ($result[0]['code'] != 200) {
182                                // ...
[b46042c]183                                // Updating user's session language for messages.
184                                $cmd->texto = <<<EOD
185UPDATE remotepc
186   SET language = '$language'
187 WHERE id = '$id';
188EOD;
189                                $cmd->Ejecutar();
[8f3c218]190                        }
[8ba8712]191                } else {
192                        throw new Exception("Database error");
[8f3c218]193                }
[b1735a7]194        } catch (Exception $e) {
[8ba8712]195                // Communication error.
[b1735a7]196                $response["message"] = $e->getMessage();
[8f3c218]197                writeLog($app->request()->getResourceUri().": ERROR: ".$response["message"]);
[b1735a7]198                jsonResponse(400, $response);
199        }
200    }
201);
202
[21e5ee3]203/**
204 * @brief    OGAgent notifies that an user logs out.
205 * @note     Route: /ogagent/loggedout, Method: POST, Format: JSON
206 * @param    string ip         IP address
207 * @param    string user       username
208 * @return   Null string if OK, else error message.
209 */
[b1735a7]210$app->post('/ogagent/loggedout',
211    function() use ($app) {
[b942930]212        global $cmd;
213        $redirto = Array();
214        $result = Array();
215
[b1735a7]216        try {
217                // Reading POST parameters in JSON format.
218                $input = json_decode($app->request()->getBody());
219                $ip = htmlspecialchars($input->ip);
220                $user = htmlspecialchars($input->user);
[21e5ee3]221                // Check sender agent type and IP address consistency (same as parameter value).
222                if (empty(preg_match('/^python-requests\//', $_SERVER['HTTP_USER_AGENT'])) or $ip !== $_SERVER['REMOTE_ADDR']) {
223                    throw new Exception("Bad OGAgent: ip=$ip, sender=".$_SERVER['REMOTE_ADDR'].", agent=".$_SERVER['HTTP_USER_AGENT']);
[a9140b0]224                }
[b942930]225                // Check if client is included in the server database.
[8ba8712]226                $cmd->CreaParametro("@ip", $ip, 0);
[b942930]227                $cmd->texto = <<<EOD
[17c28dc]228SELECT ordenadores.idordenador, ordenadores.nombreordenador, remotepc.urllogout,
[8ba8712]229       remotepc.reserved > NOW() AS reserved
[b942930]230  FROM remotepc
231 RIGHT JOIN ordenadores ON remotepc.id=ordenadores.idordenador
[8ba8712]232 WHERE ordenadores.ip=@ip
[b942930]233 LIMIT 1;
234EOD;
235                $rs=new Recordset;
236                $rs->Comando=&$cmd;
237                if ($rs->Abrir()) {
238                        // Read query data.
239                        $rs->Primero();
[8ba8712]240                        $id = $rs->campos['idordenador'];
[b942930]241                        $redirto[0]['url'] = $rs->campos['urllogout'];
[8ba8712]242                        $reserved = $rs->campos['reserved'];
[b942930]243                        $rs->Cerrar();
[8ba8712]244                        if (!is_null($id)) {
245                                // Log activity, respond to client and continue processing.
[4d06fd4b]246                                writeLog("User logged out: ip=$ip, user=$user.");
[8ba8712]247                                $response = "";
248                                jsonResponseNow(200, $response);
249                        } else {
250                                throw new Exception("Client is not in the database: ip=$ip, user=$user");
251                        }
252                        // Redirect notification to UDS server, if needed.
253                        if ($reserved == 1 and !is_null($redirto[0]['url'])) {
[030ee20]254                                $redirto[0]['get'] = $app->request()->getBody();
[b942930]255                                $result = multiRequest($redirto);
256                                // ... (check response)
257                                //if ($result[0]['code'] != 200) {
258                                // ...
259                        }
[8ba8712]260                } else {
261                        throw new Exception("Database error");
[b942930]262                }
[b1735a7]263        } catch (Exception $e) {
[8ba8712]264                // Communication error.
[b1735a7]265                $response["message"] = $e->getMessage();
[8f3c218]266                writeLog($app->request()->getResourceUri().": ERROR: ".$response["message"]);
[b1735a7]267                jsonResponse(400, $response);
268        }
269    }
270);
271
272?>
Note: See TracBrowser for help on using the repository browser.