]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
refactor states. abstracting generic functions
authorJosh <jrosenba@cisco.com>
Wed, 11 Jun 2014 21:51:55 +0000 (17:51 -0400)
committerJosh <jrosenba@cisco.com>
Wed, 11 Jun 2014 21:51:55 +0000 (17:51 -0400)
tools/snort2lua/conversion_state.h
tools/snort2lua/preprocessor/CMakeLists.txt
tools/snort2lua/preprocessor/http_inspect.cc
tools/snort2lua/preprocessor/http_inspect_server.cc [new file with mode: 0644]
tools/snort2lua/preprocessor/preprocessor_api.cc
tools/snort2lua/preprocessor/smtp.cc [new file with mode: 0644]
tools/snort2lua/state_template.cc

index 726a0ffaf3a69ce6b909fb51277fa1bde8c0ac77..611805d6e1d35b713f502f8adc0584287d923a6e 100644 (file)
 
 #include <string>
 #include <fstream>
+#include <sstream>
 
-class Converter;
-
+#include "converter.h"
 class ConversionState
 {
 
@@ -35,10 +36,23 @@ public:
     virtual ~ConversionState() {};
     virtual bool convert(std::stringstream& data)=0;
 
-
 protected:
     Converter* converter;
 
+    inline bool add_int_option(std::string keyword, std::stringstream& stream)
+    {
+        int val;
+
+        if(stream >> val)
+        {
+            converter->add_option_to_table(keyword, val);
+            return true;
+        }
+
+        converter->add_comment_to_table("snort.conf missing argument for: " + keyword + " <int>");
+        return false;
+    }
+
 private:
 
 };
index f880a8daf46b95b1cefa1c6d27253d4de0db29ed..087eefe1e408272a444322f4a4e9c585717392a5 100644 (file)
@@ -1,6 +1,7 @@
 
 add_library(preprocessor
     http_inspect.cc
+    smtp.cc
     preprocessor_api.h
     preprocessor_api.cc
 )
\ No newline at end of file
index 6f0f50c1c51e70ad28bffc19869be8184ef15cb2..a02d584a50a99af18536679f7aa5409dd15491a6 100644 (file)
@@ -21,7 +21,6 @@
 
 #include <sstream>
 #include <vector>
-#include <iomanip>
 #include <string>
 
 #include "conversion_state.h"
@@ -38,11 +37,8 @@ public:
     virtual bool convert(std::stringstream& data);
 
 private:
-    void add_decode_option(std::string opt_name, int val);
+    bool add_decode_option(std::string opt_name,  std::stringstream& stream);
     bool missing_arg_error(std::string error_string);
-
-    bool first_line;
-    bool correct_keyword;
 };
 
 } // namespace
@@ -63,7 +59,9 @@ bool HttpInspect::convert(std::stringstream& data_stream)
     std::string s_value;
     int i_value;
 
