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
RevLine 
[e0b6a5e]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/**
[9ed6a67]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.
[e0b6a5e]19 * @note     Route: /ous/:ouid/labs/:labid/clients/:clntid/events, Method: POST
[9a39c75]20 * @param    integer ouid      OU identificator
21 * @param    integer imageid   image identificator
[e0b6a5e]22 * @param    integer labid     lab. identificator (optional)
23 */
[9a39c75]24$app->post('/ous/:ouid/images/:imageid/reserve', 'validateApiKey',
[e0b6a5e]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;
[6f17d76]32        $response = Array();
33        $ogagent = Array();
[e0b6a5e]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
[e7d47882]42SELECT adm.idadministradorcentro, entornos.ipserveradm, entornos.portserveradm,
[e0b6a5e]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)
[e7d47882]48 RIGHT JOIN administradores_centros AS adm USING(idcentro)
[e0b6a5e]49 RIGHT JOIN usuarios USING(idusuario)
50 RIGHT JOIN ordenadores_particiones USING(idordenador)
51 RIGHT JOIN imagenes USING(idimagen)
[6f17d76]52  LEFT JOIN remotepc ON remotepc.id=ordenadores.idordenador
[e7d47882]53 WHERE adm.idadministradorcentro = '$userid'
[9a39c75]54   AND aulas.idcentro = '$ouid' AND aulas.idaula LIKE '$labid' AND aulas.inremotepc = 1
55   AND imagenes.idimagen = '$imageid' AND imagenes.inremotepc = 1
[e0b6a5e]56 ORDER BY RAND() LIMIT 1;
57EOD;
58        $rs=new Recordset;
59        $rs->Comando=&$cmd;
60        if (!$rs->Abrir()) return(false);       // Error opening recordset.
[e7d47882]61        // Check if user is admin and client exists.
[e0b6a5e]62        $rs->Primero();
[e7d47882]63        if (checkAdmin($rs->campos["idadministradorcentro"]) and checkParameter($rs->campos["idordenador"])) {
[9a39c75]64                // Check if client is not reserved.
[6f17d76]65                if ($rs->campos["reserved"] !== 1) {
[9a39c75]66                        // Read query data.
67                        $serverip = $rs->campos["ipserveradm"];
68                        $serverport = $rs->campos["portserveradm"];
[6f17d76]69                        $clntid = $rs->campos["idordenador"];
70                        $clntip = $rs->campos["ip"];
71                        $clntmac = $rs->campos["mac"];
[9a39c75]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.
[6f17d76]78                        $ogagent[$clntip]['url'] = "https://$clntip:8000/opengnsys/status";
79                        $result = multiRequest($ogagent);
[357352b]80                        if (empty($result[$clntip]['data'])) {
[6f17d76]81                                // Client is off, send a boot command to ogAdmServer.
[9a39c75]82                                $reqframe = "nfn=Arrancar\r".
[6f17d76]83                                            "ido=$clntid\r".
84                                            "iph=$clntip\r".
85                                            "mac=$clntmac\r".
[9a39c75]86                                            "mar=1\r";
87                                sendCommand($serverip, $serverport, $reqframe, $values);
88                        } else {
[6f17d76]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);
[9a39c75]93                                // ... (check response)
[357352b]94                                //if ($result[$clntip]['code'] != 200) {
[9a39c75]95                                // ...
96                        }
[6f17d76]97                        // DB Transaction: mark choosed client as reserved and
[9ed6a67]98                        // create an init session command into client's actions queue.
[6f17d76]99                        $cmd->texto = "START TRANSACTION;";
100                        $cmd->Ejecutar();
101                        $timestamp = time();
[9a39c75]102                        $cmd->texto = <<<EOD
[e0b6a5e]103INSERT INTO remotepc
[9a39c75]104   SET id='$clntid', reserved=1, urllogin=NULL, urllogout=NULL
[6f17d76]105    ON DUPLICATE KEY UPDATE
[e0b6a5e]106       id=VALUES(id), reserved=VALUES(reserved),
[6f17d76]107       urllogin=VALUES(urllogin), urllogout=VALUES(urllogout);
108EOD;
109                        $t1 = $cmd->Ejecutar();
110                        $cmd->texto = <<<EOD
[e0b6a5e]111INSERT INTO acciones
112   SET tipoaccion=$EJECUCION_COMANDO,
113       idtipoaccion=9,
114       idcomando=9,
[6f17d76]115       parametros='nfn=IniciarSesion\rdsk=$disk\rpar=$part',
[e0b6a5e]116       descriaccion='RemotePC Session',
[6f17d76]117       idordenador=$clntid,
118       ip='$clntip',
119       sesion=$timestamp,
[e0b6a5e]120       fechahorareg=NOW(),
121       estado=$ACCION_INICIADA,
122       resultado=$ACCION_SINRESULTADO,
123       ambito=$AMBITO_ORDENADORES,
[6f17d76]124       idambito=$clntid,
125       restrambito='$clntip',
[e0b6a5e]126       idcentro=$ouid;
[9a39c75]127EOD;
[6f17d76]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.
[d7352ab]152                                $response["message"] = "Database error";
[6f17d76]153                                jsonResponse(400, $response);
154                                $app->stop();
155                        }
[9a39c75]156                } else {
157                        // Error message.
158                        $response["message"] = "Client is already reserved";
159                        jsonResponse(400, $response);
160                        $app->stop();
161                }
[9ed6a67]162        }
[e0b6a5e]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;
[6f17d76]179        $response = Array();
[e0b6a5e]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
[e7d47882]199SELECT adm.idadministradorcentro, ordenadores.idordenador, remotepc.*
[e0b6a5e]200  FROM remotepc
201 RIGHT JOIN ordenadores ON remotepc.id=ordenadores.idordenador
202  JOIN aulas USING(idaula)
[e7d47882]203 RIGHT JOIN administradores_centros AS adm USING(idcentro)
[e0b6a5e]204 RIGHT JOIN usuarios USING(idusuario)
[e7d47882]205 WHERE adm.idadministradorcentro = '$userid'
[e0b6a5e]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.
[e7d47882]212        // Check if user is admin and client exists.
[e0b6a5e]213        $rs->Primero();
[e7d47882]214        if (checkAdmin($rs->campos["idadministradorcentro"]) and checkParameter($rs->campos["idordenador"])) {
[e0b6a5e]215                // Check if client is reserved.
[a26527d]216                if ($rs->campos["reserved"] == 1) {
[9a39c75]217                        // Updating DB if client is reserved.
[d7352ab]218                        $cmd->CreaParametro("@urllogin", $urlLogin, 0);
219                        $cmd->CreaParametro("@urllogout", $urlLogout, 0);
[e0b6a5e]220                        $cmd->texto = <<<EOD
221INSERT INTO remotepc
[d7352ab]222   SET id='$clntid', reserved=1, urllogin=@urllogin, urllogout=@urllogout
[a26527d]223    ON DUPLICATE KEY UPDATE
[e0b6a5e]224       id=VALUES(id), reserved=VALUES(reserved),
[a26527d]225       urllogin=VALUES(urllogin), urllogout=VALUES(urllogout);
[9a39c75]226EOD;
[d7352ab]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                        }
[e0b6a5e]236                } else {
237                        // Error message.
[9a39c75]238                        $response["message"] = "Client is not reserved";
[e0b6a5e]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
[9a39c75]254$app->delete('/ous/:ouid/labs/:labid/clients/:clntid/unreserve', 'validateApiKey',
[9ed6a67]255    function($ouid, $labid, $clntid) {
[e0b6a5e]256        global $cmd;
257        global $userid;
[d7352ab]258        global $ACCION_INICIADA;
[9ed6a67]259        $response = Array();
260        $ogagent = Array();
[e0b6a5e]261
[9ed6a67]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
[e7d47882]268SELECT adm.idadministradorcentro, ordenadores.idordenador, ordenadores.ip, ordenadores.agentkey, remotepc.reserved
[9ed6a67]269  FROM remotepc
270 RIGHT JOIN ordenadores ON remotepc.id=ordenadores.idordenador
271  JOIN aulas USING(idaula)
[e7d47882]272 RIGHT JOIN administradores_centros AS adm USING(idcentro)
[9ed6a67]273 RIGHT JOIN usuarios USING(idusuario)
[e7d47882]274 WHERE adm.idadministradorcentro = '$userid'
[9ed6a67]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.
[e7d47882]281        // Check if user is admin and client exists.
[9ed6a67]282        $rs->Primero();
[e7d47882]283        if (checkAdmin($rs->campos["idadministradorcentro"]) and checkParameter($rs->campos["idordenador"])) {
[9ed6a67]284                // Check if client is reserved.
285                if ($rs->campos["reserved"] == 1) {
286                        // Read query data.
[40db2a3]287                        $clntip = $rs->campos["ip"];
[9ed6a67]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'
[d7352ab]303   AND estado = $ACCION_INICIADA;
[9ed6a67]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)
[357352b]313                        //if ($result[$clntip]['code'] != 200) {
[9ed6a67]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();
[e0b6a5e]324    }
325);
326
327?>
Note: See TracBrowser for help on using the repository browser.