mirror of
https://github.com/Cisco-Talos/clamav.git
synced 2025-10-19 10:23:17 +00:00
clamd: add ExtendedDetectionInfo (bb#1228, #1626)
This commit is contained in:
parent
fd45238eb6
commit
edbba730b3
18 changed files with 128 additions and 24 deletions
|
@ -1,3 +1,7 @@
|
|||
Tue Jul 6 19:19:39 CEST 2010 (tk)
|
||||
----------------------------------
|
||||
* clamd: add ExtendedDetectionInfo (bb#1228, #1626)
|
||||
|
||||
Mon Jul 5 17:30:11 CEST 2010 (tk)
|
||||
----------------------------------
|
||||
* libclamav: fix some error messages (bb#2083)
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "libclamav/clamav.h"
|
||||
#include "libclamav/scanners.h"
|
||||
|
||||
#include "shared/optparser.h"
|
||||
#include "shared/output.h"
|
||||
|
@ -73,8 +74,10 @@ static void *clamukolegacyth(void *arg)
|
|||
unsigned long mask = 0;
|
||||
const struct optstruct *pt;
|
||||
short int scan;
|
||||
int sizelimit = 0;
|
||||
int sizelimit = 0, extinfo;
|
||||
struct stat sb;
|
||||
char virhash[33];
|
||||
unsigned int virsize;
|
||||
|
||||
|
||||
clamuko_scanning = 0;
|
||||
|
@ -166,6 +169,8 @@ static void *clamukolegacyth(void *arg)
|
|||
else
|
||||
logg("Clamuko: File size limit disabled.\n");
|
||||
|
||||
extinfo = optget(tharg->opts, "ExtendedDetectionInfo")->enabled;
|
||||
|
||||
while(1) {
|
||||
|
||||
if(dazukoGetAccess(&acc) == 0) {
|
||||
|
@ -180,8 +185,11 @@ static void *clamukolegacyth(void *arg)
|
|||
}
|
||||
}
|
||||
|
||||
if(scan && cl_scanfile(acc->filename, &virname, NULL, tharg->engine, tharg->options) == CL_VIRUS) {
|
||||
logg("Clamuko: %s: %s FOUND\n", acc->filename, virname);
|
||||
if(scan && cli_scanfile_stats(acc->filename, &virname, virhash, &virsize, NULL, tharg->engine, tharg->options) == CL_VIRUS) {
|
||||
if(extinfo && virsize)
|
||||
logg("Clamuko: %s: %s(%s:%u) FOUND\n", acc->filename, virname, virhash, virsize);
|
||||
else
|
||||
logg("Clamuko: %s: %s FOUND\n", acc->filename, virname);
|
||||
virusaction(acc->filename, virname, tharg->opts);
|
||||
acc->deny = 1;
|
||||
} else
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <pthread.h>
|
||||
|
||||
#include "libclamav/clamav.h"
|
||||
#include "libclamav/scanners.h"
|
||||
|
||||
#include "shared/optparser.h"
|
||||
#include "shared/output.h"
|
||||
|
@ -82,14 +83,14 @@ static void *clamuko_scanth(void *arg)
|
|||
{
|
||||
struct thrarg *tharg = (struct thrarg *) arg;
|
||||
sigset_t sigset;
|
||||
unsigned int sizelimit = 0;
|
||||
unsigned int sizelimit = 0, virsize;
|
||||
struct stat sb;
|
||||
dazukofs_handle_t scan_hndl;
|
||||
struct dazukofs_access acc;
|
||||
const char *groupname = "ClamAV";
|
||||
int skip_scan = 0;
|
||||
int skip_scan = 0, extinfo;
|
||||
const char *virname;
|
||||
char filename[4096];
|
||||
char filename[4096], virhash[33];
|
||||
|
||||
/* ignore all signals */
|
||||
sigfillset(&sigset);
|
||||
|
@ -130,6 +131,8 @@ static void *clamuko_scanth(void *arg)
|
|||
else
|
||||
logg("Clamuko: File size limit disabled.\n");
|
||||
|
||||
extinfo = optget(tharg->opts, "ExtendedDetectionInfo")->enabled;
|
||||
|
||||
while(1) {
|
||||
if(dazukofs_get_access(scan_hndl, &acc)) {
|
||||
if(!shutdown_hndl)
|
||||
|
@ -152,10 +155,13 @@ static void *clamuko_scanth(void *arg)
|
|||
acc.deny = 0;
|
||||
/* reset skip flag */
|
||||
skip_scan = 0;
|
||||
} else if(cl_scandesc(acc.fd, &virname, NULL, tharg->engine,
|
||||
} else if(cli_scandesc_stats(acc.fd, &virname, virhash, &virsize, NULL, tharg->engine,
|
||||
tharg->options) == CL_VIRUS) {
|
||||
dazukofs_get_filename(&acc, filename, sizeof(filename));
|
||||
logg("Clamuko: %s: %s FOUND\n", filename, virname);
|
||||
if(extinfo && virsize)
|
||||
logg("Clamuko: %s: %s(%s:%u) FOUND\n", filename, virname, virhash, virsize);
|
||||
else
|
||||
logg("Clamuko: %s: %s FOUND\n", filename, virname);
|
||||
/* we can not perform any special action because it will
|
||||
* trigger DazukoFS recursively */
|
||||
acc.deny = 1;
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
|
||||
#include "libclamav/clamav.h"
|
||||
#include "libclamav/others.h"
|
||||
#include "libclamav/scanners.h"
|
||||
|
||||
#include "shared/optparser.h"
|
||||
#include "shared/output.h"
|
||||
|
@ -77,6 +78,8 @@ int scan_callback(struct stat *sb, char *filename, const char *msg, enum cli_ftw
|
|||
const char *virname;
|
||||
int ret;
|
||||
int type = scandata->type;
|
||||
char virhash[33];
|
||||
unsigned int virsize;
|
||||
|
||||
/* detect disconnected socket,
|
||||
* this should NOT detect half-shutdown sockets (SHUT_WR) */
|
||||
|
@ -193,7 +196,7 @@ int scan_callback(struct stat *sb, char *filename, const char *msg, enum cli_ftw
|
|||
|
||||
thrmgr_setactivetask(filename,
|
||||
type == TYPE_MULTISCAN ? "MULTISCANFILE" : NULL);
|
||||
ret = cl_scanfile(filename, &virname, &scandata->scanned, scandata->engine, scandata->options);
|
||||
ret = cli_scanfile_stats(filename, &virname, virhash, &virsize, &scandata->scanned, scandata->engine, scandata->options);
|
||||
thrmgr_setactivetask(NULL, NULL);
|
||||
|
||||
if (thrmgr_group_need_terminate(scandata->conn->group)) {
|
||||
|
@ -204,11 +207,16 @@ int scan_callback(struct stat *sb, char *filename, const char *msg, enum cli_ftw
|
|||
|
||||
if (ret == CL_VIRUS) {
|
||||
scandata->infected++;
|
||||
if (conn_reply(scandata->conn, filename, virname, "FOUND") == -1) {
|
||||
if(!optget(scandata->opts, "ExtendedDetectionInfo")->enabled)
|
||||
virsize = 0;
|
||||
if (conn_reply_virus(scandata->conn, filename, virname, virhash, virsize) == -1) {
|
||||
free(filename);
|
||||
return CL_ETIMEOUT;
|
||||
}
|
||||
logg("~%s: %s FOUND\n", filename, virname);
|
||||
if(virsize)
|
||||
logg("~%s: %s(%s:%u) FOUND\n", filename, virname, virhash, virsize);
|
||||
else
|
||||
logg("~%s: %s FOUND\n", filename, virname);
|
||||
virusaction(filename, virname, scandata->opts);
|
||||
} else if (ret != CL_CLEAN) {
|
||||
scandata->errors++;
|
||||
|
@ -271,7 +279,8 @@ int scanfd(const int fd, const client_conn_t *conn, unsigned long int *scanned,
|
|||
int ret;
|
||||
const char *virname;
|
||||
struct stat statbuf;
|
||||
char fdstr[32];
|
||||
char fdstr[32], virhash[33];
|
||||
unsigned int virsize;
|
||||
|
||||
if (stream)
|
||||
strncpy(fdstr, "stream", sizeof(fdstr));
|
||||
|
@ -285,7 +294,7 @@ int scanfd(const int fd, const client_conn_t *conn, unsigned long int *scanned,
|
|||
}
|
||||
|
||||
thrmgr_setactivetask(fdstr, NULL);
|
||||
ret = cl_scandesc(fd, &virname, scanned, engine, options);
|
||||
ret = cli_scandesc_stats(fd, &virname, virhash, &virsize, scanned, engine, options);
|
||||
thrmgr_setactivetask(NULL, NULL);
|
||||
|
||||
if (thrmgr_group_need_terminate(conn->group)) {
|
||||
|
@ -294,9 +303,14 @@ int scanfd(const int fd, const client_conn_t *conn, unsigned long int *scanned,
|
|||
}
|
||||
|
||||
if(ret == CL_VIRUS) {
|
||||
if (conn_reply(conn, fdstr, virname, "FOUND") == -1)
|
||||
if(!optget(opts, "ExtendedDetectionInfo")->enabled)
|
||||
virsize = 0;
|
||||
if (conn_reply_virus(conn, fdstr, virname, virhash, virsize) == -1)
|
||||
ret = CL_ETIMEOUT;
|
||||
logg("%s: %s FOUND\n", fdstr, virname);
|
||||
if(virsize)
|
||||
logg("%s: %s(%s:%u) FOUND\n", fdstr, virname, virhash, virsize);
|
||||
else
|
||||
logg("%s: %s FOUND\n", fdstr, virname);
|
||||
virusaction(fdstr, virname, opts);
|
||||
} else if(ret != CL_CLEAN) {
|
||||
if (conn_reply(conn, fdstr, cl_strerror(ret), "ERROR") == -1)
|
||||
|
@ -315,12 +329,12 @@ int scanstream(int odesc, unsigned long int *scanned, const struct cl_engine *en
|
|||
{
|
||||
int ret, sockfd, acceptd;
|
||||
int tmpd, bread, retval, firsttimeout, timeout, btread;
|
||||
unsigned int port = 0, portscan, min_port, max_port;
|
||||
unsigned int port = 0, portscan, min_port, max_port, virsize;
|
||||
unsigned long int quota = 0, maxsize = 0;
|
||||
short bound = 0;
|
||||
const char *virname;
|
||||
char buff[FILEBUFF];
|
||||
char peer_addr[32];
|
||||
char peer_addr[32], virhash[33];
|
||||
struct sockaddr_in server;
|
||||
struct sockaddr_in peer;
|
||||
socklen_t addrlen;
|
||||
|
@ -448,7 +462,7 @@ int scanstream(int odesc, unsigned long int *scanned, const struct cl_engine *en
|
|||
if(retval == 1) {
|
||||
lseek(tmpd, 0, SEEK_SET);
|
||||
thrmgr_setactivetask(peer_addr, NULL);
|
||||
ret = cl_scandesc(tmpd, &virname, scanned, engine, options);
|
||||
ret = cli_scandesc_stats(tmpd, &virname, virhash, &virsize, scanned, engine, options);
|
||||
thrmgr_setactivetask(NULL, NULL);
|
||||
} else {
|
||||
ret = -1;
|
||||
|
@ -462,8 +476,13 @@ int scanstream(int odesc, unsigned long int *scanned, const struct cl_engine *en
|
|||
closesocket(sockfd);
|
||||
|
||||
if(ret == CL_VIRUS) {
|
||||
mdprintf(odesc, "stream: %s FOUND%c", virname, term);
|
||||
logg("stream(%s@%u): %s FOUND\n", peer_addr, port, virname);
|
||||
if(optget(opts, "ExtendedDetectionInfo")->enabled && virsize) {
|
||||
mdprintf(odesc, "stream: %s(%s:%u) FOUND%c", virname, virhash, virsize, term);
|
||||
logg("stream(%s@%u): %s(%s:%u) FOUND\n", peer_addr, port, virname, virhash, virsize);
|
||||
} else {
|
||||
mdprintf(odesc, "stream: %s FOUND%c", virname, term);
|
||||
logg("stream(%s@%u): %s FOUND\n", peer_addr, port, virname);
|
||||
}
|
||||
virusaction("stream", virname, opts);
|
||||
} else if(ret != CL_CLEAN) {
|
||||
if(retval == 1) {
|
||||
|
|
|
@ -154,6 +154,22 @@ int conn_reply(const client_conn_t *conn, const char *path,
|
|||
return mdprintf(conn->sd, "%s %s%c", msg, status, conn->term);
|
||||
}
|
||||
|
||||
int conn_reply_virus(const client_conn_t *conn, const char *file,
|
||||
const char *virname, const char *virhash, unsigned int virsize)
|
||||
{
|
||||
if (conn->id) {
|
||||
if (virsize)
|
||||
return mdprintf(conn->sd, "%u: %s: %s(%s:%u) FOUND%c", conn->id, file,
|
||||
virname, virhash, virsize, conn->term);
|
||||
return mdprintf(conn->sd, "%u: %s: %s FOUND%c", conn->id, file, virname,
|
||||
conn->term);
|
||||
}
|
||||
if (virsize)
|
||||
return mdprintf(conn->sd, "%s: %s(%s:%u) FOUND%c", file, virname, virhash,
|
||||
virsize, conn->term);
|
||||
return mdprintf(conn->sd, "%s: %s FOUND%c", file, virname, conn->term);
|
||||
}
|
||||
|
||||
int conn_reply_error(const client_conn_t *conn, const char *msg)
|
||||
{
|
||||
return conn_reply(conn, NULL, msg, "ERROR");
|
||||
|
|
|
@ -92,6 +92,7 @@ int execute_or_dispatch_command(client_conn_t *conn, enum commands command, cons
|
|||
|
||||
int conn_reply(const client_conn_t *conn, const char *path, const char *msg, const char *status);
|
||||
int conn_reply_single(const client_conn_t *conn, const char *path, const char *status);
|
||||
int conn_reply_virus(const client_conn_t *conn, const char *file, const char *virname, const char *virhash, unsigned int virsize);
|
||||
int conn_reply_error(const client_conn_t *conn, const char *msg);
|
||||
int conn_reply_errno(const client_conn_t *conn, const char *path, const char *msg);
|
||||
#endif
|
||||
|
|
|
@ -66,6 +66,11 @@ Enable verbose logging.
|
|||
.br
|
||||
Default: no
|
||||
.TP
|
||||
\fBExtendedDetectionInfo BOOL\fR
|
||||
Provide additional information about the infected file, such as its size and hash, together with the virus name. It's recommended to enable this option along with SubmitDetectionStats in freshclam.conf.
|
||||
.br
|
||||
Default: no
|
||||
.TP
|
||||
\fBPidFile STRING\fR
|
||||
Save the process identifier of a listening daemon (main thread) to a specified file.
|
||||
.br
|
||||
|
|
|
@ -155,7 +155,7 @@ Timeout in seconds when reading from database server.
|
|||
Default: 30
|
||||
.TP
|
||||
\fBSubmitDetectionStats STRING\fR
|
||||
When enabled freshclam will submit statistics to the ClamAV Project about the latest virus detections in your environment. The ClamAV maintainers will then use this data to determine what types of malware are the most detected in the field and in what geographic area they are. This feature requires LogTime and LogFile to be enabled in clamd.conf. The path for clamd.conf file must be provided.
|
||||
When enabled freshclam will submit statistics to the ClamAV Project about the latest virus detections in your environment. The ClamAV maintainers will then use this data to determine what types of malware are the most detected in the field and in what geographic area they are. This feature requires LogTime and LogFile to be enabled in clamd.conf, it's also recommended to turn on ExtendedDetectionInfo. The path for clamd.conf file must be provided.
|
||||
.br
|
||||
Default: disabled
|
||||
.TP
|
||||
|
|
|
@ -51,6 +51,11 @@ Example
|
|||
# Default: no
|
||||
#LogVerbose yes
|
||||
|
||||
# Provide additional information about the infected file, such as its
|
||||
# size and hash, together with the virus name. It's recommended to enable
|
||||
# this option along with SubmitDetectionStats in freshclam.conf.
|
||||
#ExtendedDetectionInfo yes
|
||||
|
||||
# This option allows you to save a process identifier of the listening
|
||||
# daemon (main thread).
|
||||
# Default: disabled
|
||||
|
|
|
@ -152,7 +152,8 @@ DatabaseMirror database.clamav.net
|
|||
# the latest virus detections in your environment. The ClamAV maintainers
|
||||
# will then use this data to determine what types of malware are the most
|
||||
# detected in the field and in what geographic area they are.
|
||||
# This feature requires LogTime and LogFile to be enabled in clamd.conf.
|
||||
# This feature requires LogTime and LogFile to be enabled in clamd.conf,
|
||||
# it's also recommended to turn on ExtendedDetectionInfo.
|
||||
# Default: no
|
||||
#SubmitDetectionStats /path/to/clamd.conf
|
||||
|
||||
|
|
|
@ -582,6 +582,7 @@ int submitstats(const char *clamdcfg, const struct optstruct *opts)
|
|||
|
||||
if(!(opt = optget(clamdopt, "LogFile"))->enabled) {
|
||||
logg("!SubmitDetectionStats: LogFile needs to be enabled in %s\n", clamdcfg);
|
||||
logg("SubmitDetectionStats: Please consider enabling ExtendedDetectionInfo\n");
|
||||
optfree(clamdopt);
|
||||
return 56;
|
||||
}
|
||||
|
|
|
@ -128,6 +128,8 @@ CLAMAV_PRIVATE {
|
|||
cli_initroots;
|
||||
cli_scanbuff;
|
||||
cli_fmap_scandesc;
|
||||
cli_scandesc_stats;
|
||||
cli_scanfile_stats;
|
||||
html_screnc_decode;
|
||||
mpool_create;
|
||||
mpool_calloc;
|
||||
|
|
|
@ -419,6 +419,13 @@ int cli_checkfp(unsigned char *digest, size_t size, cli_ctx *ctx)
|
|||
}
|
||||
#endif
|
||||
|
||||
if(ctx->virsize && !*ctx->virsize) {
|
||||
if(ctx->virsize)
|
||||
*ctx->virsize = size;
|
||||
if(ctx->virhash)
|
||||
strcpy(ctx->virhash, md5);
|
||||
}
|
||||
|
||||
return CL_VIRUS;
|
||||
}
|
||||
|
||||
|
|
|
@ -109,6 +109,8 @@ typedef struct bitset_tag
|
|||
/* internal clamav context */
|
||||
typedef struct cli_ctx_tag {
|
||||
const char **virname;
|
||||
char *virhash;
|
||||
unsigned int *virsize;
|
||||
unsigned long int *scanned;
|
||||
const struct cli_matcher *root;
|
||||
const struct cl_engine *engine;
|
||||
|
|
|
@ -2368,7 +2368,7 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
|
|||
}
|
||||
}
|
||||
|
||||
int cl_scandesc(int desc, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, unsigned int scanoptions)
|
||||
int cli_scandesc_stats(int desc, const char **virname, char *virhash, unsigned int *virsize, unsigned long int *scanned, const struct cl_engine *engine, unsigned int scanoptions)
|
||||
{
|
||||
cli_ctx ctx;
|
||||
int rc;
|
||||
|
@ -2376,6 +2376,11 @@ int cl_scandesc(int desc, const char **virname, unsigned long int *scanned, cons
|
|||
memset(&ctx, '\0', sizeof(cli_ctx));
|
||||
ctx.engine = engine;
|
||||
ctx.virname = virname;
|
||||
if(virsize) {
|
||||
*virsize = 0;
|
||||
ctx.virsize = virsize;
|
||||
ctx.virhash = virhash;
|
||||
}
|
||||
ctx.scanned = scanned;
|
||||
ctx.options = scanoptions;
|
||||
ctx.found_possibly_unwanted = 0;
|
||||
|
@ -2414,6 +2419,11 @@ int cl_scandesc(int desc, const char **virname, unsigned long int *scanned, cons
|
|||
return rc;
|
||||
}
|
||||
|
||||
int cl_scandesc(int desc, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, unsigned int scanoptions)
|
||||
{
|
||||
return cli_scandesc_stats(desc, virname, NULL, NULL, scanned, engine, scanoptions);
|
||||
}
|
||||
|
||||
int cli_found_possibly_unwanted(cli_ctx* ctx)
|
||||
{
|
||||
if(ctx->virname) {
|
||||
|
@ -2463,6 +2473,19 @@ int cl_scanfile(const char *filename, const char **virname, unsigned long int *s
|
|||
return ret;
|
||||
}
|
||||
|
||||
int cli_scanfile_stats(const char *filename, const char **virname, char *virhash, unsigned int *virsize, unsigned long int *scanned, const struct cl_engine *engine, unsigned int scanoptions)
|
||||
{
|
||||
int fd, ret;
|
||||
|
||||
if((fd = safe_open(filename, O_RDONLY|O_BINARY)) == -1)
|
||||
return CL_EOPEN;
|
||||
|
||||
ret = cli_scandesc_stats(fd, virname, virhash, virsize, scanned, engine, scanoptions);
|
||||
close(fd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
c-basic-offset: 4
|
||||
|
|
|
@ -26,5 +26,7 @@
|
|||
|
||||
int cli_magic_scandesc(int desc, cli_ctx *ctx);
|
||||
int cli_found_possibly_unwanted(cli_ctx* ctx);
|
||||
int cli_scandesc_stats(int desc, const char **virname, char *virhash, unsigned int *virsize, unsigned long int *scanned, const struct cl_engine *engine, unsigned int scanoptions);
|
||||
int cli_scanfile_stats(const char *filename, const char **virname, char *virhash, unsigned int *virsize, unsigned long int *scanned, const struct cl_engine *engine, unsigned int scanoptions);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -177,6 +177,8 @@ const struct clam_option __clam_options[] = {
|
|||
|
||||
{ "LogVerbose", NULL, 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD | OPT_FRESHCLAM | OPT_MILTER, "Enable verbose logging.", "yes" },
|
||||
|
||||
{ "ExtendedDetectionInfo", NULL, 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD, "Provide additional information about the infected file, such as its\nsize and hash, together with the virus name.", "yes" },
|
||||
|
||||
{ "PidFile", "pid", 'p', TYPE_STRING, NULL, -1, NULL, 0, OPT_CLAMD | OPT_FRESHCLAM | OPT_MILTER, "Save the process ID to a file.", "/var/run/clam.pid" },
|
||||
|
||||
{ "TemporaryDirectory", "tempdir", 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_CLAMD | OPT_MILTER | OPT_CLAMSCAN | OPT_SIGTOOL, "This option allows you to change the default temporary directory.", "/tmp" },
|
||||
|
|
|
@ -502,7 +502,7 @@
|
|||
/* #undef USE_SYSLOG */
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "devel-clamav-0.96-186-g5f12eac"
|
||||
#define VERSION "devel-clamav-0.96-192-gfd45238"
|
||||
|
||||
/* Version suffix for package */
|
||||
#define VERSION_SUFFIX ""
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue