im so happy the tcp comms just worked ok
[ga4php.git] / authserver / authd / authd.php
1 <?php
2
3 // TODO: SO MUCH ERROR CHECKING ITS NOT FUNNY
4
5
6 // get out master library for ga4php
7 require_once("../lib/lib.php");
8
9         
10 //exit(0);
11 // first we want to fork into the background like all good daemons should
12 //$pid = pcntl_fork();
13
14
15 // uncomment this bit and comment the fork above to stop it going into the background
16 $pid = 0;
17
18 if($pid == -1) {
19         
20 } else if($pid) {
21         // i am the parent, i shall leave
22         //echo "i am a parent, i leave\n";
23         exit(0);
24 } else {
25         // here is where i need to swithc to TCP network protocol stuff
26         // i must bind 127.0.0.1 though.
27         // what i want to happen is this:
28         // 1) server receives connection
29         // 2) server forks off process to process connection
30         // 3) main server continues.
31         // a forked process thingy should be fully self contained and capable of dealing
32         // with "problems", i.e. the parent doesnt want to have to clean up children
33         
34         // Here goes the tcp equivalent
35         global $TCP_PORT_NUMBER;
36         $res = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
37         socket_bind($res, "127.0.0.1", $TCP_PORT_NUMBER);
38         socket_listen($res);
39
40         while(true) {
41                 $data_socket = socket_accept($res);
42                 // now i fork
43                 $forked = pcntl_fork();
44                 
45                 // TODO: DEAL WITH THIS PROPERLY
46                 if($forked == -1) {
47                         echo "Failed to fork\n";
48                 } else if(!$forked) {
49                         // I am the child, i process the request
50                         // all the shit down below goes in here
51                         $recvd = "";
52                         $continue = true;
53                         while($continue) {
54                                 $size = socket_recv($data_socket, $recvd_a, 1024, 0);
55                                 $recvd .= $recvd_a;
56                                 if(preg_match("/.*\:EOD$/", $recvd)) {
57                                         // we have a full string... break out
58                                         $continue = false;
59                                         break;
60                                 }
61                         }
62
63                         $myga = new gaasGA();
64                         
65                         $xps = explode(":", $recvd);
66                         $component =  unserialize(base64_decode($xps[1]));
67                         $msg_type = $component["type"];
68                         $msg = $component["data"];
69
70                         //echo "I now have a message of $msg_type\n";
71                         //echo "with data:\n";
72                         //print_r($msg);
73                         //echo "eof\n";
74                         // the switch should now set a $data_returned value that gets bundled up and sent back to the client
75                         // HERES WHERE THE SWITCH GOES
76                         // ******
77                         switch($msg_type) {
78                                 case MSG_GET_RADIUS_CLIENTS:
79                                         $sql = "select * from radclients";
80                                         $dbo = getDatabase();
81                                         $res = $dbo->query($sql);
82                                         $clients = "";
83                                         $i=0;
84                                         foreach($res as $row) {
85                                                 //              $sql = 'CREATE TABLE "radclients" ("rad_id" INTEGER PRIMARY KEY AUTOINCREMENT,"rad_name" TEXT, "rad_ip" TEXT, "rad_secret" TEXT, "rad_desc" TEXT);';
86                                                 $clients[$i]["name"] = $row["rad_name"];
87                                                 $clients[$i]["ip"] = $row["rad_ip"];
88                                                 $clients[$i]["secret"] = $row["rad_secret"];
89                                                 $clients[$i]["desc"] = $row["rad_desc"];
90                                                 $i++;
91                                         }
92                                         $data_returned = $clients;
93                                         break;
94                                 case MSG_REMOVE_RADIUS_CLIENT:
95                                         // it should send us a client by rad_name - doesnt work yet
96                                         $client = $msg["clientname"];
97                                         $sql = "delete from radclients where rad_name='$client'";
98                                         $dbo = getDatabase();
99                                         $res = $dbo->query($sql);
100                                         updateRadius();
101                                         $data_returned = true;
102                                         break;
103                                 case MSG_ADD_RADIUS_CLIENT:
104                                         //echo "in addradclient\n";
105                                         $client = $msg["clientname"];
106                                         $clientsecret = $msg["clientsecret"];
107                                         $clientip = $msg["clientip"];
108                                         $clientdesc = $msg["clientdescription"];
109                                         $dbo = getDatabase();
110                                         
111                                         // check for existing clients with same name
112                                         $sql = "select * from radclients where rad_name='$client'";
113                                         //echo "doing select, $sql\n";
114                                         $res = $dbo->query($sql);
115                                         if($res->fetchColumn() > 0) {
116                                                 $data_returned = "name";
117                                                         
118                                         } else {
119                                                 // check for existing clients with same ip
120                                                 $sql = "select * from radclients where rad_ip='$clientip'";
121                                                 $res = $dbo->query($sql);
122                                                 //echo "doing select, $sql\n";
123                                                 if($res->fetchColumn() > 0) {
124                                                         $data_returned = "ip";
125                                                                         
126                                                 } else {
127                                                         $sql = "insert into radclients values (NULL, '$client', '$clientip', '$clientsecret', '$clientdesc')";
128                                                         $res = $dbo->query($sql);
129                                                         updateRadius();
130                                                         $data_returned = true;
131                                                         break;
132                                                 }
133                                         }
134                                         break;
135                                 case MSG_DELETE_USER_TOKEN:
136                                         $username = $msg["username"];
137                                         
138                                         $sql = "select users_otk from users where users_username='$username'";
139                                         $dbo = getDatabase();
140                                         $res = $dbo->query($sql);
141                                         $otkid = "";
142                                         foreach($res as $row) {
143                                                 $otkid = $row["users_otk"];
144                                         }
145                                         if($otkid!="") {
146                                                 global $BASE_DIR;
147                                                 unlink("$BASE_DIR/authserver/authd/otks/$otkid.png");
148                                         }
149                                         
150                                         $sql = "update users set users_tokendata='',users_otk='' where users_username='$username'";
151                                         $dbo = getDatabase();
152                                         $res = $dbo->query($sql);
153                                         
154                                         $data_returned = true;
155                                         break;
156                                 case MSG_AUTH_USER_TOKEN:
157                                         //echo "Call to auth user token\n";
158                                         // minimal checking, we leav it up to authenticateUser to do the real
159                                         // checking
160                                         if(!isset($msg["username"])) $msg["username"] = "";
161                                         if(!isset($msg["passcode"])) $msg["passcode"] = "";
162                                         $username = $msg["username"];
163                                         $passcode = $msg["passcode"];
164                                         global $myga;
165                                         $authval = $myga->authenticateUser($username, $passcode);
166                                         $data_returned = $authval;
167                                         break;
168                                 case MSG_GET_OTK_ID:
169                                         if(!isset($msg["username"])) {
170                                                 msg_send($cl_queue, MSG_GET_OTK_ID, false);
171                                         } else {
172                                                 $username = $msg["username"];
173                                                 $sql = "select users_otk from users where users_username='$username'";
174                                                 $dbo = getDatabase();
175                                                 $res = $dbo->query($sql);
176                                                 $otkid = "";
177                                                 foreach($res as $row) {
178                                                         $otkid = $row["users_otk"];
179                                                 }
180                                                 
181                                                 if($otkid == "") {
182                                                         $data_returned = false;
183                                                 } else {
184                                                         $data_returned = $otkid;
185                                                 }
186                                         }
187                                         break;
188                                 case MSG_GET_OTK_PNG:
189                                         if(!isset($msg["otk"])) {
190                                                 msg_send($cl_queue, MSG_GET_OTK_PNG, false);
191                                         } else {
192                                                 $otk = $msg["otk"];
193                                                 $sql = "select users_username from users where users_otk='$otk'";
194                                                 $dbo = getDatabase();
195                                                 $res = $dbo->query($sql);
196                                                 $username = "";
197                                                 foreach($res as $row) {
198                                                         $username = $row["users_username"];
199                                                 }
200                                                 
201                                                 if($username == "") {
202                                                         $data_returned = false;
203                                                         
204                                                 } else if($username != $msg["username"]) {
205                                                         $data_returned = false;
206                                                 } else {
207                                                         global $BASE_DIR;
208                                                         $hand = fopen("$BASE_DIR/authserver/authd/otks/$otk.png", "rb");
209                                                         $data = fread($hand, filesize("$BASE_DIR/authserver/authd/otks/$otk.png"));
210                                                         fclose($hand);
211                                                         unlink("$BASE_DIR/authserver/authd/otks/$otk.png");
212                                                         $sql = "update users set users_otk='' where users_username='$username'";
213                                                         $dbo->query($sql);
214                                                         error_log("senting otk, fsize: ".filesize("$BASE_DIR/authserver/authd/otks/$otk.png")." $otk ");
215                                                         $data_returned = $data;
216                                                 }
217                                         }
218                                         
219                                         break;
220                                 case MSG_SYNC_TOKEN:
221                                         if(!isset($msg["username"])) {
222                                                 $data_returned = false;
223                                         } else {
224                                                 $tokenone = $msg["tokenone"];
225                                                 $tokentwo = $msg["tokentwo"];
226                                                 
227                                                 $data_returned = $myga->resyncCode($msg["username"], $tokenone, $tokentwo);
228                                         }
229                                         
230                                         break;
231                                 case MSG_GET_TOKEN_TYPE:
232                                         if(!isset($msg["username"])) {
233                                                 $data_returned = false;
234                                         } else {
235                                                 $data_returned = $myga->getTokenType($msg["username"]);
236                                         }
237                                         break;
238                                 case MSG_ADD_USER_TOKEN:
239                                         //echo "Call to add user token\n";
240                                         if(!isset($msg["username"])) {
241                                                 $data_returned = false;
242                                         } else {
243                                                 global $BASE_DIR;
244                                                 $username = $msg["username"];
245                                                 $tokentype="TOTP";
246                                                 if(isset($msg["tokentype"])) {
247                                                         $tokentype=$msg["tokentype"];
248                                                 }
249                                                 $hexkey = "";
250                                                 if(isset($msg["hexkey"])) {
251                                                         $hexkey = $msg["hexkey"];
252                                                 }
253                                                 global $myga;
254                                                 $myga->setUser($username, $tokentype, "", $hexkey);
255                                                 
256                                                 $url = $myga->createUrl($username);
257                                                 //echo "Url was: $url\n";
258                                                 if(!file_exists("$BASE_DIR/authserver/authd/otks")) mkdir("$BASE_DIR/authserver/authd/otks");
259                                                 $otk = generateRandomString();
260                                                 system("qrencode -o $BASE_DIR/authserver/authd/otks/$otk.png '$url'");
261                                                 
262                                                 $sql = "update users set users_otk='$otk' where users_username='$username'";
263                                                 $dbo = getDatabase();
264                                                 $res = $dbo->query($sql);
265                                                 
266                                                 $data_returned = true;
267                                         }
268                                         break;
269                                 case MSG_DELETE_USER:
270                                         //echo "Call to del user\n";
271                                         if(!isset($msg["username"])) {
272                                                 $data_returned = false; 
273                                         } else {
274                                                 $username = $msg["username"];                           
275                                                 global $myga;
276         
277                                                 $sql = "select users_otk from users where users_username='$username'";
278                                                 $dbo = getDatabase();
279                                                 $res = $dbo->query($sql);
280                                                 $otkid = "";
281                                                 foreach($res as $row) {
282                                                         $otkid = $row["users_otk"];
283                                                 }
284                                                 if($otkid!="") {
285                                                         unlink("otks/$otkid.png");
286                                                 }
287                                                 
288         
289                                                 $sql = "delete from users where users_username='$username'";
290                                                 $dbo = getDatabase();
291                                                 $dbo->query($sql);
292         
293                                                 $data_returned = true;
294                                         }
295                                         break;
296                                 case MSG_AUTH_USER_PASSWORD:
297                                         // TODO
298                                         //echo "Call to auth user pass\n";
299                                         if(!isset($msg["username"])) {
300                                                 $data_returned = false;
301                                                 break;
302                                         }
303                                         if(!isset($msg["password"])) {
304                                                 $data_returned = false;
305                                                 break;
306                                         }
307                                         
308                                         $username = $msg["username"];
309                                         $password = $msg["password"];
310                                         $sql = "select users_password from users where users_username='$username'";
311                                         $dbo = getDatabase();
312                                         $res = $dbo->query($sql);
313                                         $pass = "";
314                                         foreach($res as $row) {
315                                                 $pass = $row["users_password"];
316                                         }
317                                         
318                                         // TODO now do auth
319                                         $ourpass = hash('sha512', $password);
320                                         //echo "ourpass: $ourpass\nourhash: $pass\n";
321                                         if($ourpass == $pass) {
322                                                 $data_returned = true;
323                                                 
324                                         } else {
325                                                 $data_returned = false;
326                                                 
327                                         }
328                                         
329                                         break;
330                                 case MSG_SET_USER_PASSWORD:
331                                         //echo "how on earth is that happening Call to set user pass, wtf?\n";
332                                         // TODO
333                                         //print_r($msg);
334                                         if(!isset($msg["username"])) {
335                                                 $data_returned = false;
336                                                 //echo "in break 1\n";
337                                                 break;
338                                         }
339                                         if(!isset($msg["password"])) {
340                                                 $data_returned = false;
341                                                 //echo "in break 1\n";
342                                                 break;
343                                         }
344                                         
345                                         $username = $msg["username"];
346                                         $password = $msg["password"];
347                                         
348                                         //echo "would set pass for $username, to $password\n";
349                                         if($password == "") $pass = "";
350                                         else $pass = hash('sha512', $password);
351                                         
352                                         $dbo = getDatabase();
353                                         //echo "in set user pass for $username, $pass\n";
354                                         $sql = "update users set users_password='$pass' where users_username='$username'";
355                                         
356                                         $dbo->query($sql);
357         
358                                         $data_returned = true;
359                                         
360                                         
361                                         // these are irrelavent yet
362                                         // TODO now set pass
363                                         break;
364                                 case MSG_SET_USER_REALNAME:
365                                         //echo "Call to set user realname\n";
366                                         // TODO
367                                         if(!isset($msg["username"])) {
368                                                 $data_returned = false;
369                                                 break;
370                                         }
371                                         if(!isset($msg["realname"])) {
372                                                 $data_returned = false;
373                                                 break;
374                                         }
375                                         
376                                         $username = $msg["username"];
377                                         $realname = $msg["realname"];
378                                         $sql = "update users set users_realname='$realname' where users_username='$username'";
379                                         $dbo = getDatabase();
380                                         
381                                         $dbo->query($sql);
382         
383                                         $data_returned = true;
384                                         
385                                         // TODO now set real name
386                                         break;
387                                 case MSG_SET_USER_TOKEN:
388                                         // TODO
389                                         //echo "Call to set user token\n";
390                                         if(!isset($msg["username"])) {
391                                                 $data_returned = false;
392                                                 break;
393                                         }
394                                         if(!isset($msg["tokenstring"])) {
395                                                 $data_returned = false;
396                                                 break;
397                                         }
398                                         
399                                         global $myga;
400                                         $username = $msg["username"];
401                                         $token = $msg["tokenstring"];
402                                         $return = $myga->setUserKey($username, $token);
403                                         $data_returned = $return;
404                                         
405                                         // TODO now set token 
406                                         break;                  
407                                 case MSG_SET_USER_TOKEN_TYPE:
408                                         // TODO
409                                         //echo "Call to set user token type\n";
410                                         if(!isset($msg["username"])) {
411                                                 $data_returned = false;
412                                                 break;
413                                         }
414                                         if(!isset($msg["tokentype"])) {
415                                                 $data_returned = false;
416                                                 break;
417                                         }
418                                         
419                                         $username = $msg["username"];
420                                         $tokentype = $msg["tokentype"];
421                                         global $myga;
422                                         $data_returned = $myga->setTokenType($username, $tokentype);
423                                         
424                                         // TODO now set token 
425                                         break;
426                                 case MSG_GET_USERS:
427                                         // TODO this needs to be better
428                                         $sql = "select * from users order by users_username";
429                                         
430                                         $dbo = getDatabase();
431                                         $res = $dbo->query($sql);
432                                         
433                                         $users = "";
434                                         $i = 0;
435                                         foreach($res as $row) {
436                                                 $users[$i]["username"] = $row["users_username"];
437                                                 $users[$i]["realname"] = $row["users_realname"];
438                                                 if($row["users_password"]!="") {
439                                                         $users[$i]["haspass"] = true;
440                                                 } else {
441                                                         $users[$i]["haspass"] = false;
442                                                 }
443                                                 //echo "user: ".$users[$i]["username"]." has tdata: \"".$row["users_tokendata"]."\"\n";
444                                                 if($row["users_tokendata"]!="") {
445                                                         $users[$i]["hastoken"] = true;
446                                                 } else {
447                                                         $users[$i]["hastoken"] = false;
448                                                 }
449                                                 
450                                                 if($row["users_otk"]!="") {
451                                                         $users[$i]["otk"] = $row["users_otk"];
452                                                 } else {
453                                                         $users[$i]["otk"] = "";
454                                                 }
455                                                 $i++; 
456                                         }
457                                         $data_returned = $users;
458                                         
459                                         // TODO now set token 
460                                         break;
461                                         
462                         }               
463                         
464                         $d_comp["type"] = $msg_type;
465                         $d_comp["data"] = $data_returned;
466                         
467                         $realdata_returning = "AS:".base64_encode(serialize($d_comp)).":EOD";
468                         
469                         socket_send($data_socket, $realdata_returning, strlen($realdata_returning), 0);
470                         socket_close($data_socket);
471                         
472                         // now our child exits?
473                         return 0;
474                 }
475                 // otherwise return to the accept loop
476         }
477 }
478
479 ?>