From 11e89622d4a3ed6f45cb2f4fe9f2275d1550553e Mon Sep 17 00:00:00 2001 From: Cory McWilliams Date: Sun, 16 Feb 2025 14:07:14 -0500 Subject: [PATCH] security: Respect the autologin setting better. --- src/httpd.js.c | 146 +++++++++++++++++++++++-------------------------- 1 file changed, 69 insertions(+), 77 deletions(-) diff --git a/src/httpd.js.c b/src/httpd.js.c index ed7f3f13..7773947d 100644 --- a/src/httpd.js.c +++ b/src/httpd.js.c @@ -2166,56 +2166,48 @@ static void _httpd_endpoint_logout(tf_http_request_t* request) tf_http_respond(request, 303, headers, tf_countof(headers) / 2, NULL, 0); } -static bool _task_arg_is_mobile(tf_task_t* task) -{ - bool result = false; - JSContext* context = tf_task_get_context(task); - JSValue global = JS_GetGlobalObject(context); - JSValue tildefriends = JS_GetPropertyStr(context, global, "tildefriends"); - JSValue args = JS_GetPropertyStr(context, tildefriends, "args"); - JSValue mobile = JS_GetPropertyStr(context, args, "mobile"); - result = JS_ToBool(context, mobile) != 0; - JS_FreeValue(context, mobile); - JS_FreeValue(context, args); - JS_FreeValue(context, tildefriends); - JS_FreeValue(context, global); - return result; -} - typedef struct _auto_login_t { tf_http_request_t* request; + bool autologin; const char* users; } auto_login_t; static void _httpd_auto_login_work(tf_ssb_t* ssb, void* user_data) { auto_login_t* request = user_data; - request->users = tf_ssb_db_get_property(ssb, "auth", "users"); - if (request->users && strcmp(request->users, "[]") == 0) - { - tf_free((void*)request->users); - request->users = NULL; - } + sqlite3* db = tf_ssb_acquire_db_reader(ssb); + tf_ssb_db_get_global_setting_bool(db, "autologin", &request->autologin); + tf_ssb_release_db_reader(ssb, db); - if (!request->users) + if (request->autologin) { - JSMallocFunctions funcs = { 0 }; - tf_get_js_malloc_functions(&funcs); - JSRuntime* runtime = JS_NewRuntime2(&funcs, NULL); - JSContext* context = JS_NewContext(runtime); - static const char* k_account_name = "mobile"; - sqlite3* db = tf_ssb_acquire_db_writer(ssb); - bool registered = tf_ssb_db_register_account(tf_ssb_get_loop(ssb), db, context, k_account_name, k_account_name); - tf_ssb_release_db_writer(ssb, db); - if (registered) - { - _make_administrator_if_first(ssb, context, k_account_name, true); - } - JS_FreeContext(context); - JS_FreeRuntime(runtime); - request->users = tf_ssb_db_get_property(ssb, "auth", "users"); + if (request->users && strcmp(request->users, "[]") == 0) + { + tf_free((void*)request->users); + request->users = NULL; + } + + if (!request->users) + { + JSMallocFunctions funcs = { 0 }; + tf_get_js_malloc_functions(&funcs); + JSRuntime* runtime = JS_NewRuntime2(&funcs, NULL); + JSContext* context = JS_NewContext(runtime); + static const char* k_account_name = "mobile"; + sqlite3* db = tf_ssb_acquire_db_writer(ssb); + bool registered = tf_ssb_db_register_account(tf_ssb_get_loop(ssb), db, context, k_account_name, k_account_name); + tf_ssb_release_db_writer(ssb, db); + if (registered) + { + _make_administrator_if_first(ssb, context, k_account_name, true); + } + JS_FreeContext(context); + JS_FreeRuntime(runtime); + + request->users = tf_ssb_db_get_property(ssb, "auth", "users"); + } } } @@ -2224,36 +2216,44 @@ static void _httpd_auto_login_after_work(tf_ssb_t* ssb, int status, void* user_d auto_login_t* work = user_data; JSContext* context = tf_ssb_get_context(ssb); const char* session_token = NULL; - if (work->users) + if (!work->autologin) { - JSValue json = JS_ParseJSON(context, work->users, strlen(work->users), NULL); - JSValue user = JS_GetPropertyUint32(context, json, 0); - const char* user_string = JS_ToCString(context, user); - session_token = _make_session_jwt(context, ssb, user_string); - JS_FreeCString(context, user_string); - JS_FreeValue(context, user); - JS_FreeValue(context, json); - } - if (session_token) - { - const char* cookie = _make_set_session_cookie_header(work->request, session_token); - tf_free((void*)session_token); - const char* headers[] = { - "Set-Cookie", - cookie, - "Location", - "/", - }; - tf_http_respond(work->request, 303, headers, tf_countof(headers) / 2, NULL, 0); - tf_free((void*)cookie); + const char* k_payload = tf_http_status_text(404); + tf_http_respond(work->request, 404, NULL, 0, k_payload, strlen(k_payload)); } else { - const char* headers[] = { - "Location", - "/", - }; - tf_http_respond(work->request, 303, headers, tf_countof(headers) / 2, NULL, 0); + if (work->users) + { + JSValue json = JS_ParseJSON(context, work->users, strlen(work->users), NULL); + JSValue user = JS_GetPropertyUint32(context, json, 0); + const char* user_string = JS_ToCString(context, user); + session_token = _make_session_jwt(context, ssb, user_string); + JS_FreeCString(context, user_string); + JS_FreeValue(context, user); + JS_FreeValue(context, json); + } + if (session_token) + { + const char* cookie = _make_set_session_cookie_header(work->request, session_token); + tf_free((void*)session_token); + const char* headers[] = { + "Set-Cookie", + cookie, + "Location", + "/", + }; + tf_http_respond(work->request, 303, headers, tf_countof(headers) / 2, NULL, 0); + tf_free((void*)cookie); + } + else + { + const char* headers[] = { + "Location", + "/", + }; + tf_http_respond(work->request, 303, headers, tf_countof(headers) / 2, NULL, 0); + } } tf_http_request_unref(work->request); tf_free((void*)work->users); @@ -2263,20 +2263,12 @@ static void _httpd_auto_login_after_work(tf_ssb_t* ssb, int status, void* user_d static void _httpd_endpoint_login_auto(tf_http_request_t* request) { tf_task_t* task = request->user_data; - if (tf_util_is_mobile() || _task_arg_is_mobile(task)) - { - tf_http_request_ref(request); - tf_ssb_t* ssb = tf_task_get_ssb(task); + tf_http_request_ref(request); + tf_ssb_t* ssb = tf_task_get_ssb(task); - auto_login_t* work = tf_malloc(sizeof(auto_login_t)); - *work = (auto_login_t) { .request = request }; - tf_ssb_run_work(ssb, _httpd_auto_login_work, _httpd_auto_login_after_work, work); - } - else - { - const char* k_payload = tf_http_status_text(404); - tf_http_respond(request, 404, NULL, 0, k_payload, strlen(k_payload)); - } + auto_login_t* work = tf_malloc(sizeof(auto_login_t)); + *work = (auto_login_t) { .request = request }; + tf_ssb_run_work(ssb, _httpd_auto_login_work, _httpd_auto_login_after_work, work); } static void _httpd_endpoint_app_socket(tf_http_request_t* request)