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:
Jordan Bancino 2023-03-22 14:52:04 +00:00
parent 8782aa046d
commit f3c4c0ac65
13 changed files with 207 additions and 142 deletions

View file

@ -6,52 +6,63 @@ Key:
[ ] Not Started
[x] Done
[~] In Progress
[!] Won't Fix
[!] Won't Do
Milestone: v0.3.0
-----------------
[~] Stream API
[x] Stream API
[x] Implementation
[x] Convert all code that deals with I/O
[!] Multi-output (proof of concept)
[!] Memory streams (proof of concept)
[~] TLS
[ ] SOCKS
[x] TLS
[!] SOCKS
[x] Move/convert UtilStreamCopy()
[ ] Io man page
[ ] Stream man page
[ ] Tls man page
[~] HTTP Client API
[x] HTTP Client API
[x] Document HttpParseHeaders()
[ ] HttpClient man page
[ ] Uri man page
[x] Test on other platforms
[x] Option to pretty-print Json
[x] Document JsonEncode() and JsonEncodeValue()
[ ] Update man page for td
[x] Document Telodendria and Main
[ ] Document tt and http-debug-server
[x] Simple command line tool to make matrix requests
[x] Built on HTTP client API
[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] Query fields for use in shell scripts.
[x] Encode user-provided JSON strings
[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
- Support regex matching
[ ] Move configuration to database
[ ] Initial configuration
[ ] If no config, create one-time use registration token that
grants user admin privileges.
[ ] /_telodendria/admin/config endpoint
[ ] 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
[x] 4: Token-based user registration

View file

@ -45,6 +45,8 @@ struct LogConfig
pthread_mutex_t lock;
};
LogConfig *globalConfig = NULL;
LogConfig *
LogConfigCreate(void)
{
@ -68,6 +70,17 @@ LogConfigCreate(void)
return config;
}
LogConfig *
LogConfigGlobal(void)
{
if (!globalConfig)
{
globalConfig = LogConfigCreate();
}
return globalConfig;
}
void
LogConfigFlagClear(LogConfig * config, int flags)
{
@ -111,6 +124,11 @@ LogConfigFree(LogConfig * config)
StreamClose(config->out);
Free(config);
if (config == globalConfig)
{
globalConfig = NULL;
}
}
void
@ -202,12 +220,11 @@ LogConfigUnindent(LogConfig * config)
}
void
Log(LogConfig * config, int level, const char *msg,...)
Logv(LogConfig * config, int level, const char *msg, va_list argp)
{
size_t i;
int doColor;
char indicator;
va_list argp;
/*
* 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
* for us. */
va_start(argp, msg);
vsyslog(level, msg, argp);
va_end(argp);
pthread_mutex_unlock(&config->lock);
return;
}
@ -345,12 +360,30 @@ Log(LogConfig * config, int level, const char *msg,...)
StreamPutc(config->out, ' ');
}
va_start(argp, msg);
StreamVprintf(config->out, msg, argp);
StreamPutc(config->out, '\n');
va_end(argp);
StreamFlush(config->out);
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);
}

View file

@ -63,7 +63,6 @@ typedef enum ArgFlag
int
main(int argc, char **argv)
{
LogConfig *lc;
int exit = EXIT_SUCCESS;
/* Arg parsing */
@ -90,17 +89,15 @@ main(int argc, char **argv)
memset(&matrixArgs, 0, sizeof(matrixArgs));
lc = LogConfigCreate();
if (!lc)
if (!LogConfigGlobal())
{
printf("Fatal error: unable to allocate memory for logger.\n");
return EXIT_FAILURE;
}
MemoryHook(TelodendriaMemoryHook, lc);
MemoryHook(TelodendriaMemoryHook, NULL);
TelodendriaPrintHeader(lc);
TelodendriaPrintHeader();
while ((opt = getopt(argc, argv, "f:Vvn")) != -1)
{
@ -128,7 +125,7 @@ main(int argc, char **argv)
if (flags & ARG_VERBOSE)
{
LogConfigLevelSet(lc, LOG_DEBUG);
LogConfigLevelSet(LogConfigGlobal(), LOG_DEBUG);
}
if (flags & ARG_VERSION)
@ -138,7 +135,7 @@ main(int argc, char **argv)
if (!configArg)
{
Log(lc, LOG_ERR, "No configuration file specified.");
Log(LOG_ERR, "No configuration file specified.");
exit = EXIT_FAILURE;
goto finish;
}
@ -153,25 +150,25 @@ main(int argc, char **argv)
configFile = StreamOpen(configArg, "r");
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;
goto finish;
}
}
Log(lc, LOG_NOTICE, "Processing configuration file '%s'.", configArg);
Log(LOG_NOTICE, "Processing configuration file '%s'.", configArg);
config = JsonDecode(configFile);
StreamClose(configFile);
if (!config)
{
Log(lc, LOG_ERR, "Syntax error in configuration file.");
Log(LOG_ERR, "Syntax error in configuration file.");
exit = EXIT_FAILURE;
goto finish;
}
tConfig = TelodendriaConfigParse(config, lc);
tConfig = TelodendriaConfigParse(config, LogConfigGlobal());
JsonFree(config);
if (!tConfig)
@ -182,13 +179,13 @@ main(int argc, char **argv)
if (flags & ARG_CONFIGTEST)
{
Log(lc, LOG_INFO, "Configuration is OK.");
Log(LOG_INFO, "Configuration is OK.");
goto finish;
}
if (!tConfig->logTimestamp || strcmp(tConfig->logTimestamp, "default") != 0)
{
LogConfigTimeStampFormatSet(lc, tConfig->logTimestamp);
LogConfigTimeStampFormatSet(LogConfigGlobal(), tConfig->logTimestamp);
}
else
{
@ -198,24 +195,24 @@ main(int argc, char **argv)
if (tConfig->flags & TELODENDRIA_LOG_COLOR)
{
LogConfigFlagSet(lc, LOG_FLAG_COLOR);
LogConfigFlagSet(LogConfigGlobal(), LOG_FLAG_COLOR);
}
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)
{
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;
goto finish;
}
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)
{
Log(lc, LOG_ERR, "Unable to open log file for appending.");
Log(LOG_ERR, "Unable to open log file for appending.");
exit = EXIT_FAILURE;
goto finish;
}
Log(lc, LOG_INFO, "Logging to the log file. Check there for all future messages.");
LogConfigOutputSet(lc, logFile);
Log(LOG_INFO, "Logging to the log file. Check there for all future messages.");
LogConfigOutputSet(LogConfigGlobal(), logFile);
}
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)
{
Log(lc, LOG_INFO, "Logging to the syslog. Check there for all future messages.");
LogConfigFlagSet(lc, LOG_FLAG_SYSLOG);
Log(LOG_INFO, "Logging to the syslog. Check there for all future messages.");
LogConfigFlagSet(LogConfigGlobal(), LOG_FLAG_SYSLOG);
openlog("telodendria", LOG_PID | LOG_NDELAY, LOG_DAEMON);
/* Always log everything, because the Log API will control what
@ -249,28 +246,27 @@ main(int argc, char **argv)
}
else
{
Log(lc, 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, "Unknown logging method in flags: '%d'", tConfig->flags);
Log(LOG_ERR, "This is a programmer error; please report it.");
exit = EXIT_FAILURE;
goto finish;
}
Log(lc, LOG_DEBUG, "Configuration:");
LogConfigIndent(lc);
Log(lc, LOG_DEBUG, "Listen On: %d", tConfig->listenPort);
Log(lc, LOG_DEBUG, "Server Name: %s", tConfig->serverName);
Log(lc, LOG_DEBUG, "Base URL: %s", tConfig->baseUrl);
Log(lc, LOG_DEBUG, "Identity Server: %s", tConfig->identityServer);
Log(lc, LOG_DEBUG, "Run As: %s:%s", tConfig->uid, tConfig->gid);
Log(lc, LOG_DEBUG, "Data Directory: %s", tConfig->dataDir);
Log(lc, LOG_DEBUG, "Threads: %d", tConfig->threads);
Log(lc, LOG_DEBUG, "Max Connections: %d", tConfig->maxConnections);
Log(lc, LOG_DEBUG, "Max Cache: %ld", tConfig->maxCache);
Log(lc, LOG_DEBUG, "Flags: %x", tConfig->flags);
LogConfigUnindent(lc);
Log(LOG_DEBUG, "Configuration:");
LogConfigIndent(LogConfigGlobal());
Log(LOG_DEBUG, "Listen On: %d", tConfig->listenPort);
Log(LOG_DEBUG, "Server Name: %s", tConfig->serverName);
Log(LOG_DEBUG, "Base URL: %s", tConfig->baseUrl);
Log(LOG_DEBUG, "Identity Server: %s", tConfig->identityServer);
Log(LOG_DEBUG, "Run As: %s:%s", tConfig->uid, tConfig->gid);
Log(LOG_DEBUG, "Data Directory: %s", tConfig->dataDir);
Log(LOG_DEBUG, "Threads: %d", tConfig->threads);
Log(LOG_DEBUG, "Max Connections: %d", tConfig->maxConnections);
Log(LOG_DEBUG, "Max Cache: %ld", tConfig->maxCache);
Log(LOG_DEBUG, "Flags: %x", tConfig->flags);
LogConfigUnindent(LogConfigGlobal());
/* Arguments to pass into the HTTP handler */
matrixArgs.lc = lc;
matrixArgs.config = tConfig;
/* Bind the socket before possibly dropping permissions */
@ -278,13 +274,13 @@ main(int argc, char **argv)
tConfig->maxConnections, MatrixHttpHandler, &matrixArgs);
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));
exit = EXIT_FAILURE;
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)
{
@ -293,18 +289,18 @@ main(int argc, char **argv)
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;
goto finish;
}
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
{
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)
@ -313,35 +309,35 @@ main(int argc, char **argv)
{
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;
goto finish;
}
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
{
Log(lc, 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(lc, LOG_WARNING, "This is probably a security issue.");
Log(LOG_WARNING, "We are running as root, and we are not dropping to another user");
Log(LOG_WARNING, "because none was specified in the configuration file.");
Log(LOG_WARNING, "This is probably a security issue.");
}
}
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 (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
{
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)
{
Log(lc, LOG_WARNING, "Database caching is disabled.");
Log(lc, LOG_WARNING,
"If this is not what you intended, check the config file");
Log(lc, LOG_WARNING,
"and ensure that maxCache is a valid number of bytes.");
Log(LOG_WARNING, "Database caching is disabled.");
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.");
}
matrixArgs.db = DbOpen(".", tConfig->maxCache);
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;
goto finish;
}
@ -378,28 +372,28 @@ main(int argc, char **argv)
cron = CronCreate(60 * 1000); /* 1-minute tick */
if (!cron)
{
Log(lc, LOG_ERR, "Unable to set up job scheduler.");
Log(LOG_ERR, "Unable to set up job scheduler.");
exit = EXIT_FAILURE;
goto finish;
}
Log(lc, LOG_DEBUG, "Registering jobs...");
Log(LOG_DEBUG, "Registering jobs...");
CronEvery(cron, 30 * 60 * 1000, (JobFunc *) UiaCleanup, &matrixArgs);
Log(lc, LOG_NOTICE, "Starting job scheduler...");
Log(LOG_NOTICE, "Starting job scheduler...");
CronStart(cron);
Log(lc, LOG_NOTICE, "Starting server...");
Log(LOG_NOTICE, "Starting server...");
if (!HttpServerStart(httpServer))
{
Log(lc, LOG_ERR, "Unable to start HTTP server.");
Log(LOG_ERR, "Unable to start HTTP server.");
exit = EXIT_FAILURE;
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;
sigfillset(&sigAction.sa_mask);
@ -407,7 +401,7 @@ main(int argc, char **argv)
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;
goto finish;
}
@ -417,18 +411,18 @@ main(int argc, char **argv)
HttpServerJoin(httpServer);
finish:
Log(lc, LOG_NOTICE, "Shutting down...");
Log(LOG_NOTICE, "Shutting down...");
if (httpServer)
{
HttpServerFree(httpServer);
Log(lc, LOG_DEBUG, "Freed HTTP Server.");
Log(LOG_DEBUG, "Freed HTTP Server.");
}
if (cron)
{
CronStop(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);
LogConfigTimeStampFormatSet(lc, NULL);
TelodendriaConfigFree(tConfig);
Log(lc, LOG_DEBUG, "Exiting with code '%d'.", exit);
Log(LOG_DEBUG, "Exiting with code '%d'.", exit);
/*
* Uninstall the memory hook because it uses the Log
@ -455,7 +447,7 @@ finish:
*/
MemoryHook(NULL, NULL);
LogConfigFree(lc);
LogConfigFree(LogConfigGlobal());
/* Standard error should never have been opened, but just in case
* it was, this doesn't hurt anything. */

View file

@ -38,7 +38,6 @@ void
MatrixHttpHandler(HttpServerContext * context, void *argp)
{
MatrixHttpHandlerArgs *args = (MatrixHttpHandlerArgs *) argp;
LogConfig *lc = args->lc;
Stream *stream;
HashMap *response = NULL;
@ -52,12 +51,10 @@ MatrixHttpHandler(HttpServerContext * context, void *argp)
requestPath = HttpRequestPath(context);
Log(lc, LOG_INFO, "%s %s",
Log(LOG_INFO, "%s %s",
HttpRequestMethodToString(HttpRequestMethodGet(context)),
requestPath);
LogConfigIndent(lc);
HttpResponseStatus(context, HTTP_OK);
HttpResponseHeader(context, "Server", "Telodendria/" TELODENDRIA_VERSION);
@ -78,7 +75,7 @@ MatrixHttpHandler(HttpServerContext * context, void *argp)
HttpResponseStatus(context, HTTP_NO_CONTENT);
HttpSendHeaders(context);
goto finish;
return;
}
pathParts = MATRIX_PATH_CREATE();
@ -146,9 +143,6 @@ MatrixHttpHandler(HttpServerContext * context, void *argp)
}
MATRIX_PATH_FREE(pathParts);
finish:
LogConfigUnindent(lc);
}
HashMap *

