Restructured scan options flags from a single bitflag field to a structure containing multiple bitflag fields. This also required adding a new function to the bytecode API to get scan options a la carte, and modifying the existing function to hand back scan options in the old/deprecated uint32_t bitflag format. Re-generated bytecode iface header files.

Updated libclamav documentation detailing new scan options structure.
Renamed references to 'algorithmic' detection to 'heuristic' detection. Renaming references to 'properties' to 'collect metadata'.
Renamed references to 'scan all' to 'scan all match'.
Renamed a couple of 'Hueristic.*' signature names as 'Heuristics.*' signatures (plural) to match majority of other heuristics.
pull/51/head
Micah Snyder 8 years ago
parent 89d5207b31
commit d7979d4ff7
  1. 10
      NEWS.md
  2. 1
      clamconf/clamconf.c
  3. 36
      clamd/onaccess_ddd.c
  4. 13
      clamd/onaccess_ddd.h
  5. 26
      clamd/onaccess_fan.c
  6. 2
      clamd/onaccess_others.c
  7. 3
      clamd/onaccess_others.h
  8. 24
      clamd/onaccess_scth.c
  9. 8
      clamd/onaccess_scth.h
  10. 23
      clamd/scanner.c
  11. 7
      clamd/scanner.h
  12. 95
      clamd/server-th.c
  13. 12
      clamd/server.h
  14. 4
      clamd/session.c
  15. 2
      clamd/session.h
  16. 82
      clamscan/manager.c
  17. 5
      contrib/old-clamav-milter/clamav-milter.c
  18. 131
      docs/UserManual/libclamav.md
  19. 2
      etc/clamd.conf.sample
  20. 7
      examples/ex1.c
  21. 12
      libclamav/7z_iface.c
  22. 8
      libclamav/apm.c
  23. 4
      libclamav/autoit.c
  24. 5
      libclamav/blob.c
  25. 8
      libclamav/bytecode.c
  26. 193
      libclamav/bytecode_api.c
  27. 87
      libclamav/bytecode_api.h
  28. 249
      libclamav/bytecode_api_decl.c
  29. 3
      libclamav/bytecode_api_impl.h
  30. 2
      libclamav/bytecode_hooks.h
  31. 2
      libclamav/cache.c
  32. 135
      libclamav/clamav.h
  33. 2
      libclamav/clambc.h
  34. 12
      libclamav/cpio.c
  35. 2
      libclamav/dmg.c
  36. 24
      libclamav/elf.c
  37. 20
      libclamav/gpt.c
  38. 8
      libclamav/hfsplus.c
  39. 44
      libclamav/hwp.c
  40. 2
      libclamav/ishield.c
  41. 4
      libclamav/iso9660.c
  42. 2
      libclamav/json_api.c
  43. 8
      libclamav/libmspack.c
  44. 2
      libclamav/macho.c
  45. 8
      libclamav/matcher-ac.c
  46. 4
      libclamav/matcher-bm.c
  47. 2
      libclamav/matcher-pcre.c
  48. 36
      libclamav/matcher.c
  49. 7
      libclamav/mbox.c
  50. 18
      libclamav/mbr.c
  51. 18
      libclamav/msxml_parser.c
  52. 14
      libclamav/ole2_extract.c
  53. 16
      libclamav/others.c
  54. 51
      libclamav/others.h
  55. 74
      libclamav/pdf.c
  56. 3
      libclamav/pdfdecode.c
  57. 42
      libclamav/pe.c
  58. 6
      libclamav/phishcheck.c
  59. 295
      libclamav/scanners.c
  60. 2
      libclamav/tiff.c
  61. 4
      libclamav/untar.c
  62. 10
      libclamav/unzip.c
  63. 8
      libclamav/xar.c
  64. 18
      sigtool/sigtool.c
  65. 6
      unit_tests/check_bytecode.c
  66. 80
      unit_tests/check_clamav.c
  67. 18
      unit_tests/check_matchers.c
  68. 8
      unit_tests/check_regex.c
  69. 103
      win32/clamav-for-windows/clamav-for-windows/interface.c
  70. 2
      win32/conf_examples/clamd.conf.sample

@ -86,7 +86,7 @@ ClamAV 0.100, including but not limited to:
- Raw scanning of PostScript files.
- Fix clamsubmit to use the new virus and false positive submission web
interface.
- Optionally, flag files with the virus "Heuristic.Limits.Exceeded" when
- Optionally, flag files with the virus "Heuristics.Limits.Exceeded" when
size limitations are exceeded.
- Improved decoders for PDF files.
- Reduced number of compile time warnings.
@ -1147,7 +1147,7 @@ Detailed list of changes:
- Support for Sensory Networks' NodalCore hardware acceleration technology
- Advanced phishing detection module (experimental)
- Signatures are stored in separate trees depending on their target type
- Algorithmic detection can be controlled with CL_SCAN_ALGORITHMIC
- Algorithmic detection can be controlled with CL_SCAN_GENERAL_HEURISTICS
- Support for new obfuscators: SUE, Y0da Cryptor, CryptFF
- Support for new packers: NsPack, wwpack32, MEW, Upack
- Support for SIS files (SymbianOS packages)
@ -1598,11 +1598,11 @@ the new version of ClamAV have detected and blocked 100% of Mydoom attacks!
New features in this release include:
- libclamav
- Portable Executable analyser (CL_SCAN_PE) featuring:
- Portable Executable analyser (CL_SCAN_PARSE_PE) featuring:
- UPX decompression (all versions)
- Petite decompression (2.x)
- FSG decompression (1.3, 1.31, 1.33)
- detection of broken executables (CL_SCAN_BLOCKBROKEN)
- detection of broken executables (CL_SCAN_HEURISTIC_BROKEN)
- new, memory efficient, pattern matching algorithm (multipattern variant
of Boyer-Moore) - it's now primary matcher and Aho-Corasick is only used
for regular expression extended signatures
@ -1618,7 +1618,7 @@ New features in this release include:
- new method of mail files detection
- all e-mail attachments are now scanned (previously only the first ten
attachments were scanned)
- added support for scanning URLs in e-mails (CL_SCAN_MAILURL)
- added support for scanning URLs in e-mails (CL_SCAN_PARSE_MAILURL)
- detection of Worm.Mydoom.M.log
- updated API (still backward compatible but please consult clamdoc.pdf
(Section 6) and adapt your software)

@ -39,6 +39,7 @@
#include "shared/optparser.h"
#include "shared/misc.h"
#include "clamav-config.h"
#include "libclamav/str.h"
#include "libclamav/clamav.h"
#include "libclamav/others.h"

@ -68,7 +68,7 @@ static void onas_ddd_handle_in_moved_to(struct ddd_thrarg *tharg, const char *pa
static void onas_ddd_handle_in_create(struct ddd_thrarg *tharg, const char *path, const char *child_path, const struct inotify_event *event, int wd, uint64_t in_mask);
static void onas_ddd_handle_in_moved_from(struct ddd_thrarg *tharg, const char *path, const char *child_path, const struct inotify_event *event, int wd);
static void onas_ddd_handle_in_delete(struct ddd_thrarg *tharg, const char *path, const char *child_path, const struct inotify_event *event, int wd);
static void onas_ddd_handle_extra_scanning(struct ddd_thrarg *tharg, const char *pathname, int options);
static void onas_ddd_handle_extra_scanning(struct ddd_thrarg *tharg, const char *pathname, int extra_options);
static void onas_ddd_exit(int sig);
@ -527,8 +527,9 @@ static void onas_ddd_handle_in_moved_to(struct ddd_thrarg *tharg,
return;
}
static void onas_ddd_handle_extra_scanning(struct ddd_thrarg *tharg, const char *pathname, int options) {
static void onas_ddd_handle_extra_scanning(struct ddd_thrarg *tharg, const char *pathname, int extra_options) {
int thread_started = 1;
struct scth_thrarg *scth_tharg = NULL;
pthread_attr_t scth_attr;
pthread_t scth_pid = 0;
@ -537,20 +538,37 @@ static void onas_ddd_handle_extra_scanning(struct ddd_thrarg *tharg, const char
if (pthread_attr_init(&scth_attr)) break;
pthread_attr_setdetachstate(&scth_attr, PTHREAD_CREATE_JOINABLE);
if (!(scth_tharg = (struct scth_thrarg *) malloc(sizeof(struct scth_thrarg)))) break;
/* Allocate memory for arguments. Thread is responsible for freeing it. */
if (!(scth_tharg = (struct scth_thrarg *) calloc(sizeof(struct scth_thrarg), 1))) break;
if (!(scth_tharg->options = (struct cl_scan_options *) calloc(sizeof(struct cl_scan_options), 1))) break;
scth_tharg->options = options;
(void) memcpy(scth_tharg->options, tharg->options, sizeof(struct cl_scan_options));
scth_tharg->extra_options = extra_options;
scth_tharg->opts = tharg->opts;
scth_tharg->pathname = strdup(pathname);
scth_tharg->engine = tharg->engine;
if (!pthread_create(&scth_pid, &scth_attr, onas_scan_th, scth_tharg)) break;
free(scth_tharg);
scth_tharg = NULL;
thread_started = pthread_create(&scth_pid, &scth_attr, onas_scan_th, scth_tharg);
} while(0);
if (!scth_tharg) logg("!ScanOnAccess: Unable to kick off extra scanning.\n");
if (0 != thread_started) {
/* Failed to create thread. Free anything we may have allocated. */
logg("!ScanOnAccess: Unable to kick off extra scanning.\n");
if (NULL != scth_tharg) {
if (NULL != scth_tharg->pathname){
free(scth_tharg->pathname);
scth_tharg->pathname = NULL;
}
if (NULL != scth_tharg->options) {
free(scth_tharg->options);
scth_tharg->options = NULL;
}
free(scth_tharg);
scth_tharg = NULL;
}
}
return;
}

@ -22,19 +22,24 @@
#ifndef __ONAS_IN_H
#define __ONAS_IN_H
#define ONAS_IN 0x01
#define ONAS_FAN 0x02
#include "shared/optparser.h"
#include "libclamav/clamav.h"
/*
* Extra options for onas_scan_th().
*/
#define ONAS_IN 0x01
#define ONAS_FAN 0x02
#define MAX_WATCH_LEN 7
struct ddd_thrarg {
int sid;
int options;
struct cl_scan_options *options;
int fan_fd;
uint64_t fan_mask;
const struct optstruct *opts;
const struct cl_engine *engine;
const struct cl_limits *limits;
};

@ -171,24 +171,36 @@ void *onas_fan_th(void *arg)
}
} else if (!optget(tharg->opts, "OnAccessDisableDDD")->enabled) {
int thread_started = 1;
do {
if(pthread_attr_init(&ddd_attr)) break;
pthread_attr_setdetachstate(&ddd_attr, PTHREAD_CREATE_JOINABLE);
if(!(ddd_tharg = (struct ddd_thrarg *) malloc(sizeof(struct ddd_thrarg)))) break;
/* Allocate memory for arguments. Thread is responsible for freeing it. */
if (!(ddd_tharg = (struct ddd_thrarg *) calloc(sizeof(struct ddd_thrarg), 1))) break;
if (!(ddd_tharg->options = (struct cl_scan_options *) calloc(sizeof(struct cl_scan_options), 1))) break;
(void) memcpy(ddd_tharg->options, tharg->options, sizeof(struct cl_scan_options));
ddd_tharg->fan_fd = onas_fan_fd;
ddd_tharg->fan_mask = fan_mask;
ddd_tharg->opts = tharg->opts;
ddd_tharg->engine = tharg->engine;
ddd_tharg->options = tharg->options;
if(!pthread_create(&ddd_pid, &ddd_attr, onas_ddd_th, ddd_tharg)) break;
free(ddd_tharg);
ddd_tharg=NULL;
thread_started = pthread_create(&ddd_pid, &ddd_attr, onas_ddd_th, ddd_tharg);
} while(0);
if (!ddd_tharg) logg("!Unable to start dynamic directory determination.\n");
if (0 != thread_started) {
/* Failed to create thread. Free anything we may have allocated. */
logg("!Unable to start dynamic directory determination.\n");
if (NULL != ddd_tharg) {
if (NULL != ddd_tharg->options) {
free(ddd_tharg->options);
ddd_tharg->options = NULL;
}
free(ddd_tharg);
ddd_tharg = NULL;
}
}
} else {
if((pt = optget(tharg->opts, "OnAccessIncludePath"))->enabled) {

@ -94,7 +94,7 @@ int onas_fan_checkowner(int pid, const struct optstruct *opts)
return CHK_CLEAN;
}
int onas_scan(const char *fname, int fd, const char **virname, const struct cl_engine *engine, int options, int extinfo)
int onas_scan(const char *fname, int fd, const char **virname, const struct cl_engine *engine, struct cl_scan_options *options, int extinfo)
{
int ret = 0;
struct cb_context context;

@ -22,6 +22,7 @@
#define __CLAMD_ONAS_OTHERS_H
#include "shared/optparser.h"
#include "libclamav/clamav.h"
typedef enum {
CHK_CLEAN,
@ -30,6 +31,6 @@ typedef enum {
} cli_check_t;
int onas_fan_checkowner(int pid, const struct optstruct *opts);
int onas_scan(const char *fname, int fd, const char **virname, const struct cl_engine *engine, int options, int extinfo);
int onas_scan(const char *fname, int fd, const char **virname, const struct cl_engine *engine, struct cl_scan_options *options, int extinfo);
#endif

@ -38,6 +38,7 @@
#include "priv_fts.h"
#include "onaccess_scth.h"
#include "onaccess_others.h"
#include "libclamav/clamav.h"
@ -132,16 +133,31 @@ void *onas_scan_th(void *arg) {
sigaction(SIGUSR1, &act, NULL);
sigaction(SIGSEGV, &act, NULL);
if (tharg->options & ONAS_SCTH_ISDIR) {
if (NULL == tharg || NULL == tharg->pathname || NULL == tharg->opts || NULL == tharg->engine) {
logg("ScanOnAccess: Invalid thread arguments for extra scanning\n");
goto done;
}
if (tharg->extra_options & ONAS_SCTH_ISDIR) {
logg("*ScanOnAccess: Performing additional scanning on directory '%s'\n", tharg->pathname);
onas_scth_handle_dir(tharg->pathname, tharg);
} else if (tharg->options & ONAS_SCTH_ISFILE) {
} else if (tharg->extra_options & ONAS_SCTH_ISFILE) {
logg("*ScanOnAccess: Performing additional scanning on file '%s'\n", tharg->pathname);
onas_scth_handle_file(tharg->pathname, tharg);
}
free(tharg->pathname);
tharg->pathname = NULL;
done:
if (NULL != tharg->pathname){
free(tharg->pathname);
tharg->pathname = NULL;
}
if (NULL != tharg->options) {
free(tharg->options);
tharg->options = NULL;
}
if (NULL != tharg) {
free(tharg);
}
return NULL;
}

@ -21,13 +21,17 @@
#ifndef __ONAS_SCTH_H
#define __ONAS_SCTH_H
#include "shared/optparser.h"
#include "libclamav/clamav.h"
#define ONAS_SCTH_ISDIR 0x01
#define ONAS_SCTH_ISFILE 0x02
struct scth_thrarg {
int options;
uint32_t extra_options;
struct cl_scan_options *options;
const struct optstruct *opts;
const struct cl_engine *engine;
const struct cl_engine *engine;
char *pathname;
};

@ -117,7 +117,7 @@ void clamd_virus_found_cb(int fd, const char *virname, void *ctx)
if (d == NULL)
return;
if (!(d->options & CL_SCAN_ALLMATCHES) && !(d->options & CL_SCAN_HEURISTIC_PRECEDENCE))
if (!(d->options->general & CL_SCAN_GENERAL_ALLMATCHES) && !(d->options->general & CL_SCAN_GENERAL_HEURISTIC_PRECEDENCE))
return;
if (virname == NULL)
return;
@ -277,7 +277,7 @@ int scan_callback(STATBUF *sb, char *filename, const char *msg, enum cli_ftw_rea
if (ret == CL_VIRUS) {
if (scandata->options & CL_SCAN_ALLMATCHES || (scandata->infected && scandata->options & CL_SCAN_HEURISTIC_PRECEDENCE)) {
if (scandata->options->general & CL_SCAN_GENERAL_ALLMATCHES || (scandata->infected && scandata->options->general & CL_SCAN_GENERAL_HEURISTIC_PRECEDENCE)) {
if(optget(scandata->opts, "PreludeEnable")->enabled){
prelude_logging(filename, virname, context.virhash, context.virsize);
}
@ -353,9 +353,14 @@ int scan_pathchk(const char *path, struct cli_ftw_cbdata *data)
return 0;
}
int scanfd(const client_conn_t *conn, unsigned long int *scanned,
const struct cl_engine *engine,
unsigned int options, const struct optstruct *opts, int odesc, int stream)
int scanfd(
const client_conn_t *conn,
unsigned long int *scanned,
const struct cl_engine *engine,
struct cl_scan_options *options,
const struct optstruct *opts,
int odesc,
int stream)
{
int ret, fd = conn->scanfd;
const char *virname = NULL;
@ -418,7 +423,13 @@ int scanfd(const client_conn_t *conn, unsigned long int *scanned,
return ret;
}
int scanstream(int odesc, unsigned long int *scanned, const struct cl_engine *engine, unsigned int options, const struct optstruct *opts, char term)
int scanstream(
int odesc,
unsigned long int *scanned,
const struct cl_engine *engine,
struct cl_scan_options *options,
const struct optstruct *opts,
char term)
{
int ret, sockfd, acceptd;
int tmpd, bread, retval, firsttimeout, timeout, btread;

@ -24,6 +24,7 @@
#include <sys/types.h>
#include "libclamav/others.h"
#include "libclamav/clamav.h"
#include "shared/optparser.h"
#include "thrmgr.h"
@ -42,7 +43,7 @@ struct scan_cb_data {
const client_conn_t *conn;
const char *toplevel_path;
unsigned long scanned;
unsigned int options;
struct cl_scan_options *options;
struct cl_engine *engine;
const struct optstruct *opts;
threadpool_t *thr_pool;
@ -57,8 +58,8 @@ struct cb_context {
struct scan_cb_data *scandata;
};
int scanfd(const client_conn_t *conn, unsigned long int *scanned, const struct cl_engine *engine, unsigned int options, const struct optstruct *opts, int odesc, int stream);
int scanstream(int odesc, unsigned long int *scanned, const struct cl_engine *engine, unsigned int options, const struct optstruct *opts, char term);
int scanfd(const client_conn_t *conn, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *options, const struct optstruct *opts, int odesc, int stream);
int scanstream(int odesc, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *options, const struct optstruct *opts, char term);
int scan_callback(STATBUF *sb, char *filename, const char *msg, enum cli_ftw_reason reason, struct cli_ftw_cbdata *data);
int scan_pathchk(const char *path, struct cli_ftw_cbdata *data);
void hash_callback(int fd, unsigned long long size, const unsigned char *md5, const char *virname, void *ctx);

@ -718,7 +718,7 @@ static int handle_stream(client_conn_t *conn, struct fd_buf *buf, const struct o
int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsigned int dboptions, const struct optstruct *opts)
{
int max_threads, max_queue, readtimeout, ret = 0;
unsigned int options = 0;
struct cl_scan_options options;
char timestr[32];
#ifndef _WIN32
struct sigaction sigact;
@ -742,7 +742,7 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
threadpool_t *thr_pool;
#if defined(FANOTIFY) || defined(CLAMAUTH)
pthread_t fan_pid;
pthread_t fan_pid = 0;
pthread_attr_t fan_attr;
struct thrarg *tharg = NULL; /* shut up gcc */
#endif
@ -751,6 +751,9 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
memset(&sigact, 0, sizeof(struct sigaction));
#endif
/* Initalize scan options struct */
memset(&options, 0, sizeof(struct cl_scan_options));
/* set up limits */
if((opt = optget(opts, "MaxScanSize"))->active) {
if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_SCANSIZE, opt->numarg))) {
@ -922,11 +925,11 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
if(optget(opts, "ScanArchive")->enabled) {
logg("Archive support enabled.\n");
options |= CL_SCAN_ARCHIVE;
options.parse |= CL_SCAN_PARSE_ARCHIVE;
if(optget(opts, "ArchiveBlockEncrypted")->enabled) {
logg("Archive: Blocking encrypted archives.\n");
options |= CL_SCAN_BLOCKENCRYPTED;
options.heuristic |= CL_SCAN_HEURISTIC_ENCRYPTED;
}
} else {
@ -935,28 +938,28 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
if (optget(opts, "BlockMax")->enabled) {
logg("BlockMax heuristic detection enabled.\n");
options |= CL_SCAN_BLOCKMAX;
options.heuristic |= CL_SCAN_HEURISTIC_EXCEEDS_MAX;
} else {
logg("BlockMax heuristic detection disabled.\n");
}
if(optget(opts, "AlgorithmicDetection")->enabled) {
logg("Algorithmic detection enabled.\n");
options |= CL_SCAN_ALGORITHMIC;
options.general |= CL_SCAN_GENERAL_HEURISTICS;
} else {
logg("Algorithmic detection disabled.\n");
}
if(optget(opts, "ScanPE")->enabled) {
logg("Portable Executable support enabled.\n");
options |= CL_SCAN_PE;
options.parse |= CL_SCAN_PARSE_PE;
} else {
logg("Portable Executable support disabled.\n");
}
if(optget(opts, "ScanELF")->enabled) {
logg("ELF support enabled.\n");
options |= CL_SCAN_ELF;
options.parse |= CL_SCAN_PARSE_ELF;
} else {
logg("ELF support disabled.\n");
}
@ -964,17 +967,17 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
if(optget(opts, "ScanPE")->enabled || optget(opts, "ScanELF")->enabled) {
if(optget(opts, "DetectBrokenExecutables")->enabled) {
logg("Detection of broken executables enabled.\n");
options |= CL_SCAN_BLOCKBROKEN;
options.heuristic |= CL_SCAN_HEURISTIC_BROKEN;
}
}
if(optget(opts, "ScanMail")->enabled) {
logg("Mail files support enabled.\n");
options |= CL_SCAN_MAIL;
options.parse |= CL_SCAN_PARSE_MAIL;
if(optget(opts, "ScanPartialMessages")->enabled) {
logg("Mail: RFC1341 handling enabled.\n");
options |= CL_SCAN_PARTIAL_MESSAGE;
options.mail |= CL_SCAN_MAIL_PARTIAL_MESSAGE;
}
} else {
@ -983,10 +986,10 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
if(optget(opts, "ScanOLE2")->enabled) {
logg("OLE2 support enabled.\n");
options |= CL_SCAN_OLE2;
options.parse |= CL_SCAN_PARSE_OLE2;
if(optget(opts, "OLE2BlockMacros")->enabled) {
logg("OLE2: Blocking all VBA macros.\n");
options |= CL_SCAN_BLOCKMACROS;
options.heuristic |= CL_SCAN_HEURISTIC_MACROS;
}
} else {
logg("OLE2 support disabled.\n");
@ -994,35 +997,35 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
if(optget(opts, "ScanPDF")->enabled) {
logg("PDF support enabled.\n");
options |= CL_SCAN_PDF;
options.parse |= CL_SCAN_PARSE_PDF;
} else {
logg("PDF support disabled.\n");
}
if(optget(opts, "ScanSWF")->enabled) {
logg("SWF support enabled.\n");
options |= CL_SCAN_SWF;
options.parse |= CL_SCAN_PARSE_SWF;
} else {
logg("SWF support disabled.\n");
}
if(optget(opts, "ScanHTML")->enabled) {
logg("HTML support enabled.\n");
options |= CL_SCAN_HTML;
options.parse |= CL_SCAN_PARSE_HTML;
} else {
logg("HTML support disabled.\n");
}
if(optget(opts, "ScanXMLDOCS")->enabled) {
logg("XMLDOCS support enabled.\n");
options |= CL_SCAN_XMLDOCS;
options.parse |= CL_SCAN_PARSE_XMLDOCS;
} else {
logg("XMLDOCS support disabled.\n");
}
if(optget(opts, "ScanHWP3")->enabled) {
logg("HWP3 support enabled.\n");
options |= CL_SCAN_HWP3;
options.parse |= CL_SCAN_PARSE_HWP3;
} else {
logg("HWP3 support disabled.\n");
}
@ -1030,28 +1033,28 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
if(optget(opts,"PhishingScanURLs")->enabled) {
if(optget(opts,"PhishingAlwaysBlockCloak")->enabled) {
options |= CL_SCAN_PHISHING_BLOCKCLOAK;
options.heuristic |= CL_SCAN_HEURISTIC_PHISHING_CLOAK;
logg("Phishing: Always checking for cloaked urls\n");
}
if(optget(opts,"PhishingAlwaysBlockSSLMismatch")->enabled) {
options |= CL_SCAN_PHISHING_BLOCKSSL;
options.heuristic |= CL_SCAN_HEURISTIC_PHISHING_SSL_MISMATCH;
logg("Phishing: Always checking for ssl mismatches\n");
}
}
if(optget(opts,"PartitionIntersection")->enabled) {
options |= CL_SCAN_PARTITION_INTXN;
options.heuristic |= CL_SCAN_HEURISTIC_PARTITION_INTXN;
logg("Raw DMG: Always checking for partitions intersections\n");
}
if(optget(opts,"HeuristicScanPrecedence")->enabled) {
options |= CL_SCAN_HEURISTIC_PRECEDENCE;
options.general |= CL_SCAN_GENERAL_HEURISTIC_PRECEDENCE;
logg("Heuristic: precedence enabled\n");
}
if(optget(opts, "StructuredDataDetection")->enabled) {
options |= CL_SCAN_STRUCTURED;
options.heuristic |= CL_SCAN_HEURISTIC_STRUCTURED;
if((opt = optget(opts, "StructuredMinCreditCardCount"))->enabled) {
if((ret = cl_engine_set_num(engine, CL_ENGINE_MIN_CC_COUNT, opt->numarg))) {
@ -1074,15 +1077,15 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
logg("Structured: Minimum Social Security Number Count set to %u\n", (unsigned int) val);
if(optget(opts, "StructuredSSNFormatNormal")->enabled)
options |= CL_SCAN_STRUCTURED_SSN_NORMAL;
options.heuristic |= CL_SCAN_HEURISTIC_STRUCTURED_SSN_NORMAL;
if(optget(opts, "StructuredSSNFormatStripped")->enabled)
options |= CL_SCAN_STRUCTURED_SSN_STRIPPED;
options.heuristic |= CL_SCAN_HEURISTIC_STRUCTURED_SSN_STRIPPED;
}
#ifdef HAVE__INTERNAL__SHA_COLLECT
if(optget(opts, "DevCollectHashes")->enabled)
options |= CL_SCAN_INTERNAL_COLLECT_SHA;
options.dev |= CL_SCAN_DEV_COLLECT_SHA;
#endif
selfchk = optget(opts, "SelfCheck")->numarg;
@ -1209,18 +1212,34 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
#if defined(FANOTIFY) || defined(CLAMAUTH)
{
int thread_started = 1;
do {
if(pthread_attr_init(&fan_attr)) break;
pthread_attr_setdetachstate(&fan_attr, PTHREAD_CREATE_JOINABLE);
if(!(tharg = (struct thrarg *) malloc(sizeof(struct thrarg)))) break;
tharg->opts = opts;
tharg->engine = engine;
tharg->options = options;
if(!pthread_create(&fan_pid, &fan_attr, onas_fan_th, tharg)) break;
free(tharg);
tharg=NULL;
} while(0);
if (!tharg) logg("!Unable to start on-access scan\n");
if(pthread_attr_init(&fan_attr)) break;
pthread_attr_setdetachstate(&fan_attr, PTHREAD_CREATE_JOINABLE);
/* Allocate memory for arguments. Thread is responsible for freeing it. */
if (!(tharg = (struct thrarg *) calloc(sizeof(struct thrarg), 1))) break;
if (!(tharg->options = (struct cl_scan_options *) calloc(sizeof(struct cl_scan_options), 1))) break;
(void) memcpy(tharg->options, &options, sizeof(struct cl_scan_options));
tharg->opts = opts;
tharg->engine = engine;
thread_started = pthread_create(&fan_pid, &fan_attr, onas_fan_th, tharg);
} while(0);
if (0 != thread_started) {
/* Failed to create thread. Free anything we may have allocated. */
logg("!Unable to start on-access scan.\n");
if (NULL != tharg) {
if (NULL != tharg->options) {
free(tharg->options);
tharg->options = NULL;
}
free(tharg);
tharg = NULL;
}
}
}
#else
logg("!On-access scan is not available\n");
@ -1384,7 +1403,7 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
conn.scanfd = buf->recvfd;
buf->recvfd = -1;
conn.sd = buf->fd;
conn.options = options;
conn.options = &options;
conn.opts = opts;
conn.thrpool = thr_pool;
conn.engine = engine;

@ -32,19 +32,9 @@
#include "session.h"
struct thrarg {
int sid;
int options;
struct cl_scan_options *options;
const struct optstruct *opts;
const struct cl_engine *engine;
const struct cl_limits *limits;
};
/* thread watcher arguments */
struct thrwarg {
int socketd;
struct cl_engine **engine;
const struct optstruct *opts;
const struct cl_limits *limits;
unsigned int options;
};
int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsigned int dboptions, const struct optstruct *opts);

@ -191,7 +191,7 @@ int command(client_conn_t *conn, int *virus)
{
int desc = conn->sd;
struct cl_engine *engine = conn->engine;
unsigned int options = conn->options;
struct cl_scan_options *options = conn->options;
const struct optstruct *opts = conn->opts;
enum scan_type type = TYPE_INIT;
int maxdirrec;
@ -369,7 +369,7 @@ int command(client_conn_t *conn, int *virus)
return 1;
}
thrmgr_setactivetask(NULL, "ALLMATCHSCAN");
scandata.options |= CL_SCAN_ALLMATCHES;
scandata.options->general |= CL_SCAN_GENERAL_ALLMATCHES;
type = TYPE_SCAN;
break;
default:

@ -82,7 +82,7 @@ typedef struct client_conn_tag {
char *filename;
int scanfd;
int sd;
unsigned int options;
struct cl_scan_options *options;
const struct optstruct *opts;
struct cl_engine *engine;
time_t engine_timestamp;

@ -289,7 +289,7 @@ static void clamscan_virus_found_cb(int fd, const char *virname, void *context)
return;
}
static void scanfile(const char *filename, struct cl_engine *engine, const struct optstruct *opts, unsigned int options)
static void scanfile(const char *filename, struct cl_engine *engine, const struct optstruct *opts, struct cl_scan_options *options)
{
int ret = 0, fd, included;
unsigned i;
@ -427,7 +427,7 @@ static void scanfile(const char *filename, struct cl_engine *engine, const struc
action(filename);
}
static void scandirs(const char *dirname, struct cl_engine *engine, const struct optstruct *opts, unsigned int options, unsigned int depth, dev_t dev)
static void scandirs(const char *dirname, struct cl_engine *engine, const struct optstruct *opts, struct cl_scan_options *options, unsigned int depth, dev_t dev)
{
DIR *dd;
struct dirent *dent;
@ -540,7 +540,7 @@ static void scandirs(const char *dirname, struct cl_engine *engine, const struct
}
}
static int scanstdin(const struct cl_engine *engine, const struct optstruct *opts, int options)
static int scanstdin(const struct cl_engine *engine, const struct optstruct *opts, struct cl_scan_options *options)
{
int ret;
unsigned int fsize = 0;
@ -615,7 +615,8 @@ static int scanstdin(const struct cl_engine *engine, const struct optstruct *opt
int scanmanager(const struct optstruct *opts)
{
int ret = 0, i;
unsigned int options = 0, dboptions = 0, dirlnk = 1, filelnk = 1;
struct cl_scan_options options;
unsigned int dboptions = 0, dirlnk = 1, filelnk = 1;
struct cl_engine *engine;
STATBUF sb;
char *file, cwd[1024], *pua_cats = NULL;
@ -625,6 +626,9 @@ int scanmanager(const struct optstruct *opts)
struct rlimit rlim;
#endif
/* Initalize scan options struct */
memset(&options, 0, sizeof(struct cl_scan_options));
dirlnk = optget(opts, "follow-dir-symlinks")->numarg;
if(dirlnk > 2) {
logg("!--follow-dir-symlinks: Invalid argument\n");
@ -794,7 +798,7 @@ int scanmanager(const struct optstruct *opts)
/* JSON check to prevent engine loading if specified without libjson-c */
#if HAVE_JSON
if (optget(opts, "gen-json")->enabled)
options |= CL_SCAN_FILE_PROPERTIES;
options.general |= CL_SCAN_GENERAL_COLLECT_METADATA;
#else
if (optget(opts, "gen-json")->enabled) {
logg("!Can't generate json (gen-json). libjson-c dev library was missing or misconfigured when ClamAV was built.\n");
@ -1010,95 +1014,95 @@ int scanmanager(const struct optstruct *opts)
/* set scan options */
if(optget(opts, "allmatch")->enabled) {
options |= CL_SCAN_ALLMATCHES;
options.general |= CL_SCAN_GENERAL_ALLMATCHES;
}
if(optget(opts,"phishing-ssl")->enabled)
options |= CL_SCAN_PHISHING_BLOCKSSL;
options.heuristic |= CL_SCAN_HEURISTIC_PHISHING_SSL_MISMATCH;
if(optget(opts,"phishing-cloak")->enabled)
options |= CL_SCAN_PHISHING_BLOCKCLOAK;
options.heuristic |= CL_SCAN_HEURISTIC_PHISHING_CLOAK;
if(optget(opts,"partition-intersection")->enabled)
options |= CL_SCAN_PARTITION_INTXN;
options.heuristic |= CL_SCAN_HEURISTIC_PARTITION_INTXN;
if(optget(opts,"heuristic-scan-precedence")->enabled)
options |= CL_SCAN_HEURISTIC_PRECEDENCE;
options.general |= CL_SCAN_GENERAL_HEURISTIC_PRECEDENCE;
if(optget(opts, "scan-archive")->enabled)
options |= CL_SCAN_ARCHIVE;
options.parse |= CL_SCAN_PARSE_ARCHIVE;
if(optget(opts, "detect-broken")->enabled)
options |= CL_SCAN_BLOCKBROKEN;
options.heuristic |= CL_SCAN_HEURISTIC_BROKEN;
if(optget(opts, "block-encrypted")->enabled)
options |= CL_SCAN_BLOCKENCRYPTED;
options.heuristic |= CL_SCAN_HEURISTIC_ENCRYPTED;
if(optget(opts, "block-macros")->enabled)
options |= CL_SCAN_BLOCKMACROS;
options.heuristic |= CL_SCAN_HEURISTIC_MACROS;
if(optget(opts, "scan-pe")->enabled)
options |= CL_SCAN_PE;
options.parse |= CL_SCAN_PARSE_PE;
if(optget(opts, "scan-elf")->enabled)
options |= CL_SCAN_ELF;
options.parse |= CL_SCAN_PARSE_ELF;
if(optget(opts, "scan-ole2")->enabled)
options |= CL_SCAN_OLE2;
options.parse |= CL_SCAN_PARSE_OLE2;
if(optget(opts, "scan-pdf")->enabled)
options |= CL_SCAN_PDF;
options.parse |= CL_SCAN_PARSE_PDF;
if(optget(opts, "scan-swf")->enabled)
options |= CL_SCAN_SWF;
options.parse |= CL_SCAN_PARSE_SWF;
if(optget(opts, "scan-html")->enabled && optget(opts, "normalize")->enabled)
options |= CL_SCAN_HTML;
options.parse |= CL_SCAN_PARSE_HTML;
if(optget(opts, "scan-mail")->enabled)
options |= CL_SCAN_MAIL;
options.parse |= CL_SCAN_PARSE_MAIL;
if(optget(opts, "scan-xmldocs")->enabled)
options |= CL_SCAN_XMLDOCS;
options.parse |= CL_SCAN_PARSE_XMLDOCS;
if(optget(opts, "scan-hwp3")->enabled)
options |= CL_SCAN_HWP3;
options.parse |= CL_SCAN_PARSE_HWP3;
if(optget(opts, "algorithmic-detection")->enabled)
options |= CL_SCAN_ALGORITHMIC;
options.general |= CL_SCAN_GENERAL_HEURISTICS;
if(optget(opts, "block-max")->enabled) {
options |= CL_SCAN_BLOCKMAX;
options.heuristic |= CL_SCAN_HEURISTIC_EXCEEDS_MAX;
}
#ifdef HAVE__INTERNAL__SHA_COLLECT
if(optget(opts, "dev-collect-hashes")->enabled)
options |= CL_SCAN_INTERNAL_COLLECT_SHA;
options.dev |= CL_SCAN_DEV_COLLECT_SHA;
#endif
if(optget(opts, "dev-performance")->enabled)
options |= CL_SCAN_PERFORMANCE_INFO;
options.general |= CL_SCAN_DEV_COLLECT_PERFORMANCE_INFO;
if(optget(opts, "detect-structured")->enabled) {
options |= CL_SCAN_STRUCTURED;
options.heuristic |= CL_SCAN_HEURISTIC_STRUCTURED;
if((opt = optget(opts, "structured-ssn-format"))->enabled) {
switch(opt->numarg) {
case 0:
options |= CL_SCAN_STRUCTURED_SSN_NORMAL;
options.heuristic |= CL_SCAN_HEURISTIC_STRUCTURED_SSN_NORMAL;
break;
case 1:
options |= CL_SCAN_STRUCTURED_SSN_STRIPPED;
options.heuristic |= CL_SCAN_HEURISTIC_STRUCTURED_SSN_STRIPPED;
break;
case 2:
options |= (CL_SCAN_STRUCTURED_SSN_NORMAL | CL_SCAN_STRUCTURED_SSN_STRIPPED);
options.heuristic |= (CL_SCAN_HEURISTIC_STRUCTURED_SSN_NORMAL | CL_SCAN_HEURISTIC_STRUCTURED_SSN_STRIPPED);
break;
default:
logg("!Invalid argument for --structured-ssn-format\n");
return 2;
}
} else {
options |= CL_SCAN_STRUCTURED_SSN_NORMAL;
options.heuristic |= CL_SCAN_HEURISTIC_STRUCTURED_SSN_NORMAL;
}
if((opt = optget(opts, "structured-ssn-count"))->active) {
@ -1118,7 +1122,7 @@ int scanmanager(const struct optstruct *opts)
}
}
} else {
options &= ~CL_SCAN_STRUCTURED;
options.heuristic &= ~CL_SCAN_HEURISTIC_STRUCTURED;
}
#ifdef C_LINUX
@ -1135,11 +1139,11 @@ int scanmanager(const struct optstruct *opts)
ret = 2;
} else {
CLAMSTAT(cwd, &sb);
scandirs(cwd, engine, opts, options, 1, sb.st_dev);
scandirs(cwd, engine, opts, &options, 1, sb.st_dev);
}
} else if(opts->filename && !optget(opts, "file-list")->enabled && !strcmp(opts->filename[0], "-")) { /* read data from stdin */
ret = scanstdin(engine, opts, options);
ret = scanstdin(engine, opts, &options);
} else {
if(opts->filename && optget(opts, "file-list")->enabled)
logg("^Only scanning files from --file-list (files passed at cmdline are ignored)\n");
@ -1163,18 +1167,18 @@ int scanmanager(const struct optstruct *opts)
logg("%s: Symbolic link\n", file);
} else if(CLAMSTAT(file, &sb) != -1) {
if(S_ISREG(sb.st_mode) && filelnk) {
scanfile(file, engine, opts, options);
scanfile(file, engine, opts, &options);
} else if(S_ISDIR(sb.st_mode) && dirlnk) {
scandirs(file, engine, opts, options, 1, sb.st_dev);
scandirs(file, engine, opts, &options, 1, sb.st_dev);
} else {
if(!printinfected)
logg("%s: Symbolic link\n", file);
}
}
} else if(S_ISREG(sb.st_mode)) {
scanfile(file, engine, opts, options);
scanfile(file, engine, opts, &options);
} else if(S_ISDIR(sb.st_mode)) {
scandirs(file, engine, opts, options, 1, sb.st_dev);
scandirs(file, engine, opts, &options, 1, sb.st_dev);
} else {
logg("^%s: Not supported file type\n", file);
ret = 2;

@ -382,7 +382,10 @@ uint32_t maxreclevel;
uint32_t maxfiles;
static struct cl_stat dbstat;
static int options = CL_SCAN_STDOPT;
static struct cl_scan_options options;
memset(&options, 0, sizeof(struct cl_scan_options));
options.parse |= ~0; /* enable all parsers */
#ifdef BOUNCE
static int bflag = 0; /*

@ -250,59 +250,104 @@ The first argument points to the database directory, the second one specifies wh
It’s possible to scan a file or descriptor using:
```c
int cl_scanfile(const char *filename, const char **virname,
unsigned long int *scanned, const struct cl_engine *engine,
unsigned int options);
int cl_scanfile(
const char *filename,
const char **virname,
unsigned long int *scanned,
const struct cl_engine *engine,
struct cl_scan_options *options);
int cl_scandesc(
int desc,
const char **virname,
unsigned long int *scanned,
const struct cl_engine *engine,
struct cl_scan_options *options);
```
Both functions will store a virus name under the pointer `virname`, the virus name is part of the engine structure and must not be released directly. If the third argument (`scanned`) is not NULL, the functions will increase its value with the size of scanned data (in `CL_COUNT_PRECISION` units). The last argument (`options`) requires a pointer to a data structure that specifies the scan options. The data structure should be `memset()` Each variable in the structure is a bit-flag field. The structure definition is:
int cl_scandesc(int desc, const char **virname, unsigned
long int *scanned, const struct cl_engine *engine,
unsigned int options);
```c
struct cl_scan_options {
uint32_t general;
uint32_t parse;
uint32_t alert;
uint32_t heuristic_alert;
uint32_t mail;
uint32_t dev;
};
```
Both functions will store a virus name under the pointer `virname`, the virus name is part of the engine structure and must not be released directly. If the third argument (`scanned`) is not NULL, the functions will increase its value with the size of scanned data (in `CL_COUNT_PRECISION` units). The last argument (`options`) specified the scan options and supports the following flags (which can be combined using bit operators):
Supported flags for each of the fields are as follows:
`general` - General scanning options.
- **CL_SCAN_GENERAL_ALLMATCHES**
Scan in all-match mode
- **CL_SCAN_GENERAL_COLLECT_METADATA**
Collect metadata (--gen-json)
- **CL_SCAN_GENERAL_HEURISTICS**
Option to enable heuristic alerts. Required for any of the heuristic alerting options to work.
`parse` - Options to enable/disable specific parsing capabilities. Generally you will want to enable all parsers. The easiest way to do this is to set the parse flags to ~0.
- **CL_SCAN_STDOPT**
This is an alias for a recommended set of scan options. You should use it to make your software ready for new features in the future versions of libclamav.
- **CL_SCAN_RAW**
Use it alone if you want to disable support for special files.
- **CL_SCAN_ARCHIVE**
- **CL_SCAN_PARSE_ARCHIVE**
This flag enables transparent scanning of various archive formats.
- **CL_SCAN_BLOCKENCRYPTED**
With this flag the library will mark encrypted archives as viruses (Encrypted.Zip, Encrypted.RAR).
- **CL_SCAN_MAIL**
Enable support for mail files.
- **CL_SCAN_OLE2**
Enables support for OLE2 containers (used by MS Office and .msi files).
- **CL_SCAN_PDF**
- **CL_SCAN_PARSE_ELF**
Enable support for ELF files.
- **CL_SCAN_PARSE_PDF**
Enables scanning within PDF files.
- **CL_SCAN_SWF**
- **CL_SCAN_PARSE_SWF**
Enables scanning within SWF files, notably compressed SWF.
- **CL_SCAN_PE**
- **CL_SCAN_PARSE_HWP**
Enables scanning of Hangul Word Processor (HWP) files.
- **CL_SCAN_PARSE_XMLDOCS**
Enables scanning of XML-formatted documents (e.g. Word, Excel, Powerpoint, HWP).
- **CL_SCAN_PARSE_MAIL**
Enable support for mail files.
- **CL_SCAN_PARSE_OLE2**
Enables support for OLE2 containers (used by MS Office and .msi files).
- **CL_SCAN_PARSE_HTML**
This flag enables HTML normalisation (including ScrEnc decryption).
- **CL_SCAN_PARSE_PE**
This flag enables deep scanning of Portable Executable files and allows libclamav to unpack executables compressed with run-time unpackers.
- **CL_SCAN_ELF**
Enable support for ELF files.
- **CL_SCAN_BLOCKBROKEN**
`heuristic` - Options to enable specific heuristic alerts
- **CL_SCAN_GENERAL_HEURISTIC_PRECEDENCE**
Allow heuristic match to take precedence. When enabled, if a heuristic scan (such as phishingScan) detects a possible virus/phish it will stop scan immediately. Recommended, saves CPU scan-time. When *disabled*, virus/phish detected by heuristic scans will be reported only at the end of a scan. If an archive contains both a heuristically detected virus/phishing, and a real malware, the real malware will be reported.
- **CL_SCAN_HEURISTIC_ENCRYPTED**
With this flag the library will mark encrypted archives as viruses (Encrypted.Zip, Encrypted.RAR).
- **CL_SCAN_HEURISTIC_BROKEN**
libclamav will try to detect broken executables and mark them as Broken.Executable.
- **CL_SCAN_HTML**
This flag enables HTML normalisation (including ScrEnc decryption).
- **CL_SCAN_ALGORITHMIC**
Enable algorithmic detection of viruses.
- **CL_SCAN_PHISHING_BLOCKSSL**
Phishing module: always block SSL mismatches in URLs.
- **CL_SCAN_PHISHING_BLOCKCLOAK**
- **CL_SCAN_HEURISTIC_EXCEEDS_MAX**
Alert when the scan of any file exceeds maximums such as max filesize, max scansize, max recursion level.
- **CL_SCAN_HEURISTIC_PHISHING_SSL_MISMATCH**
Heuristic for Phishing module: always block SSL mismatches in URLs.
- **CL_SCAN_HEURISTIC_PHISHING_CLOAK**
Phishing module: always block cloaked URLs.
- **CL_SCAN_STRUCTURED**
Enable the DLP module which scans for credit card and SSN numbers.
- **CL_SCAN_STRUCTURED_SSN_NORMAL**
Search for SSNs formatted as xx-yy-zzzz.
- **CL_SCAN_STRUCTURED_SSN_STRIPPED**
Search for SSNs formatted as xxyyzzzz.
- **CL_SCAN_PARTIAL_MESSAGE**
Scan RFC1341 messages split over many emails. You will need to periodically clean up `$TemporaryDirectory/clamav-partial` directory.
- **CL_SCAN_HEURISTIC_PRECEDENCE**
Allow heuristic match to take precedence. When enabled, if a heuristic scan (such as phishingScan) detects a possible virus/phish it will stop scan immediately. Recommended, saves CPU scan-time. When disabled, virus/phish detected by heuristic scans will be reported only at the end of a scan. If an archive contains both a heuristically detected virus/phishing, and a real malware, the real malware will be reported.
- **CL_SCAN_BLOCKMACROS**
- **CL_SCAN_HEURISTIC_MACROS**
OLE2 containers, which contain VBA macros will be marked infected (Heuristics.OLE2.ContainsMacros).
- **CL_SCAN_HEURISTIC_PARTITION_INTXN**
alert if partition table size doesn't make sense
- **CL_SCAN_HEURISTIC_STRUCTURED**
Enable the data loss prevention (DLP) module which scans for credit card and SSN numbers. i.e. alert when detecting personal information
- **CL_SCAN_HEURISTIC_STRUCTURED_SSN_NORMAL**
Search for [and alert when detecting] SSNs formatted as xx-yy-zzzz.
- **CL_SCAN_HEURISTIC_STRUCTURED_SSN_STRIPPED**
Search for [and alert when detecting] SSNs formatted as xxyyzzzz.
`mail` - Options to enable specific mail parsing features
- **CL_SCAN_MAIL_PARTIAL_MESSAGE**
Scan RFC1341 messages split over many emails. You will need to periodically clean up `$TemporaryDirectory/clamav-partial` directory.
`dev` - Options designed for use by ClamAV developers
- **CL_SCAN_DEV_COLLECT_SHA**
Enables hash output in sha-collect builds - for internal use only
- **CL_SCAN_DEV_COLLECT_PERFORMANCE_INFO**
Collect performance timings
All functions return `CL_CLEAN` when the file seems clean, `CL_VIRUS` when a virus is detected and another value on failure.
@ -311,7 +356,7 @@ All functions return `CL_CLEAN` when the file seems clean, `CL_VIRUS` when a vir
const char *virname;
if((ret = cl_scanfile("/tmp/test.exe", &virname, NULL, engine,
CL_SCAN_STDOPT)) == CL_VIRUS) {
&options)) == CL_VIRUS) {
printf("Virus detected: %s\n", virname);
} else {
printf("No virus detected.\n");

@ -591,7 +591,7 @@ Example
# When BlockMax is set, files exceeding the MaxFileSize, MaxScanSize, or
# MaxRecursion limit will be flagged with the virus
# "Heuristic.Limits.Exceeded".
# "Heuristics.Limits.Exceeded".
# Default: no
#BlockMax yes

@ -45,6 +45,7 @@ int main(int argc, char **argv)
long double mb;
const char *virname;
struct cl_engine *engine;
struct cl_scan_options options;
if(argc != 2) {
printf("Usage: %s file\n", argv[0]);
@ -85,7 +86,11 @@ int main(int argc, char **argv)
}
/* scan file descriptor */
if((ret = cl_scandesc(fd, &virname, &size, engine, CL_SCAN_STDOPT)) == CL_VIRUS) {
memset(&options, 0, sizeof(struct cl_scan_options));
options.parse |= ~0; /* enable all parsers */
options.general |= CL_SCAN_GENERAL_HEURISTICS; /* enable heuristic alert options */
if((ret = cl_scandesc(fd, &virname, &size, engine, &options)) == CL_VIRUS) {
printf("Virus detected: %s\n", virname);
} else {
if(ret == CL_CLEAN) {

@ -106,7 +106,7 @@ int cli_7unz (cli_ctx *ctx, size_t offset) {
SzArEx_Init(&db);
res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
if(res == SZ_ERROR_ENCRYPTED && DETECT_ENCRYPTED) {
if(res == SZ_ERROR_ENCRYPTED && SCAN_HEURISTIC_ENCRYPTED) {
cli_dbgmsg("cli_7unz: Encrypted header found in archive.\n");
found = cli_append_virus(ctx, "Heuristics.Encrypted.7Zip");
} else if(res == SZ_OK) {
@ -158,12 +158,12 @@ int cli_7unz (cli_ctx *ctx, size_t offset) {
res = SzArEx_Extract(&db, &lookStream.s, i, &blockIndex, &outBuffer, &outBufferSize, &offset, &outSizeProcessed, &allocImp, &allocTempImp);
if(res == SZ_ERROR_ENCRYPTED) {
encrypted = 1;
if(DETECT_ENCRYPTED) {
if(SCAN_HEURISTIC_ENCRYPTED) {
cli_dbgmsg("cli_7unz: Encrypted files found in archive.\n");
found = cli_append_virus(ctx, "Heuristics.Encrypted.7Zip");
if (found != CL_CLEAN) {
if (found == CL_VIRUS) {
if (SCAN_ALL)
if (SCAN_ALLMATCHES)
viruses_found++;
} else
break;
@ -173,7 +173,7 @@ int cli_7unz (cli_ctx *ctx, size_t offset) {
if(cli_matchmeta(ctx, name, 0, f->Size, encrypted, i, f->CrcDefined ? f->Crc : 0, NULL)) {
found = CL_VIRUS;
viruses_found++;
if (!SCAN_ALL)
if (!SCAN_ALLMATCHES)
break;
}
if (res != SZ_OK)
@ -194,7 +194,7 @@ int cli_7unz (cli_ctx *ctx, size_t offset) {
free(name);
if(found != CL_CLEAN)
if (!(SCAN_ALL && found == CL_VIRUS))
if (!(SCAN_ALLMATCHES && found == CL_VIRUS))
break;
}
}
@ -217,7 +217,7 @@ int cli_7unz (cli_ctx *ctx, size_t offset) {
else
cli_dbgmsg("cli_7unz: error %d\n", res);
if (SCAN_ALL && viruses_found)
if (SCAN_ALLMATCHES && viruses_found)
return CL_VIRUS;
return found;
}

@ -133,10 +133,10 @@ int cli_scanapm(cli_ctx *ctx)
}
/* check that the partition table fits in the space specified - HEURISTICS */
if ((ctx->options & CL_SCAN_PARTITION_INTXN) && (ctx->dconf->other & OTHER_CONF_PRTNINTXN)) {
if (SCAN_HEURISTIC_PARTITION_INTXN && (ctx->dconf->other & OTHER_CONF_PRTNINTXN)) {
ret = apm_prtn_intxn(ctx, &aptable, sectorsize, old_school);
if (ret != CL_CLEAN) {
if ((ctx->options & CL_SCAN_ALLMATCHES) && (ret == CL_VIRUS))
if (SCAN_ALLMATCHES && (ret == CL_VIRUS))
detection = CL_VIRUS;
else
return ret;
@ -226,7 +226,7 @@ int cli_scanapm(cli_ctx *ctx)
/* send the partition to cli_map_scan */
ret = cli_map_scan(*ctx->fmap, partoff, partsize, ctx, CL_TYPE_PART_ANY);
if (ret != CL_CLEAN) {
if ((ctx->options & CL_SCAN_ALLMATCHES) && (ret == CL_VIRUS))
if (SCAN_ALLMATCHES && (ret == CL_VIRUS))
detection = CL_VIRUS;
else
return ret;
@ -296,7 +296,7 @@ static int apm_prtn_intxn(cli_ctx *ctx, struct apm_partition_info *aptable, size
ret = cli_append_virus(ctx, PRTN_INTXN_DETECTION);
if (ret == CL_VIRUS)
virus_found = 1;
if (SCAN_ALL || ret == CL_CLEAN)
if (SCAN_ALLMATCHES || ret == CL_CLEAN)
tmp = 0;
else
goto leave;

@ -394,7 +394,7 @@ static int ea05(cli_ctx *ctx, const uint8_t *base, char *tmpd) {
return CL_ESEEK;
}
if(cli_magic_scandesc(i, ctx) == CL_VIRUS) {
if (!SCAN_ALL) {
if (!SCAN_ALLMATCHES) {
close(i);
if(!ctx->engine->keeptmp)
if(cli_unlink(tempfile)) return CL_EUNLINK;
@ -921,7 +921,7 @@ static int ea06(cli_ctx *ctx, const uint8_t *base, char *tmpd) {
return CL_ESEEK;
}
if(cli_magic_scandesc(i, ctx) == CL_VIRUS) {
if (!SCAN_ALL) {
if (!SCAN_ALLMATCHES) {
close(i);
if(!ctx->engine->keeptmp)
if (cli_unlink(tempfile)) return CL_EUNLINK;

@ -618,8 +618,9 @@ int
fileblobScan(const fileblob *fb)
{
int rc;
cli_ctx *ctx = fb->ctx;
STATBUF sb;
int virus_found = 0;
int virus_found = 0;
if(fb->isInfected)
return CL_VIRUS;
@ -638,7 +639,7 @@ fileblobScan(const fileblob *fb)
lseek(fb->fd, 0, SEEK_SET);
FSTAT(fb->fd, &sb);
if(cli_matchmeta(fb->ctx, fb->b.name, sb.st_size, sb.st_size, 0, 0, 0, NULL) == CL_VIRUS) {
if (!(fb->ctx->options & CL_SCAN_ALLMATCHES))
if (!SCAN_ALLMATCHES)
return CL_VIRUS;
virus_found = 1;
}

@ -1834,7 +1834,7 @@ int cli_bytecode_run(const struct cli_all_bc *bcs, const struct cli_bc *bc, stru
/* need to be called here to catch any extracted but not yet scanned files
*/
if (ctx->outfd && (ret != CL_VIRUS || cctx->options & CL_SCAN_ALLMATCHES))
if (ctx->outfd && (ret != CL_VIRUS || cctx->options->general & CL_SCAN_GENERAL_ALLMATCHES))
cli_bcapi_extract_new(ctx, -1);
}
if (bc->state == bc_jit || test_mode) {
@ -1854,7 +1854,7 @@ int cli_bytecode_run(const struct cli_all_bc *bcs, const struct cli_bc *bc, stru
/* need to be called here to catch any extracted but not yet scanned files
*/
if (ctx->outfd && (ret != CL_VIRUS || cctx->options & CL_SCAN_ALLMATCHES))
if (ctx->outfd && (ret != CL_VIRUS || cctx->options->general & CL_SCAN_GENERAL_ALLMATCHES))
cli_bcapi_extract_new(ctx, -1);
}
cli_event_time_stop(g_sigevents, bc->sigtime_id);
@ -2866,7 +2866,7 @@ int cli_bytecode_runhook(cli_ctx *cctx, const struct cl_engine *engine, struct c
if (ctx->virname) {
cli_dbgmsg("Bytecode runhook found virus: %s\n", ctx->virname);
cli_append_virus(cctx, ctx->virname);
if (!(cctx->options & CL_SCAN_ALLMATCHES)) {
if (!(cctx->options->general & CL_SCAN_GENERAL_ALLMATCHES)) {
cli_bytecode_context_clear(ctx);
return CL_VIRUS;
}
@ -2906,7 +2906,7 @@ int cli_bytecode_runhook(cli_ctx *cctx, const struct cl_engine *engine, struct c
if (ret != CL_CLEAN) {
if (ret == CL_VIRUS) {
cli_dbgmsg("Scanning unpacked file by bytecode %u found a virus\n", bc->id);
if (cctx->options & CL_SCAN_ALLMATCHES) {
if (cctx->options->general & CL_SCAN_GENERAL_ALLMATCHES) {
cli_bytecode_context_reset(ctx);
continue;
}

@ -1275,7 +1275,198 @@ uint32_t cli_bcapi_engine_dconf_level(struct cli_bc_ctx *ctx)
uint32_t cli_bcapi_engine_scan_options(struct cli_bc_ctx *ctx)
{
cli_ctx *cctx = (cli_ctx*)ctx->ctx;
return cctx->options;
uint32_t options = CL_SCAN_RAW;
if (cctx->options->general & CL_SCAN_GENERAL_ALLMATCHES)
options |= CL_SCAN_ALLMATCHES;
if (cctx->options->general & CL_SCAN_GENERAL_HEURISTICS)
options |= CL_SCAN_ALGORITHMIC;
if (cctx->options->general & CL_SCAN_GENERAL_COLLECT_METADATA)
options |= CL_SCAN_FILE_PROPERTIES;
if (cctx->options->general & CL_SCAN_GENERAL_HEURISTIC_PRECEDENCE)
options |= CL_SCAN_HEURISTIC_PRECEDENCE;
if (cctx->options->parse & CL_SCAN_PARSE_ARCHIVE)
options |= CL_SCAN_ARCHIVE;
if (cctx->options->parse & CL_SCAN_PARSE_ELF)
options |= CL_SCAN_ELF;
if (cctx->options->parse & CL_SCAN_PARSE_PDF)
options |= CL_SCAN_PDF;
if (cctx->options->parse & CL_SCAN_PARSE_SWF)
options |= CL_SCAN_SWF;
if (cctx->options->parse & CL_SCAN_PARSE_HWP3)
options |= CL_SCAN_HWP3;
if (cctx->options->parse & CL_SCAN_PARSE_XMLDOCS)
options |= CL_SCAN_XMLDOCS;
if (cctx->options->parse & CL_SCAN_PARSE_MAIL)
options |= CL_SCAN_MAIL;
if (cctx->options->parse & CL_SCAN_PARSE_OLE2)
options |= CL_SCAN_OLE2;
if (cctx->options->parse & CL_SCAN_PARSE_HTML)
options |= CL_SCAN_HTML;
if (cctx->options->parse & CL_SCAN_PARSE_PE)
options |= CL_SCAN_PE;
// if (cctx->options->parse & CL_SCAN_MAIL_URL)
// options |= CL_SCAN_MAILURL; /* deprecated circa 2009 */
if (cctx->options->heuristic & CL_SCAN_HEURISTIC_BROKEN)
options |= CL_SCAN_BLOCKBROKEN;
if (cctx->options->heuristic & CL_SCAN_HEURISTIC_EXCEEDS_MAX)
options |= CL_SCAN_BLOCKMAX;
if (cctx->options->heuristic & CL_SCAN_HEURISTIC_PHISHING_SSL_MISMATCH)
options |= CL_SCAN_PHISHING_BLOCKSSL;
if (cctx->options->heuristic & CL_SCAN_HEURISTIC_PHISHING_CLOAK)
options |= CL_SCAN_PHISHING_BLOCKCLOAK;
if (cctx->options->heuristic & CL_SCAN_HEURISTIC_MACROS)
options |= CL_SCAN_BLOCKMACROS;
if (cctx->options->heuristic & CL_SCAN_HEURISTIC_ENCRYPTED)
options |= CL_SCAN_BLOCKENCRYPTED;
if (cctx->options->heuristic & CL_SCAN_HEURISTIC_PARTITION_INTXN)
options |= CL_SCAN_PARTITION_INTXN;
if (cctx->options->heuristic & CL_SCAN_HEURISTIC_STRUCTURED)
options |= CL_SCAN_STRUCTURED;
if (cctx->options->heuristic & CL_SCAN_HEURISTIC_STRUCTURED_SSN_NORMAL)
options |= CL_SCAN_STRUCTURED_SSN_NORMAL;
if (cctx->options->heuristic & CL_SCAN_HEURISTIC_STRUCTURED_SSN_STRIPPED)
options |= CL_SCAN_STRUCTURED_SSN_STRIPPED;
if (cctx->options->mail & CL_SCAN_MAIL_PARTIAL_MESSAGE)
options |= CL_SCAN_PARTIAL_MESSAGE;
if (cctx->options->dev & CL_SCAN_DEV_COLLECT_SHA)
options |= CL_SCAN_INTERNAL_COLLECT_SHA;
if (cctx->options->dev & CL_SCAN_DEV_COLLECT_PERFORMANCE_INFO)
options |= CL_SCAN_PERFORMANCE_INFO;
return options;
}
uint32_t cli_bcapi_engine_scan_options_ex(struct cli_bc_ctx *ctx, const uint8_t *option_name, uint32_t name_len)
{
uint32_t i = 0;
char *option_name_l = NULL;
if (ctx == NULL || option_name == NULL || name_len == 0) {
cli_warnmsg("engine_scan_options_ex: Invalid arguments!");
return 0;
}
cli_ctx *cctx = (cli_ctx*)ctx->ctx;
if (cctx == NULL || cctx->options == NULL) {
cli_warnmsg("engine_scan_options_ex: Invalid arguments!");
return 0;
}
option_name_l = malloc(name_len + 1);
for (i = 0; i < name_len; i++) {
option_name_l[0] = tolower(option_name[i]);
}
option_name_l[name_len] = '\0';
if (strncmp(option_name_l, "general", MIN(name_len, sizeof("general")))) {
if (cli_memstr(option_name_l, name_len, "allmatch", sizeof("allmatch"))) {
return (cctx->options->general & CL_SCAN_GENERAL_ALLMATCHES) ? 1 : 0;
}
if (cli_memstr(option_name_l, name_len, "collect metadata", sizeof("collect metadata"))) {
return (cctx->options->general & CL_SCAN_GENERAL_COLLECT_METADATA) ? 1 : 0;
}
if (cli_memstr(option_name_l, name_len, "heuristics", sizeof("heuristics"))) {
return (cctx->options->general & CL_SCAN_GENERAL_HEURISTICS) ? 1 : 0;
}
if (cli_memstr(option_name_l, name_len, "precedence", sizeof("precedence"))) {
return (cctx->options->general & CL_SCAN_GENERAL_HEURISTIC_PRECEDENCE) ? 1 : 0;
}
/* else unknown option */
return 0;
}
else if (strncmp(option_name_l, "parse", MIN(name_len, sizeof("parse")))) {
if (cli_memstr(option_name_l, name_len, "archive", sizeof("archive"))) {
return (cctx->options->parse & CL_SCAN_PARSE_ARCHIVE) ? 1 : 0;
}
if (cli_memstr(option_name_l, name_len, "elf", sizeof("elf"))) {
return (cctx->options->parse & CL_SCAN_PARSE_ELF) ? 1 : 0;
}
if (cli_memstr(option_name_l, name_len, "pdf", sizeof("pdf"))) {
return (cctx->options->parse & CL_SCAN_PARSE_PDF) ? 1 : 0;
}
if (cli_memstr(option_name_l, name_len, "swf", sizeof("swf"))) {
return (cctx->options->parse & CL_SCAN_PARSE_SWF) ? 1 : 0;
}
if (cli_memstr(option_name_l, name_len, "hwp3", sizeof("hwp3"))) {
return (cctx->options->parse & CL_SCAN_PARSE_HWP3) ? 1 : 0;
}
if (cli_memstr(option_name_l, name_len, "xmldocs", sizeof("xmldocs"))) {
return (cctx->options->parse & CL_SCAN_PARSE_XMLDOCS) ? 1 : 0;
}
if (cli_memstr(option_name_l, name_len, "mail", sizeof("mail"))) {
return (cctx->options->parse & CL_SCAN_PARSE_MAIL) ? 1 : 0;
}
if (cli_memstr(option_name_l, name_len, "ole2", sizeof("ole2"))) {
return (cctx->options->parse & CL_SCAN_PARSE_OLE2) ? 1 : 0;
}
if (cli_memstr(option_name_l, name_len, "html", sizeof("html"))) {
return (cctx->options->parse & CL_SCAN_PARSE_HTML) ? 1 : 0;
}
if (cli_memstr(option_name_l, name_len, "pe", sizeof("pe"))) {
return (cctx->options->parse & CL_SCAN_PARSE_PE) ? 1 : 0;
}
/* else unknown option */
return 0;
}
else if (strncmp(option_name_l, "heuristic", MIN(name_len, sizeof("heuristic")))) {
if (cli_memstr(option_name_l, name_len, "broken", sizeof("broken"))) {
return (cctx->options->heuristic & CL_SCAN_HEURISTIC_BROKEN) ? 1 : 0;
}
if (cli_memstr(option_name_l, name_len, "exceeds max", sizeof("exceeds max"))) {
return (cctx->options->heuristic & CL_SCAN_HEURISTIC_EXCEEDS_MAX) ? 1 : 0;
}
if (cli_memstr(option_name_l, name_len, "phishing ssl mismatch", sizeof("phishing ssl mismatch"))) {
return (cctx->options->heuristic & CL_SCAN_HEURISTIC_PHISHING_SSL_MISMATCH) ? 1 : 0;
}
if (cli_memstr(option_name_l, name_len, "phishing cloak", sizeof("phishing cloak"))) {
return (cctx->options->heuristic & CL_SCAN_HEURISTIC_PHISHING_CLOAK) ? 1 : 0;
}
if (cli_memstr(option_name_l, name_len, "macros", sizeof("macros"))) {
return (cctx->options->heuristic & CL_SCAN_HEURISTIC_MACROS) ? 1 : 0;
}
if (cli_memstr(option_name_l, name_len, "encrypted", sizeof("encrypted"))) {
return (cctx->options->heuristic & CL_SCAN_HEURISTIC_ENCRYPTED) ? 1 : 0;
}
if (cli_memstr(option_name_l, name_len, "partition intxn", sizeof("partition intxn"))) {
return (cctx->options->heuristic & CL_SCAN_HEURISTIC_PARTITION_INTXN) ? 1 : 0;
}
if (cli_memstr(option_name_l, name_len, "structured", sizeof("structured"))) {
return (cctx->options->heuristic & CL_SCAN_HEURISTIC_STRUCTURED) ? 1 : 0;
}
if (cli_memstr(option_name_l, name_len, "structured ssn normal", sizeof("structured ssn normal"))) {
return (cctx->options->heuristic & CL_SCAN_HEURISTIC_STRUCTURED_SSN_NORMAL) ? 1 : 0;
}
if (cli_memstr(option_name_l, name_len, "structured ssn stripped", sizeof("structured ssn stripped"))) {
return (cctx->options->heuristic & CL_SCAN_HEURISTIC_STRUCTURED_SSN_STRIPPED) ? 1 : 0;
}
/* else unknown option */
return 0;
}
else if (strncmp(option_name_l, "mail", MIN(name_len, sizeof("mail")))) {
if (cli_memstr(option_name_l, name_len, "partial message", sizeof("partial message"))) {
return (cctx->options->mail & CL_SCAN_MAIL_PARTIAL_MESSAGE) ? 1 : 0;
}
/* else unknown option */
return 0;
}
else if (strncmp(option_name_l, "dev", MIN(name_len, sizeof("dev")))) {
if (cli_memstr(option_name_l, name_len, "collect sha", sizeof("collect sha"))) {
return (cctx->options->dev & CL_SCAN_DEV_COLLECT_SHA) ? 1 : 0;
}
if (cli_memstr(option_name_l, name_len, "collect performance info", sizeof("collect performance info"))) {
return (cctx->options->dev & CL_SCAN_DEV_COLLECT_PERFORMANCE_INFO) ? 1 : 0;
}
/* else unknown option */
return 0;
} else {
/* else unknown option */
return 0;
}
}
uint32_t cli_bcapi_engine_db_options(struct cli_bc_ctx *ctx)

@ -1,5 +1,5 @@
/*
* Copyright (C) 2015 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
* Copyright (C) 2014-2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
* Copyright (C) 2009-2013 Sourcefire, Inc.
* All rights reserved.
* Authors: Török Edvin, Kevin Lin
@ -203,6 +203,45 @@ enum bc_json_type {
JSON_TYPE_STRING /* */
};
/**
\group_engine
* Scan option flag values for engine_scan_options(). *DEPRECATED*
*/
#define CL_SCAN_RAW 0x0
#define CL_SCAN_ARCHIVE 0x1
#define CL_SCAN_MAIL 0x2
#define CL_SCAN_OLE2 0x4
#define CL_SCAN_BLOCKENCRYPTED 0x8
#define CL_SCAN_HTML 0x10
#define CL_SCAN_PE 0x20
#define CL_SCAN_BLOCKBROKEN 0x40
#define CL_SCAN_MAILURL 0x80 /* deprecated circa 2009 */
#define CL_SCAN_BLOCKMAX 0x100
#define CL_SCAN_ALGORITHMIC 0x200
//#define UNUSED 0x400
#define CL_SCAN_PHISHING_BLOCKSSL 0x800 /* ssl mismatches, not ssl by itself*/
#define CL_SCAN_PHISHING_BLOCKCLOAK 0x1000
#define CL_SCAN_ELF 0x2000
#define CL_SCAN_PDF 0x4000
#define CL_SCAN_STRUCTURED 0x8000
#define CL_SCAN_STRUCTURED_SSN_NORMAL 0x10000
#define CL_SCAN_STRUCTURED_SSN_STRIPPED 0x20000
#define CL_SCAN_PARTIAL_MESSAGE 0x40000
#define CL_SCAN_HEURISTIC_PRECEDENCE 0x80000
#define CL_SCAN_BLOCKMACROS 0x100000
#define CL_SCAN_ALLMATCHES 0x200000
#define CL_SCAN_SWF 0x400000
#define CL_SCAN_PARTITION_INTXN 0x800000
#define CL_SCAN_XMLDOCS 0x1000000
#define CL_SCAN_HWP3 0x2000000
//#define UNUSED 0x4000000
//#define UNUSED 0x8000000
#define CL_SCAN_FILE_PROPERTIES 0x10000000
//#define UNUSED 0x20000000
#define CL_SCAN_PERFORMANCE_INFO 0x40000000 /* Collect performance timings */
#define CL_SCAN_INTERNAL_COLLECT_SHA 0x80000000 /* Enables hash output in sha-collect builds - for internal use only */
#ifdef __CLAMBC__
/* --------------- BEGIN GLOBALS -------------------------------------------- */
@ -885,7 +924,7 @@ uint32_t engine_dconf_level(void);
/**
\group_engine
* Returns the current engine's scan options.
* Returns the current engine's scan options. **DEPRECATED**
* @return CL_SCAN* flags
*/
uint32_t engine_scan_options(void);
@ -1222,5 +1261,49 @@ int32_t json_get_int(int32_t objid);
//double json_get_double(int32_t objid);
/* ----------------- END 0.98.4 APIs ---------------------------------- */
/* ----------------- BEGIN 0.100.0 APIs ------------------------------- */
/* ----------------- Scan Options APIs -------------------------------- */
/**
\group_engine
* Check if any given scan option is enabled.
* Returns non-zero if the following named options are set:
*
* "general allmatch" - all-match mode is enabled
* "general collect metadata" - --gen-json is enabled
* "general heuristics" - --gen-json is enabled
*
* "parse archive" - archive parsing is enabled
* "parse pdf" - pdf parsing is enabled
* "parse swf" - swf parsing is enabled
* "parse hwp3" - hwp3 parsing is enabled
* "parse xmldocs" - xmldocs parsing is enabled
* "parse mail" - mail parsing is enabled
* "parse ole2" - ole2 parsing is enabled
* "parse html" - html parsing is enabled
* "parse pe" - pe parsing is enabled
*
* "heuristic precedence" - heuristic signatures are set to take precedence
* "heuristic broken" - broken pe heuristic is enabled
* "heuristic exceeds max" - heuristic for when max settings are exceeded is enabled
* "heuristic phishing ssl mismatch" - phishing ssl mismatch heuristic is enabled
* "heuristic phishing cloak" - phishing cloak heuristic is enabled
* "heuristic macros" - macros heuristic is enabled
* "heuristic encrypted" - encrypted heuristic is enabled
* "heuristic partition intxn" - macpartition intxnros heuristic is enabled
* "heuristic structured" - structured heuristic is enabled
* "heuristic structured ssn normal" - structured ssn normal heuristic is enabled
* "heuristic structured ssn stripped" - structured ssn stripped heuristic is enabled
*
* "mail partial message" - parsing of partial mail messages is enabled
*
* "dev collect sha" - --dev-collect-hashes is enabled
* "dev collect performance info" - --dev-performance is enabled
*
* @param[in] scan_options enum value for desired scan option category.
* @return CL_SCAN_<OPTION>_* flags
*/
uint32_t engine_scan_options_ex(const uint8_t *option_name, uint32_t name_len);
/* ----------------- END 0.101 APIs ---------------------------------- */
#endif
#endif

@ -2,7 +2,7 @@
* ClamAV bytecode internal API
* This is an automatically generated file!
*
* Copyright (C) 2015 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
* Copyright (C) 2014-2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
* Copyright (C) 2009-2013 Sourcefire, Inc.
*
* Redistribution and use in source and binary forms, with or without
@ -133,6 +133,7 @@ int32_t cli_bcapi_json_get_string_length(struct cli_bc_ctx *ctx , int32_t);
int32_t cli_bcapi_json_get_string(struct cli_bc_ctx *ctx , int8_t*, int32_t, int32_t);
int32_t cli_bcapi_json_get_boolean(struct cli_bc_ctx *ctx , int32_t);
int32_t cli_bcapi_json_get_int(struct cli_bc_ctx *ctx , int32_t);
uint32_t cli_bcapi_engine_scan_options_ex(struct cli_bc_ctx *ctx , const uint8_t*, uint32_t);
const struct cli_apiglobal cli_globals[] = {
/* Bytecode globals BEGIN */
@ -157,18 +158,18 @@ static uint16_t cli_tmp4[]={16, 8, 8, 32, 32, 32, 32, 32, 32, 32, 32, 32, 16, 16
static uint16_t cli_tmp5[]={32, 16, 16, 32, 32, 32, 16, 16};
static uint16_t cli_tmp6[]={32};
static uint16_t cli_tmp7[]={32};
static uint16_t cli_tmp8[]={32, 32};
static uint16_t cli_tmp9[]={32, 65, 32, 32};
static uint16_t cli_tmp10[]={32, 32, 32};
static uint16_t cli_tmp11[]={32};
static uint16_t cli_tmp12[]={32, 65, 32, 65, 32};
static uint16_t cli_tmp13[]={65, 32, 32};
static uint16_t cli_tmp14[]={32, 32, 32, 32};
static uint16_t cli_tmp15[]={32, 85, 32};
static uint16_t cli_tmp16[]={86};
static uint16_t cli_tmp17[]={32, 32, 32, 32, 32, 32, 32, 87, 87, 87, 87, 87, 87, 87, 8, 8, 8, 8, 8, 8, 8, 8, 8};
static uint16_t cli_tmp18[]={8};
static uint16_t cli_tmp19[]={32, 65, 32};
static uint16_t cli_tmp8[]={32, 65, 32};
static uint16_t cli_tmp9[]={32, 32};
static uint16_t cli_tmp10[]={32, 65, 32, 32};
static uint16_t cli_tmp11[]={32, 32, 32};
static uint16_t cli_tmp12[]={32};
static uint16_t cli_tmp13[]={32, 65, 32, 65, 32};
static uint16_t cli_tmp14[]={65, 32, 32};
static uint16_t cli_tmp15[]={32, 32, 32, 32};
static uint16_t cli_tmp16[]={32, 86, 32};
static uint16_t cli_tmp17[]={87};
static uint16_t cli_tmp18[]={32, 32, 32, 32, 32, 32, 32, 88, 88, 88, 88, 88, 88, 88, 8, 8, 8, 8, 8, 8, 8, 8, 8};
static uint16_t cli_tmp19[]={8};
static uint16_t cli_tmp20[]={32, 65, 32, 32, 32, 32};
static uint16_t cli_tmp21[]={32, 91, 32};
static uint16_t cli_tmp22[]={92};
@ -190,18 +191,18 @@ const struct cli_bc_type cli_apicall_types[]={
{DStructType, cli_tmp5, 8, 0, 0},
{DArrayType, cli_tmp6, 1, 0, 0},
{DArrayType, cli_tmp7, 64, 0, 0},
{DFunctionType, cli_tmp8, 2, 0, 0},
{DFunctionType, cli_tmp9, 4, 0, 0},
{DFunctionType, cli_tmp10, 3, 0, 0},
{DFunctionType, cli_tmp11, 1, 0, 0},
{DFunctionType, cli_tmp12, 5, 0, 0},
{DFunctionType, cli_tmp13, 3, 0, 0},
{DFunctionType, cli_tmp14, 4, 0, 0},
{DFunctionType, cli_tmp15, 3, 0, 0},
{DPointerType, cli_tmp16, 1, 0, 0},
{DStructType, cli_tmp17, 23, 0, 0},
{DArrayType, cli_tmp18, 65, 0, 0},
{DFunctionType, cli_tmp19, 3, 0, 0},
{DFunctionType, cli_tmp8, 3, 0, 0},
{DFunctionType, cli_tmp9, 2, 0, 0},
{DFunctionType, cli_tmp10, 4, 0, 0},
{DFunctionType, cli_tmp11, 3, 0, 0},
{DFunctionType, cli_tmp12, 1, 0, 0},
{DFunctionType, cli_tmp13, 5, 0, 0},
{DFunctionType, cli_tmp14, 3, 0, 0},
{DFunctionType, cli_tmp15, 4, 0, 0},
{DFunctionType, cli_tmp16, 3, 0, 0},
{DPointerType, cli_tmp17, 1, 0, 0},
{DStructType, cli_tmp18, 23, 0, 0},
{DArrayType, cli_tmp19, 65, 0, 0},
{DFunctionType, cli_tmp20, 6, 0, 0},
{DFunctionType, cli_tmp21, 3, 0, 0},
{DPointerType, cli_tmp22, 1, 0, 0},
@ -214,110 +215,111 @@ const struct cli_bc_type cli_apicall_types[]={
{DArrayType, cli_tmp29, 3, 0, 0},
{DArrayType, cli_tmp30, 10, 0, 0}
};
const unsigned cli_apicall_maxtypes=sizeof(cli_apicall_types)/sizeof(cli_apicall_types[0]);
const unsigned cli_apicall_maxtypes=sizeof(cli_apicall_types)/sizeof(cli_apicall_types[0]);
const struct cli_apicall cli_apicalls[]={
/* Bytecode APIcalls BEGIN */
{"test1", 10, 0, 0},
{"read", 19, 0, 1},
{"write", 19, 1, 1},
{"seek", 10, 1, 0},
{"setvirusname", 19, 2, 1},
{"debug_print_str", 19, 3, 1},
{"debug_print_uint", 8, 0, 2},
{"test1", 11, 0, 0},
{"read", 8, 0, 1},
{"write", 8, 1, 1},
{"seek", 11, 1, 0},
{"setvirusname", 8, 2, 1},
{"debug_print_str", 8, 3, 1},
{"debug_print_uint", 9, 0, 2},
{"disasm_x86", 25, 4, 1},
{"trace_directory", 19, 5, 1},
{"trace_scope", 19, 6, 1},
{"trace_source", 19, 7, 1},
{"trace_op", 19, 8, 1},
{"trace_value", 19, 9, 1},
{"trace_ptr", 19, 10, 1},
{"pe_rawaddr", 8, 1, 2},
{"file_find", 19, 11, 1},
{"file_byteat", 8, 2, 2},
{"trace_directory", 8, 5, 1},
{"trace_scope", 8, 6, 1},
{"trace_source", 8, 7, 1},
{"trace_op", 8, 8, 1},
{"trace_value", 8, 9, 1},
{"trace_ptr", 8, 10, 1},
{"pe_rawaddr", 9, 1, 2},
{"file_find", 8, 11, 1},
{"file_byteat", 9, 2, 2},
{"malloc", 24, 0, 3},
{"test2", 8, 3, 2},
{"test2", 9, 3, 2},
{"get_pe_section", 21, 12, 1},
{"fill_buffer", 20, 0, 4},
{"extract_new", 8, 4, 2},
{"read_number", 8, 5, 2},
{"hashset_new", 11, 0, 5},
{"hashset_add", 10, 2, 0},
{"hashset_remove", 10, 3, 0},
{"hashset_contains", 10, 4, 0},
{"hashset_done", 8, 6, 2},
{"hashset_empty", 8, 7, 2},
{"buffer_pipe_new", 8, 8, 2},
{"buffer_pipe_new_fromfile", 8, 9, 2},
{"buffer_pipe_read_avail", 8, 10, 2},
{"buffer_pipe_read_get", 13, 0, 6},
{"buffer_pipe_read_stopped", 10, 5, 0},
{"buffer_pipe_write_avail", 8, 11, 2},
{"buffer_pipe_write_get", 13, 1, 6},
{"buffer_pipe_write_stopped", 10, 6, 0},
{"buffer_pipe_done", 8, 12, 2},
{"inflate_init", 14, 0, 7},
{"inflate_process", 8, 13, 2},
{"inflate_done", 8, 14, 2},
{"bytecode_rt_error", 8, 15, 2},
{"jsnorm_init", 8, 16, 2},
{"jsnorm_process", 8, 17, 2},
{"jsnorm_done", 8, 18, 2},
{"ilog2", 10, 7, 0},
{"ipow", 14, 1, 7},
{"iexp", 14, 2, 7},
{"isin", 14, 3, 7},
{"icos", 14, 4, 7},
{"memstr", 12, 0, 8},
{"hex2ui", 10, 8, 0},
{"atoi", 19, 13, 1},
{"debug_print_str_start", 19, 14, 1},
{"debug_print_str_nonl", 19, 15, 1},
{"entropy_buffer", 19, 16, 1},
{"map_new", 10, 9, 0},
{"map_addkey", 9, 0, 9},
{"map_setvalue", 9, 1, 9},
{"map_remove", 9, 2, 9},
{"map_find", 9, 3, 9},
{"map_getvaluesize", 8, 19, 2},
{"map_getvalue", 13, 2, 6},
{"map_done", 8, 20, 2},
{"file_find_limit", 9, 4, 9},
{"engine_functionality_level", 11, 1, 5},
{"engine_dconf_level", 11, 2, 5},
{"engine_scan_options", 11, 3, 5},
{"engine_db_options", 11, 4, 5},
{"extract_set_container", 8, 21, 2},
{"input_switch", 8, 22, 2},
{"get_environment", 15, 17, 1},
{"disable_bytecode_if", 9, 5, 9},
{"disable_jit_if", 9, 6, 9},
{"version_compare", 12, 1, 8},
{"check_platform", 14, 5, 7},
{"pdf_get_obj_num", 11, 5, 5},
{"pdf_get_flags", 11, 6, 5},
{"pdf_set_flags", 8, 23, 2},
{"pdf_lookupobj", 8, 24, 2},
{"pdf_getobjsize", 8, 25, 2},
{"pdf_getobj", 13, 3, 6},
{"pdf_getobjid", 8, 26, 2},
{"pdf_getobjflags", 8, 27, 2},
{"pdf_setobjflags", 10, 10, 0},
{"pdf_get_offset", 8, 28, 2},
{"pdf_get_phase", 11, 7, 5},
{"pdf_get_dumpedobjid", 11, 8, 5},
{"matchicon", 12, 2, 8},
{"running_on_jit", 11, 9, 5},
{"get_file_reliability", 11, 10, 5},
{"json_is_active", 11, 11, 5},
{"json_get_object", 9, 7, 9},
{"json_get_type", 8, 29, 2},
{"json_get_array_length", 8, 30, 2},
{"json_get_array_idx", 10, 11, 0},
{"json_get_string_length", 8, 31, 2},
{"json_get_string", 9, 8, 9},
{"json_get_boolean", 8, 32, 2},
{"json_get_int", 8, 33, 2}
{"extract_new", 9, 4, 2},
{"read_number", 9, 5, 2},
{"hashset_new", 12, 0, 5},
{"hashset_add", 11, 2, 0},
{"hashset_remove", 11, 3, 0},
{"hashset_contains", 11, 4, 0},
{"hashset_done", 9, 6, 2},
{"hashset_empty", 9, 7, 2},
{"buffer_pipe_new", 9, 8, 2},
{"buffer_pipe_new_fromfile", 9, 9, 2},
{"buffer_pipe_read_avail", 9, 10, 2},
{"buffer_pipe_read_get", 14, 0, 6},
{"buffer_pipe_read_stopped", 11, 5, 0},
{"buffer_pipe_write_avail", 9, 11, 2},
{"buffer_pipe_write_get", 14, 1, 6},
{"buffer_pipe_write_stopped", 11, 6, 0},
{"buffer_pipe_done", 9, 12, 2},
{"inflate_init", 15, 0, 7},
{"inflate_process", 9, 13, 2},
{"inflate_done", 9, 14, 2},
{"bytecode_rt_error", 9, 15, 2},
{"jsnorm_init", 9, 16, 2},
{"jsnorm_process", 9, 17, 2},
{"jsnorm_done", 9, 18, 2},
{"ilog2", 11, 7, 0},
{"ipow", 15, 1, 7},
{"iexp", 15, 2, 7},
{"isin", 15, 3, 7},
{"icos", 15, 4, 7},
{"memstr", 13, 0, 8},
{"hex2ui", 11, 8, 0},
{"atoi", 8, 13, 1},
{"debug_print_str_start", 8, 14, 1},
{"debug_print_str_nonl", 8, 15, 1},
{"entropy_buffer", 8, 16, 1},
{"map_new", 11, 9, 0},
{"map_addkey", 10, 0, 9},
{"map_setvalue", 10, 1, 9},
{"map_remove", 10, 2, 9},
{"map_find", 10, 3, 9},
{"map_getvaluesize", 9, 19, 2},
{"map_getvalue", 14, 2, 6},
{"map_done", 9, 20, 2},
{"file_find_limit", 10, 4, 9},
{"engine_functionality_level", 12, 1, 5},
{"engine_dconf_level", 12, 2, 5},
{"engine_scan_options", 12, 3, 5},
{"engine_db_options", 12, 4, 5},
{"extract_set_container", 9, 21, 2},
{"input_switch", 9, 22, 2},
{"get_environment", 16, 17, 1},
{"disable_bytecode_if", 10, 5, 9},
{"disable_jit_if", 10, 6, 9},
{"version_compare", 13, 1, 8},
{"check_platform", 15, 5, 7},
{"pdf_get_obj_num", 12, 5, 5},
{"pdf_get_flags", 12, 6, 5},
{"pdf_set_flags", 9, 23, 2},
{"pdf_lookupobj", 9, 24, 2},
{"pdf_getobjsize", 9, 25, 2},
{"pdf_getobj", 14, 3, 6},
{"pdf_getobjid", 9, 26, 2},
{"pdf_getobjflags", 9, 27, 2},
{"pdf_setobjflags", 11, 10, 0},
{"pdf_get_offset", 9, 28, 2},
{"pdf_get_phase", 12, 7, 5},
{"pdf_get_dumpedobjid", 12, 8, 5},
{"matchicon", 13, 2, 8},
{"running_on_jit", 12, 9, 5},
{"get_file_reliability", 12, 10, 5},
{"json_is_active", 12, 11, 5},
{"json_get_object", 10, 7, 9},
{"json_get_type", 9, 29, 2},
{"json_get_array_length", 9, 30, 2},
{"json_get_array_idx", 11, 11, 0},
{"json_get_string_length", 9, 31, 2},
{"json_get_string", 10, 8, 9},
{"json_get_boolean", 9, 32, 2},
{"json_get_int", 9, 33, 2},
{"engine_scan_options_ex", 8, 18, 1}
/* Bytecode APIcalls END */
};
const unsigned cli_numapicalls=sizeof(cli_apicalls)/sizeof(cli_apicalls[0]);
@ -354,7 +356,8 @@ const cli_apicall_pointer cli_apicalls1[] = {
(cli_apicall_pointer)cli_bcapi_debug_print_str_start,
(cli_apicall_pointer)cli_bcapi_debug_print_str_nonl,
(cli_apicall_pointer)cli_bcapi_entropy_buffer,
(cli_apicall_pointer)cli_bcapi_get_environment
(cli_apicall_pointer)cli_bcapi_get_environment,
(cli_apicall_pointer)cli_bcapi_engine_scan_options_ex
};
const cli_apicall_int1 cli_apicalls2[] = {
(cli_apicall_int1)cli_bcapi_debug_print_uint,

@ -2,7 +2,7 @@
* ClamAV bytecode internal API
* This is an automatically generated file!
*
* Copyright (C) 2015 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
* Copyright (C) 2014-2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
* Copyright (C) 2009-2013 Sourcefire, Inc.
*
* Redistribution and use in source and binary forms, with or without
@ -131,5 +131,6 @@ int32_t cli_bcapi_json_get_string_length(struct cli_bc_ctx *ctx , int32_t);
int32_t cli_bcapi_json_get_string(struct cli_bc_ctx *ctx , int8_t*, int32_t, int32_t);
int32_t cli_bcapi_json_get_boolean(struct cli_bc_ctx *ctx , int32_t);
int32_t cli_bcapi_json_get_int(struct cli_bc_ctx *ctx , int32_t);
uint32_t cli_bcapi_engine_scan_options_ex(struct cli_bc_ctx *ctx , const uint8_t*, uint32_t);
#endif

@ -2,7 +2,7 @@
* ClamAV bytecode internal API
* This is an automatically generated file!
*
* Copyright (C) 2015 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
* Copyright (C) 2014-2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
* Copyright (C) 2009-2013 Sourcefire, Inc.
*
* Redistribution and use in source and binary forms, with or without

@ -833,7 +833,7 @@ void cache_add(unsigned char *md5, size_t size, cli_ctx *ctx) {
level = (*ctx->fmap && (*ctx->fmap)->dont_cache_flag) ? ctx->recursion : 0;
if (ctx->found_possibly_unwanted && (level || !ctx->recursion))
return;
if (SCAN_ALL && (ctx->num_viruses > 0)) {
if (SCAN_ALLMATCHES && (ctx->num_viruses > 0)) {
cli_dbgmsg("cache_add: alert found within same topfile, skipping cache\n");
return;
}

@ -65,6 +65,8 @@
#include <sys/types.h>
#include <sys/stat.h>
#include "cltypes.h"
#ifdef __cplusplus
extern "C"
{
@ -121,64 +123,75 @@ typedef enum cl_error_t {
} cl_error_t;
/* db options */
#define CL_DB_PHISHING 0x2
#define CL_DB_PHISHING_URLS 0x8
#define CL_DB_PUA 0x10
#define CL_DB_CVDNOTMP 0x20 /* obsolete */
#define CL_DB_OFFICIAL 0x40 /* internal */
#define CL_DB_PUA_MODE 0x80
#define CL_DB_PUA_INCLUDE 0x100
#define CL_DB_PUA_EXCLUDE 0x200
#define CL_DB_COMPILED 0x400 /* internal */
#define CL_DB_DIRECTORY 0x800 /* internal */
#define CL_DB_OFFICIAL_ONLY 0x1000
#define CL_DB_BYTECODE 0x2000
#define CL_DB_SIGNED 0x4000 /* internal */
#define CL_DB_BYTECODE_UNSIGNED 0x8000
#define CL_DB_UNSIGNED 0x10000 /* internal */
#define CL_DB_BYTECODE_STATS 0x20000
#define CL_DB_ENHANCED 0x40000
#define CL_DB_PCRE_STATS 0x80000
#define CL_DB_YARA_EXCLUDE 0x100000
#define CL_DB_YARA_ONLY 0x200000
#define CL_DB_PHISHING 0x2
#define CL_DB_PHISHING_URLS 0x8
#define CL_DB_PUA 0x10
#define CL_DB_CVDNOTMP 0x20 /* obsolete */
#define CL_DB_OFFICIAL 0x40 /* internal */
#define CL_DB_PUA_MODE 0x80
#define CL_DB_PUA_INCLUDE 0x100
#define CL_DB_PUA_EXCLUDE 0x200
#define CL_DB_COMPILED 0x400 /* internal */
#define CL_DB_DIRECTORY 0x800 /* internal */
#define CL_DB_OFFICIAL_ONLY 0x1000
#define CL_DB_BYTECODE 0x2000
#define CL_DB_SIGNED 0x4000 /* internal */
#define CL_DB_BYTECODE_UNSIGNED 0x8000
#define CL_DB_UNSIGNED 0x10000 /* internal */
#define CL_DB_BYTECODE_STATS 0x20000
#define CL_DB_ENHANCED 0x40000
#define CL_DB_PCRE_STATS 0x80000
#define CL_DB_YARA_EXCLUDE 0x100000
#define CL_DB_YARA_ONLY 0x200000
/* recommended db settings */
#define CL_DB_STDOPT (CL_DB_PHISHING | CL_DB_PHISHING_URLS | CL_DB_BYTECODE)
/* scan options */
#define CL_SCAN_RAW 0x0
#define CL_SCAN_ARCHIVE 0x1
#define CL_SCAN_MAIL 0x2
#define CL_SCAN_OLE2 0x4
#define CL_SCAN_BLOCKENCRYPTED 0x8
#define CL_SCAN_HTML 0x10
#define CL_SCAN_PE 0x20
#define CL_SCAN_BLOCKBROKEN 0x40
#define CL_SCAN_MAILURL 0x80 /* ignored */
#define CL_SCAN_BLOCKMAX 0x100
#define CL_SCAN_ALGORITHMIC 0x200
#define CL_SCAN_PHISHING_BLOCKSSL 0x800 /* ssl mismatches, not ssl by itself*/
#define CL_SCAN_PHISHING_BLOCKCLOAK 0x1000
#define CL_SCAN_ELF 0x2000
#define CL_SCAN_PDF 0x4000
#define CL_SCAN_STRUCTURED 0x8000
#define CL_SCAN_STRUCTURED_SSN_NORMAL 0x10000
#define CL_SCAN_STRUCTURED_SSN_STRIPPED 0x20000
#define CL_SCAN_PARTIAL_MESSAGE 0x40000
#define CL_SCAN_HEURISTIC_PRECEDENCE 0x80000
#define CL_SCAN_BLOCKMACROS 0x100000
#define CL_SCAN_ALLMATCHES 0x200000
#define CL_SCAN_SWF 0x400000
#define CL_SCAN_PARTITION_INTXN 0x800000
#define CL_SCAN_XMLDOCS 0x1000000
#define CL_SCAN_HWP3 0x2000000
#define CL_SCAN_FILE_PROPERTIES 0x10000000
//#define UNUSED 0x20000000
#define CL_SCAN_PERFORMANCE_INFO 0x40000000 /* collect performance timings */
#define CL_SCAN_INTERNAL_COLLECT_SHA 0x80000000 /* Enables hash output in sha-collect builds - for internal use only */
/* recommended scan settings */
#define CL_SCAN_STDOPT (CL_SCAN_ARCHIVE | CL_SCAN_MAIL | CL_SCAN_OLE2 | CL_SCAN_PDF | CL_SCAN_HTML | CL_SCAN_PE | CL_SCAN_ALGORITHMIC | CL_SCAN_ELF | CL_SCAN_SWF | CL_SCAN_XMLDOCS | CL_SCAN_HWP3)
#define CL_DB_STDOPT (CL_DB_PHISHING | CL_DB_PHISHING_URLS | CL_DB_BYTECODE)
/*** scan options ***/
struct cl_scan_options {
uint32_t general;
uint32_t parse;
uint32_t heuristic;
uint32_t mail;
uint32_t dev;
};
/* general */
#define CL_SCAN_GENERAL_ALLMATCHES 0x1 /* scan in all-match mode */
#define CL_SCAN_GENERAL_COLLECT_METADATA 0x2 /* collect metadata (--gen-json) */
#define CL_SCAN_GENERAL_HEURISTICS 0x4 /* option to enable heuristic alerts */
#define CL_SCAN_GENERAL_HEURISTIC_PRECEDENCE 0x8 /* allow heuristic match to take precedence. */
/* parsing capabilities options */
#define CL_SCAN_PARSE_ARCHIVE 0x1
#define CL_SCAN_PARSE_ELF 0x2
#define CL_SCAN_PARSE_PDF 0x4
#define CL_SCAN_PARSE_SWF 0x8
#define CL_SCAN_PARSE_HWP3 0x10
#define CL_SCAN_PARSE_XMLDOCS 0x20
#define CL_SCAN_PARSE_MAIL 0x40
#define CL_SCAN_PARSE_OLE2 0x80
#define CL_SCAN_PARSE_HTML 0x100
#define CL_SCAN_PARSE_PE 0x200
/* heuristic alerting options */
#define CL_SCAN_HEURISTIC_BROKEN 0x2
#define CL_SCAN_HEURISTIC_EXCEEDS_MAX 0x4
#define CL_SCAN_HEURISTIC_PHISHING_SSL_MISMATCH 0x8
#define CL_SCAN_HEURISTIC_PHISHING_CLOAK 0x10
#define CL_SCAN_HEURISTIC_MACROS 0x20
#define CL_SCAN_HEURISTIC_ENCRYPTED 0x40
#define CL_SCAN_HEURISTIC_PARTITION_INTXN 0x80 /* alert if partition table size doesn't make sense */
#define CL_SCAN_HEURISTIC_STRUCTURED 0x100 /* data loss prevention options, i.e. alert when detecting personal information */
#define CL_SCAN_HEURISTIC_STRUCTURED_SSN_NORMAL 0x200 /* alert when detecting social security numbers */
#define CL_SCAN_HEURISTIC_STRUCTURED_SSN_STRIPPED 0x400 /* alert when detecting stripped social security numbers */
/* mail scanning options */
#define CL_SCAN_MAIL_PARTIAL_MESSAGE 0x1
/* dev options */
#define CL_SCAN_DEV_COLLECT_SHA 0x1 /* Enables hash output in sha-collect builds - for internal use only */
#define CL_SCAN_DEV_COLLECT_PERFORMANCE_INFO 0x2 /* collect performance timings */
/* cl_countsigs options */
#define CL_COUNTSIGS_OFFICIAL 0x1
@ -488,11 +501,11 @@ struct cl_cvd { /* field no. */
};
/* file scanning */
extern int cl_scandesc(int desc, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, unsigned int scanoptions);
extern int cl_scandesc_callback(int desc, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, unsigned int scanoptions, void *context);
extern int cl_scandesc(int desc, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options* scanoptions);
extern int cl_scandesc_callback(int desc, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options* scanoptions, void *context);
extern int cl_scanfile(const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, unsigned int scanoptions);
extern int cl_scanfile_callback(const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, unsigned int scanoptions, void *context);
extern int cl_scanfile(const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options* scanoptions);
extern int cl_scanfile_callback(const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options* scanoptions, void *context);
/* database handling */
extern int cl_load(const char *path, struct cl_engine *engine, unsigned int *signo, unsigned int dboptions);
@ -558,7 +571,7 @@ extern cl_fmap_t *cl_fmap_open_memory(const void *start, size_t len);
extern void cl_fmap_close(cl_fmap_t*);
/* Scan custom data */
extern int cl_scanmap_callback(cl_fmap_t *map, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, unsigned int scanoptions, void *context);
extern int cl_scanmap_callback(cl_fmap_t *map, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *scanoptions, void *context);
/* Crypto/hashing functions */
#define SHA1_HASH_SIZE 20

@ -1,7 +1,7 @@
/*
* ClamAV bytecode definitions.
*
* Copyright (C) 2015 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
* Copyright (C) 2014-2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
* Copyright (C) 2009-2010 Sourcefire, Inc.
*
* Authors: Török Edvin

@ -153,7 +153,7 @@ int cli_scancpio_old(cli_ctx *ctx)
continue;
if(cli_matchmeta(ctx, name, filesize, filesize, 0, file, 0, NULL) == CL_VIRUS) {
if (!SCAN_ALL)
if (!SCAN_ALLMATCHES)
return CL_VIRUS;
virus_found = 1;
}
@ -168,7 +168,7 @@ int cli_scancpio_old(cli_ctx *ctx)
} else if(ret == CL_SUCCESS) {
ret = cli_map_scan(*ctx->fmap, pos, filesize, ctx, CL_TYPE_ANY);
if(ret == CL_VIRUS) {
if (!SCAN_ALL)
if (!SCAN_ALLMATCHES)
return ret;
virus_found = 1;
}
@ -247,7 +247,7 @@ int cli_scancpio_odc(cli_ctx *ctx)
continue;
if(cli_matchmeta(ctx, name, filesize, filesize, 0, file, 0, NULL) == CL_VIRUS) {
if (!SCAN_ALL)
if (!SCAN_ALLMATCHES)
return CL_VIRUS;
virus_found = 1;
}
@ -259,7 +259,7 @@ int cli_scancpio_odc(cli_ctx *ctx)
} else if(ret == CL_SUCCESS) {
ret = cli_map_scan(*ctx->fmap, pos, filesize, ctx, CL_TYPE_ANY);
if(ret == CL_VIRUS) {
if (!SCAN_ALL)
if (!SCAN_ALLMATCHES)
return ret;
virus_found = 1;
}
@ -341,7 +341,7 @@ int cli_scancpio_newc(cli_ctx *ctx, int crc)
continue;
if(cli_matchmeta(ctx, name, filesize, filesize, 0, file, 0, NULL) == CL_VIRUS) {
if (!SCAN_ALL)
if (!SCAN_ALLMATCHES)
return CL_VIRUS;
virus_found = 1;
}
@ -352,7 +352,7 @@ int cli_scancpio_newc(cli_ctx *ctx, int crc)
} else if(ret == CL_SUCCESS) {
ret = cli_map_scan(*ctx->fmap, pos, filesize, ctx, CL_TYPE_ANY);
if(ret == CL_VIRUS) {
if (!SCAN_ALL)
if (!SCAN_ALLMATCHES)
return ret;
virus_found = 1;
}

@ -239,7 +239,7 @@ int cli_scandmg(cli_ctx *ctx)
if (depth < 0) {
break;
}
if ((depth > 50) && SCAN_ALGO) {
if ((depth > 50) && SCAN_HEURISTICS) {
// Possible heuristic, should limit runaway
cli_dbgmsg("cli_scandmg: Excessive nesting in DMG TOC.\n");
break;

@ -213,7 +213,7 @@ static int cli_elf_ph32(cli_ctx *ctx, fmap_t *map, struct cli_exe_info *elfinfo,
cli_dbgmsg("ELF: Number of program headers: %d\n", phnum);
if(phnum > 128) {
cli_dbgmsg("ELF: Suspicious number of program headers\n");
if(ctx && DETECT_BROKEN) {
if(ctx && SCAN_HEURISTIC_BROKEN) {
cli_append_virus(ctx, "Heuristics.Broken.Executable");
return CL_VIRUS;
}
@ -226,7 +226,7 @@ static int cli_elf_ph32(cli_ctx *ctx, fmap_t *map, struct cli_exe_info *elfinfo,
/* Sanity check */
if(phentsize != sizeof(struct elf_program_hdr32)) {
cli_dbgmsg("ELF: phentsize != sizeof(struct elf_program_hdr32)\n");
if(ctx && DETECT_BROKEN) {
if(ctx && SCAN_HEURISTIC_BROKEN) {
cli_append_virus(ctx, "Heuristics.Broken.Executable");
return CL_VIRUS;
}
@ -261,7 +261,7 @@ static int cli_elf_ph32(cli_ctx *ctx, fmap_t *map, struct cli_exe_info *elfinfo,
cli_dbgmsg("ELF: Possibly broken ELF file\n");
}
free(program_hdr);
if(ctx && DETECT_BROKEN) {
if(ctx && SCAN_HEURISTIC_BROKEN) {
cli_append_virus(ctx, "Heuristics.Broken.Executable");
return CL_VIRUS;
}
@ -283,7 +283,7 @@ static int cli_elf_ph32(cli_ctx *ctx, fmap_t *map, struct cli_exe_info *elfinfo,
free(program_hdr);
if(err) {
cli_dbgmsg("ELF: Can't calculate file offset of entry point\n");
if(ctx && DETECT_BROKEN) {
if(ctx && SCAN_HEURISTIC_BROKEN) {
cli_append_virus(ctx, "Heuristics.Broken.Executable");
return CL_VIRUS;
}
@ -317,7 +317,7 @@ static int cli_elf_ph64(cli_ctx *ctx, fmap_t *map, struct cli_exe_info *elfinfo,
cli_dbgmsg("ELF: Number of program headers: %d\n", phnum);
if(phnum > 128) {
cli_dbgmsg("ELF: Suspicious number of program headers\n");
if(ctx && DETECT_BROKEN) {
if(ctx && SCAN_HEURISTIC_BROKEN) {
cli_append_virus(ctx, "Heuristics.Broken.Executable");
return CL_VIRUS;
}
@ -330,7 +330,7 @@ static int cli_elf_ph64(cli_ctx *ctx, fmap_t *map, struct cli_exe_info *elfinfo,
/* Sanity check */
if (phentsize != sizeof(struct elf_program_hdr64)) {
cli_dbgmsg("ELF: phentsize != sizeof(struct elf_program_hdr64)\n");
if(ctx && DETECT_BROKEN) {
if(ctx && SCAN_HEURISTIC_BROKEN) {
cli_append_virus(ctx, "Heuristics.Broken.Executable");
return CL_VIRUS;
}
@ -365,7 +365,7 @@ static int cli_elf_ph64(cli_ctx *ctx, fmap_t *map, struct cli_exe_info *elfinfo,
cli_dbgmsg("ELF: Possibly broken ELF file\n");
}
free(program_hdr);
if(ctx && DETECT_BROKEN) {
if(ctx && SCAN_HEURISTIC_BROKEN) {
cli_append_virus(ctx, "Heuristics.Broken.Executable");
return CL_VIRUS;
}
@ -387,7 +387,7 @@ static int cli_elf_ph64(cli_ctx *ctx, fmap_t *map, struct cli_exe_info *elfinfo,
free(program_hdr);
if(err) {
cli_dbgmsg("ELF: Can't calculate file offset of entry point\n");
if(ctx && DETECT_BROKEN) {
if(ctx && SCAN_HEURISTIC_BROKEN) {
cli_append_virus(ctx, "Heuristics.Broken.Executable");
return CL_VIRUS;
}
@ -432,7 +432,7 @@ static int cli_elf_sh32(cli_ctx *ctx, fmap_t *map, struct cli_exe_info *elfinfo,
/* Sanity check */
if(shentsize != sizeof(struct elf_section_hdr32)) {
cli_dbgmsg("ELF: shentsize != sizeof(struct elf_section_hdr32)\n");
if(ctx && DETECT_BROKEN) {
if(ctx && SCAN_HEURISTIC_BROKEN) {
cli_append_virus(ctx, "Heuristics.Broken.Executable");
return CL_VIRUS;
}
@ -484,7 +484,7 @@ static int cli_elf_sh32(cli_ctx *ctx, fmap_t *map, struct cli_exe_info *elfinfo,
free(elfinfo->section);
elfinfo->section = NULL;
}
if(ctx && DETECT_BROKEN) {
if(ctx && SCAN_HEURISTIC_BROKEN) {
cli_append_virus(ctx, "Heuristics.Broken.Executable");
return CL_VIRUS;
}
@ -542,7 +542,7 @@ static int cli_elf_sh64(cli_ctx *ctx, fmap_t *map, struct cli_exe_info *elfinfo,
/* Sanity check */
if(shentsize != sizeof(struct elf_section_hdr64)) {
cli_dbgmsg("ELF: shentsize != sizeof(struct elf_section_hdr64)\n");
if(ctx && DETECT_BROKEN) {
if(ctx && SCAN_HEURISTIC_BROKEN) {
cli_append_virus(ctx, "Heuristics.Broken.Executable");
return CL_VIRUS;
}
@ -594,7 +594,7 @@ static int cli_elf_sh64(cli_ctx *ctx, fmap_t *map, struct cli_exe_info *elfinfo,
free(elfinfo->section);
elfinfo->section = NULL;
}
if(ctx && DETECT_BROKEN) {
if(ctx && SCAN_HEURISTIC_BROKEN) {
cli_append_virus(ctx, "Heuristics.Broken.Executable");
return CL_VIRUS;
}

@ -137,7 +137,7 @@ int cli_scangpt(cli_ctx *ctx, size_t sectorsize)
/* check the protective mbr */
ret = gpt_check_mbr(ctx, sectorsize);
if (ret != CL_CLEAN) {
if ((ctx->options & CL_SCAN_ALLMATCHES) && (ret == CL_VIRUS))
if (SCAN_ALLMATCHES && (ret == CL_VIRUS))
detection = CL_VIRUS;
else
return ret;
@ -198,17 +198,17 @@ int cli_scangpt(cli_ctx *ctx, size_t sectorsize)
}
/* check that the partition table has no intersections - HEURISTICS */
if ((ctx->options & CL_SCAN_PARTITION_INTXN) && (ctx->dconf->other & OTHER_CONF_PRTNINTXN)) {
if (SCAN_HEURISTIC_PARTITION_INTXN && (ctx->dconf->other & OTHER_CONF_PRTNINTXN)) {
ret = gpt_prtn_intxn(ctx, phdr, sectorsize);
if (ret != CL_CLEAN) {
if ((ctx->options & CL_SCAN_ALLMATCHES) && (ret == CL_VIRUS))
if (SCAN_ALLMATCHES && (ret == CL_VIRUS))
detection = CL_VIRUS;
else
return ret;
}
ret = gpt_prtn_intxn(ctx, shdr, sectorsize);
if (ret != CL_CLEAN) {
if ((ctx->options & CL_SCAN_ALLMATCHES) && (ret == CL_VIRUS))
if (SCAN_ALLMATCHES && (ret == CL_VIRUS))
detection = CL_VIRUS;
else
return ret;
@ -221,7 +221,7 @@ int cli_scangpt(cli_ctx *ctx, size_t sectorsize)
cli_dbgmsg("cli_scangpt: Scanning primary GPT partitions only\n");
ret = gpt_scan_partitions(ctx, phdr, sectorsize);
if (ret != CL_CLEAN) {
if ((ctx->options & CL_SCAN_ALLMATCHES) && (ret == CL_VIRUS))
if (SCAN_ALLMATCHES && (ret == CL_VIRUS))
detection = CL_VIRUS;
else
return ret;
@ -231,7 +231,7 @@ int cli_scangpt(cli_ctx *ctx, size_t sectorsize)
cli_dbgmsg("cli_scangpt: Scanning secondary GPT partitions only\n");
ret = gpt_scan_partitions(ctx, shdr, sectorsize);
if (ret != CL_CLEAN) {
if ((ctx->options & CL_SCAN_ALLMATCHES) && (ret == CL_VIRUS))
if (SCAN_ALLMATCHES && (ret == CL_VIRUS))
detection = CL_VIRUS;
else
return ret;
@ -241,7 +241,7 @@ int cli_scangpt(cli_ctx *ctx, size_t sectorsize)
cli_dbgmsg("cli_scangpt: Scanning primary GPT partitions\n");
ret = gpt_scan_partitions(ctx, phdr, sectorsize);
if (ret != CL_CLEAN) {
if ((ctx->options & CL_SCAN_ALLMATCHES) && (ret == CL_VIRUS))
if (SCAN_ALLMATCHES && (ret == CL_VIRUS))
detection = CL_VIRUS;
else
return ret;
@ -249,7 +249,7 @@ int cli_scangpt(cli_ctx *ctx, size_t sectorsize)
cli_dbgmsg("cli_scangpt: Scanning secondary GPT partitions\n");
ret = gpt_scan_partitions(ctx, shdr, sectorsize);
if (ret != CL_CLEAN) {
if ((ctx->options & CL_SCAN_ALLMATCHES) && (ret == CL_VIRUS))
if (SCAN_ALLMATCHES && (ret == CL_VIRUS))
detection = CL_VIRUS;
else
return ret;
@ -351,7 +351,7 @@ static int gpt_scan_partitions(cli_ctx *ctx, struct gpt_header hdr, size_t secto
part_size = (gpe.lastLBA - gpe.firstLBA + 1) * sectorsize;
ret = cli_map_scan(*ctx->fmap, part_off, part_size, ctx, CL_TYPE_PART_ANY);
if (ret != CL_CLEAN) {
if ((ctx->options & CL_SCAN_ALLMATCHES) && (ret == CL_VIRUS))
if (SCAN_ALLMATCHES && (ret == CL_VIRUS))
detection = CL_VIRUS;
else
return ret;
@ -654,7 +654,7 @@ static int gpt_prtn_intxn(cli_ctx *ctx, struct gpt_header hdr, size_t sectorsize
ret = cli_append_virus(ctx, PRTN_INTXN_DETECTION);
if (ret == CL_VIRUS)
virus_found = 1;
if (SCAN_ALL || ret == CL_CLEAN)
if (SCAN_ALLMATCHES || ret == CL_CLEAN)
tmp = 0;
else
goto leave;

@ -662,8 +662,8 @@ static int hfsplus_walk_catalog(cli_ctx *ctx, hfsPlusVolumeHeader *volHeader, hf
/* Check return code */
if (ret == CL_VIRUS) {
has_alerts = 1;
if (SCAN_ALL) {
/* Continue scanning in SCAN_ALL mode */
if (SCAN_ALLMATCHES) {
/* Continue scanning in SCAN_ALLMATCHES mode */
cli_dbgmsg("hfsplus_walk_catalog: data fork alert, continuing");
ret = CL_CLEAN;
}
@ -681,8 +681,8 @@ static int hfsplus_walk_catalog(cli_ctx *ctx, hfsPlusVolumeHeader *volHeader, hf
/* Check return code */
if (ret == CL_VIRUS) {
has_alerts = 1;
if (SCAN_ALL) {
/* Continue scanning in SCAN_ALL mode */
if (SCAN_ALLMATCHES) {
/* Continue scanning in SCAN_ALLMATCHES mode */
cli_dbgmsg("hfsplus_walk_catalog: resource fork alert, continuing");
ret = CL_CLEAN;
}

@ -306,7 +306,7 @@ int cli_hwp5header(cli_ctx *ctx, hwp5_header_t *hwp5)
return CL_ENULLARG;
#if HAVE_JSON
if (ctx->options & CL_SCAN_FILE_PROPERTIES) {
if (SCAN_COLLECT_METADATA) {
json_object *header, *flags;
header = cli_jsonobj(ctx->wrkproperty, "Hwp5Header");
@ -426,7 +426,7 @@ int cli_scanhwp5_stream(cli_ctx *ctx, hwp5_header_t *hwp5, char *name, int fd)
#if HAVE_JSON
/* JSON Output Summary Information */
if (ctx->options & CL_SCAN_FILE_PROPERTIES && ctx->properties != NULL) {
if (SCAN_COLLECT_METADATA && ctx->properties != NULL) {
if (name && !strncmp(name, "_5_hwpsummaryinformation", 24)) {
cli_dbgmsg("HWP5.x: Detected a '_5_hwpsummaryinformation' stream\n");
/* JSONOLE2 - what to do if something breaks? */
@ -539,7 +539,7 @@ static inline int parsehwp3_docinfo(cli_ctx *ctx, off_t offset, struct hwp3_doci
hwp3_debug("HWP3.x: di_infoblksize: %u\n", docinfo->di_infoblksize);
#if HAVE_JSON
if (ctx->options & CL_SCAN_FILE_PROPERTIES) {
if (SCAN_COLLECT_METADATA) {
json_object *header, *flags;
char *str;
@ -605,7 +605,7 @@ static inline int parsehwp3_docsummary(cli_ctx *ctx, off_t offset)
int i, iret, ret;
json_object *summary;
if (!(ctx->options & CL_SCAN_FILE_PROPERTIES))
if (!SCAN_COLLECT_METADATA)
return CL_SUCCESS;
if (!(hwp3_ptr = fmap_need_off_once(*ctx->fmap, offset, HWP3_DOCSUMMARY_SIZE))) {
@ -1537,7 +1537,7 @@ static inline int parsehwp3_infoblk_1(cli_ctx *ctx, fmap_t *dmap, off_t *offset,
hwp3_debug("HWP3.x: Information Block @ offset %llu\n", infoloc);
#if HAVE_JSON
if (ctx->options & CL_SCAN_FILE_PROPERTIES) {
if (SCAN_COLLECT_METADATA) {
infoblk_1 = cli_jsonobj(ctx->wrkproperty, "InfoBlk_1");
if (!infoblk_1) {
cli_errmsg("HWP5.x: No memory for information block object\n");
@ -1568,7 +1568,7 @@ static inline int parsehwp3_infoblk_1(cli_ctx *ctx, fmap_t *dmap, off_t *offset,
infoid = le32_to_host(infoid);
#if HAVE_JSON
if (ctx->options & CL_SCAN_FILE_PROPERTIES) {
if (SCAN_COLLECT_METADATA) {
entry = cli_jsonobj(contents, NULL);
if (!entry) {
cli_errmsg("HWP5.x: No memory for information block entry object\n");
@ -1584,7 +1584,7 @@ static inline int parsehwp3_infoblk_1(cli_ctx *ctx, fmap_t *dmap, off_t *offset,
if (infoid == 5) {
hwp3_debug("HWP3.x: Information Block[%llu]: TYPE: Booking Information\n", infoloc);
#if HAVE_JSON
if (ctx->options & CL_SCAN_FILE_PROPERTIES)
if (SCAN_COLLECT_METADATA)
cli_jsonstr(entry, "Type", "Booking Information");
#endif
return CL_SUCCESS;
@ -1599,7 +1599,7 @@ static inline int parsehwp3_infoblk_1(cli_ctx *ctx, fmap_t *dmap, off_t *offset,
infolen = le32_to_host(infolen);
#if HAVE_JSON
if (ctx->options & CL_SCAN_FILE_PROPERTIES) {
if (SCAN_COLLECT_METADATA) {
cli_jsonint64(entry, "Offset", infoloc);
cli_jsonint(entry, "Length", infolen);
}
@ -1619,7 +1619,7 @@ static inline int parsehwp3_infoblk_1(cli_ctx *ctx, fmap_t *dmap, off_t *offset,
if (infolen == 0) {
hwp3_debug("HWP3.x: Information Block[%llu]: TYPE: Terminating Entry\n", infoloc);
#if HAVE_JSON
if (ctx->options & CL_SCAN_FILE_PROPERTIES)
if (SCAN_COLLECT_METADATA)
cli_jsonstr(entry, "Type", "Terminating Entry");
#endif
if (last) *last = 1;
@ -1631,7 +1631,7 @@ static inline int parsehwp3_infoblk_1(cli_ctx *ctx, fmap_t *dmap, off_t *offset,
case 1: /* Image Data */
hwp3_debug("HWP3.x: Information Block[%llu]: TYPE: Image Data\n", infoloc);
#if HAVE_JSON
if (ctx->options & CL_SCAN_FILE_PROPERTIES)
if (SCAN_COLLECT_METADATA)
cli_jsonstr(entry, "Type", "Image Data");
#endif
#if HWP3_DEBUG /* additional fields can be added */
@ -1658,7 +1658,7 @@ static inline int parsehwp3_infoblk_1(cli_ctx *ctx, fmap_t *dmap, off_t *offset,
case 2: /* OLE2 Data */
hwp3_debug("HWP3.x: Information Block[%llu]: TYPE: OLE2 Data\n", infoloc);
#if HAVE_JSON
if (ctx->options & CL_SCAN_FILE_PROPERTIES)
if (SCAN_COLLECT_METADATA)
cli_jsonstr(entry, "Type", "OLE2 Data");
#endif
if (infolen > 0)
@ -1674,7 +1674,7 @@ static inline int parsehwp3_infoblk_1(cli_ctx *ctx, fmap_t *dmap, off_t *offset,
count = (infolen / 617);
hwp3_debug("HWP3.x: Information Block[%llu]: COUNT: %d entries\n", infoloc, count);
#if HAVE_JSON
if (ctx->options & CL_SCAN_FILE_PROPERTIES) {
if (SCAN_COLLECT_METADATA) {
cli_jsonstr(entry, "Type", "Hypertext/Hyperlink Information");
cli_jsonint(entry, "Count", count);
}
@ -1697,7 +1697,7 @@ static inline int parsehwp3_infoblk_1(cli_ctx *ctx, fmap_t *dmap, off_t *offset,
case 4: /* Presentation Information */
hwp3_debug("HWP3.x: Information Block[%llu]: TYPE: Presentation Information\n", infoloc);
#if HAVE_JSON
if (ctx->options & CL_SCAN_FILE_PROPERTIES)
if (SCAN_COLLECT_METADATA)
cli_jsonstr(entry, "Type", "Presentation Information");
#endif
/* contains nothing of interest to scan */
@ -1706,14 +1706,14 @@ static inline int parsehwp3_infoblk_1(cli_ctx *ctx, fmap_t *dmap, off_t *offset,
/* should never run this as it is short-circuited above */
hwp3_debug("HWP3.x: Information Block[%llu]: TYPE: Booking Information\n", infoloc);
#if HAVE_JSON
if (ctx->options & CL_SCAN_FILE_PROPERTIES)
if (SCAN_COLLECT_METADATA)
cli_jsonstr(entry, "Type", "Booking Information");
#endif
break;
case 6: /* Background Image Data */
hwp3_debug("HWP3.x: Information Block[%llu]: TYPE: Background Image Data\n", infoloc);
#if HAVE_JSON
if (ctx->options & CL_SCAN_FILE_PROPERTIES) {
if (SCAN_COLLECT_METADATA) {
cli_jsonstr(entry, "Type", "Background Image Data");
cli_jsonint(entry, "ImageSize", infolen-324);
}
@ -1734,7 +1734,7 @@ static inline int parsehwp3_infoblk_1(cli_ctx *ctx, fmap_t *dmap, off_t *offset,
case 0x100: /* Table Extension */
hwp3_debug("HWP3.x: Information Block[%llu]: TYPE: Table Extension\n", infoloc);
#if HAVE_JSON
if (ctx->options & CL_SCAN_FILE_PROPERTIES)
if (SCAN_COLLECT_METADATA)
cli_jsonstr(entry, "Type", "Table Extension");
#endif
/* contains nothing of interest to scan */
@ -1742,7 +1742,7 @@ static inline int parsehwp3_infoblk_1(cli_ctx *ctx, fmap_t *dmap, off_t *offset,
case 0x101: /* Press Frame Information Field Name */
hwp3_debug("HWP3.x: Information Block[%llu]: TYPE: Press Frame Information Field Name\n", infoloc);
#if HAVE_JSON
if (ctx->options & CL_SCAN_FILE_PROPERTIES)
if (SCAN_COLLECT_METADATA)
cli_jsonstr(entry, "Type", "Press Frame Information Field Name");
#endif
/* contains nothing of interest to scan */
@ -1796,7 +1796,7 @@ static int hwp3_cb(void *cbdata, int fd, cli_ctx *ctx)
/* Fonts - 7 entries of 2 + (n x 40) bytes where n is the first 2 bytes of the entry */
#if HAVE_JSON
if (ctx->options & CL_SCAN_FILE_PROPERTIES)
if (SCAN_COLLECT_METADATA)
fonts = cli_jsonarray(ctx->wrkproperty, "FontCounts");
#endif
for (i = 0; i < 7; i++) {
@ -1810,7 +1810,7 @@ static int hwp3_cb(void *cbdata, int fd, cli_ctx *ctx)
nfonts = le16_to_host(nfonts);
#if HAVE_JSON
if (ctx->options & CL_SCAN_FILE_PROPERTIES)
if (SCAN_COLLECT_METADATA)
cli_jsonint(fonts, NULL, nfonts);
#endif
hwp3_debug("HWP3.x: Font Entry %d with %u entries @ offset %llu\n", i+1, nfonts, (long long unsigned)offset);
@ -1831,7 +1831,7 @@ static int hwp3_cb(void *cbdata, int fd, cli_ctx *ctx)
nstyles = le16_to_host(nstyles);
#if HAVE_JSON
if (ctx->options & CL_SCAN_FILE_PROPERTIES)
if (SCAN_COLLECT_METADATA)
cli_jsonint(ctx->wrkproperty, "StyleCount", nstyles);
#endif
hwp3_debug("HWP3.x: %u Styles @ offset %llu\n", nstyles, (long long unsigned)offset);
@ -1853,7 +1853,7 @@ static int hwp3_cb(void *cbdata, int fd, cli_ctx *ctx)
return ret;
}
#if HAVE_JSON
if (ctx->options & CL_SCAN_FILE_PROPERTIES)
if (SCAN_COLLECT_METADATA)
cli_jsonint(ctx->wrkproperty, "ParagraphCount", p);
#endif
@ -1862,7 +1862,7 @@ static int hwp3_cb(void *cbdata, int fd, cli_ctx *ctx)
while (!last && ((ret = parsehwp3_infoblk_1(ctx, map, &offset, &last)) == CL_SUCCESS));
/* scan the uncompressed stream - both compressed and uncompressed cases [ALLMATCH] */
if ((ret == CL_SUCCESS) || ((SCAN_ALL) && (ret == CL_VIRUS))) {
if ((ret == CL_SUCCESS) || ((SCAN_ALLMATCHES) && (ret == CL_VIRUS))) {
int subret = ret;
size_t dlen = offset - start;

@ -380,7 +380,7 @@ int cli_scanishield(cli_ctx *ctx, off_t off, size_t sz) {
cli_dbgmsg("ishield: @%lx found file %s (%s) - version %s - size %lu\n", (unsigned long int) coff, fname, path, version, (unsigned long int) fsize);
if(cli_matchmeta(ctx, fname, fsize, fsize, 0, fc++, 0, NULL) == CL_VIRUS) {
if (!SCAN_ALL) {
if (!SCAN_ALLMATCHES) {
ret = CL_VIRUS;
break;
}

@ -187,7 +187,7 @@ static int iso_parse_dir(iso9660_t *iso, unsigned int block, unsigned int len) {
ret = cli_matchmeta(ctx, iso->buf, filesz, filesz, 0, 0, 0, NULL);
if (ret == CL_VIRUS) {
viruses_found = 1;
if (!SCAN_ALL)
if (!SCAN_ALLMATCHES)
break;
ret = CL_CLEAN;
}
@ -206,7 +206,7 @@ static int iso_parse_dir(iso9660_t *iso, unsigned int block, unsigned int len) {
}
if (ret == CL_VIRUS) {
viruses_found = 1;
if (!SCAN_ALL)
if (!SCAN_ALLMATCHES)
break;
ret = CL_CLEAN;
}

@ -31,7 +31,7 @@
#ifdef HAVE_JSON
int cli_json_timeout_cycle_check(cli_ctx *ctx, int *toval)
{
if (ctx->options & CL_SCAN_FILE_PROPERTIES) {
if (SCAN_COLLECT_METADATA) {
if (*toval <= 0) {
if (cli_checktimelimit(ctx) != CL_SUCCESS) {
cli_errmsg("cli_json_timeout_cycle_check: timeout!\n");

@ -385,7 +385,7 @@ int cli_scanmscab(cli_ctx *ctx, off_t sfx_offset)
if (ret) {
if (ret == CL_VIRUS) {
virus_num++;
if (!SCAN_ALL)
if (!SCAN_ALLMATCHES)
break;
}
goto out_close;
@ -434,7 +434,7 @@ int cli_scanmscab(cli_ctx *ctx, off_t sfx_offset)
}
free(tmp_fname);
files++;
if (ret == CL_VIRUS && SCAN_ALL)
if (ret == CL_VIRUS && SCAN_ALLMATCHES)
continue;
if (ret)
break;
@ -486,7 +486,7 @@ int cli_scanmschm(cli_ctx *ctx)
if (ret) {
if (ret == CL_VIRUS) {
virus_num++;
if (!SCAN_ALL)
if (!SCAN_ALLMATCHES)
break;
}
goto out_close;
@ -536,7 +536,7 @@ int cli_scanmschm(cli_ctx *ctx)
}
free(tmp_fname);
files++;
if (ret == CL_VIRUS && SCAN_ALL)
if (ret == CL_VIRUS && SCAN_ALLMATCHES)
continue;
if (ret)
break;

@ -175,7 +175,7 @@ struct macho_fat_arch
#define RETURN_BROKEN \
if(matcher) \
return -1; \
if(DETECT_BROKEN) { \
if(SCAN_HEURISTIC_BROKEN) { \
if (CL_VIRUS == cli_append_virus(ctx, "Heuristics.Broken.Executable")) \
return CL_VIRUS; \
} \

@ -1854,7 +1854,7 @@ int cli_ac_scanbuff(
ptN = ptN->next_same;
continue;
} else {
if(ctx && SCAN_ALL) {
if(ctx && SCAN_ALLMATCHES) {
cli_append_virus(ctx, (const char *)pt->virname);
viruses_found = 1;
}
@ -1862,7 +1862,7 @@ int cli_ac_scanbuff(
*virname = pt->virname;
if(customdata)
*customdata = pt->customdata;
if (!ctx || !SCAN_ALL)
if (!ctx || !SCAN_ALLMATCHES)
return CL_VIRUS;
ptN = ptN->next_same;
continue;
@ -1909,7 +1909,7 @@ int cli_ac_scanbuff(
ptN = ptN->next_same;
continue;
} else {
if(ctx && SCAN_ALL) {
if(ctx && SCAN_ALLMATCHES) {
cli_append_virus(ctx, (const char *)pt->virname);
viruses_found = 1;
}
@ -1920,7 +1920,7 @@ int cli_ac_scanbuff(
if(customdata)
*customdata = pt->customdata;
if (!ctx || !SCAN_ALL)
if (!ctx || !SCAN_ALLMATCHES)
return CL_VIRUS;
ptN = ptN->next_same;

@ -381,7 +381,7 @@ int cli_bm_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
}
if(virname) {
*virname = p->virname;
if(ctx != NULL && SCAN_ALL) {
if(ctx != NULL && SCAN_ALLMATCHES) {
cli_append_virus(ctx, *virname);
//*viroffset = offset + i + j - BM_MIN_LENGTH + BM_BLOCK_SIZE;
}
@ -391,7 +391,7 @@ int cli_bm_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
viruses_found = 1;
if(ctx != NULL && !SCAN_ALL)
if(ctx != NULL && !SCAN_ALLMATCHES)
return CL_VIRUS;
}
p = p->next;

@ -744,7 +744,7 @@ int cli_pcre_scanbuf(const unsigned char *buffer, uint32_t length, const char **
ret = cli_append_virus(ctx, (const char *)pm->virname);
if (virname)
*virname = pm->virname;
if (!ctx || !SCAN_ALL)
if (!ctx || !SCAN_ALLMATCHES)
if (ret != CL_CLEAN)
break;
}

@ -154,7 +154,7 @@ static inline int matcher_run(const struct cli_matcher *root,
return ret;
/* else (ret == CL_VIRUS) */
if (SCAN_ALL)
if (SCAN_ALLMATCHES)
viruses_found = 1;
else {
ret = cli_append_virus(ctx, *virname);
@ -167,7 +167,7 @@ static inline int matcher_run(const struct cli_matcher *root,
ret = cli_ac_scanbuff(buffer, length, virname, NULL, acres, root, mdata, offset, ftype, ftoffset, acmode, ctx);
if (ret != CL_CLEAN) {
if (ret == CL_VIRUS) {
if (SCAN_ALL)
if (SCAN_ALLMATCHES)
viruses_found = 1;
else {
ret = cli_append_virus(ctx, *virname);
@ -228,9 +228,9 @@ static inline int matcher_run(const struct cli_matcher *root,
#endif /* HAVE_PCRE */
/* end experimental fragment */
if (ctx && !SCAN_ALL && ret == CL_VIRUS)
if (ctx && !SCAN_ALLMATCHES && ret == CL_VIRUS)
return cli_append_virus(ctx, *virname);
if (ctx && SCAN_ALL && viruses_found)
if (ctx && SCAN_ALLMATCHES && viruses_found)
return CL_VIRUS;
if (saved_ret && ret == CL_CLEAN)
@ -280,7 +280,7 @@ int cli_scanbuff(const unsigned char *buffer, uint32_t length, uint32_t offset,
return ret;
if(ret == CL_VIRUS) {
viruses_found = 1;
if(ctx && !SCAN_ALL) {
if(ctx && !SCAN_ALLMATCHES) {
return ret;
}
}
@ -579,7 +579,7 @@ int cli_checkfp_virus(unsigned char *digest, size_t size, cli_ctx *ctx, const ch
}
#ifdef HAVE__INTERNAL__SHA_COLLECT
if((ctx->options & CL_SCAN_INTERNAL_COLLECT_SHA) && ctx->sha_collect>0) {
if(SCAN_DEV_COLLECT_SHA && (ctx->sha_collect > 0)) {
if((ptr = fmap_need_off_once(map, 0, size))) {
if(!have_sha256)
cl_sha256(ptr, size, shash256+SHA256_HASH_SIZE, NULL);
@ -842,7 +842,7 @@ int cli_exp_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data *acd
#endif
if (rc == CL_VIRUS) {
viruses_found = 1;
if (SCAN_ALL)
if (SCAN_ALLMATCHES)
continue;
break;
}
@ -1053,7 +1053,7 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli
/* virname already appended by matcher_run */
viruses_found = 1;
}
if((ret == CL_VIRUS && !SCAN_ALL) || ret == CL_EMEM) {
if((ret == CL_VIRUS && !SCAN_ALLMATCHES) || ret == CL_EMEM) {
if(!ftonly) {
cli_ac_freedata(&gdata);
cli_pcre_freeoff(&gpoff);
@ -1083,7 +1083,7 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli
/* virname already appended by matcher_run */
viruses_found = 1;
}
if((ret == CL_VIRUS && !SCAN_ALL) || ret == CL_EMEM) {
if((ret == CL_VIRUS && !SCAN_ALLMATCHES) || ret == CL_EMEM) {
cli_ac_freedata(&gdata);
cli_pcre_freeoff(&gpoff);
if(troot) {
@ -1158,7 +1158,7 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli
if((ret = cli_hm_scan(digest[hashtype], map->len, &virname, hdb, hashtype)) == CL_VIRUS) {
found += 1;
}
if(!found || SCAN_ALL) {
if(!found || SCAN_ALLMATCHES) {
if ((ret = cli_hm_scan_wild(digest[hashtype], &virname_w, hdb, hashtype)) == CL_VIRUS)
found += 2;
}
@ -1185,7 +1185,7 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli
if (found % 2) {
viruses_found = 1;
ret = cli_append_virus(ctx, virname);
if (!SCAN_ALL || ret != CL_CLEAN)
if (!SCAN_ALLMATCHES || ret != CL_CLEAN)
break;
virname = NULL;
}
@ -1193,7 +1193,7 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli
if (found > 1) {
viruses_found = 1;
ret = cli_append_virus(ctx, virname_w);
if (!SCAN_ALL || ret != CL_CLEAN)
if (!SCAN_ALLMATCHES || ret != CL_CLEAN)
break;
}
}
@ -1204,7 +1204,7 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli
cl_hash_destroy(sha256ctx);
if(troot) {
if(ret != CL_VIRUS || SCAN_ALL)
if(ret != CL_VIRUS || SCAN_ALLMATCHES)
ret = cli_exp_eval(ctx, troot, &tdata, &info, (const char *)refhash);
if (ret == CL_VIRUS)
viruses_found++;
@ -1216,7 +1216,7 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli
}
if(groot) {
if(ret != CL_VIRUS || SCAN_ALL)
if(ret != CL_VIRUS || SCAN_ALLMATCHES)
ret = cli_exp_eval(ctx, groot, &gdata, &info, (const char *)refhash);
cli_ac_freedata(&gdata);
cli_pcre_freeoff(&gpoff);
@ -1227,7 +1227,7 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli
cli_hashset_destroy(&info.exeinfo.vinfo);
if (SCAN_ALL && viruses_found)
if (SCAN_ALLMATCHES && viruses_found)
return CL_VIRUS;
if(ret == CL_VIRUS)
return CL_VIRUS;
@ -1251,7 +1251,7 @@ int cli_matchmeta(cli_ctx *ctx, const char *fname, size_t fsizec, size_t fsizer,
ret = cli_append_virus(ctx, "Detected.By.Callback");
viruses_found++;
if(!SCAN_ALL || ret != CL_CLEAN)
if(!SCAN_ALLMATCHES || ret != CL_CLEAN)
return ret;
}
@ -1288,12 +1288,12 @@ int cli_matchmeta(cli_ctx *ctx, const char *fname, size_t fsizec, size_t fsizer,
ret = cli_append_virus(ctx, cdb->virname);
viruses_found++;
if(!SCAN_ALL || ret != CL_CLEAN)
if(!SCAN_ALLMATCHES || ret != CL_CLEAN)
return ret;
} while((cdb = cdb->next));
if (SCAN_ALL && viruses_found)
if (SCAN_ALLMATCHES && viruses_found)
return CL_VIRUS;
return CL_CLEAN;
}

@ -51,7 +51,6 @@
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#include "clamav.h"
#include <dirent.h>
#include <limits.h>
#include <signal.h>
@ -166,7 +165,7 @@ typedef enum {
#include <fcntl.h>
/*
* Use CL_SCAN_PARTIAL_MESSAGE to handle messages covered by section 7.3.2 of RFC1341.
* Use CL_SCAN_MAIL_PARTIAL_MESSAGE to handle messages covered by section 7.3.2 of RFC1341.
* This is experimental code so it is up to YOU to (1) ensure it's secure
* (2) periodically trim the directory of old files
*
@ -594,7 +593,7 @@ cli_parse_mbox(const char *dir, cli_ctx *ctx)
}
if((retcode == CL_CLEAN) && ctx->found_possibly_unwanted &&
(*ctx->virname == NULL || SCAN_ALL)) {
(*ctx->virname == NULL || SCAN_ALLMATCHES)) {
retcode = cli_append_virus(ctx, "Heuristics.Phishing.Email");
ctx->found_possibly_unwanted = 0;
}
@ -2131,7 +2130,7 @@ parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx, unsigned int re
rc = OK;
break;
} else if(strcasecmp(mimeSubtype, "partial") == 0) {
if(mctx->ctx->options&CL_SCAN_PARTIAL_MESSAGE) {
if(mctx->ctx->options->mail & CL_SCAN_MAIL_PARTIAL_MESSAGE) {
/* RFC1341 message split over many emails */
if(rfc1341(mainMessage, mctx->dir) >= 0)
rc = OK;

@ -186,17 +186,17 @@ int cli_scanmbr(cli_ctx *ctx, size_t sectorsize)
/* MBR is valid, examine bootstrap code */
ret = cli_map_scan(*ctx->fmap, 0, sectorsize, ctx, CL_TYPE_ANY);
if (ret != CL_CLEAN) {
if ((ctx->options & CL_SCAN_ALLMATCHES) && (ret == CL_VIRUS))
if (SCAN_ALLMATCHES && (ret == CL_VIRUS))
detection = CL_VIRUS;
else
return ret;
}
/* check that the partition table has no intersections - HEURISTICS */
if ((ctx->options & CL_SCAN_PARTITION_INTXN) && (ctx->dconf->other & OTHER_CONF_PRTNINTXN)) {
if (SCAN_HEURISTIC_PARTITION_INTXN && (ctx->dconf->other & OTHER_CONF_PRTNINTXN)) {
ret = mbr_primary_prtn_intxn(ctx, mbr, sectorsize);
if (ret != CL_CLEAN) {
if ((ctx->options & CL_SCAN_ALLMATCHES) && (ret == CL_VIRUS))
if (SCAN_ALLMATCHES && (ret == CL_VIRUS))
detection = CL_VIRUS;
else
return ret;
@ -230,7 +230,7 @@ int cli_scanmbr(cli_ctx *ctx, size_t sectorsize)
ret = mbr_scanextprtn(ctx, &prtncount, mbr.entries[i].firstLBA,
mbr.entries[i].numLBA, sectorsize);
if (ret != CL_CLEAN) {
if ((ctx->options & CL_SCAN_ALLMATCHES) && (ret == CL_VIRUS))
if (SCAN_ALLMATCHES && (ret == CL_VIRUS))
detection = CL_VIRUS;
else
return ret;
@ -244,7 +244,7 @@ int cli_scanmbr(cli_ctx *ctx, size_t sectorsize)
mbr_parsemsg("cli_map_scan: [%u, +%u)\n", partoff, partsize);
ret = cli_map_scan(*ctx->fmap, partoff, partsize, ctx, CL_TYPE_PART_ANY);
if (ret != CL_CLEAN) {
if ((ctx->options & CL_SCAN_ALLMATCHES) && (ret == CL_VIRUS))
if (SCAN_ALLMATCHES && (ret == CL_VIRUS))
detection = CL_VIRUS;
else
return ret;
@ -387,7 +387,7 @@ static int mbr_scanextprtn(cli_ctx *ctx, unsigned *prtncount, off_t extlba, size
ret = cli_map_scan(*ctx->fmap, partoff, partsize, ctx, CL_TYPE_PART_ANY);
if (ret != CL_CLEAN) {
if ((ctx->options & CL_SCAN_ALLMATCHES) && (ret == CL_VIRUS))
if (SCAN_ALLMATCHES && (ret == CL_VIRUS))
detection = CL_VIRUS;
else
return ret;
@ -506,7 +506,7 @@ static int mbr_primary_prtn_intxn(cli_ctx *ctx, struct mbr_boot_record mbr, size
cli_dbgmsg("cli_scanmbr: detected intersection with partitions "
"[%u, %u]\n", pitxn, i);
ret = cli_append_virus(ctx, PRTN_INTXN_DETECTION);
if (SCAN_ALL || ret == CL_CLEAN)
if (SCAN_ALLMATCHES || ret == CL_CLEAN)
tmp = 0;
else
goto leave;
@ -521,7 +521,7 @@ static int mbr_primary_prtn_intxn(cli_ctx *ctx, struct mbr_boot_record mbr, size
tmp = mbr_extended_prtn_intxn(ctx, &prtncount,
mbr.entries[i].firstLBA, sectorsize);
if (tmp != CL_CLEAN) {
if ((ctx->options & CL_SCAN_ALLMATCHES) && (tmp == CL_VIRUS)) {
if (SCAN_ALLMATCHES && (tmp == CL_VIRUS)) {
ret = tmp;
tmp = 0;
}
@ -587,7 +587,7 @@ static int mbr_extended_prtn_intxn(cli_ctx *ctx, unsigned *prtncount, off_t extl
ret = cli_append_virus(ctx, PRTN_INTXN_DETECTION);
if (ret == CL_VIRUS)
virus_found = 1;
if (SCAN_ALL || ret == CL_CLEAN)
if (SCAN_ALLMATCHES || ret == CL_CLEAN)
tmp = 0;
else
goto leave;

@ -378,9 +378,9 @@ static int msxml_parse_element(struct msxml_ctx *mxctx, xmlTextReaderPtr reader,
switch (node_type) {
case XML_READER_TYPE_ELEMENT:
ret = msxml_parse_element(mxctx, reader, rlvl+1, thisjobj ? thisjobj : parent);
if (ret != CL_SUCCESS || (!SCAN_ALL && ret == CL_VIRUS)) {
if (ret != CL_SUCCESS || (!SCAN_ALLMATCHES && ret == CL_VIRUS)) {
return ret;
} else if (SCAN_ALL && ret == CL_VIRUS) {
} else if (SCAN_ALLMATCHES && ret == CL_VIRUS) {
virus = 1;
}
break;
@ -429,9 +429,9 @@ static int msxml_parse_element(struct msxml_ctx *mxctx, xmlTextReaderPtr reader,
if (!(ctx->engine->keeptmp))
cli_unlink(tempfile);
free(tempfile);
if (ret != CL_SUCCESS && (ret != CL_VIRUS || (!SCAN_ALL && ret == CL_VIRUS))) {
if (ret != CL_SUCCESS && (ret != CL_VIRUS || (!SCAN_ALLMATCHES && ret == CL_VIRUS))) {
return ret;
} else if (SCAN_ALL && ret == CL_VIRUS) {
} else if (SCAN_ALLMATCHES && ret == CL_VIRUS) {
virus = 1;
}
}
@ -476,9 +476,9 @@ static int msxml_parse_element(struct msxml_ctx *mxctx, xmlTextReaderPtr reader,
if (!(ctx->engine->keeptmp))
cli_unlink(tempfile);
free(tempfile);
if (ret != CL_SUCCESS && (ret != CL_VIRUS || (!SCAN_ALL && ret == CL_VIRUS))) {
if (ret != CL_SUCCESS && (ret != CL_VIRUS || (!SCAN_ALLMATCHES && ret == CL_VIRUS))) {
return ret;
} else if (SCAN_ALL && ret == CL_VIRUS) {
} else if (SCAN_ALLMATCHES && ret == CL_VIRUS) {
virus = 1;
}
}
@ -500,9 +500,9 @@ static int msxml_parse_element(struct msxml_ctx *mxctx, xmlTextReaderPtr reader,
#else
ret = mxctx->comment_cb((const char *)node_value, ctx, NULL, mxctx->comment_data);
#endif
if (ret != CL_SUCCESS && (ret != CL_VIRUS || (!SCAN_ALL && ret == CL_VIRUS))) {
if (ret != CL_SUCCESS && (ret != CL_VIRUS || (!SCAN_ALLMATCHES && ret == CL_VIRUS))) {
return ret;
} else if (SCAN_ALL && ret == CL_VIRUS) {
} else if (SCAN_ALLMATCHES && ret == CL_VIRUS) {
virus = 1;
}
@ -615,7 +615,7 @@ int cli_msxml_parse_document(cli_ctx *ctx, xmlTextReaderPtr reader, const struct
ret = msxml_parse_element(mxctx, reader, 0, NULL);
#endif
if (ret == CL_SUCCESS);
else if (SCAN_ALL && ret == CL_VIRUS) {
else if (SCAN_ALLMATCHES && ret == CL_VIRUS) {
/* non-allmatch simply propagates it down to return through ret */
virus = 1;
} else if (ret == CL_VIRUS || ret == CL_ETIMEOUT || ret == CL_BREAK) {

@ -651,7 +651,7 @@ ole2_walk_property_tree(ole2_header_t * hdr, const char *dir, int32_t prop_index
if ((int)(prop_block[idx].child) != -1) {
ret = ole2_walk_property_tree(hdr, dir, prop_block[idx].child, handler, rec_level + 1, file_count, ctx, scansize);
if (ret != CL_SUCCESS) {
if ((ctx->options & CL_SCAN_ALLMATCHES) && (ret == CL_VIRUS)) {
if (SCAN_ALLMATCHES && (ret == CL_VIRUS)) {
func_ret = ret;
}
else {
@ -686,7 +686,7 @@ ole2_walk_property_tree(ole2_header_t * hdr, const char *dir, int32_t prop_index
ole2_listmsg("running file handler\n");
ret = handler(hdr, &prop_block[idx], dir, ctx);
if (ret != CL_SUCCESS) {
if ((ctx->options & CL_SCAN_ALLMATCHES) && (ret == CL_VIRUS)) {
if (SCAN_ALLMATCHES && (ret == CL_VIRUS)) {
func_ret = ret;
}
else {
@ -701,7 +701,7 @@ ole2_walk_property_tree(ole2_header_t * hdr, const char *dir, int32_t prop_index
if ((int)(prop_block[idx].child) != -1) {
ret = ole2_walk_property_tree(hdr, dir, prop_block[idx].child, handler, rec_level, file_count, ctx, scansize);
if (ret != CL_SUCCESS) {
if ((ctx->options & CL_SCAN_ALLMATCHES) && (ret == CL_VIRUS)) {
if (SCAN_ALLMATCHES && (ret == CL_VIRUS)) {
func_ret = ret;
}
else {
@ -727,7 +727,7 @@ ole2_walk_property_tree(ole2_header_t * hdr, const char *dir, int32_t prop_index
ole2_listmsg("directory node\n");
if (dir) {
#if HAVE_JSON
if ((ctx->options & CL_SCAN_FILE_PROPERTIES) && (ctx->wrkproperty != NULL)) {
if (SCAN_COLLECT_METADATA && (ctx->wrkproperty != NULL)) {
if (!json_object_object_get_ex(ctx->wrkproperty, "DigitalSignatures", NULL)) {
name = get_property_name2(prop_block[idx].name, prop_block[idx].name_size);
if (name) {
@ -758,7 +758,7 @@ ole2_walk_property_tree(ole2_header_t * hdr, const char *dir, int32_t prop_index
if ((int)(prop_block[idx].child) != -1) {
ret = ole2_walk_property_tree(hdr, dirname, prop_block[idx].child, handler, rec_level + 1, file_count, ctx, scansize);
if (ret != CL_SUCCESS) {
if ((ctx->options & CL_SCAN_ALLMATCHES) && (ret == CL_VIRUS)) {
if (SCAN_ALLMATCHES && (ret == CL_VIRUS)) {
func_ret = ret;
}
else {
@ -926,7 +926,7 @@ handler_enum(ole2_header_t * hdr, property_t * prop, const char *dir, cli_ctx *
name = get_property_name2(prop->name, prop->name_size);
if (name) {
if (ctx->options & CL_SCAN_FILE_PROPERTIES && ctx->wrkproperty != NULL) {
if (SCAN_COLLECT_METADATA && ctx->wrkproperty != NULL) {
arrobj = cli_jsonarray(ctx->wrkproperty, "Streams");
if (NULL == arrobj) {
cli_warnmsg("ole2: no memory for streams list or streams is not an array\n");
@ -1340,7 +1340,7 @@ handler_otf(ole2_header_t * hdr, property_t * prop, const char *dir, cli_ctx * c
#if HAVE_JSON
/* JSON Output Summary Information */
if (ctx->options & CL_SCAN_FILE_PROPERTIES && ctx->properties != NULL) {
if (SCAN_COLLECT_METADATA && (ctx->properties != NULL)) {
if (!name)
name = get_property_name2(prop->name, prop->name_size);
if (name) {

@ -936,8 +936,8 @@ int cl_engine_settings_free(struct cl_settings *settings)
void cli_check_blockmax(cli_ctx *ctx, int rc)
{
if (BLOCKMAX && !ctx->limit_exceeded) {
cli_append_virus (ctx, "Heuristic.Limits.Exceeded");
if (SCAN_HEURISTIC_EXCEEDS_MAX && !ctx->limit_exceeded) {
cli_append_virus (ctx, "Heuristics.Limits.Exceeded");
ctx->limit_exceeded = 1;
cli_dbgmsg ("Limit %s Exceeded: scanning may be incomplete and additional analysis needed for this file.\n",
cl_strerror(rc));
@ -1096,9 +1096,9 @@ void cli_virus_found_cb(cli_ctx * ctx)
int cli_append_possibly_unwanted(cli_ctx * ctx, const char * virname)
{
if (SCAN_ALL)
if (SCAN_ALLMATCHES)
return cli_append_virus(ctx, virname);
else if (ctx->options & CL_SCAN_HEURISTIC_PRECEDENCE)
else if (SCAN_HEURISTIC_PRECEDENCE)
return cli_append_virus(ctx, virname);
else if (ctx->num_viruses == 0 && ctx->virname != NULL && *ctx->virname == NULL) {
ctx->found_possibly_unwanted = 1;
@ -1114,16 +1114,16 @@ int cli_append_virus(cli_ctx * ctx, const char * virname)
return CL_CLEAN;
if (ctx->fmap != NULL && (*ctx->fmap) != NULL && CL_VIRUS != cli_checkfp_virus((*ctx->fmap)->maphash, (*ctx->fmap)->len, ctx, virname))
return CL_CLEAN;
if (!SCAN_ALL && ctx->num_viruses != 0)
if (ctx->options & CL_SCAN_HEURISTIC_PRECEDENCE)
if (!SCAN_ALLMATCHES && ctx->num_viruses != 0)
if (SCAN_HEURISTIC_PRECEDENCE)
return CL_CLEAN;
if (ctx->limit_exceeded == 0 || SCAN_ALL) {
if (ctx->limit_exceeded == 0 || SCAN_ALLMATCHES) {
ctx->num_viruses++;
*ctx->virname = virname;
cli_virus_found_cb(ctx);
}
#if HAVE_JSON
if (SCAN_PROPERTIES && ctx->wrkproperty) {
if (SCAN_COLLECT_METADATA && ctx->wrkproperty) {
json_object *arrobj, *virobj;
if (!json_object_object_get_ex(ctx->wrkproperty, "Viruses", &arrobj)) {
arrobj = json_object_new_array();

@ -160,7 +160,7 @@ typedef struct cli_ctx_tag {
const struct cli_matcher *root;
const struct cl_engine *engine;
unsigned long scansize;
unsigned int options;
struct cl_scan_options *options;
unsigned int recursion;
unsigned int scannedfiles;
unsigned int found_possibly_unwanted;
@ -490,24 +490,37 @@ extern int (*cli_unrar_extract_next)(unrar_state_t *state, const char *dirname);
extern void (*cli_unrar_close)(unrar_state_t *state);
extern int have_rar;
#define SCAN_ARCHIVE (ctx->options & CL_SCAN_ARCHIVE)
#define SCAN_MAIL (ctx->options & CL_SCAN_MAIL)
#define SCAN_OLE2 (ctx->options & CL_SCAN_OLE2)
#define SCAN_PDF (ctx->options & CL_SCAN_PDF)
#define SCAN_HTML (ctx->options & CL_SCAN_HTML)
#define SCAN_PE (ctx->options & CL_SCAN_PE)
#define SCAN_ELF (ctx->options & CL_SCAN_ELF)
#define SCAN_ALGO (ctx->options & CL_SCAN_ALGORITHMIC)
#define DETECT_ENCRYPTED (ctx->options & CL_SCAN_BLOCKENCRYPTED)
#define BLOCKMAX (ctx->options & CL_SCAN_BLOCKMAX)
#define DETECT_BROKEN (ctx->options & CL_SCAN_BLOCKBROKEN)
#define BLOCK_MACROS (ctx->options & CL_SCAN_BLOCKMACROS)
#define SCAN_STRUCTURED (ctx->options & CL_SCAN_STRUCTURED)
#define SCAN_ALL (ctx->options & CL_SCAN_ALLMATCHES)
#define SCAN_SWF (ctx->options & CL_SCAN_SWF)
#define SCAN_PROPERTIES (ctx->options & CL_SCAN_FILE_PROPERTIES)
#define SCAN_XMLDOCS (ctx->options & CL_SCAN_XMLDOCS)
#define SCAN_HWP3 (ctx->options & CL_SCAN_HWP3)
#define SCAN_ALLMATCHES (ctx->options->general & CL_SCAN_GENERAL_ALLMATCHES)
#define SCAN_COLLECT_METADATA (ctx->options->general & CL_SCAN_GENERAL_COLLECT_METADATA)
#define SCAN_HEURISTICS (ctx->options->general & CL_SCAN_GENERAL_HEURISTICS)
#define SCAN_HEURISTIC_PRECEDENCE (ctx->options->general & CL_SCAN_GENERAL_HEURISTIC_PRECEDENCE)
#define SCAN_PARSE_ARCHIVE (ctx->options->parse & CL_SCAN_PARSE_ARCHIVE)
#define SCAN_PARSE_ELF (ctx->options->parse & CL_SCAN_PARSE_ELF)
#define SCAN_PARSE_PDF (ctx->options->parse & CL_SCAN_PARSE_PDF)
#define SCAN_PARSE_SWF (ctx->options->parse & CL_SCAN_PARSE_SWF)
#define SCAN_PARSE_HWP3 (ctx->options->parse & CL_SCAN_PARSE_HWP3)
#define SCAN_PARSE_XMLDOCS (ctx->options->parse & CL_SCAN_PARSE_XMLDOCS)
#define SCAN_PARSE_MAIL (ctx->options->parse & CL_SCAN_PARSE_MAIL)
#define SCAN_PARSE_OLE2 (ctx->options->parse & CL_SCAN_PARSE_OLE2)
#define SCAN_PARSE_HTML (ctx->options->parse & CL_SCAN_PARSE_HTML)
#define SCAN_PARSE_PE (ctx->options->parse & CL_SCAN_PARSE_PE)
#define SCAN_HEURISTIC_BROKEN (ctx->options->heuristic & CL_SCAN_HEURISTIC_BROKEN)
#define SCAN_HEURISTIC_EXCEEDS_MAX (ctx->options->heuristic & CL_SCAN_HEURISTIC_EXCEEDS_MAX)
#define SCAN_HEURISTIC_PHISHING_SSL_MISMATCH (ctx->options->heuristic & CL_SCAN_HEURISTIC_PHISHING_SSL_MISMATCH)
#define SCAN_HEURISTIC_PHISHING_CLOAK (ctx->options->heuristic & CL_SCAN_HEURISTIC_PHISHING_CLOAK)
#define SCAN_HEURISTIC_MACROS (ctx->options->heuristic & CL_SCAN_HEURISTIC_MACROS)
#define SCAN_HEURISTIC_ENCRYPTED (ctx->options->heuristic & CL_SCAN_HEURISTIC_ENCRYPTED)
#define SCAN_HEURISTIC_PARTITION_INTXN (ctx->options->heuristic & CL_SCAN_HEURISTIC_PARTITION_INTXN)
#define SCAN_HEURISTIC_STRUCTURED (ctx->options->heuristic & CL_SCAN_HEURISTIC_STRUCTURED)
#define SCAN_HEURISTIC_STRUCTURED_SSN_NORMAL (ctx->options->heuristic & CL_SCAN_HEURISTIC_STRUCTURED_SSN_NORMAL)
#define SCAN_HEURISTIC_STRUCTURED_SSN_STRIPPED (ctx->options->heuristic & CL_SCAN_HEURISTIC_STRUCTURED_SSN_STRIPPED)
#define SCAN_MAIL_PARTIAL_MESSAGE (ctx->options->mail & CL_SCAN_MAIL_PARTIAL_MESSAGE)
#define SCAN_DEV_COLLECT_SHA (ctx->options->dev & CL_SCAN_DEV_COLLECT_SHA)
#define SCAN_DEV_COLLECT_PERF_INFO (ctx->options->dev & CL_SCAN_DEV_COLLECT_PERFORMANCE_INFO)
/* based on macros from A. Melnikoff */
#define cbswap16(v) (((v & 0xff) << 8) | (((v) >> 8) & 0xff))

@ -1362,6 +1362,7 @@ static int pdf_scan_contents(int fd, struct pdf_struct *pdf)
int pdf_extract_obj(struct pdf_struct *pdf, struct pdf_obj *obj, uint32_t flags)
{
cli_ctx *ctx = pdf->ctx;
char fullname[NAME_MAX + 1];
int fout;
ptrdiff_t sum = 0;
@ -1618,7 +1619,7 @@ int pdf_extract_obj(struct pdf_struct *pdf, struct pdf_obj *obj, uint32_t flags)
if (dparams)
pdf_free_dict(dparams);
if (sum < 0 || (rc == CL_VIRUS && !(pdf->ctx->options & CL_SCAN_ALLMATCHES))) {
if (sum < 0 || ((rc == CL_VIRUS) && !SCAN_ALLMATCHES)) {
sum = 0; /* prevents post-filter scan */
break;
}
@ -1725,7 +1726,7 @@ int pdf_extract_obj(struct pdf_struct *pdf, struct pdf_obj *obj, uint32_t flags)
if (rc2 == CL_VIRUS || rc == CL_SUCCESS)
rc = rc2;
if ((rc == CL_CLEAN) || ((rc == CL_VIRUS) && (pdf->ctx->options & CL_SCAN_ALLMATCHES))) {
if ((rc == CL_CLEAN) || ((rc == CL_VIRUS) && SCAN_ALLMATCHES)) {
unsigned int dumpid = 0;
for (dumpid = 0; dumpid < pdf->nobjs; dumpid++) {
if (pdf->objs[dumpid] == obj)
@ -1736,7 +1737,7 @@ int pdf_extract_obj(struct pdf_struct *pdf, struct pdf_obj *obj, uint32_t flags)
rc = rc2;
}
if (((rc == CL_CLEAN) || ((rc == CL_VIRUS) && (pdf->ctx->options & CL_SCAN_ALLMATCHES))) && (obj->flags & (1 << OBJ_CONTENTS))) {
if (((rc == CL_CLEAN) || ((rc == CL_VIRUS) && SCAN_ALLMATCHES)) && (obj->flags & (1 << OBJ_CONTENTS))) {
lseek(fout, 0, SEEK_SET);
cli_dbgmsg("pdf_extract_obj: dumping contents %u %u\n", obj->id>>8, obj->id&0xff);
@ -2480,9 +2481,10 @@ static char *pdf_readstring(const char *q0, int len, const char *key, unsigned *
return s0;
}
if (*q == '<') {
if ((*q == '<') && (len >= 3)) {
start = ++q;
q = memchr(q+1, '>', len);
len -= 1;
q = memchr(q+1, '>', len-1);
if (!q)
return NULL;
@ -3065,6 +3067,7 @@ cl_error_t pdf_find_and_extract_objs(struct pdf_struct *pdf, uint32_t *alerts)
int foundobj = 0;
unsigned int i = 0, j = 0;
uint32_t badobjects = 0;
cli_ctx *ctx = pdf->ctx;
/* parse PDF and find obj offsets */
while (CL_BREAK != (rv = pdf_findobj(pdf))) {
@ -3096,7 +3099,7 @@ cl_error_t pdf_find_and_extract_objs(struct pdf_struct *pdf, uint32_t *alerts)
(pdf->flags & (1 << DECRYPTABLE_PDF)) ?
"decryptable" : "not decryptable, stream will probably fail to decompress");
if ((pdf->ctx->options & CL_SCAN_BLOCKENCRYPTED) &&
if (SCAN_HEURISTIC_ENCRYPTED &&
(pdf->flags & (1 << ENCRYPTED_PDF)) &&
!(pdf->flags & (1 << DECRYPTABLE_PDF)))
{
@ -3106,7 +3109,7 @@ cl_error_t pdf_find_and_extract_objs(struct pdf_struct *pdf, uint32_t *alerts)
status = cli_append_virus(pdf->ctx, "Heuristics.Encrypted.PDF");
if (status == CL_VIRUS) {
alerts++;
if (pdf->ctx->options & CL_SCAN_ALLMATCHES)
if (SCAN_ALLMATCHES)
status = CL_CLEAN;
}
}
@ -3116,7 +3119,7 @@ cl_error_t pdf_find_and_extract_objs(struct pdf_struct *pdf, uint32_t *alerts)
cli_dbgmsg("pdf_find_and_extract_objs: (parsed hooks) returned %d\n", status);
if (status == CL_VIRUS) {
alerts++;
if (pdf->ctx->options & CL_SCAN_ALLMATCHES) {
if (SCAN_ALLMATCHES) {
status = CL_CLEAN;
}
}
@ -3144,7 +3147,7 @@ cl_error_t pdf_find_and_extract_objs(struct pdf_struct *pdf, uint32_t *alerts)
break;
case CL_VIRUS:
alerts++;
if (pdf->ctx->options & CL_SCAN_ALLMATCHES) {
if (SCAN_ALLMATCHES) {
status = CL_CLEAN;
}
break;
@ -3351,7 +3354,7 @@ int cli_pdf(const char *dir, cli_ctx *ctx, off_t offset)
pdf.startoff = offset;
rc = run_pdf_hooks(&pdf, PDF_PHASE_PRE, -1, -1);
if ((rc == CL_VIRUS) && SCAN_ALL) {
if ((rc == CL_VIRUS) && SCAN_ALLMATCHES) {
cli_dbgmsg("cli_pdf: (pre hooks) returned %d\n", rc);
alerts++;
rc = CL_CLEAN;
@ -3383,12 +3386,12 @@ int cli_pdf(const char *dir, cli_ctx *ctx, off_t offset)
rc = run_pdf_hooks(&pdf, PDF_PHASE_END, -1, -1);
if (rc == CL_VIRUS) {
alerts++;
if (SCAN_ALL) {
if (SCAN_ALLMATCHES) {
rc = CL_CLEAN;
}
}
if (!rc && SCAN_ALGO && (ctx->dconf->other & OTHER_CONF_PDFNAMEOBJ)) {
if (!rc && SCAN_HEURISTICS && (ctx->dconf->other & OTHER_CONF_PDFNAMEOBJ)) {
if (pdf.flags & (1 << ESCAPED_COMMON_PDFNAME)) {
/* for example /Fl#61te#44#65#63#6f#64#65 instead of /FlateDecode */
cli_append_possibly_unwanted(ctx, "Heuristics.PDF.ObfuscatedNameObject");
@ -3657,6 +3660,7 @@ static void CCITTFaxDecode_cb(struct pdf_struct *pdf, struct pdf_obj *obj, struc
#if HAVE_JSON
static void JBIG2Decode_cb(struct pdf_struct *pdf, struct pdf_obj *obj, struct pdfname_action *act)
{
cli_ctx *ctx = pdf->ctx;
struct json_object *pdfobj, *jbig2arr;
UNUSEDPARAM(obj);
@ -3665,7 +3669,7 @@ static void JBIG2Decode_cb(struct pdf_struct *pdf, struct pdf_obj *obj, struct p
if (!(pdf))
return;
if (!(pdf->ctx->options & CL_SCAN_FILE_PROPERTIES))
if (!(SCAN_COLLECT_METADATA))
return;
if (!(pdf->ctx->wrkproperty))
@ -3753,6 +3757,7 @@ static void Sig_cb(struct pdf_struct *pdf, struct pdf_obj *obj, struct pdfname_a
#if HAVE_JSON
static void JavaScript_cb(struct pdf_struct *pdf, struct pdf_obj *obj, struct pdfname_action *act)
{
cli_ctx *ctx = pdf->ctx;
struct json_object *pdfobj, *jbig2arr;
UNUSEDPARAM(act);
@ -3760,7 +3765,7 @@ static void JavaScript_cb(struct pdf_struct *pdf, struct pdf_obj *obj, struct pd
if (!(pdf))
return;
if (!(pdf->ctx->options & CL_SCAN_FILE_PROPERTIES))
if (!(SCAN_COLLECT_METADATA))
return;
if (!(pdf->ctx->wrkproperty))
@ -3822,12 +3827,14 @@ static void Page_cb(struct pdf_struct *pdf, struct pdf_obj *obj, struct pdfname_
#if HAVE_JSON
static void Author_cb(struct pdf_struct *pdf, struct pdf_obj *obj, struct pdfname_action *act)
{
cli_ctx *ctx = pdf->ctx;
UNUSEDPARAM(act);
if (!(pdf))
return;
if (!(pdf->ctx->options & CL_SCAN_FILE_PROPERTIES))
if (!(SCAN_COLLECT_METADATA))
return;
if (!(pdf->stats.author)) {
@ -3845,12 +3852,14 @@ static void Author_cb(struct pdf_struct *pdf, struct pdf_obj *obj, struct pdfnam
#if HAVE_JSON
static void Creator_cb(struct pdf_struct *pdf, struct pdf_obj *obj, struct pdfname_action *act)
{
cli_ctx *ctx = pdf->ctx;
UNUSEDPARAM(act);
if (!(pdf))
return;
if (!(pdf->ctx->options & CL_SCAN_FILE_PROPERTIES))
if (!(SCAN_COLLECT_METADATA))
return;
if (!(pdf->stats.creator)) {
@ -3868,12 +3877,14 @@ static void Creator_cb(struct pdf_struct *pdf, struct pdf_obj *obj, struct pdfna
#if HAVE_JSON
static void ModificationDate_cb(struct pdf_struct *pdf, struct pdf_obj *obj, struct pdfname_action *act)
{
cli_ctx *ctx = pdf->ctx;
UNUSEDPARAM(act);
if (!(pdf))
return;
if (!(pdf->ctx->options & CL_SCAN_FILE_PROPERTIES))
if (!(SCAN_COLLECT_METADATA))
return;
if (!(pdf->stats.modificationdate)) {
@ -3891,12 +3902,14 @@ static void ModificationDate_cb(struct pdf_struct *pdf, struct pdf_obj *obj, str
#if HAVE_JSON
static void CreationDate_cb(struct pdf_struct *pdf, struct pdf_obj *obj, struct pdfname_action *act)
{
cli_ctx *ctx = pdf->ctx;
UNUSEDPARAM(act);
if (!(pdf))
return;
if (!(pdf->ctx->options & CL_SCAN_FILE_PROPERTIES))
if (!(SCAN_COLLECT_METADATA))
return;
if (!(pdf->stats.creationdate)) {
@ -3914,12 +3927,14 @@ static void CreationDate_cb(struct pdf_struct *pdf, struct pdf_obj *obj, struct
#if HAVE_JSON
static void Producer_cb(struct pdf_struct *pdf, struct pdf_obj *obj, struct pdfname_action *act)
{
cli_ctx *ctx = pdf->ctx;
UNUSEDPARAM(act);
if (!(pdf))
return;
if (!(pdf->ctx->options & CL_SCAN_FILE_PROPERTIES))
if (!(SCAN_COLLECT_METADATA))
return;
if (!(pdf->stats.producer)) {
@ -3937,12 +3952,14 @@ static void Producer_cb(struct pdf_struct *pdf, struct pdf_obj *obj, struct pdfn
#if HAVE_JSON
static void Title_cb(struct pdf_struct *pdf, struct pdf_obj *obj, struct pdfname_action *act)
{
cli_ctx *ctx = pdf->ctx;
UNUSEDPARAM(act);
if (!(pdf))
return;
if (!(pdf->ctx->options & CL_SCAN_FILE_PROPERTIES))
if (!(SCAN_COLLECT_METADATA))
return;
if (!(pdf->stats.title)) {
@ -3960,12 +3977,14 @@ static void Title_cb(struct pdf_struct *pdf, struct pdf_obj *obj, struct pdfname
#if HAVE_JSON
static void Keywords_cb(struct pdf_struct *pdf, struct pdf_obj *obj, struct pdfname_action *act)
{
cli_ctx *ctx = pdf->ctx;
UNUSEDPARAM(act);
if (!(pdf))
return;
if (!(pdf->ctx->options & CL_SCAN_FILE_PROPERTIES))
if (!(SCAN_COLLECT_METADATA))
return;
if (!(pdf->stats.keywords)) {
@ -3983,12 +4002,14 @@ static void Keywords_cb(struct pdf_struct *pdf, struct pdf_obj *obj, struct pdfn
#if HAVE_JSON
static void Subject_cb(struct pdf_struct *pdf, struct pdf_obj *obj, struct pdfname_action *act)
{
cli_ctx *ctx = pdf->ctx;
UNUSEDPARAM(act);
if (!(pdf))
return;
if (!(pdf->ctx->options & CL_SCAN_FILE_PROPERTIES))
if (!(SCAN_COLLECT_METADATA))
return;
if (!(pdf->stats.subject)) {
@ -4045,6 +4066,7 @@ static void XFA_cb(struct pdf_struct *pdf, struct pdf_obj *obj, struct pdfname_a
#if HAVE_JSON
static void Pages_cb(struct pdf_struct *pdf, struct pdf_obj *obj, struct pdfname_action *act)
{
cli_ctx *ctx = pdf->ctx;
struct pdf_array *array;
const char *objstart = (obj->objstm) ? (const char *)(obj->start + obj->objstm->streambuf)
: (const char *)(obj->start + pdf->map);
@ -4059,7 +4081,7 @@ static void Pages_cb(struct pdf_struct *pdf, struct pdf_obj *obj, struct pdfname
if (!(pdf) || !(pdf->ctx->wrkproperty))
return;
if (!(pdf->ctx->options & CL_SCAN_FILE_PROPERTIES))
if (!(SCAN_COLLECT_METADATA))
return;
objsize = obj_size(pdf, obj, 1);
@ -4112,6 +4134,7 @@ cleanup:
#if HAVE_JSON
static void Colors_cb(struct pdf_struct *pdf, struct pdf_obj *obj, struct pdfname_action *act)
{
cli_ctx *ctx = pdf->ctx;
json_object *colorsobj, *pdfobj;
unsigned long ncolors;
char *p1;
@ -4124,7 +4147,7 @@ static void Colors_cb(struct pdf_struct *pdf, struct pdf_obj *obj, struct pdfnam
if (!(pdf) || !(pdf->ctx) || !(pdf->ctx->wrkproperty))
return;
if (!(pdf->ctx->options & CL_SCAN_FILE_PROPERTIES))
if (!(SCAN_COLLECT_METADATA))
return;
objsize = obj_size(pdf, obj, 1);
@ -4167,6 +4190,7 @@ static void Colors_cb(struct pdf_struct *pdf, struct pdf_obj *obj, struct pdfnam
#if HAVE_JSON
static void pdf_export_json(struct pdf_struct *pdf)
{
cli_ctx *ctx = pdf->ctx;
json_object *pdfobj;
unsigned long i;
@ -4177,7 +4201,7 @@ static void pdf_export_json(struct pdf_struct *pdf)
goto cleanup;
}
if (!(pdf->ctx->options & CL_SCAN_FILE_PROPERTIES) || !(pdf->ctx->wrkproperty)) {
if (!(SCAN_COLLECT_METADATA) || !(pdf->ctx->wrkproperty)) {
goto cleanup;
}

@ -227,6 +227,7 @@ static ptrdiff_t pdf_decodestream_internal(
cl_error_t vir = CL_CLEAN;
cl_error_t retval = CL_SUCCESS;
ptrdiff_t bytes_scanned = -1;
cli_ctx *ctx = pdf->ctx;
const char *filter = NULL;
int i;
@ -315,7 +316,7 @@ static ptrdiff_t pdf_decodestream_internal(
}
if (retval != CL_SUCCESS) {
if (retval == CL_VIRUS && pdf->ctx->options & CL_SCAN_ALLMATCHES) {
if (retval == CL_VIRUS && SCAN_ALLMATCHES) {
vir = CL_VIRUS;
} else {
const char* reason;

@ -223,7 +223,7 @@ FSGSTUFF; \
#define CLI_UNPRESULTSFSG1(NAME,EXPR,GOOD,FREEME) CLI_UNPRESULTS_(NAME,FSGCASE(NAME,free(sections)),EXPR,GOOD,FREEME)
#define CLI_UNPRESULTSFSG2(NAME,EXPR,GOOD,FREEME) CLI_UNPRESULTS_(NAME,FSGCASE(NAME,(void)0),EXPR,GOOD,FREEME)
#define DETECT_BROKEN_PE (DETECT_BROKEN && !ctx->corrupted_input)
#define DETECT_BROKEN_PE (SCAN_HEURISTIC_BROKEN && !ctx->corrupted_input)
extern const unsigned int hashlen[];
@ -598,7 +598,7 @@ static int scan_pe_mdb (cli_ctx * ctx, struct cli_exe_section *exe_section)
if (ret != CL_CLEAN) {
if (ret != CL_VIRUS)
break;
else if (!SCAN_ALL)
else if (!SCAN_ALLMATCHES)
break;
}
}
@ -607,7 +607,7 @@ static int scan_pe_mdb (cli_ctx * ctx, struct cli_exe_section *exe_section)
if (ret != CL_CLEAN) {
if (ret != CL_VIRUS)
break;
else if (!SCAN_ALL)
else if (!SCAN_ALLMATCHES)
break;
}
}
@ -2573,7 +2573,7 @@ static int scan_pe_imp(cli_ctx *ctx, struct pe_image_data_dir *dirs, struct cli_
if (ret != CL_CLEAN) {
if (ret != CL_VIRUS)
break;
else if (!SCAN_ALL)
else if (!SCAN_ALLMATCHES)
break;
}
}
@ -2582,7 +2582,7 @@ static int scan_pe_imp(cli_ctx *ctx, struct pe_image_data_dir *dirs, struct cli_
if (ret != CL_CLEAN) {
if (ret != CL_VIRUS)
break;
else if (!SCAN_ALL)
else if (!SCAN_ALLMATCHES)
break;
}
}
@ -2758,7 +2758,7 @@ int cli_scanpe(cli_ctx *ctx)
return CL_ETIMEOUT;
}
if (ctx->options & CL_SCAN_FILE_PROPERTIES) {
if (SCAN_COLLECT_METADATA) {
pe_json = get_pe_property(ctx);
}
#endif
@ -3119,7 +3119,7 @@ int cli_scanpe(cli_ctx *ctx)
}
#if HAVE_JSON
if (ctx->options & CL_SCAN_FILE_PROPERTIES) {
if (SCAN_COLLECT_METADATA) {
snprintf(jsonbuf, sizeof(jsonbuf), "0x%x", vep);
if (pe_json != NULL)
cli_jsonstr(pe_json, "EntryPoint", jsonbuf);
@ -3349,7 +3349,7 @@ int cli_scanpe(cli_ctx *ctx)
}
if (exe_sections[i].rsz) { /* Don't bother with virtual only sections */
if(SCAN_ALGO && (DCONF & PE_CONF_POLIPOS) && !*sname && exe_sections[i].vsz > 40000 && exe_sections[i].vsz < 70000 && exe_sections[i].chr == 0xe0000060) polipos = i;
if(SCAN_HEURISTICS && (DCONF & PE_CONF_POLIPOS) && !*sname && exe_sections[i].vsz > 40000 && exe_sections[i].vsz < 70000 && exe_sections[i].chr == 0xe0000060) polipos = i;
/* check hash section sigs */
if((DCONF & PE_CONF_MD5SECT) && ctx->engine->hm_mdb) {
@ -3516,7 +3516,7 @@ int cli_scanpe(cli_ctx *ctx)
cli_warnmsg("cli_scanpe: NULL argument supplied\n");
break;
case CL_VIRUS:
if (SCAN_ALL)
if (SCAN_ALLMATCHES)
break;
/* intentional fall-through */
case CL_BREAK:
@ -3530,7 +3530,7 @@ int cli_scanpe(cli_ctx *ctx)
/* Attempt to detect some popular polymorphic viruses */
/* W32.Parite.B */
if(SCAN_ALGO && (DCONF & PE_CONF_PARITE) && !dll && epsize == 4096 && ep == exe_sections[nsections - 1].raw) {
if(SCAN_HEURISTICS && (DCONF & PE_CONF_PARITE) && !dll && epsize == 4096 && ep == exe_sections[nsections - 1].raw) {
const char *pt = cli_memstr(epbuff, 4040, "\x47\x65\x74\x50\x72\x6f\x63\x41\x64\x64\x72\x65\x73\x73\x00", 15);
if(pt) {
pt += 15;
@ -3538,7 +3538,7 @@ int cli_scanpe(cli_ctx *ctx)
ret = cli_append_virus(ctx,"Heuristics.W32.Parite.B");
if (ret != CL_CLEAN) {
if (ret == CL_VIRUS) {
if (!SCAN_ALL) {
if (!SCAN_ALLMATCHES) {
free(exe_sections);
return ret;
}
@ -3554,7 +3554,7 @@ int cli_scanpe(cli_ctx *ctx)
}
/* Kriz */
if(SCAN_ALGO && (DCONF & PE_CONF_KRIZ) && epsize >= 200 && CLI_ISCONTAINED(exe_sections[nsections - 1].raw, exe_sections[nsections - 1].rsz, ep, 0x0fd2) && epbuff[1]=='\x9c' && epbuff[2]=='\x60') {
if(SCAN_HEURISTICS && (DCONF & PE_CONF_KRIZ) && epsize >= 200 && CLI_ISCONTAINED(exe_sections[nsections - 1].raw, exe_sections[nsections - 1].rsz, ep, 0x0fd2) && epbuff[1]=='\x9c' && epbuff[2]=='\x60') {
enum {KZSTRASH,KZSCDELTA,KZSPDELTA,KZSGETSIZE,KZSXORPRFX,KZSXOR,KZSDDELTA,KZSLOOP,KZSTOP};
uint8_t kzs[] = {KZSTRASH,KZSCDELTA,KZSPDELTA,KZSGETSIZE,KZSTRASH,KZSXORPRFX,KZSXOR,KZSTRASH,KZSDDELTA,KZSTRASH,KZSLOOP,KZSTOP};
uint8_t *kzstate = kzs;
@ -3663,7 +3663,7 @@ int cli_scanpe(cli_ctx *ctx)
ret = cli_append_virus(ctx,"Heuristics.W32.Kriz");
if (ret != CL_CLEAN) {
if (ret == CL_VIRUS) {
if (!SCAN_ALL) {
if (!SCAN_ALLMATCHES) {
free(exe_sections);
return ret;
}
@ -3682,7 +3682,7 @@ int cli_scanpe(cli_ctx *ctx)
}
/* W32.Magistr.A/B */
if(SCAN_ALGO && (DCONF & PE_CONF_MAGISTR) && !dll && (nsections>1) && (exe_sections[nsections - 1].chr & 0x80000000)) {
if(SCAN_HEURISTICS && (DCONF & PE_CONF_MAGISTR) && !dll && (nsections>1) && (exe_sections[nsections - 1].chr & 0x80000000)) {
uint32_t rsize, vsize, dam = 0;
vsize = exe_sections[nsections - 1].uvsz;
@ -3701,7 +3701,7 @@ int cli_scanpe(cli_ctx *ctx)
ret = cli_append_virus(ctx, dam ? "Heuristics.W32.Magistr.A.dam" : "Heuristics.W32.Magistr.A");
if (ret != CL_CLEAN) {
if (ret == CL_VIRUS) {
if (!SCAN_ALL) {
if (!SCAN_ALLMATCHES) {
free(exe_sections);
return ret;
}
@ -3723,7 +3723,7 @@ int cli_scanpe(cli_ctx *ctx)
ret = cli_append_virus(ctx,dam ? "Heuristics.W32.Magistr.B.dam" : "Heuristics.W32.Magistr.B");
if (ret != CL_CLEAN) {
if (ret == CL_VIRUS) {
if (!SCAN_ALL) {
if (!SCAN_ALLMATCHES) {
free(exe_sections);
return ret;
}
@ -3800,7 +3800,7 @@ int cli_scanpe(cli_ctx *ctx)
ret = cli_append_virus(ctx,"Heuristics.W32.Polipos.A");
if (ret != CL_CLEAN) {
if (ret == CL_VIRUS) {
if (!SCAN_ALL) {
if (!SCAN_ALLMATCHES) {
free(jumps);
free(exe_sections);
return ret;
@ -3821,7 +3821,7 @@ int cli_scanpe(cli_ctx *ctx)
}
/* Trojan.Swizzor.Gen */
if (SCAN_ALGO && (DCONF & PE_CONF_SWIZZOR) && nsections > 1 && fsize > 64*1024 && fsize < 4*1024*1024) {
if (SCAN_HEURISTICS && (DCONF & PE_CONF_SWIZZOR) && nsections > 1 && fsize > 64*1024 && fsize < 4*1024*1024) {
if(dirs[2].Size) {
struct swizz_stats *stats = cli_calloc(1, sizeof(*stats));
unsigned int m = 1000;
@ -3836,7 +3836,7 @@ int cli_scanpe(cli_ctx *ctx)
ret = cli_append_virus(ctx,"Heuristics.Trojan.Swizzor.Gen");
if (ret != CL_CLEAN) {
if (ret == CL_VIRUS) {
if (!SCAN_ALL) {
if (!SCAN_ALLMATCHES) {
free(stats);
free(exe_sections);
return ret;
@ -4727,7 +4727,7 @@ out_no_petite:
CLI_UNPTEMP("yC",(spinned,exe_sections,0));
CLI_UNPRESULTS("yC",(yc_decrypt(ctx, spinned, fsize, exe_sections, nsections-1, e_lfanew, ndesc, ecx, offset)),0,(spinned,0));
if (SCAN_ALL && yc_unp_num_viruses != ctx->num_viruses) {
if (SCAN_ALLMATCHES && yc_unp_num_viruses != ctx->num_viruses) {
free(exe_sections);
return CL_VIRUS;
}
@ -4991,7 +4991,7 @@ out_no_petite:
return CL_ETIMEOUT;
#endif
if (SCAN_ALL && viruses_found)
if (SCAN_ALLMATCHES && viruses_found)
return CL_VIRUS;
return CL_CLEAN;

@ -739,7 +739,7 @@ int phishingScan(cli_ctx* ctx,tag_arguments_t* hrefs)
if(!pchk || pchk->is_disabled)
return CL_CLEAN;
if(!ctx->found_possibly_unwanted && !SCAN_ALL)
if(!ctx->found_possibly_unwanted && !SCAN_ALLMATCHES)
*ctx->virname=NULL;
#if 0
FILE *f = fopen("/home/edwin/quarantine/urls","r");
@ -785,10 +785,10 @@ int phishingScan(cli_ctx* ctx,tag_arguments_t* hrefs)
urls.link_type |= LINKTYPE_IMAGE;
}
urls.always_check_flags = 0;
if (ctx->options & CL_SCAN_PHISHING_BLOCKSSL) {
if (SCAN_HEURISTIC_PHISHING_SSL_MISMATCH) {
urls.always_check_flags |= CHECK_SSL;
}
if (ctx->options & CL_SCAN_PHISHING_BLOCKCLOAK) {
if (SCAN_HEURISTIC_PHISHING_CLOAK) {
urls.always_check_flags |= CHECK_CLOAKING;
}
string_init_c(&urls.realLink,(char*)hrefs->value[i]);

File diff suppressed because it is too large Load Diff

@ -146,7 +146,7 @@ int cli_parsetiff(cli_ctx *ctx)
if(entry.value + value_size > map->len) {
cli_warnmsg("cli_parsetiff: TFD entry field %u exceeds bounds of TIFF file [%llu > %llu]\n",
i, (long long unsigned)(entry.value + value_size), (long long unsigned)map->len);
return cli_append_virus(ctx, "Heuristic.TIFF.OutOfBoundsAccess");
return cli_append_virus(ctx, "Heuristics.TIFF.OutOfBoundsAccess");
}
}
}

@ -176,7 +176,7 @@ cli_untar(const char *dir, unsigned int posix, cli_ctx *ctx)
if (!ctx->engine->keeptmp)
if (cli_unlink(fullname)) return CL_EUNLINK;
if (ret==CL_VIRUS) {
if (!SCAN_ALL)
if (!SCAN_ALLMATCHES)
return CL_VIRUS;
else
num_viruses++;
@ -300,7 +300,7 @@ cli_untar(const char *dir, unsigned int posix, cli_ctx *ctx)
strncpy(name, block, 100);
name[100] = '\0';
if(cli_matchmeta(ctx, name, size, size, 0, files, 0, NULL) == CL_VIRUS) {
if (!SCAN_ALL)
if (!SCAN_ALLMATCHES)
return CL_VIRUS;
else
num_viruses++;

@ -542,7 +542,7 @@ static unsigned int lhdr(fmap_t *map, uint32_t loff,uint32_t zsize, unsigned int
if(cli_matchmeta(ctx, name, LH_csize, LH_usize, (LH_flags & F_ENCR)!=0, fc, LH_crc32, NULL) == CL_VIRUS) {
*ret = CL_VIRUS;
if (!SCAN_ALL)
if (!SCAN_ALLMATCHES)
return 0;
virus_found = 1;
}
@ -554,10 +554,10 @@ static unsigned int lhdr(fmap_t *map, uint32_t loff,uint32_t zsize, unsigned int
return 0;
}
if(detect_encrypted && (LH_flags & F_ENCR) && DETECT_ENCRYPTED) {
if(detect_encrypted && (LH_flags & F_ENCR) && SCAN_HEURISTIC_ENCRYPTED) {
cli_dbgmsg("cli_unzip: Encrypted files found in archive.\n");
*ret = cli_append_virus(ctx, "Heuristics.Encrypted.Zip");
if ((*ret == CL_VIRUS && !SCAN_ALL) || *ret != CL_CLEAN) {
if ((*ret == CL_VIRUS && !SCAN_ALLMATCHES) || *ret != CL_CLEAN) {
fmap_unneed_off(map, loff, SIZEOF_LH);
return 0;
}
@ -757,7 +757,7 @@ int cli_unzip(cli_ctx *ctx) {
}
#endif
if (ret != CL_CLEAN) {
if (ret == CL_VIRUS && SCAN_ALL) {
if (ret == CL_VIRUS && SCAN_ALLMATCHES) {
ret = CL_CLEAN;
virus_found = 1;
} else
@ -772,7 +772,7 @@ int cli_unzip(cli_ctx *ctx) {
while (ret==CL_CLEAN && lhoff<fsize && (coff=lhdr(map, lhoff, fsize-lhoff, &fu, fc+1, NULL, &ret, ctx, tmpd, 1, zip_scan_cb))) {
fc++;
lhoff+=coff;
if (SCAN_ALL && ret == CL_VIRUS) {
if (SCAN_ALLMATCHES && ret == CL_VIRUS) {
ret = CL_CLEAN;
virus_found = 1;
}

@ -285,7 +285,7 @@ static int xar_get_toc_data_values(xmlTextReaderPtr reader, size_t *length, size
reader - xmlTextReaderPtr
ctx - pointer to cli_ctx
Returns:
CL_SUCCESS - subdoc found and clean scan (or virus found and SCAN_ALL), or no subdocument
CL_SUCCESS - subdoc found and clean scan (or virus found and SCAN_ALLMATCHES), or no subdocument
other - error return code from cli_mem_scandesc()
*/
static int xar_scan_subdocuments(xmlTextReaderPtr reader, cli_ctx *ctx)
@ -316,7 +316,7 @@ static int xar_scan_subdocuments(xmlTextReaderPtr reader, cli_ctx *ctx)
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);
if (rc == CL_VIRUS && SCAN_ALL)
if (rc == CL_VIRUS && SCAN_ALLMATCHES)
rc = CL_SUCCESS;
/* make a file to leave if --leave-temps in effect */
@ -524,7 +524,7 @@ int cli_scanxar(cli_ctx *ctx)
cli_dbgmsg("cli_scanxar: scanning xar TOC xml in memory.\n");
rc = cli_mem_scandesc(toc, hdr.toc_length_decompressed, ctx);
if (rc != CL_SUCCESS) {
if (rc != CL_VIRUS || !SCAN_ALL)
if (rc != CL_VIRUS || !SCAN_ALLMATCHES)
goto exit_toc;
}
@ -855,7 +855,7 @@ int cli_scanxar(cli_ctx *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)
if (!SCAN_ALLMATCHES)
goto exit_tmpfile;
} else if (rc != CL_BREAK) {
cli_dbgmsg("cli_scanxar: cli_magic_scandesc error %i\n", rc);

@ -171,8 +171,12 @@ static int hashpe(const char *filename, unsigned int class, int type)
const char *fmptr;
struct cl_engine *engine;
cli_ctx ctx;
struct cl_scan_options options;
int fd, ret;
memset(&options, 0, sizeof(struct cl_scan_options));
ctx.options = &options;
/* build engine */
if(!(engine = cl_engine_new())) {
mprintf("!hashpe: Can't create new engine\n");
@ -201,7 +205,7 @@ static int hashpe(const char *filename, unsigned int class, int type)
/* prepare context */
memset(&ctx, '\0', sizeof(cli_ctx));
ctx.engine = engine;
ctx.options = CL_SCAN_STDOPT;
ctx.options->parse = ~0;
ctx.containers = cli_calloc(sizeof(cli_ctx_container), engine->maxreclevel + 2);
if(!ctx.containers) {
cl_engine_free(engine);
@ -2207,8 +2211,12 @@ static void matchsig(const char *sig, const char *offset, int fd)
STATBUF sb;
unsigned int matches = 0;
cli_ctx ctx;
struct cl_scan_options options;
int ret;
memset(&options, 0, sizeof(struct cl_scan_options));
ctx.options = &options;
mprintf("SUBSIG: %s\n", sig);
if(!(engine = cl_engine_new())) {
@ -2236,7 +2244,7 @@ static void matchsig(const char *sig, const char *offset, int fd)
}
memset(&ctx, '\0', sizeof(cli_ctx));
ctx.engine = engine;
ctx.options = CL_SCAN_STDOPT;
ctx.options->parse = ~0;
ctx.containers = cli_calloc(sizeof(cli_ctx_container), engine->maxreclevel + 2);
if(!ctx.containers) {
cl_engine_free(engine);
@ -3388,9 +3396,13 @@ static int dumpcerts(const struct optstruct *opts)
const char * fmptr;
struct cl_engine *engine;
cli_ctx ctx;
struct cl_scan_options options;
int fd, ret;
uint8_t shash1[SHA1_HASH_SIZE];
memset(&options, 0, sizeof(struct cl_scan_options));
ctx.options = &options;
logg_file = NULL;
filename = optget(opts, "print-certs")->strarg;
@ -3430,7 +3442,7 @@ static int dumpcerts(const struct optstruct *opts)
/* prepare context */
memset(&ctx, '\0', sizeof(cli_ctx));
ctx.engine = engine;
ctx.options = CL_SCAN_STDOPT;
ctx.options->parse = ~0;
ctx.containers = cli_calloc(sizeof(cli_ctx_container), engine->maxreclevel + 2);
if(!ctx.containers) {
cl_engine_free(engine);

@ -62,9 +62,13 @@ static void runtest(const char *file, uint64_t expected, int fail, int nojit,
int fdin = -1;
char filestr[512];
const char * virname = NULL;
struct cl_scan_options options;
memset(&cctx, 0, sizeof(cctx));
cctx.options |= CL_SCAN_ALLMATCHES;
memset(&options, 0, sizeof(struct cl_scan_options));
cctx.options = &options;
cctx.options->general |= CL_SCAN_GENERAL_ALLMATCHES;
cctx.virname = &virname;
cctx.engine = engine = cl_engine_new();
fail_unless(!!cctx.engine, "cannot create engine");

@ -160,7 +160,7 @@ static int get_test_file(int i, char *file, unsigned fsize, unsigned long *size)
static struct cl_engine *g_engine;
#ifdef CHECK_HAVE_LOOPS
/* int cl_scandesc(int desc, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options) */
/* int cl_scandesc(int desc, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, const struct cl_limits *limits, struct cl_scan_options* options) */
START_TEST (test_cl_scandesc)
{
const char *virname = NULL;
@ -168,10 +168,14 @@ START_TEST (test_cl_scandesc)
unsigned long size;
unsigned long int scanned = 0;
int ret;
struct cl_scan_options options;
memset(&options, 0, sizeof(struct cl_scan_options));
options.parse |= ~0;
int fd = get_test_file(_i, file, sizeof(file), &size);
cli_dbgmsg("scanning (scandesc) %s\n", file);
ret = cl_scandesc(fd, &virname, &scanned, g_engine, CL_SCAN_STDOPT);
ret = cl_scandesc(fd, &virname, &scanned, g_engine, &options);
cli_dbgmsg("scan end (scandesc) %s\n", file);
if (!FALSE_NEGATIVE) {
@ -189,10 +193,15 @@ START_TEST (test_cl_scandesc_allscan)
unsigned long size;
unsigned long int scanned = 0;
int ret;
struct cl_scan_options options;
memset(&options, 0, sizeof(struct cl_scan_options));
options.parse |= ~0;
options.general |= CL_SCAN_GENERAL_ALLMATCHES;
int fd = get_test_file(_i, file, sizeof(file), &size);
cli_dbgmsg("scanning (scandesc) %s\n", file);
ret = cl_scandesc(fd, &virname, &scanned, g_engine, CL_SCAN_ALLMATCHES+CL_SCAN_STDOPT);
ret = cl_scandesc(fd, &virname, &scanned, g_engine, &options);
cli_dbgmsg("scan end (scandesc) %s\n", file);
@ -212,12 +221,16 @@ START_TEST (test_cl_scanfile)
unsigned long size;
unsigned long int scanned = 0;
int ret;
struct cl_scan_options options;
memset(&options, 0, sizeof(struct cl_scan_options));
options.parse |= ~0;
int fd = get_test_file(_i, file, sizeof(file), &size);
close(fd);
cli_dbgmsg("scanning (scanfile) %s\n", file);
ret = cl_scanfile(file, &virname, &scanned, g_engine, CL_SCAN_STDOPT);
ret = cl_scanfile(file, &virname, &scanned, g_engine, &options);
cli_dbgmsg("scan end (scanfile) %s\n", file);
if (!FALSE_NEGATIVE) {
@ -234,12 +247,17 @@ START_TEST (test_cl_scanfile_allscan)
unsigned long size;
unsigned long int scanned = 0;
int ret;
struct cl_scan_options options;
memset(&options, 0, sizeof(struct cl_scan_options));
options.parse |= ~0;
options.general |= CL_SCAN_GENERAL_ALLMATCHES;
int fd = get_test_file(_i, file, sizeof(file), &size);
close(fd);
cli_dbgmsg("scanning (scanfile_allscan) %s\n", file);
ret = cl_scanfile(file, &virname, &scanned, g_engine, CL_SCAN_ALLMATCHES+CL_SCAN_STDOPT);
ret = cl_scanfile(file, &virname, &scanned, g_engine, &options);
cli_dbgmsg("scan end (scanfile_allscan) %s\n", file);
if (!FALSE_NEGATIVE) {
@ -256,13 +274,17 @@ START_TEST (test_cl_scanfile_callback)
unsigned long size;
unsigned long int scanned = 0;
int ret;
struct cl_scan_options options;
memset(&options, 0, sizeof(struct cl_scan_options));
options.parse |= ~0;
int fd = get_test_file(_i, file, sizeof(file), &size);
close(fd);
cli_dbgmsg("scanning (scanfile_cb) %s\n", file);
/* TODO: test callbacks */
ret = cl_scanfile_callback(file, &virname, &scanned, g_engine, CL_SCAN_STDOPT, NULL);
ret = cl_scanfile_callback(file, &virname, &scanned, g_engine, &options, NULL);
cli_dbgmsg("scan end (scanfile_cb) %s\n", file);
if (!FALSE_NEGATIVE) {
@ -279,13 +301,18 @@ START_TEST (test_cl_scanfile_callback_allscan)
unsigned long size;
unsigned long int scanned = 0;
int ret;
struct cl_scan_options options;
memset(&options, 0, sizeof(struct cl_scan_options));
options.parse |= ~0;
options.general |= CL_SCAN_GENERAL_ALLMATCHES;
int fd = get_test_file(_i, file, sizeof(file), &size);
close(fd);
cli_dbgmsg("scanning (scanfile_cb_allscan) %s\n", file);
/* TODO: test callbacks */
ret = cl_scanfile_callback(file, &virname, &scanned, g_engine, CL_SCAN_ALLMATCHES+CL_SCAN_STDOPT, NULL);
ret = cl_scanfile_callback(file, &virname, &scanned, g_engine, &options, NULL);
cli_dbgmsg("scan end (scanfile_cb_allscan) %s\n", file);
if (!FALSE_NEGATIVE) {
@ -302,12 +329,16 @@ START_TEST (test_cl_scandesc_callback)
unsigned long size;
unsigned long int scanned = 0;
int ret;
struct cl_scan_options options;
memset(&options, 0, sizeof(struct cl_scan_options));
options.parse |= ~0;
int fd = get_test_file(_i, file, sizeof(file), &size);
cli_dbgmsg("scanning (scandesc_cb) %s\n", file);
/* TODO: test callbacks */
ret = cl_scandesc_callback(fd, &virname, &scanned, g_engine, CL_SCAN_STDOPT, NULL);
ret = cl_scandesc_callback(fd, &virname, &scanned, g_engine, &options, NULL);
cli_dbgmsg("scan end (scandesc_cb) %s\n", file);
if (!FALSE_NEGATIVE) {
@ -325,12 +356,17 @@ START_TEST (test_cl_scandesc_callback_allscan)
unsigned long size;
unsigned long int scanned = 0;
int ret;
struct cl_scan_options options;
memset(&options, 0, sizeof(struct cl_scan_options));
options.parse |= ~0;
options.general |= CL_SCAN_GENERAL_ALLMATCHES;
int fd = get_test_file(_i, file, sizeof(file), &size);
cli_dbgmsg("scanning (scandesc_cb_allscan) %s\n", file);
/* TODO: test callbacks */
ret = cl_scandesc_callback(fd, &virname, &scanned, g_engine, CL_SCAN_ALLMATCHES+CL_SCAN_STDOPT, NULL);
ret = cl_scandesc_callback(fd, &virname, &scanned, g_engine, &options, NULL);
cli_dbgmsg("scan end (scandesc_cb_allscan) %s\n", file);
if (!FALSE_NEGATIVE) {
@ -490,6 +526,10 @@ START_TEST (test_cl_scanmap_callback_handle)
int ret;
char file[256];
unsigned long size;
struct cl_scan_options options;
memset(&options, 0, sizeof(struct cl_scan_options));
options.parse |= ~0;
int fd = get_test_file(_i, file, sizeof(file), &size);
/* intentionally use different way than scanners.c for testing */
@ -497,7 +537,7 @@ START_TEST (test_cl_scanmap_callback_handle)
fail_unless(!!map, "cl_fmap_open_handle");
cli_dbgmsg("scanning (handle) %s\n", file);
ret = cl_scanmap_callback(map, &virname, &scanned, g_engine, CL_SCAN_STDOPT, NULL);
ret = cl_scanmap_callback(map, &virname, &scanned, g_engine, &options, NULL);
cli_dbgmsg("scan end (handle) %s\n", file);
if (!FALSE_NEGATIVE) {
@ -516,6 +556,11 @@ START_TEST (test_cl_scanmap_callback_handle_allscan)
int ret;
char file[256];
unsigned long size;
struct cl_scan_options options;
memset(&options, 0, sizeof(struct cl_scan_options));
options.parse |= ~0;
options.general |= CL_SCAN_GENERAL_ALLMATCHES;
int fd = get_test_file(_i, file, sizeof(file), &size);
/* intentionally use different way than scanners.c for testing */
@ -523,7 +568,7 @@ START_TEST (test_cl_scanmap_callback_handle_allscan)
fail_unless(!!map, "cl_fmap_open_handle %s");
cli_dbgmsg("scanning (handle) allscan %s\n", file);
ret = cl_scanmap_callback(map, &virname, &scanned, g_engine, CL_SCAN_ALLMATCHES+CL_SCAN_STDOPT, NULL);
ret = cl_scanmap_callback(map, &virname, &scanned, g_engine, &options, NULL);
cli_dbgmsg("scan end (handle) allscan %s\n", file);
if (!FALSE_NEGATIVE) {
@ -543,6 +588,10 @@ START_TEST (test_cl_scanmap_callback_mem)
void *mem;
unsigned long size;
char file[256];
struct cl_scan_options options;
memset(&options, 0, sizeof(struct cl_scan_options));
options.parse |= ~0;
int fd = get_test_file(_i, file, sizeof(file), &size);
@ -554,7 +603,7 @@ START_TEST (test_cl_scanmap_callback_mem)
fail_unless(!!map, "cl_fmap_open_mem");
cli_dbgmsg("scanning (mem) %s\n", file);
ret = cl_scanmap_callback(map, &virname, &scanned, g_engine, CL_SCAN_STDOPT, NULL);
ret = cl_scanmap_callback(map, &virname, &scanned, g_engine, &options, NULL);
cli_dbgmsg("scan end (mem) %s\n", file);
if (!FALSE_NEGATIVE) {
fail_unless_fmt(ret == CL_VIRUS, "cl_scanmap_callback failed for %s: %s", file, cl_strerror(ret));
@ -576,6 +625,11 @@ START_TEST (test_cl_scanmap_callback_mem_allscan)
void *mem;
unsigned long size;
char file[256];
struct cl_scan_options options;
memset(&options, 0, sizeof(struct cl_scan_options));
options.parse |= ~0;
options.general |= CL_SCAN_GENERAL_ALLMATCHES;
int fd = get_test_file(_i, file, sizeof(file), &size);
@ -587,7 +641,7 @@ START_TEST (test_cl_scanmap_callback_mem_allscan)
fail_unless(!!map, "cl_fmap_open_mem %s");
cli_dbgmsg("scanning (mem) allscan %s\n", file);
ret = cl_scanmap_callback(map, &virname, &scanned, g_engine, CL_SCAN_ALLMATCHES+CL_SCAN_STDOPT, NULL);
ret = cl_scanmap_callback(map, &virname, &scanned, g_engine, &options, NULL);
cli_dbgmsg("scan end (mem) allscan %s\n", file);
if (!FALSE_NEGATIVE) {
fail_unless_fmt(ret == CL_VIRUS, "cl_scanmap_callback failed for %s: %s", file, cl_strerror(ret));

@ -155,6 +155,8 @@ static const struct pcre_testdata_s {
#endif /* HAVE_PCRE */
static cli_ctx ctx;
static struct cl_scan_options options;
static fmap_t *thefmap = NULL;
static const char *virname = NULL;
static void setup(void)
@ -162,6 +164,11 @@ static void setup(void)
struct cli_matcher *root;
virname = NULL;
thefmap = NULL;
memset(&ctx, 0, sizeof(ctx));
memset(&options, 0, sizeof(struct cl_scan_options));
ctx.options = &options;
ctx.virname = &virname;
ctx.fmap = &thefmap;
ctx.engine = cl_engine_new();
@ -208,6 +215,7 @@ START_TEST (test_ac_scanbuff) {
ret = cli_ac_initdata(&mdata, root->ac_partsigs, 0, 0, CLI_DEFAULT_AC_TRACKLEN);
fail_unless(ret == CL_SUCCESS, "cli_ac_initdata() failed");
ctx.options->general &= ~CL_SCAN_GENERAL_ALLMATCHES; /* make sure all-match is disabled */
for(i = 0; ac_testdata[i].data; i++) {
ret = cli_ac_scanbuff((const unsigned char*)ac_testdata[i].data, strlen(ac_testdata[i].data), &virname, NULL, NULL, root, &mdata, 0, 0, NULL, AC_SCAN_VIR, NULL);
fail_unless_fmt(ret == CL_VIRUS, "cli_ac_scanbuff() failed for %s", ac_testdata[i].virname);
@ -250,7 +258,7 @@ START_TEST (test_ac_scanbuff_allscan) {
ret = cli_ac_initdata(&mdata, root->ac_partsigs, 0, 0, CLI_DEFAULT_AC_TRACKLEN);
fail_unless(ret == CL_SUCCESS, "cli_ac_initdata() failed");
ctx.options |= CL_SCAN_ALLMATCHES;
ctx.options->general |= CL_SCAN_GENERAL_ALLMATCHES; /* enable all-match */
for(i = 0; ac_testdata[i].data; i++) {
ret = cli_ac_scanbuff((const unsigned char*)ac_testdata[i].data, strlen(ac_testdata[i].data), &virname, NULL, NULL, root, &mdata, 0, 0, NULL, AC_SCAN_VIR, NULL);
fail_unless_fmt(ret == CL_VIRUS, "cli_ac_scanbuff() failed for %s", ac_testdata[i].virname);
@ -294,6 +302,7 @@ START_TEST (test_ac_scanbuff_ex) {
ret = cli_ac_initdata(&mdata, root->ac_partsigs, 0, 0, CLI_DEFAULT_AC_TRACKLEN);
fail_unless(ret == CL_SUCCESS, "[ac_ex] cli_ac_initdata() failed");
ctx.options->general &= ~CL_SCAN_GENERAL_ALLMATCHES; /* make sure all-match is disabled */
for(i = 0; ac_sigopts_testdata[i].data; i++) {
ret = cli_ac_scanbuff((const unsigned char*)ac_sigopts_testdata[i].data, ac_sigopts_testdata[i].dlength, &virname, NULL, NULL, root, &mdata, 0, 0, NULL, AC_SCAN_VIR, NULL);
fail_unless_fmt(ret == ac_sigopts_testdata[i].expected_result, "[ac_ex] cli_ac_scanbuff() failed for %s (%d != %d)", ac_sigopts_testdata[i].virname, ret, ac_sigopts_testdata[i].expected_result);
@ -335,7 +344,7 @@ START_TEST (test_ac_scanbuff_allscan_ex) {
ret = cli_ac_initdata(&mdata, root->ac_partsigs, 0, 0, CLI_DEFAULT_AC_TRACKLEN);
fail_unless(ret == CL_SUCCESS, "[ac_ex] cli_ac_initdata() failed");
ctx.options |= CL_SCAN_ALLMATCHES;
ctx.options->general |= CL_SCAN_GENERAL_ALLMATCHES; /* enable all-match */
for(i = 0; ac_sigopts_testdata[i].data; i++) {
ret = cli_ac_scanbuff((const unsigned char*)ac_sigopts_testdata[i].data, ac_sigopts_testdata[i].dlength, &virname, NULL, NULL, root, &mdata, 0, 0, NULL, AC_SCAN_VIR, NULL);
fail_unless_fmt(ret == ac_sigopts_testdata[i].expected_result, "[ac_ex] cli_ac_scanbuff() failed for %s (%d != %d)", ac_sigopts_testdata[i].virname, ret, ac_sigopts_testdata[i].expected_result);
@ -374,6 +383,7 @@ START_TEST (test_bm_scanbuff) {
ret = cli_parse_add(root, "Sig3", "babedead", 0, 0, 0, "*", 0, NULL, 0);
fail_unless(ret == CL_SUCCESS, "cli_parse_add() failed");
ctx.options->general &= ~CL_SCAN_GENERAL_ALLMATCHES; /* make sure all-match is disabled */
ret = cli_bm_scanbuff((const unsigned char*)"blah\xde\xad\xbe\xef", 12, &virname, NULL, root, 0, NULL, NULL, NULL);
fail_unless(ret == CL_VIRUS, "cli_bm_scanbuff() failed");
fail_unless(!strncmp(virname, "Sig2", 4), "Incorrect signature matched in cli_bm_scanbuff()\n");
@ -402,6 +412,7 @@ START_TEST (test_bm_scanbuff_allscan) {
ret = cli_parse_add(root, "Sig3", "babedead", 0, 0, 0, "*", 0, NULL, 0);
fail_unless(ret == CL_SUCCESS, "cli_parse_add() failed");
ctx.options->general |= CL_SCAN_GENERAL_ALLMATCHES; /* enable all-match */
ret = cli_bm_scanbuff((const unsigned char*)"blah\xde\xad\xbe\xef", 12, &virname, NULL, root, 0, NULL, NULL, NULL);
fail_unless(ret == CL_VIRUS, "cli_bm_scanbuff() failed");
fail_unless(!strncmp(virname, "Sig2", 4), "Incorrect signature matched in cli_bm_scanbuff()\n");
@ -448,6 +459,7 @@ START_TEST (test_pcre_scanbuff) {
ret = cli_ac_initdata(&mdata, root->ac_partsigs, root->ac_lsigs, root->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN);
fail_unless(ret == CL_SUCCESS, "[pcre] cli_ac_initdata() failed");
ctx.options->general &= ~CL_SCAN_GENERAL_ALLMATCHES; /* make sure all-match is disabled */
for(i = 0; pcre_testdata[i].data; i++) {
ret = cli_pcre_scanbuf((const unsigned char*)pcre_testdata[i].data, strlen(pcre_testdata[i].data), &virname, NULL, root, NULL, NULL, NULL);
fail_unless_fmt(ret == pcre_testdata[i].expected_result, "[pcre] cli_pcre_scanbuff() failed for %s (%d != %d)", pcre_testdata[i].virname, ret, pcre_testdata[i].expected_result);
@ -500,7 +512,7 @@ START_TEST (test_pcre_scanbuff_allscan) {
ret = cli_ac_initdata(&mdata, root->ac_partsigs, root->ac_lsigs, root->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN);
fail_unless(ret == CL_SUCCESS, "[pcre] cli_ac_initdata() failed");
ctx.options |= CL_SCAN_ALLMATCHES;
ctx.options->general |= CL_SCAN_GENERAL_ALLMATCHES; /* enable all-match */
for(i = 0; pcre_testdata[i].data; i++) {
ret = cli_pcre_scanbuf((const unsigned char*)pcre_testdata[i].data, strlen(pcre_testdata[i].data), &virname, NULL, root, NULL, NULL, NULL);
fail_unless_fmt(ret == pcre_testdata[i].expected_result, "[pcre] cli_pcre_scanbuff() failed for %s (%d != %d)", pcre_testdata[i].virname, ret, pcre_testdata[i].expected_result);

@ -367,11 +367,14 @@ static void do_phishing_test(const struct rtest *rtest)
{
char *realurl;
cli_ctx ctx;
struct cl_scan_options options;
const char *virname = NULL;
tag_arguments_t hrefs;
int rc;
memset(&ctx, 0, sizeof(ctx));
memset(&options, 0, sizeof(struct cl_scan_options));
ctx.options = &options;
realurl = cli_strdup(rtest->realurl);
fail_unless(!!realurl, "cli_strdup");
@ -434,8 +437,11 @@ static void do_phishing_test_allscan(const struct rtest *rtest)
const char *virname = NULL;
tag_arguments_t hrefs;
int rc;
struct cl_scan_options options;
memset(&ctx, 0, sizeof(ctx));
memset(&options, 0, sizeof(struct cl_scan_options));
ctx.options = &options;
realurl = cli_strdup(rtest->realurl);
fail_unless(!!realurl, "cli_strdup");
@ -453,7 +459,7 @@ static void do_phishing_test_allscan(const struct rtest *rtest)
ctx.engine = engine;
ctx.virname = &virname;
ctx.options |= CL_SCAN_ALLMATCHES;
ctx.options->general |= CL_SCAN_GENERAL_ALLMATCHES;
rc = phishingScan(&ctx, &hrefs);

@ -130,7 +130,7 @@ FILETIME last_chk_time = {0, 0};
typedef struct {
CLAM_SCAN_CALLBACK scancb;
void *scancb_ctx;
unsigned int scanopts;
struct cl_scan_options* scanopts;
_int64 *filetype;
} instance;
@ -562,31 +562,46 @@ int CLAMAPI Scan_Uninitialize(void) {
int CLAMAPI Scan_CreateInstance(CClamAVScanner **ppScanner) {
instance *inst;
struct cl_scan_options *scanopts;
INFN();
if(!ppScanner)
FAIL(CL_ENULLARG, "NULL pScanner");
inst = (instance *)calloc(1, sizeof(*inst));
if(!inst)
FAIL(CL_EMEM, "CreateInstance: OOM");
FAIL(CL_EMEM, "CreateInstance: OOM");
scanopts = (struct cl_scan_options *)calloc(1, sizeof(struct cl_scan_options));
memset(scanopts, 0, sizeof(struct cl_scan_options));
if(!scanopts) {
free(inst);
FAIL(CL_EMEM, "CreateInstance: OOM");
}
inst->scanopts = scanopts;
if(lock_engine()) {
free(inst);
FAIL(CL_ELOCK, "Failed to lock engine");
free(inst->scanopts);
free(inst);
FAIL(CL_ELOCK, "CreateInstance: Failed to lock engine");
}
if(!engine) {
free(inst);
unlock_engine();
FAIL(CL_ESTATE, "Create instance called with no engine");
free(inst->scanopts);
free(inst);
unlock_engine();
FAIL(CL_ESTATE, "CreateInstance: Create instance called with no engine");
}
if(add_instance(inst)) {
free(inst);
unlock_engine();
FAIL(CL_EMEM, "add_instance failed");
free(inst->scanopts);
free(inst);
unlock_engine();
FAIL(CL_EMEM, "CreateInstance: add_instance failed");
}
unlock_engine();
inst->scanopts = CL_SCAN_STDOPT;
inst->scanopts->parser |= ~0; /* enable all parsers */
inst->scanopts->general |= CL_SCAN_GENERAL_HEURISTICS; /* enable heuristic alert options */
if (logg_verbose)
inst->scanopts |= CL_SCAN_PERFORMANCE_INFO;
inst->scanopts->dev |= CL_SCAN_DEV_COLLECT_PERFORMANCE_INFO;
*ppScanner = (CClamAVScanner *)inst;
logg("Created new instance %p\n", inst);
WIN();
@ -596,21 +611,23 @@ int CLAMAPI Scan_CreateInstance(CClamAVScanner **ppScanner) {
// No point in retrying more times since we are shutting down anyway.
int CLAMAPI Scan_DestroyInstance(CClamAVScanner *pScanner) {
int rc;
instance *inst = (instance*)pScanner;
INFN();
if(!pScanner)
FAIL(CL_ENULLARG, "NULL pScanner");
if((rc = del_instance((instance *)pScanner))) {
if (rc == CL_EBUSY) {
// wait for one of the scanner threads to finish, and retry again,
// that's better than caller always waiting 2 seconds to retry.
if (WaitForSingleObject(reload_event, 1000) != WAIT_OBJECT_0)
logg("Scan_DestroyInstance: timeout");
rc = del_instance((instance *)pScanner);
}
if (rc)
FAIL(rc, "del_instance failed for %p", pScanner);
}
free(pScanner);
FAIL(CL_ENULLARG, "NULL pScanner");
if((rc = del_instance(inst))) {
if (rc == CL_EBUSY) {
// wait for one of the scanner threads to finish, and retry again,
// that's better than caller always waiting 2 seconds to retry.
if (WaitForSingleObject(reload_event, 1000) != WAIT_OBJECT_0)
logg("Scan_DestroyInstance: timeout");
rc = del_instance(inst);
}
if (rc)
FAIL(rc, "del_instance failed for %p", pScanner);
}
free(inst->scanopts);
free(inst);
logg("in Scan_DestroyInstance: Instance %p destroyed\n", pScanner);
WIN();
}
@ -656,39 +673,39 @@ int CLAMAPI Scan_SetOption(CClamAVScanner *pScanner, int option, void *value, un
switch(option) {
case CLAM_OPTION_SCAN_ARCHIVE:
logg("CLAM_OPTION_SCAN_ARCHIVE: %s on instance %p\n", newval ? "enabled" : "disabled", inst);
whichopt = CL_SCAN_ARCHIVE;
whichopt = CL_SCAN_PARSE_ARCHIVE;
break;
case CLAM_OPTION_SCAN_MAIL:
logg("CLAM_OPTION_SCAN_MAIL: %s on instance %p\n", newval ? "enabled" : "disabled", inst);
whichopt = CL_SCAN_MAIL;
whichopt = CL_SCAN_PARSE_MAIL;
break;
case CLAM_OPTION_SCAN_OLE2:
logg("CLAM_OPTION_SCAN_OLE2: %s on instance %p\n", newval ? "enabled" : "disabled", inst);
whichopt = CL_SCAN_OLE2;
whichopt = CL_SCAN_PARSE_OLE2;
break;
case CLAM_OPTION_SCAN_HTML:
logg("CLAM_OPTION_SCAN_HTML: %s on instance %p\n", newval ? "enabled" : "disabled", inst);
whichopt = CL_SCAN_HTML;
whichopt = CL_SCAN_PARSE_HTML;
break;
case CLAM_OPTION_SCAN_PE:
logg("CLAM_OPTION_SCAN_PE: %s on instance %p\n", newval ? "enabled" : "disabled", inst);
whichopt = CL_SCAN_PE;
whichopt = CL_SCAN_PARSE_PE;
break;
case CLAM_OPTION_SCAN_PDF:
logg("CLAM_OPTION_SCAN_PDF: %s on instance %p\n", newval ? "enabled" : "disabled", inst);
whichopt = CL_SCAN_PDF;
whichopt = CL_SCAN_PARSE_PDF;
break;
case CLAM_OPTION_SCAN_ALGORITHMIC:
logg("CLAM_OPTION_SCAN_ALGORITHMIC: %s on instance %p\n", newval ? "enabled" : "disabled", inst);
whichopt = CL_SCAN_ALGORITHMIC;
whichopt = CL_SCAN_GENERAL_HEURISTICS;
break;
case CLAM_OPTION_SCAN_ELF:
logg("CLAM_OPTION_SCAN_ELF: %s on instance %p\n", newval ? "enabled" : "disabled", inst);
whichopt = CL_SCAN_ELF;
whichopt = CL_SCAN_PARSE_ELF;
break;
case CLAM_OPTION_SCAN_SWF:
logg("CLAM_OPTION_SCAN_SWF: %s on instance %p\n", newval ? "enabled" : "disabled", inst);
whichopt = CL_SCAN_SWF;
whichopt = CL_SCAN_PARSE_SWF;
break;
default:
unlock_instances();
@ -722,31 +739,31 @@ int CLAMAPI Scan_GetOption(CClamAVScanner *pScanner, int option, void *value, un
}
switch(option) {
case CLAM_OPTION_SCAN_ARCHIVE:
whichopt = CL_SCAN_ARCHIVE;
whichopt = CL_SCAN_PARSE_ARCHIVE;
break;
case CLAM_OPTION_SCAN_MAIL:
whichopt = CL_SCAN_MAIL;
whichopt = CL_SCAN_PARSE_MAIL;
break;
case CLAM_OPTION_SCAN_OLE2:
whichopt = CL_SCAN_OLE2;
whichopt = CL_SCAN_PARSE_OLE2;
break;
case CLAM_OPTION_SCAN_HTML:
whichopt = CL_SCAN_HTML;
whichopt = CL_SCAN_PARSE_HTML;
break;
case CLAM_OPTION_SCAN_PE:
whichopt = CL_SCAN_PE;
whichopt = CL_SCAN_PARSE_PE;
break;
case CLAM_OPTION_SCAN_PDF:
whichopt = CL_SCAN_PDF;
whichopt = CL_SCAN_PARSE_PDF;
break;
case CLAM_OPTION_SCAN_ALGORITHMIC:
whichopt = CL_SCAN_ALGORITHMIC;
whichopt = CL_SCAN_GENERAL_HEURISTICS;
break;
case CLAM_OPTION_SCAN_ELF:
whichopt = CL_SCAN_ELF;
whichopt = CL_SCAN_PARSE_ELF;
break;
case CLAM_OPTION_SCAN_SWF:
whichopt = CL_SCAN_SWF;
whichopt = CL_SCAN_PARSE_SWF;
break;
default:
unlock_instances();

@ -547,7 +547,7 @@ TCPAddr 127.0.0.1
#PCREMaxFileSize 100M
# When BlockMax is set, files exceeding the MaxFileSize, MaxScanSize, or MaxRecursion limit will be flagged
# with the virus "Heuristic.Limits.Exceeded".
# with the virus "Heuristics.Limits.Exceeded".
# Default: no
#BlockMax yes

Loading…
Cancel
Save