blob: 9224b0d67b975ad2d4e5c06c7b605fe07d6c83ac [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.metron.parsers;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.startsWith;
import static org.junit.Assert.assertThat;
import java.nio.charset.StandardCharsets;
import java.time.ZoneId;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;
import org.adrianwalker.multilinestring.Multiline;
import org.apache.log4j.Level;
import org.apache.metron.common.Constants;
import org.apache.metron.parsers.interfaces.MessageParser;
import org.apache.metron.parsers.snort.BasicSnortParser;
import org.apache.metron.test.utils.UnitTestHelper;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
public class SnortParserTest {
@Rule
public ExpectedException thrown = ExpectedException.none();
/**
01/27/16-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;
// we will test timestamp conversion/parsing separately
@Test
public void testGoodMessage() {
BasicSnortParser parser = new BasicSnortParser();
parser.configure(new HashMap());
Map out = parser.parse(goodMessage.getBytes(StandardCharsets.UTF_8)).get(0);
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");
Assert.assertEquals(out.get("ethsrc"), "52:54:00:12:35:02");
Assert.assertEquals(out.get("tcpseq"), "0x9AFF3D7");
Assert.assertEquals(out.get("dgmlen"), "64");
Assert.assertEquals(out.get("icmpid"), "");
Assert.assertEquals(out.get("tcplen"), "");
Assert.assertEquals(out.get("tcpwindow"), "0xFFFF");
Assert.assertEquals(out.get("icmpseq").toString().trim(), "");
Assert.assertEquals(out.get("tcpack"), "0xC8761D52");
Assert.assertEquals(out.get("icmpcode"), "");
Assert.assertEquals(out.get("tos"), "0");
Assert.assertEquals(out.get("id"), "59677");
Assert.assertEquals(out.get("ethdst"), "08:00:27:7F:93:2D");
Assert.assertEquals(out.get("ip_src_addr"), "10.0.2.2");
Assert.assertEquals(out.get("ttl"), "64");
Assert.assertEquals(out.get("ethlen"), "0x4E");
Assert.assertEquals(out.get("iplen"), "65536");
Assert.assertEquals(out.get("icmptype"), "");
Assert.assertEquals(out.get("protocol"), "TCP");
Assert.assertEquals(out.get("ip_src_port"), "56642");
Assert.assertEquals(out.get("tcpflags"), "***AP***");
Assert.assertEquals(out.get("sig_id"), "12");
Assert.assertEquals(out.get("sig_generator"), "129");
Assert.assertEquals(out.get("is_alert"), "true");
}
@Test
public void testBadMessage() {
thrown.expect(IllegalStateException.class);
BasicSnortParser parser = new BasicSnortParser();
parser.init();
UnitTestHelper.setLog4jLevel(BasicSnortParser.class, Level.FATAL);
parser.parse("foo bar".getBytes(StandardCharsets.UTF_8));
UnitTestHelper.setLog4jLevel(BasicSnortParser.class, Level.ERROR);
}
@Test
public void parses_timestamp_as_local_zone_by_default() {
// test needs to be able to run from context of multiple timezones so we will set the default manually
TimeZone defaultTimeZone = TimeZone.getDefault();
try {
TimeZone.setDefault(TimeZone.getTimeZone(ZoneId.of("America/New_York")));
BasicSnortParser parser = new BasicSnortParser();
parser.configure(new HashMap());
Map out = parser.parse(goodMessage.getBytes(StandardCharsets.UTF_8)).get(0);
Assert.assertEquals(out.get("timestamp"), 1453928464877L);
} finally {
// make sure we don't mess with other tests
TimeZone.setDefault(defaultTimeZone);
}
}
/**
01/27/2016-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 dateFormattedMessage;
@Test
public void uses_configuration_to_parse() {
Map<String, Object> parserConfig = new HashMap<>();
parserConfig.put("dateFormat", "MM/dd/yyyy-HH:mm:ss.SSSSSS");
parserConfig.put("timeZone", "America/New_York");
BasicSnortParser parser = new BasicSnortParser();
parser.configure(parserConfig);
Map result = parser.parse(dateFormattedMessage.getBytes(StandardCharsets.UTF_8)).get(0);
assertThat("timestamp should match", result.get(Constants.Fields.TIMESTAMP.getName()), equalTo(1453928464877L));
}
@Test
public void throws_exception_on_bad_config_timezone() {
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage(startsWith("Unable to find ZoneId"));
Map<String, Object> parserConfig = new HashMap<>();
parserConfig.put("dateFormat", "MM/dd/yyyy-HH:mm:ss.SSSSSS");
parserConfig.put("timeZone", "blahblahBADZONE");
BasicSnortParser parser = new BasicSnortParser();
parser.configure(parserConfig);
}
@Test
public void throws_exception_on_bad_config_date_format() {
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage(startsWith("Unknown pattern letter:"));
Map<String, Object> parserConfig = new HashMap<>();
parserConfig.put("dateFormat", "BADFORMAT");
BasicSnortParser parser = new BasicSnortParser();
parser.configure(parserConfig);
}
@Test
public void getsReadCharsetFromConfig() {
Map<String, Object> config = new HashMap<>();
config.put(MessageParser.READ_CHARSET, StandardCharsets.UTF_16.toString());
BasicSnortParser parser = new BasicSnortParser();
parser.configure(config);
assertThat(parser.getReadCharset(), equalTo(StandardCharsets.UTF_16));
}
@Test
public void getsReadCharsetFromDefault() {
Map<String, Object> config = new HashMap<>();
BasicSnortParser parser = new BasicSnortParser();
parser.configure(config);
assertThat(parser.getReadCharset(), equalTo(StandardCharsets.UTF_8));
}
}