mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
More script updates.
* Removed terminate-connection.bro as a dependency on notice-actions-filters.bro * geo_location type now has full set of defaults. * Many conn.bro logged variables are now optional instead of having defaults. * Many updates to the notice.bro script. Probably many more to come. Mostly involved with modernizing it by extracting functionality, reducing chained dependencies, and modularization. * Updated used Notice API in ssh.bro to the modified notice.bro script.
This commit is contained in:
parent
523b078f0e
commit
d19da7a60a
5 changed files with 205 additions and 331 deletions
|
@ -7,6 +7,18 @@
|
||||||
# it because it in turn loads us.
|
# it because it in turn loads us.
|
||||||
global full_id_string: function(c: connection): string;
|
global full_id_string: function(c: connection): string;
|
||||||
|
|
||||||
|
# TODO: this is a notice action filter but it shouldn't cause this
|
||||||
|
# script to be come a dependency on notice-action-filters.bro
|
||||||
|
# Figure out where to put this!
|
||||||
|
function drop_source_and_terminate(n: Notice::Info, a: Notice::Action): Notice::Action
|
||||||
|
{
|
||||||
|
if ( n?$conn )
|
||||||
|
TerminateConnection::terminate_connection(n$conn);
|
||||||
|
|
||||||
|
return NOTICE_DROP;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
module TerminateConnection;
|
module TerminateConnection;
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|
|
@ -258,11 +258,11 @@ type pcap_packet: record {
|
||||||
|
|
||||||
# GeoIP support.
|
# GeoIP support.
|
||||||
type geo_location: record {
|
type geo_location: record {
|
||||||
country_code: string;
|
country_code: string &default="";
|
||||||
region: string;
|
region: string &default="";
|
||||||
city: string;
|
city: string &default="";
|
||||||
latitude: double;
|
latitude: double &default=0.0;
|
||||||
longitude: double;
|
longitude: double &default=0.0;
|
||||||
};
|
};
|
||||||
|
|
||||||
type entropy_test_result: record {
|
type entropy_test_result: record {
|
||||||
|
|
|
@ -11,14 +11,14 @@ export {
|
||||||
resp_h: addr;
|
resp_h: addr;
|
||||||
resp_p: count;
|
resp_p: count;
|
||||||
proto: transport_proto;
|
proto: transport_proto;
|
||||||
service: string &default="other";
|
service: string &optional;
|
||||||
duration: interval &default=0secs;
|
duration: interval &optional;
|
||||||
orig_bytes: count &default=0;
|
orig_bytes: count &optional;
|
||||||
resp_bytes: count &default=0;
|
resp_bytes: count &optional;
|
||||||
conn_state: string &default="";
|
conn_state: string &default="";
|
||||||
local_orig: bool &default=F;
|
local_orig: bool &optional;
|
||||||
addl: string &default="";
|
addl: string &optional;
|
||||||
history: string &default="";
|
history: string &optional;
|
||||||
};
|
};
|
||||||
|
|
||||||
# Only log connections appear successful.
|
# Only log connections appear successful.
|
||||||
|
@ -140,7 +140,7 @@ event connection_established(c: connection) &priority = 10
|
||||||
active_conns[c$id] = get_conn_log(c);
|
active_conns[c$id] = get_conn_log(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
event connection_state_remove(c: connection) &priority = 10
|
event connection_state_remove(c: connection) &priority = -10
|
||||||
{
|
{
|
||||||
local conn_log = get_conn_log(c);
|
local conn_log = get_conn_log(c);
|
||||||
Log::write("CONN", conn_log);
|
Log::write("CONN", conn_log);
|
||||||
|
|
|
@ -1,27 +1,24 @@
|
||||||
# $Id:$
|
|
||||||
#
|
|
||||||
# A few predefined notice_action_filters (see notice.bro).
|
# A few predefined notice_action_filters (see notice.bro).
|
||||||
|
|
||||||
@load notice
|
|
||||||
@load site
|
@load site
|
||||||
@load terminate-connection
|
@load notice
|
||||||
|
|
||||||
function ignore_notice(n: notice_info, a: NoticeAction): NoticeAction
|
function ignore_notice(n: Notice::Info, a: Notice::Action): Notice::Action
|
||||||
{
|
{
|
||||||
return NOTICE_IGNORE;
|
return NOTICE_IGNORE;
|
||||||
}
|
}
|
||||||
|
|
||||||
function file_notice(n: notice_info, a: NoticeAction): NoticeAction
|
function file_notice(n: Notice::Info, a: Notice::Action): Notice::Action
|
||||||
{
|
{
|
||||||
return NOTICE_FILE;
|
return NOTICE_FILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
function send_email_notice(n: notice_info, a: NoticeAction): NoticeAction
|
function send_email_notice(n: Notice::Info, a: Notice::Action): Notice::Action
|
||||||
{
|
{
|
||||||
return NOTICE_EMAIL;
|
return NOTICE_EMAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
function send_page_notice(n: notice_info, a: NoticeAction): NoticeAction
|
function send_page_notice(n: Notice::Info, a: Notice::Action): Notice::Action
|
||||||
{
|
{
|
||||||
return NOTICE_PAGE;
|
return NOTICE_PAGE;
|
||||||
}
|
}
|
||||||
|
@ -33,28 +30,28 @@ function tally_notice(s: string)
|
||||||
++notice_tallies[s];
|
++notice_tallies[s];
|
||||||
}
|
}
|
||||||
|
|
||||||
function tally_notice_type(n: notice_info, a: NoticeAction): NoticeAction
|
function tally_notice_type(n: Notice::Info, a: Notice::Action): Notice::Action
|
||||||
{
|
{
|
||||||
tally_notice(fmt("%s", n$note));
|
tally_notice(fmt("%s", n$note));
|
||||||
return NOTICE_FILE;
|
return NOTICE_FILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
function tally_notice_type_and_ignore(n: notice_info, a: NoticeAction)
|
function tally_notice_type_and_ignore(n: Notice::Info, a: Notice::Action)
|
||||||
: NoticeAction
|
: Notice::Action
|
||||||
{
|
{
|
||||||
tally_notice(fmt("%s", n$note));
|
tally_notice(fmt("%s", n$note));
|
||||||
return NOTICE_IGNORE;
|
return NOTICE_IGNORE;
|
||||||
}
|
}
|
||||||
|
|
||||||
function file_local_bro_notices(n: notice_info, a: NoticeAction): NoticeAction
|
function file_local_bro_notices(n: Notice::Info, a: Notice::Action): Notice::Action
|
||||||
{
|
{
|
||||||
if ( n$src_peer$is_local )
|
#if ( n$src_peer$is_local )
|
||||||
return NOTICE_FILE;
|
# return NOTICE_FILE;
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
function file_if_remote(n: notice_info, a: NoticeAction): NoticeAction
|
function file_if_remote(n: Notice::Info, a: Notice::Action): Notice::Action
|
||||||
{
|
{
|
||||||
if ( n?$src && ! is_local_addr(n$src) )
|
if ( n?$src && ! is_local_addr(n$src) )
|
||||||
return NOTICE_FILE;
|
return NOTICE_FILE;
|
||||||
|
@ -62,18 +59,11 @@ function file_if_remote(n: notice_info, a: NoticeAction): NoticeAction
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
function drop_source(n: notice_info, a: NoticeAction): NoticeAction
|
function drop_source(n: Notice::Info, a: Notice::Action): Notice::Action
|
||||||
{
|
{
|
||||||
return NOTICE_DROP;
|
return NOTICE_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
function drop_source_and_terminate(n: notice_info, a: NoticeAction): NoticeAction
|
|
||||||
{
|
|
||||||
if ( n?$conn )
|
|
||||||
TerminateConnection::terminate_connection(n$conn);
|
|
||||||
|
|
||||||
return NOTICE_DROP;
|
|
||||||
}
|
|
||||||
|
|
||||||
event bro_done()
|
event bro_done()
|
||||||
{
|
{
|
||||||
|
@ -90,32 +80,32 @@ event bro_done()
|
||||||
# Reports a specific NoticeType the first time we see it for a source. From
|
# Reports a specific NoticeType the first time we see it for a source. From
|
||||||
# then on, we tally instances per source.
|
# then on, we tally instances per source.
|
||||||
|
|
||||||
global notice_once_per_orig: table[Notice, addr] of count
|
#global notice_once_per_orig: table[Notice::Info, addr] of count
|
||||||
&default=0 &read_expire=5hrs;
|
# &default=0 &read_expire=5hrs;
|
||||||
global notice_once_per_orig_tally_interval = 1 hr &redef;
|
global notice_once_per_orig_tally_interval = 1 hr &redef;
|
||||||
|
|
||||||
event notice_alarm_per_orig_tally(n: notice_info, host: addr)
|
event notice_alarm_per_orig_tally(n: Notice::Info, host: addr)
|
||||||
{
|
{
|
||||||
local i = notice_once_per_orig[n$note, host];
|
#local i = notice_once_per_orig[n$note, host];
|
||||||
if ( i > 1 )
|
#if ( i > 1 )
|
||||||
{
|
# {
|
||||||
local msg = fmt("%s seen %d time%s from %s",
|
# local msg = fmt("%s seen %d time%s from %s",
|
||||||
n$note, i, i > 1 ? "s" : "", host);
|
# n$note, i, i > 1 ? "s" : "", host);
|
||||||
NOTICE([$note=NoticeTally, $msg=msg, $src=host, $n=i]);
|
# NOTICE([$note=NoticeTally, $msg=msg, $src=host, $n=i]);
|
||||||
}
|
# }
|
||||||
}
|
}
|
||||||
|
|
||||||
function notice_alarm_per_orig(n: notice_info, a: NoticeAction): NoticeAction
|
function notice_alarm_per_orig(n: Notice::Info, a: Notice::Action): Notice::Action
|
||||||
{
|
{
|
||||||
local host = n$src;
|
local host = n$src;
|
||||||
|
|
||||||
++notice_once_per_orig[n$note, host];
|
#++notice_once_per_orig[n$note, host];
|
||||||
|
|
||||||
if ( notice_once_per_orig[n$note, host] > 1 )
|
#if ( notice_once_per_orig[n$note, host] > 1 )
|
||||||
return NOTICE_FILE;
|
# return NOTICE_FILE;
|
||||||
|
#
|
||||||
schedule notice_once_per_orig_tally_interval
|
#schedule notice_once_per_orig_tally_interval
|
||||||
{ notice_alarm_per_orig_tally(n, host) };
|
# { notice_alarm_per_orig_tally(n, host) };
|
||||||
|
|
||||||
return NOTICE_ALARM_ALWAYS;
|
return NOTICE_ALARM_ALWAYS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,146 +1,141 @@
|
||||||
# $Id: notice.bro 6756 2009-06-14 21:31:19Z vern $
|
|
||||||
|
|
||||||
const use_tagging = F &redef;
|
|
||||||
|
|
||||||
type Notice: enum {
|
|
||||||
NoticeNone, # placeholder
|
|
||||||
NoticeTally, # notice reporting count of how often a notice occurred
|
|
||||||
};
|
|
||||||
|
|
||||||
type NoticeAction: enum {
|
|
||||||
# Similar to WeirdAction in weird.bro.
|
|
||||||
NOTICE_UNKNOWN, # placeholder
|
|
||||||
NOTICE_IGNORE, NOTICE_FILE, NOTICE_ALARM_ALWAYS,
|
|
||||||
NOTICE_EMAIL, NOTICE_PAGE,
|
|
||||||
NOTICE_DROP, # drops the address via Drop::drop_address, and alarms
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
type notice_info: record {
|
module Notice;
|
||||||
note: Notice;
|
|
||||||
msg: string &default="";
|
|
||||||
sub: string &optional; # sub-message
|
|
||||||
|
|
||||||
conn: connection &optional; # connection associated with notice
|
export {
|
||||||
iconn: icmp_conn &optional; # associated ICMP "connection"
|
type Type: enum {
|
||||||
id: conn_id &optional; # connection-ID, if we don't have a connection handy
|
NoticeNone, # placeholder
|
||||||
src: addr &optional; # source address, if we don't have a connection
|
NoticeTally, # notice reporting count of how often a notice occurred
|
||||||
dst: addr &optional; # destination address
|
};
|
||||||
|
|
||||||
p: port &optional; # associated port, if we don't have a conn.
|
type Action: enum {
|
||||||
|
# Similar to WeirdAction in weird.bro.
|
||||||
|
NOTICE_UNKNOWN, # placeholder
|
||||||
|
NOTICE_IGNORE, NOTICE_ALARM_ALWAYS,
|
||||||
|
NOTICE_EMAIL, NOTICE_FILE, NOTICE_PAGE,
|
||||||
|
NOTICE_DROP, # drops the address via Drop::drop_address, and alarms
|
||||||
|
};
|
||||||
|
|
||||||
|
type Info: record {
|
||||||
|
note: Notice::Type;
|
||||||
|
msg: string &default="";
|
||||||
|
sub: string &optional; # sub-message
|
||||||
|
|
||||||
# The following are detailed attributes that are associated with some
|
conn: connection &optional; # connection associated with notice
|
||||||
# notices, but not all.
|
iconn: icmp_conn &optional; # associated ICMP "connection"
|
||||||
|
id: conn_id &optional; # connection-ID, if we don't have a connection handy
|
||||||
|
src: addr &optional; # source address, if we don't have a connection
|
||||||
|
dst: addr &optional; # destination address
|
||||||
|
p: port &optional; # associated port, if we don't have a conn.
|
||||||
|
|
||||||
user: string &optional;
|
n: count &optional; # associated count, or perhaps status code
|
||||||
|
|
||||||
filename: string &optional;
|
# Automatically set attributes.
|
||||||
|
action: Notice::Action &default=NOTICE_UNKNOWN; # once action determined
|
||||||
|
#src_peer: event_peer &optional; # source that raised this notice
|
||||||
|
#tag: string &optional; # tag associated with this notice
|
||||||
|
#dropped: bool &optional &default=F; # true if src successfully dropped
|
||||||
|
|
||||||
method: string &optional;
|
# If we asked the Time Machine to capture, the filename prefix.
|
||||||
URL: string &optional;
|
#captured: string &optional;
|
||||||
|
|
||||||
n: count &optional; # associated count, or perhaps status code
|
# If false, don't alarm independent of the determined notice action.
|
||||||
|
# If true, alarm dependening on notice action.
|
||||||
|
do_alarm: bool &default=T;
|
||||||
|
};
|
||||||
|
|
||||||
aux: table[string] of string &optional; # further NOTICE-specific data
|
type PolicyItem: record {
|
||||||
|
result: Notice::Action &default=NOTICE_FILE;
|
||||||
|
pred: function(n: Notice::Info): bool;
|
||||||
|
priority: count &default=1;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
# Variables the control email notification.
|
||||||
|
const mail_script = "/bin/mail" &redef; # local system mail program
|
||||||
|
const mail_dest = "" &redef; # email address to send mail to
|
||||||
|
const mail_page_dest = "bro-page" &redef; # email address of pager
|
||||||
|
|
||||||
|
# Do not generate notice_action events for these NOTICE types.
|
||||||
|
const suppress_notice_actions: set[Notice::Type] &redef;
|
||||||
|
|
||||||
|
# Hack to suppress duplicate notice_actions for remote notices.
|
||||||
|
global suppress_notice_action = F;
|
||||||
|
|
||||||
|
|
||||||
|
# This is the Notice::policy where the local notice conversion policy
|
||||||
|
# is set.
|
||||||
|
const policy: set[Notice::PolicyItem] = {
|
||||||
|
[$pred(n: Notice::Info) = { return T; },
|
||||||
|
$result = NOTICE_ALARM_ALWAYS,
|
||||||
|
$priority = 0],
|
||||||
|
} &redef;
|
||||||
|
|
||||||
|
# Table that maps notices into a function that should be called
|
||||||
|
# to determine the action.
|
||||||
|
const action_filters:
|
||||||
|
table[Notice::Type] of
|
||||||
|
function(n: Notice::Info, a: Notice::Action): Notice::Action &redef;
|
||||||
|
|
||||||
|
# This should have a high probability of being unique without
|
||||||
|
# generating overly long tags. This is redef'able in case you need
|
||||||
|
# determinism in tags (such as for regression testing).
|
||||||
|
const notice_tag_prefix =
|
||||||
|
fmt("%x-%x-",
|
||||||
|
double_to_count(time_to_double(current_time())) % 255,
|
||||||
|
getpid()) &redef;
|
||||||
|
|
||||||
# Automatically set attributes.
|
# Likewise redef'able for regression testing.
|
||||||
action: NoticeAction &default=NOTICE_UNKNOWN; # once action determined
|
const new_notice_tag = function(): string { return ""; } &redef;
|
||||||
src_peer: event_peer &optional; # source that raised this notice
|
|
||||||
tag: string &optional; # tag associated with this notice
|
|
||||||
dropped: bool &optional &default=F; # true if src successfully dropped
|
|
||||||
|
|
||||||
# If we asked the Time Machine to capture, the filename prefix.
|
# Function to add a unique NOTICE tag to a connection. This is done
|
||||||
captured: string &optional;
|
# automatically whenever a NOTICE is raised, but sometimes one might need
|
||||||
|
# to call this function in advance of that to ensure that the tag appears
|
||||||
# If false, don't alarm independent of the determined notice action.
|
# in the connection summaries (i.e., when connection_state_remove() can be
|
||||||
# If true, alarm dependening on notice action.
|
# raised before the NOTICE is generated.)
|
||||||
do_alarm: bool &default=T;
|
global tags: table[conn_id] of string;
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
type notice_policy_item: record {
|
|
||||||
result: NoticeAction &default=NOTICE_FILE;
|
|
||||||
pred: function(n: notice_info): bool;
|
|
||||||
priority: count &default=1;
|
|
||||||
};
|
|
||||||
|
|
||||||
global notice_policy: set[notice_policy_item] = {
|
|
||||||
[$pred(n: notice_info) = { return T; },
|
|
||||||
$result = NOTICE_ALARM_ALWAYS,
|
|
||||||
$priority = 0],
|
|
||||||
} &redef;
|
|
||||||
|
|
||||||
global NOTICE: function(n: notice_info);
|
|
||||||
|
|
||||||
# Variables the control email notification.
|
|
||||||
const mail_script = "/bin/mail" &redef; # local system mail program
|
|
||||||
const mail_dest = "" &redef; # email address to send mail to
|
|
||||||
const mail_page_dest = "bro-page" &redef; # email address of pager
|
|
||||||
|
|
||||||
|
|
||||||
# Table that maps notices into a function that should be called
|
|
||||||
# to determine the action.
|
|
||||||
global notice_action_filters:
|
|
||||||
table[Notice] of
|
|
||||||
function(n: notice_info, a: NoticeAction): NoticeAction &redef;
|
|
||||||
|
|
||||||
|
# These are implemented below
|
||||||
|
global email_notice_to: function(n: Notice::Info, dest: string) &redef;
|
||||||
|
global NOTICE: function(n: Notice::Info);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
# Each notice has a unique ID associated with it.
|
# Each notice has a unique ID associated with it.
|
||||||
global notice_id = 0;
|
global notice_id = 0;
|
||||||
|
redef new_notice_tag = function(): string
|
||||||
|
{ return fmt("%s%x", notice_tag_prefix, ++notice_id); };
|
||||||
|
|
||||||
# This should have a high probability of being unique without
|
event bro_init()
|
||||||
# generating overly long tags. This is redef'able in case you need
|
{
|
||||||
# determinism in tags (such as for regression testing).
|
Log::create_stream("NOTICE", "Notice::Info");
|
||||||
global notice_tag_prefix =
|
Log::add_default_filter("NOTICE");
|
||||||
fmt("%x-%x-",
|
}
|
||||||
double_to_count(time_to_double(current_time())) % 255,
|
|
||||||
getpid())
|
|
||||||
&redef;
|
|
||||||
|
|
||||||
# Likewise redef'able for regression testing.
|
|
||||||
global new_notice_tag =
|
|
||||||
function(): string
|
|
||||||
{
|
|
||||||
return fmt("%s%x", notice_tag_prefix, ++notice_id);
|
|
||||||
}
|
|
||||||
&redef;
|
|
||||||
|
|
||||||
# Function to add a unique NOTICE tag to a connection. This is done
|
|
||||||
# automatically whenever a NOTICE is raised, but sometimes one might need
|
|
||||||
# to call this function in advance of that to ensure that the tag appears
|
|
||||||
# in the connection summaries (i.e., when connection_state_remove() can be
|
|
||||||
# raised before the NOTICE is generated.)
|
|
||||||
global notice_tags: table[conn_id] of string;
|
|
||||||
|
|
||||||
function add_notice_tag(c: connection): string
|
function add_notice_tag(c: connection): string
|
||||||
{
|
{
|
||||||
if ( c$id in notice_tags )
|
if ( c$id in tags )
|
||||||
return notice_tags[c$id];
|
return tags[c$id];
|
||||||
|
|
||||||
local tag_id = new_notice_tag();
|
local tag_id = new_notice_tag();
|
||||||
append_addl(c, fmt("@%s", tag_id));
|
append_addl(c, fmt("@%s", tag_id));
|
||||||
notice_tags[c$id] = tag_id;
|
tags[c$id] = tag_id;
|
||||||
|
|
||||||
return tag_id;
|
return tag_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
event delete_notice_tags(c: connection)
|
event delete_notice_tags(c: connection)
|
||||||
{
|
{
|
||||||
delete notice_tags[c$id];
|
delete tags[c$id];
|
||||||
}
|
}
|
||||||
|
|
||||||
event connection_state_remove(c: connection)
|
event connection_state_remove(c: connection) &priority = -10
|
||||||
{
|
{
|
||||||
# We do not delete the tag right here because there may be other
|
event delete_notice_tags(c);
|
||||||
# connection_state_remove handlers invoked after us which
|
|
||||||
# want to generate a notice.
|
|
||||||
schedule 1 secs { delete_notice_tags(c) };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const notice_file = open_log_file("notice") &redef;
|
|
||||||
|
|
||||||
# This handler is useful for processing notices after the notice filters
|
# This handler is useful for processing notices after the notice filters
|
||||||
# have been applied and yielded an NoticeAction.
|
# have been applied and yielded an Notice::Action.
|
||||||
#
|
#
|
||||||
# It's tempting to make the default handler do the logging and
|
# It's tempting to make the default handler do the logging and
|
||||||
# printing to notice_file, rather than NOTICE. I hesitate to do that,
|
# printing to notice_file, rather than NOTICE. I hesitate to do that,
|
||||||
|
@ -148,133 +143,38 @@ const notice_file = open_log_file("notice") &redef;
|
||||||
# in the absence of event priorities, the event would have to wait
|
# in the absence of event priorities, the event would have to wait
|
||||||
# behind any other already-queued events.
|
# behind any other already-queued events.
|
||||||
|
|
||||||
event notice_action(n: notice_info, action: NoticeAction)
|
event notice_action(n: Notice::Info, action: Notice::Action)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
# Do not generate notice_action events for these NOTICE types.
|
|
||||||
global suppress_notice_actions: set[Notice] &redef;
|
|
||||||
|
|
||||||
# Similar to notice_action but only generated if the notice also
|
# Similar to notice_action but only generated if the notice also
|
||||||
# triggers an alarm.
|
# triggers an alarm.
|
||||||
event notice_alarm(n: notice_info, action: NoticeAction)
|
event notice_alarm(n: Notice::Info, action: Notice::Action)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
# Hack to suppress duplicate notice_actions for remote notices.
|
function notice_tags(n: Notice::Info) : table[string] of string
|
||||||
global suppress_notice_action = F;
|
|
||||||
|
|
||||||
function notice_info_tags(n: notice_info) : table[string] of string
|
|
||||||
{
|
{
|
||||||
local tags: table[string] of string;
|
|
||||||
|
|
||||||
local t = is_remote_event() ? current_time() : network_time();
|
|
||||||
tags["t"] = fmt("%.06f", t);
|
|
||||||
tags["no"] = fmt("%s", n$note);
|
|
||||||
tags["na"] = fmt("%s", n$action);
|
|
||||||
tags["sa"] = n?$src ? fmt("%s", n$src) : "";
|
|
||||||
tags["sp"] = n?$id && n$id$orig_h == n$src ? fmt("%s", n$id$orig_p) : "";
|
|
||||||
tags["da"] = n?$dst ? fmt("%s", n$dst) : "";
|
|
||||||
tags["dp"] = n?$id && n$id$resp_h == n$dst ? fmt("%s", n$id$resp_p) : "";
|
|
||||||
tags["p"] = n?$p ? fmt("%s", n$p) : "";
|
|
||||||
tags["user"] = n?$user ? n$user : "";
|
|
||||||
tags["file"] = n?$filename ? n$filename : "";
|
|
||||||
tags["method"] = n?$method ? n$method : "";
|
|
||||||
tags["url"] = n?$URL ? n$URL : "";
|
|
||||||
tags["num"] = n?$n ? fmt("%s", n$n) : "";
|
|
||||||
tags["msg"] = n?$msg ? n$msg : "";
|
|
||||||
tags["sub"] = n?$sub ? n$sub : "";
|
|
||||||
tags["captured"] = n?$captured ? n$captured : "";
|
|
||||||
tags["tag"] = fmt("@%s", n$tag);
|
|
||||||
tags["dropped"] = n$dropped ? "1" : "";
|
|
||||||
|
|
||||||
if ( n?$aux )
|
|
||||||
{
|
|
||||||
for ( a in n$aux )
|
|
||||||
tags[fmt("aux_%s", a)] = n$aux[a];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( is_remote_event() )
|
if ( is_remote_event() )
|
||||||
{
|
{
|
||||||
if ( n$src_peer$descr != "" )
|
#if ( n$src_peer$descr != "" )
|
||||||
tags["es"] = n$src_peer$descr;
|
# {
|
||||||
else
|
# #tags["es"] = n$src_peer$descr;
|
||||||
tags["es"] = fmt("%s/%s", n$src_peer$host, n$src_peer$p);
|
# }
|
||||||
|
#else
|
||||||
|
# {
|
||||||
|
# #tags["es"] = fmt("%s/%s", n$src_peer$host, n$src_peer$p);
|
||||||
|
# }
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
tags["es"] = peer_description;
|
{
|
||||||
|
#tags["es"] = peer_description;
|
||||||
return tags;
|
}
|
||||||
|
#return tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
function build_notice_info_string_untagged(n: notice_info) : string
|
function email_notice_to(n: Notice::Info, dest: string)
|
||||||
{
|
|
||||||
# We add the fields in this order. Fields not listed won't be added.
|
|
||||||
local fields = vector("t", "no", "na", "es", "sa", "sp", "da", "dp",
|
|
||||||
"user", "file", "method", "url", "num", "msg", "sub", "tag");
|
|
||||||
|
|
||||||
local tags = notice_info_tags(n);
|
|
||||||
local cur_info = "";
|
|
||||||
|
|
||||||
for ( i in fields )
|
|
||||||
{
|
|
||||||
local val = tags[fields[i]];
|
|
||||||
val = string_escape(val, ":");
|
|
||||||
|
|
||||||
if ( cur_info == "" )
|
|
||||||
cur_info = val;
|
|
||||||
else
|
|
||||||
cur_info = fmt("%s:%s", cur_info, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
return cur_info;
|
|
||||||
}
|
|
||||||
|
|
||||||
function build_notice_info_string_tagged(n: notice_info) : string
|
|
||||||
{
|
|
||||||
# We add the fields in this order. Fields not listed won't be added
|
|
||||||
# (except aux_*).
|
|
||||||
local fields = vector("t", "no", "na", "dropped", "es", "sa", "sp",
|
|
||||||
"da", "dp", "p", "user", "file", "method", "url",
|
|
||||||
"num", "msg", "sub", "captured", "tag");
|
|
||||||
|
|
||||||
local tags = notice_info_tags(n);
|
|
||||||
local cur_info = "";
|
|
||||||
|
|
||||||
for ( i in fields )
|
|
||||||
{
|
|
||||||
local val = tags[fields[i]];
|
|
||||||
local f = fields[i];
|
|
||||||
|
|
||||||
if ( val == "" )
|
|
||||||
next;
|
|
||||||
|
|
||||||
val = string_escape(val, "= ");
|
|
||||||
|
|
||||||
if ( cur_info == "" )
|
|
||||||
cur_info = fmt("%s=%s", f, val);
|
|
||||||
else
|
|
||||||
cur_info = fmt("%s %s=%s", cur_info, f, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( t in tags )
|
|
||||||
{
|
|
||||||
if ( t == /aux_.*/ )
|
|
||||||
{
|
|
||||||
if ( cur_info == "" )
|
|
||||||
cur_info = fmt("%s=%s", t, tags[t]);
|
|
||||||
else
|
|
||||||
cur_info = fmt("%s %s=%s", cur_info, t, tags[t]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return cur_info;
|
|
||||||
}
|
|
||||||
|
|
||||||
global email_notice_to: function(n: notice_info, dest: string) &redef;
|
|
||||||
|
|
||||||
function email_notice_to(n: notice_info, dest: string)
|
|
||||||
{
|
{
|
||||||
if ( reading_traces() || dest == "" )
|
if ( reading_traces() || dest == "" )
|
||||||
return;
|
return;
|
||||||
|
@ -288,27 +188,26 @@ function email_notice_to(n: notice_info, dest: string)
|
||||||
system(mail_cmd);
|
system(mail_cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
function email_notice(n: notice_info, action: NoticeAction)
|
function email_notice(n: Notice::Info, action: Notice::Action)
|
||||||
{
|
{
|
||||||
# Choose destination address based on action type.
|
# Choose destination address based on action type.
|
||||||
local destination =
|
local dest = (action == NOTICE_EMAIL) ? mail_dest : mail_page_dest;
|
||||||
(action == NOTICE_EMAIL) ? mail_dest : mail_page_dest;
|
email_notice_to(n, dest);
|
||||||
|
|
||||||
email_notice_to(n, destination);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Executes a script with all of the notice fields put into the
|
# Executes a script with all of the notice fields put into the
|
||||||
# new process' environment as "BRO_ARG_<field>" variables.
|
# new process' environment as "BRO_ARG_<field>" variables.
|
||||||
function execute_with_notice(cmd: string, n: notice_info)
|
function execute_with_notice(cmd: string, n: Notice::Info)
|
||||||
{
|
{
|
||||||
local tags = notice_info_tags(n);
|
# TODO: fix system calls
|
||||||
|
#local tags = tags(n);
|
||||||
system_env(cmd, tags);
|
system_env(cmd, tags);
|
||||||
}
|
}
|
||||||
|
|
||||||
# Can't load it at the beginning due to circular dependencies.
|
# Can't load it at the beginning due to circular dependencies.
|
||||||
@load drop
|
#@load drop
|
||||||
|
|
||||||
function NOTICE(n: notice_info)
|
function NOTICE(n: Notice::Info)
|
||||||
{
|
{
|
||||||
# Fill in some defaults.
|
# Fill in some defaults.
|
||||||
if ( ! n?$id && n?$conn )
|
if ( ! n?$id && n?$conn )
|
||||||
|
@ -327,72 +226,45 @@ function NOTICE(n: notice_info)
|
||||||
if ( ! n?$dst && n?$iconn )
|
if ( ! n?$dst && n?$iconn )
|
||||||
n$dst = n$iconn$resp_h;
|
n$dst = n$iconn$resp_h;
|
||||||
|
|
||||||
if ( ! n?$src_peer )
|
#if ( ! n?$src_peer )
|
||||||
n$src_peer = get_event_peer();
|
# n$src_peer = get_event_peer();
|
||||||
|
|
||||||
if ( n?$conn )
|
#if ( n?$conn )
|
||||||
n$tag = add_notice_tag(n$conn);
|
# n$tag = add_notice_tag(n$conn);
|
||||||
|
#if ( ! n?$tag )
|
||||||
|
# n$tag = new_notice_tag();
|
||||||
|
|
||||||
if ( ! n?$tag )
|
local action = match n using policy;
|
||||||
n$tag = new_notice_tag();
|
|
||||||
|
|
||||||
local action = match n using notice_policy;
|
if ( action != NOTICE_IGNORE &&
|
||||||
|
action != NOTICE_FILE &&
|
||||||
local n_id = "";
|
n$note in action_filters )
|
||||||
|
action = action_filters[n$note](n, action);
|
||||||
if ( action != NOTICE_IGNORE && action != NOTICE_FILE &&
|
|
||||||
n$note in notice_action_filters )
|
|
||||||
action = notice_action_filters[n$note](n, action);
|
|
||||||
|
|
||||||
n$action = action;
|
n$action = action;
|
||||||
|
|
||||||
if ( action == NOTICE_EMAIL || action == NOTICE_PAGE )
|
if ( action == NOTICE_EMAIL || action == NOTICE_PAGE )
|
||||||
email_notice(n, action);
|
email_notice(n, action);
|
||||||
|
|
||||||
if ( action == NOTICE_DROP )
|
# if ( action == NOTICE_DROP )
|
||||||
{
|
# {
|
||||||
local drop = Drop::drop_address(n$src, "");
|
# local drop = Drop::drop_address(n$src, "");
|
||||||
local addl = drop?$sub ? fmt(" %s", drop$sub) : "";
|
# local addl = drop?$sub ? fmt(" %s", drop$sub) : "";
|
||||||
n$dropped = drop$note != Drop::AddressDropIgnored;
|
# n$dropped = drop$note != Drop::AddressDropIgnored;
|
||||||
n$msg += fmt(" [%s%s]", drop$note, addl);
|
# n$msg += fmt(" [%s%s]", drop$note, addl);
|
||||||
}
|
# }
|
||||||
|
|
||||||
if ( action != NOTICE_IGNORE )
|
if ( action != NOTICE_IGNORE )
|
||||||
{
|
{
|
||||||
# Build the info here after we had a chance to set the
|
# Build the info here after we had a chance to set the
|
||||||
# $dropped field.
|
# $dropped field.
|
||||||
local info: string;
|
Log::write("NOTICE", n);
|
||||||
if ( use_tagging )
|
|
||||||
info = build_notice_info_string_tagged(n);
|
|
||||||
else
|
|
||||||
info = build_notice_info_string_untagged(n);
|
|
||||||
|
|
||||||
print notice_file, info;
|
|
||||||
|
|
||||||
if ( action != NOTICE_FILE && n$do_alarm )
|
if ( action != NOTICE_FILE && n$do_alarm )
|
||||||
{
|
{
|
||||||
if ( use_tagging )
|
# TODO: alarm may turn into a filter.
|
||||||
{
|
alarm n;
|
||||||
alarm info;
|
event notice_alarm(n, action);
|
||||||
event notice_alarm(n, action);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
local descr = "";
|
|
||||||
if ( is_remote_event() )
|
|
||||||
{
|
|
||||||
if ( n$src_peer$descr != "" )
|
|
||||||
descr = fmt("<%s> ",
|
|
||||||
n$src_peer$descr);
|
|
||||||
else
|
|
||||||
descr = fmt("<%s:%s> ",
|
|
||||||
n$src_peer$host,
|
|
||||||
n$src_peer$p);
|
|
||||||
}
|
|
||||||
|
|
||||||
alarm fmt("%s %s%s", n$note, descr, n$msg);
|
|
||||||
event notice_alarm(n, action);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue