changeset 18:59ea628abb81

sqlickrypt.c: add the ability to register new users. When sqlickrypt is run with the option "register", it expects a username, password, and email, and adds them to the database if the username is not already in use.
author John "Elwin" Edwards <elwin@sdf.org>
date Mon, 21 May 2012 21:40:56 -0700
parents d3e3d6b4016b
children 188bbd857124
files sqlickrypt.c
diffstat 1 files changed, 91 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/sqlickrypt.c	Sun May 20 15:52:07 2012 -0700
+++ b/sqlickrypt.c	Mon May 21 21:40:56 2012 -0700
@@ -7,6 +7,7 @@
 #include <crypt.h>
 
 #define DATABASE "/dgldir/dgamelaunch.db"
+#define IBUFSIZE 200
 
 int xcallback(void *targ, int ncols, char **vals, char **colnames) {
   char *pws;
@@ -22,33 +23,18 @@
   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;
+/* Simple callback, for checking if there are any matches. */
+int searchcallback(void *targ, int ncols, char **vals, char **colnames) {
+  *((int *) targ) = 1;
+  return 0;
+}
 
-  /* 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 */
+int check(char *uname, char *pw) {
+  char finduser_sql[160];
+  char *pwhash = NULL, *comphash;
+  int status;
+  sqlite3 *db;
+
   strcpy(finduser_sql, "SELECT * FROM dglusers WHERE username='");
   strncat(finduser_sql, uname, 40);
   strcat(finduser_sql, "';");
@@ -61,7 +47,6 @@
   sqlite3_exec(db, finduser_sql, xcallback, (void *) &pwhash, NULL);
 
   sqlite3_close(db);
-
   /* Now check the password. */
   if (pwhash == NULL) {
     return 2;
@@ -71,3 +56,82 @@
     return 0;
   return 1;
 }
+
+int insertuser(char *uname, char *pw, char *email) {
+  char finduser_sql[160];
+  int status;
+  sqlite3 *db;
+
+  strcpy(finduser_sql, "BEGIN; 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;
+  }
+  status = 0;
+  sqlite3_exec(db, finduser_sql, searchcallback, (void *) &status, NULL);
+  if (!status) {
+    /* FIXME This is ugly, and email is unsanitzed. */
+    strcpy(finduser_sql, "INSERT INTO dglusers (username, password, email) VALUES ('");
+    strncat(finduser_sql, uname, 20);
+    strcat(finduser_sql, "', '");
+    strcat(finduser_sql, crypt(pw, pw));
+    strcat(finduser_sql, "', '");
+    strncat(finduser_sql, email, 40);
+    strcat(finduser_sql, "');");
+    sqlite3_exec(db, finduser_sql, NULL, NULL, NULL);
+  }
+  sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL);
+  sqlite3_close(db);
+  return status;
+}
+
+int main(int argc, char *argv[]) {
+  char ibuf[IBUFSIZE], *uname, *pw, *email;
+  char *cptr; // Utility pointer
+  int status;
+
+  /* Read in the username and password */
+  fgets(ibuf, IBUFSIZE, stdin);
+  uname = ibuf;
+  pw = strchr(uname, '\n');
+  if (pw == NULL)
+    exit(4); /* Truncated */
+  *pw = '\0';
+  pw++;
+  fgets(pw, IBUFSIZE - (pw - ibuf), stdin);
+  if (pw[strlen(pw) - 1] == '\n')
+    pw[strlen(pw) - 1] = '\0';
+  else
+    exit(4); /* Truncated */
+  if (argc > 1 && !strcmp(argv[1], "register")) {
+    email = pw + strlen(pw) + 1;
+    fgets(email, IBUFSIZE - (email - ibuf), stdin);
+    if (email[strlen(email) - 1] == '\n')
+      email[strlen(email) - 1] = '\0';
+    else
+      exit(4);
+    for (cptr = email; *cptr != '\0'; cptr++) {
+      if (!isalnum(*cptr) && !strchr("@._-", *cptr)) {
+        exit(4);
+      }
+    }
+  }
+  /* Sanitize the username, because it gets put into a query. */
+  for (cptr = uname; *cptr != '\0'; cptr++) {
+    if (!isalnum(*cptr)) {
+      exit(4);
+    }
+  }
+  if (argc == 1 || !strcmp(argv[1], "check"))
+    status = check(uname, pw);
+  else if (!strcmp(argv[1], "register")) {
+    status = insertuser(uname, pw, email);
+  }
+  else
+    status = 127;
+  return status;
+}