GH-1119: add base/protcols/conn/removal-hooks.zeek

This adds two new functions: `Conn::register_removal_hook()` and
`Conn::unregister_removal_hook()` for registering a hook function to be
called back during `connection_state_remove`.  The benefit of using hook
callback approach is better scalability: the overhead of unrelated
protocols having to dispatch no-op `connection_state_remove` handlers is
avoided.
This commit is contained in:
Jon Siwek 2020-09-10 21:19:14 -07:00
parent 49e2047da0
commit 05cf511f18
31 changed files with 659 additions and 386 deletions

View file

@ -3,3 +3,4 @@
@load ./inactivity
@load ./polling
@load ./thresholds
@load ./removal-hooks

View file

@ -0,0 +1,79 @@
##! Adds a framework for registering "connection removal hooks".
##! All registered hooks for a given connection get run within the
##! :zeek:see:`connection_state_remove` event for that connection.
##! This functionality is useful from a performance/scaling concern:
##! if every new protocol-analysis script uses
##! :zeek:see:`connection_state_remove` to implement its finalization/cleanup
##! logic, then all connections take the performance hit of dispatching that
##! event, even if they aren't related to that specific protocol.
module Conn;
export {
## A hook function for use with either :zeek:see:`Conn::register_removal_hook`
## or :zeek:see:`Conn::unregister_removal_hook`. The :zeek:see:`connection`
## argument refers to the connection currently being removed within a
## :zeek:see:`connection_state_remove` event.
type RemovalHook: hook(c: connection);
## Register a hook that will later be called during a connection's
## :zeek:see:`connection_state_remove` event.
##
## c: The associated connection whose :zeek:see:`connection_state_remove`
## event should trigger a callback to *hk*.
##
## hk: The hook function to use as a callback.
##
## Returns: false if the provided hook was previously registered, else true.
global register_removal_hook: function(c: connection, hk: RemovalHook): bool;
## Unregister a hook that would have been called during a connection's
## :zeek:see:`connection_state_remove` event such that it will no longer
## be called.
##
## c: The associated connection whose :zeek:see:`connection_state_remove`
## event could have triggered a callback to *hk*.
##
## hk: The hook function that would have been used as a callback.
##
## Returns: true if the provided hook was previously registered, else false.
global unregister_removal_hook: function(c: connection, hk: RemovalHook): bool;
}
redef record connection += {
removal_hooks: set[RemovalHook] &optional;
};
function register_removal_hook(c: connection, hk: RemovalHook): bool
{
if ( c?$removal_hooks )
{
if ( hk in c$removal_hooks )
return F;
add c$removal_hooks[hk];
return T;
}
c$removal_hooks = set(hk);
return T;
}
function unregister_removal_hook(c: connection, hk: RemovalHook): bool
{
if ( ! c?$removal_hooks )
return F;
if ( hk !in c$removal_hooks )
return F;
delete c$removal_hooks[hk];
return T;
}
event connection_state_remove(c: connection) &priority=-3
{
if ( c?$removal_hooks )
for ( removal_hook in c$removal_hooks )
hook removal_hook(c);
}

View file

@ -1,5 +1,6 @@
@load ./consts
@load base/frameworks/dpd
@load base/protocols/conn/removal-hooks
module DCE_RPC;
@ -46,6 +47,9 @@ export {
info: Info;
state: State;
};
## DCE_RPC finalization hook. Remaining DCE_RPC info may get logged when it's called.
global finalize_dce_rpc: Conn::RemovalHook;
}
redef DPD::ignore_violations += { Analyzer::ANALYZER_DCE_RPC };
@ -83,6 +87,8 @@ function set_state(c: connection, state_x: BackingState)
c$dce_rpc$endpoint = uuid_endpoint_map[c$dce_rpc_state$uuid];
if ( c$dce_rpc_state?$named_pipe )
c$dce_rpc$named_pipe = c$dce_rpc_state$named_pipe;
Conn::register_removal_hook(c, finalize_dce_rpc);
}
function set_session(c: connection, fid: count)
@ -209,7 +215,7 @@ event dce_rpc_response(c: connection, fid: count, ctx_id: count, opnum: count, s
}
}
event connection_state_remove(c: connection)
hook finalize_dce_rpc(c: connection)
{
if ( ! c?$dce_rpc )
return;

View file

@ -1,8 +1,9 @@
##! A very basic DNP3 analysis script that just logs requests and replies.
module DNP3;
@load ./consts
@load base/protocols/conn/removal-hooks
module DNP3;
export {
redef enum Log::ID += { LOG };
@ -25,6 +26,9 @@ export {
## Event that can be handled to access the DNP3 record as it is sent on
## to the logging framework.
global log_dnp3: event(rec: Info);
## DNP3 finalization hook. Remaining DNP3 info may get logged when it's called.
global finalize_dnp3: Conn::RemovalHook;
}
redef record connection += {
@ -43,7 +47,10 @@ event zeek_init() &priority=5
event dnp3_application_request_header(c: connection, is_orig: bool, application_control: count, fc: count)
{
if ( ! c?$dnp3 )
{
c$dnp3 = [$ts=network_time(), $uid=c$uid, $id=c$id];
Conn::register_removal_hook(c, finalize_dnp3);
}
c$dnp3$ts = network_time();
c$dnp3$fc_request = function_codes[fc];
@ -52,7 +59,10 @@ event dnp3_application_request_header(c: connection, is_orig: bool, application_
event dnp3_application_response_header(c: connection, is_orig: bool, application_control: count, fc: count, iin: count)
{
if ( ! c?$dnp3 )
{
c$dnp3 = [$ts=network_time(), $uid=c$uid, $id=c$id];
Conn::register_removal_hook(c, finalize_dnp3);
}
c$dnp3$ts = network_time();
c$dnp3$fc_reply = function_codes[fc];
@ -63,7 +73,7 @@ event dnp3_application_response_header(c: connection, is_orig: bool, application
delete c$dnp3;
}
event connection_state_remove(c: connection) &priority=-5
hook finalize_dnp3(c: connection)
{
if ( ! c?$dnp3 )
return;

View file

@ -3,6 +3,7 @@
@load base/utils/queue
@load ./consts
@load base/protocols/conn/removal-hooks
module DNS;
@ -143,6 +144,9 @@ export {
## replies that haven't been matched with a query yet.
pending_replies: PendingMessages &optional;
};
## DNS finalization hook. Remaining DNS info may get logged when it's called.
global finalize_dns: Conn::RemovalHook;
}
@ -233,6 +237,7 @@ hook set_session(c: connection, msg: dns_msg, is_query: bool) &priority=5
{
local state: State;
c$dns_state = state;
Conn::register_removal_hook(c, finalize_dns);
}
if ( is_query )
@ -582,7 +587,7 @@ event dns_rejected(c: connection, msg: dns_msg, query: string, qtype: count, qcl
c$dns$rejected = T;
}
event connection_state_remove(c: connection) &priority=-5
hook finalize_dns(c: connection)
{
if ( ! c?$dns_state )
return;

View file

@ -10,6 +10,7 @@
@load base/utils/numbers
@load base/utils/addrs
@load base/frameworks/cluster
@load base/protocols/conn/removal-hooks
module FTP;
@ -40,6 +41,13 @@ export {
## Event that can be handled to access the :zeek:type:`FTP::Info`
## record as it is sent on to the logging framework.
global log_ftp: event(rec: Info);
## FTP finalization hook. Remaining FTP info may get logged when it's called.
global finalize_ftp: Conn::RemovalHook;
## FTP data finalization hook. Expected FTP data channel state may
## get purged when called.
global finalize_ftp_data: hook(c: connection);
}
# Add the state tracking information variable to the connection record
@ -127,6 +135,7 @@ function set_ftp_session(c: connection)
s$uid=c$uid;
s$id=c$id;
c$ftp=s;
Conn::register_removal_hook(c, finalize_ftp);
# Add a shim command so the server can respond with some init response.
add_pending_cmd(c$ftp$pending_commands, "<init>", "");
@ -317,7 +326,10 @@ event scheduled_analyzer_applied(c: connection, a: Analyzer::Tag) &priority=10
{
local id = c$id;
if ( [id$resp_h, id$resp_p] in ftp_data_expected )
{
add c$service["ftp-data"];
Conn::register_removal_hook(c, finalize_ftp_data);
}
}
event file_transferred(c: connection, prefix: string, descr: string,
@ -337,7 +349,7 @@ event connection_reused(c: connection) &priority=5
c$ftp_data_reuse = T;
}
event connection_state_remove(c: connection) &priority=-5
hook finalize_ftp_data(c: connection)
{
if ( c$ftp_data_reuse ) return;
if ( [c$id$resp_h, c$id$resp_p] in ftp_data_expected )
@ -349,8 +361,8 @@ event connection_state_remove(c: connection) &priority=-5
}
}
# Use remove event to cover connections terminated by RST.
event connection_state_remove(c: connection) &priority=-5
# Covers connections terminated by RST.
hook finalize_ftp(c: connection)
{
if ( ! c?$ftp ) return;

View file

@ -5,6 +5,7 @@
@load base/utils/numbers
@load base/utils/files
@load base/frameworks/tunnels
@load base/protocols/conn/removal-hooks
module HTTP;
@ -124,6 +125,9 @@ export {
## Event that can be handled to access the HTTP record as it is sent on
## to the logging framework.
global log_http: event(rec: Info);
## HTTP finalization hook. Remaining HTTP info may get logged when it's called.
global finalize_http: Conn::RemovalHook;
}
# Add the http state tracking fields to the connection record.
@ -166,6 +170,7 @@ function set_state(c: connection, is_orig: bool)
{
local s: State;
c$http_state = s;
Conn::register_removal_hook(c, finalize_http);
}
# These deal with new requests and responses.
@ -192,6 +197,7 @@ event http_request(c: connection, method: string, original_URI: string,
{
local s: State;
c$http_state = s;
Conn::register_removal_hook(c, finalize_http);
}
++c$http_state$current_request;
@ -210,6 +216,7 @@ event http_reply(c: connection, version: string, code: count, reason: string) &p
{
local s: State;
c$http_state = s;
Conn::register_removal_hook(c, finalize_http);
}
# If the last response was an informational 1xx, we're still expecting
@ -321,7 +328,7 @@ event http_message_done(c: connection, is_orig: bool, stat: http_message_stat) &
}
}
event connection_state_remove(c: connection) &priority=-5
hook finalize_http(c: connection)
{
# Flush all pending but incomplete request/response pairs.
if ( c?$http_state )

View file

@ -12,6 +12,7 @@
@load ./main
@load base/utils/files
@load base/frameworks/cluster
@load base/protocols/conn/removal-hooks
module IRC;
@ -24,6 +25,10 @@ export {
## Sniffed mime type of the file.
dcc_mime_type: string &log &optional;
};
## IRC DCC data finalization hook. Remaining expected IRC DCC state may be
## purged when it's called.
global finalize_irc_data: Conn::RemovalHook;
}
global dcc_expected_transfers: table[addr, port] of Info &read_expire=5mins;
@ -121,10 +126,13 @@ event scheduled_analyzer_applied(c: connection, a: Analyzer::Tag) &priority=10
{
local id = c$id;
if ( [id$resp_h, id$resp_p] in dcc_expected_transfers )
{
add c$service["irc-dcc-data"];
Conn::register_removal_hook(c, finalize_irc_data);
}
}
event connection_state_remove(c: connection) &priority=-5
hook finalize_irc_data(c: connection)
{
if ( [c$id$resp_h, c$id$resp_p] in dcc_expected_transfers )
{

View file

@ -118,7 +118,7 @@ event krb_tgs_response(c: connection, msg: KDC_Response)
fill_in_subjects(c);
}
event connection_state_remove(c: connection)
hook finalize_krb(c: connection) &priority=+5
{
fill_in_subjects(c);
}

View file

@ -1,9 +1,10 @@
##! Implements base functionality for KRB analysis. Generates the kerberos.log
##! file.
module KRB;
@load ./consts
@load base/protocols/conn/removal-hooks
module KRB;
export {
redef enum Log::ID += { LOG };
@ -63,6 +64,9 @@ export {
## Event that can be handled to access the KRB record as it is sent on
## to the logging framework.
global log_krb: event(rec: Info);
## Kerberos finalization hook. Remaining Kerberos info may get logged when it's called.
global finalize_krb: Conn::RemovalHook;
}
redef record connection += {
@ -87,6 +91,7 @@ function set_session(c: connection): bool
c$krb = Info($ts = network_time(),
$uid = c$uid,
$id = c$id);
Conn::register_removal_hook(c, finalize_krb);
}
return c$krb$logged;
@ -228,7 +233,7 @@ event krb_tgs_response(c: connection, msg: KDC_Response) &priority=-5
do_log(c);
}
event connection_state_remove(c: connection) &priority=-5
hook finalize_krb(c: connection)
{
do_log(c);
}

View file

@ -1,8 +1,9 @@
##! Implements base functionality for MySQL analysis. Generates the mysql.log file.
module MySQL;
@load ./consts
@load base/protocols/conn/removal-hooks
module MySQL;
export {
redef enum Log::ID += { mysql::LOG };
@ -29,6 +30,9 @@ export {
## Event that can be handled to access the MySQL record as it is sent on
## to the logging framework.
global log_mysql: event(rec: Info);
## MySQL finalization hook. Remaining MySQL info may get logged when it's called.
global finalize_mysql: Conn::RemovalHook;
}
redef record connection += {
@ -54,6 +58,7 @@ event mysql_handshake(c: connection, username: string)
info$cmd = "login";
info$arg = username;
c$mysql = info;
Conn::register_removal_hook(c, finalize_mysql);
}
}
@ -74,6 +79,7 @@ event mysql_command_request(c: connection, command: count, arg: string) &priorit
info$cmd = commands[command];
info$arg = sub(arg, /\0$/, "");
c$mysql = info;
Conn::register_removal_hook(c, finalize_mysql);
}
event mysql_command_request(c: connection, command: count, arg: string) &priority=-5
@ -122,7 +128,7 @@ event mysql_ok(c: connection, affected_rows: count) &priority=-5
}
}
event connection_state_remove(c: connection) &priority=-5
hook finalize_mysql(c: connection)
{
if ( c?$mysql )
{

View file

@ -1,4 +1,5 @@
@load base/frameworks/dpd
@load base/protocols/conn/removal-hooks
module NTLM;
@ -34,6 +35,9 @@ export {
## has already been logged.
done: bool &default=F;
};
## NTLM finalization hook. Remaining NTLM info may get logged when it's called.
global finalize_ntlm: Conn::RemovalHook;
}
redef DPD::ignore_violations += { Analyzer::ANALYZER_NTLM };
@ -50,7 +54,10 @@ event zeek_init() &priority=5
function set_session(c: connection)
{
if ( ! c?$ntlm )
{
c$ntlm = NTLM::Info($ts=network_time(), $uid=c$uid, $id=c$id);
Conn::register_removal_hook(c, finalize_ntlm);
}
}
event ntlm_negotiate(c: connection, request: NTLM::Negotiate) &priority=5
@ -106,7 +113,7 @@ event gssapi_neg_result(c: connection, state: count) &priority=-3
}
}
event connection_state_remove(c: connection) &priority=-5
hook finalize_ntlm(c: connection)
{
if ( c?$ntlm && ! c$ntlm$done )
{

View file

@ -1,9 +1,10 @@
##! Implements base functionality for RADIUS analysis. Generates the radius.log file.
module RADIUS;
@load ./consts
@load base/utils/addrs
@load base/protocols/conn/removal-hooks
module RADIUS;
export {
redef enum Log::ID += { LOG };
@ -48,6 +49,9 @@ export {
## Event that can be handled to access the RADIUS record as it is sent on
## to the logging framework.
global log_radius: event(rec: Info);
## RADIUS finalization hook. Remaining RADIUS info may get logged when it's called.
global finalize_radius: Conn::RemovalHook;
}
redef record connection += {
@ -70,6 +74,7 @@ event radius_message(c: connection, result: RADIUS::Message) &priority=5
c$radius = Info($ts = network_time(),
$uid = c$uid,
$id = c$id);
Conn::register_removal_hook(c, finalize_radius);
}
switch ( RADIUS::msg_types[result$code] )
@ -138,7 +143,7 @@ event radius_message(c: connection, result: RADIUS::Message) &priority=-5
}
}
event connection_state_remove(c: connection) &priority=-5
hook finalize_radius(c: connection)
{
if ( c?$radius && ! c$radius$logged )
{

View file

@ -1,6 +1,7 @@
##! Implements base functionality for RDP analysis. Generates the rdp.log file.
@load ./consts
@load base/protocols/conn/removal-hooks
module RDP;
@ -69,6 +70,9 @@ export {
## Event that can be handled to access the rdp record as it is sent on
## to the logging framework.
global log_rdp: event(rec: Info);
## RDP finalization hook. Remaining RDP info may get logged when it's called.
global finalize_rdp: Conn::RemovalHook;
}
# Internal fields that aren't useful externally
@ -149,6 +153,7 @@ function set_session(c: connection)
if ( ! c?$rdp )
{
c$rdp = [$ts=network_time(),$id=c$id,$uid=c$uid];
Conn::register_removal_hook(c, finalize_rdp);
# The RDP session is scheduled to be logged from
# the time it is first initiated.
schedule rdp_check_interval { check_record(c) };
@ -274,7 +279,7 @@ event protocol_violation(c: connection, atype: Analyzer::Tag, aid: count, reason
write_log(c);
}
event connection_state_remove(c: connection) &priority=-5
hook finalize_rdp(c: connection)
{
# If the connection is removed, then log the record immediately.
if ( c?$rdp )

View file

@ -1,3 +1,5 @@
@load base/protocols/conn/removal-hooks
module RFB;
export {
@ -41,6 +43,9 @@ export {
};
global log_rfb: event(rec: Info);
## RFB finalization hook. Remaining RFB info may get logged when it's called.
global finalize_rfb: Conn::RemovalHook;
}
function friendly_auth_name(auth: count): string
@ -103,6 +108,7 @@ function set_session(c: connection)
info$id = c$id;
c$rfb = info;
Conn::register_removal_hook(c, finalize_rfb);
}
}
@ -151,7 +157,7 @@ event rfb_share_flag(c: connection, flag: bool) &priority=5
c$rfb$share_flag = flag;
}
event connection_state_remove(c: connection) &priority=-5
hook finalize_rfb(c: connection)
{
if ( c?$rfb )
{

View file

@ -4,6 +4,7 @@
@load base/utils/numbers
@load base/utils/files
@load base/protocols/conn/removal-hooks
module SIP;
@ -87,6 +88,9 @@ export {
## Event that can be handled to access the SIP record as it is sent on
## to the logging framework.
global log_sip: event(rec: Info);
## SIP finalization hook. Remaining SIP info may get logged when it's called.
global finalize_sip: Conn::RemovalHook;
}
# Add the sip state tracking fields to the connection record.
@ -126,6 +130,7 @@ function set_state(c: connection, is_request: bool)
{
local s: State;
c$sip_state = s;
Conn::register_removal_hook(c, finalize_sip);
}
if ( is_request )
@ -189,6 +194,7 @@ event sip_header(c: connection, is_request: bool, name: string, value: string) &
{
local s: State;
c$sip_state = s;
Conn::register_removal_hook(c, finalize_sip);
}
if ( is_request ) # from client
@ -289,7 +295,7 @@ event sip_end_entity(c: connection, is_request: bool) &priority = -5
}
}
event connection_state_remove(c: connection) &priority=-5
hook finalize_sip(c: connection)
{
if ( c?$sip_state )
{

View file

@ -1,6 +1,7 @@
@load base/utils/addrs
@load base/utils/directions-and-hosts
@load base/utils/email
@load base/protocols/conn/removal-hooks
module SMTP;
@ -82,6 +83,9 @@ export {
global describe: function(rec: Info): string;
global log_smtp: event(rec: Info);
## SMTP finalization hook. Remaining SMTP info may get logged when it's called.
global finalize_smtp: Conn::RemovalHook;
}
redef record connection += {
@ -129,6 +133,7 @@ function new_smtp_log(c: connection): Info
# The lower values in the vector are the end of the path.
l$path = vector(c$id$resp_h, c$id$orig_h);
Conn::register_removal_hook(c, finalize_smtp);
return l;
}
@ -298,7 +303,7 @@ event mime_one_header(c: connection, h: mime_header_rec) &priority=3
c$smtp$path += ip;
}
event connection_state_remove(c: connection) &priority=-5
hook finalize_smtp(c: connection)
{
if ( c?$smtp )
smtp_message(c);

View file

@ -1,5 +1,7 @@
##! Enables analysis and logging of SNMP datagrams.
@load base/protocols/conn/removal-hooks
module SNMP;
export {
@ -54,6 +56,9 @@ export {
## Event that can be handled to access the SNMP record as it is sent on
## to the logging framework.
global log_snmp: event(rec: Info);
## SNMP finalization hook. Remaining SNMP info may get logged when it's called.
global finalize_snmp: Conn::RemovalHook;
}
redef record connection += {
@ -76,6 +81,7 @@ function init_state(c: connection, h: SNMP::Header): Info
c$snmp = Info($ts=network_time(),
$uid=c$uid, $id=c$id,
$version=version_map[h$version]);
Conn::register_removal_hook(c, finalize_snmp);
}
local s = c$snmp;
@ -92,8 +98,7 @@ function init_state(c: connection, h: SNMP::Header): Info
return s;
}
event connection_state_remove(c: connection) &priority=-5
hook finalize_snmp(c: connection)
{
if ( c?$snmp )
Log::write(LOG, c$snmp);

View file

@ -1,5 +1,6 @@
@load base/frameworks/tunnels
@load ./consts
@load base/protocols/conn/removal-hooks
module SOCKS;
@ -42,6 +43,9 @@ export {
## Event that can be handled to access the SOCKS
## record as it is sent on to the logging framework.
global log_socks: event(rec: Info);
## SOCKS finalization hook. Remaining SOCKS info may get logged when it's called.
global finalize_socks: Conn::RemovalHook;
}
const ports = { 1080/tcp };
@ -60,7 +64,10 @@ redef record connection += {
function set_session(c: connection, version: count)
{
if ( ! c?$socks )
{
c$socks = [$ts=network_time(), $id=c$id, $uid=c$uid, $version=version];
Conn::register_removal_hook(c, finalize_socks);
}
}
event socks_request(c: connection, version: count, request_type: count,
@ -111,7 +118,7 @@ event socks_login_userpass_reply(c: connection, code: count) &priority=5
c$socks$status = v5_status[code];
}
event connection_state_remove(c: connection)
hook finalize_socks(c: connection)
{
# This will handle the case where the analyzer failed in some way and was
# removed. We probably don't want to log these connections.

View file

@ -1,6 +1,7 @@
##! Implements base functionality for SSH analysis. Generates the ssh.log file.
@load base/utils/directions-and-hosts
@load base/protocols/conn/removal-hooks
module SSH;
@ -60,6 +61,9 @@ export {
## Event that can be handled to access the SSH record as it is sent on
## to the logging framework.
global log_ssh: event(rec: Info);
## SSH finalization hook. Remaining SSH info may get logged when it's called.
global finalize_ssh: Conn::RemovalHook;
}
module GLOBAL;
@ -155,6 +159,7 @@ function set_session(c: connection)
if ( Site::is_local_addr(c$id$orig_h) != Site::is_local_addr(c$id$resp_h) )
info$direction = Site::is_local_addr(c$id$orig_h) ? OUTBOUND: INBOUND;
c$ssh = info;
Conn::register_removal_hook(c, finalize_ssh);
}
}
@ -247,26 +252,29 @@ event ssh_capabilities(c: connection, cookie: string, capabilities: Capabilities
server_caps$server_host_key_algorithms);
}
event connection_state_remove(c: connection)
hook finalize_ssh(c: connection)
{
if ( c?$ssh && !c$ssh$logged )
{
# Do we have enough information to make a determination about auth success?
if ( c$ssh?$client && c$ssh?$server && c$ssh?$auth_success )
{
# Successes get logged immediately. To protect against a race condition, we'll double check:
if ( c$ssh$auth_success )
return;
if ( ! c?$ssh )
return;
# Now that we know it's a failure, we'll raise the event.
event ssh_auth_failed(c);
}
# If not, we'll just log what we have
else
{
c$ssh$logged = T;
Log::write(SSH::LOG, c$ssh);
}
if ( c$ssh$logged )
return;
# Do we have enough information to make a determination about auth success?
if ( c$ssh?$client && c$ssh?$server && c$ssh?$auth_success )
{
# Successes get logged immediately. To protect against a race condition, we'll double check:
if ( c$ssh$auth_success )
return;
# Now that we know it's a failure, we'll raise the event.
event ssh_auth_failed(c);
}
# If not, we'll just log what we have
else
{
c$ssh$logged = T;
Log::write(SSH::LOG, c$ssh);
}
}

View file

@ -3,6 +3,7 @@
@load base/frameworks/notice/weird
@load ./consts
@load base/protocols/conn/removal-hooks
module SSL;
@ -113,6 +114,13 @@ export {
# Hook that can be used to perform actions right before the log record
# is written.
global ssl_finishing: hook(c: connection);
## SSL finalization hook. Remaining SSL info may get logged when it's called.
## The :zeek:see:`SSL::ssl_finishing` hook may either
## be called before this finalization hook for established SSL connections
## or during this finalization hook for SSL connections may have info still
## left to log.
global finalize_ssl: Conn::RemovalHook;
}
redef record connection += {
@ -147,7 +155,10 @@ event zeek_init() &priority=5
function set_session(c: connection)
{
if ( ! c?$ssl )
{
c$ssl = [$ts=network_time(), $uid=c$uid, $id=c$id];
Conn::register_removal_hook(c, finalize_ssl);
}
}
function delay_log(info: Info, token: string)
@ -329,17 +340,16 @@ event ssl_established(c: connection) &priority=-5
finish(c, T);
}
event connection_state_remove(c: connection) &priority=20
hook finalize_ssl(c: connection)
{
if ( c?$ssl && ! c$ssl$logged )
hook ssl_finishing(c);
}
if ( ! c?$ssl )
return;
event connection_state_remove(c: connection) &priority=-5
{
if ( c?$ssl )
# called in case a SSL connection that has not been established terminates
finish(c, F);
if ( ! c$ssl$logged )
hook ssl_finishing(c);
# called in case a SSL connection that has not been established terminates
finish(c, F);
}
event protocol_confirmation(c: connection, atype: Analyzer::Tag, aid: count) &priority=5