... | ... |
@@ -186,7 +186,8 @@ am__clamd_SOURCES_DIST = $(top_srcdir)/shared/output.c \ |
186 | 186 |
localserver.c localserver.h session.c session.h thrmgr.c \ |
187 | 187 |
thrmgr.h server-th.c server.h scanner.c scanner.h others.c \ |
188 | 188 |
others.h shared.h onaccess_fan.c onaccess_fan.h onaccess_ddd.c \ |
189 |
- onaccess_ddd.h onaccess_hash.c onaccess_hash.h |
|
189 |
+ onaccess_ddd.h onaccess_hash.c onaccess_hash.h onaccess_scth.c \ |
|
190 |
+ onaccess_scth.h |
|
190 | 191 |
@BUILD_CLAMD_TRUE@am_clamd_OBJECTS = output.$(OBJEXT) \ |
191 | 192 |
@BUILD_CLAMD_TRUE@ optparser.$(OBJEXT) getopt.$(OBJEXT) \ |
192 | 193 |
@BUILD_CLAMD_TRUE@ misc.$(OBJEXT) clamd.$(OBJEXT) \ |
... | ... |
@@ -195,7 +196,8 @@ am__clamd_SOURCES_DIST = $(top_srcdir)/shared/output.c \ |
195 | 195 |
@BUILD_CLAMD_TRUE@ server-th.$(OBJEXT) scanner.$(OBJEXT) \ |
196 | 196 |
@BUILD_CLAMD_TRUE@ others.$(OBJEXT) onaccess_fan.$(OBJEXT) \ |
197 | 197 |
@BUILD_CLAMD_TRUE@ onaccess_ddd.$(OBJEXT) \ |
198 |
-@BUILD_CLAMD_TRUE@ onaccess_hash.$(OBJEXT) |
|
198 |
+@BUILD_CLAMD_TRUE@ onaccess_hash.$(OBJEXT) \ |
|
199 |
+@BUILD_CLAMD_TRUE@ onaccess_scth.$(OBJEXT) |
|
199 | 200 |
clamd_OBJECTS = $(am_clamd_OBJECTS) |
200 | 201 |
clamd_LDADD = $(LDADD) |
201 | 202 |
AM_V_lt = $(am__v_lt_@AM_V@) |
... | ... |
@@ -493,7 +495,9 @@ top_srcdir = @top_srcdir@ |
493 | 493 |
@BUILD_CLAMD_TRUE@ onaccess_ddd.c \ |
494 | 494 |
@BUILD_CLAMD_TRUE@ onaccess_ddd.h \ |
495 | 495 |
@BUILD_CLAMD_TRUE@ onaccess_hash.c \ |
496 |
-@BUILD_CLAMD_TRUE@ onaccess_hash.h |
|
496 |
+@BUILD_CLAMD_TRUE@ onaccess_hash.h \ |
|
497 |
+@BUILD_CLAMD_TRUE@ onaccess_scth.c \ |
|
498 |
+@BUILD_CLAMD_TRUE@ onaccess_scth.h |
|
497 | 499 |
|
498 | 500 |
@BUILD_CLAMD_TRUE@AM_CFLAGS = @WERR_CFLAGS@ |
499 | 501 |
AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/shared -I$(top_srcdir)/libclamav @SSL_CPPFLAGS@ @JSON_CPPFLAGS@ @PCRE_CPPFLAGS@ |
... | ... |
@@ -619,6 +623,7 @@ distclean-compile: |
619 | 619 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/onaccess_ddd.Po@am__quote@ |
620 | 620 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/onaccess_fan.Po@am__quote@ |
621 | 621 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/onaccess_hash.Po@am__quote@ |
622 |
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/onaccess_scth.Po@am__quote@ |
|
622 | 623 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/optparser.Po@am__quote@ |
623 | 624 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/others.Po@am__quote@ |
624 | 625 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/output.Po@am__quote@ |
... | ... |
@@ -44,6 +44,7 @@ |
44 | 44 |
#include "onaccess_fan.h" |
45 | 45 |
#include "onaccess_hash.h" |
46 | 46 |
#include "onaccess_ddd.h" |
47 |
+#include "onaccess_scth.h" |
|
47 | 48 |
|
48 | 49 |
#include "libclamav/clamav.h" |
49 | 50 |
#include "libclamav/scanners.h" |
... | ... |
@@ -285,12 +286,12 @@ void *onas_ddd_th(void *arg) { |
285 | 285 |
/* ignore all signals except SIGUSR1 */ |
286 | 286 |
sigfillset(&sigset); |
287 | 287 |
sigdelset(&sigset, SIGUSR1); |
288 |
- /* The behavior of a process is undefined after it ignores a |
|
288 |
+ /* The behavior of a process is undefined after it ignores a |
|
289 | 289 |
* SIGFPE, SIGILL, SIGSEGV, or SIGBUS signal */ |
290 | 290 |
sigdelset(&sigset, SIGFPE); |
291 | 291 |
sigdelset(&sigset, SIGILL); |
292 | 292 |
sigdelset(&sigset, SIGSEGV); |
293 |
-#ifdef SIGBUS |
|
293 |
+#ifdef SIGBUS |
|
294 | 294 |
sigdelset(&sigset, SIGBUS); |
295 | 295 |
#endif |
296 | 296 |
pthread_sigmask(SIG_SETMASK, &sigset, NULL); |
... | ... |
@@ -366,6 +367,10 @@ void *onas_ddd_th(void *arg) { |
366 | 366 |
} |
367 | 367 |
} |
368 | 368 |
|
369 |
+ if(optget(tharg->opts, "OnAccessExtraScanning")->enabled) { |
|
370 |
+ logg("ScanOnAccess: Extra scanning and notifications enabled.\n"); |
|
371 |
+ } |
|
372 |
+ |
|
369 | 373 |
|
370 | 374 |
FD_ZERO(&rfds); |
371 | 375 |
FD_SET(onas_in_fd, &rfds); |
... | ... |
@@ -393,35 +398,24 @@ void *onas_ddd_th(void *arg) { |
393 | 393 |
size_t size = strlen(child) + len + 2; |
394 | 394 |
char *child_path = (char *) cli_malloc(size); |
395 | 395 |
if (child_path == NULL) |
396 |
- return CL_EMEM; |
|
396 |
+ return NULL; |
|
397 |
+ |
|
397 | 398 |
if (path[len-1] == '/') |
398 | 399 |
snprintf(child_path, --size, "%s%s", path, child); |
399 | 400 |
else |
400 | 401 |
snprintf(child_path, size, "%s/%s", path, child); |
401 | 402 |
|
402 |
- struct stat s; |
|
403 |
- if(stat(child_path, &s) == 0 && S_ISREG(s.st_mode)) continue; |
|
404 |
- if(!(event->mask & IN_ISDIR)) continue; |
|
405 |
- |
|
406 | 403 |
if (event->mask & IN_DELETE) { |
407 |
- logg("*ddd: DELETE - Removing %s from %s with wd:%d\n", child_path, path, wd); |
|
408 |
- onas_ddd_unwatch(child_path, tharg->fan_fd, onas_in_fd); |
|
409 |
- onas_ht_rm_hierarchy(ddd_ht, child_path, strlen(child_path), 0); |
|
404 |
+ onas_ddd_handle_in_delete(tharg, path, child_path, event, wd); |
|
410 | 405 |
|
411 | 406 |
} else if (event->mask & IN_MOVED_FROM) { |
412 |
- logg("*ddd: MOVED_FROM - Removing %s from %s with wd:%d\n", child_path, path, wd); |
|
413 |
- onas_ddd_unwatch(child_path, tharg->fan_fd, onas_in_fd); |
|
414 |
- onas_ht_rm_hierarchy(ddd_ht, child_path, strlen(child_path), 0); |
|
407 |
+ onas_ddd_handle_in_moved_from(tharg, path, child_path, event, wd); |
|
415 | 408 |
|
416 | 409 |
} else if (event->mask & IN_CREATE) { |
417 |
- logg("*ddd: CREATE - Adding %s to %s with wd:%d\n", child_path, path, wd); |
|
418 |
- onas_ht_add_hierarchy(ddd_ht, child_path); |
|
419 |
- onas_ddd_watch(child_path, tharg->fan_fd, tharg->fan_mask, onas_in_fd, in_mask); |
|
410 |
+ onas_ddd_handle_in_create(tharg, path, child_path, event, wd, in_mask); |
|
420 | 411 |
|
421 | 412 |
} else if (event->mask & IN_MOVED_TO) { |
422 |
- logg("*ddd: MOVED_TO - Adding %s to %s with wd:%d\n", child_path, path, wd); |
|
423 |
- onas_ht_add_hierarchy(ddd_ht, child_path); |
|
424 |
- onas_ddd_watch(child_path, tharg->fan_fd, tharg->fan_mask, onas_in_fd, in_mask); |
|
413 |
+ onas_ddd_handle_in_moved_to(tharg, path, child_path, event, wd, in_mask); |
|
425 | 414 |
} |
426 | 415 |
} |
427 | 416 |
} |
... | ... |
@@ -430,6 +424,118 @@ void *onas_ddd_th(void *arg) { |
430 | 430 |
return NULL; |
431 | 431 |
} |
432 | 432 |
|
433 |
+static void onas_ddd_handle_in_delete(struct ddd_thrarg *tharg, |
|
434 |
+ const char *path, const char *child_path, const struct inotify_event *event, int wd) { |
|
435 |
+ |
|
436 |
+ struct stat s; |
|
437 |
+ if(stat(child_path, &s) == 0 && S_ISREG(s.st_mode)) return; |
|
438 |
+ if(!(event->mask & IN_ISDIR)) return; |
|
439 |
+ |
|
440 |
+ logg("*ddd: DELETE - Removing %s from %s with wd:%d\n", child_path, path, wd); |
|
441 |
+ onas_ddd_unwatch(child_path, tharg->fan_fd, onas_in_fd); |
|
442 |
+ onas_ht_rm_hierarchy(ddd_ht, child_path, strlen(child_path), 0); |
|
443 |
+ |
|
444 |
+ return; |
|
445 |
+} |
|
446 |
+ |
|
447 |
+ |
|
448 |
+static void onas_ddd_handle_in_moved_from(struct ddd_thrarg *tharg, |
|
449 |
+ const char *path, const char *child_path, const struct inotify_event *event, int wd) { |
|
450 |
+ |
|
451 |
+ struct stat s; |
|
452 |
+ if(stat(child_path, &s) == 0 && S_ISREG(s.st_mode)) return; |
|
453 |
+ if(!(event->mask & IN_ISDIR)) return; |
|
454 |
+ |
|
455 |
+ logg("*ddd: MOVED_FROM - Removing %s from %s with wd:%d\n", child_path, path, wd); |
|
456 |
+ onas_ddd_unwatch(child_path, tharg->fan_fd, onas_in_fd); |
|
457 |
+ onas_ht_rm_hierarchy(ddd_ht, child_path, strlen(child_path), 0); |
|
458 |
+ |
|
459 |
+ return; |
|
460 |
+} |
|
461 |
+ |
|
462 |
+ |
|
463 |
+static void onas_ddd_handle_in_create(struct ddd_thrarg *tharg, |
|
464 |
+ const char *path, const char *child_path, const struct inotify_event *event, int wd, uint64_t in_mask) { |
|
465 |
+ |
|
466 |
+ struct stat s; |
|
467 |
+ if (optget(tharg->opts, "OnAccessExtraScanning")->enabled) { |
|
468 |
+ if(stat(child_path, &s) == 0 && S_ISREG(s.st_mode)) { |
|
469 |
+ onas_ddd_handle_extra_scanning(tharg, child_path, ONAS_SCTH_ISFILE); |
|
470 |
+ |
|
471 |
+ } else if(stat(child_path, &s) == 0 && S_ISDIR(s.st_mode)) { |
|
472 |
+ logg("*ddd: CREATE - Adding %s to %s with wd:%d\n", child_path, path, wd); |
|
473 |
+ onas_ht_add_hierarchy(ddd_ht, child_path); |
|
474 |
+ onas_ddd_watch(child_path, tharg->fan_fd, tharg->fan_mask, onas_in_fd, in_mask); |
|
475 |
+ |
|
476 |
+ onas_ddd_handle_extra_scanning(tharg, child_path, ONAS_SCTH_ISDIR); |
|
477 |
+ } |
|
478 |
+ } else { |
|
479 |
+ |
|
480 |
+ if(stat(child_path, &s) == 0 && S_ISREG(s.st_mode)) return; |
|
481 |
+ if(!(event->mask & IN_ISDIR)) return; |
|
482 |
+ |
|
483 |
+ logg("*ddd: MOVED_TO - Adding %s to %s with wd:%d\n", child_path, path, wd); |
|
484 |
+ onas_ht_add_hierarchy(ddd_ht, child_path); |
|
485 |
+ onas_ddd_watch(child_path, tharg->fan_fd, tharg->fan_mask, onas_in_fd, in_mask); |
|
486 |
+ } |
|
487 |
+ |
|
488 |
+ return; |
|
489 |
+} |
|
490 |
+ |
|
491 |
+static void onas_ddd_handle_in_moved_to(struct ddd_thrarg *tharg, |
|
492 |
+ const char *path, const char *child_path, const struct inotify_event *event, int wd, uint64_t in_mask) { |
|
493 |
+ |
|
494 |
+ struct stat s; |
|
495 |
+ if (optget(tharg->opts, "OnAccessExtraScanning")->enabled) { |
|
496 |
+ if(stat(child_path, &s) == 0 && S_ISREG(s.st_mode)) { |
|
497 |
+ onas_ddd_handle_extra_scanning(tharg, child_path, ONAS_SCTH_ISFILE); |
|
498 |
+ |
|
499 |
+ } else if(stat(child_path, &s) == 0 && S_ISDIR(s.st_mode)) { |
|
500 |
+ logg("*ddd: MOVED_TO - Adding %s to %s with wd:%d\n", child_path, path, wd); |
|
501 |
+ onas_ht_add_hierarchy(ddd_ht, child_path); |
|
502 |
+ onas_ddd_watch(child_path, tharg->fan_fd, tharg->fan_mask, onas_in_fd, in_mask); |
|
503 |
+ |
|
504 |
+ onas_ddd_handle_extra_scanning(tharg, child_path, ONAS_SCTH_ISDIR); |
|
505 |
+ } |
|
506 |
+ } else { |
|
507 |
+ if(stat(child_path, &s) == 0 && S_ISREG(s.st_mode)) return; |
|
508 |
+ if(!(event->mask & IN_ISDIR)) return; |
|
509 |
+ |
|
510 |
+ logg("*ddd: MOVED_TO - Adding %s to %s with wd:%d\n", child_path, path, wd); |
|
511 |
+ onas_ht_add_hierarchy(ddd_ht, child_path); |
|
512 |
+ onas_ddd_watch(child_path, tharg->fan_fd, tharg->fan_mask, onas_in_fd, in_mask); |
|
513 |
+ } |
|
514 |
+ |
|
515 |
+ return; |
|
516 |
+} |
|
517 |
+ |
|
518 |
+static void onas_ddd_handle_extra_scanning(struct ddd_thrarg *tharg, const char *pathname, int options) { |
|
519 |
+ |
|
520 |
+ struct scth_thrarg *scth_tharg = NULL; |
|
521 |
+ pthread_attr_t scth_attr; |
|
522 |
+ pthread_t scth_pid = 0; |
|
523 |
+ |
|
524 |
+ do { |
|
525 |
+ if (pthread_attr_init(&scth_attr)) break; |
|
526 |
+ pthread_attr_setdetachstate(&scth_attr, PTHREAD_CREATE_JOINABLE); |
|
527 |
+ |
|
528 |
+ if (!(scth_tharg = (struct scth_thrarg *) malloc(sizeof(struct scth_thrarg)))) break; |
|
529 |
+ |
|
530 |
+ scth_tharg->options = options; |
|
531 |
+ scth_tharg->opts = tharg->opts; |
|
532 |
+ scth_tharg->pathname = strdup(pathname); |
|
533 |
+ |
|
534 |
+ if (!pthread_create(&scth_pid, &scth_attr, onas_scan_th, scth_tharg)) break; |
|
535 |
+ |
|
536 |
+ free(scth_tharg); |
|
537 |
+ scth_tharg = NULL; |
|
538 |
+ } while(0); |
|
539 |
+ if (!scth_tharg) logg("!ScanOnAccess: Unable to kick off extra scanning.\n"); |
|
540 |
+ |
|
541 |
+ return; |
|
542 |
+} |
|
543 |
+ |
|
544 |
+ |
|
433 | 545 |
static void onas_ddd_exit(int sig) { |
434 | 546 |
logg("*ScanOnAccess: onas_ddd_exit(), signal %d\n", sig); |
435 | 547 |
|
... | ... |
@@ -437,7 +543,7 @@ static void onas_ddd_exit(int sig) { |
437 | 437 |
|
438 | 438 |
onas_free_ht(ddd_ht); |
439 | 439 |
free(wdlt); |
440 |
- |
|
440 |
+ |
|
441 | 441 |
pthread_exit(NULL); |
442 | 442 |
logg("ScanOnAccess: stopped\n"); |
443 | 443 |
} |
... | ... |
@@ -46,6 +46,12 @@ static int onas_ddd_watch_hierarchy(const char* pathname, size_t len, int fd, ui |
46 | 46 |
static int onas_ddd_unwatch(const char *pathname, int fan_fd, int in_fd); |
47 | 47 |
static int onas_ddd_unwatch_hierarchy(const char* pathname, size_t len, int fd, uint32_t type); |
48 | 48 |
|
49 |
+static void onas_ddd_handle_in_moved_to(struct ddd_thrarg *tharg, const char *path, const char *child_path, const struct inotify_event *event, int wd, uint64_t in_mask); |
|
50 |
+static void onas_ddd_handle_in_create(struct ddd_thrarg *tharg, const char *path, const char *child_path, const struct inotify_event *event, int wd, uint64_t in_mask); |
|
51 |
+static void onas_ddd_handle_in_moved_from(struct ddd_thrarg *tharg, const char *path, const char *child_path, const struct inotify_event *event, int wd); |
|
52 |
+static void onas_ddd_handle_in_delete(struct ddd_thrarg *tharg, const char *path, const char *child_path, const struct inotify_event *event, int wd); |
|
53 |
+static void onas_ddd_handle_extra_scanning(struct ddd_thrarg *tharg, const char *pathname, int options); |
|
54 |
+ |
|
49 | 55 |
int onas_ddd_init(uint64_t nwatches, size_t ht_size); |
50 | 56 |
void *onas_ddd_th(void *arg); |
51 | 57 |
static void onas_ddd_exit(int sig); |
52 | 58 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,117 @@ |
0 |
+/* |
|
1 |
+ * Copyright (C) 2015 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
|
2 |
+ * |
|
3 |
+ * Authors: Mickey Sola |
|
4 |
+ * |
|
5 |
+ * This program is free software; you can redistribute it and/or modify |
|
6 |
+ * it under the terms of the GNU General Public License version 2 as |
|
7 |
+ * published by the Free Software Foundation. |
|
8 |
+ * |
|
9 |
+ * This program is distributed in the hope that it will be useful, |
|
10 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
+ * GNU General Public License for more details. |
|
13 |
+ * |
|
14 |
+ * You should have received a copy of the GNU General Public License |
|
15 |
+ * along with this program; if not, write to the Free Software |
|
16 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
|
17 |
+ * MA 02110-1301, USA. |
|
18 |
+ */ |
|
19 |
+ |
|
20 |
+#if HAVE_CONFIG_H |
|
21 |
+#include "clamav-config.h" |
|
22 |
+#endif |
|
23 |
+ |
|
24 |
+#if defined(FANOTIFY) |
|
25 |
+ |
|
26 |
+#include <stdio.h> |
|
27 |
+#include <unistd.h> |
|
28 |
+#include <string.h> |
|
29 |
+#include <fcntl.h> |
|
30 |
+#include <fts.h> |
|
31 |
+#include <signal.h> |
|
32 |
+#include <pthread.h> |
|
33 |
+ |
|
34 |
+#include "shared/optparser.h" |
|
35 |
+#include "shared/output.h" |
|
36 |
+ |
|
37 |
+#include "others.h" |
|
38 |
+ |
|
39 |
+#include "onaccess_scth.h" |
|
40 |
+ |
|
41 |
+static void onas_scth_exit(int sig) { |
|
42 |
+ logg("*ScanOnAccess: onas_scth_exit(), signal %d\n", sig); |
|
43 |
+ |
|
44 |
+ pthread_exit(NULL); |
|
45 |
+} |
|
46 |
+ |
|
47 |
+static void onas_scth_handle_dir(const char *pathname) { |
|
48 |
+ FTS *ftsp = NULL; |
|
49 |
+ int ftspopts = FTS_PHYSICAL | FTS_XDEV; |
|
50 |
+ FTSENT *curr = NULL; |
|
51 |
+ |
|
52 |
+ char *const pathargv[] = { pathname, NULL }; |
|
53 |
+ if (!(ftsp = fts_open(pathargv, ftspopts, NULL))) return; |
|
54 |
+ |
|
55 |
+ /* Offload scanning work to fanotify thread to avoid potential deadlocks. */ |
|
56 |
+ while (curr = fts_read(ftsp)) { |
|
57 |
+ if (curr->fts_info != FTS_D) { |
|
58 |
+ int fd = open(curr->fts_path, O_RDONLY); |
|
59 |
+ if (fd > 0) close(fd); |
|
60 |
+ } |
|
61 |
+ } |
|
62 |
+ |
|
63 |
+ return; |
|
64 |
+} |
|
65 |
+ |
|
66 |
+ |
|
67 |
+static void onas_scth_handle_file(const char *pathname) { |
|
68 |
+ if (!pathname) return; |
|
69 |
+ |
|
70 |
+ /* Offload scanning work to fanotify thread to avoid potential deadlocks. */ |
|
71 |
+ int fd = open(pathname, O_RDONLY); |
|
72 |
+ if (fd > 0) close(fd); |
|
73 |
+ |
|
74 |
+ return; |
|
75 |
+} |
|
76 |
+ |
|
77 |
+void *onas_scan_th(void *arg) { |
|
78 |
+ struct scth_thrarg *tharg = (struct scth_thrarg *) arg; |
|
79 |
+ sigset_t sigset; |
|
80 |
+ struct sigaction act; |
|
81 |
+ const struct optstruct *pt; |
|
82 |
+ short int scan; |
|
83 |
+ |
|
84 |
+ /* ignore all signals except SIGUSR1 */ |
|
85 |
+ sigfillset(&sigset); |
|
86 |
+ sigdelset(&sigset, SIGUSR1); |
|
87 |
+ /* The behavior of a process is undefined after it ignores a |
|
88 |
+ * SIGFPE, SIGILL, SIGSEGV, or SIGBUS signal */ |
|
89 |
+ sigdelset(&sigset, SIGFPE); |
|
90 |
+ sigdelset(&sigset, SIGILL); |
|
91 |
+ sigdelset(&sigset, SIGSEGV); |
|
92 |
+#ifdef SIGBUS |
|
93 |
+ sigdelset(&sigset, SIGBUS); |
|
94 |
+#endif |
|
95 |
+ pthread_sigmask(SIG_SETMASK, &sigset, NULL); |
|
96 |
+ memset(&act, 0, sizeof(struct sigaction)); |
|
97 |
+ act.sa_handler = onas_scth_exit; |
|
98 |
+ sigfillset(&(act.sa_mask)); |
|
99 |
+ sigaction(SIGUSR1, &act, NULL); |
|
100 |
+ sigaction(SIGSEGV, &act, NULL); |
|
101 |
+ |
|
102 |
+ |
|
103 |
+ if (tharg->options & ONAS_SCTH_ISDIR) { |
|
104 |
+ logg("ScanOnAccess: Performing additional scanning on directory '%s'\n", tharg->pathname); |
|
105 |
+ onas_scth_handle_dir(tharg->pathname); |
|
106 |
+ } else if (tharg->options & ONAS_SCTH_ISFILE) { |
|
107 |
+ logg("ScanOnAccess: Performing additional scanning on file '%s'\n", tharg->pathname); |
|
108 |
+ onas_scth_handle_file(tharg->pathname); |
|
109 |
+ } |
|
110 |
+ |
|
111 |
+ free(tharg->pathname); |
|
112 |
+ tharg->pathname = NULL; |
|
113 |
+ |
|
114 |
+ return NULL; |
|
115 |
+} |
|
116 |
+#endif |
0 | 117 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,39 @@ |
0 |
+/* |
|
1 |
+ * Copyright (C) 2015 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
|
2 |
+ * |
|
3 |
+ * Authors: Mickey Sola |
|
4 |
+ * |
|
5 |
+ * This program is free software; you can redistribute it and/or modify |
|
6 |
+ * it under the terms of the GNU General Public License version 2 as |
|
7 |
+ * published by the Free Software Foundation. |
|
8 |
+ * |
|
9 |
+ * This program is distributed in the hope that it will be useful, |
|
10 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
+ * GNU General Public License for more details. |
|
13 |
+ * |
|
14 |
+ * You should have received a copy of the GNU General Public License |
|
15 |
+ * along with this program; if not, write to the Free Software |
|
16 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
|
17 |
+ * MA 02110-1301, USA. |
|
18 |
+ */ |
|
19 |
+ |
|
20 |
+#ifndef __ONAS_SCTH_H |
|
21 |
+#define __ONAS_SCTH_H |
|
22 |
+ |
|
23 |
+#define ONAS_SCTH_ISDIR 0x01 |
|
24 |
+#define ONAS_SCTH_ISFILE 0x02 |
|
25 |
+ |
|
26 |
+struct scth_thrarg { |
|
27 |
+ int options; |
|
28 |
+ const struct optstruct *opts; |
|
29 |
+ const char *pathname; |
|
30 |
+}; |
|
31 |
+ |
|
32 |
+static void onas_scth_handle_dir(const char *pathname); |
|
33 |
+static void onas_scth_handle_file(const char *pathname); |
|
34 |
+ |
|
35 |
+void *onas_scan_th(void *arg); |
|
36 |
+static void onas_scth_exit(int sig); |
|
37 |
+ |
|
38 |
+#endif |
... | ... |
@@ -599,6 +599,12 @@ Example |
599 | 599 |
# Default: no |
600 | 600 |
#OnAccessPrevention yes |
601 | 601 |
|
602 |
+# Toggles extra scanning and notifications when a file or directory is created or moved. |
|
603 |
+# Requires the DDD system to kick-off extra scans. |
|
604 |
+# (On-access scan only) |
|
605 |
+# Default: no |
|
606 |
+#OnAccessExtraScanning yes |
|
607 |
+ |
|
602 | 608 |
## |
603 | 609 |
## Bytecode |
604 | 610 |
## |
... | ... |
@@ -407,6 +407,8 @@ const struct clam_option __clam_options[] = { |
407 | 407 |
|
408 | 408 |
{ "OnAccessPrevention", NULL, 0, CLOPT_TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD, "This option changes fanotify behavior to prevent access attempts on malicious files instead of simply notifying the user (On Access scan only).", "yes" }, |
409 | 409 |
|
410 |
+ { "OnAccessExtraScanning", NULL, 0, CLOPT_TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD, "Enables extra scanning and notification after catching certain inotify events. Only works with the DDD system enabled.", "yes" }, |
|
411 |
+ |
|
410 | 412 |
/* FIXME: mark these as private and don't output into clamd.conf/man */ |
411 | 413 |
{ "DevACOnly", "dev-ac-only", 0, CLOPT_TYPE_BOOL, MATCH_BOOL, -1, NULL, FLAG_HIDDEN, OPT_CLAMD | OPT_CLAMSCAN, "", "" }, |
412 | 414 |
|