diff --git a/src/Telodendria.c b/src/Telodendria.c index 506a6c2..dc2307c 100644 --- a/src/Telodendria.c +++ b/src/Telodendria.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -105,6 +106,17 @@ main(int argc, char **argv) TelodendriaPrintHeader(lc); +#ifdef __OpenBSD__ + Log(lc, LOG_DEBUG, "Attempting pledge() and unveil()..."); + + if (pledge("stdio rpath wpath cpath inet dns getpw id unveil", NULL) != 0) + { + Log(lc, LOG_ERROR, "Pledge failed: %s", strerror(errno)); + exit = EXIT_FAILURE; + goto finish; + } +#endif + while ((opt = getopt(argc, argv, "c:Vh")) != -1) { switch (opt) @@ -147,6 +159,14 @@ main(int argc, char **argv) } else { +#ifdef __OpenBSD__ + if (unveil(configArg, "r") != 0) + { + Log(lc, LOG_ERROR, "Unable to unveil() configuration file '%s' for reading.", configArg); + exit = EXIT_FAILURE; + goto finish; + } +#endif configFile = fopen(configArg, "r"); if (!configFile) { @@ -181,6 +201,42 @@ main(int argc, char **argv) ConfigFree(config); +#ifdef __OpenBSD__ + if (unveil(tConfig->chroot, "rwc") != 0) + { + Log(lc, LOG_ERROR, "Unveil of data directory failed: %s", strerror(errno)); + exit = EXIT_FAILURE; + goto finish; + } + + unveil(NULL, NULL); /* Done with unveil(), so disable it */ +#endif + + LogConfigTimeStampFormatSet(lc, tConfig->logTimestamp); + + /* Color is enabled by default in the logger. */ + if (!(tConfig->flags & TELODENDRIA_LOG_COLOR)) + { + LogConfigFlagClear(lc, LOG_FLAG_COLOR); + } + + LogConfigLevelSet(lc, tConfig->logLevel); + + if (tConfig->logOut) + { + FILE *logFile = fopen(tConfig->logOut, "w"); + + if (!logFile) + { + Log(lc, LOG_ERROR, "Unable to open log file '%s' for writing.", tConfig->logOut); + exit = EXIT_FAILURE; + goto finish; + } + + Log(lc, LOG_DEBUG, "Redirecting future output to '%s'.", tConfig->logOut); + LogConfigOutputSet(lc, logFile); + } + Log(lc, LOG_DEBUG, "Configuration:"); LogConfigIndent(lc); Log(lc, LOG_DEBUG, "Listen On: %s:%s", tConfig->listenHost, tConfig->listenPort); @@ -192,16 +248,20 @@ main(int argc, char **argv) Log(lc, LOG_DEBUG, "Flags: %x", tConfig->flags); LogConfigUnindent(lc); - Log(lc, LOG_TASK, "Evaluating permissions..."); + Log(lc, LOG_TASK, "Setting permissions..."); if (chdir(tConfig->chroot) != 0) { - Log(lc, LOG_ERROR, "Unable to change into directory: %s.", tConfig->chroot); + Log(lc, LOG_ERROR, "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->chroot); + } - Log(lc, LOG_DEBUG, "Running as uid/gid: %d/%d.", getuid(), getgid()); + Log(lc, LOG_DEBUG, "Running as uid:gid: %d:%d.", getuid(), getgid()); userInfo = getpwnam(tConfig->uid); groupInfo = getgrnam(tConfig->gid); @@ -212,17 +272,25 @@ main(int argc, char **argv) exit = EXIT_FAILURE; goto finish; } + else + { + Log(lc, LOG_DEBUG, "Found user/group information using getpwnam() and getgrnam()."); + } if (getuid() == 0) { +#ifndef __OpenBSD__ if (chroot(tConfig->chroot) == 0) { - Log(lc, LOG_MESSAGE, "Changed the root directory to: %s.", tConfig->chroot); + Log(lc, LOG_DEBUG, "Changed the root directory to: %s.", tConfig->chroot); } else { Log(lc, LOG_WARNING, "Unable to chroot into directory: %s.", tConfig->chroot); } +#else + Log(lc, LOG_DEBUG, "Not attempting chroot() after pledge() and unveil()."); +#endif if (setgid(groupInfo->gr_gid) != 0 || setuid(userInfo->pw_uid) != 0) { @@ -230,12 +298,12 @@ main(int argc, char **argv) } else { - Log(lc, LOG_MESSAGE, "Set uid/gid to %s:%s.", tConfig->uid, tConfig->gid); + Log(lc, LOG_DEBUG, "Set uid/gid to %s:%s.", tConfig->uid, tConfig->gid); } } else { - Log(lc, LOG_MESSAGE, "Not changing root directory, because we are not root."); + Log(lc, LOG_DEBUG, "Not changing root directory, because we are not root."); if (getuid() != userInfo->pw_uid || getgid() != groupInfo->gr_gid) { @@ -260,5 +328,6 @@ main(int argc, char **argv) finish: Log(lc, LOG_DEBUG, "Exiting with code '%d'.", exit); TelodendriaConfigFree(tConfig); + LogConfigFree(lc); return exit; } diff --git a/src/TelodendriaConfig.c b/src/TelodendriaConfig.c index afc0f10..0114b77 100644 --- a/src/TelodendriaConfig.c +++ b/src/TelodendriaConfig.c @@ -211,23 +211,23 @@ TelodendriaConfigParse(HashMap * config, LogConfig * lc) cVal = ArrayGet(ConfigValuesGet(cDirective), 0); if (strcmp(cVal, "message") == 0) { - LogConfigLevelSet(lc, LOG_MESSAGE); + tConfig->logLevel = LOG_MESSAGE; } else if (strcmp(cVal, "debug") == 0) { - LogConfigLevelSet(lc, LOG_DEBUG); + tConfig->logLevel = LOG_DEBUG; } else if (strcmp(cVal, "task") == 0) { - LogConfigLevelSet(lc, LOG_TASK); + tConfig->logLevel = LOG_TASK; } else if (strcmp(cVal, "warning") == 0) { - LogConfigLevelSet(lc, LOG_WARNING); + tConfig->logLevel = LOG_WARNING; } else if (strcmp(cVal, "error") == 0) { - LogConfigLevelSet(lc, LOG_ERROR); + tConfig->logLevel = LOG_ERROR; } else { @@ -250,11 +250,11 @@ TelodendriaConfigParse(HashMap * config, LogConfig * lc) if (strcmp(cVal, "none") == 0) { - LogConfigTimeStampFormatSet(lc, NULL); + tConfig->logTimestamp = NULL; } else if (strcmp(cVal, "default") != 0) { - LogConfigTimeStampFormatSet(lc, UtilStringDuplicate(cVal)); + tConfig->logTimestamp = UtilStringDuplicate(cVal); } } @@ -270,11 +270,11 @@ TelodendriaConfigParse(HashMap * config, LogConfig * lc) cVal = ArrayGet(ConfigValuesGet(cDirective), 0); - if (strcmp(cVal, "false") == 0) + if (strcmp(cVal, "true") == 0) { - LogConfigFlagClear(lc, LOG_FLAG_COLOR); + tConfig->flags |= TELODENDRIA_LOG_COLOR; } - else if (strcmp(cVal, "true") != 0) + else if (strcmp(cVal, "false") != 0) { Log(lc, LOG_ERROR, "Expected boolean value for log.color, got '%s'.", cVal); goto error; @@ -285,20 +285,13 @@ TelodendriaConfigParse(HashMap * config, LogConfig * lc) /* Set the actual log output file last */ if (strcmp(ArrayGet(value, 0), "stdout") != 0) { - FILE *out = fopen(ArrayGet(value, 0), "w"); - - if (!out) - { - Log(lc, LOG_ERROR, "Unable to open log file '%s' for writing.", - ArrayGet(value, 0)); - goto error; - } - - Log(lc, LOG_DEBUG, "Redirecting output to '%s'.", ArrayGet(value, 0)); - LogConfigOutputSet(lc, out); + tConfig->logOut = UtilStringDuplicate(ArrayGet(value, 0)); + } + else + { + tConfig->logOut = NULL; } - tConfig->logConfig = lc; return tConfig; error: TelodendriaConfigFree(tConfig); @@ -325,7 +318,5 @@ TelodendriaConfigFree(TelodendriaConfig * tConfig) free(tConfig->gid); free(tConfig->dataDir); - LogConfigFree(tConfig->logConfig); - free(tConfig); } diff --git a/src/include/TelodendriaConfig.h b/src/include/TelodendriaConfig.h index 398c525..a622ff1 100644 --- a/src/include/TelodendriaConfig.h +++ b/src/include/TelodendriaConfig.h @@ -37,7 +37,8 @@ typedef enum TelodendriaConfigFlag { TELODENDRIA_FEDERATION = (1 << 0), - TELODENDRIA_REGISTRATION = (1 << 1) + TELODENDRIA_REGISTRATION = (1 << 1), + TELODENDRIA_LOG_COLOR = (1 << 2) } TelodendriaConfigFlag; /* @@ -62,7 +63,9 @@ typedef struct TelodendriaConfig unsigned int flags; unsigned int threads; - LogConfig *logConfig; + char *logOut; + char *logTimestamp; + LogLevel logLevel; } TelodendriaConfig; /*