logstash-patterns-core 4.0.1 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -31,7 +31,7 @@ HAPROXYCAPTUREDRESPONSEHEADERS %{DATA:captured_response_headers}
31
31
  # HAPROXYCAPTUREDRESPONSEHEADERS %{DATA:response_header_content_type}\|%{DATA:response_header_content_encoding}\|%{DATA:response_header_cache_control}\|%{DATA:response_header_last_modified}
32
32
 
33
33
  # parse a haproxy 'httplog' line
34
- HAPROXYHTTPBASE %{IP:client_ip}:%{INT:client_port} \[%{HAPROXYDATE:accept_date}\] %{NOTSPACE:frontend_name} %{NOTSPACE:backend_name}/%{NOTSPACE:server_name} %{INT:time_request}/%{INT:time_queue}/%{INT:time_backend_connect}/%{INT:time_backend_response}/%{NOTSPACE:time_duration} %{INT:http_status_code} %{NOTSPACE:bytes_read} %{DATA:captured_request_cookie} %{DATA:captured_response_cookie} %{NOTSPACE:termination_state} %{INT:actconn}/%{INT:feconn}/%{INT:beconn}/%{INT:srvconn}/%{NOTSPACE:retries} %{INT:srv_queue}/%{INT:backend_queue} (\{%{HAPROXYCAPTUREDREQUESTHEADERS}\})?( )?(\{%{HAPROXYCAPTUREDRESPONSEHEADERS}\})?( )?"(<BADREQ>|(%{WORD:http_verb} (%{URIPROTO:http_proto}://)?(?:%{USER:http_user}(?::[^@]*)?@)?(?:%{URIHOST:http_host})?(?:%{URIPATHPARAM:http_request})?( HTTP/%{NUMBER:http_version})?))?"
34
+ HAPROXYHTTPBASE %{IP:client_ip}:%{INT:client_port} \[%{HAPROXYDATE:accept_date}\] %{NOTSPACE:frontend_name} %{NOTSPACE:backend_name}/%{NOTSPACE:server_name} %{INT:time_request}/%{INT:time_queue}/%{INT:time_backend_connect}/%{INT:time_backend_response}/%{NOTSPACE:time_duration} %{INT:http_status_code} %{NOTSPACE:bytes_read} %{DATA:captured_request_cookie} %{DATA:captured_response_cookie} %{NOTSPACE:termination_state} %{INT:actconn}/%{INT:feconn}/%{INT:beconn}/%{INT:srvconn}/%{NOTSPACE:retries} %{INT:srv_queue}/%{INT:backend_queue} (\{%{HAPROXYCAPTUREDREQUESTHEADERS}\})?( )?(\{%{HAPROXYCAPTUREDRESPONSEHEADERS}\})?( )?"(<BADREQ>|(%{WORD:http_verb} (%{URIPROTO:http_proto}://)?(?:%{USER:http_user}(?::[^@]*)?@)?(?:%{URIHOST:http_host})?(?:%{URIPATHPARAM:http_request})?( HTTP/%{NUMBER:http_version})?))?"?
35
35
 
36
36
  HAPROXYHTTP (?:%{SYSLOGTIMESTAMP:syslog_timestamp}|%{TIMESTAMP_ISO8601:timestamp8601}) %{IPORHOST:syslog_server} %{SYSLOGPROG}: %{HAPROXYHTTPBASE}
37
37
 
