From 5c0704eec8832153b8542a5fdf2acf2f94424cf1 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Wed, 1 Jun 2011 22:33:44 -0700 Subject: [PATCH] ASCII logger now escapes non-printable characters. Closes #450. --- src/Desc.cc | 56 ++++++++++++++---- src/LogWriterAscii.cc | 2 +- .../Baseline/logging.ascii-binary/ssh.log | Bin 0 -> 86 bytes .../Baseline/logging.ascii-escape/ssh.log | Bin 376 -> 376 bytes testing/btest/logging/ascii-binary.bro | 25 ++++++++ 5 files changed, 69 insertions(+), 14 deletions(-) create mode 100644 testing/btest/Baseline/logging.ascii-binary/ssh.log create mode 100644 testing/btest/logging/ascii-binary.bro diff --git a/src/Desc.cc b/src/Desc.cc index ce6083800c..c15a461bb2 100644 --- a/src/Desc.cc +++ b/src/Desc.cc @@ -207,41 +207,71 @@ void ODesc::Indent() } } -static const char hex_chars[] = "0123456789ABCDEF"; +static const char hex_chars[] = "0123456789abcdef"; + +static const char* find_first_unprintable(ODesc* d, const char* bytes, unsigned int n) + { + if ( d->IsBinary() ) + return 0; + + while ( n-- ) + { + if ( ! isprint(*bytes) ) + return bytes; + ++bytes; + } + + return 0; + } void ODesc::AddBytes(const void* bytes, unsigned int n) { - if ( ! escape ) - return AddBytesRaw(bytes, n); - const char* s = (const char*) bytes; const char* e = (const char*) bytes + n; while ( s < e ) { - const char* t = (const char*) memchr(s, escape[0], e - s); + const char* t1 = escape ? (const char*) memchr(s, escape[0], e - s) : e; + const char* t2 = find_first_unprintable(this, s, t1 ? e - t1 : e - s); - if ( ! t ) + if ( t2 && (t2 < t1 || ! t1) ) + { + AddBytesRaw(s, t2 - s); + + char hex[6] = "\\x00"; + hex[2] = hex_chars[((*t2) & 0xf0) >> 4]; + hex[3] = hex_chars[(*t2) & 0x0f]; + AddBytesRaw(hex, sizeof(hex)); + + s = t2 + 1; + continue; + } + + if ( ! escape ) break; - if ( memcmp(t, escape, escape_len) != 0 ) + if ( ! t1 ) break; - AddBytesRaw(s, t - s); + if ( memcmp(t1, escape, escape_len) != 0 ) + break; + + AddBytesRaw(s, t1 - s); for ( int i = 0; i < escape_len; ++i ) { char hex[5] = "\\x00"; - hex[2] = hex_chars[(*t) >> 4]; - hex[3] = hex_chars[(*t) & 0x0f]; + hex[2] = hex_chars[((*t1) & 0xf0) >> 4]; + hex[3] = hex_chars[(*t1) & 0x0f]; AddBytesRaw(hex, sizeof(hex)); - ++t; + ++t1; } - s = t; + s = t1; } - AddBytesRaw(s, e - s); + if ( s < e ) + AddBytesRaw(s, e - s); } void ODesc::AddBytesRaw(const void* bytes, unsigned int n) diff --git a/src/LogWriterAscii.cc b/src/LogWriterAscii.cc index 4c54e76715..d831960a3c 100644 --- a/src/LogWriterAscii.cc +++ b/src/LogWriterAscii.cc @@ -223,7 +223,7 @@ bool LogWriterAscii::DoWrite(int num_fields, const LogField* const * fields, return false; } - desc.Add("\n"); + desc.AddRaw("\n", 1); if ( fwrite(desc.Bytes(), desc.Len(), 1, file) != 1 ) { diff --git a/testing/btest/Baseline/logging.ascii-binary/ssh.log b/testing/btest/Baseline/logging.ascii-binary/ssh.log new file mode 100644 index 0000000000000000000000000000000000000000..84a2cc609efabb58fde7117111bb3142d49e967e GIT binary patch literal 86 zcmY#ZNJ%V7tN{^5T!~4^F%<@h3=A<9X=w}$DXD2SE{-9NPzm#7?BXD$F%>{rgn9sa C3K_-# literal 0 HcmV?d00001 diff --git a/testing/btest/Baseline/logging.ascii-escape/ssh.log b/testing/btest/Baseline/logging.ascii-escape/ssh.log index 6797e1e302234c2b6e90ab6fcf02df8a778a3b97..aa08625281cf22112c46686d758ebaf329c49060 100644 GIT binary patch literal 376 zcmY#ZD5XKrjoy%%ard0;njM2^1|ZNh~QXuBl1RFU>0{s^l^>HZZfa zG%~X=(la(UH#DiKG1LPx^*{_GV;~9U=$Y2kSQr3xmnJ8t76Y}H=4I#Qm*(X;_ literal 376 zcmY#ZD5XKrjoy%%ard0;njM2^1|ZNh~QXuBl1RFU>0{s^l^>va~ce zv@kU=(=#zQHn6CvG1N2CGuAT!GK`FYB$%UTT2o_T0MuQYoSa$=)LxpGotIypN22z$ t#LS%1qSTt2&|s2v##ER)Gk^(*3Em`{P+W>I0qg~*AQDZ0yWTf~3jn{Ua{K@Q diff --git a/testing/btest/logging/ascii-binary.bro b/testing/btest/logging/ascii-binary.bro new file mode 100644 index 0000000000..6f095db0c7 --- /dev/null +++ b/testing/btest/logging/ascii-binary.bro @@ -0,0 +1,25 @@ +# +# @TEST-EXEC: bro %INPUT +# @TEST-EXEC: btest-diff ssh.log + +module SSH; + +export { + redef enum Log::ID += { SSH }; + + type Log: record { + data: string; + data2: string; + } &log; +} + +redef LogAscii::separator = "|"; + +event bro_init() +{ + Log::create_stream(SSH, [$columns=Log]); + Log::write(SSH, [$data="abc\n\xffdef", $data2="DATA2"]); + Log::write(SSH, [$data="abc|\xffdef", $data2="DATA2"]); + Log::write(SSH, [$data="abc\xff|def", $data2="DATA2"]); +} +