add_subdirectory(codecs)
add_subdirectory(control)
add_subdirectory(detection)
+add_subdirectory(dump_config)
add_subdirectory(events)
add_subdirectory(file_api)
add_subdirectory(filters)
$<TARGET_OBJECTS:control>
$<TARGET_OBJECTS:decompress>
$<TARGET_OBJECTS:detection>
+ $<TARGET_OBJECTS:dump_config>
$<TARGET_OBJECTS:events>
$<TARGET_OBJECTS:file_api>
$<TARGET_OBJECTS:file_connector>
if ( log_rule_group_details )
LogMessage("Service Based Rule Maps Done....\n");
- if ( !sc->validation_mode() or sc->mem_check() )
+ if ( !sc->test_mode() or sc->mem_check() )
{
unsigned c = compile_mpses(sc, can_build_mt(fp));
unsigned expected = mpse_count + offload_mpse_count;
--- /dev/null
+
+add_library ( dump_config OBJECT
+ config_data.cc
+ config_data.h
+ config_output.cc
+ config_output.h
+ json_config_output.cc
+ json_config_output.h
+ text_config_output.cc
+ text_config_output.h
+)
+
--- /dev/null
+//--------------------------------------------------------------------------
+// Copyright (C) 2020-2020 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation. You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//--------------------------------------------------------------------------
+// config_data.cc author Serhii Vlasiuk <svlasiuk@cisco.com>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "config_data.h"
+
+#include <cassert>
+
+using namespace snort;
+
+BaseConfigNode::BaseConfigNode(BaseConfigNode* p) :
+ parent(p)
+{}
+
+void BaseConfigNode::add_child_node(BaseConfigNode* node)
+{
+ assert(node);
+ children.push_back(node);
+}
+
+void BaseConfigNode::clear_nodes(BaseConfigNode* node)
+{
+ for ( auto& config_node : node->children )
+ clear_nodes(config_node);
+
+ delete node;
+}
+
+TreeConfigNode::TreeConfigNode(BaseConfigNode* parent_node,
+ const std::string& node_name, const Parameter::Type node_type) :
+ BaseConfigNode(parent_node), name(node_name), type(node_type)
+{}
+
+BaseConfigNode* TreeConfigNode::get_node(const std::string& name)
+{
+ for ( auto node : children )
+ {
+ if ( node->get_name() == name )
+ return node;
+ }
+ return nullptr;
+}
+
+ValueConfigNode::ValueConfigNode(BaseConfigNode* parent_node, const Value& val,
+ const std::string& name) :
+ BaseConfigNode(parent_node), value(val), custom_name(name)
+{}
+
+void ValueConfigNode::set_value(const snort::Value& v)
+{
+ if ( value.get_param_type() == Parameter::PT_MULTI )
+ {
+ std::string origin = value.get_origin_string();
+ if ( !multi_value && value.has_default() )
+ origin.clear();
+
+ origin += " ";
+ origin += v.get_origin_string();
+ value.set_origin(origin.c_str());
+ multi_value = true;
+ }
+ else
+ value = v;
+}
+
+BaseConfigNode* ValueConfigNode::get_node(const std::string& name)
+{
+ if ( !custom_name.empty() )
+ return ((custom_name == name) and value.has_default()) ? this : nullptr;
+ else
+ return value.is(name.c_str()) and value.has_default() ? this : nullptr;
+}
+
+ConfigData::ConfigData(const char* file)
+{
+ if ( file )
+ file_name = file;
+}
+
+void ConfigData::sort()
+{
+ config_trees.sort([](const BaseConfigNode* l, const BaseConfigNode* r)
+ { return l->get_name() < r->get_name(); });
+}
+
+void ConfigData::clear()
+{
+ for ( auto config_tree: config_trees )
+ BaseConfigNode::clear_nodes(config_tree);
+
+ config_trees.clear();
+}
+
+#ifdef UNIT_TEST
+#include <catch/snort_catch.h>
+
+TEST_CASE("add_nodes", "[ConfigData]")
+{
+ ConfigData config_data("test_file");
+
+ auto node_test1 = new TreeConfigNode(nullptr, "test1", Parameter::Type::PT_TABLE);
+ auto node_test2 = new TreeConfigNode(nullptr, "test2", Parameter::Type::PT_TABLE);
+
+ config_data.add_config_tree(node_test1);
+ config_data.add_config_tree(node_test2);
+
+ CHECK(config_data.config_trees.size() == 2);
+
+ config_data.clear();
+}
+
+TEST_CASE("clear_nodes", "[ConfigData]")
+{
+ ConfigData config_data("test_file");
+
+ auto node_test1 = new TreeConfigNode(nullptr, "test1", Parameter::Type::PT_TABLE);
+ auto node_test2 = new TreeConfigNode(nullptr, "test2", Parameter::Type::PT_TABLE);
+
+ config_data.add_config_tree(node_test1);
+ config_data.add_config_tree(node_test2);
+
+ config_data.clear();
+
+ CHECK(config_data.config_trees.size() == 0);
+}
+
+TEST_CASE("sort_nodes", "[ConfigData]")
+{
+ ConfigData config_data("test_file");
+
+ auto node_test1 = new TreeConfigNode(nullptr, "test1", Parameter::Type::PT_TABLE);
+ auto node_test2 = new TreeConfigNode(nullptr, "test2", Parameter::Type::PT_TABLE);
+ auto node_test3 = new TreeConfigNode(nullptr, "test3", Parameter::Type::PT_TABLE);
+ auto node_test4 = new TreeConfigNode(nullptr, "test4", Parameter::Type::PT_TABLE);
+
+ config_data.add_config_tree(node_test2);
+ config_data.add_config_tree(node_test3);
+ config_data.add_config_tree(node_test4);
+ config_data.add_config_tree(node_test1);
+
+ CHECK(config_data.config_trees.front()->get_name() == "test2");
+ CHECK(config_data.config_trees.back()->get_name() == "test1");
+
+ config_data.sort();
+
+ CHECK(config_data.config_trees.front()->get_name() == "test1");
+ CHECK(config_data.config_trees.back()->get_name() == "test4");
+
+ config_data.clear();
+}
+
+TEST_CASE("tree_config_node", "[TreeConfigNode]")
+{
+ BaseConfigNode* parent_node = new TreeConfigNode(nullptr, "parent_node",
+ Parameter::Type::PT_TABLE);
+ BaseConfigNode* child_node = new TreeConfigNode(parent_node, "child_node",
+ Parameter::Type::PT_LIST);
+
+ parent_node->add_child_node(child_node);
+
+ SECTION("get_name")
+ {
+ CHECK(parent_node->get_name() == "parent_node");
+ CHECK(child_node->get_name() == "child_node");
+ }
+ SECTION("get_type")
+ {
+ CHECK(parent_node->get_type() == Parameter::Type::PT_TABLE);
+ CHECK(child_node->get_type() == Parameter::Type::PT_LIST);
+ }
+ SECTION("get_node")
+ {
+ CHECK(parent_node->get_node("child_node") == child_node);
+ CHECK(parent_node->get_node("other_node") == nullptr);
+ CHECK(child_node->get_node("child_node") == nullptr);
+ }
+ SECTION("get_parent_node")
+ {
+ CHECK(child_node->get_parent_node() == parent_node);
+ CHECK(parent_node->get_parent_node() == nullptr);
+ }
+ SECTION("get_children")
+ {
+ CHECK(parent_node->get_children().size() == 1);
+ CHECK(child_node->get_children().size() == 0);
+ }
+ SECTION("get_value")
+ {
+ CHECK(parent_node->get_value() == nullptr);
+ CHECK(child_node->get_value() == nullptr);
+ }
+
+ BaseConfigNode::clear_nodes(parent_node);
+}
+
+TEST_CASE("value_config_node", "[ValueConfigNode]")
+{
+ BaseConfigNode* parent_node = new TreeConfigNode(nullptr, "parent_node",
+ Parameter::Type::PT_TABLE);
+
+ const Parameter p_string("param_str", Parameter::PT_STRING, nullptr, nullptr,
+ "test param PT_STRING type");
+
+ const Parameter p_string_custom("param_str_custom", Parameter::PT_STRING, nullptr,
+ "custom_default", "test param PT_STRING type with custom name");
+
+ const Parameter p_bool_w_default("param_bool", Parameter::PT_BOOL, nullptr, "false",
+ "test param PT_BOOL type with default");
+
+ const Parameter p_multi_w_default("param_multi", Parameter::PT_MULTI,
+ "test1 | test2 | test3 | test4", "test2 test3", "test param PT_MULTI type with default");
+
+ Value val_str("test_str");
+ val_str.set(&p_string);
+
+ Value val_str_custom("test_str_custom");
+ val_str_custom.set(&p_string_custom);
+
+ Value val_bool(true);
+ val_bool.set(&p_bool_w_default);
+
+ Value val_multi("test2 test3");
+ val_multi.set(&p_multi_w_default);
+
+ BaseConfigNode* value_node_str = new ValueConfigNode(parent_node, val_str);
+ BaseConfigNode* value_node_bool = new ValueConfigNode(parent_node, val_bool);
+ BaseConfigNode* value_node_multi = new ValueConfigNode(parent_node, val_multi);
+ BaseConfigNode* value_node_custom_name = new ValueConfigNode(parent_node, val_str_custom,
+ "custom_name");
+
+ parent_node->add_child_node(value_node_str);
+ parent_node->add_child_node(value_node_bool);
+ parent_node->add_child_node(value_node_multi);
+ parent_node->add_child_node(value_node_custom_name);
+
+ SECTION("get_name")
+ {
+ CHECK(value_node_str->get_name() == "param_str");
+ CHECK(value_node_bool->get_name() == "param_bool");
+ CHECK(value_node_multi->get_name() == "param_multi");
+ CHECK(value_node_custom_name->get_name() == "custom_name");
+ }
+ SECTION("get_type")
+ {
+ CHECK(value_node_str->get_type() == Parameter::PT_STRING);
+ CHECK(value_node_bool->get_type() == Parameter::PT_BOOL);
+ CHECK(value_node_multi->get_type() == Parameter::PT_MULTI);
+ CHECK(value_node_custom_name->get_type() == Parameter::PT_STRING);
+ }
+ SECTION("get_node")
+ {
+ CHECK(parent_node->get_node("param_str") == value_node_str);
+ CHECK(parent_node->get_node("param_bool") == value_node_bool);
+ CHECK(parent_node->get_node("param_multi") == value_node_multi);
+ CHECK(parent_node->get_node("custom_name") == value_node_custom_name);
+
+ CHECK(value_node_str->get_node("param_str") == nullptr);
+ CHECK(value_node_bool->get_node("param_bool") == value_node_bool);
+ CHECK(value_node_multi->get_node("param_multi") == value_node_multi);
+ CHECK(value_node_custom_name->get_node("custom_name") == value_node_custom_name);
+ }
+ SECTION("get_parent_node")
+ {
+ CHECK(value_node_str->get_parent_node() == parent_node);
+ CHECK(value_node_bool->get_parent_node() == parent_node);
+ CHECK(value_node_multi->get_parent_node() == parent_node);
+ CHECK(value_node_custom_name->get_parent_node() == parent_node);
+ }
+ SECTION("get_children")
+ {
+ CHECK(parent_node->get_children().size() == 4);
+ CHECK(value_node_multi->get_children().size() == 0);
+ CHECK(value_node_str->get_children().size() == 0);
+ CHECK(value_node_bool->get_children().size() == 0);
+ CHECK(value_node_custom_name->get_children().size() == 0);
+ }
+ SECTION("get_value")
+ {
+ CHECK(value_node_str->get_value()->get_origin_string() == "test_str");
+ CHECK(value_node_bool->get_value()->get_bool() == true);
+ CHECK(value_node_multi->get_value()->get_origin_string() == "test2 test3");
+ CHECK(value_node_custom_name->get_value()->get_origin_string() == "test_str_custom");
+ }
+
+ Value new_val_str("new_value");
+ value_node_str->set_value(new_val_str);
+
+ Value new_custom_val_str("new_custom_value");
+ value_node_custom_name->set_value(new_custom_val_str);
+
+ Value new_val_bool(false);
+ value_node_bool->set_value(new_val_bool);
+
+ Value new_val1_multi("test1");
+ value_node_multi->set_value(new_val1_multi);
+
+ Value new_val2_multi("test2");
+ value_node_multi->set_value(new_val2_multi);
+
+ Value new_val3_multi("test3");
+ value_node_multi->set_value(new_val3_multi);
+
+ SECTION("get_value_after_update")
+ {
+ CHECK(value_node_str->get_value()->get_origin_string() == "new_value");
+ CHECK(value_node_bool->get_value()->get_bool() == false);
+ CHECK(value_node_multi->get_value()->get_origin_string() == "test1 test2 test3");
+ CHECK(value_node_custom_name->get_value()->get_origin_string() == "new_custom_value");
+ }
+
+ BaseConfigNode::clear_nodes(parent_node);
+}
+
+#endif
+
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
-// config_tree.h author Serhii Vlasiuk <svlasiuk@cisco.com>
+// config_data.h author Serhii Vlasiuk <svlasiuk@cisco.com>
-#ifndef CONFIG_TREE_H
-#define CONFIG_TREE_H
+#ifndef CONFIG_DATA_H
+#define CONFIG_DATA_H
#include <list>
class BaseConfigNode;
-using ChildrenNodes = std::list<BaseConfigNode*>;
-
-class ConfigTextFormat
-{
-public:
- static void print(const BaseConfigNode* parent, const std::string& config_name);
-};
+using ConfigTrees = std::list<BaseConfigNode*>;
class BaseConfigNode
{
virtual std::string get_name() const = 0;
virtual snort::Parameter::Type get_type() const = 0;
virtual BaseConfigNode* get_node(const std::string& name) = 0;
- virtual std::string data() const { return ""; }
virtual void set_value(const snort::Value&) {}
+ virtual const snort::Value* get_value() const { return nullptr; }
- const ChildrenNodes& get_children() const
+ const ConfigTrees& get_children() const
{ return children; }
BaseConfigNode* get_parent_node() const
static void clear_nodes(BaseConfigNode* root);
protected:
- ChildrenNodes children;
+ ConfigTrees children;
BaseConfigNode* parent = nullptr;
};
class ValueConfigNode : public BaseConfigNode
{
public:
- ValueConfigNode(BaseConfigNode* parent, const snort::Value& value);
+ ValueConfigNode(BaseConfigNode* parent, const snort::Value& value,
+ const std::string& name = "");
private:
virtual std::string get_name() const override
- { return value.get_name(); }
+ { return !custom_name.empty() ? custom_name : value.get_name(); }
virtual snort::Parameter::Type get_type() const override
{ return value.get_param_type(); }
- virtual std::string data() const override
- { return value.get_origin_string(); }
-
- virtual void set_value(const snort::Value& v) override
- { value = v; }
+ virtual const snort::Value* get_value() const override
+ { return &value; }
+ virtual void set_value(const snort::Value& v) override;
virtual BaseConfigNode* get_node(const std::string& name) override;
private:
snort::Value value;
+ bool multi_value = false;
+ std::string custom_name;
+};
+
+class ConfigData
+{
+public:
+ ConfigData(const char* file_name);
+
+ void add_config_tree(BaseConfigNode* root)
+ { config_trees.push_back(root); }
+
+ void sort();
+ void clear();
+
+public:
+ std::string file_name;
+ ConfigTrees config_trees;
};
-#endif // CONFIG_TREE_H
+#endif // CONFIG_DATA_H
--- /dev/null
+//--------------------------------------------------------------------------
+// Copyright (C) 2020-2020 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation. You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//--------------------------------------------------------------------------
+// config_output.cc author Serhii Vlasiuk <svlasiuk@cisco.com>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "config_output.h"
+
+#include "config_data.h"
+
+void ConfigOutput::dump_config(ConfigData& config_data)
+{
+ config_data.sort();
+ dump(config_data);
+ config_data.clear();
+}
+
--- /dev/null
+//--------------------------------------------------------------------------
+// Copyright (C) 2020-2020 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation. You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//--------------------------------------------------------------------------
+// config_output.h author Serhii Vlasiuk <svlasiuk@cisco.com>
+
+#ifndef CONFIG_OUTPUT_H
+#define CONFIG_OUTPUT_H
+
+class ConfigData;
+
+class ConfigOutput
+{
+public:
+ ConfigOutput() = default;
+ virtual ~ConfigOutput() = default;
+
+ void dump_config(ConfigData&);
+
+private:
+ virtual void dump(const ConfigData&) = 0;
+};
+
+#endif // CONFIG_OUTPUT_H
+
--- /dev/null
+This directory contains classes related to Snort configuration dump.
+
+Snort supports dumping config into a file for JSON and text formats.
+
+* ConfigData
+
+ The ConfigData structure represents the internal config data of a particular Lua file.
+ A unique shell is associated with every base and targeted policy file.
+ Every module in a Lua file is represented by the General Tree.
+ The Tree node can be one of the following types: TreeConfigNode, ValueConfigNode.
+ The TreeConfigNode represents a table or list.
+ The ValueConfigNode represents a config value itself.
+
+* ConfigOutput
+
+ The ConfigOutput class is a base class that encapsulates dumping config into a file.
+ Pure virtual function dump() should be overridden by derived classes for particular
+ output format.
+
+* JsonAllConfigOutput
+
+ The JsonAllConfigOutput class inherits from ConfigOutput and dumps base and targeted
+ policy file in JSON format.
+
+* TextConfigOutput
+
+ The TextConfigOutput class inherits from ConfigOutput and dumps base and targeted
+ policy file in text format.
+
--- /dev/null
+//--------------------------------------------------------------------------
+// Copyright (C) 2020-2020 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation. You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//--------------------------------------------------------------------------
+// json_config_output.cc author Serhii Vlasiuk <svlasiuk@cisco.com>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "json_config_output.h"
+
+#include "config_data.h"
+
+using namespace snort;
+
+JsonAllConfigOutput::JsonAllConfigOutput() :
+ ConfigOutput(), json(std::cout)
+{ json.open_array(); }
+
+JsonAllConfigOutput::~JsonAllConfigOutput()
+{ json.close_array(); }
+
+void JsonAllConfigOutput::dump(const ConfigData& config_data)
+{
+ json.open();
+ json.put("filename", config_data.file_name);
+ json.open("config");
+
+ for ( const auto config_tree: config_data.config_trees )
+ dump_modules(config_tree);
+
+ json.close();
+ json.close();
+}
+
+void JsonAllConfigOutput::dump_modules(const BaseConfigNode* node)
+{
+ Parameter::Type type = node->get_type();
+ if ( type == Parameter::PT_LIST )
+ json.open_array(node->get_name().c_str());
+ else if ( type == Parameter::PT_TABLE )
+ {
+ std::string name = node->get_name();
+ name.empty() ? json.open() : json.open(name.c_str());
+ }
+ else
+ dump_value(node);
+
+ for ( const auto n : node->get_children() )
+ dump_modules(n);
+
+ if ( type == Parameter::PT_LIST )
+ json.close_array();
+ else if ( type == Parameter::PT_TABLE )
+ json.close();
+}
+
+void JsonAllConfigOutput::dump_value(const BaseConfigNode* node)
+{
+ const Value* value = node->get_value();
+ if ( !value )
+ return;
+
+ switch ( node->get_type() )
+ {
+ case Parameter::PT_BOOL:
+ case Parameter::PT_IMPLIED:
+ value->get_bool() ? json.put_true(node->get_name().c_str()) :
+ json.put_false(node->get_name().c_str());
+ break;
+ case Parameter::PT_INT:
+ json.put(node->get_name().c_str(), value->get_long());
+ break;
+ case Parameter::PT_REAL:
+ {
+ std::string value_str = value->get_as_string();
+ auto pos = value_str.find(".");
+ int precision = 0;
+ if ( pos != std::string::npos )
+ precision = value_str.size() - pos - 1;
+
+ json.put(node->get_name().c_str(), value->get_real(), precision);
+ break;
+ }
+ default:
+ json.put(node->get_name().c_str(), value->get_origin_string());
+ break;
+ }
+}
+
--- /dev/null
+//--------------------------------------------------------------------------
+// Copyright (C) 2020-2020 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation. You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//--------------------------------------------------------------------------
+// json_config_output.h author Serhii Vlasiuk <svlasiuk@cisco.com>
+
+#ifndef JSON_CONFIG_OUTPUT_H
+#define JSON_CONFIG_OUTPUT_H
+
+#include "config_output.h"
+#include "helpers/json_stream.h"
+
+class BaseConfigNode;
+
+class JsonAllConfigOutput : public ConfigOutput
+{
+public:
+ JsonAllConfigOutput();
+ ~JsonAllConfigOutput() override;
+
+private:
+ void dump(const ConfigData&) override;
+
+ void dump_modules(const BaseConfigNode* node);
+ void dump_value(const BaseConfigNode* node);
+
+private:
+ JsonStream json;
+};
+
+#endif // JSON_CONFIG_OUTPUT_H
+
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
-// config_tree.cc author Serhii Vlasiuk <svlasiuk@cisco.com>
+// text_config_output.cc author Serhii Vlasiuk <svlasiuk@cisco.com>
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+#include "text_config_output.h"
-#include "config_tree.h"
+#include <iomanip>
+#include <iostream>
-#include <cassert>
-
-#include "log/messages.h"
+#include "config_data.h"
using namespace snort;
-void ConfigTextFormat::print(const BaseConfigNode* parent, const std::string& config_name)
+void TextConfigOutput::dump_value(const BaseConfigNode* node, const std::string& config_name)
+{
+ const Value* value = node->get_value();
+ if ( !value )
+ return;
+
+ if ( value->get_as_string().empty() )
+ return;
+
+ switch ( node->get_type() )
+ {
+ case Parameter::PT_BOOL:
+ case Parameter::PT_IMPLIED:
+ {
+ std::string value_str = value->get_bool() ? "true" : "false";
+ std::cout << config_name << "=" << value_str << std::endl;
+ break;
+ }
+ case Parameter::PT_INT:
+ std::cout << config_name << "=" << value->get_long() << std::endl;
+ break;
+ case Parameter::PT_REAL:
+ std::cout << config_name << "=" << value->get_real() << std::endl;
+ break;
+ default:
+ std::cout << config_name << "=" << std::quoted(value->get_origin_string()) << std::endl;
+ break;
+ }
+}
+
+void TextConfigOutput::dump_modules(const BaseConfigNode* parent, const std::string& config_name)
{
static char buf[16];
int list_index = 0;
full_config_name += "]";
}
- print(node, full_config_name);
+ dump_modules(node, full_config_name);
}
- std::string config_data = parent->data();
- if ( !config_data.empty() )
- LogConfig("%s=%s\n", config_name.c_str(), config_data.c_str());
-}
-
-BaseConfigNode::BaseConfigNode(BaseConfigNode* p) :
- parent(p)
-{}
-
-void BaseConfigNode::add_child_node(BaseConfigNode* node)
-{
- assert(node);
- children.push_back(node);
-}
-
-void BaseConfigNode::clear_nodes(BaseConfigNode* node)
-{
- for ( auto& config_node : node->children )
- clear_nodes(config_node);
-
- delete node;
+ dump_value(parent, config_name);
}
-TreeConfigNode::TreeConfigNode(BaseConfigNode* parent_node,
- const std::string& node_name, const Parameter::Type node_type) :
- BaseConfigNode(parent_node), name(node_name), type(node_type)
-{}
-
-BaseConfigNode* TreeConfigNode::get_node(const std::string& name)
+void TextConfigOutput::dump(const ConfigData& config_data)
{
- for ( auto node : children )
- {
- if ( node->get_name() == name )
- return node;
- }
- return nullptr;
-}
-
-ValueConfigNode::ValueConfigNode(BaseConfigNode* parent_node, const Value& val) :
- BaseConfigNode(parent_node), value(val)
-{}
+ std::string output("consolidated config for ");
+ output += config_data.file_name;
+ std::cout << output << std::endl;
-BaseConfigNode* ValueConfigNode::get_node(const std::string& name)
-{
- return value.is(name.c_str()) and value.has_default() ? this : nullptr;
+ for ( const auto config_tree: config_data.config_trees )
+ dump_modules(config_tree, config_tree->get_name());
}
--- /dev/null
+//--------------------------------------------------------------------------
+// Copyright (C) 2020-2020 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation. You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//--------------------------------------------------------------------------
+// text_config_output.h author Serhii Vlasiuk <svlasiuk@cisco.com>
+
+#ifndef TEXT_CONFIG_OUTPUT_H
+#define TEXT_CONFIG_OUTPUT_H
+
+#include <string>
+
+#include "config_output.h"
+
+class BaseConfigNode;
+
+class TextConfigOutput : public ConfigOutput
+{
+public:
+ TextConfigOutput() = default;
+
+private:
+ void dump(const ConfigData&) override;
+
+ void dump_modules(const BaseConfigNode* parent, const std::string& config_name);
+ void dump_value(const BaseConfigNode* parent, const std::string& config_name);
+};
+
+#endif // TEXT_CONFIG_OUTPUT_H
+
return true;
}
-const char* Value::get_as_string()
+std::string Value::get_as_string() const
{
+ std::string value_str = str;
switch ( type )
{
case VT_BOOL:
- str = num ? "true" : "false";
+ value_str = num ? "true" : "false";
break;
case VT_NUM:
- ss = new stringstream;
- *ss << num;
- str = ss->str();
+ {
+ stringstream tmp;
+ tmp << std::fixed;
+ tmp << num;
+ value_str = tmp.str();
+ auto dot_pos = value_str.find('.');
+ auto pos = value_str.find_last_not_of("0");
+ if ( pos == dot_pos )
+ --pos;
+
+ value_str = value_str.substr(0, pos + 1);
break;
+ }
default:
break;
}
- return str.c_str();
+ return value_str;
}
std::string Value::get_origin_string() const
{
+ if ( origin_str.empty() )
+ return "";
+
std::string value;
std::string token;
}
value.erase(value.size() - 1);
- if ( param && param->type != Parameter::PT_BOOL
- && param->type != Parameter::PT_REAL
- && param->type != Parameter::PT_INT
- && param->type != Parameter::PT_IMPLIED )
- {
- value.insert(0, "'");
- value.insert(value.length(), "'");
- }
-
return value;
}
TEST_CASE("get as string", "[Value]")
{
- const char* str_val;
bool bool_val = true;
double num_val = 6;
Value test_val(bool_val);
- str_val = (const char *)test_val.get_as_string();
- REQUIRE(str_val != nullptr);
- CHECK((strcmp(str_val,"true")==0));
+ CHECK((strcmp(test_val.get_as_string().c_str(),"true") == 0));
test_val.set(num_val);
- str_val = (const char *)test_val.get_as_string();
- REQUIRE(str_val != nullptr);
- CHECK((strcmp(str_val,"6")==0));
+ CHECK((strcmp(test_val.get_as_string().c_str(),"6") == 0));
+
+ test_val.set(1234.2);
+ CHECK((strcmp(test_val.get_as_string().c_str(),"1234.2") == 0));
+
+ test_val.set(123456.0893);
+ CHECK((strcmp(test_val.get_as_string().c_str(),"123456.0893") == 0));
+
+ test_val.set(0.0803);
+ CHECK((strcmp(test_val.get_as_string().c_str(),"0.0803") == 0));
}
enum ValueType { VT_BOOL, VT_NUM, VT_STR };
Value(bool b)
- { set(b); set_origin(b); }
+ { set(b); }
Value(double d)
- { set(d); set_origin(d); }
+ { set(d); }
Value(const char* s)
{ set(s); set_origin(s); }
void set(bool b)
{ type = VT_BOOL; num = b ? 1 : 0; str.clear(); }
- void set_origin(bool val)
- { origin_str = val ? "true" : "false"; }
-
void set(double d)
{ type = VT_NUM; num = d; str.clear(); }
- void set_origin(double val)
- {
- auto temp = new std::stringstream;
- *temp << val;
- origin_str = temp->str();
- delete temp;
- }
-
void set(long n)
{ set((double)n); }
const char* get_string() const
{ return str.c_str(); }
- const char* get_as_string();
+ std::string get_as_string() const;
Parameter::Type get_param_type() const;
std::string get_origin_string() const;
CHECK(ss.str() == x);
}
+ SECTION("backslash")
+ {
+ const char* s = R"-(content:\test\;)-";
+ const char* x = R"-("content:\\test\\;")-";
+ js.put(nullptr, s);
+ CHECK(ss.str() == x);
+ }
+
SECTION("embedded quotes")
{
const char* s = R"-(content:"foo";)-";
CHECK(ss.str() == x);
}
+ SECTION("special characters")
+ {
+ const char* s = R"-(content: / " \ $ # ! @ % ^ & * ' \b\f\t\r\n . )-";
+ const char* x = R"-("content: / \" \\ $ # ! @ % ^ & * ' \\b\\f\\t\\r\\n . ")-";
+ js.put(nullptr, s);
+ CHECK(ss.str() == x);
+ }
+
SECTION("null list")
{
js.put("i");
va_end(ap);
}
-void LogConfig(const char* format, ...)
-{
- va_list ap;
- va_start(ap, format);
-
- WriteLogMessage(stdout, false, format, ap);
-
- va_end(ap);
-}
-
/*
* Function: WarningMessage(const char *, ...)
*
SO_PUBLIC void ReloadError(const char*, ...) __attribute__((format (printf, 1, 2)));
[[noreturn]] SO_PUBLIC void ParseAbort(const char*, ...) __attribute__((format (printf, 1, 2)));
-SO_PUBLIC void LogConfig(const char*, ...) __attribute__((format (printf, 1, 2)));
SO_PUBLIC void LogMessage(const char*, ...) __attribute__((format (printf, 1, 2)));
SO_PUBLIC void LogMessage(FILE*, const char*, ...) __attribute__((format (printf, 2, 3)));
SO_PUBLIC void WarningMessage(const char*, ...) __attribute__((format (printf, 1, 2)));
return false;
}
- if ( sc->dump_config() )
- return false;
-
if ( just_validate(sc) )
{
LogMessage("\nSnort successfully validated the configuration (with %u warnings).\n",
analyzer.h
analyzer_command.cc
build.h
- config_tree.cc
- config_tree.h
help.cc
help.h
modules.cc
mechanism for managing CPU affinity of threads, but it will be used in the
future for NUMA (non-uniform memory access) awareness among other things.
-Consolidated Config output
-
-The snort config parsed is stored as an internal tree structure within the Shell.
-A unique shell is associated with every base and targeted policy file.
-Every module in a lua file is represented by the General Tree.
-The Tree node can be one of the following types: TreeConfigNode, ValueConfigNode.
-The TreeConfigNode represents a table or list.
-The ValueConfigNode represents a config value itself.
#include <cassert>
#include <stdexcept>
-#include "config_tree.h"
+#include "dump_config/config_output.h"
#include "log/messages.h"
#include "lua/lua.h"
#include "main/policy.h"
string Shell::fatal;
std::stack<Shell*> Shell::current_shells;
+ConfigOutput* Shell::s_config_output = nullptr;
+BaseConfigNode* Shell::s_current_node = nullptr;
+bool Shell::s_close_table = true;
// FIXIT-M Shell::panic() works on Linux but on OSX we can't throw from lua
// to C++. unprotected lua calls could be wrapped in a pcall to ensure lua
return nullptr;
}
+void Shell::set_config_output(ConfigOutput* output)
+{ s_config_output = output; }
+
+void Shell::clear_config_output()
+{
+ s_config_output = nullptr;
+ s_current_node = nullptr;
+}
+
bool Shell::is_whitelisted(const std::string& key)
{
Shell* sh = Shell::get_current_shell();
if ( p )
node_type = p->type;
+ if ( node_type == Parameter::PT_MULTI )
+ {
+ s_close_table = false;
+ return;
+ }
+
if ( node_type == Parameter::PT_TABLE )
update_current_config_node(table_name);
else
void Shell::add_config_child_node(const std::string& node_name, snort::Parameter::Type type)
{
- Shell* sh = Shell::get_current_shell();
-
- if ( !sh )
+ if ( !s_current_node )
return;
std::string name;
- if ( sh->s_current_node->get_name() != node_name )
+ if ( s_current_node->get_name() != node_name )
name = node_name;
- auto new_node = new TreeConfigNode(sh->s_current_node, name, type);
- sh->s_current_node->add_child_node(new_node);
- sh->s_current_node = new_node;
+ auto new_node = new TreeConfigNode(s_current_node, name, type);
+ s_current_node->add_child_node(new_node);
+ s_current_node = new_node;
}
void Shell::add_config_root_node(const std::string& root_name, snort::Parameter::Type node_type)
return;
sh->s_current_node = new TreeConfigNode(nullptr, root_name, node_type);
- sh->config_trees.push_back(sh->s_current_node);
+ sh->config_data.add_config_tree(sh->s_current_node);
}
void Shell::update_current_config_node(const std::string& node_name)
{
- Shell* sh = Shell::get_current_shell();
-
- if ( !sh )
- return;
-
- if ( !sh->s_current_node )
+ if ( !s_current_node )
return;
// node has been added during setting default options
if ( !node_name.empty() )
- sh->s_current_node = sh->s_current_node->get_node(node_name);
- else if ( sh->s_current_node->get_parent_node() and
- sh->s_current_node->get_type() == Parameter::PT_TABLE and
- !sh->s_current_node->get_name().empty() )
- sh->s_current_node = sh->s_current_node->get_parent_node();
+ s_current_node = s_current_node->get_node(node_name);
+ else if ( s_current_node->get_parent_node() and
+ s_current_node->get_type() == Parameter::PT_TABLE and
+ !s_current_node->get_name().empty() )
+ s_current_node = s_current_node->get_parent_node();
- assert(sh->s_current_node);
+ assert(s_current_node);
}
void Shell::config_close_table()
{
- Shell* sh = Shell::get_current_shell();
-
- if ( !sh )
+ if ( !s_close_table )
+ {
+ s_close_table = true;
return;
+ }
- if ( !sh->s_current_node )
+ if ( !s_current_node )
return;
- sh->s_current_node = sh->s_current_node->get_parent_node();
+ s_current_node = s_current_node->get_parent_node();
}
-void Shell::set_config_value(const snort::Value& value)
+void Shell::set_config_value(const std::string& fqn, const snort::Value& value)
{
- Shell* sh = Shell::get_current_shell();
-
- if ( !sh )
- return;
-
- if ( !sh->s_current_node )
+ if ( !s_current_node )
return;
- // lua interpreter does not call open_table for simple list items like (string)
- // we have to add tree node for this item too
- if ( sh->s_current_node->get_type() == Parameter::PT_LIST )
+ // lua interpreter does not call open_table for simple list items like (string) or
+ // special rule_state list items
+ // We have to add tree node for this item too
+ if ( s_current_node->get_type() == Parameter::PT_LIST )
{
- add_config_child_node("", Parameter::PT_TABLE);
- sh->s_current_node->add_child_node(new ValueConfigNode(sh->s_current_node, value));
- sh->s_current_node = sh->s_current_node->get_parent_node();
+ auto node = s_current_node->get_node("");
+ if ( !node || s_current_node->get_name().find(":") == std::string::npos )
+ {
+ node = new TreeConfigNode(s_current_node, "", Parameter::PT_TABLE);
+ s_current_node->add_child_node(node);
+ }
+
+ node->add_child_node(new ValueConfigNode(node, value));
return;
}
-
+
BaseConfigNode* child_node = nullptr;
- for ( auto node : sh->s_current_node->get_children() )
+
+ std::string custom_name;
+ if ( strchr(value.get_name(), '$') )
+ custom_name = fqn.substr(fqn.find_last_of(".") + 1);
+
+ for ( auto node : s_current_node->get_children() )
{
- child_node = node->get_node(value.get_name());
+ if ( (node->get_type() == Parameter::PT_MULTI) and (node->get_name() == value.get_name()) )
+ {
+ child_node = node;
+ break;
+ }
+
+ if ( !custom_name.empty() )
+ child_node = node->get_node(custom_name);
+ else
+ child_node = node->get_node(value.get_name());
+
if ( child_node )
break;
}
if ( !child_node )
- sh->s_current_node->add_child_node(new ValueConfigNode(sh->s_current_node, value));
+ s_current_node->add_child_node(new ValueConfigNode(s_current_node, value, custom_name));
else
child_node->set_value(value);
}
// public methods
//-------------------------------------------------------------------------
-Shell::Shell(const char* s, bool load_defaults)
+Shell::Shell(const char* s, bool load_defaults) :
+ config_data(s)
{
// FIXIT-M should wrap in Lua::State
lua = luaL_newstate();
void Shell::set_file(const char* s)
{
file = s;
+ config_data.file_name = file;
}
void Shell::set_overrides(const char* s)
clear_whitelist();
- if ( SnortConfig::get_conf()->dump_config() )
- {
- sort_config();
- print_config_text();
- clear_config_tree();
- }
+ auto config_output = Shell::get_current_shell()->s_config_output;
+ if ( config_output )
+ config_output->dump_config(config_data);
current_shells.pop();
//-------------------------------------------------------------------------
// private methods
//-------------------------------------------------------------------------
-void Shell::sort_config()
-{
- config_trees.sort([](const BaseConfigNode* l, const BaseConfigNode* r)
- { return l->get_name() < r->get_name(); });
-}
-
-void Shell::print_config_text() const
-{
- std::string output("consolidated config for ");
- output += file;
- LogConfig("%s\n", output.c_str());
-
- for ( const auto config_tree: config_trees )
- ConfigTextFormat::print(config_tree, config_tree->get_name());
-}
-
-void Shell::clear_config_tree()
-{
- for ( auto config_tree: config_trees )
- BaseConfigNode::clear_nodes(config_tree);
-
- config_trees.clear();
-}
void Shell::print_whitelist() const
{
#include <stack>
#include <string>
+#include "dump_config/config_data.h"
#include "framework/parameter.h"
struct lua_State;
class BaseConfigNode;
+class ConfigOutput;
namespace snort
{
static void config_open_table(bool is_root_node, bool is_list, int idx,
const std::string& table_name, const snort::Parameter* p);
- static void set_config_value(const snort::Value& value);
+ static void set_config_value(const std::string& fqn, const snort::Value& value);
static void add_config_child_node(const std::string& node_name, snort::Parameter::Type type);
static void update_current_config_node(const std::string& node_name = "");
static void config_close_table();
+ static void set_config_output(ConfigOutput* config_output);
+ static void clear_config_output();
private:
static void add_config_root_node(const std::string& root_name, snort::Parameter::Type type);
private:
static std::string fatal;
static std::stack<Shell*> current_shells;
+ static ConfigOutput* s_config_output;
+ static BaseConfigNode* s_current_node;
+ static bool s_close_table;
private:
void clear_whitelist()
void print_whitelist() const;
void whitelist_update(const char* keyword, bool is_prefix);
- void sort_config();
- void print_config_text() const;
- void clear_config_tree();
-
private:
bool loaded;
bool bootstrapped = false;
Whitelist whitelist;
Whitelist internal_whitelist;
Whitelist whitelist_prefixes;
- std::list<BaseConfigNode*> config_trees;
- BaseConfigNode* s_current_node = nullptr;
+ ConfigData config_data;
};
#endif
SFDAQ::term();
FileService::close();
- if ( !SnortConfig::get_conf()->validation_mode() ) // FIXIT-M ideally the check is in one place
+ if ( !SnortConfig::get_conf()->test_mode() ) // FIXIT-M ideally the check is in one place
PrintStatistics();
CloseLogger();
#include "detection/detection_engine.h"
#include "detection/fp_config.h"
#include "detection/fp_create.h"
+#include "dump_config/json_config_output.h"
+#include "dump_config/text_config_output.h"
#include "filters/detection_filter.h"
#include "filters/rate_filter.h"
#include "filters/sfrf.h"
return true;
}
+ConfigOutput* SnortConfig::create_config_output() const
+{
+ ConfigOutput* output = nullptr;
+
+ switch (dump_config_type)
+ {
+ case DUMP_CONFIG_JSON_ALL:
+ output = new JsonAllConfigOutput();
+ break;
+ case DUMP_CONFIG_TEXT:
+ output = new TextConfigOutput();
+ break;
+ default:
+ break;
+ }
+
+ return output;
+}
+
bool SnortConfig::tunnel_bypass_enabled(uint16_t proto) const
{
return !((tunnel_mask & proto) or SFDAQ::get_tunnel_bypass(proto));
RUN_FLAG__IP_FRAGS_ONLY = 0x08000000,
RUN_FLAG__DUMP_RULE_STATE = 0x10000000,
- RUN_FLAG__DUMP_CONFIG = 0x20000000,
};
enum OutputFlag
TUNNEL_VXLAN = 0x100
};
+enum DumpConfigType
+{
+ DUMP_CONFIG_NONE = 0,
+ DUMP_CONFIG_JSON_ALL,
+ DUMP_CONFIG_TEXT
+};
+
+class ConfigOutput;
class FastPatternConfig;
class RuleStateMap;
class TraceConfig;
bool cloned = false;
Plugins* plugins = nullptr;
SoRules* so_rules = nullptr;
+
+ DumpConfigType dump_config_type = DUMP_CONFIG_NONE;
private:
bool active_enabled = false;
std::list<ReloadResourceTuner*> reload_tuners;
{ return address_anomaly_check_enabled; }
// mode related
- bool dump_config() const
- { return run_flags & RUN_FLAG__DUMP_CONFIG; }
+ bool dump_config_mode() const
+ { return dump_config_type > DUMP_CONFIG_NONE; }
bool dump_msg_map() const
{ return run_flags & RUN_FLAG__DUMP_MSG_MAP; }
bool test_mode() const
{ return run_flags & RUN_FLAG__TEST; }
- bool validation_mode() const
- { return test_mode() or dump_config(); }
-
bool mem_check() const
- { return (run_flags & RUN_FLAG__MEM_CHECK) and !dump_config(); }
+ { return run_flags & RUN_FLAG__MEM_CHECK; }
bool daemon_mode() const
- { return (run_flags & RUN_FLAG__DAEMON) and !dump_config(); }
+ { return run_flags & RUN_FLAG__DAEMON; }
bool read_mode() const
{ return run_flags & RUN_FLAG__READ; }
bool get_default_rule_state() const;
+ ConfigOutput* create_config_output() const;
+
SO_PUBLIC bool tunnel_bypass_enabled(uint16_t proto) const;
// FIXIT-L snort_conf needed for static hash before initialized
{ "--dump-builtin-rules", Parameter::PT_STRING, "(optional)", nullptr,
"[<module prefix>] output stub rules for selected modules" },
+ { "--dump-config", Parameter::PT_SELECT, "all", nullptr,
+ "dump config in json format" },
+
{ "--dump-config-text", Parameter::PT_IMPLIED, nullptr, nullptr,
"dump config in text format" },
else if ( v.is("--dump-builtin-rules") )
dump_builtin_rules(sc, v.get_string());
+ else if ( v.is("--dump-config") )
+ {
+ sc->set_quiet(true);
+ sc->run_flags |= RUN_FLAG__TEST;
+ if ( v.get_as_string() == "all" )
+ sc->dump_config_type = DUMP_CONFIG_JSON_ALL;
+ }
+
else if ( v.is("--dump-config-text") )
{
- sc->run_flags |= RUN_FLAG__DUMP_CONFIG;
- sc->set_quiet(true);
+ sc->set_quiet(true);
+ sc->run_flags |= RUN_FLAG__TEST;
+ sc->dump_config_type = DUMP_CONFIG_TEXT;
}
else if ( v.is("--dump-dynamic-rules") )
static bool set_param(Module* mod, const char* fqn, Value& val)
{
- if ( s_config->dump_config() )
- Shell::set_config_value(val);
+ if ( s_config->dump_config_mode() )
+ Shell::set_config_value(fqn, val);
if ( !mod->verified_set(fqn, val, s_config) )
{
{
const Parameter* table_item_params = reinterpret_cast<const Parameter*>(p->range);
- if ( s_config->dump_config() )
+ if ( s_config->dump_config_mode() )
Shell::add_config_child_node(get_sub_table(fqn), p->type);
if ( !begin(m, table_item_params, fqn.c_str(), idx, depth+1) )
}
++p;
}
- if ( s_config->dump_config() )
+ if ( s_config->dump_config_mode() )
Shell::update_current_config_node();
return true;
}
s_current = unique_key;
}
- if ( s_config->dump_config() )
+ if ( s_config->dump_config_mode() )
{
std::string table_name = get_sub_table(s);
bool is_top_level = false;
s_type.clear();
}
- if ( s_config->dump_config() )
+ if ( s_config->dump_config_mode() )
Shell::config_close_table();
}
#include "detection/fp_config.h"
#include "detection/rules.h"
#include "detection/sfrim.h"
+#include "dump_config/config_output.h"
#include "filters/detection_filter.h"
#include "filters/rate_filter.h"
#include "filters/sfthreshold.h"
sc->output_flags = boot_conf->output_flags;
sc->logging_flags = boot_conf->logging_flags;
sc->tweaks = boot_conf->tweaks;
+ sc->dump_config_type = boot_conf->dump_config_type;
VarNode* tmp = boot_conf->var_list;
sh->set_file(fname);
}
+ bool parse_file_failed = false;
+ auto output = SnortConfig::get_conf()->create_config_output();
+ Shell::set_config_output(output);
for ( unsigned i = 0; true; i++ )
{
sh = sc->policy_map->get_shell(i);
set_policies(sc, sh);
if (!parse_file(sc, sh, is_fatal, (i == 0)))
- return sc;
+ {
+ parse_file_failed = true;
+ break;
+ }
}
- set_default_policy(sc);
+ delete output;
+ Shell::clear_config_output();
+
+ if ( !parse_file_failed )
+ set_default_policy(sc);
+
return sc;
}
{
assert(trace_parser);
- if ( sc->dump_config() )
+ if ( sc->dump_config_mode() )
trace_parser->clear_traces();
else
{
switch ( log_output_type )
{
- case OUTPUT_TYPE_STDOUT:
- trace_parser->get_trace_config()->logger_factory = new StdoutLoggerFactory();
- break;
- case OUTPUT_TYPE_SYSLOG:
- trace_parser->get_trace_config()->logger_factory = new SyslogLoggerFactory();
- break;
- default:
- break;
+ case OUTPUT_TYPE_STDOUT:
+ trace_parser->get_trace_config()->logger_factory = new StdoutLoggerFactory();
+ break;
+ case OUTPUT_TYPE_SYSLOG:
+ trace_parser->get_trace_config()->logger_factory = new SyslogLoggerFactory();
+ break;
+ default:
+ break;
}
// "output=syslog" config override case
!trace_parser.set_traces(module_name, val) )
{
LogMessage("== invalid trace value is provided: %s.%s.%s = %s\n",
- root_element_key, module_name, val_name, val.get_as_string());
+ root_element_key, module_name, val_name, val.get_as_string().c_str());
parse_err = true;
}
!trace_parser.set_constraints(val) )
{
LogMessage("== invalid constraints value is provided: %s.%s = %s\n",
- root_element_key, val_name, val.get_as_string());
+ root_element_key, val_name, val.get_as_string().c_str());
parse_err = true;
}