Browse code

secfilter: print statistics of blocked and allowed messages using RPC commands

Jose Luis Verdeguer authored on 12/03/2019 12:26:45
Showing 3 changed files
... ...
@@ -35,6 +35,7 @@
35 35
 MODULE_VERSION
36 36
 
37 37
 secf_data_p secf_data = NULL;
38
+int *secf_stats;
38 39
 
39 40
 /* Static and shared functions */
40 41
 static int mod_init(void);
... ...
@@ -111,6 +112,7 @@ struct module_exports exports = {
111 111
 /* RPC exported commands */
112 112
 static const char *rpc_reload_doc[2] = {"Reload values from database", NULL};
113 113
 static const char *rpc_print_doc[2] = {"Print values from database", NULL};
114
+static const char *rpc_stats_doc[2] = {"Print statistics of blocked and allowed messages", NULL};
114 115
 static const char *rpc_add_dst_doc[2] = {
115 116
 		"Add new values to destination blacklist", NULL};
116 117
 static const char *rpc_add_bl_doc[2] = {"Add new values to blacklist", NULL};
... ...
@@ -119,6 +121,7 @@ static const char *rpc_add_wl_doc[2] = {"Add new values to whitelist", NULL};
119 119
 rpc_export_t secfilter_rpc[] = {
120 120
 		{"secfilter.reload", secf_rpc_reload, rpc_reload_doc, 0},
121 121
 		{"secfilter.print", secf_rpc_print, rpc_print_doc, 0},
122
+		{"secfilter.stats", secf_rpc_stats, rpc_stats_doc, 0},
122 123
 		{"secfilter.add_dst", secf_rpc_add_dst, rpc_add_dst_doc, 0},
123 124
 		{"secfilter.add_bl", secf_rpc_add_bl, rpc_add_bl_doc, 0},
124 125
 		{"secfilter.add_wl", secf_rpc_add_wl, rpc_add_wl_doc, 0}, {0, 0, 0, 0}};
... ...
@@ -268,6 +271,7 @@ static int w_check_sqli(str val)
268 268
 			|| strstr(cval, "%27") || strstr(cval, "%24")
269 269
 			|| strstr(cval, "%60")) {
270 270
 		/* Illegal characters found */
271
+		secf_stats[BL_SQL]++;
271 272
 		res = -1;
272 273
 		goto end;
273 274
 	}
... ...
@@ -299,6 +303,7 @@ static int w_check_dst(struct sip_msg *msg, char *val)
299 299
 			/* Exact match */
300 300
 			if(list->s.len == dst.len) {
301 301
 				if(cmpi_str(&list->s, &dst) == 0) {
302
+					secf_stats[BL_DST]++;
302 303
 					return -2;
303 304
 				}
304 305
 			}
... ...
@@ -307,6 +312,7 @@ static int w_check_dst(struct sip_msg *msg, char *val)
307 307
 			if(dst.len > list->s.len)
308 308
 				dst.len = list->s.len;
309 309
 			if(cmpi_str(&list->s, &dst) == 0) {
310
+				secf_stats[BL_DST]++;
310 311
 				return -2;
311 312
 			}
312 313
 		}
... ...
@@ -343,6 +349,7 @@ static int w_check_ua(struct sip_msg *msg)
343 343
 			ua.len = list->s.len;
344 344
 		res = cmpi_str(&list->s, &ua);
345 345
 		if(res == 0) {
346
+			secf_stats[WL_UA]++;
346 347
 			return 2;
347 348
 		}
348 349
 		list = list->next;
... ...
@@ -356,6 +363,7 @@ static int w_check_ua(struct sip_msg *msg)
356 356
 			ua.len = list->s.len;
357 357
 		res = cmpi_str(&list->s, &ua);
358 358
 		if(res == 0) {
359
+			secf_stats[BL_UA]++;
359 360
 			return -2;
360 361
 		}
361 362
 		list = list->next;
... ...
@@ -441,6 +449,17 @@ static int check_user(struct sip_msg *msg, int type)
441 441
 		if (name.s != NULL) {
442 442
 			res = cmpi_str(&list->s, &name);
443 443
 			if(res == 0) {
444
+				switch(type) {
445
+					case 1:
446
+						secf_stats[WL_FNAME]++;
447
+						break;
448
+					case 2:
449
+						secf_stats[WL_TNAME]++;
450
+						break;
451
+					case 3:
452
+						secf_stats[WL_CNAME]++;
453
+						break;
454
+				}
444 455
 				return 4;
445 456
 			}
446 457
 		}
... ...
@@ -448,6 +467,17 @@ static int check_user(struct sip_msg *msg, int type)
448 448
 			user.len = list->s.len;
449 449
 		res = cmpi_str(&list->s, &user);
450 450
 		if(res == 0) {
451
+			switch(type) {
452
+				case 1:
453
+					secf_stats[WL_FUSER]++;
454
+					break;
455
+				case 2:
456
+					secf_stats[WL_TUSER]++;
457
+					break;
458
+				case 3:
459
+					secf_stats[WL_CUSER]++;
460
+					break;
461
+			}
451 462
 			return 2;
452 463
 		}
453 464
 		list = list->next;
... ...
@@ -462,6 +492,17 @@ static int check_user(struct sip_msg *msg, int type)
462 462
 		if (name.s != NULL) {
463 463
 			res = cmpi_str(&list->s, &name);
464 464
 			if(res == 0) {
465
+				switch(type) {
466
+					case 1:
467
+						secf_stats[BL_FNAME]++;
468
+						break;
469
+					case 2:
470
+						secf_stats[BL_TNAME]++;
471
+						break;
472
+					case 3:
473
+						secf_stats[BL_CNAME]++;
474
+						break;
475
+				}
465 476
 				return -4;
466 477
 			}
467 478
 		}
... ...
@@ -469,6 +510,17 @@ static int check_user(struct sip_msg *msg, int type)
469 469
 			user.len = list->s.len;
470 470
 		res = cmpi_str(&list->s, &user);
471 471
 		if(res == 0) {
472
+			switch(type) {
473
+				case 1:
474
+					secf_stats[BL_FUSER]++;
475
+					break;
476
+				case 2:
477
+					secf_stats[BL_TUSER]++;
478
+					break;
479
+				case 3:
480
+					secf_stats[BL_CUSER]++;
481
+					break;
482
+			}
472 483
 			return -2;
473 484
 		}
474 485
 		list = list->next;
... ...
@@ -483,6 +535,17 @@ static int check_user(struct sip_msg *msg, int type)
483 483
 			domain.len = list->s.len;
484 484
 		res = cmpi_str(&list->s, &domain);
485 485
 		if(res == 0) {
486
+			switch(type) {
487
+				case 1:
488
+					secf_stats[WL_FDOMAIN]++;
489
+					break;
490
+				case 2:
491
+					secf_stats[WL_TDOMAIN]++;
492
+					break;
493
+				case 3:
494
+					secf_stats[WL_CDOMAIN]++;
495
+					break;
496
+			}
486 497
 			return 3;
487 498
 		}
488 499
 		list = list->next;
... ...
@@ -495,6 +558,17 @@ static int check_user(struct sip_msg *msg, int type)
495 495
 			domain.len = list->s.len;
496 496
 		res = cmpi_str(&list->s, &domain);
497 497
 		if(res == 0) {
498
+			switch(type) {
499
+				case 1:
500
+					secf_stats[BL_FDOMAIN]++;
501
+					break;
502
+				case 2:
503
+					secf_stats[BL_TDOMAIN]++;
504
+					break;
505
+				case 3:
506
+					secf_stats[BL_CDOMAIN]++;
507
+					break;
508
+			}
498 509
 			return -3;
499 510
 		}
500 511
 		list = list->next;
... ...
@@ -534,6 +608,7 @@ static int w_check_ip(struct sip_msg *msg)
534 534
 			ip.len = list->s.len;
535 535
 		res = cmpi_str(&list->s, &ip);
536 536
 		if(res == 0) {
537
+			secf_stats[WL_IP]++;
537 538
 			return 2;
538 539
 		}
539 540
 		list = list->next;
... ...
@@ -546,6 +621,7 @@ static int w_check_ip(struct sip_msg *msg)
546 546
 			ip.len = list->s.len;
547 547
 		res = cmpi_str(&list->s, &ip);
548 548
 		if(res == 0) {
549
+			secf_stats[BL_IP]++;
549 550
 			return -2;
550 551
 		}
551 552
 		list = list->next;
... ...
@@ -581,6 +657,7 @@ static int w_check_country(struct sip_msg *msg, char *val)
581 581
 			country.len = list->s.len;
582 582
 		res = cmpi_str(&list->s, &country);
583 583
 		if(res == 0) {
584
+			secf_stats[WL_COUNTRY]++;
584 585
 			return 2;
585 586
 		}
586 587
 		list = list->next;
... ...
@@ -593,6 +670,7 @@ static int w_check_country(struct sip_msg *msg, char *val)
593 593
 			country.len = list->s.len;
594 594
 		res = cmpi_str(&list->s, &country);
595 595
 		if(res == 0) {
596
+			secf_stats[BL_COUNTRY]++;
596 597
 			return -2;
597 598
 		}
598 599
 		list = list->next;
... ...
@@ -610,6 +688,8 @@ INIT AND DESTROY FUNCTIONS
610 610
 /* Initialize data */
611 611
 int secf_init_data(void)
612 612
 {
613
+	int i;
614
+
613 615
 	secf_data = (secf_data_p)shm_malloc(sizeof(secf_data_t));
614 616
 	if(!secf_data) {
615 617
 		SHM_MEM_ERROR;
... ...
@@ -617,6 +697,10 @@ int secf_init_data(void)
617 617
 	}
618 618
 	memset(secf_data, 0, sizeof(secf_data_t));
619 619
 
620
+	secf_stats = shm_malloc(26 * sizeof(int));
621
+	for (i=0; i<26; i++)
622
+		secf_stats[i] = 0;
623
+	
620 624
 	if(secf_dst_exact_match != 0)
621 625
 		secf_dst_exact_match = 1;
622 626
 
... ...
@@ -734,6 +818,8 @@ void secf_free_data(void)
734 734
 	free_sec_info(&secf_data->bl);
735 735
 	memset(&secf_data->bl_last, 0, sizeof(secf_info_t));
736 736
 	LM_DBG("so, ua[%p] should be NULL\n", secf_data->bl.ua);
737
+	
738
+	shm_free(secf_stats);
737 739
 
738 740
 	lock_release(&secf_data->lock);
739 741
 }
... ...
@@ -4,6 +4,32 @@
4 4
 #include "../../core/str_list.h"
5 5
 #include "../../core/sr_module.h"
6 6
 
7
+#define BL_UA 0
8
+#define BL_COUNTRY 1
9
+#define BL_FDOMAIN 2
10
+#define BL_TDOMAIN 3
11
+#define BL_CDOMAIN 4
12
+#define BL_IP 5
13
+#define BL_FNAME 6
14
+#define BL_TNAME 7
15
+#define BL_CNAME 8
16
+#define BL_FUSER 9
17
+#define BL_TUSER 10
18
+#define BL_CUSER 11
19
+#define WL_UA 12
20
+#define WL_COUNTRY 13
21
+#define WL_FDOMAIN 14
22
+#define WL_TDOMAIN 15
23
+#define WL_CDOMAIN 16
24
+#define WL_IP 17
25
+#define WL_FNAME 18
26
+#define WL_TNAME 19
27
+#define WL_CNAME 20
28
+#define WL_FUSER 21
29
+#define WL_TUSER 22
30
+#define WL_CUSER 23
31
+#define BL_DST 24
32
+#define BL_SQL 25
7 33
 
8 34
 typedef struct _secf_info
9 35
 {
... ...
@@ -26,6 +52,9 @@ typedef struct _secf_data
26 26
 
27 27
 extern secf_data_p secf_data;
28 28
 
29
+//extern int secf_stats[22];
30
+extern int *secf_stats;
31
+
29 32
 int secf_append_rule(int action, int type, str *value);
30 33
 
31 34
 /* Get header values from message */
... ...
@@ -51,6 +80,7 @@ extern int secf_dst_exact_match;
51 51
 /* RPC commands */
52 52
 void secf_rpc_reload(rpc_t *rpc, void *ctx);
53 53
 void secf_rpc_print(rpc_t *rpc, void *ctx);
54
+void secf_rpc_stats(rpc_t *rpc, void *ctx);
54 55
 void secf_rpc_add_dst(rpc_t *rpc, void *ctx);
55 56
 void secf_rpc_add_bl(rpc_t *rpc, void *ctx);
56 57
 void secf_rpc_add_wl(rpc_t *rpc, void *ctx);
... ...
@@ -261,3 +261,47 @@ void secf_rpc_print(rpc_t *rpc, void *ctx)
261 261
 
262 262
 	rpc->rpl_printf(ctx, "");
263 263
 }
264
+
265
+/* Print stats */
266
+void secf_rpc_stats(rpc_t *rpc, void *ctx)
267
+{
268
+	rpc->rpl_printf(ctx, "");
269
+	rpc->rpl_printf(ctx, "Blocked messages (blacklist)");
270
+	rpc->rpl_printf(ctx, "============================");
271
+	rpc->rpl_printf(ctx, "[+] By user-agent    : %d", secf_stats[BL_UA]);
272
+	rpc->rpl_printf(ctx, "[+] By country       : %d", secf_stats[BL_COUNTRY]);
273
+	rpc->rpl_printf(ctx, "[+] By from domain   : %d", secf_stats[BL_FDOMAIN]);
274
+	rpc->rpl_printf(ctx, "[+] By to domain     : %d", secf_stats[BL_TDOMAIN]);
275
+	rpc->rpl_printf(ctx, "[+] By contact domain: %d", secf_stats[BL_CDOMAIN]);
276
+	rpc->rpl_printf(ctx, "[+] By IP address    : %d", secf_stats[BL_IP]);
277
+	rpc->rpl_printf(ctx, "[+] By from name     : %d", secf_stats[BL_FNAME]);
278
+	rpc->rpl_printf(ctx, "[+] By to name       : %d", secf_stats[BL_TNAME]);
279
+	rpc->rpl_printf(ctx, "[+] By contact name  : %d", secf_stats[BL_CNAME]);
280
+	rpc->rpl_printf(ctx, "[+] By from user     : %d", secf_stats[BL_FUSER]);
281
+	rpc->rpl_printf(ctx, "[+] By to user       : %d", secf_stats[BL_TUSER]);
282
+	rpc->rpl_printf(ctx, "[+] By contact user  : %d", secf_stats[BL_CUSER]);
283
+
284
+	rpc->rpl_printf(ctx, "");
285
+	rpc->rpl_printf(ctx, "Allowed messages (whitelist)");
286
+	rpc->rpl_printf(ctx, "============================");
287
+	rpc->rpl_printf(ctx, "[+] By user-agent    : %d", secf_stats[WL_UA]);
288
+	rpc->rpl_printf(ctx, "[+] By country       : %d", secf_stats[WL_COUNTRY]);
289
+	rpc->rpl_printf(ctx, "[+] By from domain   : %d", secf_stats[WL_FDOMAIN]);
290
+	rpc->rpl_printf(ctx, "[+] By to domain     : %d", secf_stats[WL_TDOMAIN]);
291
+	rpc->rpl_printf(ctx, "[+] By contact domain: %d", secf_stats[WL_CDOMAIN]);
292
+	rpc->rpl_printf(ctx, "[+] By IP address    : %d", secf_stats[WL_IP]);
293
+	rpc->rpl_printf(ctx, "[+] By from name     : %d", secf_stats[WL_FNAME]);
294
+	rpc->rpl_printf(ctx, "[+] By to name       : %d", secf_stats[WL_TNAME]);
295
+	rpc->rpl_printf(ctx, "[+] By contact name  : %d", secf_stats[WL_CNAME]);
296
+	rpc->rpl_printf(ctx, "[+] By from user     : %d", secf_stats[WL_FUSER]);
297
+	rpc->rpl_printf(ctx, "[+] By to user       : %d", secf_stats[WL_TUSER]);
298
+	rpc->rpl_printf(ctx, "[+] By contact user  : %d", secf_stats[WL_CUSER]);
299
+
300
+	rpc->rpl_printf(ctx, "");
301
+	rpc->rpl_printf(ctx, "Other blocked messages");
302
+	rpc->rpl_printf(ctx, "======================");
303
+	rpc->rpl_printf(ctx, "[+] Destinations   : %d", secf_stats[BL_DST]);
304
+	rpc->rpl_printf(ctx, "[+] SQL injection  : %d", secf_stats[BL_SQL]);
305
+	rpc->rpl_printf(ctx, "");
306
+}
307
+