Repository: incubator-metron
Updated Branches:
  refs/heads/master 6f5c84ee2 -> 609ea40c2


METRON-488: Snort should use a proper CSV implementation (cestella via 
mmiklavc) closes apache/incubator-metron#297


Project: http://git-wip-us.apache.org/repos/asf/incubator-metron/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-metron/commit/609ea40c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-metron/tree/609ea40c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-metron/diff/609ea40c

Branch: refs/heads/master
Commit: 609ea40c2e8ab3b35b645f4238d2f66afc120fb5
Parents: 6f5c84e
Author: cstella <ceste...@gmail.com>
Authored: Tue Oct 11 13:59:45 2016 -0400
Committer: Michael Miklavcic <michael.miklav...@gmail.com>
Committed: Tue Oct 11 13:59:45 2016 -0400

----------------------------------------------------------------------
 .../main/sample/data/snort/parsed/SnortParsed   |  6 +--
 .../metron/parsers/snort/BasicSnortParser.java  | 39 +++++++++++++++-----
 .../apache/metron/parsers/SnortParserTest.java  |  6 ++-
 3 files changed, 37 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/609ea40c/metron-platform/metron-integration-test/src/main/sample/data/snort/parsed/SnortParsed
----------------------------------------------------------------------
diff --git 
a/metron-platform/metron-integration-test/src/main/sample/data/snort/parsed/SnortParsed
 
b/metron-platform/metron-integration-test/src/main/sample/data/snort/parsed/SnortParsed
index 318b158..e2894b3 100644
--- 
a/metron-platform/metron-integration-test/src/main/sample/data/snort/parsed/SnortParsed
+++ 
b/metron-platform/metron-integration-test/src/main/sample/data/snort/parsed/SnortParsed
@@ -1,3 +1,3 @@
-{"msg":"\"Consecutive TCP small segments exceeding 
threshold\"","sig_rev":"1","ip_dst_addr":"10.0.2.15","ip_dst_port":"22","ethsrc":"52:54:00:12:35:02","tcpseq":"0x9AFF3D7","dgmlen":"64","icmpid":"","tcplen":"","tcpwindow":"0xFFFF","icmpseq":"","tcpack":"0xC8761D52","original_string":"01\/27-16:01:04.877970
 ,129,12,1,\"Consecutive TCP small segments exceeding 
threshold\",TCP,10.0.2.2,56642,10.0.2.15,22,52:54:00:12:35:02,08:00:27:7F:93:2D,0x4E,***AP***,0x9AFF3D7,0xC8761D52,,0xFFFF,64,0,59677,64,65536,,,,","icmpcode":"","tos":"0","id":"59677","timestamp":1453932941970,"ethdst":"08:00:27:7F:93:2D","ip_src_addr":"10.0.2.2","ttl":"64","source.type":"snort","ethlen":"0x4E","iplen":"65536","icmptype":"","protocol":"TCP","ip_src_port":"56642","tcpflags":"***AP***","sig_id":"12","sig_generator":"129",
 "is_alert" : "true"}
-{"msg":"\"Consecutive TCP small segments exceeding 
threshold\"","sig_rev":"1","ip_dst_addr":"10.0.2.15","ip_dst_port":"50895","ethsrc":"52:54:00:12:35:02","tcpseq":"0xDB45F7A","dgmlen":"96","icmpid":"","tcplen":"","tcpwindow":"0xFFFF","icmpseq":"","tcpack":"0x7701DD5B","original_string":"02\/22-15:56:48.612494
 ,129,12,1,\"Consecutive TCP small segments exceeding 
threshold\",TCP,96.44.142.5,80,10.0.2.15,50895,52:54:00:12:35:02,08:00:27:7F:93:2D,0x6E,***AP***,0xDB45F7A,0x7701DD5B,,0xFFFF,64,0,16785,96,98304,,,,","icmpcode":"","tos":"0","id":"16785","timestamp":1456178820494,"ethdst":"08:00:27:7F:93:2D","ip_src_addr":"96.44.142.5","ttl":"64","source.type":"snort","ethlen":"0x6E","iplen":"98304","icmptype":"","protocol":"TCP","ip_src_port":"80","tcpflags":"***AP***","sig_id":"12","sig_generator":"129",
 "is_alert" : "true"}
-{"msg":"\"Consecutive TCP small segments exceeding 
threshold\"","sig_rev":"1","ip_dst_addr":"10.0.2.15","ip_dst_port":"50895","ethsrc":"52:54:00:12:35:02","tcpseq":"0xDB508F2","dgmlen":"152","icmpid":"","tcplen":"","tcpwindow":"0xFFFF","icmpseq":"","tcpack":"0x7701DD5B","original_string":"02\/22-15:56:48.616775
 ,129,12,1,\"Consecutive TCP small segments exceeding 
threshold\",TCP,96.44.142.5,80,10.0.2.15,50895,52:54:00:12:35:02,08:00:27:7F:93:2D,0xA6,***AP***,0xDB508F2,0x7701DD5B,,0xFFFF,64,0,16824,152,155648,,,,","icmpcode":"","tos":"0","id":"16824","timestamp":1456178824775,"ethdst":"08:00:27:7F:93:2D","ip_src_addr":"96.44.142.5","ttl":"64","source.type":"snort","ethlen":"0xA6","iplen":"155648","icmptype":"","protocol":"TCP","ip_src_port":"80","tcpflags":"***AP***","sig_id":"12","sig_generator":"129",
 "is_alert" : "true"}
