2012-05-20 15:52:07 -07:00
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <ctype.h>
|
|
|
|
|
#include <sqlite3.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <crypt.h>
|
|
|
|
|
|
|
|
|
|
#define DATABASE "/dgldir/dgamelaunch.db"
|
2012-05-21 21:40:56 -07:00
|
|
|
#define IBUFSIZE 200
|
2012-05-20 15:52:07 -07:00
|
|
|
|
2012-07-18 17:00:05 -07:00
|
|
|
/* 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;
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-21 21:40:56 -07:00
|
|
|
int check(char *uname, char *pw) {
|
2012-06-03 17:08:40 -07:00
|
|
|
char *pwhash, *comphash;
|
|
|
|
|
char *query = "SELECT password FROM dglusers WHERE username=?;";
|
2012-05-20 15:52:07 -07:00
|
|
|
int status;
|
2012-05-21 21:40:56 -07:00
|
|
|
sqlite3 *db;
|
2012-06-03 17:08:40 -07:00
|
|
|
sqlite3_stmt *qstmt;
|
2012-05-20 15:52:07 -07:00
|
|
|
|
2012-07-18 17:00:05 -07:00
|
|
|
opendb(&db, &qstmt, query);
|
2012-06-03 17:08:40 -07:00
|
|
|
status = sqlite3_bind_text(qstmt, 1, uname, -1, SQLITE_TRANSIENT);
|
2012-07-18 17:00:05 -07:00
|
|
|
if (status)
|
|
|
|
|
cleanup(db, qstmt, 3);
|
2012-06-03 17:08:40 -07:00
|
|
|
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;
|
2012-05-20 15:52:07 -07:00
|
|
|
}
|
2012-06-03 17:08:40 -07:00
|
|
|
pwhash = strdup((char *) sqlite3_column_text(qstmt, 0));
|
2012-07-18 17:00:05 -07:00
|
|
|
cleanup(db, qstmt, 0);
|
2012-06-03 17:08:40 -07:00
|
|
|
|
|
|
|
|
/* Check the password */
|
2012-05-20 15:52:07 -07:00
|
|
|
comphash = crypt(pw, pwhash);
|
|
|
|
|
if (!strcmp(pwhash, comphash))
|
2012-06-03 17:08:40 -07:00
|
|
|
status = 0;
|
|
|
|
|
else
|
|
|
|
|
status = 1;
|
|
|
|
|
free(pwhash);
|
|
|
|
|
return status;
|
2012-05-20 15:52:07 -07:00
|
|
|
}
|
2012-05-21 21:40:56 -07:00
|
|
|
|
|
|
|
|
int insertuser(char *uname, char *pw, char *email) {
|
2012-06-03 18:26:11 -07:00
|
|
|
char *checkquery = "SELECT * FROM dglusers WHERE username = ?;";
|
|
|
|
|
char *addquery = "INSERT INTO dglusers (username, password, email) VALUES (?, ?, ?);";
|
2012-05-21 21:40:56 -07:00
|
|
|
int status;
|
|
|
|
|
sqlite3 *db;
|
2012-06-03 18:26:11 -07:00
|
|
|
sqlite3_stmt *qstmt;
|
2012-05-21 21:40:56 -07:00
|
|
|
|
2012-07-18 17:00:05 -07:00
|
|
|
opendb(&db, &qstmt, checkquery);
|
2012-06-03 18:26:11 -07:00
|
|
|
/* Check for existing account in the same transaction with creating it. */
|
|
|
|
|
status = sqlite3_exec(db, "BEGIN;", NULL, NULL, NULL);
|
2012-07-18 17:00:05 -07:00
|
|
|
if (status)
|
|
|
|
|
cleanup(db, qstmt, 3);
|
2012-06-03 18:26:11 -07:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
/* The username doesn't exist yet, so create a new account. */
|
|
|
|
|
sqlite3_finalize(qstmt);
|
|
|
|
|
sqlite3_prepare_v2(db, addquery, -1, &qstmt, NULL);
|
2012-07-18 17:00:05 -07:00
|
|
|
if (qstmt == NULL)
|
|
|
|
|
cleanup(db, NULL, 3);
|
2012-06-03 18:26:11 -07:00
|
|
|
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);
|
2012-07-18 17:00:05 -07:00
|
|
|
if (status != SQLITE_DONE)
|
|
|
|
|
cleanup(db, qstmt, 3);
|
|
|
|
|
status = sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL);
|
|
|
|
|
cleanup(db, qstmt, 0);
|
|
|
|
|
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) {
|
2012-06-03 18:26:11 -07:00
|
|
|
sqlite3_finalize(qstmt);
|
|
|
|
|
sqlite3_close(db);
|
2012-07-18 17:00:05 -07:00
|
|
|
if (status == SQLITE_DONE)
|
|
|
|
|
return 2; /* User not found */
|
2012-06-03 18:26:11 -07:00
|
|
|
return 3;
|
|
|
|
|
}
|
2012-07-18 17:00:05 -07:00
|
|
|
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;
|
2012-05-21 21:40:56 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main(int argc, char *argv[]) {
|
2012-07-18 17:00:05 -07:00
|
|
|
char ibuf[IBUFSIZE], *uname, *line1, *line2;
|
2012-05-21 21:40:56 -07:00
|
|
|
char *cptr; // Utility pointer
|
|
|
|
|
int status;
|
|
|
|
|
|
|
|
|
|
/* Read in the username and password */
|
|
|
|
|
fgets(ibuf, IBUFSIZE, stdin);
|
|
|
|
|
uname = ibuf;
|
2012-07-18 17:00:05 -07:00
|
|
|
line1 = strchr(uname, '\n');
|
|
|
|
|
if (line1 == NULL)
|
2012-05-21 21:40:56 -07:00
|
|
|
exit(4); /* Truncated */
|
2012-07-18 17:00:05 -07:00
|
|
|
*line1 = '\0';
|
|
|
|
|
if (argc == 1 || strcmp(argv[1], "getmail")) {
|
|
|
|
|
line1++;
|
|
|
|
|
fgets(line1, IBUFSIZE - (line1 - ibuf), stdin);
|
|
|
|
|
if (line1[strlen(line1) - 1] == '\n')
|
|
|
|
|
line1[strlen(line1) - 1] = '\0';
|
|
|
|
|
else
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-05-21 21:40:56 -07:00
|
|
|
if (argc > 1 && !strcmp(argv[1], "register")) {
|
2012-07-18 17:00:05 -07:00
|
|
|
line2 = line1 + strlen(line1) + 1;
|
|
|
|
|
fgets(line2, IBUFSIZE - (line2 - ibuf), stdin);
|
|
|
|
|
if (line2[strlen(line2) - 1] == '\n')
|
|
|
|
|
line2[strlen(line2) - 1] = '\0';
|
2012-05-21 21:40:56 -07:00
|
|
|
else
|
|
|
|
|
exit(4);
|
2012-07-18 17:00:05 -07:00
|
|
|
for (cptr = line2; *cptr != '\0'; cptr++) {
|
2012-05-21 21:40:56 -07:00
|
|
|
if (!isalnum(*cptr) && !strchr("@._-", *cptr)) {
|
|
|
|
|
exit(4);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* Sanitize the username, because it gets put into a query. */
|
|
|
|
|
for (cptr = uname; *cptr != '\0'; cptr++) {
|
|
|
|
|
if (!isalnum(*cptr)) {
|
|
|
|
|
exit(4);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (argc == 1 || !strcmp(argv[1], "check"))
|
2012-07-18 17:00:05 -07:00
|
|
|
status = check(uname, line1);
|
2012-05-21 21:40:56 -07:00
|
|
|
else if (!strcmp(argv[1], "register")) {
|
2012-07-18 17:00:05 -07:00
|
|
|
status = insertuser(uname, line1, line2);
|
|
|
|
|
}
|
|
|
|
|
else if (!strcmp(argv[1], "getmail")) {
|
|
|
|
|
status = getmail(uname);
|
|
|
|
|
}
|
|
|
|
|
else if (!strcmp(argv[1], "setmail")) {
|
|
|
|
|
status = setmail(uname, line1);
|
2012-05-21 21:40:56 -07:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
status = 127;
|
|
|
|
|
return status;
|
|
|
|
|
}
|