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.
This commit is contained in:
John "Elwin" Edwards 2012-07-18 17:00:05 -07:00
parent 55f7c3e7de
commit 931bc5cb87

View file

@ -9,6 +9,39 @@
#define DATABASE "/dgldir/dgamelaunch.db" #define DATABASE "/dgldir/dgamelaunch.db"
#define IBUFSIZE 200 #define IBUFSIZE 200
/* General idea for return status:
* 0: success
* 1: password check failed
* 2: username not found
* 3: database error
* 4: invalid input
*/
/* Opens the database and, less obviously, initializes a statement. */
int opendb(sqlite3 **dbp, sqlite3_stmt **stmtp, char *query) {
int status;
status = sqlite3_open(DATABASE, dbp);
if (status) {
sqlite3_close(*dbp);
exit(3);
}
sqlite3_prepare_v2(*dbp, query, -1, stmtp, NULL);
if (*stmtp == NULL) {
sqlite3_close(*dbp);
exit(3);
}
return 0;
}
void cleanup(sqlite3 *db, sqlite3_stmt *stmt, int status) {
if (stmt)
sqlite3_finalize(stmt);
sqlite3_close(db);
if (status)
exit(status);
return;
}
int check(char *uname, char *pw) { int check(char *uname, char *pw) {
char *pwhash, *comphash; char *pwhash, *comphash;
char *query = "SELECT password FROM dglusers WHERE username=?;"; char *query = "SELECT password FROM dglusers WHERE username=?;";
@ -16,22 +49,10 @@ int check(char *uname, char *pw) {
sqlite3 *db; sqlite3 *db;
sqlite3_stmt *qstmt; sqlite3_stmt *qstmt;
status = sqlite3_open(DATABASE, &db); opendb(&db, &qstmt, query);
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); status = sqlite3_bind_text(qstmt, 1, uname, -1, SQLITE_TRANSIENT);
if (status) { if (status)
sqlite3_finalize(qstmt); cleanup(db, qstmt, 3);
sqlite3_close(db);
return 3;
}
status = sqlite3_step(qstmt); status = sqlite3_step(qstmt);
if (status != SQLITE_ROW) { if (status != SQLITE_ROW) {
sqlite3_finalize(qstmt); sqlite3_finalize(qstmt);
@ -41,9 +62,7 @@ int check(char *uname, char *pw) {
return 3; return 3;
} }
pwhash = strdup((char *) sqlite3_column_text(qstmt, 0)); pwhash = strdup((char *) sqlite3_column_text(qstmt, 0));
/* Clean up */ cleanup(db, qstmt, 0);
sqlite3_finalize(qstmt);
sqlite3_close(db);
/* Check the password */ /* Check the password */
comphash = crypt(pw, pwhash); comphash = crypt(pw, pwhash);
@ -62,22 +81,11 @@ int insertuser(char *uname, char *pw, char *email) {
sqlite3 *db; sqlite3 *db;
sqlite3_stmt *qstmt; sqlite3_stmt *qstmt;
status = sqlite3_open(DATABASE, &db); opendb(&db, &qstmt, checkquery);
if (status) {
sqlite3_close(db);
return 3;
}
/* Check for existing account in the same transaction with creating it. */ /* Check for existing account in the same transaction with creating it. */
status = sqlite3_exec(db, "BEGIN;", NULL, NULL, NULL); status = sqlite3_exec(db, "BEGIN;", NULL, NULL, NULL);
if (status) { if (status)
sqlite3_close(db); cleanup(db, qstmt, 3);
return 3;
}
sqlite3_prepare_v2(db, checkquery, -1, &qstmt, NULL);
if (qstmt == NULL) {
sqlite3_close(db);
return 3;
}
sqlite3_bind_text(qstmt, 1, uname, -1, SQLITE_TRANSIENT); sqlite3_bind_text(qstmt, 1, uname, -1, SQLITE_TRANSIENT);
status = sqlite3_step(qstmt); status = sqlite3_step(qstmt);
if (status != SQLITE_DONE) { if (status != SQLITE_DONE) {
@ -90,51 +98,98 @@ int insertuser(char *uname, char *pw, char *email) {
/* The username doesn't exist yet, so create a new account. */ /* The username doesn't exist yet, so create a new account. */
sqlite3_finalize(qstmt); sqlite3_finalize(qstmt);
sqlite3_prepare_v2(db, addquery, -1, &qstmt, NULL); sqlite3_prepare_v2(db, addquery, -1, &qstmt, NULL);
if (qstmt == NULL) { if (qstmt == NULL)
sqlite3_close(db); cleanup(db, NULL, 3);
return 3;
}
sqlite3_bind_text(qstmt, 1, uname, -1, SQLITE_TRANSIENT); sqlite3_bind_text(qstmt, 1, uname, -1, SQLITE_TRANSIENT);
sqlite3_bind_text(qstmt, 2, strdup(crypt(pw, pw)), -1, free); sqlite3_bind_text(qstmt, 2, strdup(crypt(pw, pw)), -1, free);
sqlite3_bind_text(qstmt, 3, email, -1, SQLITE_TRANSIENT); sqlite3_bind_text(qstmt, 3, email, -1, SQLITE_TRANSIENT);
status = sqlite3_step(qstmt); status = sqlite3_step(qstmt);
if (status != SQLITE_DONE) { if (status != SQLITE_DONE)
sqlite3_finalize(qstmt); cleanup(db, qstmt, 3);
sqlite3_close(db);
return 3;
}
status = sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL); status = sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL);
sqlite3_finalize(qstmt); cleanup(db, qstmt, 0);
sqlite3_close(db);
return status; return status;
} }
int getmail(char *uname) {
char *mailquery = "SELECT email FROM dglusers WHERE username = ?;";
int status;
sqlite3 *db;
sqlite3_stmt *qstmt;
opendb(&db, &qstmt, mailquery);
status = sqlite3_bind_text(qstmt, 1, uname, -1, SQLITE_TRANSIENT);
if (status)
cleanup(db, qstmt, 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;
}
printf("%s\n", sqlite3_column_text(qstmt, 0));
cleanup(db, qstmt, 0);
return 0;
}
int setmail(char *uname, char *newmail) {
char *setquery = "UPDATE dglusers SET email = ? WHERE username = ?;";
sqlite3 *db;
sqlite3_stmt *qstmt;
int status;
opendb(&db, &qstmt, setquery);
status = sqlite3_bind_text(qstmt, 2, uname, -1, SQLITE_TRANSIENT);
if (status)
cleanup(db, qstmt, 3);
status = sqlite3_bind_text(qstmt, 1, newmail, -1, SQLITE_TRANSIENT);
if (status)
cleanup(db, qstmt, 3);
status = sqlite3_step(qstmt);
if (status != SQLITE_DONE)
cleanup(db, qstmt, 3);
cleanup(db, qstmt, 0);
return 0;
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
char ibuf[IBUFSIZE], *uname, *pw, *email; char ibuf[IBUFSIZE], *uname, *line1, *line2;
char *cptr; // Utility pointer char *cptr; // Utility pointer
int status; int status;
/* Read in the username and password */ /* Read in the username and password */
fgets(ibuf, IBUFSIZE, stdin); fgets(ibuf, IBUFSIZE, stdin);
uname = ibuf; uname = ibuf;
pw = strchr(uname, '\n'); line1 = strchr(uname, '\n');
if (pw == NULL) if (line1 == NULL)
exit(4); /* Truncated */ exit(4); /* Truncated */
*pw = '\0'; *line1 = '\0';
pw++; if (argc == 1 || strcmp(argv[1], "getmail")) {
fgets(pw, IBUFSIZE - (pw - ibuf), stdin); line1++;
if (pw[strlen(pw) - 1] == '\n') fgets(line1, IBUFSIZE - (line1 - ibuf), stdin);
pw[strlen(pw) - 1] = '\0'; if (line1[strlen(line1) - 1] == '\n')
line1[strlen(line1) - 1] = '\0';
else else
exit(4); /* Truncated */ exit(4); /* Truncated */
}
if (argc > 1 && !strcmp(argv[1], "setmail")) {
/* E-mail, sanitize */
for (cptr = line1; *cptr != '\0'; cptr++) {
if (!isalnum(*cptr) && !strchr("@._-", *cptr)) {
exit(4);
}
}
}
if (argc > 1 && !strcmp(argv[1], "register")) { if (argc > 1 && !strcmp(argv[1], "register")) {
email = pw + strlen(pw) + 1; line2 = line1 + strlen(line1) + 1;
fgets(email, IBUFSIZE - (email - ibuf), stdin); fgets(line2, IBUFSIZE - (line2 - ibuf), stdin);
if (email[strlen(email) - 1] == '\n') if (line2[strlen(line2) - 1] == '\n')
email[strlen(email) - 1] = '\0'; line2[strlen(line2) - 1] = '\0';
else else
exit(4); exit(4);
for (cptr = email; *cptr != '\0'; cptr++) { for (cptr = line2; *cptr != '\0'; cptr++) {
if (!isalnum(*cptr) && !strchr("@._-", *cptr)) { if (!isalnum(*cptr) && !strchr("@._-", *cptr)) {
exit(4); exit(4);
} }
@ -147,9 +202,15 @@ int main(int argc, char *argv[]) {
} }
} }
if (argc == 1 || !strcmp(argv[1], "check")) if (argc == 1 || !strcmp(argv[1], "check"))
status = check(uname, pw); status = check(uname, line1);
else if (!strcmp(argv[1], "register")) { else if (!strcmp(argv[1], "register")) {
status = insertuser(uname, pw, email); status = insertuser(uname, line1, line2);
}
else if (!strcmp(argv[1], "getmail")) {
status = getmail(uname);
}
else if (!strcmp(argv[1], "setmail")) {
status = setmail(uname, line1);
} }
else else
status = 127; status = 127;