TelodendriaConfigParse() doesn't modify the LogConfig.

Also pledge() and unveil() as soon as possible, to avoid the log file
breaking out.
This commit is contained in:
Jordan Bancino 2022-08-10 21:13:05 -04:00
parent 9ae05e84f2
commit 4304a28302
3 changed files with 95 additions and 32 deletions

View file

@ -25,6 +25,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <grp.h>
#include <pwd.h>
@ -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;
}

View file

@ -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)
tConfig->logOut = UtilStringDuplicate(ArrayGet(value, 0));
}
else
{
Log(lc, LOG_ERROR, "Unable to open log file '%s' for writing.",
ArrayGet(value, 0));
goto error;
tConfig->logOut = NULL;
}
Log(lc, LOG_DEBUG, "Redirecting output to '%s'.", ArrayGet(value, 0));
LogConfigOutputSet(lc, out);
}
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);
}

View file

@ -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;
/*