mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00

Scripting errors/mistakes now consistently generate a runtime error which have the behavior of unwinding the call stack all the way out of the current event handler. Before, such errors were not treated consistently and either aborted the process entirely or emitted a message while continuing to execute subsequent statements without well-defined behavior (possibly causing a cascade of errors). The previous behavior also would only unwind out of the current function (if within a function body), not out the current event handler, which is especially problematic for functions that return a value: the caller is essentially left a mess with no way to deal with it. This also changes the behavior of the startup/initialization process to abort if there's errors during bro_init() rather than continue one to the main run loop. The `allow_init_errors` option may change this new, default behavior.
161 lines
4.6 KiB
Text
161 lines
4.6 KiB
Text
##! Definitions describing a site - which networks and DNS zones are "local"
|
|
##! and "neighbors", and servers running particular services.
|
|
@load ./patterns
|
|
|
|
module Site;
|
|
|
|
export {
|
|
## Address space that is considered private and unrouted.
|
|
## By default it has RFC defined non-routable IPv4 address space.
|
|
option private_address_space: set[subnet] = {
|
|
10.0.0.0/8,
|
|
192.168.0.0/16,
|
|
172.16.0.0/12,
|
|
100.64.0.0/10, # RFC6598 Carrier Grade NAT
|
|
127.0.0.0/8,
|
|
[fe80::]/10,
|
|
[::1]/128,
|
|
};
|
|
|
|
## Networks that are considered "local". Note that BroControl sets
|
|
## this automatically.
|
|
option local_nets: set[subnet] = {};
|
|
|
|
## This is used for retrieving the subnet when using multiple entries in
|
|
## :bro:id:`Site::local_nets`. It's populated automatically from there.
|
|
## A membership query can be done with an
|
|
## :bro:type:`addr` and the table will yield the subnet it was found
|
|
## within.
|
|
global local_nets_table: table[subnet] of subnet = {};
|
|
|
|
## Networks that are considered "neighbors".
|
|
option neighbor_nets: set[subnet] = {};
|
|
|
|
## If local network administrators are known and they have responsibility
|
|
## for defined address space, then a mapping can be defined here between
|
|
## networks for which they have responsibility and a set of email
|
|
## addresses.
|
|
option local_admins: table[subnet] of set[string] = {};
|
|
|
|
## DNS zones that are considered "local".
|
|
option local_zones: set[string] = {};
|
|
|
|
## DNS zones that are considered "neighbors".
|
|
option neighbor_zones: set[string] = {};
|
|
|
|
## Function that returns true if an address corresponds to one of
|
|
## the local networks, false if not.
|
|
## The function inspects :bro:id:`Site::local_nets`.
|
|
global is_local_addr: function(a: addr): bool;
|
|
|
|
## Function that returns true if an address corresponds to one of
|
|
## the neighbor networks, false if not.
|
|
## The function inspects :bro:id:`Site::neighbor_nets`.
|
|
global is_neighbor_addr: function(a: addr): bool;
|
|
|
|
## Function that returns true if an address corresponds to one of
|
|
## the private/unrouted networks, false if not.
|
|
## The function inspects :bro:id:`Site::private_address_space`.
|
|
global is_private_addr: function(a: addr): bool;
|
|
|
|
## Function that returns true if a host name is within a local
|
|
## DNS zone.
|
|
## The function inspects :bro:id:`Site::local_zones`.
|
|
global is_local_name: function(name: string): bool;
|
|
|
|
## Function that returns true if a host name is within a neighbor
|
|
## DNS zone.
|
|
## The function inspects :bro:id:`Site::neighbor_zones`.
|
|
global is_neighbor_name: function(name: string): bool;
|
|
|
|
## Function that returns a comma-separated list of email addresses
|
|
## that are considered administrators for the IP address provided as
|
|
## an argument.
|
|
## The function inspects :bro:id:`Site::local_admins`.
|
|
global get_emails: function(a: addr): string;
|
|
}
|
|
|
|
# Please ignore, this is an interally used variable.
|
|
global local_dns_suffix_regex: pattern = /MATCH_NOTHING/;
|
|
global local_dns_neighbor_suffix_regex: pattern = /MATCH_NOTHING/;
|
|
|
|
|
|
function is_local_addr(a: addr): bool
|
|
{
|
|
return a in local_nets;
|
|
}
|
|
|
|
function is_neighbor_addr(a: addr): bool
|
|
{
|
|
return a in neighbor_nets;
|
|
}
|
|
|
|
function is_private_addr(a: addr): bool
|
|
{
|
|
return a in private_address_space;
|
|
}
|
|
|
|
function is_local_name(name: string): bool
|
|
{
|
|
return local_dns_suffix_regex in name;
|
|
}
|
|
|
|
function is_neighbor_name(name: string): bool
|
|
{
|
|
return local_dns_neighbor_suffix_regex in name;
|
|
}
|
|
|
|
# This is a hack for doing a for loop.
|
|
const one_to_32: vector of count = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32};
|
|
|
|
# TODO: make this work with IPv6
|
|
function find_all_emails(ip: addr): set[string]
|
|
{
|
|
if ( ip !in local_admins ) return set();
|
|
|
|
local output_values: set[string] = set();
|
|
local tmp_subnet: subnet;
|
|
local i: count;
|
|
local emails: string;
|
|
for ( i in one_to_32 )
|
|
{
|
|
tmp_subnet = mask_addr(ip, one_to_32[i]);
|
|
if ( tmp_subnet in local_admins )
|
|
for ( email in local_admins[tmp_subnet] )
|
|
{
|
|
if ( email != "" )
|
|
add output_values[email];
|
|
}
|
|
}
|
|
return output_values;
|
|
}
|
|
|
|
function fmt_email_string(emails: set[string]): string
|
|
{
|
|
local output="";
|
|
for( email in emails )
|
|
{
|
|
if ( output == "" )
|
|
output = email;
|
|
else
|
|
output = fmt("%s, %s", output, email);
|
|
}
|
|
return output;
|
|
}
|
|
|
|
function get_emails(a: addr): string
|
|
{
|
|
return fmt_email_string(find_all_emails(a));
|
|
}
|
|
|
|
event bro_init() &priority=10
|
|
{
|
|
# Double backslashes are needed due to string parsing.
|
|
local_dns_suffix_regex = set_to_regex(local_zones, "(^\\.?|\\.)(~~)$");
|
|
local_dns_neighbor_suffix_regex = set_to_regex(neighbor_zones, "(^\\.?|\\.)(~~)$");
|
|
|
|
# Create the local_nets mapping table.
|
|
for ( cidr in Site::local_nets )
|
|
local_nets_table[cidr] = cidr;
|
|
|
|
}
|