comparison sqlickrypt.c @ 18:59ea628abb81

sqlickrypt.c: add the ability to register new users. When sqlickrypt is run with the option "register", it expects a username, password, and email, and adds them to the database if the username is not already in use.
author John "Elwin" Edwards <elwin@sdf.org>
date Mon, 21 May 2012 21:40:56 -0700
parents d3e3d6b4016b
children 9d5da43c0e83
comparison
equal deleted inserted replaced
17:d3e3d6b4016b 18:59ea628abb81
5 #include <sqlite3.h> 5 #include <sqlite3.h>
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 11
11 int xcallback(void *targ, int ncols, char **vals, char **colnames) { 12 int xcallback(void *targ, int ncols, char **vals, char **colnames) {
12 char *pws; 13 char *pws;
13 int j; 14 int j;
14 pws = *((char **) targ); 15 pws = *((char **) targ);
20 } 21 }
21 /* Otherwise, this isn't the first row. */ 22 /* Otherwise, this isn't the first row. */
22 return 0; 23 return 0;
23 } 24 }
24 25
25 int main(int argc, char *argv[]) { 26 /* Simple callback, for checking if there are any matches. */
26 char ibuf[160], *uname, *pw, *pwhash = NULL, *comphash; 27 int searchcallback(void *targ, int ncols, char **vals, char **colnames) {
28 *((int *) targ) = 1;
29 return 0;
30 }
31
32 int check(char *uname, char *pw) {
27 char finduser_sql[160]; 33 char finduser_sql[160];
28 char *cptr; // Utility pointer 34 char *pwhash = NULL, *comphash;
35 int status;
29 sqlite3 *db; 36 sqlite3 *db;
30 int status;
31 37
32 /* Read in the username and password */
33 fgets(ibuf, 160, stdin);
34 uname = ibuf;
35 pw = strchr(uname, '\n');
36 if (pw == NULL)
37 exit(4); /* Truncated */
38 *pw = '\0';
39 pw++;
40 fgets(pw, 160 - (pw - ibuf), stdin);
41 if (pw[strlen(pw) - 1] == '\n')
42 pw[strlen(pw) - 1] = '\0';
43 else
44 exit(4); /* Truncated */
45 /* Sanitize the username, because it gets put into a query. */
46 for (cptr = uname; *cptr != '\0'; cptr++) {
47 if (!isalnum(*cptr)) {
48 exit(4);
49 }
50 }
51 /* Construct the query */
52 strcpy(finduser_sql, "SELECT * FROM dglusers WHERE username='"); 38 strcpy(finduser_sql, "SELECT * FROM dglusers WHERE username='");
53 strncat(finduser_sql, uname, 40); 39 strncat(finduser_sql, uname, 40);
54 strcat(finduser_sql, "';"); 40 strcat(finduser_sql, "';");
55 41
56 status = sqlite3_open(DATABASE, &db); 42 status = sqlite3_open(DATABASE, &db);
59 return 1; 45 return 1;
60 } 46 }
61 sqlite3_exec(db, finduser_sql, xcallback, (void *) &pwhash, NULL); 47 sqlite3_exec(db, finduser_sql, xcallback, (void *) &pwhash, NULL);
62 48
63 sqlite3_close(db); 49 sqlite3_close(db);
64
65 /* Now check the password. */ 50 /* Now check the password. */
66 if (pwhash == NULL) { 51 if (pwhash == NULL) {
67 return 2; 52 return 2;
68 } 53 }
69 comphash = crypt(pw, pwhash); 54 comphash = crypt(pw, pwhash);
70 if (!strcmp(pwhash, comphash)) 55 if (!strcmp(pwhash, comphash))
71 return 0; 56 return 0;
72 return 1; 57 return 1;
73 } 58 }
59
60 int insertuser(char *uname, char *pw, char *email) {
61 char finduser_sql[160];
62 int status;
63 sqlite3 *db;
64
65 strcpy(finduser_sql, "BEGIN; SELECT * FROM dglusers WHERE username='");
66 strncat(finduser_sql, uname, 40);
67 strcat(finduser_sql, "';");
68
69 status = sqlite3_open(DATABASE, &db);
70 if (status) {
71 sqlite3_close(db);
72 return 1;
73 }
74 status = 0;
75 sqlite3_exec(db, finduser_sql, searchcallback, (void *) &status, NULL);
76 if (!status) {
77 /* FIXME This is ugly, and email is unsanitzed. */
78 strcpy(finduser_sql, "INSERT INTO dglusers (username, password, email) VALUES ('");
79 strncat(finduser_sql, uname, 20);
80 strcat(finduser_sql, "', '");
81 strcat(finduser_sql, crypt(pw, pw));
82 strcat(finduser_sql, "', '");
83 strncat(finduser_sql, email, 40);
84 strcat(finduser_sql, "');");
85 sqlite3_exec(db, finduser_sql, NULL, NULL, NULL);
86 }
87 sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL);
88 sqlite3_close(db);
89 return status;
90 }
91
92 int main(int argc, char *argv[]) {
93 char ibuf[IBUFSIZE], *uname, *pw, *email;
94 char *cptr; // Utility pointer
95 int status;
96
97 /* Read in the username and password */
98 fgets(ibuf, IBUFSIZE, stdin);
99 uname = ibuf;
100 pw = strchr(uname, '\n');
101 if (pw == NULL)
102 exit(4); /* Truncated */
103 *pw = '\0';
104 pw++;
105 fgets(pw, IBUFSIZE - (pw - ibuf), stdin);
106 if (pw[strlen(pw) - 1] == '\n')
107 pw[strlen(pw) - 1] = '\0';
108 else
109 exit(4); /* Truncated */
110 if (argc > 1 && !strcmp(argv[1], "register")) {
111 email = pw + strlen(pw) + 1;
112 fgets(email, IBUFSIZE - (email - ibuf), stdin);
113 if (email[strlen(email) - 1] == '\n')
114 email[strlen(email) - 1] = '\0';
115 else
116 exit(4);
117 for (cptr = email; *cptr != '\0'; cptr++) {
118 if (!isalnum(*cptr) && !strchr("@._-", *cptr)) {
119 exit(4);
120 }
121 }
122 }
123 /* Sanitize the username, because it gets put into a query. */
124 for (cptr = uname; *cptr != '\0'; cptr++) {
125 if (!isalnum(*cptr)) {
126 exit(4);
127 }
128 }
129 if (argc == 1 || !strcmp(argv[1], "check"))
130 status = check(uname, pw);
131 else if (!strcmp(argv[1], "register")) {
132 status = insertuser(uname, pw, email);
133 }
134 else
135 status = 127;
136 return status;
137 }