@@ -0,0 +1,15 @@
1
+ HTTPDUSER %{EMAILADDRESS}|%{USER}
2
+ HTTPDERROR_DATE %{DAY} %{MONTH} %{MONTHDAY} %{TIME} %{YEAR}
3
+
4
+ # Log formats
5
+ HTTPD_COMMONLOG %{IPORHOST:clientip} %{HTTPDUSER:ident} %{HTTPDUSER:auth} \[%{HTTPDATE:timestamp}\] "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})" (?:-|%{NUMBER:response}) (?:-|%{NUMBER:bytes})
6
+ HTTPD_COMBINEDLOG %{HTTPD_COMMONLOG} %{QS:referrer} %{QS:agent}
7
+
8
+ # Error logs
9
+ HTTPD20_ERRORLOG \[%{HTTPDERROR_DATE:timestamp}\] \[%{LOGLEVEL:loglevel}\] (?:\[client %{IPORHOST:clientip}\] ){0,1}%{GREEDYDATA:message}
10
+ HTTPD24_ERRORLOG \[%{HTTPDERROR_DATE:timestamp}\] \[%{WORD:module}:%{LOGLEVEL:loglevel}\] \[pid %{POSINT:pid}(:tid %{NUMBER:tid})?\]( \(%{POSINT:proxy_errorcode}\)%{DATA:proxy_message}:)?( \[client %{IPORHOST:clientip}:%{POSINT:clientport}\])?( %{DATA:errorcode}:)? %{GREEDYDATA:message}
11
+ HTTPD_ERRORLOG %{HTTPD20_ERRORLOG}|%{HTTPD24_ERRORLOG}
12
+
13
+ # Deprecated
14
+ COMMONAPACHELOG %{HTTPD_COMMONLOG}
15
+ COMBINEDAPACHELOG %{HTTPD_COMBINEDLOG}
@@ -1,15 +1,12 @@
1
1
  JAVACLASS (?:[a-zA-Z$_][a-zA-Z$_0-9]*\.)*[a-zA-Z$_][a-zA-Z$_0-9]*
2
2
  #Space is an allowed character to match special cases like 'Native Method' or 'Unknown Source'
3
- JAVAFILE (?:[A-Za-z0-9_. -]+)
4
- #Allow special <init> method
5
- JAVAMETHOD (?:(<init>)|[a-zA-Z$_][a-zA-Z$_0-9]*)
3
+ JAVAFILE (?:[a-zA-Z$_0-9. -]+)
4
+ #Allow special <init>, <clinit> methods
5
+ JAVAMETHOD (?:(<(?:cl)?init>)|[a-zA-Z$_][a-zA-Z$_0-9]*)
6
6
  #Line number is optional in special cases 'Native method' or 'Unknown source'
7
7
  JAVASTACKTRACEPART %{SPACE}at %{JAVACLASS:class}\.%{JAVAMETHOD:method}\(%{JAVAFILE:file}(?::%{NUMBER:line})?\)
8
8
  # Java Logs
9
9
  JAVATHREAD (?:[A-Z]{2}-Processor[\d]+)
10
- JAVACLASS (?:[a-zA-Z0-9-]+\.)+[A-Za-z0-9$]+
11
- JAVAFILE (?:[A-Za-z0-9_.-]+)
12
- JAVASTACKTRACEPART at %{JAVACLASS:class}\.%{WORD:method}\(%{JAVAFILE:file}:%{NUMBER:line}\)
13
10
  JAVALOGMESSAGE (.*)
14
11
  # MMM dd, yyyy HH:mm:ss eg: Jan 9, 2014 7:13:13 AM
15
12
  CATALINA_DATESTAMP %{MONTH} %{MONTHDAY}, 20%{YEAR} %{HOUR}:?%{MINUTE}(?::?%{SECOND}) (?:AM|PM)
@@ -11,6 +11,6 @@ SYSLOGLINE %{SYSLOGBASE2} %{GREEDYDATA:message}
11
11
  # IETF 5424 syslog(8) format (see http://www.rfc-editor.org/info/rfc5424)
12
12
  SYSLOG5424PRI <%{NONNEGINT:syslog5424_pri}>
13
13
  SYSLOG5424SD \[%{DATA}\]+
14
- SYSLOG5424BASE %{SYSLOG5424PRI}%{NONNEGINT:syslog5424_ver} +(?:%{TIMESTAMP_ISO8601:syslog5424_ts}|-) +(?:%{HOSTNAME:syslog5424_host}|-) +(-|%{SYSLOG5424PRINTASCII:syslog5424_app}) +(-|%{SYSLOG5424PRINTASCII:syslog5424_proc}) +(-|%{SYSLOG5424PRINTASCII:syslog5424_msgid}) +(?:%{SYSLOG5424SD:syslog5424_sd}|-|)
14
+ SYSLOG5424BASE %{SYSLOG5424PRI}%{NONNEGINT:syslog5424_ver} +(?:%{TIMESTAMP_ISO8601:syslog5424_ts}|-) +(?:%{IPORHOST:syslog5424_host}|-) +(-|%{SYSLOG5424PRINTASCII:syslog5424_app}) +(-|%{SYSLOG5424PRINTASCII:syslog5424_proc}) +(-|%{SYSLOG5424PRINTASCII:syslog5424_msgid}) +(?:%{SYSLOG5424SD:syslog5424_sd}|-|)
15
15
 
