1 /*
2 * Copyright (c) 2008-2016 Balabit
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published
6 * by the Free Software Foundation, or (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 *
17 * As an additional exemption you are allowed to compile & link against the
18 * OpenSSL libraries as published by the OpenSSL project. See the file
19 * COPYING for details.
20 *
21 */
22
23 #include <criterion/criterion.h>
24
25 #include "logmatcher.h"
26 #include "apphook.h"
27 #include "plugin.h"
28 #include "cfg.h"
29 #include "msg_parse_lib.h"
30
31 #include <stdlib.h>
32 #include <string.h>
33
34 MsgFormatOptions parse_options;
35
36 static LogMessage *
_create_log_message(const gchar * log)37 _create_log_message(const gchar *log)
38 {
39 LogMessage *msg;
40 gchar buf[1024];
41 NVHandle nonasciiz = log_msg_get_value_handle("NON-ASCIIZ");
42 gssize msglen;
43
44 msg = log_msg_new(log, strlen(log), &parse_options);
45
46 /* NOTE: we test how our matchers cope with non-zero terminated values. We don't change message_len, only the value */
47 g_snprintf(buf, sizeof(buf), "%sAAAAAAAAAAAA", log_msg_get_value(msg, LM_V_MESSAGE, &msglen));
48 log_msg_set_value_by_name(msg, "MESSAGE2", buf, -1);
49
50 /* add a non-zero terminated indirect value which contains the whole message */
51 log_msg_set_value_indirect(msg, nonasciiz, log_msg_get_value_handle("MESSAGE2"), 0, 0, msglen);
52
53 return msg;
54 }
55
56 static LogMatcher *
_construct_matcher(gint matcher_flags,LogMatcher * (* construct)(const LogMatcherOptions * options))57 _construct_matcher(gint matcher_flags, LogMatcher *(*construct)(const LogMatcherOptions *options))
58 {
59 LogMatcherOptions matcher_options;
60
61 log_matcher_options_defaults(&matcher_options);
62 matcher_options.flags = matcher_flags;
63
64 return construct(&matcher_options);
65 }
66
67
68 void
testcase_match(const gchar * log,const gchar * pattern,gboolean expected_result,LogMatcher * m)69 testcase_match(const gchar *log, const gchar *pattern, gboolean expected_result, LogMatcher *m)
70 {
71 LogMessage *msg;
72 gboolean result;
73 NVHandle nonasciiz = log_msg_get_value_handle("NON-ASCIIZ");
74 gssize msglen;
75 const gchar *value;
76
77 msg = _create_log_message(log);
78 log_matcher_compile(m, pattern, NULL);
79
80 value = log_msg_get_value(msg, nonasciiz, &msglen);
81 result = log_matcher_match(m, msg, nonasciiz, value, msglen);
82
83 cr_assert_eq(result, expected_result,
84 "pattern=%s, result=%d, expected=%d\n",
85 pattern, result, expected_result);
86
87 log_matcher_unref(m);
88 log_msg_unref(msg);
89 }
90
91 void
testcase_replace(const gchar * log,const gchar * re,gchar * replacement,const gchar * expected_result,LogMatcher * m)92 testcase_replace(const gchar *log, const gchar *re, gchar *replacement, const gchar *expected_result, LogMatcher *m)
93 {
94 LogMessage *msg;
95 LogTemplate *r;
96 gchar *result;
97 gssize length;
98 gssize msglen;
99 NVHandle nonasciiz = log_msg_get_value_handle("NON-ASCIIZ");
100 const gchar *value;
101
102 msg = _create_log_message(log);
103 log_matcher_compile(m, re, NULL);
104
105 r = log_template_new(configuration, NULL);
106 cr_assert(log_template_compile(r, replacement, NULL));
107
108 NVTable *nv_table = nv_table_ref(msg->payload);
109 value = log_msg_get_value(msg, nonasciiz, &msglen);
110 result = log_matcher_replace(m, msg, nonasciiz, value, msglen, r, &length);
111 value = log_msg_get_value(msg, nonasciiz, &msglen);
112 nv_table_unref(nv_table);
113
114 cr_assert_arr_eq((result ? result : value), expected_result, (result ? length : msglen),
115 "pattern=%s, result=%.*s, expected=%s\n",
116 re, (int) length, (result ? result : value), expected_result);
117
118 g_free(result);
119
120 log_template_unref(r);
121 log_matcher_unref(m);
122 log_msg_unref(msg);
123 }
124
125
126 void
setup(void)127 setup(void)
128 {
129 app_startup();
130 init_parse_options_and_load_syslogformat(&parse_options);
131 }
132
133 void
teardown(void)134 teardown(void)
135 {
136 deinit_syslogformat_module();
137 app_shutdown();
138 }
139
140 TestSuite(matcher, .init = setup, .fini = teardown);
141
142 Test(matcher, pcre_regexp, .description = "PCRE regexp")
143 {
144 testcase_replace("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: árvíztűrőtükörfúrógép", "árvíz",
145 "favíz", "favíztűrőtükörfúrógép", _construct_matcher(0, log_matcher_pcre_re_new));
146 testcase_replace("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: árvíztűrőtükörfúrógép", "^tűrő",
147 "faró", "árvíztűrőtükörfúrógép", _construct_matcher(0, log_matcher_pcre_re_new));
148 testcase_replace("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: árvíztűrőtükörfúrógép", "tűrő", "",
149 "árvíztükörfúrógép", _construct_matcher(0, log_matcher_pcre_re_new));
150 testcase_replace("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: wikiwiki", "wi", "", "kiki",
151 _construct_matcher(LMF_GLOBAL, log_matcher_pcre_re_new));
152 testcase_replace("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: wikiwiki", "wi", "kuku", "kukukikukuki",
153 _construct_matcher(LMF_GLOBAL, log_matcher_pcre_re_new));
154 }
155
Test(matcher,back_ref)156 Test(matcher, back_ref)
157 {
158 testcase_replace("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: wikiwiki", "(wiki)\\1", "", "",
159 _construct_matcher(LMF_STORE_MATCHES, log_matcher_pcre_re_new));
160 }
161
162 Test(matcher, empty_global, .description = "empty match with global flag")
163 {
164 testcase_replace("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: aa bb", "c*", "#", "#a#a# #b#b#",
165 _construct_matcher(LMF_GLOBAL, log_matcher_pcre_re_new));
166 testcase_replace("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: aa bb", "a*", "#", "## #b#b#",
167 _construct_matcher(LMF_GLOBAL, log_matcher_pcre_re_new));
168
169 testcase_replace("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: aa bb", "c*", "#", "#a#a# #b#b#",
170 _construct_matcher(LMF_GLOBAL, log_matcher_pcre_re_new));
171 testcase_replace("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: aa bb", "a*", "?", "?? ?b?b?",
172 _construct_matcher(LMF_GLOBAL, log_matcher_pcre_re_new));
173 testcase_replace("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: aa", "aa|b*", "@", "@@",
174 _construct_matcher(LMF_GLOBAL, log_matcher_pcre_re_new));
175 testcase_replace("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: aa", "aa|b*", "@", "@", _construct_matcher(0,
176 log_matcher_pcre_re_new));
177 testcase_replace("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: aa", "b*|aa", "@", "@@@",
178 _construct_matcher(LMF_GLOBAL, log_matcher_pcre_re_new));
179 testcase_replace("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: aa", "b*|aa", "@", "@aa", _construct_matcher(0,
180 log_matcher_pcre_re_new));
181
182 testcase_replace("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: wikiwiki", "wi", "", "kiki",
183 _construct_matcher(LMF_GLOBAL, log_matcher_pcre_re_new));
184 testcase_replace("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: wikiwiki", "wi", "kuku", "kukukikukuki",
185 _construct_matcher(LMF_GLOBAL, log_matcher_pcre_re_new));
186 }
187
Test(matcher,disable_jit)188 Test(matcher, disable_jit)
189 {
190 testcase_replace("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: árvíztűrőtükörfúrógép", "árvíz",
191 "favíz", "favíztűrőtükörfúrógép", _construct_matcher(LMF_DISABLE_JIT, log_matcher_pcre_re_new));
192 }
193
Test(matcher,string_match)194 Test(matcher, string_match)
195 {
196 testcase_replace("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: árvíztűrőtükörfúrógép", "árvíz",
197 "favíz", "favíztűrőtükörfúrógép", _construct_matcher(LMF_PREFIX, log_matcher_string_new));
198 testcase_replace("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: árvíztűrőtükörfúrógép", "tűrő",
199 "faró", "árvízfarótükörfúrógép", _construct_matcher(LMF_SUBSTRING, log_matcher_string_new));
200 testcase_replace("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: árvíztűrőtükörfúrógép", "tűrő", "",
201 "árvíztükörfúrógép", _construct_matcher(LMF_SUBSTRING, log_matcher_string_new));
202 testcase_replace("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: árvíztűrőtükörfúrógép",
203 "árvíztűrőtükörfúrógép", "almafa", "almafa", _construct_matcher(0, log_matcher_string_new));
204 testcase_replace("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: ", "valami-amivel-nem-szabadna-matchelni",
205 "almafa", "", _construct_matcher(0, log_matcher_string_new));
206
207
208 testcase_match("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: val", "valami-amivel-nem-szabadna-matchelni",
209 FALSE, _construct_matcher(0, log_matcher_string_new));
210 testcase_match("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: ", "valami-amivel-nem-szabadna-matchelni", FALSE,
211 _construct_matcher(0, log_matcher_string_new));
212 testcase_match("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: ", "valami-amivel-nem-szabadna-matchelni", 0,
213 _construct_matcher(LMF_PREFIX, log_matcher_string_new));
214 testcase_match("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: ", "valami-amivel-nem-szabadna-matchelni", 0,
215 _construct_matcher(LMF_SUBSTRING, log_matcher_string_new));
216
217 testcase_match("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: match", "match", TRUE, _construct_matcher(0,
218 log_matcher_string_new));
219 testcase_match("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: match", "ma", TRUE,
220 _construct_matcher(LMF_PREFIX, log_matcher_string_new));
221 testcase_match("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: match", "tch", TRUE,
222 _construct_matcher(LMF_SUBSTRING, log_matcher_string_new));
223
224 testcase_replace("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: abcdef", "ABCDEF", "qwerty", "qwerty",
225 _construct_matcher(LMF_PREFIX | LMF_ICASE, log_matcher_string_new));
226 testcase_replace("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: abcdef", "BCD", "qwerty", "aqwertyef",
227 _construct_matcher(LMF_SUBSTRING | LMF_ICASE, log_matcher_string_new));
228 }
229
Test(matcher,glob_match)230 Test(matcher, glob_match)
231 {
232 testcase_match("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: árvíztűrőtükörfúrógép", "árvíz*",
233 TRUE, _construct_matcher(0, log_matcher_glob_new));
234 testcase_match("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: árvíztűrőtükörfúrógép", "*fúrógép",
235 TRUE, _construct_matcher(0, log_matcher_glob_new));
236 testcase_match("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: árvíztűrőtükörfúrógép", "*fúró*",
237 TRUE, _construct_matcher(0, log_matcher_glob_new));
238 testcase_match("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: árvíztűrőtükörfúrógép", "tükör",
239 FALSE, _construct_matcher(0, log_matcher_glob_new));
240 testcase_match("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: árvíztűrőtükörfúrógép", "viziló",
241 FALSE, _construct_matcher(0, log_matcher_glob_new));
242 }
243
244 Test(matcher, iso88592_never, .description = "match in iso-8859-2 never matches")
245 {
246 testcase_match("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: \xe1rv\xedzt\xfbr\xf5t\xfck\xf6rf\xfar\xf3g\xe9p",
247 "\xe1rv\xed*", FALSE, _construct_matcher(0, log_matcher_glob_new));
248 }
249
Test(matcher,replace)250 Test(matcher, replace)
251 {
252 testcase_replace("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: árvíztűrőtükörfúrógép", "árvíz",
253 "favíz", "favíztűrőtükörfúrógép", _construct_matcher(0, log_matcher_pcre_re_new));
254 testcase_replace("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: árvíztűrőtükörfúrógép", "^tűrő",
255 "faró", "árvíztűrőtükörfúrógép", _construct_matcher(0, log_matcher_pcre_re_new));
256 testcase_replace("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: árvíztűrőtükörfúrógép", "tűrő", "",
257 "árvíztükörfúrógép", _construct_matcher(0, log_matcher_pcre_re_new));
258 testcase_replace("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: wikiwiki", "(wiki)\\1", "", "",
259 _construct_matcher(0, log_matcher_pcre_re_new));
260 /* back ref with perl style $1 */
261 testcase_replace("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: wikiwiki", "(wiki).+", "#$1#", "#wiki#",
262 _construct_matcher(0, log_matcher_pcre_re_new));
263 }
264
265 Test(matcher, pcre812_incompatibility, .description = "tests a pcre 8.12 incompatibility")
266 {
267 testcase_replace("<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: wikiwiki",
268 "([[:digit:]]{1,3}\\.){3}[[:digit:]]{1,3}", "foo", "wikiwiki", _construct_matcher(LMF_GLOBAL, log_matcher_pcre_re_new));
269 }
270