Skip to content

Commit

Permalink
syslog-format: cannot parse ipv6 into hostname
Browse files Browse the repository at this point in the history
Hostname parser expected colon to separate msg part from host-program
part. But colon is valid character for host in case of ipv6. So some
heuristics are added to allow colon during parsing hostname: looking
for at maximum 8 blocks of at maximum 4-hexa values, separated by
:. This heuristic automatically allows usage of double colons as well.

Signed-off-by: Antal Nemes <antal.nemes@balabit.com>
  • Loading branch information
furiel committed Aug 7, 2017
1 parent 6303ce1 commit 399d565
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 1 deletion.
52 changes: 51 additions & 1 deletion modules/syslogformat/syslog-format.c
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,47 @@ _init_parse_hostname_invalid_chars(void)
}
}

typedef struct _IPv6Heuristics
{
gint8 current_segment;
gint8 digits_in_segment;
gboolean heuristic_failed;
} IPv6Heuristics;

static gboolean
ipv6_heuristics_feed_gchar(IPv6Heuristics *self, gchar c)
{
if (self->heuristic_failed)
return FALSE;

if (c != ':' && !g_ascii_isxdigit(c))
{
self->heuristic_failed = TRUE;
return FALSE;
}

if (g_ascii_isxdigit(c))
{
if (++self->digits_in_segment > 4)
{
self->heuristic_failed = TRUE;
return FALSE;
}
}

if (c == ':')
{
self->digits_in_segment = 0;
if (++self->current_segment >= 8)
{
self->heuristic_failed = TRUE;
return FALSE;
}
}

return TRUE;
}

static void
log_msg_parse_hostname(LogMessage *self, const guchar **data, gint *length,
const guchar **hostname_start, int *hostname_len,
Expand All @@ -646,6 +687,8 @@ log_msg_parse_hostname(LogMessage *self, const guchar **data, gint *length,
gchar hostname_buf[256];
gint dst = 0;

IPv6Heuristics ipv6_heuristics = {0};

src = *data;
left = *length;

Expand All @@ -655,8 +698,15 @@ log_msg_parse_hostname(LogMessage *self, const guchar **data, gint *length,
oldsrc = src;
oldleft = left;

while (left && *src != ' ' && *src != ':' && *src != '[' && dst < sizeof(hostname_buf) - 1)
while (left && *src != ' ' && *src != '[' && dst < sizeof(hostname_buf) - 1)
{
ipv6_heuristics_feed_gchar(&ipv6_heuristics, *src);

if (*src == ':' && ipv6_heuristics.heuristic_failed)
{
break;
}

if (G_UNLIKELY((flags & LP_CHECK_HOSTNAME) && (invalid_chars[((guint) *src) >> 8] & (1 << (((guint) *src) % 8)))))
{
break;
Expand Down
62 changes: 62 additions & 0 deletions tests/unit/test_msgparse.c
Original file line number Diff line number Diff line change
Expand Up @@ -1067,6 +1067,68 @@ Test(msgparse, test_expected_sd_pairs_without_sd_param)
run_parameterized_test(params);
}

Test(msgparse, test_ip_in_host)
{
struct msgparse_params params[] =
{
(struct msgparse_params)
{
.msg = "<0>Jan 10 01:00:00 1.2.3.4 prg0",
.parse_flags = LP_EXPECT_HOSTNAME,
.expected_stamp_sec = _get_epoch_with_bsd_year(0, 10, 1, 0, 0),
.expected_stamp_ofs = 3600,
.expected_program = "prg0",
.expected_host = "1.2.3.4"
},
(struct msgparse_params)
{
.msg = "<0>Jan 10 01:00:00 0000:BABA:BA00:DAB:BABA:BABA:BABA:BAB0 prg0",
.parse_flags = LP_EXPECT_HOSTNAME,
.expected_stamp_sec = _get_epoch_with_bsd_year(0, 10, 1, 0, 0),
.expected_stamp_ofs = 3600,
.expected_program = "prg0",
.expected_host = "0000:BABA:BA00:DAB:BABA:BABA:BABA:BAB0"
},
(struct msgparse_params)
{
.msg = "<0>Jan 10 01:00:00 0001:BABA:BA00:DAB::BAB0 prg0",
.parse_flags = LP_EXPECT_HOSTNAME,
.expected_stamp_sec = _get_epoch_with_bsd_year(0, 10, 1, 0, 0),
.expected_stamp_ofs = 3600,
.expected_program = "prg0",
.expected_host = "0001:BABA:BA00:DAB::BAB0"
},
{
.msg = "<0>Jan 10 01:00:00 0002:: prg0: msgtxt",
.parse_flags = LP_EXPECT_HOSTNAME,
.expected_stamp_sec = _get_epoch_with_bsd_year(0, 10, 1, 0, 0),
.expected_stamp_ofs = 3600,
.expected_program = "prg0",
.expected_host = "0002::",
.expected_msg = "msgtxt"
},
(struct msgparse_params)
{
.msg = "<0>Jan 10 01:00:00 prg0", // No ip no msg
.parse_flags = LP_EXPECT_HOSTNAME,
.expected_stamp_sec = _get_epoch_with_bsd_year(0, 10, 1, 0, 0),
.expected_stamp_ofs = 3600,
.expected_program = "prg0",
.expected_host = ""
},
(struct msgparse_params)
{
.msg = "<0>Jan 10 01:00:00 prg0: msgtxt", // program name with message, no ip
.expected_stamp_sec = _get_epoch_with_bsd_year(0, 10, 1, 0, 0),
.expected_stamp_ofs = 3600,
.expected_program = "prg0",
.expected_msg = "msgtxt"
},
{NULL}
};
run_parameterized_test(params);
}

Test(msgparse, test_simple_message)
{
struct msgparse_params params[] =
Expand Down

0 comments on commit 399d565

Please sign in to comment.