16
16
  SYSLOG5424LINE %{SYSLOG5424BASE} +%{GREEDYDATA:syslog5424_msg}
@@ -0,0 +1 @@
1
+ MAVEN_VERSION (?:(\d+)\.)?(?:(\d+)\.)?(\*|\d+)(?:[.-](RELEASE|SNAPSHOT))?
@@ -89,7 +89,7 @@ NAGIOS_PASSIVE_HOST_CHECK %{NAGIOS_TYPE_PASSIVE_HOST_CHECK:nagios_type}: %{DATA:
89
89
  NAGIOS_SERVICE_EVENT_HANDLER %{NAGIOS_TYPE_SERVICE_EVENT_HANDLER:nagios_type}: %{DATA:nagios_hostname};%{DATA:nagios_service};%{DATA:nagios_state};%{DATA:nagios_statelevel};%{DATA:nagios_event_handler_name}
90
90
  NAGIOS_HOST_EVENT_HANDLER %{NAGIOS_TYPE_HOST_EVENT_HANDLER:nagios_type}: %{DATA:nagios_hostname};%{DATA:nagios_state};%{DATA:nagios_statelevel};%{DATA:nagios_event_handler_name}
91
91
 
92
- NAGIOS_TIMEPERIOD_TRANSITION %{NAGIOS_TYPE_TIMEPERIOD_TRANSITION:nagios_type}: %{DATA:nagios_service};%{DATA:nagios_unknown1};%{DATA:nagios_unknown2}
92
+ NAGIOS_TIMEPERIOD_TRANSITION %{NAGIOS_TYPE_TIMEPERIOD_TRANSITION:nagios_type}: %{DATA:nagios_service};%{NUMBER:nagios_unknown1};%{NUMBER:nagios_unknown2}
93
93
 
94
94
  ####################
95
95
  #### External checks
@@ -1,3 +1,3 @@
1
1
  REDISTIMESTAMP %{MONTHDAY} %{MONTH} %{TIME}
2
2
  REDISLOG \[%{POSINT:pid}\] %{REDISTIMESTAMP:timestamp} \*
3
-
3
+ REDISMONLOG %{NUMBER:timestamp} \[%{INT:database} %{IP:client}:%{NUMBER:port}\] "%{WORD:command}"\s?%{GREEDYDATA:params}
@@ -0,0 +1,4 @@
1
+ # Pattern squid3
2
+ # Documentation of squid3 logs formats can be found at the following link:
3
+ # http://wiki.squid-cache.org/Features/LogFormat
4
+ SQUID3 %{NUMBER:timestamp}\s+%{NUMBER:duration}\s%{IP:client_address}\s%{WORD:cache_result}/%{POSINT:status_code}\s%{NUMBER:bytes}\s%{WORD:request_method}\s%{NOTSPACE:url}\s(%{NOTSPACE:user}|-)\s%{WORD:hierarchy_code}/%{IPORHOST:server}\s%{NOTSPACE:content_type}
@@ -20,16 +20,6 @@ describe "SYSLOGLINE" do
20
20
 
21
21
  end
22
22
 
23
- describe "COMMONAPACHELOG" do
24
-
25
- let(:value) { '83.149.9.216 - - [24/Feb/2015:23:13:42 +0000] "GET /presentations/logstash-monitorama-2013/images/kibana-search.png HTTP/1.1" 200 203023 "http://semicomplete.com/presentations/logstash-monitorama-2013/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36'}
26
-
27
- it "generates the clientip field" do
28
- expect(grok_match(subject, value)).to include("clientip" => "83.149.9.216")
29
- end
30
-
31
- end
32
-
33
23
  describe "HTTP DATE parsing" do
34
24
 
35
25
  context "HTTPDATE", "when having a German month" do
@@ -73,6 +63,19 @@ describe "TOMCATLOG" do
73
63
  end
74
64
  end
75
65
 
66
+ describe 'LOGLEVEL' do
67
+ it 'matches info label' do
68
+ expect(grok_match(subject, 'INFO')).to pass
69
+ expect(grok_match(subject, 'info')).to pass
70
+ end
71
+
72
+ it 'matches information label' do
73
+ expect(grok_match(subject, 'information')).to pass
74
+ expect(grok_match(subject, 'Information')).to pass
75
+ expect(grok_match(subject, 'INFORMATION')).to pass
76
+ end
77
+ end
78
+
76
79
  describe "IPORHOST" do
77
80
 
78
81
  let(:pattern) { "IPORHOST" }
@@ -100,14 +103,224 @@ describe "UNIXPATH" do
100
103
  let(:value) { '/foo/bar' }
101
104
 
102
105
  it "should match the path" do
103
- expect(grok_match(pattern,value)).to pass
106
+ expect(grok_match(pattern, value, true)).to pass
104
107
  end
105
108
 
106
109
  context "when using comma separators and other regexp" do
107
110
 
111
+ let(:pattern) { '((a=(?<a>%{UNIXPATH})?|b=(?<b>%{UNIXPATH})?)(,\s)?)+' }
112
+
113
+ let(:grok) do
114
+ grok = LogStash::Filters::Grok.new("match" => ["message", pattern])
115
+ grok.register
116
+ grok
117
+ end
118
+
108
119
  let(:value) { 'a=/some/path, b=/some/other/path' }
109
120
 
121
+ it "was expected to extract both but never really did" do # or maybe on JRuby 1.7
122
+ event = build_event(value)
123
+ grok.filter(event)
124
+ expect( event.to_hash['a'] ).to eql '/some/path,'
125
+ expect( event.to_hash['b'] ).to be nil
126
+ end
127
+
128
+ end
129
+
130
+ context 'relative path' do
131
+
132
+ let(:path_matcher) do # non-exact matcher
133
+ grok = LogStash::Filters::Grok.new("match" => ["message", '%{UNIXPATH:path}'])
134
+ grok.register
135
+ lambda { |msg| event = build_event(msg); grok.filter(event); event }
136
+ end
137
+
138
+ it "should not match (only partially)" do
139
+ expect(grok_match(pattern, 'a/./b/c', true)).to_not pass
140
+ event = path_matcher.('a/./b/c')
141
+ expect( event.to_hash['path'] ).to eql '/./b/c'
142
+
143
+ expect(grok_match(pattern, ',/.', true)).to_not pass
144
+ event = path_matcher.(',/.')
145
+ expect( event.to_hash['path'] ).to eql '/.'
146
+
147
+ expect(grok_match(pattern, '+/.../', true)).to_not pass
148
+ event = path_matcher.('+/.../')
149
+ expect( event.to_hash['path'] ).to eql '/.../'
150
+
151
+ expect(grok_match(pattern, '~/b/', true)).to_not pass
152
+ event = path_matcher.('~/b/')
153
+ expect( event.to_hash['path'] ).to eql '/b/'
154
+
155
+ expect(grok_match(pattern, './b//', true)).to_not pass
156
+ expect(grok_match(pattern, 'a//b', true)).to_not pass
157
+ end
158
+
159
+ it "should not match paths starting with ." do
160
+ expect(grok_match(pattern, '../0', true)).to_not pass
161
+ expect(grok_match(pattern, './~', true)).to_not pass
162
+ expect(grok_match(pattern, '.../-', true)).to_not pass
163
+ expect(grok_match(pattern, './', true)).to_not pass
164
+ expect(grok_match(pattern, './,', true)).to_not pass
165
+ expect(grok_match(pattern, '../', true)).to_not pass
166
+ expect(grok_match(pattern, '.a/', true)).to_not pass
167
+ expect(grok_match(pattern, '.~/', true)).to_not pass
168
+ end
169
+
170
+ it "should not match expression wout separator" do
171
+ expect(grok_match(pattern, '.')).to_not pass
172
+ expect(grok_match(pattern, '..')).to_not pass
173
+ expect(grok_match(pattern, '...')).to_not pass
174
+ expect(grok_match(pattern, '.,')).to_not pass
175
+ expect(grok_match(pattern, '.-')).to_not pass
176
+ end
177
+
178
+ end
179
+
180
+ context "dotted path" do
181
+
182
+ it "should match path containing ." do
183
+ expect(grok_match(pattern, '/some/./path/', true)).to pass
184
+ expect(grok_match(pattern, '/some/../path', true)).to pass
185
+ expect(grok_match(pattern, '/../.', true)).to pass
186
+ expect(grok_match(pattern, '/.', true)).to pass
187
+ expect(grok_match(pattern, '/..', true)).to pass
188
+ expect(grok_match(pattern, '/...', true)).to pass
189
+ end
190
+
191
+ end
192
+
193
+ context "separators" do
194
+
195
+ it "should match root" do
196
+ expect(grok_match(pattern, '/', true)).to pass
197
+ end
198
+
199
+ it "should match" do
200
+ expect(grok_match(pattern, '//', true)).to pass
201
+ expect(grok_match(pattern, '//00', true)).to pass
202
+ expect(grok_match(pattern, '///a', true)).to pass
203
+ expect(grok_match(pattern, '/a//', true)).to pass
204
+ expect(grok_match(pattern, '///a//b/c///', true)).to pass
205
+ end
206
+
207
+ it "should not match windows separator" do
208
+ expect(grok_match(pattern, "\\a", true)).to_not pass
209
+ expect(grok_match(pattern, '/0\\', true)).to_not pass
210
+ expect(grok_match(pattern, "/a\\b", true)).to_not pass
211
+ end
212
+
213
+ end
214
+
215
+ context "long path" do
216
+
217
+ let(:grok) do
218
+ grok = LogStash::Filters::Grok.new("match" => ["message", '%{UNIXPATH:path} '], 'timeout_millis' => 1500)
219
+ grok.register
220
+ grok
221
+ end
222
+
223
+ let(:value) { '/opt/abcdef/1/.22/3:3+3/foo@BAR/X-Y+Z/~Sample_l_SUBc b' }
224
+
110
225
  it "should match the path" do
226
+ event = build_event(value)
227
+ grok.filter(event)
228
+ expect( event.to_hash['path'] ).to eql '/opt/abcdef/1/.22/3:3+3/foo@BAR/X-Y+Z/~Sample_l_SUBc'
229
+ end
230
+
231
+ it "should not match with invalid chars (or cause DoS)" do
232
+ event = build_event(value.sub('SUB', '&^_'))
233
+ grok.filter(event) # used to call a looong looop (DoS) despite the timeout guard
234
+ expect( event.to_hash['tags'] ).to include '_grokparsefailure'
235
+ end
236
+ end
237
+
238
+ it "matches paths with non-ascii characters" do
239
+ event = build_event path = '/opt/Čierný_Peter/.中'
240
+ build_grok('UNIXPATH:path').filter event
241
+ expect( event.get('path') ).to eql path
242
+ end
243
+
244
+ end
245
+
246
+ describe "WINPATH" do
247
+
248
+ let(:pattern) { 'WINPATH' }
249
+ let(:value) { 'C:\\foo\\bar' }
250
+
251
+ it "should match the path" do
252
+ expect(grok_match(pattern, value, true)).to pass
253
+ end
254
+
255
+ it "should match root path" do
256
+ expect(grok_match(pattern, 'C:\\', true)).to pass
257
+ expect(grok_match(pattern, 'C:\\\\', true)).to pass
258
+ expect(grok_match(pattern, 'a:\\', true)).to pass
259
+ expect(grok_match(pattern, 'x:\\\\', true)).to pass
260
+ end
261
+
262
+ it "should match paths with spaces" do
263
+ expect(grok_match(pattern, 'C:\\Documents and Settings\\Public', true)).to pass
264
+ expect(grok_match(pattern, 'C:\\\\Users\\\\Public\\\\.Mozilla Firefox', true)).to pass
265
+ end
266
+
267
+ it "should not match unix-style paths" do
268
+ expect(grok_match(pattern, '/foo', true)).to_not pass
269
+ expect(grok_match(pattern, '//C/path', true)).to_not pass
270
+ expect(grok_match(pattern, '/', true)).to_not pass
271
+ expect(grok_match(pattern, '/foo/bar', true)).to_not pass
272
+ expect(grok_match(pattern, '/..', true)).to_not pass
273
+ expect(grok_match(pattern, 'C://', true)).to_not pass
274
+ end
275
+
276
+ it "matches paths with non-ascii characters" do
277
+ expect(grok_match(pattern, 'C:\\Čierný Peter\\.中.exe', true)).to pass
278
+ end
279
+
280
+ context 'relative paths' do
281
+
282
+ it "should not match" do
283
+ expect(grok_match(pattern, 'a\\bar', true)).to_not pass
284
+ expect(grok_match(pattern, 'foo\\bar', true)).to_not pass
285
+ expect(grok_match(pattern, 'C\\A\\B', true)).to_not pass
286
+ expect(grok_match(pattern, 'C\\\\0', true)).to_not pass
287
+ expect(grok_match(pattern, '.\\0', true)).to_not pass
288
+ expect(grok_match(pattern, '..\\', true)).to_not pass
289
+ expect(grok_match(pattern, '...\\-', true)).to_not pass
290
+ expect(grok_match(pattern, '.\\', true)).to_not pass
291
+ expect(grok_match(pattern, '.\\,', true)).to_not pass
292
+ expect(grok_match(pattern, '..\\', true)).to_not pass
293
+ expect(grok_match(pattern, '.a\\', true)).to_not pass
294
+ end
295
+
296
+ it "should not match expression wout separator" do
297
+ expect(grok_match(pattern, '.')).to_not pass
298
+ expect(grok_match(pattern, '..')).to_not pass
299
+ expect(grok_match(pattern, '...')).to_not pass
300
+ expect(grok_match(pattern, 'C:')).to_not pass
301
+ expect(grok_match(pattern, 'C')).to_not pass
302
+ end
303
+
304
+ end
305
+
306
+ end
307
+
308
+
309
+ describe "URIPROTO" do
310
+ let(:pattern) { 'URIPROTO' }
311
+
312
+ context "http is a valid URIPROTO" do
313
+ let(:value) { 'http' }
314
+
315
+ it "should match" do
316
+ expect(grok_match(pattern,value)).to pass
317
+ end
318
+ end
319
+
320
+ context "android-app is a valid URIPROTO" do
321
+ let(:value) { 'android-app' }
322
+
323
+ it "should match" do
111
324
  expect(grok_match(pattern,value)).to pass
112
325
  end
113
326
  end
@@ -193,5 +406,92 @@ describe "IPV4" do
193
406
  expect(grok_match(pattern,value)).not_to pass
194
407
  end
195
408
  end
409
+ end
410
+
411
+ describe "URN" do
412
+
413
+ let(:pattern) { "URN" }
414
+
415
+ # Valid URNs
416
+ # http://tools.ietf.org/html/rfc2141#section-2
417
+ let(:simple) { "urn:example:foo" }
418
+ let(:unreserved) { "urn:example:" +
419
+ [*'A'..'Z', *'a'..'z', *'0'..'9', "()+,-.::=@;$_!*'"].join() }
420
+ let(:reserved) { "urn:example:/#?" }
421
+ let(:escaped_upper) { "urn:example:%25foo%2Fbar%3F%23" }
422
+ let(:escaped_lower) { "urn:example:%25foo%2fbar%3f%23" }
423
+ let(:only_escaped) { "urn:example:%00" }
424
+ let(:long_nid) { "urn:example-example-example-example-:foo" }
425
+
426
+ # Invalid URNs
427
+ let(:bad_prefix) { "URN:example:foo" }
428
+ let(:empty_nid) { "urn::foo" }
429
+ let(:leading_hyphen) { "urn:-example:foo" }
430
+ let(:bad_nid) { "urn:example.com:foo" }
431
+ let(:percent_nid) { "urn:example%41com:foo" }
432
+ let(:too_long_nid) { "urn:example-example-example-example-x:foo" }
433
+ let(:empty_nss) { "urn:example:" }
434
+ let(:naked_percent) { "urn:example:%" }
435
+ let(:short_percent) { "urn:example:%a" }
436
+ let(:nonhex_percent) { "urn:example:%ax" }
437
+
438
+ context "when testing a valid URN" do
439
+ it "should match a simple URN" do
440
+ expect(grok_match(pattern, simple)).to pass
441
+ end
442
+
443
+ it "should match a complex URN" do
444
+ expect(grok_match(pattern, unreserved)).to pass
445
+ end
446
+
447
+ it "should allow reserved characters" do
448
+ expect(grok_match(pattern, reserved)).to pass
449
+ end
450
+
451
+ it "should allow percent-escapes" do
452
+ expect(grok_match(pattern, escaped_upper)).to pass
453
+ expect(grok_match(pattern, escaped_lower)).to pass
454
+ expect(grok_match(pattern, only_escaped)).to pass
455
+ end
456
+
457
+ it "should match a URN with a 32-character NID" do
458
+ expect(grok_match(pattern, long_nid)).to pass
459
+ end
460
+ end
461
+
462
+ context "when testing an invalid URN" do
463
+ it "should reject capitalized 'URN'" do
464
+ expect(grok_match(pattern, bad_prefix)).not_to pass
465
+ end
196
466
 
467
+ it "should reject an empty NID" do
468
+ expect(grok_match(pattern, empty_nid)).not_to pass
469
+ end
470
+
471
+ it "should reject an NID with a leading hyphen" do
472
+ expect(grok_match(pattern, leading_hyphen)).not_to pass
473
+ end
474
+
475
+ it "should reject an NID with a special character" do
476
+ expect(grok_match(pattern, bad_nid)).not_to pass
477
+ end
478
+
479
+ it "should reject an NID with a percent sign" do
480
+ expect(grok_match(pattern, percent_nid)).not_to pass
481
+ end
482
+
483
+ it "should reject an NID longer than 32 characters" do
484
+ expect(grok_match(pattern, too_long_nid)).not_to pass
485
+ end
486
+
487
+ it "should reject a URN with an empty NSS" do
488
+ expect(grok_match(pattern, empty_nss)).not_to pass
489
+ end
490
+
491
+ it "should reject non-escape percent signs" do
492
+ expect(grok_match(pattern, naked_percent)).not_to pass
493
+ expect(grok_match(pattern, short_percent)).not_to pass
494
+ expect(grok_match(pattern, nonhex_percent)).not_to pass
495
+ end
496
+ end
197
497
  end
@@ -19,6 +19,21 @@ describe "FIREWALLS" do
19
19
  expect(subject["message"]).to include("(Secondary) Switching to ACTIVE - Service card in other unit has failed")
20
20
  end
21
21
  end
22
+
23
+ let(:pattern106015) { "CISCOFW106015" }
24
+
25
+ context "parsing a 106015 message" do
26
+
27
+ let(:value) { "Deny TCP (no connection) from 192.168.150.65/2278 to 64.101.128.83/80 flags RST on interface inside" }
28
+
29
+ subject { grok_match(pattern106015, value) }
30
+
31
+ it { should include("interface" => "inside") }
32
+
33
+ it "generates a message field" do
34
+ expect(subject["message"]).to include("Deny TCP (no connection) from 192.168.150.65/2278 to 64.101.128.83/80 flags RST on interface inside")
35
+ end
36
+ end
22
37
 
23
38
  let(:pattern106100) { "CISCOFW106100" }
24
39
 
@@ -50,6 +65,22 @@ describe "FIREWALLS" do
50
65
  end
51
66
  end
52
67
 
68
+ let(:pattern304001) { "CISCOFW304001" }
69
+
70
+ context "parsing a 304001 message" do
71
+
72
+ let(:value) { "10.20.30.40(DOMAIN\\login) Accessed URL 10.11.12.13:http://example.org/" }
73
+
74
+ subject { grok_match(pattern304001, value) }
75
+
76
+ it 'should break the message up into fields' do
77
+ expect(subject['src_ip']).to eq('10.20.30.40')
78
+ expect(subject['src_fwuser']).to eq('DOMAIN\\login')
79
+ expect(subject['dst_ip']).to eq('10.11.12.13')
80
+ expect(subject['dst_url']).to eq('http://example.org/')
81
+ end
82
+ end
83
+
53
84
  let(:pattern106023) { "CISCOFW106023" }
54
85
 
55
86
  context "parsing a 106023 message" do