-    bool retval = true;;
+    // using this to keep track of any errors.  I want to convert as much 
+    // as possible while being aware something went wrong
+    bool retval = true;
 
     if(data_stream >> keyword)
     {
@@ -80,107 +78,59 @@ bool HttpInspect::convert(std::stringstream& data_stream)
     while(data_stream >> keyword)
     {
         if(!keyword.compare("compress_depth"))
-        {
-            if(data_stream >> i_value)
-                converter->add_option_to_table("compress_depth", i_value);
-            else
-                retval = missing_arg_error("compress_depth <int>");
-        }
-        
+            retval = add_int_option("compress_depth", data_stream) && retval;
+
         else if(!keyword.compare("decompress_depth")) 
-        {
-            if(data_stream >> i_value)
-                converter->add_option_to_table("decompress_depth", i_value);
-            else
-                retval = missing_arg_error("decompress_depth <int>");
-        }
+            retval = add_int_option("decompress_depth", data_stream) && retval;
 
         else if(!keyword.compare("detect_anomalous_servers"))
-        {
             converter->add_option_to_table("detect_anomalous_servers", true);
-        }
 
-        else if(!keyword.compare("iis_unicode_map"))
-        {
-            std::string codemap;
-            if( (data_stream >> s_value) &&
-                (data_stream >> i_value))
-            {
-                converter->open_table("unicode_map");
-                converter->add_option_to_table("map_file", s_value);
-                converter->add_option_to_table("code_page", i_value);
-                converter->close_table();
-            }
-            else
-            {
-                retval = missing_arg_error("iis_unicode_map <filename> <codemap>");
-            }
-        }
         else if(!keyword.compare("proxy_alert"))
-        {
             converter->add_option_to_table("proxy_alert", true);
-        }
 
         else if(!keyword.compare("max_gzip_mem"))
-        {
-            if(data_stream >> i_value)
-                converter->add_option_to_table("max_gzip_mem", i_value);
-            else
-                retval = missing_arg_error("max_gzip_mem <int>");
-        }
+            retval = add_int_option("max_gzip_mem", data_stream) && retval;
         
         else if(!keyword.compare("memcap"))
-        {
-            if(data_stream >> i_value)
-                converter->add_option_to_table("memcap", i_value);
-            else
-                retval = missing_arg_error("memcap <int>");
-        }
+            retval = add_int_option("memcap", data_stream) && retval;
         
         else if(!keyword.compare("disabled"))
-        {
             converter->add_comment_to_table("'disabled' is deprecated");
-        }
-        
+
         else if(!keyword.compare("b64_decode_depth"))
-        {
-            if(data_stream >> i_value)
-                add_decode_option("b64_decode_depth", i_value);
-            else
-                retval = missing_arg_error("b64_decode_depth <int>");
-        }
+            retval = add_decode_option("b64_decode_depth", data_stream) && retval;
 
         else if(!keyword.compare("bitenc_decode_depth"))
-        {
-            if(data_stream >> i_value)
-                add_decode_option("bitenc_decode_depth", i_value);
-            else
-                retval = missing_arg_error("b64_decode_depth <int>");
-        }
-        else if(!keyword.compare("max_mime_mem"))
-        {
-            if(data_stream >> i_value)
-                add_decode_option("max_mime_mem", i_value);
-            else
-                retval = missing_arg_error("max_mime_mem <int>");
-        }
+            retval = add_decode_option("bitenc_decode_depth", data_stream) && retval;
 
+        else if(!keyword.compare("max_mime_mem"))
+            retval = add_decode_option("max_mime_mem", data_stream) && retval;
+        
         else if(!keyword.compare("qp_decode_depth"))
-        {
-            if(data_stream >> i_value)
-                add_decode_option("qp_decode_depth", i_value);
-            else
-                retval = missing_arg_error("qp_decode_depth <int>");
-        }
+            retval = add_decode_option("qp_decode_depth", data_stream) && retval;
 
         else if(!keyword.compare("uu_decode_depth"))
+            retval = add_decode_option("uu_decode_depth", data_stream) && retval;
+
+        else if(!keyword.compare("iis_unicode_map"))
         {
-            if(data_stream >> i_value)
-                add_decode_option("uu_decode_depth", i_value);
+            std::string codemap;
+            if( (data_stream >> s_value) &&
+                (data_stream >> i_value))
+            {
+                converter->open_table("unicode_map");
+                converter->add_option_to_table("map_file", s_value);
+                converter->add_option_to_table("code_page", i_value);
+                converter->close_table();
+            }
             else
-                retval = missing_arg_error("uu_decode_depth <int>");
+            {
+                retval = missing_arg_error("iis_unicode_map <filename> <codemap>");
+            }
         }
 
+
         else
         {
             converter->log_error("'preprocessor http_inspect: global' --> Invalid argument!!");
@@ -191,12 +141,22 @@ bool HttpInspect::convert(std::stringstream& data_stream)
     return retval;    
 }
 
-
-void HttpInspect::add_decode_option(std::string opt_name, int val)
+bool HttpInspect::add_decode_option(std::string opt_name,  std::stringstream& stream)
 {
-    converter->open_table("decode");
-    converter->add_option_to_table(opt_name, val);
-    converter->close_table();
+    int val;
+
+    if (stream >> val)
+    {
+        converter->open_table("decode");
+        converter->add_option_to_table(opt_name, val);
+        converter->close_table();
+        return true;
+    }
+    else
+    {
+        missing_arg_error(opt_name + " <int>");
+        return false;
+    }
 }
 
 /**************************
diff --git a/tools/snort2lua/preprocessor/http_inspect_server.cc b/tools/snort2lua/preprocessor/http_inspect_server.cc
new file mode 100644 (file)
index 0000000..b034406
--- /dev/null
@@ -0,0 +1,290 @@
+/*
+** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
+ * Copyright (C) 2002-2013 Sourcefire, Inc.
+ *
+ * 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.cc author Josh Rosenbaum <jorosenba@cisco.com>
+
+#include <sstream>
+#include <vector>
+#include <iomanip>
+
+#include "conversion_state.h"
+#include "converter.h"
+#include "snort2lua_util.h"
+
+namespace {
+
+class HttpInspectServer : public ConversionState
+{
+public:
+    HttpInspectServer(Converter* cv)  : ConversionState(cv) {};
+    virtual ~HttpInspectServer() {};
+    virtual bool convert(std::stringstream& data_stream);
+
+private:
+    missing_arge_error(std::string arg);
+};
+
+} // namespace
+
+bool HttpInspectServer::missing_arg_error(std::string arg)
+{
+    converter->add_comment_to_table("snort.conf missing argument for " + arg);
+    return false;
+}
+
+
+#if 0
+
+#* ports { [port] [port] . . . } *
+#* iis_unicode_map [file (located in config dir)] [codemap (integer)] *
+#* extended_response_inspection *
+#* enable_cookie *
+#* inspect_gzip *
+#* unlimited_decompress *
+#* decompress_swf { deflate lzma } *
+#* decompress_pdf { deflate } *
+#* normalize_javascript *
+#* max_javascript_whitespaces [positive integer] *
+#* enable_xff *
+#* server_flow_depth [integer] *
+#* flow_depth [integer] *  (to be deprecated)
+#* client_flow_depth [integer] *
+#* post_depth [integer] *
+#* ascii [yes/no] *
+#* extended_ascii_uri *
+#* utf_8 [yes/no] *
+#* u_encode [yes/no] *
+#* bare_byte [yes/no] *
+#* iis_unicode [yes/no] *
+#* double_decode [yes/no] *
+#* non_rfc_char { [byte] [0x00] . . . } *
+#* multi_slash [yes/no] *
+#* iis_backslash [yes/no] *
+#* directory [yes/no] *
+#* apache_whitespace [yes/no] *
+#* iis_delimiter [yes/no] *
+#* chunk_length [non-zero positive integer] *
+#* small_chunk_length { <chunk size> <consecutive chunks> } *
+#* no_pipeline_req *
+#* non_strict *
+#* allow_proxy_use *
+#* no_alerts *
+#* oversize_dir_length [non-zero positive integer] *
+#* inspect_uri_only *
+#* max_header_length [positive integer] *
+#* max_spaces [positive integer] *
+#* webroot *
+#* tab_uri_delimiter *
+#* normalize_headers *
+#* normalize_cookies *
+#* normalize_utf *
+#* max_headers [positive integer] *
+#*http_methods { <CMD1> <CMD2> } *
+#* log_uri *
+#* log_hostname *
+#-- Profile Breakout --
+#* http_client_body *
+#* http_cookie *
+#* http_raw_cookie *
+#* http_header *
+#* http_raw_header *
+#* http_method *
+#* http_uri *
+#* http_raw_uri *
+#* http_stat_code *
+#* http_stat_msg *
+#* http_encode *
+
+
+    { "allow_proxy_use", Parameter::PT_BOOL, nullptr, "false",
+      "don't alert on proxy use for this server" },
+
+    { "apache_whitespace", Parameter::PT_BOOL, nullptr, "true",
+      "don't alert if tab is used in lieu of space characters" },
+
+    { "ascii", Parameter::PT_BOOL, nullptr, "true",
+      "enable decoding ASCII like %2f to /" },
+
+    { "bare_byte", Parameter::PT_BOOL, nullptr, "false",
+      "decode non-standard, non-ASCII character encodings" },
+
+    { "chunk_length", Parameter::PT_INT, "1:", "500000",
+      "alert on chunk lengths greater than specified" },
+
+    { "client_flow_depth", Parameter::PT_INT, "-1:1460", "300",
+      "raw request payload to inspect" },
+
+    { "directory", Parameter::PT_BOOL, nullptr, "true",
+      "normalize . and .. sequences out of URI" },
+
+    { "double_decode", Parameter::PT_BOOL, nullptr, "false",
+      "iis specific extra decoding" },
+
+    { "enable_cookies", Parameter::PT_BOOL, nullptr, "false",
+      "extract cookies" },
+
+    { "enable_xff", Parameter::PT_BOOL, nullptr, "false",
+      "log True-Client-IP and X-Forwarded-For headers with unified2 alerts as extra data" },
+
+    { "extended_ascii_uri", Parameter::PT_BOOL, nullptr, "false",
+      "help" },
+
+    { "extended_response_inspection", Parameter::PT_BOOL, nullptr, "false",
+      "extract resonse headers" },
+
+    { "http_methods", Parameter::PT_STRING, nullptr, nullptr,
+      "request methods allowed in addition to GET and POST" },
+
+    { "iis_backslash", Parameter::PT_BOOL, nullptr, "false",
+      "normalize directory slashes" },
+
+    { "iis_delimiter", Parameter::PT_BOOL, nullptr, "true",
+      "allow use of non-standard delimiter" },
+
+    { "iis_unicode", Parameter::PT_BOOL, nullptr, "false",
+      "enable unicode code point mapping using unicode_map settings" },
+
+    { "iis_unicode_map", Parameter::PT_TABLE, hi_umap_params, nullptr,
+      "help" },
+
+    { "inspect_gzip", Parameter::PT_BOOL, nullptr, "false",
+      "enable gzip decompression of compressed bodies" },
+
+    { "inspect_uri_only", Parameter::PT_BOOL, nullptr, "false",
+      "disable all detection except for uricontent" },
+
+    { "log_hostname", Parameter::PT_BOOL, nullptr, "false",
+      "enable logging of Hostname with unified2 alerts as extra data" },
+
+    { "log_uri", Parameter::PT_BOOL, nullptr, "false",
+      "enable logging of URI with unified2 alerts as extra data" },
+
+    { "max_header_length", Parameter::PT_INT, "0:65535", "0",
+      "maximum allowed client request header field" },
+
+    { "max_headers", Parameter::PT_INT, "0:1024", "0",
+      "maximum allowd client request headers" },
+
+    { "max_spaces", Parameter::PT_INT, "0:65535", "200",
+      "help" },
+
+    { "multi_slash", Parameter::PT_BOOL, nullptr, "true",
+      "normalize out consecutive slashes in URI" },
+
+    { "no_pipeline_req", Parameter::PT_BOOL, nullptr, "false",
+      "don't inspect pipelined requests after first (still does general detection)" },
+
+    { "non_rfc_chars", Parameter::PT_BIT_LIST, "255", "false",
+      "alert on given non-RFC chars being present in the URI" },
+
+    { "non_strict", Parameter::PT_BOOL, nullptr, "true",
+      "allows HTTP 0.9 processing" },
+
+    { "normalize_cookies", Parameter::PT_BOOL, nullptr, "false",
+      "help" },
+
+    { "normalize_headers", Parameter::PT_BOOL, nullptr, "false",
+      "help" },
+
+    { "normalize_javascript", Parameter::PT_BOOL, nullptr, "false",
+      "normalize javascript between <script> tags" },
+
+    { "max_javascript_whitespaces", Parameter::PT_INT, "0:", "200",
+      "maximum number of consecutive whitespaces" },
+
+    { "normalize_utf", Parameter::PT_BOOL, nullptr, "false",
+      "help" },
+
+    { "oversize_dir_length", Parameter::PT_INT, "0:", "0",
+      "alert if a URL has a directory longer than this limit" },
+
+    { "post_depth", Parameter::PT_INT, "-1:65535", "-1",
+      "amount of POST data to inspect" },
+
+    { "profile", Parameter::PT_ENUM, profiles, "none",
+      "set defaults appropriate for selected server" },
+
+    { "server_flow_depth", Parameter::PT_INT, "-1:65535", "300",
+      "response payload to inspect; includes headers with extended_response_inspection" },
+
+    { "small_chunk_count", Parameter::PT_INT, "0:255", "0",
+      "alert if more than this limit of consecutive chunks are below small_chunk_length" },
+
+    { "small_chunk_length", Parameter::PT_INT, "0:255", "0",
+      "alert if more than small_chunk_count consecutive chunks below this limit" },
+
+    { "tab_uri_delimiter", Parameter::PT_BOOL, nullptr, "false",
+      "help" },
+
+    { "u_encode", Parameter::PT_BOOL, nullptr, "false",
+      "decode %uXXXX character sequences" },
+
+    { "unicode_map", Parameter::PT_TABLE, hi_umap_params, nullptr,
+      "help" },
+
+    { "unlimited_decompress", Parameter::PT_INT, nullptr, "false",
+      "decompress across multiple packets" },
+
+    { "utf_8", Parameter::PT_BOOL, nullptr, "true",
+      "decode UTF-8 unicode sequences in URI" },
+
+    { "webroot", Parameter::PT_BOOL, nullptr, "true",
+      "alert on directory traversals past the top level (web server root)" },
+
+    { "whitespace_chars", Parameter::PT_BIT_LIST, "255", "false",
+      "help" },
+#endif
+
+bool HttpInspectServer::convert(std::stringstream& data_stream)
+{
+    std::string keyword;
+
+    if(data_stream >> keyword)
+    {
+        const ConvertMap* map = util::find_map(output_api, keyword);
+        if (map)
+        {
+            converter->set_state(map->ctor(converter));
+            return true;
+        }
+    }
+
+    return false;    
+
+    data_stream.setstate(std::basic_ios<char>::eofbit);
+    return true;    
+}
+
+/**************************
+ *******  A P I ***********
+ **************************/
+
+static ConversionState* ctor(Converter* cv)
+{
+    return new HttpInspectServer(cv);
+}
+
+static const ConvertMap preprocessor_httpinsepct_server = 
+{
+    "http_inspect_server",
+    ctor,
+};
+
+const ConvertMap* httpinspect_server_map = &preprocessor_httpinsepct_server;
+
index 1569fcbf90a391af3ddf4aee740e399da36bd66d..ff922039d677de6f7c64dc947f7adef00d2e69a4 100644 (file)
 
 
 extern const ConvertMap *httpinspect_map;
+extern const ConvertMap *smtp_map;
 
 
 
 const std::vector<const ConvertMap*> preprocessor_api = 
 {
     httpinspect_map,
+    smtp_map,
 //    nullptr,
 };
diff --git a/tools/snort2lua/preprocessor/smtp.cc b/tools/snort2lua/preprocessor/smtp.cc
new file mode 100644 (file)
index 0000000..03efd68
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
+ * Copyright (C) 2002-2013 Sourcefire, Inc.
+ *
+ * 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.cc author Josh Rosenbaum <jorosenba@cisco.com>
+
+#include <sstream>
+#include <vector>
+
+#include "conversion_state.h"
+#include "converter.h"
+#include "snort2lua_util.h"
+
+namespace {
+
+class Smtp : public ConversionState
+{
+public:
+    Smtp(Converter* cv)  : ConversionState(cv) {};
+    virtual ~Smtp() {};
+    virtual bool convert(std::stringstream& data_stream);
+};
+
+} // namespace
+
+
+bool Smtp::convert(std::stringstream& data_stream)
+{
+
+#if 0
+    std::string keyword;
+    if(data_stream >> keyword)
+    {
+        const ConvertMap* map = util::find_map(output_api, keyword);
+        if (map)
+        {
+            converter->set_state(map->ctor(converter));
+            return true;
+        }
+    }
+
+ports
+inspection_type stateful|stateless
+normalize all|none|cmds *
+ignore_data
+ignore_tls_data
+max_command_line_len <int> 
+max_header_line_len <int> *
+max_response_line_len <int>
+alt_max_command_line_len <int> { <cmd> [<cmd>] }
+no_alerts
+invalid_cmds { <Space-delimited list of commands> } 
+valid_cmds { <Space-delimited list of commands> } 
+data_cmds { <Space-delimited list of commands> } 
+binary_data_cmds { <Space-delimited list of commands> }
+auth_cmds { <Space-delimited list of commands> } 
+alert_unknown_cmds
+normalize_cmds { <Space-delimited list of commands> } 
+xlink2state { enable/disable [drop] }
+print_cmds
+disabled
+b64_decode_depth
+qp_decode_depth
+bitenc_decode_depth
+uu_decode_depth
+enable_mime_decoding
+max_mime_depth <int> 
+max_mime_mem <int> 
+log_mailfrom
+log_rcptto
+log_filename
+log_email_hdrs
+email_hdrs_log_depth <int> 
+memcap <int>
+#endif
+
+    return false;    
+}
+
+/**************************
+ *******  A P I ***********
+ **************************/
+
+static ConversionState* ctor(Converter* cv)
+{
+    return new Smtp(cv);
+}
+
+static const ConvertMap preprocessor_smtp = 
+{
+    "smtp",
+    ctor,
+};
+
+const ConvertMap* smtp_map = &preprocessor_smtp;
index f000608f91fe8d1d4bf838af59e889f97c2337ce..573eb00b5111cc2909b199779e2b767f1cb7d4e7 100644 (file)
@@ -34,13 +34,13 @@ class Suppress : public ConversionState
 public:
     Suppress(Converter* cv)  : ConversionState(cv) {};
     virtual ~Suppress() {};
-    virtual bool convert(std::stringstream& data_stream, std::ofstream&);
+    virtual bool convert(std::stringstream& data_stream);
 };
 
 } // namespace
 
 
-bool Suppress::convert(std::stringstream& data_stream, std::ofstream&)
+bool Suppress::convert(std::stringstream& data_stream)
 {
 #if 0
     std::string keyword;