Squash w Move falco_init() code to individual app actions

This commit is contained in:
Mark Stemm
2022-03-03 16:15:15 -08:00
parent 63123c405f
commit fcd67307f6
13 changed files with 752 additions and 0 deletions

View File

@@ -76,6 +76,8 @@ runnable_action::run_result act_init_falco_engine::run()
throw std::invalid_argument("The event source \"syscall\" and \"k8s_audit\" can not be disabled together");
}
app().state().engine->set_min_priority(app().state().config->m_min_priority);
return ret;
}

View File

@@ -0,0 +1,66 @@
/*
Copyright (C) 2022 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "list_fields.h"
namespace falco {
namespace app {
act_list_fields::act_list_fields(application &app)
: action(app), m_name("list fields"),
m_prerequsites({"load plugins"})
{
}
act_list_fields::~act_list_fields()
{
}
const std::string &act_list_fields::name()
{
return m_name;
}
const std::list<std::string> &act_list_fields::prerequsites()
{
return m_prerequsites;
}
runnable_action::run_result act_list_fields::run()
{
run_result ret = {true, "", true};
if(app().options().list_fields)
{
if(app().options().list_source_fields != "" &&
!app().state().engine->is_source_valid(app().options().list_source_fields))
{
ret.success = false;
ret.errstr = "Value for --list must be a valid source type";
ret.proceed = false;
return ret;
}
app().state().engine->list_fields(app().options().list_source_fields, app().options().verbose, app().options().names_only);
ret.proceed = false;
}
return ret;
}
}; // namespace application
}; // namespace falco

View File

@@ -0,0 +1,45 @@
/*
Copyright (C) 2022 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#pragma once
#include <string>
#include "app_action.h"
namespace falco {
namespace app {
class act_list_fields : public action {
public:
act_list_fields(application &app);
virtual ~act_list_fields();
const std::string &name() override;
const std::list<std::string> &prerequsites() override;
run_result run() override;
private:
std::string m_name;
std::list<std::string> m_prerequsites;
};
}; // namespace application
}; // namespace falco

View File

@@ -63,6 +63,8 @@ runnable_action::run_result act_load_config::run()
#endif
}
app().state().config->m_buffered_outputs = !app().options().unbuffered_outputs;
return ret;
}

View File

@@ -0,0 +1,200 @@
/*
Copyright (C) 2022 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "load_rules_files.h"
namespace falco {
namespace app {
act_load_rules_files::act_load_rules_files(application &app)
: action(app), m_name("load rules files"),
m_prerequsites({"load plugins"})
{
}
act_load_rules_files::~act_load_rules_files()
{
}
const std::string &act_load_rules_files::name()
{
return m_name;
}
const std::list<std::string> &act_load_rules_files::prerequsites()
{
return m_prerequsites;
}
runnable_action::run_result act_load_rules_files::run()
{
run_result ret = {true, "", true};
string all_rules;
if (app().options().rules_filenames.size())
{
app().state().config->m_rules_filenames = app().options().rules_filenames;
}
if(app().state().config->m_rules_filenames.size() == 0)
{
ret.success = false;
ret.errstr = "You must specify at least one rules file/directory via -r or a rules_file entry in falco.yaml";
ret.proceed = false;
return ret;
}
falco_logger::log(LOG_DEBUG, "Configured rules filenames:\n");
for (auto filename : app().state().config->m_rules_filenames)
{
falco_logger::log(LOG_DEBUG, string(" ") + filename + "\n");
}
for (auto filename : app().state().config->m_rules_filenames)
{
falco_logger::log(LOG_INFO, "Loading rules from file " + filename + ":\n");
uint64_t required_engine_version;
try {
app().state().engine->load_rules_file(filename, app().options().verbose, app().options().all_events, required_engine_version);
}
catch(falco_exception &e)
{
ret.success = false;
ret.errstr = string("Could not load rules file ") + filename + ": " + e.what();
ret.proceed = false;
return ret;
}
app().state().required_engine_versions[filename] = required_engine_version;
}
// Ensure that all plugins are compatible with the loaded set of rules
for(auto &info : app().state().plugin_infos)
{
std::string required_version;
if(!app().state().engine->is_plugin_compatible(info.name, info.plugin_version.as_string(), required_version))
{
ret.success = false;
ret.errstr = std::string("Plugin ") + info.name + " version " + info.plugin_version.as_string() + " not compatible with required plugin version " + required_version;
ret.proceed = false;
}
}
for (auto substring : app().options().disabled_rule_substrings)
{
falco_logger::log(LOG_INFO, "Disabling rules matching substring: " + substring + "\n");
app().state().engine->enable_rule(substring, false);
}
if(app().options().disabled_rule_tags.size() > 0)
{
for(auto &tag : app().options().disabled_rule_tags)
{
falco_logger::log(LOG_INFO, "Disabling rules with tag: " + tag + "\n");
}
app().state().engine->enable_rule_by_tag(app().options().disabled_rule_tags, false);
}
if(app().options().enabled_rule_tags.size() > 0)
{
// Since we only want to enable specific
// rules, first disable all rules.
app().state().engine->enable_rule(all_rules, false);
for(auto &tag : app().options().enabled_rule_tags)
{
falco_logger::log(LOG_INFO, "Enabling rules with tag: " + tag + "\n");
}
app().state().engine->enable_rule_by_tag(app().options().enabled_rule_tags, true);
}
if(!app().options().all_events)
{
// For syscalls, see if any event types used by the
// loaded rules are ones with the EF_DROP_SIMPLE_CONS
// label.
check_for_ignored_events();
}
if (app().options().describe_all_rules)
{
app().state().engine->describe_rule(NULL);
ret.proceed = false;
return ret;
}
if (!app().options().describe_rule.empty())
{
app().state().engine->describe_rule(&(app().options().describe_rule));
ret.proceed = false;
return ret;
}
return ret;
}
void act_load_rules_files::check_for_ignored_events()
{
std::set<uint16_t> evttypes;
sinsp_evttables* einfo = app().state().inspector->get_event_info_tables();
const struct ppm_event_info* etable = einfo->m_event_info;
app().state().engine->evttypes_for_ruleset(application::s_syscall_source, evttypes);
// Save event names so we don't warn for both the enter and exit event.
std::set<std::string> warn_event_names;
for(auto evtnum : evttypes)
{
if(evtnum == PPME_GENERIC_E || evtnum == PPME_GENERIC_X)
{
continue;
}
if(!sinsp::simple_consumer_consider_evtnum(evtnum))
{
std::string name = etable[evtnum].name;
if(warn_event_names.find(name) == warn_event_names.end())
{
warn_event_names.insert(name);
}
}
}
// Print a single warning with the list of ignored events
if (!warn_event_names.empty())
{
std::string skipped_events;
bool first = true;
for (const auto& evtname : warn_event_names)
{
if (first)
{
skipped_events += evtname;
first = false;
} else
{
skipped_events += "," + evtname;
}
}
fprintf(stderr,"Rules match ignored syscall: warning (ignored-evttype):\n loaded rules match the following events: %s;\n but these events are not returned unless running falco with -A\n", skipped_events.c_str());
}
}
}; // namespace application
}; // namespace falco

View File

@@ -0,0 +1,47 @@
/*
Copyright (C) 2022 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#pragma once
#include <string>
#include "app_action.h"
namespace falco {
namespace app {
class act_load_rules_files : public action {
public:
act_load_rules_files(application &app);
virtual ~act_load_rules_files();
const std::string &name() override;
const std::list<std::string> &prerequsites() override;
run_result run() override;
private:
void check_for_ignored_events();
std::string m_name;
std::list<std::string> m_prerequsites;
};
}; // namespace application
}; // namespace falco

View File

@@ -0,0 +1,100 @@
/*
Copyright (C) 2022 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include <sys/utsname.h>
#include "falco_engine_version.h"
#include "print_support.h"
namespace falco {
namespace app {
act_print_support::act_print_support(application &app)
: action(app), m_name("print support"),
m_prerequsites({"load rules files"})
{
}
act_print_support::~act_print_support()
{
}
const std::string &act_print_support::name()
{
return m_name;
}
const std::list<std::string> &act_print_support::prerequsites()
{
return m_prerequsites;
}
runnable_action::run_result act_print_support::run()
{
run_result ret = {true, "", true};
if(app().options().print_support)
{
nlohmann::json support;
struct utsname sysinfo;
std::string cmdline;
if(uname(&sysinfo) != 0)
{
ret.success = false;
ret.errstr = string("Could not uname() to find system info: ") + strerror(errno);
ret.proceed = false;
return ret;
}
support["version"] = FALCO_VERSION;
support["system_info"]["sysname"] = sysinfo.sysname;
support["system_info"]["nodename"] = sysinfo.nodename;
support["system_info"]["release"] = sysinfo.release;
support["system_info"]["version"] = sysinfo.version;
support["system_info"]["machine"] = sysinfo.machine;
support["cmdline"] = app().state().cmdline;
support["engine_info"]["engine_version"] = FALCO_ENGINE_VERSION;
support["config"] = read_file(app().options().conf_filename);
support["rules_files"] = nlohmann::json::array();
for(auto filename : app().state().config->m_rules_filenames)
{
nlohmann::json finfo;
finfo["name"] = filename;
nlohmann::json variant;
variant["required_engine_version"] = app().state().required_engine_versions[filename];
variant["content"] = read_file(filename);
finfo["variants"].push_back(variant);
support["rules_files"].push_back(finfo);
}
printf("%s\n", support.dump().c_str());
}
return ret;
}
std::string act_print_support::read_file(std::string &filename)
{
std::ifstream t(filename);
std::string str((std::istreambuf_iterator<char>(t)),
std::istreambuf_iterator<char>());
return str;
}
}; // namespace application
}; // namespace falco

View File

@@ -0,0 +1,46 @@
/*
Copyright (C) 2022 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#pragma once
#include <string>
#include "app_action.h"
namespace falco {
namespace app {
class act_print_support : public action {
public:
act_print_support(application &app);
virtual ~act_print_support();
const std::string &name() override;
const std::list<std::string> &prerequsites() override;
run_result run() override;
private:
std::string read_file(std::string &filename);
std::string m_name;
std::list<std::string> m_prerequsites;
};
}; // namespace application
}; // namespace falco

View File

@@ -0,0 +1,68 @@
/*
Copyright (C) 2022 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "start_webserver.h"
#ifndef MINIMAL_BUILD
namespace falco {
namespace app {
act_start_webserver::act_start_webserver(application &app)
: action(app), m_name("start webserver"),
m_prerequsites({"init outputs"})
{
}
act_start_webserver::~act_start_webserver()
{
}
const std::string &act_start_webserver::name()
{
return m_name;
}
const std::list<std::string> &act_start_webserver::prerequsites()
{
return m_prerequsites;
}
runnable_action::run_result act_start_webserver::run()
{
run_result ret = {true, "", true};
if(app().options().trace_filename.empty() && app().state().config->m_webserver_enabled && app().state().enabled_sources.find(application::s_k8s_audit_source) != app().state().enabled_sources.end())
{
std::string ssl_option = (app().state().config->m_webserver_ssl_enabled ? " (SSL)" : "");
falco_logger::log(LOG_INFO, "Starting internal webserver, listening on port " + to_string(app().state().config->m_webserver_listen_port) + ssl_option + "\n");
m_webserver.init(app().state().config, app().state().engine, app().state().outputs);
m_webserver.start();
}
return ret;
}
void act_start_webserver::deinit()
{
m_webserver.stop();
}
#endif
}; // namespace application
}; // namespace falco

View File

@@ -0,0 +1,49 @@
/*
Copyright (C) 2022 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#pragma once
#include <string>
#include "app_action.h"
#include "webserver.h"
namespace falco {
namespace app {
class act_start_webserver : public action {
public:
act_start_webserver(application &app);
virtual ~act_start_webserver();
const std::string &name() override;
const std::list<std::string> &prerequsites() override;
run_result run() override;
void deinit() override;
private:
falco_webserver m_webserver;
std::string m_name;
std::list<std::string> m_prerequsites;
};
}; // namespace application
}; // namespace falco

View File

@@ -0,0 +1,77 @@
/*
Copyright (C) 2022 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "validate_rules_files.h"
namespace falco {
namespace app {
act_validate_rules_files::act_validate_rules_files(application &app)
: action(app), m_name("validate rules files"),
m_prerequsites({"load plugins"})
{
}
act_validate_rules_files::~act_validate_rules_files()
{
}
const std::string &act_validate_rules_files::name()
{
return m_name;
}
const std::list<std::string> &act_validate_rules_files::prerequsites()
{
return m_prerequsites;
}
runnable_action::run_result act_validate_rules_files::run()
{
run_result ret = {true, "", true};
if(app().options().validate_rules_filenames.size() > 0)
{
falco_logger::log(LOG_INFO, "Validating rules file(s):\n");
for(auto file : app().options().validate_rules_filenames)
{
falco_logger::log(LOG_INFO, " " + file + "\n");
}
for(auto file : app().options().validate_rules_filenames)
{
// Only include the prefix if there is more than one file
std::string prefix = (app().options().validate_rules_filenames.size() > 1 ? file + ": " : "");
try {
app().state().engine->load_rules_file(file, app().options().verbose, app().options().all_events);
}
catch(falco_exception &e)
{
ret.success = false;
ret.errstr = prefix + e.what();
ret.proceed = false;
return ret;
}
printf("%sOk\n", prefix.c_str());
}
falco_logger::log(LOG_INFO, "Ok\n");
}
return ret;
}
}; // namespace application
}; // namespace falco

View File

@@ -0,0 +1,45 @@
/*
Copyright (C) 2022 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#pragma once
#include <string>
#include "app_action.h"
namespace falco {
namespace app {
class act_validate_rules_files : public action {
public:
act_validate_rules_files(application &app);
virtual ~act_validate_rules_files();
const std::string &name() override;
const std::list<std::string> &prerequsites() override;
run_result run() override;
private:
std::string m_name;
std::list<std::string> m_prerequsites;
};
}; // namespace application
}; // namespace falco

View File

@@ -19,11 +19,16 @@ limitations under the License.
#include "app_actions/init_inspector.h"
#include "app_actions/init_outputs.h"
#include "app_actions/list_plugins.h"
#include "app_actions/list_fields.h"
#include "app_actions/load_config.h"
#include "app_actions/load_plugins.h"
#include "app_actions/load_rules_files.h"
#include "app_actions/print_help.h"
#include "app_actions/print_ignored_events.h"
#include "app_actions/print_support.h"
#include "app_actions/print_version.h"
#include "app_actions/start_grpc_server.h"
#include "app_actions/start_webserver.h"
#include "app_actions/validate_rules_files.h"