Mercurial > hg > rlgwebd
comparison sqlickrypt.c @ 25:f275d816e857
sqlickrypt.c: finish switching to parametrized queries.
sqlickrypt should now be injection-resistant.
author | John "Elwin" Edwards <elwin@sdf.org> |
---|---|
date | Sun, 03 Jun 2012 18:26:11 -0700 |
parents | 9d5da43c0e83 |
children | c08717cb7793 |
comparison
equal
deleted
inserted
replaced
24:9d5da43c0e83 | 25:f275d816e857 |
---|---|
6 #include <unistd.h> | 6 #include <unistd.h> |
7 #include <crypt.h> | 7 #include <crypt.h> |
8 | 8 |
9 #define DATABASE "/dgldir/dgamelaunch.db" | 9 #define DATABASE "/dgldir/dgamelaunch.db" |
10 #define IBUFSIZE 200 | 10 #define IBUFSIZE 200 |
11 | |
12 int xcallback(void *targ, int ncols, char **vals, char **colnames) { | |
13 char *pws; | |
14 int j; | |
15 pws = *((char **) targ); | |
16 if (pws == NULL) { | |
17 for (j = 0; j < ncols; j++) { | |
18 if (!strcmp(colnames[j], "password")) | |
19 *((char **) targ) = strdup(vals[j]); | |
20 } | |
21 } | |
22 /* Otherwise, this isn't the first row. */ | |
23 return 0; | |
24 } | |
25 | |
26 /* Simple callback, for checking if there are any matches. */ | |
27 int searchcallback(void *targ, int ncols, char **vals, char **colnames) { | |
28 *((int *) targ) = 1; | |
29 return 0; | |
30 } | |
31 | 11 |
32 int check(char *uname, char *pw) { | 12 int check(char *uname, char *pw) { |
33 char *pwhash, *comphash; | 13 char *pwhash, *comphash; |
34 char *query = "SELECT password FROM dglusers WHERE username=?;"; | 14 char *query = "SELECT password FROM dglusers WHERE username=?;"; |
35 int status; | 15 int status; |
74 free(pwhash); | 54 free(pwhash); |
75 return status; | 55 return status; |
76 } | 56 } |
77 | 57 |
78 int insertuser(char *uname, char *pw, char *email) { | 58 int insertuser(char *uname, char *pw, char *email) { |
79 char finduser_sql[160]; | 59 char *checkquery = "SELECT * FROM dglusers WHERE username = ?;"; |
60 char *addquery = "INSERT INTO dglusers (username, password, email) VALUES (?, ?, ?);"; | |
80 int status; | 61 int status; |
81 sqlite3 *db; | 62 sqlite3 *db; |
82 | 63 sqlite3_stmt *qstmt; |
83 strcpy(finduser_sql, "BEGIN; SELECT * FROM dglusers WHERE username='"); | |
84 strncat(finduser_sql, uname, 40); | |
85 strcat(finduser_sql, "';"); | |
86 | 64 |
87 status = sqlite3_open(DATABASE, &db); | 65 status = sqlite3_open(DATABASE, &db); |
88 if (status) { | 66 if (status) { |
89 sqlite3_close(db); | 67 sqlite3_close(db); |
90 return 1; | 68 return 3; |
91 } | 69 } |
92 status = 0; | 70 /* Check for existing account in the same transaction with creating it. */ |
93 sqlite3_exec(db, finduser_sql, searchcallback, (void *) &status, NULL); | 71 status = sqlite3_exec(db, "BEGIN;", NULL, NULL, NULL); |
94 if (!status) { | 72 if (status) { |
95 /* FIXME This is ugly, and email is unsanitzed. */ | 73 sqlite3_close(db); |
96 strcpy(finduser_sql, "INSERT INTO dglusers (username, password, email) VALUES ('"); | 74 return 3; |
97 strncat(finduser_sql, uname, 20); | |
98 strcat(finduser_sql, "', '"); | |
99 strcat(finduser_sql, crypt(pw, pw)); | |
100 strcat(finduser_sql, "', '"); | |
101 strncat(finduser_sql, email, 40); | |
102 strcat(finduser_sql, "');"); | |
103 sqlite3_exec(db, finduser_sql, NULL, NULL, NULL); | |
104 } | 75 } |
105 sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL); | 76 sqlite3_prepare_v2(db, checkquery, -1, &qstmt, NULL); |
77 if (qstmt == NULL) { | |
78 sqlite3_close(db); | |
79 return 3; | |
80 } | |
81 sqlite3_bind_text(qstmt, 1, uname, -1, SQLITE_TRANSIENT); | |
82 status = sqlite3_step(qstmt); | |
83 if (status != SQLITE_DONE) { | |
84 sqlite3_finalize(qstmt); | |
85 sqlite3_close(db); | |
86 if (status == SQLITE_ROW) | |
87 return 1; /* User already exists */ | |
88 return 3; | |
89 } | |
90 /* The username doesn't exist yet, so create a new account. */ | |
91 sqlite3_finalize(qstmt); | |
92 sqlite3_prepare_v2(db, addquery, -1, &qstmt, NULL); | |
93 if (qstmt == NULL) { | |
94 sqlite3_close(db); | |
95 return 3; | |
96 } | |
97 sqlite3_bind_text(qstmt, 1, uname, -1, SQLITE_TRANSIENT); | |
98 sqlite3_bind_text(qstmt, 2, strdup(crypt(pw, pw)), -1, free); | |
99 sqlite3_bind_text(qstmt, 3, email, -1, SQLITE_TRANSIENT); | |
100 status = sqlite3_step(qstmt); | |
101 if (status != SQLITE_DONE) { | |
102 sqlite3_finalize(qstmt); | |
103 sqlite3_close(db); | |
104 return 3; | |
105 } | |
106 status = sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL); | |
107 sqlite3_finalize(qstmt); | |
106 sqlite3_close(db); | 108 sqlite3_close(db); |
107 return status; | 109 return status; |
108 } | 110 } |
109 | 111 |
110 int main(int argc, char *argv[]) { | 112 int main(int argc, char *argv[]) { |