diff --git a/TODO.txt b/TODO.txt index acaefa7..238afd0 100644 --- a/TODO.txt +++ b/TODO.txt @@ -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 diff --git a/src/Log.c b/src/Log.c index f1188c1..cb0618a 100644 --- a/src/Log.c +++ b/src/Log.c @@ -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); +} diff --git a/src/Main.c b/src/Main.c index d4d303c..b6379df 100644 --- a/src/Main.c +++ b/src/Main.c @@ -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. */ diff --git a/src/Matrix.c b/src/Matrix.c index 2d6cd2b..9b6f0a2 100644 --- a/src/Matrix.c +++ b/src/Matrix.c @@ -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 * diff --git a/src/Routes/RouteRefresh.c b/src/Routes/RouteRefresh.c index 3bf960a..10ef1ba 100644 --- a/src/Routes/RouteRefresh.c +++ b/src/Routes/RouteRefresh.c @@ -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); diff --git a/src/Routes/RouteRegister.c b/src/Routes/RouteRegister.c index 6e55869..035e730 100644 --- a/src/Routes/RouteRegister.c +++ b/src/Routes/RouteRegister.c @@ -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: diff --git a/src/Telodendria.c b/src/Telodendria.c index 8a6f868..14f50ae 100644 --- a/src/Telodendria.c +++ b/src/Telodendria.c @@ -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, ""); } diff --git a/src/TelodendriaConfig.c b/src/TelodendriaConfig.c index 4eba79d..67996c7 100644 --- a/src/TelodendriaConfig.c +++ b/src/TelodendriaConfig.c @@ -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; } } diff --git a/src/Tls/TlsLibreSSL.c b/src/Tls/TlsLibreSSL.c index f91b60c..e06f949 100644 --- a/src/Tls/TlsLibreSSL.c +++ b/src/Tls/TlsLibreSSL.c @@ -26,6 +26,8 @@ #if TLS_IMPL == TLS_LIBRESSL #include +#include + #include /* 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 diff --git a/src/Uia.c b/src/Uia.c index e0e460a..8f0b748 100644 --- a/src/Uia.c +++ b/src/Uia.c @@ -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); diff --git a/src/include/Log.h b/src/include/Log.h index 932e894..f1a39b9 100644 --- a/src/include/Log.h +++ b/src/include/Log.h @@ -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 diff --git a/src/include/Matrix.h b/src/include/Matrix.h index 98d0f4a..a07f559 100644 --- a/src/include/Matrix.h +++ b/src/include/Matrix.h @@ -69,7 +69,6 @@ typedef enum MatrixError typedef struct MatrixHttpHandlerArgs { - LogConfig *lc; TelodendriaConfig *config; Db *db; } MatrixHttpHandlerArgs; diff --git a/src/include/Telodendria.h b/src/include/Telodendria.h index dde0a39..50f452d 100644 --- a/src/include/Telodendria.h +++ b/src/include/Telodendria.h @@ -46,6 +46,6 @@ extern void TelodendriaGenerateMemReport(void); extern void - TelodendriaPrintHeader(LogConfig *); + TelodendriaPrintHeader(void); #endif