From: nishi Date: Wed, 8 May 2024 05:16:28 +0000 (+0000) Subject: uhm X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=21709138b140e15bdd8f5905aa339b0181fdf298;p=mandshurica.git uhm git-svn-id: file:///raid/svn-main/nishi-mandshurica/trunk@65 f982e544-4a7d-3444-ad1a-fde59a2a69f1 --- diff --git a/Mandshurica/config.c b/Mandshurica/config.c index 740652b..74ab251 100644 --- a/Mandshurica/config.c +++ b/Mandshurica/config.c @@ -207,6 +207,7 @@ int mandshurica_create_config(const char* path) { fprintf(f, "# Generated by Mandshurica " MANDSHURICA_VERSION "\n"); fprintf(f, "ServerRoot %s\n", PREFIX); fprintf(f, "\n"); + fprintf(f, "Set LoginDB %s/login.db\n", PREFIX); fprintf(f, "Set CookieDB %s/passwd.db\n", PREFIX); fprintf(f, "Set HTTPPort 1024\n"); fprintf(f, "Set HTTPRoot %s\n", WEBROOT_PREFIX); diff --git a/Mandshurica/main.c b/Mandshurica/main.c index a9cbfd8..2b844b4 100644 --- a/Mandshurica/main.c +++ b/Mandshurica/main.c @@ -40,6 +40,7 @@ #include #include #include +#include extern struct mandshurica_config config; @@ -47,6 +48,7 @@ extern int nloaded_mods; extern int nerror_mods; int main(int argc, char** argv) { + srand(time(NULL)); int i; bool loaded_config = false; mandshurica_log(MS_INFO, "Mandshurica " MANDSHURICA_VERSION " Copyright (C) 2024 Nishi"); diff --git a/Module/cookie.c b/Module/cookie.c index 7888a61..ed0bcd8 100644 --- a/Module/cookie.c +++ b/Module/cookie.c @@ -41,6 +41,7 @@ const char mod_type[] = MS_MOD_AUTH; const char mod_auth_type[] = "Cookie"; const char mod_http_path[] = "/cookie-login"; +const char mod_http_path2[] = "/cookie-logout"; struct mandshurica_config* config; @@ -62,25 +63,57 @@ int mod_init(struct mandshurica_config* _config) { return 0; } +#define TOKEN_LENGTH 16 +/* 47672401706823533450263330816 tokens are enoguh */ + +char* generate_token(const char* username){ + struct ms_db* db = mandshurica_db_open(config->mandshurica_get_param("LoginDB")); +generate_again:; + char* token = NULL; + if(token != NULL) free(token); + token = malloc(TOKEN_LENGTH + 1); + token[TOKEN_LENGTH] = 0; + int i; + const char ch[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + for(i = 0; i < TOKEN_LENGTH; i++){ + token[i] = ch[rand() % (26 + 26 + 10)]; + } + char* t = mandshurica_db_get(db, token); + if(t != NULL){ + free(t); + goto generate_again; + } + mandshurica_db_write(db, token, username); + mandshurica_db_close(db); + return token; +} + int mod_auth(const char* username, const char* password, char** ptr) { - *ptr = NULL; - struct ms_db* db = mandshurica_db_open(config->mandshurica_get_param("CookieDB")); - if(db != NULL) { - char* pwd = mandshurica_db_get(db, username); - if(pwd == NULL) { - mandshurica_db_close(db); - return MS_AUTH_ERROR; - } else { - char* sh = config->mandshurica_sha512(password); - if(strcmp(sh, pwd) == 0) { + bool login = false; + if(*ptr != NULL){ + if(strcmp(*ptr, "/cookie-login") == 0) login = true; + free(*ptr); + } + if(login){ + *ptr = NULL; + struct ms_db* db = mandshurica_db_open(config->mandshurica_get_param("CookieDB")); + if(db != NULL) { + char* pwd = mandshurica_db_get(db, username); + if(pwd == NULL) { + mandshurica_db_close(db); + return MS_AUTH_ERROR; + } else { + char* sh = config->mandshurica_sha512(password); + if(strcmp(sh, pwd) == 0) { + free(sh); + *ptr = generate_token(username); + return MS_AUTH_OK; + } free(sh); - *ptr = mandshurica_strdup("what"); - return MS_AUTH_OK; + return MS_AUTH_FAIL; } - free(sh); - return MS_AUTH_FAIL; + mandshurica_db_close(db); } - mandshurica_db_close(db); + return MS_AUTH_ERROR; } - return MS_AUTH_ERROR; } diff --git a/Module/http.c b/Module/http.c index caf4681..e9b9f06 100644 --- a/Module/http.c +++ b/Module/http.c @@ -30,6 +30,7 @@ #include "../Mandshurica/mandshurica.h" +#include "../Mandshurica/ms_db.h" #include "../Mandshurica/ms_log.h" #include "../Mandshurica/ms_util.h" @@ -53,6 +54,38 @@ const char mod_type[] = MS_MOD_SRV; struct mandshurica_config* config; +char* get_cookie(const char* cookie, const char* key){ + char* str = mandshurica_strdup(cookie); + int i; + int start = 0; + for(i = 0; str[i] != 0; i++){ + if(str[i] == '='){ + char* k = malloc(i - start + 1); + k[i] = 0; + memcpy(k, str + start, i - start); + if(strcmp(key, k) == 0){ + int epos = i + 1; + for(; str[i] != 0 && str[i] != ';'; i++); + char* v = malloc(i - epos + 1); + v[i] = 0; + memcpy(v, str + epos, i - epos); + for(; str[i] != 0 && str[i] != ' ' && str[i] != '\t'; i++); + start = i + 1; + free(k); + free(str); + return v; + }else{ + for(; str[i] != 0 && str[i] != ';'; i++); + for(; str[i] != 0 && str[i] != ' ' && str[i] != '\t'; i++); + start = i + 1; + } + free(k); + } + } + free(str); + return NULL; +} + int mod_init(struct mandshurica_config* _config) { config = _config; config->mandshurica_log(MS_INFO, "HTTP Module init"); @@ -131,6 +164,7 @@ void http_handler(int sock) { struct ms_param param; param.login = false; cbuf[1] = 0; + char* cookie = NULL; while(true) { int state; int count; @@ -188,160 +222,234 @@ void http_handler(int sock) { send(sock, "Content-Length: 0\r\n", 19, 0); send(sock, "\r\n", 2, 0); } else if(form) { - bool sent = false; - for(j = 0; (*config->libs)[j] != NULL; j++) { - const char* type = (const char*)dlsym((*config->libs)[j]->lib, "mod_type"); - if(strcmp(type, MS_MOD_AUTH) == 0) { - const char* httppath = (const char*)dlsym((*config->libs)[j]->lib, "mod_http_path"); - if(httppath != NULL) { - if(strcmp(httppath, path) == 0) { - int (*mod_auth)(const char*, const char*, char**) = (int (*)(const char*, const char*, char**))dlsym((*config->libs)[j]->lib, "mod_auth"); - char* usr = mandshurica_parse_form(postbuf, "username"); - char* pwd = mandshurica_parse_form(postbuf, "password"); - if(usr != NULL && pwd != NULL) { - char* token; - int res = mod_auth(usr, pwd, &token); - if(res == MS_AUTH_OK) { - char* type; - uint64_t len; - char* data = NULL; - char* s; - - struct stat st; - char* lastmod = NULL; - const char* pth = mandshurica_strcat(webroot, "/login-success/"); - if(stat(pth, &st) == 0) { - if(S_ISDIR(st.st_mode)) { - if(data == NULL) { - s = mandshurica_strcat(pth, "/index.html.tmpl"); - data = config->mandshurica_load(s, &type, &lastmod, &len, param); - free(s); + if(strcmp(path, "/cookie-logout") == 0){ + bool did_logout = false; + if(cookie != NULL){ + char* token = get_cookie(cookie, "TOKEN"); + if(token != NULL){ + struct ms_db* db = mandshurica_db_open(config->mandshurica_get_param("LoginDB")); + char* usr = mandshurica_db_get(db, token); + if(usr != NULL){ + free(usr); + did_logout = true; + } + mandshurica_db_close(db); + } + free(token); + } + if(did_logout){ + char* type; + uint64_t len; + char* data = NULL; + char* s; + + struct stat st; + char* lastmod = NULL; + const char* pth = mandshurica_strcat(webroot, "/logout-success/"); + if(stat(pth, &st) == 0) { + if(S_ISDIR(st.st_mode)) { + if(data == NULL) { + s = mandshurica_strcat(pth, "/index.html.tmpl"); + data = config->mandshurica_load(s, &type, &lastmod, &len, param); + free(s); + } + if(data == NULL) { + s = mandshurica_strcat(pth, "/index.html"); + data = config->mandshurica_load(s, &type, &lastmod, &len, param); + free(s); + } + } else { + data = config->mandshurica_load(pth, &type, &lastmod, &len, param); + } + } + if(data != NULL) { + send(sock, "HTTP/1.1 200 OK\r\n", 9 + 8, 0); + send(sock, "Connection: keep-alive\r\n", 24, 0); + send(sock, "Content-Type: ", 14, 0); + send(sock, type, strlen(type), 0); + send(sock, "\r\n", 2, 0); + if(lastmod != NULL) { + send(sock, "Last-Modified: ", 15, 0); + send(sock, lastmod, strlen(lastmod), 0); + send(sock, "\r\n", 2, 0); + free(lastmod); + } + send(sock, "Content-Length: ", 16, 0); + + char* lenstr = malloc(513); + sprintf(lenstr, "%llu", len); + send(sock, lenstr, strlen(lenstr), 0); + free(lenstr); + + send(sock, "\r\n", 2, 0); + send(sock, "\r\n", 2, 0); + send(sock, data, len, 0); + free(type); + } else { + send(sock, "HTTP/1.1 200 OK\r\n", 9 + 8, 0); + send(sock, "Connection: keep-alive\r\n", 24, 0); + send(sock, "Content-Length: 0\r\n", 19, 0); + send(sock, "\r\n", 2, 0); + send(sock, "\r\n", 2, 0); + } + } + }else{ + bool sent = false; + for(j = 0; (*config->libs)[j] != NULL; j++) { + const char* type = (const char*)dlsym((*config->libs)[j]->lib, "mod_type"); + if(strcmp(type, MS_MOD_AUTH) == 0) { + const char* httppath = (const char*)dlsym((*config->libs)[j]->lib, "mod_http_path"); + run_again:; + if(httppath != NULL) { + if(strcmp(httppath, path) == 0) { + int (*mod_auth)(const char*, const char*, char**) = (int (*)(const char*, const char*, char**))dlsym((*config->libs)[j]->lib, "mod_auth"); + char* usr = mandshurica_parse_form(postbuf, "username"); + char* pwd = mandshurica_parse_form(postbuf, "password"); + if(usr != NULL && pwd != NULL) { + char* token = mandshurica_strdup(httppath); + int res = mod_auth(usr, pwd, &token); + if(res == MS_AUTH_OK) { + char* type; + uint64_t len; + char* data = NULL; + char* s; + + struct stat st; + char* lastmod = NULL; + const char* pth = mandshurica_strcat(webroot, "/login-success/"); + if(stat(pth, &st) == 0) { + if(S_ISDIR(st.st_mode)) { + if(data == NULL) { + s = mandshurica_strcat(pth, "/index.html.tmpl"); + data = config->mandshurica_load(s, &type, &lastmod, &len, param); + free(s); + } + if(data == NULL) { + s = mandshurica_strcat(pth, "/index.html"); + data = config->mandshurica_load(s, &type, &lastmod, &len, param); + free(s); + } + } else { + data = config->mandshurica_load(pth, &type, &lastmod, &len, param); } - if(data == NULL) { - s = mandshurica_strcat(pth, "/index.html"); - data = config->mandshurica_load(s, &type, &lastmod, &len, param); - free(s); + } + if(data != NULL) { + send(sock, "HTTP/1.1 200 OK\r\n", 9 + 8, 0); + send(sock, "Connection: keep-alive\r\n", 24, 0); + send(sock, "Content-Type: ", 14, 0); + send(sock, type, strlen(type), 0); + send(sock, "\r\n", 2, 0); + if(lastmod != NULL) { + send(sock, "Last-Modified: ", 15, 0); + send(sock, lastmod, strlen(lastmod), 0); + send(sock, "\r\n", 2, 0); + free(lastmod); } + send(sock, "Content-Length: ", 16, 0); + + char* lenstr = malloc(513); + sprintf(lenstr, "%llu", len); + send(sock, lenstr, strlen(lenstr), 0); + free(lenstr); + + send(sock, "\r\n", 2, 0); + send(sock, "Set-Cookie: ", 11, 0); + send(sock, "TOKEN=", 6, 0); + send(sock, token, strlen(token), 0); + send(sock, "; HttpOnly", 10, 0); + send(sock, "\r\n", 2, 0); + send(sock, "\r\n", 2, 0); + send(sock, data, len, 0); + free(type); } else { - data = config->mandshurica_load(pth, &type, &lastmod, &len, param); - } - } - if(data != NULL) { - send(sock, "HTTP/1.1 200 OK\r\n", 9 + 8, 0); - send(sock, "Connection: keep-alive\r\n", 24, 0); - send(sock, "Content-Type: ", 14, 0); - send(sock, type, strlen(type), 0); - send(sock, "\r\n", 2, 0); - if(lastmod != NULL) { - send(sock, "Last-Modified: ", 15, 0); - send(sock, lastmod, strlen(lastmod), 0); + send(sock, "HTTP/1.1 200 OK\r\n", 9 + 8, 0); + send(sock, "Connection: keep-alive\r\n", 24, 0); + send(sock, "Content-Length: 0\r\n", 19, 0); + send(sock, "Set-Cookie: ", 11, 0); + send(sock, "TOKEN=", 6, 0); + send(sock, token, strlen(token), 0); + send(sock, "; HttpOnly", 10, 0); + send(sock, "\r\n", 2, 0); send(sock, "\r\n", 2, 0); - free(lastmod); } - send(sock, "Content-Length: ", 16, 0); - - char* lenstr = malloc(513); - sprintf(lenstr, "%llu", len); - send(sock, lenstr, strlen(lenstr), 0); - free(lenstr); - - send(sock, "\r\n", 2, 0); - send(sock, "Set-Cookie: ", 11, 0); - send(sock, "TOKEN=", 6, 0); - send(sock, token, strlen(token), 0); - send(sock, "; HttpOnly", 10, 0); - send(sock, "\r\n", 2, 0); - send(sock, "\r\n", 2, 0); - send(sock, data, len, 0); - free(type); - } else { - send(sock, "HTTP/1.1 200 OK\r\n", 9 + 8, 0); + free(token); + } else if(res == MS_AUTH_ERROR) { + send(sock, "HTTP/1.1 400 Bad Request\r\n", 17 + 9, 0); send(sock, "Connection: keep-alive\r\n", 24, 0); send(sock, "Content-Length: 0\r\n", 19, 0); - send(sock, "Set-Cookie: ", 11, 0); - send(sock, "TOKEN=", 6, 0); - send(sock, token, strlen(token), 0); - send(sock, "; HttpOnly", 10, 0); - send(sock, "\r\n", 2, 0); send(sock, "\r\n", 2, 0); - } - free(token); - } else if(res == MS_AUTH_ERROR) { - send(sock, "HTTP/1.1 400 Bad Request\r\n", 17 + 9, 0); - send(sock, "Connection: keep-alive\r\n", 24, 0); - send(sock, "Content-Length: 0\r\n", 19, 0); - send(sock, "\r\n", 2, 0); - } else if(res == MS_AUTH_FAIL) { - char* type; - uint64_t len; - char* data = NULL; - char* s; - - struct stat st; - char* lastmod = NULL; - const char* pth = mandshurica_strcat(webroot, "/login-fail/"); - if(stat(pth, &st) == 0) { - if(S_ISDIR(st.st_mode)) { - if(data == NULL) { - s = mandshurica_strcat(pth, "/index.html.tmpl"); - data = config->mandshurica_load(s, &type, &lastmod, &len, param); - free(s); + } else if(res == MS_AUTH_FAIL) { + char* type; + uint64_t len; + char* data = NULL; + char* s; + + struct stat st; + char* lastmod = NULL; + const char* pth = mandshurica_strcat(webroot, "/login-fail/"); + if(stat(pth, &st) == 0) { + if(S_ISDIR(st.st_mode)) { + if(data == NULL) { + s = mandshurica_strcat(pth, "/index.html.tmpl"); + data = config->mandshurica_load(s, &type, &lastmod, &len, param); + free(s); + } + if(data == NULL) { + s = mandshurica_strcat(pth, "/index.html"); + data = config->mandshurica_load(s, &type, &lastmod, &len, param); + free(s); + } + } else { + data = config->mandshurica_load(pth, &type, &lastmod, &len, param); } - if(data == NULL) { - s = mandshurica_strcat(pth, "/index.html"); - data = config->mandshurica_load(s, &type, &lastmod, &len, param); - free(s); + } + if(data != NULL) { + send(sock, "HTTP/1.1 403 Forbidden\r\n", 24, 0); + send(sock, "Connection: keep-alive\r\n", 24, 0); + send(sock, "Content-Type: ", 14, 0); + send(sock, type, strlen(type), 0); + send(sock, "\r\n", 2, 0); + if(lastmod != NULL) { + send(sock, "Last-Modified: ", 15, 0); + send(sock, lastmod, strlen(lastmod), 0); + send(sock, "\r\n", 2, 0); + free(lastmod); } + send(sock, "Content-Length: ", 16, 0); + + char* lenstr = malloc(513); + sprintf(lenstr, "%llu", len); + send(sock, lenstr, strlen(lenstr), 0); + free(lenstr); + + send(sock, "\r\n", 2, 0); + send(sock, "\r\n", 2, 0); + send(sock, data, len, 0); + free(type); } else { - data = config->mandshurica_load(pth, &type, &lastmod, &len, param); - } - } - if(data != NULL) { - send(sock, "HTTP/1.1 403 Forbidden\r\n", 24, 0); - send(sock, "Connection: keep-alive\r\n", 24, 0); - send(sock, "Content-Type: ", 14, 0); - send(sock, type, strlen(type), 0); - send(sock, "\r\n", 2, 0); - if(lastmod != NULL) { - send(sock, "Last-Modified: ", 15, 0); - send(sock, lastmod, strlen(lastmod), 0); + send(sock, "HTTP/1.1 403 Forbidden\r\n", 24, 0); + send(sock, "Connection: keep-alive\r\n", 24, 0); + send(sock, "Content-Length: 0\r\n", 19, 0); send(sock, "\r\n", 2, 0); - free(lastmod); } - send(sock, "Content-Length: ", 16, 0); - - char* lenstr = malloc(513); - sprintf(lenstr, "%llu", len); - send(sock, lenstr, strlen(lenstr), 0); - free(lenstr); - - send(sock, "\r\n", 2, 0); - send(sock, "\r\n", 2, 0); - send(sock, data, len, 0); - free(type); - } else { - send(sock, "HTTP/1.1 403 Forbidden\r\n", 24, 0); - send(sock, "Connection: keep-alive\r\n", 24, 0); - send(sock, "Content-Length: 0\r\n", 19, 0); - send(sock, "\r\n", 2, 0); } + } else { + send(sock, "HTTP/1.1 400 Bad Request\r\n", 17 + 9, 0); + send(sock, "Connection: keep-alive\r\n", 24, 0); + send(sock, "Content-Length: 0\r\n", 19, 0); + send(sock, "\r\n", 2, 0); } - } else { - send(sock, "HTTP/1.1 400 Bad Request\r\n", 17 + 9, 0); - send(sock, "Connection: keep-alive\r\n", 24, 0); - send(sock, "Content-Length: 0\r\n", 19, 0); - send(sock, "\r\n", 2, 0); + sent = true; } - sent = true; } } } - } - if(!sent) { - send(sock, "HTTP/1.1 403 Forbidden\r\n", 15 + 9, 0); - send(sock, "Connection: keep-alive\r\n", 24, 0); - send(sock, "Content-Length: 0\r\n", 19, 0); - send(sock, "\r\n", 2, 0); + if(!sent) { + send(sock, "HTTP/1.1 403 Forbidden\r\n", 15 + 9, 0); + send(sock, "Connection: keep-alive\r\n", 24, 0); + send(sock, "Content-Length: 0\r\n", 19, 0); + send(sock, "\r\n", 2, 0); + } } } else { send(sock, "HTTP/1.1 500 Internal Server Error\r\n", 15 + 9 + 12, 0); @@ -384,6 +492,25 @@ void http_handler(int sock) { } else if(buf[i] == '\n') { count++; if(count == 2) { + if(headers != NULL){ + int j; + for(j = 0; headers[j] != NULL; j += 2) { + if(mandshurica_strcaseequ(headers[j], "Cookie")){ + cookie = mandshurica_strdup(headers[j + 1]); + char* v = get_cookie(headers[j + 1], "TOKEN"); + if(v != NULL){ + struct ms_db* db = mandshurica_db_open(config->mandshurica_get_param("LoginDB")); + char* username = mandshurica_db_get(db, v); + if(username != NULL){ + param.login = true; + free(username); + } + mandshurica_db_close(db); + free(v); + } + } + } + } if(strcmp(method, "POST") == 0) { if(headers != NULL) { int j;