From: Nishi Date: Tue, 20 Aug 2024 22:43:56 +0000 (+0000) Subject: login system works X-Git-Url: https://git.chaotic.ninja/gitweb/nishi/?a=commitdiff_plain;h=76afef5562dabe708ea00cab56f1eead5da77106;p=repoview.git login system works git-svn-id: file:///raid/svn-personal/repoview/trunk@5 7e8b2a19-8934-dd40-8cb3-db22cdd5a80f --- diff --git a/CGI/auth/cookie.c b/CGI/auth/cookie.c index a2924f9..c8240a6 100644 --- a/CGI/auth/cookie.c +++ b/CGI/auth/cookie.c @@ -3,7 +3,9 @@ #include "rv_auth.h" #include "rv_util.h" +#include "rv_db.h" +#include #include #include @@ -68,10 +70,24 @@ void parse_cookie(void) { } 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++) { diff --git a/CGI/db/sqlite.c b/CGI/db/sqlite.c index e2b1e2a..2f3ec87 100644 --- a/CGI/db/sqlite.c +++ b/CGI/db/sqlite.c @@ -5,9 +5,11 @@ #include "../../config.h" #include "rv_util.h" +#include "rv_sha512.h" #include +#include #include #include #include @@ -43,40 +45,135 @@ void rv_close_db(void) { sqlite3_close(sql); } 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) { diff --git a/CGI/main.c b/CGI/main.c index 2170c13..39da12f 100644 --- a/CGI/main.c +++ b/CGI/main.c @@ -12,10 +12,12 @@ #include "rv_auth.h" #include +#include char* postdata; int main() { + srand(time(NULL)); rv_check_sanity(); rv_init_db(); rv_parse_query(getenv("QUERY_STRING")); @@ -33,6 +35,7 @@ int main() { } rv_parse_query(postdata); rv_save_query('P'); + rv_init_auth(); rv_process_page(); printf("Content-Type: text/html\r\n"); printf("\r\n"); diff --git a/CGI/rv_auth.h b/CGI/rv_auth.h index c9595aa..857b855 100644 --- a/CGI/rv_auth.h +++ b/CGI/rv_auth.h @@ -7,5 +7,7 @@ char* rv_logged_in(void); void rv_free_auth(void); +void rv_init_auth(void); +void rv_save_login(const char* username); #endif diff --git a/CGI/rv_db.h b/CGI/rv_db.h index 307916a..1814222 100644 --- a/CGI/rv_db.h +++ b/CGI/rv_db.h @@ -8,5 +8,9 @@ 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 diff --git a/CGI/rv_util.h b/CGI/rv_util.h index c59e113..98ce5a5 100644 --- a/CGI/rv_util.h +++ b/CGI/rv_util.h @@ -14,5 +14,6 @@ char* rv_strcat3(const char* a, const char* b, const char* c); 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 diff --git a/CGI/theme/modern.c b/CGI/theme/modern.c index 2e8e730..fc96c01 100644 --- a/CGI/theme/modern.c +++ b/CGI/theme/modern.c @@ -59,11 +59,17 @@ void render_page(void) { 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."); } } } @@ -103,6 +109,7 @@ char* escape(const char* str) { } void render_stuff(void) { + char* user = rv_logged_in(); char* escaped; add_data(&buffer, "\n"); add_data(&buffer, "\n"); @@ -218,11 +225,13 @@ void render_stuff(void) { add_data(&buffer, INSTANCE_ROOT); add_data(&buffer, "/\">Home\n"); add_data(&buffer, " \n"); - add_data(&buffer, "
\n"); - add_data(&buffer, " Login\n"); - add_data(&buffer, "
\n"); + if(user == NULL) { + add_data(&buffer, "
\n"); + add_data(&buffer, " Login\n"); + add_data(&buffer, "
\n"); + } add_data(&buffer, " \n"); add_data(&buffer, "
\n"); add_data(&buffer, "
\n"); @@ -263,4 +272,5 @@ void render_stuff(void) { add_data(&buffer, "
\n"); add_data(&buffer, " \n"); add_data(&buffer, "\n"); + if(user != NULL) free(user); } diff --git a/CGI/util.c b/CGI/util.c index 7efe558..ef8d199 100644 --- a/CGI/util.c +++ b/CGI/util.c @@ -5,6 +5,7 @@ #include "../config.h" #include "rv_version.h" +#include "rv_db.h" #include #include @@ -73,3 +74,17 @@ char* rv_url_decode(const char* str) { } 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; +}