options from the input configuration that have changed.
-// FIXIT-J L include Snort2Lua commands
:leveloffset: 1
include::snort2lua_cmds.txt[]
:leveloffset: 0
new files name will automatically become the old file’s name with a .lua
extension. There is currently no way to specify or change that files name.
+* If a rule's action is a custom ruletype, that rule will silently be
+converted to the rultype's 'type'. No warnings or errors are currently
+emmitted. Additionally, the custom ruletypes outputs will be silently
+discarded.
Converter::Converter()
: state(nullptr),
- error(false)
+ error(false),
+ multiline_state(false)
{
}
}
orig_text.clear();
- reset_state();
+
+ if ( !multiline_state )
+ reset_state();
}
}
// tells this class whether to convert a file inline or pull all data into one file.
inline static void create_mult_rule_files(bool var)
{ convert_rules_mult_files = var; }
+
inline static bool include_create_rule()
{ return convert_rules_mult_files; }
{ return data_api.failed_conversions() || rule_api.failed_conversions(); }
+ inline void start_multiline_parsing()
+ { multiline_state = true; }
+
+ inline void end_multiline_parsing()
+ { multiline_state = false; }
+
inline DataApi& get_data_api()
{ return data_api; }
// the current parsing state.
ConversionState* state;
bool error;
+ bool multiline_state;
// initialize data class
return elems;
}
-const ConvertMap* find_map(const std::vector<const ConvertMap*> map, std::string keyword)
+const ConvertMap* find_map(
+ const std::vector<const ConvertMap*>& map,
+ const std::string& keyword)
{
for (const ConvertMap *p : map)
if (p->keyword.compare(0, p->keyword.size(), keyword) == 0)
return nullptr;
}
-Table* find_table(std::vector<Table*> vec, std::string name)
+const std::unique_ptr<const ConvertMap>& find_map(
+ const std::vector<std::unique_ptr<const ConvertMap> >& map,
+ const std::string& keyword)
+{
+ for (auto& p : map)
+ if (p->keyword.compare(0, p->keyword.size(), keyword) == 0)
+ return p;
+
+ static std::unique_ptr<const ConvertMap> np(nullptr);
+ return np;
+}
+
+
+Table* find_table(const std::vector<Table*>& vec, const std::string& name)
{
if(name.empty())
return nullptr;
#include <cctype>
#include <locale>
#include <sstream>
+#include <memory>
struct ConvertMap;
class Table;
std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems);
// Search through the vector for the map which matches keyword
-const ConvertMap* find_map(const std::vector<const ConvertMap*>, std::string keyword);
-Table* find_table(std::vector<Table*> vec, std::string name);
+
+Table* find_table(const std::vector<Table*>& vec, const std::string& name);
+const ConvertMap* find_map(const std::vector<const ConvertMap*>&, const std::string& keyword);
+const std::unique_ptr<const ConvertMap>& find_map(
+ const std::vector<std::unique_ptr<const ConvertMap> >&, const std::string& keyword);
// trim from begining
std::string <rim(std::string &s);
return true;
}
+ const std::unique_ptr<const ConvertMap>& ruletype =
+ util::find_map(keywords::ruletype_api, keyword);
+ if ( ruletype != nullptr )
+ {
+ cv.set_state(ruletype->ctor(cv));
+ return true;
+ }
+
data_api.failed_conversion(data_stream, keyword);
}
else
kws_output.cc
kws_paths.cc
kws_preprocessor.cc
+ kws_rate_filter.cc
kws_rule.cc
kws_rule_state.cc
- kws_rate_filter.cc
+ kws_ruletype.cc
kws_var.cc
kws_suppress.cc
keywords_api.h
kws_preprocessor.cc \
kws_rule.cc \
kws_rule_state.cc \
+kws_ruletype.cc \
kws_rate_filter.cc \
kws_var.cc \
kws_suppress.cc \
extern const ConvertMap* rate_filter_map;
extern const ConvertMap* reject_map;
extern const ConvertMap* rule_state_map;
+extern const ConvertMap* ruletype_map;
extern const ConvertMap* sblock_map;
extern const ConvertMap* sdrop_map;
extern const ConvertMap* suppress_map;
rate_filter_map,
reject_map,
rule_state_map,
+ ruletype_map,
sblock_map,
sdrop_map,
suppress_map,
#define KEYWORD_STATES_KEYWORDS_API_H
#include <vector>
+#include <memory>
#include "conversion_defines.h"
extern const std::vector<const ConvertMap*> keywords_api;
+// instantiated in kws_ruletype.cc
+extern const std::vector<std::unique_ptr<const ConvertMap> > ruletype_api;
+
} // namespace keywords
#include "conversion_state.h"
#include "helpers/converter.h"
#include "config_states/config_api.h"
+#include "keyword_states/keywords_api.h"
namespace keywords
{
+const std::vector<std::unique_ptr<const ConvertMap> > ruletype_api;
+
namespace {
+enum class ParseState
+{
+ NAME,
+ OPEN_BRACKET,
+ TYPE_KEYWORD,
+ TYPE_NAME,
+ OUTPUT_OR_BRACKET,
+ OUTPUT_ARGS
+};
+
class RuleType : public ConversionState
{
public:
- RuleType(Converter& c) : ConversionState(c) {};
+ RuleType(Converter& c) : ConversionState(c),
+ state(ParseState::NAME),
+ entire_line("ruletype")
+ {}
+
virtual ~RuleType() {};
virtual bool convert(std::istringstream& data);
+
+private:
+ ParseState state;
+ std::string name;
+ std::string type;
+ std::string entire_line;
};
} // namespace
-bool RuleType::convert(std::istringstream& data_stream)
+bool RuleType::convert(std::istringstream& stream)
{
- std::string keyword;
-#if 0
- if(data_stream >> keyword)
- {
+ std::string val;
- if(keyword.back() == ':')
- keyword.pop_back();
+ if ( !entire_line.empty() )
+ entire_line += "\n";
- const ConvertMap* map = util::find_map(rules::rule_api, keyword);
- if (map)
+ while ( stream >> val)
+ {
+ entire_line += " " + val;
+
+ switch (state)
{
- cv.set_state(map->ctor());
- return true;
- }
+ case ParseState::NAME:
+ cv.start_multiline_parsing();
+ name = val;
+ state = ParseState::OPEN_BRACKET;
+ break;
+
+ case ParseState::OPEN_BRACKET:
+ if ( val.compare("{") )
+ {
+ std::istringstream tmp(entire_line);
+ data_api.failed_conversion(tmp, val);
+ return false;
+ }
+ state = ParseState::TYPE_KEYWORD;
+ break;
+
+ case ParseState::TYPE_KEYWORD:
+ if ( val.compare("type") )
+ {
+ std::istringstream tmp(entire_line);
+ data_api.failed_conversion(tmp, val);
+ return false;
+ }
+ state = ParseState::TYPE_NAME;
+ break;
+
+ case ParseState::TYPE_NAME:
+ type = val;
+ state = ParseState::OUTPUT_OR_BRACKET;
+ break;
+
+ case ParseState::OUTPUT_OR_BRACKET:
+ if ( !val.compare("}") )
+ {
+ cv.end_multiline_parsing();
+
+ if ( util::find_map(ruletype_api, name) != nullptr )
+ {
+ std::istringstream tmp(entire_line);
+ data_api.failed_conversion(tmp, name + " -- defined multiple times in configuration file");
+ return false;
+ }
+
+ const ConvertMap* map = util::find_map(keywords_api, type);
+
+ if (map)
+ {
+
+ // using smart pointer to gaurantee new Map is deleted
+ const std::vector<std::unique_ptr<const ConvertMap> >& ruletype_map = ruletype_api;
+ std::unique_ptr<ConvertMap> new_map(new ConvertMap());
+ new_map->keyword = name;
+ new_map->ctor = map->ctor;
+ const_cast<std::vector<std::unique_ptr<const ConvertMap> >&>(
+ ruletype_map).push_back(std::move(new_map));
+ return true;
+ }
+ else
+ {
+ std::istringstream tmp(entire_line);
+ data_api.failed_conversion(tmp, "type " + type);
+ return false;
+ }
+ }
+ else if (!val.compare("output") )
+ {
+ state = ParseState::OUTPUT_ARGS;
+ }
+ else
+ {
+ std::istringstream tmp(entire_line);
+ data_api.failed_conversion(tmp, "type " + type);
+ return false;
+ }
+
+ break;
+
+ case ParseState::OUTPUT_ARGS:
+ // eat this argument. Do nothing.
+ break;
+ }
}
-#endif
- return false;
+
+
+ // OUTPUT_ARGS ate up the rest of the line.
+ // Now, start a new line.
+ if ( state == ParseState::OUTPUT_ARGS )
+ state = ParseState::OUTPUT_OR_BRACKET;
+
+ else if ( state == ParseState::TYPE_NAME )
+ return false;
+
+ return true;
}
/**************************
**************************/
static ConversionState* ctor(Converter& c)
-{ return new RuleType(); }
+{ return new RuleType(c); }
static const ConvertMap keyword_ruletype =
{
alert ip any any -> any any (msg:"TTL RULE OPTION"; ttl:7-; sid:11111114;)
alert tcp $EXTERNAL_NET $HTTP_PORTS -> $HOME_NET any (content:"fe, fe, fe, fe, fe, fe, fe,"; msg:"BROWSER-FIREFOX Mozilla Firefox Javascript engine function arguments memory corruption attempt"; flow:to_client,established; file_data; content:"|3B|i<25|3B|i++|29| fe += fe|3B|"; fast_pattern:only; content:"fu=new Function|28 0A|"; content:"fe, fe, fe, fe, fe, fe, fe,"; within:30; metadata:policy balanced-ips drop, policy security-ips drop, service http; reference:bugtraq,19181; reference:cve,2006-3806; classtype:attempted-user; sid:18262; rev:3;)
+
+
+ruletype suspicious
+{
+ type log
+}
+ruletype suspicious1
+{
+ type log
+ output log_tcpdump: suspicious.log
+}
+ruletype suspicious2
+{
+ type log
+ output log_tcpdump: suspicious.log
+ output unified2: filename merged.log
+}
+
+suspicious tcp any any -> any any (msg:"SUSPICIOUS ruletype"; sid:11111115;)
+suspicious1 tcp any any -> any any (msg:"SUSPICIOUS ruletype"; sid:11111116;)
+suspicious2 tcp any any -> any any (msg:"SUSPICIOUS ruletype"; sid:111111167;)
\ No newline at end of file