From: Mike Stepanek (mstepane) Date: Tue, 14 Dec 2021 16:20:22 +0000 (+0000) Subject: Pull request #3204: snort2lua: fix conversion of variable sets X-Git-Tag: 3.1.19.0~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6eabac6583fb208bb541905d85e59f8810fd02db;p=thirdparty%2Fsnort3.git Pull request #3204: snort2lua: fix conversion of variable sets Merge in SNORT/snort3 from ~VHORBATO/snort3:snort2lua_variable_sets to master Squashed commit of the following: commit be7fda807ef950888e6a0a60aa191afc6bc0cd44 Author: Vitalii Date: Tue Dec 14 15:19:48 2021 +0200 parser: fix parsing of portsets commit de2580df2b80d2a7af35263337adde967b09ba76 Author: Vitalii Date: Tue Dec 14 15:18:52 2021 +0200 snort2lua: fix conversion of variable sets --- diff --git a/src/parser/parse_ports.cc b/src/parser/parse_ports.cc index 14f2f4a9a..4798817ae 100644 --- a/src/parser/parse_ports.cc +++ b/src/parser/parse_ports.cc @@ -306,10 +306,28 @@ static PortObject* _POParsePort(POParser* pop) return po; } +const char* _POFindMatchingBraces(const char* s) +{ + uint32_t depth = 0; + + do + { + if (*s == '[') + { + ++depth; + } + else if (*s == ']') + { + if (depth-- == 0) + return s; + } + } while (*s++); + return nullptr; +} + // FIXIT-L _POParseString creates 1 PortObject per port in the list and // then consolidates into one PortObject; it should just create a single // PortObject and put each port into appropriate PortItems - static PortObject* _POParseString(POParser* pop) { PortObject* potmp = nullptr; @@ -341,7 +359,7 @@ static PortObject* _POParseString(POParser* pop) list_count++; - if ( (end = strrchr(pop->s, (int)']')) == nullptr ) + if ( (end = _POFindMatchingBraces(pop->s)) == nullptr ) { pop->errflag = POPERR_NO_ENDLIST_BRACKET; PortObjectFree(po); @@ -363,8 +381,8 @@ static PortObject* _POParseString(POParser* pop) } /* Advance "cursor" to end of this list */ - for (; c && pop->s != end; c = POPGetChar2(pop)) - ; + while (c && pop->s != end) + c = POPGetChar(pop); } else if (c == ']') { diff --git a/tools/snort2lua/data/data_types/dt_var.cc b/tools/snort2lua/data/data_types/dt_var.cc index 24cfc0447..ce2e6b060 100644 --- a/tools/snort2lua/data/data_types/dt_var.cc +++ b/tools/snort2lua/data/data_types/dt_var.cc @@ -67,7 +67,9 @@ bool Variable::add_value(std::string elem) { std::string s; std::string end; - util::trim(elem); + + if (elem != " ") + util::trim(elem); if (elem.size() <= 1) { @@ -91,16 +93,32 @@ bool Variable::add_value(std::string elem) if (!s.empty() and s.front() == '$') { - // add a space between strings if (!vars.empty()) { + // wrap in square braces if negation before var + if (vars.back()->data.back() == '!') + { + vars.back()->data.push_back('['); + end.insert(0, 1, ']'); + } + + // add a space between strings if (vars.back()->type == VarType::STRING) - vars.back()->data += " "; + vars.back()->data.push_back(' '); else add_value(" "); } s.erase(s.begin()); + + size_t brace_pos = s.find("]", 1); + while (brace_pos != std::string::npos) + { + end.insert(0, 1, ']'); + s.erase(brace_pos, 1); + brace_pos = s.find("]", brace_pos); + } + VarData* vd = new VarData(); vd->type = VarType::VARIABLE; vd->data = s; @@ -117,7 +135,7 @@ bool Variable::add_value(std::string elem) vd->type = VarType::STRING; // if the previous variable was a symbol, we need a space separator. - if (!vars.empty()) + if (!vars.empty() and s != " ") s.insert(0, " "); vd->data = s; @@ -195,6 +213,16 @@ std::ostream& operator<<(std::ostream& out, const Variable& var) out << "[[ "; count += 3; + // trim spaces, because they are added with braces + if (v->data.length() > 1) + { + if (v->data.front() == ' ') + v->data.erase(v->data.begin()); + + if (v->data.back() == ' ') + v->data.pop_back(); + } + std::size_t printed_length = 0; std::size_t str_size = v->data.size(); bool first_loop = true; diff --git a/tools/snort2lua/helpers/s2l_util.cc b/tools/snort2lua/helpers/s2l_util.cc index 880d176bc..bc04e9519 100644 --- a/tools/snort2lua/helpers/s2l_util.cc +++ b/tools/snort2lua/helpers/s2l_util.cc @@ -139,6 +139,8 @@ std::string& trim_quotes(std::string& s) std::string& sanitize_lua_string(std::string& s) { + // FIXIT-L we shouldn't change the data, parts that use this function + // should be refactored and use Lua multilevel long brackets [=[...]=] std::size_t found = s.find("]]"); while (found != std::string::npos) { diff --git a/tools/snort2lua/keyword_states/kws_var.cc b/tools/snort2lua/keyword_states/kws_var.cc index 4ff07e3a1..01c74949a 100644 --- a/tools/snort2lua/keyword_states/kws_var.cc +++ b/tools/snort2lua/keyword_states/kws_var.cc @@ -42,17 +42,18 @@ static bool var_convert(std::istringstream& data_stream, DataApi& data_api, " - " + keyword + " begins with a number!"); return false; } - else if (ports.front() == '[') + + size_t brace_pos = ports.find("[", 0, 1); + if (brace_pos != std::string::npos) { std::vector port_list; bool retval = true; - // FIXIT-M should not be removing the '[' from a PORT_LIST - if (ports.front() == '[') + if (brace_pos == 0 && ports.back() == ']') + { ports.erase(ports.begin()); - - if (ports.back() == ']') ports.pop_back(); + } util::split(ports, ',', port_list);