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 <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <errno.h>
#include <grp.h> #include <grp.h>
#include <pwd.h> #include <pwd.h>
@ -105,6 +106,17 @@ main(int argc, char **argv)
TelodendriaPrintHeader(lc); 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) while ((opt = getopt(argc, argv, "c:Vh")) != -1)
{ {
switch (opt) switch (opt)
@ -147,6 +159,14 @@ main(int argc, char **argv)
} }
else 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"); configFile = fopen(configArg, "r");
if (!configFile) if (!configFile)
{ {
@ -181,6 +201,42 @@ main(int argc, char **argv)
ConfigFree(config); 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:"); Log(lc, LOG_DEBUG, "Configuration:");
LogConfigIndent(lc); LogConfigIndent(lc);
Log(lc, LOG_DEBUG, "Listen On: %s:%s", tConfig->listenHost, tConfig->listenPort); 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); Log(lc, LOG_DEBUG, "Flags: %x", tConfig->flags);
LogConfigUnindent(lc); LogConfigUnindent(lc);
Log(lc, LOG_TASK, "Evaluating permissions..."); Log(lc, LOG_TASK, "Setting permissions...");
if (chdir(tConfig->chroot) != 0) 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; exit = EXIT_FAILURE;
goto finish; 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); userInfo = getpwnam(tConfig->uid);
groupInfo = getgrnam(tConfig->gid); groupInfo = getgrnam(tConfig->gid);
@ -212,17 +272,25 @@ main(int argc, char **argv)
exit = EXIT_FAILURE; exit = EXIT_FAILURE;
goto finish; goto finish;
} }
else
{
Log(lc, LOG_DEBUG, "Found user/group information using getpwnam() and getgrnam().");
}
if (getuid() == 0) if (getuid() == 0)
{ {
#ifndef __OpenBSD__
if (chroot(tConfig->chroot) == 0) 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 else
{ {
Log(lc, LOG_WARNING, "Unable to chroot into directory: %s.", tConfig->chroot); 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) if (setgid(groupInfo->gr_gid) != 0 || setuid(userInfo->pw_uid) != 0)
{ {
@ -230,12 +298,12 @@ main(int argc, char **argv)
} }
else 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 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) if (getuid() != userInfo->pw_uid || getgid() != groupInfo->gr_gid)
{ {
@ -260,5 +328,6 @@ main(int argc, char **argv)
finish: finish:
Log(lc, LOG_DEBUG, "Exiting with code '%d'.", exit); Log(lc, LOG_DEBUG, "Exiting with code '%d'.", exit);
TelodendriaConfigFree(tConfig); TelodendriaConfigFree(tConfig);
LogConfigFree(lc);
return exit; return exit;
} }

View file

@ -211,23 +211,23 @@ TelodendriaConfigParse(HashMap * config, LogConfig * lc)
cVal = ArrayGet(ConfigValuesGet(cDirective), 0); cVal = ArrayGet(ConfigValuesGet(cDirective), 0);
if (strcmp(cVal, "message") == 0) if (strcmp(cVal, "message") == 0)
{ {
LogConfigLevelSet(lc, LOG_MESSAGE); tConfig->logLevel = LOG_MESSAGE;
} }
else if (strcmp(cVal, "debug") == 0) else if (strcmp(cVal, "debug") == 0)
{ {
LogConfigLevelSet(lc, LOG_DEBUG); tConfig->logLevel = LOG_DEBUG;
} }
else if (strcmp(cVal, "task") == 0) else if (strcmp(cVal, "task") == 0)
{ {
LogConfigLevelSet(lc, LOG_TASK); tConfig->logLevel = LOG_TASK;
} }
else if (strcmp(cVal, "warning") == 0) else if (strcmp(cVal, "warning") == 0)
{ {
LogConfigLevelSet(lc, LOG_WARNING); tConfig->logLevel = LOG_WARNING;
} }
else if (strcmp(cVal, "error") == 0) else if (strcmp(cVal, "error") == 0)
{ {
LogConfigLevelSet(lc, LOG_ERROR); tConfig->logLevel = LOG_ERROR;
} }
else else
{ {
@ -250,11 +250,11 @@ TelodendriaConfigParse(HashMap * config, LogConfig * lc)
if (strcmp(cVal, "none") == 0) if (strcmp(cVal, "none") == 0)
{ {
LogConfigTimeStampFormatSet(lc, NULL); tConfig->logTimestamp = NULL;
} }
else if (strcmp(cVal, "default") != 0) 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); 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); Log(lc, LOG_ERROR, "Expected boolean value for log.color, got '%s'.", cVal);
goto error; goto error;
@ -285,20 +285,13 @@ TelodendriaConfigParse(HashMap * config, LogConfig * lc)
/* Set the actual log output file last */ /* Set the actual log output file last */
if (strcmp(ArrayGet(value, 0), "stdout") != 0) if (strcmp(ArrayGet(value, 0), "stdout") != 0)
{ {
FILE *out = fopen(ArrayGet(value, 0), "w"); tConfig->logOut = UtilStringDuplicate(ArrayGet(value, 0));
}
if (!out) else
{ {
Log(lc, LOG_ERROR, "Unable to open log file '%s' for writing.", tConfig->logOut = NULL;
ArrayGet(value, 0));
goto error;
}
Log(lc, LOG_DEBUG, "Redirecting output to '%s'.", ArrayGet(value, 0));
LogConfigOutputSet(lc, out);
} }
tConfig->logConfig = lc;
return tConfig; return tConfig;
error: error:
TelodendriaConfigFree(tConfig); TelodendriaConfigFree(tConfig);
@ -325,7 +318,5 @@ TelodendriaConfigFree(TelodendriaConfig * tConfig)
free(tConfig->gid); free(tConfig->gid);
free(tConfig->dataDir); free(tConfig->dataDir);
LogConfigFree(tConfig->logConfig);
free(tConfig); free(tConfig);
} }

View file

@ -37,7 +37,8 @@
typedef enum TelodendriaConfigFlag typedef enum TelodendriaConfigFlag
{ {
TELODENDRIA_FEDERATION = (1 << 0), TELODENDRIA_FEDERATION = (1 << 0),
TELODENDRIA_REGISTRATION = (1 << 1) TELODENDRIA_REGISTRATION = (1 << 1),
TELODENDRIA_LOG_COLOR = (1 << 2)
} TelodendriaConfigFlag; } TelodendriaConfigFlag;
/* /*
@ -62,7 +63,9 @@ typedef struct TelodendriaConfig
unsigned int flags; unsigned int flags;
unsigned int threads; unsigned int threads;
LogConfig *logConfig; char *logOut;
char *logTimestamp;
LogLevel logLevel;
} TelodendriaConfig; } TelodendriaConfig;
/* /*