source: admin/WebConsole/rest/ogagent.php @ 7d8c134

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 7d8c134 was 4d06fd4b, checked in by ramon <ramongomez@…>, 7 years ago

#718: Adaptar la API REST que atiende notificaciones de logout de OGAgent.

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

  • Property mode set to 100644
File size: 9.9 KB
Line 
1<?php
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 */
12
13
14// OGAgent sessions log file.
15define('LOG_FILE', '/opt/opengnsys/log/ogagent.log');
16
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
22/**
23 * @brief    OGAgent notifies that its service is started on a client.
24 * @note     Route: /ogagent/started, Method: POST, Format: JSON
25 * @param    string ip         IP address
26 * @param    string mac        MAC (Ethernet) address
27 * @param    string ostype     OS type (Linux, Windows)
28 * @param    string osversion  OS version
29 * @param    string secret     random secret key to access client's REST API
30 * @return   Null string if OK, else error message.
31 */
32$app->post('/ogagent/started',
33    function() use ($app) {
34        global $cmd;
35        $osType = $osVersion = "none";
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);
41                if (isset($input->ostype))  $osType = htmlspecialchars($input->ostype);
42                if (isset($input->osversion))  $osVersion = str_replace(",", ";", htmlspecialchars($input->osversion));
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']);
46                }
47                // Client secret key for secure communications.
48                if (isset($input->secret)) {
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                    }
53                    // Store secret key in DB.
54                    if (isset($input->secret))  $secret = htmlspecialchars($input->secret);
55                    $cmd->texto = <<<EOD
56UPDATE ordenadores
57   SET agentkey='$secret'
58 WHERE ip='$ip' AND mac=UPPER(REPLACE('$mac', ':', ''))
59 LIMIT 1;
60EOD;
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.");
64                    }
65                } else {
66                    // Insecure agent exception.
67                    throw new Exception("Insecure OGAgent started: ip=$ip, mac=$mac, os=$osType:$osVersion.");
68                }
69                // Default processing: log activity.
70                writeLog("OGAgent started: ip=$ip, mac=$mac, os=$osType:$osVersion.");
71                // Response.
72                $response = "";
73                jsonResponse(200, $response);
74        } catch (Exception $e) {
75                // Communication error.
76                $response["message"] = $e->getMessage();
77                writeLog($app->request()->getResourceUri().": ERROR: ".$response["message"]);
78                jsonResponse(400, $response);
79        }
80    }
81);
82
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
88 * @param    string ostype     OS type (Linux, Windows)
89 * @param    string osversion  OS version
90 * @return   Null string if OK, else error message.
91 */
92$app->post('/ogagent/stopped',
93    function() use ($app) {
94        $osType = $osVersion = "none";
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);
100                if (isset($input->ostype))  $osType = htmlspecialchars($input->ostype);
101                if (isset($input->osversion))  $osVersion = str_replace(",", ";", htmlspecialchars($input->osversion));
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']);
105                }
106                // May check if client is included in the server database?
107                // Default processing: log activity.
108                writeLog("OGAgent stopped: ip=$ip, mac=$mac, os=$osType:$osVersion.");
109                // Response.
110                $response = "";
111                jsonResponse(200, $response);
112        } catch (Exception $e) {
113                // Communication error.
114                $response["message"] = $e->getMessage();
115                writeLog($app->request()->getResourceUri().": ERROR: ".$response["message"]);
116                jsonResponse(400, $response);
117        }
118    }
119);
120
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
126 * @return   Null string if OK, else error message.
127 */
128$app->post('/ogagent/loggedin',
129    function() use ($app) {
130        global $cmd;
131        $redirto = Array();
132        $result = Array();
133
134        try {
135                // Reading POST parameters in JSON format.
136                $input = json_decode($app->request()->getBody());
137                $ip = htmlspecialchars($input->ip);
138                $user = htmlspecialchars($input->user);
139                $language = isset($input->language) ? substr($input->language, 0, strpos($input->language, "_")) : "";
140                if (isset($input->ostype))  $osType = htmlspecialchars($input->ostype);
141                if (isset($input->osversion))  $osVersion = str_replace(",", ";", htmlspecialchars($input->osversion));
142                // Check sender IP address consistency (same as parameter value).
143                if (empty(preg_match('/^python-requests\//', $_SERVER['HTTP_USER_AGENT'])) or $ip !== $_SERVER['REMOTE_ADDR']) {
144                    throw new Exception("Bad OGAgent: ip=$ip, sender=".$_SERVER['REMOTE_ADDR'].", agent=".$_SERVER['HTTP_USER_AGENT']);
145                }
146                // Check if client is included in the server database.
147                $cmd->CreaParametro("@ip", $ip, 0);
148                $cmd->texto = <<<EOD
149SELECT ordenadores.idordenador, ordenadores.nombreordenador, remotepc.urllogin,
150       remotepc.reserved > NOW() AS reserved
151  FROM remotepc
152 RIGHT JOIN ordenadores ON remotepc.id=ordenadores.idordenador
153 WHERE ordenadores.ip=@ip
154 LIMIT 1;
155EOD;
156                $rs=new Recordset;
157                $rs->Comando=&$cmd;
158                if ($rs->Abrir()) {
159                        // Read query data.
160                        $rs->Primero();
161                        $id = $rs->campos['idordenador'];
162                        $redirto[0]['url'] = $rs->campos['urllogin'];
163                        $reserved = $rs->campos['reserved'];
164                        $rs->Cerrar();
165                        if (!is_null($id)) {
166                                // Log activity, respond to client and continue processing.
167                                writeLog("User logged in: ip=$ip, user=$user, lang=$language, os=$osType:$osVersion.");
168                                $response = "";
169                                jsonResponseNow(200, $response);
170                        } else {
171                                throw new Exception("Client is not in the database: ip=$ip, user=$user");
172                        }
173                        // Redirect notification to UDS server, if needed.
174                        if ($reserved == 1 and !is_null($redirto[0]['url'])) {
175                                $redirto[0]['get'] = $app->request()->getBody();
176                                $result = multiRequest($redirto);
177                                // ... (check response)
178                                //if ($result[0]['code'] != 200) {
179                                // ...
180                                // Updating user's session language for messages.
181                                $cmd->texto = <<<EOD
182UPDATE remotepc
183   SET language = '$language'
184 WHERE id = '$id';
185EOD;
186                                $cmd->Ejecutar();
187                        }
188                } else {
189                        throw new Exception("Database error");
190                }
191        } catch (Exception $e) {
192                // Communication error.
193                $response["message"] = $e->getMessage();
194                writeLog($app->request()->getResourceUri().": ERROR: ".$response["message"]);
195                jsonResponse(400, $response);
196        }
197    }
198);
199
200/**
201 * @brief    OGAgent notifies that an user logs out.
202 * @note     Route: /ogagent/loggedout, Method: POST, Format: JSON
203 * @param    string ip         IP address
204 * @param    string user       username
205 * @return   Null string if OK, else error message.
206 */
207$app->post('/ogagent/loggedout',
208    function() use ($app) {
209        global $cmd;
210        $redirto = Array();
211        $result = Array();
212
213        try {
214                // Reading POST parameters in JSON format.
215                $input = json_decode($app->request()->getBody());
216                $ip = htmlspecialchars($input->ip);
217                $user = htmlspecialchars($input->user);
218                // Check sender agent type and IP address consistency (same as parameter value).
219                if (empty(preg_match('/^python-requests\//', $_SERVER['HTTP_USER_AGENT'])) or $ip !== $_SERVER['REMOTE_ADDR']) {
220                    throw new Exception("Bad OGAgent: ip=$ip, sender=".$_SERVER['REMOTE_ADDR'].", agent=".$_SERVER['HTTP_USER_AGENT']);
221                }
222                // Check if client is included in the server database.
223                $cmd->CreaParametro("@ip", $ip, 0);
224                $cmd->texto = <<<EOD
225SELECT ordenadores.idordenador, ordenadores.nombreordenador, remotepc.urllogout,
226       remotepc.reserved > NOW() AS reserved
227  FROM remotepc
228 RIGHT JOIN ordenadores ON remotepc.id=ordenadores.idordenador
229 WHERE ordenadores.ip=@ip
230 LIMIT 1;
231EOD;
232                $rs=new Recordset;
233                $rs->Comando=&$cmd;
234                if ($rs->Abrir()) {
235                        // Read query data.
236                        $rs->Primero();
237                        $id = $rs->campos['idordenador'];
238                        $redirto[0]['url'] = $rs->campos['urllogout'];
239                        $reserved = $rs->campos['reserved'];
240                        $rs->Cerrar();
241                        if (!is_null($id)) {
242                                // Log activity, respond to client and continue processing.
243                                writeLog("User logged out: ip=$ip, user=$user.");
244                                $response = "";
245                                jsonResponseNow(200, $response);
246                        } else {
247                                throw new Exception("Client is not in the database: ip=$ip, user=$user");
248                        }
249                        // Redirect notification to UDS server, if needed.
250                        if ($reserved == 1 and !is_null($redirto[0]['url'])) {
251                                $redirto[0]['get'] = $app->request()->getBody();
252                                $result = multiRequest($redirto);
253                                // ... (check response)
254                                //if ($result[0]['code'] != 200) {
255                                // ...
256                        }
257                } else {
258                        throw new Exception("Database error");
259                }
260        } catch (Exception $e) {
261                // Communication error.
262                $response["message"] = $e->getMessage();
263                writeLog($app->request()->getResourceUri().": ERROR: ".$response["message"]);
264                jsonResponse(400, $response);
265        }
266    }
267);
268
269?>
Note: See TracBrowser for help on using the repository browser.