Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/topic/robin/gh-3443-skip'
Browse files Browse the repository at this point in the history
* origin/topic/robin/gh-3443-skip:
  Spicy: Provide `zeek::skip_input()` to disable deliver to current analyzer.
  • Loading branch information
rsmmr committed Nov 9, 2023
2 parents a7e1841 + f5aa5c3 commit 2498f7d
Show file tree
Hide file tree
Showing 10 changed files with 146 additions and 3 deletions.
5 changes: 5 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
6.2.0-dev.123 | 2023-11-09 17:22:29 +0100

* GH-3443: Spicy: Provide `zeek::skip_input()` to disable deliver to
current analyzer. (Robin Sommer, Corelight)

6.2.0-dev.121 | 2023-11-09 10:42:16 +0100

* btest/opt: Update pure-inlining baseline (Arne Welzel, Corelight)
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
6.2.0-dev.121
6.2.0-dev.123
2 changes: 1 addition & 1 deletion doc
4 changes: 4 additions & 0 deletions scripts/spicy/zeek.spicy
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ public function fuid() : string &cxxname="zeek::spicy::rt::fuid";
## called from inside a protocol analyzer.
public function terminate_session() : void &cxxname="zeek::spicy::rt::terminate_session";

## Tells Zeek to skip sending any further input data to the current analyzer.
## This is supported for protocol and file analyzers.
public function skip_input() : void &cxxname="zeek::spicy::rt::skip_input";

## Signals the expected size of a file to Zeek's file analysis.
##
## size: expected size of file
Expand Down
13 changes: 13 additions & 0 deletions src/spicy/runtime-support.cc
Original file line number Diff line number Diff line change
Expand Up @@ -748,6 +748,19 @@ void rt::terminate_session() {
throw spicy::rt::ValueUnavailable("terminate_session() not available in the current context");
}

void rt::skip_input() {
auto _ = hilti::rt::profiler::start("zeek/rt/skip_input");
auto cookie = static_cast<Cookie*>(hilti::rt::context::cookie());
assert(cookie);

if ( auto p = cookie->protocol )
p->analyzer->SetSkip(true);
else if ( auto f = cookie->file )
f->analyzer->SetSkip(true);
else
throw spicy::rt::ValueUnavailable("skip() not available in the current context");
}

std::string rt::fuid() {
auto _ = hilti::rt::profiler::start("zeek/rt/fuid");
auto cookie = static_cast<Cookie*>(hilti::rt::context::cookie());
Expand Down
8 changes: 7 additions & 1 deletion src/spicy/runtime-support.h
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ void protocol_handle_close(const ProtocolHandle& handle);
* Signals the beginning of a file to Zeek's file analysis, associating it
* with the current connection.
*
* param mime_type optional mime type passed to Zeek
* @param mime_type optional mime type passed to Zeek
* @returns Zeek-side file ID of the new file
*/
std::string file_begin(const std::optional<std::string>& mime_type);
Expand All @@ -397,6 +397,12 @@ std::string fuid();
*/
void terminate_session();

/**
* Tells Zeek to skip sending any further input data to the current protocol
* or file analyzer.
*/
void skip_input();

/**
* Signals the expected size of a file to Zeek's file analysis.
*
Expand Down
4 changes: 4 additions & 0 deletions testing/btest/Baseline/spicy.skip-input-file/output
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
1, 12
2, 34
3, 56
7 changes: 7 additions & 0 deletions testing/btest/Baseline/spicy.skip-input-protocol/output
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
1, True, 28
event
2, False, 256
event
3, True, 28
event
60 changes: 60 additions & 0 deletions testing/btest/spicy/skip-input-file.zeek
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# @TEST-REQUIRES: have-spicy
#
# @TEST-EXEC: spicyz -d -o test.hlto ssh.spicy ./ssh-cond.evt
# @TEST-EXEC: zeek -r ${TRACES}/ssh/single-conn.trace test.hlto %INPUT Spicy::enable_print=T >output
# @TEST-EXEC: btest-diff output
#
# @TEST-DOC: Validate that `skip_input` works for file analyzers.

# @TEST-START-FILE ssh.spicy
module SSH;

import spicy;
import zeek;

public type Banner = unit {
magic : /SSH-/;
version : /[^-]*/;
dash : /-/;
software: /[^\r\n]*/;
};

type Context = tuple<counter: uint64>;

public type Data = unit {
%context = Context;

: (bytes &size=2)[] foreach {
self.context().counter = self.context().counter + 1;

print self.context().counter, $$;

if ( self.context().counter == 3 )
zeek::skip_input();
}
};

on Banner::%done {
local fid1 = zeek::file_begin("foo/bar");
zeek::file_data_in(b"12", fid1);
zeek::file_data_in(b"34", fid1);
zeek::file_data_in(b"56", fid1);
zeek::file_data_in(b"78", fid1);
zeek::file_data_in(b"90", fid1);
zeek::file_end(fid1);
}
# @TEST-END-FILE

# @TEST-START-FILE ssh-cond.evt

import zeek;

protocol analyzer spicy::SSH over TCP:
parse originator with SSH::Banner,
port 22/tcp,
replaces SSH;

file analyzer spicy::Text:
parse with SSH::Data,
mime-type foo/bar;
# @TEST-END-FILE
44 changes: 44 additions & 0 deletions testing/btest/spicy/skip-input-protocol.zeek
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# @TEST-REQUIRES: have-spicy
#
# @TEST-EXEC: spicyz -d -o test.hlto test.spicy test.evt
# @TEST-EXEC: zeek -b -r ${TRACES}/dns/long-connection.pcap Zeek::Spicy test.hlto %INPUT "Spicy::enable_print = T;" >output
# @TEST-EXEC: btest-diff output
#
# @TEST-DOC: Validate that `skip_input` works for protocol analyzers.

redef likely_server_ports += { 53/udp }; # avoid flipping direction after termination
redef udp_inactivity_timeout = 24hrs; # avoid long gaps to trigger removal

event Test::foo() { print "event"; }

# @TEST-START-FILE test.spicy
module Test;

import zeek;

type Counter = tuple<counter: int64>;

public type Foo = unit {
%context = Counter;

data: bytes &eod;

on %done {
self.context().counter = self.context().counter + 1;

print self.context().counter, zeek::is_orig(), |self.data|;

if ( self.context().counter == 3 )
zeek::skip_input();
}
};

# @TEST-END-FILE

# @TEST-START-FILE test.evt
protocol analyzer spicy::Test over UDP:
port 53/udp,
parse with Test::Foo;

on Test::Foo -> event Test::foo();
# @TEST-END-FILE

0 comments on commit 2498f7d

Please sign in to comment.