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 } |