mirror of
https://github.com/zeek/zeek.git
synced 2025-10-04 23:58:20 +00:00
Merge remote-tracking branch 'origin/master' into topic/johanna/hash-unification
* origin/master: Use zeek::detail namespace for fuzzer utils Set terminating flag during fuzzer cleanup Add missing include to standalone fuzzer driver Improve standalone fuzzer driver error messages Test fuzzers against seed corpus under CI ASan build Update fuzzing README with OSS-Fuzz integration notes Link fuzzers against shared library to reduce executable sizes Improve FuzzBuffer chunking Fix compiler warning in standalone fuzzer driver Adjust minor fuzzing documentation Exit immediately after running unit tests Add OSS-Fuzz Zeek script search path to fuzzers Assume libFuzzer when LIB_FUZZING_ENGINE file doesn't exist Change handling of LIB_FUZZING_ENGINE Change --enable-fuzzing to --enable-fuzzers Add standalone driver for fuzz targets Add basic structure for fuzzing targets
This commit is contained in:
commit
892023ed9a
30 changed files with 1703 additions and 932 deletions
893
src/zeek-setup.cc
Normal file
893
src/zeek-setup.cc
Normal file
|
@ -0,0 +1,893 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "zeek-config.h"
|
||||
#include "zeek-setup.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <list>
|
||||
#include <optional>
|
||||
|
||||
#ifdef USE_IDMEF
|
||||
extern "C" {
|
||||
#include <libidmef/idmefxml.h>
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "Options.h"
|
||||
#include "input.h"
|
||||
#include "DNS_Mgr.h"
|
||||
#include "Frame.h"
|
||||
#include "Scope.h"
|
||||
#include "Event.h"
|
||||
#include "File.h"
|
||||
#include "Reporter.h"
|
||||
#include "Net.h"
|
||||
#include "NetVar.h"
|
||||
#include "Var.h"
|
||||
#include "Timer.h"
|
||||
#include "Stmt.h"
|
||||
#include "Desc.h"
|
||||
#include "Debug.h"
|
||||
#include "DFA.h"
|
||||
#include "RuleMatcher.h"
|
||||
#include "Anon.h"
|
||||
#include "EventRegistry.h"
|
||||
#include "Stats.h"
|
||||
#include "Brofiler.h"
|
||||
#include "Traverse.h"
|
||||
#include "Trigger.h"
|
||||
#include "Hash.h"
|
||||
|
||||
#include "supervisor/Supervisor.h"
|
||||
#include "threading/Manager.h"
|
||||
#include "input/Manager.h"
|
||||
#include "logging/Manager.h"
|
||||
#include "input/readers/raw/Raw.h"
|
||||
#include "analyzer/Manager.h"
|
||||
#include "analyzer/Tag.h"
|
||||
#include "plugin/Manager.h"
|
||||
#include "file_analysis/Manager.h"
|
||||
#include "zeekygen/Manager.h"
|
||||
#include "iosource/Manager.h"
|
||||
#include "broker/Manager.h"
|
||||
|
||||
#include "binpac_bro.h"
|
||||
|
||||
#include "3rdparty/sqlite3.h"
|
||||
|
||||
#define DOCTEST_CONFIG_IMPLEMENT
|
||||
#include "3rdparty/doctest.h"
|
||||
|
||||
Brofiler brofiler;
|
||||
|
||||
#ifndef HAVE_STRSEP
|
||||
extern "C" {
|
||||
char* strsep(char**, const char*);
|
||||
};
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
#include "setsignal.h"
|
||||
};
|
||||
|
||||
#ifdef USE_PERFTOOLS_DEBUG
|
||||
HeapLeakChecker* heap_checker = 0;
|
||||
int perftools_leaks = 0;
|
||||
int perftools_profile = 0;
|
||||
#endif
|
||||
|
||||
DNS_Mgr* dns_mgr;
|
||||
TimerMgr* timer_mgr;
|
||||
ValManager* val_mgr = nullptr;
|
||||
logging::Manager* log_mgr = nullptr;
|
||||
threading::Manager* thread_mgr = nullptr;
|
||||
input::Manager* input_mgr = nullptr;
|
||||
plugin::Manager* plugin_mgr = nullptr;
|
||||
analyzer::Manager* analyzer_mgr = nullptr;
|
||||
file_analysis::Manager* file_mgr = nullptr;
|
||||
zeekygen::Manager* zeekygen_mgr = nullptr;
|
||||
iosource::Manager* iosource_mgr = nullptr;
|
||||
bro_broker::Manager* broker_mgr = nullptr;
|
||||
zeek::Supervisor* zeek::supervisor_mgr = nullptr;
|
||||
trigger::Manager* trigger_mgr = nullptr;
|
||||
|
||||
std::vector<std::string> zeek_script_prefixes;
|
||||
Stmt* stmts;
|
||||
EventHandlerPtr net_done = nullptr;
|
||||
RuleMatcher* rule_matcher = nullptr;
|
||||
EventRegistry* event_registry = nullptr;
|
||||
ProfileLogger* profiling_logger = nullptr;
|
||||
ProfileLogger* segment_logger = nullptr;
|
||||
SampleLogger* sample_logger = nullptr;
|
||||
int signal_val = 0;
|
||||
extern char version[];
|
||||
const char* command_line_policy = nullptr;
|
||||
vector<string> params;
|
||||
set<string> requested_plugins;
|
||||
const char* proc_status_file = nullptr;
|
||||
|
||||
OpaqueType* md5_type = nullptr;
|
||||
OpaqueType* sha1_type = nullptr;
|
||||
OpaqueType* sha256_type = nullptr;
|
||||
OpaqueType* entropy_type = nullptr;
|
||||
OpaqueType* cardinality_type = nullptr;
|
||||
OpaqueType* topk_type = nullptr;
|
||||
OpaqueType* bloomfilter_type = nullptr;
|
||||
OpaqueType* x509_opaque_type = nullptr;
|
||||
OpaqueType* ocsp_resp_opaque_type = nullptr;
|
||||
OpaqueType* paraglob_type = nullptr;
|
||||
|
||||
// Keep copy of command line
|
||||
int bro_argc;
|
||||
char** bro_argv;
|
||||
|
||||
const char* zeek_version()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
static char* debug_version = nullptr;
|
||||
|
||||
if ( ! debug_version )
|
||||
{
|
||||
int n = strlen(version) + sizeof("-debug") + 1;
|
||||
debug_version = new char[n];
|
||||
snprintf(debug_version, n, "%s%s", version, "-debug");
|
||||
}
|
||||
|
||||
return debug_version;
|
||||
#else
|
||||
return version;
|
||||
#endif
|
||||
}
|
||||
|
||||
static std::vector<const char*> to_cargs(const std::vector<std::string>& args)
|
||||
{
|
||||
std::vector<const char*> rval;
|
||||
rval.reserve(args.size());
|
||||
|
||||
for ( const auto& arg : args )
|
||||
rval.emplace_back(arg.data());
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
bool show_plugins(int level)
|
||||
{
|
||||
plugin::Manager::plugin_list plugins = plugin_mgr->ActivePlugins();
|
||||
|
||||
if ( ! plugins.size() )
|
||||
{
|
||||
printf("No plugins registered, not even any built-ins. This is probably a bug.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
ODesc d;
|
||||
|
||||
if ( level == 1 )
|
||||
d.SetShort();
|
||||
|
||||
int count = 0;
|
||||
|
||||
for ( plugin::Manager::plugin_list::const_iterator i = plugins.begin(); i != plugins.end(); i++ )
|
||||
{
|
||||
if ( requested_plugins.size()
|
||||
&& requested_plugins.find((*i)->Name()) == requested_plugins.end() )
|
||||
continue;
|
||||
|
||||
(*i)->Describe(&d);
|
||||
|
||||
if ( ! d.IsShort() )
|
||||
d.Add("\n");
|
||||
|
||||
++count;
|
||||
}
|
||||
|
||||
printf("%s", d.Description());
|
||||
|
||||
plugin::Manager::inactive_plugin_list inactives = plugin_mgr->InactivePlugins();
|
||||
|
||||
if ( inactives.size() && ! requested_plugins.size() )
|
||||
{
|
||||
printf("\nInactive dynamic plugins:\n");
|
||||
|
||||
for ( plugin::Manager::inactive_plugin_list::const_iterator i = inactives.begin(); i != inactives.end(); i++ )
|
||||
{
|
||||
string name = (*i).first;
|
||||
string path = (*i).second;
|
||||
printf(" %s (%s)\n", name.c_str(), path.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
return count != 0;
|
||||
}
|
||||
|
||||
void done_with_network()
|
||||
{
|
||||
set_processing_status("TERMINATING", "done_with_network");
|
||||
|
||||
// Cancel any pending alarms (watchdog, in particular).
|
||||
(void) alarm(0);
|
||||
|
||||
if ( net_done )
|
||||
{
|
||||
mgr.Drain();
|
||||
// Don't propagate this event to remote clients.
|
||||
mgr.Dispatch(new Event(net_done,
|
||||
{make_intrusive<Val>(timer_mgr->Time(), TYPE_TIME)}),
|
||||
true);
|
||||
}
|
||||
|
||||
if ( profiling_logger )
|
||||
profiling_logger->Log();
|
||||
|
||||
terminating = true;
|
||||
|
||||
analyzer_mgr->Done();
|
||||
timer_mgr->Expire();
|
||||
dns_mgr->Flush();
|
||||
mgr.Drain();
|
||||
mgr.Drain();
|
||||
|
||||
net_finish(1);
|
||||
|
||||
#ifdef USE_PERFTOOLS_DEBUG
|
||||
|
||||
if ( perftools_profile )
|
||||
{
|
||||
HeapProfilerDump("post net_run");
|
||||
HeapProfilerStop();
|
||||
}
|
||||
|
||||
if ( heap_checker && ! heap_checker->NoLeaks() )
|
||||
{
|
||||
fprintf(stderr, "Memory leaks - aborting.\n");
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
|
||||
ZEEK_LSAN_DISABLE();
|
||||
}
|
||||
|
||||
void terminate_bro()
|
||||
{
|
||||
set_processing_status("TERMINATING", "terminate_bro");
|
||||
|
||||
terminating = true;
|
||||
|
||||
iosource_mgr->Wakeup("terminate_bro");
|
||||
|
||||
// File analysis termination may produce events, so do it early on in
|
||||
// the termination process.
|
||||
file_mgr->Terminate();
|
||||
|
||||
brofiler.WriteStats();
|
||||
|
||||
EventHandlerPtr zeek_done = internal_handler("zeek_done");
|
||||
if ( zeek_done )
|
||||
mgr.Enqueue(zeek_done, zeek::Args{});
|
||||
|
||||
timer_mgr->Expire();
|
||||
mgr.Drain();
|
||||
|
||||
if ( profiling_logger )
|
||||
{
|
||||
// FIXME: There are some occasional crashes in the memory
|
||||
// allocation code when killing Bro. Disabling this for now.
|
||||
if ( ! (signal_val == SIGTERM || signal_val == SIGINT) )
|
||||
profiling_logger->Log();
|
||||
|
||||
delete profiling_logger;
|
||||
}
|
||||
|
||||
mgr.Drain();
|
||||
|
||||
notifier::registry.Terminate();
|
||||
log_mgr->Terminate();
|
||||
input_mgr->Terminate();
|
||||
thread_mgr->Terminate();
|
||||
broker_mgr->Terminate();
|
||||
dns_mgr->Terminate();
|
||||
|
||||
mgr.Drain();
|
||||
|
||||
plugin_mgr->FinishPlugins();
|
||||
|
||||
delete zeekygen_mgr;
|
||||
delete analyzer_mgr;
|
||||
delete file_mgr;
|
||||
// broker_mgr, timer_mgr, and supervisor are deleted via iosource_mgr
|
||||
delete iosource_mgr;
|
||||
delete event_registry;
|
||||
delete log_mgr;
|
||||
delete reporter;
|
||||
delete plugin_mgr;
|
||||
delete val_mgr;
|
||||
|
||||
// free the global scope
|
||||
pop_scope();
|
||||
|
||||
reporter = nullptr;
|
||||
}
|
||||
|
||||
void zeek_terminate_loop(const char* reason)
|
||||
{
|
||||
set_processing_status("TERMINATING", reason);
|
||||
reporter->Info("%s", reason);
|
||||
|
||||
net_get_final_stats();
|
||||
done_with_network();
|
||||
net_delete();
|
||||
|
||||
terminate_bro();
|
||||
|
||||
// Close files after net_delete(), because net_delete()
|
||||
// might write to connection content files.
|
||||
BroFile::CloseOpenFiles();
|
||||
|
||||
delete rule_matcher;
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
RETSIGTYPE sig_handler(int signo)
|
||||
{
|
||||
set_processing_status("TERMINATING", "sig_handler");
|
||||
signal_val = signo;
|
||||
|
||||
if ( ! terminating )
|
||||
iosource_mgr->Wakeup("sig_handler");
|
||||
|
||||
return RETSIGVAL;
|
||||
}
|
||||
|
||||
static void atexit_handler()
|
||||
{
|
||||
set_processing_status("TERMINATED", "atexit");
|
||||
}
|
||||
|
||||
static void bro_new_handler()
|
||||
{
|
||||
out_of_memory("new");
|
||||
}
|
||||
|
||||
static std::vector<std::string> get_script_signature_files()
|
||||
{
|
||||
std::vector<std::string> rval;
|
||||
|
||||
// Parse rule files defined on the script level.
|
||||
char* script_signature_files =
|
||||
copy_string(internal_val("signature_files")->AsString()->CheckString());
|
||||
|
||||
char* tmp = script_signature_files;
|
||||
char* s;
|
||||
while ( (s = strsep(&tmp, " \t")) )
|
||||
if ( *s )
|
||||
rval.emplace_back(s);
|
||||
|
||||
delete [] script_signature_files;
|
||||
return rval;
|
||||
}
|
||||
|
||||
zeek::detail::SetupResult zeek::detail::setup(int argc, char** argv,
|
||||
zeek::Options* zopts)
|
||||
{
|
||||
ZEEK_LSAN_DISABLE();
|
||||
std::set_new_handler(bro_new_handler);
|
||||
|
||||
auto zeek_exe_path = get_exe_path(argv[0]);
|
||||
|
||||
if ( zeek_exe_path.empty() )
|
||||
{
|
||||
fprintf(stderr, "failed to get path to executable '%s'", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
bro_argc = argc;
|
||||
bro_argv = new char* [argc];
|
||||
|
||||
for ( int i = 0; i < argc; i++ )
|
||||
bro_argv[i] = copy_string(argv[i]);
|
||||
|
||||
auto options = zopts ? *zopts : zeek::parse_cmdline(argc, argv);
|
||||
|
||||
if ( options.print_usage )
|
||||
zeek::usage(argv[0], 0);
|
||||
|
||||
if ( options.print_version )
|
||||
{
|
||||
fprintf(stdout, "%s version %s\n", argv[0], zeek_version());
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if ( options.run_unit_tests )
|
||||
{
|
||||
doctest::Context context;
|
||||
auto dargs = to_cargs(options.doctest_args);
|
||||
context.applyCommandLine(dargs.size(), dargs.data());
|
||||
ZEEK_LSAN_ENABLE();
|
||||
exit(context.run());
|
||||
}
|
||||
|
||||
auto stem_state = zeek::Supervisor::CreateStem(options.supervisor_mode);
|
||||
|
||||
if ( zeek::Supervisor::ThisNode() )
|
||||
zeek::Supervisor::ThisNode()->Init(&options);
|
||||
|
||||
brofiler.ReadStats();
|
||||
|
||||
auto dns_type = options.dns_mode;
|
||||
|
||||
if ( dns_type == DNS_DEFAULT && zeek::fake_dns() )
|
||||
dns_type = DNS_FAKE;
|
||||
|
||||
RETSIGTYPE (*oldhandler)(int);
|
||||
|
||||
zeek_script_prefixes = options.script_prefixes;
|
||||
auto zeek_prefixes = zeekenv("ZEEK_PREFIXES");
|
||||
|
||||
if ( zeek_prefixes )
|
||||
tokenize_string(zeek_prefixes, ":", &zeek_script_prefixes);
|
||||
|
||||
pseudo_realtime = options.pseudo_realtime;
|
||||
|
||||
#ifdef USE_PERFTOOLS_DEBUG
|
||||
perftools_leaks = options.perftools_check_leaks;
|
||||
perftools_profile = options.perftools_profile;
|
||||
#endif
|
||||
|
||||
if ( options.debug_scripts )
|
||||
{
|
||||
g_policy_debug = options.debug_scripts;
|
||||
fprintf(stderr, "Zeek script debugging ON.\n");
|
||||
}
|
||||
|
||||
if ( options.script_code_to_exec )
|
||||
command_line_policy = options.script_code_to_exec->data();
|
||||
|
||||
if ( options.debug_script_tracing_file )
|
||||
{
|
||||
g_trace_state.SetTraceFile(options.debug_script_tracing_file->data());
|
||||
g_trace_state.TraceOn();
|
||||
}
|
||||
|
||||
if ( options.process_status_file )
|
||||
proc_status_file = options.process_status_file->data();
|
||||
|
||||
atexit(atexit_handler);
|
||||
set_processing_status("INITIALIZING", "main");
|
||||
|
||||
bro_start_time = current_time(true);
|
||||
|
||||
val_mgr = new ValManager();
|
||||
reporter = new Reporter(options.abort_on_scripting_errors);
|
||||
thread_mgr = new threading::Manager();
|
||||
plugin_mgr = new plugin::Manager();
|
||||
|
||||
#ifdef DEBUG
|
||||
if ( options.debug_log_streams )
|
||||
{
|
||||
debug_logger.EnableStreams(options.debug_log_streams->data());
|
||||
|
||||
if ( getenv("ZEEK_DEBUG_LOG_STDERR") )
|
||||
debug_logger.OpenDebugLog(nullptr);
|
||||
else
|
||||
debug_logger.OpenDebugLog("debug");
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( options.supervisor_mode )
|
||||
{
|
||||
zeek::Supervisor::Config cfg = {};
|
||||
cfg.zeek_exe_path = zeek_exe_path;
|
||||
options.filter_supervisor_options();
|
||||
zeek::supervisor_mgr = new zeek::Supervisor(std::move(cfg),
|
||||
std::move(*stem_state));
|
||||
}
|
||||
|
||||
const char* seed_load_file = zeekenv("ZEEK_SEED_FILE");
|
||||
|
||||
if ( options.random_seed_input_file )
|
||||
seed_load_file = options.random_seed_input_file->data();
|
||||
|
||||
init_random_seed((seed_load_file && *seed_load_file ? seed_load_file : nullptr),
|
||||
options.random_seed_output_file ? options.random_seed_output_file->data() : nullptr,
|
||||
options.deterministic_mode);
|
||||
// DEBUG_MSG("HMAC key: %s\n", md5_digest_print(shared_hmac_md5_key));
|
||||
init_hash_function();
|
||||
|
||||
ERR_load_crypto_strings();
|
||||
OPENSSL_add_all_algorithms_conf();
|
||||
SSL_library_init();
|
||||
SSL_load_error_strings();
|
||||
|
||||
// FIXME: On systems that don't provide /dev/urandom, OpenSSL doesn't
|
||||
// seed the PRNG. We should do this here (but at least Linux, FreeBSD
|
||||
// and Solaris provide /dev/urandom).
|
||||
|
||||
int r = sqlite3_initialize();
|
||||
|
||||
if ( r != SQLITE_OK )
|
||||
reporter->Error("Failed to initialize sqlite3: %s", sqlite3_errstr(r));
|
||||
|
||||
#ifdef USE_IDMEF
|
||||
char* libidmef_dtd_path_cstr = new char[options.libidmef_dtd_file.size() + 1];
|
||||
safe_strncpy(libidmef_dtd_path_cstr, options.libidmef_dtd_file.data(),
|
||||
options.libidmef_dtd_file.size());
|
||||
globalsInit(libidmef_dtd_path_cstr); // Init LIBIDMEF globals
|
||||
createCurrentDoc("1.0"); // Set a global XML document
|
||||
#endif
|
||||
|
||||
timer_mgr = new PQ_TimerMgr();
|
||||
|
||||
auto zeekygen_cfg = options.zeekygen_config_file.value_or("");
|
||||
zeekygen_mgr = new zeekygen::Manager(zeekygen_cfg, bro_argv[0]);
|
||||
|
||||
add_essential_input_file("base/init-bare.zeek");
|
||||
add_essential_input_file("base/init-frameworks-and-bifs.zeek");
|
||||
|
||||
if ( ! options.bare_mode )
|
||||
add_input_file("base/init-default.zeek");
|
||||
|
||||
plugin_mgr->SearchDynamicPlugins(bro_plugin_path());
|
||||
|
||||
if ( options.plugins_to_load.empty() && options.scripts_to_load.empty() &&
|
||||
options.script_options_to_set.empty() &&
|
||||
! options.pcap_file && ! options.interface &&
|
||||
! options.identifier_to_print &&
|
||||
! command_line_policy && ! options.print_plugins &&
|
||||
! options.supervisor_mode && ! zeek::Supervisor::ThisNode() )
|
||||
add_input_file("-");
|
||||
|
||||
for ( const auto& script_option : options.script_options_to_set )
|
||||
params.push_back(script_option);
|
||||
|
||||
for ( const auto& plugin : options.plugins_to_load )
|
||||
requested_plugins.insert(plugin);
|
||||
|
||||
for ( const auto& script : options.scripts_to_load )
|
||||
add_input_file(script.data());
|
||||
|
||||
push_scope(nullptr, nullptr);
|
||||
|
||||
dns_mgr = new DNS_Mgr(dns_type);
|
||||
|
||||
// It would nice if this were configurable. This is similar to the
|
||||
// chicken and the egg problem. It would be configurable by parsing
|
||||
// policy, but we can't parse policy without DNS resolution.
|
||||
dns_mgr->SetDir(".state");
|
||||
|
||||
iosource_mgr = new iosource::Manager();
|
||||
event_registry = new EventRegistry();
|
||||
analyzer_mgr = new analyzer::Manager();
|
||||
log_mgr = new logging::Manager();
|
||||
input_mgr = new input::Manager();
|
||||
file_mgr = new file_analysis::Manager();
|
||||
auto broker_real_time = ! options.pcap_file && ! options.deterministic_mode;
|
||||
broker_mgr = new bro_broker::Manager(broker_real_time);
|
||||
trigger_mgr = new trigger::Manager();
|
||||
|
||||
plugin_mgr->InitPreScript();
|
||||
analyzer_mgr->InitPreScript();
|
||||
file_mgr->InitPreScript();
|
||||
zeekygen_mgr->InitPreScript();
|
||||
|
||||
bool missing_plugin = false;
|
||||
|
||||
for ( set<string>::const_iterator i = requested_plugins.begin();
|
||||
i != requested_plugins.end(); i++ )
|
||||
{
|
||||
if ( ! plugin_mgr->ActivateDynamicPlugin(*i) )
|
||||
missing_plugin = true;
|
||||
}
|
||||
|
||||
if ( missing_plugin )
|
||||
reporter->FatalError("Failed to activate requested dynamic plugin(s).");
|
||||
|
||||
plugin_mgr->ActivateDynamicPlugins(! options.bare_mode);
|
||||
|
||||
init_event_handlers();
|
||||
|
||||
md5_type = new OpaqueType("md5");
|
||||
sha1_type = new OpaqueType("sha1");
|
||||
sha256_type = new OpaqueType("sha256");
|
||||
entropy_type = new OpaqueType("entropy");
|
||||
cardinality_type = new OpaqueType("cardinality");
|
||||
topk_type = new OpaqueType("topk");
|
||||
bloomfilter_type = new OpaqueType("bloomfilter");
|
||||
x509_opaque_type = new OpaqueType("x509");
|
||||
ocsp_resp_opaque_type = new OpaqueType("ocsp_resp");
|
||||
paraglob_type = new OpaqueType("paraglob");
|
||||
|
||||
// The leak-checker tends to produce some false
|
||||
// positives (memory which had already been
|
||||
// allocated before we start the checking is
|
||||
// nevertheless reported; see perftools docs), thus
|
||||
// we suppress some messages here.
|
||||
|
||||
#ifdef USE_PERFTOOLS_DEBUG
|
||||
{
|
||||
HeapLeakChecker::Disabler disabler;
|
||||
#endif
|
||||
|
||||
is_parsing = true;
|
||||
yyparse();
|
||||
is_parsing = false;
|
||||
|
||||
RecordVal::DoneParsing();
|
||||
TableVal::DoneParsing();
|
||||
|
||||
init_general_global_var();
|
||||
init_net_var();
|
||||
init_builtin_funcs_subdirs();
|
||||
|
||||
// Must come after plugin activation (and also after hash
|
||||
// initialization).
|
||||
binpac::FlowBuffer::Policy flowbuffer_policy;
|
||||
flowbuffer_policy.max_capacity = global_scope()->Lookup(
|
||||
"BinPAC::flowbuffer_capacity_max")->ID_Val()->AsCount();
|
||||
flowbuffer_policy.min_capacity = global_scope()->Lookup(
|
||||
"BinPAC::flowbuffer_capacity_min")->ID_Val()->AsCount();
|
||||
flowbuffer_policy.contract_threshold = global_scope()->Lookup(
|
||||
"BinPAC::flowbuffer_contract_threshold")->ID_Val()->AsCount();
|
||||
binpac::init(&flowbuffer_policy);
|
||||
|
||||
plugin_mgr->InitBifs();
|
||||
|
||||
if ( reporter->Errors() > 0 )
|
||||
exit(1);
|
||||
|
||||
iosource_mgr->InitPostScript();
|
||||
plugin_mgr->InitPostScript();
|
||||
zeekygen_mgr->InitPostScript();
|
||||
broker_mgr->InitPostScript();
|
||||
timer_mgr->InitPostScript();
|
||||
mgr.InitPostScript();
|
||||
|
||||
if ( zeek::supervisor_mgr )
|
||||
zeek::supervisor_mgr->InitPostScript();
|
||||
|
||||
if ( options.print_plugins )
|
||||
{
|
||||
bool success = show_plugins(options.print_plugins);
|
||||
exit(success ? 0 : 1);
|
||||
}
|
||||
|
||||
analyzer_mgr->InitPostScript();
|
||||
file_mgr->InitPostScript();
|
||||
dns_mgr->InitPostScript();
|
||||
|
||||
if ( options.parse_only )
|
||||
{
|
||||
int rc = (reporter->Errors() > 0 ? 1 : 0);
|
||||
exit(rc);
|
||||
}
|
||||
|
||||
#ifdef USE_PERFTOOLS_DEBUG
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( reporter->Errors() > 0 )
|
||||
{
|
||||
delete dns_mgr;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
reporter->InitOptions();
|
||||
KeyedHash::InitOptions();
|
||||
zeekygen_mgr->GenerateDocs();
|
||||
|
||||
if ( options.pcap_filter )
|
||||
{
|
||||
ID* id = global_scope()->Lookup("cmd_line_bpf_filter");
|
||||
|
||||
if ( ! id )
|
||||
reporter->InternalError("global cmd_line_bpf_filter not defined");
|
||||
|
||||
id->SetVal(make_intrusive<StringVal>(*options.pcap_filter));
|
||||
}
|
||||
|
||||
auto all_signature_files = options.signature_files;
|
||||
|
||||
// Append signature files defined in "signature_files" script option
|
||||
for ( auto&& sf : get_script_signature_files() )
|
||||
all_signature_files.emplace_back(std::move(sf));
|
||||
|
||||
// Append signature files defined in @load-sigs
|
||||
for ( const auto& sf : sig_files )
|
||||
all_signature_files.emplace_back(sf);
|
||||
|
||||
if ( ! all_signature_files.empty() )
|
||||
{
|
||||
rule_matcher = new RuleMatcher(options.signature_re_level);
|
||||
if ( ! rule_matcher->ReadFiles(all_signature_files) )
|
||||
{
|
||||
delete dns_mgr;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ( options.print_signature_debug_info )
|
||||
rule_matcher->PrintDebug();
|
||||
|
||||
file_mgr->InitMagic();
|
||||
}
|
||||
|
||||
if ( g_policy_debug )
|
||||
// ### Add support for debug command file.
|
||||
dbg_init_debugger(nullptr);
|
||||
|
||||
if ( ! options.pcap_file && ! options.interface )
|
||||
{
|
||||
Val* interfaces_val = internal_val("interfaces");
|
||||
if ( interfaces_val )
|
||||
{
|
||||
char* interfaces_str =
|
||||
interfaces_val->AsString()->Render();
|
||||
|
||||
if ( interfaces_str[0] != '\0' )
|
||||
options.interface = interfaces_str;
|
||||
|
||||
delete [] interfaces_str;
|
||||
}
|
||||
}
|
||||
|
||||
if ( dns_type != DNS_PRIME )
|
||||
net_init(options.interface, options.pcap_file, options.pcap_output_file, options.use_watchdog);
|
||||
|
||||
net_done = internal_handler("net_done");
|
||||
|
||||
if ( ! g_policy_debug )
|
||||
{
|
||||
(void) setsignal(SIGTERM, sig_handler);
|
||||
(void) setsignal(SIGINT, sig_handler);
|
||||
(void) setsignal(SIGPIPE, SIG_IGN);
|
||||
}
|
||||
|
||||
// Cooperate with nohup(1).
|
||||
if ( (oldhandler = setsignal(SIGHUP, sig_handler)) != SIG_DFL )
|
||||
(void) setsignal(SIGHUP, oldhandler);
|
||||
|
||||
if ( dns_type == DNS_PRIME )
|
||||
{
|
||||
dns_mgr->Verify();
|
||||
dns_mgr->Resolve();
|
||||
|
||||
if ( ! dns_mgr->Save() )
|
||||
reporter->FatalError("can't update DNS cache");
|
||||
|
||||
mgr.Drain();
|
||||
delete dns_mgr;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// Print the ID.
|
||||
if ( options.identifier_to_print )
|
||||
{
|
||||
ID* id = global_scope()->Lookup(*options.identifier_to_print);
|
||||
if ( ! id )
|
||||
reporter->FatalError("No such ID: %s\n", options.identifier_to_print->data());
|
||||
|
||||
ODesc desc;
|
||||
desc.SetQuotes(true);
|
||||
desc.SetIncludeStats(true);
|
||||
id->DescribeExtended(&desc);
|
||||
|
||||
fprintf(stdout, "%s\n", desc.Description());
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if ( profiling_interval > 0 )
|
||||
{
|
||||
profiling_logger = new ProfileLogger(profiling_file->AsFile(),
|
||||
profiling_interval);
|
||||
|
||||
if ( segment_profiling )
|
||||
segment_logger = profiling_logger;
|
||||
}
|
||||
|
||||
if ( ! reading_live && ! reading_traces )
|
||||
// Set up network_time to track real-time, since
|
||||
// we don't have any other source for it.
|
||||
net_update_time(current_time());
|
||||
|
||||
EventHandlerPtr zeek_init = internal_handler("zeek_init");
|
||||
if ( zeek_init ) //### this should be a function
|
||||
mgr.Enqueue(zeek_init, zeek::Args{});
|
||||
|
||||
EventRegistry::string_list dead_handlers =
|
||||
event_registry->UnusedHandlers();
|
||||
|
||||
if ( ! dead_handlers.empty() && check_for_unused_event_handlers )
|
||||
{
|
||||
for ( const string& handler : dead_handlers )
|
||||
reporter->Warning("event handler never invoked: %s", handler.c_str());
|
||||
}
|
||||
|
||||
// Enable LeakSanitizer before zeek_init() and even before executing
|
||||
// top-level statements. Even though it's not bad if a leak happens only
|
||||
// once at initialization, we have to assume that script-layer code causing
|
||||
// such a leak can be placed in any arbitrary event handler and potentially
|
||||
// cause more severe problems.
|
||||
ZEEK_LSAN_ENABLE();
|
||||
|
||||
if ( stmts )
|
||||
{
|
||||
stmt_flow_type flow;
|
||||
Frame f(current_scope()->Length(), nullptr, nullptr);
|
||||
g_frame_stack.push_back(&f);
|
||||
|
||||
try
|
||||
{
|
||||
stmts->Exec(&f, flow);
|
||||
}
|
||||
catch ( InterpreterException& )
|
||||
{
|
||||
reporter->FatalError("failed to execute script statements at top-level scope");
|
||||
}
|
||||
|
||||
g_frame_stack.pop_back();
|
||||
}
|
||||
|
||||
if ( options.ignore_checksums )
|
||||
ignore_checksums = 1;
|
||||
|
||||
if ( zeek_script_loaded )
|
||||
{
|
||||
// Queue events reporting loaded scripts.
|
||||
for ( std::list<ScannedFile>::iterator i = files_scanned.begin(); i != files_scanned.end(); i++ )
|
||||
{
|
||||
if ( i->skipped )
|
||||
continue;
|
||||
|
||||
mgr.Enqueue(zeek_script_loaded,
|
||||
make_intrusive<StringVal>(i->name.c_str()),
|
||||
val_mgr->Count(i->include_level)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
reporter->ReportViaEvents(true);
|
||||
|
||||
// Drain the event queue here to support the protocols framework configuring DPM
|
||||
mgr.Drain();
|
||||
|
||||
if ( reporter->Errors() > 0 && ! zeekenv("ZEEK_ALLOW_INIT_ERRORS") )
|
||||
reporter->FatalError("errors occurred while initializing");
|
||||
|
||||
broker_mgr->ZeekInitDone();
|
||||
reporter->ZeekInitDone();
|
||||
analyzer_mgr->DumpDebug();
|
||||
|
||||
have_pending_timers = ! reading_traces && timer_mgr->Size() > 0;
|
||||
|
||||
return {0, std::move(options)};
|
||||
}
|
||||
|
||||
int zeek::detail::cleanup(bool did_net_run)
|
||||
{
|
||||
if ( did_net_run )
|
||||
done_with_network();
|
||||
|
||||
net_delete();
|
||||
terminate_bro();
|
||||
|
||||
sqlite3_shutdown();
|
||||
|
||||
ERR_free_strings();
|
||||
EVP_cleanup();
|
||||
CRYPTO_cleanup_all_ex_data();
|
||||
|
||||
// Close files after net_delete(), because net_delete()
|
||||
// might write to connection content files.
|
||||
BroFile::CloseOpenFiles();
|
||||
|
||||
delete rule_matcher;
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue