Merge remote-tracking branch 'origin/master' into topic/johanna/tls12-decryption

This commit is contained in:
Johanna Amann 2021-10-13 10:49:29 +01:00
commit b8b6ac744e
1531 changed files with 109968 additions and 46436 deletions

View file

@ -0,0 +1,46 @@
# @TEST-EXEC: zeek -b -C -r $TRACES/tls/google-cert-repeat.pcap common.zeek %INPUT
# @TEST-EXEC: btest-diff ssl.log
# @TEST-EXEC: btest-diff x509.log
# @TEST-EXEC: btest-diff .stdout
@TEST-START-FILE common.zeek
@load base/protocols/ssl
@load protocols/ssl/validate-certs.zeek
event x509_certificate(f: fa_file, cert_ref: opaque of x509, cert: X509::Certificate)
{
print "x509_certificate", cert$subject;
}
hook SSL::ssl_finishing(c: connection)
{
print "finishing", c$ssl$cert_chain[0]$x509$certificate$subject;
}
hook X509::x509_certificate_cache_replay(f: fa_file, e: X509::Info, sha256: string) &priority=5
{
print "Hook for", e$certificate$subject;
}
@TEST-END-FILE
# First: Plain, no changes - certificate event caching won't even engage.
# @TEST-START-NEXT
# Second - engage certificate caching.
# Log files and events are unchanged - but the replay hook engages
redef X509::caching_required_encounters = 1;
redef X509::certificate_cache_minimum_eviction_interval = 11min;
# @TEST-START-NEXT
# Third - load policy script to not raise events
# Log files are unchanged; events are not raised from the third time.
redef X509::caching_required_encounters = 1;
redef X509::certificate_cache_minimum_eviction_interval = 11min;
@load policy/files/x509/disable-certificate-events-known-certs

View file

@ -1,4 +1,4 @@
# Test that certificate caching works as expected.
# Test that certificate event caching works as expected.
# @TEST-EXEC: zeek -b -r $TRACES/tls/google-duplicate.trace %INPUT
# @TEST-EXEC: btest-diff x509.log
@ -8,6 +8,8 @@
redef X509::caching_required_encounters = 1;
redef X509::relog_known_certificates_after = 0secs;
hook X509::x509_certificate_cache_replay(f: fa_file, e: any, sha256: string) &priority=1
{
print "Encountered cached certificate not further handled by core", sha256;

View file

@ -0,0 +1,8 @@
# Test that checks that files.log is generated if the respective option is set.
# @TEST-EXEC: zeek -b -r $TRACES/tls/google-duplicate.trace %INPUT
# @TEST-EXEC: btest-diff files.log
@load base/protocols/ssl
redef X509::log_x509_in_files_log = T;

View file

@ -0,0 +1,63 @@
# Test that certificate log deduplication works in clustered mode.
#
# @TEST-PORT: BROKER_PORT1
# @TEST-PORT: BROKER_PORT2
# @TEST-PORT: BROKER_PORT3
#
# @TEST-EXEC: btest-bg-run manager-1 "cp ../cluster-layout.zeek . && CLUSTER_NODE=manager-1 zeek -b %INPUT"
# @TEST-EXEC: btest-bg-run worker-1 "cp ../cluster-layout.zeek . && CLUSTER_NODE=worker-1 zeek -b --pseudo-realtime -C -r $TRACES/tls/ecdhe.pcap %INPUT"
# @TEST-EXEC: $SCRIPTS/wait-for-file manager-1/lost 15 || (btest-bg-wait -k 1 && false)
# @TEST-EXEC: btest-bg-run worker-2 "cp ../cluster-layout.zeek . && CLUSTER_NODE=worker-2 zeek -b --pseudo-realtime -C -r $TRACES/tls/ecdhe.pcap %INPUT"
# @TEST-EXEC: btest-bg-wait 30
# @TEST-EXEC: btest-diff manager-1/x509.log
@TEST-START-FILE cluster-layout.zeek
redef Cluster::nodes = {
["manager-1"] = [$node_type=Cluster::MANAGER, $ip=127.0.0.1, $p=to_port(getenv("BROKER_PORT1"))],
["worker-1"] = [$node_type=Cluster::WORKER, $ip=127.0.0.1, $p=to_port(getenv("BROKER_PORT2")), $manager="manager-1", $interface="eth0"],
["worker-2"] = [$node_type=Cluster::WORKER, $ip=127.0.0.1, $p=to_port(getenv("BROKER_PORT3")), $manager="manager-1", $interface="eth0"],
};
@TEST-END-FILE
@load base/protocols/ssl
@load base/frameworks/cluster
@load base/frameworks/logging
redef Log::default_rotation_interval = 0secs;
redef Log::default_rotation_postprocessor_cmd = "echo";
redef exit_only_after_terminate = T;
event terminate_me() {
terminate();
}
@if ( Cluster::local_node_type() == Cluster::WORKER )
event zeek_init()
{
suspend_processing();
}
event Broker::peer_added(endpoint: Broker::EndpointInfo, msg: string)
{
continue_processing();
}
@endif
event SSL::log_ssl(i: SSL::Info)
{
print "log_line";
schedule 2secs { terminate_me() };
}
global peers_lost = 0;
event Broker::peer_lost(endpoint: Broker::EndpointInfo, msg: string)
{
++peers_lost;
system("touch lost");
if ( peers_lost == 2 )
schedule 2sec { terminate_me() };
}

View file

@ -0,0 +1,65 @@
# Test that certificate log deduplication can be disabled in clustered mode.
#
# @TEST-PORT: BROKER_PORT1
# @TEST-PORT: BROKER_PORT2
# @TEST-PORT: BROKER_PORT3
#
# @TEST-EXEC: btest-bg-run manager-1 "cp ../cluster-layout.zeek . && CLUSTER_NODE=manager-1 zeek -b %INPUT"
# @TEST-EXEC: btest-bg-run worker-1 "cp ../cluster-layout.zeek . && CLUSTER_NODE=worker-1 zeek -b --pseudo-realtime -C -r $TRACES/tls/ecdhe.pcap %INPUT"
# @TEST-EXEC: $SCRIPTS/wait-for-file manager-1/lost 15 || (btest-bg-wait -k 1 && false)
# @TEST-EXEC: btest-bg-run worker-2 "cp ../cluster-layout.zeek . && CLUSTER_NODE=worker-2 zeek -b --pseudo-realtime -C -r $TRACES/tls/ecdhe.pcap %INPUT"
# @TEST-EXEC: btest-bg-wait 30
# @TEST-EXEC: btest-diff manager-1/x509.log
@TEST-START-FILE cluster-layout.zeek
redef Cluster::nodes = {
["manager-1"] = [$node_type=Cluster::MANAGER, $ip=127.0.0.1, $p=to_port(getenv("BROKER_PORT1"))],
["worker-1"] = [$node_type=Cluster::WORKER, $ip=127.0.0.1, $p=to_port(getenv("BROKER_PORT2")), $manager="manager-1", $interface="eth0"],
["worker-2"] = [$node_type=Cluster::WORKER, $ip=127.0.0.1, $p=to_port(getenv("BROKER_PORT3")), $manager="manager-1", $interface="eth0"],
};
@TEST-END-FILE
@load base/protocols/ssl
@load base/frameworks/cluster
@load base/frameworks/logging
redef Log::default_rotation_interval = 0secs;
redef Log::default_rotation_postprocessor_cmd = "echo";
redef exit_only_after_terminate = T;
redef X509::relog_known_certificates_after = 0secs;
event terminate_me() {
terminate();
}
@if ( Cluster::local_node_type() == Cluster::WORKER )
event zeek_init()
{
suspend_processing();
}
event Broker::peer_added(endpoint: Broker::EndpointInfo, msg: string)
{
continue_processing();
}
@endif
event SSL::log_ssl(i: SSL::Info)
{
print "log_line";
schedule 2secs { terminate_me() };
}
global peers_lost = 0;
event Broker::peer_lost(endpoint: Broker::EndpointInfo, msg: string)
{
++peers_lost;
system("touch lost");
if ( peers_lost == 2 )
schedule 2sec { terminate_me() };
}

View file

@ -0,0 +1,7 @@
# Test that certificate log caching works as expected.
# The trace has duplicate certificates - they should only be output once to X509.log.
# @TEST-EXEC: zeek -b -r $TRACES/tls/google-duplicate.trace %INPUT
# @TEST-EXEC: btest-diff x509.log
@load base/protocols/ssl

View file

@ -0,0 +1,55 @@
# Test that certificate event caching works as expected.
# @TEST-EXEC: zeek -b -r $TRACES/tls/google-duplicate.trace common.zeek google-duplicate.zeek
# @TEST-EXEC: cat $TRACES/tls/tls-fragmented-handshake.pcap.gz | gunzip | zeek -b -r - common.zeek fragmented.zeek
# @TEST-EXEC: zeek -b -r $TRACES/rdp/rdp-to-ssl.pcap common.zeek rdp.zeek
# @TEST-EXEC: btest-diff .stdout
@TEST-START-FILE common.zeek
@load base/protocols/ssl
function test_it(cert_ref: opaque of x509, name: string, subject: string)
{
print subject, name, x509_check_cert_hostname(cert_ref, name);
}
@TEST-END-FILE
@TEST-START-FILE google-duplicate.zeek
event x509_certificate(f: fa_file, cert_ref: opaque of x509, cert: X509::Certificate)
{
test_it(cert_ref, "www.google.com", cert$subject);
test_it(cert_ref, "www.zeek.org", cert$subject);
test_it(cert_ref, "hello.android.com", cert$subject);
test_it(cert_ref, "g.co", cert$subject);
test_it(cert_ref, "Google Internet Authority G2", cert$subject);
}
@TEST-END-FILE
@TEST-START-FILE fragmented.zeek
event x509_certificate(f: fa_file, cert_ref: opaque of x509, cert: X509::Certificate)
{
test_it(cert_ref, "Bro", cert$subject);
test_it(cert_ref, "Broo", cert$subject);
test_it(cert_ref, "www.zeek.org", cert$subject);
test_it(cert_ref, "9566.alt.helloIamADomain.example", cert$subject);
}
@TEST-END-FILE
@TEST-START-FILE rdp.zeek
@load base/protocols/rdp
event x509_certificate(f: fa_file, cert_ref: opaque of x509, cert: X509::Certificate)
{
test_it(cert_ref, "WIN2K8R2.awakecoding.ath.cx", cert$subject);
test_it(cert_ref, "awakecoding.ath.cx", cert$subject);
test_it(cert_ref, "www.zeek.org", cert$subject);
}
@TEST-END-FILE

View file

@ -5,6 +5,10 @@
@TEST-START-FILE configfile
mycolors Red,asdf,Blue
nocolors
color_vec Green
bad_color_vec Green,1234,Blue
no_color_vec
@TEST-END-FILE
@load base/frameworks/config
@ -12,9 +16,21 @@ mycolors Red,asdf,Blue
type Color: enum { Red, Green, Blue, };
option mycolors = set(Red, Green);
option nocolors = set(Red, Green);
option color_vec: vector of Color = { Red };
option bad_color_vec: vector of Color = { Red };
option no_color_vec: vector of Color = { Red };
event zeek_init()
{ Config::read_config("../configfile"); }
event Input::end_of_data(name: string, source:string)
{ print mycolors; terminate(); }
{
print mycolors;
print nocolors;
print color_vec;
print bad_color_vec;
print no_color_vec;
terminate();
}

View file

@ -1,3 +1,8 @@
# Don't run the test for compiled scripts. To work, they need separate
# compilation of the manager and worker parts, and that also leads to
# lines (and sets) being displayed in a different order due to different
# hash function seedings (though probably -D would control for that).
# @TEST-REQUIRES: test "${ZEEK_USE_CPP}" != "1"
# @TEST-PORT: BROKER_PORT1
# @TEST-PORT: BROKER_PORT2
# @TEST-PORT: BROKER_PORT3

View file

@ -1,7 +1,7 @@
# @TEST-PORT: BROKER_PORT
#
# @TEST-EXEC: btest-bg-run controllee ZEEKPATH=$ZEEKPATH:.. zeek -b -Bbroker %INPUT frameworks/control/controllee Broker::default_port=$BROKER_PORT
# @TEST-EXEC: btest-bg-run controller ZEEKPATH=$ZEEKPATH:.. zeek -b -Bbroker %INPUT test-redef frameworks/control/controller Control::host=127.0.0.1 Control::host_port=$BROKER_PORT Control::cmd=configuration_update
# @TEST-EXEC: btest-bg-run controllee ZEEKPATH=$ZEEKPATH:.. zeek -b %INPUT frameworks/control/controllee Broker::default_port=$BROKER_PORT
# @TEST-EXEC: btest-bg-run controller ZEEKPATH=$ZEEKPATH:.. zeek -b %INPUT test-redef frameworks/control/controller Control::host=127.0.0.1 Control::host_port=$BROKER_PORT Control::cmd=configuration_update
# @TEST-EXEC: btest-bg-wait 30
# @TEST-EXEC: btest-diff controllee/.stdout

View file

@ -11,15 +11,18 @@
#separator \x09
#fields i s ss
#types int sting string
1 - TEST
2 - -
1 - -
2 - TEST
3 TEST -
4 TEST TEST
@TEST-END-FILE
@TEST-START-FILE input2.log
#separator \x09
#fields i s ss
#types int sting string
1 TEST -
2 TEST TEST
1 TEST2 -
4 TEST2 TEST2
5 - TEST2
@TEST-END-FILE
redef exit_only_after_terminate = T;
@ -32,7 +35,7 @@ type Idx: record {
type Val: record {
s: string;
ss: string;
ss: string &optional;
};
type servers_type: table[int] of Val;

View file

@ -1,14 +1,31 @@
# This test verifies the handling of unset fields in input files.
# For table indexes, columns wwith undefined fields cannot work
# and are skipped. For values, unset fields are safe for the user
# only when those fields are defined &optional, otherwise they
# too are skipped.
# @TEST-EXEC: btest-bg-run zeek zeek -b %INPUT
# @TEST-EXEC: btest-bg-wait 10
# @TEST-EXEC: btest-diff out
@TEST-START-FILE input.log
@TEST-START-FILE input1.log
#separator \x09
#path ssh
#fields b i
##types bool int
T 1
- 2
F -
@TEST-END-FILE
@TEST-START-FILE input2.log
#separator \x09
#path ssh
#fields b i j
##types bool int int
T 1 1
- 2 2
F - 3
@TEST-END-FILE
redef exit_only_after_terminate = T;
@ -19,27 +36,52 @@ redef InputAscii::empty_field = "EMPTY";
module A;
type Idx: record {
# We use two different index records just because the internal code
# paths differ slightly for these. And one used to crash. :)
type Idx1: record {
i: int;
};
type Val: record {
type Idx2: record {
i: int;
j: int;
};
type ValReq: record {
b: bool;
};
global servers: table[int] of Val = table();
type ValOpt: record {
b: bool &optional;
};
global servers1: table[int] of ValReq = table();
global servers2: table[int, int] of ValOpt = table();
# Counter to track when we're ready to report both table's contents in
# pre-defined order.
global reads_done = 0;
event zeek_init()
{
outfile = open("../out");
outfile = open("../out");
# first read in the old stuff into the table...
Input::add_table([$source="../input.log", $name="ssh", $idx=Idx, $val=Val, $destination=servers]);
Input::add_table([$source="../input1.log", $name="ssh1", $idx=Idx1, $val=ValReq, $destination=servers1]);
Input::add_table([$source="../input2.log", $name="ssh2", $idx=Idx2, $val=ValOpt, $destination=servers2]);
}
event Input::end_of_data(name: string, source:string)
{
print outfile, servers;
Input::remove("ssh");
reads_done += 1;
if ( reads_done < 2 )
return;
print outfile, servers1;
print outfile, servers2;
Input::remove("ssh1");
Input::remove("ssh2");
close(outfile);
terminate();
}

View file

@ -50,13 +50,19 @@ event zeek_init()
outfile = open("../out");
# first read in the old stuff into the table...
Input::add_table([$source="../input.log", $name="ssh", $error_ev=handle_our_errors, $idx=Idx, $val=Val, $destination=servers]);
Input::add_event([$source="../input.log", $name="sshevent", $error_ev=handle_our_errors_event, $fields=Val, $want_record=T, $ev=line]);
}
event Input::end_of_data(name: string, source:string)
{
++endcount;
# ... and when we're done, move to reading via events.
# This makes the reads sequential, avoding races in the output.
if ( endcount == 1 )
{
Input::add_event([$source="../input.log", $name="sshevent", $error_ev=handle_our_errors_event, $fields=Val, $want_record=T, $ev=line]);
}
if ( endcount == 2 )
{
print outfile, servers;

View file

@ -51,13 +51,19 @@ event zeek_init()
outfile = open("../out");
# first read in the old stuff into the table...
Input::add_table([$source="../input.log", $name="ssh", $error_ev=handle_our_errors, $idx=Idx, $val=Val, $destination=servers]);
Input::add_event([$source="../input.log", $name="sshevent", $error_ev=handle_our_errors_event, $fields=Val, $want_record=T, $ev=line]);
}
event Input::end_of_data(name: string, source:string)
{
++endcount;
# ... and when we're done, move to reading via events.
# This makes the reads sequential, avoding races in the output.
if ( endcount == 1 )
{
Input::add_event([$source="../input.log", $name="sshevent", $error_ev=handle_our_errors_event, $fields=Val, $want_record=T, $ev=line]);
}
if ( endcount == 2 )
{
print outfile, servers;

View file

@ -1,3 +1,6 @@
# This test verifies update events, predicates, and multiple data
# updates when using Input::REREAD mode.
# @TEST-EXEC: mv input1.log input.log
# @TEST-EXEC: btest-bg-run zeek zeek -b %INPUT
# @TEST-EXEC: $SCRIPTS/wait-for-file zeek/got1 15 || (btest-bg-wait -k 1 && false)
@ -9,7 +12,9 @@
# @TEST-EXEC: $SCRIPTS/wait-for-file zeek/got4 15 || (btest-bg-wait -k 1 && false)
# @TEST-EXEC: mv input5.log input.log
# @TEST-EXEC: btest-bg-wait 30
# @TEST-EXEC: btest-diff out
# @TEST-EXEC: btest-diff servers.out
# @TEST-EXEC: btest-diff events.out
# @TEST-EXEC: btest-diff preds.out
@TEST-START-FILE input1.log
#separator \x09
@ -84,47 +89,59 @@ type Val: record {
ve: vector of int;
};
global servers: table[int] of Val = table();
type servers_type: table[int] of Val;
global servers: servers_type = table();
global outfile: file;
global events_file = open("../events.out");
global predicates_file = open("../preds.out");
global servers_file = open("../servers.out");
global try: count;
event line(description: Input::TableDescription, tpe: Input::Event, left: Idx, right: Val)
{
print outfile, "============EVENT============";
print outfile, "Description";
print outfile, description;
print outfile, "Type";
print outfile, tpe;
print outfile, "Left";
print outfile, left;
print outfile, "Right";
print outfile, right;
# Printing description details here avoids printing the
# destination table itself. Its content is not deterministic
# at the time this event handler runs: it depends on how many
# entries the reader backend thread has sent over.
print events_file, "============EVENT============";
print events_file, "Description";
print events_file, " source", description$source;
print events_file, " reader", description$reader;
print events_file, " mode", description$mode;
print events_file, " name", description$name;
print events_file, fmt(" destination[left = %s]", left$i),
(description$destination as servers_type)[left$i];
print events_file, " idx", description$idx;
print events_file, " val", description$val;
print events_file, " want_record", description$want_record;
print events_file, "Type", tpe;
print events_file, "Left", left;
print events_file, "Right", right;
}
event zeek_init()
{
outfile = open("../out");
try = 0;
# first read in the old stuff into the table...
Input::add_table([$source="../input.log", $mode=Input::REREAD, $name="ssh", $idx=Idx, $val=Val, $destination=servers, $ev=line,
$pred(typ: Input::Event, left: Idx, right: Val) = {
print outfile, "============PREDICATE============";
print outfile, typ;
print outfile, left;
print outfile, right;
return T;
}
Input::add_table([$source="../input.log", $mode=Input::REREAD, $name="ssh",
$idx=Idx, $val=Val, $destination=servers, $ev=line,
$pred(typ: Input::Event, left: Idx, right: Val) = {
print predicates_file, "============PREDICATE============";
print predicates_file, typ;
print predicates_file, left;
print predicates_file, right;
return T;
}
]);
}
event Input::end_of_data(name: string, source: string)
{
print outfile, "==========SERVERS============";
print outfile, servers;
print servers_file, "==========SERVERS============";
print servers_file, servers;
try = try + 1;
if ( try == 1 )
@ -137,8 +154,10 @@ event Input::end_of_data(name: string, source: string)
system("touch got4");
else if ( try == 5 )
{
print outfile, "done";
close(outfile);
print servers_file, "done";
close(events_file);
close(predicates_file);
close(servers_file);
Input::remove("input");
terminate();
}

View file

@ -114,7 +114,7 @@ event Input::end_of_data(name: string, source: string)
{
print fin_out, "==========SERVERS============";
#print fin_out, servers;
try = try + 1;
if ( try == 2 )
system("touch got2");

View file

@ -2,6 +2,8 @@
# @TEST-EXEC: btest-diff test.log
# @TEST-EXEC: btest-diff output
redef LogAscii::enable_utf_8 = F;
module Test;
export {

View file

@ -0,0 +1,38 @@
#
# @TEST-EXEC: mkdir logdir
# @TEST-EXEC: zeek -b %INPUT LogAscii::logdir=logdir
# @TEST-EXEC: cat logdir/ssh.log | grep -v PREFIX.*20..- >ssh-filtered.log
# @TEST-EXEC: btest-diff ssh-filtered.log
redef LogAscii::output_to_stdout = F;
redef LogAscii::separator = "|";
redef LogAscii::empty_field = "EMPTY";
redef LogAscii::unset_field = "NOT-SET";
redef LogAscii::meta_prefix = "PREFIX<>";
module SSH;
export {
redef enum Log::ID += { LOG };
type Log: record {
t: time;
id: conn_id; # Will be rolled out into individual columns.
status: string &optional;
country: string &default="unknown";
b: bool &optional;
} &log;
}
event zeek_init()
{
Log::create_stream(SSH::LOG, [$columns=Log]);
local cid = [$orig_h=1.2.3.4, $orig_p=1234/tcp, $resp_h=2.3.4.5, $resp_p=80/tcp];
Log::write(SSH::LOG, [$t=network_time(), $id=cid, $status="success"]);
Log::write(SSH::LOG, [$t=network_time(), $id=cid, $country="US"]);
Log::write(SSH::LOG, [$t=network_time(), $id=cid, $status="failure", $country="UK"]);
Log::write(SSH::LOG, [$t=network_time(), $id=cid, $country="BR"]);
Log::write(SSH::LOG, [$t=network_time(), $id=cid, $b=T, $status="failure", $country=""]);
}

View file

@ -3,13 +3,14 @@
# @TEST-EXEC: zeek -b test.zeek %INPUT
# @TEST-EXEC: btest-diff test.log
# @TEST-EXEC: test -f other.log && btest-diff other.log || true
# @TEST-EXEC: test -f output && btest-diff output || true
@TEST-START-FILE test.zeek
# This provides a simple test module harness, used by all of the individual tests below.
module Test;
export {
# Create a new ID for our log stream
# Create new IDs for our log streams
redef enum Log::ID += { LOG, LOG_OTHER };
# Create a corresponding policy hook:
@ -167,3 +168,126 @@ event zeek_init()
Log::write(Test::LOG_OTHER, [$t=network_time(), $status="foo"]);
Log::write(Test::LOG_OTHER, [$t=network_time(), $status="bar"]);
}
@TEST-START-NEXT
# Verify that the global policy hook is effective. We have no
# filter-specific hook handlers, only the global one is vetoing
# some entries.
hook Log::log_stream_policy(rec: any, id: Log::ID)
{
if ( id == Test::LOG )
{
local r: Test::Info = rec;
if ( r$status == "foo" )
break;
}
}
event zeek_init()
{
Log::write(Test::LOG, [$t=network_time(), $status="foo"]);
Log::write(Test::LOG, [$t=network_time(), $status="bar"]);
}
@TEST-START-NEXT
# Verify the combination of global and filter-specific policy hooks.
# The former get invoked first.
hook Log::log_stream_policy(rec: any, id: Log::ID)
{
if ( id == Test::LOG )
{
local r: Test::Info = rec;
if ( r$status == "foo" )
break;
}
}
hook Test::log_policy(rec: Test::Info, id: Log::ID, filter: Log::Filter)
{
# Test::log_policy should have blocked this one
if ( rec$status == "foo" )
rec$status = "foobar";
# This just verifies the hook can mod entries.
# It should make it into the log.
if ( rec$status == "bar" )
rec$status = "barbaz";
}
event zeek_init()
{
Log::write(Test::LOG, [$t=network_time(), $status="foo"]);
Log::write(Test::LOG, [$t=network_time(), $status="bar"]);
}
@TEST-START-NEXT
# Verify that per write, the global hook gets invoked once and the
# filter-level hooks once per filter, that filter hooks get
# invoked even when the global hook already vetoed, and that they
# do not "un-veto".
global output = open("output");
hook Log::log_stream_policy(rec: any, id: Log::ID)
{
print output, "Log::log_stream_policy";
if ( id == Test::LOG )
{
local r: Test::Info = rec;
if ( r$status == "foo" )
break;
}
}
hook Test::log_policy(rec: Test::Info, id: Log::ID, filter: Log::Filter)
{
print output, rec$status;
}
event zeek_init()
{
local filter: Log::Filter = [$name="other"];
Log::add_filter(Test::LOG, filter);
Log::write(Test::LOG, [$t=network_time(), $status="foo"]);
Log::write(Test::LOG, [$t=network_time(), $status="bar"]);
}
@TEST-START-NEXT
# Verify the global policy works on streams with no per-filter hooks, since
# their logic is a bit intertwined.
module Test;
export {
redef enum Log::ID += { LOG2 };
}
hook Log::log_stream_policy(rec: any, id: Log::ID)
{
if ( id == Test::LOG2 )
{
local r: Test::Info = rec;
if ( r$status == "foo" )
break;
}
}
event zeek_init() &priority=2
{
Log::create_stream(Test::LOG2, [$columns=Info, $path="test"]);
Log::write(Test::LOG2, [$t=network_time(), $status="foo"]);
Log::write(Test::LOG2, [$t=network_time(), $status="bar"]);
}

View file

@ -1,5 +1,5 @@
#
# @TEST-EXEC: zeek -b -B logging %INPUT
# @TEST-EXEC: zeek -b %INPUT
# @TEST-EXEC: btest-diff ssh.log
# @TEST-EXEC: btest-diff ssh.failure.log
# @TEST-EXEC: btest-diff .stdout

View file

@ -0,0 +1,29 @@
# @TEST-EXEC: zeek -b -r ${TRACES}/rotation.trace %INPUT
# @TEST-EXEC-FAIL: test -f must-not-exist
module Test;
export {
# Create a new ID for our log stream
redef enum Log::ID += { LOG };
# Define a record with all the columns the log file can have.
# (I'm using a subset of fields from ssh-ext for demonstration.)
type Log: record {
t: time;
id: conn_id; # Will be rolled out into individual columns.
} &log;
}
redef Log::default_rotation_interval = 1hr;
redef Log::default_rotation_postprocessor_cmd = "echo";
event zeek_init()
{
Log::create_stream(Test::LOG, [$columns=Log, $path="; touch must-not-exist; true "]);
}
event new_connection(c: connection)
{
Log::write(Test::LOG, [$t=network_time(), $id=c$id]);
}

View file

@ -2,6 +2,10 @@
#
# @TEST-REQUIRES: which sqlite3
# @TEST-REQUIRES: has-writer Zeek::SQLiteWriter
# Don't run this test if we build with '--sanitizers=thread' because we
# disable the shared cache in that case due to a SQLite bug.
# @TEST-REQUIRES: grep -q "#define ZEEK_TSAN" zeek-config.h || test $? == 0
# @TEST-GROUP: sqlite
#
# @TEST-EXEC: zeek -b %INPUT
@ -87,4 +91,3 @@ event zeek_init()
Log::write(SSH::LOG, out);
Log::write(SSH::LOG2, out);
}

View file

@ -5,10 +5,11 @@
# @TEST-EXEC: btest-bg-run manager-1 "cp ../cluster-layout.zeek . && CLUSTER_NODE=manager-1 zeek -b %INPUT"
# @TEST-EXEC: btest-bg-run worker-1 "cp ../cluster-layout.zeek . && CLUSTER_NODE=worker-1 zeek -b --pseudo-realtime -C -r $TRACES/tls/ecdhe.pcap %INPUT"
# @TEST-EXEC: $SCRIPTS/wait-for-file manager-1/lost 15 || (btest-bg-wait -k 1 && false)
# @TEST-EXEC: $SCRIPTS/wait-for-file manager-1/lost 45 || (btest-bg-wait -k 1 && false)
# @TEST-EXEC: btest-bg-run worker-2 "cp ../cluster-layout.zeek . && CLUSTER_NODE=worker-2 zeek -b --pseudo-realtime -C -r $TRACES/tls/ecdhe.pcap %INPUT"
# @TEST-EXEC: btest-bg-wait 30
# This timeout needs to be large to accommodate ZAM compilation delays.
# @TEST-EXEC: btest-bg-wait 90
# @TEST-EXEC: btest-diff worker-1/.stdout
# @TEST-EXEC: btest-diff worker-2/.stdout

View file

@ -0,0 +1,28 @@
# @TEST-EXEC: zeek -b %INPUT
# @TEST-EXEC: btest-diff sendmail.out
# @TEST-EXEC: btest-diff notice.log
@load base/frameworks/notice
@load base/utils/site
redef Notice::mail_dest = "user@example.net";
redef Notice::sendmail = "fake-sendmail";
redef Site::local_admins += {
[1.0.0.0/8] = set("cloudflare@example.net", "postmaster@the.cloud"),
[2.0.0.0/8] = set("2_dot@example.net"),
};
redef enum Notice::Type += {
Test_Notice,
};
event zeek_init()
{
NOTICE([$note=Test_Notice, $msg="test", $identifier="static", $src=1.1.1.1, $dst=2.2.2.2]);
}
hook Notice::policy(n: Notice::Info) &priority=1
{
add n$actions[Notice::ACTION_EMAIL_ADMIN];
}

View file

@ -0,0 +1,29 @@
# @TEST-EXEC: zeek -b %INPUT
# @TEST-EXEC: btest-diff sendmail.out
# Tests overriding the e-mail destination for a specific notice
@load base/frameworks/notice
hook Notice::policy(n: Notice::Info) &priority=1
{
add n$actions[Notice::ACTION_EMAIL];
}
redef Notice::mail_dest = "user@example.net";
redef Notice::sendmail = "fake-sendmail";
redef enum Notice::Type += {
Test_Notice,
};
event zeek_init()
{
NOTICE([$note=Test_Notice, $msg="test", $identifier="static"]);
}
hook Notice::policy(n: Notice::Info)
{
n$email_dest = set("admin@example.net");
}

View file

@ -0,0 +1,25 @@
# @TEST-EXEC: zeek -b %INPUT
# @TEST-EXEC: btest-diff sendmail.out
# Test what happens with PAGE and EMAIL
@load base/frameworks/notice
redef Notice::mail_dest = "user@example.net";
redef Notice::mail_page_dest = "page@example.net";
redef Notice::sendmail = "fake-sendmail";
redef enum Notice::Type += {
Test_Notice,
};
event zeek_init()
{
NOTICE([$note=Test_Notice, $msg="test", $identifier="static"]);
}
hook Notice::policy(n: Notice::Info) &priority=1
{
add n$actions[Notice::ACTION_PAGE];
add n$actions[Notice::ACTION_EMAIL];
}

View file

@ -0,0 +1,21 @@
# @TEST-EXEC: zeek -b %INPUT
# @TEST-EXEC: btest-diff sendmail.out
@load base/frameworks/notice
redef Notice::mail_dest = "user@example.net";
redef Notice::sendmail = "fake-sendmail";
redef enum Notice::Type += {
Test_Notice,
};
event zeek_init()
{
NOTICE([$note=Test_Notice, $msg="test", $identifier="static"]);
}
hook Notice::policy(n: Notice::Info) &priority=1
{
add n$actions[Notice::ACTION_EMAIL];
}

View file

@ -0,0 +1,23 @@
# @TEST-EXEC: zeek -b %INPUT
# @TEST-EXEC: btest-diff sendmail.out
@load base/frameworks/notice
@load frameworks/notice/extend-email/hostnames
redef Notice::mail_dest = "user@example.net";
redef Notice::mail_page_dest = "page@example.net";
redef Notice::sendmail = "fake-sendmail";
redef enum Notice::Type += {
Test_Notice,
};
event zeek_init()
{
NOTICE([$note=Test_Notice, $msg="test", $identifier="static", $src=1.1.1.1, $dst=[::1]]);
}
hook Notice::policy(n: Notice::Info) &priority=1
{
add n$actions[Notice::ACTION_PAGE];
}

View file

@ -0,0 +1,22 @@
# @TEST-EXEC: zeek -b %INPUT
# @TEST-EXEC: btest-diff sendmail.out
@load base/frameworks/notice
redef Notice::mail_dest = "user@example.net";
redef Notice::mail_page_dest = "page@example.net";
redef Notice::sendmail = "fake-sendmail";
redef enum Notice::Type += {
Test_Notice,
};
event zeek_init()
{
NOTICE([$note=Test_Notice, $msg="test", $identifier="static"]);
}
hook Notice::policy(n: Notice::Info) &priority=1
{
add n$actions[Notice::ACTION_PAGE];
}

View file

@ -5,7 +5,8 @@
# @TEST-EXEC: btest-bg-run manager-1 ZEEKPATH=$ZEEKPATH:.. CLUSTER_NODE=manager-1 zeek -b %INPUT
# @TEST-EXEC: btest-bg-run worker-1 ZEEKPATH=$ZEEKPATH:.. CLUSTER_NODE=worker-1 zeek -b %INPUT
# @TEST-EXEC: btest-bg-run worker-2 ZEEKPATH=$ZEEKPATH:.. CLUSTER_NODE=worker-2 zeek -b %INPUT
# @TEST-EXEC: btest-bg-wait 45
# This timeout needs to be large to accommodate ZAM compilation delays.
# @TEST-EXEC: btest-bg-wait 90
# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-sort btest-diff manager-1/.stdout
@load base/frameworks/sumstats

View file

@ -0,0 +1,7 @@
# @TEST-EXEC: zeek -b -r $TRACES/dce-rpc/dce_rpc_netlogon.pcap %INPUT
# @TEST-EXEC: btest-diff weird.log
# @TEST-EXEC: btest-diff dce_rpc.log
@load base/protocols/dce-rpc
@load base/protocols/ntlm
@load base/frameworks/notice/weird

View file

@ -0,0 +1,5 @@
# @TEST-EXEC: zeek -b -r $TRACES/dce-rpc/dce_rpc_ntlm.pcap %INPUT
# @TEST-EXEC: btest-diff ntlm.log
@load base/protocols/dce-rpc
@load base/protocols/ntlm

View file

@ -0,0 +1,10 @@
# @TEST-EXEC: zeek -b -C -r $TRACES/dns/dns-binds.pcap %INPUT > output
# @TEST-EXEC: btest-diff dns.log
# @TEST-EXEC: btest-diff output
@load policy/protocols/dns/auth-addl
event dns_BINDS(c: connection, msg: dns_msg, ans: dns_answer, binds: dns_binds_rr)
{
print "BINDS", binds;
}

View file

@ -0,0 +1,9 @@
# @TEST-EXEC: zeek -b -r $TRACES/dns/hinfo.pcap %INPUT
# @TEST-EXEC: btest-diff .stdout
@load base/protocols/dns
event dns_HINFO_reply(c: connection, msg: dns_msg, ans: dns_answer, cpu: string, os: string)
{
print "HINFO", msg, ans, cpu, os;
}

View file

@ -0,0 +1,11 @@
# @TEST-EXEC: zeek -b -C -r $TRACES/dnssec/nsec3param.pcap %INPUT > output
# @TEST-EXEC: btest-diff dns.log
# @TEST-EXEC: btest-diff output
@load policy/protocols/dns/auth-addl
event dns_NSEC3PARAM(c: connection, msg: dns_msg, ans: dns_answer, nsec3param: dns_nsec3param_rr)
{
print "NSEC3PARAM", nsec3param,
bytestring_to_hexstr(nsec3param$nsec_salt);
}

View file

@ -0,0 +1,10 @@
# @TEST-EXEC: zeek -b -C -r $TRACES/dns/dns-wks.pcap %INPUT > output
# @TEST-EXEC: btest-diff dns.log
# @TEST-EXEC: btest-diff output
@load policy/protocols/dns/auth-addl
event dns_WKS_reply(c: connection, msg: dns_msg, ans: dns_answer)
{
print "WKS", dns_msg, dns_answer;
}

View file

@ -10,6 +10,8 @@ module GridFTP;
redef size_threshold = 2;
redef X509::relog_known_certificates_after = 0secs;
redef enum Notice::Type += {
Data_Channel
};

View file

@ -0,0 +1,10 @@
# This tests that the HTTP analyzer handles HTTP with no CRLF at end correctly.
# @TEST-EXEC: zeek -b -r $TRACES/http/no_crlf.pcap %INPUT
# @TEST-EXEC: btest-diff conn.log
# @TEST-EXEC: btest-diff http.log
# @TEST-EXEC: test ! -f weird.log
@load base/protocols/conn
@load base/protocols/http
@load base/frameworks/dpd

View file

@ -9,6 +9,8 @@
@load base/frameworks/dpd
@load base/protocols/imap
redef SSL::log_include_server_certificate_subject_issuer=T;
event imap_starttls(c: connection)
{
print "Tls started for connection";

View file

@ -4,3 +4,5 @@
@load base/protocols/rdp
@load base/protocols/ssl
redef SSL::log_include_server_certificate_subject_issuer=T;

View file

@ -0,0 +1,117 @@
# @TEST-EXEC: zeek -b %INPUT >output
# @TEST-EXEC: btest-diff output
@load base/bif/event.bif.zeek
@load base/protocols/ssh
module SSH;
# Creates a mock connection. This connection is good enough for e.g.,
# `SSH::set_version`, but not in line with what Zeek considers active
# connections.
function make_conn(server: string, client: string): connection
{
local c: connection;
c$uid = "uid";
local id: conn_id;
id$orig_h = 127.0.0.1;
id$resp_h = 127.0.0.1;
id$orig_p = 40/tcp;
id$resp_p = 40/tcp;
c$id = id;
local ssh: SSH::Info;
ssh$ts = network_time();
ssh$server = server;
ssh$client = client;
c$ssh = ssh;
SSH::set_session(c);
delete c$ssh$version;
return c;
}
# While `SSH::set_version` triggers a `conn_weird` we are dealing with mock
# connections which since they are injected are always considered expired by
# Zeek.
event expired_conn_weird(name: string, id: conn_id, uid: string, addl: string, source: string)
{
print "conn_weird:", name, id, addl, source;
}
const v1 = "SSH-1.5-OpenSSH_6.2";
const v199 = "SSH-1.99-OpenSSH_3.1p1";
const v2 = "SSH-2.0-OpenSSH_5.9";
event zeek_init()
{
local c: connection;
# Good cases.
{
# SSH1 vs SSH1 -> 1.
c = make_conn(v1, v1);
SSH::set_version(c);
print "SSH1 vs SSH1", c$ssh$version;
# SSH199 vs SSH1 -> 1.
c = make_conn(v1, v199);
SSH::set_version(c);
print "SSH199 vs SSH1", c$ssh$version; # 1.
# SSH2 vs SSH2 -> 2.
c = make_conn(v2, v2);
SSH::set_version(c);
print "SSH2 vs SSH2", c$ssh$version; # 2.
# SSH199 vs SSH2 -> 2.
c = make_conn(v2, v199);
SSH::set_version(c);
print "SSH199 vs SSH2", c$ssh$version; # 2.
}
# Error cases.
{
# Unset vs unset -> unset.
c = make_conn("", "");
c$ssh$version = 42;
SSH::set_version(c);
print "unset vs unset", c$ssh?$version; # Unset.
# Client unset.
c = make_conn(v2, "");
c$ssh$version = 42;
SSH::set_version(c);
print "client unset", c$ssh?$version; # Unset.
# Server unset.
c = make_conn("", v2);
c$ssh$version = 42;
SSH::set_version(c);
print "server unset", c$ssh?$version; # Unset.
# Unable to extract full server version.
c = make_conn("SSH", v1);
c$ssh$version = 42;
SSH::set_version(c);
print "incomplete server version", c$ssh?$version;
# Unable to extract full client version.
c = make_conn(v1, "SSH");
c$ssh$version = 42;
SSH::set_version(c);
print "incomplete client version", c$ssh?$version;
# SSH1 vs SSH2.
c = make_conn(v1, v2);
SSH::set_version(c);
print "SSH1 vs SSH2", c$ssh?$version; # Unset.
# SSH2 vs SSH1.
c = make_conn(v2, v1);
SSH::set_version(c);
print "SSH2 vs SSH1", c$ssh?$version; # Unset.
}
}

View file

@ -4,3 +4,4 @@
# @TEST-EXEC: btest-diff ssl.log
# @TEST-EXEC: btest-diff x509.log
# @TEST-EXEC: test ! -f dpd.log
# @TEST-EXEC: test ! -f files.log

View file

@ -6,6 +6,9 @@
@load base/protocols/ssl
@load base/frameworks/dpd
redef SSL::log_include_client_certificate_subject_issuer = T;
redef SSL::log_include_server_certificate_subject_issuer = T;
event ssl_client_hello(c: connection, version: count, record_version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec, comp_methods: index_vec)
{
print version, client_random, session_id, ciphers;

View file

@ -6,6 +6,9 @@
@load base/protocols/ssl
redef SSL::log_include_client_certificate_subject_issuer = T;
redef SSL::log_include_server_certificate_subject_issuer = T;
# Certificate has 10,000 alternative names :)
event x509_ext_subject_alternative_name(f: fa_file, ext: X509::SubjectAlternativeName)
{

View file

@ -4,8 +4,6 @@
# @TEST-EXEC: btest-diff ocsp.log
# @TEST-EXEC: btest-diff .stdout
@load files/x509/log-ocsp
event zeek_init()
{
Files::register_for_mime_type(Files::ANALYZER_OCSP_REQUEST, "application/ocsp-request");

View file

@ -3,8 +3,6 @@
# @TEST-EXEC: zeek -C -r $TRACES/tls/ocsp-request-only.pcap %INPUT
# @TEST-EXEC: btest-diff .stdout
@load files/x509/log-ocsp
event zeek_init()
{
Files::register_for_mime_type(Files::ANALYZER_OCSP_REQUEST, "application/ocsp-request");

View file

@ -4,8 +4,6 @@
# @TEST-EXEC: btest-diff ocsp.log
# @TEST-EXEC: btest-diff .stdout
@load files/x509/log-ocsp
event zeek_init()
{
Files::register_for_mime_type(Files::ANALYZER_OCSP_REQUEST, "application/ocsp-request");

View file

@ -4,8 +4,6 @@
# @TEST-EXEC: btest-diff ocsp.log
# @TEST-EXEC: btest-diff .stdout
@load files/x509/log-ocsp
event zeek_init()
{
Files::register_for_mime_type(Files::ANALYZER_OCSP_REQUEST, "application/ocsp-request");

View file

@ -4,8 +4,6 @@
# @TEST-EXEC: btest-diff ocsp.log
# @TEST-EXEC: btest-diff .stdout
@load files/x509/log-ocsp
event zeek_init()
{
Files::register_for_mime_type(Files::ANALYZER_OCSP_REQUEST, "application/ocsp-request");

View file

@ -0,0 +1,6 @@
# @TEST-EXEC: zeek -b -C -r $TRACES/tcp/timestamp.pcap %INPUT
# @TEST-EXEC: btest-diff .stdout
event connection_SYN_packet(c: connection, pkt: SYN_packet) {
print pkt;
}

View file

@ -17,7 +17,7 @@ function check_exit_condition()
{
c += 1;
if ( c == 2 )
if ( c == 3 )
terminate();
}
@ -39,4 +39,5 @@ event zeek_init()
{
test_request("test1", [$url="127.0.0.1:32123"]);
test_request("test2", [$url="127.0.0.1:32123/empty", $method="POST"]);
test_request("test3", [$url="127.0.0.1:32123", $method="POST 123"]); # will be rejected and not execute request
}

View file

@ -135,6 +135,15 @@ event zeek_init()
print "============ test extract_ip_addresses()";
print extract_ip_addresses("this is 1.1.1.1 a test 2.2.2.2 string with ip addresses 3.3.3.3");
print extract_ip_addresses("this is 1.1.1.1 a test 0:0:0:0:0:0:0:0 string with ip addresses 3.3.3.3");
print extract_ip_addresses("text 1.1.1.1 text", T);
print extract_ip_addresses("text 1.1.1.1 text", F);
print extract_ip_addresses("text1.1.1.1text", T);
print extract_ip_addresses("text1.1.1.1text", F);
print extract_ip_addresses("text[1.1.1.1]text", T);
print extract_ip_addresses("text[1.1.1.1]text", F);
print extract_ip_addresses("[1.1.1.1] [2.2.2.2]", T);
print extract_ip_addresses("1.1.1.1", T);
print extract_ip_addresses("1.1.1.1", F);
# This will use the leading 6 from "IPv6" (maybe that's not intended
# by a person trying to parse such a string, but that's just what's going