... | ... |
@@ -1,3 +1,7 @@ |
1 |
+Thu Jan 7 18:22:39 CET 2010 (tk) |
|
2 |
+--------------------------------- |
|
3 |
+ * libclamav: base code for unified container metadata matcher (bb#1579) |
|
4 |
+ |
|
1 | 5 |
Tue Jan 5 12:04:47 CET 2010 (acab) |
2 | 6 |
----------------------------------- |
3 | 7 |
* libclamav/readdb.c: force VI anchored sigs into AC |
... | ... |
@@ -636,10 +636,7 @@ fileblobScan(const fileblob *fb) |
636 | 636 |
fflush(fb->fp); |
637 | 637 |
lseek(fb->fd, 0, SEEK_SET); |
638 | 638 |
|
639 |
- fb->ctx->container_type = CL_TYPE_MAIL; |
|
640 | 639 |
rc = cli_magic_scandesc(fb->fd, fb->ctx); |
641 |
- fb->ctx->container_type = 0; |
|
642 |
- |
|
643 | 640 |
if(rc == CL_VIRUS) { |
644 | 641 |
cli_dbgmsg("%s is infected\n", fb->fullname); |
645 | 642 |
return CL_VIRUS; |
... | ... |
@@ -53,7 +53,7 @@ static const struct ftmap_s { |
53 | 53 |
{ "CL_TYPE_TEXT_UTF16BE", CL_TYPE_TEXT_UTF16BE }, |
54 | 54 |
{ "CL_TYPE_BINARY_DATA", CL_TYPE_BINARY_DATA }, |
55 | 55 |
{ "CL_TYPE_IGNORED", CL_TYPE_IGNORED }, |
56 |
- { "CL_TYPE_ANY", 0 }, /* for ft-sigs */ |
|
56 |
+ { "CL_TYPE_ANY", CL_TYPE_ANY }, |
|
57 | 57 |
{ "CL_TYPE_MSEXE", CL_TYPE_MSEXE }, |
58 | 58 |
{ "CL_TYPE_ELF", CL_TYPE_ELF }, |
59 | 59 |
{ "CL_TYPE_MACHO", CL_TYPE_MACHO }, |
... | ... |
@@ -47,6 +47,7 @@ |
47 | 47 |
#include "macho.h" |
48 | 48 |
#include "fmap.h" |
49 | 49 |
#include "pe_icons.h" |
50 |
+#include "regex/regex.h" |
|
50 | 51 |
|
51 | 52 |
int cli_scanbuff(const unsigned char *buffer, uint32_t length, uint32_t offset, cli_ctx *ctx, cli_file_t ftype, struct cli_ac_data **acdata) |
52 | 53 |
{ |
... | ... |
@@ -541,3 +542,52 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli |
541 | 541 |
|
542 | 542 |
return (acmode & AC_SCAN_FT) ? type : CL_CLEAN; |
543 | 543 |
} |
544 |
+ |
|
545 |
+int cli_matchmeta(cli_ctx *ctx, cli_file_t ftype, const char *fname, size_t fsizec, size_t fsizer, int encrypted, void *res1, void *res2) |
|
546 |
+{ |
|
547 |
+ const struct cli_cdb *cdb; |
|
548 |
+ |
|
549 |
+ if(!(cdb = ctx->engine->cdb)) |
|
550 |
+ return CL_CLEAN; |
|
551 |
+ |
|
552 |
+ do { |
|
553 |
+ if(cdb->ctype != CL_TYPE_ANY && cdb->ctype != ctx->container_type) |
|
554 |
+ continue; |
|
555 |
+ |
|
556 |
+ if(cdb->ftype != CL_TYPE_ANY && cdb->ftype != ftype) |
|
557 |
+ continue; |
|
558 |
+ |
|
559 |
+ if(cdb->encrypted != 2 && cdb->encrypted != encrypted) |
|
560 |
+ continue; |
|
561 |
+ |
|
562 |
+ if(cdb->csize[0] != CLI_OFF_ANY) { |
|
563 |
+ if(cdb->csize[0] == cdb->csize[1] && cdb->csize[0] != ctx->container_size) |
|
564 |
+ continue; |
|
565 |
+ else if(cdb->csize[0] != cdb->csize[1] && ((cdb->csize[0] && cdb->csize[0] > ctx->container_size) || (cdb->csize[1] && cdb->csize[1] < ctx->container_size))) |
|
566 |
+ continue; |
|
567 |
+ } |
|
568 |
+ |
|
569 |
+ if(cdb->fsizec[0] != CLI_OFF_ANY) { |
|
570 |
+ if(cdb->fsizec[0] == cdb->fsizec[1] && cdb->fsizec[0] != fsizec) |
|
571 |
+ continue; |
|
572 |
+ else if(cdb->fsizec[0] != cdb->fsizec[1] && ((cdb->fsizec[0] && cdb->fsizec[0] > fsizec) || (cdb->fsizec[1] && cdb->fsizec[1] < fsizec))) |
|
573 |
+ continue; |
|
574 |
+ } |
|
575 |
+ |
|
576 |
+ if(cdb->fsizer[0] != CLI_OFF_ANY) { |
|
577 |
+ if(cdb->fsizer[0] == cdb->fsizer[1] && cdb->fsizer[0] != fsizer) |
|
578 |
+ continue; |
|
579 |
+ else if(cdb->fsizer[0] != cdb->fsizer[1] && ((cdb->fsizer[0] && cdb->fsizer[0] > fsizer) || (cdb->fsizer[1] && cdb->fsizer[1] < fsizer))) |
|
580 |
+ continue; |
|
581 |
+ } |
|
582 |
+ |
|
583 |
+ if(cdb->name.re_magic && (!fname || cli_regexec(&cdb->name, fname, 0, NULL, 0) == REG_NOMATCH)) |
|
584 |
+ continue; |
|
585 |
+ |
|
586 |
+ *ctx->virname = cdb->virname; |
|
587 |
+ return CL_VIRUS; |
|
588 |
+ |
|
589 |
+ } while((cdb = cdb->next)); |
|
590 |
+ |
|
591 |
+ return CL_CLEAN; |
|
592 |
+} |
... | ... |
@@ -106,6 +106,24 @@ struct cli_meta_node { |
106 | 106 |
unsigned int crc32, fileno, encrypted, maxdepth; |
107 | 107 |
}; |
108 | 108 |
|
109 |
+struct cli_cdb |
|
110 |
+{ |
|
111 |
+ char *virname; /* virus name */ |
|
112 |
+ cli_file_t ctype; /* container type */ |
|
113 |
+ cli_file_t ftype; /* file type */ |
|
114 |
+ regex_t name; /* filename regex */ |
|
115 |
+ size_t csize[2]; /* container size (min, max); if csize[0] != csize[1] |
|
116 |
+ * then value of 0 makes the field ignored |
|
117 |
+ */ |
|
118 |
+ size_t fsizec[2]; /* file size in container */ |
|
119 |
+ size_t fsizer[2]; /* real file size */ |
|
120 |
+ int encrypted; /* file is encrypted; 2 == ignore */ |
|
121 |
+ void *res1; /* reserved / format specific */ |
|
122 |
+ void *res2; /* reserved / format specific */ |
|
123 |
+ |
|
124 |
+ struct cli_cdb *next; |
|
125 |
+}; |
|
126 |
+ |
|
109 | 127 |
struct cli_mtarget { |
110 | 128 |
cli_file_t target; |
111 | 129 |
const char *name; |
... | ... |
@@ -152,4 +170,6 @@ int cli_caloff(const char *offstr, struct cli_target_info *info, fmap_t *map, un |
152 | 152 |
|
153 | 153 |
int cli_checkfp(int fd, cli_ctx *ctx); |
154 | 154 |
|
155 |
+int cli_matchmeta(cli_ctx *ctx, cli_file_t ftype, const char *fname, size_t fsizec, size_t fsizer, int encrypted, void *res1, void *res2); |
|
156 |
+ |
|
155 | 157 |
#endif |
... | ... |
@@ -111,6 +111,7 @@ typedef struct { |
111 | 111 |
unsigned int scannedfiles; |
112 | 112 |
unsigned int found_possibly_unwanted; |
113 | 113 |
cli_file_t container_type; /* FIXME: to be made into a stack or array - see bb#1579 & bb#1293 */ |
114 |
+ size_t container_size; |
|
114 | 115 |
struct cli_dconf *dconf; |
115 | 116 |
fmap_t **fmap; |
116 | 117 |
} cli_ctx; |
... | ... |
@@ -199,6 +200,9 @@ struct cl_engine { |
199 | 199 |
/* RAR metadata */ |
200 | 200 |
struct cli_meta_node *rar_mlist; |
201 | 201 |
|
202 |
+ /* Container metadata */ |
|
203 |
+ struct cli_cdb *cdb; |
|
204 |
+ |
|
202 | 205 |
/* Phishing .pdb and .wdb databases*/ |
203 | 206 |
struct regex_matcher *whitelist_matcher; |
204 | 207 |
struct regex_matcher *domainlist_matcher; |
... | ... |
@@ -1869,6 +1869,200 @@ static int cli_loadmd(FILE *fs, struct cl_engine *engine, unsigned int *signo, i |
1869 | 1869 |
return CL_SUCCESS; |
1870 | 1870 |
} |
1871 | 1871 |
|
1872 |
+/* 0 1 2 3 4 5 6 7 8 9 10 11 |
|
1873 |
+ * VirusName:ContainerType:FileType:FileNameREGEX:ContainerSize:FileSizeInContainer:FileSizeReal:IsEncrypted:Res1:Res2[:MinFL[:MaxFL]] |
|
1874 |
+ */ |
|
1875 |
+#define CDB_TOKENS 12 |
|
1876 |
+static int cli_loadcdb(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigned int options, struct cli_dbio *dbio) |
|
1877 |
+{ |
|
1878 |
+ const char *tokens[MD_TOKENS + 1]; |
|
1879 |
+ char buffer[FILEBUFF], *buffer_cpy; |
|
1880 |
+ unsigned int line = 0, sigs = 0, tokens_count, n0, n1; |
|
1881 |
+ int ret = CL_SUCCESS; |
|
1882 |
+ struct cli_cdb *new; |
|
1883 |
+ |
|
1884 |
+ |
|
1885 |
+ if(engine->ignored) |
|
1886 |
+ if(!(buffer_cpy = cli_malloc(FILEBUFF))) |
|
1887 |
+ return CL_EMEM; |
|
1888 |
+ |
|
1889 |
+ while(cli_dbgets(buffer, FILEBUFF, fs, dbio)) { |
|
1890 |
+ line++; |
|
1891 |
+ if(buffer[0] == '#') |
|
1892 |
+ continue; |
|
1893 |
+ |
|
1894 |
+ cli_chomp(buffer); |
|
1895 |
+ if(engine->ignored) |
|
1896 |
+ strcpy(buffer_cpy, buffer); |
|
1897 |
+ |
|
1898 |
+ tokens_count = cli_strtokenize(buffer, ':', CDB_TOKENS + 1, tokens); |
|
1899 |
+ if(tokens_count > CDB_TOKENS) { |
|
1900 |
+ ret = CL_EMALFDB; |
|
1901 |
+ break; |
|
1902 |
+ } |
|
1903 |
+ |
|
1904 |
+ if(tokens_count > 10) { /* min version */ |
|
1905 |
+ if(!cli_isnumber(tokens[10])) { |
|
1906 |
+ ret = CL_EMALFDB; |
|
1907 |
+ break; |
|
1908 |
+ } |
|
1909 |
+ if((unsigned int) atoi(tokens[10]) > cl_retflevel()) { |
|
1910 |
+ cli_dbgmsg("cli_loadcdb: Container signature for %s not loaded (required f-level: %u)\n", tokens[0], atoi(tokens[10])); |
|
1911 |
+ continue; |
|
1912 |
+ } |
|
1913 |
+ if(tokens_count == 12) { /* max version */ |
|
1914 |
+ if(!cli_isnumber(tokens[11])) { |
|
1915 |
+ ret = CL_EMALFDB; |
|
1916 |
+ break; |
|
1917 |
+ } |
|
1918 |
+ if((unsigned int) atoi(tokens[11]) < cl_retflevel()) |
|
1919 |
+ continue; |
|
1920 |
+ } |
|
1921 |
+ } |
|
1922 |
+ |
|
1923 |
+ new = (struct cli_cdb *) mpool_calloc(engine->mempool, 1, sizeof(struct cli_cdb)); |
|
1924 |
+ if(!new) { |
|
1925 |
+ ret = CL_EMEM; |
|
1926 |
+ break; |
|
1927 |
+ } |
|
1928 |
+ |
|
1929 |
+ new->virname = cli_mpool_virname(engine->mempool, (char *)tokens[0], options & CL_DB_OFFICIAL); |
|
1930 |
+ if(!new->virname) { |
|
1931 |
+ mpool_free(engine->mempool, new); |
|
1932 |
+ ret = CL_EMEM; |
|
1933 |
+ break; |
|
1934 |
+ } |
|
1935 |
+ |
|
1936 |
+ if(engine->ignored && cli_chkign(engine->ignored, new->virname, buffer/*_cpy*/)) { |
|
1937 |
+ mpool_free(engine->mempool, new->virname); |
|
1938 |
+ mpool_free(engine->mempool, new); |
|
1939 |
+ continue; |
|
1940 |
+ } |
|
1941 |
+ |
|
1942 |
+ if(!strcmp(tokens[1], "*")) { |
|
1943 |
+ new->ctype = CL_TYPE_ANY; |
|
1944 |
+ } else if((new->ctype = cli_ftcode(tokens[1])) == CL_TYPE_ERROR) { |
|
1945 |
+ cli_dbgmsg("cli_cdb: Unknown container type %s in signature for %s, skipping\n", tokens[1], tokens[0]); |
|
1946 |
+ mpool_free(engine->mempool, new->virname); |
|
1947 |
+ mpool_free(engine->mempool, new); |
|
1948 |
+ continue; |
|
1949 |
+ } |
|
1950 |
+ |
|
1951 |
+ if(!strcmp(tokens[2], "*")) { |
|
1952 |
+ new->ftype = CL_TYPE_ANY; |
|
1953 |
+ } else if((new->ftype = cli_ftcode(tokens[2])) == CL_TYPE_ERROR) { |
|
1954 |
+ cli_dbgmsg("cli_cdb: Unknown file type %s in signature for %s, skipping\n", tokens[2], tokens[0]); |
|
1955 |
+ mpool_free(engine->mempool, new->virname); |
|
1956 |
+ mpool_free(engine->mempool, new); |
|
1957 |
+ continue; |
|
1958 |
+ } |
|
1959 |
+ |
|
1960 |
+ if(strcmp(tokens[3], "*") && cli_regcomp(&new->name, tokens[3], REG_EXTENDED | REG_NOSUB)) { |
|
1961 |
+ cli_errmsg("cli_cdb: Can't compile regular expression %s in signature for %s\n", tokens[3], tokens[0]); |
|
1962 |
+ mpool_free(engine->mempool, new->virname); |
|
1963 |
+ mpool_free(engine->mempool, new); |
|
1964 |
+ ret = CL_EMEM; |
|
1965 |
+ break; |
|
1966 |
+ } |
|
1967 |
+ |
|
1968 |
+#define CDBRANGE(token_str, dest) \ |
|
1969 |
+ if(strcmp(token_str, "*")) { \ |
|
1970 |
+ if(strchr(token_str, '-')) { \ |
|
1971 |
+ if(sscanf(token_str, "%u-%u", &n0, &n1) != 2) { \ |
|
1972 |
+ ret = CL_EMALFDB; \ |
|
1973 |
+ } else { \ |
|
1974 |
+ dest[0] = n0; \ |
|
1975 |
+ dest[1] = n1; \ |
|
1976 |
+ } \ |
|
1977 |
+ } else { \ |
|
1978 |
+ if(!cli_isnumber(token_str)) \ |
|
1979 |
+ ret = CL_EMALFDB; \ |
|
1980 |
+ else \ |
|
1981 |
+ dest[0] = dest[1] = atoi(token_str); \ |
|
1982 |
+ } \ |
|
1983 |
+ if(ret != CL_SUCCESS) { \ |
|
1984 |
+ cli_errmsg("cli_cdb: Invalid value %s in signature for %s\n",\ |
|
1985 |
+ token_str, tokens[0]); \ |
|
1986 |
+ if(new->name.re_magic) \ |
|
1987 |
+ cli_regfree(&new->name); \ |
|
1988 |
+ mpool_free(engine->mempool, new->virname); \ |
|
1989 |
+ mpool_free(engine->mempool, new); \ |
|
1990 |
+ ret = CL_EMEM; \ |
|
1991 |
+ break; \ |
|
1992 |
+ } \ |
|
1993 |
+ } else { \ |
|
1994 |
+ dest[0] = dest[1] = CLI_OFF_ANY; \ |
|
1995 |
+ } |
|
1996 |
+ |
|
1997 |
+ CDBRANGE(tokens[4], new->csize); |
|
1998 |
+ CDBRANGE(tokens[5], new->fsizec); |
|
1999 |
+ CDBRANGE(tokens[6], new->fsizer); |
|
2000 |
+ |
|
2001 |
+ if(!strcmp(tokens[7], "*")) { |
|
2002 |
+ new->encrypted = 2; |
|
2003 |
+ } else { |
|
2004 |
+ if(strcmp(tokens[7], "0") && strcmp(tokens[7], "1")) { |
|
2005 |
+ cli_errmsg("cli_cdb: Invalid encryption flag value in signature for %s\n", tokens[0]); |
|
2006 |
+ if(new->name.re_magic) |
|
2007 |
+ cli_regfree(&new->name); |
|
2008 |
+ mpool_free(engine->mempool, new->virname); |
|
2009 |
+ mpool_free(engine->mempool, new); |
|
2010 |
+ ret = CL_EMEM; |
|
2011 |
+ break; |
|
2012 |
+ } |
|
2013 |
+ new->encrypted = *tokens[7] - 0x30; |
|
2014 |
+ } |
|
2015 |
+ |
|
2016 |
+ if(strcmp(tokens[8], "*")) { |
|
2017 |
+ new->res1 = cli_mpool_strdup(engine->mempool, tokens[8]); |
|
2018 |
+ if(!new->res1) { |
|
2019 |
+ cli_errmsg("cli_cdb: Can't allocate memory for res1 in signature for %s\n", tokens[0]); |
|
2020 |
+ if(new->name.re_magic) |
|
2021 |
+ cli_regfree(&new->name); |
|
2022 |
+ mpool_free(engine->mempool, new->virname); |
|
2023 |
+ mpool_free(engine->mempool, new); |
|
2024 |
+ ret = CL_EMEM; |
|
2025 |
+ break; |
|
2026 |
+ } |
|
2027 |
+ } |
|
2028 |
+ |
|
2029 |
+ if(strcmp(tokens[9], "*")) { |
|
2030 |
+ new->res2 = cli_mpool_strdup(engine->mempool, tokens[9]); |
|
2031 |
+ if(!new->res2) { |
|
2032 |
+ cli_errmsg("cli_cdb: Can't allocate memory for res2 in signature for %s\n", tokens[0]); |
|
2033 |
+ if(new->name.re_magic) |
|
2034 |
+ cli_regfree(&new->name); |
|
2035 |
+ mpool_free(engine->mempool, new->res1); |
|
2036 |
+ mpool_free(engine->mempool, new->virname); |
|
2037 |
+ mpool_free(engine->mempool, new); |
|
2038 |
+ ret = CL_EMEM; |
|
2039 |
+ break; |
|
2040 |
+ } |
|
2041 |
+ } |
|
2042 |
+ |
|
2043 |
+ new->next = engine->cdb; |
|
2044 |
+ engine->cdb = new; |
|
2045 |
+ sigs++; |
|
2046 |
+ } |
|
2047 |
+ if(engine->ignored) |
|
2048 |
+ free(buffer_cpy); |
|
2049 |
+ |
|
2050 |
+ if(!line) { |
|
2051 |
+ cli_errmsg("Empty database file\n"); |
|
2052 |
+ return CL_EMALFDB; |
|
2053 |
+ } |
|
2054 |
+ |
|
2055 |
+ if(ret) { |
|
2056 |
+ cli_errmsg("Problem parsing database at line %u\n", line); |
|
2057 |
+ return ret; |
|
2058 |
+ } |
|
2059 |
+ |
|
2060 |
+ if(signo) |
|
2061 |
+ *signo += sigs; |
|
2062 |
+ |
|
2063 |
+ return CL_SUCCESS; |
|
2064 |
+} |
|
2065 |
+ |
|
1872 | 2066 |
static int cli_loaddbdir(const char *dirname, struct cl_engine *engine, unsigned int *signo, unsigned int options); |
1873 | 2067 |
|
1874 | 2068 |
int cli_load(const char *filename, struct cl_engine *engine, unsigned int *signo, unsigned int options, struct cli_dbio *dbio) |
... | ... |
@@ -1980,6 +2174,9 @@ int cli_load(const char *filename, struct cl_engine *engine, unsigned int *signo |
1980 | 1980 |
} else if(cli_strbcasestr(dbname, ".idb")) { |
1981 | 1981 |
ret = cli_loadidb(fs, engine, signo, options, dbio); |
1982 | 1982 |
|
1983 |
+ } else if(cli_strbcasestr(dbname, ".cdb")) { |
|
1984 |
+ ret = cli_loadcdb(fs, engine, signo, options, dbio); |
|
1985 |
+ |
|
1983 | 1986 |
} else { |
1984 | 1987 |
cli_dbgmsg("cli_load: unknown extension - assuming old database format\n"); |
1985 | 1988 |
ret = cli_loaddb(fs, engine, signo, options, dbio, dbname); |
... | ... |
@@ -2494,6 +2691,17 @@ int cl_engine_free(struct cl_engine *engine) |
2494 | 2494 |
mpool_free(engine->mempool, metah); |
2495 | 2495 |
} |
2496 | 2496 |
|
2497 |
+ while(engine->cdb) { |
|
2498 |
+ struct cli_cdb *pt = engine->cdb; |
|
2499 |
+ engine->cdb = pt->next; |
|
2500 |
+ if(pt->name.re_magic) |
|
2501 |
+ cli_regfree(&pt->name); |
|
2502 |
+ mpool_free(engine->mempool, pt->res2); |
|
2503 |
+ mpool_free(engine->mempool, pt->res1); |
|
2504 |
+ mpool_free(engine->mempool, pt->virname); |
|
2505 |
+ mpool_free(engine->mempool, pt); |
|
2506 |
+ } |
|
2507 |
+ |
|
2497 | 2508 |
if(engine->dconf->bytecode & BYTECODE_ENGINE_MASK) { |
2498 | 2509 |
unsigned i; |
2499 | 2510 |
if (engine->bcs.all_bcs) |
... | ... |
@@ -978,7 +978,6 @@ static int cli_scanscript(cli_ctx *ctx) |
978 | 978 |
unsigned char *buff; |
979 | 979 |
unsigned char* normalized; |
980 | 980 |
struct text_norm_state state; |
981 |
- struct stat sb; |
|
982 | 981 |
char *tmpname = NULL; |
983 | 982 |
int ofd = -1, ret; |
984 | 983 |
const struct cli_matcher *troot = ctx->engine->root[7]; |
... | ... |
@@ -1529,9 +1528,7 @@ static int cli_scanmail(int desc, cli_ctx *ctx) |
1529 | 1529 |
return ret; |
1530 | 1530 |
} |
1531 | 1531 |
|
1532 |
- ctx->container_type = CL_TYPE_MAIL; |
|
1533 | 1532 |
ret = cli_scandir(dir, ctx); |
1534 |
- ctx->container_type = 0; |
|
1535 | 1533 |
|
1536 | 1534 |
if(!ctx->engine->keeptmp) |
1537 | 1535 |
cli_rmdirs(dir); |
... | ... |
@@ -1839,7 +1836,8 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx) |
1839 | 1839 |
cli_file_t type, dettype = 0; |
1840 | 1840 |
struct stat sb; |
1841 | 1841 |
uint8_t typercg = 1; |
1842 |
- cli_file_t current_container = ctx->container_type; /* TODO: container tracking code TBD - bb#1293 */ |
|
1842 |
+ cli_file_t current_container_type = ctx->container_type; /* TODO: container tracking code TBD - bb#1293 */ |
|
1843 |
+ size_t current_container_size = ctx->container_size; |
|
1843 | 1844 |
|
1844 | 1845 |
if(ctx->engine->maxreclevel && ctx->recursion > ctx->engine->maxreclevel) { |
1845 | 1846 |
cli_dbgmsg("cli_magic_scandesc: Archive recursion limit exceeded (%u, max: %u)\n", ctx->recursion, ctx->engine->maxreclevel); |
... | ... |
@@ -1906,18 +1904,21 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx) |
1906 | 1906 |
lseek(desc, 0, SEEK_SET); /* FIXMEFMAP: remove ? */ |
1907 | 1907 |
} |
1908 | 1908 |
|
1909 |
- ctx->container_type = 0; |
|
1910 | 1909 |
ctx->recursion++; |
1911 | 1910 |
switch(type) { |
1912 | 1911 |
case CL_TYPE_IGNORED: |
1913 | 1912 |
break; |
1914 | 1913 |
|
1915 | 1914 |
case CL_TYPE_RAR: |
1915 |
+ ctx->container_type = CL_TYPE_RAR; |
|
1916 |
+ ctx->container_size = sb.st_size; |
|
1916 | 1917 |
if(have_rar && SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_RAR)) |
1917 | 1918 |
ret = cli_scanrar(desc, ctx, 0, NULL); |
1918 | 1919 |
break; |
1919 | 1920 |
|
1920 | 1921 |
case CL_TYPE_ZIP: |
1922 |
+ ctx->container_type = CL_TYPE_ZIP; |
|
1923 |
+ ctx->container_size = sb.st_size; |
|
1921 | 1924 |
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_ZIP)) |
1922 | 1925 |
ret = cli_unzip(ctx); |
1923 | 1926 |
break; |
... | ... |
@@ -1931,17 +1932,24 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx) |
1931 | 1931 |
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_BZ)) |
1932 | 1932 |
ret = cli_scanbzip(desc, ctx); |
1933 | 1933 |
break; |
1934 |
+ |
|
1934 | 1935 |
case CL_TYPE_ARJ: |
1936 |
+ ctx->container_type = CL_TYPE_ARJ; |
|
1937 |
+ ctx->container_size = sb.st_size; |
|
1935 | 1938 |
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_ARJ)) |
1936 | 1939 |
ret = cli_scanarj(desc, ctx, 0, NULL); |
1937 | 1940 |
break; |
1938 | 1941 |
|
1939 | 1942 |
case CL_TYPE_NULSFT: |
1940 |
- if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_NSIS)) |
|
1943 |
+ ctx->container_type = CL_TYPE_NULSFT; |
|
1944 |
+ ctx->container_size = sb.st_size; |
|
1945 |
+ if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_NSIS)) |
|
1941 | 1946 |
ret = cli_scannulsft(desc, ctx, 0); |
1942 | 1947 |
break; |
1943 | 1948 |
|
1944 | 1949 |
case CL_TYPE_AUTOIT: |
1950 |
+ ctx->container_type = CL_TYPE_AUTOIT; |
|
1951 |
+ ctx->container_size = sb.st_size; |
|
1945 | 1952 |
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_AUTOIT)) |
1946 | 1953 |
ret = cli_scanautoit(desc, ctx, 23); |
1947 | 1954 |
break; |
... | ... |
@@ -1952,6 +1960,8 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx) |
1952 | 1952 |
break; |
1953 | 1953 |
|
1954 | 1954 |
case CL_TYPE_MSCAB: |
1955 |
+ ctx->container_type = CL_TYPE_MSCAB; |
|
1956 |
+ ctx->container_size = sb.st_size; |
|
1955 | 1957 |
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CAB)) |
1956 | 1958 |
ret = cli_scanmscab(desc, ctx, 0); |
1957 | 1959 |
break; |
... | ... |
@@ -1972,11 +1982,15 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx) |
1972 | 1972 |
break; |
1973 | 1973 |
|
1974 | 1974 |
case CL_TYPE_RTF: |
1975 |
+ ctx->container_type = CL_TYPE_RTF; |
|
1976 |
+ ctx->container_size = sb.st_size; |
|
1975 | 1977 |
if(SCAN_ARCHIVE && (DCONF_DOC & DOC_CONF_RTF)) |
1976 | 1978 |
ret = cli_scanrtf(desc, ctx); |
1977 | 1979 |
break; |
1978 | 1980 |
|
1979 | 1981 |
case CL_TYPE_MAIL: |
1982 |
+ ctx->container_type = CL_TYPE_MAIL; |
|
1983 |
+ ctx->container_size = sb.st_size; |
|
1980 | 1984 |
if(SCAN_MAIL && (DCONF_MAIL & MAIL_CONF_MBOX)) |
1981 | 1985 |
ret = cli_scanmail(desc, ctx); |
1982 | 1986 |
break; |
... | ... |
@@ -1992,46 +2006,64 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx) |
1992 | 1992 |
break; |
1993 | 1993 |
|
1994 | 1994 |
case CL_TYPE_MSCHM: |
1995 |
+ ctx->container_type = CL_TYPE_MSCHM; |
|
1996 |
+ ctx->container_size = sb.st_size; |
|
1995 | 1997 |
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CHM)) |
1996 | 1998 |
ret = cli_scanmschm(desc, ctx); |
1997 | 1999 |
break; |
1998 | 2000 |
|
1999 | 2001 |
case CL_TYPE_MSOLE2: |
2002 |
+ ctx->container_type = CL_TYPE_MSOLE2; |
|
2003 |
+ ctx->container_size = sb.st_size; |
|
2000 | 2004 |
if(SCAN_OLE2 && (DCONF_ARCH & ARCH_CONF_OLE2)) |
2001 | 2005 |
ret = cli_scanole2(ctx); |
2002 | 2006 |
break; |
2003 | 2007 |
|
2004 | 2008 |
case CL_TYPE_7Z: |
2009 |
+ ctx->container_type = CL_TYPE_7Z; |
|
2010 |
+ ctx->container_size = sb.st_size; |
|
2005 | 2011 |
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_7Z)) |
2006 | 2012 |
ret = cli_7unz(desc, ctx); |
2007 | 2013 |
break; |
2008 | 2014 |
|
2009 | 2015 |
case CL_TYPE_POSIX_TAR: |
2016 |
+ ctx->container_type = CL_TYPE_POSIX_TAR; |
|
2017 |
+ ctx->container_size = sb.st_size; |
|
2010 | 2018 |
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_TAR)) |
2011 | 2019 |
ret = cli_scantar(desc, ctx, 1); |
2012 | 2020 |
break; |
2013 | 2021 |
|
2014 | 2022 |
case CL_TYPE_OLD_TAR: |
2023 |
+ ctx->container_type = CL_TYPE_OLD_TAR; |
|
2024 |
+ ctx->container_size = sb.st_size; |
|
2015 | 2025 |
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_TAR)) |
2016 | 2026 |
ret = cli_scantar(desc, ctx, 0); |
2017 | 2027 |
break; |
2018 | 2028 |
|
2019 | 2029 |
case CL_TYPE_CPIO_OLD: |
2030 |
+ ctx->container_type = CL_TYPE_CPIO_OLD; |
|
2031 |
+ ctx->container_size = sb.st_size; |
|
2020 | 2032 |
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CPIO)) |
2021 | 2033 |
ret = cli_scancpio_old(desc, ctx); |
2022 | 2034 |
break; |
2023 | 2035 |
|
2024 | 2036 |
case CL_TYPE_CPIO_ODC: |
2037 |
+ ctx->container_type = CL_TYPE_CPIO_ODC; |
|
2038 |
+ ctx->container_size = sb.st_size; |
|
2025 | 2039 |
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CPIO)) |
2026 | 2040 |
ret = cli_scancpio_odc(desc, ctx); |
2027 | 2041 |
break; |
2028 | 2042 |
|
2029 | 2043 |
case CL_TYPE_CPIO_NEWC: |
2044 |
+ ctx->container_type = CL_TYPE_CPIO_NEWC; |
|
2045 |
+ ctx->container_size = sb.st_size; |
|
2030 | 2046 |
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CPIO)) |
2031 | 2047 |
ret = cli_scancpio_newc(desc, ctx, 0); |
2032 | 2048 |
break; |
2033 | 2049 |
|
2034 | 2050 |
case CL_TYPE_CPIO_CRC: |
2051 |
+ ctx->container_type = CL_TYPE_CPIO_CRC; |
|
2052 |
+ ctx->container_size = sb.st_size; |
|
2035 | 2053 |
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CPIO)) |
2036 | 2054 |
ret = cli_scancpio_newc(desc, ctx, 1); |
2037 | 2055 |
break; |
... | ... |
@@ -2057,6 +2089,8 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx) |
2057 | 2057 |
break; |
2058 | 2058 |
|
2059 | 2059 |
case CL_TYPE_PDF: /* FIXMELIMITS: pdf should be an archive! */ |
2060 |
+ ctx->container_type = CL_TYPE_PDF; |
|
2061 |
+ ctx->container_size = sb.st_size; |
|
2060 | 2062 |
if(SCAN_PDF && (DCONF_DOC & DOC_CONF_PDF)) |
2061 | 2063 |
ret = cli_scanpdf(ctx, 0); |
2062 | 2064 |
break; |
... | ... |
@@ -2082,6 +2116,8 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx) |
2082 | 2082 |
break; |
2083 | 2083 |
|
2084 | 2084 |
case CL_TYPE_SIS: |
2085 |
+ ctx->container_type = CL_TYPE_SIS; |
|
2086 |
+ ctx->container_size = sb.st_size; |
|
2085 | 2087 |
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_SIS)) |
2086 | 2088 |
ret = cli_scansis(desc, ctx); |
2087 | 2089 |
break; |
... | ... |
@@ -2103,7 +2139,8 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx) |
2103 | 2103 |
break; |
2104 | 2104 |
} |
2105 | 2105 |
ctx->recursion--; |
2106 |
- ctx->container_type = current_container; |
|
2106 |
+ ctx->container_type = current_container_type; |
|
2107 |
+ ctx->container_size = current_container_size; |
|
2107 | 2108 |
|
2108 | 2109 |
if(ret == CL_VIRUS) { |
2109 | 2110 |
ret = cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS; |
... | ... |
@@ -2184,7 +2221,8 @@ int cl_scandesc(int desc, const char **virname, unsigned long int *scanned, cons |
2184 | 2184 |
ctx.scanned = scanned; |
2185 | 2185 |
ctx.options = scanoptions; |
2186 | 2186 |
ctx.found_possibly_unwanted = 0; |
2187 |
- ctx.container_type = 0; |
|
2187 |
+ ctx.container_type = CL_TYPE_ANY; |
|
2188 |
+ ctx.container_size = 0; |
|
2188 | 2189 |
ctx.dconf = (struct cli_dconf *) engine->dconf; |
2189 | 2190 |
ctx.fmap = cli_calloc(sizeof(fmap_t *), ctx.engine->maxreclevel + 1); |
2190 | 2191 |
if(!ctx.fmap) |