Merged branch klin/raw_dmg into master

Conflicts:
	libclamav/clamav.h
	libclamav/others.c
0.98.2
Kevin Lin 12 years ago
commit 9caa235ba6
  1. 4
      ChangeLog
  2. 3
      clamd/Makefile.am
  3. 2
      clamd/Makefile.in
  4. 8
      clamd/clamd.c
  5. 28
      clamd/fan-syscalllib.h
  6. 3
      clamd/fan.c
  7. 354
      clamdtop/clamdtop.c
  8. 4
      clamscan/manager.c
  9. 4
      configure
  10. 2
      configure.ac
  11. 2
      docs/man/clamd.conf.5.in
  12. 2
      docs/man/clamscan.1.in
  13. 4
      freshclam/freshclam.c
  14. 9
      freshclam/notify.c
  15. 1
      libclamav/clamav.h
  16. 625
      libclamav/dconf.c
  17. 8
      libclamav/dconf.h
  18. 31
      libclamav/hostid.c
  19. 20
      libclamav/hostid.h
  20. 20
      libclamav/json.c
  21. 20
      libclamav/json.h
  22. 2
      libclamav/matcher.c
  23. 57
      libclamav/others.c
  24. 1
      libclamav/others.h
  25. 7
      libclamav/readdb.c
  26. 49
      libclamav/stats.c
  27. 20
      libclamav/stats.h
  28. 35
      libclamav/www.c
  29. 24
      libclamav/www.h
  30. 116
      libclamav/xar.c
  31. 3
      shared/optparser.c
  32. 31
      sigtool/sigtool.c
  33. 15
      unit_tests/valgrind.supp

@ -1,3 +1,7 @@
Wed Feb 5 14:30:24 2013 EDT 2013 (dar)
------------------------------------
* bb#9156/10335: switch fanotify support to use sys/fanotify.h instead of coded syscalls
Mon Dec 5 18:10:24 2013 EDT 2013 (morgan)
------------------------------------
* bb#9595 fix for sigs targeted for ascii files containing offsets of the form EOF-n.

@ -46,8 +46,7 @@ clamd_SOURCES = \
others.h \
shared.h \
fan.c \
fan.h \
fan-syscalllib.h
fan.h
AM_CFLAGS=@WERR_CFLAGS@

@ -100,7 +100,7 @@ am__clamd_SOURCES_DIST = $(top_srcdir)/shared/output.c \
$(top_srcdir)/shared/misc.h clamd.c tcpserver.c tcpserver.h \
localserver.c localserver.h session.c session.h thrmgr.c \
thrmgr.h server-th.c server.h scanner.c scanner.h others.c \
others.h shared.h fan.c fan.h fan-syscalllib.h
others.h shared.h fan.c fan.h
@BUILD_CLAMD_TRUE@am_clamd_OBJECTS = output.$(OBJEXT) \
@BUILD_CLAMD_TRUE@ optparser.$(OBJEXT) getopt.$(OBJEXT) \
@BUILD_CLAMD_TRUE@ misc.$(OBJEXT) clamd.$(OBJEXT) \

@ -438,6 +438,10 @@ int main(int argc, char **argv)
cl_engine_set_num(engine, CL_ENGINE_DISABLE_PE_STATS, 1);
}
if (optget(opts, "StatsTimeout")->enabled) {
cl_engine_set_num(engine, CL_ENGINE_STATS_TIMEOUT, optget(opts, "StatsTimeout")->numarg);
}
if (optget(opts, "StatsHostID")->enabled) {
char *p = optget(opts, "StatsHostID")->strarg;
@ -447,7 +451,6 @@ int main(int argc, char **argv)
} else {
if (strlen(p) > 36) {
logg("!Invalid HostID\n");
optfree(opts);
cl_engine_set_clcb_stats_submit(engine, NULL);
cl_engine_free(engine);
ret = 1;
@ -601,9 +604,6 @@ int main(int argc, char **argv)
t = realloc(lsockets, sizeof(int) * (nlsockets + 1));
if (!(t)) {
if ((lsockets))
free(lsockets);
ret = 1;
break;
}

@ -1,28 +0,0 @@
#ifndef __FANOTIFY_SYSCALL_LIB
#define __FANOTIFY_SYSCALL_LIB
#include <unistd.h>
#include <linux/types.h>
#if defined(__x86_64__)
# define __NR_fanotify_init 300
# define __NR_fanotify_mark 301
#elif defined(__i386__)
# define __NR_fanotify_init 338
# define __NR_fanotify_mark 339
#else
# error "System call numbers not defined for this architecture"
#endif
static inline int fanotify_init(unsigned int flags, unsigned int event_f_flags)
{
return syscall(__NR_fanotify_init, flags, event_f_flags);
}
static inline int fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
int dfd, const char *pathname)
{
return syscall(__NR_fanotify_mark, fanotify_fd, flags, mask,
dfd, pathname);
}
#endif

@ -34,8 +34,7 @@
#include <string.h>
#include <errno.h>
#include <linux/fanotify.h>
#include "fan-syscalllib.h"
#include <sys/fanotify.h>
#include "fan.h"
#include "libclamav/clamav.h"

@ -510,77 +510,97 @@ static void print_con_info(conn_t *conn, const char *fmt, ...)
static int make_connection_real(const char *soname, conn_t *conn)
{
int s;
struct timeval tv;
conn->tcp = 0;
#ifdef _WIN32
{
#else
if(cli_is_abspath(soname) || (access(soname, F_OK) == 0)) {
struct sockaddr_un addr;
s = socket(AF_UNIX, SOCK_STREAM, 0);
if(s < 0) {
perror("socket");
return -1;
}
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, soname, sizeof(addr.sun_path));
addr.sun_path[sizeof(addr.sun_path) - 1] = 0x0;
print_con_info(conn, "Connecting to: %s\n", soname);
if (connect(s, (struct sockaddr *)&addr, sizeof(addr))) {
perror("connect");
int s;
struct timeval tv;
char *port;
char *name, *pt = strdup(soname);
const char *host = pt;
struct addrinfo hints, *res=NULL, *p;
conn->tcp = 0;
#ifndef _WIN32
if(cli_is_abspath(soname) || (access(soname, F_OK) == 0)) {
struct sockaddr_un addr;
s = socket(AF_UNIX, SOCK_STREAM, 0);
if(s < 0) {
perror("socket");
return -1;
}
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, soname, sizeof(addr.sun_path));
addr.sun_path[sizeof(addr.sun_path) - 1] = 0x0;
print_con_info(conn, "Connecting to: %s\n", soname);
if (connect(s, (struct sockaddr *)&addr, sizeof(addr))) {
perror("connect");
close(s);
return -1;
}
} else {
return -1;
}
goto end;
}
#endif
struct sockaddr_in server;
struct hostent *hp;
unsigned port = 0;
char *name, *pt = strdup(soname);
const char *host = pt;
memset(&server, 0x00, sizeof(struct sockaddr_in));
conn->tcp=1;
name = strchr(pt, ':');
if(name) {
*name++ = '\0';
port = atoi(name);
}
if(!port)
port = 3310;
print_con_info(conn, "Looking up: %s\n", host);
if((hp = gethostbyname(host)) == NULL) {
fprintf(stderr, "Cannot find host");
return -1;
}
free(pt);
s = socket(AF_INET, SOCK_STREAM, 0);
if(s < 0) {
perror("socket");
return -1;
}
server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_addr.s_addr = ((struct in_addr*)(hp->h_addr))->s_addr;
print_con_info(conn, "Connecting to: %s:%u\n", inet_ntoa(server.sin_addr), port);
if (connect(s, (struct sockaddr *)&server, (socklen_t)sizeof(server))) {
perror("connect");
memset(&hints, 0x00, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
conn->tcp=1;
name = strchr(pt, '/');
if(name) {
*name = '\0';
port = name+1;
} else {
port = NULL;
}
print_con_info(conn, "Looking up: %s\n", host);
if (getaddrinfo(host, (port != NULL) ? port : "3310", &hints, &res))
return -1;
for (p = res; p != NULL; p = p->ai_next) {
if ((s = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) < 0) {
perror("socket");
continue;
}
print_con_info(conn, "Connecting to: %s:%s\n", host, port);
if (connect(s, p->ai_addr, p->ai_addrlen)) {
perror("connect");
close(s);
return -1;
}
}
if (conn->remote != soname) {
/* when we reconnect, they are the same */
if (conn->remote) free(conn->remote);
conn->remote = strdup(soname);
}
conn->sd = s;
gettimeofday(&conn->tv_conn, NULL);
tv.tv_sec = 30;
tv.tv_usec = 0;
setsockopt(conn->sd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
return 0;
continue;
}
break;
}
free(pt);
if (res)
freeaddrinfo(res);
if (p == NULL)
return -1;
end:
if (conn->remote != soname) {
/* when we reconnect, they are the same */
if (conn->remote)
free(conn->remote);
conn->remote = strdup(soname);
}
conn->sd = s;
gettimeofday(&conn->tv_conn, NULL);
tv.tv_sec = 30;
tv.tv_usec = 0;
setsockopt(conn->sd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
return 0;
}
static int make_connection(const char *soname, conn_t *conn)
@ -588,20 +608,23 @@ static int make_connection(const char *soname, conn_t *conn)
int rc;
if ((rc = make_connection_real(soname, conn)))
return rc;
return rc;
send_string(conn, "nIDSESSION\nnVERSION\n");
free(conn->version);
conn->version = NULL;
if (!read_version(conn))
return 0;
return 0;
/* clamd < 0.95 */
if ((rc = make_connection_real(soname, conn)))
return rc;
return rc;
send_string(conn, "nSESSION\nnVERSION\n");
conn->version = NULL;
if (!read_version(conn))
return 0;
return 0;
return -1;
}
@ -1109,7 +1132,7 @@ static void help(void)
printf(" --version -V Show version\n");
printf(" --config-file=FILE -c FILE Read clamd's configuration files from FILE\n");
printf(" --defaultcolors -d Use default terminal colors\n");
printf(" host[:port] Connect to clamd on host at port (default 3310)\n");
printf(" host[/port] Connect to clamd on host at port (default 3310)\n");
printf(" /path/to/clamd.socket Connect to clamd over a local socket\n");
printf("\n");
return;
@ -1118,100 +1141,105 @@ static int default_colors=0;
/* -------------------------- Initialization ---------------- */
static void setup_connections(int argc, char *argv[])
{
struct optstruct *opts;
struct optstruct *clamd_opts;
unsigned i;
char *conn = NULL;
opts = optparse(NULL, argc, argv, 1, OPT_CLAMDTOP, 0, NULL);
if (!opts) {
fprintf(stderr, "ERROR: Can't parse command line options\n");
EXIT_PROGRAM(FAIL_CMDLINE);
}
if(optget(opts, "help")->enabled) {
optfree(opts);
help();
normal_exit = 1;
exit(0);
}
if(optget(opts, "version")->enabled) {
printf("Clam AntiVirus Monitoring Tool %s\n", get_version());
optfree(opts);
normal_exit = 1;
exit(0);
}
if(optget(opts, "defaultcolors")->enabled)
default_colors = 1;
memset(&global, 0, sizeof(global));
if (!opts->filename || !opts->filename[0]) {
const struct optstruct *opt;
const char *clamd_conf = optget(opts, "config-file")->strarg;
if ((clamd_opts = optparse(clamd_conf, 0, NULL, 1, OPT_CLAMD, 0, NULL)) == NULL) {
fprintf(stderr, "Can't parse clamd configuration file %s\n", clamd_conf);
EXIT_PROGRAM(FAIL_CMDLINE);
}
if((opt = optget(clamd_opts, "LocalSocket"))->enabled) {
conn = strdup(opt->strarg);
if (!conn) {
fprintf(stderr, "Can't strdup LocalSocket value\n");
EXIT_PROGRAM(FAIL_INITIAL_CONN);
}
} else if ((opt = optget(clamd_opts, "TCPSocket"))->enabled) {
char buf[512];
const struct optstruct *opt_addr;
const char *host = "localhost";
if ((opt_addr = optget(clamd_opts, "TCPAddr"))->enabled) {
host = opt_addr->strarg;
}
snprintf(buf, sizeof(buf), "%s:%llu", host, opt->numarg);
conn = strdup(buf);
} else {
fprintf(stderr, "Can't find how to connect to clamd\n");
EXIT_PROGRAM(FAIL_INITIAL_CONN);
}
optfree(clamd_opts);
global.num_clamd = 1;
} else {
unsigned i = 0;
while (opts->filename[i]) { i++; }
global.num_clamd = i;
}
struct optstruct *opts;
struct optstruct *clamd_opts;
unsigned i;
char *conn = NULL;
opts = optparse(NULL, argc, argv, 1, OPT_CLAMDTOP, 0, NULL);
if (!opts) {
fprintf(stderr, "ERROR: Can't parse command line options\n");
EXIT_PROGRAM(FAIL_CMDLINE);
}
if(optget(opts, "help")->enabled) {
optfree(opts);
help();
normal_exit = 1;
exit(0);
}
if(optget(opts, "version")->enabled) {
printf("Clam AntiVirus Monitoring Tool %s\n", get_version());
optfree(opts);
normal_exit = 1;
exit(0);
}
if(optget(opts, "defaultcolors")->enabled)
default_colors = 1;
memset(&global, 0, sizeof(global));
if (!opts->filename || !opts->filename[0]) {
const struct optstruct *opt;
const char *clamd_conf = optget(opts, "config-file")->strarg;
if ((clamd_opts = optparse(clamd_conf, 0, NULL, 1, OPT_CLAMD, 0, NULL)) == NULL) {
fprintf(stderr, "Can't parse clamd configuration file %s\n", clamd_conf);
EXIT_PROGRAM(FAIL_CMDLINE);
}
if((opt = optget(clamd_opts, "LocalSocket"))->enabled) {
conn = strdup(opt->strarg);
if (!conn) {
fprintf(stderr, "Can't strdup LocalSocket value\n");
EXIT_PROGRAM(FAIL_INITIAL_CONN);
}
} else if ((opt = optget(clamd_opts, "TCPSocket"))->enabled) {
char buf[512];
const struct optstruct *opt_addr;
const char *host = "localhost";
if ((opt_addr = optget(clamd_opts, "TCPAddr"))->enabled) {
host = opt_addr->strarg;
}
snprintf(buf, sizeof(buf), "%s/%llu", host, opt->numarg);
conn = strdup(buf);
} else {
fprintf(stderr, "Can't find how to connect to clamd\n");
EXIT_PROGRAM(FAIL_INITIAL_CONN);
}
optfree(clamd_opts);
global.num_clamd = 1;
} else {
unsigned i = 0;
while (opts->filename[i]) { i++; }
global.num_clamd = i;
}
#ifdef _WIN32
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) {
fprintf(stderr, "Error at WSAStartup(): %d\n", WSAGetLastError());
EXIT_PROGRAM(FAIL_INITIAL_CONN);
}
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) {
fprintf(stderr, "Error at WSAStartup(): %d\n", WSAGetLastError());
EXIT_PROGRAM(FAIL_INITIAL_CONN);
}
#endif
/* clamdtop */
puts( " __ ____");
puts(" _____/ /___ _____ ___ ____/ / /_____ ____");
puts(" / ___/ / __ `/ __ `__ \\/ __ / __/ __ \\/ __ \\");
puts("/ /__/ / /_/ / / / / / / /_/ / /_/ /_/ / /_/ /");
puts("\\___/_/\\__,_/_/ /_/ /_/\\__,_/\\__/\\____/ .___/");
puts(" /_/");
global.all_stats = calloc(global.num_clamd, sizeof(*global.all_stats));
OOM_CHECK(global.all_stats);
global.conn = calloc(global.num_clamd, sizeof(*global.conn));
OOM_CHECK(global.conn);
for (i=0;i < global.num_clamd;i++) {
const char *soname = conn ? conn : opts->filename[i];
global.conn[i].line = i+1;
if (make_connection(soname, &global.conn[i]) < 0) {
EXIT_PROGRAM(FAIL_INITIAL_CONN);
}
}
optfree(opts);
free(conn);
/* clamdtop */
puts( " __ ____");
puts(" _____/ /___ _____ ___ ____/ / /_____ ____");
puts(" / ___/ / __ `/ __ `__ \\/ __ / __/ __ \\/ __ \\");
puts("/ /__/ / /_/ / / / / / / /_/ / /_/ /_/ / /_/ /");
puts("\\___/_/\\__,_/_/ /_/ /_/\\__,_/\\__/\\____/ .___/");
puts(" /_/");
global.all_stats = calloc(global.num_clamd, sizeof(*global.all_stats));
OOM_CHECK(global.all_stats);
global.conn = calloc(global.num_clamd, sizeof(*global.conn));
OOM_CHECK(global.conn);
for (i=0;i < global.num_clamd;i++) {
const char *soname = conn ? conn : opts->filename[i];
global.conn[i].line = i+1;
if (make_connection(soname, &global.conn[i]) < 0) {
EXIT_PROGRAM(FAIL_INITIAL_CONN);
}
}
optfree(opts);
free(conn);
#ifndef _WIN32
signal(SIGPIPE, SIG_IGN);
signal(SIGINT, sigint);
signal(SIGPIPE, SIG_IGN);
signal(SIGINT, sigint);
#endif
}

@ -582,6 +582,10 @@ int scanmanager(const struct optstruct *opts)
cl_engine_set_clcb_stats_add_sample(engine, NULL);
}
if (optget(opts, "stats-timeout")->enabled) {
cl_engine_set_num(engine, CL_ENGINE_STATS_TIMEOUT, optget(opts, "StatsTimeout")->numarg);
}
if (optget(opts, "stats-host-id")->enabled) {
char *p = optget(opts, "stats-host-id")->strarg;

4
configure vendored

@ -17890,8 +17890,8 @@ $as_echo "#define C_LINUX 1" >>confdefs.h
THREAD_LIBS="-lpthread"
TH_SAFE="-thread-safe"
if test "$want_fanotify" = "yes"; then
ac_fn_c_check_header_mongrel "$LINENO" "linux/fanotify.h" "ac_cv_header_linux_fanotify_h" "$ac_includes_default"
if test "x$ac_cv_header_linux_fanotify_h" = xyes; then :
ac_fn_c_check_header_mongrel "$LINENO" "sys/fanotify.h" "ac_cv_header_sys_fanotify_h" "$ac_includes_default"
if test "x$ac_cv_header_sys_fanotify_h" = xyes; then :
$as_echo "#define FANOTIFY 1" >>confdefs.h

@ -1072,7 +1072,7 @@ linux*)
THREAD_LIBS="-lpthread"
TH_SAFE="-thread-safe"
if test "$want_fanotify" = "yes"; then
AC_CHECK_HEADER([linux/fanotify.h],AC_DEFINE([FANOTIFY],1,[use fanotify]),)
AC_CHECK_HEADER([sys/fanotify.h],AC_DEFINE([FANOTIFY],1,[use fanotify]),)
fi
fi
;;

@ -505,7 +505,7 @@ Default: no
Default: no
.TP
\fBMaxScanSize SIZE\fR
Sets the maximum amount of data to be scanned for each input file. Archives and other containers are recursively extracted and scanned up to this value. \fBWarning: disabling this limit or setting it too high may result in severe damage to the system.\fR
Sets the maximum amount of data to be scanned for each input file. Archives and other containers are recursively extracted and scanned up to this value. The size of an archive plus the sum of the sizes of all files within archive count toward the scan size. For example, a 1M uncompressed archive containing a single 1M inner file counts as 2M toward the max scan size. \fBWarning: disabling this limit or setting it too high may result in severe damage to the system.\fR
.br
Default: 100M
.TP

@ -178,7 +178,7 @@ Mark encrypted archives as viruses (Encrypted.Zip, Encrypted.RAR).
Extract and scan at most #n bytes from each archive. You may pass the value in kilobytes in format xK or xk, or megabytes in format xM or xm, where x is a number. This option protects your system against DoS attacks (default: 25 MB, max: <4 GB)
.TP
\fB\-\-max\-scansize=#n\fR
Extract and scan at most #n bytes from each archive. You may pass the value in kilobytes in format xK or xk, or megabytes in format xM or xm, where x is a number. This option protects your system against DoS attacks (default: 100 MB, max: <4 GB)
Extract and scan at most #n bytes from each archive. The size the archive plus the sum of the sizes of all files within archive count toward the scan size. For example, a 1M uncompressed archive containing a single 1M inner file counts as 2M toward max-scansize. You may pass the value in kilobytes in format xK or xk, or megabytes in format xM or xm, where x is a number. This option protects your system against DoS attacks (default: 100 MB, max: <4 GB)
.TP
\fB\-\-max\-files=#n\fR
Extract at most #n files from each scanned file (when this is an archive, a document or another kind of container). This option protects your system against DoS attacks (default: 10000)

@ -763,6 +763,10 @@ void submit_host_info(struct optstruct *opts)
else if (strcmp(hostid, "default"))
cl_engine_set_clcb_stats_get_hostid(engine, get_hostid);
if (optget(opts, "stats-timeout")->enabled) {
cl_engine_set_num(engine, CL_ENGINE_STATS_TIMEOUT, optget(opts, "StatsTimeout")->numarg);
}
cl_engine_free(engine);
}

@ -96,6 +96,8 @@ clamd_connect (const char *cfgfile, const char *option)
return -11;
}
return sockd;
}
else
#endif
@ -143,6 +145,7 @@ clamd_connect (const char *cfgfile, const char *option)
optfree(opts);
freeaddrinfo(res);
return sockd;
}
@ -190,8 +193,8 @@ clamd_connect (const char *cfgfile, const char *option)
return -1;
}
return sockd;
#endif
}
else
{
@ -202,7 +205,7 @@ clamd_connect (const char *cfgfile, const char *option)
}
optfree (opts);
return sockd;
return -1;
}
int
@ -229,7 +232,7 @@ notify (const char *cfgfile)
{
logg ("!NotifyClamd: Unknown answer from clamd: '%s'\n", buff);
closesocket (sockd);
return 1;
return -1;
}
}

@ -206,6 +206,7 @@ enum cl_engine_field {
CL_ENGINE_FORCETODISK, /* uint32_t */
CL_ENGINE_DISABLE_CACHE, /* uint32_t */
CL_ENGINE_DISABLE_PE_STATS, /* uint32_t */
CL_ENGINE_STATS_TIMEOUT, /* uint32_t */
CL_ENGINE_MAX_PARTITIONS /* uint32_t */
};

@ -1,5 +1,6 @@
/*
* Copyright (C) 2007-2008 Sourcefire, Inc.
* Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
* Copyright (C) 2007-2013 Sourcefire, Inc.
*
* Authors: Tomasz Kojm
*
@ -38,10 +39,10 @@
#include "mpool.h"
struct dconf_module {
const char *mname; /* module name */
const char *sname; /* submodule name */
uint32_t bflag; /* bit flag */
uint8_t state; /* default state (on/off) */
const char *mname; /* module name */
const char *sname; /* submodule name */
uint32_t bflag; /* bit flag */
uint8_t state; /* default state (on/off) */
};
#ifdef CL_EXPERIMENTAL
@ -52,73 +53,73 @@ struct dconf_module {
static struct dconf_module modules[] = {
{ "PE", "PARITE", PE_CONF_PARITE, 1 },
{ "PE", "KRIZ", PE_CONF_KRIZ, 1 },
{ "PE", "MAGISTR", PE_CONF_MAGISTR, 1 },
{ "PE", "POLIPOS", PE_CONF_POLIPOS, 1 },
{ "PE", "MD5SECT", PE_CONF_MD5SECT, 1 },
{ "PE", "UPX", PE_CONF_UPX, 1 },
{ "PE", "FSG", PE_CONF_FSG, 1 },
{ "PE", "PARITE", PE_CONF_PARITE, 1 },
{ "PE", "KRIZ", PE_CONF_KRIZ, 1 },
{ "PE", "MAGISTR", PE_CONF_MAGISTR, 1 },
{ "PE", "POLIPOS", PE_CONF_POLIPOS, 1 },
{ "PE", "MD5SECT", PE_CONF_MD5SECT, 1 },
{ "PE", "UPX", PE_CONF_UPX, 1 },
{ "PE", "FSG", PE_CONF_FSG, 1 },
{ "PE", "SWIZZOR", PE_CONF_SWIZZOR, 1 },
{ "PE", "PETITE", PE_CONF_PETITE, 1 },
{ "PE", "PESPIN", PE_CONF_PESPIN, 1 },
{ "PE", "YC", PE_CONF_YC, 1 },
{ "PE", "WWPACK", PE_CONF_WWPACK, 1 },
{ "PE", "PETITE", PE_CONF_PETITE, 1 },
{ "PE", "PESPIN", PE_CONF_PESPIN, 1 },
{ "PE", "YC", PE_CONF_YC, 1 },
{ "PE", "WWPACK", PE_CONF_WWPACK, 1 },
{ "PE", "NSPACK", PE_CONF_NSPACK, 1 },
{ "PE", "MEW", PE_CONF_MEW, 1 },
{ "PE", "UPACK", PE_CONF_UPACK, 1 },
{ "PE", "ASPACK", PE_CONF_ASPACK, 1 },
{ "PE", "CATALOG", PE_CONF_CATALOG, 1 },
{ "PE", "NSPACK", PE_CONF_NSPACK, 1 },
{ "PE", "MEW", PE_CONF_MEW, 1 },
{ "PE", "UPACK", PE_CONF_UPACK, 1 },
{ "PE", "ASPACK", PE_CONF_ASPACK, 1 },
{ "PE", "CATALOG", PE_CONF_CATALOG, 1 },
{ "PE", "DISABLECERT", PE_CONF_DISABLECERT, 0 },
{ "PE", "DUMPCERT", PE_CONF_DUMPCERT, 0 },
{ "ELF", NULL, 0x1, 1 },
{ "MACHO", NULL, 0x1, 1 },
{ "ARCHIVE", "RAR", ARCH_CONF_RAR, 1 },
{ "ARCHIVE", "ZIP", ARCH_CONF_ZIP, 1 },
{ "ARCHIVE", "GZIP", ARCH_CONF_GZ, 1 },
{ "ARCHIVE", "BZIP", ARCH_CONF_BZ, 1 },
{ "ARCHIVE", "ARJ", ARCH_CONF_ARJ, 1 },
{ "ARCHIVE", "SZDD", ARCH_CONF_SZDD, 1 },
{ "ARCHIVE", "CAB", ARCH_CONF_CAB, 1 },
{ "ARCHIVE", "CHM", ARCH_CONF_CHM, 1 },
{ "ARCHIVE", "OLE2", ARCH_CONF_OLE2, 1 },
{ "ARCHIVE", "TAR", ARCH_CONF_TAR, 1 },
{ "ARCHIVE", "CPIO", ARCH_CONF_CPIO, 1 },
{ "ARCHIVE", "BINHEX", ARCH_CONF_BINHEX, 1 },
{ "ARCHIVE", "SIS", ARCH_CONF_SIS, 1 },
{ "ARCHIVE", "NSIS", ARCH_CONF_NSIS, 1 },
{ "ARCHIVE", "AUTOIT", ARCH_CONF_AUTOIT, 1 },
{ "ARCHIVE", "ISHIELD", ARCH_CONF_ISHIELD, 1 },
{ "ARCHIVE", "7zip", ARCH_CONF_7Z, 1 },
{ "ARCHIVE", "ISO9660", ARCH_CONF_ISO9660, 1 },
{ "ARCHIVE", "DMG", ARCH_CONF_DMG, 1 },
{ "ARCHIVE", "XAR", ARCH_CONF_XAR, 1 },
{ "ARCHIVE", "HFSPLUS", ARCH_CONF_HFSPLUS, 1 },
{ "ARCHIVE", "XZ", ARCH_CONF_XZ, 1 },
{ "DOCUMENT", "HTML", DOC_CONF_HTML, 1 },
{ "DOCUMENT", "RTF", DOC_CONF_RTF, 1 },
{ "DOCUMENT", "PDF", DOC_CONF_PDF, 1 },
{ "DOCUMENT", "SCRIPT", DOC_CONF_SCRIPT, 1 },
{ "ELF", NULL, 0x1, 1 },
{ "MACHO", NULL, 0x1, 1 },
{ "ARCHIVE", "RAR", ARCH_CONF_RAR, 1 },
{ "ARCHIVE", "ZIP", ARCH_CONF_ZIP, 1 },
{ "ARCHIVE", "GZIP", ARCH_CONF_GZ, 1 },
{ "ARCHIVE", "BZIP", ARCH_CONF_BZ, 1 },
{ "ARCHIVE", "ARJ", ARCH_CONF_ARJ, 1 },
{ "ARCHIVE", "SZDD", ARCH_CONF_SZDD, 1 },
{ "ARCHIVE", "CAB", ARCH_CONF_CAB, 1 },
{ "ARCHIVE", "CHM", ARCH_CONF_CHM, 1 },
{ "ARCHIVE", "OLE2", ARCH_CONF_OLE2, 1 },
{ "ARCHIVE", "TAR", ARCH_CONF_TAR, 1 },
{ "ARCHIVE", "CPIO", ARCH_CONF_CPIO, 1 },
{ "ARCHIVE", "BINHEX", ARCH_CONF_BINHEX, 1 },
{ "ARCHIVE", "SIS", ARCH_CONF_SIS, 1 },
{ "ARCHIVE", "NSIS", ARCH_CONF_NSIS, 1 },
{ "ARCHIVE", "AUTOIT", ARCH_CONF_AUTOIT, 1 },
{ "ARCHIVE", "ISHIELD", ARCH_CONF_ISHIELD, 1 },
{ "ARCHIVE", "7zip", ARCH_CONF_7Z, 1 },
{ "ARCHIVE", "ISO9660", ARCH_CONF_ISO9660, 1 },
{ "ARCHIVE", "DMG", ARCH_CONF_DMG, 1 },
{ "ARCHIVE", "XAR", ARCH_CONF_XAR, 1 },
{ "ARCHIVE", "HFSPLUS", ARCH_CONF_HFSPLUS, 1 },
{ "ARCHIVE", "XZ", ARCH_CONF_XZ, 1 },
{ "DOCUMENT", "HTML", DOC_CONF_HTML, 1 },
{ "DOCUMENT", "RTF", DOC_CONF_RTF, 1 },
{ "DOCUMENT", "PDF", DOC_CONF_PDF, 1 },
{ "DOCUMENT", "SCRIPT", DOC_CONF_SCRIPT, 1 },
{ "DOCUMENT", "HTMLSKIPRAW", DOC_CONF_HTML_SKIPRAW, 1 },
{ "DOCUMENT", "JSNORM", DOC_CONF_JSNORM, 1 },
{ "DOCUMENT", "SWF", DOC_CONF_SWF, 1 },
{ "MAIL", "MBOX", MAIL_CONF_MBOX, 1 },
{ "MAIL", "TNEF", MAIL_CONF_TNEF, 1 },
{ "OTHER", "UUENCODED", OTHER_CONF_UUENC, 1 },
{ "OTHER", "SCRENC", OTHER_CONF_SCRENC, 1 },
{ "OTHER", "RIFF", OTHER_CONF_RIFF, 1 },
{ "OTHER", "JPEG", OTHER_CONF_JPEG, 1 },
{ "OTHER", "CRYPTFF", OTHER_CONF_CRYPTFF, 1 },
{ "OTHER", "DLP", OTHER_CONF_DLP, 1 },
{ "OTHER", "MYDOOMLOG", OTHER_CONF_MYDOOMLOG, 1 },
{ "DOCUMENT", "SWF", DOC_CONF_SWF, 1 },
{ "MAIL", "MBOX", MAIL_CONF_MBOX, 1 },
{ "MAIL", "TNEF", MAIL_CONF_TNEF, 1 },
{ "OTHER", "UUENCODED", OTHER_CONF_UUENC, 1 },
{ "OTHER", "SCRENC", OTHER_CONF_SCRENC, 1 },
{ "OTHER", "RIFF", OTHER_CONF_RIFF, 1 },
{ "OTHER", "JPEG", OTHER_CONF_JPEG, 1 },
{ "OTHER", "CRYPTFF", OTHER_CONF_CRYPTFF, 1 },
{ "OTHER", "DLP", OTHER_CONF_DLP, 1 },
{ "OTHER", "MYDOOMLOG", OTHER_CONF_MYDOOMLOG, 1 },
{ "OTHER", "PREFILTERING", OTHER_CONF_PREFILTERING,1 },
{ "OTHER", "PDFNAMEOBJ", OTHER_CONF_PDFNAMEOBJ, 1 },
@ -130,7 +131,10 @@ static struct dconf_module modules[] = {
{ "BYTECODE", "JIT PPC", BYTECODE_JIT_PPC, 1 },
{ "BYTECODE", "JIT ARM", BYTECODE_JIT_ARM, 0 },
{ NULL, NULL, 0, 0 }
{ "STATS", "DISABLED", DCONF_STATS_DISABLED, 0 },
{ "STATS", "PESECTION DISABLED", DCONF_STATS_PE_SECTION_DISABLED, 0 },
{ NULL, NULL, 0, 0 }
};
#ifdef USE_MPOOL
@ -139,48 +143,51 @@ struct cli_dconf *cli_dconf_init(mpool_t *mempool)
struct cli_dconf *cli_dconf_init(void)
#endif
{
unsigned int i;
struct cli_dconf *dconf;
unsigned int i;
struct cli_dconf *dconf;
dconf = (struct cli_dconf *) mpool_calloc(mempool, sizeof(struct cli_dconf), 1);
if(!dconf)
return NULL;
return NULL;
for(i = 0; modules[i].mname; i++) {
if(!strcmp(modules[i].mname, "PE")) {
if(modules[i].state)
dconf->pe |= modules[i].bflag;
} else if(!strcmp(modules[i].mname, "ELF")) {
if(modules[i].state)
dconf->elf |= modules[i].bflag;
} else if(!strcmp(modules[i].mname, "MACHO")) {
if(modules[i].state)
dconf->macho |= modules[i].bflag;
} else if(!strcmp(modules[i].mname, "ARCHIVE")) {
if(modules[i].state)
dconf->archive |= modules[i].bflag;
} else if(!strcmp(modules[i].mname, "DOCUMENT")) {
if(modules[i].state)
dconf->doc |= modules[i].bflag;
} else if(!strcmp(modules[i].mname, "MAIL")) {
if(modules[i].state)
dconf->mail |= modules[i].bflag;
} else if(!strcmp(modules[i].mname, "OTHER")) {
if(modules[i].state)
dconf->other |= modules[i].bflag;
} else if(!strcmp(modules[i].mname, "PHISHING")) {
if(modules[i].state)
dconf->phishing |= modules[i].bflag;
} else if(!strcmp(modules[i].mname, "BYTECODE")) {
if (modules[i].state)
dconf->bytecode |= modules[i].bflag;
}
if(!strcmp(modules[i].mname, "PE")) {
if(modules[i].state)
dconf->pe |= modules[i].bflag;
} else if(!strcmp(modules[i].mname, "ELF")) {
if(modules[i].state)
dconf->elf |= modules[i].bflag;
} else if(!strcmp(modules[i].mname, "MACHO")) {
if(modules[i].state)
dconf->macho |= modules[i].bflag;
} else if(!strcmp(modules[i].mname, "ARCHIVE")) {
if(modules[i].state)
dconf->archive |= modules[i].bflag;
} else if(!strcmp(modules[i].mname, "DOCUMENT")) {
if(modules[i].state)
dconf->doc |= modules[i].bflag;
} else if(!strcmp(modules[i].mname, "MAIL")) {
if(modules[i].state)
dconf->mail |= modules[i].bflag;
} else if(!strcmp(modules[i].mname, "OTHER")) {
if(modules[i].state)
dconf->other |= modules[i].bflag;
} else if(!strcmp(modules[i].mname, "PHISHING")) {
if(modules[i].state)
dconf->phishing |= modules[i].bflag;
} else if(!strcmp(modules[i].mname, "BYTECODE")) {
if (modules[i].state)
dconf->bytecode |= modules[i].bflag;
} else if (!strcmp(modules[i].mname, "STATS")) {
if (modules[i].state)
dconf->stats |= modules[i].bflag;
}
}
return dconf;
@ -188,128 +195,139 @@ struct cli_dconf *cli_dconf_init(void)
void cli_dconf_print(struct cli_dconf *dconf)
{
unsigned int pe = 0, elf = 0, macho = 0, arch = 0, doc = 0, mail = 0;
unsigned int other = 0, phishing = 0, i, bytecode=0;
unsigned int pe = 0, elf = 0, macho = 0, arch = 0, doc = 0, mail = 0;
unsigned int other = 0, phishing = 0, i, bytecode=0, stats=0;
cli_dbgmsg("Dynamic engine configuration settings:\n");
cli_dbgmsg("--------------------------------------\n");
for(i = 0; modules[i].mname; i++) {
if(!strcmp(modules[i].mname, "PE")) {
if(!pe) {
cli_dbgmsg("Module PE: %s\n", dconf->pe ? "On" : "Off");
pe = 1;
}
if(dconf->pe)
cli_dbgmsg(" * Submodule %10s:\t%s\n", modules[i].sname, (dconf->pe & modules[i].bflag) ? "On" : "** Off **");
else
continue;
} else if(!strcmp(modules[i].mname, "ELF")) {
if(!elf) {
cli_dbgmsg("Module ELF: %s\n", dconf->elf ? "On" : "Off");
elf = 1;
}
} else if(!strcmp(modules[i].mname, "MACHO")) {
if(!macho) {
cli_dbgmsg("Module MACHO: %s\n", dconf->elf ? "On" : "Off");
macho = 1;
}
} else if(!strcmp(modules[i].mname, "ARCHIVE")) {
if(!arch) {
cli_dbgmsg("Module ARCHIVE: %s\n", dconf->archive ? "On" : "Off");
arch = 1;
}
if(dconf->archive)
cli_dbgmsg(" * Submodule %10s:\t%s\n", modules[i].sname, (dconf->archive & modules[i].bflag) ? "On" : "** Off **");
else
continue;
} else if(!strcmp(modules[i].mname, "DOCUMENT")) {
if(!doc) {
cli_dbgmsg("Module DOCUMENT: %s\n", dconf->doc ? "On" : "Off");
doc = 1;
}
if(dconf->doc)
cli_dbgmsg(" * Submodule %10s:\t%s\n", modules[i].sname, (dconf->doc & modules[i].bflag) ? "On" : "** Off **");
else
continue;
} else if(!strcmp(modules[i].mname, "MAIL")) {
if(!mail) {
cli_dbgmsg("Module MAIL: %s\n", dconf->mail ? "On" : "Off");
mail = 1;
}
if(dconf->mail)
cli_dbgmsg(" * Submodule %10s:\t%s\n", modules[i].sname, (dconf->mail & modules[i].bflag) ? "On" : "** Off **");
else
continue;
} else if(!strcmp(modules[i].mname, "OTHER")) {
if(!other) {
cli_dbgmsg("Module OTHER: %s\n", dconf->other ? "On" : "Off");
other = 1;
}
if(dconf->other)
cli_dbgmsg(" * Submodule %10s:\t%s\n", modules[i].sname, (dconf->other & modules[i].bflag) ? "On" : "** Off **");
else
continue;
} else if(!strcmp(modules[i].mname, "PHISHING")) {
if(!phishing) {
cli_dbgmsg("Module PHISHING %s\n", dconf->phishing ? "On" : "Off");
phishing = 1;
}
if(dconf->phishing)
cli_dbgmsg(" * Submodule %10s:\t%s\n", modules[i].sname, (dconf->phishing & modules[i].bflag) ? "On" : "** Off **");
else
continue;
} else if(!strcmp(modules[i].mname, "BYTECODE")) {
if(!bytecode) {
cli_dbgmsg("Module BYTECODE %s\n", dconf->bytecode ? "On" : "Off");
bytecode = 1;
}
if(dconf->bytecode)
cli_dbgmsg(" * Submodule %10s:\t%s\n", modules[i].sname, (dconf->bytecode & modules[i].bflag) ? "On" : "** Off **");
else
continue;
}
if(!strcmp(modules[i].mname, "PE")) {
if(!pe) {
cli_dbgmsg("Module PE: %s\n", dconf->pe ? "On" : "Off");
pe = 1;
}
if(dconf->pe)
cli_dbgmsg(" * Submodule %10s:\t%s\n", modules[i].sname, (dconf->pe & modules[i].bflag) ? "On" : "** Off **");
else
continue;
} else if(!strcmp(modules[i].mname, "ELF")) {
if(!elf) {
cli_dbgmsg("Module ELF: %s\n", dconf->elf ? "On" : "Off");
elf = 1;
}
} else if(!strcmp(modules[i].mname, "MACHO")) {
if(!macho) {
cli_dbgmsg("Module MACHO: %s\n", dconf->elf ? "On" : "Off");
macho = 1;
}
} else if(!strcmp(modules[i].mname, "ARCHIVE")) {
if(!arch) {
cli_dbgmsg("Module ARCHIVE: %s\n", dconf->archive ? "On" : "Off");
arch = 1;
}
if(dconf->archive)
cli_dbgmsg(" * Submodule %10s:\t%s\n", modules[i].sname, (dconf->archive & modules[i].bflag) ? "On" : "** Off **");
else
continue;
} else if(!strcmp(modules[i].mname, "DOCUMENT")) {
if(!doc) {
cli_dbgmsg("Module DOCUMENT: %s\n", dconf->doc ? "On" : "Off");
doc = 1;
}
if(dconf->doc)
cli_dbgmsg(" * Submodule %10s:\t%s\n", modules[i].sname, (dconf->doc & modules[i].bflag) ? "On" : "** Off **");
else
continue;
} else if(!strcmp(modules[i].mname, "MAIL")) {
if(!mail) {
cli_dbgmsg("Module MAIL: %s\n", dconf->mail ? "On" : "Off");
mail = 1;
}
if(dconf->mail)
cli_dbgmsg(" * Submodule %10s:\t%s\n", modules[i].sname, (dconf->mail & modules[i].bflag) ? "On" : "** Off **");
else
continue;
} else if(!strcmp(modules[i].mname, "OTHER")) {
if(!other) {
cli_dbgmsg("Module OTHER: %s\n", dconf->other ? "On" : "Off");
other = 1;
}
if(dconf->other)
cli_dbgmsg(" * Submodule %10s:\t%s\n", modules[i].sname, (dconf->other & modules[i].bflag) ? "On" : "** Off **");
else
continue;
} else if(!strcmp(modules[i].mname, "PHISHING")) {
if(!phishing) {
cli_dbgmsg("Module PHISHING %s\n", dconf->phishing ? "On" : "Off");
phishing = 1;
}
if(dconf->phishing)
cli_dbgmsg(" * Submodule %10s:\t%s\n", modules[i].sname, (dconf->phishing & modules[i].bflag) ? "On" : "** Off **");
else
continue;
} else if(!strcmp(modules[i].mname, "BYTECODE")) {
if(!bytecode) {
cli_dbgmsg("Module BYTECODE %s\n", dconf->bytecode ? "On" : "Off");
bytecode = 1;
}
if(dconf->bytecode)
cli_dbgmsg(" * Submodule %10s:\t%s\n", modules[i].sname, (dconf->bytecode & modules[i].bflag) ? "On" : "** Off **");
else
continue;
} else if (!strcmp(modules[i].mname, "STATS")) {
if (!stats) {
cli_dbgmsg("Module STATS %s\n", dconf->stats ? "On" : "Off");
stats = 1;
}
if (dconf->stats)
cli_dbgmsg(" * Submodule %10s:\t%s\n", modules[i].sname, (dconf->stats & modules[i].bflag) ? "On" : "** Off **");
else
continue;
}
}
}
static int chkflevel(const char *entry, int field)
{
char *pt;
char *pt;
if((pt = cli_strtok(entry, field, ":"))) { /* min version */
if(!isdigit(*pt)) {
free(pt);
return 0;
}
if((unsigned int) atoi(pt) > CL_FLEVEL_DCONF) {
free(pt);
return 0;
}
free(pt);
if((pt = cli_strtok(entry, field + 1, ":"))) { /* max version */
if(!isdigit(*pt)) {
free(pt);
return 0;
}
if((unsigned int) atoi(pt) < CL_FLEVEL_DCONF) {
free(pt);
return 0;
}
free(pt);
}
if(!isdigit(*pt)) {
free(pt);
return 0;
}
if((unsigned int) atoi(pt) > CL_FLEVEL_DCONF) {
free(pt);
return 0;
}
free(pt);
if((pt = cli_strtok(entry, field + 1, ":"))) { /* max version */
if(!isdigit(*pt)) {
free(pt);
return 0;
}
if((unsigned int) atoi(pt) < CL_FLEVEL_DCONF) {
free(pt);
return 0;
}
free(pt);
}
}
return 1;
@ -317,101 +335,110 @@ static int chkflevel(const char *entry, int field)
int cli_dconf_load(FILE *fs, struct cl_engine *engine, unsigned int options, struct cli_dbio *dbio)
{
char buffer[FILEBUFF];
unsigned int line = 0;
int ret = 0;
uint32_t val;
char buffer[FILEBUFF];
unsigned int line = 0;
int ret = 0;
uint32_t val;
while(cli_dbgets(buffer, FILEBUFF, fs, dbio)) {
line++;
cli_chomp(buffer);
if(!strncmp(buffer, "PE:", 3) && chkflevel(buffer, 2)) {
if(sscanf(buffer + 3, "0x%x", &val) == 1) {
engine->dconf->pe = val;
} else {
ret = CL_EMALFDB;
break;
}
}
if(!strncmp(buffer, "ELF:", 4) && chkflevel(buffer, 2)) {
if(sscanf(buffer + 4, "0x%x", &val) == 1) {
engine->dconf->elf = val;
} else {
ret = CL_EMALFDB;
break;
}
}
if(!strncmp(buffer, "MACHO:", 4) && chkflevel(buffer, 2)) {
if(sscanf(buffer + 4, "0x%x", &val) == 1) {
engine->dconf->macho = val;
} else {
ret = CL_EMALFDB;
break;
}
}
if(!strncmp(buffer, "ARCHIVE:", 8) && chkflevel(buffer, 2)) {
if(sscanf(buffer + 8, "0x%x", &val) == 1) {
engine->dconf->archive = val;
} else {
ret = CL_EMALFDB;
break;
}
}
if(!strncmp(buffer, "DOCUMENT:", 9) && chkflevel(buffer, 2)) {
if(sscanf(buffer + 9, "0x%x", &val) == 1) {
engine->dconf->doc = val;
} else {
ret = CL_EMALFDB;
break;
}
}
if(!strncmp(buffer, "MAIL:", 5) && chkflevel(buffer, 2)) {
if(sscanf(buffer + 5, "0x%x", &val) == 1) {
engine->dconf->mail = val;
} else {
ret = CL_EMALFDB;
break;
}
}
if(!strncmp(buffer, "OTHER:", 6) && chkflevel(buffer, 2)) {
if(sscanf(buffer + 6, "0x%x", &val) == 1) {
engine->dconf->other = val;
} else {
ret = CL_EMALFDB;
break;
}
}
if(!strncmp(buffer, "PHISHING:", 9) && chkflevel(buffer, 2)) {
if(sscanf(buffer + 9, "0x%x", &val) == 1) {
engine->dconf->phishing = val;
} else {
ret = CL_EMALFDB;
break;
}
}
if(!strncmp(buffer, "BYTECODE:", 9) && chkflevel(buffer, 2)) {
if(sscanf(buffer + 9, "0x%x", &val) == 1) {
engine->dconf->bytecode = val;
} else {
ret = CL_EMALFDB;
break;
}
}
line++;
cli_chomp(buffer);
if(!strncmp(buffer, "PE:", 3) && chkflevel(buffer, 2)) {
if(sscanf(buffer + 3, "0x%x", &val) == 1) {
engine->dconf->pe = val;
} else {
ret = CL_EMALFDB;
break;
}
}
if(!strncmp(buffer, "ELF:", 4) && chkflevel(buffer, 2)) {
if(sscanf(buffer + 4, "0x%x", &val) == 1) {
engine->dconf->elf = val;
} else {
ret = CL_EMALFDB;
break;
}
}
if(!strncmp(buffer, "MACHO:", 4) && chkflevel(buffer, 2)) {
if(sscanf(buffer + 4, "0x%x", &val) == 1) {
engine->dconf->macho = val;
} else {
ret = CL_EMALFDB;
break;
}
}
if(!strncmp(buffer, "ARCHIVE:", 8) && chkflevel(buffer, 2)) {
if(sscanf(buffer + 8, "0x%x", &val) == 1) {
engine->dconf->archive = val;
} else {
ret = CL_EMALFDB;
break;
}
}
if(!strncmp(buffer, "DOCUMENT:", 9) && chkflevel(buffer, 2)) {
if(sscanf(buffer + 9, "0x%x", &val) == 1) {
engine->dconf->doc = val;
} else {
ret = CL_EMALFDB;
break;
}
}
if(!strncmp(buffer, "MAIL:", 5) && chkflevel(buffer, 2)) {
if(sscanf(buffer + 5, "0x%x", &val) == 1) {
engine->dconf->mail = val;
} else {
ret = CL_EMALFDB;
break;
}
}
if(!strncmp(buffer, "OTHER:", 6) && chkflevel(buffer, 2)) {
if(sscanf(buffer + 6, "0x%x", &val) == 1) {
engine->dconf->other = val;
} else {
ret = CL_EMALFDB;
break;
}
}
if(!strncmp(buffer, "PHISHING:", 9) && chkflevel(buffer, 2)) {
if(sscanf(buffer + 9, "0x%x", &val) == 1) {
engine->dconf->phishing = val;
} else {
ret = CL_EMALFDB;
break;
}
}
if(!strncmp(buffer, "BYTECODE:", 9) && chkflevel(buffer, 2)) {
if(sscanf(buffer + 9, "0x%x", &val) == 1) {
engine->dconf->bytecode = val;
} else {
ret = CL_EMALFDB;
break;
}
}
if(!strncmp(buffer, "STATS:", 6) && chkflevel(buffer, 2)) {
if(sscanf(buffer + 6, "0x%x", &val) == 1) {
engine->dconf->stats = val;
} else {
ret = CL_EMALFDB;
break;
}
}
}
if(ret) {
cli_errmsg("Problem parsing configuration file at line %u\n", line);
return ret;
cli_errmsg("Problem parsing configuration file at line %u\n", line);
return ret;
}
return CL_SUCCESS;

@ -1,5 +1,6 @@
/*
* Copyright (C) 2007-2008 Sourcefire, Inc.
* Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
* Copyright (C) 2007-2013 Sourcefire, Inc.
*
* Authors: Tomasz Kojm
*
@ -40,6 +41,7 @@ struct cli_dconf {
uint32_t other;
uint32_t phishing;
uint32_t bytecode;
uint32_t stats;
};
/* PE flags */
@ -121,6 +123,10 @@ struct cli_dconf {
#define BYTECODE_JIT_PPC 0x4
#define BYTECODE_JIT_ARM 0x8
/* Stats/Intel flags */
#define DCONF_STATS_DISABLED 0x1
#define DCONF_STATS_PE_SECTION_DISABLED 0x2
#define BYTECODE_ENGINE_MASK (BYTECODE_INTERPRETER | BYTECODE_JIT_X86 | BYTECODE_JIT_PPC | BYTECODE_JIT_ARM)
#ifdef USE_MPOOL

@ -1,3 +1,23 @@
/*
* Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
*
* Author: Shawn Webb
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#if HAVE_CONFIG_H
#include "clamav-config.h"
#endif
@ -155,8 +175,6 @@ struct device *get_devices(void)
/* This is the Linux version of getting the MAC addresses */
#if defined(SIOCGIFHWADDR)
for (i=0; i < ndevices; i++) {
cli_warnmsg("devices[%lu]: %s\n", i, devices[i].name);
if (!(devices[i].name))
continue;
@ -184,8 +202,6 @@ struct device *get_devices(void)
}
#endif
close(sock);
p = realloc(devices, sizeof(struct device) * (ndevices + 1));
if (!(p))
goto err;
@ -197,9 +213,6 @@ struct device *get_devices(void)
return devices;
err:
if (addrs)
freeifaddrs(addrs);
if (devices) {
for (i=0; i < ndevices; i++)
if (devices[i].name)
@ -235,8 +248,10 @@ char *internal_get_host_id(void)
return NULL;
printable_md5 = calloc(1, 37);
if (!(printable_md5))
if (!(printable_md5)) {
free(devices);
return NULL;
}
cli_md5_init(&ctx);
for (i=0; devices[i].name != NULL; i++)

@ -1,3 +1,23 @@
/*
* Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
*
* Author: Shawn Webb
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#if !defined(_LIBCLAMAV_HOSTID_H)
#define _LIBCLAMAV_HOSTID_H

@ -1,3 +1,23 @@
/*
* Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
*
* Author: Shawn Webb
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

@ -1,3 +1,23 @@
/*
* Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
*
* Author: Shawn Webb
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#if !defined(_LIBCLAMAV_JSON_H)
#define _LIBCLAMAV_JSON_H

@ -526,7 +526,7 @@ int cli_checkfp(unsigned char *digest, size_t size, cli_ctx *ctx)
memset(&sections, 0x00, sizeof(stats_section_t));
if(do_dsig_check || ctx->engine->cb_stats_add_sample) {
uint32_t flags = (do_dsig_check ? CL_CHECKFP_PE_FLAG_AUTHENTICODE : 0);
if (!(ctx->engine->engine_options & ENGINE_OPTIONS_DISABLE_PE_STATS))
if (!(ctx->engine->engine_options & ENGINE_OPTIONS_DISABLE_PE_STATS) && !(ctx->engine->dconf->stats & (DCONF_STATS_DISABLED | DCONF_STATS_PE_SECTION_DISABLED)))
flags |= CL_CHECKFP_PE_FLAG_STATS;
switch(cli_checkfp_pe(ctx, shash1, &sections, flags)) {

@ -394,12 +394,14 @@ struct cl_engine *cl_engine_new(void)
mpool_destroy(new->mempool);
#endif
free(new);
free(intel);
return NULL;
}
#endif
intel->engine = new;
intel->maxsamples = STATS_MAX_SAMPLES;
intel->maxmem = STATS_MAX_MEM;
intel->timeout = 10;
new->stats_data = intel;
new->cb_stats_add_sample = clamav_stats_add_sample;
new->cb_stats_submit = clamav_stats_submit;
@ -529,25 +531,32 @@ int cl_engine_set_num(struct cl_engine *engine, enum cl_engine_field field, long
if (num == CL_BYTECODE_MODE_TEST)
cli_infomsg(NULL, "bytecode engine in test mode\n");
break;
case CL_ENGINE_DISABLE_CACHE:
if (num) {
engine->engine_options |= ENGINE_OPTIONS_DISABLE_CACHE;
} else {
engine->engine_options &= ~(ENGINE_OPTIONS_DISABLE_CACHE);
if (!(engine->cache))
cli_cache_init(engine);
}
break;
case CL_ENGINE_DISABLE_PE_STATS:
if (num) {
engine->engine_options |= ENGINE_OPTIONS_DISABLE_PE_STATS;
} else {
engine->engine_options &= ~(ENGINE_OPTIONS_DISABLE_PE_STATS);
}
break;
case CL_ENGINE_MAX_PARTITIONS:
engine->maxpartitions = (uint32_t)num;
break;
case CL_ENGINE_DISABLE_CACHE:
if (num) {
engine->engine_options |= ENGINE_OPTIONS_DISABLE_CACHE;
} else {
engine->engine_options &= ~(ENGINE_OPTIONS_DISABLE_CACHE);
if (!(engine->cache))
cli_cache_init(engine);
}
break;
case CL_ENGINE_DISABLE_PE_STATS:
if (num) {
engine->engine_options |= ENGINE_OPTIONS_DISABLE_PE_STATS;
} else {
engine->engine_options &= ~(ENGINE_OPTIONS_DISABLE_PE_STATS);
}
break;
case CL_ENGINE_STATS_TIMEOUT:
if ((engine->stats_data)) {
cli_intel_t *intel = (cli_intel_t *)(engine->stats_data);
intel->timeout = (uint32_t)num;
}
break;
case CL_ENGINE_MAX_PARTITIONS:
engine->maxpartitions = (uint32_t)num;
break;
default:
cli_errmsg("cl_engine_set_num: Incorrect field number\n");
return CL_EARG;
@ -613,10 +622,12 @@ long long cl_engine_get_num(const struct cl_engine *engine, enum cl_engine_field
return engine->bytecode_timeout;
case CL_ENGINE_BYTECODE_MODE:
return engine->bytecode_mode;
case CL_ENGINE_DISABLE_CACHE:
return engine->engine_options & ENGINE_OPTIONS_DISABLE_CACHE;
case CL_ENGINE_MAX_PARTITIONS:
return engine->maxpartitions;
case CL_ENGINE_DISABLE_CACHE:
return engine->engine_options & ENGINE_OPTIONS_DISABLE_CACHE;
case CL_ENGINE_STATS_TIMEOUT:
return ((cli_intel_t *)(engine->stats_data))->timeout;
case CL_ENGINE_MAX_PARTITIONS:
return engine->maxpartitions;
default:
cli_errmsg("cl_engine_get: Incorrect field number\n");
if(err)

@ -164,6 +164,7 @@ typedef struct cli_clamav_intel {
uint32_t nsamples;
uint32_t maxsamples;
uint32_t maxmem;
uint32_t timeout;
time_t nextupdate;
struct cl_engine *engine;
#ifdef CL_THREAD_SAFE

@ -1227,6 +1227,10 @@ static int lsigattribs(char *attribs, struct cli_lsig_tdb *tdb)
mpool_free(x.mempool, x.macro_ptids);\
} while(0);
/* 0 1 2 3 4 5 ... (max 66)
* VirusName:Attributes:Logic:SubSig1[:SubSig2[:SubSig3 ... ]]
* NOTE: Maximum of 64 subsignatures (last would be token 66)
*/
#define LDB_TOKENS 67
static int load_oneldb(char *buffer, int chkpua, struct cl_engine *engine, unsigned int options, const char *dbname, unsigned int line, unsigned int *sigs, unsigned bc_idx, const char *buffer_cpy, int *skip)
{
@ -1580,6 +1584,9 @@ static int cli_loadcbc(FILE *fs, struct cl_engine *engine, unsigned int *signo,
return CL_SUCCESS;
}
/* 0 1 2 3 4 5 6 7
* MagicType:Offset:HexSig:Name:RequiredType:DetectedType[:MinFL[:MaxFL]]
*/
#define FTM_TOKENS 8
static int cli_loadftm(FILE *fs, struct cl_engine *engine, unsigned int options, unsigned int internal, struct cli_dbio *dbio)
{

@ -1,3 +1,23 @@
/*
* Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
*
* Author: Shawn Webb
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#if HAVE_CONFIG_H
#include "clamav-config.h"
#endif
@ -26,12 +46,13 @@
#include "libclamav/others.h"
#include "libclamav/clamav.h"
#include "libclamav/dconf.h"
#include "libclamav/json.h"
#include "libclamav/stats.h"
#include "libclamav/hostid.h"
#include "libclamav/www.h"
#define DEBUG_STATS 1
#define DEBUG_STATS 0
static cli_flagged_sample_t *find_sample(cli_intel_t *intel, const char *virname, const unsigned char *md5, size_t size, stats_section_t *sections);
void free_sample(cli_flagged_sample_t *sample);
@ -123,6 +144,9 @@ void clamav_stats_add_sample(const char *virname, const unsigned char *md5, size
if (!(intel->engine))
return;
if (intel->engine->dconf->stats & DCONF_STATS_DISABLED)
return;
/* First check if we need to submit stats based on memory/number limits */
if ((intel->engine->cb_stats_get_size))
submit = (intel->engine->cb_stats_get_size(cbdata) >= intel->maxmem);
@ -174,6 +198,17 @@ void clamav_stats_add_sample(const char *virname, const unsigned char *md5, size
if ((sample->virus_name)) {
for (i=0; sample->virus_name[i] != NULL; i++)
;
p = realloc(sample->virus_name, sizeof(char **) * (i + 1));
if (!(p)) {
free(sample->virus_name);
free(sample);
if (sample == intel->samples)
intel->samples = NULL;
goto end;
}
sample->virus_name = p;
} else {
i=0;
sample->virus_name = calloc(1, sizeof(char **));
@ -188,15 +223,15 @@ void clamav_stats_add_sample(const char *virname, const unsigned char *md5, size
sample->virus_name[i] = strdup((virname != NULL) ? virname : "[unknown]");
if (!(sample->virus_name[i])) {
free(sample);
free(sample->virus_name);
free(sample);
if (sample == intel->samples)
intel->samples = NULL;
goto end;
}
p = realloc(sample->virus_name, sizeof(char **) * (i == 0 ? 2 : i+1));
p = realloc(sample->virus_name, sizeof(char **) * (i+2));
if (!(p)) {
free(sample->virus_name);
free(sample);
@ -229,8 +264,6 @@ void clamav_stats_add_sample(const char *virname, const unsigned char *md5, size
}
}
cli_warnmsg("Added %s to the stats cache\n", (virname != NULL) ? virname: "[unknown]");
sample->hits++;
end:
@ -311,6 +344,9 @@ void clamav_stats_submit(struct cl_engine *engine, void *cbdata)
if (!(intel) || !(engine))
return;
if (engine->dconf->stats & DCONF_STATS_DISABLED)
return;
if (!(engine->cb_stats_get_hostid)) {
/* Submitting stats is disabled due to HostID being turned off */
if ((engine->cb_stats_flush))
@ -355,8 +391,7 @@ void clamav_stats_submit(struct cl_engine *engine, void *cbdata)
}
if (json) {
cli_warnmsg("====\tSUBMITTING STATS\t====\n");
submit_post(STATS_HOST, STATS_PORT, "PUT", "/clamav/1/submit/stats", json);
submit_post(STATS_HOST, STATS_PORT, "PUT", "/clamav/1/submit/stats", json, myintel.timeout);
free(json);
}

@ -1,3 +1,23 @@
/*
* Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
*
* Author: Shawn Webb
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#if !defined(_LIBCLAMAV_STATS_H)
#define _LIBCLAMAV_STATS_H

@ -1,3 +1,23 @@
/*
* Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
*
* Author: Shawn Webb
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -24,7 +44,7 @@
#include "libclamav/clamav.h"
#include "libclamav/www.h"
int connect_host(const char *host, const char *port, int useAsync)
int connect_host(const char *host, const char *port, uint32_t timeout, int useAsync)
{
int sockfd;
struct addrinfo hints, *servinfo, *p;
@ -67,7 +87,7 @@ int connect_host(const char *host, const char *port, int useAsync)
FD_SET(sockfd, &write_fds);
/* TODO: Make this timeout configurable */
tv.tv_sec = 10;
tv.tv_sec = timeout;
tv.tv_usec = 0;
if (select(sockfd + 1, &read_fds, &write_fds, NULL, &tv) <= 0) {
close(sockfd);
@ -97,7 +117,8 @@ int connect_host(const char *host, const char *port, int useAsync)
if (!(p)) {
freeaddrinfo(servinfo);
close(sockfd);
if (sockfd >= 0)
close(sockfd);
return -1;
}
@ -150,7 +171,7 @@ char *encode_data(const char *postdata)
return buf;
}
void submit_post(const char *host, const char *port, const char *method, const char *url, const char *postdata)
void submit_post(const char *host, const char *port, const char *method, const char *url, const char *postdata, uint32_t timeout)
{
int sockfd, n;
unsigned int i;
@ -214,7 +235,7 @@ void submit_post(const char *host, const char *port, const char *method, const c
free(encoded);
}
sockfd = connect_host(host, port, 1);
sockfd = connect_host(host, port, timeout, 1);
if (sockfd < 0) {
free(buf);
return;
@ -235,7 +256,7 @@ void submit_post(const char *host, const char *port, const char *method, const c
* while it's being processed). Give a ten-second timeout so we don't have a major
* impact on scanning.
*/
tv.tv_sec = 10;
tv.tv_sec = timeout;
tv.tv_usec = 0;
if ((n = select(sockfd+1, &readfds, NULL, NULL, &tv)) <= 0)
break;
@ -245,6 +266,8 @@ void submit_post(const char *host, const char *port, const char *method, const c
if ((recvsz = recv(sockfd, buf, bufsz-1, 0) <= 0))
break;
buf[bufsz-1] = '\0';
if (strstr(buf, "STATOK"))
break;
}

@ -1,9 +1,29 @@
/*
* Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
*
* Author: Shawn Webb
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#if !defined(_LIBCLAMAV_WWW_H)
#define _LIBCLAMAV_WWW_H
int connect_host(const char *host, const char *port, int useAsync);
int connect_host(const char *host, const char *port, uint32_t timeout, int useAsync);
size_t encoded_size(const char *postdata);
char *encode_data(const char *postdata);
void submit_post(const char *host, const char *port, const char *method, const char *url, const char *postdata);
void submit_post(const char *host, const char *port, const char *method, const char *url, const char *postdata, uint32_t timeout);
#endif

@ -117,6 +117,8 @@ static void xar_get_checksum_values(xmlTextReaderPtr reader, unsigned char ** ck
*hash = XAR_CKSUM_OTHER;
}
}
if (style != NULL)
xmlFree(style);
if (xmlTextReaderRead(reader) == 1 && xmlTextReaderNodeType(reader) == XML_READER_TYPE_TEXT) {
xmlval = xmlTextReaderConstValue(reader);
@ -216,6 +218,8 @@ static int xar_get_toc_data_values(xmlTextReaderPtr reader, long *length, long *
cli_dbgmsg("cli_scaxar: unknown style value=%s for encoding element\n", style);
*encoding = CL_TYPE_ANY;
}
if (style != NULL)
xmlFree(style);
} else if (indata && xmlStrEqual(name, (const xmlChar *)"data") &&
xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) {
@ -290,7 +294,6 @@ static int xar_scan_subdocuments(xmlTextReaderPtr reader, cli_ctx *ctx)
xmlTextReaderNext(reader);
continue;
}
// printf("subdoc:\n%s\n", subdoc);
subdoc_len = xmlStrlen(subdoc);
cli_dbgmsg("cli_scanxar: in-memory scan of xml subdocument, len %i.\n", subdoc_len);
rc = cli_mem_scandesc(subdoc, subdoc_len, ctx);
@ -300,7 +303,7 @@ static int xar_scan_subdocuments(xmlTextReaderPtr reader, cli_ctx *ctx)
/* make a file to leave if --leave-temps in effect */
if(ctx->engine->keeptmp) {
if ((rc = cli_gentempfd(ctx->engine->tmpdir, &tmpname, &fd)) != CL_SUCCESS) {
cli_warnmsg("cli_scanxar: Can't create temporary file for subdocument.\n");
cli_dbgmsg("cli_scanxar: Can't create temporary file for subdocument.\n");
} else {
cli_dbgmsg("cli_scanxar: Writing subdoc to temp file %s.\n", tmpname);
if (cli_writen(fd, subdoc, subdoc_len) < 0) {
@ -412,6 +415,7 @@ int cli_scanxar(cli_ctx *ctx)
{
int rc = CL_SUCCESS;
unsigned int cksum_fails = 0;
unsigned int extract_errors = 0;
#if HAVE_LIBXML2
int fd = -1;
struct xar_header hdr;
@ -569,7 +573,8 @@ int cli_scanxar(cli_ctx *ctx)
if ((rc = inflateInit(&strm)) != Z_OK) {
cli_dbgmsg("cli_scanxar: InflateInit failed: %d\n", rc);
rc = CL_EFORMAT;
goto exit_tmpfile;
extract_errors++;
break;
}
while (at < map->len && at < offset+hdr.toc_length_compressed+hdr.size+length) {
@ -577,7 +582,6 @@ int cli_scanxar(cli_ctx *ctx)
void * next_in;
unsigned int bytes = MIN(map->len - at, map->pgsz);
bytes = MIN(length, bytes);
//cli_dbgmsg("cli_scanxar: fmap %u bytes\n", bytes);
if(!(strm.next_in = next_in = (void*)fmap_need_off_once(map, at, bytes))) {
cli_dbgmsg("cli_scanxar: Can't read %u bytes @ %lu.\n", bytes, (long unsigned)at);
inflateEnd(&strm);
@ -591,13 +595,12 @@ int cli_scanxar(cli_ctx *ctx)
unsigned char buff[FILEBUFF];
strm.avail_out = sizeof(buff);
strm.next_out = buff;
//cli_dbgmsg("cli_scanxar: inflating.....\n");
inf = inflate(&strm, Z_SYNC_FLUSH);
if (inf != Z_OK && inf != Z_STREAM_END && inf != Z_BUF_ERROR) {
cli_dbgmsg("cli_scanxar: inflate error %i %s.\n", inf, strm.msg?strm.msg:"");
at = map->len;
rc = CL_EFORMAT;
goto exit_tmpfile;
extract_errors++;
break;
}
bytes = sizeof(buff) - strm.avail_out;
@ -619,10 +622,13 @@ int cli_scanxar(cli_ctx *ctx)
}
} while (strm.avail_out == 0);
if (rc != CL_SUCCESS)
break;
avail_in -= strm.avail_in;
xar_hash_update(a_hash_ctx, next_in, avail_in, a_hash);
}
inflateEnd(&strm);
break;
case CL_TYPE_7Z:
@ -664,9 +670,10 @@ int cli_scanxar(cli_ctx *ctx)
cli_dbgmsg("cli_scanxar: cli_LzmaInit() fails: %i.\n", rc);
rc = CL_EFORMAT;
__lzma_wrap_free(NULL, buff);
goto exit_tmpfile;
extract_errors++;
break;
}
at += CLI_LZMA_HDR_SIZE;
in_remaining -= CLI_LZMA_HDR_SIZE;
while (at < map->len && at < offset+hdr.toc_length_compressed+hdr.size+length) {
@ -694,9 +701,8 @@ int cli_scanxar(cli_ctx *ctx)
if (rc != LZMA_RESULT_OK && rc != LZMA_STREAM_END) {
cli_dbgmsg("cli_scanxar: cli_LzmaDecode() fails: %i.\n", rc);
rc = CL_EFORMAT;
__lzma_wrap_free(NULL, buff);
cli_LzmaShutdown(&lz);
goto exit_tmpfile;
extract_errors++;
break;
}
in_consumed = avail_in - lz.avail_in;
@ -715,7 +721,7 @@ int cli_scanxar(cli_ctx *ctx)
/* cli_dbgmsg("Writing %li bytes to LZMA decompress temp file, " */
/* "consumed %li of %li available compressed bytes.\n", */
/* avail_out, in_consumed, avail_in); */
if (cli_writen(fd, buff, avail_out) < 0) {
cli_dbgmsg("cli_scanxar: cli_writen error writing lzma temp file for %li bytes.\n",
avail_out);
@ -724,18 +730,17 @@ int cli_scanxar(cli_ctx *ctx)
rc = CL_EWRITE;
goto exit_tmpfile;
}
/* Check file size limitation. */
out_size += avail_out;
if (cli_checklimits("cli_scanxar", ctx, out_size, 0, 0) != CL_CLEAN) {
break;
}
if (rc == LZMA_STREAM_END)
break;
}
cli_LzmaShutdown(&lz);
__lzma_wrap_free(NULL, buff);
}
@ -774,47 +779,54 @@ int cli_scanxar(cli_ctx *ctx)
}
}
xar_hash_final(a_hash_ctx, result, a_hash);
if (a_cksum != NULL) {
expected = cli_hex2str((char *)a_cksum);
if (xar_hash_check(a_hash, result, expected) != 0) {
cli_dbgmsg("cli_scanxar: archived-checksum missing or mismatch.\n");
cksum_fails++;
} else {
cli_dbgmsg("cli_scanxar: archived-checksum matched.\n");
}
free(expected);
xmlFree(a_cksum);
a_cksum = NULL;
}
if (e_cksum != NULL) {
if (do_extract_cksum) {
xar_hash_final(e_hash_ctx, result, e_hash);
expected = cli_hex2str((char *)e_cksum);
if (xar_hash_check(e_hash, result, expected) != 0) {
cli_dbgmsg("cli_scanxar: extracted-checksum missing or mismatch.\n");
if (rc == CL_SUCCESS) {
xar_hash_final(a_hash_ctx, result, a_hash);
if (a_cksum != NULL) {
expected = cli_hex2str((char *)a_cksum);
if (xar_hash_check(a_hash, result, expected) != 0) {
cli_dbgmsg("cli_scanxar: archived-checksum missing or mismatch.\n");
cksum_fails++;
} else {
cli_dbgmsg("cli_scanxar: extracted-checksum matched.\n");
cli_dbgmsg("cli_scanxar: archived-checksum matched.\n");
}
free(expected);
}
xmlFree(e_cksum);
e_cksum = NULL;
}
if (e_cksum != NULL) {
if (do_extract_cksum) {
xar_hash_final(e_hash_ctx, result, e_hash);
expected = cli_hex2str((char *)e_cksum);
if (xar_hash_check(e_hash, result, expected) != 0) {
cli_dbgmsg("cli_scanxar: extracted-checksum missing or mismatch.\n");
cksum_fails++;
} else {
cli_dbgmsg("cli_scanxar: extracted-checksum matched.\n");
}
free(expected);
}
}
rc = cli_magic_scandesc(fd, ctx);
if (rc != CL_SUCCESS) {
if (rc == CL_VIRUS) {
cli_dbgmsg("cli_scanxar: Infected with %s\n", cli_get_last_virus(ctx));
if (!SCAN_ALL)
rc = cli_magic_scandesc(fd, ctx);
if (rc != CL_SUCCESS) {
if (rc == CL_VIRUS) {
cli_dbgmsg("cli_scanxar: Infected with %s\n", cli_get_last_virus(ctx));
if (!SCAN_ALL)
goto exit_tmpfile;
} else if (rc != CL_BREAK) {
cli_dbgmsg("cli_scanxar: cli_magic_scandesc error %i\n", rc);
goto exit_tmpfile;
} else if (rc != CL_BREAK) {
cli_dbgmsg("cli_scanxar: cli_magic_scandesc error %i\n", rc);
goto exit_tmpfile;
}
}
}
}
if (a_cksum != NULL) {
xmlFree(a_cksum);
a_cksum = NULL;
}
if (e_cksum != NULL) {
xmlFree(e_cksum);
e_cksum = NULL;
}
}
exit_tmpfile:
xar_cleanup_temp_file(ctx, fd, tmpname);
@ -834,8 +846,10 @@ int cli_scanxar(cli_ctx *ctx)
#else
cli_dbgmsg("cli_scanxar: can't scan xar files, need libxml2.\n");
#endif
if (cksum_fails != 0)
cli_warnmsg("cli_scanxar: %u checksums missing, mismatched, or unsupported - use --debug for more info.\n", cksum_fails);
if (cksum_fails + extract_errors != 0) {
cli_warnmsg("cli_scanxar: %u checksum errors and %u extraction errors, use --debug for more info.\n",
cksum_fails, extract_errors);
}
return rc;
}

@ -112,6 +112,7 @@ const struct clam_option __clam_options[] = {
{ NULL, "build", 'b', TYPE_STRING, NULL, -1, NULL, 0, OPT_SIGTOOL, "", "" },
{ NULL, "max-bad-sigs", 0, TYPE_NUMBER, MATCH_NUMBER, 3000, NULL, 0, OPT_SIGTOOL, "Maximum number of mismatched signatures when building a CVD. Zero disables this limit.", "3000" },
{ NULL, "flevel", 0, TYPE_NUMBER, MATCH_NUMBER, CL_FLEVEL, NULL, 0, OPT_SIGTOOL, "Feature level to put in the CVD", "" },
{ NULL, "cvd-version", 0, TYPE_NUMBER, MATCH_NUMBER, 0, NULL, 0, OPT_SIGTOOL, "Version number of the CVD to build", "" },
{ NULL, "unsigned", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_SIGTOOL, "", "" },
{ NULL, "no-cdiff", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_SIGTOOL, "", "" },
{ NULL, "server", 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_SIGTOOL, "", "" },
@ -185,6 +186,8 @@ const struct clam_option __clam_options[] = {
{ "StatsPEDisabled", "disable-pe-stats", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "Disable submission of PE section statistical data", "no" },
{ "StatsTimeout", "stats-timeout", 0, TYPE_NUMBER, MATCH_NUMBER, -1, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN | OPT_FRESHCLAM, "Timeout in seconds to timeout communication with the stats server.", "10" },
{ "LogFileUnlock", NULL, 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD | OPT_MILTER, "By default the log file is locked for writing and only a single\ndaemon process can write to it. This option disables the lock.", "yes" },
{ "LogFileMaxSize", NULL, 0, TYPE_SIZE, MATCH_SIZE, 1048576, NULL, 0, OPT_CLAMD | OPT_FRESHCLAM | OPT_MILTER, "Maximum size of the log file.\nValue of 0 disables the limit.", "5M" },

@ -793,6 +793,8 @@ static int build(const struct optstruct *opts)
version = oldcvd->version + 1;
oldsigs = oldcvd->sigs;
cl_cvdfree(oldcvd);
} else if (optget(opts, "cvd-version")->numarg != 0) {
version = optget(opts, "cvd-version")->numarg;
} else {
mprintf("Version number: ");
if(scanf("%u", &version) == EOF) {
@ -2903,9 +2905,9 @@ static int dumpcerts(const struct optstruct *opts)
static void help(void)
{
mprintf("\n");
mprintf(" Clam AntiVirus: Signature Tool (sigtool) %s\n", get_version());
printf(" By The ClamAV Team: http://www.clamav.net/team\n");
printf(" (C) 2007-2009 Sourcefire, Inc. et al.\n\n");
mprintf("Clam AntiVirus: Signature Tool (sigtool) %s\n", get_version());
mprintf(" By The ClamAV Team: http://www.clamav.net/team\n");
mprintf(" (C) 2007-2009 Sourcefire, Inc. et al.\n\n");
mprintf(" --help -h show help\n");
mprintf(" --version -V print version number and exit\n");
@ -2925,23 +2927,36 @@ static void help(void)
mprintf(" --utf16-decode=FILE decode UTF16 encoded files\n");
mprintf(" --info=FILE -i FILE print database information\n");
mprintf(" --build=NAME [cvd] -b NAME build a CVD file\n");
mprintf(" --max-bad-sigs=NUMBER Maximum number of mismatched signatures when building a CVD. Default: 3000\n");
mprintf(" --flevel=FLEVEL Specify a custom flevel. Default: %u\n", cl_retflevel());
mprintf(" --max-bad-sigs=NUMBER Maximum number of mismatched signatures\n");
mprintf(" when building a CVD. Default: 3000\n");
mprintf(" --flevel=FLEVEL Specify a custom flevel.\n");
mprintf(" Default: %u\n", cl_retflevel());
mprintf(" --cvd-version=NUMBER Specify the version number to use for\n");
mprintf(" the build. Default is to use the value+1\n");
mprintf(" from the current CVD in --datadir.\n");
mprintf(" If no datafile is found the default\n");
mprintf(" behaviour is to prompt for a version\n");
mprintf(" number, this switch will prevent the\n");
mprintf(" prompt. NOTE: If a CVD is found in the\n");
mprintf(" --datadir its version+1 is used and\n");
mprintf(" this value is ignored.\n");
mprintf(" --no-cdiff Don't generate .cdiff file\n");
mprintf(" --unsigned Create unsigned database file (.cud)\n");
mprintf(" --print-certs=FILE Print Authenticode details from a PE\n");
mprintf(" --server=ADDR ClamAV Signing Service address\n");
mprintf(" --datadir=DIR Use DIR as default database directory\n");
mprintf(" --datadir=DIR Use DIR as default database directory\n");
mprintf(" --unpack=FILE -u FILE Unpack a CVD/CLD file\n");
mprintf(" --unpack-current=SHORTNAME Unpack local CVD/CLD into cwd\n");
mprintf(" --list-sigs[=FILE] -l[FILE] List signature names\n");
mprintf(" --find-sigs=REGEX -fREGEX Find signatures matching REGEX\n");
mprintf(" --decode-sigs Decode signatures from stdin\n");
mprintf(" --test-sigs=DATABASE TARGET_FILE Test signatures from DATABASE against TARGET_FILE\n");
mprintf(" --test-sigs=DATABASE TARGET_FILE Test signatures from DATABASE against \n");
mprintf(" TARGET_FILE\n");
mprintf(" --vba=FILE Extract VBA/Word6 macro code\n");
mprintf(" --vba-hex=FILE Extract Word6 macro code with hex values\n");
mprintf(" --diff=OLD NEW -d OLD NEW Create diff for OLD and NEW CVDs\n");
mprintf(" --compare=OLD NEW -c OLD NEW Show diff between OLD and NEW files in cdiff format\n");
mprintf(" --compare=OLD NEW -c OLD NEW Show diff between OLD and NEW files in\n");
mprintf(" cdiff format\n");
mprintf(" --run-cdiff=FILE -r FILE Execute update script FILE in cwd\n");
mprintf(" --verify-cdiff=DIFF CVD/CLD Verify DIFF against CVD/CLD\n");
mprintf("\n");

@ -23,6 +23,14 @@
fun:_ZN4llvm12PassRegistry12registerPassERKNS_8PassInfoE
fun:*
}
{
llvm-03
Memcheck:Leak
fun:_Znwm
...
fun:_ZN4llvm12PassRegistry12registerPassERKNS_8PassInfoE
...
}
{
dl_catch_error-leak-1
Memcheck:Leak
@ -49,3 +57,10 @@
fun:parseEmailHeader
...
}
{
ubuntu-libc-getaddrinfo-01
Memcheck:Param
sendmsg(mmsg[0].msg_hdr)
fun:sendmmsg
...
}

Loading…
Cancel
Save