Mercurial > hg > rlgwebd
view sqlickrypt.c @ 24:9d5da43c0e83
sqlickrypt.c: begin converting to parametrized queries.
Switch the check() function to use parametrized SQL queries instead of
contructing statements with strcat(), for obvious reasons.
author | John "Elwin" Edwards <elwin@sdf.org> |
---|---|
date | Sun, 03 Jun 2012 17:08:40 -0700 |
parents | 59ea628abb81 |
children | f275d816e857 |
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 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; } /* Simple callback, for checking if there are any matches. */ int searchcallback(void *targ, int ncols, char **vals, char **colnames) { *((int *) targ) = 1; return 0; } 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 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; }