forked from Telodendria/Telodendria
Add a global log configuration.
This is the easiest and cleanest way to get logging into some of the fundamental APIs, such as the database and TLS APIs. We don't want to have to pass logging functions to those, but they can safely use the global logging configuration.
This commit is contained in:
parent
8782aa046d
commit
f3c4c0ac65
13 changed files with 207 additions and 142 deletions
41
TODO.txt
41
TODO.txt
|
@ -6,52 +6,63 @@ Key:
|
||||||
[ ] Not Started
|
[ ] Not Started
|
||||||
[x] Done
|
[x] Done
|
||||||
[~] In Progress
|
[~] In Progress
|
||||||
[!] Won't Fix
|
[!] Won't Do
|
||||||
|
|
||||||
Milestone: v0.3.0
|
Milestone: v0.3.0
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
[~] Stream API
|
[x] Stream API
|
||||||
[x] Implementation
|
[x] Implementation
|
||||||
[x] Convert all code that deals with I/O
|
[x] Convert all code that deals with I/O
|
||||||
[!] Multi-output (proof of concept)
|
[!] Multi-output (proof of concept)
|
||||||
[!] Memory streams (proof of concept)
|
[!] Memory streams (proof of concept)
|
||||||
[~] TLS
|
[x] TLS
|
||||||
[ ] SOCKS
|
[!] SOCKS
|
||||||
[x] Move/convert UtilStreamCopy()
|
[x] Move/convert UtilStreamCopy()
|
||||||
[ ] Io man page
|
[x] HTTP Client API
|
||||||
[ ] Stream man page
|
|
||||||
[ ] Tls man page
|
|
||||||
[~] HTTP Client API
|
|
||||||
[x] Document HttpParseHeaders()
|
[x] Document HttpParseHeaders()
|
||||||
[ ] HttpClient man page
|
|
||||||
[ ] Uri man page
|
|
||||||
[x] Test on other platforms
|
[x] Test on other platforms
|
||||||
[x] Option to pretty-print Json
|
[x] Option to pretty-print Json
|
||||||
[x] Document JsonEncode() and JsonEncodeValue()
|
[x] Document JsonEncode() and JsonEncodeValue()
|
||||||
[ ] Update man page for td
|
|
||||||
[x] Document Telodendria and Main
|
[x] Document Telodendria and Main
|
||||||
[ ] Document tt and http-debug-server
|
|
||||||
|
|
||||||
[x] Simple command line tool to make matrix requests
|
[x] Simple command line tool to make matrix requests
|
||||||
[x] Built on HTTP client API
|
[x] Built on HTTP client API
|
||||||
[x] http man page
|
[x] http man page
|
||||||
[~] Simple command line tool for working with JSON
|
[x] Simple command line tool for working with JSON
|
||||||
[x] Pretty-print Json
|
[x] Pretty-print Json
|
||||||
[x] Query fields for use in shell scripts.
|
[x] Query fields for use in shell scripts.
|
||||||
[x] Encode user-provided JSON strings
|
[x] Encode user-provided JSON strings
|
||||||
[x] json man page
|
[x] json man page
|
||||||
[ ] Update man pages for tp and send-patch
|
|
||||||
|
|
||||||
|
[x] Global log object
|
||||||
|
- So we don't have to pass LogConfig around everywhere
|
||||||
|
- Also allows debug and error logging in other APIs
|
||||||
[ ] Proper HTTP request router
|
[ ] Proper HTTP request router
|
||||||
- Support regex matching
|
- Support regex matching
|
||||||
|
|
||||||
[ ] Move configuration to database
|
[ ] Move configuration to database
|
||||||
[ ] Initial configuration
|
[ ] Initial configuration
|
||||||
[ ] If no config, create one-time use registration token that
|
[ ] If no config, create one-time use registration token that
|
||||||
grants user admin privileges.
|
grants user admin privileges.
|
||||||
[ ] /_telodendria/admin/config endpoint
|
[ ] /_telodendria/admin/config endpoint
|
||||||
[ ] Refactor TelodendriaConfig to just Config (ConfigLock() and ConfigUnlock())
|
[ ] Refactor TelodendriaConfig to just Config (ConfigLock() and ConfigUnlock())
|
||||||
|
[ ] Make 'listen' directive in config an array of objects
|
||||||
|
- Each object has port, threads, maxConnections
|
||||||
|
- If tls is given, it can be null, false, or an object with cert and key
|
||||||
|
[ ] Pass TLS certs and keys into HttpServer
|
||||||
|
|
||||||
|
[ ] Documentation
|
||||||
|
[ ] Io
|
||||||
|
[ ] Stream
|
||||||
|
[ ] Tls
|
||||||
|
[ ] HttpClient
|
||||||
|
[ ] Uri
|
||||||
|
[ ] td
|
||||||
|
[ ] tt
|
||||||
|
[ ] http-debug-server
|
||||||
|
[ ] tp
|
||||||
|
[ ] send-patch
|
||||||
|
[ ] Log
|
||||||
|
|
||||||
[~] Client-Server API
|
[~] Client-Server API
|
||||||
[x] 4: Token-based user registration
|
[x] 4: Token-based user registration
|
||||||
|
|
45
src/Log.c
45
src/Log.c
|
@ -45,6 +45,8 @@ struct LogConfig
|
||||||
pthread_mutex_t lock;
|
pthread_mutex_t lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
LogConfig *globalConfig = NULL;
|
||||||
|
|
||||||
LogConfig *
|
LogConfig *
|
||||||
LogConfigCreate(void)
|
LogConfigCreate(void)
|
||||||
{
|
{
|
||||||
|
@ -68,6 +70,17 @@ LogConfigCreate(void)
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LogConfig *
|
||||||
|
LogConfigGlobal(void)
|
||||||
|
{
|
||||||
|
if (!globalConfig)
|
||||||
|
{
|
||||||
|
globalConfig = LogConfigCreate();
|
||||||
|
}
|
||||||
|
|
||||||
|
return globalConfig;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
LogConfigFlagClear(LogConfig * config, int flags)
|
LogConfigFlagClear(LogConfig * config, int flags)
|
||||||
{
|
{
|
||||||
|
@ -111,6 +124,11 @@ LogConfigFree(LogConfig * config)
|
||||||
|
|
||||||
StreamClose(config->out);
|
StreamClose(config->out);
|
||||||
Free(config);
|
Free(config);
|
||||||
|
|
||||||
|
if (config == globalConfig)
|
||||||
|
{
|
||||||
|
globalConfig = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -202,12 +220,11 @@ LogConfigUnindent(LogConfig * config)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Log(LogConfig * config, int level, const char *msg,...)
|
Logv(LogConfig * config, int level, const char *msg, va_list argp)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
int doColor;
|
int doColor;
|
||||||
char indicator;
|
char indicator;
|
||||||
va_list argp;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Only proceed if we have a config and its log level is set to a
|
* Only proceed if we have a config and its log level is set to a
|
||||||
|
@ -232,9 +249,7 @@ Log(LogConfig * config, int level, const char *msg,...)
|
||||||
{
|
{
|
||||||
/* No further print logic is needed; syslog will handle it all
|
/* No further print logic is needed; syslog will handle it all
|
||||||
* for us. */
|
* for us. */
|
||||||
va_start(argp, msg);
|
|
||||||
vsyslog(level, msg, argp);
|
vsyslog(level, msg, argp);
|
||||||
va_end(argp);
|
|
||||||
pthread_mutex_unlock(&config->lock);
|
pthread_mutex_unlock(&config->lock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -345,12 +360,30 @@ Log(LogConfig * config, int level, const char *msg,...)
|
||||||
StreamPutc(config->out, ' ');
|
StreamPutc(config->out, ' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
va_start(argp, msg);
|
|
||||||
StreamVprintf(config->out, msg, argp);
|
StreamVprintf(config->out, msg, argp);
|
||||||
StreamPutc(config->out, '\n');
|
StreamPutc(config->out, '\n');
|
||||||
va_end(argp);
|
|
||||||
|
|
||||||
StreamFlush(config->out);
|
StreamFlush(config->out);
|
||||||
|
|
||||||
pthread_mutex_unlock(&config->lock);
|
pthread_mutex_unlock(&config->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LogTo(LogConfig *config, int level, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list argp;
|
||||||
|
|
||||||
|
va_start(argp, fmt);
|
||||||
|
Logv(config, level, fmt, argp);
|
||||||
|
va_end(argp);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void
|
||||||
|
Log(int level, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list argp;
|
||||||
|
|
||||||
|
va_start(argp, fmt);
|
||||||
|
Logv(LogConfigGlobal(), level, fmt, argp);
|
||||||
|
va_end(argp);
|
||||||
|
}
|
||||||
|
|
140
src/Main.c
140
src/Main.c
|
@ -63,7 +63,6 @@ typedef enum ArgFlag
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
LogConfig *lc;
|
|
||||||
int exit = EXIT_SUCCESS;
|
int exit = EXIT_SUCCESS;
|
||||||
|
|
||||||
/* Arg parsing */
|
/* Arg parsing */
|
||||||
|
@ -90,17 +89,15 @@ main(int argc, char **argv)
|
||||||
|
|
||||||
memset(&matrixArgs, 0, sizeof(matrixArgs));
|
memset(&matrixArgs, 0, sizeof(matrixArgs));
|
||||||
|
|
||||||
lc = LogConfigCreate();
|
if (!LogConfigGlobal())
|
||||||
|
|
||||||
if (!lc)
|
|
||||||
{
|
{
|
||||||
printf("Fatal error: unable to allocate memory for logger.\n");
|
printf("Fatal error: unable to allocate memory for logger.\n");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryHook(TelodendriaMemoryHook, lc);
|
MemoryHook(TelodendriaMemoryHook, NULL);
|
||||||
|
|
||||||
TelodendriaPrintHeader(lc);
|
TelodendriaPrintHeader();
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv, "f:Vvn")) != -1)
|
while ((opt = getopt(argc, argv, "f:Vvn")) != -1)
|
||||||
{
|
{
|
||||||
|
@ -128,7 +125,7 @@ main(int argc, char **argv)
|
||||||
|
|
||||||
if (flags & ARG_VERBOSE)
|
if (flags & ARG_VERBOSE)
|
||||||
{
|
{
|
||||||
LogConfigLevelSet(lc, LOG_DEBUG);
|
LogConfigLevelSet(LogConfigGlobal(), LOG_DEBUG);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & ARG_VERSION)
|
if (flags & ARG_VERSION)
|
||||||
|
@ -138,7 +135,7 @@ main(int argc, char **argv)
|
||||||
|
|
||||||
if (!configArg)
|
if (!configArg)
|
||||||
{
|
{
|
||||||
Log(lc, LOG_ERR, "No configuration file specified.");
|
Log(LOG_ERR, "No configuration file specified.");
|
||||||
exit = EXIT_FAILURE;
|
exit = EXIT_FAILURE;
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
@ -153,25 +150,25 @@ main(int argc, char **argv)
|
||||||
configFile = StreamOpen(configArg, "r");
|
configFile = StreamOpen(configArg, "r");
|
||||||
if (!configFile)
|
if (!configFile)
|
||||||
{
|
{
|
||||||
Log(lc, LOG_ERR, "Unable to open configuration file '%s' for reading.", configArg);
|
Log(LOG_ERR, "Unable to open configuration file '%s' for reading.", configArg);
|
||||||
exit = EXIT_FAILURE;
|
exit = EXIT_FAILURE;
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Log(lc, LOG_NOTICE, "Processing configuration file '%s'.", configArg);
|
Log(LOG_NOTICE, "Processing configuration file '%s'.", configArg);
|
||||||
|
|
||||||
config = JsonDecode(configFile);
|
config = JsonDecode(configFile);
|
||||||
StreamClose(configFile);
|
StreamClose(configFile);
|
||||||
|
|
||||||
if (!config)
|
if (!config)
|
||||||
{
|
{
|
||||||
Log(lc, LOG_ERR, "Syntax error in configuration file.");
|
Log(LOG_ERR, "Syntax error in configuration file.");
|
||||||
exit = EXIT_FAILURE;
|
exit = EXIT_FAILURE;
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
tConfig = TelodendriaConfigParse(config, lc);
|
tConfig = TelodendriaConfigParse(config, LogConfigGlobal());
|
||||||
JsonFree(config);
|
JsonFree(config);
|
||||||
|
|
||||||
if (!tConfig)
|
if (!tConfig)
|
||||||
|
@ -182,13 +179,13 @@ main(int argc, char **argv)
|
||||||
|
|
||||||
if (flags & ARG_CONFIGTEST)
|
if (flags & ARG_CONFIGTEST)
|
||||||
{
|
{
|
||||||
Log(lc, LOG_INFO, "Configuration is OK.");
|
Log(LOG_INFO, "Configuration is OK.");
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tConfig->logTimestamp || strcmp(tConfig->logTimestamp, "default") != 0)
|
if (!tConfig->logTimestamp || strcmp(tConfig->logTimestamp, "default") != 0)
|
||||||
{
|
{
|
||||||
LogConfigTimeStampFormatSet(lc, tConfig->logTimestamp);
|
LogConfigTimeStampFormatSet(LogConfigGlobal(), tConfig->logTimestamp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -198,24 +195,24 @@ main(int argc, char **argv)
|
||||||
|
|
||||||
if (tConfig->flags & TELODENDRIA_LOG_COLOR)
|
if (tConfig->flags & TELODENDRIA_LOG_COLOR)
|
||||||
{
|
{
|
||||||
LogConfigFlagSet(lc, LOG_FLAG_COLOR);
|
LogConfigFlagSet(LogConfigGlobal(), LOG_FLAG_COLOR);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogConfigFlagClear(lc, LOG_FLAG_COLOR);
|
LogConfigFlagClear(LogConfigGlobal(), LOG_FLAG_COLOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogConfigLevelSet(lc, flags & ARG_VERBOSE ? LOG_DEBUG : tConfig->logLevel);
|
LogConfigLevelSet(LogConfigGlobal(), flags & ARG_VERBOSE ? LOG_DEBUG : tConfig->logLevel);
|
||||||
|
|
||||||
if (chdir(tConfig->dataDir) != 0)
|
if (chdir(tConfig->dataDir) != 0)
|
||||||
{
|
{
|
||||||
Log(lc, LOG_ERR, "Unable to change into data directory: %s.", strerror(errno));
|
Log(LOG_ERR, "Unable to change into data directory: %s.", strerror(errno));
|
||||||
exit = EXIT_FAILURE;
|
exit = EXIT_FAILURE;
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log(lc, LOG_DEBUG, "Changed working directory to: %s", tConfig->dataDir);
|
Log(LOG_DEBUG, "Changed working directory to: %s", tConfig->dataDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -225,22 +222,22 @@ main(int argc, char **argv)
|
||||||
|
|
||||||
if (!logFile)
|
if (!logFile)
|
||||||
{
|
{
|
||||||
Log(lc, 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;
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log(lc, 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(lc, logFile);
|
LogConfigOutputSet(LogConfigGlobal(), logFile);
|
||||||
}
|
}
|
||||||
else if (tConfig->flags & TELODENDRIA_LOG_STDOUT)
|
else if (tConfig->flags & TELODENDRIA_LOG_STDOUT)
|
||||||
{
|
{
|
||||||
Log(lc, LOG_DEBUG, "Already logging to standard output.");
|
Log(LOG_DEBUG, "Already logging to standard output.");
|
||||||
}
|
}
|
||||||
else if (tConfig->flags & TELODENDRIA_LOG_SYSLOG)
|
else if (tConfig->flags & TELODENDRIA_LOG_SYSLOG)
|
||||||
{
|
{
|
||||||
Log(lc, 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(lc, LOG_FLAG_SYSLOG);
|
LogConfigFlagSet(LogConfigGlobal(), LOG_FLAG_SYSLOG);
|
||||||
|
|
||||||
openlog("telodendria", LOG_PID | LOG_NDELAY, LOG_DAEMON);
|
openlog("telodendria", LOG_PID | LOG_NDELAY, LOG_DAEMON);
|
||||||
/* Always log everything, because the Log API will control what
|
/* Always log everything, because the Log API will control what
|
||||||
|
@ -249,28 +246,27 @@ main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log(lc, LOG_ERR, "Unknown logging method in flags: '%d'", tConfig->flags);
|
Log(LOG_ERR, "Unknown logging method in flags: '%d'", tConfig->flags);
|
||||||
Log(lc, LOG_ERR, "This is a programmer error; please report it.");
|
Log(LOG_ERR, "This is a programmer error; please report it.");
|
||||||
exit = EXIT_FAILURE;
|
exit = EXIT_FAILURE;
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log(lc, LOG_DEBUG, "Configuration:");
|
Log(LOG_DEBUG, "Configuration:");
|
||||||
LogConfigIndent(lc);
|
LogConfigIndent(LogConfigGlobal());
|
||||||
Log(lc, LOG_DEBUG, "Listen On: %d", tConfig->listenPort);
|
Log(LOG_DEBUG, "Listen On: %d", tConfig->listenPort);
|
||||||
Log(lc, LOG_DEBUG, "Server Name: %s", tConfig->serverName);
|
Log(LOG_DEBUG, "Server Name: %s", tConfig->serverName);
|
||||||
Log(lc, LOG_DEBUG, "Base URL: %s", tConfig->baseUrl);
|
Log(LOG_DEBUG, "Base URL: %s", tConfig->baseUrl);
|
||||||
Log(lc, LOG_DEBUG, "Identity Server: %s", tConfig->identityServer);
|
Log(LOG_DEBUG, "Identity Server: %s", tConfig->identityServer);
|
||||||
Log(lc, LOG_DEBUG, "Run As: %s:%s", tConfig->uid, tConfig->gid);
|
Log(LOG_DEBUG, "Run As: %s:%s", tConfig->uid, tConfig->gid);
|
||||||
Log(lc, LOG_DEBUG, "Data Directory: %s", tConfig->dataDir);
|
Log(LOG_DEBUG, "Data Directory: %s", tConfig->dataDir);
|
||||||
Log(lc, LOG_DEBUG, "Threads: %d", tConfig->threads);
|
Log(LOG_DEBUG, "Threads: %d", tConfig->threads);
|
||||||
Log(lc, LOG_DEBUG, "Max Connections: %d", tConfig->maxConnections);
|
Log(LOG_DEBUG, "Max Connections: %d", tConfig->maxConnections);
|
||||||
Log(lc, LOG_DEBUG, "Max Cache: %ld", tConfig->maxCache);
|
Log(LOG_DEBUG, "Max Cache: %ld", tConfig->maxCache);
|
||||||
Log(lc, LOG_DEBUG, "Flags: %x", tConfig->flags);
|
Log(LOG_DEBUG, "Flags: %x", tConfig->flags);
|
||||||
LogConfigUnindent(lc);
|
LogConfigUnindent(LogConfigGlobal());
|
||||||
|
|
||||||
/* Arguments to pass into the HTTP handler */
|
/* Arguments to pass into the HTTP handler */
|
||||||
matrixArgs.lc = lc;
|
|
||||||
matrixArgs.config = tConfig;
|
matrixArgs.config = tConfig;
|
||||||
|
|
||||||
/* Bind the socket before possibly dropping permissions */
|
/* Bind the socket before possibly dropping permissions */
|
||||||
|
@ -278,13 +274,13 @@ main(int argc, char **argv)
|
||||||
tConfig->maxConnections, MatrixHttpHandler, &matrixArgs);
|
tConfig->maxConnections, MatrixHttpHandler, &matrixArgs);
|
||||||
if (!httpServer)
|
if (!httpServer)
|
||||||
{
|
{
|
||||||
Log(lc, LOG_ERR, "Unable to create HTTP server on port %d: %s",
|
Log(LOG_ERR, "Unable to create HTTP server on port %d: %s",
|
||||||
tConfig->listenPort, strerror(errno));
|
tConfig->listenPort, strerror(errno));
|
||||||
exit = EXIT_FAILURE;
|
exit = EXIT_FAILURE;
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log(lc, LOG_DEBUG, "Running as uid:gid: %d:%d.", getuid(), getgid());
|
Log(LOG_DEBUG, "Running as uid:gid: %d:%d.", getuid(), getgid());
|
||||||
|
|
||||||
if (tConfig->uid && tConfig->gid)
|
if (tConfig->uid && tConfig->gid)
|
||||||
{
|
{
|
||||||
|
@ -293,18 +289,18 @@ main(int argc, char **argv)
|
||||||
|
|
||||||
if (!userInfo || !groupInfo)
|
if (!userInfo || !groupInfo)
|
||||||
{
|
{
|
||||||
Log(lc, LOG_ERR, "Unable to locate the user/group specified in the configuration.");
|
Log(LOG_ERR, "Unable to locate the user/group specified in the configuration.");
|
||||||
exit = EXIT_FAILURE;
|
exit = EXIT_FAILURE;
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log(lc, LOG_DEBUG, "Found user/group information using getpwnam() and getgrnam().");
|
Log(LOG_DEBUG, "Found user/group information using getpwnam() and getgrnam().");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log(lc, LOG_DEBUG, "No user/group info specified in the config.");
|
Log(LOG_DEBUG, "No user/group info specified in the config.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getuid() == 0)
|
if (getuid() == 0)
|
||||||
|
@ -313,35 +309,35 @@ main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
if (setgid(groupInfo->gr_gid) != 0 || setuid(userInfo->pw_uid) != 0)
|
if (setgid(groupInfo->gr_gid) != 0 || setuid(userInfo->pw_uid) != 0)
|
||||||
{
|
{
|
||||||
Log(lc, LOG_ERR, "Unable to set process uid/gid.");
|
Log(LOG_ERR, "Unable to set process uid/gid.");
|
||||||
exit = EXIT_FAILURE;
|
exit = EXIT_FAILURE;
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log(lc, LOG_DEBUG, "Set uid/gid to %s:%s.", tConfig->uid, tConfig->gid);
|
Log(LOG_DEBUG, "Set uid/gid to %s:%s.", tConfig->uid, tConfig->gid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log(lc, LOG_WARNING, "We are running as root, and we are not dropping to another user");
|
Log(LOG_WARNING, "We are running as root, and we are not dropping to another user");
|
||||||
Log(lc, LOG_WARNING, "because none was specified in the configuration file.");
|
Log(LOG_WARNING, "because none was specified in the configuration file.");
|
||||||
Log(lc, LOG_WARNING, "This is probably a security issue.");
|
Log(LOG_WARNING, "This is probably a security issue.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log(lc, LOG_WARNING, "Not setting root directory, because we are not root.");
|
Log(LOG_WARNING, "Not setting root directory, because we are not root.");
|
||||||
|
|
||||||
if (tConfig->uid && tConfig->gid)
|
if (tConfig->uid && tConfig->gid)
|
||||||
{
|
{
|
||||||
if (getuid() != userInfo->pw_uid || getgid() != groupInfo->gr_gid)
|
if (getuid() != userInfo->pw_uid || getgid() != groupInfo->gr_gid)
|
||||||
{
|
{
|
||||||
Log(lc, LOG_WARNING, "Not running as the uid/gid specified in the configuration.");
|
Log(LOG_WARNING, "Not running as the uid/gid specified in the configuration.");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log(lc, LOG_DEBUG, "Running as the uid/gid specified in the configuration.");
|
Log(LOG_DEBUG, "Running as the uid/gid specified in the configuration.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -359,18 +355,16 @@ main(int argc, char **argv)
|
||||||
|
|
||||||
if (!tConfig->maxCache)
|
if (!tConfig->maxCache)
|
||||||
{
|
{
|
||||||
Log(lc, LOG_WARNING, "Database caching is disabled.");
|
Log(LOG_WARNING, "Database caching is disabled.");
|
||||||
Log(lc, LOG_WARNING,
|
Log(LOG_WARNING, "If this is not what you intended, check the config file");
|
||||||
"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(lc, LOG_WARNING,
|
|
||||||
"and ensure that maxCache is a valid number of bytes.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
matrixArgs.db = DbOpen(".", tConfig->maxCache);
|
matrixArgs.db = DbOpen(".", tConfig->maxCache);
|
||||||
|
|
||||||
if (!matrixArgs.db)
|
if (!matrixArgs.db)
|
||||||
{
|
{
|
||||||
Log(lc, LOG_ERR, "Unable to open data directory as a database.");
|
Log(LOG_ERR, "Unable to open data directory as a database.");
|
||||||
exit = EXIT_FAILURE;
|
exit = EXIT_FAILURE;
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
@ -378,28 +372,28 @@ main(int argc, char **argv)
|
||||||
cron = CronCreate(60 * 1000); /* 1-minute tick */
|
cron = CronCreate(60 * 1000); /* 1-minute tick */
|
||||||
if (!cron)
|
if (!cron)
|
||||||
{
|
{
|
||||||
Log(lc, LOG_ERR, "Unable to set up job scheduler.");
|
Log(LOG_ERR, "Unable to set up job scheduler.");
|
||||||
exit = EXIT_FAILURE;
|
exit = EXIT_FAILURE;
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log(lc, LOG_DEBUG, "Registering jobs...");
|
Log(LOG_DEBUG, "Registering jobs...");
|
||||||
|
|
||||||
CronEvery(cron, 30 * 60 * 1000, (JobFunc *) UiaCleanup, &matrixArgs);
|
CronEvery(cron, 30 * 60 * 1000, (JobFunc *) UiaCleanup, &matrixArgs);
|
||||||
|
|
||||||
Log(lc, LOG_NOTICE, "Starting job scheduler...");
|
Log(LOG_NOTICE, "Starting job scheduler...");
|
||||||
CronStart(cron);
|
CronStart(cron);
|
||||||
|
|
||||||
Log(lc, LOG_NOTICE, "Starting server...");
|
Log(LOG_NOTICE, "Starting server...");
|
||||||
|
|
||||||
if (!HttpServerStart(httpServer))
|
if (!HttpServerStart(httpServer))
|
||||||
{
|
{
|
||||||
Log(lc, LOG_ERR, "Unable to start HTTP server.");
|
Log(LOG_ERR, "Unable to start HTTP server.");
|
||||||
exit = EXIT_FAILURE;
|
exit = EXIT_FAILURE;
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log(lc, LOG_INFO, "Listening on port: %d", tConfig->listenPort);
|
Log(LOG_INFO, "Listening on port: %d", tConfig->listenPort);
|
||||||
|
|
||||||
sigAction.sa_handler = TelodendriaSignalHandler;
|
sigAction.sa_handler = TelodendriaSignalHandler;
|
||||||
sigfillset(&sigAction.sa_mask);
|
sigfillset(&sigAction.sa_mask);
|
||||||
|
@ -407,7 +401,7 @@ main(int argc, char **argv)
|
||||||
|
|
||||||
if (sigaction(SIGINT, &sigAction, NULL) < 0)
|
if (sigaction(SIGINT, &sigAction, NULL) < 0)
|
||||||
{
|
{
|
||||||
Log(lc, LOG_ERR, "Unable to install signal handler.");
|
Log(LOG_ERR, "Unable to install signal handler.");
|
||||||
exit = EXIT_FAILURE;
|
exit = EXIT_FAILURE;
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
@ -417,18 +411,18 @@ main(int argc, char **argv)
|
||||||
HttpServerJoin(httpServer);
|
HttpServerJoin(httpServer);
|
||||||
|
|
||||||
finish:
|
finish:
|
||||||
Log(lc, LOG_NOTICE, "Shutting down...");
|
Log(LOG_NOTICE, "Shutting down...");
|
||||||
if (httpServer)
|
if (httpServer)
|
||||||
{
|
{
|
||||||
HttpServerFree(httpServer);
|
HttpServerFree(httpServer);
|
||||||
Log(lc, LOG_DEBUG, "Freed HTTP Server.");
|
Log(LOG_DEBUG, "Freed HTTP Server.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cron)
|
if (cron)
|
||||||
{
|
{
|
||||||
CronStop(cron);
|
CronStop(cron);
|
||||||
CronFree(cron);
|
CronFree(cron);
|
||||||
Log(lc, LOG_DEBUG, "Stopped and freed job scheduler.");
|
Log(LOG_DEBUG, "Stopped and freed job scheduler.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -442,11 +436,9 @@ finish:
|
||||||
|
|
||||||
DbClose(matrixArgs.db);
|
DbClose(matrixArgs.db);
|
||||||
|
|
||||||
LogConfigTimeStampFormatSet(lc, NULL);
|
|
||||||
TelodendriaConfigFree(tConfig);
|
TelodendriaConfigFree(tConfig);
|
||||||
|
|
||||||
|
Log(LOG_DEBUG, "Exiting with code '%d'.", exit);
|
||||||
Log(lc, LOG_DEBUG, "Exiting with code '%d'.", exit);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Uninstall the memory hook because it uses the Log
|
* Uninstall the memory hook because it uses the Log
|
||||||
|
@ -455,7 +447,7 @@ finish:
|
||||||
*/
|
*/
|
||||||
MemoryHook(NULL, NULL);
|
MemoryHook(NULL, NULL);
|
||||||
|
|
||||||
LogConfigFree(lc);
|
LogConfigFree(LogConfigGlobal());
|
||||||
|
|
||||||
/* Standard error should never have been opened, but just in case
|
/* Standard error should never have been opened, but just in case
|
||||||
* it was, this doesn't hurt anything. */
|
* it was, this doesn't hurt anything. */
|
||||||
|
|
10
src/Matrix.c
10
src/Matrix.c
|
@ -38,7 +38,6 @@ void
|
||||||
MatrixHttpHandler(HttpServerContext * context, void *argp)
|
MatrixHttpHandler(HttpServerContext * context, void *argp)
|
||||||
{
|
{
|
||||||
MatrixHttpHandlerArgs *args = (MatrixHttpHandlerArgs *) argp;
|
MatrixHttpHandlerArgs *args = (MatrixHttpHandlerArgs *) argp;
|
||||||
LogConfig *lc = args->lc;
|
|
||||||
Stream *stream;
|
Stream *stream;
|
||||||
HashMap *response = NULL;
|
HashMap *response = NULL;
|
||||||
|
|
||||||
|
@ -52,12 +51,10 @@ MatrixHttpHandler(HttpServerContext * context, void *argp)
|
||||||
|
|
||||||
requestPath = HttpRequestPath(context);
|
requestPath = HttpRequestPath(context);
|
||||||
|
|
||||||
Log(lc, LOG_INFO, "%s %s",
|
Log(LOG_INFO, "%s %s",
|
||||||
HttpRequestMethodToString(HttpRequestMethodGet(context)),
|
HttpRequestMethodToString(HttpRequestMethodGet(context)),
|
||||||
requestPath);
|
requestPath);
|
||||||
|
|
||||||
LogConfigIndent(lc);
|
|
||||||
|
|
||||||
HttpResponseStatus(context, HTTP_OK);
|
HttpResponseStatus(context, HTTP_OK);
|
||||||
HttpResponseHeader(context, "Server", "Telodendria/" TELODENDRIA_VERSION);
|
HttpResponseHeader(context, "Server", "Telodendria/" TELODENDRIA_VERSION);
|
||||||
|
|
||||||
|
@ -78,7 +75,7 @@ MatrixHttpHandler(HttpServerContext * context, void *argp)
|
||||||
HttpResponseStatus(context, HTTP_NO_CONTENT);
|
HttpResponseStatus(context, HTTP_NO_CONTENT);
|
||||||
HttpSendHeaders(context);
|
HttpSendHeaders(context);
|
||||||
|
|
||||||
goto finish;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pathParts = MATRIX_PATH_CREATE();
|
pathParts = MATRIX_PATH_CREATE();
|
||||||
|
@ -146,9 +143,6 @@ MatrixHttpHandler(HttpServerContext * context, void *argp)
|
||||||
}
|
}
|
||||||
|
|
||||||
MATRIX_PATH_FREE(pathParts);
|
MATRIX_PATH_FREE(pathParts);
|
||||||
|
|
||||||
finish:
|
|
||||||
LogConfigUnindent(lc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HashMap *
|
HashMap *
|
||||||
|
|
|
@ -45,7 +45,6 @@ ROUTE_IMPL(RouteRefresh, args)
|
||||||
char *deviceId;
|
char *deviceId;
|
||||||
|
|
||||||
Db *db = args->matrixArgs->db;
|
Db *db = args->matrixArgs->db;
|
||||||
LogConfig *lc = args->matrixArgs->lc;
|
|
||||||
|
|
||||||
User *user = NULL;
|
User *user = NULL;
|
||||||
DbRef *rtRef = NULL;
|
DbRef *rtRef = NULL;
|
||||||
|
@ -96,9 +95,9 @@ ROUTE_IMPL(RouteRefresh, args)
|
||||||
|
|
||||||
if (!oAtRef)
|
if (!oAtRef)
|
||||||
{
|
{
|
||||||
Log(lc, LOG_ERR, "Refresh token '%s' points to an access token that doesn't exist.",
|
Log(LOG_ERR, "Refresh token '%s' points to an access token that doesn't exist.",
|
||||||
refreshToken);
|
refreshToken);
|
||||||
Log(lc, LOG_WARNING, "This refresh token will be deleted.");
|
Log(LOG_WARNING, "This refresh token will be deleted.");
|
||||||
HttpResponseStatus(args->context, HTTP_INTERNAL_SERVER_ERROR);
|
HttpResponseStatus(args->context, HTTP_INTERNAL_SERVER_ERROR);
|
||||||
response = MatrixErrorCreate(M_UNKNOWN);
|
response = MatrixErrorCreate(M_UNKNOWN);
|
||||||
|
|
||||||
|
@ -114,9 +113,9 @@ ROUTE_IMPL(RouteRefresh, args)
|
||||||
user = UserLock(db, JsonValueAsString(HashMapGet(DbJson(oAtRef), "user")));
|
user = UserLock(db, JsonValueAsString(HashMapGet(DbJson(oAtRef), "user")));
|
||||||
if (!user)
|
if (!user)
|
||||||
{
|
{
|
||||||
Log(lc, LOG_ERR, "Access token '%s' points to a user that doesn't exist.",
|
Log(LOG_ERR, "Access token '%s' points to a user that doesn't exist.",
|
||||||
oldAccessToken);
|
oldAccessToken);
|
||||||
Log(lc, LOG_WARNING, "This access token will be deleted.");
|
Log(LOG_WARNING, "This access token will be deleted.");
|
||||||
HttpResponseStatus(args->context, HTTP_INTERNAL_SERVER_ERROR);
|
HttpResponseStatus(args->context, HTTP_INTERNAL_SERVER_ERROR);
|
||||||
response = MatrixErrorCreate(M_UNKNOWN);
|
response = MatrixErrorCreate(M_UNKNOWN);
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,6 @@ ROUTE_IMPL(RouteRegister, args)
|
||||||
char *fullUsername;
|
char *fullUsername;
|
||||||
|
|
||||||
Db *db = args->matrixArgs->db;
|
Db *db = args->matrixArgs->db;
|
||||||
LogConfig *lc = args->matrixArgs->lc;
|
|
||||||
|
|
||||||
User *user = NULL;
|
User *user = NULL;
|
||||||
|
|
||||||
|
@ -249,7 +248,7 @@ ROUTE_IMPL(RouteRegister, args)
|
||||||
Free(loginInfo);
|
Free(loginInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
Log(lc, LOG_INFO, "Registered user '%s'", UserGetName(user));
|
Log(LOG_INFO, "Registered user '%s'", UserGetName(user));
|
||||||
|
|
||||||
UserUnlock(user);
|
UserUnlock(user);
|
||||||
finish:
|
finish:
|
||||||
|
|
|
@ -67,9 +67,10 @@ const char
|
||||||
void
|
void
|
||||||
TelodendriaMemoryHook(MemoryAction a, MemoryInfo * i, void *args)
|
TelodendriaMemoryHook(MemoryAction a, MemoryInfo * i, void *args)
|
||||||
{
|
{
|
||||||
LogConfig *lc = (LogConfig *) args;
|
|
||||||
char *action;
|
char *action;
|
||||||
|
|
||||||
|
(void) args;
|
||||||
|
|
||||||
switch (a)
|
switch (a)
|
||||||
{
|
{
|
||||||
case MEMORY_ALLOCATE:
|
case MEMORY_ALLOCATE:
|
||||||
|
@ -89,7 +90,7 @@ TelodendriaMemoryHook(MemoryAction a, MemoryInfo * i, void *args)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log(lc, a == MEMORY_BAD_POINTER ? LOG_WARNING : LOG_DEBUG,
|
Log(a == MEMORY_BAD_POINTER ? LOG_WARNING : LOG_DEBUG,
|
||||||
"%s:%d: %s %lu bytes of memory at %p.",
|
"%s:%d: %s %lu bytes of memory at %p.",
|
||||||
MemoryInfoGetFile(i), MemoryInfoGetLine(i),
|
MemoryInfoGetFile(i), MemoryInfoGetLine(i),
|
||||||
action, MemoryInfoGetSize(i),
|
action, MemoryInfoGetSize(i),
|
||||||
|
@ -171,25 +172,25 @@ TelodendriaGenerateMemReport(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TelodendriaPrintHeader(LogConfig * lc)
|
TelodendriaPrintHeader(void)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; i < TELODENDRIA_LOGO_HEIGHT; i++)
|
for (i = 0; i < TELODENDRIA_LOGO_HEIGHT; i++)
|
||||||
{
|
{
|
||||||
Log(lc, LOG_INFO, "%s", TelodendriaLogo[i]);
|
Log(LOG_INFO, "%s", TelodendriaLogo[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < TELODENDRIA_HEADER_HEIGHT; i++)
|
for (i = 0; i < TELODENDRIA_HEADER_HEIGHT; i++)
|
||||||
{
|
{
|
||||||
Log(lc, LOG_INFO, "%s", TelodendriaHeader[i]);
|
Log(LOG_INFO, "%s", TelodendriaHeader[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Log(lc, LOG_INFO, "Telodendria v" TELODENDRIA_VERSION);
|
Log(LOG_INFO, "Telodendria v" TELODENDRIA_VERSION);
|
||||||
Log(lc, LOG_INFO, "");
|
Log(LOG_INFO, "");
|
||||||
Log(lc, LOG_INFO,
|
Log(LOG_INFO,
|
||||||
"Copyright (C) 2023 Jordan Bancino <@jordan:bancino.net>");
|
"Copyright (C) 2023 Jordan Bancino <@jordan:bancino.net>");
|
||||||
Log(lc, LOG_INFO,
|
Log(LOG_INFO,
|
||||||
"Documentation/Support: https://telodendria.io");
|
"Documentation/Support: https://telodendria.io");
|
||||||
Log(lc, LOG_INFO, "");
|
Log(LOG_INFO, "");
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,17 +38,17 @@
|
||||||
value = HashMapGet(config, key); \
|
value = HashMapGet(config, key); \
|
||||||
if (!value) \
|
if (!value) \
|
||||||
{ \
|
{ \
|
||||||
Log(lc, LOG_ERR, "Missing required " key " directive."); \
|
Log(LOG_ERR, "Missing required " key " directive."); \
|
||||||
goto error; \
|
goto error; \
|
||||||
} \
|
} \
|
||||||
if (JsonValueType(value) == JSON_NULL) \
|
if (JsonValueType(value) == JSON_NULL) \
|
||||||
{ \
|
{ \
|
||||||
Log(lc, LOG_ERR, "Missing value for " key " directive."); \
|
Log(LOG_ERR, "Missing value for " key " directive."); \
|
||||||
goto error; \
|
goto error; \
|
||||||
} \
|
} \
|
||||||
if (JsonValueType(value) != type) \
|
if (JsonValueType(value) != type) \
|
||||||
{ \
|
{ \
|
||||||
Log(lc, LOG_ERR, "Expected " key " to be of type " #type); \
|
Log(LOG_ERR, "Expected " key " to be of type " #type); \
|
||||||
goto error; \
|
goto error; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,14 +61,14 @@
|
||||||
{ \
|
{ \
|
||||||
if (JsonValueType(value) != JSON_STRING) \
|
if (JsonValueType(value) != JSON_STRING) \
|
||||||
{ \
|
{ \
|
||||||
Log(lc, LOG_ERR, "Expected " key " to be of type JSON_STRING"); \
|
Log(LOG_ERR, "Expected " key " to be of type JSON_STRING"); \
|
||||||
goto error; \
|
goto error; \
|
||||||
} \
|
} \
|
||||||
into = StrDuplicate(JsonValueAsString(value)); \
|
into = StrDuplicate(JsonValueAsString(value)); \
|
||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
{ \
|
{ \
|
||||||
Log(lc, LOG_INFO, "Using default value " #default " for " key "."); \
|
Log(LOG_INFO, "Using default value " #default " for " key "."); \
|
||||||
into = default ? StrDuplicate(default) : NULL; \
|
into = default ? StrDuplicate(default) : NULL; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,14 +78,14 @@
|
||||||
{ \
|
{ \
|
||||||
if (JsonValueType(value) != JSON_INTEGER) \
|
if (JsonValueType(value) != JSON_INTEGER) \
|
||||||
{ \
|
{ \
|
||||||
Log(lc, LOG_ERR, "Expected " key " to be of type JSON_INTEGER"); \
|
Log(LOG_ERR, "Expected " key " to be of type JSON_INTEGER"); \
|
||||||
goto error; \
|
goto error; \
|
||||||
} \
|
} \
|
||||||
into = JsonValueAsInteger(value); \
|
into = JsonValueAsInteger(value); \
|
||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
{ \
|
{ \
|
||||||
Log(lc, LOG_INFO, "Using default value " #default " for " key "."); \
|
Log(LOG_INFO, "Using default value " #default " for " key "."); \
|
||||||
into = default; \
|
into = default; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ ConfigParseLog(LogConfig * lc, TelodendriaConfig * tConfig, HashMap * config)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log(lc, LOG_ERR, "Invalid value for log.output: '%s'.", str);
|
Log(LOG_ERR, "Invalid value for log.output: '%s'.", str);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,7 +156,7 @@ ConfigParseLog(LogConfig * lc, TelodendriaConfig * tConfig, HashMap * config)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log(lc, LOG_ERR, "Invalid value for log.level: '%s'.", tConfig->logLevel);
|
Log(LOG_ERR, "Invalid value for log.level: '%s'.", tConfig->logLevel);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,7 +175,7 @@ ConfigParseLog(LogConfig * lc, TelodendriaConfig * tConfig, HashMap * config)
|
||||||
{
|
{
|
||||||
if (JsonValueType(value) != JSON_BOOLEAN)
|
if (JsonValueType(value) != JSON_BOOLEAN)
|
||||||
{
|
{
|
||||||
Log(lc, LOG_ERR, "Expected type JSON_BOOLEAN for log.color.");
|
Log(LOG_ERR, "Expected type JSON_BOOLEAN for log.color.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,11 +222,11 @@ TelodendriaConfigParse(HashMap * config, LogConfig * lc)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log(lc, LOG_WARNING, "Base URL not specified. Assuming it's 'https://%s'.", tConfig->serverName);
|
Log(LOG_WARNING, "Base URL not specified. Assuming it's 'https://%s'.", tConfig->serverName);
|
||||||
tConfig->baseUrl = Malloc(strlen(tConfig->serverName) + 10);
|
tConfig->baseUrl = Malloc(strlen(tConfig->serverName) + 10);
|
||||||
if (!tConfig->baseUrl)
|
if (!tConfig->baseUrl)
|
||||||
{
|
{
|
||||||
Log(lc, LOG_ERR, "Error allocating memory for default config value 'baseUrl'.");
|
Log(LOG_ERR, "Error allocating memory for default config value 'baseUrl'.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,8 +247,8 @@ TelodendriaConfigParse(HashMap * config, LogConfig * lc)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log(lc, LOG_ERR, "Config directive 'runAs' should be a JSON object");
|
Log(LOG_ERR, "Config directive 'runAs' should be a JSON object");
|
||||||
Log(lc, LOG_ERR, "that contains a 'uid' and 'gid'.");
|
Log(LOG_ERR, "that contains a 'uid' and 'gid'.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
#if TLS_IMPL == TLS_LIBRESSL
|
#if TLS_IMPL == TLS_LIBRESSL
|
||||||
|
|
||||||
#include <Memory.h>
|
#include <Memory.h>
|
||||||
|
#include <Log.h>
|
||||||
|
|
||||||
#include <tls.h> /* LibreSSL TLS */
|
#include <tls.h> /* LibreSSL TLS */
|
||||||
|
|
||||||
typedef struct LibreSSLCookie
|
typedef struct LibreSSLCookie
|
||||||
|
@ -77,6 +79,11 @@ TlsInitClient(int fd, const char *serverName)
|
||||||
error:
|
error:
|
||||||
if (cookie->ctx)
|
if (cookie->ctx)
|
||||||
{
|
{
|
||||||
|
if (tls_error(cookie->ctx))
|
||||||
|
{
|
||||||
|
Log(LOG_ERR, "TlsInitClient(): %s", tls_error(cookie->ctx));
|
||||||
|
}
|
||||||
|
|
||||||
tls_free(cookie->ctx);
|
tls_free(cookie->ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,11 +142,20 @@ TlsInitServer(int fd, const char *crt, const char *key)
|
||||||
error:
|
error:
|
||||||
if (cookie->ctx)
|
if (cookie->ctx)
|
||||||
{
|
{
|
||||||
|
if (tls_error(cookie->ctx))
|
||||||
|
{
|
||||||
|
Log(LOG_ERR, "TlsInitServer(): %s", tls_error(cookie->ctx));
|
||||||
|
}
|
||||||
tls_free(cookie->ctx);
|
tls_free(cookie->ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cookie->cctx)
|
if (cookie->cctx)
|
||||||
{
|
{
|
||||||
|
if (tls_error(cookie->cctx))
|
||||||
|
{
|
||||||
|
Log(LOG_ERR, "TlsInitServer(): %s", tls_error(cookie->cctx));
|
||||||
|
}
|
||||||
|
|
||||||
tls_free(cookie->cctx);
|
tls_free(cookie->cctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,16 +173,28 @@ ssize_t
|
||||||
TlsRead(void *cookie, void *buf, size_t nBytes)
|
TlsRead(void *cookie, void *buf, size_t nBytes)
|
||||||
{
|
{
|
||||||
LibreSSLCookie *tls = cookie;
|
LibreSSLCookie *tls = cookie;
|
||||||
|
ssize_t ret = tls_read(tls->cctx ? tls->cctx : tls->ctx, buf, nBytes);
|
||||||
|
|
||||||
return tls_read(tls->cctx ? tls->cctx : tls->ctx, buf, nBytes);
|
if (ret == -1)
|
||||||
|
{
|
||||||
|
Log(LOG_ERR, "TlsRead(): %s", tls_error(tls->cctx ? tls->cctx : tls->ctx));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
TlsWrite(void *cookie, void *buf, size_t nBytes)
|
TlsWrite(void *cookie, void *buf, size_t nBytes)
|
||||||
{
|
{
|
||||||
LibreSSLCookie *tls = cookie;
|
LibreSSLCookie *tls = cookie;
|
||||||
|
ssize_t ret = tls_write(tls->cctx ? tls->cctx : tls->ctx, buf, nBytes);
|
||||||
|
|
||||||
return tls_write(tls->cctx ? tls->cctx : tls->ctx, buf, nBytes);
|
if (ret == -1)
|
||||||
|
{
|
||||||
|
Log(LOG_ERR, "TlsWrite(): %s", tls_error(tls->cctx ? tls->cctx : tls->ctx));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
@ -491,7 +491,7 @@ UiaCleanup(MatrixHttpHandlerArgs * args)
|
||||||
Array *sessions = DbList(args->db, 1, "user_interactive");
|
Array *sessions = DbList(args->db, 1, "user_interactive");
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
Log(args->lc, LOG_DEBUG, "User Interactive Auth sessions: %lu",
|
Log(LOG_DEBUG, "User Interactive Auth sessions: %lu",
|
||||||
ArraySize(sessions));
|
ArraySize(sessions));
|
||||||
for (i = 0; i < ArraySize(sessions); i++)
|
for (i = 0; i < ArraySize(sessions); i++)
|
||||||
{
|
{
|
||||||
|
@ -502,7 +502,7 @@ UiaCleanup(MatrixHttpHandlerArgs * args)
|
||||||
|
|
||||||
if (!ref)
|
if (!ref)
|
||||||
{
|
{
|
||||||
Log(args->lc, LOG_ERR, "Unable to lock uia %s for inspection.",
|
Log(LOG_ERR, "Unable to lock uia %s for inspection.",
|
||||||
session);
|
session);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -515,7 +515,7 @@ UiaCleanup(MatrixHttpHandlerArgs * args)
|
||||||
{
|
{
|
||||||
DbUnlock(args->db, ref);
|
DbUnlock(args->db, ref);
|
||||||
DbDelete(args->db, 2, "user_interactive", session);
|
DbDelete(args->db, 2, "user_interactive", session);
|
||||||
Log(args->lc, LOG_DEBUG, "Deleted session %s", session);
|
Log(LOG_DEBUG, "Deleted session %s", session);
|
||||||
}
|
}
|
||||||
|
|
||||||
DbUnlock(args->db, ref);
|
DbUnlock(args->db, ref);
|
||||||
|
|
|
@ -39,6 +39,9 @@ typedef struct LogConfig LogConfig;
|
||||||
extern LogConfig *
|
extern LogConfig *
|
||||||
LogConfigCreate(void);
|
LogConfigCreate(void);
|
||||||
|
|
||||||
|
extern LogConfig *
|
||||||
|
LogConfigGlobal(void);
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
LogConfigFree(LogConfig *);
|
LogConfigFree(LogConfig *);
|
||||||
|
|
||||||
|
@ -67,6 +70,12 @@ extern void
|
||||||
LogConfigTimeStampFormatSet(LogConfig *, char *);
|
LogConfigTimeStampFormatSet(LogConfig *, char *);
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
Log(LogConfig *, int, const char *,...);
|
Logv(LogConfig *, int, const char *, va_list);
|
||||||
|
|
||||||
|
extern void
|
||||||
|
LogTo(LogConfig *, int, const char *,...);
|
||||||
|
|
||||||
|
extern void
|
||||||
|
Log(int, const char *, ...);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -69,7 +69,6 @@ typedef enum MatrixError
|
||||||
|
|
||||||
typedef struct MatrixHttpHandlerArgs
|
typedef struct MatrixHttpHandlerArgs
|
||||||
{
|
{
|
||||||
LogConfig *lc;
|
|
||||||
TelodendriaConfig *config;
|
TelodendriaConfig *config;
|
||||||
Db *db;
|
Db *db;
|
||||||
} MatrixHttpHandlerArgs;
|
} MatrixHttpHandlerArgs;
|
||||||
|
|
|
@ -46,6 +46,6 @@ extern void
|
||||||
TelodendriaGenerateMemReport(void);
|
TelodendriaGenerateMemReport(void);
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
TelodendriaPrintHeader(LogConfig *);
|
TelodendriaPrintHeader(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue