changeset 17:d3e3d6b4016b

rlgwebd: switch to dgamelaunch's SQLite database. The quickrypt utility is replaced with sqlickrypt, which takes a username and password pair and checks them against the SQLite password database used by dgamelaunch. This will be more extensible to using rlgwebd to register, change passwords, etc.
author John "Elwin" Edwards <elwin@sdf.org>
date Sun, 20 May 2012 15:52:07 -0700
parents ef6127ed6da3
children 59ea628abb81
files quickrypt.c rlgwebd.js sqlickrypt.c
diffstat 3 files changed, 84 insertions(+), 53 deletions(-) [+]
line wrap: on
line diff
--- a/quickrypt.c	Thu May 17 09:32:19 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-/*
- * quickrypt: a quick and dirty crypt(3) utility for use with node.js.
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <crypt.h>
-
-int main(int argc, char *argv[]) {
-  char clear[32], enc[120], *ptr;
-  fgets(&clear, 32, stdin);
-  if (!(ptr = strchr(&clear, '\n')))
-    return 1;
-  else
-    *ptr = '\0';
-  fgets(&enc, 120, stdin);
-  if (!(ptr = strchr(&enc, '\n')))
-    return 1;
-  else
-    *ptr = '\0';
-  ptr = crypt(clear, enc);
-  if (!strcmp(argv[argc - 1], "-s")) {
-    /* Option -s for "show": output the encrypted version. */
-    printf("%s\n", ptr);
-    return 0;
-  }
-  /* Otherwise this is a check. */
-  else if (!strcmp(ptr, enc))
-    return 0;
-  return 1;
-}
--- a/rlgwebd.js	Thu May 17 09:32:19 2012 -0700
+++ b/rlgwebd.js	Sun May 20 15:52:07 2012 -0700
@@ -296,7 +296,12 @@
     // check the password
     if (code != 0) {
       sendError(res, 3);
-      console.log("Password check failed for user " + username);
+      if (code == 1)
+        console.log("Password check failed for user " + username);
+      else if (code == 2)
+        console.log("Attempted login by nonexistent user " + username);
+      else
+        console.log("Login failed: sqlickrypt error " + code);
       return;
     }
     // check for an existing game
@@ -306,6 +311,7 @@
         for (var i = 0; i < files.length; i++) {
           if (files[i].match(fre)) {
             sendError(res, 4, null);
+            console.log(username + " is already playing " + gname);
             return;
           }
         }
@@ -314,27 +320,10 @@
       startgame();
     });
   }
-  /* Look for the user in the password file */
-  fs.readFile(passwdfile, "utf8", function(err, data) {
-    if (err) {
-      sendError(res, 3);
-      console.log("Can't authenticate: " + err.toString());
-      return;
-    }
-    var dlines = data.split('\n');
-    for (var n = 0; n < dlines.length; n++) {
-      var fields = dlines[n].split(':');
-      if (fields[0] == username) {
-        // check the password with the quickrypt utility
-        checker = require('child_process').spawn("/bin/quickrypt")
-        checker.on("exit", checkit);
-        checker.stdin.end(password + '\n' + fields[2] + '\n', "utf8");
-        return;
-      }
-    }
-    sendError(res, 3);
-    console.log("Attempted login by nonexistent user " + username);
-  });
+  /* Launch the sqlickrypt utility to check the password. */
+  var checker = require('child_process').spawn("/bin/sqlickrypt");
+  checker.on("exit", checkit);
+  checker.stdin.end(username + '\n' + password + '\n', "utf8");
   return;
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sqlickrypt.c	Sun May 20 15:52:07 2012 -0700
@@ -0,0 +1,73 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <sqlite3.h>
+#include <unistd.h>
+#include <crypt.h>
+
+#define DATABASE "/dgldir/dgamelaunch.db"
+
+int xcallback(void *targ, int ncols, char **vals, char **colnames) {
+  char *pws;
+  int j;
+  pws = *((char **) targ);
+  if (pws == NULL) {
+    for (j = 0; j < ncols; j++) {
+      if (!strcmp(colnames[j], "password"))
+        *((char **) targ) = strdup(vals[j]);
+    }
+  }
+  /* Otherwise, this isn't the first row. */
+  return 0;
+}
+
+int main(int argc, char *argv[]) {
+  char ibuf[160], *uname, *pw, *pwhash = NULL, *comphash;
+  char finduser_sql[160];
+  char *cptr; // Utility pointer
+  sqlite3 *db;
+  int status;
+
+  /* Read in the username and password */
+  fgets(ibuf, 160, stdin);
+  uname = ibuf;
+  pw = strchr(uname, '\n');
+  if (pw == NULL)
+    exit(4); /* Truncated */
+  *pw = '\0';
+  pw++;
+  fgets(pw, 160 - (pw - ibuf), stdin);
+  if (pw[strlen(pw) - 1] == '\n')
+    pw[strlen(pw) - 1] = '\0';
+  else
+    exit(4); /* Truncated */
+  /* Sanitize the username, because it gets put into a query. */
+  for (cptr = uname; *cptr != '\0'; cptr++) {
+    if (!isalnum(*cptr)) {
+      exit(4);
+    }
+  }
+  /* Construct the query */
+  strcpy(finduser_sql, "SELECT * FROM dglusers WHERE username='");
+  strncat(finduser_sql, uname, 40);
+  strcat(finduser_sql, "';");
+
+  status = sqlite3_open(DATABASE, &db);
+  if (status) {
+    sqlite3_close(db);
+    return 1;
+  }
+  sqlite3_exec(db, finduser_sql, xcallback, (void *) &pwhash, NULL);
+
+  sqlite3_close(db);
+
+  /* Now check the password. */
+  if (pwhash == NULL) {
+    return 2;
+  }
+  comphash = crypt(pw, pwhash);
+  if (!strcmp(pwhash, comphash))
+    return 0;
+  return 1;
+}