summaryrefslogtreecommitdiff
path: root/logging.c
diff options
context:
space:
mode:
authorLuke Bratch <luke@bratch.co.uk>2019-07-10 20:44:35 +0100
committerLuke Bratch <luke@bratch.co.uk>2019-07-10 20:44:35 +0100
commitb9a8951cf86214a3dcb430ae0d34e8d5dc1adb11 (patch)
treef868ace1f3e1763279eb513a49c3fdee9d3c0fab /logging.c
parent22a4f361329ed4e303e2f1bdce9edf49e70970f3 (diff)
Ensure log filenames are safe for writing.
Diffstat (limited to 'logging.c')
-rw-r--r--logging.c31
1 files changed, 27 insertions, 4 deletions
diff --git a/logging.c b/logging.c
index 5b790b1..6e8d9b7 100644
--- a/logging.c
+++ b/logging.c
@@ -77,10 +77,24 @@ int logline(char *str, char *ournick, char *basedir, int type) {
debugprint(DEBUG_FULL, "logline(): extracted '%s'.\n", tokens[i]);
}
+ // Make "filename safe" copies of from and to names to ensure filename ends up being safe
+ char from[MAXCHAR], to[MAXCHAR];
+ strcpy(from, tokens[0]);
+ strcpy(to, tokens[2]);
+ // Remove unsafe characters (assuming POSIX, just strip "/" and replace with "_")
+ replacechar(from, '/', '_');
+ replacechar(to, '/', '_');
+ // Ensure filename wouldn't be too long
+ if (strlen(from) > NAME_MAX || strlen(to) > NAME_MAX) {
+ debugprint(DEBUG_CRIT, "Filename would be too long if logging either '%s' or '%s', returning!\n", from, to);
+ return 0;
+ }
+
switch(type) {
case LOG_PRIVMSG:
// Extract the username from the prefix
extractnickfromprefix(tokens[0]);
+ extractnickfromprefix(from);
// Remove the leading ":" from the real message
stripprefix(str);
@@ -88,10 +102,16 @@ int logline(char *str, char *ournick, char *basedir, int type) {
// Build the log filename
// If the message was sent to us, then log it in the sender's log file
if (strncmp(tokens[2], ournick, strlen(tokens[0])) == 0) {
- snprintf(filename, MAXCHAR, "%s/logs/%s.log", basedir, tokens[0]);
+ if (!snprintf(filename, MAXCHAR, "%s/logs/%s.log", basedir, from)) {
+ debugprint(DEBUG_CRIT, "Error while log filename for from name, returning!\n");
+ return 0;
+ }
} else {
// Otherwise log it in the "to" log file
- snprintf(filename, MAXCHAR, "%s/logs/%s.log", basedir, tokens[2]);
+ if (!snprintf(filename, MAXCHAR, "%s/logs/%s.log", basedir, to)) {
+ debugprint(DEBUG_CRIT, "Error while log filename for to name, returning!\n");
+ return 0;
+ }
}
debugprint(DEBUG_FULL, "logline(): Logging PRIVMSG from '%s' to '%s' message '%s' in filename '%s'.\n", tokens[0], tokens[2], str, filename);
@@ -112,7 +132,7 @@ int logline(char *str, char *ournick, char *basedir, int type) {
return 0;
}
- snprintf(filename, MAXCHAR, "%s/logs/%s.log", basedir, tokens[2] + pos);
+ snprintf(filename, MAXCHAR, "%s/logs/%s.log", basedir, to + pos);
debugprint(DEBUG_FULL, "logline(): Logging JOIN/PART to/from '%s' in filename '%s'.\n", tokens[2] + pos, filename);
@@ -151,7 +171,10 @@ int logline(char *str, char *ournick, char *basedir, int type) {
// Remove the leading ":" from the topic
stripprefix(str);
- snprintf(filename, MAXCHAR, "%s/logs/%s.log", basedir, tokens[2]);
+ if (!snprintf(filename, MAXCHAR, "%s/logs/%s.log", basedir, to)) {
+ debugprint(DEBUG_CRIT, "Error while log filename for topic, returning!\n");
+ return 0;
+ }
debugprint(DEBUG_FULL, "logline(): Logging TOPIC for '%s' in filename '%s'.\n", tokens[2], filename);