forked from Telodendria/Telodendria
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:
parent
9ae05e84f2
commit
4304a28302
3 changed files with 95 additions and 32 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue