Mercurial
view connectors/main.c @ 281:c57149ad216e default tip
Copilot-Session: f68442b1-fa8f-46a0-9689-81710613bbd4
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Tue, 18 Aug 2026 22:18:15 -0700 |
| parents | b3b547563ec7 |
| children |
line wrap: on
line source
#include "connectors/connector.h" #include "connectors/auth_http_adapter.h" #include <openssl/crypto.h> #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct { char database[1024]; char auth_database[1024]; char auth_cookie_secret_hex[AUTH_CRYPTO_COOKIE_SECRET_MAX_BYTES * 2 + 1]; int64 auth_session_idle_ttl; char bind[128]; char port[16]; char static_dir[1024]; char client_id[1024]; char client_secret[2048]; char redirect_uri[2048]; char master_key[256]; uint32 master_key_version; } Service_Config; static boolean set_value(Service_Config *config, const char *key, const char *value) { #define SET(name, field) if (!strcmp(key, name)) { \ if (strlen(value) >= sizeof(config->field)) return FALSE; \ strcpy(config->field, value); return TRUE; \ } SET("DATABASE", database) SET("DB_PATH", database) SET("database", database) SET("AUTH_DATABASE", auth_database) SET("AUTH_DB_PATH", auth_database) SET("auth_database", auth_database) SET("AUTH_COOKIE_SECRET", auth_cookie_secret_hex) SET("AUTH_COOKIE_SECRET_HEX", auth_cookie_secret_hex) SET("auth_cookie_secret_hex", auth_cookie_secret_hex) SET("BIND", bind) SET("SERVER_HOST", bind) SET("bind", bind) SET("PORT", port) SET("SERVER_PORT", port) SET("port", port) SET("STATIC_DIR", static_dir) SET("static_dir", static_dir) SET("GOOGLE_CLIENT_ID", client_id) SET("google_client_id", client_id) SET("GOOGLE_CLIENT_SECRET", client_secret) SET("google_client_secret", client_secret) SET("GOOGLE_REDIRECT_URI", redirect_uri) SET("google_redirect_uri", redirect_uri) SET("MASTER_KEY_BASE64URL", master_key) SET("master_key_base64url", master_key) if (!strcmp(key, "MASTER_KEY_VERSION") || !strcmp(key, "master_key_version")) { config->master_key_version = (uint32)strtoul(value, NULL, 10); return config->master_key_version > 0; } if (!strcmp(key, "AUTH_SESSION_IDLE_TTL") || !strcmp(key, "auth_session_idle_ttl")) { char *end = NULL; long long parsed = strtoll(value, &end, 10); if (!end || *end || parsed <= 0) return FALSE; config->auth_session_idle_ttl = (int64)parsed; return TRUE; } #undef SET return TRUE; } static boolean load_config(const char *path, Service_Config *config) { FILE *file = fopen(path, "r"); char workspace_path[2048] = {0}; if (!file) { const char *workspace = getenv("BUILD_WORKSPACE_DIRECTORY"); if (workspace && workspace[0]) { int written = snprintf( workspace_path, sizeof(workspace_path), "%s/%s", workspace, path); if (written > 0 && (size_t)written < sizeof(workspace_path)) file = fopen(workspace_path, "r"); } } if (!file) return FALSE; memset(config, 0, sizeof(*config)); strcpy(config->bind, "127.0.0.1"); strcpy(config->port, "6981"); strcpy(config->static_dir, "connectors"); config->auth_session_idle_ttl = 604800; char line[4096]; boolean ok = TRUE; while (ok && fgets(line, sizeof(line), file)) { char *newline = strpbrk(line, "\r\n"); if (newline) *newline = '\0'; if (!line[0] || line[0] == '#') continue; char *equals = strchr(line, '='); if (!equals) { ok = FALSE; break; } *equals = '\0'; ok = set_value(config, line, equals + 1); } fclose(file); return ok && config->database[0] && config->auth_database[0] && config->auth_cookie_secret_hex[0] && config->client_id[0] && config->client_secret[0] && config->redirect_uri[0] && config->master_key[0] && config->master_key_version; } int main(int argc, char **argv) { const char *config_path = argc > 1 ? argv[1] : getenv("CONNECTOR_CONFIG_PATH"); if (!config_path || !config_path[0]) config_path = "connectors/.config"; Service_Config service; if (!load_config(config_path, &service)) { fprintf(stderr, "Invalid connector config: %s\n", config_path); return 1; } Connector_Master_Key key = {.version = service.master_key_version}; size_t key_length = 0; if (!Connector_Base64Url_Decode( service.master_key, key.key, sizeof(key.key), &key_length) || key_length != sizeof(key.key)) { fprintf(stderr, "MASTER_KEY_BASE64URL must decode to 32 bytes\n"); return 1; } Connector_Store store; if (!Connector_Store_Open(&store, service.database, &key)) { fprintf(stderr, "Unable to open connector database\n"); return 1; } Connector_Auth_HTTP_Context auth_context; if (!Connector_Auth_HTTP_Init( &auth_context, service.auth_database, service.auth_cookie_secret_hex, service.auth_session_idle_ttl)) { OPENSSL_cleanse( service.auth_cookie_secret_hex, sizeof(service.auth_cookie_secret_hex)); fprintf(stderr, "Unable to initialize shared HTTP authentication\n"); Connector_Store_Close(&store); return 1; } OPENSSL_cleanse( service.auth_cookie_secret_hex, sizeof(service.auth_cookie_secret_hex)); Connector_Google_Config google = { .client_id = service.client_id, .client_secret = service.client_secret, .redirect_uri = service.redirect_uri, .oauth_authorize_url = "https://accounts.google.com/o/oauth2/v2/auth", .oauth_token_url = "https://oauth2.googleapis.com/token", .oauth_revoke_url = "https://oauth2.googleapis.com/revoke", .identity_url = "https://openidconnect.googleapis.com/v1/userinfo", .drive_api_url = "https://www.googleapis.com", .drive_upload_url = "https://www.googleapis.com", .gmail_api_url = "https://gmail.googleapis.com" }; Connector_Auth_Adapter auth = Connector_Auth_HTTP_Create_Adapter(&auth_context); Connector_Service_Configure(&store, &google, auth); Seobeo_Router_Init(); Connector_Service_Register_Routes(); int result = Seobeo_Web_Server_Start_On( service.bind, service.static_dir, service.port, SEOBEO_MODE_EDGE, 4); Seobeo_Router_Destroy(); Connector_Auth_HTTP_Destroy(&auth_context); Connector_Store_Close(&store); return result; }