# HG changeset patch # User John "Elwin" Edwards # Date 1338773171 25200 # Node ID f275d816e85751097608807b0f2b9d9b128487c9 # Parent 9d5da43c0e83a1b1f0e94a8a2216c50b97b549a2 sqlickrypt.c: finish switching to parametrized queries. sqlickrypt should now be injection-resistant. diff -r 9d5da43c0e83 -r f275d816e857 sqlickrypt.c --- a/sqlickrypt.c Sun Jun 03 17:08:40 2012 -0700 +++ b/sqlickrypt.c Sun Jun 03 18:26:11 2012 -0700 @@ -9,26 +9,6 @@ #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=?;"; @@ -76,33 +56,55 @@ } int insertuser(char *uname, char *pw, char *email) { - char finduser_sql[160]; + char *checkquery = "SELECT * FROM dglusers WHERE username = ?;"; + char *addquery = "INSERT INTO dglusers (username, password, email) VALUES (?, ?, ?);"; int status; sqlite3 *db; - - strcpy(finduser_sql, "BEGIN; SELECT * FROM dglusers WHERE username='"); - strncat(finduser_sql, uname, 40); - strcat(finduser_sql, "';"); + sqlite3_stmt *qstmt; status = sqlite3_open(DATABASE, &db); if (status) { sqlite3_close(db); - return 1; + 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; } - 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_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; } - sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL); + /* 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; }