view sqlickrypt.c @ 63:a077f9f84052

RLG-Web client: adjust polling for watching. The ajaxterm state machine assumed data appears in response to user actions, which is not true when watching. It now uses different sets of parameters for playing and watching.
author John "Elwin" Edwards <elwin@sdf.org>
date Wed, 20 Jun 2012 07:41:59 -0700
parents f275d816e857
children c08717cb7793
line wrap: on
line source

#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"
#define IBUFSIZE 200

int check(char *uname, char *pw) {
  char *pwhash, *comphash;
  char *query = "SELECT password FROM dglusers WHERE username=?;";
  int status;
  sqlite3 *db;
  sqlite3_stmt *qstmt;

  status = sqlite3_open(DATABASE, &db);
  if (status) {
    sqlite3_close(db);
    return 3;
  }
  sqlite3_prepare_v2(db, query, -1, &qstmt, NULL);
  if (qstmt == NULL) {
    sqlite3_close(db);
    return 3;
  }
  status = sqlite3_bind_text(qstmt, 1, uname, -1, SQLITE_TRANSIENT);
  if (status) {
    sqlite3_finalize(qstmt);
    sqlite3_close(db);
    return 3;
  }
  status = sqlite3_step(qstmt);
  if (status != SQLITE_ROW) {
    sqlite3_finalize(qstmt);
    sqlite3_close(db);
    if (status == SQLITE_DONE)
      return 2; /* User not found */
    return 3;
  }
  pwhash = strdup((char *) sqlite3_column_text(qstmt, 0));
  /* Clean up */
  sqlite3_finalize(qstmt);
  sqlite3_close(db);

  /* Check the password */
  comphash = crypt(pw, pwhash);
  if (!strcmp(pwhash, comphash))
    status = 0;
  else
    status = 1;
  free(pwhash);
  return status;
}

int insertuser(char *uname, char *pw, char *email) {
  char *checkquery = "SELECT * FROM dglusers WHERE username = ?;";
  char *addquery =  "INSERT INTO dglusers (username, password, email) VALUES (?, ?, ?);";
  int status;
  sqlite3 *db;
  sqlite3_stmt *qstmt;

  status = sqlite3_open(DATABASE, &db);
  if (status) {
    sqlite3_close(db);
    return 3;
  }
  /* Check for existing account in the same transaction with creating it. */
  status = sqlite3_exec(db, "BEGIN;", NULL, NULL, NULL);
  if (status) {
    sqlite3_close(db);
    return 3;
  }
  sqlite3_prepare_v2(db, checkquery, -1, &qstmt, NULL);
  if (qstmt == NULL) {
    sqlite3_close(db);
    return 3;
  }
  sqlite3_bind_text(qstmt, 1, uname, -1, SQLITE_TRANSIENT);
  status = sqlite3_step(qstmt);
  if (status != SQLITE_DONE) {
    sqlite3_finalize(qstmt);
    sqlite3_close(db);
    if (status == SQLITE_ROW)
      return 1; /* User already exists */
    return 3;
  }
  /* The username doesn't exist yet, so create a new account. */
  sqlite3_finalize(qstmt);
  sqlite3_prepare_v2(db, addquery, -1, &qstmt, NULL);
  if (qstmt == NULL) {
    sqlite3_close(db);
    return 3;
  }
  sqlite3_bind_text(qstmt, 1, uname, -1, SQLITE_TRANSIENT);
  sqlite3_bind_text(qstmt, 2, strdup(crypt(pw, pw)), -1, free);
  sqlite3_bind_text(qstmt, 3, email, -1, SQLITE_TRANSIENT);
  status = sqlite3_step(qstmt);
  if (status != SQLITE_DONE) {
    sqlite3_finalize(qstmt);
    sqlite3_close(db);
    return 3;
  }
  status = sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL);
  sqlite3_finalize(qstmt);
  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;
}