+{"msg":"Consecutive TCP small segments exceeding 
threshold","sig_rev":"1","ip_dst_addr":"10.0.2.15","ip_dst_port":"22","ethsrc":"52:54:00:12:35:02","tcpseq":"0x9AFF3D7","dgmlen":"64","icmpid":"","tcplen":"","tcpwindow":"0xFFFF","icmpseq":"","tcpack":"0xC8761D52","original_string":"01\/27-16:01:04.877970
 ,129,12,1,\"Consecutive TCP small segments exceeding 
threshold\",TCP,10.0.2.2,56642,10.0.2.15,22,52:54:00:12:35:02,08:00:27:7F:93:2D,0x4E,***AP***,0x9AFF3D7,0xC8761D52,,0xFFFF,64,0,59677,64,65536,,,,","icmpcode":"","tos":"0","id":"59677","timestamp":1453932941970,"ethdst":"08:00:27:7F:93:2D","ip_src_addr":"10.0.2.2","ttl":"64","source.type":"snort","ethlen":"0x4E","iplen":"65536","icmptype":"","protocol":"TCP","ip_src_port":"56642","tcpflags":"***AP***","sig_id":"12","sig_generator":"129",
 "is_alert" : "true"}
+{"msg":"Consecutive TCP small segments exceeding 
threshold","sig_rev":"1","ip_dst_addr":"10.0.2.15","ip_dst_port":"50895","ethsrc":"52:54:00:12:35:02","tcpseq":"0xDB45F7A","dgmlen":"96","icmpid":"","tcplen":"","tcpwindow":"0xFFFF","icmpseq":"","tcpack":"0x7701DD5B","original_string":"02\/22-15:56:48.612494
 ,129,12,1,\"Consecutive TCP small segments exceeding 
threshold\",TCP,96.44.142.5,80,10.0.2.15,50895,52:54:00:12:35:02,08:00:27:7F:93:2D,0x6E,***AP***,0xDB45F7A,0x7701DD5B,,0xFFFF,64,0,16785,96,98304,,,,","icmpcode":"","tos":"0","id":"16785","timestamp":1456178820494,"ethdst":"08:00:27:7F:93:2D","ip_src_addr":"96.44.142.5","ttl":"64","source.type":"snort","ethlen":"0x6E","iplen":"98304","icmptype":"","protocol":"TCP","ip_src_port":"80","tcpflags":"***AP***","sig_id":"12","sig_generator":"129",
 "is_alert" : "true"}
+{"msg":"Consecutive TCP small segments exceeding 
threshold","sig_rev":"1","ip_dst_addr":"10.0.2.15","ip_dst_port":"50895","ethsrc":"52:54:00:12:35:02","tcpseq":"0xDB508F2","dgmlen":"152","icmpid":"","tcplen":"","tcpwindow":"0xFFFF","icmpseq":"","tcpack":"0x7701DD5B","original_string":"02\/22-15:56:48.616775
 ,129,12,1,\"Consecutive TCP small segments exceeding 
threshold\",TCP,96.44.142.5,80,10.0.2.15,50895,52:54:00:12:35:02,08:00:27:7F:93:2D,0xA6,***AP***,0xDB508F2,0x7701DD5B,,0xFFFF,64,0,16824,152,155648,,,,","icmpcode":"","tos":"0","id":"16824","timestamp":1456178824775,"ethdst":"08:00:27:7F:93:2D","ip_src_addr":"96.44.142.5","ttl":"64","source.type":"snort","ethlen":"0xA6","iplen":"155648","icmptype":"","protocol":"TCP","ip_src_port":"80","tcpflags":"***AP***","sig_id":"12","sig_generator":"129",
 "is_alert" : "true"}

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/609ea40c/metron-platform/metron-parsers/src/main/java/org/apache/metron/parsers/snort/BasicSnortParser.java
----------------------------------------------------------------------
diff --git 
a/metron-platform/metron-parsers/src/main/java/org/apache/metron/parsers/snort/BasicSnortParser.java
 
b/metron-platform/metron-parsers/src/main/java/org/apache/metron/parsers/snort/BasicSnortParser.java
index f295d4c..e50926c 100644
--- 
a/metron-platform/metron-parsers/src/main/java/org/apache/metron/parsers/snort/BasicSnortParser.java
+++ 
b/metron-platform/metron-parsers/src/main/java/org/apache/metron/parsers/snort/BasicSnortParser.java
@@ -17,7 +17,10 @@
  */
 package org.apache.metron.parsers.snort;
 
+import com.google.common.collect.Lists;
+import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
 import org.apache.metron.common.Constants;
+import org.apache.metron.common.csv.CSVConverter;
 import org.apache.metron.parsers.BasicParser;
 import org.json.simple.JSONObject;
 import org.slf4j.Logger;
