Sanitise filenames logged by TFTP

This commit is contained in:
Simon Kelley
2012-04-20 17:15:01 +01:00
parent 6f13e53886
commit 42fb8153ba

View File

@@ -24,6 +24,7 @@ static ssize_t tftp_err(int err, char *packet, char *mess, char *file);
static ssize_t tftp_err_oops(char *packet, char *file); static ssize_t tftp_err_oops(char *packet, char *file);
static ssize_t get_block(char *packet, struct tftp_transfer *transfer); static ssize_t get_block(char *packet, struct tftp_transfer *transfer);
static char *next(char **p, char *end); static char *next(char **p, char *end);
static void sanitise(char *buf);
#define OP_RRQ 1 #define OP_RRQ 1
#define OP_WRQ 2 #define OP_WRQ 2
@@ -562,17 +563,12 @@ void check_tftp_listeners(fd_set *rset, time_t now)
len = tftp_err_oops(daemon->packet, transfer->file->filename); len = tftp_err_oops(daemon->packet, transfer->file->filename);
endcon = 1; endcon = 1;
} }
else if (++transfer->backoff > 5) /* don't complain about timeout when we're awaiting the last
ACK, some clients never send it */
else if (++transfer->backoff > 5 && len != 0)
{ {
/* don't complain about timeout when we're awaiting the last endcon = 1;
ACK, some clients never send it */ len = 0;
if (len != 0)
{
my_syslog(MS_TFTP | LOG_ERR, _("failed sending %s to %s"),
transfer->file->filename, daemon->addrbuff);
len = 0;
endcon = 1;
}
} }
if (len != 0) if (len != 0)
@@ -581,8 +577,9 @@ void check_tftp_listeners(fd_set *rset, time_t now)
if (endcon || len == 0) if (endcon || len == 0)
{ {
if (!endcon) strcpy(daemon->namebuff, transfer->file->filename);
my_syslog(MS_TFTP | LOG_INFO, _("sent %s to %s"), transfer->file->filename, daemon->addrbuff); sanitise(daemon->namebuff);
my_syslog(MS_TFTP | LOG_INFO, endcon ? _("failed sending %s to %s") : _("sent %s to %s"), daemon->namebuff, daemon->addrbuff);
/* unlink */ /* unlink */
*up = tmp; *up = tmp;
/* put on queue to be sent to script and deleted */ /* put on queue to be sent to script and deleted */
@@ -621,6 +618,15 @@ static char *next(char **p, char *end)
return ret; return ret;
} }
static void sanitise(char *buf)
{
char *end = buf + strlen(buf);
while (*(buf++))
if (!isprint(*buf))
memmove(buf, buf + 1, end - buf);
}
static ssize_t tftp_err(int err, char *packet, char *message, char *file) static ssize_t tftp_err(int err, char *packet, char *message, char *file)
{ {
struct errmess { struct errmess {
@@ -630,6 +636,8 @@ static ssize_t tftp_err(int err, char *packet, char *message, char *file)
ssize_t ret = 4; ssize_t ret = 4;
char *errstr = strerror(errno); char *errstr = strerror(errno);
sanitise(file);
mess->op = htons(OP_ERR); mess->op = htons(OP_ERR);
mess->err = htons(err); mess->err = htons(err);
ret += (snprintf(mess->message, 500, message, file, errstr) + 1); ret += (snprintf(mess->message, 500, message, file, errstr) + 1);
@@ -640,7 +648,9 @@ static ssize_t tftp_err(int err, char *packet, char *message, char *file)
static ssize_t tftp_err_oops(char *packet, char *file) static ssize_t tftp_err_oops(char *packet, char *file)
{ {
return tftp_err(ERR_NOTDEF, packet, _("cannot read %s: %s"), file); /* May have >1 refs to file, so potentially mangle a copy of the name */
strcpy(daemon->namebuff, file);
return tftp_err(ERR_NOTDEF, packet, _("cannot read %s: %s"), daemon->namebuff);
} }
/* return -1 for error, zero for done. */ /* return -1 for error, zero for done. */