View file

@ -45,7 +45,6 @@ ROUTE_IMPL(RouteRefresh, args)
char *deviceId;
Db *db = args->matrixArgs->db;
LogConfig *lc = args->matrixArgs->lc;
User *user = NULL;
DbRef *rtRef = NULL;
@ -96,9 +95,9 @@ ROUTE_IMPL(RouteRefresh, args)
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);
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);
response = MatrixErrorCreate(M_UNKNOWN);
@ -114,9 +113,9 @@ ROUTE_IMPL(RouteRefresh, args)
user = UserLock(db, JsonValueAsString(HashMapGet(DbJson(oAtRef), "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);
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);
response = MatrixErrorCreate(M_UNKNOWN);

View file

@ -66,7 +66,6 @@ ROUTE_IMPL(RouteRegister, args)
char *fullUsername;
Db *db = args->matrixArgs->db;
LogConfig *lc = args->matrixArgs->lc;
User *user = NULL;
@ -249,7 +248,7 @@ ROUTE_IMPL(RouteRegister, args)
Free(loginInfo);
}
Log(lc, LOG_INFO, "Registered user '%s'", UserGetName(user));
Log(LOG_INFO, "Registered user '%s'", UserGetName(user));
UserUnlock(user);
finish:

View file

@ -67,9 +67,10 @@ const char
void
TelodendriaMemoryHook(MemoryAction a, MemoryInfo * i, void *args)
{
LogConfig *lc = (LogConfig *) args;
char *action;
(void) args;
switch (a)
{
case MEMORY_ALLOCATE:
@ -89,7 +90,7 @@ TelodendriaMemoryHook(MemoryAction a, MemoryInfo * i, void *args)
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.",
MemoryInfoGetFile(i), MemoryInfoGetLine(i),
action, MemoryInfoGetSize(i),
@ -171,25 +172,25 @@ TelodendriaGenerateMemReport(void)
}
void
TelodendriaPrintHeader(LogConfig * lc)
TelodendriaPrintHeader(void)
{
size_t 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++)
{
Log(lc, LOG_INFO, "%s", TelodendriaHeader[i]);
Log(LOG_INFO, "%s", TelodendriaHeader[i]);
}
Log(lc, LOG_INFO, "Telodendria v" TELODENDRIA_VERSION);
Log(lc, LOG_INFO, "");
Log(lc, LOG_INFO,
Log(LOG_INFO, "Telodendria v" TELODENDRIA_VERSION);
Log(LOG_INFO, "");
Log(LOG_INFO,
"Copyright (C) 2023 Jordan Bancino <@jordan:bancino.net>");
Log(lc, LOG_INFO,
Log(LOG_INFO,
"Documentation/Support: https://telodendria.io");
Log(lc, LOG_INFO, "");
Log(LOG_INFO, "");
}

View file

@ -38,17 +38,17 @@
value = HashMapGet(config, key); \
if (!value) \
{ \
Log(lc, LOG_ERR, "Missing required " key " directive."); \
Log(LOG_ERR, "Missing required " key " directive."); \
goto error; \
} \
if (JsonValueType(value) == JSON_NULL) \
{ \
Log(lc, LOG_ERR, "Missing value for " key " directive."); \
Log(LOG_ERR, "Missing value for " key " directive."); \
goto error; \
} \
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; \
}
@ -61,14 +61,14 @@
{ \
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; \
} \
into = StrDuplicate(JsonValueAsString(value)); \
} \
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; \
}
@ -78,14 +78,14 @@
{ \
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; \
} \
into = JsonValueAsInteger(value); \
} \
else \
{ \
Log(lc, LOG_INFO, "Using default value " #default " for " key "."); \
Log(LOG_INFO, "Using default value " #default " for " key "."); \
into = default; \
}
@ -128,7 +128,7 @@ ConfigParseLog(LogConfig * lc, TelodendriaConfig * tConfig, HashMap * config)
}
else
{
Log(lc, LOG_ERR, "Invalid value for log.output: '%s'.", str);
Log(LOG_ERR, "Invalid value for log.output: '%s'.", str);
goto error;
}
@ -156,7 +156,7 @@ ConfigParseLog(LogConfig * lc, TelodendriaConfig * tConfig, HashMap * config)
}
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;
}
@ -175,7 +175,7 @@ ConfigParseLog(LogConfig * lc, TelodendriaConfig * tConfig, HashMap * config)
{
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;
}
@ -222,11 +222,11 @@ TelodendriaConfigParse(HashMap * config, LogConfig * lc)
}
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);
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;
}
@ -247,8 +247,8 @@ TelodendriaConfigParse(HashMap * config, LogConfig * lc)
}
else
{
Log(lc, LOG_ERR, "Config directive 'runAs' should be a JSON object");
Log(lc, LOG_ERR, "that contains a 'uid' and 'gid'.");
Log(LOG_ERR, "Config directive 'runAs' should be a JSON object");
Log(LOG_ERR, "that contains a 'uid' and 'gid'.");
goto error;
}
}

