#include "rv_auth.h"
#include "rv_util.h"
+#include "rv_db.h"
+#include <string.h>
#include <stdio.h>
#include <stdlib.h>
}
char* rv_logged_in(void) {
- parse_cookie();
+ int i;
+ for(i = 0; cookie_entries[i] != NULL; i++) {
+ if(strcmp(cookie_entries[i]->key, "token") == 0) {
+ return rv_who_has_token(cookie_entries[i]->value);
+ break;
+ }
+ }
return NULL;
}
+void rv_save_login(const char* username) {
+ char* token = rv_new_token(username);
+ printf("Set-Cookie: token=%s; HttpOnly\r\n", token);
+ free(token);
+}
+
+void rv_init_auth(void) { parse_cookie(); }
+
void rv_free_auth(void) {
int i;
for(i = 0; cookie_entries[i] != NULL; i++) {
#include "../../config.h"
#include "rv_util.h"
+#include "rv_sha512.h"
#include <sqlite3.h>
+#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int count = 0;
+struct user {
+ char* username;
+ char* password;
+ bool valid;
+};
+
int sqlcount(void* param, int ncol, char** row, char** col) {
count = ncol;
- fprintf(stderr, "%d\n", ncol);
return 0;
}
-bool rv_has_user(const char* username) {
- char* err;
+int sqlgetpasswd(void* param, int ncol, char** row, char** col) {
+ struct user* user = (struct user*)param;
+ if(strcmp(row[0], user->username) == 0) {
+ char* hash = rv_sha512(user->password);
+ if(strcmp(row[1], hash) == 0) {
+ user->valid = true;
+ }
+ free(hash);
+ }
+ return 0;
+}
+
+char* escape_sql(const char* input) {
+ char* query = malloc(1);
+ query[0] = 0;
char cbuf[2];
cbuf[1] = 0;
- char* query = rv_strdup("select * from users where user = '");
int i;
- for(i = 0; username[i] != 0; i++) {
- if(username[i] == '\'') {
- cbuf[0] = username[i];
+ for(i = 0; input[i] != 0; i++) {
+ if(input[i] == '\'') {
+ cbuf[0] = input[i];
char* tmp = query;
tmp = rv_strcat(tmp, cbuf);
free(tmp);
- cbuf[0] = username[i];
+ cbuf[0] = input[i];
tmp = query;
query = rv_strcat(tmp, cbuf);
free(tmp);
} else {
- cbuf[0] = username[i];
+ cbuf[0] = input[i];
char* tmp = query;
query = rv_strcat(tmp, cbuf);
free(tmp);
}
}
- char* tmp = query;
- query = rv_strcat(tmp, "'");
+ return query;
+}
+
+bool rv_check_password(const char* username, const char* password) {
+ char* err;
+ int ret;
+ struct user user;
+ user.username = (char*)username;
+ user.password = (char*)password;
+ user.valid = false;
+ char* esc = escape_sql(username);
+ char* query = rv_strcat3("select * from users where user = '", esc, "'");
+ free(esc);
+ ret = sqlite3_exec(sql, query, sqlgetpasswd, (void*)&user, &err);
+ if(ret != SQLITE_OK) {
+ sqlite3_free(err);
+ }
+ return user.valid;
+}
+
+void rv_save_token(const char* username, const char* token) {
+ char* err;
+ int ret;
+ char* esc = escape_sql(username);
+ char* tmp = rv_strcat3("insert into tokens values('", esc, "', '");
+ char* query = rv_strcat3(tmp, token, "')");
free(tmp);
+ free(esc);
+ ret = sqlite3_exec(sql, query, NULL, NULL, &err);
+ free(query);
+ if(ret != SQLITE_OK) {
+ sqlite3_free(err);
+ }
+}
+
+char* has_username;
+
+int sqlget(void* param, int ncol, char** row, char** col) {
+ has_username = rv_strdup(row[0]);
+ return 0;
+}
+
+char* rv_who_has_token(const char* token) {
+ char* err;
+ char cbuf[2];
+ cbuf[1] = 0;
+ count = 0;
+ char* query = rv_strcat3("select * from tokens where token = '", token, "'");
+ int ret;
+ has_username = NULL;
+ ret = sqlite3_exec(sql, query, sqlget, (void*)token, &err);
+ free(query);
+ if(ret != SQLITE_OK) {
+ sqlite3_free(err);
+ return NULL;
+ }
+ return has_username;
+}
+
+bool rv_has_token(const char* token) {
+ char* err;
+ char cbuf[2];
+ cbuf[1] = 0;
+ count = 0;
+ char* query = rv_strcat3("select * from tokens where token = '", token, "'");
+ int ret;
+ ret = sqlite3_exec(sql, query, sqlcount, NULL, &err);
+ free(query);
+ if(ret != SQLITE_OK) {
+ sqlite3_free(err);
+ }
+ return count > 0;
+}
+
+bool rv_has_user(const char* username) {
+ char* err;
+ char cbuf[2];
+ cbuf[1] = 0;
+ count = 0;
+ char* esc = escape_sql(username);
+ char* query = rv_strcat3("select * from users where user = '", esc, "'");
+ free(esc);
int ret;
- fprintf(stderr, "%s\n", query);
ret = sqlite3_exec(sql, query, sqlcount, NULL, &err);
free(query);
if(ret != SQLITE_OK) {
#include "rv_auth.h"
#include <stdlib.h>
+#include <time.h>
char* postdata;
int main() {
+ srand(time(NULL));
rv_check_sanity();
rv_init_db();
rv_parse_query(getenv("QUERY_STRING"));
}
rv_parse_query(postdata);
rv_save_query('P');
+ rv_init_auth();
rv_process_page();
printf("Content-Type: text/html\r\n");
printf("\r\n");
char* rv_logged_in(void);
void rv_free_auth(void);
+void rv_init_auth(void);
+void rv_save_login(const char* username);
#endif
void rv_init_db(void);
void rv_close_db(void);
bool rv_has_user(const char* name);
+bool rv_check_password(const char* username, const char* password);
+void rv_save_token(const char* username, const char* token);
+char* rv_who_has_token(const char* token);
+bool rv_has_token(const char* token);
#endif
char* rv_strdup(const char* str);
char* rv_url_decode(const char* str);
void rv_error_http(void);
+char* rv_new_token(const char* username);
#endif
rv_load_query('P');
if(rv_get_query("username") == NULL || rv_get_query("password") == NULL) {
- add_data(&page, "Invalid form\n");
+ add_data(&page, "Invalid form.\n");
} else {
if(rv_has_user(rv_get_query("username"))) {
+ if(rv_check_password(rv_get_query("username"), rv_get_query("password"))) {
+ add_data(&page, "Welcome back.\n");
+ rv_save_login(rv_get_query("username"));
+ } else {
+ add_data(&page, "Invalid password.");
+ }
} else {
- add_data(&page, "User does not exist");
+ add_data(&page, "User does not exist.");
}
}
}
}
void render_stuff(void) {
+ char* user = rv_logged_in();
char* escaped;
add_data(&buffer, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n");
add_data(&buffer, "<html>\n");
add_data(&buffer, INSTANCE_ROOT);
add_data(&buffer, "/\">Home</a>\n");
add_data(&buffer, " </div>\n");
- add_data(&buffer, " <div>\n");
- add_data(&buffer, " <a href=\"");
- add_data(&buffer, INSTANCE_ROOT);
- add_data(&buffer, "/?page=login\">Login</a>\n");
- add_data(&buffer, " </div>\n");
+ if(user == NULL) {
+ add_data(&buffer, " <div>\n");
+ add_data(&buffer, " <a href=\"");
+ add_data(&buffer, INSTANCE_ROOT);
+ add_data(&buffer, "/?page=login\">Login</a>\n");
+ add_data(&buffer, " </div>\n");
+ }
add_data(&buffer, " </div>\n");
add_data(&buffer, " <div id=\"desc\">\n");
add_data(&buffer, " <div id=\"descinside\">\n");
add_data(&buffer, " </div>\n");
add_data(&buffer, " </body>\n");
add_data(&buffer, "</html>\n");
+ if(user != NULL) free(user);
}
#include "../config.h"
#include "rv_version.h"
+#include "rv_db.h"
#include <stdio.h>
#include <stdlib.h>
}
return r;
}
+
+char* rv_new_token(const char* username) {
+ const char tokenstr[] = "0123456789abcdefghijklmnopqrstuvwxyz";
+ char* token = malloc(17);
+ token[16] = 0;
+ int i;
+regenerate:
+ for(i = 0; i < 16; i++) {
+ token[i] = tokenstr[rand() % strlen(tokenstr)];
+ }
+ if(rv_has_token(token)) goto regenerate;
+ rv_save_token(username, token);
+ return token;
+}