source: admin/WebConsole/rest/remotepc.php @ 0dcf48a

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 0dcf48a was d7352ab, checked in by ramon <ramongomez@…>, 8 years ago

#708: Controlar inyección SQL en API REST.

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

  • Property mode set to 100644
File size: 10.9 KB
Line 
1<?php
2/**
3 * @file    remotepc.php
4 * @brief   OpenGnsys Server REST API consumed by UDS Server for Remote PC implementation.
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    2017-02-01
11 */
12
13
14// REST routes.
15
16/**
17 * @brief    Reserve a random client with an installed image and send a boot/reboot operation depending on its status.
18 * @warning  If "lab" parameter is specified, then choose a client from this lab.
19 * @note     Route: /ous/:ouid/labs/:labid/clients/:clntid/events, Method: POST
20 * @param    integer ouid      OU identificator
21 * @param    integer imageid   image identificator
22 * @param    integer labid     lab. identificator (optional)
23 */
24$app->post('/ous/:ouid/images/:imageid/reserve', 'validateApiKey',
25    function($ouid, $imageid) use ($app) {
26        global $cmd;
27        global $AMBITO_ORDENADORES;
28        global $EJECUCION_COMANDO;
29        global $ACCION_INICIADA;
30        global $ACCION_SINRESULTADO;
31        global $userid;
32        $response = Array();
33        $ogagent = Array();
34
35        // Checking parameters.
36        $ouid = htmlspecialchars($ouid);
37        $imageid = htmlspecialchars($imageid);
38        $labid = str_replace("%", "\%", htmlspecialchars($app->request()->params('lab')));
39        if (empty($labid))  $labid = '%';    // Clients in any lab.
40        // Randomly choose a client with image installed and get ogAdmServer data.
41        $cmd->texto = <<<EOD
42SELECT adm.idadministradorcentro, entornos.ipserveradm, entornos.portserveradm,
43       ordenadores.idordenador, ordenadores.ip, ordenadores.mac, ordenadores.agentkey,
44       ordenadores_particiones.numdisk, ordenadores_particiones.numpar,
45       aulas.idaula, aulas.idcentro, remotepc.reserved
46  FROM entornos, ordenadores
47  JOIN aulas USING(idaula)
48 RIGHT JOIN administradores_centros AS adm USING(idcentro)
49 RIGHT JOIN usuarios USING(idusuario)
50 RIGHT JOIN ordenadores_particiones USING(idordenador)
51 RIGHT JOIN imagenes USING(idimagen)
52  LEFT JOIN remotepc ON remotepc.id=ordenadores.idordenador
53 WHERE adm.idadministradorcentro = '$userid'
54   AND aulas.idcentro = '$ouid' AND aulas.idaula LIKE '$labid' AND aulas.inremotepc = 1
55   AND imagenes.idimagen = '$imageid' AND imagenes.inremotepc = 1
56 ORDER BY RAND() LIMIT 1;
57EOD;
58        $rs=new Recordset;
59        $rs->Comando=&$cmd;
60        if (!$rs->Abrir()) return(false);       // Error opening recordset.
61        // Check if user is admin and client exists.
62        $rs->Primero();
63        if (checkAdmin($rs->campos["idadministradorcentro"]) and checkParameter($rs->campos["idordenador"])) {
64                // Check if client is not reserved.
65                if ($rs->campos["reserved"] !== 1) {
66                        // Read query data.
67                        $serverip = $rs->campos["ipserveradm"];
68                        $serverport = $rs->campos["portserveradm"];
69                        $clntid = $rs->campos["idordenador"];
70                        $clntip = $rs->campos["ip"];
71                        $clntmac = $rs->campos["mac"];
72                        $agentkey = $rs->campos["agentkey"];
73                        $disk = $rs->campos["numdisk"];
74                        $part = $rs->campos["numpar"];
75                        $labid = $rs->campos["idaula"];
76                        $ouid = $rs->campos["idcentro"];
77                        // Check client's status.
78                        $ogagent[$clntip]['url'] = "https://$clntip:8000/opengnsys/status";
79                        $result = multiRequest($ogagent);
80                        if (empty($result[$clntip]['data'])) {
81                                // Client is off, send a boot command to ogAdmServer.
82                                $reqframe = "nfn=Arrancar\r".
83                                            "ido=$clntid\r".
84                                            "iph=$clntip\r".
85                                            "mac=$clntmac\r".
86                                            "mar=1\r";
87                                sendCommand($serverip, $serverport, $reqframe, $values);
88                        } else {
89                                // Client is on, send a reboot command to its OGAgent.
90                                $ogagent[$clntip]['url'] = "https://$clntip:8000/opengnsys/reboot";
91                                $ogagent[$clntip]['header'] = Array("Authorization: ".$agentkey);
92                                $result = multiRequest($ogagent);
93                                // ... (check response)
94                                //if ($result[$clntip]['code'] != 200) {
95                                // ...
96                        }
97                        // DB Transaction: mark choosed client as reserved and
98                        // create an init session command into client's actions queue.
99                        $cmd->texto = "START TRANSACTION;";
100                        $cmd->Ejecutar();
101                        $timestamp = time();
102                        $cmd->texto = <<<EOD
103INSERT INTO remotepc
104   SET id='$clntid', reserved=1, urllogin=NULL, urllogout=NULL
105    ON DUPLICATE KEY UPDATE
106       id=VALUES(id), reserved=VALUES(reserved),
107       urllogin=VALUES(urllogin), urllogout=VALUES(urllogout);
108EOD;
109                        $t1 = $cmd->Ejecutar();
110                        $cmd->texto = <<<EOD
111INSERT INTO acciones
112   SET tipoaccion=$EJECUCION_COMANDO,
113       idtipoaccion=9,
114       idcomando=9,
115       parametros='nfn=IniciarSesion\rdsk=$disk\rpar=$part',
116       descriaccion='RemotePC Session',
117       idordenador=$clntid,
118       ip='$clntip',
119       sesion=$timestamp,
120       fechahorareg=NOW(),
121       estado=$ACCION_INICIADA,
122       resultado=$ACCION_SINRESULTADO,
123       ambito=$AMBITO_ORDENADORES,
124       idambito=$clntid,
125       restrambito='$clntip',
126       idcentro=$ouid;
127EOD;
128                        $t2 = $cmd->Ejecutar();
129                        if ($t1 and $t2) {
130                                // Commit transaction on success.
131                                $cmd->texto = "COMMIT;";
132                                $cmd->Ejecutar();
133                                // Send init session command if client is booted on ogLive.
134                                $reqframe = "nfn=IniciarSesion\r".
135                                        "ido=$clntid\r".
136                                            "iph=$clntip\r".
137                                            "dsk=$disk\r".
138                                            "par=$part\r";
139                                sendCommand($serverip, $serverport, $reqframe, $values);
140                                // Compose JSON response.
141                                $response['id'] = $clntid;
142                                $response['ip'] = $clntip;
143                                $response['mac'] = $clntmac;
144                                $response['lab']['id'] = $labid;
145                                $response['ou']['id'] = $ouid;
146                                jsonResponse(200, $response);
147                        } else{
148                                // Roll-back transaction on DB error.
149                                $cmd->texto = "ROLLBACK;";
150                                $cmd->Ejecutar();
151                                // Error message.
152                                $response["message"] = "Database error";
153                                jsonResponse(400, $response);
154                                $app->stop();
155                        }
156                } else {
157                        // Error message.
158                        $response["message"] = "Client is already reserved";
159                        jsonResponse(400, $response);
160                        $app->stop();
161                }
162        }
163        $rs->Cerrar();
164    }
165);
166
167
168/**
169 * @brief    Store UDS server URLs to resend some events recieved from OGAgent.
170 * @note     Route: /ous/:ouid/labs/:labid/clients/:clntid/events, Method: POST
171 * @param    string urlLogin   URL to redirect login notification.
172 * @param    string urlLogout  URL to redirect logout notification.
173 * @warning  Events parameters will be stored in a new "remotepc" table.
174 */
175$app->post('/ous/:ouid/labs/:labid/clients/:clntid/events', 'validateApiKey',
176    function($ouid, $labid, $clntid) use ($app) {
177        global $cmd;
178        global $userid;
179        $response = Array();
180
181        // Reading JSON parameters.
182        try {
183                $input = json_decode($app->request()->getBody());
184                $urlLogin = htmlspecialchars($input->urlLogin);
185                $urlLogout = htmlspecialchars($input->urlLogout);
186        } catch (Exception $e) {
187                // Error message.
188                $response["message"] = $e->getMessage();
189                jsonResponse(400, $response);
190                $app->stop();
191        }
192
193        // Checking parameters.
194        $ouid = htmlspecialchars($ouid);
195        $labid = htmlspecialchars($labid);
196        $clntid = htmlspecialchars($clntid);
197        // Select client data for UDS compatibility.
198        $cmd->texto = <<<EOD
199SELECT adm.idadministradorcentro, ordenadores.idordenador, remotepc.*
200  FROM remotepc
201 RIGHT JOIN ordenadores ON remotepc.id=ordenadores.idordenador
202  JOIN aulas USING(idaula)
203 RIGHT JOIN administradores_centros AS adm USING(idcentro)
204 RIGHT JOIN usuarios USING(idusuario)
205 WHERE adm.idadministradorcentro = '$userid'
206   AND idcentro = '$ouid' AND aulas.idaula ='$labid'
207   AND ordenadores.idordenador = '$clntid';
208EOD;
209        $rs=new Recordset;
210        $rs->Comando=&$cmd;
211        if (!$rs->Abrir()) return(false);       // Error opening recordset.
212        // Check if user is admin and client exists.
213        $rs->Primero();
214        if (checkAdmin($rs->campos["idadministradorcentro"]) and checkParameter($rs->campos["idordenador"])) {
215                // Check if client is reserved.
216                if ($rs->campos["reserved"] == 1) {
217                        // Updating DB if client is reserved.
218                        $cmd->CreaParametro("@urllogin", $urlLogin, 0);
219                        $cmd->CreaParametro("@urllogout", $urlLogout, 0);
220                        $cmd->texto = <<<EOD
221INSERT INTO remotepc
222   SET id='$clntid', reserved=1, urllogin=@urllogin, urllogout=@urllogout
223    ON DUPLICATE KEY UPDATE
224       id=VALUES(id), reserved=VALUES(reserved),
225       urllogin=VALUES(urllogin), urllogout=VALUES(urllogout);
226EOD;
227                        if ($cmd->Ejecutar()) {
228                                // Confirm operation.
229                                jsonResponse(200, "");
230                        } else {
231                                // Error message.
232                                $response["message"] = "Database error";
233                                jsonResponse(400, $response);
234                                $app->stop();
235                        }
236                } else {
237                        // Error message.
238                        $response["message"] = "Client is not reserved";
239                        jsonResponse(400, $response);
240                        $app->stop();
241                }
242        }
243        $rs->Cerrar();
244    }
245);
246
247
248$app->post('/ous/:ouid/labs/:labid/clients/:clntid/session', 'validateApiKey',
249    function($ouid, $imageid) use ($app) {
250    }
251);
252
253
254$app->delete('/ous/:ouid/labs/:labid/clients/:clntid/unreserve', 'validateApiKey',
255    function($ouid, $labid, $clntid) {
256        global $cmd;
257        global $userid;
258        global $ACCION_INICIADA;
259        $response = Array();
260        $ogagent = Array();
261
262        // Checking parameters.
263        $ouid = htmlspecialchars($ouid);
264        $labid = htmlspecialchars($labid);
265        $clntid = htmlspecialchars($clntid);
266        // Select client data for UDS compatibility.
267        $cmd->texto = <<<EOD
268SELECT adm.idadministradorcentro, ordenadores.idordenador, ordenadores.ip, ordenadores.agentkey, remotepc.reserved
269  FROM remotepc
270 RIGHT JOIN ordenadores ON remotepc.id=ordenadores.idordenador
271  JOIN aulas USING(idaula)
272 RIGHT JOIN administradores_centros AS adm USING(idcentro)
273 RIGHT JOIN usuarios USING(idusuario)
274 WHERE adm.idadministradorcentro = '$userid'
275   AND idcentro = '$ouid' AND aulas.idaula ='$labid'
276   AND ordenadores.idordenador = '$clntid';
277EOD;
278        $rs=new Recordset;
279        $rs->Comando=&$cmd;
280        if (!$rs->Abrir()) return(false);       // Error opening recordset.
281        // Check if user is admin and client exists.
282        $rs->Primero();
283        if (checkAdmin($rs->campos["idadministradorcentro"]) and checkParameter($rs->campos["idordenador"])) {
284                // Check if client is reserved.
285                if ($rs->campos["reserved"] == 1) {
286                        // Read query data.
287                        $clntip = $rs->campos["ip"];
288                        $agentkey = $rs->campos["agentkey"];
289                        // DB Transaction: clear client reservation data and
290                        // remove pending boot commands from client's actions queue.
291                        $cmd->texto = "START TRANSACTION;";
292                        $cmd->Ejecutar();
293                        $cmd->texto = <<<EOD
294UPDATE remotepc
295   SET reserved=0, urllogin=NULL, urllogout=NULL
296 WHERE id='$clntid';
297EOD;
298                        $cmd->Ejecutar();
299                        $cmd->texto = <<<EOD
300DELETE FROM acciones
301 WHERE idordenador = '$clntid'
302   AND descriaccion = 'RemotePC Session'
303   AND estado = $ACCION_INICIADA;
304EOD;
305                        $cmd->Ejecutar();
306                        $cmd->texto = "COMMIT;";
307                        $cmd->Ejecutar();
308                        // Send a poweroff command to client's OGAgent.
309                        $ogagent[$clntip]['url'] = "https://$clntip:8000/opengnsys/poweroff";
310                        $ogagent[$clntip]['header'] = Array("Authorization: ".$agentkey);
311                        $result = multiRequest($ogagent);
312                        // ... (check response)
313                        //if ($result[$clntip]['code'] != 200) {
314                        // ...
315                        // Confirm operation.
316                        jsonResponse(200, "");
317                } else {
318                        // Error message.
319                        $response["message"] = "Client is not reserved";
320                        jsonResponse(400, $response);
321                }
322        }
323        $rs->Cerrar();
324    }
325);
326
327?>
Note: See TracBrowser for help on using the repository browser.