Compare commits

..

2 commits

Author SHA1 Message Date
lda
da8a64534a
[MOD] Remove ConfigFullyFree by using the stack. 2024-01-05 17:17:06 +01:00
lda
1d93b1c22c
[MOD] Make tls optional 2024-01-05 13:00:50 +01:00
17 changed files with 131 additions and 159 deletions

View file

@ -6,8 +6,8 @@
"types": { "types": {
"ConfigTls": { "ConfigTls": {
"fields": { "fields": {
"cert": { "type": "string" }, "cert": { "type": "string", "required": true },
"key": { "type": "string" } "key": { "type": "string", "required": true }
}, },
"type": "struct" "type": "struct"
}, },

View file

@ -19,8 +19,7 @@ key-value form:
"serverName": "telodendria.io", "serverName": "telodendria.io",
"listen": [ "listen": [
{ {
"port": 8008, "port": 8008
"tls": false
} }
] ]
@ -51,7 +50,7 @@ Here are the top-level directives:
this is a concern, a reverse-proxy such as `relayd` can be placed this is a concern, a reverse-proxy such as `relayd` can be placed
in front of Telodendria to block access to undesired APIs. in front of Telodendria to block access to undesired APIs.
- **tls:** `Object|null|false` - **tls:** `Object`
Telodendria can be compiled with TLS support. If it is, then a Telodendria can be compiled with TLS support. If it is, then a
particular listener can be set to use TLS for connections. If particular listener can be set to use TLS for connections. If

View file

@ -44,47 +44,48 @@
#define HOST_NAME_MAX _POSIX_HOST_NAME_MAX #define HOST_NAME_MAX _POSIX_HOST_NAME_MAX
#endif #endif
Config * Config
ConfigParse(HashMap * config) ConfigParse(HashMap * config)
{ {
Config *tConfig; Config tConfig;
size_t i; size_t i;
if (!config) if (!config)
{ {
return NULL; tConfig.ok = 0;
tConfig.err = "Invalid object given as config.";
return tConfig;
} }
tConfig = Malloc(sizeof(Config)); memset(&tConfig, 0, sizeof(Config));
memset(tConfig, 0, sizeof(Config));
tConfig->maxCache = Int64Create(0, 0); tConfig.maxCache = Int64Create(0, 0);
if (!ConfigFromJson(config, tConfig, &tConfig->err)) if (!ConfigFromJson(config, &tConfig, &tConfig.err))
{ {
ConfigFree(tConfig); ConfigFree(&tConfig);
goto error; goto error;
} }
if (!tConfig->baseUrl) if (!tConfig.baseUrl)
{ {
size_t len = strlen(tConfig->serverName) + 10; size_t len = strlen(tConfig.serverName) + 10;
tConfig->baseUrl = Malloc(len); tConfig.baseUrl = Malloc(len);
if (!tConfig->baseUrl) if (!tConfig.baseUrl)
{ {
tConfig->err = "Couldn't allocate enough memory for 'baseUrl'."; tConfig.err = "Couldn't allocate enough memory for 'baseUrl'.";
goto error; goto error;
} }
snprintf(tConfig->baseUrl, len, "https://%s/", tConfig->serverName); snprintf(tConfig.baseUrl, len, "https://%s/", tConfig.serverName);
} }
if (!tConfig->log.timestampFormat) if (!tConfig.log.timestampFormat)
{ {
tConfig->log.timestampFormat = StrDuplicate("default"); tConfig.log.timestampFormat = StrDuplicate("default");
} }
for (i = 0; i < ArraySize(tConfig->listen); i++) for (i = 0; i < ArraySize(tConfig.listen); i++)
{ {
ConfigListener *listener = ArrayGet(tConfig->listen, i); ConfigListener *listener = ArrayGet(tConfig.listen, i);
if (Int64Eq(listener->maxConnections, Int64Create(0, 0))) if (Int64Eq(listener->maxConnections, Int64Create(0, 0)))
{ {
listener->maxConnections = Int64Create(0, 32); listener->maxConnections = Int64Create(0, 32);
@ -98,12 +99,12 @@ ConfigParse(HashMap * config)
listener->port = Int64Create(0, 8008); listener->port = Int64Create(0, 8008);
} }
} }
tConfig->ok = 1; tConfig.ok = 1;
tConfig->err = NULL; tConfig.err = NULL;
return tConfig; return tConfig;
error: error:
tConfig->ok = 0; tConfig.ok = 0;
return tConfig; return tConfig;
} }
@ -120,6 +121,7 @@ ConfigCreateDefault(Db * db)
ConfigListener *listener; ConfigListener *listener;
HashMap *json; HashMap *json;
JsonValue *val;
DbRef *ref; DbRef *ref;
@ -147,16 +149,17 @@ ConfigCreateDefault(Db * db)
/* Add simple listener without TLS. */ /* Add simple listener without TLS. */
config.listen = ArrayCreate(); config.listen = ArrayCreate();
listener = Malloc(sizeof(ConfigListener)); listener = Malloc(sizeof(ConfigListener));
listener->maxConnections = Int64Create(0, 0); listener->maxConnections = Int64Create(0, 32);
listener->port = Int64Create(0, 8008); listener->port = Int64Create(0, 8008);
listener->threads = Int64Create(0, 0); listener->threads = Int64Create(0, 4);
listener->tls.key = NULL;
listener->tls.cert = NULL;
ArrayAdd(config.listen, listener); ArrayAdd(config.listen, listener);
/* Write it all out to the configuration file. */ /* Write it all out to the configuration file. */
json = ConfigToJson(&config); json = ConfigToJson(&config);
val = JsonGet(json, 1, "listen");
val = ArrayGet(JsonValueAsArray(val), 0);
JsonValueFree(HashMapDelete(JsonValueAsObject(val), "tls"));
ref = DbCreate(db, 1, "config"); ref = DbCreate(db, 1, "config");
if (!ref) if (!ref)
@ -173,53 +176,44 @@ ConfigCreateDefault(Db * db)
return 1; return 1;
} }
Config * Config
ConfigLock(Db * db) ConfigLock(Db * db)
{ {
Config *config; Config config;
DbRef *ref = DbLock(db, 1, "config"); DbRef *ref = DbLock(db, 1, "config");
if (!ref) if (!ref)
{ {
return NULL; config.ok = 0;
config.err = "Couldn't lock configuration.";
} }
config = ConfigParse(DbJson(ref)); config = ConfigParse(DbJson(ref));
if (config) if (config.ok)
{ {
config->db = db; config.db = db;
config->ref = ref; config.ref = ref;
} }
return config; return config;
} }
void
ConfigFullyFree(Config * config)
{
if (!config)
{
return;
}
ConfigFree(config);
Free(config);
}
int int
ConfigUnlock(Config * config) ConfigUnlock(Config config)
{ {
Db *db; Db *db;
DbRef *dbRef; DbRef *dbRef;
if (!config) if (!config.ok)
{ {
return 0; return 0;
} }
db = config->db; db = config.db;
dbRef = config->ref; dbRef = config.ref;
ConfigFree(&config);
ConfigFullyFree(config);
return DbUnlock(db, dbRef); return DbUnlock(db, dbRef);
} }
int int

View file

@ -102,7 +102,7 @@ Main(Array * args)
char *dbPath; char *dbPath;
/* Program configuration */ /* Program configuration */
Config *tConfig; Config tConfig;
Stream *logFile; Stream *logFile;
Stream *pidFile = NULL; Stream *pidFile = NULL;
@ -135,7 +135,7 @@ start:
exit = EXIT_SUCCESS; exit = EXIT_SUCCESS;
flags = 0; flags = 0;
dbPath = NULL; dbPath = NULL;
tConfig = NULL; /*tConfig = NULL;*/
logFile = NULL; logFile = NULL;
userInfo = NULL; userInfo = NULL;
groupInfo = NULL; groupInfo = NULL;
@ -265,27 +265,19 @@ start:
Log(LOG_NOTICE, "Loading configuration..."); Log(LOG_NOTICE, "Loading configuration...");
tConfig = ConfigLock(matrixArgs.db); tConfig = ConfigLock(matrixArgs.db);
if (!tConfig) if (!tConfig.ok)
{ {
Log(LOG_ERR, "Error locking the configuration."); Log(LOG_ERR, tConfig.err);
Log(LOG_ERR, "The configuration object is corrupted or otherwise invalid.");
Log(LOG_ERR, "Please restore from a backup.");
exit = EXIT_FAILURE;
goto finish;
}
else if (!tConfig->ok)
{
Log(LOG_ERR, tConfig->err);
exit = EXIT_FAILURE; exit = EXIT_FAILURE;
goto finish; goto finish;
} }
if (!tConfig->log.timestampFormat || !StrEquals(tConfig->log.timestampFormat, "default")) if (!tConfig.log.timestampFormat || !StrEquals(tConfig.log.timestampFormat, "default"))
{ {
LogConfigTimeStampFormatSet(LogConfigGlobal(), tConfig->log.timestampFormat); LogConfigTimeStampFormatSet(LogConfigGlobal(), tConfig.log.timestampFormat);
} }
if (tConfig->log.color) if (tConfig.log.color)
{ {
LogConfigFlagSet(LogConfigGlobal(), LOG_FLAG_COLOR); LogConfigFlagSet(LogConfigGlobal(), LOG_FLAG_COLOR);
} }
@ -298,9 +290,9 @@ start:
LogConfigGlobal(), LogConfigGlobal(),
flags & ARG_VERBOSE ? flags & ARG_VERBOSE ?
LOG_DEBUG : LOG_DEBUG :
ConfigLogLevelToSyslog(tConfig->log.level)); ConfigLogLevelToSyslog(tConfig.log.level));
if (tConfig->log.output == CONFIG_LOG_OUTPUT_FILE) if (tConfig.log.output == CONFIG_LOG_OUTPUT_FILE)
{ {
logFile = StreamOpen("telodendria.log", "a"); logFile = StreamOpen("telodendria.log", "a");
@ -308,18 +300,18 @@ start:
{ {
Log(LOG_ERR, "Unable to open log file for appending."); Log(LOG_ERR, "Unable to open log file for appending.");
exit = EXIT_FAILURE; exit = EXIT_FAILURE;
tConfig->log.output = CONFIG_LOG_OUTPUT_STDOUT; tConfig.log.output = CONFIG_LOG_OUTPUT_STDOUT;
goto finish; goto finish;
} }
Log(LOG_INFO, "Logging to the log file. Check there for all future messages."); Log(LOG_INFO, "Logging to the log file. Check there for all future messages.");
LogConfigOutputSet(LogConfigGlobal(), logFile); LogConfigOutputSet(LogConfigGlobal(), logFile);
} }
else if (tConfig->log.output == CONFIG_LOG_OUTPUT_STDOUT) else if (tConfig.log.output == CONFIG_LOG_OUTPUT_STDOUT)
{ {
Log(LOG_DEBUG, "Already logging to standard output."); Log(LOG_DEBUG, "Already logging to standard output.");
} }
else if (tConfig->log.output == CONFIG_LOG_OUTPUT_SYSLOG) else if (tConfig.log.output == CONFIG_LOG_OUTPUT_SYSLOG)
{ {
Log(LOG_INFO, "Logging to the syslog. Check there for all future messages."); Log(LOG_INFO, "Logging to the syslog. Check there for all future messages.");
LogConfigFlagSet(LogConfigGlobal(), LOG_FLAG_SYSLOG); LogConfigFlagSet(LogConfigGlobal(), LOG_FLAG_SYSLOG);
@ -338,30 +330,30 @@ start:
Free(token); Free(token);
} }
if (tConfig->pid) if (tConfig.pid)
{ {
pidFile = StreamOpen(tConfig->pid, "w+"); pidFile = StreamOpen(tConfig.pid, "w+");
if (!pidFile) if (!pidFile)
{ {
char *msg = "Couldn't lock PID file at '%s'"; char *msg = "Couldn't lock PID file at '%s'";
Log(LOG_ERR, msg, tConfig->pid); Log(LOG_ERR, msg, tConfig.pid);
exit = EXIT_FAILURE; exit = EXIT_FAILURE;
goto finish; goto finish;
} }
pidPath = StrDuplicate(tConfig->pid); pidPath = StrDuplicate(tConfig.pid);
StreamPrintf(pidFile, "%ld", (long) getpid()); StreamPrintf(pidFile, "%ld", (long) getpid());
StreamClose(pidFile); StreamClose(pidFile);
} }
Log(LOG_DEBUG, "Configuration:"); Log(LOG_DEBUG, "Configuration:");
LogConfigIndent(LogConfigGlobal()); LogConfigIndent(LogConfigGlobal());
Log(LOG_DEBUG, "Server Name: %s", tConfig->serverName); Log(LOG_DEBUG, "Server Name: %s", tConfig.serverName);
Log(LOG_DEBUG, "Base URL: %s", tConfig->baseUrl); Log(LOG_DEBUG, "Base URL: %s", tConfig.baseUrl);
Log(LOG_DEBUG, "Identity Server: %s", tConfig->identityServer); Log(LOG_DEBUG, "Identity Server: %s", tConfig.identityServer);
Log(LOG_DEBUG, "Run As: %s:%s", tConfig->runAs.uid, tConfig->runAs.gid); Log(LOG_DEBUG, "Run As: %s:%s", tConfig.runAs.uid, tConfig.runAs.gid);
Log(LOG_DEBUG, "Max Cache: %ld", tConfig->maxCache); Log(LOG_DEBUG, "Max Cache: %ld", tConfig.maxCache);
Log(LOG_DEBUG, "Registration: %s", tConfig->registration ? "true" : "false"); Log(LOG_DEBUG, "Registration: %s", tConfig.registration ? "true" : "false");
Log(LOG_DEBUG, "Federation: %s", tConfig->federation ? "true" : "false"); Log(LOG_DEBUG, "Federation: %s", tConfig.federation ? "true" : "false");
LogConfigUnindent(LogConfigGlobal()); LogConfigUnindent(LogConfigGlobal());
httpServers = ArrayCreate(); httpServers = ArrayCreate();
@ -373,9 +365,9 @@ start:
} }
/* Bind servers before possibly dropping permissions. */ /* Bind servers before possibly dropping permissions. */
for (i = 0; i < ArraySize(tConfig->listen); i++) for (i = 0; i < ArraySize(tConfig.listen); i++)
{ {
ConfigListener *serverCfg = ArrayGet(tConfig->listen, i); ConfigListener *serverCfg = ArrayGet(tConfig.listen, i);
HttpServerConfig args; HttpServerConfig args;
@ -438,10 +430,10 @@ start:
Log(LOG_DEBUG, "Running as uid:gid: %d:%d.", getuid(), getgid()); Log(LOG_DEBUG, "Running as uid:gid: %d:%d.", getuid(), getgid());
if (tConfig->runAs.uid && tConfig->runAs.gid) if (tConfig.runAs.uid && tConfig.runAs.gid)
{ {
userInfo = getpwnam(tConfig->runAs.uid); userInfo = getpwnam(tConfig.runAs.uid);
groupInfo = getgrnam(tConfig->runAs.gid); groupInfo = getgrnam(tConfig.runAs.gid);
if (!userInfo || !groupInfo) if (!userInfo || !groupInfo)
{ {
@ -471,7 +463,7 @@ start:
} }
else else
{ {
Log(LOG_DEBUG, "Set uid/gid to %s:%s.", tConfig->runAs.uid, tConfig->runAs.gid); Log(LOG_DEBUG, "Set uid/gid to %s:%s.", tConfig.runAs.uid, tConfig.runAs.gid);
} }
} }
else else
@ -483,7 +475,7 @@ start:
} }
else else
{ {
if (tConfig->runAs.uid && tConfig->runAs.gid) if (tConfig.runAs.uid && tConfig.runAs.gid)
{ {
if (getuid() != userInfo->pw_uid || getgid() != groupInfo->gr_gid) if (getuid() != userInfo->pw_uid || getgid() != groupInfo->gr_gid)
{ {
@ -496,17 +488,18 @@ start:
} }
} }
if (!tConfig->maxCache) if (!tConfig.maxCache)
{ {
Log(LOG_WARNING, "Database caching is disabled."); Log(LOG_WARNING, "Database caching is disabled.");
Log(LOG_WARNING, "If this is not what you intended, check the config file"); Log(LOG_WARNING, "If this is not what you intended, check the config file");
Log(LOG_WARNING, "and ensure that maxCache is a valid number of bytes."); Log(LOG_WARNING, "and ensure that maxCache is a valid number of bytes.");
} }
DbMaxCacheSet(matrixArgs.db, tConfig->maxCache); DbMaxCacheSet(matrixArgs.db, tConfig.maxCache);
ConfigUnlock(tConfig); ConfigUnlock(tConfig);
tConfig = NULL;
tConfig.ok = 0;
cron = CronCreate(60 * 1000); /* 1-minute tick */ cron = CronCreate(60 * 1000); /* 1-minute tick */
if (!cron) if (!cron)

View file

@ -67,9 +67,9 @@ ROUTE_IMPL(RouteChangePwd, path, argp)
char *msg; char *msg;
Config *config = ConfigLock(db); Config config = ConfigLock(db);
if (!config) if (!config.ok)
{ {
Log(LOG_ERR, "Password endpoint failed to lock configuration."); Log(LOG_ERR, "Password endpoint failed to lock configuration.");
HttpResponseStatus(args->context, HTTP_INTERNAL_SERVER_ERROR); HttpResponseStatus(args->context, HTTP_INTERNAL_SERVER_ERROR);

View file

@ -36,10 +36,10 @@ ROUTE_IMPL(RouteConfig, path, argp)
char *msg; char *msg;
User *user = NULL; User *user = NULL;
Config *config = NULL; Config config;
HashMap *request = NULL; HashMap *request = NULL;
Config *newConf; Config newConf;
HashMap *newJson = NULL; HashMap *newJson = NULL;
(void) path; (void) path;
@ -67,7 +67,7 @@ ROUTE_IMPL(RouteConfig, path, argp)
} }
config = ConfigLock(args->matrixArgs->db); config = ConfigLock(args->matrixArgs->db);
if (!config) if (!config.ok)
{ {
msg = "Internal server error while locking configuration."; msg = "Internal server error while locking configuration.";
Log(LOG_ERR, "Config endpoint failed to lock configuration."); Log(LOG_ERR, "Config endpoint failed to lock configuration.");
@ -79,7 +79,7 @@ ROUTE_IMPL(RouteConfig, path, argp)
switch (HttpRequestMethodGet(args->context)) switch (HttpRequestMethodGet(args->context))
{ {
case HTTP_GET: case HTTP_GET:
response = JsonDuplicate(DbJson(config->ref)); response = JsonDuplicate(DbJson(config.ref));
break; break;
case HTTP_POST: case HTTP_POST:
request = JsonDecode(HttpServerStream(args->context)); request = JsonDecode(HttpServerStream(args->context));
@ -91,17 +91,9 @@ ROUTE_IMPL(RouteConfig, path, argp)
} }
newConf = ConfigParse(request); newConf = ConfigParse(request);
if (!newConf) if (newConf.ok)
{ {
msg = "Internal server error while parsing config."; if (DbJsonSet(config.ref, request))
HttpResponseStatus(args->context, HTTP_INTERNAL_SERVER_ERROR);
response = MatrixErrorCreate(M_UNKNOWN, msg);
break;
}
if (newConf->ok)
{
if (DbJsonSet(config->ref, request))
{ {
response = HashMapCreate(); response = HashMapCreate();
/* /*
@ -120,10 +112,10 @@ ROUTE_IMPL(RouteConfig, path, argp)
else else
{ {
HttpResponseStatus(args->context, HTTP_BAD_REQUEST); HttpResponseStatus(args->context, HTTP_BAD_REQUEST);
response = MatrixErrorCreate(M_BAD_JSON, newConf->err); response = MatrixErrorCreate(M_BAD_JSON, newConf.err);
} }
ConfigFullyFree(newConf); ConfigFree(&newConf);
JsonFree(request); JsonFree(request);
break; break;
case HTTP_PUT: case HTTP_PUT:
@ -135,12 +127,12 @@ ROUTE_IMPL(RouteConfig, path, argp)
break; break;
} }
newJson = JsonDuplicate(DbJson(config->ref)); newJson = JsonDuplicate(DbJson(config.ref));
JsonMerge(newJson, request); JsonMerge(newJson, request);
newConf = ConfigParse(newJson); newConf = ConfigParse(newJson);
if (!newConf) if (!newConf.ok)
{ {
msg = "Internal server error while parsing config."; msg = "Internal server error while parsing config.";
HttpResponseStatus(args->context, HTTP_INTERNAL_SERVER_ERROR); HttpResponseStatus(args->context, HTTP_INTERNAL_SERVER_ERROR);
@ -148,9 +140,9 @@ ROUTE_IMPL(RouteConfig, path, argp)
break; break;
} }
if (newConf->ok) if (newConf.ok)
{ {
if (DbJsonSet(config->ref, newJson)) if (DbJsonSet(config.ref, newJson))
{ {
response = HashMapCreate(); response = HashMapCreate();
/* /*
@ -169,10 +161,10 @@ ROUTE_IMPL(RouteConfig, path, argp)
else else
{ {
HttpResponseStatus(args->context, HTTP_BAD_REQUEST); HttpResponseStatus(args->context, HTTP_BAD_REQUEST);
response = MatrixErrorCreate(M_BAD_JSON, newConf->err); response = MatrixErrorCreate(M_BAD_JSON, newConf.err);
} }
ConfigFullyFree(newConf); ConfigFree(&newConf);
JsonFree(request); JsonFree(request);
JsonFree(newJson); JsonFree(newJson);
break; break;

View file

@ -45,13 +45,13 @@ ROUTE_IMPL(RouteDeactivate, path, argp)
Db *db = args->matrixArgs->db; Db *db = args->matrixArgs->db;
User *user = NULL; User *user = NULL;
Config *config = ConfigLock(db); Config config = ConfigLock(db);
char *msg; char *msg;
(void) path; (void) path;
if (!config) if (!config.ok)
{ {
Log(LOG_ERR, "Deactivate endpoint failed to lock configuration."); Log(LOG_ERR, "Deactivate endpoint failed to lock configuration.");
HttpResponseStatus(args->context, HTTP_INTERNAL_SERVER_ERROR); HttpResponseStatus(args->context, HTTP_INTERNAL_SERVER_ERROR);

View file

@ -39,14 +39,14 @@ GetServerName(Db * db)
{ {
char *name; char *name;
Config *config = ConfigLock(db); Config config = ConfigLock(db);
if (!config) if (!config.ok)
{ {
return NULL; return NULL;
} }
name = StrDuplicate(config->serverName); name = StrDuplicate(config.serverName);
ConfigUnlock(config); ConfigUnlock(config);

View file

@ -64,9 +64,9 @@ ROUTE_IMPL(RouteLogin, path, argp)
char *msg; char *msg;
Config *config = ConfigLock(db); Config config = ConfigLock(db);
if (!config) if (!config.ok)
{ {
Log(LOG_ERR, "Login endpoint failed to lock configuration."); Log(LOG_ERR, "Login endpoint failed to lock configuration.");
HttpResponseStatus(args->context, HTTP_INTERNAL_SERVER_ERROR); HttpResponseStatus(args->context, HTTP_INTERNAL_SERVER_ERROR);
@ -149,7 +149,7 @@ ROUTE_IMPL(RouteLogin, path, argp)
} }
userId = UserIdParse(userIdentifier.user, config->serverName); userId = UserIdParse(userIdentifier.user, config.serverName);
if (!userId) if (!userId)
{ {
msg = "Invalid user ID."; msg = "Invalid user ID.";
@ -158,7 +158,7 @@ ROUTE_IMPL(RouteLogin, path, argp)
break; break;
} }
if (!StrEquals(userId->server, config->serverName) if (!StrEquals(userId->server, config.serverName)
|| !UserExists(db, userId->localpart)) || !UserExists(db, userId->localpart))
{ {
msg = "Unknown user ID."; msg = "Unknown user ID.";
@ -221,13 +221,13 @@ ROUTE_IMPL(RouteLogin, path, argp)
} }
fullUsername = StrConcat(4, "@", UserGetName(user), ":", fullUsername = StrConcat(4, "@", UserGetName(user), ":",
config->serverName); config.serverName);
HashMapSet(response, "user_id", JsonValueString(fullUsername)); HashMapSet(response, "user_id", JsonValueString(fullUsername));
Free(fullUsername); Free(fullUsername);
HashMapSet(response, "well_known", HashMapSet(response, "well_known",
JsonValueObject( JsonValueObject(
MatrixClientWellKnown(config->baseUrl, config->identityServer))); MatrixClientWellKnown(config.baseUrl, config.identityServer)));
UserAccessTokenFree(loginInfo->accessToken); UserAccessTokenFree(loginInfo->accessToken);
Free(loginInfo->refreshToken); Free(loginInfo->refreshToken);

View file

@ -72,7 +72,7 @@ ROUTE_IMPL(RouteRegister, path, argp)
char *session; char *session;
DbRef *sessionRef; DbRef *sessionRef;
Config *config = ConfigLock(db); Config config = ConfigLock(db);
regReq.username = NULL; regReq.username = NULL;
regReq.password = NULL; regReq.password = NULL;
@ -84,7 +84,7 @@ ROUTE_IMPL(RouteRegister, path, argp)
if (!config) if (!config.ok)
{ {
msg = "Internal server error while locking configuration."; msg = "Internal server error while locking configuration.";
Log(LOG_ERR, "Registration endpoint failed to lock configuration."); Log(LOG_ERR, "Registration endpoint failed to lock configuration.");
@ -117,7 +117,7 @@ ROUTE_IMPL(RouteRegister, path, argp)
if (regReq.username) if (regReq.username)
{ {
if (!UserValidate(regReq.username, config->serverName)) if (!UserValidate(regReq.username, config.serverName))
{ {
HttpResponseStatus(args->context, HTTP_BAD_REQUEST); HttpResponseStatus(args->context, HTTP_BAD_REQUEST);
response = MatrixErrorCreate(M_INVALID_USERNAME, NULL); response = MatrixErrorCreate(M_INVALID_USERNAME, NULL);
@ -135,7 +135,7 @@ ROUTE_IMPL(RouteRegister, path, argp)
uiaFlows = ArrayCreate(); uiaFlows = ArrayCreate();
ArrayAdd(uiaFlows, RouteRegisterRegFlow()); ArrayAdd(uiaFlows, RouteRegisterRegFlow());
if (config->registration) if (config.registration)
{ {
ArrayAdd(uiaFlows, UiaDummyFlow()); ArrayAdd(uiaFlows, UiaDummyFlow());
} }
@ -182,7 +182,7 @@ ROUTE_IMPL(RouteRegister, path, argp)
response = HashMapCreate(); response = HashMapCreate();
fullUsername = StrConcat(4, fullUsername = StrConcat(4,
"@", UserGetName(user), ":", config->serverName); "@", UserGetName(user), ":", config.serverName);
HashMapSet(response, "user_id", JsonValueString(fullUsername)); HashMapSet(response, "user_id", JsonValueString(fullUsername));
Free(fullUsername); Free(fullUsername);
@ -259,7 +259,7 @@ finish:
HttpResponseStatus(args->context, HTTP_BAD_REQUEST); HttpResponseStatus(args->context, HTTP_BAD_REQUEST);
response = MatrixErrorCreate(M_MISSING_PARAM, msg); response = MatrixErrorCreate(M_MISSING_PARAM, msg);
} }
else if (!UserValidate(username, config->serverName)) else if (!UserValidate(username, config.serverName))
{ {
HttpResponseStatus(args->context, HTTP_BAD_REQUEST); HttpResponseStatus(args->context, HTTP_BAD_REQUEST);
response = MatrixErrorCreate(M_INVALID_USERNAME, NULL); response = MatrixErrorCreate(M_INVALID_USERNAME, NULL);

View file

@ -51,12 +51,12 @@ ROUTE_IMPL(RouteUiaFallback, path, argp)
HashMap *request; HashMap *request;
HashMap *response; HashMap *response;
int uiaResult; int uiaResult;
Config *config; Config config;
Array *flows; Array *flows;
Array *flow; Array *flow;
config = ConfigLock(args->matrixArgs->db); config = ConfigLock(args->matrixArgs->db);
if (!config) if (!config.ok)
{ {
msg = "Internal server error: failed to lock configuration."; msg = "Internal server error: failed to lock configuration.";
Log(LOG_ERR, "UIA fallback failed to lock configuration."); Log(LOG_ERR, "UIA fallback failed to lock configuration.");

View file

@ -50,16 +50,16 @@ ROUTE_IMPL(RouteUserProfile, path, argp)
char *msg; char *msg;
Config *config = ConfigLock(db); Config config = ConfigLock(db);
if (!config) if (!config.ok)
{ {
Log(LOG_ERR, "User profile endpoint failed to lock configuration."); Log(LOG_ERR, "User profile endpoint failed to lock configuration.");
HttpResponseStatus(args->context, HTTP_INTERNAL_SERVER_ERROR); HttpResponseStatus(args->context, HTTP_INTERNAL_SERVER_ERROR);
return MatrixErrorCreate(M_UNKNOWN, NULL); return MatrixErrorCreate(M_UNKNOWN, NULL);
} }
serverName = config->serverName; serverName = config.serverName;
username = ArrayGet(path, 0); username = ArrayGet(path, 0);
userId = UserIdParse(username, serverName); userId = UserIdParse(username, serverName);

View file

@ -35,11 +35,11 @@ ROUTE_IMPL(RouteWellKnown, path, argp)
RouteArgs *args = argp; RouteArgs *args = argp;
HashMap *response; HashMap *response;
Config *config = ConfigLock(args->matrixArgs->db); Config config = ConfigLock(args->matrixArgs->db);
char *msg; char *msg;
if (!config) if (!config.ok)
{ {
Log(LOG_ERR, "Well-known endpoint failed to lock configuration."); Log(LOG_ERR, "Well-known endpoint failed to lock configuration.");
msg = "Internal server error: couldn't lock database."; msg = "Internal server error: couldn't lock database.";
@ -49,7 +49,7 @@ ROUTE_IMPL(RouteWellKnown, path, argp)
if (StrEquals(ArrayGet(path, 0), "client")) if (StrEquals(ArrayGet(path, 0), "client"))
{ {
response = MatrixClientWellKnown(config->baseUrl, config->identityServer); response = MatrixClientWellKnown(config.baseUrl, config.identityServer);
} }
else else
{ {

View file

@ -44,9 +44,9 @@ ROUTE_IMPL(RouteWhoami, path, argp)
char *deviceID; char *deviceID;
char *msg; char *msg;
Config *config = ConfigLock(db); Config config = ConfigLock(db);
if (!config) if (!config.ok)
{ {
msg = "Internal server error: couldn't lock database."; msg = "Internal server error: couldn't lock database.";
Log(LOG_ERR, "Who am I endpoint failed to lock configuration."); Log(LOG_ERR, "Who am I endpoint failed to lock configuration.");
@ -75,7 +75,7 @@ ROUTE_IMPL(RouteWhoami, path, argp)
response = HashMapCreate(); response = HashMapCreate();
userID = StrConcat(4, "@", UserGetName(user), ":", config->serverName); userID = StrConcat(4, "@", UserGetName(user), ":", config.serverName);
deviceID = StrDuplicate(UserGetDeviceId(user)); deviceID = StrDuplicate(UserGetDeviceId(user));
UserUnlock(user); UserUnlock(user);
@ -88,5 +88,6 @@ ROUTE_IMPL(RouteWhoami, path, argp)
finish: finish:
ConfigUnlock(config); ConfigUnlock(config);
ConfigFree(&config);
return response; return response;
} }

View file

@ -205,7 +205,7 @@ UiaStageBuild(char *type, HashMap * params)
int int
UiaComplete(Array * flows, HttpServerContext * context, Db * db, UiaComplete(Array * flows, HttpServerContext * context, Db * db,
HashMap * request, HashMap ** response, Config * config) HashMap * request, HashMap ** response, Config config)
{ {
JsonValue *val; JsonValue *val;
HashMap *auth; HashMap *auth;
@ -362,10 +362,10 @@ UiaComplete(Array * flows, HttpServerContext * context, Db * db,
type = JsonValueAsString(HashMapGet(identifier, "type")); type = JsonValueAsString(HashMapGet(identifier, "type"));
userId = UserIdParse(JsonValueAsString(HashMapGet(identifier, "user")), userId = UserIdParse(JsonValueAsString(HashMapGet(identifier, "user")),
config->serverName); config.serverName);
if (!type || !StrEquals(type, "m.id.user") if (!type || !StrEquals(type, "m.id.user")
|| !userId || !StrEquals(userId->server, config->serverName)) || !userId || !StrEquals(userId->server, config.serverName))
{ {
HttpResponseStatus(context, HTTP_UNAUTHORIZED); HttpResponseStatus(context, HTTP_UNAUTHORIZED);
ret = BuildResponse(flows, db, response, session, dbRef); ret = BuildResponse(flows, db, response, session, dbRef);

View file

@ -64,14 +64,7 @@
* set the ok flag to 0. The caller should always check the ok flag, * set the ok flag to 0. The caller should always check the ok flag,
* and if there is an error, it should display the error to the user. * and if there is an error, it should display the error to the user.
*/ */
extern Config * ConfigParse(HashMap *); extern Config ConfigParse(HashMap *);
/**
* Free all the values inside of the given configuration structure,
* as well as the structure itself, such that it is completely invalid
* when this function returns.
*/
extern void ConfigFullyFree(Config *);
/** /**
* Check whether or not the configuration exists in the database, * Check whether or not the configuration exists in the database,
@ -94,7 +87,7 @@ extern int ConfigCreateDefault(Db *);
* The return value of this function is the same as * The return value of this function is the same as
* .Fn ConfigParse . * .Fn ConfigParse .
*/ */
extern Config * ConfigLock(Db *); extern Config ConfigLock(Db *);
/** /**
* Unlock the specified configuration, returning it back to the * Unlock the specified configuration, returning it back to the
@ -102,7 +95,7 @@ extern Config * ConfigLock(Db *);
* this config object, so values that should be retained after this is * this config object, so values that should be retained after this is
* called should be duplicated as necessary. * called should be duplicated as necessary.
*/ */
extern int ConfigUnlock(Config *); extern int ConfigUnlock(Config);
/** /**
* Converts a ConfigLogLevel into a valid syslog level. * Converts a ConfigLogLevel into a valid syslog level.

View file

@ -132,7 +132,7 @@ extern void UiaCleanup(MatrixHttpHandlerArgs *);
* the caller proceed with its logic. * the caller proceed with its logic.
*/ */
extern int extern int
UiaComplete(Array *, HttpServerContext *, Db *, HashMap *, HashMap **, Config *); UiaComplete(Array *, HttpServerContext *, Db *, HashMap *, HashMap **, Config);
/** /**
* Free an array of flows, as described above. Even though the caller * Free an array of flows, as described above. Even though the caller