diff --git a/scripts/base/protocols/redis/main.zeek b/scripts/base/protocols/redis/main.zeek index 4d11aede9f..22ecda0402 100644 --- a/scripts/base/protocols/redis/main.zeek +++ b/scripts/base/protocols/redis/main.zeek @@ -26,6 +26,11 @@ export { key: string &log; }; + type AuthCommand: record { + username: string &optional; + password: string; + }; + type Command: record { ## The raw command, exactly as parsed raw: vector of string; @@ -71,15 +76,18 @@ export { type State: record { ## Pending requests. - pending: table[count] of Info; + pending: table[count] of Info; ## Current request in the pending queue. - current_request: count &default=0; + current_request: count &default=0; ## Current response in the pending queue. current_response: count &default=0; ## Ranges where we do not expect a response ## Each range is one or two elements, one meaning it's unbounded, two meaning ## it begins at one and ends at the second. no_response_ranges: vector of vector of count; + ## We store if this analyzer had a violation to avoid logging if so. + ## This should not be super necessary, but worth a shot. + violation: bool &default=F; }; # Redis specifically mentions 10k commands as a good pipelining threshold, so @@ -102,6 +110,21 @@ event zeek_init() &priority=5 Analyzer::register_for_ports(Analyzer::ANALYZER_SPICY_REDIS, ports); } +event analyzer_violation_info(atype: AllAnalyzers::Tag, + info: AnalyzerViolationInfo) + { + if ( atype == Analyzer::ANALYZER_SPICY_REDIS ) + { + if ( info?$c ) + { + if ( info$c?$redis_state ) + { + info$c$redis_state$violation = T; + } + } + } + } + function new_redis_session(c: connection): Info { return Info($ts=network_time(), $uid=c$uid, $id=c$id); @@ -116,11 +139,14 @@ function make_new_state(c: connection) function set_state(c: connection, is_orig: bool) { - if ( ! c?$redis_state ) make_new_state(c); + if ( ! c?$redis_state ) + make_new_state(c); local current: count; - if ( is_orig ) current = c$redis_state$current_request; - else current = c$redis_state$current_response; + if ( is_orig ) + current = c$redis_state$current_request; + else + current = c$redis_state$current_response; if ( current !in c$redis_state$pending ) c$redis_state$pending[current] = new_redis_session(c); @@ -131,28 +157,24 @@ function set_state(c: connection, is_orig: bool) # Returns true if the last interval exists and is closed function is_last_interval_closed(c: connection): bool { - return |c$redis_state$no_response_ranges| == 0 || |c$redis_state$no_response_ranges[|c$redis_state$no_response_ranges| - 1]| != 1; + return |c$redis_state$no_response_ranges| == 0 + || |c$redis_state$no_response_ranges[|c$redis_state$no_response_ranges| - 1]| != 1; } event Redis::command(c: connection, is_orig: bool, command: Command) { - if ( ! c?$redis_state ) make_new_state(c); + if ( ! c?$redis_state ) + make_new_state(c); - if ( max_pending_requests > 0 && |c$redis_state$pending| > max_pending_requests ) + if ( max_pending_requests > 0 + && |c$redis_state$pending| > max_pending_requests ) { Reporter::conn_weird("Redis_excessive_pipelining", c); - - # Just spit out what we have - while ( c$redis_state$current_response < c$redis_state$current_request ) - { - local cr = c$redis_state$current_response; - if ( cr in c$redis_state$pending ) - { - Log::write(Redis::LOG, c$redis_state$pending[cr]); - delete c$redis_state$pending[cr]; - } - ++c$redis_state$current_response; - } + # Delete the current state and restart later. We'll be in a weird state, but + # really we want to abort. I don't quite get how to register this as a + # violation. :) + delete c$redis_state; + return; } ++c$redis_state$current_request; @@ -164,9 +186,10 @@ event Redis::command(c: connection, is_orig: bool, command: Command) if ( to_lower(command$raw[2]) == "on" ) { # If the last range is open, close it here. Otherwise, noop - if ( |c$redis_state$no_response_ranges| > 0 ) + if ( |c$redis_state$no_response_ranges| > 0 ) { - local range = c$redis_state$no_response_ranges[|c$redis_state$no_response_ranges| - 1]; + local range = c$redis_state$no_response_ranges[|c$redis_state$no_response_ranges| + - 1]; if ( |range| == 1 ) { range += c$redis_state$current_request; @@ -176,16 +199,17 @@ event Redis::command(c: connection, is_orig: bool, command: Command) if ( to_lower(command$raw[2]) == "off" ) { # Only add a new interval if the last one is closed - if ( is_last_interval_closed(c) ) + if ( is_last_interval_closed(c) ) { c$redis_state$no_response_ranges += vector(c$redis_state$current_request); } } if ( to_lower(command$raw[2]) == "skip" ) { - if ( is_last_interval_closed(c) ) + if ( is_last_interval_closed(c) ) # It skips this one and the next one - c$redis_state$no_response_ranges += vector(c$redis_state$current_request, c$redis_state$current_request + 2); + c$redis_state$no_response_ranges += vector(c$redis_state$current_request, + c$redis_state$current_request + 2); } } } @@ -202,10 +226,10 @@ function response_num(c: connection): count for ( i in c$redis_state$no_response_ranges ) { local range = c$redis_state$no_response_ranges[i]; - assert |range| >= 1; + assert | range | >= 1; if ( |range| == 1 && resp_num > range[0] ) - {} # TODO: This is necessary if not using pipelining - if ( |range| == 2 && resp_num >= range[0] && resp_num < range[1] ) + { } # TODO: This is necessary if not using pipelining + if ( |range| == 2 && resp_num >= range[0] && resp_num < range[1] ) return range[1]; } @@ -215,7 +239,8 @@ function response_num(c: connection): count event Redis::server_data(c: connection, is_orig: bool, data: ServerData) { - if ( ! c?$redis_state ) make_new_state(c); + if ( ! c?$redis_state ) + make_new_state(c); local previous_response_num = c$redis_state$current_response; c$redis_state$current_response = response_num(c); @@ -232,27 +257,37 @@ event Redis::server_data(c: connection, is_orig: bool, data: ServerData) next; } - if ( previous_response_num in c$redis_state$pending ) + if ( previous_response_num in c$redis_state$pending && + c$redis_state$pending[previous_response_num]?$cmd ) { Log::write(Redis::LOG, c$redis_state$pending[previous_response_num]); delete c$redis_state$pending[previous_response_num]; } previous_response_num += 1; } - # Log this one - Log::write(Redis::LOG, c$redis); - delete c$redis_state$pending[c$redis_state$current_response]; + # Log this one if we have the request and response + if ( c$redis?$cmd ) + { + Log::write(Redis::LOG, c$redis); + delete c$redis_state$pending[c$redis_state$current_response]; + } } hook finalize_redis(c: connection) { + if ( c$redis_state$violation ) + { + # If there's a violation, make sure everything gets deleted + delete c$redis_state; + } # Flush all pending but incomplete request/response pairs. - if ( c?$redis_state ) + if ( c?$redis_state && c$redis_state$current_response != 0 ) { for ( r, info in c$redis_state$pending ) { # We don't use pending elements at index 0. - if ( r == 0 ) next; + if ( r == 0 ) + next; Log::write(Redis::LOG, info); } } diff --git a/src/analyzer/protocol/redis/redis.spicy b/src/analyzer/protocol/redis/redis.spicy index b782380cd1..96cd222068 100644 --- a/src/analyzer/protocol/redis/redis.spicy +++ b/src/analyzer/protocol/redis/redis.spicy @@ -6,6 +6,7 @@ import RESP; public type KnownCommand = enum { APPEND, + AUTH, BITCOUNT, BITFIELD, BITFIELD_RO, @@ -234,6 +235,7 @@ function command_from(cmd_bytes: bytes): optional { switch (cmd_bytes.lower()) { case b"set": cmd = KnownCommand::SET; case b"append": cmd = KnownCommand::APPEND; + case b"auth": cmd = KnownCommand::AUTH; case b"bitcount": cmd = KnownCommand::BITCOUNT; case b"bitfield": cmd = KnownCommand::BITFIELD; case b"bitfield_ro": cmd = KnownCommand::BITFIELD_RO; @@ -352,3 +354,21 @@ public function make_get(command: Command): Get { public function is_get(data: RESP::ClientData): bool { return data.command.known && *(data.command.known) == KnownCommand::GET && |data.command.raw| >= 2; } + +type Auth = struct { + username: optional; + password: bytes; +}; + +public function make_auth(command: Command): Auth { + assert |command.raw| >= 2 : "AUTH must have arguments"; + if (|command.raw| == 2) { + return [$username = Null, $password = command.raw[1]]; + } + + return [$username = command.raw[1], $password = command.raw[2]]; +} + +public function is_auth(data: RESP::ClientData): bool { + return data.command.known && *(data.command.known) == KnownCommand::AUTH && |data.command.raw| >= 2; +} diff --git a/src/analyzer/protocol/redis/resp.evt b/src/analyzer/protocol/redis/resp.evt index a8a9db92a8..035a21a2db 100644 --- a/src/analyzer/protocol/redis/resp.evt +++ b/src/analyzer/protocol/redis/resp.evt @@ -12,6 +12,7 @@ export Zeek_Redis::ZeekServerData; on RESP::ClientData if ( Redis::is_set(self) ) -> event Redis::set_command($conn, $is_orig, Redis::make_set(self.command)); on RESP::ClientData if ( Redis::is_get(self) ) -> event Redis::get_command($conn, $is_orig, Redis::make_get(self.command)); +on RESP::ClientData if ( Redis::is_auth(self) ) -> event Redis::auth_command($conn, $is_orig, Redis::make_auth(self.command)); # All client data is a command on RESP::ClientData -> event Redis::command($conn, $is_orig, self.command); diff --git a/src/analyzer/protocol/redis/resp.spicy b/src/analyzer/protocol/redis/resp.spicy index 7302f4103f..1396a65b2a 100644 --- a/src/analyzer/protocol/redis/resp.spicy +++ b/src/analyzer/protocol/redis/resp.spicy @@ -9,7 +9,7 @@ import spicy; const MAX_SIZE = 1024 * 1024; public type ClientMessages = unit { - : (ClientData &synchronize)[]; + : ClientData[]; }; public type ServerMessages = unit { @@ -17,21 +17,22 @@ public type ServerMessages = unit { }; public type ClientData = unit { - %synchronize-after = b"\x0d\x0a"; + on %init() { self.start = self.input(); } + # Clients can only be an array or inline - ty: uint8 &convert=DataType($$); + ty: uint8 &convert=DataType($$) { + if (self.ty != DataType::ARRAY) { + # This is inline, so we need to reparse `ty` + self.set_input(self.start); + } + } if (self.ty == DataType::ARRAY) { multibulk: Array; } else { - # HACK: If the type isn'tan array, this is just some random unserialized - # string until \r\n - do this by prepending the type to the remaining bytes. - # Formally in Redis code, that's an "inline command." - # - # As an extra point, this is handled in redis in `processInlineBuffer`, - # which has a hardcoded limit of 1024*64. That seems too big. We'll do 1024. - inline: RedisBytes &convert=(pack(cast(self.ty), spicy::ByteOrder::Network) + $$) &max-size=1024; + inline: RedisBytes &max-size=1024; }; + var start: iterator; var command: Redis::Command; on %done { @@ -152,10 +153,10 @@ type Set = unit { elements: Data[self.num_elements]; }; -on Data::%done { +on ServerData::%done { spicy::accept_input(); } -on Data::%error { - spicy::decline_input("error while parsing RESP data"); +on ServerData::%error { + spicy::decline_input("error while parsing RESP server data"); } diff --git a/testing/btest/Baseline/scripts.base.protocols.redis.almost-redis/redis.log b/testing/btest/Baseline/scripts.base.protocols.redis.almost-redis/redis.log new file mode 100644 index 0000000000..5d183629a1 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.redis.almost-redis/redis.log @@ -0,0 +1,12 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path redis +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p cmd.command cmd.key cmd.value response.err response.data +#types time string addr port addr port string string string bool string +XXXXXXXXXX.XXXXXX CtPZjS20MLrsMUOJi2 127.0.0.1 53099 127.0.0.1 6379 AUTH - - F OK +XXXXXXXXXX.XXXXXX CtPZjS20MLrsMUOJi2 127.0.0.1 53099 127.0.0.1 6379 PING - - F OK +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.redis.auth/output b/testing/btest/Baseline/scripts.base.protocols.redis.auth/output new file mode 100644 index 0000000000..e859b654d6 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.redis.auth/output @@ -0,0 +1,10 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +AUTH +username: notauser +password: notapassword +AUTH +username: default +password: defaultpasswordinvalid +AUTH +username: noone +password: password diff --git a/testing/btest/Baseline/scripts.base.protocols.redis.excessive-pipelining/redis.log b/testing/btest/Baseline/scripts.base.protocols.redis.excessive-pipelining/redis.log index e5c9e70dbb..4d68ceed52 100644 --- a/testing/btest/Baseline/scripts.base.protocols.redis.excessive-pipelining/redis.log +++ b/testing/btest/Baseline/scripts.base.protocols.redis.excessive-pipelining/redis.log @@ -7,17 +7,10 @@ #open XXXX-XX-XX-XX-XX-XX #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p cmd.command cmd.key cmd.value response.err response.data #types time string addr port addr port string string string bool string -XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h ::1 57156 ::1 6379 PING - - - - -XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h ::1 57156 ::1 6379 PING - - - - -XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h ::1 57156 ::1 6379 PING - - - - -XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h ::1 57156 ::1 6379 PING - - - - -XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h ::1 57156 ::1 6379 PING - - - - -XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h ::1 57156 ::1 6379 PING - - - - -XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h ::1 57156 ::1 6379 PING - - - - -XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h ::1 57156 ::1 6379 PING - - - - -XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h ::1 57156 ::1 6379 PING - - - - -XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h ::1 57156 ::1 6379 PING - - - - -XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h ::1 57156 ::1 6379 PING - - - - +XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h ::1 57156 ::1 6379 PING - - F PONG +XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h ::1 57156 ::1 6379 PING - - F PONG +XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h ::1 57156 ::1 6379 PING - - F PONG +XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h ::1 57156 ::1 6379 PING - - F PONG XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h ::1 57156 ::1 6379 PING - - F PONG XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h ::1 57156 ::1 6379 - - - F PONG XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h ::1 57156 ::1 6379 - - - F PONG @@ -26,8 +19,4 @@ XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h ::1 57156 ::1 6379 - - - F PONG XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h ::1 57156 ::1 6379 - - - F PONG XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h ::1 57156 ::1 6379 - - - F PONG XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h ::1 57156 ::1 6379 - - - F PONG -XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h ::1 57156 ::1 6379 - - - F PONG -XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h ::1 57156 ::1 6379 - - - F PONG -XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h ::1 57156 ::1 6379 - - - F PONG -XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h ::1 57156 ::1 6379 - - - F PONG #close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Traces/redis/almost-resp.trace b/testing/btest/Traces/redis/almost-resp.trace new file mode 100644 index 0000000000..168df9a754 Binary files /dev/null and b/testing/btest/Traces/redis/almost-resp.trace differ diff --git a/testing/btest/Traces/redis/auth.trace b/testing/btest/Traces/redis/auth.trace new file mode 100644 index 0000000000..3f56116fe2 Binary files /dev/null and b/testing/btest/Traces/redis/auth.trace differ diff --git a/testing/btest/scripts/base/protocols/redis/almost-redis.zeek b/testing/btest/scripts/base/protocols/redis/almost-redis.zeek new file mode 100644 index 0000000000..697785ea81 --- /dev/null +++ b/testing/btest/scripts/base/protocols/redis/almost-redis.zeek @@ -0,0 +1,8 @@ +# @TEST-DOC: Test 2 commands that look like RESP, then server responses don't +# +# @TEST-EXEC: zeek -Cr $TRACES/redis/almost-resp.trace base/protocols/redis %INPUT >output +# @TEST-EXEC: btest-diff redis.log +# +# Really, the first 2 ARE Redis. The later ones should not be logged because we +# realized it's not Redis. The output from the server is: +# +OK\r\n+OK\r\nnot RESP\r\nStill not RESP\r\nNope\r\n diff --git a/testing/btest/scripts/base/protocols/redis/auth.zeek b/testing/btest/scripts/base/protocols/redis/auth.zeek new file mode 100644 index 0000000000..e271fbf510 --- /dev/null +++ b/testing/btest/scripts/base/protocols/redis/auth.zeek @@ -0,0 +1,16 @@ +# @TEST-DOC: Test Zeek with AUTH commands +# +# @TEST-EXEC: zeek -Cr $TRACES/redis/auth.trace base/protocols/redis %INPUT >output +# @TEST-EXEC: btest-diff output + +event Redis::auth_command(c: connection, is_orig: bool, + command: Redis::AuthCommand) + { + print "AUTH"; + if ( command?$username ) + print fmt("username: %s", command$username); + else + print "username: default"; + + print fmt("password: %s", command$password); + } diff --git a/testing/btest/scripts/base/protocols/redis/bulk.zeek b/testing/btest/scripts/base/protocols/redis/bulk.zeek index 6068c34b23..4d7d23e33a 100644 --- a/testing/btest/scripts/base/protocols/redis/bulk.zeek +++ b/testing/btest/scripts/base/protocols/redis/bulk.zeek @@ -7,7 +7,8 @@ # code directly to the server, but it's useful to see if that trace might come # up with something different. See: # https://redis.io/docs/latest/develop/use/patterns/bulk-loading/ -event Redis::set_command(c: connection, is_orig: bool, command: Redis::SetCommand) - { - print fmt("SET: %s %s", command$key, command$value); - } +event Redis::set_command(c: connection, is_orig: bool, + command: Redis::SetCommand) + { + print fmt("SET: %s %s", command$key, command$value); + } diff --git a/testing/btest/scripts/base/protocols/redis/client-reply-off-2conn.zeek b/testing/btest/scripts/base/protocols/redis/client-reply-off-2conn.zeek index 6a707fc7d7..211a9cb6ce 100644 --- a/testing/btest/scripts/base/protocols/redis/client-reply-off-2conn.zeek +++ b/testing/btest/scripts/base/protocols/redis/client-reply-off-2conn.zeek @@ -2,4 +2,3 @@ # # @TEST-EXEC: zeek -Cr $TRACES/redis/reply-off-on-2conn.trace base/protocols/redis %INPUT >output # @TEST-EXEC: btest-diff redis.log - diff --git a/testing/btest/scripts/base/protocols/redis/client-reply-off.zeek b/testing/btest/scripts/base/protocols/redis/client-reply-off.zeek index d977272279..3cda5fa9dd 100644 --- a/testing/btest/scripts/base/protocols/redis/client-reply-off.zeek +++ b/testing/btest/scripts/base/protocols/redis/client-reply-off.zeek @@ -2,4 +2,3 @@ # # @TEST-EXEC: zeek -Cr $TRACES/redis/reply-off-on.trace base/protocols/redis %INPUT >output # @TEST-EXEC: btest-diff redis.log - diff --git a/testing/btest/scripts/base/protocols/redis/client-skip-while-off.zeek b/testing/btest/scripts/base/protocols/redis/client-skip-while-off.zeek index eeed61422b..eb4678346f 100644 --- a/testing/btest/scripts/base/protocols/redis/client-skip-while-off.zeek +++ b/testing/btest/scripts/base/protocols/redis/client-skip-while-off.zeek @@ -2,4 +2,3 @@ # # @TEST-EXEC: zeek -Cr $TRACES/redis/client-skip-while-off.trace base/protocols/redis %INPUT >output # @TEST-EXEC: btest-diff redis.log - diff --git a/testing/btest/scripts/base/protocols/redis/django-cloud.zeek b/testing/btest/scripts/base/protocols/redis/django-cloud.zeek index 2aef19e4e8..b8faa8e31e 100644 --- a/testing/btest/scripts/base/protocols/redis/django-cloud.zeek +++ b/testing/btest/scripts/base/protocols/redis/django-cloud.zeek @@ -4,12 +4,12 @@ # @TEST-EXEC: btest-diff output # @TEST-EXEC: btest-diff redis.log -redef Redis::ports += { - 10625/tcp, -}; +redef Redis::ports += { 10625/tcp, }; -event Redis::set_command(c: connection, is_orig: bool, command: Redis::SetCommand) - { - # Print the whole command because these have extra data that's worth capturing. - print fmt("SET: %s %s expires in %d milliseconds", command$key, command$value, command$px); - } +event Redis::set_command(c: connection, is_orig: bool, + command: Redis::SetCommand) + { + # Print the whole command because these have extra data that's worth capturing. + print fmt("SET: %s %s expires in %d milliseconds", command$key, command$value, + command$px); + } diff --git a/testing/btest/scripts/base/protocols/redis/django.zeek b/testing/btest/scripts/base/protocols/redis/django.zeek index 0831e8e3a3..fecc1f1277 100644 --- a/testing/btest/scripts/base/protocols/redis/django.zeek +++ b/testing/btest/scripts/base/protocols/redis/django.zeek @@ -4,8 +4,10 @@ # @TEST-EXEC: btest-diff output # @TEST-EXEC: btest-diff redis.log -event Redis::set_command(c: connection, is_orig: bool, command: Redis::SetCommand) - { - # Print the whole command because these have extra data that's worth capturing. - print fmt("SET: %s %s expires in %d milliseconds", command$key, command$value, command$px); - } +event Redis::set_command(c: connection, is_orig: bool, + command: Redis::SetCommand) + { + # Print the whole command because these have extra data that's worth capturing. + print fmt("SET: %s %s expires in %d milliseconds", command$key, command$value, + command$px); + } diff --git a/testing/btest/scripts/base/protocols/redis/pipelined-with-commands.zeek b/testing/btest/scripts/base/protocols/redis/pipelined-with-commands.zeek index 23559e93b1..8c05b5a636 100644 --- a/testing/btest/scripts/base/protocols/redis/pipelined-with-commands.zeek +++ b/testing/btest/scripts/base/protocols/redis/pipelined-with-commands.zeek @@ -7,12 +7,14 @@ # Sometimes commands aren't serialized, like when pipelining. This still works! So we # should handle this. This particular example has a few commands, amongst them a SET and # a GET. -event Redis::set_command(c: connection, is_orig: bool, command: Redis::SetCommand) - { - print fmt("SET: %s %s", command$key, command$value); - } +event Redis::set_command(c: connection, is_orig: bool, + command: Redis::SetCommand) + { + print fmt("SET: %s %s", command$key, command$value); + } -event Redis::get_command(c: connection, is_orig: bool, command: Redis::GetCommand) - { - print fmt("GET: %s", command); - } +event Redis::get_command(c: connection, is_orig: bool, + command: Redis::GetCommand) + { + print fmt("GET: %s", command); + } diff --git a/testing/btest/scripts/base/protocols/redis/set.zeek b/testing/btest/scripts/base/protocols/redis/set.zeek index 7264d93760..804a740486 100644 --- a/testing/btest/scripts/base/protocols/redis/set.zeek +++ b/testing/btest/scripts/base/protocols/redis/set.zeek @@ -3,7 +3,8 @@ # @TEST-EXEC: zeek -Cr $TRACES/redis/set.trace base/protocols/redis %INPUT >output # @TEST-EXEC: btest-diff output -event Redis::set_command(c: connection, is_orig: bool, command: Redis::SetCommand) - { - print fmt("Key: %s Value: %s", command$key, command$value); - } +event Redis::set_command(c: connection, is_orig: bool, + command: Redis::SetCommand) + { + print fmt("Key: %s Value: %s", command$key, command$value); + } diff --git a/testing/btest/scripts/base/protocols/redis/standalone.spicy b/testing/btest/scripts/base/protocols/redis/standalone.spicy deleted file mode 100644 index 17bd61ed15..0000000000 --- a/testing/btest/scripts/base/protocols/redis/standalone.spicy +++ /dev/null @@ -1,11 +0,0 @@ -# @TEST-DOC: Test parsing behavior of RESP. -# -# @TEST-EXEC: spicyc ${DIST}/analyzer/resp.spicy ${DIST}/analyzer/redis.spicy -j -d -o redis.hlto -# -# TODO: A lot of tests are possible from the docs and having them would be nice. -# But, a lot of characters ($, -, etc.) cause problems with TEST_EXEC. ugh. -# @TEST-EXEC: printf "+OK\x0d\x0a" | spicy-dump -p RESP::Data redis.hlto >>output 2>&1 -# @TEST-EXEC: printf ":1000\x0d\x0a" | spicy-dump -p RESP::Data redis.hlto >>output 2>&1 -# @TEST-EXEC: printf ":-1000\x0d\x0a" | spicy-dump -p RESP::Data redis.hlto >>output 2>&1 -# @TEST-EXEC: printf ":+1000\x0d\x0a" | spicy-dump -p RESP::Data redis.hlto >>output 2>&1 -# @TEST-EXEC: TEST_DIFF_CANONIFIER= btest-diff output diff --git a/testing/btest/scripts/base/protocols/redis/trace.zeek b/testing/btest/scripts/base/protocols/redis/trace.zeek index 1daf90ce16..383602adde 100644 --- a/testing/btest/scripts/base/protocols/redis/trace.zeek +++ b/testing/btest/scripts/base/protocols/redis/trace.zeek @@ -4,12 +4,14 @@ # @TEST-EXEC: btest-diff output # @TEST-EXEC: btest-diff redis.log -event Redis::set_command(c: connection, is_orig: bool, command: Redis::SetCommand) - { - print fmt("SET: %s %s", command$key, command$value); - } +event Redis::set_command(c: connection, is_orig: bool, + command: Redis::SetCommand) + { + print fmt("SET: %s %s", command$key, command$value); + } -event Redis::get_command(c: connection, is_orig: bool, command: Redis::GetCommand) - { - print fmt("GET: %s", command); - } +event Redis::get_command(c: connection, is_orig: bool, + command: Redis::GetCommand) + { + print fmt("GET: %s", command); + }