... | ... |
@@ -1,3 +1,7 @@ |
1 |
+Wed Nov 3 13:38:47 CET 2010 (tk) |
|
2 |
+--------------------------------- |
|
3 |
+ * clamd: add new commands DETSTATS and DETSTATSCLEAR (part of bb#2312) |
|
4 |
+ |
|
1 | 5 |
Tue Nov 2 13:01:14 EET 2010 (edwin) |
2 | 6 |
------------------------------------ |
3 | 7 |
* libclamav/7z.c: fix file descriptor leak (bb #2347) |
... | ... |
@@ -426,9 +426,8 @@ int main(int argc, char **argv) |
426 | 426 |
} |
427 | 427 |
} |
428 | 428 |
|
429 |
- if(optget(opts, "ExtendedDetectionInfo")->enabled) |
|
430 |
- cl_engine_set_clcb_hash(engine, hash_callback); |
|
431 |
- |
|
429 |
+ cl_engine_set_clcb_hash(engine, hash_callback); |
|
430 |
+ detstats_clear(); |
|
432 | 431 |
|
433 | 432 |
if(optget(opts, "LeaveTemporaryFiles")->enabled) |
434 | 433 |
cl_engine_set_num(engine, CL_ENGINE_KEEPTMP, 1); |
... | ... |
@@ -189,6 +189,8 @@ static void *clamukolegacyth(void *arg) |
189 | 189 |
context.virsize = 0; |
190 | 190 |
if(scan && cl_scanfile_callback(acc->filename, &virname, NULL, tharg->engine, tharg->options, &context) == CL_VIRUS) { |
191 | 191 |
if(context.virsize) |
192 |
+ detstats_add(virname, acc->filename, context.virsize, context.virhash); |
|
193 |
+ if(extinfo && context.virsize) |
|
192 | 194 |
logg("Clamuko: %s: %s(%s:%llu) FOUND\n", acc->filename, virname, context.virhash, context.virsize); |
193 | 195 |
else |
194 | 196 |
logg("Clamuko: %s: %s FOUND\n", acc->filename, virname); |
... | ... |
@@ -163,6 +163,8 @@ static void *clamuko_scanth(void *arg) |
163 | 163 |
tharg->options, &context) == CL_VIRUS) { |
164 | 164 |
dazukofs_get_filename(&acc, filename, sizeof(filename)); |
165 | 165 |
if(context.virsize) |
166 |
+ detstats_add(virname, filename, context.virsize, context.virhash); |
|
167 |
+ if(extinfo && context.virsize) |
|
166 | 168 |
logg("Clamuko: %s: %s(%s:%llu) FOUND\n", filename, virname, context.virhash, context.virsize); |
167 | 169 |
else |
168 | 170 |
logg("Clamuko: %s: %s FOUND\n", filename, virname); |
... | ... |
@@ -87,6 +87,7 @@ void virusaction(const char *filename, const char *virname, const struct optstru |
87 | 87 |
#define VE_VIRUSNAME "CLAM_VIRUSEVENT_VIRUSNAME" |
88 | 88 |
|
89 | 89 |
static pthread_mutex_t virusaction_lock = PTHREAD_MUTEX_INITIALIZER; |
90 |
+static pthread_mutex_t detstats_lock = PTHREAD_MUTEX_INITIALIZER; |
|
90 | 91 |
|
91 | 92 |
void virusaction(const char *filename, const char *virname, const struct optstruct *opts) |
92 | 93 |
{ |
... | ... |
@@ -670,3 +671,54 @@ void fds_free(struct fd_data *data) |
670 | 670 |
data->nfds = 0; |
671 | 671 |
fds_unlock(data); |
672 | 672 |
} |
673 |
+ |
|
674 |
+struct detstats_s { |
|
675 |
+ char virname[128]; |
|
676 |
+ char fname[128]; |
|
677 |
+ char md5[33]; |
|
678 |
+ unsigned int fsize; |
|
679 |
+ unsigned int time; |
|
680 |
+}; |
|
681 |
+#define DETSTATS_MAX 50 |
|
682 |
+static struct detstats_s detstats_data[DETSTATS_MAX]; |
|
683 |
+static unsigned int detstats_idx = 0, detstats_total = 0; |
|
684 |
+ |
|
685 |
+void detstats_clear(void) |
|
686 |
+{ |
|
687 |
+ pthread_mutex_lock(&detstats_lock); |
|
688 |
+ detstats_idx = detstats_total = 0; |
|
689 |
+ pthread_mutex_unlock(&detstats_lock); |
|
690 |
+} |
|
691 |
+ |
|
692 |
+void detstats_add(const char *virname, const char *fname, unsigned int fsize, const char *md5) |
|
693 |
+{ |
|
694 |
+ pthread_mutex_lock(&detstats_lock); |
|
695 |
+ |
|
696 |
+ strncpy(detstats_data[detstats_idx].virname, virname, sizeof(detstats_data[detstats_idx].virname)); |
|
697 |
+ detstats_data[detstats_idx].virname[sizeof(detstats_data[detstats_idx].virname) - 1] = 0; |
|
698 |
+ |
|
699 |
+ if((fname = strrchr(fname, *PATHSEP))) |
|
700 |
+ fname++; |
|
701 |
+ strncpy(detstats_data[detstats_idx].fname, (fname || !strlen(fname)) ? "NOFNAME" : fname, sizeof(detstats_data[detstats_idx].fname)); |
|
702 |
+ detstats_data[detstats_idx].fname[sizeof(detstats_data[detstats_idx].fname) - 1] = 0; |
|
703 |
+ |
|
704 |
+ strncpy(detstats_data[detstats_idx].md5, md5, sizeof(detstats_data[detstats_idx].md5)); |
|
705 |
+ detstats_data[detstats_idx].md5[sizeof(detstats_data[detstats_idx].md5) - 1] = 0; |
|
706 |
+ |
|
707 |
+ detstats_data[detstats_idx].fsize = fsize; |
|
708 |
+ detstats_data[detstats_idx++].time = time(NULL); |
|
709 |
+ if(detstats_idx == DETSTATS_MAX) |
|
710 |
+ detstats_idx = 0; |
|
711 |
+ detstats_total++; |
|
712 |
+ pthread_mutex_unlock(&detstats_lock); |
|
713 |
+} |
|
714 |
+ |
|
715 |
+void detstats_print(int desc, char term) |
|
716 |
+{ |
|
717 |
+ unsigned int i; |
|
718 |
+ |
|
719 |
+ pthread_mutex_lock(&detstats_lock); |
|
720 |
+ for(i = 0; i < DETSTATS_MAX && i < detstats_total; i++) |
|
721 |
+ mdprintf(desc, "%u:%s:%u:%s:%s%c", detstats_data[i].time, detstats_data[i].md5, detstats_data[i].fsize, detstats_data[i].virname, detstats_data[i].fname, term); |
|
722 |
+ pthread_mutex_unlock(&detstats_lock); |
|
723 |
+} |
... | ... |
@@ -82,4 +82,8 @@ void fds_cleanup(struct fd_data *data); |
82 | 82 |
int fds_poll_recv(struct fd_data *data, int timeout, int check_signals, void *event); |
83 | 83 |
void fds_free(struct fd_data *data); |
84 | 84 |
|
85 |
+void detstats_clear(void); |
|
86 |
+void detstats_add(const char *virname, const char *fname, unsigned int fsize, const char *md5); |
|
87 |
+void detstats_print(int desc, char term); |
|
88 |
+ |
|
85 | 89 |
#endif |
... | ... |
@@ -244,6 +244,8 @@ int scan_callback(struct stat *sb, char *filename, const char *msg, enum cli_ftw |
244 | 244 |
return CL_ETIMEOUT; |
245 | 245 |
} |
246 | 246 |
if(context.virsize) |
247 |
+ detstats_add(virname, filename, context.virsize, context.virhash); |
|
248 |
+ if(context.virsize && optget(scandata->opts, "ExtendedDetectionInfo")->enabled) |
|
247 | 249 |
logg("~%s: %s(%s:%llu) FOUND\n", filename, virname, context.virhash, context.virsize); |
248 | 250 |
else |
249 | 251 |
logg("~%s: %s FOUND\n", filename, virname); |
... | ... |
@@ -338,6 +340,8 @@ int scanfd(const int fd, const client_conn_t *conn, unsigned long int *scanned, |
338 | 338 |
if (conn_reply_virus(conn, fdstr, virname, context.virhash, context.virsize) == -1) |
339 | 339 |
ret = CL_ETIMEOUT; |
340 | 340 |
if(context.virsize) |
341 |
+ detstats_add(virname, "NOFNAME", context.virsize, context.virhash); |
|
342 |
+ if(context.virsize && optget(opts, "ExtendedDetectionInfo")->enabled) |
|
341 | 343 |
logg("%s: %s(%s:%llu) FOUND\n", fdstr, virname, context.virhash, context.virsize); |
342 | 344 |
else |
343 | 345 |
logg("%s: %s FOUND\n", fdstr, virname); |
... | ... |
@@ -509,7 +513,9 @@ int scanstream(int odesc, unsigned long int *scanned, const struct cl_engine *en |
509 | 509 |
closesocket(sockfd); |
510 | 510 |
|
511 | 511 |
if(ret == CL_VIRUS) { |
512 |
- if(context.virsize) { |
|
512 |
+ if(context.virsize) |
|
513 |
+ detstats_add(virname, "NOFNAME", context.virsize, context.virhash); |
|
514 |
+ if(context.virsize && optget(opts, "ExtendedDetectionInfo")->enabled) { |
|
513 | 515 |
mdprintf(odesc, "stream: %s(%s:%llu) FOUND%c", virname, context.virhash, context.virsize, term); |
514 | 516 |
logg("stream(%s@%u): %s(%s:%llu) FOUND\n", peer_addr, port, virname, context.virhash, context.virsize); |
515 | 517 |
} else { |
... | ... |
@@ -92,10 +92,11 @@ static struct { |
92 | 92 |
{CMD14, sizeof(CMD14)-1, COMMAND_FILDES, 0, 1, FEATURE_FDPASSING}, |
93 | 93 |
{CMD15, sizeof(CMD15)-1, COMMAND_STATS, 0, 0, 1}, |
94 | 94 |
{CMD16, sizeof(CMD16)-1, COMMAND_IDSESSION, 0, 0, 1}, |
95 |
- {CMD17, sizeof(CMD17)-1, COMMAND_INSTREAM, 0, 0, 1} |
|
95 |
+ {CMD17, sizeof(CMD17)-1, COMMAND_INSTREAM, 0, 0, 1}, |
|
96 |
+ {CMD19, sizeof(CMD19)-1, COMMAND_DETSTATSCLEAR, 0, 1, 1}, |
|
97 |
+ {CMD20, sizeof(CMD20)-1, COMMAND_DETSTATS, 0, 1, 1} |
|
96 | 98 |
}; |
97 | 99 |
|
98 |
- |
|
99 | 100 |
enum commands parse_command(const char *cmd, const char **argument, int oldstyle) |
100 | 101 |
{ |
101 | 102 |
size_t i; |
... | ... |
@@ -571,6 +572,16 @@ int execute_or_dispatch_command(client_conn_t *conn, enum commands cmd, const ch |
571 | 571 |
print_commands(desc, conn->term, engine); |
572 | 572 |
return conn->group ? 0 : 1; |
573 | 573 |
} |
574 |
+ case COMMAND_DETSTATSCLEAR: |
|
575 |
+ { |
|
576 |
+ detstats_clear(); |
|
577 |
+ return 1; |
|
578 |
+ } |
|
579 |
+ case COMMAND_DETSTATS: |
|
580 |
+ { |
|
581 |
+ detstats_print(desc, conn->term); |
|
582 |
+ return 1; |
|
583 |
+ } |
|
574 | 584 |
case COMMAND_INSTREAM: |
575 | 585 |
{ |
576 | 586 |
int rc = cli_gentempfd(optget(conn->opts, "TemporaryDirectory")->strarg, &conn->filename, &conn->scanfd); |
... | ... |
@@ -40,6 +40,8 @@ |
40 | 40 |
#define CMD16 "IDSESSION" |
41 | 41 |
#define CMD17 "INSTREAM" |
42 | 42 |
#define CMD18 "VERSIONCOMMANDS" |
43 |
+#define CMD19 "DETSTATSCLEAR" |
|
44 |
+#define CMD20 "DETSTATS" |
|
43 | 45 |
|
44 | 46 |
#include "libclamav/clamav.h" |
45 | 47 |
#include "shared/optparser.h" |
... | ... |
@@ -64,6 +66,8 @@ enum commands { |
64 | 64 |
COMMAND_IDSESSION, |
65 | 65 |
COMMAND_INSTREAM, |
66 | 66 |
COMMAND_COMMANDS, |
67 |
+ COMMAND_DETSTATSCLEAR, |
|
68 |
+ COMMAND_DETSTATS, |
|
67 | 69 |
/* internal commands */ |
68 | 70 |
COMMAND_MULTISCANFILE, |
69 | 71 |
COMMAND_INSTREAMSCAN |