forked from Telodendria/Telodendria
Compare commits
No commits in common. "da8a64534a0a945bcd0ea4fe8d3b87bd1c6f55df" and "a089224630f7434b6b50ee3d166e410400b39224" have entirely different histories.
da8a64534a
...
a089224630
17 changed files with 159 additions and 131 deletions
|
@ -6,8 +6,8 @@
|
||||||
"types": {
|
"types": {
|
||||||
"ConfigTls": {
|
"ConfigTls": {
|
||||||
"fields": {
|
"fields": {
|
||||||
"cert": { "type": "string", "required": true },
|
"cert": { "type": "string" },
|
||||||
"key": { "type": "string", "required": true }
|
"key": { "type": "string" }
|
||||||
},
|
},
|
||||||
"type": "struct"
|
"type": "struct"
|
||||||
},
|
},
|
||||||
|
|
|
@ -19,7 +19,8 @@ key-value form:
|
||||||
"serverName": "telodendria.io",
|
"serverName": "telodendria.io",
|
||||||
"listen": [
|
"listen": [
|
||||||
{
|
{
|
||||||
"port": 8008
|
"port": 8008,
|
||||||
|
"tls": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -50,7 +51,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`
|
- **tls:** `Object|null|false`
|
||||||
|
|
||||||
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
|
||||||
|
|
88
src/Config.c
88
src/Config.c
|
@ -44,48 +44,47 @@
|
||||||
#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)
|
||||||
{
|
{
|
||||||
tConfig.ok = 0;
|
return NULL;
|
||||||
tConfig.err = "Invalid object given as config.";
|
|
||||||
return tConfig;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&tConfig, 0, sizeof(Config));
|
tConfig = Malloc(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);
|
||||||
|
@ -99,12 +98,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +120,6 @@ ConfigCreateDefault(Db * db)
|
||||||
ConfigListener *listener;
|
ConfigListener *listener;
|
||||||
|
|
||||||
HashMap *json;
|
HashMap *json;
|
||||||
JsonValue *val;
|
|
||||||
|
|
||||||
DbRef *ref;
|
DbRef *ref;
|
||||||
|
|
||||||
|
@ -149,17 +147,16 @@ 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, 32);
|
listener->maxConnections = Int64Create(0, 0);
|
||||||
listener->port = Int64Create(0, 8008);
|
listener->port = Int64Create(0, 8008);
|
||||||
listener->threads = Int64Create(0, 4);
|
listener->threads = Int64Create(0, 0);
|
||||||
|
|
||||||
|
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)
|
||||||
|
@ -176,44 +173,53 @@ 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)
|
||||||
{
|
{
|
||||||
config.ok = 0;
|
return NULL;
|
||||||
config.err = "Couldn't lock configuration.";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
config = ConfigParse(DbJson(ref));
|
config = ConfigParse(DbJson(ref));
|
||||||
if (config.ok)
|
if (config)
|
||||||
{
|
{
|
||||||
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.ok)
|
if (!config)
|
||||||
{
|
{
|
||||||
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
|
||||||
|
|
75
src/Main.c
75
src/Main.c
|
@ -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,19 +265,27 @@ start:
|
||||||
Log(LOG_NOTICE, "Loading configuration...");
|
Log(LOG_NOTICE, "Loading configuration...");
|
||||||
|
|
||||||
tConfig = ConfigLock(matrixArgs.db);
|
tConfig = ConfigLock(matrixArgs.db);
|
||||||
if (!tConfig.ok)
|
if (!tConfig)
|
||||||
{
|
{
|
||||||
Log(LOG_ERR, tConfig.err);
|
Log(LOG_ERR, "Error locking the configuration.");
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
@ -290,9 +298,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");
|
||||||
|
|
||||||
|
@ -300,18 +308,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);
|
||||||
|
@ -330,30 +338,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();
|
||||||
|
@ -365,9 +373,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;
|
||||||
|
|
||||||
|
@ -430,10 +438,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)
|
||||||
{
|
{
|
||||||
|
@ -463,7 +471,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
|
||||||
|
@ -475,7 +483,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)
|
||||||
{
|
{
|
||||||
|
@ -488,18 +496,17 @@ 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)
|
||||||
|
|
|
@ -67,9 +67,9 @@ ROUTE_IMPL(RouteChangePwd, path, argp)
|
||||||
|
|
||||||
char *msg;
|
char *msg;
|
||||||
|
|
||||||
Config config = ConfigLock(db);
|
Config *config = ConfigLock(db);
|
||||||
|
|
||||||
if (!config.ok)
|
if (!config)
|
||||||
{
|
{
|
||||||
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);
|
||||||
|
|
|
@ -36,10 +36,10 @@ ROUTE_IMPL(RouteConfig, path, argp)
|
||||||
char *msg;
|
char *msg;
|
||||||
|
|
||||||
User *user = NULL;
|
User *user = NULL;
|
||||||
Config config;
|
Config *config = NULL;
|
||||||
|
|
||||||
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.ok)
|
if (!config)
|
||||||
{
|
{
|
||||||
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,9 +91,17 @@ ROUTE_IMPL(RouteConfig, path, argp)
|
||||||
}
|
}
|
||||||
|
|
||||||
newConf = ConfigParse(request);
|
newConf = ConfigParse(request);
|
||||||
if (newConf.ok)
|
if (!newConf)
|
||||||
{
|
{
|
||||||
if (DbJsonSet(config.ref, request))
|
msg = "Internal server error while parsing config.";
|
||||||
|
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();
|
||||||
/*
|
/*
|
||||||
|
@ -112,10 +120,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigFree(&newConf);
|
ConfigFullyFree(newConf);
|
||||||
JsonFree(request);
|
JsonFree(request);
|
||||||
break;
|
break;
|
||||||
case HTTP_PUT:
|
case HTTP_PUT:
|
||||||
|
@ -127,12 +135,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.ok)
|
if (!newConf)
|
||||||
{
|
{
|
||||||
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);
|
||||||
|
@ -140,9 +148,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();
|
||||||
/*
|
/*
|
||||||
|
@ -161,10 +169,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigFree(&newConf);
|
ConfigFullyFree(newConf);
|
||||||
JsonFree(request);
|
JsonFree(request);
|
||||||
JsonFree(newJson);
|
JsonFree(newJson);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -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.ok)
|
if (!config)
|
||||||
{
|
{
|
||||||
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);
|
||||||
|
|
|
@ -39,14 +39,14 @@ GetServerName(Db * db)
|
||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
Config config = ConfigLock(db);
|
Config *config = ConfigLock(db);
|
||||||
|
|
||||||
if (!config.ok)
|
if (!config)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
name = StrDuplicate(config.serverName);
|
name = StrDuplicate(config->serverName);
|
||||||
|
|
||||||
ConfigUnlock(config);
|
ConfigUnlock(config);
|
||||||
|
|
||||||
|
|
|
@ -64,9 +64,9 @@ ROUTE_IMPL(RouteLogin, path, argp)
|
||||||
|
|
||||||
char *msg;
|
char *msg;
|
||||||
|
|
||||||
Config config = ConfigLock(db);
|
Config *config = ConfigLock(db);
|
||||||
|
|
||||||
if (!config.ok)
|
if (!config)
|
||||||
{
|
{
|
||||||
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);
|
||||||
|
|
|
@ -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.ok)
|
if (!config)
|
||||||
{
|
{
|
||||||
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);
|
||||||
|
|
|
@ -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.ok)
|
if (!config)
|
||||||
{
|
{
|
||||||
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.");
|
||||||
|
|
|
@ -50,16 +50,16 @@ ROUTE_IMPL(RouteUserProfile, path, argp)
|
||||||
|
|
||||||
char *msg;
|
char *msg;
|
||||||
|
|
||||||
Config config = ConfigLock(db);
|
Config *config = ConfigLock(db);
|
||||||
|
|
||||||
if (!config.ok)
|
if (!config)
|
||||||
{
|
{
|
||||||
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);
|
||||||
|
|
|
@ -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.ok)
|
if (!config)
|
||||||
{
|
{
|
||||||
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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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.ok)
|
if (!config)
|
||||||
{
|
{
|
||||||
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,6 +88,5 @@ ROUTE_IMPL(RouteWhoami, path, argp)
|
||||||
|
|
||||||
finish:
|
finish:
|
||||||
ConfigUnlock(config);
|
ConfigUnlock(config);
|
||||||
ConfigFree(&config);
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -64,7 +64,14 @@
|
||||||
* 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,
|
||||||
|
@ -87,7 +94,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
|
||||||
|
@ -95,7 +102,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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue