Mercurial
view connectors/auth_http_adapter.c @ 282:6bd4a3990696 default tip
Add cross-platform canvas orchestration and typed composer
Enable native ARM dependencies, macOS Copilot orchestration, portable service supervision, CPU dictation, and a shared N-key speak-or-type composer.
Co-authored-by: Copilot <[email protected]>
Copilot-Session: f68442b1-fa8f-46a0-9689-81710613bbd4
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Thu, 20 Aug 2026 20:45:25 -0700 |
| parents | b3b547563ec7 |
| children |
line wrap: on
line source
#include "connectors/auth_http_adapter.h" #include <openssl/crypto.h> #include <string.h> #include <time.h> static int32 hex_value(char value) { if (value >= '0' && value <= '9') return value - '0'; if (value >= 'a' && value <= 'f') return value - 'a' + 10; if (value >= 'A' && value <= 'F') return value - 'A' + 10; return -1; } static boolean decode_secret( const char *hex, uint8 *output, size_t capacity, size_t *length_out) { if (!hex || !output || !length_out) return FALSE; size_t length = strlen(hex); if (length % 2 != 0 || length / 2 > capacity || length / 2 < AUTH_CRYPTO_COOKIE_SECRET_MIN_BYTES) return FALSE; for (size_t i = 0; i < length; i += 2) { int32 high = hex_value(hex[i]); int32 low = hex_value(hex[i + 1]); if (high < 0 || low < 0) { OPENSSL_cleanse(output, capacity); return FALSE; } output[i / 2] = (uint8)((high << 4) | low); } *length_out = length / 2; return TRUE; } boolean Connector_Auth_HTTP_Init( Connector_Auth_HTTP_Context *context, const char *database_path, const char *cookie_secret_hex, int64 session_idle_ttl_secs) { if (!context || !database_path || !cookie_secret_hex || session_idle_ttl_secs <= 0) return FALSE; memset(context, 0, sizeof(*context)); if (!decode_secret( cookie_secret_hex, context->cookie_secret, sizeof(context->cookie_secret), &context->cookie_secret_length)) return FALSE; context->store = Auth_Store_Create(database_path); if (!context->store) { OPENSSL_cleanse(context->cookie_secret, sizeof(context->cookie_secret)); context->cookie_secret_length = 0; return FALSE; } context->session_idle_ttl_secs = session_idle_ttl_secs; return TRUE; } void Connector_Auth_HTTP_Destroy(Connector_Auth_HTTP_Context *context) { if (!context) return; if (context->store) Auth_Store_Destroy(context->store); OPENSSL_cleanse(context, sizeof(*context)); } static const char *resolve_user( Seobeo_Request_Entry *request, boolean require_csrf, Dowa_Arena *arena, void *opaque) { Connector_Auth_HTTP_Context *context = opaque; if (!context || !context->store || !arena) return NULL; Auth_HTTP_Authenticated_User authenticated; Auth_HTTP_Resolve_Result result = Auth_HTTP_Resolve_Authenticated_User( request, context->store, context->cookie_secret, context->cookie_secret_length, (int64)time(NULL), context->session_idle_ttl_secs, &authenticated); if (result != AUTH_HTTP_RESOLVE_OK) return NULL; if (require_csrf && !Auth_HTTP_Verify_CSRF( request, context->cookie_secret, context->cookie_secret_length, authenticated.token_digest)) { OPENSSL_cleanse(&authenticated, sizeof(authenticated)); return NULL; } size_t id_length = strlen(authenticated.user.id); char *user_id = Dowa_Arena_Allocate(arena, id_length + 1); if (user_id) memcpy(user_id, authenticated.user.id, id_length + 1); OPENSSL_cleanse(&authenticated, sizeof(authenticated)); return user_id; } static boolean resolve_session( Seobeo_Request_Entry *request, Connector_Auth_Session *session, void *opaque) { Connector_Auth_HTTP_Context *context = opaque; if (!context || !context->store || !session) return FALSE; Auth_HTTP_Authenticated_User authenticated; Auth_HTTP_Resolve_Result result = Auth_HTTP_Resolve_Authenticated_User( request, context->store, context->cookie_secret, context->cookie_secret_length, (int64)time(NULL), context->session_idle_ttl_secs, &authenticated); if (result != AUTH_HTTP_RESOLVE_OK) return FALSE; memset(session, 0, sizeof(*session)); snprintf(session->user_id, sizeof(session->user_id), "%s", authenticated.user.id); snprintf(session->username, sizeof(session->username), "%s", authenticated.user.username); snprintf(session->role, sizeof(session->role), "%s", authenticated.user.role); snprintf(session->csrf_token, sizeof(session->csrf_token), "%s", authenticated.csrf_token); OPENSSL_cleanse(&authenticated, sizeof(authenticated)); return TRUE; } Connector_Auth_Adapter Connector_Auth_HTTP_Create_Adapter( Connector_Auth_HTTP_Context *context) { Connector_Auth_Adapter adapter = { .resolve_user = resolve_user, .resolve_session = resolve_session, .context = context }; return adapter; }