@@ -72,14 +75,26 @@ public class BasicSnortParser extends BasicParser {
    */
   private String recordDelimiter = ",";
 
+  private transient CSVConverter converter;
+
+  public BasicSnortParser() {
+
+  }
+
   @Override
   public void configure(Map<String, Object> parserConfig) {
-
+    init();
   }
 
   @Override
   public void init() {
-
+    if(converter == null) {
+      converter = new CSVConverter();
+      Map<String, Object> config = new HashMap<>();
+      config.put(CSVConverter.SEPARATOR_KEY, recordDelimiter);
+      config.put(CSVConverter.COLUMNS_KEY, Lists.newArrayList(fieldNames));
+      converter.initialize(config);
+    }
   }
 
   @Override
@@ -90,18 +105,24 @@ public class BasicSnortParser extends BasicParser {
     try {
       // snort alerts expected as csv records
       String csvMessage = new String(rawMessage, "UTF-8");
-      String[] records = csvMessage.split(recordDelimiter, -1);
+      Map<String, String> records = null;
+      try {
+         records = converter.toMap(csvMessage);
+      }
+      catch(ArrayIndexOutOfBoundsException aioob) {
+        throw new IllegalArgumentException("Unexpected number of fields, 
expected: " + fieldNames.length + " in " + csvMessage);
+      }
 
       // validate the number of fields
-      if (records.length != fieldNames.length) {
-        throw new IllegalArgumentException("Unexpected number of fields, 
expected: " + fieldNames.length + " got: " + records.length);
+      if (records.size() != fieldNames.length) {
+        throw new IllegalArgumentException("Unexpected number of fields, 
expected: " + fieldNames.length + " got: " + records.size());
       }
       long timestamp = 0L;
       // build the json record from each field
-      for (int i=0; i<records.length; i++) {
+      for (Map.Entry<String, String> kv : records.entrySet()) {
 
-        String field = fieldNames[i];
-        String record = records[i];
+        String field = kv.getKey();
+        String record = kv.getValue();
 
         if("timestamp".equals(field)) {
 
@@ -119,7 +140,7 @@ public class BasicSnortParser extends BasicParser {
       jsonMessage.put("is_alert", "true");
       messages.add(jsonMessage);
     } catch (Exception e) {
-      String message = "Unable to parse message: " + rawMessage;
+      String message = "Unable to parse message: " + (rawMessage == 
null?"null" : new String(rawMessage));
       _LOG.error(message, e);
       throw new IllegalStateException(message, e);
     }

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/609ea40c/metron-platform/metron-parsers/src/test/java/org/apache/metron/parsers/SnortParserTest.java
----------------------------------------------------------------------
diff --git 
a/metron-platform/metron-parsers/src/test/java/org/apache/metron/parsers/SnortParserTest.java
 
b/metron-platform/metron-parsers/src/test/java/org/apache/metron/parsers/SnortParserTest.java
index 6d777aa..8114e83 100644
--- 
a/metron-platform/metron-parsers/src/test/java/org/apache/metron/parsers/SnortParserTest.java
+++ 
b/metron-platform/metron-parsers/src/test/java/org/apache/metron/parsers/SnortParserTest.java
@@ -27,7 +27,7 @@ import java.util.Map;
 
 public class SnortParserTest {
   /**
-  01/27-16:01:04.877970 ,129,12,1,"Consecutive TCP small segments exceeding 
threshold",TCP,10.0.2.2,56642,10.0.2.15,22,52:54:00:12:35:02,08:00:27:7F:93:2D,0x4E,***AP***,0x9AFF3D7,0xC8761D52,,0xFFFF,64,0,59677,64,65536,,,,
+  01/27-16:01:04.877970 ,129,12,1,"Consecutive TCP small segments, exceeding 
threshold",TCP,10.0.2.2,56642,10.0.2.15,22,52:54:00:12:35:02,08:00:27:7F:93:2D,0x4E,***AP***,0x9AFF3D7,0xC8761D52,,0xFFFF,64,0,59677,64,65536,,,,
    **/
   @Multiline
   public static String goodMessage;
@@ -36,8 +36,9 @@ public class SnortParserTest {
   @Test
   public void testGoodMessage() {
     BasicSnortParser parser = new BasicSnortParser();
+    parser.init();
     Map out = parser.parse(goodMessage.getBytes()).get(0);
-    Assert.assertEquals(out.get("msg"),"\"Consecutive TCP small segments 
exceeding threshold\"");
+    Assert.assertEquals(out.get("msg"),"Consecutive TCP small segments, 
exceeding threshold");
     Assert.assertEquals(out.get("sig_rev"), "1");
     Assert.assertEquals(out.get("ip_dst_addr"), "10.0.2.15");
     Assert.assertEquals(out.get("ip_dst_port"), "22");
@@ -69,6 +70,7 @@ public class SnortParserTest {
   @Test(expected=IllegalStateException.class)
   public void testBadMessage() {
     BasicSnortParser parser = new BasicSnortParser();
+    parser.init();
     parser.parse("foo bar".getBytes());
   }
 }

Reply via email to