View file

@ -26,6 +26,8 @@
#if TLS_IMPL == TLS_LIBRESSL
#include <Memory.h>
#include <Log.h>
#include <tls.h> /* LibreSSL TLS */
typedef struct LibreSSLCookie
@ -77,6 +79,11 @@ TlsInitClient(int fd, const char *serverName)
error:
if (cookie->ctx)
{
if (tls_error(cookie->ctx))
{
Log(LOG_ERR, "TlsInitClient(): %s", tls_error(cookie->ctx));
}
tls_free(cookie->ctx);
}
@ -135,11 +142,20 @@ TlsInitServer(int fd, const char *crt, const char *key)
error:
if (cookie->ctx)
{
if (tls_error(cookie->ctx))
{
Log(LOG_ERR, "TlsInitServer(): %s", tls_error(cookie->ctx));
}
tls_free(cookie->ctx);
}
if (cookie->cctx)
{
if (tls_error(cookie->cctx))
{
Log(LOG_ERR, "TlsInitServer(): %s", tls_error(cookie->cctx));
}
tls_free(cookie->cctx);
}
@ -157,16 +173,28 @@ ssize_t
TlsRead(void *cookie, void *buf, size_t nBytes)
{
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
TlsWrite(void *cookie, void *buf, size_t nBytes)
{
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

View file

@ -491,7 +491,7 @@ UiaCleanup(MatrixHttpHandlerArgs * args)
Array *sessions = DbList(args->db, 1, "user_interactive");
size_t i;
Log(args->lc, LOG_DEBUG, "User Interactive Auth sessions: %lu",
Log(LOG_DEBUG, "User Interactive Auth sessions: %lu",
ArraySize(sessions));
for (i = 0; i < ArraySize(sessions); i++)
{
@ -502,7 +502,7 @@ UiaCleanup(MatrixHttpHandlerArgs * args)
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);
continue;
}
@ -515,7 +515,7 @@ UiaCleanup(MatrixHttpHandlerArgs * args)
{
DbUnlock(args->db, ref);
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);

View file

@ -39,6 +39,9 @@ typedef struct LogConfig LogConfig;
extern LogConfig *
LogConfigCreate(void);
extern LogConfig *
LogConfigGlobal(void);
extern void
LogConfigFree(LogConfig *);
@ -67,6 +70,12 @@ extern void
LogConfigTimeStampFormatSet(LogConfig *, char *);
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

View file

@ -69,7 +69,6 @@ typedef enum MatrixError
typedef struct MatrixHttpHandlerArgs
{
LogConfig *lc;
TelodendriaConfig *config;
Db *db;
} MatrixHttpHandlerArgs;

View file

@ -46,6 +46,6 @@ extern void
TelodendriaGenerateMemReport(void);
extern void
TelodendriaPrintHeader(LogConfig *);
TelodendriaPrintHeader(void);
#endif