... | ... |
@@ -213,7 +213,7 @@ static int cli_tgzload(int fd, struct cl_engine *engine, unsigned int *signo, un |
213 | 213 |
unsigned int type, size, pad, compr = 1; |
214 | 214 |
off_t off; |
215 | 215 |
struct cli_dbinfo *db; |
216 |
- unsigned char hash[32]; |
|
216 |
+ char hash[32]; |
|
217 | 217 |
|
218 | 218 |
cli_dbgmsg("in cli_tgzload()\n"); |
219 | 219 |
|
... | ... |
@@ -2341,13 +2341,13 @@ inline static int ac_special_altstr(const char *hexpr, uint8_t sigopts, struct c |
2341 | 2341 |
|
2342 | 2342 |
for (i = 0; i < num; i++) { |
2343 | 2343 |
if (num == 1) { |
2344 |
- c = (char *) cli_mpool_hex2str(root->mempool, hexprcpy); |
|
2344 |
+ c = cli_mpool_hex2str(root->mempool, hexprcpy); |
|
2345 | 2345 |
} else { |
2346 | 2346 |
if(!(h = cli_strtok(hexprcpy, i, "|"))) { |
2347 | 2347 |
free(hexprcpy); |
2348 | 2348 |
return CL_EMEM; |
2349 | 2349 |
} |
2350 |
- c = (char *) cli_mpool_hex2str(root->mempool, h); |
|
2350 |
+ c = cli_mpool_hex2str(root->mempool, h); |
|
2351 | 2351 |
free(h); |
2352 | 2352 |
} |
2353 | 2353 |
if (!c) { |
... | ... |
@@ -2356,10 +2356,10 @@ inline static int ac_special_altstr(const char *hexpr, uint8_t sigopts, struct c |
2356 | 2356 |
} |
2357 | 2357 |
|
2358 | 2358 |
if (special->type == AC_SPECIAL_ALT_CHAR) { |
2359 |
- (special->alt).byte[i] = *c; |
|
2359 |
+ (special->alt).byte[i] = (unsigned char)*c; |
|
2360 | 2360 |
mpool_free(root->mempool, c); |
2361 | 2361 |
} else { |
2362 |
- (special->alt).f_str[i] = c; |
|
2362 |
+ (special->alt).f_str[i] = (unsigned char*)c; |
|
2363 | 2363 |
} |
2364 | 2364 |
special->num++; |
2365 | 2365 |
} |
... | ... |
@@ -756,8 +756,8 @@ void *mpool_realloc2(struct MP *mp, void *ptr, size_t size) { |
756 | 756 |
return NULL; |
757 | 757 |
} |
758 | 758 |
|
759 |
-unsigned char *cli_mpool_hex2str(mpool_t *mp, const char *hex) { |
|
760 |
- unsigned char *str; |
|
759 |
+char *cli_mpool_hex2str(mpool_t *mp, const char *hex) { |
|
760 |
+ char *str; |
|
761 | 761 |
size_t len = strlen((const char*)hex); |
762 | 762 |
|
763 | 763 |
if (len&1) { |
... | ... |
@@ -770,7 +770,7 @@ unsigned char *cli_mpool_hex2str(mpool_t *mp, const char *hex) { |
770 | 770 |
cli_errmsg("cli_mpool_hex2str(): Can't allocate memory (%lu bytes).\n", (unsigned long)(len/2 + 1)); |
771 | 771 |
return NULL; |
772 | 772 |
} |
773 |
- if (cli_hex2str_to(hex, (char*)str, len) == -1) { |
|
773 |
+ if (cli_hex2str_to(hex, str, len) == -1) { |
|
774 | 774 |
mpool_free(mp, str); |
775 | 775 |
return NULL; |
776 | 776 |
} |
... | ... |
@@ -34,7 +34,7 @@ void mpool_free(mpool_t *mpool, void *ptr); |
34 | 34 |
void *mpool_calloc(mpool_t *mpool, size_t nmemb, size_t size); |
35 | 35 |
void *mpool_realloc(mpool_t *mpool, void *ptr, size_t size); |
36 | 36 |
void *mpool_realloc2(mpool_t *mpool, void *ptr, size_t size); |
37 |
-unsigned char *cli_mpool_hex2str(mpool_t* mpool, const char *src); |
|
37 |
+char *cli_mpool_hex2str(mpool_t* mpool, const char *src); |
|
38 | 38 |
char *cli_mpool_strdup(mpool_t *mpool, const char *s); |
39 | 39 |
char *cli_mpool_strndup(mpool_t *mpool, const char *s, size_t n); |
40 | 40 |
char *cli_mpool_virname(mpool_t *mpool, const char *virname, unsigned int official); |
... | ... |
@@ -234,7 +234,7 @@ struct icon_matcher { |
234 | 234 |
|
235 | 235 |
struct cli_dbinfo { |
236 | 236 |
char *name; |
237 |
- unsigned char *hash; |
|
237 |
+ char *hash; |
|
238 | 238 |
size_t size; |
239 | 239 |
struct cl_cvd *cvd; |
240 | 240 |
struct cli_dbinfo *next; |
... | ... |
@@ -249,7 +249,7 @@ typedef enum { |
249 | 249 |
|
250 | 250 |
struct cli_pwdb { |
251 | 251 |
char *name; |
252 |
- unsigned char *passwd; |
|
252 |
+ char *passwd; |
|
253 | 253 |
uint16_t length; |
254 | 254 |
struct cli_pwdb *next; |
255 | 255 |
}; |
... | ... |
@@ -2193,8 +2193,8 @@ static int cli_loadinfo(FILE *fs, struct cl_engine *engine, unsigned int options |
2193 | 2193 |
const char *tokens[INFO_TOKENS + 1]; |
2194 | 2194 |
char buffer[FILEBUFF]; |
2195 | 2195 |
unsigned int line = 0, tokens_count, len; |
2196 |
- unsigned char hash[32]; |
|
2197 |
- struct cli_dbinfo *last = NULL, *new; |
|
2196 |
+ char hash[32]; |
|
2197 |
+ struct cli_dbinfo *last = NULL, *new; |
|
2198 | 2198 |
int ret = CL_SUCCESS, dsig = 0; |
2199 | 2199 |
void *ctx; |
2200 | 2200 |
|
... | ... |
@@ -2213,7 +2213,7 @@ static int cli_loadinfo(FILE *fs, struct cl_engine *engine, unsigned int options |
2213 | 2213 |
if(!(options & CL_DB_UNSIGNED) && !strncmp(buffer, "DSIG:", 5)) { |
2214 | 2214 |
dsig = 1; |
2215 | 2215 |
cl_finish_hash(ctx, hash); |
2216 |
- if(cli_versig2(hash, buffer + 5, INFO_NSTR, INFO_ESTR) != CL_SUCCESS) { |
|
2216 |
+ if(cli_versig2((unsigned char*)hash, buffer + 5, INFO_NSTR, INFO_ESTR) != CL_SUCCESS) { |
|
2217 | 2217 |
cli_errmsg("cli_loadinfo: Incorrect digital signature\n"); |
2218 | 2218 |
ret = CL_EMALFDB; |
2219 | 2219 |
} |
... | ... |
@@ -2262,7 +2262,7 @@ static int cli_loadinfo(FILE *fs, struct cl_engine *engine, unsigned int options |
2262 | 2262 |
ret = CL_EMALFDB; |
2263 | 2263 |
break; |
2264 | 2264 |
} |
2265 |
- new = (struct cli_dbinfo *) mpool_calloc(engine->mempool, 1, sizeof(struct cli_dbinfo)); |
|
2265 |
+ new = (struct cli_dbinfo *) mpool_calloc(engine->mempool, 1, sizeof(struct cli_dbinfo)); |
|
2266 | 2266 |
if(!new) { |
2267 | 2267 |
ret = CL_EMEM; |
2268 | 2268 |
break; |
... | ... |
@@ -2381,7 +2381,7 @@ static int cli_loadign(FILE *fs, struct cl_engine *engine, unsigned int options, |
2381 | 2381 |
break; |
2382 | 2382 |
} |
2383 | 2383 |
if(hash) { |
2384 |
- if(strlen(hash) != 32 || !(new->virname = (char *) cli_mpool_hex2str(engine->mempool, hash))) { |
|
2384 |
+ if(strlen(hash) != 32 || !(new->virname = cli_mpool_hex2str(engine->mempool, hash))) { |
|
2385 | 2385 |
cli_errmsg("cli_loadign: Malformed MD5 string at line %u\n", line); |
2386 | 2386 |
mpool_free(engine->mempool, new->pattern); |
2387 | 2387 |
mpool_free(engine->mempool, new); |
... | ... |
@@ -32,10 +32,10 @@ |
32 | 32 |
#include <errno.h> |
33 | 33 |
#include <sys/types.h> |
34 | 34 |
#include <sys/stat.h> |
35 |
-#ifdef HAVE_UNISTD_H |
|
35 |
+#ifdef HAVE_UNISTD_H |
|
36 | 36 |
#include <unistd.h> |
37 | 37 |
#endif |
38 |
-#ifdef HAVE_SYS_PARAM_H |
|
38 |
+#ifdef HAVE_SYS_PARAM_H |
|
39 | 39 |
#include <sys/param.h> |
40 | 40 |
#endif |
41 | 41 |
#include <fcntl.h> |
... | ... |
@@ -44,9 +44,9 @@ |
44 | 44 |
#include <sys/times.h> |
45 | 45 |
#endif |
46 | 46 |
|
47 |
-#define DCONF_ARCH ctx->dconf->archive |
|
48 |
-#define DCONF_DOC ctx->dconf->doc |
|
49 |
-#define DCONF_MAIL ctx->dconf->mail |
|
47 |
+#define DCONF_ARCH ctx->dconf->archive |
|
48 |
+#define DCONF_DOC ctx->dconf->doc |
|
49 |
+#define DCONF_MAIL ctx->dconf->mail |
|
50 | 50 |
#define DCONF_OTHER ctx->dconf->other |
51 | 51 |
|
52 | 52 |
#include "clamav.h" |
... | ... |
@@ -122,112 +122,133 @@ static int cli_scanfile(const char *filename, cli_ctx *ctx); |
122 | 122 |
|
123 | 123 |
static int cli_scandir(const char *dirname, cli_ctx *ctx) |
124 | 124 |
{ |
125 |
- DIR *dd; |
|
126 |
- struct dirent *dent; |
|
125 |
+ DIR *dd; |
|
126 |
+ struct dirent *dent; |
|
127 | 127 |
#if defined(HAVE_READDIR_R_3) || defined(HAVE_READDIR_R_2) |
128 |
- union { |
|
129 |
- struct dirent d; |
|
130 |
- char b[offsetof(struct dirent, d_name) + NAME_MAX + 1]; |
|
131 |
- } result; |
|
128 |
+ union { |
|
129 |
+ struct dirent d; |
|
130 |
+ char b[offsetof(struct dirent, d_name) + NAME_MAX + 1]; |
|
131 |
+ } result; |
|
132 | 132 |
#endif |
133 |
- STATBUF statbuf; |
|
134 |
- char *fname; |
|
135 |
- unsigned int viruses_found = 0; |
|
133 |
+ STATBUF statbuf; |
|
134 |
+ char *fname; |
|
135 |
+ unsigned int viruses_found = 0; |
|
136 | 136 |
|
137 |
- if((dd = opendir(dirname)) != NULL) { |
|
137 |
+ if ((dd = opendir(dirname)) != NULL) |
|
138 |
+ { |
|
138 | 139 |
#ifdef HAVE_READDIR_R_3 |
139 |
- while(!readdir_r(dd, &result.d, &dent) && dent) { |
|
140 |
+ while (!readdir_r(dd, &result.d, &dent) && dent) |
|
141 |
+ { |
|
140 | 142 |
#elif defined(HAVE_READDIR_R_2) |
141 |
- while((dent = (struct dirent *) readdir_r(dd, &result.d))) { |
|
143 |
+ while ((dent = (struct dirent *)readdir_r(dd, &result.d))) |
|
144 |
+ { |
|
142 | 145 |
#else |
143 |
- while((dent = readdir(dd))) { |
|
146 |
+ while ((dent = readdir(dd))) |
|
147 |
+ { |
|
144 | 148 |
#endif |
145 |
- if(dent->d_ino) |
|
146 |
- { |
|
147 |
- if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..")) { |
|
148 |
- /* build the full name */ |
|
149 |
- fname = cli_malloc(strlen(dirname) + strlen(dent->d_name) + 2); |
|
150 |
- if(!fname) { |
|
151 |
- closedir(dd); |
|
152 |
- cli_dbgmsg("cli_scandir: Unable to allocate memory for filename\n"); |
|
153 |
- return CL_EMEM; |
|
154 |
- } |
|
155 |
- |
|
156 |
- sprintf(fname, "%s"PATHSEP"%s", dirname, dent->d_name); |
|
157 |
- |
|
158 |
- /* stat the file */ |
|
159 |
- if(LSTAT(fname, &statbuf) != -1) { |
|
160 |
- if(S_ISDIR(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode)) { |
|
161 |
- if(cli_scandir(fname, ctx) == CL_VIRUS) { |
|
162 |
- free(fname); |
|
163 |
- |
|
164 |
- if (SCAN_ALL) { |
|
165 |
- viruses_found++; |
|
166 |
- continue; |
|
167 |
- } |
|
149 |
+ if (dent->d_ino) |
|
150 |
+ { |
|
151 |
+ if (strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..")) |
|
152 |
+ { |
|
153 |
+ /* build the full name */ |
|
154 |
+ fname = cli_malloc(strlen(dirname) + strlen(dent->d_name) + 2); |
|
155 |
+ if (!fname) |
|
156 |
+ { |
|
157 |
+ closedir(dd); |
|
158 |
+ cli_dbgmsg("cli_scandir: Unable to allocate memory for filename\n"); |
|
159 |
+ return CL_EMEM; |
|
160 |
+ } |
|
161 |
+ |
|
162 |
+ sprintf(fname, "%s" PATHSEP "%s", dirname, dent->d_name); |
|
163 |
+ |
|
164 |
+ /* stat the file */ |
|
165 |
+ if (LSTAT(fname, &statbuf) != -1) |
|
166 |
+ { |
|
167 |
+ if (S_ISDIR(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode)) |
|
168 |
+ { |
|
169 |
+ if (cli_scandir(fname, ctx) == CL_VIRUS) |
|
170 |
+ { |
|
171 |
+ free(fname); |
|
172 |
+ |
|
173 |
+ if (SCAN_ALL) |
|
174 |
+ { |
|
175 |
+ viruses_found++; |
|
176 |
+ continue; |
|
177 |
+ } |
|
168 | 178 |
|
169 | 179 |
closedir(dd); |
170 | 180 |
return CL_VIRUS; |
171 |
- } |
|
172 |
- } else { |
|
173 |
- if(S_ISREG(statbuf.st_mode)) { |
|
174 |
- if(cli_scanfile(fname, ctx) == CL_VIRUS) { |
|
175 |
- free(fname); |
|
176 |
- |
|
177 |
- if (SCAN_ALL) { |
|
178 |
- viruses_found++; |
|
179 |
- continue; |
|
180 |
- } |
|
181 |
+ } |
|
182 |
+ } |
|
183 |
+ else |
|
184 |
+ { |
|
185 |
+ if (S_ISREG(statbuf.st_mode)) |
|
186 |
+ { |
|
187 |
+ if (cli_scanfile(fname, ctx) == CL_VIRUS) |
|
188 |
+ { |
|
189 |
+ free(fname); |
|
190 |
+ |
|
191 |
+ if (SCAN_ALL) |
|
192 |
+ { |
|
193 |
+ viruses_found++; |
|
194 |
+ continue; |
|
195 |
+ } |
|
181 | 196 |
|
182 | 197 |
closedir(dd); |
183 | 198 |
return CL_VIRUS; |
184 |
- } |
|
185 |
- } |
|
186 |
- } |
|
187 |
- } |
|
188 |
- free(fname); |
|
189 |
- } |
|
190 |
- } |
|
191 |
- } |
|
192 |
- } else { |
|
193 |
- cli_dbgmsg("cli_scandir: Can't open directory %s.\n", dirname); |
|
194 |
- return CL_EOPEN; |
|
199 |
+ } |
|
200 |
+ } |
|
201 |
+ } |
|
202 |
+ } |
|
203 |
+ free(fname); |
|
204 |
+ } |
|
205 |
+ } |
|
206 |
+ } |
|
207 |
+ } |
|
208 |
+ else |
|
209 |
+ { |
|
210 |
+ cli_dbgmsg("cli_scandir: Can't open directory %s.\n", dirname); |
|
211 |
+ return CL_EOPEN; |
|
195 | 212 |
} |
196 | 213 |
|
197 | 214 |
closedir(dd); |
198 | 215 |
if (SCAN_ALL && viruses_found) |
199 |
- return CL_VIRUS; |
|
216 |
+ return CL_VIRUS; |
|
200 | 217 |
return CL_CLEAN; |
201 | 218 |
} |
202 | 219 |
|
203 |
-static int cli_unrar_scanmetadata(int desc, unrar_metadata_t *metadata, cli_ctx *ctx, unsigned int files, uint32_t* sfx_check) |
|
220 |
+static int cli_unrar_scanmetadata(int desc, unrar_metadata_t *metadata, cli_ctx *ctx, unsigned int files, uint32_t *sfx_check) |
|
204 | 221 |
{ |
205 |
- int ret = CL_SUCCESS; |
|
206 |
- int virus_found = 0; |
|
222 |
+ int ret = CL_SUCCESS; |
|
223 |
+ int virus_found = 0; |
|
207 | 224 |
|
208 |
- if(files == 1 && sfx_check) { |
|
209 |
- if(*sfx_check == metadata->crc) |
|
210 |
- return CL_BREAK;/* break extract loop */ |
|
211 |
- else |
|
212 |
- *sfx_check = metadata->crc; |
|
225 |
+ if (files == 1 && sfx_check) |
|
226 |
+ { |
|
227 |
+ if (*sfx_check == metadata->crc) |
|
228 |
+ return CL_BREAK; /* break extract loop */ |
|
229 |
+ else |
|
230 |
+ *sfx_check = metadata->crc; |
|
213 | 231 |
} |
214 | 232 |
|
215 | 233 |
cli_dbgmsg("RAR: %s, crc32: 0x%x, encrypted: %u, compressed: %u, normal: %u, method: %u, ratio: %u\n", |
216 |
- metadata->filename, metadata->crc, metadata->encrypted, (unsigned int) metadata->pack_size, |
|
217 |
- (unsigned int) metadata->unpack_size, metadata->method, |
|
218 |
- metadata->pack_size ? (unsigned int) (metadata->unpack_size / metadata->pack_size) : 0); |
|
234 |
+ metadata->filename, metadata->crc, metadata->encrypted, (unsigned int)metadata->pack_size, |
|
235 |
+ (unsigned int)metadata->unpack_size, metadata->method, |
|
236 |
+ metadata->pack_size ? (unsigned int)(metadata->unpack_size / metadata->pack_size) : 0); |
|
219 | 237 |
|
220 |
- if(cli_matchmeta(ctx, metadata->filename, metadata->pack_size, metadata->unpack_size, metadata->encrypted, files, metadata->crc, NULL) == CL_VIRUS) { |
|
238 |
+ if (cli_matchmeta(ctx, metadata->filename, metadata->pack_size, metadata->unpack_size, metadata->encrypted, files, metadata->crc, NULL) == CL_VIRUS) |
|
239 |
+ { |
|
221 | 240 |
if (!SCAN_ALL) |
222 | 241 |
return CL_VIRUS; |
223 | 242 |
virus_found = 1; |
224 | 243 |
} |
225 | 244 |
|
226 |
- if(DETECT_ENCRYPTED && metadata->encrypted) { |
|
227 |
- cli_dbgmsg("RAR: Encrypted files found in archive.\n"); |
|
228 |
- ret = cli_scandesc(desc, ctx, 0, 0, NULL, AC_SCAN_VIR, NULL); |
|
229 |
- if(ret != CL_VIRUS) { |
|
230 |
- if (CL_VIRUS == cli_append_virus(ctx, "Heuristics.Encrypted.RAR")) |
|
245 |
+ if (DETECT_ENCRYPTED && metadata->encrypted) |
|
246 |
+ { |
|
247 |
+ cli_dbgmsg("RAR: Encrypted files found in archive.\n"); |
|
248 |
+ ret = cli_scandesc(desc, ctx, 0, 0, NULL, AC_SCAN_VIR, NULL); |
|
249 |
+ if (ret != CL_VIRUS) |
|
250 |
+ { |
|
251 |
+ if (CL_VIRUS == cli_append_virus(ctx, "Heuristics.Encrypted.RAR")) |
|
231 | 252 |
return CL_VIRUS; |
232 | 253 |
} |
233 | 254 |
} |
... | ... |
@@ -239,147 +260,165 @@ static int cli_unrar_scanmetadata(int desc, unrar_metadata_t *metadata, cli_ctx |
239 | 239 |
|
240 | 240 |
static int cli_scanrar(int desc, cli_ctx *ctx, off_t sfx_offset, uint32_t *sfx_check) |
241 | 241 |
{ |
242 |
- int ret = CL_CLEAN; |
|
243 |
- unrar_metadata_t *metadata, *metadata_tmp; |
|
244 |
- char *dir; |
|
245 |
- unrar_state_t rar_state; |
|
246 |
- unsigned int viruses_found = 0; |
|
242 |
+ int ret = CL_CLEAN; |
|
243 |
+ unrar_metadata_t *metadata, *metadata_tmp; |
|
244 |
+ char *dir; |
|
245 |
+ unrar_state_t rar_state; |
|
246 |
+ unsigned int viruses_found = 0; |
|
247 | 247 |
|
248 | 248 |
cli_dbgmsg("in scanrar()\n"); |
249 | 249 |
|
250 |
- if(sfx_offset) |
|
251 |
- if(lseek(desc, sfx_offset, SEEK_SET) == -1) |
|
252 |
- return CL_ESEEK; |
|
250 |
+ if (sfx_offset) |
|
251 |
+ if (lseek(desc, sfx_offset, SEEK_SET) == -1) |
|
252 |
+ return CL_ESEEK; |
|
253 | 253 |
|
254 | 254 |
/* generate the temporary directory */ |
255 |
- if(!(dir = cli_gentemp(ctx->engine->tmpdir))) |
|
256 |
- return CL_EMEM; |
|
257 |
- |
|
258 |
- if(mkdir(dir, 0700)) { |
|
259 |
- cli_dbgmsg("RAR: Can't create temporary directory %s\n", dir); |
|
260 |
- free(dir); |
|
261 |
- return CL_ETMPDIR; |
|
262 |
- } |
|
263 |
- |
|
264 |
- if((ret = cli_unrar_open(desc, dir, &rar_state)) != UNRAR_OK) { |
|
265 |
- if(!ctx->engine->keeptmp) |
|
266 |
- cli_rmdirs(dir); |
|
267 |
- free(dir); |
|
268 |
- if(ret == UNRAR_PASSWD) { |
|
269 |
- cli_dbgmsg("RAR: Encrypted main header\n"); |
|
270 |
- if(DETECT_ENCRYPTED) { |
|
271 |
- if (lseek(desc, 0, SEEK_SET) == -1) { |
|
255 |
+ if (!(dir = cli_gentemp(ctx->engine->tmpdir))) |
|
256 |
+ return CL_EMEM; |
|
257 |
+ |
|
258 |
+ if (mkdir(dir, 0700)) |
|
259 |
+ { |
|
260 |
+ cli_dbgmsg("RAR: Can't create temporary directory %s\n", dir); |
|
261 |
+ free(dir); |
|
262 |
+ return CL_ETMPDIR; |
|
263 |
+ } |
|
264 |
+ |
|
265 |
+ if ((ret = cli_unrar_open(desc, dir, &rar_state)) != UNRAR_OK) |
|
266 |
+ { |
|
267 |
+ if (!ctx->engine->keeptmp) |
|
268 |
+ cli_rmdirs(dir); |
|
269 |
+ free(dir); |
|
270 |
+ if (ret == UNRAR_PASSWD) |
|
271 |
+ { |
|
272 |
+ cli_dbgmsg("RAR: Encrypted main header\n"); |
|
273 |
+ if (DETECT_ENCRYPTED) |
|
274 |
+ { |
|
275 |
+ if (lseek(desc, 0, SEEK_SET) == -1) |
|
276 |
+ { |
|
272 | 277 |
cli_dbgmsg("RAR: call to lseek() failed\n"); |
273 | 278 |
return CL_ESEEK; |
274 | 279 |
} |
275 |
- ret = cli_scandesc(desc, ctx, 0, 0, NULL, AC_SCAN_VIR, NULL); |
|
276 |
- if(ret != CL_VIRUS) |
|
277 |
- if (CL_VIRUS == cli_append_virus(ctx, "Heuristics.Encrypted.RAR")) |
|
280 |
+ ret = cli_scandesc(desc, ctx, 0, 0, NULL, AC_SCAN_VIR, NULL); |
|
281 |
+ if (ret != CL_VIRUS) |
|
282 |
+ if (CL_VIRUS == cli_append_virus(ctx, "Heuristics.Encrypted.RAR")) |
|
278 | 283 |
return CL_VIRUS; |
279 |
- } |
|
280 |
- return CL_CLEAN; |
|
281 |
- } if(ret == UNRAR_EMEM) { |
|
282 |
- return CL_EMEM; |
|
283 |
- } else { |
|
284 |
- return CL_EUNPACK; |
|
285 |
- } |
|
286 |
- } |
|
287 |
- |
|
288 |
- do { |
|
289 |
- int rc; |
|
290 |
- rar_state.ofd = -1; |
|
291 |
- ret = cli_unrar_extract_next_prepare(&rar_state,dir); |
|
292 |
- if(ret != UNRAR_OK) { |
|
293 |
- if(ret == UNRAR_BREAK) |
|
294 |
- ret = CL_BREAK; |
|
295 |
- else if(ret == UNRAR_EMEM) |
|
296 |
- ret = CL_EMEM; |
|
297 |
- else |
|
298 |
- ret = CL_EUNPACK; |
|
299 |
- break; |
|
300 |
- } |
|
301 |
- if(ctx->engine->maxscansize && ctx->scansize >= ctx->engine->maxscansize) { |
|
302 |
- free(rar_state.file_header->filename); |
|
303 |
- free(rar_state.file_header); |
|
304 |
- ret = CL_CLEAN; |
|
305 |
- break; |
|
306 |
- } |
|
307 |
- if(ctx->engine->maxscansize && ctx->scansize + ctx->engine->maxfilesize >= ctx->engine->maxscansize) |
|
308 |
- rar_state.maxfilesize = ctx->engine->maxscansize - ctx->scansize; |
|
309 |
- else |
|
310 |
- rar_state.maxfilesize = ctx->engine->maxfilesize; |
|
311 |
- |
|
312 |
- ret = cli_unrar_extract_next(&rar_state,dir); |
|
313 |
- if(ret == UNRAR_OK) |
|
314 |
- ret = CL_SUCCESS; |
|
315 |
- else if(ret == UNRAR_EMEM) |
|
316 |
- ret = CL_EMEM; |
|
317 |
- else |
|
318 |
- ret = CL_EFORMAT; |
|
319 |
- |
|
320 |
- if(rar_state.ofd > 0) { |
|
321 |
- if (lseek(rar_state.ofd,0,SEEK_SET) == -1) { |
|
322 |
- cli_dbgmsg("RAR: Call to lseek() failed\n"); |
|
323 |
- ret = CL_ESEEK; |
|
324 |
- } |
|
325 |
- rc = cli_magic_scandesc(rar_state.ofd,ctx); |
|
326 |
- close(rar_state.ofd); |
|
327 |
- if(!ctx->engine->keeptmp) |
|
328 |
- if (cli_unlink(rar_state.filename)) ret = CL_EUNLINK; |
|
329 |
- if(rc == CL_VIRUS ) { |
|
330 |
- cli_dbgmsg("RAR: infected with %s\n", cli_get_last_virus(ctx)); |
|
331 |
- ret = CL_VIRUS; |
|
332 |
- viruses_found++; |
|
333 |
- } |
|
334 |
- } |
|
335 |
- |
|
336 |
- if(ret == CL_VIRUS) { |
|
337 |
- if(SCAN_ALL) |
|
338 |
- ret = CL_SUCCESS; |
|
339 |
- else |
|
340 |
- break; |
|
341 |
- } |
|
342 |
- |
|
343 |
- if(ret == CL_SUCCESS) |
|
344 |
- ret = cli_unrar_scanmetadata(desc,rar_state.metadata_tail, ctx, rar_state.file_count, sfx_check); |
|
345 |
- |
|
346 |
- } while(ret == CL_SUCCESS); |
|
347 |
- |
|
348 |
- if(ret == CL_BREAK) |
|
349 |
- ret = CL_CLEAN; |
|
350 |
- |
|
351 |
- metadata = metadata_tmp = rar_state.metadata; |
|
352 |
- |
|
353 |
- if(cli_scandir(rar_state.comment_dir, ctx) == CL_VIRUS) |
|
354 |
- ret = CL_VIRUS; |
|
284 |
+ } |
|
285 |
+ return CL_CLEAN; |
|
286 |
+ } |
|
287 |
+ if (ret == UNRAR_EMEM) |
|
288 |
+ { |
|
289 |
+ return CL_EMEM; |
|
290 |
+ } |
|
291 |
+ else |
|
292 |
+ { |
|
293 |
+ return CL_EUNPACK; |
|
294 |
+ } |
|
295 |
+ } |
|
296 |
+ |
|
297 |
+ do |
|
298 |
+ { |
|
299 |
+ int rc; |
|
300 |
+ rar_state.ofd = -1; |
|
301 |
+ ret = cli_unrar_extract_next_prepare(&rar_state, dir); |
|
302 |
+ if (ret != UNRAR_OK) |
|
303 |
+ { |
|
304 |
+ if (ret == UNRAR_BREAK) |
|
305 |
+ ret = CL_BREAK; |
|
306 |
+ else if (ret == UNRAR_EMEM) |
|
307 |
+ ret = CL_EMEM; |
|
308 |
+ else |
|
309 |
+ ret = CL_EUNPACK; |
|
310 |
+ break; |
|
311 |
+ } |
|
312 |
+ if (ctx->engine->maxscansize && ctx->scansize >= ctx->engine->maxscansize) |
|
313 |
+ { |
|
314 |
+ free(rar_state.file_header->filename); |
|
315 |
+ free(rar_state.file_header); |
|
316 |
+ ret = CL_CLEAN; |
|
317 |
+ break; |
|
318 |
+ } |
|
319 |
+ if (ctx->engine->maxscansize && ctx->scansize + ctx->engine->maxfilesize >= ctx->engine->maxscansize) |
|
320 |
+ rar_state.maxfilesize = ctx->engine->maxscansize - ctx->scansize; |
|
321 |
+ else |
|
322 |
+ rar_state.maxfilesize = ctx->engine->maxfilesize; |
|
323 |
+ |
|
324 |
+ ret = cli_unrar_extract_next(&rar_state, dir); |
|
325 |
+ if (ret == UNRAR_OK) |
|
326 |
+ ret = CL_SUCCESS; |
|
327 |
+ else if (ret == UNRAR_EMEM) |
|
328 |
+ ret = CL_EMEM; |
|
329 |
+ else |
|
330 |
+ ret = CL_EFORMAT; |
|
331 |
+ |
|
332 |
+ if (rar_state.ofd > 0) |
|
333 |
+ { |
|
334 |
+ if (lseek(rar_state.ofd, 0, SEEK_SET) == -1) |
|
335 |
+ { |
|
336 |
+ cli_dbgmsg("RAR: Call to lseek() failed\n"); |
|
337 |
+ ret = CL_ESEEK; |
|
338 |
+ } |
|
339 |
+ rc = cli_magic_scandesc(rar_state.ofd, ctx); |
|
340 |
+ close(rar_state.ofd); |
|
341 |
+ if (!ctx->engine->keeptmp) |
|
342 |
+ if (cli_unlink(rar_state.filename)) |
|
343 |
+ ret = CL_EUNLINK; |
|
344 |
+ if (rc == CL_VIRUS) |
|
345 |
+ { |
|
346 |
+ cli_dbgmsg("RAR: infected with %s\n", cli_get_last_virus(ctx)); |
|
347 |
+ ret = CL_VIRUS; |
|
348 |
+ viruses_found++; |
|
349 |
+ } |
|
350 |
+ } |
|
351 |
+ |
|
352 |
+ if (ret == CL_VIRUS) |
|
353 |
+ { |
|
354 |
+ if (SCAN_ALL) |
|
355 |
+ ret = CL_SUCCESS; |
|
356 |
+ else |
|
357 |
+ break; |
|
358 |
+ } |
|
359 |
+ |
|
360 |
+ if (ret == CL_SUCCESS) |
|
361 |
+ ret = cli_unrar_scanmetadata(desc, rar_state.metadata_tail, ctx, rar_state.file_count, sfx_check); |
|
362 |
+ |
|
363 |
+ } while (ret == CL_SUCCESS); |
|
364 |
+ |
|
365 |
+ if (ret == CL_BREAK) |
|
366 |
+ ret = CL_CLEAN; |
|
367 |
+ |
|
368 |
+ metadata = metadata_tmp = rar_state.metadata; |
|
369 |
+ |
|
370 |
+ if (cli_scandir(rar_state.comment_dir, ctx) == CL_VIRUS) |
|
371 |
+ ret = CL_VIRUS; |
|
355 | 372 |
|
356 | 373 |
cli_unrar_close(&rar_state); |
357 | 374 |
|
358 |
- if(!ctx->engine->keeptmp) |
|
375 |
+ if (!ctx->engine->keeptmp) |
|
359 | 376 |
cli_rmdirs(dir); |
360 | 377 |
|
361 | 378 |
free(dir); |
362 | 379 |
|
363 | 380 |
metadata = metadata_tmp; |
364 |
- while (metadata) { |
|
365 |
- metadata_tmp = metadata->next; |
|
366 |
- free(metadata->filename); |
|
367 |
- free(metadata); |
|
368 |
- metadata = metadata_tmp; |
|
381 |
+ while (metadata) |
|
382 |
+ { |
|
383 |
+ metadata_tmp = metadata->next; |
|
384 |
+ free(metadata->filename); |
|
385 |
+ free(metadata); |
|
386 |
+ metadata = metadata_tmp; |
|
369 | 387 |
} |
370 | 388 |
cli_dbgmsg("RAR: Exit code: %d\n", ret); |
371 | 389 |
|
372 | 390 |
if (SCAN_ALL && viruses_found) |
373 |
- return CL_VIRUS; |
|
391 |
+ return CL_VIRUS; |
|
374 | 392 |
return ret; |
375 | 393 |
} |
376 | 394 |
|
377 | 395 |
static int cli_scanarj(cli_ctx *ctx, off_t sfx_offset, uint32_t *sfx_check) |
378 | 396 |
{ |
379 |
- int ret = CL_CLEAN, rc, file = 0; |
|
380 |
- arj_metadata_t metadata; |
|
381 |
- char *dir; |
|
382 |
- int virus_found = 0; |
|
397 |
+ int ret = CL_CLEAN, rc, file = 0; |
|
398 |
+ arj_metadata_t metadata; |
|
399 |
+ char *dir; |
|
400 |
+ int virus_found = 0; |
|
383 | 401 |
|
384 | 402 |
UNUSEDPARAM(sfx_check); |
385 | 403 |
|
... | ... |
@@ -387,35 +426,41 @@ static int cli_scanarj(cli_ctx *ctx, off_t sfx_offset, uint32_t *sfx_check) |
387 | 387 |
|
388 | 388 |
memset(&metadata, 0, sizeof(arj_metadata_t)); |
389 | 389 |
|
390 |
- /* generate the temporary directory */ |
|
391 |
- if(!(dir = cli_gentemp(ctx->engine->tmpdir))) |
|
392 |
- return CL_EMEM; |
|
390 |
+ /* generate the temporary directory */ |
|
391 |
+ if (!(dir = cli_gentemp(ctx->engine->tmpdir))) |
|
392 |
+ return CL_EMEM; |
|
393 | 393 |
|
394 |
- if(mkdir(dir, 0700)) { |
|
395 |
- cli_dbgmsg("ARJ: Can't create temporary directory %s\n", dir); |
|
396 |
- free(dir); |
|
397 |
- return CL_ETMPDIR; |
|
394 |
+ if (mkdir(dir, 0700)) |
|
395 |
+ { |
|
396 |
+ cli_dbgmsg("ARJ: Can't create temporary directory %s\n", dir); |
|
397 |
+ free(dir); |
|
398 |
+ return CL_ETMPDIR; |
|
398 | 399 |
} |
399 | 400 |
|
400 | 401 |
ret = cli_unarj_open(*ctx->fmap, dir, &metadata, sfx_offset); |
401 |
- if (ret != CL_SUCCESS) { |
|
402 |
- if(!ctx->engine->keeptmp) |
|
403 |
- cli_rmdirs(dir); |
|
404 |
- free(dir); |
|
405 |
- cli_dbgmsg("ARJ: Error: %s\n", cl_strerror(ret)); |
|
406 |
- return ret; |
|
407 |
- } |
|
408 |
- |
|
409 |
- do { |
|
402 |
+ if (ret != CL_SUCCESS) |
|
403 |
+ { |
|
404 |
+ if (!ctx->engine->keeptmp) |
|
405 |
+ cli_rmdirs(dir); |
|
406 |
+ free(dir); |
|
407 |
+ cli_dbgmsg("ARJ: Error: %s\n", cl_strerror(ret)); |
|
408 |
+ return ret; |
|
409 |
+ } |
|
410 |
+ |
|
411 |
+ do |
|
412 |
+ { |
|
410 | 413 |
metadata.filename = NULL; |
411 |
- ret = cli_unarj_prepare_file(dir, &metadata); |
|
412 |
- if (ret != CL_SUCCESS) { |
|
413 |
- cli_dbgmsg("ARJ: cli_unarj_prepare_file Error: %s\n", cl_strerror(ret)); |
|
414 |
- break; |
|
415 |
- } |
|
416 |
- file++; |
|
417 |
- if(cli_matchmeta(ctx, metadata.filename, metadata.comp_size, metadata.orig_size, metadata.encrypted, file, 0, NULL) == CL_VIRUS) { |
|
418 |
- if (!SCAN_ALL) { |
|
414 |
+ ret = cli_unarj_prepare_file(dir, &metadata); |
|
415 |
+ if (ret != CL_SUCCESS) |
|
416 |
+ { |
|
417 |
+ cli_dbgmsg("ARJ: cli_unarj_prepare_file Error: %s\n", cl_strerror(ret)); |
|
418 |
+ break; |
|
419 |
+ } |
|
420 |
+ file++; |
|
421 |
+ if (cli_matchmeta(ctx, metadata.filename, metadata.comp_size, metadata.orig_size, metadata.encrypted, file, 0, NULL) == CL_VIRUS) |
|
422 |
+ { |
|
423 |
+ if (!SCAN_ALL) |
|
424 |
+ { |
|
419 | 425 |
cli_rmdirs(dir); |
420 | 426 |
free(dir); |
421 | 427 |
return CL_VIRUS; |
... | ... |
@@ -424,27 +469,34 @@ static int cli_scanarj(cli_ctx *ctx, off_t sfx_offset, uint32_t *sfx_check) |
424 | 424 |
ret = CL_SUCCESS; |
425 | 425 |
} |
426 | 426 |
|
427 |
- if ((ret = cli_checklimits("ARJ", ctx, metadata.orig_size, metadata.comp_size, 0))!=CL_CLEAN) { |
|
428 |
- ret = CL_SUCCESS; |
|
429 |
- if (metadata.filename) |
|
430 |
- free(metadata.filename); |
|
431 |
- continue; |
|
432 |
- } |
|
433 |
- ret = cli_unarj_extract_file(dir, &metadata); |
|
434 |
- if (ret != CL_SUCCESS) { |
|
435 |
- cli_dbgmsg("ARJ: cli_unarj_extract_file Error: %s\n", cl_strerror(ret)); |
|
436 |
- } |
|
437 |
- if (metadata.ofd >= 0) { |
|
438 |
- if (lseek(metadata.ofd, 0, SEEK_SET) == -1) { |
|
439 |
- cli_dbgmsg("ARJ: call to lseek() failed\n"); |
|
440 |
- } |
|
441 |
- rc = cli_magic_scandesc(metadata.ofd, ctx); |
|
442 |
- close(metadata.ofd); |
|
443 |
- if (rc == CL_VIRUS) { |
|
444 |
- cli_dbgmsg("ARJ: infected with %s\n", cli_get_last_virus(ctx)); |
|
445 |
- if (!SCAN_ALL) { |
|
427 |
+ if ((ret = cli_checklimits("ARJ", ctx, metadata.orig_size, metadata.comp_size, 0)) != CL_CLEAN) |
|
428 |
+ { |
|
429 |
+ ret = CL_SUCCESS; |
|
430 |
+ if (metadata.filename) |
|
431 |
+ free(metadata.filename); |
|
432 |
+ continue; |
|
433 |
+ } |
|
434 |
+ ret = cli_unarj_extract_file(dir, &metadata); |
|
435 |
+ if (ret != CL_SUCCESS) |
|
436 |
+ { |
|
437 |
+ cli_dbgmsg("ARJ: cli_unarj_extract_file Error: %s\n", cl_strerror(ret)); |
|
438 |
+ } |
|
439 |
+ if (metadata.ofd >= 0) |
|
440 |
+ { |
|
441 |
+ if (lseek(metadata.ofd, 0, SEEK_SET) == -1) |
|
442 |
+ { |
|
443 |
+ cli_dbgmsg("ARJ: call to lseek() failed\n"); |
|
444 |
+ } |
|
445 |
+ rc = cli_magic_scandesc(metadata.ofd, ctx); |
|
446 |
+ close(metadata.ofd); |
|
447 |
+ if (rc == CL_VIRUS) |
|
448 |
+ { |
|
449 |
+ cli_dbgmsg("ARJ: infected with %s\n", cli_get_last_virus(ctx)); |
|
450 |
+ if (!SCAN_ALL) |
|
451 |
+ { |
|
446 | 452 |
ret = CL_VIRUS; |
447 |
- if (metadata.filename) { |
|
453 |
+ if (metadata.filename) |
|
454 |
+ { |
|
448 | 455 |
free(metadata.filename); |
449 | 456 |
metadata.filename = NULL; |
450 | 457 |
} |
... | ... |
@@ -452,199 +504,229 @@ static int cli_scanarj(cli_ctx *ctx, off_t sfx_offset, uint32_t *sfx_check) |
452 | 452 |
} |
453 | 453 |
virus_found = 1; |
454 | 454 |
ret = CL_SUCCESS; |
455 |
- } |
|
456 |
- } |
|
457 |
- if (metadata.filename) { |
|
458 |
- free(metadata.filename); |
|
459 |
- metadata.filename = NULL; |
|
460 |
- } |
|
461 |
- |
|
462 |
- } while(ret == CL_SUCCESS); |
|
463 |
- |
|
464 |
- if(!ctx->engine->keeptmp) |
|
465 |
- cli_rmdirs(dir); |
|
455 |
+ } |
|
456 |
+ } |
|
457 |
+ if (metadata.filename) |
|
458 |
+ { |
|
459 |
+ free(metadata.filename); |
|
460 |
+ metadata.filename = NULL; |
|
461 |
+ } |
|
462 |
+ |
|
463 |
+ } while (ret == CL_SUCCESS); |
|
464 |
+ |
|
465 |
+ if (!ctx->engine->keeptmp) |
|
466 |
+ cli_rmdirs(dir); |
|
466 | 467 |
|
467 | 468 |
free(dir); |
468 |
- if (metadata.filename) { |
|
469 |
- free(metadata.filename); |
|
469 |
+ if (metadata.filename) |
|
470 |
+ { |
|
471 |
+ free(metadata.filename); |
|
470 | 472 |
} |
471 | 473 |
|
472 | 474 |
if (virus_found != 0) |
473 | 475 |
ret = CL_VIRUS; |
474 | 476 |
cli_dbgmsg("ARJ: Exit code: %d\n", ret); |
475 | 477 |
if (ret == CL_BREAK) |
476 |
- ret = CL_CLEAN; |
|
478 |
+ ret = CL_CLEAN; |
|
477 | 479 |
|
478 | 480 |
return ret; |
479 | 481 |
} |
480 | 482 |
|
481 |
- |
|
482 |
-static int cli_scangzip_with_zib_from_the_80s(cli_ctx *ctx, unsigned char *buff) { |
|
483 |
+static int cli_scangzip_with_zib_from_the_80s(cli_ctx *ctx, unsigned char *buff) |
|
484 |
+{ |
|
483 | 485 |
int fd, ret, outsize = 0, bytes; |
484 | 486 |
fmap_t *map = *ctx->fmap; |
485 | 487 |
char *tmpname; |
486 | 488 |
gzFile gz; |
487 | 489 |
|
488 | 490 |
ret = fmap_fd(map); |
489 |
- if(ret < 0) |
|
490 |
- return CL_EDUP; |
|
491 |
+ if (ret < 0) |
|
492 |
+ return CL_EDUP; |
|
491 | 493 |
fd = dup(ret); |
492 |
- if(fd < 0) |
|
493 |
- return CL_EDUP; |
|
494 |
- |
|
495 |
- if(!(gz = gzdopen(fd, "rb"))) { |
|
496 |
- close(fd); |
|
497 |
- return CL_EOPEN; |
|
498 |
- } |
|
499 |
- |
|
500 |
- if((ret = cli_gentempfd(ctx->engine->tmpdir, &tmpname, &fd)) != CL_SUCCESS) { |
|
501 |
- cli_dbgmsg("GZip: Can't generate temporary file.\n"); |
|
502 |
- gzclose(gz); |
|
503 |
- close(fd); |
|
504 |
- return ret; |
|
505 |
- } |
|
506 |
- |
|
507 |
- while((bytes = gzread(gz, buff, FILEBUFF)) > 0) { |
|
508 |
- outsize += bytes; |
|
509 |
- if(cli_checklimits("GZip", ctx, outsize, 0, 0)!=CL_CLEAN) |
|
510 |
- break; |
|
511 |
- if(cli_writen(fd, buff, bytes) != bytes) { |
|
512 |
- close(fd); |
|
513 |
- gzclose(gz); |
|
514 |
- if(cli_unlink(tmpname)) { |
|
515 |
- free(tmpname); |
|
516 |
- return CL_EUNLINK; |
|
517 |
- } |
|
518 |
- free(tmpname); |
|
519 |
- return CL_EWRITE; |
|
520 |
- } |
|
494 |
+ if (fd < 0) |
|
495 |
+ return CL_EDUP; |
|
496 |
+ |
|
497 |
+ if (!(gz = gzdopen(fd, "rb"))) |
|
498 |
+ { |
|
499 |
+ close(fd); |
|
500 |
+ return CL_EOPEN; |
|
501 |
+ } |
|
502 |
+ |
|
503 |
+ if ((ret = cli_gentempfd(ctx->engine->tmpdir, &tmpname, &fd)) != CL_SUCCESS) |
|
504 |
+ { |
|
505 |
+ cli_dbgmsg("GZip: Can't generate temporary file.\n"); |
|
506 |
+ gzclose(gz); |
|
507 |
+ close(fd); |
|
508 |
+ return ret; |
|
509 |
+ } |
|
510 |
+ |
|
511 |
+ while ((bytes = gzread(gz, buff, FILEBUFF)) > 0) |
|
512 |
+ { |
|
513 |
+ outsize += bytes; |
|
514 |
+ if (cli_checklimits("GZip", ctx, outsize, 0, 0) != CL_CLEAN) |
|
515 |
+ break; |
|
516 |
+ if (cli_writen(fd, buff, bytes) != bytes) |
|
517 |
+ { |
|
518 |
+ close(fd); |
|
519 |
+ gzclose(gz); |
|
520 |
+ if (cli_unlink(tmpname)) |
|
521 |
+ { |
|
522 |
+ free(tmpname); |
|
523 |
+ return CL_EUNLINK; |
|
524 |
+ } |
|
525 |
+ free(tmpname); |
|
526 |
+ return CL_EWRITE; |
|
527 |
+ } |
|
521 | 528 |
} |
522 | 529 |
|
523 | 530 |
gzclose(gz); |
524 | 531 |
|
525 |
- if((ret = cli_magic_scandesc(fd, ctx)) == CL_VIRUS) { |
|
526 |
- cli_dbgmsg("GZip: Infected with %s\n", cli_get_last_virus(ctx)); |
|
527 |
- close(fd); |
|
528 |
- if(!ctx->engine->keeptmp) { |
|
529 |
- if (cli_unlink(tmpname)) { |
|
530 |
- free(tmpname); |
|
531 |
- return CL_EUNLINK; |
|
532 |
- } |
|
533 |
- } |
|
534 |
- free(tmpname); |
|
535 |
- return CL_VIRUS; |
|
532 |
+ if ((ret = cli_magic_scandesc(fd, ctx)) == CL_VIRUS) |
|
533 |
+ { |
|
534 |
+ cli_dbgmsg("GZip: Infected with %s\n", cli_get_last_virus(ctx)); |
|
535 |
+ close(fd); |
|
536 |
+ if (!ctx->engine->keeptmp) |
|
537 |
+ { |
|
538 |
+ if (cli_unlink(tmpname)) |
|
539 |
+ { |
|
540 |
+ free(tmpname); |
|
541 |
+ return CL_EUNLINK; |
|
542 |
+ } |
|
543 |
+ } |
|
544 |
+ free(tmpname); |
|
545 |
+ return CL_VIRUS; |
|
536 | 546 |
} |
537 | 547 |
close(fd); |
538 |
- if(!ctx->engine->keeptmp) |
|
539 |
- if (cli_unlink(tmpname)) ret = CL_EUNLINK; |
|
548 |
+ if (!ctx->engine->keeptmp) |
|
549 |
+ if (cli_unlink(tmpname)) |
|
550 |
+ ret = CL_EUNLINK; |
|
540 | 551 |
free(tmpname); |
541 | 552 |
return ret; |
542 | 553 |
} |
543 | 554 |
|
544 | 555 |
static int cli_scangzip(cli_ctx *ctx) |
545 | 556 |
{ |
546 |
- int fd, ret = CL_CLEAN; |
|
547 |
- unsigned char buff[FILEBUFF]; |
|
548 |
- char *tmpname; |
|
549 |
- z_stream z; |
|
550 |
- size_t at = 0, outsize = 0; |
|
551 |
- fmap_t *map = *ctx->fmap; |
|
552 |
- |
|
557 |
+ int fd, ret = CL_CLEAN; |
|
558 |
+ unsigned char buff[FILEBUFF]; |
|
559 |
+ char *tmpname; |
|
560 |
+ z_stream z; |
|
561 |
+ size_t at = 0, outsize = 0; |
|
562 |
+ fmap_t *map = *ctx->fmap; |
|
563 |
+ |
|
553 | 564 |
cli_dbgmsg("in cli_scangzip()\n"); |
554 | 565 |
|
555 | 566 |
memset(&z, 0, sizeof(z)); |
556 |
- if((ret = inflateInit2(&z, MAX_WBITS + 16)) != Z_OK) { |
|
557 |
- cli_dbgmsg("GZip: InflateInit failed: %d\n", ret); |
|
558 |
- return cli_scangzip_with_zib_from_the_80s(ctx, buff); |
|
559 |
- } |
|
560 |
- |
|
561 |
- if((ret = cli_gentempfd(ctx->engine->tmpdir, &tmpname, &fd)) != CL_SUCCESS) { |
|
562 |
- cli_dbgmsg("GZip: Can't generate temporary file.\n"); |
|
563 |
- inflateEnd(&z); |
|
564 |
- return ret; |
|
565 |
- } |
|
566 |
- |
|
567 |
- while (at < map->len) { |
|
568 |
- unsigned int bytes = MIN(map->len - at, map->pgsz); |
|
569 |
- if(!(z.next_in = (void*)fmap_need_off_once(map, at, bytes))) { |
|
570 |
- cli_dbgmsg("GZip: Can't read %u bytes @ %lu.\n", bytes, (long unsigned)at); |
|
571 |
- inflateEnd(&z); |
|
572 |
- close(fd); |
|
573 |
- if (cli_unlink(tmpname)) { |
|
574 |
- free(tmpname); |
|
575 |
- return CL_EUNLINK; |
|
576 |
- } |
|
577 |
- free(tmpname); |
|
578 |
- return CL_EREAD; |
|
579 |
- } |
|
580 |
- at += bytes; |
|
581 |
- z.avail_in = bytes; |
|
582 |
- do { |
|
583 |
- int inf; |
|
584 |
- z.avail_out = sizeof(buff); |
|
567 |
+ if ((ret = inflateInit2(&z, MAX_WBITS + 16)) != Z_OK) |
|
568 |
+ { |
|
569 |
+ cli_dbgmsg("GZip: InflateInit failed: %d\n", ret); |
|
570 |
+ return cli_scangzip_with_zib_from_the_80s(ctx, buff); |
|
571 |
+ } |
|
572 |
+ |
|
573 |
+ if ((ret = cli_gentempfd(ctx->engine->tmpdir, &tmpname, &fd)) != CL_SUCCESS) |
|
574 |
+ { |
|
575 |
+ cli_dbgmsg("GZip: Can't generate temporary file.\n"); |
|
576 |
+ inflateEnd(&z); |
|
577 |
+ return ret; |
|
578 |
+ } |
|
579 |
+ |
|
580 |
+ while (at < map->len) |
|
581 |
+ { |
|
582 |
+ unsigned int bytes = MIN(map->len - at, map->pgsz); |
|
583 |
+ if (!(z.next_in = (void *)fmap_need_off_once(map, at, bytes))) |
|
584 |
+ { |
|
585 |
+ cli_dbgmsg("GZip: Can't read %u bytes @ %lu.\n", bytes, (long unsigned)at); |
|
586 |
+ inflateEnd(&z); |
|
587 |
+ close(fd); |
|
588 |
+ if (cli_unlink(tmpname)) |
|
589 |
+ { |
|
590 |
+ free(tmpname); |
|
591 |
+ return CL_EUNLINK; |
|
592 |
+ } |
|
593 |
+ free(tmpname); |
|
594 |
+ return CL_EREAD; |
|
595 |
+ } |
|
596 |
+ at += bytes; |
|
597 |
+ z.avail_in = bytes; |
|
598 |
+ do |
|
599 |
+ { |
|
600 |
+ int inf; |
|
601 |
+ z.avail_out = sizeof(buff); |
|
585 | 602 |
z.next_out = buff; |
586 |
- inf = inflate(&z, Z_NO_FLUSH); |
|
587 |
- if(inf != Z_OK && inf != Z_STREAM_END && inf != Z_BUF_ERROR) { |
|
588 |
- if (sizeof(buff) == z.avail_out) { |
|
589 |
- cli_dbgmsg("GZip: Bad stream, nothing in output buffer.\n"); |
|
590 |
- at = map->len; |
|
591 |
- break; |
|
592 |
- } |
|
593 |
- else { |
|
594 |
- cli_dbgmsg("GZip: Bad stream, data in output buffer.\n"); |
|
595 |
- /* no break yet, flush extracted bytes to file */ |
|
596 |
- } |
|
597 |
- } |
|
598 |
- if(cli_writen(fd, buff, sizeof(buff) - z.avail_out) < 0) { |
|
599 |
- inflateEnd(&z); |
|
600 |
- close(fd); |
|
601 |
- if (cli_unlink(tmpname)) { |
|
602 |
- free(tmpname); |
|
603 |
- return CL_EUNLINK; |
|
604 |
- } |
|
605 |
- free(tmpname); |
|
606 |
- return CL_EWRITE; |
|
607 |
- } |
|
608 |
- outsize += sizeof(buff) - z.avail_out; |
|
609 |
- if(cli_checklimits("GZip", ctx, outsize, 0, 0)!=CL_CLEAN) { |
|
610 |
- at = map->len; |
|
611 |
- break; |
|
612 |
- } |
|
613 |
- if(inf == Z_STREAM_END) { |
|
614 |
- at -= z.avail_in; |
|
615 |
- inflateReset(&z); |
|
616 |
- break; |
|
617 |
- } |
|
618 |
- else if(inf != Z_OK && inf != Z_BUF_ERROR) { |
|
619 |
- at = map->len; |
|
620 |
- break; |
|
621 |
- } |
|
622 |
- } while (z.avail_out == 0); |
|
623 |
- } |
|
624 |
- |
|
625 |
- inflateEnd(&z); |
|
626 |
- |
|
627 |
- if((ret = cli_magic_scandesc(fd, ctx)) == CL_VIRUS) { |
|
628 |
- cli_dbgmsg("GZip: Infected with %s\n", cli_get_last_virus(ctx)); |
|
629 |
- close(fd); |
|
630 |
- if(!ctx->engine->keeptmp) { |
|
631 |
- if (cli_unlink(tmpname)) { |
|
632 |
- free(tmpname); |
|
633 |
- return CL_EUNLINK; |
|
634 |
- } |
|
635 |
- } |
|
636 |
- free(tmpname); |
|
637 |
- return CL_VIRUS; |
|
603 |
+ inf = inflate(&z, Z_NO_FLUSH); |
|
604 |
+ if (inf != Z_OK && inf != Z_STREAM_END && inf != Z_BUF_ERROR) |
|
605 |
+ { |
|
606 |
+ if (sizeof(buff) == z.avail_out) |
|
607 |
+ { |
|
608 |
+ cli_dbgmsg("GZip: Bad stream, nothing in output buffer.\n"); |
|
609 |
+ at = map->len; |
|
610 |
+ break; |
|
611 |
+ } |
|
612 |
+ else |
|
613 |
+ { |
|
614 |
+ cli_dbgmsg("GZip: Bad stream, data in output buffer.\n"); |
|
615 |
+ /* no break yet, flush extracted bytes to file */ |
|
616 |
+ } |
|
617 |
+ } |
|
618 |
+ if (cli_writen(fd, buff, sizeof(buff) - z.avail_out) < 0) |
|
619 |
+ { |
|
620 |
+ inflateEnd(&z); |
|
621 |
+ close(fd); |
|
622 |
+ if (cli_unlink(tmpname)) |
|
623 |
+ { |
|
624 |
+ free(tmpname); |
|
625 |
+ return CL_EUNLINK; |
|
626 |
+ } |
|
627 |
+ free(tmpname); |
|
628 |
+ return CL_EWRITE; |
|
629 |
+ } |
|
630 |
+ outsize += sizeof(buff) - z.avail_out; |
|
631 |
+ if (cli_checklimits("GZip", ctx, outsize, 0, 0) != CL_CLEAN) |
|
632 |
+ { |
|
633 |
+ at = map->len; |
|
634 |
+ break; |
|
635 |
+ } |
|
636 |
+ if (inf == Z_STREAM_END) |
|
637 |
+ { |
|
638 |
+ at -= z.avail_in; |
|
639 |
+ inflateReset(&z); |
|
640 |
+ break; |
|
641 |
+ } |
|
642 |
+ else if (inf != Z_OK && inf != Z_BUF_ERROR) |
|
643 |
+ { |
|
644 |
+ at = map->len; |
|
645 |
+ break; |
|
646 |
+ } |
|
647 |
+ } while (z.avail_out == 0); |
|
648 |
+ } |
|
649 |
+ |
|
650 |
+ inflateEnd(&z); |
|
651 |
+ |
|
652 |
+ if ((ret = cli_magic_scandesc(fd, ctx)) == CL_VIRUS) |
|
653 |
+ { |
|
654 |
+ cli_dbgmsg("GZip: Infected with %s\n", cli_get_last_virus(ctx)); |
|
655 |
+ close(fd); |
|
656 |
+ if (!ctx->engine->keeptmp) |
|
657 |
+ { |
|
658 |
+ if (cli_unlink(tmpname)) |
|
659 |
+ { |
|
660 |
+ free(tmpname); |
|
661 |
+ return CL_EUNLINK; |
|
662 |
+ } |
|
663 |
+ } |
|
664 |
+ free(tmpname); |
|
665 |
+ return CL_VIRUS; |
|
638 | 666 |
} |
639 | 667 |
close(fd); |
640 |
- if(!ctx->engine->keeptmp) |
|
641 |
- if (cli_unlink(tmpname)) ret = CL_EUNLINK; |
|
668 |
+ if (!ctx->engine->keeptmp) |
|
669 |
+ if (cli_unlink(tmpname)) |
|
670 |
+ ret = CL_EUNLINK; |
|
642 | 671 |
free(tmpname); |
643 | 672 |
return ret; |
644 | 673 |
} |
645 | 674 |
|
646 | 675 |
#ifndef HAVE_BZLIB_H |
647 |
-static int cli_scanbzip(cli_ctx *ctx) { |
|
676 |
+static int cli_scanbzip(cli_ctx *ctx) |
|
677 |
+{ |
|
648 | 678 |
cli_warnmsg("cli_scanbzip: bzip2 support not compiled in\n"); |
649 | 679 |
return CL_CLEAN; |
650 | 680 |
} |
... | ... |
@@ -671,78 +753,92 @@ static int cli_scanbzip(cli_ctx *ctx) |
671 | 671 |
strm.next_out = buf; |
672 | 672 |
strm.avail_out = sizeof(buf); |
673 | 673 |
rc = BZ2_bzDecompressInit(&strm, 0, 0); |
674 |
- if (BZ_OK != rc) { |
|
675 |
- cli_dbgmsg("Bzip: DecompressInit failed: %d\n", rc); |
|
676 |
- return CL_EOPEN; |
|
677 |
- } |
|
678 |
- |
|
679 |
- if((ret = cli_gentempfd(ctx->engine->tmpdir, &tmpname, &fd))) { |
|
680 |
- cli_dbgmsg("Bzip: Can't generate temporary file.\n"); |
|
681 |
- BZ2_bzDecompressEnd(&strm); |
|
682 |
- return ret; |
|
683 |
- } |
|
684 |
- |
|
685 |
- do { |
|
686 |
- if (!strm.avail_in) { |
|
687 |
- strm.next_in = (void*)fmap_need_off_once_len(*ctx->fmap, off, FILEBUFF, &avail); |
|
688 |
- strm.avail_in = avail; |
|
689 |
- off += avail; |
|
690 |
- if (!strm.avail_in) { |
|
691 |
- cli_dbgmsg("Bzip: premature end of compressed stream\n"); |
|
692 |
- break; |
|
693 |
- } |
|
694 |
- } |
|
695 |
- |
|
696 |
- rc = BZ2_bzDecompress(&strm); |
|
697 |
- if (BZ_OK != rc && BZ_STREAM_END != rc) { |
|
698 |
- cli_dbgmsg("Bzip: decompress error: %d\n", rc); |
|
699 |
- break; |
|
700 |
- } |
|
701 |
- |
|
702 |
- if (!strm.avail_out || BZ_STREAM_END == rc) { |
|
703 |
- |
|
704 |
- size += sizeof(buf) - strm.avail_out; |
|
705 |
- |
|
706 |
- if(cli_writen(fd, buf, sizeof(buf) - strm.avail_out) != sizeof(buf) - strm.avail_out) { |
|
707 |
- cli_dbgmsg("Bzip: Can't write to file.\n"); |
|
708 |
- BZ2_bzDecompressEnd(&strm); |
|
709 |
- close(fd); |
|
710 |
- if(!ctx->engine->keeptmp) { |
|
711 |
- if (cli_unlink(tmpname)) { |
|
712 |
- free(tmpname); |
|
713 |
- return CL_EUNLINK; |
|
714 |
- } |
|
715 |
- } |
|
716 |
- free(tmpname); |
|
717 |
- return CL_EWRITE; |
|
718 |
- } |
|
719 |
- |
|
720 |
- if(cli_checklimits("Bzip", ctx, size, 0, 0) != CL_CLEAN) |
|
721 |
- break; |
|
722 |
- |
|
723 |
- strm.next_out = buf; |
|
724 |
- strm.avail_out = sizeof(buf); |
|
725 |
- } |
|
674 |
+ if (BZ_OK != rc) |
|
675 |
+ { |
|
676 |
+ cli_dbgmsg("Bzip: DecompressInit failed: %d\n", rc); |
|
677 |
+ return CL_EOPEN; |
|
678 |
+ } |
|
679 |
+ |
|
680 |
+ if ((ret = cli_gentempfd(ctx->engine->tmpdir, &tmpname, &fd))) |
|
681 |
+ { |
|
682 |
+ cli_dbgmsg("Bzip: Can't generate temporary file.\n"); |
|
683 |
+ BZ2_bzDecompressEnd(&strm); |
|
684 |
+ return ret; |
|
685 |
+ } |
|
686 |
+ |
|
687 |
+ do |
|
688 |
+ { |
|
689 |
+ if (!strm.avail_in) |
|
690 |
+ { |
|
691 |
+ strm.next_in = (void *)fmap_need_off_once_len(*ctx->fmap, off, FILEBUFF, &avail); |
|
692 |
+ strm.avail_in = avail; |
|
693 |
+ off += avail; |
|
694 |
+ if (!strm.avail_in) |
|
695 |
+ { |
|
696 |
+ cli_dbgmsg("Bzip: premature end of compressed stream\n"); |
|
697 |
+ break; |
|
698 |
+ } |
|
699 |
+ } |
|
700 |
+ |
|
701 |
+ rc = BZ2_bzDecompress(&strm); |
|
702 |
+ if (BZ_OK != rc && BZ_STREAM_END != rc) |
|
703 |
+ { |
|
704 |
+ cli_dbgmsg("Bzip: decompress error: %d\n", rc); |
|
705 |
+ break; |
|
706 |
+ } |
|
707 |
+ |
|
708 |
+ if (!strm.avail_out || BZ_STREAM_END == rc) |
|
709 |
+ { |
|
710 |
+ |
|
711 |
+ size += sizeof(buf) - strm.avail_out; |
|
712 |
+ |
|
713 |
+ if (cli_writen(fd, buf, sizeof(buf) - strm.avail_out) != sizeof(buf) - strm.avail_out) |
|
714 |
+ { |
|
715 |
+ cli_dbgmsg("Bzip: Can't write to file.\n"); |
|
716 |
+ BZ2_bzDecompressEnd(&strm); |
|
717 |
+ close(fd); |
|
718 |
+ if (!ctx->engine->keeptmp) |
|
719 |
+ { |
|
720 |
+ if (cli_unlink(tmpname)) |
|
721 |
+ { |
|
722 |
+ free(tmpname); |
|
723 |
+ return CL_EUNLINK; |
|
724 |
+ } |
|
725 |
+ } |
|
726 |
+ free(tmpname); |
|
727 |
+ return CL_EWRITE; |
|
728 |
+ } |
|
729 |
+ |
|
730 |
+ if (cli_checklimits("Bzip", ctx, size, 0, 0) != CL_CLEAN) |
|
731 |
+ break; |
|
732 |
+ |
|
733 |
+ strm.next_out = buf; |
|
734 |
+ strm.avail_out = sizeof(buf); |
|
735 |
+ } |
|
726 | 736 |
} while (BZ_STREAM_END != rc); |
727 | 737 |
|
728 | 738 |
BZ2_bzDecompressEnd(&strm); |
729 | 739 |
|
730 |
- if((ret = cli_magic_scandesc(fd, ctx)) == CL_VIRUS ) { |
|
731 |
- cli_dbgmsg("Bzip: Infected with %s\n", cli_get_last_virus(ctx)); |
|
732 |
- close(fd); |
|
733 |
- if(!ctx->engine->keeptmp) { |
|
734 |
- if (cli_unlink(tmpname)) { |
|
735 |
- ret = CL_EUNLINK; |
|
736 |
- free(tmpname); |
|
737 |
- return ret; |
|
738 |
- } |
|
739 |
- } |
|
740 |
- free(tmpname); |
|
741 |
- return CL_VIRUS; |
|
740 |
+ if ((ret = cli_magic_scandesc(fd, ctx)) == CL_VIRUS) |
|
741 |
+ { |
|
742 |
+ cli_dbgmsg("Bzip: Infected with %s\n", cli_get_last_virus(ctx)); |
|
743 |
+ close(fd); |
|
744 |
+ if (!ctx->engine->keeptmp) |
|
745 |
+ { |
|
746 |
+ if (cli_unlink(tmpname)) |
|
747 |
+ { |
|
748 |
+ ret = CL_EUNLINK; |
|
749 |
+ free(tmpname); |
|
750 |
+ return ret; |
|
751 |
+ } |
|
752 |
+ } |
|
753 |
+ free(tmpname); |
|
754 |
+ return CL_VIRUS; |
|
742 | 755 |
} |
743 | 756 |
close(fd); |
744 |
- if(!ctx->engine->keeptmp) |
|
745 |
- if (cli_unlink(tmpname)) ret = CL_EUNLINK; |
|
757 |
+ if (!ctx->engine->keeptmp) |
|
758 |
+ if (cli_unlink(tmpname)) |
|
759 |
+ ret = CL_EUNLINK; |
|
746 | 760 |
free(tmpname); |
747 | 761 |
|
748 | 762 |
return ret; |
... | ... |
@@ -760,88 +856,101 @@ static int cli_scanxz(cli_ctx *ctx) |
760 | 760 |
unsigned char *buf; |
761 | 761 |
|
762 | 762 |
buf = cli_malloc(CLI_XZ_OBUF_SIZE); |
763 |
- if (buf == NULL) { |
|
764 |
- cli_errmsg("cli_scanxz: nomemory for decompress buffer.\n"); |
|
763 |
+ if (buf == NULL) |
|
764 |
+ { |
|
765 |
+ cli_errmsg("cli_scanxz: nomemory for decompress buffer.\n"); |
|
765 | 766 |
return CL_EMEM; |
766 | 767 |
} |
767 | 768 |
memset(&strm, 0x00, sizeof(struct CLI_XZ)); |
768 | 769 |
strm.next_out = buf; |
769 | 770 |
strm.avail_out = CLI_XZ_OBUF_SIZE; |
770 | 771 |
rc = cli_XzInit(&strm); |
771 |
- if (rc != XZ_RESULT_OK) { |
|
772 |
- cli_errmsg("cli_scanxz: DecompressInit failed: %i\n", rc); |
|
772 |
+ if (rc != XZ_RESULT_OK) |
|
773 |
+ { |
|
774 |
+ cli_errmsg("cli_scanxz: DecompressInit failed: %i\n", rc); |
|
773 | 775 |
free(buf); |
774 |
- return CL_EOPEN; |
|
776 |
+ return CL_EOPEN; |
|
775 | 777 |
} |
776 | 778 |
|
777 |
- if ((ret = cli_gentempfd(ctx->engine->tmpdir, &tmpname, &fd))) { |
|
778 |
- cli_errmsg("cli_scanxz: Can't generate temporary file.\n"); |
|
779 |
- cli_XzShutdown(&strm); |
|
779 |
+ if ((ret = cli_gentempfd(ctx->engine->tmpdir, &tmpname, &fd))) |
|
780 |
+ { |
|
781 |
+ cli_errmsg("cli_scanxz: Can't generate temporary file.\n"); |
|
782 |
+ cli_XzShutdown(&strm); |
|
780 | 783 |
free(buf); |
781 |
- return ret; |
|
784 |
+ return ret; |
|
782 | 785 |
} |
783 | 786 |
cli_dbgmsg("cli_scanxz: decompressing to file %s\n", tmpname); |
784 | 787 |
|
785 |
- do { |
|
788 |
+ do |
|
789 |
+ { |
|
786 | 790 |
/* set up input buffer */ |
787 |
- if (!strm.avail_in) { |
|
788 |
- strm.next_in = (void*)fmap_need_off_once_len(*ctx->fmap, off, CLI_XZ_IBUF_SIZE, &avail); |
|
789 |
- strm.avail_in = avail; |
|
790 |
- off += avail; |
|
791 |
- if (!strm.avail_in) { |
|
792 |
- cli_errmsg("cli_scanxz: premature end of compressed stream\n"); |
|
791 |
+ if (!strm.avail_in) |
|
792 |
+ { |
|
793 |
+ strm.next_in = (void *)fmap_need_off_once_len(*ctx->fmap, off, CLI_XZ_IBUF_SIZE, &avail); |
|
794 |
+ strm.avail_in = avail; |
|
795 |
+ off += avail; |
|
796 |
+ if (!strm.avail_in) |
|
797 |
+ { |
|
798 |
+ cli_errmsg("cli_scanxz: premature end of compressed stream\n"); |
|
793 | 799 |
ret = CL_EFORMAT; |
794 |
- goto xz_exit; |
|
795 |
- } |
|
796 |
- } |
|
800 |
+ goto xz_exit; |
|
801 |
+ } |
|
802 |
+ } |
|
797 | 803 |
|
798 | 804 |
/* xz decompress a chunk */ |
799 |
- rc = cli_XzDecode(&strm); |
|
800 |
- if (XZ_RESULT_OK != rc && XZ_STREAM_END != rc) { |
|
801 |
- if (rc == XZ_DIC_HEURISTIC) { |
|
805 |
+ rc = cli_XzDecode(&strm); |
|
806 |
+ if (XZ_RESULT_OK != rc && XZ_STREAM_END != rc) |
|
807 |
+ { |
|
808 |
+ if (rc == XZ_DIC_HEURISTIC) |
|
809 |
+ { |
|
802 | 810 |
ret = cli_append_virus(ctx, "Heuristic.XZ.DicSizeLimit"); |
803 | 811 |
goto xz_exit; |
804 | 812 |
} |
805 |
- cli_errmsg("cli_scanxz: decompress error: %d\n", rc); |
|
813 |
+ cli_errmsg("cli_scanxz: decompress error: %d\n", rc); |
|
806 | 814 |
ret = CL_EFORMAT; |
807 | 815 |
goto xz_exit; |
808 |
- } |
|
816 |
+ } |
|
809 | 817 |
//cli_dbgmsg("cli_scanxz: xz decompressed %li of %li available bytes\n", |
810 | 818 |
// avail - strm.avail_in, avail); |
811 |
- |
|
819 |
+ |
|
812 | 820 |
/* write decompress buffer */ |
813 |
- if (!strm.avail_out || rc == XZ_STREAM_END) { |
|
814 |
- size_t towrite = CLI_XZ_OBUF_SIZE - strm.avail_out; |
|
815 |
- size += towrite; |
|
821 |
+ if (!strm.avail_out || rc == XZ_STREAM_END) |
|
822 |
+ { |
|
823 |
+ size_t towrite = CLI_XZ_OBUF_SIZE - strm.avail_out; |
|
824 |
+ size += towrite; |
|
816 | 825 |
|
817 | 826 |
//cli_dbgmsg("Writing %li bytes to XZ decompress temp file(%li byte total)\n", |
818 | 827 |
// towrite, size); |
819 | 828 |
|
820 |
- if((size_t)cli_writen(fd, buf, towrite) != towrite) { |
|
821 |
- cli_errmsg("cli_scanxz: Can't write to file.\n"); |
|
829 |
+ if ((size_t)cli_writen(fd, buf, towrite) != towrite) |
|
830 |
+ { |
|
831 |
+ cli_errmsg("cli_scanxz: Can't write to file.\n"); |
|
822 | 832 |
ret = CL_EWRITE; |
823 | 833 |
goto xz_exit; |
824 |
- } |
|
825 |
- if (cli_checklimits("cli_scanxz", ctx, size, 0, 0) != CL_CLEAN) { |
|
834 |
+ } |
|
835 |
+ if (cli_checklimits("cli_scanxz", ctx, size, 0, 0) != CL_CLEAN) |
|
836 |
+ { |
|
826 | 837 |
cli_warnmsg("cli_scanxz: decompress file size exceeds limits - " |
827 |
- "only scanning %li bytes\n", size); |
|
828 |
- break; |
|
838 |
+ "only scanning %li bytes\n", |
|
839 |
+ size); |
|
840 |
+ break; |
|
829 | 841 |
} |
830 |
- strm.next_out = buf; |
|
831 |
- strm.avail_out = CLI_XZ_OBUF_SIZE; |
|
832 |
- } |
|
842 |
+ strm.next_out = buf; |
|
843 |
+ strm.avail_out = CLI_XZ_OBUF_SIZE; |
|
844 |
+ } |
|
833 | 845 |
} while (XZ_STREAM_END != rc); |
834 | 846 |
|
835 | 847 |
/* scan decompressed file */ |
836 |
- if ((ret = cli_magic_scandesc(fd, ctx)) == CL_VIRUS ) { |
|
837 |
- cli_dbgmsg("cli_scanxz: Infected with %s\n", cli_get_last_virus(ctx)); |
|
848 |
+ if ((ret = cli_magic_scandesc(fd, ctx)) == CL_VIRUS) |
|
849 |
+ { |
|
850 |
+ cli_dbgmsg("cli_scanxz: Infected with %s\n", cli_get_last_virus(ctx)); |
|
838 | 851 |
} |
839 | 852 |
|
840 |
- xz_exit: |
|
853 |
+xz_exit: |
|
841 | 854 |
cli_XzShutdown(&strm); |
842 | 855 |
close(fd); |
843 |
- if(!ctx->engine->keeptmp) |
|
844 |
- if (cli_unlink(tmpname) && ret == CL_CLEAN) |
|
856 |
+ if (!ctx->engine->keeptmp) |
|
857 |
+ if (cli_unlink(tmpname) && ret == CL_CLEAN) |
|
845 | 858 |
ret = CL_EUNLINK; |
846 | 859 |
free(tmpname); |
847 | 860 |
free(buf); |
... | ... |
@@ -850,248 +959,284 @@ static int cli_scanxz(cli_ctx *ctx) |
850 | 850 |
|
851 | 851 |
static int cli_scanszdd(cli_ctx *ctx) |
852 | 852 |
{ |
853 |
- int ofd, ret; |
|
854 |
- char *tmpname; |
|
855 |
- |
|
853 |
+ int ofd, ret; |
|
854 |
+ char *tmpname; |
|
856 | 855 |
|
857 | 856 |
cli_dbgmsg("in cli_scanszdd()\n"); |
858 | 857 |
|
859 |
- if((ret = cli_gentempfd(ctx->engine->tmpdir, &tmpname, &ofd))) { |
|
860 |
- cli_dbgmsg("MSEXPAND: Can't generate temporary file/descriptor\n"); |
|
861 |
- return ret; |
|
858 |
+ if ((ret = cli_gentempfd(ctx->engine->tmpdir, &tmpname, &ofd))) |
|
859 |
+ { |
|
860 |
+ cli_dbgmsg("MSEXPAND: Can't generate temporary file/descriptor\n"); |
|
861 |
+ return ret; |
|
862 | 862 |
} |
863 | 863 |
|
864 | 864 |
ret = cli_msexpand(ctx, ofd); |
865 | 865 |
|
866 |
- if(ret != CL_SUCCESS) { /* CL_VIRUS or some error */ |
|
867 |
- close(ofd); |
|
868 |
- if(!ctx->engine->keeptmp) |
|
869 |
- if (cli_unlink(tmpname)) ret = CL_EUNLINK; |
|
870 |
- free(tmpname); |
|
871 |
- return ret; |
|
866 |
+ if (ret != CL_SUCCESS) |
|
867 |
+ { /* CL_VIRUS or some error */ |
|
868 |
+ close(ofd); |
|
869 |
+ if (!ctx->engine->keeptmp) |
|
870 |
+ if (cli_unlink(tmpname)) |
|
871 |
+ ret = CL_EUNLINK; |
|
872 |
+ free(tmpname); |
|
873 |
+ return ret; |
|
872 | 874 |
} |
873 | 875 |
|
874 | 876 |
cli_dbgmsg("MSEXPAND: Decompressed into %s\n", tmpname); |
875 | 877 |
ret = cli_magic_scandesc(ofd, ctx); |
876 | 878 |
close(ofd); |
877 |
- if(!ctx->engine->keeptmp) |
|
878 |
- if (cli_unlink(tmpname)) ret = CL_EUNLINK; |
|
879 |
- free(tmpname); |
|
879 |
+ if (!ctx->engine->keeptmp) |
|
880 |
+ if (cli_unlink(tmpname)) |
|
881 |
+ ret = CL_EUNLINK; |
|
882 |
+ free(tmpname); |
|
880 | 883 |
|
881 | 884 |
return ret; |
882 | 885 |
} |
883 | 886 |
|
884 | 887 |
static int vba_scandata(const unsigned char *data, unsigned int len, cli_ctx *ctx) |
885 | 888 |
{ |
886 |
- struct cli_matcher *groot = ctx->engine->root[0]; |
|
887 |
- struct cli_matcher *troot = ctx->engine->root[2]; |
|
888 |
- struct cli_ac_data gmdata, tmdata; |
|
889 |
- struct cli_ac_data *mdata[2]; |
|
890 |
- int ret; |
|
891 |
- unsigned int viruses_found = 0; |
|
889 |
+ struct cli_matcher *groot = ctx->engine->root[0]; |
|
890 |
+ struct cli_matcher *troot = ctx->engine->root[2]; |
|
891 |
+ struct cli_ac_data gmdata, tmdata; |
|
892 |
+ struct cli_ac_data *mdata[2]; |
|
893 |
+ int ret; |
|
894 |
+ unsigned int viruses_found = 0; |
|
892 | 895 |
|
893 |
- if((ret = cli_ac_initdata(&tmdata, troot->ac_partsigs, troot->ac_lsigs, troot->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN))) |
|
894 |
- return ret; |
|
896 |
+ if ((ret = cli_ac_initdata(&tmdata, troot->ac_partsigs, troot->ac_lsigs, troot->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN))) |
|
897 |
+ return ret; |
|
895 | 898 |
|
896 |
- if((ret = cli_ac_initdata(&gmdata, groot->ac_partsigs, groot->ac_lsigs, groot->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN))) { |
|
897 |
- cli_ac_freedata(&tmdata); |
|
898 |
- return ret; |
|
899 |
+ if ((ret = cli_ac_initdata(&gmdata, groot->ac_partsigs, groot->ac_lsigs, groot->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN))) |
|
900 |
+ { |
|
901 |
+ cli_ac_freedata(&tmdata); |
|
902 |
+ return ret; |
|
899 | 903 |
} |
900 | 904 |
mdata[0] = &tmdata; |
901 | 905 |
mdata[1] = &gmdata; |
902 | 906 |
|
903 | 907 |
ret = cli_scanbuff(data, len, 0, ctx, CL_TYPE_MSOLE2, mdata); |
904 | 908 |
if (ret == CL_VIRUS) |
905 |
- viruses_found++; |
|
909 |
+ viruses_found++; |
|
906 | 910 |
|
907 |
- if (ret == CL_CLEAN || (ret == CL_VIRUS && SCAN_ALL)) { |
|
908 |
- fmap_t *map = *ctx->fmap; |
|
911 |
+ if (ret == CL_CLEAN || (ret == CL_VIRUS && SCAN_ALL)) |
|
912 |
+ { |
|
913 |
+ fmap_t *map = *ctx->fmap; |
|
909 | 914 |
*ctx->fmap = cl_fmap_open_memory(data, len); |
910 | 915 |
if (*ctx->fmap == NULL) |
911 | 916 |
return CL_EMEM; |
912 |
- ret = cli_exp_eval(ctx, troot, &tmdata, NULL, NULL); |
|
913 |
- if (ret == CL_VIRUS) |
|
914 |
- viruses_found++; |
|
917 |
+ ret = cli_exp_eval(ctx, troot, &tmdata, NULL, NULL); |
|
918 |
+ if (ret == CL_VIRUS) |
|
919 |
+ viruses_found++; |
|
915 | 920 |
|
916 |
- if (ret == CL_CLEAN || (ret == CL_VIRUS && SCAN_ALL)) |
|
917 |
- ret = cli_exp_eval(ctx, groot, &gmdata, NULL, NULL); |
|
921 |
+ if (ret == CL_CLEAN || (ret == CL_VIRUS && SCAN_ALL)) |
|
922 |
+ ret = cli_exp_eval(ctx, groot, &gmdata, NULL, NULL); |
|
918 | 923 |
funmap(*ctx->fmap); |
919 | 924 |
*ctx->fmap = map; |
920 | 925 |
} |
921 | 926 |
cli_ac_freedata(&tmdata); |
922 | 927 |
cli_ac_freedata(&gmdata); |
923 | 928 |
|
924 |
- return (ret != CL_CLEAN)?ret:viruses_found?CL_VIRUS:CL_CLEAN; |
|
929 |
+ return (ret != CL_CLEAN) ? ret : viruses_found ? CL_VIRUS : CL_CLEAN; |
|
925 | 930 |
} |
926 | 931 |
|
927 | 932 |
static int cli_vba_scandir(const char *dirname, cli_ctx *ctx, struct uniq *U) |
928 | 933 |
{ |
929 |
- int ret = CL_CLEAN, i, j, fd, data_len, hasmacros = 0; |
|
930 |
- vba_project_t *vba_project; |
|
931 |
- DIR *dd; |
|
932 |
- struct dirent *dent; |
|
934 |
+ int ret = CL_CLEAN, i, j, fd, data_len, hasmacros = 0; |
|
935 |
+ vba_project_t *vba_project; |
|
936 |
+ DIR *dd; |
|
937 |
+ struct dirent *dent; |
|
933 | 938 |
#if defined(HAVE_READDIR_R_3) || defined(HAVE_READDIR_R_2) |
934 |
- union { |
|
935 |
- struct dirent d; |
|
936 |
- char b[offsetof(struct dirent, d_name) + NAME_MAX + 1]; |
|
937 |
- } result; |
|
939 |
+ union { |
|
940 |
+ struct dirent d; |
|
941 |
+ char b[offsetof(struct dirent, d_name) + NAME_MAX + 1]; |
|
942 |
+ } result; |
|
938 | 943 |
#endif |
939 |
- STATBUF statbuf; |
|
940 |
- char *fullname, vbaname[1024]; |
|
941 |
- unsigned char *data; |
|
942 |
- char *hash; |
|
943 |
- uint32_t hashcnt; |
|
944 |
- unsigned int viruses_found = 0; |
|
945 |
- |
|
944 |
+ STATBUF statbuf; |
|
945 |
+ char *fullname, vbaname[1024]; |
|
946 |
+ unsigned char *data; |
|
947 |
+ char *hash; |
|
948 |
+ uint32_t hashcnt; |
|
949 |
+ unsigned int viruses_found = 0; |
|
946 | 950 |
|
947 | 951 |
cli_dbgmsg("VBADir: %s\n", dirname); |
948 | 952 |
hashcnt = uniq_get(U, "_vba_project", 12, NULL); |
949 |
- while(hashcnt--) { |
|
950 |
- if(!(vba_project = (vba_project_t *)cli_vba_readdir(dirname, U, hashcnt))) continue; |
|
951 |
- |
|
952 |
- for(i = 0; i < vba_project->count; i++) { |
|
953 |
- for(j = 0; (unsigned int)j < vba_project->colls[i]; j++) { |
|
954 |
- snprintf(vbaname, 1024, "%s"PATHSEP"%s_%u", vba_project->dir, vba_project->name[i], j); |
|
955 |
- vbaname[sizeof(vbaname)-1] = '\0'; |
|
956 |
- fd = open(vbaname, O_RDONLY|O_BINARY); |
|
957 |
- if(fd == -1) continue; |
|
958 |
- cli_dbgmsg("VBADir: Decompress VBA project '%s_%u'\n", vba_project->name[i], j); |
|
959 |
- data = (unsigned char *)cli_vba_inflate(fd, vba_project->offset[i], &data_len); |
|
960 |
- close(fd); |
|
961 |
- hasmacros++; |
|
962 |
- if(!data) { |
|
963 |
- cli_dbgmsg("VBADir: WARNING: VBA project '%s_%u' decompressed to NULL\n", vba_project->name[i], j); |
|
964 |
- } else { |
|
965 |
- /* cli_dbgmsg("Project content:\n%s", data); */ |
|
966 |
- if(ctx->scanned) |
|
967 |
- *ctx->scanned += data_len / CL_COUNT_PRECISION; |
|
968 |
- if (ctx->engine->keeptmp) { |
|
969 |
- char *tempfile; |
|
970 |
- int of; |
|
971 |
- |
|
972 |
- if ((ret = cli_gentempfd(ctx->engine->tmpdir, &tempfile, &of)) != CL_SUCCESS) { |
|
973 |
- cli_warnmsg("VBADir: WARNING: VBA project '%s_%u' cannot be dumped to file\n", vba_project->name[i], j); |
|
974 |
- return ret; |
|
975 |
- } |
|
976 |
- if (cli_writen(of, data, data_len) != data_len) { |
|
977 |
- cli_warnmsg("VBADir: WARNING: VBA project '%s_%u' failed to write to file\n", vba_project->name[i], j); |
|
978 |
- close(of); |
|
979 |
- free(tempfile); |
|
980 |
- return CL_EWRITE; |
|
981 |
- } |
|
982 |
- |
|
983 |
- cli_dbgmsg("VBADir: VBA project '%s_%u' dumped to %s\n", vba_project->name[i], j, tempfile); |
|
984 |
- free(tempfile); |
|
985 |
- } |
|
986 |
- |
|
987 |
- if(vba_scandata(data, data_len, ctx) == CL_VIRUS) { |
|
988 |
- if (SCAN_ALL) |
|
989 |
- viruses_found++; |
|
990 |
- else { |
|
991 |
- free(data); |
|
992 |
- ret = CL_VIRUS; |
|
993 |
- break; |
|
994 |
- } |
|
995 |
- } |
|
996 |
- free(data); |
|
997 |
- } |
|
998 |
- } |
|
999 |
- } |
|
1000 |
- |
|
1001 |
- free(vba_project->name); |
|
1002 |
- free(vba_project->colls); |
|
1003 |
- free(vba_project->dir); |
|
1004 |
- free(vba_project->offset); |
|
1005 |
- free(vba_project); |
|
1006 |
- if (ret == CL_VIRUS && !SCAN_ALL) |
|
1007 |
- break; |
|
1008 |
- } |
|
1009 |
- |
|
1010 |
- if((ret == CL_CLEAN || (ret == CL_VIRUS && SCAN_ALL)) && |
|
1011 |
- (hashcnt = uniq_get(U, "powerpoint document", 19, &hash))) { |
|
1012 |
- while(hashcnt--) { |
|
1013 |
- snprintf(vbaname, 1024, "%s"PATHSEP"%s_%u", dirname, hash, hashcnt); |
|
1014 |
- vbaname[sizeof(vbaname)-1] = '\0'; |
|
1015 |
- fd = open(vbaname, O_RDONLY|O_BINARY); |
|
1016 |
- if (fd == -1) continue; |
|
1017 |
- if ((fullname = cli_ppt_vba_read(fd, ctx))) { |
|
1018 |
- if(cli_scandir(fullname, ctx) == CL_VIRUS) { |
|
1019 |
- ret = CL_VIRUS; |
|
1020 |
- viruses_found++; |
|
1021 |
- } |
|
1022 |
- if(!ctx->engine->keeptmp) |
|
1023 |
- cli_rmdirs(fullname); |
|
1024 |
- free(fullname); |
|
1025 |
- } |
|
1026 |
- close(fd); |
|
1027 |
- } |
|
1028 |
- } |
|
1029 |
- |
|
1030 |
- if ((ret == CL_CLEAN || (ret == CL_VIRUS && SCAN_ALL)) && |
|
1031 |
- (hashcnt = uniq_get(U, "worddocument", 12, &hash))) { |
|
1032 |
- while(hashcnt--) { |
|
1033 |
- snprintf(vbaname, sizeof(vbaname), "%s"PATHSEP"%s_%u", dirname, hash, hashcnt); |
|
1034 |
- vbaname[sizeof(vbaname)-1] = '\0'; |
|
1035 |
- fd = open(vbaname, O_RDONLY|O_BINARY); |
|
1036 |
- if (fd == -1) continue; |
|
1037 |
- |
|
1038 |
- if (!(vba_project = (vba_project_t *)cli_wm_readdir(fd))) { |
|
1039 |
- close(fd); |
|
1040 |
- continue; |
|
1041 |
- } |
|
1042 |
- |
|
1043 |
- for (i = 0; i < vba_project->count; i++) { |
|
1044 |
- cli_dbgmsg("VBADir: Decompress WM project macro:%d key:%d length:%d\n", i, vba_project->key[i], vba_project->length[i]); |
|
1045 |
- data = (unsigned char *)cli_wm_decrypt_macro(fd, vba_project->offset[i], vba_project->length[i], vba_project->key[i]); |
|
1046 |
- if(!data) { |
|
1047 |
- cli_dbgmsg("VBADir: WARNING: WM project '%s' macro %d decrypted to NULL\n", vba_project->name[i], i); |
|
1048 |
- } else { |
|
1049 |
- cli_dbgmsg("Project content:\n%s", data); |
|
1050 |
- if(ctx->scanned) |
|
1051 |
- *ctx->scanned += vba_project->length[i] / CL_COUNT_PRECISION; |
|
1052 |
- if(vba_scandata(data, vba_project->length[i], ctx) == CL_VIRUS) { |
|
1053 |
- if (SCAN_ALL) |
|
1054 |
- viruses_found++; |
|
1055 |
- else { |
|
1056 |
- free(data); |
|
1057 |
- ret = CL_VIRUS; |
|
1058 |
- break; |
|
1059 |
- } |
|
1060 |
- } |
|
1061 |
- free(data); |
|
1062 |
- } |
|
1063 |
- } |
|
1064 |
- |
|
1065 |
- close(fd); |
|
1066 |
- free(vba_project->name); |
|
1067 |
- free(vba_project->colls); |
|
1068 |
- free(vba_project->dir); |
|
1069 |
- free(vba_project->offset); |
|
1070 |
- free(vba_project->key); |
|
1071 |
- free(vba_project->length); |
|
1072 |
- free(vba_project); |
|
1073 |
- if(ret == CL_VIRUS) { |
|
1074 |
- if (SCAN_ALL) |
|
1075 |
- viruses_found++; |
|
1076 |
- else |
|
1077 |
- break; |
|
1078 |
- } |
|
1079 |
- } |
|
1080 |
- } |
|
1081 |
- |
|
1082 |
- if(ret != CL_CLEAN && !(ret == CL_VIRUS && SCAN_ALL)) |
|
1083 |
- return ret; |
|
953 |
+ while (hashcnt--) |
|
954 |
+ { |
|
955 |
+ if (!(vba_project = (vba_project_t *)cli_vba_readdir(dirname, U, hashcnt))) |
|
956 |
+ continue; |
|
957 |
+ |
|
958 |
+ for (i = 0; i < vba_project->count; i++) |
|
959 |
+ { |
|
960 |
+ for (j = 0; (unsigned int)j < vba_project->colls[i]; j++) |
|
961 |
+ { |
|
962 |
+ snprintf(vbaname, 1024, "%s" PATHSEP "%s_%u", vba_project->dir, vba_project->name[i], j); |
|
963 |
+ vbaname[sizeof(vbaname) - 1] = '\0'; |
|
964 |
+ fd = open(vbaname, O_RDONLY | O_BINARY); |
|
965 |
+ if (fd == -1) |
|
966 |
+ continue; |
|
967 |
+ cli_dbgmsg("VBADir: Decompress VBA project '%s_%u'\n", vba_project->name[i], j); |
|
968 |
+ data = (unsigned char *)cli_vba_inflate(fd, vba_project->offset[i], &data_len); |
|
969 |
+ close(fd); |
|
970 |
+ hasmacros++; |
|
971 |
+ if (!data) |
|
972 |
+ { |
|
973 |
+ cli_dbgmsg("VBADir: WARNING: VBA project '%s_%u' decompressed to NULL\n", vba_project->name[i], j); |
|
974 |
+ } |
|
975 |
+ else |
|
976 |
+ { |
|
977 |
+ /* cli_dbgmsg("Project content:\n%s", data); */ |
|
978 |
+ if (ctx->scanned) |
|
979 |
+ *ctx->scanned += data_len / CL_COUNT_PRECISION; |
|
980 |
+ if (ctx->engine->keeptmp) |
|
981 |
+ { |
|
982 |
+ char *tempfile; |
|
983 |
+ int of; |
|
984 |
+ |
|
985 |
+ if ((ret = cli_gentempfd(ctx->engine->tmpdir, &tempfile, &of)) != CL_SUCCESS) |
|
986 |
+ { |
|
987 |
+ cli_warnmsg("VBADir: WARNING: VBA project '%s_%u' cannot be dumped to file\n", vba_project->name[i], j); |
|
988 |
+ return ret; |
|
989 |
+ } |
|
990 |
+ if (cli_writen(of, data, data_len) != data_len) |
|
991 |
+ { |
|
992 |
+ cli_warnmsg("VBADir: WARNING: VBA project '%s_%u' failed to write to file\n", vba_project->name[i], j); |
|
993 |
+ close(of); |
|
994 |
+ free(tempfile); |
|
995 |
+ return CL_EWRITE; |
|
996 |
+ } |
|
997 |
+ |
|
998 |
+ cli_dbgmsg("VBADir: VBA project '%s_%u' dumped to %s\n", vba_project->name[i], j, tempfile); |
|
999 |
+ free(tempfile); |
|
1000 |
+ } |
|
1001 |
+ |
|
1002 |
+ if (vba_scandata(data, data_len, ctx) == CL_VIRUS) |
|
1003 |
+ { |
|
1004 |
+ if (SCAN_ALL) |
|
1005 |
+ viruses_found++; |
|
1006 |
+ else |
|
1007 |
+ { |
|
1008 |
+ free(data); |
|
1009 |
+ ret = CL_VIRUS; |
|
1010 |
+ break; |
|
1011 |
+ } |
|
1012 |
+ } |
|
1013 |
+ free(data); |
|
1014 |
+ } |
|
1015 |
+ } |
|
1016 |
+ } |
|
1017 |
+ |
|
1018 |
+ free(vba_project->name); |
|
1019 |
+ free(vba_project->colls); |
|
1020 |
+ free(vba_project->dir); |
|
1021 |
+ free(vba_project->offset); |
|
1022 |
+ free(vba_project); |
|
1023 |
+ if (ret == CL_VIRUS && !SCAN_ALL) |
|
1024 |
+ break; |
|
1025 |
+ } |
|
1026 |
+ |
|
1027 |
+ if ((ret == CL_CLEAN || (ret == CL_VIRUS && SCAN_ALL)) && |
|
1028 |
+ (hashcnt = uniq_get(U, "powerpoint document", 19, &hash))) |
|
1029 |
+ { |
|
1030 |
+ while (hashcnt--) |
|
1031 |
+ { |
|
1032 |
+ snprintf(vbaname, 1024, "%s" PATHSEP "%s_%u", dirname, hash, hashcnt); |
|
1033 |
+ vbaname[sizeof(vbaname) - 1] = '\0'; |
|
1034 |
+ fd = open(vbaname, O_RDONLY | O_BINARY); |
|
1035 |
+ if (fd == -1) |
|
1036 |
+ continue; |
|
1037 |
+ if ((fullname = cli_ppt_vba_read(fd, ctx))) |
|
1038 |
+ { |
|
1039 |
+ if (cli_scandir(fullname, ctx) == CL_VIRUS) |
|
1040 |
+ { |
|
1041 |
+ ret = CL_VIRUS; |
|
1042 |
+ viruses_found++; |
|
1043 |
+ } |
|
1044 |
+ if (!ctx->engine->keeptmp) |
|
1045 |
+ cli_rmdirs(fullname); |
|
1046 |
+ free(fullname); |
|
1047 |
+ } |
|
1048 |
+ close(fd); |
|
1049 |
+ } |
|
1050 |
+ } |
|
1051 |
+ |
|
1052 |
+ if ((ret == CL_CLEAN || (ret == CL_VIRUS && SCAN_ALL)) && |
|
1053 |
+ (hashcnt = uniq_get(U, "worddocument", 12, &hash))) |
|
1054 |
+ { |
|
1055 |
+ while (hashcnt--) |
|
1056 |
+ { |
|
1057 |
+ snprintf(vbaname, sizeof(vbaname), "%s" PATHSEP "%s_%u", dirname, hash, hashcnt); |
|
1058 |
+ vbaname[sizeof(vbaname) - 1] = '\0'; |
|
1059 |
+ fd = open(vbaname, O_RDONLY | O_BINARY); |
|
1060 |
+ if (fd == -1) |
|
1061 |
+ continue; |
|
1062 |
+ |
|
1063 |
+ if (!(vba_project = (vba_project_t *)cli_wm_readdir(fd))) |
|
1064 |
+ { |
|
1065 |
+ close(fd); |
|
1066 |
+ continue; |
|
1067 |
+ } |
|
1068 |
+ |
|
1069 |
+ for (i = 0; i < vba_project->count; i++) |
|
1070 |
+ { |
|
1071 |
+ cli_dbgmsg("VBADir: Decompress WM project macro:%d key:%d length:%d\n", i, vba_project->key[i], vba_project->length[i]); |
|
1072 |
+ data = (unsigned char *)cli_wm_decrypt_macro(fd, vba_project->offset[i], vba_project->length[i], vba_project->key[i]); |
|
1073 |
+ if (!data) |
|
1074 |
+ { |
|
1075 |
+ cli_dbgmsg("VBADir: WARNING: WM project '%s' macro %d decrypted to NULL\n", vba_project->name[i], i); |
|
1076 |
+ } |
|
1077 |
+ else |
|
1078 |
+ { |
|
1079 |
+ cli_dbgmsg("Project content:\n%s", data); |
|
1080 |
+ if (ctx->scanned) |
|
1081 |
+ *ctx->scanned += vba_project->length[i] / CL_COUNT_PRECISION; |
|
1082 |
+ if (vba_scandata(data, vba_project->length[i], ctx) == CL_VIRUS) |
|
1083 |
+ { |
|
1084 |
+ if (SCAN_ALL) |
|
1085 |
+ viruses_found++; |
|
1086 |
+ else |
|
1087 |
+ { |
|
1088 |
+ free(data); |
|
1089 |
+ ret = CL_VIRUS; |
|
1090 |
+ break; |
|
1091 |
+ } |
|
1092 |
+ } |
|
1093 |
+ free(data); |
|
1094 |
+ } |
|
1095 |
+ } |
|
1096 |
+ |
|
1097 |
+ close(fd); |
|
1098 |
+ free(vba_project->name); |
|
1099 |
+ free(vba_project->colls); |
|
1100 |
+ free(vba_project->dir); |
|
1101 |
+ free(vba_project->offset); |
|
1102 |
+ free(vba_project->key); |
|
1103 |
+ free(vba_project->length); |
|
1104 |
+ free(vba_project); |
|
1105 |
+ if (ret == CL_VIRUS) |
|
1106 |
+ { |
|
1107 |
+ if (SCAN_ALL) |
|
1108 |
+ viruses_found++; |
|
1109 |
+ else |
|
1110 |
+ break; |
|
1111 |
+ } |
|
1112 |
+ } |
|
1113 |
+ } |
|
1114 |
+ |
|
1115 |
+ if (ret != CL_CLEAN && !(ret == CL_VIRUS && SCAN_ALL)) |
|
1116 |
+ return ret; |
|
1084 | 1117 |
|
1085 | 1118 |
#if HAVE_JSON |
1086 | 1119 |
/* JSON Output Summary Information */ |
1087 |
- if (ctx->options & CL_SCAN_FILE_PROPERTIES && ctx->wrkproperty != NULL) { |
|
1120 |
+ if (ctx->options & CL_SCAN_FILE_PROPERTIES && ctx->wrkproperty != NULL) |
|
1121 |
+ { |
|
1088 | 1122 |
hashcnt = uniq_get(U, "_5_summaryinformation", 21, &hash); |
1089 |
- while(hashcnt--) { |
|
1090 |
- snprintf(vbaname, sizeof(vbaname), "%s"PATHSEP"%s_%u", dirname, hash, hashcnt); |
|
1091 |
- vbaname[sizeof(vbaname)-1] = '\0'; |
|
1092 |
- |
|
1093 |
- fd = open(vbaname, O_RDONLY|O_BINARY); |
|
1094 |
- if (fd >= 0) { |
|
1123 |
+ while (hashcnt--) |
|
1124 |
+ { |
|
1125 |
+ snprintf(vbaname, sizeof(vbaname), "%s" PATHSEP "%s_%u", dirname, hash, hashcnt); |
|
1126 |
+ vbaname[sizeof(vbaname) - 1] = '\0'; |
|
1127 |
+ |
|
1128 |
+ fd = open(vbaname, O_RDONLY | O_BINARY); |
|
1129 |
+ if (fd >= 0) |
|
1130 |
+ { |
|
1095 | 1131 |
cli_dbgmsg("VBADir: detected a '_5_summaryinformation' stream\n"); |
1096 | 1132 |
/* JSONOLE2 - what to do if something breaks? */ |
1097 | 1133 |
cli_ole2_summary_json(ctx, fd, 0); |
... | ... |
@@ -1100,12 +1245,14 @@ static int cli_vba_scandir(const char *dirname, cli_ctx *ctx, struct uniq *U) |
1100 | 1100 |
} |
1101 | 1101 |
|
1102 | 1102 |
hashcnt = uniq_get(U, "_5_documentsummaryinformation", 29, &hash); |
1103 |
- while(hashcnt--) { |
|
1104 |
- snprintf(vbaname, sizeof(vbaname), "%s"PATHSEP"%s_%u", dirname, hash, hashcnt); |
|
1105 |
- vbaname[sizeof(vbaname)-1] = '\0'; |
|
1106 |
- |
|
1107 |
- fd = open(vbaname, O_RDONLY|O_BINARY); |
|
1108 |
- if (fd >= 0) { |
|
1103 |
+ while (hashcnt--) |
|
1104 |
+ { |
|
1105 |
+ snprintf(vbaname, sizeof(vbaname), "%s" PATHSEP "%s_%u", dirname, hash, hashcnt); |
|
1106 |
+ vbaname[sizeof(vbaname) - 1] = '\0'; |
|
1107 |
+ |
|
1108 |
+ fd = open(vbaname, O_RDONLY | O_BINARY); |
|
1109 |
+ if (fd >= 0) |
|
1110 |
+ { |
|
1109 | 1111 |
cli_dbgmsg("VBADir: detected a '_5_documentsummaryinformation' stream\n"); |
1110 | 1112 |
/* JSONOLE2 - what to do if something breaks? */ |
1111 | 1113 |
cli_ole2_summary_json(ctx, fd, 1); |
... | ... |
@@ -1113,68 +1260,80 @@ static int cli_vba_scandir(const char *dirname, cli_ctx *ctx, struct uniq *U) |
1113 | 1113 |
} |
1114 | 1114 |
} |
1115 | 1115 |
} |
1116 |
-#endif |
|
1116 |
+#endif |
|
1117 | 1117 |
|
1118 | 1118 |
/* Check directory for embedded OLE objects */ |
1119 | 1119 |
hashcnt = uniq_get(U, "_1_ole10native", 14, &hash); |
1120 |
- while(hashcnt--) { |
|
1121 |
- snprintf(vbaname, sizeof(vbaname), "%s"PATHSEP"%s_%u", dirname, hash, hashcnt); |
|
1122 |
- vbaname[sizeof(vbaname)-1] = '\0'; |
|
1123 |
- |
|
1124 |
- fd = open(vbaname, O_RDONLY|O_BINARY); |
|
1125 |
- if (fd >= 0) { |
|
1126 |
- ret = cli_scan_ole10(fd, ctx); |
|
1127 |
- close(fd); |
|
1128 |
- if(ret != CL_CLEAN && !(ret == CL_VIRUS && SCAN_ALL)) |
|
1129 |
- return ret; |
|
1130 |
- } |
|
1120 |
+ while (hashcnt--) |
|
1121 |
+ { |
|
1122 |
+ snprintf(vbaname, sizeof(vbaname), "%s" PATHSEP "%s_%u", dirname, hash, hashcnt); |
|
1123 |
+ vbaname[sizeof(vbaname) - 1] = '\0'; |
|
1124 |
+ |
|
1125 |
+ fd = open(vbaname, O_RDONLY | O_BINARY); |
|
1126 |
+ if (fd >= 0) |
|
1127 |
+ { |
|
1128 |
+ ret = cli_scan_ole10(fd, ctx); |
|
1129 |
+ close(fd); |
|
1130 |
+ if (ret != CL_CLEAN && !(ret == CL_VIRUS && SCAN_ALL)) |
|
1131 |
+ return ret; |
|
1132 |
+ } |
|
1131 | 1133 |
} |
1132 | 1134 |
|
1133 |
- |
|
1134 | 1135 |
/* ACAB: since we now hash filenames and handle collisions we |
1135 | 1136 |
* could avoid recursion by removing the block below and by |
1136 | 1137 |
* flattening the paths in ole2_walk_property_tree (case 1) */ |
1137 | 1138 |
|
1138 |
- if((dd = opendir(dirname)) != NULL) { |
|
1139 |
+ if ((dd = opendir(dirname)) != NULL) |
|
1140 |
+ { |
|
1139 | 1141 |
#ifdef HAVE_READDIR_R_3 |
1140 |
- while(!readdir_r(dd, &result.d, &dent) && dent) { |
|
1142 |
+ while (!readdir_r(dd, &result.d, &dent) && dent) |
|
1143 |
+ { |
|
1141 | 1144 |
#elif defined(HAVE_READDIR_R_2) |
1142 |
- while((dent = (struct dirent *) readdir_r(dd, &result.d))) { |
|
1145 |
+ while ((dent = (struct dirent *)readdir_r(dd, &result.d))) |
|
1146 |
+ { |
|
1143 | 1147 |
#else |
1144 |
- while((dent = readdir(dd))) { |
|
1148 |
+ while ((dent = readdir(dd))) |
|
1149 |
+ { |
|
1145 | 1150 |
#endif |
1146 |
- if(dent->d_ino) |
|
1147 |
- { |
|
1148 |
- if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..")) { |
|
1149 |
- /* build the full name */ |
|
1150 |
- fullname = cli_malloc(strlen(dirname) + strlen(dent->d_name) + 2); |
|
1151 |
- if(!fullname) { |
|
1152 |
- cli_dbgmsg("cli_vba_scandir: Unable to allocate memory for fullname\n"); |
|
1153 |
- ret = CL_EMEM; |
|
1154 |
- break; |
|
1155 |
- } |
|
1156 |
- sprintf(fullname, "%s"PATHSEP"%s", dirname, dent->d_name); |
|
1157 |
- |
|
1158 |
- /* stat the file */ |
|
1159 |
- if(LSTAT(fullname, &statbuf) != -1) { |
|
1160 |
- if(S_ISDIR(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode)) |
|
1161 |
- if (cli_vba_scandir(fullname, ctx, U) == CL_VIRUS) { |
|
1162 |
- if (SCAN_ALL) |
|
1163 |
- viruses_found++; |
|
1164 |
- else { |
|
1165 |
- ret = CL_VIRUS; |
|
1166 |
- free(fullname); |
|
1167 |
- break; |
|
1168 |
- } |
|
1169 |
- } |
|
1170 |
- } |
|
1171 |
- free(fullname); |
|
1172 |
- } |
|
1173 |
- } |
|
1174 |
- } |
|
1175 |
- } else { |
|
1176 |
- cli_dbgmsg("VBADir: Can't open directory %s.\n", dirname); |
|
1177 |
- return CL_EOPEN; |
|
1151 |
+ if (dent->d_ino) |
|
1152 |
+ { |
|
1153 |
+ if (strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..")) |
|
1154 |
+ { |
|
1155 |
+ /* build the full name */ |
|
1156 |
+ fullname = cli_malloc(strlen(dirname) + strlen(dent->d_name) + 2); |
|
1157 |
+ if (!fullname) |
|
1158 |
+ { |
|
1159 |
+ cli_dbgmsg("cli_vba_scandir: Unable to allocate memory for fullname\n"); |
|
1160 |
+ ret = CL_EMEM; |
|
1161 |
+ break; |
|
1162 |
+ } |
|
1163 |
+ sprintf(fullname, "%s" PATHSEP "%s", dirname, dent->d_name); |
|
1164 |
+ |
|
1165 |
+ /* stat the file */ |
|
1166 |
+ if (LSTAT(fullname, &statbuf) != -1) |
|
1167 |
+ { |
|
1168 |
+ if (S_ISDIR(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode)) |
|
1169 |
+ if (cli_vba_scandir(fullname, ctx, U) == CL_VIRUS) |
|
1170 |
+ { |
|
1171 |
+ if (SCAN_ALL) |
|
1172 |
+ viruses_found++; |
|
1173 |
+ else |
|
1174 |
+ { |
|
1175 |
+ ret = CL_VIRUS; |
|
1176 |
+ free(fullname); |
|
1177 |
+ break; |
|
1178 |
+ } |
|
1179 |
+ } |
|
1180 |
+ } |
|
1181 |
+ free(fullname); |
|
1182 |
+ } |
|
1183 |
+ } |
|
1184 |
+ } |
|
1185 |
+ } |
|
1186 |
+ else |
|
1187 |
+ { |
|
1188 |
+ cli_dbgmsg("VBADir: Can't open directory %s.\n", dirname); |
|
1189 |
+ return CL_EOPEN; |
|
1178 | 1190 |
} |
1179 | 1191 |
|
1180 | 1192 |
closedir(dd); |
... | ... |
@@ -1182,20 +1341,21 @@ static int cli_vba_scandir(const char *dirname, cli_ctx *ctx, struct uniq *U) |
1182 | 1182 |
if (hasmacros && ctx->options & CL_SCAN_FILE_PROPERTIES && ctx->wrkproperty != NULL) |
1183 | 1183 |
cli_jsonbool(ctx->wrkproperty, "HasMacros", 1); |
1184 | 1184 |
#endif |
1185 |
- if(BLOCK_MACROS && hasmacros) { |
|
1186 |
- ret = cli_append_virus(ctx, "Heuristics.OLE2.ContainsMacros"); |
|
1187 |
- if (ret == CL_VIRUS) |
|
1185 |
+ if (BLOCK_MACROS && hasmacros) |
|
1186 |
+ { |
|
1187 |
+ ret = cli_append_virus(ctx, "Heuristics.OLE2.ContainsMacros"); |
|
1188 |
+ if (ret == CL_VIRUS) |
|
1188 | 1189 |
viruses_found++; |
1189 | 1190 |
} |
1190 | 1191 |
if (SCAN_ALL && viruses_found) |
1191 |
- return CL_VIRUS; |
|
1192 |
+ return CL_VIRUS; |
|
1192 | 1193 |
return ret; |
1193 | 1194 |
} |
1194 | 1195 |
|
1195 | 1196 |
static int cli_scanhtml(cli_ctx *ctx) |
1196 | 1197 |
{ |
1197 | 1198 |
char *tempname, fullname[1024]; |
1198 |
- int ret=CL_CLEAN, fd; |
|
1199 |
+ int ret = CL_CLEAN, fd; |
|
1199 | 1200 |
fmap_t *map = *ctx->fmap; |
1200 | 1201 |
unsigned int viruses_found = 0; |
1201 | 1202 |
uint64_t curr_len = map->len; |
... | ... |
@@ -1203,309 +1363,355 @@ static int cli_scanhtml(cli_ctx *ctx) |
1203 | 1203 |
cli_dbgmsg("in cli_scanhtml()\n"); |
1204 | 1204 |
|
1205 | 1205 |
/* CL_ENGINE_MAX_HTMLNORMALIZE */ |
1206 |
- if(curr_len > ctx->engine->maxhtmlnormalize) { |
|
1207 |
- cli_dbgmsg("cli_scanhtml: exiting (file larger than MaxHTMLNormalize)\n"); |
|
1208 |
- return CL_CLEAN; |
|
1206 |
+ if (curr_len > ctx->engine->maxhtmlnormalize) |
|
1207 |
+ { |
|
1208 |
+ cli_dbgmsg("cli_scanhtml: exiting (file larger than MaxHTMLNormalize)\n"); |
|
1209 |
+ return CL_CLEAN; |
|
1209 | 1210 |
} |
1210 | 1211 |
|
1211 |
- if(!(tempname = cli_gentemp(ctx->engine->tmpdir))) |
|
1212 |
- return CL_EMEM; |
|
1212 |
+ if (!(tempname = cli_gentemp(ctx->engine->tmpdir))) |
|
1213 |
+ return CL_EMEM; |
|
1213 | 1214 |
|
1214 |
- if(mkdir(tempname, 0700)) { |
|
1215 |
+ if (mkdir(tempname, 0700)) |
|
1216 |
+ { |
|
1215 | 1217 |
cli_errmsg("cli_scanhtml: Can't create temporary directory %s\n", tempname); |
1216 |
- free(tempname); |
|
1218 |
+ free(tempname); |
|
1217 | 1219 |
return CL_ETMPDIR; |
1218 | 1220 |
} |
1219 | 1221 |
|
1220 | 1222 |
cli_dbgmsg("cli_scanhtml: using tempdir %s\n", tempname); |
1221 | 1223 |
|
1222 | 1224 |
html_normalise_map(map, tempname, NULL, ctx->dconf); |
1223 |
- snprintf(fullname, 1024, "%s"PATHSEP"nocomment.html", tempname); |
|
1224 |
- fd = open(fullname, O_RDONLY|O_BINARY); |
|
1225 |
- if (fd >= 0) { |
|
1226 |
- if ((ret = cli_scandesc(fd, ctx, CL_TYPE_HTML, 0, NULL, AC_SCAN_VIR, NULL)) == CL_VIRUS) |
|
1227 |
- viruses_found++; |
|
1228 |
- close(fd); |
|
1225 |
+ snprintf(fullname, 1024, "%s" PATHSEP "nocomment.html", tempname); |
|
1226 |
+ fd = open(fullname, O_RDONLY | O_BINARY); |
|
1227 |
+ if (fd >= 0) |
|
1228 |
+ { |
|
1229 |
+ if ((ret = cli_scandesc(fd, ctx, CL_TYPE_HTML, 0, NULL, AC_SCAN_VIR, NULL)) == CL_VIRUS) |
|
1230 |
+ viruses_found++; |
|
1231 |
+ close(fd); |
|
1229 | 1232 |
} |
1230 | 1233 |
|
1231 |
- if(ret == CL_CLEAN || (ret == CL_VIRUS && SCAN_ALL)) { |
|
1234 |
+ if (ret == CL_CLEAN || (ret == CL_VIRUS && SCAN_ALL)) |
|
1235 |
+ { |
|
1232 | 1236 |
/* CL_ENGINE_MAX_HTMLNOTAGS */ |
1233 | 1237 |
curr_len = map->len; |
1234 |
- if (curr_len > ctx->engine->maxhtmlnotags) { |
|
1235 |
- /* we're not interested in scanning large files in notags form */ |
|
1238 |
+ if (curr_len > ctx->engine->maxhtmlnotags) |
|
1239 |
+ { |
|
1240 |
+ /* we're not interested in scanning large files in notags form */ |
|
1236 | 1241 |
/* TODO: don't even create notags if file is over limit */ |
1237 | 1242 |
cli_dbgmsg("cli_scanhtml: skipping notags (normalized size over MaxHTMLNoTags)\n"); |
1238 |
- } |
|
1239 |
- else { |
|
1240 |
- snprintf(fullname, 1024, "%s"PATHSEP"notags.html", tempname); |
|
1241 |
- fd = open(fullname, O_RDONLY|O_BINARY); |
|
1242 |
- if(fd >= 0) { |
|
1243 |
- if ((ret = cli_scandesc(fd, ctx, CL_TYPE_HTML, 0, NULL, AC_SCAN_VIR, NULL)) == CL_VIRUS) |
|
1243 |
+ } |
|
1244 |
+ else |
|
1245 |
+ { |
|
1246 |
+ snprintf(fullname, 1024, "%s" PATHSEP "notags.html", tempname); |
|
1247 |
+ fd = open(fullname, O_RDONLY | O_BINARY); |
|
1248 |
+ if (fd >= 0) |
|
1249 |
+ { |
|
1250 |
+ if ((ret = cli_scandesc(fd, ctx, CL_TYPE_HTML, 0, NULL, AC_SCAN_VIR, NULL)) == CL_VIRUS) |
|
1244 | 1251 |
viruses_found++; |
1245 | 1252 |
close(fd); |
1246 | 1253 |
} |
1247 | 1254 |
} |
1248 | 1255 |
} |
1249 | 1256 |
|
1250 |
- if(ret == CL_CLEAN || (ret == CL_VIRUS && SCAN_ALL)) { |
|
1251 |
- snprintf(fullname, 1024, "%s"PATHSEP"javascript", tempname); |
|
1252 |
- fd = open(fullname, O_RDONLY|O_BINARY); |
|
1253 |
- if(fd >= 0) { |
|
1254 |
- if ((ret = cli_scandesc(fd, ctx, CL_TYPE_HTML, 0, NULL, AC_SCAN_VIR, NULL)) == CL_VIRUS) |
|
1255 |
- viruses_found++; |
|
1256 |
- if (ret == CL_CLEAN || (ret == CL_VIRUS && SCAN_ALL)) { |
|
1257 |
- if ((ret = cli_scandesc(fd, ctx, CL_TYPE_TEXT_ASCII, 0, NULL, AC_SCAN_VIR, NULL)) == CL_VIRUS) |
|
1258 |
- viruses_found++; |
|
1259 |
- } |
|
1260 |
- close(fd); |
|
1261 |
- } |
|
1257 |
+ if (ret == CL_CLEAN || (ret == CL_VIRUS && SCAN_ALL)) |
|
1258 |
+ { |
|
1259 |
+ snprintf(fullname, 1024, "%s" PATHSEP "javascript", tempname); |
|
1260 |
+ fd = open(fullname, O_RDONLY | O_BINARY); |
|
1261 |
+ if (fd >= 0) |
|
1262 |
+ { |
|
1263 |
+ if ((ret = cli_scandesc(fd, ctx, CL_TYPE_HTML, 0, NULL, AC_SCAN_VIR, NULL)) == CL_VIRUS) |
|
1264 |
+ viruses_found++; |
|
1265 |
+ if (ret == CL_CLEAN || (ret == CL_VIRUS && SCAN_ALL)) |
|
1266 |
+ { |
|
1267 |
+ if ((ret = cli_scandesc(fd, ctx, CL_TYPE_TEXT_ASCII, 0, NULL, AC_SCAN_VIR, NULL)) == CL_VIRUS) |
|
1268 |
+ viruses_found++; |
|
1269 |
+ } |
|
1270 |
+ close(fd); |
|
1271 |
+ } |
|
1262 | 1272 |
} |
1263 | 1273 |
|
1264 |
- if (ret == CL_CLEAN || (ret == CL_VIRUS && SCAN_ALL)) { |
|
1265 |
- snprintf(fullname, 1024, "%s"PATHSEP"rfc2397", tempname); |
|
1266 |
- ret = cli_scandir(fullname, ctx); |
|
1274 |
+ if (ret == CL_CLEAN || (ret == CL_VIRUS && SCAN_ALL)) |
|
1275 |
+ { |
|
1276 |
+ snprintf(fullname, 1024, "%s" PATHSEP "rfc2397", tempname); |
|
1277 |
+ ret = cli_scandir(fullname, ctx); |
|
1267 | 1278 |
} |
1268 | 1279 |
|
1269 |
- if(!ctx->engine->keeptmp) |
|
1280 |
+ if (!ctx->engine->keeptmp) |
|
1270 | 1281 |
cli_rmdirs(tempname); |
1271 | 1282 |
|
1272 | 1283 |
free(tempname); |
1273 | 1284 |
if (SCAN_ALL && viruses_found) |
1274 |
- return CL_VIRUS; |
|
1285 |
+ return CL_VIRUS; |
|
1275 | 1286 |
return ret; |
1276 | 1287 |
} |
1277 | 1288 |
|
1278 | 1289 |
static int cli_scanscript(cli_ctx *ctx) |
1279 | 1290 |
{ |
1280 |
- const unsigned char *buff; |
|
1281 |
- unsigned char* normalized; |
|
1282 |
- struct text_norm_state state; |
|
1283 |
- char *tmpname = NULL; |
|
1284 |
- int ofd = -1, ret; |
|
1285 |
- struct cli_matcher *troot; |
|
1286 |
- uint32_t maxpatlen, offset = 0; |
|
1287 |
- struct cli_matcher *groot; |
|
1288 |
- struct cli_ac_data gmdata, tmdata; |
|
1289 |
- struct cli_ac_data *mdata[2]; |
|
1290 |
- fmap_t *map; |
|
1291 |
- size_t at = 0; |
|
1292 |
- unsigned int viruses_found = 0; |
|
1293 |
- uint64_t curr_len; |
|
1294 |
- struct cli_target_info info; |
|
1295 |
- |
|
1296 |
- if (!ctx || !ctx->engine->root) |
|
1297 |
- return CL_ENULLARG; |
|
1298 |
- |
|
1299 |
- map = *ctx->fmap; |
|
1300 |
- curr_len = map->len; |
|
1301 |
- groot = ctx->engine->root[0]; |
|
1302 |
- troot = ctx->engine->root[7]; |
|
1303 |
- maxpatlen = troot ? troot->maxpatlen : 0; |
|
1304 |
- |
|
1305 |
- cli_dbgmsg("in cli_scanscript()\n"); |
|
1306 |
- |
|
1307 |
- /* CL_ENGINE_MAX_SCRIPTNORMALIZE */ |
|
1308 |
- if(curr_len > ctx->engine->maxscriptnormalize) { |
|
1309 |
- cli_dbgmsg("cli_scanscript: exiting (file larger than MaxScriptSize)\n"); |
|
1310 |
- return CL_CLEAN; |
|
1311 |
- } |
|
1312 |
- |
|
1313 |
- if(!(normalized = cli_malloc(SCANBUFF + maxpatlen))) { |
|
1314 |
- cli_dbgmsg("cli_scanscript: Unable to malloc %u bytes\n", SCANBUFF); |
|
1315 |
- return CL_EMEM; |
|
1316 |
- } |
|
1317 |
- text_normalize_init(&state, normalized, SCANBUFF + maxpatlen); |
|
1318 |
- |
|
1319 |
- if ((ret = cli_ac_initdata(&tmdata, troot?troot->ac_partsigs:0, troot?troot->ac_lsigs:0, troot?troot->ac_reloff_num:0, CLI_DEFAULT_AC_TRACKLEN))) { |
|
1320 |
- free(normalized); |
|
1321 |
- return ret; |
|
1322 |
- } |
|
1291 |
+ const unsigned char *buff; |
|
1292 |
+ unsigned char *normalized; |
|
1293 |
+ struct text_norm_state state; |
|
1294 |
+ char *tmpname = NULL; |
|
1295 |
+ int ofd = -1, ret; |
|
1296 |
+ struct cli_matcher *troot; |
|
1297 |
+ uint32_t maxpatlen, offset = 0; |
|
1298 |
+ struct cli_matcher *groot; |
|
1299 |
+ struct cli_ac_data gmdata, tmdata; |
|
1300 |
+ struct cli_ac_data *mdata[2]; |
|
1301 |
+ fmap_t *map; |
|
1302 |
+ size_t at = 0; |
|
1303 |
+ unsigned int viruses_found = 0; |
|
1304 |
+ uint64_t curr_len; |
|
1305 |
+ struct cli_target_info info; |
|
1323 | 1306 |
|
1324 |
- if ((ret = cli_ac_initdata(&gmdata, groot->ac_partsigs, groot->ac_lsigs, groot->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN))) { |
|
1325 |
- cli_ac_freedata(&tmdata); |
|
1326 |
- free(normalized); |
|
1327 |
- return ret; |
|
1328 |
- } |
|
1329 |
- |
|
1330 |
- /* dump to disk only if explicitly asked to |
|
1331 |
- * or if necessary to check relative offsets, |
|
1332 |
- * otherwise we can process just in-memory */ |
|
1333 |
- if(ctx->engine->keeptmp || (troot && (troot->ac_reloff_num > 0 || troot->linked_bcs))) { |
|
1334 |
- if((ret = cli_gentempfd(ctx->engine->tmpdir, &tmpname, &ofd))) { |
|
1335 |
- cli_dbgmsg("cli_scanscript: Can't generate temporary file/descriptor\n"); |
|
1307 |
+ if (!ctx || !ctx->engine->root) |
|
1308 |
+ return CL_ENULLARG; |
|
1309 |
+ |
|
1310 |
+ map = *ctx->fmap; |
|
1311 |
+ curr_len = map->len; |
|
1312 |
+ groot = ctx->engine->root[0]; |
|
1313 |
+ troot = ctx->engine->root[7]; |
|
1314 |
+ maxpatlen = troot ? troot->maxpatlen : 0; |
|
1315 |
+ |
|
1316 |
+ cli_dbgmsg("in cli_scanscript()\n"); |
|
1317 |
+ |
|
1318 |
+ /* CL_ENGINE_MAX_SCRIPTNORMALIZE */ |
|
1319 |
+ if (curr_len > ctx->engine->maxscriptnormalize) |
|
1320 |
+ { |
|
1321 |
+ cli_dbgmsg("cli_scanscript: exiting (file larger than MaxScriptSize)\n"); |
|
1322 |
+ return CL_CLEAN; |
|
1323 |
+ } |
|
1324 |
+ |
|
1325 |
+ if (!(normalized = cli_malloc(SCANBUFF + maxpatlen))) |
|
1326 |
+ { |
|
1327 |
+ cli_dbgmsg("cli_scanscript: Unable to malloc %u bytes\n", SCANBUFF); |
|
1328 |
+ return CL_EMEM; |
|
1329 |
+ } |
|
1330 |
+ text_normalize_init(&state, normalized, SCANBUFF + maxpatlen); |
|
1331 |
+ |
|
1332 |
+ if ((ret = cli_ac_initdata(&tmdata, troot ? troot->ac_partsigs : 0, troot ? troot->ac_lsigs : 0, troot ? troot->ac_reloff_num : 0, CLI_DEFAULT_AC_TRACKLEN))) |
|
1333 |
+ { |
|
1334 |
+ free(normalized); |
|
1335 |
+ return ret; |
|
1336 |
+ } |
|
1337 |
+ |
|
1338 |
+ if ((ret = cli_ac_initdata(&gmdata, groot->ac_partsigs, groot->ac_lsigs, groot->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN))) |
|
1339 |
+ { |
|
1340 |
+ cli_ac_freedata(&tmdata); |
|
1341 |
+ free(normalized); |
|
1342 |
+ return ret; |
|
1343 |
+ } |
|
1344 |
+ |
|
1345 |
+ /* dump to disk only if explicitly asked to |
|
1346 |
+ * or if necessary to check relative offsets, |
|
1347 |
+ * otherwise we can process just in-memory */ |
|
1348 |
+ if (ctx->engine->keeptmp || (troot && (troot->ac_reloff_num > 0 || troot->linked_bcs))) |
|
1349 |
+ { |
|
1350 |
+ if ((ret = cli_gentempfd(ctx->engine->tmpdir, &tmpname, &ofd))) |
|
1351 |
+ { |
|
1352 |
+ cli_dbgmsg("cli_scanscript: Can't generate temporary file/descriptor\n"); |
|
1353 |
+ goto done; |
|
1354 |
+ } |
|
1355 |
+ if (ctx->engine->keeptmp) |
|
1356 |
+ cli_dbgmsg("cli_scanscript: saving normalized file to %s\n", tmpname); |
|
1357 |
+ } |
|
1358 |
+ |
|
1359 |
+ mdata[0] = &tmdata; |
|
1360 |
+ mdata[1] = &gmdata; |
|
1361 |
+ |
|
1362 |
+ /* If there's a relative offset in troot or triggered bytecodes, normalize to file.*/ |
|
1363 |
+ if (troot && (troot->ac_reloff_num > 0 || troot->linked_bcs)) |
|
1364 |
+ { |
|
1365 |
+ size_t map_off = 0; |
|
1366 |
+ while (map_off < map->len) |
|
1367 |
+ { |
|
1368 |
+ size_t written; |
|
1369 |
+ if (!(written = text_normalize_map(&state, map, map_off))) |
|
1370 |
+ break; |
|
1371 |
+ map_off += written; |
|
1372 |
+ |
|
1373 |
+ if (write(ofd, state.out, state.out_pos) == -1) |
|
1374 |
+ { |
|
1375 |
+ cli_errmsg("cli_scanscript: can't write to file %s\n", tmpname); |
|
1376 |
+ ret = CL_EWRITE; |
|
1336 | 1377 |
goto done; |
1337 | 1378 |
} |
1338 |
- if (ctx->engine->keeptmp) |
|
1339 |
- cli_dbgmsg("cli_scanscript: saving normalized file to %s\n", tmpname); |
|
1340 |
- } |
|
1341 |
- |
|
1342 |
- mdata[0] = &tmdata; |
|
1343 |
- mdata[1] = &gmdata; |
|
1344 |
- |
|
1345 |
- /* If there's a relative offset in troot or triggered bytecodes, normalize to file.*/ |
|
1346 |
- if (troot && (troot->ac_reloff_num > 0 || troot->linked_bcs)) { |
|
1347 |
- size_t map_off = 0; |
|
1348 |
- while(map_off < map->len) { |
|
1349 |
- size_t written; |
|
1350 |
- if (!(written = text_normalize_map(&state, map, map_off))) break; |
|
1351 |
- map_off += written; |
|
1352 |
- |
|
1353 |
- if (write(ofd, state.out, state.out_pos) == -1) { |
|
1354 |
- cli_errmsg("cli_scanscript: can't write to file %s\n",tmpname); |
|
1355 |
- ret = CL_EWRITE; |
|
1356 |
- goto done; |
|
1357 |
- } |
|
1358 |
- text_normalize_reset(&state); |
|
1359 |
- } |
|
1360 |
- |
|
1361 |
- /* Temporarily store the normalized file map in the context. */ |
|
1362 |
- *ctx->fmap = fmap(ofd, 0, 0); |
|
1363 |
- if (!(*ctx->fmap)) { |
|
1364 |
- cli_dbgmsg("cli_scanscript: could not map file %s\n",tmpname); |
|
1365 |
- } else { |
|
1366 |
- |
|
1367 |
- /* scan map */ |
|
1368 |
- ret = cli_fmap_scandesc(ctx, CL_TYPE_TEXT_ASCII, 0, NULL, AC_SCAN_VIR, NULL, NULL); |
|
1369 |
- if(ret == CL_VIRUS) { |
|
1370 |
- viruses_found++; |
|
1371 |
- } |
|
1372 |
- funmap(*ctx->fmap); |
|
1373 |
- } |
|
1374 |
- *ctx->fmap = map; |
|
1375 |
- } else { |
|
1376 |
- /* Since the above is moderately costly all in all, |
|
1377 |
- * do the old stuff if there's no relative offsets. */ |
|
1378 |
- |
|
1379 |
- if (troot) { |
|
1380 |
- cli_targetinfo(&info, 7, map); |
|
1381 |
- ret = cli_ac_caloff(troot, &tmdata, &info); |
|
1382 |
- if (ret) |
|
1383 |
- goto done; |
|
1384 |
- } |
|
1385 |
- |
|
1386 |
- while(1) { |
|
1387 |
- size_t len = MIN(map->pgsz, map->len - at); |
|
1388 |
- buff = fmap_need_off_once(map, at, len); |
|
1389 |
- at += len; |
|
1390 |
- if(!buff || !len || state.out_pos + len > state.out_len) { |
|
1391 |
- /* flush if error/EOF, or too little buffer space left */ |
|
1392 |
- if((ofd != -1) && (write(ofd, state.out, state.out_pos) == -1)) { |
|
1393 |
- cli_errmsg("cli_scanscript: can't write to file %s\n",tmpname); |
|
1394 |
- close(ofd); |
|
1395 |
- ofd = -1; |
|
1396 |
- /* we can continue to scan in memory */ |
|
1397 |
- } |
|
1398 |
- /* when we flush the buffer also scan */ |
|
1399 |
- if(cli_scanbuff(state.out, state.out_pos, offset, ctx, CL_TYPE_TEXT_ASCII, mdata) == CL_VIRUS) { |
|
1400 |
- if (SCAN_ALL) |
|
1401 |
- viruses_found++; |
|
1402 |
- else { |
|
1403 |
- ret = CL_VIRUS; |
|
1404 |
- break; |
|
1405 |
- } |
|
1406 |
- } |
|
1407 |
- if(ctx->scanned) |
|
1408 |
- *ctx->scanned += state.out_pos / CL_COUNT_PRECISION; |
|
1409 |
- offset += state.out_pos; |
|
1410 |
- /* carry over maxpatlen from previous buffer */ |
|
1411 |
- if (state.out_pos > maxpatlen) |
|
1412 |
- memmove(state.out, state.out + state.out_pos - maxpatlen, maxpatlen); |
|
1413 |
- text_normalize_reset(&state); |
|
1414 |
- state.out_pos = maxpatlen; |
|
1415 |
- } |
|
1416 |
- if(!len) break; |
|
1417 |
- if(!buff || text_normalize_buffer(&state, buff, len) != len) { |
|
1418 |
- cli_dbgmsg("cli_scanscript: short read during normalizing\n"); |
|
1419 |
- } |
|
1420 |
- } |
|
1421 |
- |
|
1422 |
- } |
|
1423 |
- |
|
1424 |
- if(ret != CL_VIRUS || SCAN_ALL) { |
|
1425 |
- if ((ret = cli_exp_eval(ctx, troot, &tmdata, NULL, NULL)) == CL_VIRUS) |
|
1426 |
- viruses_found++; |
|
1427 |
- if(ret != CL_VIRUS || SCAN_ALL) |
|
1428 |
- if ((ret = cli_exp_eval(ctx, groot, &gmdata, NULL, NULL)) == CL_VIRUS) |
|
1429 |
- viruses_found++; |
|
1430 |
- } |
|
1431 |
- |
|
1432 |
- done: |
|
1433 |
- free(normalized); |
|
1434 |
- cli_ac_freedata(&tmdata); |
|
1435 |
- cli_ac_freedata(&gmdata); |
|
1436 |
- |
|
1437 |
- if (ofd != -1) |
|
1438 |
- close(ofd); |
|
1439 |
- if (tmpname != NULL) { |
|
1440 |
- if (!ctx->engine->keeptmp) |
|
1441 |
- cli_unlink(tmpname); |
|
1442 |
- free(tmpname); |
|
1379 |
+ text_normalize_reset(&state); |
|
1443 | 1380 |
} |
1444 | 1381 |
|
1445 |
- if (viruses_found) |
|
1446 |
- return CL_VIRUS; |
|
1382 |
+ /* Temporarily store the normalized file map in the context. */ |
|
1383 |
+ *ctx->fmap = fmap(ofd, 0, 0); |
|
1384 |
+ if (!(*ctx->fmap)) |
|
1385 |
+ { |
|
1386 |
+ cli_dbgmsg("cli_scanscript: could not map file %s\n", tmpname); |
|
1387 |
+ } |
|
1388 |
+ else |
|
1389 |
+ { |
|
1390 |
+ |
|
1391 |
+ /* scan map */ |
|
1392 |
+ ret = cli_fmap_scandesc(ctx, CL_TYPE_TEXT_ASCII, 0, NULL, AC_SCAN_VIR, NULL, NULL); |
|
1393 |
+ if (ret == CL_VIRUS) |
|
1394 |
+ { |
|
1395 |
+ viruses_found++; |
|
1396 |
+ } |
|
1397 |
+ funmap(*ctx->fmap); |
|
1398 |
+ } |
|
1399 |
+ *ctx->fmap = map; |
|
1400 |
+ } |
|
1401 |
+ else |
|
1402 |
+ { |
|
1403 |
+ /* Since the above is moderately costly all in all, |
|
1404 |
+ * do the old stuff if there's no relative offsets. */ |
|
1405 |
+ |
|
1406 |
+ if (troot) |
|
1407 |
+ { |
|
1408 |
+ cli_targetinfo(&info, 7, map); |
|
1409 |
+ ret = cli_ac_caloff(troot, &tmdata, &info); |
|
1410 |
+ if (ret) |
|
1411 |
+ goto done; |
|
1412 |
+ } |
|
1447 | 1413 |
|
1448 |
- return ret; |
|
1414 |
+ while (1) |
|
1415 |
+ { |
|
1416 |
+ size_t len = MIN(map->pgsz, map->len - at); |
|
1417 |
+ buff = fmap_need_off_once(map, at, len); |
|
1418 |
+ at += len; |
|
1419 |
+ if (!buff || !len || state.out_pos + len > state.out_len) |
|
1420 |
+ { |
|
1421 |
+ /* flush if error/EOF, or too little buffer space left */ |
|
1422 |
+ if ((ofd != -1) && (write(ofd, state.out, state.out_pos) == -1)) |
|
1423 |
+ { |
|
1424 |
+ cli_errmsg("cli_scanscript: can't write to file %s\n", tmpname); |
|
1425 |
+ close(ofd); |
|
1426 |
+ ofd = -1; |
|
1427 |
+ /* we can continue to scan in memory */ |
|
1428 |
+ } |
|
1429 |
+ /* when we flush the buffer also scan */ |
|
1430 |
+ if (cli_scanbuff(state.out, state.out_pos, offset, ctx, CL_TYPE_TEXT_ASCII, mdata) == CL_VIRUS) |
|
1431 |
+ { |
|
1432 |
+ if (SCAN_ALL) |
|
1433 |
+ viruses_found++; |
|
1434 |
+ else |
|
1435 |
+ { |
|
1436 |
+ ret = CL_VIRUS; |
|
1437 |
+ break; |
|
1438 |
+ } |
|
1439 |
+ } |
|
1440 |
+ if (ctx->scanned) |
|
1441 |
+ *ctx->scanned += state.out_pos / CL_COUNT_PRECISION; |
|
1442 |
+ offset += state.out_pos; |
|
1443 |
+ /* carry over maxpatlen from previous buffer */ |
|
1444 |
+ if (state.out_pos > maxpatlen) |
|
1445 |
+ memmove(state.out, state.out + state.out_pos - maxpatlen, maxpatlen); |
|
1446 |
+ text_normalize_reset(&state); |
|
1447 |
+ state.out_pos = maxpatlen; |
|
1448 |
+ } |
|
1449 |
+ if (!len) |
|
1450 |
+ break; |
|
1451 |
+ if (!buff || text_normalize_buffer(&state, buff, len) != len) |
|
1452 |
+ { |
|
1453 |
+ cli_dbgmsg("cli_scanscript: short read during normalizing\n"); |
|
1454 |
+ } |
|
1455 |
+ } |
|
1456 |
+ } |
|
1457 |
+ |
|
1458 |
+ if (ret != CL_VIRUS || SCAN_ALL) |
|
1459 |
+ { |
|
1460 |
+ if ((ret = cli_exp_eval(ctx, troot, &tmdata, NULL, NULL)) == CL_VIRUS) |
|
1461 |
+ viruses_found++; |
|
1462 |
+ if (ret != CL_VIRUS || SCAN_ALL) |
|
1463 |
+ if ((ret = cli_exp_eval(ctx, groot, &gmdata, NULL, NULL)) == CL_VIRUS) |
|
1464 |
+ viruses_found++; |
|
1465 |
+ } |
|
1466 |
+ |
|
1467 |
+done: |
|
1468 |
+ free(normalized); |
|
1469 |
+ cli_ac_freedata(&tmdata); |
|
1470 |
+ cli_ac_freedata(&gmdata); |
|
1471 |
+ |
|
1472 |
+ if (ofd != -1) |
|
1473 |
+ close(ofd); |
|
1474 |
+ if (tmpname != NULL) |
|
1475 |
+ { |
|
1476 |
+ if (!ctx->engine->keeptmp) |
|
1477 |
+ cli_unlink(tmpname); |
|
1478 |
+ free(tmpname); |
|
1479 |
+ } |
|
1480 |
+ |
|
1481 |
+ if (viruses_found) |
|
1482 |
+ return CL_VIRUS; |
|
1483 |
+ |
|
1484 |
+ return ret; |
|
1449 | 1485 |
} |
1450 | 1486 |
|
1451 | 1487 |
static int cli_scanhtml_utf16(cli_ctx *ctx) |
1452 | 1488 |
{ |
1453 |
- char *tempname, *decoded; |
|
1454 |
- const char *buff; |
|
1455 |
- int ret = CL_CLEAN, fd, bytes; |
|
1456 |
- size_t at = 0; |
|
1457 |
- fmap_t *map = *ctx->fmap; |
|
1489 |
+ char *tempname, *decoded; |
|
1490 |
+ const char *buff; |
|
1491 |
+ int ret = CL_CLEAN, fd, bytes; |
|
1492 |
+ size_t at = 0; |
|
1493 |
+ fmap_t *map = *ctx->fmap; |
|
1458 | 1494 |
|
1459 | 1495 |
cli_dbgmsg("in cli_scanhtml_utf16()\n"); |
1460 | 1496 |
|
1461 |
- if(!(tempname = cli_gentemp(ctx->engine->tmpdir))) |
|
1462 |
- return CL_EMEM; |
|
1497 |
+ if (!(tempname = cli_gentemp(ctx->engine->tmpdir))) |
|
1498 |
+ return CL_EMEM; |
|
1463 | 1499 |
|
1464 |
- if((fd = open(tempname, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) { |
|
1465 |
- cli_errmsg("cli_scanhtml_utf16: Can't create file %s\n", tempname); |
|
1466 |
- free(tempname); |
|
1467 |
- return CL_EOPEN; |
|
1500 |
+ if ((fd = open(tempname, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, S_IRWXU)) < 0) |
|
1501 |
+ { |
|
1502 |
+ cli_errmsg("cli_scanhtml_utf16: Can't create file %s\n", tempname); |
|
1503 |
+ free(tempname); |
|
1504 |
+ return CL_EOPEN; |
|
1468 | 1505 |
} |
1469 | 1506 |
|
1470 | 1507 |
cli_dbgmsg("cli_scanhtml_utf16: using tempfile %s\n", tempname); |
1471 | 1508 |
|
1472 |
- while(at < map->len) { |
|
1473 |
- bytes = MIN(map->len - at, map->pgsz * 16); |
|
1474 |
- if(!(buff = fmap_need_off_once(map, at, bytes))) { |
|
1475 |
- close(fd); |
|
1476 |
- cli_unlink(tempname); |
|
1477 |
- free(tempname); |
|
1478 |
- return CL_EREAD; |
|
1479 |
- } |
|
1480 |
- at += bytes; |
|
1481 |
- decoded = cli_utf16toascii(buff, bytes); |
|
1482 |
- if(decoded) { |
|
1483 |
- if(write(fd, decoded, bytes / 2) == -1) { |
|
1484 |
- cli_errmsg("cli_scanhtml_utf16: Can't write to file %s\n", tempname); |
|
1485 |
- free(decoded); |
|
1486 |
- close(fd); |
|
1487 |
- cli_unlink(tempname); |
|
1488 |
- free(tempname); |
|
1489 |
- return CL_EWRITE; |
|
1490 |
- } |
|
1491 |
- free(decoded); |
|
1492 |
- } |
|
1509 |
+ while (at < map->len) |
|
1510 |
+ { |
|
1511 |
+ bytes = MIN(map->len - at, map->pgsz * 16); |
|
1512 |
+ if (!(buff = fmap_need_off_once(map, at, bytes))) |
|
1513 |
+ { |
|
1514 |
+ close(fd); |
|
1515 |
+ cli_unlink(tempname); |
|
1516 |
+ free(tempname); |
|
1517 |
+ return CL_EREAD; |
|
1518 |
+ } |
|
1519 |
+ at += bytes; |
|
1520 |
+ decoded = cli_utf16toascii(buff, bytes); |
|
1521 |
+ if (decoded) |
|
1522 |
+ { |
|
1523 |
+ if (write(fd, decoded, bytes / 2) == -1) |
|
1524 |
+ { |
|
1525 |
+ cli_errmsg("cli_scanhtml_utf16: Can't write to file %s\n", tempname); |
|
1526 |
+ free(decoded); |
|
1527 |
+ close(fd); |
|
1528 |
+ cli_unlink(tempname); |
|
1529 |
+ free(tempname); |
|
1530 |
+ return CL_EWRITE; |
|
1531 |
+ } |
|
1532 |
+ free(decoded); |
|
1533 |
+ } |
|
1493 | 1534 |
} |
1494 | 1535 |
|
1495 | 1536 |
*ctx->fmap = fmap(fd, 0, 0); |
1496 |
- if(*ctx->fmap) { |
|
1497 |
- ret = cli_scanhtml(ctx); |
|
1498 |
- funmap(*ctx->fmap); |
|
1499 |
- } else |
|
1500 |
- cli_errmsg("cli_scanhtml_utf16: fmap of %s failed\n", tempname); |
|
1537 |
+ if (*ctx->fmap) |
|
1538 |
+ { |
|
1539 |
+ ret = cli_scanhtml(ctx); |
|
1540 |
+ funmap(*ctx->fmap); |
|
1541 |
+ } |
|
1542 |
+ else |
|
1543 |
+ cli_errmsg("cli_scanhtml_utf16: fmap of %s failed\n", tempname); |
|
1501 | 1544 |
|
1502 | 1545 |
*ctx->fmap = map; |
1503 | 1546 |
close(fd); |
1504 | 1547 |
|
1505 |
- if(!ctx->engine->keeptmp) { |
|
1506 |
- if (cli_unlink(tempname)) ret = CL_EUNLINK; |
|
1507 |
- } else |
|
1508 |
- cli_dbgmsg("cli_scanhtml_utf16: Decoded HTML data saved in %s\n", tempname); |
|
1548 |
+ if (!ctx->engine->keeptmp) |
|
1549 |
+ { |
|
1550 |
+ if (cli_unlink(tempname)) |
|
1551 |
+ ret = CL_EUNLINK; |
|
1552 |
+ } |
|
1553 |
+ else |
|
1554 |
+ cli_dbgmsg("cli_scanhtml_utf16: Decoded HTML data saved in %s\n", tempname); |
|
1509 | 1555 |
free(tempname); |
1510 | 1556 |
|
1511 | 1557 |
return ret; |
... | ... |
@@ -1513,73 +1719,76 @@ static int cli_scanhtml_utf16(cli_ctx *ctx) |
1513 | 1513 |
|
1514 | 1514 |
static int cli_scanole2(cli_ctx *ctx) |
1515 | 1515 |
{ |
1516 |
- char *dir; |
|
1517 |
- int ret = CL_CLEAN; |
|
1518 |
- struct uniq *vba = NULL; |
|
1516 |
+ char *dir; |
|
1517 |
+ int ret = CL_CLEAN; |
|
1518 |
+ struct uniq *vba = NULL; |
|
1519 | 1519 |
|
1520 | 1520 |
cli_dbgmsg("in cli_scanole2()\n"); |
1521 | 1521 |
|
1522 |
- if(ctx->engine->maxreclevel && ctx->recursion >= ctx->engine->maxreclevel) |
|
1522 |
+ if (ctx->engine->maxreclevel && ctx->recursion >= ctx->engine->maxreclevel) |
|
1523 | 1523 |
return CL_EMAXREC; |
1524 | 1524 |
|
1525 | 1525 |
/* generate the temporary directory */ |
1526 |
- if(!(dir = cli_gentemp(ctx->engine->tmpdir))) |
|
1527 |
- return CL_EMEM; |
|
1526 |
+ if (!(dir = cli_gentemp(ctx->engine->tmpdir))) |
|
1527 |
+ return CL_EMEM; |
|
1528 | 1528 |
|
1529 |
- if(mkdir(dir, 0700)) { |
|
1530 |
- cli_dbgmsg("OLE2: Can't create temporary directory %s\n", dir); |
|
1531 |
- free(dir); |
|
1532 |
- return CL_ETMPDIR; |
|
1529 |
+ if (mkdir(dir, 0700)) |
|
1530 |
+ { |
|
1531 |
+ cli_dbgmsg("OLE2: Can't create temporary directory %s\n", dir); |
|
1532 |
+ free(dir); |
|
1533 |
+ return CL_ETMPDIR; |
|
1533 | 1534 |
} |
1534 | 1535 |
|
1535 | 1536 |
ret = cli_ole2_extract(dir, ctx, &vba); |
1536 |
- if(ret!=CL_CLEAN && ret!=CL_VIRUS) { |
|
1537 |
- cli_dbgmsg("OLE2: %s\n", cl_strerror(ret)); |
|
1538 |
- if(!ctx->engine->keeptmp) |
|
1539 |
- cli_rmdirs(dir); |
|
1540 |
- free(dir); |
|
1541 |
- return ret; |
|
1537 |
+ if (ret != CL_CLEAN && ret != CL_VIRUS) |
|
1538 |
+ { |
|
1539 |
+ cli_dbgmsg("OLE2: %s\n", cl_strerror(ret)); |
|
1540 |
+ if (!ctx->engine->keeptmp) |
|
1541 |
+ cli_rmdirs(dir); |
|
1542 |
+ free(dir); |
|
1543 |
+ return ret; |
|
1542 | 1544 |
} |
1543 | 1545 |
|
1544 |
- if (vba) { |
|
1546 |
+ if (vba) |
|
1547 |
+ { |
|
1545 | 1548 |
ctx->recursion++; |
1546 | 1549 |
|
1547 |
- ret = cli_vba_scandir(dir, ctx, vba); |
|
1548 |
- uniq_free(vba); |
|
1549 |
- if(ret != CL_VIRUS) |
|
1550 |
- if(cli_scandir(dir, ctx) == CL_VIRUS) |
|
1551 |
- ret = CL_VIRUS; |
|
1552 |
- ctx->recursion--; |
|
1550 |
+ ret = cli_vba_scandir(dir, ctx, vba); |
|
1551 |
+ uniq_free(vba); |
|
1552 |
+ if (ret != CL_VIRUS) |
|
1553 |
+ if (cli_scandir(dir, ctx) == CL_VIRUS) |
|
1554 |
+ ret = CL_VIRUS; |
|
1555 |
+ ctx->recursion--; |
|
1553 | 1556 |
} |
1554 | 1557 |
|
1555 |
- if(!ctx->engine->keeptmp) |
|
1556 |
- cli_rmdirs(dir); |
|
1558 |
+ if (!ctx->engine->keeptmp) |
|
1559 |
+ cli_rmdirs(dir); |
|
1557 | 1560 |
free(dir); |
1558 | 1561 |
return ret; |
1559 | 1562 |
} |
1560 | 1563 |
|
1561 | 1564 |
static int cli_scantar(cli_ctx *ctx, unsigned int posix) |
1562 | 1565 |
{ |
1563 |
- char *dir; |
|
1564 |
- int ret = CL_CLEAN; |
|
1565 |
- |
|
1566 |
+ char *dir; |
|
1567 |
+ int ret = CL_CLEAN; |
|
1566 | 1568 |
|
1567 | 1569 |
cli_dbgmsg("in cli_scantar()\n"); |
1568 | 1570 |
|
1569 | 1571 |
/* generate temporary directory */ |
1570 |
- if(!(dir = cli_gentemp(ctx->engine->tmpdir))) |
|
1571 |
- return CL_EMEM; |
|
1572 |
+ if (!(dir = cli_gentemp(ctx->engine->tmpdir))) |
|
1573 |
+ return CL_EMEM; |
|
1572 | 1574 |
|
1573 |
- if(mkdir(dir, 0700)) { |
|
1574 |
- cli_errmsg("Tar: Can't create temporary directory %s\n", dir); |
|
1575 |
- free(dir); |
|
1576 |
- return CL_ETMPDIR; |
|
1575 |
+ if (mkdir(dir, 0700)) |
|
1576 |
+ { |
|
1577 |
+ cli_errmsg("Tar: Can't create temporary directory %s\n", dir); |
|
1578 |
+ free(dir); |
|
1579 |
+ return CL_ETMPDIR; |
|
1577 | 1580 |
} |
1578 | 1581 |
|
1579 | 1582 |
ret = cli_untar(dir, posix, ctx); |
1580 | 1583 |
|
1581 |
- if(!ctx->engine->keeptmp) |
|
1582 |
- cli_rmdirs(dir); |
|
1584 |
+ if (!ctx->engine->keeptmp) |
|
1585 |
+ cli_rmdirs(dir); |
|
1583 | 1586 |
|
1584 | 1587 |
free(dir); |
1585 | 1588 |
return ret; |
... | ... |
@@ -1587,25 +1796,26 @@ static int cli_scantar(cli_ctx *ctx, unsigned int posix) |
1587 | 1587 |
|
1588 | 1588 |
static int cli_scanscrenc(cli_ctx *ctx) |
1589 | 1589 |
{ |
1590 |
- char *tempname; |
|
1591 |
- int ret = CL_CLEAN; |
|
1590 |
+ char *tempname; |
|
1591 |
+ int ret = CL_CLEAN; |
|
1592 | 1592 |
|
1593 | 1593 |
cli_dbgmsg("in cli_scanscrenc()\n"); |
1594 | 1594 |
|
1595 |
- if(!(tempname = cli_gentemp(ctx->engine->tmpdir))) |
|
1596 |
- return CL_EMEM; |
|
1595 |
+ if (!(tempname = cli_gentemp(ctx->engine->tmpdir))) |
|
1596 |
+ return CL_EMEM; |
|
1597 | 1597 |
|
1598 |
- if(mkdir(tempname, 0700)) { |
|
1599 |
- cli_dbgmsg("CHM: Can't create temporary directory %s\n", tempname); |
|
1600 |
- free(tempname); |
|
1601 |
- return CL_ETMPDIR; |
|
1598 |
+ if (mkdir(tempname, 0700)) |
|
1599 |
+ { |
|
1600 |
+ cli_dbgmsg("CHM: Can't create temporary directory %s\n", tempname); |
|
1601 |
+ free(tempname); |
|
1602 |
+ return CL_ETMPDIR; |
|
1602 | 1603 |
} |
1603 | 1604 |
|
1604 | 1605 |
if (html_screnc_decode(*ctx->fmap, tempname)) |
1605 |
- ret = cli_scandir(tempname, ctx); |
|
1606 |
+ ret = cli_scandir(tempname, ctx); |
|
1606 | 1607 |
|
1607 |
- if(!ctx->engine->keeptmp) |
|
1608 |
- cli_rmdirs(tempname); |
|
1608 |
+ if (!ctx->engine->keeptmp) |
|
1609 |
+ cli_rmdirs(tempname); |
|
1609 | 1610 |
|
1610 | 1611 |
free(tempname); |
1611 | 1612 |
return ret; |
... | ... |
@@ -1616,7 +1826,7 @@ static int cli_scanriff(cli_ctx *ctx) |
1616 | 1616 |
int ret = CL_CLEAN; |
1617 | 1617 |
|
1618 | 1618 |
if (cli_check_riff_exploit(ctx) == 2) |
1619 |
- ret = cli_append_virus(ctx, "Heuristics.Exploit.W32.MS05-002"); |
|
1619 |
+ ret = cli_append_virus(ctx, "Heuristics.Exploit.W32.MS05-002"); |
|
1620 | 1620 |
|
1621 | 1621 |
return ret; |
1622 | 1622 |
} |
... | ... |
@@ -1625,7 +1835,7 @@ static int cli_scanjpeg(cli_ctx *ctx) |
1625 | 1625 |
{ |
1626 | 1626 |
int ret = CL_CLEAN; |
1627 | 1627 |
|
1628 |
- if(cli_check_jpeg_exploit(ctx, 0) == 1) |
|
1628 |
+ if (cli_check_jpeg_exploit(ctx, 0) == 1) |
|
1629 | 1629 |
ret = cli_append_virus(ctx, "Heuristics.Exploit.W32.MS04-028"); |
1630 | 1630 |
|
1631 | 1631 |
return ret; |
... | ... |
@@ -1633,61 +1843,64 @@ static int cli_scanjpeg(cli_ctx *ctx) |
1633 | 1633 |
|
1634 | 1634 |
static int cli_scancryptff(cli_ctx *ctx) |
1635 | 1635 |
{ |
1636 |
- int ret = CL_CLEAN, ndesc; |
|
1637 |
- unsigned int i; |
|
1638 |
- const unsigned char *src; |
|
1639 |
- unsigned char *dest = NULL; |
|
1640 |
- char *tempfile; |
|
1641 |
- size_t pos; |
|
1642 |
- size_t bread; |
|
1643 |
- |
|
1636 |
+ int ret = CL_CLEAN, ndesc; |
|
1637 |
+ unsigned int i; |
|
1638 |
+ const unsigned char *src; |
|
1639 |
+ unsigned char *dest = NULL; |
|
1640 |
+ char *tempfile; |
|
1641 |
+ size_t pos; |
|
1642 |
+ size_t bread; |
|
1644 | 1643 |
|
1645 | 1644 |
/* Skip the CryptFF file header */ |
1646 | 1645 |
pos = 0x10; |
1647 | 1646 |
|
1648 |
- if((dest = (unsigned char *) cli_malloc(FILEBUFF)) == NULL) { |
|
1649 |
- cli_dbgmsg("CryptFF: Can't allocate memory\n"); |
|
1647 |
+ if ((dest = (unsigned char *)cli_malloc(FILEBUFF)) == NULL) |
|
1648 |
+ { |
|
1649 |
+ cli_dbgmsg("CryptFF: Can't allocate memory\n"); |
|
1650 | 1650 |
return CL_EMEM; |
1651 | 1651 |
} |
1652 | 1652 |
|
1653 |
- if(!(tempfile = cli_gentemp(ctx->engine->tmpdir))) { |
|
1654 |
- free(dest); |
|
1655 |
- return CL_EMEM; |
|
1653 |
+ if (!(tempfile = cli_gentemp(ctx->engine->tmpdir))) |
|
1654 |
+ { |
|
1655 |
+ free(dest); |
|
1656 |
+ return CL_EMEM; |
|
1656 | 1657 |
} |
1657 | 1658 |
|
1658 |
- if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) { |
|
1659 |
- cli_errmsg("CryptFF: Can't create file %s\n", tempfile); |
|
1660 |
- free(dest); |
|
1661 |
- free(tempfile); |
|
1662 |
- return CL_ECREAT; |
|
1659 |
+ if ((ndesc = open(tempfile, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, S_IRWXU)) < 0) |
|
1660 |
+ { |
|
1661 |
+ cli_errmsg("CryptFF: Can't create file %s\n", tempfile); |
|
1662 |
+ free(dest); |
|
1663 |
+ free(tempfile); |
|
1664 |
+ return CL_ECREAT; |
|
1663 | 1665 |
} |
1664 | 1666 |
|
1665 |
- for(; (src = fmap_need_off_once_len(*ctx->fmap, pos, FILEBUFF, &bread)) && bread; pos += bread) { |
|
1666 |
- for (i=0;i<bread;i++) |
|
1667 |
- dest[i] = src[i] ^ (unsigned char) 0xff; |
|
1668 |
- if(cli_writen(ndesc, dest, bread) == -1) { |
|
1669 |
- cli_dbgmsg("CryptFF: Can't write to descriptor %d\n", ndesc); |
|
1670 |
- free(dest); |
|
1671 |
- close(ndesc); |
|
1672 |
- free(tempfile); |
|
1673 |
- return CL_EWRITE; |
|
1674 |
- } |
|
1667 |
+ for (; (src = fmap_need_off_once_len(*ctx->fmap, pos, FILEBUFF, &bread)) && bread; pos += bread) |
|
1668 |
+ { |
|
1669 |
+ for (i = 0; i < bread; i++) |
|
1670 |
+ dest[i] = src[i] ^ (unsigned char)0xff; |
|
1671 |
+ if (cli_writen(ndesc, dest, bread) == -1) |
|
1672 |
+ { |
|
1673 |
+ cli_dbgmsg("CryptFF: Can't write to descriptor %d\n", ndesc); |
|
1674 |
+ free(dest); |
|
1675 |
+ close(ndesc); |
|
1676 |
+ free(tempfile); |
|
1677 |
+ return CL_EWRITE; |
|
1678 |
+ } |
|
1675 | 1679 |
} |
1676 | 1680 |
|
1677 | 1681 |
free(dest); |
1678 | 1682 |
|
1679 |
- |
|
1680 | 1683 |
cli_dbgmsg("CryptFF: Scanning decrypted data\n"); |
1681 | 1684 |
|
1682 |
- if((ret = cli_magic_scandesc(ndesc, ctx)) == CL_VIRUS) |
|
1683 |
- cli_dbgmsg("CryptFF: Infected with %s\n", cli_get_last_virus(ctx)); |
|
1685 |
+ if ((ret = cli_magic_scandesc(ndesc, ctx)) == CL_VIRUS) |
|
1686 |
+ cli_dbgmsg("CryptFF: Infected with %s\n", cli_get_last_virus(ctx)); |
|
1684 | 1687 |
|
1685 | 1688 |
close(ndesc); |
1686 | 1689 |
|
1687 |
- if(ctx->engine->keeptmp) |
|
1688 |
- cli_dbgmsg("CryptFF: Decompressed data saved in %s\n", tempfile); |
|
1689 |
- else |
|
1690 |
- if (cli_unlink(tempfile)) ret = CL_EUNLINK; |
|
1690 |
+ if (ctx->engine->keeptmp) |
|
1691 |
+ cli_dbgmsg("CryptFF: Decompressed data saved in %s\n", tempfile); |
|
1692 |
+ else if (cli_unlink(tempfile)) |
|
1693 |
+ ret = CL_EUNLINK; |
|
1691 | 1694 |
|
1692 | 1695 |
free(tempfile); |
1693 | 1696 |
return ret; |
... | ... |
@@ -1695,22 +1908,23 @@ static int cli_scancryptff(cli_ctx *ctx) |
1695 | 1695 |
|
1696 | 1696 |
static int cli_scanpdf(cli_ctx *ctx, off_t offset) |
1697 | 1697 |
{ |
1698 |
- int ret; |
|
1699 |
- char *dir = cli_gentemp(ctx->engine->tmpdir); |
|
1698 |
+ int ret; |
|
1699 |
+ char *dir = cli_gentemp(ctx->engine->tmpdir); |
|
1700 | 1700 |
|
1701 |
- if(!dir) |
|
1702 |
- return CL_EMEM; |
|
1701 |
+ if (!dir) |
|
1702 |
+ return CL_EMEM; |
|
1703 | 1703 |
|
1704 |
- if(mkdir(dir, 0700)) { |
|
1705 |
- cli_dbgmsg("Can't create temporary directory for PDF file %s\n", dir); |
|
1706 |
- free(dir); |
|
1707 |
- return CL_ETMPDIR; |
|
1704 |
+ if (mkdir(dir, 0700)) |
|
1705 |
+ { |
|
1706 |
+ cli_dbgmsg("Can't create temporary directory for PDF file %s\n", dir); |
|
1707 |
+ free(dir); |
|
1708 |
+ return CL_ETMPDIR; |
|
1708 | 1709 |
} |
1709 | 1710 |
|
1710 | 1711 |
ret = cli_pdf(dir, ctx, offset); |
1711 | 1712 |
|
1712 |
- if(!ctx->engine->keeptmp) |
|
1713 |
- cli_rmdirs(dir); |
|
1713 |
+ if (!ctx->engine->keeptmp) |
|
1714 |
+ cli_rmdirs(dir); |
|
1714 | 1715 |
|
1715 | 1716 |
free(dir); |
1716 | 1717 |
return ret; |
... | ... |
@@ -1718,25 +1932,26 @@ static int cli_scanpdf(cli_ctx *ctx, off_t offset) |
1718 | 1718 |
|
1719 | 1719 |
static int cli_scantnef(cli_ctx *ctx) |
1720 | 1720 |
{ |
1721 |
- int ret; |
|
1722 |
- char *dir = cli_gentemp(ctx->engine->tmpdir); |
|
1721 |
+ int ret; |
|
1722 |
+ char *dir = cli_gentemp(ctx->engine->tmpdir); |
|
1723 | 1723 |
|
1724 |
- if(!dir) |
|
1725 |
- return CL_EMEM; |
|
1724 |
+ if (!dir) |
|
1725 |
+ return CL_EMEM; |
|
1726 | 1726 |
|
1727 |
- if(mkdir(dir, 0700)) { |
|
1728 |
- cli_dbgmsg("Can't create temporary directory for tnef file %s\n", dir); |
|
1729 |
- free(dir); |
|
1730 |
- return CL_ETMPDIR; |
|
1727 |
+ if (mkdir(dir, 0700)) |
|
1728 |
+ { |
|
1729 |
+ cli_dbgmsg("Can't create temporary directory for tnef file %s\n", dir); |
|
1730 |
+ free(dir); |
|
1731 |
+ return CL_ETMPDIR; |
|
1731 | 1732 |
} |
1732 | 1733 |
|
1733 | 1734 |
ret = cli_tnef(dir, ctx); |
1734 | 1735 |
|
1735 |
- if(ret == CL_CLEAN) |
|
1736 |
- ret = cli_scandir(dir, ctx); |
|
1736 |
+ if (ret == CL_CLEAN) |
|
1737 |
+ ret = cli_scandir(dir, ctx); |
|
1737 | 1738 |
|
1738 |
- if(!ctx->engine->keeptmp) |
|
1739 |
- cli_rmdirs(dir); |
|
1739 |
+ if (!ctx->engine->keeptmp) |
|
1740 |
+ cli_rmdirs(dir); |
|
1740 | 1741 |
|
1741 | 1742 |
free(dir); |
1742 | 1743 |
return ret; |
... | ... |
@@ -1744,25 +1959,26 @@ static int cli_scantnef(cli_ctx *ctx) |
1744 | 1744 |
|
1745 | 1745 |
static int cli_scanuuencoded(cli_ctx *ctx) |
1746 | 1746 |
{ |
1747 |
- int ret; |
|
1748 |
- char *dir = cli_gentemp(ctx->engine->tmpdir); |
|
1747 |
+ int ret; |
|
1748 |
+ char *dir = cli_gentemp(ctx->engine->tmpdir); |
|
1749 | 1749 |
|
1750 |
- if(!dir) |
|
1751 |
- return CL_EMEM; |
|
1750 |
+ if (!dir) |
|
1751 |
+ return CL_EMEM; |
|
1752 | 1752 |
|
1753 |
- if(mkdir(dir, 0700)) { |
|
1754 |
- cli_dbgmsg("Can't create temporary directory for uuencoded file %s\n", dir); |
|
1755 |
- free(dir); |
|
1756 |
- return CL_ETMPDIR; |
|
1753 |
+ if (mkdir(dir, 0700)) |
|
1754 |
+ { |
|
1755 |
+ cli_dbgmsg("Can't create temporary directory for uuencoded file %s\n", dir); |
|
1756 |
+ free(dir); |
|
1757 |
+ return CL_ETMPDIR; |
|
1757 | 1758 |
} |
1758 | 1759 |
|
1759 | 1760 |
ret = cli_uuencode(dir, *ctx->fmap); |
1760 | 1761 |
|
1761 |
- if(ret == CL_CLEAN) |
|
1762 |
- ret = cli_scandir(dir, ctx); |
|
1762 |
+ if (ret == CL_CLEAN) |
|
1763 |
+ ret = cli_scandir(dir, ctx); |
|
1763 | 1764 |
|
1764 |
- if(!ctx->engine->keeptmp) |
|
1765 |
- cli_rmdirs(dir); |
|
1765 |
+ if (!ctx->engine->keeptmp) |
|
1766 |
+ cli_rmdirs(dir); |
|
1766 | 1767 |
|
1767 | 1768 |
free(dir); |
1768 | 1769 |
return ret; |
... | ... |
@@ -1770,183 +1986,214 @@ static int cli_scanuuencoded(cli_ctx *ctx) |
1770 | 1770 |
|
1771 | 1771 |
static int cli_scanmail(cli_ctx *ctx) |
1772 | 1772 |
{ |
1773 |
- char *dir; |
|
1774 |
- int ret; |
|
1775 |
- unsigned int viruses_found = 0; |
|
1773 |
+ char *dir; |
|
1774 |
+ int ret; |
|
1775 |
+ unsigned int viruses_found = 0; |
|
1776 | 1776 |
|
1777 | 1777 |
cli_dbgmsg("Starting cli_scanmail(), recursion = %u\n", ctx->recursion); |
1778 | 1778 |
|
1779 | 1779 |
/* generate the temporary directory */ |
1780 |
- if(!(dir = cli_gentemp(ctx->engine->tmpdir))) |
|
1781 |
- return CL_EMEM; |
|
1780 |
+ if (!(dir = cli_gentemp(ctx->engine->tmpdir))) |
|
1781 |
+ return CL_EMEM; |
|
1782 | 1782 |
|
1783 |
- if(mkdir(dir, 0700)) { |
|
1784 |
- cli_dbgmsg("Mail: Can't create temporary directory %s\n", dir); |
|
1785 |
- free(dir); |
|
1786 |
- return CL_ETMPDIR; |
|
1783 |
+ if (mkdir(dir, 0700)) |
|
1784 |
+ { |
|
1785 |
+ cli_dbgmsg("Mail: Can't create temporary directory %s\n", dir); |
|
1786 |
+ free(dir); |
|
1787 |
+ return CL_ETMPDIR; |
|
1787 | 1788 |
} |
1788 | 1789 |
|
1789 | 1790 |
/* |
1790 | 1791 |
* Extract the attachments into the temporary directory |
1791 | 1792 |
*/ |
1792 |
- if((ret = cli_mbox(dir, ctx))) { |
|
1793 |
- if (ret == CL_VIRUS && SCAN_ALL) |
|
1794 |
- viruses_found++; |
|
1795 |
- else { |
|
1796 |
- if(!ctx->engine->keeptmp) |
|
1797 |
- cli_rmdirs(dir); |
|
1798 |
- free(dir); |
|
1799 |
- return ret; |
|
1800 |
- } |
|
1793 |
+ if ((ret = cli_mbox(dir, ctx))) |
|
1794 |
+ { |
|
1795 |
+ if (ret == CL_VIRUS && SCAN_ALL) |
|
1796 |
+ viruses_found++; |
|
1797 |
+ else |
|
1798 |
+ { |
|
1799 |
+ if (!ctx->engine->keeptmp) |
|
1800 |
+ cli_rmdirs(dir); |
|
1801 |
+ free(dir); |
|
1802 |
+ return ret; |
|
1803 |
+ } |
|
1801 | 1804 |
} |
1802 | 1805 |
|
1803 | 1806 |
ret = cli_scandir(dir, ctx); |
1804 | 1807 |
|
1805 |
- if(!ctx->engine->keeptmp) |
|
1806 |
- cli_rmdirs(dir); |
|
1808 |
+ if (!ctx->engine->keeptmp) |
|
1809 |
+ cli_rmdirs(dir); |
|
1807 | 1810 |
|
1808 | 1811 |
free(dir); |
1809 | 1812 |
if (viruses_found) |
1810 |
- return CL_VIRUS; |
|
1813 |
+ return CL_VIRUS; |
|
1811 | 1814 |
return ret; |
1812 | 1815 |
} |
1813 | 1816 |
|
1814 | 1817 |
static int cli_scan_structured(cli_ctx *ctx) |
1815 | 1818 |
{ |
1816 |
- char buf[8192]; |
|
1817 |
- int result = 0; |
|
1818 |
- unsigned int cc_count = 0; |
|
1819 |
- unsigned int ssn_count = 0; |
|
1820 |
- int done = 0; |
|
1821 |
- fmap_t *map; |
|
1822 |
- size_t pos = 0; |
|
1823 |
- int (*ccfunc)(const unsigned char *buffer, int length); |
|
1824 |
- int (*ssnfunc)(const unsigned char *buffer, int length); |
|
1825 |
- unsigned int viruses_found = 0; |
|
1826 |
- |
|
1827 |
- if(ctx == NULL) |
|
1828 |
- return CL_ENULLARG; |
|
1819 |
+ char buf[8192]; |
|
1820 |
+ int result = 0; |
|
1821 |
+ unsigned int cc_count = 0; |
|
1822 |
+ unsigned int ssn_count = 0; |
|
1823 |
+ int done = 0; |
|
1824 |
+ fmap_t *map; |
|
1825 |
+ size_t pos = 0; |
|
1826 |
+ int (*ccfunc)(const unsigned char *buffer, int length); |
|
1827 |
+ int (*ssnfunc)(const unsigned char *buffer, int length); |
|
1828 |
+ unsigned int viruses_found = 0; |
|
1829 |
+ |
|
1830 |
+ if (ctx == NULL) |
|
1831 |
+ return CL_ENULLARG; |
|
1829 | 1832 |
|
1830 | 1833 |
map = *ctx->fmap; |
1831 | 1834 |
|
1832 |
- if(ctx->engine->min_cc_count == 1) |
|
1833 |
- ccfunc = dlp_has_cc; |
|
1835 |
+ if (ctx->engine->min_cc_count == 1) |
|
1836 |
+ ccfunc = dlp_has_cc; |
|
1834 | 1837 |
else |
1835 |
- ccfunc = dlp_get_cc_count; |
|
1838 |
+ ccfunc = dlp_get_cc_count; |
|
1836 | 1839 |
|
1837 |
- switch((ctx->options & CL_SCAN_STRUCTURED_SSN_NORMAL) | (ctx->options & CL_SCAN_STRUCTURED_SSN_STRIPPED)) { |
|
1840 |
+ switch ((ctx->options & CL_SCAN_STRUCTURED_SSN_NORMAL) | (ctx->options & CL_SCAN_STRUCTURED_SSN_STRIPPED)) |
|
1841 |
+ { |
|
1838 | 1842 |
|
1839 |
- case (CL_SCAN_STRUCTURED_SSN_NORMAL | CL_SCAN_STRUCTURED_SSN_STRIPPED): |
|
1840 |
- if(ctx->engine->min_ssn_count == 1) |
|
1841 |
- ssnfunc = dlp_has_ssn; |
|
1842 |
- else |
|
1843 |
- ssnfunc = dlp_get_ssn_count; |
|
1844 |
- break; |
|
1843 |
+ case (CL_SCAN_STRUCTURED_SSN_NORMAL | CL_SCAN_STRUCTURED_SSN_STRIPPED): |
|
1844 |
+ if (ctx->engine->min_ssn_count == 1) |
|
1845 |
+ ssnfunc = dlp_has_ssn; |
|
1846 |
+ else |
|
1847 |
+ ssnfunc = dlp_get_ssn_count; |
|
1848 |
+ break; |
|
1845 | 1849 |
|
1846 |
- case CL_SCAN_STRUCTURED_SSN_NORMAL: |
|
1847 |
- if(ctx->engine->min_ssn_count == 1) |
|
1848 |
- ssnfunc = dlp_has_normal_ssn; |
|
1849 |
- else |
|
1850 |
- ssnfunc = dlp_get_normal_ssn_count; |
|
1851 |
- break; |
|
1850 |
+ case CL_SCAN_STRUCTURED_SSN_NORMAL: |
|
1851 |
+ if (ctx->engine->min_ssn_count == 1) |
|
1852 |
+ ssnfunc = dlp_has_normal_ssn; |
|
1853 |
+ else |
|
1854 |
+ ssnfunc = dlp_get_normal_ssn_count; |
|
1855 |
+ break; |
|
1852 | 1856 |
|
1853 |
- case CL_SCAN_STRUCTURED_SSN_STRIPPED: |
|
1854 |
- if(ctx->engine->min_ssn_count == 1) |
|
1855 |
- ssnfunc = dlp_has_stripped_ssn; |
|
1856 |
- else |
|
1857 |
- ssnfunc = dlp_get_stripped_ssn_count; |
|
1858 |
- break; |
|
1857 |
+ case CL_SCAN_STRUCTURED_SSN_STRIPPED: |
|
1858 |
+ if (ctx->engine->min_ssn_count == 1) |
|
1859 |
+ ssnfunc = dlp_has_stripped_ssn; |
|
1860 |
+ else |
|
1861 |
+ ssnfunc = dlp_get_stripped_ssn_count; |
|
1862 |
+ break; |
|
1859 | 1863 |
|
1860 |
- default: |
|
1861 |
- ssnfunc = NULL; |
|
1864 |
+ default: |
|
1865 |
+ ssnfunc = NULL; |
|
1862 | 1866 |
} |
1863 | 1867 |
|
1864 |
- while(!done && ((result = fmap_readn(map, buf, pos, 8191)) > 0)) { |
|
1865 |
- pos += result; |
|
1866 |
- if((cc_count += ccfunc((const unsigned char *)buf, result)) >= ctx->engine->min_cc_count) |
|
1867 |
- done = 1; |
|
1868 |
+ while (!done && ((result = fmap_readn(map, buf, pos, 8191)) > 0)) |
|
1869 |
+ { |
|
1870 |
+ pos += result; |
|
1871 |
+ if ((cc_count += ccfunc((const unsigned char *)buf, result)) >= ctx->engine->min_cc_count) |
|
1872 |
+ { |
|
1873 |
+ done = 1; |
|
1874 |
+ } |
|
1868 | 1875 |
|
1869 |
- if(ssnfunc && ((ssn_count += ssnfunc((const unsigned char *)buf, result)) >= ctx->engine->min_ssn_count)) |
|
1870 |
- done = 1; |
|
1876 |
+ if (ssnfunc && ((ssn_count += ssnfunc((const unsigned char *)buf, result)) >= ctx->engine->min_ssn_count)) |
|
1877 |
+ { |
|
1878 |
+ done = 1; |
|
1879 |
+ } |
|
1871 | 1880 |
} |
1872 | 1881 |
|
1873 |
- if(cc_count != 0 && cc_count >= ctx->engine->min_cc_count) { |
|
1874 |
- cli_dbgmsg("cli_scan_structured: %u credit card numbers detected\n", cc_count); |
|
1875 |
- if (CL_VIRUS == cli_append_virus(ctx,"Heuristics.Structured.CreditCardNumber")) |
|
1882 |
+ if (cc_count != 0 && cc_count >= ctx->engine->min_cc_count) |
|
1883 |
+ { |
|
1884 |
+ cli_dbgmsg("cli_scan_structured: %u credit card numbers detected\n", cc_count); |
|
1885 |
+ if (CL_VIRUS == cli_append_virus(ctx, "Heuristics.Structured.CreditCardNumber")) |
|
1886 |
+ { |
|
1876 | 1887 |
if (SCAN_ALL) |
1888 |
+ { |
|
1877 | 1889 |
viruses_found++; |
1890 |
+ } |
|
1878 | 1891 |
else |
1892 |
+ { |
|
1879 | 1893 |
return CL_VIRUS; |
1894 |
+ } |
|
1895 |
+ } |
|
1880 | 1896 |
} |
1881 | 1897 |
|
1882 |
- if(ssn_count != 0 && ssn_count >= ctx->engine->min_ssn_count) { |
|
1883 |
- cli_dbgmsg("cli_scan_structured: %u social security numbers detected\n", ssn_count); |
|
1884 |
- if (CL_VIRUS == cli_append_virus(ctx,"Heuristics.Structured.SSN")) |
|
1898 |
+ if (ssn_count != 0 && ssn_count >= ctx->engine->min_ssn_count) |
|
1899 |
+ { |
|
1900 |
+ cli_dbgmsg("cli_scan_structured: %u social security numbers detected\n", ssn_count); |
|
1901 |
+ if (CL_VIRUS == cli_append_virus(ctx, "Heuristics.Structured.SSN")) |
|
1902 |
+ { |
|
1885 | 1903 |
if (SCAN_ALL) |
1904 |
+ { |
|
1886 | 1905 |
viruses_found++; |
1906 |
+ } |
|
1887 | 1907 |
else |
1908 |
+ { |
|
1888 | 1909 |
return CL_VIRUS; |
1910 |
+ } |
|
1911 |
+ } |
|
1889 | 1912 |
} |
1890 | 1913 |
|
1891 | 1914 |
if (viruses_found) |
1892 |
- return CL_VIRUS; |
|
1915 |
+ return CL_VIRUS; |
|
1893 | 1916 |
return CL_CLEAN; |
1894 | 1917 |
} |
1895 | 1918 |
|
1896 | 1919 |
static int cli_scanembpe(cli_ctx *ctx, off_t offset) |
1897 | 1920 |
{ |
1898 |
- int fd, bytes, ret = CL_CLEAN; |
|
1899 |
- unsigned long int size = 0, todo; |
|
1900 |
- const char *buff; |
|
1901 |
- char *tmpname; |
|
1902 |
- fmap_t *map = *ctx->fmap; |
|
1903 |
- unsigned int corrupted_input; |
|
1921 |
+ int fd, bytes, ret = CL_CLEAN; |
|
1922 |
+ unsigned long int size = 0, todo; |
|
1923 |
+ const char *buff; |
|
1924 |
+ char *tmpname; |
|
1925 |
+ fmap_t *map = *ctx->fmap; |
|
1926 |
+ unsigned int corrupted_input; |
|
1904 | 1927 |
|
1905 | 1928 |
tmpname = cli_gentemp(ctx->engine->tmpdir); |
1906 |
- if(!tmpname) |
|
1907 |
- return CL_EMEM; |
|
1929 |
+ if (!tmpname) |
|
1930 |
+ return CL_EMEM; |
|
1908 | 1931 |
|
1909 |
- if((fd = open(tmpname, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) { |
|
1910 |
- cli_errmsg("cli_scanembpe: Can't create file %s\n", tmpname); |
|
1911 |
- free(tmpname); |
|
1912 |
- return CL_ECREAT; |
|
1932 |
+ if ((fd = open(tmpname, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, S_IRWXU)) < 0) |
|
1933 |
+ { |
|
1934 |
+ cli_errmsg("cli_scanembpe: Can't create file %s\n", tmpname); |
|
1935 |
+ free(tmpname); |
|
1936 |
+ return CL_ECREAT; |
|
1913 | 1937 |
} |
1914 | 1938 |
|
1915 | 1939 |
todo = map->len - offset; |
1916 |
- while(1) { |
|
1917 |
- bytes = MIN(todo, map->pgsz); |
|
1918 |
- if(!bytes) |
|
1919 |
- break; |
|
1920 |
- |
|
1921 |
- if(!(buff = fmap_need_off_once(map, offset + size, bytes))) { |
|
1922 |
- close(fd); |
|
1923 |
- if(!ctx->engine->keeptmp) { |
|
1924 |
- if (cli_unlink(tmpname)) { |
|
1925 |
- free(tmpname); |
|
1926 |
- return CL_EUNLINK; |
|
1927 |
- } |
|
1928 |
- } |
|
1929 |
- free(tmpname); |
|
1930 |
- return CL_EREAD; |
|
1931 |
- } |
|
1932 |
- size += bytes; |
|
1933 |
- todo -= bytes; |
|
1934 |
- |
|
1935 |
- if(cli_checklimits("cli_scanembpe", ctx, size, 0, 0)!=CL_CLEAN) |
|
1936 |
- break; |
|
1937 |
- |
|
1938 |
- if(cli_writen(fd, buff, bytes) != bytes) { |
|
1939 |
- cli_dbgmsg("cli_scanembpe: Can't write to temporary file\n"); |
|
1940 |
- close(fd); |
|
1941 |
- if(!ctx->engine->keeptmp) { |
|
1942 |
- if (cli_unlink(tmpname)) { |
|
1943 |
- free(tmpname); |
|
1944 |
- return CL_EUNLINK; |
|
1945 |
- } |
|
1946 |
- } |
|
1947 |
- free(tmpname); |
|
1948 |
- return CL_EWRITE; |
|
1949 |
- } |
|
1940 |
+ while (1) |
|
1941 |
+ { |
|
1942 |
+ bytes = MIN(todo, map->pgsz); |
|
1943 |
+ if (!bytes) |
|
1944 |
+ break; |
|
1945 |
+ |
|
1946 |
+ if (!(buff = fmap_need_off_once(map, offset + size, bytes))) |
|
1947 |
+ { |
|
1948 |
+ close(fd); |
|
1949 |
+ if (!ctx->engine->keeptmp) |
|
1950 |
+ { |
|
1951 |
+ if (cli_unlink(tmpname)) |
|
1952 |
+ { |
|
1953 |
+ free(tmpname); |
|
1954 |
+ return CL_EUNLINK; |
|
1955 |
+ } |
|
1956 |
+ } |
|
1957 |
+ free(tmpname); |
|
1958 |
+ return CL_EREAD; |
|
1959 |
+ } |
|
1960 |
+ size += bytes; |
|
1961 |
+ todo -= bytes; |
|
1962 |
+ |
|
1963 |
+ if (cli_checklimits("cli_scanembpe", ctx, size, 0, 0) != CL_CLEAN) |
|
1964 |
+ break; |
|
1965 |
+ |
|
1966 |
+ if (cli_writen(fd, buff, bytes) != bytes) |
|
1967 |
+ { |
|
1968 |
+ cli_dbgmsg("cli_scanembpe: Can't write to temporary file\n"); |
|
1969 |
+ close(fd); |
|
1970 |
+ if (!ctx->engine->keeptmp) |
|
1971 |
+ { |
|
1972 |
+ if (cli_unlink(tmpname)) |
|
1973 |
+ { |
|
1974 |
+ free(tmpname); |
|
1975 |
+ return CL_EUNLINK; |
|
1976 |
+ } |
|
1977 |
+ } |
|
1978 |
+ free(tmpname); |
|
1979 |
+ return CL_EWRITE; |
|
1980 |
+ } |
|
1950 | 1981 |
} |
1951 | 1982 |
|
1952 | 1983 |
ctx->recursion++; |
... | ... |
@@ -1954,26 +2201,31 @@ static int cli_scanembpe(cli_ctx *ctx, off_t offset) |
1954 | 1954 |
ctx->corrupted_input = 1; |
1955 | 1955 |
ret = cli_magic_scandesc(fd, ctx); |
1956 | 1956 |
ctx->corrupted_input = corrupted_input; |
1957 |
- if(ret == CL_VIRUS) { |
|
1958 |
- cli_dbgmsg("cli_scanembpe: Infected with %s\n", cli_get_last_virus(ctx)); |
|
1959 |
- close(fd); |
|
1960 |
- if(!ctx->engine->keeptmp) { |
|
1961 |
- if (cli_unlink(tmpname)) { |
|
1962 |
- free(tmpname); |
|
1963 |
- return CL_EUNLINK; |
|
1964 |
- } |
|
1965 |
- } |
|
1966 |
- free(tmpname); |
|
1967 |
- return CL_VIRUS; |
|
1957 |
+ if (ret == CL_VIRUS) |
|
1958 |
+ { |
|
1959 |
+ cli_dbgmsg("cli_scanembpe: Infected with %s\n", cli_get_last_virus(ctx)); |
|
1960 |
+ close(fd); |
|
1961 |
+ if (!ctx->engine->keeptmp) |
|
1962 |
+ { |
|
1963 |
+ if (cli_unlink(tmpname)) |
|
1964 |
+ { |
|
1965 |
+ free(tmpname); |
|
1966 |
+ return CL_EUNLINK; |
|
1967 |
+ } |
|
1968 |
+ } |
|
1969 |
+ free(tmpname); |
|
1970 |
+ return CL_VIRUS; |
|
1968 | 1971 |
} |
1969 | 1972 |
ctx->recursion--; |
1970 | 1973 |
|
1971 | 1974 |
close(fd); |
1972 |
- if(!ctx->engine->keeptmp) { |
|
1973 |
- if (cli_unlink(tmpname)) { |
|
1974 |
- free(tmpname); |
|
1975 |
- return CL_EUNLINK; |
|
1976 |
- } |
|
1975 |
+ if (!ctx->engine->keeptmp) |
|
1976 |
+ { |
|
1977 |
+ if (cli_unlink(tmpname)) |
|
1978 |
+ { |
|
1979 |
+ free(tmpname); |
|
1980 |
+ return CL_EUNLINK; |
|
1981 |
+ } |
|
1977 | 1982 |
} |
1978 | 1983 |
free(tmpname); |
1979 | 1984 |
|
... | ... |
@@ -1981,14 +2233,14 @@ static int cli_scanembpe(cli_ctx *ctx, off_t offset) |
1981 | 1981 |
return CL_CLEAN; |
1982 | 1982 |
} |
1983 | 1983 |
|
1984 |
- |
|
1985 | 1984 |
#if defined(_WIN32) || defined(C_LINUX) |
1986 | 1985 |
#define PERF_MEASURE |
1987 | 1986 |
#endif |
1988 | 1987 |
|
1989 | 1988 |
#ifdef PERF_MEASURE |
1990 | 1989 |
|
1991 |
-static struct { |
|
1990 |
+static struct |
|
1991 |
+{ |
|
1992 | 1992 |
enum perfev id; |
1993 | 1993 |
const char *name; |
1994 | 1994 |
enum ev_type type; |
... | ... |
@@ -2004,19 +2256,19 @@ static struct { |
2004 | 2004 |
{PERFT_RAW, "raw", ev_time}, |
2005 | 2005 |
{PERFT_RAWTYPENO, "raw container", ev_time}, |
2006 | 2006 |
{PERFT_MAP, "map", ev_time}, |
2007 |
- {PERFT_BYTECODE,"bytecode", ev_time}, |
|
2008 |
- {PERFT_KTIME,"kernel", ev_int}, |
|
2009 |
- {PERFT_UTIME,"user", ev_int} |
|
2010 |
-}; |
|
2007 |
+ {PERFT_BYTECODE, "bytecode", ev_time}, |
|
2008 |
+ {PERFT_KTIME, "kernel", ev_int}, |
|
2009 |
+ {PERFT_UTIME, "user", ev_int}}; |
|
2011 | 2010 |
|
2012 | 2011 |
static void get_thread_times(uint64_t *kt, uint64_t *ut) |
2013 | 2012 |
{ |
2014 | 2013 |
#ifdef _WIN32 |
2015 |
- FILETIME c,e,k,u; |
|
2016 |
- ULARGE_INTEGER kl,ul; |
|
2017 |
- if (!GetThreadTimes(GetCurrentThread(), &c, &e, &k, &u)) { |
|
2018 |
- *kt = *ut = 0; |
|
2019 |
- return; |
|
2014 |
+ FILETIME c, e, k, u; |
|
2015 |
+ ULARGE_INTEGER kl, ul; |
|
2016 |
+ if (!GetThreadTimes(GetCurrentThread(), &c, &e, &k, &u)) |
|
2017 |
+ { |
|
2018 |
+ *kt = *ut = 0; |
|
2019 |
+ return; |
|
2020 | 2020 |
} |
2021 | 2021 |
kl.LowPart = k.dwLowDateTime; |
2022 | 2022 |
kl.HighPart = k.dwHighDateTime; |
... | ... |
@@ -2026,29 +2278,33 @@ static void get_thread_times(uint64_t *kt, uint64_t *ut) |
2026 | 2026 |
*ut = ul.QuadPart / 10; |
2027 | 2027 |
#else |
2028 | 2028 |
struct tms tbuf; |
2029 |
- if (times(&tbuf) != -1) { |
|
2030 |
- clock_t tck = sysconf(_SC_CLK_TCK); |
|
2031 |
- *kt = ((uint64_t)1000000)*tbuf.tms_stime / tck; |
|
2032 |
- *ut = ((uint64_t)1000000)*tbuf.tms_utime / tck; |
|
2033 |
- } else { |
|
2034 |
- *kt = *ut = 0; |
|
2029 |
+ if (times(&tbuf) != -1) |
|
2030 |
+ { |
|
2031 |
+ clock_t tck = sysconf(_SC_CLK_TCK); |
|
2032 |
+ *kt = ((uint64_t)1000000) * tbuf.tms_stime / tck; |
|
2033 |
+ *ut = ((uint64_t)1000000) * tbuf.tms_utime / tck; |
|
2034 |
+ } |
|
2035 |
+ else |
|
2036 |
+ { |
|
2037 |
+ *kt = *ut = 0; |
|
2035 | 2038 |
} |
2036 | 2039 |
#endif |
2037 | 2040 |
} |
2038 | 2041 |
|
2039 | 2042 |
static inline void perf_init(cli_ctx *ctx) |
2040 | 2043 |
{ |
2041 |
- uint64_t kt,ut; |
|
2044 |
+ uint64_t kt, ut; |
|
2042 | 2045 |
unsigned i; |
2043 | 2046 |
|
2044 | 2047 |
if (!(ctx->options & CL_SCAN_PERFORMANCE_INFO)) |
2045 |
- return; |
|
2048 |
+ return; |
|
2046 | 2049 |
|
2047 | 2050 |
ctx->perf = cli_events_new(PERFT_LAST); |
2048 |
- for (i=0;i<sizeof(perf_events)/sizeof(perf_events[0]);i++) { |
|
2049 |
- if (cli_event_define(ctx->perf, perf_events[i].id, perf_events[i].name, |
|
2050 |
- perf_events[i].type, multiple_sum) == -1) |
|
2051 |
- continue; |
|
2051 |
+ for (i = 0; i < sizeof(perf_events) / sizeof(perf_events[0]); i++) |
|
2052 |
+ { |
|
2053 |
+ if (cli_event_define(ctx->perf, perf_events[i].id, perf_events[i].name, |
|
2054 |
+ perf_events[i].type, multiple_sum) == -1) |
|
2055 |
+ continue; |
|
2052 | 2056 |
} |
2053 | 2057 |
cli_event_time_start(ctx->perf, PERFT_SCAN); |
2054 | 2058 |
get_thread_times(&kt, &ut); |
... | ... |
@@ -2056,17 +2312,17 @@ static inline void perf_init(cli_ctx *ctx) |
2056 | 2056 |
cli_event_int(ctx->perf, PERFT_UTIME, -ut); |
2057 | 2057 |
} |
2058 | 2058 |
|
2059 |
-static inline void perf_done(cli_ctx* ctx) |
|
2059 |
+static inline void perf_done(cli_ctx *ctx) |
|
2060 | 2060 |
{ |
2061 | 2061 |
char timestr[512]; |
2062 | 2062 |
char *p; |
2063 | 2063 |
unsigned i; |
2064 |
- uint64_t kt,ut; |
|
2064 |
+ uint64_t kt, ut; |
|
2065 | 2065 |
char *pend; |
2066 | 2066 |
cli_events_t *perf = ctx->perf; |
2067 | 2067 |
|
2068 | 2068 |
if (!perf) |
2069 |
- return; |
|
2069 |
+ return; |
|
2070 | 2070 |
|
2071 | 2071 |
p = timestr; |
2072 | 2072 |
pend = timestr + sizeof(timestr) - 1; |
... | ... |
@@ -2077,129 +2333,160 @@ static inline void perf_done(cli_ctx* ctx) |
2077 | 2077 |
cli_event_int(perf, PERFT_KTIME, kt); |
2078 | 2078 |
cli_event_int(perf, PERFT_UTIME, ut); |
2079 | 2079 |
|
2080 |
- for (i=0;i<sizeof(perf_events)/sizeof(perf_events[0]);i++) { |
|
2081 |
- union ev_val val; |
|
2082 |
- unsigned count; |
|
2080 |
+ for (i = 0; i < sizeof(perf_events) / sizeof(perf_events[0]); i++) |
|
2081 |
+ { |
|
2082 |
+ union ev_val val; |
|
2083 |
+ unsigned count; |
|
2083 | 2084 |
|
2084 |
- cli_event_get(perf, perf_events[i].id, &val, &count); |
|
2085 |
- if (p < pend) |
|
2086 |
- p += snprintf(p, pend - p, "%s: %d.%03ums, ", perf_events[i].name, |
|
2087 |
- (signed)(val.v_int / 1000), |
|
2088 |
- (unsigned)(val.v_int % 1000)); |
|
2085 |
+ cli_event_get(perf, perf_events[i].id, &val, &count); |
|
2086 |
+ if (p < pend) |
|
2087 |
+ p += snprintf(p, pend - p, "%s: %d.%03ums, ", perf_events[i].name, |
|
2088 |
+ (signed)(val.v_int / 1000), |
|
2089 |
+ (unsigned)(val.v_int % 1000)); |
|
2089 | 2090 |
} |
2090 | 2091 |
*p = 0; |
2091 | 2092 |
cli_infomsg(ctx, "performance: %s\n", timestr); |
2092 | 2093 |
|
2093 |
- |
|
2094 | 2094 |
cli_events_free(perf); |
2095 | 2095 |
ctx->perf = NULL; |
2096 | 2096 |
} |
2097 | 2097 |
|
2098 |
-static inline void perf_start(cli_ctx* ctx, int id) |
|
2098 |
+static inline void perf_start(cli_ctx *ctx, int id) |
|
2099 | 2099 |
{ |
2100 | 2100 |
cli_event_time_start(ctx->perf, id); |
2101 | 2101 |
} |
2102 | 2102 |
|
2103 |
-static inline void perf_stop(cli_ctx* ctx, int id) |
|
2103 |
+static inline void perf_stop(cli_ctx *ctx, int id) |
|
2104 | 2104 |
{ |
2105 | 2105 |
cli_event_time_stop(ctx->perf, id); |
2106 | 2106 |
} |
2107 | 2107 |
|
2108 |
-static inline void perf_nested_start(cli_ctx* ctx, int id, int nestedid) |
|
2108 |
+static inline void perf_nested_start(cli_ctx *ctx, int id, int nestedid) |
|
2109 | 2109 |
{ |
2110 | 2110 |
cli_event_time_nested_start(ctx->perf, id, nestedid); |
2111 | 2111 |
} |
2112 | 2112 |
|
2113 |
-static inline void perf_nested_stop(cli_ctx* ctx, int id, int nestedid) |
|
2113 |
+static inline void perf_nested_stop(cli_ctx *ctx, int id, int nestedid) |
|
2114 | 2114 |
{ |
2115 | 2115 |
cli_event_time_nested_stop(ctx->perf, id, nestedid); |
2116 | 2116 |
} |
2117 | 2117 |
|
2118 |
- |
|
2119 | 2118 |
#else |
2120 |
-static inline void perf_init(cli_ctx* ctx) { UNUSEDPARAM(ctx); } |
|
2121 |
-static inline void perf_start(cli_ctx* ctx, int id){ UNUSEDPARAM(ctx); UNUSEDPARAM(id); } |
|
2122 |
-static inline void perf_stop(cli_ctx* ctx, int id){ UNUSEDPARAM(ctx); UNUSEDPARAM(id); } |
|
2123 |
-static inline void perf_nested_start(cli_ctx* ctx, int id, int nestedid){ UNUSEDPARAM(ctx); UNUSEDPARAM(id); UNUSEDPARAM(nestedid); } |
|
2124 |
-static inline void perf_nested_stop(cli_ctx* ctx, int id, int nestedid){ UNUSEDPARAM(ctx); UNUSEDPARAM(id); UNUSEDPARAM(nestedid); } |
|
2125 |
-static inline void perf_done(cli_ctx* ctx){ UNUSEDPARAM(ctx); } |
|
2119 |
+static inline void perf_init(cli_ctx *ctx) |
|
2120 |
+{ |
|
2121 |
+ UNUSEDPARAM(ctx); |
|
2122 |
+} |
|
2123 |
+static inline void perf_start(cli_ctx *ctx, int id) |
|
2124 |
+{ |
|
2125 |
+ UNUSEDPARAM(ctx); |
|
2126 |
+ UNUSEDPARAM(id); |
|
2127 |
+} |
|
2128 |
+static inline void perf_stop(cli_ctx *ctx, int id) |
|
2129 |
+{ |
|
2130 |
+ UNUSEDPARAM(ctx); |
|
2131 |
+ UNUSEDPARAM(id); |
|
2132 |
+} |
|
2133 |
+static inline void perf_nested_start(cli_ctx *ctx, int id, int nestedid) |
|
2134 |
+{ |
|
2135 |
+ UNUSEDPARAM(ctx); |
|
2136 |
+ UNUSEDPARAM(id); |
|
2137 |
+ UNUSEDPARAM(nestedid); |
|
2138 |
+} |
|
2139 |
+static inline void perf_nested_stop(cli_ctx *ctx, int id, int nestedid) |
|
2140 |
+{ |
|
2141 |
+ UNUSEDPARAM(ctx); |
|
2142 |
+ UNUSEDPARAM(id); |
|
2143 |
+ UNUSEDPARAM(nestedid); |
|
2144 |
+} |
|
2145 |
+static inline void perf_done(cli_ctx *ctx) { UNUSEDPARAM(ctx); } |
|
2126 | 2146 |
#endif |
2127 | 2147 |
|
2128 |
- |
|
2129 | 2148 |
static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_t *dettype, unsigned char *refhash) |
2130 | 2149 |
{ |
2131 |
- int ret = CL_CLEAN, nret = CL_CLEAN; |
|
2132 |
- struct cli_matched_type *ftoffset = NULL, *fpt; |
|
2133 |
- uint32_t lastrar; |
|
2134 |
- struct cli_exe_info peinfo; |
|
2135 |
- unsigned int acmode = AC_SCAN_VIR, break_loop = 0; |
|
2136 |
- fmap_t *map = *ctx->fmap; |
|
2137 |
- |
|
2150 |
+ int ret = CL_CLEAN, nret = CL_CLEAN; |
|
2151 |
+ struct cli_matched_type *ftoffset = NULL, *fpt; |
|
2152 |
+ uint32_t lastrar; |
|
2153 |
+ struct cli_exe_info peinfo; |
|
2154 |
+ unsigned int acmode = AC_SCAN_VIR, break_loop = 0; |
|
2155 |
+ fmap_t *map = *ctx->fmap; |
|
2138 | 2156 |
|
2139 |
- if(ctx->engine->maxreclevel && ctx->recursion >= ctx->engine->maxreclevel) { |
|
2157 |
+ if (ctx->engine->maxreclevel && ctx->recursion >= ctx->engine->maxreclevel) |
|
2158 |
+ { |
|
2140 | 2159 |
cli_check_blockmax(ctx, CL_EMAXREC); |
2141 | 2160 |
return CL_EMAXREC; |
2142 | 2161 |
} |
2143 | 2162 |
|
2144 | 2163 |
perf_start(ctx, PERFT_RAW); |
2145 |
- if(typercg) |
|
2146 |
- acmode |= AC_SCAN_FT; |
|
2164 |
+ if (typercg) |
|
2165 |
+ acmode |= AC_SCAN_FT; |
|
2147 | 2166 |
|
2148 | 2167 |
ret = cli_fmap_scandesc(ctx, type == CL_TYPE_TEXT_ASCII ? 0 : type, 0, &ftoffset, acmode, NULL, refhash); |
2149 | 2168 |
perf_stop(ctx, PERFT_RAW); |
2150 | 2169 |
|
2151 |
- if(ret >= CL_TYPENO) { |
|
2152 |
- perf_nested_start(ctx, PERFT_RAWTYPENO, PERFT_SCAN); |
|
2153 |
- ctx->recursion++; |
|
2170 |
+ if (ret >= CL_TYPENO) |
|
2171 |
+ { |
|
2172 |
+ perf_nested_start(ctx, PERFT_RAWTYPENO, PERFT_SCAN); |
|
2173 |
+ ctx->recursion++; |
|
2154 | 2174 |
lastrar = 0xdeadbeef; |
2155 | 2175 |
fpt = ftoffset; |
2156 | 2176 |
|
2157 |
- while(fpt) { |
|
2177 |
+ while (fpt) |
|
2178 |
+ { |
|
2158 | 2179 |
/* set current level as container AFTER recursing */ |
2159 | 2180 |
cli_set_container(ctx, fpt->type, map->len); |
2160 |
- if(fpt->offset) switch(fpt->type) { |
|
2181 |
+ if (fpt->offset) |
|
2182 |
+ switch (fpt->type) |
|
2183 |
+ { |
|
2161 | 2184 |
case CL_TYPE_MHTML: |
2162 |
- if(SCAN_MAIL && (DCONF_MAIL & MAIL_CONF_MBOX)) { |
|
2163 |
- cli_dbgmsg("MHTML signature found at %u\n", (unsigned int) fpt->offset); |
|
2185 |
+ if (SCAN_MAIL && (DCONF_MAIL & MAIL_CONF_MBOX)) |
|
2186 |
+ { |
|
2187 |
+ cli_dbgmsg("MHTML signature found at %u\n", (unsigned int)fpt->offset); |
|
2164 | 2188 |
nret = ret = cli_scanmail(ctx); |
2165 | 2189 |
} |
2166 | 2190 |
break; |
2167 | 2191 |
|
2168 | 2192 |
case CL_TYPE_XDP: |
2169 |
- if(SCAN_PDF && (DCONF_DOC & DOC_CONF_PDF)) { |
|
2170 |
- cli_dbgmsg("XDP signature found at %u\n", (unsigned int) fpt->offset); |
|
2193 |
+ if (SCAN_PDF && (DCONF_DOC & DOC_CONF_PDF)) |
|
2194 |
+ { |
|
2195 |
+ cli_dbgmsg("XDP signature found at %u\n", (unsigned int)fpt->offset); |
|
2171 | 2196 |
nret = ret = cli_scanxdp(ctx); |
2172 | 2197 |
} |
2173 | 2198 |
break; |
2174 | 2199 |
case CL_TYPE_XML_WORD: |
2175 |
- if(SCAN_XMLDOCS && (DCONF_DOC & DOC_CONF_MSXML)) { |
|
2176 |
- cli_dbgmsg("XML-WORD signature found at %u\n", (unsigned int) fpt->offset); |
|
2200 |
+ if (SCAN_XMLDOCS && (DCONF_DOC & DOC_CONF_MSXML)) |
|
2201 |
+ { |
|
2202 |
+ cli_dbgmsg("XML-WORD signature found at %u\n", (unsigned int)fpt->offset); |
|
2177 | 2203 |
nret = ret = cli_scanmsxml(ctx); |
2178 | 2204 |
} |
2179 | 2205 |
break; |
2180 | 2206 |
case CL_TYPE_XML_XL: |
2181 |
- if(SCAN_XMLDOCS && (DCONF_DOC & DOC_CONF_MSXML)) { |
|
2182 |
- cli_dbgmsg("XML-XL signature found at %u\n", (unsigned int) fpt->offset); |
|
2207 |
+ if (SCAN_XMLDOCS && (DCONF_DOC & DOC_CONF_MSXML)) |
|
2208 |
+ { |
|
2209 |
+ cli_dbgmsg("XML-XL signature found at %u\n", (unsigned int)fpt->offset); |
|
2183 | 2210 |
nret = ret = cli_scanmsxml(ctx); |
2184 | 2211 |
} |
2185 | 2212 |
break; |
2186 | 2213 |
case CL_TYPE_XML_HWP: |
2187 |
- if(SCAN_XMLDOCS && (DCONF_DOC & DOC_CONF_HWP)) { |
|
2188 |
- cli_dbgmsg("XML-HWP signature found at %u\n", (unsigned int) fpt->offset); |
|
2214 |
+ if (SCAN_XMLDOCS && (DCONF_DOC & DOC_CONF_HWP)) |
|
2215 |
+ { |
|
2216 |
+ cli_dbgmsg("XML-HWP signature found at %u\n", (unsigned int)fpt->offset); |
|
2189 | 2217 |
nret = ret = cli_scanhwpml(ctx); |
2190 | 2218 |
} |
2191 | 2219 |
break; |
2192 | 2220 |
case CL_TYPE_RARSFX: |
2193 |
- if(type != CL_TYPE_RAR && have_rar && SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_RAR)) { |
|
2221 |
+ if (type != CL_TYPE_RAR && have_rar && SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_RAR)) |
|
2222 |
+ { |
|
2194 | 2223 |
char *tmpname = NULL; |
2195 | 2224 |
int tmpfd = fmap_fd(map); |
2196 | 2225 |
size_t csize = map->len - fpt->offset; /* not precise */ |
2197 | 2226 |
cli_set_container(ctx, CL_TYPE_RAR, csize); |
2198 |
- cli_dbgmsg("RAR/RAR-SFX signature found at %u\n", (unsigned int) fpt->offset); |
|
2227 |
+ cli_dbgmsg("RAR/RAR-SFX signature found at %u\n", (unsigned int)fpt->offset); |
|
2199 | 2228 |
/* if map is not file-backed, have to dump to file for scanrar */ |
2200 |
- if(tmpfd == -1) { |
|
2229 |
+ if (tmpfd == -1) |
|
2230 |
+ { |
|
2201 | 2231 |
nret = fmap_dump_to_file(map, ctx->engine->tmpdir, &tmpname, &tmpfd); |
2202 |
- if(nret != CL_SUCCESS) { |
|
2232 |
+ if (nret != CL_SUCCESS) |
|
2233 |
+ { |
|
2203 | 2234 |
cli_dbgmsg("cli_scanraw: failed to generate temporary file.\n"); |
2204 | 2235 |
ret = nret; |
2205 | 2236 |
break_loop = 1; |
... | ... |
@@ -2209,10 +2496,13 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_ |
2209 | 2209 |
/* scan existing file */ |
2210 | 2210 |
nret = cli_scanrar(tmpfd, ctx, fpt->offset, &lastrar); |
2211 | 2211 |
/* if dumped tempfile, need to cleanup */ |
2212 |
- if(tmpname) { |
|
2212 |
+ if (tmpname) |
|
2213 |
+ { |
|
2213 | 2214 |
close(tmpfd); |
2214 |
- if(!ctx->engine->keeptmp) { |
|
2215 |
- if (cli_unlink(tmpname)) { |
|
2215 |
+ if (!ctx->engine->keeptmp) |
|
2216 |
+ { |
|
2217 |
+ if (cli_unlink(tmpname)) |
|
2218 |
+ { |
|
2216 | 2219 |
ret = nret = CL_EUNLINK; |
2217 | 2220 |
break_loop = 1; |
2218 | 2221 |
} |
... | ... |
@@ -2223,127 +2513,142 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_ |
2223 | 2223 |
break; |
2224 | 2224 |
|
2225 | 2225 |
case CL_TYPE_ZIPSFX: |
2226 |
- if(type != CL_TYPE_ZIP && SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_ZIP)) { |
|
2226 |
+ if (type != CL_TYPE_ZIP && SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_ZIP)) |
|
2227 |
+ { |
|
2227 | 2228 |
size_t csize = map->len - fpt->offset; /* not precise */ |
2228 | 2229 |
cli_set_container(ctx, CL_TYPE_ZIP, csize); |
2229 |
- cli_dbgmsg("ZIP/ZIP-SFX signature found at %u\n", (unsigned int) fpt->offset); |
|
2230 |
+ cli_dbgmsg("ZIP/ZIP-SFX signature found at %u\n", (unsigned int)fpt->offset); |
|
2230 | 2231 |
nret = cli_unzip_single(ctx, fpt->offset); |
2231 | 2232 |
} |
2232 | 2233 |
break; |
2233 | 2234 |
|
2234 | 2235 |
case CL_TYPE_CABSFX: |
2235 |
- if(type != CL_TYPE_MSCAB && SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CAB)) { |
|
2236 |
+ if (type != CL_TYPE_MSCAB && SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CAB)) |
|
2237 |
+ { |
|
2236 | 2238 |
size_t csize = map->len - fpt->offset; /* not precise */ |
2237 | 2239 |
cli_set_container(ctx, CL_TYPE_MSCAB, csize); |
2238 |
- cli_dbgmsg("CAB/CAB-SFX signature found at %u\n", (unsigned int) fpt->offset); |
|
2240 |
+ cli_dbgmsg("CAB/CAB-SFX signature found at %u\n", (unsigned int)fpt->offset); |
|
2239 | 2241 |
nret = cli_scanmscab(ctx, fpt->offset); |
2240 | 2242 |
} |
2241 | 2243 |
break; |
2242 | 2244 |
|
2243 | 2245 |
case CL_TYPE_ARJSFX: |
2244 |
- if(type != CL_TYPE_ARJ && SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_ARJ)) { |
|
2246 |
+ if (type != CL_TYPE_ARJ && SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_ARJ)) |
|
2247 |
+ { |
|
2245 | 2248 |
size_t csize = map->len - fpt->offset; /* not precise */ |
2246 | 2249 |
cli_set_container(ctx, CL_TYPE_ARJ, csize); |
2247 |
- cli_dbgmsg("ARJ-SFX signature found at %u\n", (unsigned int) fpt->offset); |
|
2250 |
+ cli_dbgmsg("ARJ-SFX signature found at %u\n", (unsigned int)fpt->offset); |
|
2248 | 2251 |
nret = cli_scanarj(ctx, fpt->offset, &lastrar); |
2249 | 2252 |
} |
2250 | 2253 |
break; |
2251 | 2254 |
|
2252 | 2255 |
case CL_TYPE_7ZSFX: |
2253 |
- if(type != CL_TYPE_7Z && SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_7Z)) { |
|
2256 |
+ if (type != CL_TYPE_7Z && SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_7Z)) |
|
2257 |
+ { |
|
2254 | 2258 |
size_t csize = map->len - fpt->offset; /* not precise */ |
2255 | 2259 |
cli_set_container(ctx, CL_TYPE_7Z, csize); |
2256 |
- cli_dbgmsg("7Zip-SFX signature found at %u\n", (unsigned int) fpt->offset); |
|
2260 |
+ cli_dbgmsg("7Zip-SFX signature found at %u\n", (unsigned int)fpt->offset); |
|
2257 | 2261 |
nret = cli_7unz(ctx, fpt->offset); |
2258 | 2262 |
} |
2259 | 2263 |
break; |
2260 | 2264 |
|
2261 | 2265 |
case CL_TYPE_ISO9660: |
2262 |
- if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_ISO9660)) { |
|
2266 |
+ if (SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_ISO9660)) |
|
2267 |
+ { |
|
2263 | 2268 |
size_t csize = map->len - fpt->offset; /* not precise */ |
2264 | 2269 |
cli_set_container(ctx, CL_TYPE_ISO9660, csize); |
2265 |
- cli_dbgmsg("ISO9660 signature found at %u\n", (unsigned int) fpt->offset); |
|
2270 |
+ cli_dbgmsg("ISO9660 signature found at %u\n", (unsigned int)fpt->offset); |
|
2266 | 2271 |
nret = cli_scaniso(ctx, fpt->offset); |
2267 | 2272 |
} |
2268 | 2273 |
break; |
2269 | 2274 |
|
2270 | 2275 |
case CL_TYPE_NULSFT: |
2271 |
- if(SCAN_ARCHIVE && type == CL_TYPE_MSEXE && (DCONF_ARCH & ARCH_CONF_NSIS) && |
|
2272 |
- fpt->offset > 4) { |
|
2276 |
+ if (SCAN_ARCHIVE && type == CL_TYPE_MSEXE && (DCONF_ARCH & ARCH_CONF_NSIS) && |
|
2277 |
+ fpt->offset > 4) |
|
2278 |
+ { |
|
2273 | 2279 |
size_t csize = map->len - fpt->offset; /* not precise */ |
2274 | 2280 |
cli_set_container(ctx, CL_TYPE_NULSFT, csize); |
2275 |
- cli_dbgmsg("NSIS signature found at %u\n", (unsigned int) fpt->offset-4); |
|
2281 |
+ cli_dbgmsg("NSIS signature found at %u\n", (unsigned int)fpt->offset - 4); |
|
2276 | 2282 |
nret = cli_scannulsft(ctx, fpt->offset - 4); |
2277 | 2283 |
} |
2278 | 2284 |
break; |
2279 | 2285 |
|
2280 | 2286 |
case CL_TYPE_AUTOIT: |
2281 |
- if(SCAN_ARCHIVE && type == CL_TYPE_MSEXE && (DCONF_ARCH & ARCH_CONF_AUTOIT)) { |
|
2287 |
+ if (SCAN_ARCHIVE && type == CL_TYPE_MSEXE && (DCONF_ARCH & ARCH_CONF_AUTOIT)) |
|
2288 |
+ { |
|
2282 | 2289 |
size_t csize = map->len - fpt->offset; /* not precise */ |
2283 | 2290 |
cli_set_container(ctx, CL_TYPE_AUTOIT, csize); |
2284 |
- cli_dbgmsg("AUTOIT signature found at %u\n", (unsigned int) fpt->offset); |
|
2291 |
+ cli_dbgmsg("AUTOIT signature found at %u\n", (unsigned int)fpt->offset); |
|
2285 | 2292 |
nret = cli_scanautoit(ctx, fpt->offset + 23); |
2286 | 2293 |
} |
2287 | 2294 |
break; |
2288 | 2295 |
|
2289 | 2296 |
case CL_TYPE_ISHIELD_MSI: |
2290 |
- if(SCAN_ARCHIVE && type == CL_TYPE_MSEXE && (DCONF_ARCH & ARCH_CONF_ISHIELD)) { |
|
2297 |
+ if (SCAN_ARCHIVE && type == CL_TYPE_MSEXE && (DCONF_ARCH & ARCH_CONF_ISHIELD)) |
|
2298 |
+ { |
|
2291 | 2299 |
size_t csize = map->len - fpt->offset; /* not precise */ |
2292 | 2300 |
cli_set_container(ctx, CL_TYPE_AUTOIT, csize); |
2293 |
- cli_dbgmsg("ISHIELD-MSI signature found at %u\n", (unsigned int) fpt->offset); |
|
2301 |
+ cli_dbgmsg("ISHIELD-MSI signature found at %u\n", (unsigned int)fpt->offset); |
|
2294 | 2302 |
nret = cli_scanishield_msi(ctx, fpt->offset + 14); |
2295 | 2303 |
} |
2296 | 2304 |
break; |
2297 | 2305 |
|
2298 | 2306 |
case CL_TYPE_DMG: |
2299 |
- if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_DMG)) { |
|
2300 |
- cli_dbgmsg("DMG signature found at %u\n", (unsigned int) fpt->offset); |
|
2307 |
+ if (SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_DMG)) |
|
2308 |
+ { |
|
2309 |
+ cli_dbgmsg("DMG signature found at %u\n", (unsigned int)fpt->offset); |
|
2301 | 2310 |
nret = cli_scandmg(ctx); |
2302 | 2311 |
} |
2303 | 2312 |
break; |
2304 | 2313 |
|
2305 | 2314 |
case CL_TYPE_MBR: |
2306 |
- if(SCAN_ARCHIVE) { |
|
2315 |
+ if (SCAN_ARCHIVE) |
|
2316 |
+ { |
|
2307 | 2317 |
int iret = cli_mbr_check2(ctx, 0); |
2308 |
- if ((iret == CL_TYPE_GPT) && (DCONF_ARCH & ARCH_CONF_GPT)) { |
|
2318 |
+ if ((iret == CL_TYPE_GPT) && (DCONF_ARCH & ARCH_CONF_GPT)) |
|
2319 |
+ { |
|
2309 | 2320 |
cli_dbgmsg("Recognized GUID Partition Table file\n"); |
2310 | 2321 |
cli_set_container(ctx, CL_TYPE_GPT, map->len); |
2311 |
- cli_dbgmsg("GPT signature found at %u\n", (unsigned int) fpt->offset); |
|
2322 |
+ cli_dbgmsg("GPT signature found at %u\n", (unsigned int)fpt->offset); |
|
2312 | 2323 |
nret = cli_scangpt(ctx, 0); |
2313 | 2324 |
} |
2314 |
- else if ((iret == CL_CLEAN) && (DCONF_ARCH & ARCH_CONF_MBR)) { |
|
2315 |
- cli_dbgmsg("MBR signature found at %u\n", (unsigned int) fpt->offset); |
|
2325 |
+ else if ((iret == CL_CLEAN) && (DCONF_ARCH & ARCH_CONF_MBR)) |
|
2326 |
+ { |
|
2327 |
+ cli_dbgmsg("MBR signature found at %u\n", (unsigned int)fpt->offset); |
|
2316 | 2328 |
nret = cli_scanmbr(ctx, 0); |
2317 | 2329 |
} |
2318 | 2330 |
} |
2319 | 2331 |
break; |
2320 | 2332 |
|
2321 | 2333 |
case CL_TYPE_PDF: |
2322 |
- if(type != CL_TYPE_PDF && SCAN_PDF && (DCONF_DOC & DOC_CONF_PDF)) { |
|
2334 |
+ if (type != CL_TYPE_PDF && SCAN_PDF && (DCONF_DOC & DOC_CONF_PDF)) |
|
2335 |
+ { |
|
2323 | 2336 |
size_t csize = map->len - fpt->offset; /* not precise */ |
2324 | 2337 |
cli_set_container(ctx, CL_TYPE_PDF, csize); |
2325 |
- cli_dbgmsg("PDF signature found at %u\n", (unsigned int) fpt->offset); |
|
2338 |
+ cli_dbgmsg("PDF signature found at %u\n", (unsigned int)fpt->offset); |
|
2326 | 2339 |
nret = cli_scanpdf(ctx, fpt->offset); |
2327 | 2340 |
} |
2328 | 2341 |
break; |
2329 | 2342 |
|
2330 | 2343 |
case CL_TYPE_MSEXE: |
2331 |
- if(SCAN_PE && (type == CL_TYPE_MSEXE || type == CL_TYPE_ZIP || type == CL_TYPE_MSOLE2) |
|
2332 |
- && ctx->dconf->pe) { |
|
2344 |
+ if (SCAN_PE && (type == CL_TYPE_MSEXE || type == CL_TYPE_ZIP || type == CL_TYPE_MSOLE2) && ctx->dconf->pe) |
|
2345 |
+ { |
|
2333 | 2346 |
uint64_t curr_len = map->len; |
2334 | 2347 |
size_t csize = map->len - fpt->offset; /* not precise */ |
2335 | 2348 |
/* CL_ENGINE_MAX_EMBEDDED_PE */ |
2336 |
- if(curr_len > ctx->engine->maxembeddedpe) { |
|
2349 |
+ if (curr_len > ctx->engine->maxembeddedpe) |
|
2350 |
+ { |
|
2337 | 2351 |
cli_dbgmsg("cli_scanraw: MaxEmbeddedPE exceeded\n"); |
2338 | 2352 |
break; |
2339 | 2353 |
} |
2340 | 2354 |
cli_set_container(ctx, CL_TYPE_MSEXE, csize); |
2341 | 2355 |
memset(&peinfo, 0, sizeof(struct cli_exe_info)); |
2342 | 2356 |
peinfo.offset = fpt->offset; |
2343 |
- if(cli_peheader(map, &peinfo) == 0) { |
|
2344 |
- cli_dbgmsg("*** Detected embedded PE file at %u ***\n", |
|
2345 |
- (unsigned int) fpt->offset); |
|
2346 |
- if(peinfo.section) |
|
2357 |
+ if (cli_peheader(map, &peinfo) == 0) |
|
2358 |
+ { |
|
2359 |
+ cli_dbgmsg("*** Detected embedded PE file at %u ***\n", |
|
2360 |
+ (unsigned int)fpt->offset); |
|
2361 |
+ if (peinfo.section) |
|
2347 | 2362 |
free(peinfo.section); |
2348 | 2363 |
cli_hashset_destroy(&peinfo.vinfo); |
2349 | 2364 |
|
... | ... |
@@ -2359,76 +2664,85 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_ |
2359 | 2359 |
|
2360 | 2360 |
default: |
2361 | 2361 |
cli_warnmsg("cli_scanraw: Type %u not handled in fpt loop\n", fpt->type); |
2362 |
- } |
|
2362 |
+ } |
|
2363 | 2363 |
|
2364 |
- if(nret == CL_VIRUS || break_loop) |
|
2364 |
+ if (nret == CL_VIRUS || break_loop) |
|
2365 | 2365 |
break; |
2366 | 2366 |
|
2367 | 2367 |
fpt = fpt->next; |
2368 | 2368 |
} |
2369 |
- |
|
2370 |
- if(nret != CL_VIRUS) switch(ret) { |
|
2371 |
- case CL_TYPE_HTML: |
|
2372 |
- /* bb#11196 - autoit script file misclassified as HTML */ |
|
2373 |
- if (cli_get_container_intermediate(ctx, -2) == CL_TYPE_AUTOIT) { |
|
2374 |
- ret = CL_TYPE_TEXT_ASCII; |
|
2375 |
- } else if (SCAN_HTML && (type == CL_TYPE_TEXT_ASCII || type == CL_TYPE_GRAPHICS) && |
|
2376 |
- (DCONF_DOC & DOC_CONF_HTML)) { |
|
2377 |
- *dettype = CL_TYPE_HTML; |
|
2378 |
- nret = cli_scanhtml(ctx); |
|
2379 |
- } |
|
2380 |
- break; |
|
2381 |
- |
|
2382 |
- case CL_TYPE_MAIL: |
|
2383 |
- cli_set_container(ctx, CL_TYPE_MAIL, map->len); |
|
2384 |
- if(SCAN_MAIL && type == CL_TYPE_TEXT_ASCII && (DCONF_MAIL & MAIL_CONF_MBOX)) { |
|
2385 |
- *dettype = CL_TYPE_MAIL; |
|
2386 |
- nret = cli_scanmail(ctx); |
|
2387 |
- } |
|
2388 |
- break; |
|
2389 |
- |
|
2390 |
- default: |
|
2391 |
- break; |
|
2392 |
- } |
|
2393 |
- perf_nested_stop(ctx, PERFT_RAWTYPENO, PERFT_SCAN); |
|
2394 |
- ctx->recursion--; |
|
2395 |
- ret = nret; |
|
2396 |
- } |
|
2397 |
- |
|
2398 |
- while(ftoffset) { |
|
2399 |
- fpt = ftoffset; |
|
2400 |
- ftoffset = ftoffset->next; |
|
2401 |
- free(fpt); |
|
2402 |
- } |
|
2403 |
- |
|
2404 |
- if(ret == CL_VIRUS) |
|
2405 |
- cli_dbgmsg("%s found\n", cli_get_last_virus(ctx)); |
|
2369 |
+ |
|
2370 |
+ if (nret != CL_VIRUS) |
|
2371 |
+ switch (ret) |
|
2372 |
+ { |
|
2373 |
+ case CL_TYPE_HTML: |
|
2374 |
+ /* bb#11196 - autoit script file misclassified as HTML */ |
|
2375 |
+ if (cli_get_container_intermediate(ctx, -2) == CL_TYPE_AUTOIT) |
|
2376 |
+ { |
|
2377 |
+ ret = CL_TYPE_TEXT_ASCII; |
|
2378 |
+ } |
|
2379 |
+ else if (SCAN_HTML && (type == CL_TYPE_TEXT_ASCII || type == CL_TYPE_GRAPHICS) && |
|
2380 |
+ (DCONF_DOC & DOC_CONF_HTML)) |
|
2381 |
+ { |
|
2382 |
+ *dettype = CL_TYPE_HTML; |
|
2383 |
+ nret = cli_scanhtml(ctx); |
|
2384 |
+ } |
|
2385 |
+ break; |
|
2386 |
+ |
|
2387 |
+ case CL_TYPE_MAIL: |
|
2388 |
+ cli_set_container(ctx, CL_TYPE_MAIL, map->len); |
|
2389 |
+ if (SCAN_MAIL && type == CL_TYPE_TEXT_ASCII && (DCONF_MAIL & MAIL_CONF_MBOX)) |
|
2390 |
+ { |
|
2391 |
+ *dettype = CL_TYPE_MAIL; |
|
2392 |
+ nret = cli_scanmail(ctx); |
|
2393 |
+ } |
|
2394 |
+ break; |
|
2395 |
+ |
|
2396 |
+ default: |
|
2397 |
+ break; |
|
2398 |
+ } |
|
2399 |
+ perf_nested_stop(ctx, PERFT_RAWTYPENO, PERFT_SCAN); |
|
2400 |
+ ctx->recursion--; |
|
2401 |
+ ret = nret; |
|
2402 |
+ } |
|
2403 |
+ |
|
2404 |
+ while (ftoffset) |
|
2405 |
+ { |
|
2406 |
+ fpt = ftoffset; |
|
2407 |
+ ftoffset = ftoffset->next; |
|
2408 |
+ free(fpt); |
|
2409 |
+ } |
|
2410 |
+ |
|
2411 |
+ if (ret == CL_VIRUS) |
|
2412 |
+ cli_dbgmsg("%s found\n", cli_get_last_virus(ctx)); |
|
2406 | 2413 |
|
2407 | 2414 |
return ret; |
2408 | 2415 |
} |
2409 | 2416 |
|
2410 |
- |
|
2411 |
-static void emax_reached(cli_ctx *ctx) { |
|
2417 |
+static void emax_reached(cli_ctx *ctx) |
|
2418 |
+{ |
|
2412 | 2419 |
fmap_t **ctx_fmap = ctx->fmap; |
2413 | 2420 |
if (!ctx_fmap) |
2414 |
- return; |
|
2415 |
- while(*ctx_fmap) { |
|
2416 |
- fmap_t *map = *ctx_fmap; |
|
2417 |
- map->dont_cache_flag = 1; |
|
2418 |
- ctx_fmap--; |
|
2421 |
+ return; |
|
2422 |
+ while (*ctx_fmap) |
|
2423 |
+ { |
|
2424 |
+ fmap_t *map = *ctx_fmap; |
|
2425 |
+ map->dont_cache_flag = 1; |
|
2426 |
+ ctx_fmap--; |
|
2419 | 2427 |
} |
2420 | 2428 |
cli_dbgmsg("emax_reached: marked parents as non cacheable\n"); |
2421 | 2429 |
} |
2422 | 2430 |
|
2423 | 2431 |
#define LINESTR(x) #x |
2424 | 2432 |
#define LINESTR2(x) LINESTR(x) |
2425 |
-#define __AT__ " at line "LINESTR2(__LINE__) |
|
2433 |
+#define __AT__ " at line " LINESTR2(__LINE__) |
|
2426 | 2434 |
|
2427 |
-#define early_ret_from_magicscan(retcode) \ |
|
2428 |
- do { \ |
|
2429 |
- cli_dbgmsg("cli_magic_scandesc: returning %d %s (no post, no cache)\n", retcode, __AT__); \ |
|
2430 |
- return retcode; \ |
|
2431 |
- } while(0) |
|
2435 |
+#define early_ret_from_magicscan(retcode) \ |
|
2436 |
+ do \ |
|
2437 |
+ { \ |
|
2438 |
+ cli_dbgmsg("cli_magic_scandesc: returning %d %s (no post, no cache)\n", retcode, __AT__); \ |
|
2439 |
+ return retcode; \ |
|
2440 |
+ } while (0) |
|
2432 | 2441 |
|
2433 | 2442 |
static int magic_scandesc_cleanup(cli_ctx *ctx, cli_file_t type, unsigned char *hash, size_t hashed_size, int cache_clean, int retcode, void *parent_property) |
2434 | 2443 |
{ |
... | ... |
@@ -2441,11 +2755,13 @@ static int magic_scandesc_cleanup(cli_ctx *ctx, cli_file_t type, unsigned char * |
2441 | 2441 |
|
2442 | 2442 |
UNUSEDPARAM(type); |
2443 | 2443 |
|
2444 |
- if (retcode == CL_CLEAN && ctx->found_possibly_unwanted) { |
|
2444 |
+ if (retcode == CL_CLEAN && ctx->found_possibly_unwanted) |
|
2445 |
+ { |
|
2445 | 2446 |
cli_virus_found_cb(ctx); |
2446 | 2447 |
cb_retcode = CL_VIRUS; |
2447 | 2448 |
} |
2448 |
- else { |
|
2449 |
+ else |
|
2450 |
+ { |
|
2449 | 2451 |
if (retcode == CL_CLEAN && ctx->num_viruses != 0) |
2450 | 2452 |
cb_retcode = CL_VIRUS; |
2451 | 2453 |
else |
... | ... |
@@ -2453,12 +2769,14 @@ static int magic_scandesc_cleanup(cli_ctx *ctx, cli_file_t type, unsigned char * |
2453 | 2453 |
} |
2454 | 2454 |
|
2455 | 2455 |
cli_dbgmsg("cli_magic_scandesc: returning %d %s\n", retcode, __AT__); |
2456 |
- if(ctx->engine->cb_post_scan) { |
|
2457 |
- const char * virusname = NULL; |
|
2456 |
+ if (ctx->engine->cb_post_scan) |
|
2457 |
+ { |
|
2458 |
+ const char *virusname = NULL; |
|
2458 | 2459 |
perf_start(ctx, PERFT_POSTCB); |
2459 | 2460 |
if (cb_retcode == CL_VIRUS) |
2460 | 2461 |
virusname = cli_get_last_virus(ctx); |
2461 |
- switch(ctx->engine->cb_post_scan(fmap_fd(*ctx->fmap), cb_retcode, virusname, ctx->cb_ctx)) { |
|
2462 |
+ switch (ctx->engine->cb_post_scan(fmap_fd(*ctx->fmap), cb_retcode, virusname, ctx->cb_ctx)) |
|
2463 |
+ { |
|
2462 | 2464 |
case CL_BREAK: |
2463 | 2465 |
cli_dbgmsg("cli_magic_scandesc: file whitelisted by post_scan callback\n"); |
2464 | 2466 |
perf_stop(ctx, PERFT_POSTCB); |
... | ... |
@@ -2477,7 +2795,8 @@ static int magic_scandesc_cleanup(cli_ctx *ctx, cli_file_t type, unsigned char * |
2477 | 2477 |
} |
2478 | 2478 |
perf_stop(ctx, PERFT_POSTCB); |
2479 | 2479 |
} |
2480 |
- if (cb_retcode == CL_CLEAN && cache_clean) { |
|
2480 |
+ if (cb_retcode == CL_CLEAN && cache_clean) |
|
2481 |
+ { |
|
2481 | 2482 |
perf_start(ctx, PERFT_CACHE); |
2482 | 2483 |
if (!(SCAN_PROPERTIES)) |
2483 | 2484 |
cache_add(hash, hashed_size, ctx); |
... | ... |
@@ -2490,7 +2809,7 @@ static int magic_scandesc_cleanup(cli_ctx *ctx, cli_file_t type, unsigned char * |
2490 | 2490 |
|
2491 | 2491 |
static int dispatch_prescan(clcb_pre_scan cb, cli_ctx *ctx, const char *filetype, bitset_t *old_hook_lsig_matches, void *parent_property, unsigned char *hash, size_t hashed_size, int *run_cleanup) |
2492 | 2492 |
{ |
2493 |
- int res=CL_CLEAN; |
|
2493 |
+ int res = CL_CLEAN; |
|
2494 | 2494 |
|
2495 | 2495 |
UNUSEDPARAM(parent_property); |
2496 | 2496 |
UNUSEDPARAM(hash); |
... | ... |
@@ -2498,9 +2817,11 @@ static int dispatch_prescan(clcb_pre_scan cb, cli_ctx *ctx, const char *filetype |
2498 | 2498 |
|
2499 | 2499 |
*run_cleanup = 0; |
2500 | 2500 |
|
2501 |
- if(cb) { |
|
2501 |
+ if (cb) |
|
2502 |
+ { |
|
2502 | 2503 |
perf_start(ctx, PERFT_PRECB); |
2503 |
- switch(cb(fmap_fd(*ctx->fmap), filetype, ctx->cb_ctx)) { |
|
2504 |
+ switch (cb(fmap_fd(*ctx->fmap), filetype, ctx->cb_ctx)) |
|
2505 |
+ { |
|
2504 | 2506 |
case CL_BREAK: |
2505 | 2507 |
cli_dbgmsg("cli_magic_scandesc: file whitelisted by callback\n"); |
2506 | 2508 |
perf_stop(ctx, PERFT_PRECB); |
... | ... |
@@ -2530,64 +2851,73 @@ static int dispatch_prescan(clcb_pre_scan cb, cli_ctx *ctx, const char *filetype |
2530 | 2530 |
|
2531 | 2531 |
static int magic_scandesc(cli_ctx *ctx, cli_file_t type) |
2532 | 2532 |
{ |
2533 |
- int ret = CL_CLEAN; |
|
2534 |
- cli_file_t dettype = 0; |
|
2535 |
- uint8_t typercg = 1; |
|
2536 |
- size_t hashed_size; |
|
2537 |
- unsigned char hash[16] = {'\0'}; |
|
2538 |
- bitset_t *old_hook_lsig_matches; |
|
2539 |
- const char *filetype; |
|
2540 |
- int cache_clean = 0, res; |
|
2541 |
- int run_cleanup = 0; |
|
2533 |
+ int ret = CL_CLEAN; |
|
2534 |
+ cli_file_t dettype = 0; |
|
2535 |
+ uint8_t typercg = 1; |
|
2536 |
+ size_t hashed_size; |
|
2537 |
+ unsigned char hash[16] = {'\0'}; |
|
2538 |
+ bitset_t *old_hook_lsig_matches; |
|
2539 |
+ const char *filetype; |
|
2540 |
+ int cache_clean = 0, res; |
|
2541 |
+ int run_cleanup = 0; |
|
2542 | 2542 |
#if HAVE_JSON |
2543 |
- struct json_object *parent_property = NULL; |
|
2543 |
+ struct json_object *parent_property = NULL; |
|
2544 | 2544 |
#else |
2545 |
- void *parent_property = NULL; |
|
2545 |
+ void *parent_property = NULL; |
|
2546 | 2546 |
#endif |
2547 | 2547 |
|
2548 |
- if(!ctx->engine) { |
|
2549 |
- cli_errmsg("CRITICAL: engine == NULL\n"); |
|
2550 |
- early_ret_from_magicscan(CL_ENULLARG); |
|
2548 |
+ if (!ctx->engine) |
|
2549 |
+ { |
|
2550 |
+ cli_errmsg("CRITICAL: engine == NULL\n"); |
|
2551 |
+ early_ret_from_magicscan(CL_ENULLARG); |
|
2551 | 2552 |
} |
2552 | 2553 |
|
2553 |
- if(!(ctx->engine->dboptions & CL_DB_COMPILED)) { |
|
2554 |
- cli_errmsg("CRITICAL: engine not compiled\n"); |
|
2555 |
- early_ret_from_magicscan(CL_EMALFDB); |
|
2554 |
+ if (!(ctx->engine->dboptions & CL_DB_COMPILED)) |
|
2555 |
+ { |
|
2556 |
+ cli_errmsg("CRITICAL: engine not compiled\n"); |
|
2557 |
+ early_ret_from_magicscan(CL_EMALFDB); |
|
2556 | 2558 |
} |
2557 | 2559 |
|
2558 |
- if(ctx->engine->maxreclevel && ctx->recursion > ctx->engine->maxreclevel) { |
|
2560 |
+ if (ctx->engine->maxreclevel && ctx->recursion > ctx->engine->maxreclevel) |
|
2561 |
+ { |
|
2559 | 2562 |
cli_dbgmsg("cli_magic_scandesc: Archive recursion limit exceeded (%u, max: %u)\n", ctx->recursion, ctx->engine->maxreclevel); |
2560 |
- emax_reached(ctx); |
|
2563 |
+ emax_reached(ctx); |
|
2561 | 2564 |
cli_check_blockmax(ctx, CL_EMAXREC); |
2562 |
- early_ret_from_magicscan(CL_CLEAN); |
|
2565 |
+ early_ret_from_magicscan(CL_CLEAN); |
|
2563 | 2566 |
} |
2564 | 2567 |
|
2565 |
- if(cli_updatelimits(ctx, (*ctx->fmap)->len)!=CL_CLEAN) { |
|
2566 |
- emax_reached(ctx); |
|
2568 |
+ if (cli_updatelimits(ctx, (*ctx->fmap)->len) != CL_CLEAN) |
|
2569 |
+ { |
|
2570 |
+ emax_reached(ctx); |
|
2567 | 2571 |
early_ret_from_magicscan(CL_CLEAN); |
2568 | 2572 |
} |
2569 | 2573 |
old_hook_lsig_matches = ctx->hook_lsig_matches; |
2570 |
- if(type == CL_TYPE_PART_ANY) { |
|
2571 |
- typercg = 0; |
|
2574 |
+ if (type == CL_TYPE_PART_ANY) |
|
2575 |
+ { |
|
2576 |
+ typercg = 0; |
|
2572 | 2577 |
} |
2573 | 2578 |
|
2574 | 2579 |
perf_start(ctx, PERFT_FT); |
2575 |
- if((type == CL_TYPE_ANY) || type == CL_TYPE_PART_ANY) { |
|
2576 |
- type = cli_filetype2(*ctx->fmap, ctx->engine, type); |
|
2580 |
+ if ((type == CL_TYPE_ANY) || type == CL_TYPE_PART_ANY) |
|
2581 |
+ { |
|
2582 |
+ type = cli_filetype2(*ctx->fmap, ctx->engine, type); |
|
2577 | 2583 |
} |
2578 | 2584 |
perf_stop(ctx, PERFT_FT); |
2579 |
- if(type == CL_TYPE_ERROR) { |
|
2580 |
- cli_dbgmsg("cli_magic_scandesc: cli_filetype2 returned CL_TYPE_ERROR\n"); |
|
2581 |
- early_ret_from_magicscan(CL_EREAD); |
|
2585 |
+ if (type == CL_TYPE_ERROR) |
|
2586 |
+ { |
|
2587 |
+ cli_dbgmsg("cli_magic_scandesc: cli_filetype2 returned CL_TYPE_ERROR\n"); |
|
2588 |
+ early_ret_from_magicscan(CL_EREAD); |
|
2582 | 2589 |
} |
2583 | 2590 |
filetype = cli_ftname(type); |
2584 | 2591 |
|
2585 | 2592 |
#if HAVE_JSON |
2586 |
- if (ctx->options & CL_SCAN_FILE_PROPERTIES) { |
|
2593 |
+ if (ctx->options & CL_SCAN_FILE_PROPERTIES) |
|
2594 |
+ { |
|
2587 | 2595 |
json_object *arrobj; |
2588 | 2596 |
|
2589 |
- if (NULL == ctx->properties) { |
|
2590 |
- if (type == CL_TYPE_PDF || /* file types we collect properties about */ |
|
2597 |
+ if (NULL == ctx->properties) |
|
2598 |
+ { |
|
2599 |
+ if (type == CL_TYPE_PDF || /* file types we collect properties about */ |
|
2591 | 2600 |
type == CL_TYPE_MSOLE2 || |
2592 | 2601 |
type == CL_TYPE_MSEXE || |
2593 | 2602 |
//type == CL_TYPE_ZIP || |
... | ... |
@@ -2600,37 +2930,47 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type) |
2600 | 2600 |
type == CL_TYPE_XML_HWP || |
2601 | 2601 |
type == CL_TYPE_HWPOLE2 || |
2602 | 2602 |
type == CL_TYPE_OOXML_HWP || |
2603 |
- type == CL_TYPE_MHTML) { |
|
2603 |
+ type == CL_TYPE_MHTML) |
|
2604 |
+ { |
|
2604 | 2605 |
ctx->properties = json_object_new_object(); |
2605 |
- if (NULL == ctx->properties) { |
|
2606 |
+ if (NULL == ctx->properties) |
|
2607 |
+ { |
|
2606 | 2608 |
cli_errmsg("magic_scandesc: no memory for json properties object\n"); |
2607 |
- early_ret_from_magicscan(CL_EMEM); |
|
2609 |
+ early_ret_from_magicscan(CL_EMEM); |
|
2608 | 2610 |
} |
2609 | 2611 |
ctx->wrkproperty = ctx->properties; |
2610 | 2612 |
ret = cli_jsonstr(ctx->properties, "Magic", "CLAMJSONv0"); |
2611 |
- if (ret != CL_SUCCESS) { |
|
2613 |
+ if (ret != CL_SUCCESS) |
|
2614 |
+ { |
|
2612 | 2615 |
early_ret_from_magicscan(ret); |
2613 | 2616 |
} |
2614 | 2617 |
ret = cli_jsonstr(ctx->properties, "RootFileType", filetype); |
2615 |
- if (ret != CL_SUCCESS) { |
|
2618 |
+ if (ret != CL_SUCCESS) |
|
2619 |
+ { |
|
2616 | 2620 |
early_ret_from_magicscan(ret); |
2617 | 2621 |
} |
2618 |
- } else { /* turn off property collection flag for file types we don't care about */ |
|
2619 |
- ctx->options &= ~CL_SCAN_FILE_PROPERTIES; |
|
2622 |
+ } |
|
2623 |
+ else |
|
2624 |
+ { /* turn off property collection flag for file types we don't care about */ |
|
2625 |
+ ctx->options &= ~CL_SCAN_FILE_PROPERTIES; |
|
2620 | 2626 |
} |
2621 | 2627 |
} |
2622 |
- else { |
|
2628 |
+ else |
|
2629 |
+ { |
|
2623 | 2630 |
parent_property = ctx->wrkproperty; |
2624 |
- if (!json_object_object_get_ex(parent_property, "ContainedObjects", &arrobj)) { |
|
2631 |
+ if (!json_object_object_get_ex(parent_property, "ContainedObjects", &arrobj)) |
|
2632 |
+ { |
|
2625 | 2633 |
arrobj = json_object_new_array(); |
2626 |
- if (NULL == arrobj) { |
|
2634 |
+ if (NULL == arrobj) |
|
2635 |
+ { |
|
2627 | 2636 |
cli_errmsg("magic_scandesc: no memory for json properties object\n"); |
2628 | 2637 |
early_ret_from_magicscan(CL_EMEM); |
2629 | 2638 |
} |
2630 | 2639 |
json_object_object_add(parent_property, "ContainedObjects", arrobj); |
2631 | 2640 |
} |
2632 | 2641 |
ctx->wrkproperty = json_object_new_object(); |
2633 |
- if (NULL == ctx->wrkproperty) { |
|
2642 |
+ if (NULL == ctx->wrkproperty) |
|
2643 |
+ { |
|
2634 | 2644 |
cli_errmsg("magic_scandesc: no memory for json properties object\n"); |
2635 | 2645 |
early_ret_from_magicscan(CL_EMEM); |
2636 | 2646 |
} |
... | ... |
@@ -2638,13 +2978,16 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type) |
2638 | 2638 |
} |
2639 | 2639 |
} |
2640 | 2640 |
|
2641 |
- if (ctx->options & CL_SCAN_FILE_PROPERTIES) { /* separated for cases json is not tracked */ |
|
2641 |
+ if (ctx->options & CL_SCAN_FILE_PROPERTIES) |
|
2642 |
+ { /* separated for cases json is not tracked */ |
|
2642 | 2643 |
ret = cli_jsonstr(ctx->wrkproperty, "FileType", filetype); |
2643 |
- if (ret != CL_SUCCESS) { |
|
2644 |
+ if (ret != CL_SUCCESS) |
|
2645 |
+ { |
|
2644 | 2646 |
early_ret_from_magicscan(ret); |
2645 | 2647 |
} |
2646 | 2648 |
ret = cli_jsonint(ctx->wrkproperty, "FileSize", (*ctx->fmap)->len); |
2647 |
- if (ret != CL_SUCCESS) { |
|
2649 |
+ if (ret != CL_SUCCESS) |
|
2650 |
+ { |
|
2648 | 2651 |
early_ret_from_magicscan(ret); |
2649 | 2652 |
} |
2650 | 2653 |
} |
... | ... |
@@ -2652,7 +2995,8 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type) |
2652 | 2652 |
|
2653 | 2653 |
hashed_size = 0; |
2654 | 2654 |
ret = dispatch_prescan(ctx->engine->cb_pre_cache, ctx, filetype, old_hook_lsig_matches, parent_property, hash, hashed_size, &run_cleanup); |
2655 |
- if (run_cleanup) { |
|
2655 |
+ if (run_cleanup) |
|
2656 |
+ { |
|
2656 | 2657 |
if (ret == CL_VIRUS) |
2657 | 2658 |
return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, cli_checkfp(hash, hashed_size, ctx), parent_property); |
2658 | 2659 |
else |
... | ... |
@@ -2666,10 +3010,12 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type) |
2666 | 2666 |
res = CL_VIRUS; |
2667 | 2667 |
|
2668 | 2668 |
#if HAVE_JSON |
2669 |
- if (SCAN_PROPERTIES /* ctx.options & CL_SCAN_FILE_PROPERTIES && ctx->wrkproperty != NULL */) { |
|
2669 |
+ if (SCAN_PROPERTIES /* ctx.options & CL_SCAN_FILE_PROPERTIES && ctx->wrkproperty != NULL */) |
|
2670 |
+ { |
|
2670 | 2671 |
char hashstr[33]; |
2671 | 2672 |
ret = cache_get_MD5(hash, ctx); |
2672 |
- if (ret != CL_SUCCESS) { |
|
2673 |
+ if (ret != CL_SUCCESS) |
|
2674 |
+ { |
|
2673 | 2675 |
early_ret_from_magicscan(ret); |
2674 | 2676 |
} |
2675 | 2677 |
snprintf(hashstr, 33, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", |
... | ... |
@@ -2679,18 +3025,20 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type) |
2679 | 2679 |
ret = cli_jsonstr(ctx->wrkproperty, "FileMD5", hashstr); |
2680 | 2680 |
if (ctx->engine->engine_options & ENGINE_OPTIONS_DISABLE_CACHE) |
2681 | 2681 |
memset(hash, 0, sizeof(hash)); |
2682 |
- if (ret != CL_SUCCESS) { |
|
2682 |
+ if (ret != CL_SUCCESS) |
|
2683 |
+ { |
|
2683 | 2684 |
early_ret_from_magicscan(ret); |
2684 | 2685 |
} |
2685 | 2686 |
} |
2686 | 2687 |
#endif |
2687 | 2688 |
|
2688 |
- if(res != CL_VIRUS) { |
|
2689 |
- perf_stop(ctx, PERFT_CACHE); |
|
2689 |
+ if (res != CL_VIRUS) |
|
2690 |
+ { |
|
2691 |
+ perf_stop(ctx, PERFT_CACHE); |
|
2690 | 2692 |
#if HAVE_JSON |
2691 | 2693 |
ctx->wrkproperty = parent_property; |
2692 | 2694 |
#endif |
2693 |
- early_ret_from_magicscan(res); |
|
2695 |
+ early_ret_from_magicscan(res); |
|
2694 | 2696 |
} |
2695 | 2697 |
|
2696 | 2698 |
perf_stop(ctx, PERFT_CACHE); |
... | ... |
@@ -2698,507 +3046,536 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type) |
2698 | 2698 |
memcpy((*ctx->fmap)->maphash, hash, 16); |
2699 | 2699 |
ctx->hook_lsig_matches = NULL; |
2700 | 2700 |
|
2701 |
- if(!(ctx->options&~CL_SCAN_ALLMATCHES) || (ctx->recursion == ctx->engine->maxreclevel)) { /* raw mode (stdin, etc.) or last level of recursion */ |
|
2702 |
- if(ctx->recursion == ctx->engine->maxreclevel) { |
|
2701 |
+ if (!(ctx->options & ~CL_SCAN_ALLMATCHES) || (ctx->recursion == ctx->engine->maxreclevel)) |
|
2702 |
+ { /* raw mode (stdin, etc.) or last level of recursion */ |
|
2703 |
+ if (ctx->recursion == ctx->engine->maxreclevel) |
|
2704 |
+ { |
|
2703 | 2705 |
cli_check_blockmax(ctx, CL_EMAXREC); |
2704 |
- cli_dbgmsg("cli_magic_scandesc: Hit recursion limit, only scanning raw file\n"); |
|
2706 |
+ cli_dbgmsg("cli_magic_scandesc: Hit recursion limit, only scanning raw file\n"); |
|
2705 | 2707 |
} |
2706 |
- else |
|
2707 |
- cli_dbgmsg("Raw mode: No support for special files\n"); |
|
2708 |
- |
|
2709 |
- ret = dispatch_prescan(ctx->engine->cb_pre_scan, ctx, filetype, old_hook_lsig_matches, parent_property, hash, hashed_size, &run_cleanup); |
|
2710 |
- if (run_cleanup) { |
|
2711 |
- if (ret == CL_VIRUS) |
|
2712 |
- return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, cli_checkfp(hash, hashed_size, ctx), parent_property); |
|
2713 | 2708 |
else |
2714 |
- return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, ret, parent_property); |
|
2715 |
- } |
|
2716 |
- /* ret_from_magicscan can be used below here*/ |
|
2717 |
- if((ret = cli_fmap_scandesc(ctx, 0, 0, NULL, AC_SCAN_VIR, NULL, hash)) == CL_VIRUS) |
|
2718 |
- cli_dbgmsg("%s found in descriptor %d\n", cli_get_last_virus(ctx), fmap_fd(*ctx->fmap)); |
|
2719 |
- else if(ret == CL_CLEAN) { |
|
2720 |
- if(ctx->recursion != ctx->engine->maxreclevel) |
|
2721 |
- cache_clean = 1; /* Only cache if limits are not reached */ |
|
2722 |
- else |
|
2723 |
- emax_reached(ctx); |
|
2724 |
- } |
|
2709 |
+ cli_dbgmsg("Raw mode: No support for special files\n"); |
|
2725 | 2710 |
|
2726 |
- ctx->hook_lsig_matches = old_hook_lsig_matches; |
|
2727 |
- return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, ret, parent_property); |
|
2711 |
+ ret = dispatch_prescan(ctx->engine->cb_pre_scan, ctx, filetype, old_hook_lsig_matches, parent_property, hash, hashed_size, &run_cleanup); |
|
2712 |
+ if (run_cleanup) |
|
2713 |
+ { |
|
2714 |
+ if (ret == CL_VIRUS) |
|
2715 |
+ return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, cli_checkfp(hash, hashed_size, ctx), parent_property); |
|
2716 |
+ else |
|
2717 |
+ return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, ret, parent_property); |
|
2718 |
+ } |
|
2719 |
+ /* ret_from_magicscan can be used below here*/ |
|
2720 |
+ if ((ret = cli_fmap_scandesc(ctx, 0, 0, NULL, AC_SCAN_VIR, NULL, hash)) == CL_VIRUS) |
|
2721 |
+ cli_dbgmsg("%s found in descriptor %d\n", cli_get_last_virus(ctx), fmap_fd(*ctx->fmap)); |
|
2722 |
+ else if (ret == CL_CLEAN) |
|
2723 |
+ { |
|
2724 |
+ if (ctx->recursion != ctx->engine->maxreclevel) |
|
2725 |
+ cache_clean = 1; /* Only cache if limits are not reached */ |
|
2726 |
+ else |
|
2727 |
+ emax_reached(ctx); |
|
2728 |
+ } |
|
2729 |
+ |
|
2730 |
+ ctx->hook_lsig_matches = old_hook_lsig_matches; |
|
2731 |
+ return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, ret, parent_property); |
|
2728 | 2732 |
} |
2729 | 2733 |
|
2730 | 2734 |
ret = dispatch_prescan(ctx->engine->cb_pre_scan, ctx, filetype, old_hook_lsig_matches, parent_property, hash, hashed_size, &run_cleanup); |
2731 |
- if (run_cleanup) { |
|
2735 |
+ if (run_cleanup) |
|
2736 |
+ { |
|
2732 | 2737 |
if (ret == CL_VIRUS) |
2733 | 2738 |
return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, cli_checkfp(hash, hashed_size, ctx), parent_property); |
2734 | 2739 |
else |
2735 | 2740 |
return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, ret, parent_property); |
2736 | 2741 |
} |
2737 |
- /* ret_from_magicscan can be used below here*/ |
|
2742 |
+/* ret_from_magicscan can be used below here*/ |
|
2738 | 2743 |
|
2739 | 2744 |
#ifdef HAVE__INTERNAL__SHA_COLLECT |
2740 |
- if(!ctx->sha_collect && type==CL_TYPE_MSEXE) ctx->sha_collect = 1; |
|
2745 |
+ if (!ctx->sha_collect && type == CL_TYPE_MSEXE) |
|
2746 |
+ ctx->sha_collect = 1; |
|
2741 | 2747 |
#endif |
2742 | 2748 |
|
2743 | 2749 |
ctx->hook_lsig_matches = cli_bitset_init(); |
2744 |
- if (!ctx->hook_lsig_matches) { |
|
2745 |
- ctx->hook_lsig_matches = old_hook_lsig_matches; |
|
2746 |
- return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, CL_EMEM, parent_property); |
|
2750 |
+ if (!ctx->hook_lsig_matches) |
|
2751 |
+ { |
|
2752 |
+ ctx->hook_lsig_matches = old_hook_lsig_matches; |
|
2753 |
+ return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, CL_EMEM, parent_property); |
|
2747 | 2754 |
} |
2748 | 2755 |
|
2749 |
- if(type != CL_TYPE_IGNORED && ctx->engine->sdb) { |
|
2750 |
- if((ret = cli_scanraw(ctx, type, 0, &dettype, (ctx->engine->engine_options & ENGINE_OPTIONS_DISABLE_CACHE) ? NULL : hash)) == CL_VIRUS) { |
|
2751 |
- ret = cli_checkfp(hash, hashed_size, ctx); |
|
2752 |
- cli_bitset_free(ctx->hook_lsig_matches); |
|
2753 |
- ctx->hook_lsig_matches = old_hook_lsig_matches; |
|
2754 |
- return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, ret, parent_property); |
|
2755 |
- } |
|
2756 |
+ if (type != CL_TYPE_IGNORED && ctx->engine->sdb) |
|
2757 |
+ { |
|
2758 |
+ if ((ret = cli_scanraw(ctx, type, 0, &dettype, (ctx->engine->engine_options & ENGINE_OPTIONS_DISABLE_CACHE) ? NULL : hash)) == CL_VIRUS) |
|
2759 |
+ { |
|
2760 |
+ ret = cli_checkfp(hash, hashed_size, ctx); |
|
2761 |
+ cli_bitset_free(ctx->hook_lsig_matches); |
|
2762 |
+ ctx->hook_lsig_matches = old_hook_lsig_matches; |
|
2763 |
+ return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, ret, parent_property); |
|
2764 |
+ } |
|
2756 | 2765 |
} |
2757 | 2766 |
|
2758 | 2767 |
ctx->recursion++; |
2759 | 2768 |
perf_nested_start(ctx, PERFT_CONTAINER, PERFT_SCAN); |
2760 | 2769 |
/* set current level as container AFTER recursing */ |
2761 | 2770 |
cli_set_container(ctx, type, (*ctx->fmap)->len); |
2762 |
- switch(type) { |
|
2763 |
- case CL_TYPE_IGNORED: |
|
2764 |
- break; |
|
2765 |
- |
|
2766 |
- case CL_TYPE_HWP3: |
|
2767 |
- if(SCAN_HWP3 && (DCONF_DOC & DOC_CONF_HWP)) |
|
2768 |
- ret = cli_scanhwp3(ctx); |
|
2769 |
- break; |
|
2770 |
- |
|
2771 |
- case CL_TYPE_HWPOLE2: |
|
2772 |
- if(SCAN_OLE2 && (DCONF_ARCH & ARCH_CONF_OLE2)) |
|
2773 |
- ret = cli_scanhwpole2(ctx); |
|
2774 |
- break; |
|
2775 |
- |
|
2776 |
- case CL_TYPE_XML_WORD: |
|
2777 |
- if(SCAN_XMLDOCS && (DCONF_DOC & DOC_CONF_MSXML)) |
|
2778 |
- ret = cli_scanmsxml(ctx); |
|
2779 |
- break; |
|
2780 |
- |
|
2781 |
- case CL_TYPE_XML_XL: |
|
2782 |
- if(SCAN_XMLDOCS && (DCONF_DOC & DOC_CONF_MSXML)) |
|
2783 |
- ret = cli_scanmsxml(ctx); |
|
2784 |
- break; |
|
2785 |
- |
|
2786 |
- case CL_TYPE_XML_HWP: |
|
2787 |
- if(SCAN_XMLDOCS && (DCONF_DOC & DOC_CONF_HWP)) |
|
2788 |
- ret = cli_scanhwpml(ctx); |
|
2789 |
- break; |
|
2790 |
- |
|
2791 |
- case CL_TYPE_XDP: |
|
2792 |
- if(SCAN_PDF && (DCONF_DOC & DOC_CONF_PDF)) |
|
2793 |
- ret = cli_scanxdp(ctx); |
|
2794 |
- break; |
|
2795 |
- |
|
2796 |
- case CL_TYPE_RAR: |
|
2797 |
- if(have_rar && SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_RAR)) { |
|
2798 |
- char *tmpname = NULL; |
|
2799 |
- int desc = fmap_fd(*ctx->fmap); |
|
2800 |
- if (desc == -1) { |
|
2801 |
- cli_dbgmsg("fmap not backed by file, dumping ...\n"); |
|
2802 |
- ret = fmap_dump_to_file(*ctx->fmap, ctx->engine->tmpdir, &tmpname, &desc); |
|
2803 |
- if (ret != CL_SUCCESS) { |
|
2804 |
- cli_dbgmsg("fmap_fd: failed to generate temporary file.\n"); |
|
2805 |
- break; |
|
2806 |
- } |
|
2807 |
- } |
|
2808 |
- ret = cli_scanrar(desc, ctx, 0, NULL); |
|
2809 |
- if (tmpname) { |
|
2810 |
- close(desc); |
|
2811 |
- unlink(tmpname); |
|
2812 |
- free(tmpname); |
|
2813 |
- } |
|
2814 |
- } |
|
2815 |
- break; |
|
2816 |
- |
|
2817 |
- case CL_TYPE_OOXML_WORD: |
|
2818 |
- case CL_TYPE_OOXML_PPT: |
|
2819 |
- case CL_TYPE_OOXML_XL: |
|
2820 |
- case CL_TYPE_OOXML_HWP: |
|
2771 |
+ switch (type) |
|
2772 |
+ { |
|
2773 |
+ case CL_TYPE_IGNORED: |
|
2774 |
+ break; |
|
2775 |
+ |
|
2776 |
+ case CL_TYPE_HWP3: |
|
2777 |
+ if (SCAN_HWP3 && (DCONF_DOC & DOC_CONF_HWP)) |
|
2778 |
+ ret = cli_scanhwp3(ctx); |
|
2779 |
+ break; |
|
2780 |
+ |
|
2781 |
+ case CL_TYPE_HWPOLE2: |
|
2782 |
+ if (SCAN_OLE2 && (DCONF_ARCH & ARCH_CONF_OLE2)) |
|
2783 |
+ ret = cli_scanhwpole2(ctx); |
|
2784 |
+ break; |
|
2785 |
+ |
|
2786 |
+ case CL_TYPE_XML_WORD: |
|
2787 |
+ if (SCAN_XMLDOCS && (DCONF_DOC & DOC_CONF_MSXML)) |
|
2788 |
+ ret = cli_scanmsxml(ctx); |
|
2789 |
+ break; |
|
2790 |
+ |
|
2791 |
+ case CL_TYPE_XML_XL: |
|
2792 |
+ if (SCAN_XMLDOCS && (DCONF_DOC & DOC_CONF_MSXML)) |
|
2793 |
+ ret = cli_scanmsxml(ctx); |
|
2794 |
+ break; |
|
2795 |
+ |
|
2796 |
+ case CL_TYPE_XML_HWP: |
|
2797 |
+ if (SCAN_XMLDOCS && (DCONF_DOC & DOC_CONF_HWP)) |
|
2798 |
+ ret = cli_scanhwpml(ctx); |
|
2799 |
+ break; |
|
2800 |
+ |
|
2801 |
+ case CL_TYPE_XDP: |
|
2802 |
+ if (SCAN_PDF && (DCONF_DOC & DOC_CONF_PDF)) |
|
2803 |
+ ret = cli_scanxdp(ctx); |
|
2804 |
+ break; |
|
2805 |
+ |
|
2806 |
+ case CL_TYPE_RAR: |
|
2807 |
+ if (have_rar && SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_RAR)) |
|
2808 |
+ { |
|
2809 |
+ char *tmpname = NULL; |
|
2810 |
+ int desc = fmap_fd(*ctx->fmap); |
|
2811 |
+ if (desc == -1) |
|
2812 |
+ { |
|
2813 |
+ cli_dbgmsg("fmap not backed by file, dumping ...\n"); |
|
2814 |
+ ret = fmap_dump_to_file(*ctx->fmap, ctx->engine->tmpdir, &tmpname, &desc); |
|
2815 |
+ if (ret != CL_SUCCESS) |
|
2816 |
+ { |
|
2817 |
+ cli_dbgmsg("fmap_fd: failed to generate temporary file.\n"); |
|
2818 |
+ break; |
|
2819 |
+ } |
|
2820 |
+ } |
|
2821 |
+ ret = cli_scanrar(desc, ctx, 0, NULL); |
|
2822 |
+ if (tmpname) |
|
2823 |
+ { |
|
2824 |
+ close(desc); |
|
2825 |
+ unlink(tmpname); |
|
2826 |
+ free(tmpname); |
|
2827 |
+ } |
|
2828 |
+ } |
|
2829 |
+ break; |
|
2830 |
+ |
|
2831 |
+ case CL_TYPE_OOXML_WORD: |
|
2832 |
+ case CL_TYPE_OOXML_PPT: |
|
2833 |
+ case CL_TYPE_OOXML_XL: |
|
2834 |
+ case CL_TYPE_OOXML_HWP: |
|
2821 | 2835 |
#if HAVE_JSON |
2822 |
- if(SCAN_XMLDOCS && (DCONF_DOC & DOC_CONF_OOXML)) { |
|
2823 |
- if ((ctx->options & CL_SCAN_FILE_PROPERTIES) && (ctx->wrkproperty != NULL)) { |
|
2824 |
- ret = cli_process_ooxml(ctx, type); |
|
2825 |
- |
|
2826 |
- if (ret == CL_EMEM || ret == CL_ENULLARG) { |
|
2827 |
- /* critical error */ |
|
2828 |
- break; |
|
2829 |
- } else if (ret != CL_SUCCESS) { |
|
2830 |
- /* |
|
2831 |
- * non-critical return => allow for the CL_TYPE_ZIP scan to occur |
|
2832 |
- * cli_process_ooxml other possible returns: |
|
2833 |
- * CL_ETIMEOUT, CL_EMAXSIZE, CL_EMAXFILES, CL_EPARSE, |
|
2834 |
- * CL_EFORMAT, CL_BREAK, CL_ESTAT |
|
2835 |
- */ |
|
2836 |
- ret = CL_SUCCESS; |
|
2837 |
- } |
|
2838 |
- } |
|
2839 |
- } |
|
2836 |
+ if (SCAN_XMLDOCS && (DCONF_DOC & DOC_CONF_OOXML)) |
|
2837 |
+ { |
|
2838 |
+ if ((ctx->options & CL_SCAN_FILE_PROPERTIES) && (ctx->wrkproperty != NULL)) |
|
2839 |
+ { |
|
2840 |
+ ret = cli_process_ooxml(ctx, type); |
|
2841 |
+ |
|
2842 |
+ if (ret == CL_EMEM || ret == CL_ENULLARG) |
|
2843 |
+ { |
|
2844 |
+ /* critical error */ |
|
2845 |
+ break; |
|
2846 |
+ } |
|
2847 |
+ else if (ret != CL_SUCCESS) |
|
2848 |
+ { |
|
2849 |
+ /* |
|
2850 |
+ * non-critical return => allow for the CL_TYPE_ZIP scan to occur |
|
2851 |
+ * cli_process_ooxml other possible returns: |
|
2852 |
+ * CL_ETIMEOUT, CL_EMAXSIZE, CL_EMAXFILES, CL_EPARSE, |
|
2853 |
+ * CL_EFORMAT, CL_BREAK, CL_ESTAT |
|
2854 |
+ */ |
|
2855 |
+ ret = CL_SUCCESS; |
|
2856 |
+ } |
|
2857 |
+ } |
|
2858 |
+ } |
|
2840 | 2859 |
#endif |
2841 |
- case CL_TYPE_ZIP: |
|
2842 |
- if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_ZIP)) |
|
2843 |
- ret = cli_unzip(ctx); |
|
2844 |
- break; |
|
2845 |
- |
|
2846 |
- case CL_TYPE_GZ: |
|
2847 |
- if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_GZ)) |
|
2848 |
- ret = cli_scangzip(ctx); |
|
2849 |
- break; |
|
2850 |
- |
|
2851 |
- case CL_TYPE_BZ: |
|
2852 |
- if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_BZ)) |
|
2853 |
- ret = cli_scanbzip(ctx); |
|
2854 |
- break; |
|
2855 |
- |
|
2856 |
- case CL_TYPE_XZ: |
|
2857 |
- if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_XZ)) |
|
2858 |
- ret = cli_scanxz(ctx); |
|
2859 |
- break; |
|
2860 |
- |
|
2861 |
- case CL_TYPE_GPT: |
|
2862 |
- if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_GPT)) |
|
2863 |
- ret = cli_scangpt(ctx, 0); |
|
2864 |
- break; |
|
2865 |
- |
|
2866 |
- case CL_TYPE_APM: |
|
2867 |
- if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_APM)) |
|
2868 |
- ret = cli_scanapm(ctx); |
|
2869 |
- break; |
|
2870 |
- |
|
2871 |
- case CL_TYPE_ARJ: |
|
2872 |
- if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_ARJ)) |
|
2873 |
- ret = cli_scanarj(ctx, 0, NULL); |
|
2874 |
- break; |
|
2875 |
- |
|
2876 |
- case CL_TYPE_NULSFT: |
|
2877 |
- if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_NSIS)) |
|
2878 |
- ret = cli_scannulsft(ctx, 0); |
|
2879 |
- break; |
|
2880 |
- |
|
2881 |
- case CL_TYPE_AUTOIT: |
|
2882 |
- if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_AUTOIT)) |
|
2883 |
- ret = cli_scanautoit(ctx, 23); |
|
2884 |
- break; |
|
2885 |
- |
|
2886 |
- case CL_TYPE_MSSZDD: |
|
2887 |
- if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_SZDD)) |
|
2888 |
- ret = cli_scanszdd(ctx); |
|
2889 |
- break; |
|
2890 |
- |
|
2891 |
- case CL_TYPE_MSCAB: |
|
2892 |
- if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CAB)) |
|
2893 |
- ret = cli_scanmscab(ctx, 0); |
|
2894 |
- break; |
|
2895 |
- |
|
2896 |
- case CL_TYPE_HTML: |
|
2897 |
- if(SCAN_HTML && (DCONF_DOC & DOC_CONF_HTML)) |
|
2898 |
- ret = cli_scanhtml(ctx); |
|
2899 |
- break; |
|
2900 |
- |
|
2901 |
- case CL_TYPE_HTML_UTF16: |
|
2902 |
- if(SCAN_HTML && (DCONF_DOC & DOC_CONF_HTML)) |
|
2903 |
- ret = cli_scanhtml_utf16(ctx); |
|
2904 |
- break; |
|
2905 |
- |
|
2906 |
- case CL_TYPE_SCRIPT: |
|
2907 |
- if((DCONF_DOC & DOC_CONF_SCRIPT) && dettype != CL_TYPE_HTML) |
|
2908 |
- ret = cli_scanscript(ctx); |
|
2909 |
- break; |
|
2910 |
- |
|
2911 |
- case CL_TYPE_SWF: |
|
2912 |
- if(SCAN_SWF && (DCONF_DOC & DOC_CONF_SWF)) |
|
2913 |
- ret = cli_scanswf(ctx); |
|
2914 |
- break; |
|
2915 |
- |
|
2916 |
- case CL_TYPE_RTF: |
|
2917 |
- if(SCAN_ARCHIVE && (DCONF_DOC & DOC_CONF_RTF)) |
|
2918 |
- ret = cli_scanrtf(ctx); |
|
2919 |
- break; |
|
2920 |
- |
|
2921 |
- case CL_TYPE_MAIL: |
|
2922 |
- if(SCAN_MAIL && (DCONF_MAIL & MAIL_CONF_MBOX)) |
|
2923 |
- ret = cli_scanmail(ctx); |
|
2924 |
- break; |
|
2925 |
- |
|
2926 |
- case CL_TYPE_MHTML: |
|
2927 |
- if(SCAN_MAIL && (DCONF_MAIL & MAIL_CONF_MBOX)) |
|
2928 |
- ret = cli_scanmail(ctx); |
|
2929 |
- break; |
|
2930 |
- |
|
2931 |
- case CL_TYPE_TNEF: |
|
2932 |
- if(SCAN_MAIL && (DCONF_MAIL & MAIL_CONF_TNEF)) |
|
2933 |
- ret = cli_scantnef(ctx); |
|
2934 |
- break; |
|
2935 |
- |
|
2936 |
- case CL_TYPE_UUENCODED: |
|
2937 |
- if(DCONF_OTHER & OTHER_CONF_UUENC) |
|
2938 |
- ret = cli_scanuuencoded(ctx); |
|
2939 |
- break; |
|
2940 |
- |
|
2941 |
- case CL_TYPE_MSCHM: |
|
2942 |
- if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CHM)) |
|
2943 |
- ret = cli_scanmschm(ctx); |
|
2944 |
- break; |
|
2945 |
- |
|
2946 |
- case CL_TYPE_MSOLE2: |
|
2947 |
- if(SCAN_OLE2 && (DCONF_ARCH & ARCH_CONF_OLE2)) |
|
2948 |
- ret = cli_scanole2(ctx); |
|
2949 |
- break; |
|
2950 |
- |
|
2951 |
- case CL_TYPE_7Z: |
|
2952 |
- if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_7Z)) |
|
2953 |
- ret = cli_7unz(ctx, 0); |
|
2954 |
- break; |
|
2955 |
- |
|
2956 |
- case CL_TYPE_POSIX_TAR: |
|
2957 |
- if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_TAR)) |
|
2958 |
- ret = cli_scantar(ctx, 1); |
|
2959 |
- break; |
|
2960 |
- |
|
2961 |
- case CL_TYPE_OLD_TAR: |
|
2962 |
- if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_TAR)) |
|
2963 |
- ret = cli_scantar(ctx, 0); |
|
2964 |
- break; |
|
2965 |
- |
|
2966 |
- case CL_TYPE_CPIO_OLD: |
|
2967 |
- if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CPIO)) |
|
2968 |
- ret = cli_scancpio_old(ctx); |
|
2969 |
- break; |
|
2970 |
- |
|
2971 |
- case CL_TYPE_CPIO_ODC: |
|
2972 |
- if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CPIO)) |
|
2973 |
- ret = cli_scancpio_odc(ctx); |
|
2974 |
- break; |
|
2975 |
- |
|
2976 |
- case CL_TYPE_CPIO_NEWC: |
|
2977 |
- if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CPIO)) |
|
2978 |
- ret = cli_scancpio_newc(ctx, 0); |
|
2979 |
- break; |
|
2980 |
- |
|
2981 |
- case CL_TYPE_CPIO_CRC: |
|
2982 |
- if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CPIO)) |
|
2983 |
- ret = cli_scancpio_newc(ctx, 1); |
|
2984 |
- break; |
|
2985 |
- |
|
2986 |
- case CL_TYPE_BINHEX: |
|
2987 |
- if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_BINHEX)) |
|
2988 |
- ret = cli_binhex(ctx); |
|
2989 |
- break; |
|
2990 |
- |
|
2991 |
- case CL_TYPE_SCRENC: |
|
2992 |
- if(DCONF_OTHER & OTHER_CONF_SCRENC) |
|
2993 |
- ret = cli_scanscrenc(ctx); |
|
2994 |
- break; |
|
2995 |
- |
|
2996 |
- case CL_TYPE_RIFF: |
|
2997 |
- if(SCAN_ALGO && (DCONF_OTHER & OTHER_CONF_RIFF)) |
|
2998 |
- ret = cli_scanriff(ctx); |
|
2999 |
- break; |
|
3000 |
- |
|
3001 |
- case CL_TYPE_GRAPHICS: |
|
3002 |
- if(SCAN_ALGO && (DCONF_OTHER & OTHER_CONF_JPEG)) |
|
3003 |
- ret = cli_scanjpeg(ctx); |
|
3004 |
- |
|
3005 |
- if(ctx->img_validate && SCAN_ALGO && ret != CL_VIRUS) |
|
3006 |
- ret = cli_parsejpeg(ctx); |
|
3007 |
- |
|
3008 |
- if(ctx->img_validate && SCAN_ALGO && ret != CL_VIRUS && ret != CL_EPARSE) |
|
3009 |
- ret = cli_parsepng(ctx); |
|
3010 |
- |
|
3011 |
- if(ctx->img_validate && SCAN_ALGO && ret != CL_VIRUS && ret != CL_EPARSE) |
|
3012 |
- ret = cli_parsegif(ctx); |
|
3013 |
- |
|
3014 |
- if(ctx->img_validate && SCAN_ALGO && ret != CL_VIRUS && ret != CL_EPARSE) |
|
3015 |
- ret = cli_parsetiff(ctx); |
|
3016 |
- |
|
3017 |
- break; |
|
3018 |
- |
|
3019 |
- case CL_TYPE_PDF: /* FIXMELIMITS: pdf should be an archive! */ |
|
3020 |
- if(SCAN_PDF && (DCONF_DOC & DOC_CONF_PDF)) |
|
3021 |
- ret = cli_scanpdf(ctx, 0); |
|
3022 |
- break; |
|
3023 |
- |
|
3024 |
- case CL_TYPE_CRYPTFF: |
|
3025 |
- if(DCONF_OTHER & OTHER_CONF_CRYPTFF) |
|
3026 |
- ret = cli_scancryptff(ctx); |
|
3027 |
- break; |
|
3028 |
- |
|
3029 |
- case CL_TYPE_ELF: |
|
3030 |
- if(SCAN_ELF && ctx->dconf->elf) |
|
3031 |
- ret = cli_scanelf(ctx); |
|
3032 |
- break; |
|
3033 |
- |
|
3034 |
- case CL_TYPE_MACHO: |
|
3035 |
- if(ctx->dconf->macho) |
|
3036 |
- ret = cli_scanmacho(ctx, NULL); |
|
3037 |
- break; |
|
3038 |
- |
|
3039 |
- case CL_TYPE_MACHO_UNIBIN: |
|
3040 |
- if(ctx->dconf->macho) |
|
3041 |
- ret = cli_scanmacho_unibin(ctx); |
|
3042 |
- break; |
|
3043 |
- |
|
3044 |
- case CL_TYPE_SIS: |
|
3045 |
- if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_SIS)) |
|
3046 |
- ret = cli_scansis(ctx); |
|
3047 |
- break; |
|
3048 |
- |
|
3049 |
- case CL_TYPE_XAR: |
|
3050 |
- if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_XAR)) |
|
3051 |
- ret = cli_scanxar(ctx); |
|
3052 |
- break; |
|
3053 |
- |
|
3054 |
- case CL_TYPE_PART_HFSPLUS: |
|
3055 |
- if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_HFSPLUS)) |
|
3056 |
- ret = cli_scanhfsplus(ctx); |
|
3057 |
- break; |
|
3058 |
- |
|
3059 |
- case CL_TYPE_BINARY_DATA: |
|
3060 |
- case CL_TYPE_TEXT_UTF16BE: |
|
3061 |
- if(SCAN_ALGO && (DCONF_OTHER & OTHER_CONF_MYDOOMLOG)) |
|
3062 |
- ret = cli_check_mydoom_log(ctx); |
|
3063 |
- break; |
|
3064 |
- |
|
3065 |
- case CL_TYPE_TEXT_ASCII: |
|
3066 |
- if(SCAN_STRUCTURED && (DCONF_OTHER & OTHER_CONF_DLP)) |
|
3067 |
- /* TODO: consider calling this from cli_scanscript() for |
|
3068 |
- * a normalised text |
|
3069 |
- */ |
|
3070 |
- |
|
3071 |
- ret = cli_scan_structured(ctx); |
|
3072 |
- break; |
|
3073 |
- |
|
3074 |
- default: |
|
3075 |
- break; |
|
2860 |
+ case CL_TYPE_ZIP: |
|
2861 |
+ if (SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_ZIP)) |
|
2862 |
+ ret = cli_unzip(ctx); |
|
2863 |
+ break; |
|
2864 |
+ |
|
2865 |
+ case CL_TYPE_GZ: |
|
2866 |
+ if (SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_GZ)) |
|
2867 |
+ ret = cli_scangzip(ctx); |
|
2868 |
+ break; |
|
2869 |
+ |
|
2870 |
+ case CL_TYPE_BZ: |
|
2871 |
+ if (SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_BZ)) |
|
2872 |
+ ret = cli_scanbzip(ctx); |
|
2873 |
+ break; |
|
2874 |
+ |
|
2875 |
+ case CL_TYPE_XZ: |
|
2876 |
+ if (SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_XZ)) |
|
2877 |
+ ret = cli_scanxz(ctx); |
|
2878 |
+ break; |
|
2879 |
+ |
|
2880 |
+ case CL_TYPE_GPT: |
|
2881 |
+ if (SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_GPT)) |
|
2882 |
+ ret = cli_scangpt(ctx, 0); |
|
2883 |
+ break; |
|
2884 |
+ |
|
2885 |
+ case CL_TYPE_APM: |
|
2886 |
+ if (SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_APM)) |
|
2887 |
+ ret = cli_scanapm(ctx); |
|
2888 |
+ break; |
|
2889 |
+ |
|
2890 |
+ case CL_TYPE_ARJ: |
|
2891 |
+ if (SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_ARJ)) |
|
2892 |
+ ret = cli_scanarj(ctx, 0, NULL); |
|
2893 |
+ break; |
|
2894 |
+ |
|
2895 |
+ case CL_TYPE_NULSFT: |
|
2896 |
+ if (SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_NSIS)) |
|
2897 |
+ ret = cli_scannulsft(ctx, 0); |
|
2898 |
+ break; |
|
2899 |
+ |
|
2900 |
+ case CL_TYPE_AUTOIT: |
|
2901 |
+ if (SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_AUTOIT)) |
|
2902 |
+ ret = cli_scanautoit(ctx, 23); |
|
2903 |
+ break; |
|
2904 |
+ |
|
2905 |
+ case CL_TYPE_MSSZDD: |
|
2906 |
+ if (SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_SZDD)) |
|
2907 |
+ ret = cli_scanszdd(ctx); |
|
2908 |
+ break; |
|
2909 |
+ |
|
2910 |
+ case CL_TYPE_MSCAB: |
|
2911 |
+ if (SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CAB)) |
|
2912 |
+ ret = cli_scanmscab(ctx, 0); |
|
2913 |
+ break; |
|
2914 |
+ |
|
2915 |
+ case CL_TYPE_HTML: |
|
2916 |
+ if (SCAN_HTML && (DCONF_DOC & DOC_CONF_HTML)) |
|
2917 |
+ ret = cli_scanhtml(ctx); |
|
2918 |
+ break; |
|
2919 |
+ |
|
2920 |
+ case CL_TYPE_HTML_UTF16: |
|
2921 |
+ if (SCAN_HTML && (DCONF_DOC & DOC_CONF_HTML)) |
|
2922 |
+ ret = cli_scanhtml_utf16(ctx); |
|
2923 |
+ break; |
|
2924 |
+ |
|
2925 |
+ case CL_TYPE_SCRIPT: |
|
2926 |
+ if ((DCONF_DOC & DOC_CONF_SCRIPT) && dettype != CL_TYPE_HTML) |
|
2927 |
+ ret = cli_scanscript(ctx); |
|
2928 |
+ break; |
|
2929 |
+ |
|
2930 |
+ case CL_TYPE_SWF: |
|
2931 |
+ if (SCAN_SWF && (DCONF_DOC & DOC_CONF_SWF)) |
|
2932 |
+ ret = cli_scanswf(ctx); |
|
2933 |
+ break; |
|
2934 |
+ |
|
2935 |
+ case CL_TYPE_RTF: |
|
2936 |
+ if (SCAN_ARCHIVE && (DCONF_DOC & DOC_CONF_RTF)) |
|
2937 |
+ ret = cli_scanrtf(ctx); |
|
2938 |
+ break; |
|
2939 |
+ |
|
2940 |
+ case CL_TYPE_MAIL: |
|
2941 |
+ if (SCAN_MAIL && (DCONF_MAIL & MAIL_CONF_MBOX)) |
|
2942 |
+ ret = cli_scanmail(ctx); |
|
2943 |
+ break; |
|
2944 |
+ |
|
2945 |
+ case CL_TYPE_MHTML: |
|
2946 |
+ if (SCAN_MAIL && (DCONF_MAIL & MAIL_CONF_MBOX)) |
|
2947 |
+ ret = cli_scanmail(ctx); |
|
2948 |
+ break; |
|
2949 |
+ |
|
2950 |
+ case CL_TYPE_TNEF: |
|
2951 |
+ if (SCAN_MAIL && (DCONF_MAIL & MAIL_CONF_TNEF)) |
|
2952 |
+ ret = cli_scantnef(ctx); |
|
2953 |
+ break; |
|
2954 |
+ |
|
2955 |
+ case CL_TYPE_UUENCODED: |
|
2956 |
+ if (DCONF_OTHER & OTHER_CONF_UUENC) |
|
2957 |
+ ret = cli_scanuuencoded(ctx); |
|
2958 |
+ break; |
|
2959 |
+ |
|
2960 |
+ case CL_TYPE_MSCHM: |
|
2961 |
+ if (SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CHM)) |
|
2962 |
+ ret = cli_scanmschm(ctx); |
|
2963 |
+ break; |
|
2964 |
+ |
|
2965 |
+ case CL_TYPE_MSOLE2: |
|
2966 |
+ if (SCAN_OLE2 && (DCONF_ARCH & ARCH_CONF_OLE2)) |
|
2967 |
+ ret = cli_scanole2(ctx); |
|
2968 |
+ break; |
|
2969 |
+ |
|
2970 |
+ case CL_TYPE_7Z: |
|
2971 |
+ if (SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_7Z)) |
|
2972 |
+ ret = cli_7unz(ctx, 0); |
|
2973 |
+ break; |
|
2974 |
+ |
|
2975 |
+ case CL_TYPE_POSIX_TAR: |
|
2976 |
+ if (SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_TAR)) |
|
2977 |
+ ret = cli_scantar(ctx, 1); |
|
2978 |
+ break; |
|
2979 |
+ |
|
2980 |
+ case CL_TYPE_OLD_TAR: |
|
2981 |
+ if (SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_TAR)) |
|
2982 |
+ ret = cli_scantar(ctx, 0); |
|
2983 |
+ break; |
|
2984 |
+ |
|
2985 |
+ case CL_TYPE_CPIO_OLD: |
|
2986 |
+ if (SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CPIO)) |
|
2987 |
+ ret = cli_scancpio_old(ctx); |
|
2988 |
+ break; |
|
2989 |
+ |
|
2990 |
+ case CL_TYPE_CPIO_ODC: |
|
2991 |
+ if (SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CPIO)) |
|
2992 |
+ ret = cli_scancpio_odc(ctx); |
|
2993 |
+ break; |
|
2994 |
+ |
|
2995 |
+ case CL_TYPE_CPIO_NEWC: |
|
2996 |
+ if (SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CPIO)) |
|
2997 |
+ ret = cli_scancpio_newc(ctx, 0); |
|
2998 |
+ break; |
|
2999 |
+ |
|
3000 |
+ case CL_TYPE_CPIO_CRC: |
|
3001 |
+ if (SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CPIO)) |
|
3002 |
+ ret = cli_scancpio_newc(ctx, 1); |
|
3003 |
+ break; |
|
3004 |
+ |
|
3005 |
+ case CL_TYPE_BINHEX: |
|
3006 |
+ if (SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_BINHEX)) |
|
3007 |
+ ret = cli_binhex(ctx); |
|
3008 |
+ break; |
|
3009 |
+ |
|
3010 |
+ case CL_TYPE_SCRENC: |
|
3011 |
+ if (DCONF_OTHER & OTHER_CONF_SCRENC) |
|
3012 |
+ ret = cli_scanscrenc(ctx); |
|
3013 |
+ break; |
|
3014 |
+ |
|
3015 |
+ case CL_TYPE_RIFF: |
|
3016 |
+ if (SCAN_ALGO && (DCONF_OTHER & OTHER_CONF_RIFF)) |
|
3017 |
+ ret = cli_scanriff(ctx); |
|
3018 |
+ break; |
|
3019 |
+ |
|
3020 |
+ case CL_TYPE_GRAPHICS: |
|
3021 |
+ if (SCAN_ALGO && (DCONF_OTHER & OTHER_CONF_JPEG)) |
|
3022 |
+ ret = cli_scanjpeg(ctx); |
|
3023 |
+ |
|
3024 |
+ if (ctx->img_validate && SCAN_ALGO && ret != CL_VIRUS) |
|
3025 |
+ ret = cli_parsejpeg(ctx); |
|
3026 |
+ |
|
3027 |
+ if (ctx->img_validate && SCAN_ALGO && ret != CL_VIRUS && ret != CL_EPARSE) |
|
3028 |
+ ret = cli_parsepng(ctx); |
|
3029 |
+ |
|
3030 |
+ if (ctx->img_validate && SCAN_ALGO && ret != CL_VIRUS && ret != CL_EPARSE) |
|
3031 |
+ ret = cli_parsegif(ctx); |
|
3032 |
+ |
|
3033 |
+ if (ctx->img_validate && SCAN_ALGO && ret != CL_VIRUS && ret != CL_EPARSE) |
|
3034 |
+ ret = cli_parsetiff(ctx); |
|
3035 |
+ |
|
3036 |
+ break; |
|
3037 |
+ |
|
3038 |
+ case CL_TYPE_PDF: /* FIXMELIMITS: pdf should be an archive! */ |
|
3039 |
+ if (SCAN_PDF && (DCONF_DOC & DOC_CONF_PDF)) |
|
3040 |
+ ret = cli_scanpdf(ctx, 0); |
|
3041 |
+ break; |
|
3042 |
+ |
|
3043 |
+ case CL_TYPE_CRYPTFF: |
|
3044 |
+ if (DCONF_OTHER & OTHER_CONF_CRYPTFF) |
|
3045 |
+ ret = cli_scancryptff(ctx); |
|
3046 |
+ break; |
|
3047 |
+ |
|
3048 |
+ case CL_TYPE_ELF: |
|
3049 |
+ if (SCAN_ELF && ctx->dconf->elf) |
|
3050 |
+ ret = cli_scanelf(ctx); |
|
3051 |
+ break; |
|
3052 |
+ |
|
3053 |
+ case CL_TYPE_MACHO: |
|
3054 |
+ if (ctx->dconf->macho) |
|
3055 |
+ ret = cli_scanmacho(ctx, NULL); |
|
3056 |
+ break; |
|
3057 |
+ |
|
3058 |
+ case CL_TYPE_MACHO_UNIBIN: |
|
3059 |
+ if (ctx->dconf->macho) |
|
3060 |
+ ret = cli_scanmacho_unibin(ctx); |
|
3061 |
+ break; |
|
3062 |
+ |
|
3063 |
+ case CL_TYPE_SIS: |
|
3064 |
+ if (SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_SIS)) |
|
3065 |
+ ret = cli_scansis(ctx); |
|
3066 |
+ break; |
|
3067 |
+ |
|
3068 |
+ case CL_TYPE_XAR: |
|
3069 |
+ if (SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_XAR)) |
|
3070 |
+ ret = cli_scanxar(ctx); |
|
3071 |
+ break; |
|
3072 |
+ |
|
3073 |
+ case CL_TYPE_PART_HFSPLUS: |
|
3074 |
+ if (SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_HFSPLUS)) |
|
3075 |
+ ret = cli_scanhfsplus(ctx); |
|
3076 |
+ break; |
|
3077 |
+ |
|
3078 |
+ case CL_TYPE_BINARY_DATA: |
|
3079 |
+ case CL_TYPE_TEXT_UTF16BE: |
|
3080 |
+ if (SCAN_ALGO && (DCONF_OTHER & OTHER_CONF_MYDOOMLOG)) |
|
3081 |
+ ret = cli_check_mydoom_log(ctx); |
|
3082 |
+ break; |
|
3083 |
+ |
|
3084 |
+ case CL_TYPE_TEXT_ASCII: |
|
3085 |
+ if (SCAN_STRUCTURED && (DCONF_OTHER & OTHER_CONF_DLP)) |
|
3086 |
+ /* TODO: consider calling this from cli_scanscript() for |
|
3087 |
+ * a normalised text |
|
3088 |
+ */ |
|
3089 |
+ |
|
3090 |
+ ret = cli_scan_structured(ctx); |
|
3091 |
+ break; |
|
3092 |
+ |
|
3093 |
+ default: |
|
3094 |
+ break; |
|
3076 | 3095 |
} |
3077 | 3096 |
perf_nested_stop(ctx, PERFT_CONTAINER, PERFT_SCAN); |
3078 | 3097 |
ctx->recursion--; |
3079 | 3098 |
|
3080 |
- if(ret == CL_VIRUS && !SCAN_ALL) { |
|
3081 |
- cli_bitset_free(ctx->hook_lsig_matches); |
|
3082 |
- ctx->hook_lsig_matches = old_hook_lsig_matches; |
|
3083 |
- return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, ret, parent_property); |
|
3099 |
+ if (ret == CL_VIRUS && !SCAN_ALL) |
|
3100 |
+ { |
|
3101 |
+ cli_bitset_free(ctx->hook_lsig_matches); |
|
3102 |
+ ctx->hook_lsig_matches = old_hook_lsig_matches; |
|
3103 |
+ return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, ret, parent_property); |
|
3084 | 3104 |
} |
3085 | 3105 |
|
3086 |
- if(type == CL_TYPE_ZIP && SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_ZIP)) { |
|
3087 |
- /* CL_ENGINE_MAX_ZIPTYPERCG */ |
|
3088 |
- uint64_t curr_len = (*ctx->fmap)->len; |
|
3089 |
- if(curr_len > ctx->engine->maxziptypercg) { |
|
3090 |
- cli_dbgmsg("cli_magic_scandesc: Not checking for embedded PEs (zip file > MaxZipTypeRcg)\n"); |
|
3091 |
- typercg = 0; |
|
3092 |
- } |
|
3106 |
+ if (type == CL_TYPE_ZIP && SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_ZIP)) |
|
3107 |
+ { |
|
3108 |
+ /* CL_ENGINE_MAX_ZIPTYPERCG */ |
|
3109 |
+ uint64_t curr_len = (*ctx->fmap)->len; |
|
3110 |
+ if (curr_len > ctx->engine->maxziptypercg) |
|
3111 |
+ { |
|
3112 |
+ cli_dbgmsg("cli_magic_scandesc: Not checking for embedded PEs (zip file > MaxZipTypeRcg)\n"); |
|
3113 |
+ typercg = 0; |
|
3114 |
+ } |
|
3093 | 3115 |
} |
3094 | 3116 |
|
3095 | 3117 |
/* CL_TYPE_HTML: raw HTML files are not scanned, unless safety measure activated via DCONF */ |
3096 |
- if(type != CL_TYPE_IGNORED && (type != CL_TYPE_HTML || !(SCAN_HTML) || !(DCONF_DOC & DOC_CONF_HTML_SKIPRAW)) && !ctx->engine->sdb) { |
|
3097 |
- res = cli_scanraw(ctx, type, typercg, &dettype, (ctx->engine->engine_options & ENGINE_OPTIONS_DISABLE_CACHE) ? NULL : hash); |
|
3098 |
- if(res != CL_CLEAN) { |
|
3099 |
- switch(res) { |
|
3100 |
- /* List of scan halts, runtime errors only! */ |
|
3101 |
- case CL_EUNLINK: |
|
3102 |
- case CL_ESTAT: |
|
3103 |
- case CL_ESEEK: |
|
3104 |
- case CL_EWRITE: |
|
3105 |
- case CL_EDUP: |
|
3106 |
- case CL_ETMPFILE: |
|
3107 |
- case CL_ETMPDIR: |
|
3108 |
- case CL_EMEM: |
|
3109 |
- case CL_ETIMEOUT: |
|
3110 |
- cli_dbgmsg("Descriptor[%d]: cli_scanraw error %s\n", fmap_fd(*ctx->fmap), cl_strerror(res)); |
|
3111 |
- cli_bitset_free(ctx->hook_lsig_matches); |
|
3112 |
- ctx->hook_lsig_matches = old_hook_lsig_matches; |
|
3113 |
- return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, res, parent_property); |
|
3114 |
- /* CL_VIRUS = malware found, check FP and report */ |
|
3115 |
- case CL_VIRUS: |
|
3116 |
- ret = res; |
|
3117 |
- if (SCAN_ALL) |
|
3118 |
- break; |
|
3119 |
- cli_bitset_free(ctx->hook_lsig_matches); |
|
3120 |
- ctx->hook_lsig_matches = old_hook_lsig_matches; |
|
3121 |
- return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, ret, parent_property); |
|
3122 |
- /* "MAX" conditions should still fully scan the current file */ |
|
3123 |
- case CL_EMAXREC: |
|
3124 |
- case CL_EMAXSIZE: |
|
3125 |
- case CL_EMAXFILES: |
|
3126 |
- ret = res; |
|
3127 |
- cli_dbgmsg("Descriptor[%d]: Continuing after cli_scanraw reached %s\n", |
|
3128 |
- fmap_fd(*ctx->fmap), cl_strerror(res)); |
|
3129 |
- break; |
|
3130 |
- /* Other errors must not block further scans below |
|
3131 |
- * This specifically includes CL_EFORMAT & CL_EREAD & CL_EUNPACK |
|
3132 |
- * Malformed/truncated files could report as any of these three. |
|
3133 |
- */ |
|
3134 |
- default: |
|
3135 |
- ret = res; |
|
3136 |
- cli_dbgmsg("Descriptor[%d]: Continuing after cli_scanraw error %s\n", |
|
3137 |
- fmap_fd(*ctx->fmap), cl_strerror(res)); |
|
3138 |
- } |
|
3139 |
- } |
|
3118 |
+ if (type != CL_TYPE_IGNORED && (type != CL_TYPE_HTML || !(SCAN_HTML) || !(DCONF_DOC & DOC_CONF_HTML_SKIPRAW)) && !ctx->engine->sdb) |
|
3119 |
+ { |
|
3120 |
+ res = cli_scanraw(ctx, type, typercg, &dettype, (ctx->engine->engine_options & ENGINE_OPTIONS_DISABLE_CACHE) ? NULL : hash); |
|
3121 |
+ if (res != CL_CLEAN) |
|
3122 |
+ { |
|
3123 |
+ switch (res) |
|
3124 |
+ { |
|
3125 |
+ /* List of scan halts, runtime errors only! */ |
|
3126 |
+ case CL_EUNLINK: |
|
3127 |
+ case CL_ESTAT: |
|
3128 |
+ case CL_ESEEK: |
|
3129 |
+ case CL_EWRITE: |
|
3130 |
+ case CL_EDUP: |
|
3131 |
+ case CL_ETMPFILE: |
|
3132 |
+ case CL_ETMPDIR: |
|
3133 |
+ case CL_EMEM: |
|
3134 |
+ case CL_ETIMEOUT: |
|
3135 |
+ cli_dbgmsg("Descriptor[%d]: cli_scanraw error %s\n", fmap_fd(*ctx->fmap), cl_strerror(res)); |
|
3136 |
+ cli_bitset_free(ctx->hook_lsig_matches); |
|
3137 |
+ ctx->hook_lsig_matches = old_hook_lsig_matches; |
|
3138 |
+ return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, res, parent_property); |
|
3139 |
+ /* CL_VIRUS = malware found, check FP and report */ |
|
3140 |
+ case CL_VIRUS: |
|
3141 |
+ ret = res; |
|
3142 |
+ if (SCAN_ALL) |
|
3143 |
+ break; |
|
3144 |
+ cli_bitset_free(ctx->hook_lsig_matches); |
|
3145 |
+ ctx->hook_lsig_matches = old_hook_lsig_matches; |
|
3146 |
+ return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, ret, parent_property); |
|
3147 |
+ /* "MAX" conditions should still fully scan the current file */ |
|
3148 |
+ case CL_EMAXREC: |
|
3149 |
+ case CL_EMAXSIZE: |
|
3150 |
+ case CL_EMAXFILES: |
|
3151 |
+ ret = res; |
|
3152 |
+ cli_dbgmsg("Descriptor[%d]: Continuing after cli_scanraw reached %s\n", |
|
3153 |
+ fmap_fd(*ctx->fmap), cl_strerror(res)); |
|
3154 |
+ break; |
|
3155 |
+ /* Other errors must not block further scans below |
|
3156 |
+ * This specifically includes CL_EFORMAT & CL_EREAD & CL_EUNPACK |
|
3157 |
+ * Malformed/truncated files could report as any of these three. |
|
3158 |
+ */ |
|
3159 |
+ default: |
|
3160 |
+ ret = res; |
|
3161 |
+ cli_dbgmsg("Descriptor[%d]: Continuing after cli_scanraw error %s\n", |
|
3162 |
+ fmap_fd(*ctx->fmap), cl_strerror(res)); |
|
3163 |
+ } |
|
3164 |
+ } |
|
3140 | 3165 |
} |
3141 | 3166 |
|
3142 | 3167 |
ctx->recursion++; |
3143 |
- switch(type) { |
|
3144 |
- /* bytecode hooks triggered by a lsig must be a hook |
|
3145 |
- * called from one of the functions here */ |
|
3146 |
- case CL_TYPE_TEXT_ASCII: |
|
3147 |
- case CL_TYPE_TEXT_UTF16BE: |
|
3148 |
- case CL_TYPE_TEXT_UTF16LE: |
|
3149 |
- case CL_TYPE_TEXT_UTF8: |
|
3150 |
- perf_nested_start(ctx, PERFT_SCRIPT, PERFT_SCAN); |
|
3151 |
- if((DCONF_DOC & DOC_CONF_SCRIPT) && dettype != CL_TYPE_HTML && (ret != CL_VIRUS || SCAN_ALL) && SCAN_HTML) |
|
3152 |
- ret = cli_scanscript(ctx); |
|
3153 |
- if(SCAN_MAIL && (DCONF_MAIL & MAIL_CONF_MBOX) && ret != CL_VIRUS && (cli_get_container(ctx, -1) == CL_TYPE_MAIL || dettype == CL_TYPE_MAIL)) { |
|
3154 |
- ret = cli_fmap_scandesc(ctx, CL_TYPE_MAIL, 0, NULL, AC_SCAN_VIR, NULL, NULL); |
|
3155 |
- } |
|
3156 |
- perf_nested_stop(ctx, PERFT_SCRIPT, PERFT_SCAN); |
|
3157 |
- break; |
|
3158 |
- /* Due to performance reasons all executables were first scanned |
|
3159 |
- * in raw mode. Now we will try to unpack them |
|
3160 |
- */ |
|
3161 |
- case CL_TYPE_MSEXE: |
|
3162 |
- perf_nested_start(ctx, PERFT_PE, PERFT_SCAN); |
|
3163 |
- if(SCAN_PE && ctx->dconf->pe) { |
|
3164 |
- unsigned int corrupted_input = ctx->corrupted_input; |
|
3165 |
- ret = cli_scanpe(ctx); |
|
3166 |
- ctx->corrupted_input = corrupted_input; |
|
3167 |
- } |
|
3168 |
- perf_nested_stop(ctx, PERFT_PE, PERFT_SCAN); |
|
3169 |
- break; |
|
3170 |
- case CL_TYPE_BINARY_DATA: |
|
3171 |
- ret = cli_fmap_scandesc(ctx, CL_TYPE_OTHER, 0, NULL, AC_SCAN_VIR, NULL, NULL); |
|
3172 |
- break; |
|
3173 |
- default: |
|
3174 |
- break; |
|
3168 |
+ switch (type) |
|
3169 |
+ { |
|
3170 |
+ /* bytecode hooks triggered by a lsig must be a hook |
|
3171 |
+ * called from one of the functions here */ |
|
3172 |
+ case CL_TYPE_TEXT_ASCII: |
|
3173 |
+ case CL_TYPE_TEXT_UTF16BE: |
|
3174 |
+ case CL_TYPE_TEXT_UTF16LE: |
|
3175 |
+ case CL_TYPE_TEXT_UTF8: |
|
3176 |
+ perf_nested_start(ctx, PERFT_SCRIPT, PERFT_SCAN); |
|
3177 |
+ if ((DCONF_DOC & DOC_CONF_SCRIPT) && dettype != CL_TYPE_HTML && (ret != CL_VIRUS || SCAN_ALL) && SCAN_HTML) |
|
3178 |
+ ret = cli_scanscript(ctx); |
|
3179 |
+ if (SCAN_MAIL && (DCONF_MAIL & MAIL_CONF_MBOX) && ret != CL_VIRUS && (cli_get_container(ctx, -1) == CL_TYPE_MAIL || dettype == CL_TYPE_MAIL)) |
|
3180 |
+ { |
|
3181 |
+ ret = cli_fmap_scandesc(ctx, CL_TYPE_MAIL, 0, NULL, AC_SCAN_VIR, NULL, NULL); |
|
3182 |
+ } |
|
3183 |
+ perf_nested_stop(ctx, PERFT_SCRIPT, PERFT_SCAN); |
|
3184 |
+ break; |
|
3185 |
+ /* Due to performance reasons all executables were first scanned |
|
3186 |
+ * in raw mode. Now we will try to unpack them |
|
3187 |
+ */ |
|
3188 |
+ case CL_TYPE_MSEXE: |
|
3189 |
+ perf_nested_start(ctx, PERFT_PE, PERFT_SCAN); |
|
3190 |
+ if (SCAN_PE && ctx->dconf->pe) |
|
3191 |
+ { |
|
3192 |
+ unsigned int corrupted_input = ctx->corrupted_input; |
|
3193 |
+ ret = cli_scanpe(ctx); |
|
3194 |
+ ctx->corrupted_input = corrupted_input; |
|
3195 |
+ } |
|
3196 |
+ perf_nested_stop(ctx, PERFT_PE, PERFT_SCAN); |
|
3197 |
+ break; |
|
3198 |
+ case CL_TYPE_BINARY_DATA: |
|
3199 |
+ ret = cli_fmap_scandesc(ctx, CL_TYPE_OTHER, 0, NULL, AC_SCAN_VIR, NULL, NULL); |
|
3200 |
+ break; |
|
3201 |
+ default: |
|
3202 |
+ break; |
|
3175 | 3203 |
} |
3176 | 3204 |
|
3177 | 3205 |
ctx->recursion--; |
3178 | 3206 |
cli_bitset_free(ctx->hook_lsig_matches); |
3179 | 3207 |
ctx->hook_lsig_matches = old_hook_lsig_matches; |
3180 | 3208 |
|
3181 |
- switch(ret) { |
|
3182 |
- /* Malformed file cases */ |
|
3183 |
- case CL_EFORMAT: |
|
3184 |
- case CL_EREAD: |
|
3185 |
- case CL_EUNPACK: |
|
3186 |
- /* Limits exceeded */ |
|
3187 |
- case CL_EMAXREC: |
|
3188 |
- case CL_EMAXSIZE: |
|
3189 |
- case CL_EMAXFILES: |
|
3190 |
- cli_dbgmsg("Descriptor[%d]: %s\n", fmap_fd(*ctx->fmap), cl_strerror(ret)); |
|
3209 |
+ switch (ret) |
|
3210 |
+ { |
|
3211 |
+ /* Malformed file cases */ |
|
3212 |
+ case CL_EFORMAT: |
|
3213 |
+ case CL_EREAD: |
|
3214 |
+ case CL_EUNPACK: |
|
3215 |
+ /* Limits exceeded */ |
|
3216 |
+ case CL_EMAXREC: |
|
3217 |
+ case CL_EMAXSIZE: |
|
3218 |
+ case CL_EMAXFILES: |
|
3219 |
+ cli_dbgmsg("Descriptor[%d]: %s\n", fmap_fd(*ctx->fmap), cl_strerror(ret)); |
|
3191 | 3220 |
#if HAVE_JSON |
3192 | 3221 |
ctx->wrkproperty = parent_property; |
3193 | 3222 |
#endif |
3194 | 3223 |
return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, CL_CLEAN, parent_property); |
3195 |
- case CL_CLEAN: |
|
3196 |
- cache_clean = 1; |
|
3224 |
+ case CL_CLEAN: |
|
3225 |
+ cache_clean = 1; |
|
3197 | 3226 |
#if HAVE_JSON |
3198 | 3227 |
ctx->wrkproperty = parent_property; |
3199 | 3228 |
#endif |
3200 | 3229 |
return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, CL_CLEAN, parent_property); |
3201 |
- default: |
|
3230 |
+ default: |
|
3202 | 3231 |
return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, ret, parent_property); |
3203 | 3232 |
} |
3204 | 3233 |
} |
... | ... |
@@ -3209,25 +3586,29 @@ static int cli_base_scandesc(int desc, cli_ctx *ctx, cli_file_t type) |
3209 | 3209 |
int ret; |
3210 | 3210 |
|
3211 | 3211 |
#ifdef HAVE__INTERNAL__SHA_COLLECT |
3212 |
- if(ctx->sha_collect>0) ctx->sha_collect = 0; |
|
3212 |
+ if (ctx->sha_collect > 0) |
|
3213 |
+ ctx->sha_collect = 0; |
|
3213 | 3214 |
#endif |
3214 | 3215 |
cli_dbgmsg("in cli_magic_scandesc (reclevel: %u/%u)\n", ctx->recursion, ctx->engine->maxreclevel); |
3215 |
- if(FSTAT(desc, &sb) == -1) { |
|
3216 |
- cli_errmsg("magic_scandesc: Can't fstat descriptor %d\n", desc); |
|
3217 |
- early_ret_from_magicscan(CL_ESTAT); |
|
3216 |
+ if (FSTAT(desc, &sb) == -1) |
|
3217 |
+ { |
|
3218 |
+ cli_errmsg("magic_scandesc: Can't fstat descriptor %d\n", desc); |
|
3219 |
+ early_ret_from_magicscan(CL_ESTAT); |
|
3218 | 3220 |
} |
3219 |
- if(sb.st_size <= 5) { |
|
3220 |
- cli_dbgmsg("Small data (%u bytes)\n", (unsigned int) sb.st_size); |
|
3221 |
- early_ret_from_magicscan(CL_CLEAN); |
|
3221 |
+ if (sb.st_size <= 5) |
|
3222 |
+ { |
|
3223 |
+ cli_dbgmsg("Small data (%u bytes)\n", (unsigned int)sb.st_size); |
|
3224 |
+ early_ret_from_magicscan(CL_CLEAN); |
|
3222 | 3225 |
} |
3223 | 3226 |
|
3224 | 3227 |
ctx->fmap++; |
3225 | 3228 |
perf_start(ctx, PERFT_MAP); |
3226 |
- if(!(*ctx->fmap = fmap(desc, 0, sb.st_size))) { |
|
3227 |
- cli_errmsg("CRITICAL: fmap() failed\n"); |
|
3228 |
- ctx->fmap--; |
|
3229 |
- perf_stop(ctx, PERFT_MAP); |
|
3230 |
- early_ret_from_magicscan(CL_EMEM); |
|
3229 |
+ if (!(*ctx->fmap = fmap(desc, 0, sb.st_size))) |
|
3230 |
+ { |
|
3231 |
+ cli_errmsg("CRITICAL: fmap() failed\n"); |
|
3232 |
+ ctx->fmap--; |
|
3233 |
+ perf_stop(ctx, PERFT_MAP); |
|
3234 |
+ early_ret_from_magicscan(CL_EMEM); |
|
3231 | 3235 |
} |
3232 | 3236 |
perf_stop(ctx, PERFT_MAP); |
3233 | 3237 |
|
... | ... |
@@ -3267,13 +3648,15 @@ int cli_map_scan(cl_fmap_t *map, off_t offset, size_t length, cli_ctx *ctx, cli_ |
3267 | 3267 |
int ret = CL_CLEAN; |
3268 | 3268 |
|
3269 | 3269 |
cli_dbgmsg("cli_map_scan: [%ld, +%lu)\n", |
3270 |
- (long)offset, (unsigned long)length); |
|
3271 |
- if (offset < 0 || (size_t)offset >= old_len) { |
|
3272 |
- cli_dbgmsg("Invalid offset: %ld\n", (long)offset); |
|
3273 |
- return CL_CLEAN; |
|
3270 |
+ (long)offset, (unsigned long)length); |
|
3271 |
+ if (offset < 0 || (size_t)offset >= old_len) |
|
3272 |
+ { |
|
3273 |
+ cli_dbgmsg("Invalid offset: %ld\n", (long)offset); |
|
3274 |
+ return CL_CLEAN; |
|
3274 | 3275 |
} |
3275 | 3276 |
|
3276 |
- if (ctx->engine->engine_options & ENGINE_OPTIONS_FORCE_TO_DISK) { |
|
3277 |
+ if (ctx->engine->engine_options & ENGINE_OPTIONS_FORCE_TO_DISK) |
|
3278 |
+ { |
|
3277 | 3279 |
/* if this is forced to disk, then need to write the nested map and scan it */ |
3278 | 3280 |
const uint8_t *mapdata = NULL; |
3279 | 3281 |
char *tempfile = NULL; |
... | ... |
@@ -3281,17 +3664,21 @@ int cli_map_scan(cl_fmap_t *map, off_t offset, size_t length, cli_ctx *ctx, cli_ |
3281 | 3281 |
size_t nread = 0; |
3282 | 3282 |
|
3283 | 3283 |
/* Then check length */ |
3284 |
- if (!length) length = old_len - offset; |
|
3285 |
- if (length > old_len - offset) { |
|
3284 |
+ if (!length) |
|
3285 |
+ length = old_len - offset; |
|
3286 |
+ if (length > old_len - offset) |
|
3287 |
+ { |
|
3286 | 3288 |
cli_dbgmsg("cli_map_scan: Data truncated: %lu -> %lu\n", |
3287 | 3289 |
(unsigned long)length, (unsigned long)(old_len - offset)); |
3288 | 3290 |
length = old_len - offset; |
3289 | 3291 |
} |
3290 |
- if (length <= 5) { |
|
3291 |
- cli_dbgmsg("cli_map_scan: Small data (%u bytes)\n", (unsigned int) length); |
|
3292 |
+ if (length <= 5) |
|
3293 |
+ { |
|
3294 |
+ cli_dbgmsg("cli_map_scan: Small data (%u bytes)\n", (unsigned int)length); |
|
3292 | 3295 |
return CL_CLEAN; |
3293 | 3296 |
} |
3294 |
- if (!CLI_ISCONTAINED(old_off, old_len, old_off + offset, length)) { |
|
3297 |
+ if (!CLI_ISCONTAINED(old_off, old_len, old_off + offset, length)) |
|
3298 |
+ { |
|
3295 | 3299 |
cli_dbgmsg("cli_map_scan: map error occurred [%ld, %lu]\n", |
3296 | 3300 |
(long)old_off, (unsigned long)old_len); |
3297 | 3301 |
return CL_CLEAN; |
... | ... |
@@ -3299,18 +3686,21 @@ int cli_map_scan(cl_fmap_t *map, off_t offset, size_t length, cli_ctx *ctx, cli_ |
3299 | 3299 |
|
3300 | 3300 |
/* Length checked, now get map */ |
3301 | 3301 |
mapdata = fmap_need_off_once_len(map, offset, length, &nread); |
3302 |
- if (!mapdata || (nread != length)) { |
|
3302 |
+ if (!mapdata || (nread != length)) |
|
3303 |
+ { |
|
3303 | 3304 |
cli_errmsg("cli_map_scan: could not map sub-file\n"); |
3304 | 3305 |
return CL_EMAP; |
3305 | 3306 |
} |
3306 | 3307 |
|
3307 | 3308 |
ret = cli_gentempfd(ctx->engine->tmpdir, &tempfile, &fd); |
3308 |
- if (ret != CL_SUCCESS) { |
|
3309 |
+ if (ret != CL_SUCCESS) |
|
3310 |
+ { |
|
3309 | 3311 |
return ret; |
3310 | 3312 |
} |
3311 | 3313 |
|
3312 | 3314 |
cli_dbgmsg("cli_map_scan: writing nested map content to temp file %s\n", tempfile); |
3313 |
- if (cli_writen(fd, mapdata, length) < 0) { |
|
3315 |
+ if (cli_writen(fd, mapdata, length) < 0) |
|
3316 |
+ { |
|
3314 | 3317 |
cli_errmsg("cli_map_scan: cli_writen error writing subdoc temporary file.\n"); |
3315 | 3318 |
ret = CL_EWRITE; |
3316 | 3319 |
} |
... | ... |
@@ -3319,18 +3709,22 @@ int cli_map_scan(cl_fmap_t *map, off_t offset, size_t length, cli_ctx *ctx, cli_ |
3319 | 3319 |
ret = cli_base_scandesc(fd, ctx, type); |
3320 | 3320 |
|
3321 | 3321 |
/* remove the temp file, if needed */ |
3322 |
- if (fd >= 0) { |
|
3322 |
+ if (fd >= 0) |
|
3323 |
+ { |
|
3323 | 3324 |
close(fd); |
3324 | 3325 |
} |
3325 |
- if(!ctx->engine->keeptmp) { |
|
3326 |
- if (cli_unlink(tempfile)) { |
|
3326 |
+ if (!ctx->engine->keeptmp) |
|
3327 |
+ { |
|
3328 |
+ if (cli_unlink(tempfile)) |
|
3329 |
+ { |
|
3327 | 3330 |
cli_errmsg("cli_map_scan: error unlinking tempfile %s\n", tempfile); |
3328 | 3331 |
ret = CL_EUNLINK; |
3329 | 3332 |
} |
3330 | 3333 |
} |
3331 | 3334 |
free(tempfile); |
3332 | 3335 |
} |
3333 |
- else { |
|
3336 |
+ else |
|
3337 |
+ { |
|
3334 | 3338 |
/* Not forced to disk, use nested map */ |
3335 | 3339 |
ret = cli_map_scandesc(map, offset, length, ctx, type); |
3336 | 3340 |
} |
... | ... |
@@ -3346,23 +3740,27 @@ int cli_map_scandesc(cl_fmap_t *map, off_t offset, size_t length, cli_ctx *ctx, |
3346 | 3346 |
int ret = CL_CLEAN; |
3347 | 3347 |
|
3348 | 3348 |
cli_dbgmsg("cli_map_scandesc: [%ld, +%lu), [%ld, +%lu)\n", |
3349 |
- (long)old_off, (unsigned long)old_len, |
|
3350 |
- (long)offset, (unsigned long)length); |
|
3351 |
- if (offset < 0 || (size_t)offset >= old_len) { |
|
3352 |
- cli_dbgmsg("Invalid offset: %ld\n", (long)offset); |
|
3353 |
- return CL_CLEAN; |
|
3349 |
+ (long)old_off, (unsigned long)old_len, |
|
3350 |
+ (long)offset, (unsigned long)length); |
|
3351 |
+ if (offset < 0 || (size_t)offset >= old_len) |
|
3352 |
+ { |
|
3353 |
+ cli_dbgmsg("Invalid offset: %ld\n", (long)offset); |
|
3354 |
+ return CL_CLEAN; |
|
3354 | 3355 |
} |
3355 | 3356 |
|
3356 |
- if (!length) length = old_len - offset; |
|
3357 |
- if (length > old_len - offset) { |
|
3358 |
- cli_dbgmsg("Data truncated: %lu -> %lu\n", |
|
3359 |
- (unsigned long)length, old_len - offset); |
|
3360 |
- length = old_len - offset; |
|
3357 |
+ if (!length) |
|
3358 |
+ length = old_len - offset; |
|
3359 |
+ if (length > old_len - offset) |
|
3360 |
+ { |
|
3361 |
+ cli_dbgmsg("Data truncated: %zu -> %zu\n", |
|
3362 |
+ length, old_len - (size_t)offset); |
|
3363 |
+ length = old_len - (size_t)offset; |
|
3361 | 3364 |
} |
3362 | 3365 |
|
3363 |
- if (length <= 5) { |
|
3364 |
- cli_dbgmsg("Small data (%u bytes)\n", (unsigned int) length); |
|
3365 |
- return CL_CLEAN; |
|
3366 |
+ if (length <= 5) |
|
3367 |
+ { |
|
3368 |
+ cli_dbgmsg("Small data (%u bytes)\n", (unsigned int)length); |
|
3369 |
+ return CL_CLEAN; |
|
3366 | 3370 |
} |
3367 | 3371 |
ctx->fmap++; |
3368 | 3372 |
*ctx->fmap = map; |
... | ... |
@@ -3371,14 +3769,17 @@ int cli_map_scandesc(cl_fmap_t *map, off_t offset, size_t length, cli_ctx *ctx, |
3371 | 3371 |
map->nested_offset += offset; |
3372 | 3372 |
map->len = length; |
3373 | 3373 |
map->real_len = map->nested_offset + length; |
3374 |
- if (CLI_ISCONTAINED(old_off, old_len, map->nested_offset, map->len)) { |
|
3375 |
- ret = magic_scandesc(ctx, type); |
|
3376 |
- } else { |
|
3377 |
- long long len1, len2; |
|
3378 |
- len1 = old_off + old_len; |
|
3374 |
+ if (CLI_ISCONTAINED(old_off, old_len, map->nested_offset, map->len)) |
|
3375 |
+ { |
|
3376 |
+ ret = magic_scandesc(ctx, type); |
|
3377 |
+ } |
|
3378 |
+ else |
|
3379 |
+ { |
|
3380 |
+ long long len1, len2; |
|
3381 |
+ len1 = old_off + old_len; |
|
3379 | 3382 |
len2 = map->nested_offset + map->len; |
3380 |
- cli_warnmsg("internal map error: %lu, %llu; %lu, %llu\n", (long unsigned)old_off, |
|
3381 |
- (long long unsigned)len1, (long unsigned)map->offset, (long long unsigned)len2); |
|
3383 |
+ cli_warnmsg("internal map error: %lu, %llu; %lu, %llu\n", (long unsigned)old_off, |
|
3384 |
+ (long long unsigned)len1, (long unsigned)map->offset, (long long unsigned)len2); |
|
3382 | 3385 |
} |
3383 | 3386 |
|
3384 | 3387 |
ctx->fmap--; |
... | ... |
@@ -3392,8 +3793,9 @@ int cli_mem_scandesc(const void *buffer, size_t length, cli_ctx *ctx) |
3392 | 3392 |
{ |
3393 | 3393 |
int ret; |
3394 | 3394 |
fmap_t *map = cl_fmap_open_memory(buffer, length); |
3395 |
- if (!map) { |
|
3396 |
- return CL_EMAP; |
|
3395 |
+ if (!map) |
|
3396 |
+ { |
|
3397 |
+ return CL_EMAP; |
|
3397 | 3398 |
} |
3398 | 3399 |
ret = cli_map_scan(map, 0, length, ctx, CL_TYPE_ANY); |
3399 | 3400 |
cl_fmap_close(map); |
... | ... |
@@ -3407,10 +3809,13 @@ static int scan_common(int desc, cl_fmap_t *map, const char **virname, unsigned |
3407 | 3407 |
STATBUF sb; |
3408 | 3408 |
|
3409 | 3409 |
/* We have a limit of around 2.17GB (INT_MAX - 2). Enforce it here. */ |
3410 |
- if (map != NULL) { |
|
3410 |
+ if (map != NULL) |
|
3411 |
+ { |
|
3411 | 3412 |
if ((size_t)(map->real_len) > (size_t)(INT_MAX - 2)) |
3412 | 3413 |
return CL_CLEAN; |
3413 |
- } else { |
|
3414 |
+ } |
|
3415 |
+ else |
|
3416 |
+ { |
|
3414 | 3417 |
if (FSTAT(desc, &sb)) |
3415 | 3418 |
return CL_ESTAT; |
3416 | 3419 |
|
... | ... |
@@ -3425,67 +3830,80 @@ static int scan_common(int desc, cl_fmap_t *map, const char **virname, unsigned |
3425 | 3425 |
ctx.options = scanoptions; |
3426 | 3426 |
ctx.found_possibly_unwanted = 0; |
3427 | 3427 |
ctx.containers = cli_calloc(sizeof(cli_ctx_container), ctx.engine->maxreclevel + 2); |
3428 |
- if(!ctx.containers) |
|
3429 |
- return CL_EMEM; |
|
3428 |
+ if (!ctx.containers) |
|
3429 |
+ return CL_EMEM; |
|
3430 | 3430 |
cli_set_container(&ctx, CL_TYPE_ANY, 0); |
3431 |
- ctx.dconf = (struct cli_dconf *) engine->dconf; |
|
3431 |
+ ctx.dconf = (struct cli_dconf *)engine->dconf; |
|
3432 | 3432 |
ctx.cb_ctx = context; |
3433 | 3433 |
ctx.fmap = cli_calloc(sizeof(fmap_t *), ctx.engine->maxreclevel + 2); |
3434 |
- if(!ctx.fmap) |
|
3435 |
- return CL_EMEM; |
|
3436 |
- if (!(ctx.hook_lsig_matches = cli_bitset_init())) { |
|
3437 |
- free(ctx.fmap); |
|
3438 |
- return CL_EMEM; |
|
3434 |
+ if (!ctx.fmap) |
|
3435 |
+ return CL_EMEM; |
|
3436 |
+ if (!(ctx.hook_lsig_matches = cli_bitset_init())) |
|
3437 |
+ { |
|
3438 |
+ free(ctx.fmap); |
|
3439 |
+ return CL_EMEM; |
|
3439 | 3440 |
} |
3440 | 3441 |
perf_init(&ctx); |
3441 | 3442 |
|
3442 |
- if (ctx.options & CL_SCAN_FILE_PROPERTIES && ctx.engine->time_limit != 0) { |
|
3443 |
- if (gettimeofday(&ctx.time_limit, NULL) == 0) { |
|
3443 |
+ if (ctx.options & CL_SCAN_FILE_PROPERTIES && ctx.engine->time_limit != 0) |
|
3444 |
+ { |
|
3445 |
+ if (gettimeofday(&ctx.time_limit, NULL) == 0) |
|
3446 |
+ { |
|
3444 | 3447 |
uint32_t secs = ctx.engine->time_limit / 1000; |
3445 | 3448 |
uint32_t usecs = (ctx.engine->time_limit % 1000) * 1000; |
3446 | 3449 |
ctx.time_limit.tv_sec += secs; |
3447 | 3450 |
ctx.time_limit.tv_usec += usecs; |
3448 |
- if (ctx.time_limit.tv_usec >= 1000000) { |
|
3451 |
+ if (ctx.time_limit.tv_usec >= 1000000) |
|
3452 |
+ { |
|
3449 | 3453 |
ctx.time_limit.tv_usec -= 1000000; |
3450 | 3454 |
ctx.time_limit.tv_sec++; |
3451 | 3455 |
} |
3452 |
- } else { |
|
3456 |
+ } |
|
3457 |
+ else |
|
3458 |
+ { |
|
3453 | 3459 |
char buf[64]; |
3454 | 3460 |
cli_dbgmsg("scan_common; gettimeofday error: %s\n", cli_strerror(errno, buf, 64)); |
3455 | 3461 |
} |
3456 | 3462 |
} |
3457 | 3463 |
|
3458 | 3464 |
#ifdef HAVE__INTERNAL__SHA_COLLECT |
3459 |
- if(scanoptions & CL_SCAN_INTERNAL_COLLECT_SHA) { |
|
3460 |
- char link[32]; |
|
3461 |
- ssize_t linksz; |
|
3462 |
- |
|
3463 |
- |
|
3464 |
- snprintf(link, sizeof(link), "/proc/self/fd/%u", desc); |
|
3465 |
- link[sizeof(link)-1]='\0'; |
|
3466 |
- if((linksz=readlink(link, ctx.entry_filename, sizeof(ctx.entry_filename)-1))==-1) { |
|
3467 |
- cli_errmsg("failed to resolve filename for descriptor %d (%s)\n", desc, link); |
|
3468 |
- strcpy(ctx.entry_filename, "NO_IDEA"); |
|
3469 |
- } else |
|
3470 |
- ctx.entry_filename[linksz]='\0'; |
|
3471 |
- } while(0); |
|
3465 |
+ if (scanoptions & CL_SCAN_INTERNAL_COLLECT_SHA) |
|
3466 |
+ { |
|
3467 |
+ char link[32]; |
|
3468 |
+ ssize_t linksz; |
|
3469 |
+ |
|
3470 |
+ snprintf(link, sizeof(link), "/proc/self/fd/%u", desc); |
|
3471 |
+ link[sizeof(link) - 1] = '\0'; |
|
3472 |
+ if ((linksz = readlink(link, ctx.entry_filename, sizeof(ctx.entry_filename) - 1)) == -1) |
|
3473 |
+ { |
|
3474 |
+ cli_errmsg("failed to resolve filename for descriptor %d (%s)\n", desc, link); |
|
3475 |
+ strcpy(ctx.entry_filename, "NO_IDEA"); |
|
3476 |
+ } |
|
3477 |
+ else |
|
3478 |
+ ctx.entry_filename[linksz] = '\0'; |
|
3479 |
+ } |
|
3480 |
+ while (0) |
|
3481 |
+ ; |
|
3472 | 3482 |
#endif |
3473 | 3483 |
|
3474 | 3484 |
cli_logg_setup(&ctx); |
3475 | 3485 |
rc = map ? cli_map_scandesc(map, 0, map->len, &ctx, CL_TYPE_ANY) : cli_magic_scandesc(desc, &ctx); |
3476 | 3486 |
|
3477 | 3487 |
#if HAVE_JSON |
3478 |
- if (ctx.options & CL_SCAN_FILE_PROPERTIES && ctx.properties!=NULL) { |
|
3488 |
+ if (ctx.options & CL_SCAN_FILE_PROPERTIES && ctx.properties != NULL) |
|
3489 |
+ { |
|
3479 | 3490 |
json_object *jobj; |
3480 | 3491 |
const char *jstring; |
3481 | 3492 |
|
3482 | 3493 |
/* set value of unique root object tag */ |
3483 |
- if (json_object_object_get_ex(ctx.properties, "FileType", &jobj)) { |
|
3494 |
+ if (json_object_object_get_ex(ctx.properties, "FileType", &jobj)) |
|
3495 |
+ { |
|
3484 | 3496 |
enum json_type type; |
3485 | 3497 |
const char *jstr; |
3486 | 3498 |
|
3487 | 3499 |
type = json_object_get_type(jobj); |
3488 |
- if (type == json_type_string) { |
|
3500 |
+ if (type == json_type_string) |
|
3501 |
+ { |
|
3489 | 3502 |
jstr = json_object_get_string(jobj); |
3490 | 3503 |
cli_jsonstr(ctx.properties, "RootFileType", jstr); |
3491 | 3504 |
} |
... | ... |
@@ -3493,35 +3911,43 @@ static int scan_common(int desc, cl_fmap_t *map, const char **virname, unsigned |
3493 | 3493 |
|
3494 | 3494 |
/* serialize json properties to string */ |
3495 | 3495 |
jstring = json_object_to_json_string(ctx.properties); |
3496 |
- if (NULL == jstring) { |
|
3496 |
+ if (NULL == jstring) |
|
3497 |
+ { |
|
3497 | 3498 |
cli_errmsg("scan_common: no memory for json serialization.\n"); |
3498 | 3499 |
rc = CL_EMEM; |
3499 | 3500 |
} |
3500 |
- else { |
|
3501 |
+ else |
|
3502 |
+ { |
|
3501 | 3503 |
int ret = CL_SUCCESS; |
3502 | 3504 |
struct cli_matcher *iroot = ctx.engine->root[13]; |
3503 | 3505 |
cli_dbgmsg("%s\n", jstring); |
3504 | 3506 |
|
3505 |
- if (rc != CL_VIRUS) { |
|
3507 |
+ if (rc != CL_VIRUS) |
|
3508 |
+ { |
|
3506 | 3509 |
/* run bytecode preclass hook; generate fmap if needed for running hook */ |
3507 | 3510 |
struct cli_bc_ctx *bc_ctx = cli_bytecode_context_alloc(); |
3508 |
- if (!bc_ctx) { |
|
3511 |
+ if (!bc_ctx) |
|
3512 |
+ { |
|
3509 | 3513 |
cli_errmsg("scan_common: can't allocate memory for bc_ctx\n"); |
3510 | 3514 |
rc = CL_EMEM; |
3511 | 3515 |
} |
3512 |
- else { |
|
3516 |
+ else |
|
3517 |
+ { |
|
3513 | 3518 |
fmap_t *pc_map = map; |
3514 | 3519 |
|
3515 |
- if (!pc_map) { |
|
3520 |
+ if (!pc_map) |
|
3521 |
+ { |
|
3516 | 3522 |
perf_start(&ctx, PERFT_MAP); |
3517 |
- if(!(pc_map = fmap(desc, 0, sb.st_size))) { |
|
3523 |
+ if (!(pc_map = fmap(desc, 0, sb.st_size))) |
|
3524 |
+ { |
|
3518 | 3525 |
perf_stop(&ctx, PERFT_MAP); |
3519 | 3526 |
rc = CL_EMEM; |
3520 | 3527 |
} |
3521 | 3528 |
perf_stop(&ctx, PERFT_MAP); |
3522 | 3529 |
} |
3523 | 3530 |
|
3524 |
- if (pc_map) { |
|
3531 |
+ if (pc_map) |
|
3532 |
+ { |
|
3525 | 3533 |
cli_bytecode_context_setctx(bc_ctx, &ctx); |
3526 | 3534 |
rc = cli_bytecode_runhook(&ctx, ctx.engine, bc_ctx, BC_PRECLASS, pc_map); |
3527 | 3535 |
cli_bytecode_context_destroy(bc_ctx); |
... | ... |
@@ -3532,7 +3958,8 @@ static int scan_common(int desc, cl_fmap_t *map, const char **virname, unsigned |
3532 | 3532 |
} |
3533 | 3533 |
|
3534 | 3534 |
/* backwards compatibility: scan the json string unless a virus was detected */ |
3535 |
- if (rc != CL_VIRUS && (iroot->ac_lsigs || iroot->ac_patterns || iroot->pcre_metas)) { |
|
3535 |
+ if (rc != CL_VIRUS && (iroot->ac_lsigs || iroot->ac_patterns || iroot->pcre_metas)) |
|
3536 |
+ { |
|
3536 | 3537 |
cli_dbgmsg("scan_common: running deprecated preclass bytecodes for target type 13\n"); |
3537 | 3538 |
ctx.options &= ~CL_SCAN_FILE_PROPERTIES; |
3538 | 3539 |
rc = cli_mem_scandesc(jstring, strlen(jstring), &ctx); |
... | ... |
@@ -3540,19 +3967,24 @@ static int scan_common(int desc, cl_fmap_t *map, const char **virname, unsigned |
3540 | 3540 |
} |
3541 | 3541 |
|
3542 | 3542 |
/* Invoke file props callback */ |
3543 |
- if (ctx.engine->cb_file_props != NULL) { |
|
3543 |
+ if (ctx.engine->cb_file_props != NULL) |
|
3544 |
+ { |
|
3544 | 3545 |
ret = ctx.engine->cb_file_props(jstring, rc, ctx.cb_ctx); |
3545 | 3546 |
if (ret != CL_SUCCESS) |
3546 | 3547 |
rc = ret; |
3547 | 3548 |
} |
3548 | 3549 |
|
3549 | 3550 |
/* keeptmp file processing for file properties json string */ |
3550 |
- if (ctx.engine->keeptmp) { |
|
3551 |
+ if (ctx.engine->keeptmp) |
|
3552 |
+ { |
|
3551 | 3553 |
int fd = -1; |
3552 |
- char * tmpname = NULL; |
|
3553 |
- if ((ret = cli_gentempfd(ctx.engine->tmpdir, &tmpname, &fd)) != CL_SUCCESS) { |
|
3554 |
+ char *tmpname = NULL; |
|
3555 |
+ if ((ret = cli_gentempfd(ctx.engine->tmpdir, &tmpname, &fd)) != CL_SUCCESS) |
|
3556 |
+ { |
|
3554 | 3557 |
cli_dbgmsg("scan_common: Can't create json properties file, ret = %i.\n", ret); |
3555 |
- } else { |
|
3558 |
+ } |
|
3559 |
+ else |
|
3560 |
+ { |
|
3556 | 3561 |
if (cli_writen(fd, jstring, strlen(jstring)) < 0) |
3557 | 3562 |
cli_dbgmsg("scan_common: cli_writen error writing json properties file.\n"); |
3558 | 3563 |
else |
... | ... |
@@ -3578,10 +4010,11 @@ static int scan_common(int desc, cl_fmap_t *map, const char **virname, unsigned |
3578 | 3578 |
free(ctx.containers); |
3579 | 3579 |
cli_bitset_free(ctx.hook_lsig_matches); |
3580 | 3580 |
free(ctx.fmap); |
3581 |
- if (rc == CL_CLEAN) { |
|
3581 |
+ if (rc == CL_CLEAN) |
|
3582 |
+ { |
|
3582 | 3583 |
if ((ctx.num_viruses != 0 && (ctx.options & (CL_SCAN_ALLMATCHES | CL_SCAN_BLOCKMAX))) || |
3583 | 3584 |
ctx.found_possibly_unwanted) |
3584 |
- rc = CL_VIRUS; |
|
3585 |
+ rc = CL_VIRUS; |
|
3585 | 3586 |
} |
3586 | 3587 |
cli_logg_unsetup(); |
3587 | 3588 |
perf_done(&ctx); |
... | ... |
@@ -3598,23 +4031,27 @@ int cl_scanmap_callback(cl_fmap_t *map, const char **virname, unsigned long int |
3598 | 3598 |
return scan_common(-1, map, virname, scanned, engine, scanoptions, context); |
3599 | 3599 |
} |
3600 | 3600 |
|
3601 |
-int cli_found_possibly_unwanted(cli_ctx* ctx) |
|
3601 |
+int cli_found_possibly_unwanted(cli_ctx *ctx) |
|
3602 | 3602 |
{ |
3603 |
- if(cli_get_last_virus(ctx)) { |
|
3604 |
- cli_dbgmsg("found Possibly Unwanted: %s\n", cli_get_last_virus(ctx)); |
|
3605 |
- if(ctx->options & CL_SCAN_HEURISTIC_PRECEDENCE) { |
|
3606 |
- /* we found a heuristic match, don't scan further, |
|
3607 |
- * but consider it a virus. */ |
|
3608 |
- cli_dbgmsg("cli_found_possibly_unwanted: CL_VIRUS\n"); |
|
3609 |
- return CL_VIRUS; |
|
3610 |
- } |
|
3611 |
- /* heuristic scan isn't taking precedence, keep scanning. |
|
3612 |
- * If this is part of an archive, and |
|
3613 |
- * we find a real malware we report that instead of the |
|
3614 |
- * heuristic match */ |
|
3615 |
- ctx->found_possibly_unwanted = 1; |
|
3616 |
- } else { |
|
3617 |
- cli_warnmsg("cli_found_possibly_unwanted called, but virname is not set\n"); |
|
3603 |
+ if (cli_get_last_virus(ctx)) |
|
3604 |
+ { |
|
3605 |
+ cli_dbgmsg("found Possibly Unwanted: %s\n", cli_get_last_virus(ctx)); |
|
3606 |
+ if (ctx->options & CL_SCAN_HEURISTIC_PRECEDENCE) |
|
3607 |
+ { |
|
3608 |
+ /* we found a heuristic match, don't scan further, |
|
3609 |
+ * but consider it a virus. */ |
|
3610 |
+ cli_dbgmsg("cli_found_possibly_unwanted: CL_VIRUS\n"); |
|
3611 |
+ return CL_VIRUS; |
|
3612 |
+ } |
|
3613 |
+ /* heuristic scan isn't taking precedence, keep scanning. |
|
3614 |
+ * If this is part of an archive, and |
|
3615 |
+ * we find a real malware we report that instead of the |
|
3616 |
+ * heuristic match */ |
|
3617 |
+ ctx->found_possibly_unwanted = 1; |
|
3618 |
+ } |
|
3619 |
+ else |
|
3620 |
+ { |
|
3621 |
+ cli_warnmsg("cli_found_possibly_unwanted called, but virname is not set\n"); |
|
3618 | 3622 |
} |
3619 | 3623 |
emax_reached(ctx); |
3620 | 3624 |
return CL_CLEAN; |
... | ... |
@@ -3622,11 +4059,11 @@ int cli_found_possibly_unwanted(cli_ctx* ctx) |
3622 | 3622 |
|
3623 | 3623 |
static int cli_scanfile(const char *filename, cli_ctx *ctx) |
3624 | 3624 |
{ |
3625 |
- int fd, ret; |
|
3625 |
+ int fd, ret; |
|
3626 | 3626 |
|
3627 | 3627 |
/* internal version of cl_scanfile with arec/mrec preserved */ |
3628 |
- if((fd = safe_open(filename, O_RDONLY|O_BINARY)) == -1) |
|
3629 |
- return CL_EOPEN; |
|
3628 |
+ if ((fd = safe_open(filename, O_RDONLY | O_BINARY)) == -1) |
|
3629 |
+ return CL_EOPEN; |
|
3630 | 3630 |
|
3631 | 3631 |
ret = cli_magic_scandesc(fd, ctx); |
3632 | 3632 |
|
... | ... |
@@ -3641,17 +4078,17 @@ int cl_scanfile(const char *filename, const char **virname, unsigned long int *s |
3641 | 3641 |
|
3642 | 3642 |
int cl_scanfile_callback(const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, unsigned int scanoptions, void *context) |
3643 | 3643 |
{ |
3644 |
- int fd, ret; |
|
3645 |
- const char *fname = cli_to_utf8_maybe_alloc(filename); |
|
3644 |
+ int fd, ret; |
|
3645 |
+ const char *fname = cli_to_utf8_maybe_alloc(filename); |
|
3646 | 3646 |
|
3647 |
- if(!fname) |
|
3648 |
- return CL_EARG; |
|
3647 |
+ if (!fname) |
|
3648 |
+ return CL_EARG; |
|
3649 | 3649 |
|
3650 |
- if((fd = safe_open(fname, O_RDONLY|O_BINARY)) == -1) |
|
3651 |
- return CL_EOPEN; |
|
3650 |
+ if ((fd = safe_open(fname, O_RDONLY | O_BINARY)) == -1) |
|
3651 |
+ return CL_EOPEN; |
|
3652 | 3652 |
|
3653 |
- if(fname != filename) |
|
3654 |
- free((void*)fname); |
|
3653 |
+ if (fname != filename) |
|
3654 |
+ free((void *)fname); |
|
3655 | 3655 |
|
3656 | 3656 |
ret = cl_scandesc_callback(fd, virname, scanned, engine, scanoptions, context); |
3657 | 3657 |
close(fd); |