Mercurial > hg > rlgwebd
comparison sqlickrypt.c @ 117:c08717cb7793
sqlickrypt: add getmail and setmail commands.
Add the ability to retrieve and alter users' e-mail addresses, and
clean up some of the code too.
| author | John "Elwin" Edwards <elwin@sdf.org> |
|---|---|
| date | Wed, 18 Jul 2012 17:00:05 -0700 |
| parents | f275d816e857 |
| children | b1480488ce9d |
comparison
equal
deleted
inserted
replaced
| 116:d7d7cdcba3b4 | 117:c08717cb7793 |
|---|---|
| 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 | 11 |
| 12 /* General idea for return status: | |
| 13 * 0: success | |
| 14 * 1: password check failed | |
| 15 * 2: username not found | |
| 16 * 3: database error | |
| 17 * 4: invalid input | |
| 18 */ | |
| 19 | |
| 20 /* Opens the database and, less obviously, initializes a statement. */ | |
| 21 int opendb(sqlite3 **dbp, sqlite3_stmt **stmtp, char *query) { | |
| 22 int status; | |
| 23 status = sqlite3_open(DATABASE, dbp); | |
| 24 if (status) { | |
| 25 sqlite3_close(*dbp); | |
| 26 exit(3); | |
| 27 } | |
| 28 sqlite3_prepare_v2(*dbp, query, -1, stmtp, NULL); | |
| 29 if (*stmtp == NULL) { | |
| 30 sqlite3_close(*dbp); | |
| 31 exit(3); | |
| 32 } | |
| 33 return 0; | |
| 34 } | |
| 35 | |
| 36 void cleanup(sqlite3 *db, sqlite3_stmt *stmt, int status) { | |
| 37 if (stmt) | |
| 38 sqlite3_finalize(stmt); | |
| 39 sqlite3_close(db); | |
| 40 if (status) | |
| 41 exit(status); | |
| 42 return; | |
| 43 } | |
| 44 | |
| 12 int check(char *uname, char *pw) { | 45 int check(char *uname, char *pw) { |
| 13 char *pwhash, *comphash; | 46 char *pwhash, *comphash; |
| 14 char *query = "SELECT password FROM dglusers WHERE username=?;"; | 47 char *query = "SELECT password FROM dglusers WHERE username=?;"; |
| 15 int status; | 48 int status; |
| 16 sqlite3 *db; | 49 sqlite3 *db; |
| 17 sqlite3_stmt *qstmt; | 50 sqlite3_stmt *qstmt; |
| 18 | 51 |
| 19 status = sqlite3_open(DATABASE, &db); | 52 opendb(&db, &qstmt, query); |
| 20 if (status) { | |
| 21 sqlite3_close(db); | |
| 22 return 3; | |
| 23 } | |
| 24 sqlite3_prepare_v2(db, query, -1, &qstmt, NULL); | |
| 25 if (qstmt == NULL) { | |
| 26 sqlite3_close(db); | |
| 27 return 3; | |
| 28 } | |
| 29 status = sqlite3_bind_text(qstmt, 1, uname, -1, SQLITE_TRANSIENT); | 53 status = sqlite3_bind_text(qstmt, 1, uname, -1, SQLITE_TRANSIENT); |
| 30 if (status) { | 54 if (status) |
| 31 sqlite3_finalize(qstmt); | 55 cleanup(db, qstmt, 3); |
| 32 sqlite3_close(db); | |
| 33 return 3; | |
| 34 } | |
| 35 status = sqlite3_step(qstmt); | 56 status = sqlite3_step(qstmt); |
| 36 if (status != SQLITE_ROW) { | 57 if (status != SQLITE_ROW) { |
| 37 sqlite3_finalize(qstmt); | 58 sqlite3_finalize(qstmt); |
| 38 sqlite3_close(db); | 59 sqlite3_close(db); |
| 39 if (status == SQLITE_DONE) | 60 if (status == SQLITE_DONE) |
| 40 return 2; /* User not found */ | 61 return 2; /* User not found */ |
| 41 return 3; | 62 return 3; |
| 42 } | 63 } |
| 43 pwhash = strdup((char *) sqlite3_column_text(qstmt, 0)); | 64 pwhash = strdup((char *) sqlite3_column_text(qstmt, 0)); |
| 44 /* Clean up */ | 65 cleanup(db, qstmt, 0); |
| 45 sqlite3_finalize(qstmt); | |
| 46 sqlite3_close(db); | |
| 47 | 66 |
| 48 /* Check the password */ | 67 /* Check the password */ |
| 49 comphash = crypt(pw, pwhash); | 68 comphash = crypt(pw, pwhash); |
| 50 if (!strcmp(pwhash, comphash)) | 69 if (!strcmp(pwhash, comphash)) |
| 51 status = 0; | 70 status = 0; |
| 60 char *addquery = "INSERT INTO dglusers (username, password, email) VALUES (?, ?, ?);"; | 79 char *addquery = "INSERT INTO dglusers (username, password, email) VALUES (?, ?, ?);"; |
| 61 int status; | 80 int status; |
| 62 sqlite3 *db; | 81 sqlite3 *db; |
| 63 sqlite3_stmt *qstmt; | 82 sqlite3_stmt *qstmt; |
| 64 | 83 |
| 65 status = sqlite3_open(DATABASE, &db); | 84 opendb(&db, &qstmt, checkquery); |
| 66 if (status) { | |
| 67 sqlite3_close(db); | |
| 68 return 3; | |
| 69 } | |
| 70 /* Check for existing account in the same transaction with creating it. */ | 85 /* Check for existing account in the same transaction with creating it. */ |
| 71 status = sqlite3_exec(db, "BEGIN;", NULL, NULL, NULL); | 86 status = sqlite3_exec(db, "BEGIN;", NULL, NULL, NULL); |
| 72 if (status) { | 87 if (status) |
| 73 sqlite3_close(db); | 88 cleanup(db, qstmt, 3); |
| 74 return 3; | |
| 75 } | |
| 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); | 89 sqlite3_bind_text(qstmt, 1, uname, -1, SQLITE_TRANSIENT); |
| 82 status = sqlite3_step(qstmt); | 90 status = sqlite3_step(qstmt); |
| 83 if (status != SQLITE_DONE) { | 91 if (status != SQLITE_DONE) { |
| 84 sqlite3_finalize(qstmt); | 92 sqlite3_finalize(qstmt); |
| 85 sqlite3_close(db); | 93 sqlite3_close(db); |
| 88 return 3; | 96 return 3; |
| 89 } | 97 } |
| 90 /* The username doesn't exist yet, so create a new account. */ | 98 /* The username doesn't exist yet, so create a new account. */ |
| 91 sqlite3_finalize(qstmt); | 99 sqlite3_finalize(qstmt); |
| 92 sqlite3_prepare_v2(db, addquery, -1, &qstmt, NULL); | 100 sqlite3_prepare_v2(db, addquery, -1, &qstmt, NULL); |
| 93 if (qstmt == NULL) { | 101 if (qstmt == NULL) |
| 94 sqlite3_close(db); | 102 cleanup(db, NULL, 3); |
| 95 return 3; | |
| 96 } | |
| 97 sqlite3_bind_text(qstmt, 1, uname, -1, SQLITE_TRANSIENT); | 103 sqlite3_bind_text(qstmt, 1, uname, -1, SQLITE_TRANSIENT); |
| 98 sqlite3_bind_text(qstmt, 2, strdup(crypt(pw, pw)), -1, free); | 104 sqlite3_bind_text(qstmt, 2, strdup(crypt(pw, pw)), -1, free); |
| 99 sqlite3_bind_text(qstmt, 3, email, -1, SQLITE_TRANSIENT); | 105 sqlite3_bind_text(qstmt, 3, email, -1, SQLITE_TRANSIENT); |
| 100 status = sqlite3_step(qstmt); | 106 status = sqlite3_step(qstmt); |
| 101 if (status != SQLITE_DONE) { | 107 if (status != SQLITE_DONE) |
| 108 cleanup(db, qstmt, 3); | |
| 109 status = sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL); | |
| 110 cleanup(db, qstmt, 0); | |
| 111 return status; | |
| 112 } | |
| 113 | |
| 114 int getmail(char *uname) { | |
| 115 char *mailquery = "SELECT email FROM dglusers WHERE username = ?;"; | |
| 116 int status; | |
| 117 sqlite3 *db; | |
| 118 sqlite3_stmt *qstmt; | |
| 119 | |
| 120 opendb(&db, &qstmt, mailquery); | |
| 121 status = sqlite3_bind_text(qstmt, 1, uname, -1, SQLITE_TRANSIENT); | |
| 122 if (status) | |
| 123 cleanup(db, qstmt, 3); | |
| 124 status = sqlite3_step(qstmt); | |
| 125 if (status != SQLITE_ROW) { | |
| 102 sqlite3_finalize(qstmt); | 126 sqlite3_finalize(qstmt); |
| 103 sqlite3_close(db); | 127 sqlite3_close(db); |
| 128 if (status == SQLITE_DONE) | |
| 129 return 2; /* User not found */ | |
| 104 return 3; | 130 return 3; |
| 105 } | 131 } |
| 106 status = sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL); | 132 printf("%s\n", sqlite3_column_text(qstmt, 0)); |
| 107 sqlite3_finalize(qstmt); | 133 cleanup(db, qstmt, 0); |
| 108 sqlite3_close(db); | 134 return 0; |
| 109 return status; | 135 } |
| 136 | |
| 137 int setmail(char *uname, char *newmail) { | |
| 138 char *setquery = "UPDATE dglusers SET email = ? WHERE username = ?;"; | |
| 139 sqlite3 *db; | |
| 140 sqlite3_stmt *qstmt; | |
| 141 int status; | |
| 142 | |
| 143 opendb(&db, &qstmt, setquery); | |
| 144 status = sqlite3_bind_text(qstmt, 2, uname, -1, SQLITE_TRANSIENT); | |
| 145 if (status) | |
| 146 cleanup(db, qstmt, 3); | |
| 147 status = sqlite3_bind_text(qstmt, 1, newmail, -1, SQLITE_TRANSIENT); | |
| 148 if (status) | |
| 149 cleanup(db, qstmt, 3); | |
| 150 status = sqlite3_step(qstmt); | |
| 151 if (status != SQLITE_DONE) | |
| 152 cleanup(db, qstmt, 3); | |
| 153 cleanup(db, qstmt, 0); | |
| 154 return 0; | |
| 110 } | 155 } |
| 111 | 156 |
| 112 int main(int argc, char *argv[]) { | 157 int main(int argc, char *argv[]) { |
| 113 char ibuf[IBUFSIZE], *uname, *pw, *email; | 158 char ibuf[IBUFSIZE], *uname, *line1, *line2; |
| 114 char *cptr; // Utility pointer | 159 char *cptr; // Utility pointer |
| 115 int status; | 160 int status; |
| 116 | 161 |
| 117 /* Read in the username and password */ | 162 /* Read in the username and password */ |
| 118 fgets(ibuf, IBUFSIZE, stdin); | 163 fgets(ibuf, IBUFSIZE, stdin); |
| 119 uname = ibuf; | 164 uname = ibuf; |
| 120 pw = strchr(uname, '\n'); | 165 line1 = strchr(uname, '\n'); |
| 121 if (pw == NULL) | 166 if (line1 == NULL) |
| 122 exit(4); /* Truncated */ | 167 exit(4); /* Truncated */ |
| 123 *pw = '\0'; | 168 *line1 = '\0'; |
| 124 pw++; | 169 if (argc == 1 || strcmp(argv[1], "getmail")) { |
| 125 fgets(pw, IBUFSIZE - (pw - ibuf), stdin); | 170 line1++; |
| 126 if (pw[strlen(pw) - 1] == '\n') | 171 fgets(line1, IBUFSIZE - (line1 - ibuf), stdin); |
| 127 pw[strlen(pw) - 1] = '\0'; | 172 if (line1[strlen(line1) - 1] == '\n') |
| 128 else | 173 line1[strlen(line1) - 1] = '\0'; |
| 129 exit(4); /* Truncated */ | 174 else |
| 175 exit(4); /* Truncated */ | |
| 176 } | |
| 177 if (argc > 1 && !strcmp(argv[1], "setmail")) { | |
| 178 /* E-mail, sanitize */ | |
| 179 for (cptr = line1; *cptr != '\0'; cptr++) { | |
| 180 if (!isalnum(*cptr) && !strchr("@._-", *cptr)) { | |
| 181 exit(4); | |
| 182 } | |
| 183 } | |
| 184 } | |
| 130 if (argc > 1 && !strcmp(argv[1], "register")) { | 185 if (argc > 1 && !strcmp(argv[1], "register")) { |
| 131 email = pw + strlen(pw) + 1; | 186 line2 = line1 + strlen(line1) + 1; |
| 132 fgets(email, IBUFSIZE - (email - ibuf), stdin); | 187 fgets(line2, IBUFSIZE - (line2 - ibuf), stdin); |
| 133 if (email[strlen(email) - 1] == '\n') | 188 if (line2[strlen(line2) - 1] == '\n') |
| 134 email[strlen(email) - 1] = '\0'; | 189 line2[strlen(line2) - 1] = '\0'; |
| 135 else | 190 else |
| 136 exit(4); | 191 exit(4); |
| 137 for (cptr = email; *cptr != '\0'; cptr++) { | 192 for (cptr = line2; *cptr != '\0'; cptr++) { |
| 138 if (!isalnum(*cptr) && !strchr("@._-", *cptr)) { | 193 if (!isalnum(*cptr) && !strchr("@._-", *cptr)) { |
| 139 exit(4); | 194 exit(4); |
| 140 } | 195 } |
| 141 } | 196 } |
| 142 } | 197 } |
| 145 if (!isalnum(*cptr)) { | 200 if (!isalnum(*cptr)) { |
| 146 exit(4); | 201 exit(4); |
| 147 } | 202 } |
| 148 } | 203 } |
| 149 if (argc == 1 || !strcmp(argv[1], "check")) | 204 if (argc == 1 || !strcmp(argv[1], "check")) |
| 150 status = check(uname, pw); | 205 status = check(uname, line1); |
| 151 else if (!strcmp(argv[1], "register")) { | 206 else if (!strcmp(argv[1], "register")) { |
| 152 status = insertuser(uname, pw, email); | 207 status = insertuser(uname, line1, line2); |
| 208 } | |
| 209 else if (!strcmp(argv[1], "getmail")) { | |
| 210 status = getmail(uname); | |
| 211 } | |
| 212 else if (!strcmp(argv[1], "setmail")) { | |
| 213 status = setmail(uname, line1); | |
| 153 } | 214 } |
| 154 else | 215 else |
| 155 status = 127; | 216 status = 127; |
| 156 return status; | 217 return status; |
| 157 } | 218 } |
