source: admin/WebConsole/rest/ogagent.php @ 3dc4053

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-instalacion
Last change on this file since 3dc4053 was b6ec162, checked in by Ramón M. Gómez <ramongomez@…>, 6 years ago

#834: Remove all redundant PHP closing tags.

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