2
* Copyright (c) 2002-2010 BalaBit IT Ltd, Budapest, Hungary
3
* Copyright (c) 1998-2010 Balázs Scheidler
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Lesser General Public
7
* License as published by the Free Software Foundation; either
8
* version 2.1 of the License, or (at your option) any later version.
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Lesser General Public License for more details.
15
* You should have received a copy of the GNU Lesser General Public
16
* License along with this library; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
* As an additional exemption you are allowed to compile & link against the
20
* OpenSSL libraries as published by the OpenSSL project. See the file
21
* COPYING for details.
26
#include "syslog-names.h"
29
#include "logprocess.h"
33
#include "filter-expr-grammar.h"
39
typedef struct _LogFilterRule
45
/****************************************************************
46
* Filter expression nodes
47
****************************************************************/
50
filter_expr_eval(FilterExprNode *self, LogMessage *msg)
54
res = self->eval(self, msg);
55
msg_debug("Filter node evaluation result",
56
evt_tag_str("filter_result", res ? "match" : "not-match"),
57
evt_tag_str("filter_type", self->type),
63
filter_expr_free(FilterExprNode *self)
71
typedef struct _FilterOp
74
FilterExprNode *left, *right;
78
fop_free(FilterExprNode *s)
80
FilterOp *self = (FilterOp *) s;
82
filter_expr_free(self->left);
83
filter_expr_free(self->right);
88
fop_or_eval(FilterExprNode *s, LogMessage *msg)
90
FilterOp *self = (FilterOp *) s;
92
return (filter_expr_eval(self->left, msg) || filter_expr_eval(self->right, msg)) ^ s->comp;
96
fop_or_new(FilterExprNode *e1, FilterExprNode *e2)
98
FilterOp *self = g_new0(FilterOp, 1);
100
self->super.eval = fop_or_eval;
101
self->super.free_fn = fop_free;
102
self->super.modify = e1->modify || e2->modify;
105
self->super.type = "OR";
110
fop_and_eval(FilterExprNode *s, LogMessage *msg)
112
FilterOp *self = (FilterOp *) s;
114
return (filter_expr_eval(self->left, msg) && filter_expr_eval(self->right, msg)) ^ s->comp;
118
fop_and_new(FilterExprNode *e1, FilterExprNode *e2)
120
FilterOp *self = g_new0(FilterOp, 1);
122
self->super.eval = fop_and_eval;
123
self->super.free_fn = fop_free;
124
self->super.modify = e1->modify || e2->modify;
127
self->super.type = "AND";
131
#define FCMP_EQ 0x0001
132
#define FCMP_LT 0x0002
133
#define FCMP_GT 0x0004
134
#define FCMP_NUM 0x0010
136
typedef struct _FilterCmp
138
FilterExprNode super;
139
LogTemplate *left, *right;
140
GString *left_buf, *right_buf;
145
fop_cmp_eval(FilterExprNode *s, LogMessage *msg)
147
FilterCmp *self = (FilterCmp *) s;
148
gboolean result = FALSE;
151
log_template_format(self->left, msg, NULL, LTZ_LOCAL, 0, self->left_buf);
152
log_template_format(self->right, msg, NULL, LTZ_LOCAL, 0, self->right_buf);
154
if (self->cmp_op & FCMP_NUM)
158
l = atoi(self->left_buf->str);
159
r = atoi(self->right_buf->str);
169
cmp = strcmp(self->left_buf->str, self->right_buf->str);
174
result = self->cmp_op & FCMP_EQ;
178
result = self->cmp_op & FCMP_LT || self->cmp_op == 0;
182
result = self->cmp_op & FCMP_GT || self->cmp_op == 0;
184
return result ^ s->comp;
188
fop_cmp_free(FilterExprNode *s)
190
FilterCmp *self = (FilterCmp *) s;
192
log_template_unref(self->left);
193
log_template_unref(self->right);
194
g_string_free(self->left_buf, TRUE);
195
g_string_free(self->right_buf, TRUE);
200
fop_cmp_new(LogTemplate *left, LogTemplate *right, gint op)
202
FilterCmp *self = g_new0(FilterCmp, 1);
204
self->super.eval = fop_cmp_eval;
205
self->super.free_fn = fop_cmp_free;
208
self->left_buf = g_string_sized_new(32);
209
self->right_buf = g_string_sized_new(32);
210
self->super.type = "CMP";
215
self->cmp_op = FCMP_NUM;
217
self->cmp_op = FCMP_LT;
221
self->cmp_op = FCMP_NUM;
223
self->cmp_op = FCMP_LT | FCMP_EQ;
227
self->cmp_op = FCMP_NUM;
229
self->cmp_op = FCMP_EQ;
233
self->cmp_op = FCMP_NUM;
239
self->cmp_op = FCMP_NUM;
241
self->cmp_op = FCMP_GT | FCMP_EQ;
245
self->cmp_op = FCMP_NUM;
247
self->cmp_op = FCMP_GT;
254
typedef struct _FilterPri
256
FilterExprNode super;
261
filter_facility_eval(FilterExprNode *s, LogMessage *msg)
263
FilterPri *self = (FilterPri *) s;
264
guint32 fac_num = (msg->pri & LOG_FACMASK) >> 3;
266
if (G_UNLIKELY(self->valid & 0x80000000))
268
/* exact number specified */
269
return ((self->valid & ~0x80000000) == fac_num) ^ s->comp;
273
return !!(self->valid & (1 << fac_num)) ^ self->super.comp;
275
return self->super.comp;
279
filter_facility_new(guint32 facilities)
281
FilterPri *self = g_new0(FilterPri, 1);
283
self->super.eval = filter_facility_eval;
284
self->valid = facilities;
285
self->super.type = "facility";
290
filter_level_eval(FilterExprNode *s, LogMessage *msg)
292
FilterPri *self = (FilterPri *) s;
293
guint32 pri = msg->pri & LOG_PRIMASK;
295
return !!((1 << pri) & self->valid) ^ self->super.comp;
299
filter_level_new(guint32 levels)
301
FilterPri *self = g_new0(FilterPri, 1);
303
self->super.eval = filter_level_eval;
304
self->valid = levels;
305
self->super.type = "level";
310
filter_re_eval_string(FilterExprNode *s, LogMessage *msg, gint value_handle, const gchar *str, gssize str_len)
312
FilterRE *self = (FilterRE *) s;
315
str_len = strlen(str);
317
return log_matcher_match(self->matcher, msg, value_handle, str, str_len) ^ self->super.comp;
321
filter_re_eval(FilterExprNode *s, LogMessage *msg)
323
FilterRE *self = (FilterRE *) s;
327
value = log_msg_get_value(msg, self->value_handle, &len);
329
value = APPEND_ZERO(value, len);
330
return filter_re_eval_string(s, msg, self->value_handle, value, len);
335
filter_re_free(FilterExprNode *s)
337
FilterRE *self = (FilterRE *) s;
339
log_matcher_free(self->matcher);
344
filter_re_set_matcher(FilterRE *self, LogMatcher *matcher)
349
/* save the flags to use them in the new matcher */
350
flags = self->matcher->flags;
351
log_matcher_free(self->matcher);
353
self->matcher = matcher;
355
filter_re_set_flags(self, flags);
359
filter_re_set_flags(FilterRE *self, gint flags)
361
/* if there is only a flags() param, we must crete the default matcher*/
363
self->matcher = log_matcher_posix_re_new();
364
if (flags & LMF_STORE_MATCHES)
365
self->super.modify = TRUE;
366
log_matcher_set_flags(self->matcher, flags | LMF_MATCH_ONLY);
370
filter_re_set_regexp(FilterRE *self, gchar *re)
373
self->matcher = log_matcher_posix_re_new();
375
return log_matcher_compile(self->matcher, re);
379
filter_re_new(NVHandle value_handle)
381
FilterRE *self = g_new0(FilterRE, 1);
383
self->value_handle = value_handle;
384
self->super.eval = filter_re_eval;
385
self->super.free_fn = filter_re_free;
390
filter_match_eval(FilterExprNode *s, LogMessage *msg)
392
FilterRE *self = (FilterRE *) s;
396
if (G_UNLIKELY(!self->value_handle))
401
pid = log_msg_get_value(msg, LM_V_PID, &pid_len);
403
/* compatibility mode */
404
str = g_strdup_printf("%s%s%s%s: %s",
405
log_msg_get_value(msg, LM_V_PROGRAM, NULL),
406
pid_len > 0 ? "[" : "",
408
pid_len > 0 ? "]" : "",
409
log_msg_get_value(msg, LM_V_MESSAGE, NULL));
410
res = filter_re_eval_string(s, msg, LM_V_NONE, str, -1);
415
res = filter_re_eval(s, msg);
423
FilterRE *self = g_new0(FilterRE, 1);
425
self->super.free_fn = filter_re_free;
426
self->super.eval = filter_match_eval;
430
typedef struct _FilterCall
432
FilterExprNode super;
435
gboolean error_logged;
439
filter_call_eval(FilterExprNode *s, LogMessage *msg)
441
FilterCall *self = (FilterCall *) s;
444
rule = g_hash_table_lookup(self->cfg->filters, self->rule->str);
448
return filter_expr_eval(rule->expr, msg) ^ s->comp;
452
if (!self->error_logged)
454
msg_error("Referenced filter rule not found",
455
evt_tag_str("rule", self->rule->str),
457
self->error_logged = TRUE;
464
filter_call_free(FilterExprNode *s)
466
FilterCall *self = (FilterCall *) s;
468
g_string_free(self->rule, TRUE);
469
g_free((gchar *) self->super.type);
474
filter_call_new(gchar *rule, GlobalConfig *cfg)
476
FilterCall *self = g_new0(FilterCall, 1);
478
self->super.eval = filter_call_eval;
479
self->super.free_fn = filter_call_free;
480
self->rule = g_string_new(rule);
482
self->super.type = g_strdup_printf("filter(%s)", rule);
487
typedef struct _FilterNetmask
489
FilterExprNode super;
490
struct in_addr address;
491
struct in_addr netmask;
495
filter_netmask_eval(FilterExprNode *s, LogMessage *msg)
497
FilterNetmask *self = (FilterNetmask *) s;
500
if (msg->saddr && g_sockaddr_inet_check(msg->saddr))
502
addr = ((struct sockaddr_in *) &msg->saddr->sa)->sin_addr;
504
else if (!msg->saddr || msg->saddr->sa.sa_family == AF_UNIX)
506
addr.s_addr = htonl(INADDR_LOOPBACK);
510
/* no address information, return FALSE */
513
return ((addr.s_addr & self->netmask.s_addr) == (self->address.s_addr)) ^ s->comp;
518
filter_netmask_new(gchar *cidr)
520
FilterNetmask *self = g_new0(FilterNetmask, 1);
524
slash = strchr(cidr, '/');
525
if (strlen(cidr) >= sizeof(buf) || !slash)
527
g_inet_aton(cidr, &self->address);
528
self->netmask.s_addr = htonl(0xFFFFFFFF);
532
strncpy(buf, cidr, slash - cidr + 1);
533
buf[slash - cidr] = 0;
534
g_inet_aton(buf, &self->address);
535
if (strchr(slash + 1, '.'))
537
g_inet_aton(slash + 1, &self->netmask);
541
gint prefix = strtol(slash + 1, NULL, 10);
543
self->netmask.s_addr = htonl(0xFFFFFFFF);
545
self->netmask.s_addr = htonl(((1 << prefix) - 1) << (32 - prefix));
548
self->address.s_addr &= self->netmask.s_addr;
549
self->super.eval = filter_netmask_eval;
553
typedef struct _FilterTags
555
FilterExprNode super;
560
filter_tags_eval(FilterExprNode *s, LogMessage *msg)
562
FilterTags *self = (FilterTags *)s;
565
for (i = 0; i < self->tags->len; i++)
567
if (log_msg_is_tag_by_id(msg, g_array_index(self->tags, LogTagId, i)))
568
return TRUE ^ s->comp;
571
return FALSE ^ s->comp;
575
filter_tags_add(FilterExprNode *s, GList *tags)
577
FilterTags *self = (FilterTags *)s;
582
id = log_tags_get_by_name((gchar *) tags->data);
584
tags = g_list_delete_link(tags, tags);
585
g_array_append_val(self->tags, id);
590
filter_tags_free(FilterExprNode *s)
592
FilterTags *self = (FilterTags *)s;
594
g_array_free(self->tags, TRUE);
600
filter_tags_new(GList *tags)
602
FilterTags *self = g_new0(FilterTags, 1);
604
self->tags = g_array_new(FALSE, FALSE, sizeof(LogTagId));
606
filter_tags_add(&self->super, tags);
608
self->super.eval = filter_tags_eval;
609
self->super.free_fn = filter_tags_free;
615
log_filter_rule_free(LogProcessRule *s)
617
LogFilterRule *self = (LogFilterRule *) s;
619
filter_expr_free(self->expr);
623
log_filter_rule_process(LogProcessRule *s, LogMessage *msg)
625
LogFilterRule *self = (LogFilterRule *) s;
628
msg_debug("Filter rule evaluation begins",
629
evt_tag_str("filter_rule", self->super.name),
631
res = filter_expr_eval(self->expr, msg);
632
msg_debug("Filter rule evaluation result",
633
evt_tag_str("filter_result", res ? "match" : "not-match"),
634
evt_tag_str("filter_rule", self->super.name),
640
log_filter_rule_new(const gchar *name, FilterExprNode *expr)
642
LogFilterRule *self = g_new0(LogFilterRule, 1);
644
log_process_rule_init_instance(&self->super, name);
645
self->super.process = log_filter_rule_process;
646
self->super.free_fn = log_filter_rule_free;
647
self->super.modify = expr->modify;