# HG changeset patch # User John "Elwin" Edwards # Date 1337554327 25200 # Node ID d3e3d6b4016b61b3ca9b652ccbfd902cbec6399e # Parent ef6127ed6da34171ada52d4f9bd1ef990a0e01d7 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. diff -r ef6127ed6da3 -r d3e3d6b4016b quickrypt.c --- 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 -#include -#include -#include - -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; -} diff -r ef6127ed6da3 -r d3e3d6b4016b rlgwebd.js --- 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; } diff -r ef6127ed6da3 -r d3e3d6b4016b sqlickrypt.c --- /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 +#include +#include +#include +#include +#include +#include + +#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; +}