... | ... |
@@ -377,9 +377,21 @@ struct cl_engine *cl_engine_new(void) |
377 | 377 |
return NULL; |
378 | 378 |
} |
379 | 379 |
|
380 |
+ new->pwdbs = mpool_calloc(new->mempool, CLI_PWDB_COUNT, sizeof(struct cli_pwdb *)); |
|
381 |
+ if (!new->pwdbs) { |
|
382 |
+ cli_errmsg("cl_engine_new: Can't initialize password databases\n"); |
|
383 |
+ mpool_free(new->mempool, new->dconf); |
|
384 |
+ mpool_free(new->mempool, new->root); |
|
385 |
+#ifdef USE_MPOOL |
|
386 |
+ mpool_destroy(new->mempool); |
|
387 |
+#endif |
|
388 |
+ free(new); |
|
389 |
+ } |
|
390 |
+ |
|
380 | 391 |
crtmgr_init(&(new->cmgr)); |
381 | 392 |
if(crtmgr_add_roots(new, &(new->cmgr))) { |
382 | 393 |
cli_errmsg("cl_engine_new: Can't initialize root certificates\n"); |
394 |
+ mpool_free(new->mempool, new->pwdbs); |
|
383 | 395 |
mpool_free(new->mempool, new->dconf); |
384 | 396 |
mpool_free(new->mempool, new->root); |
385 | 397 |
#ifdef USE_MPOOL |
... | ... |
@@ -395,6 +407,7 @@ struct cl_engine *cl_engine_new(void) |
395 | 395 |
#ifdef CL_THREAD_SAFE |
396 | 396 |
if (pthread_mutex_init(&(intel->mutex), NULL)) { |
397 | 397 |
cli_errmsg("cli_engine_new: Cannot initialize stats gathering mutex\n"); |
398 |
+ mpool_free(new->mempool, new->pwdbs); |
|
398 | 399 |
mpool_free(new->mempool, new->dconf); |
399 | 400 |
mpool_free(new->mempool, new->root); |
400 | 401 |
#ifdef USE_MPOOL |
... | ... |
@@ -440,6 +453,7 @@ struct cl_engine *cl_engine_new(void) |
440 | 440 |
/* YARA */ |
441 | 441 |
if (cli_yara_init(new) != CL_SUCCESS) { |
442 | 442 |
cli_errmsg("cli_engine_new: failed to initialize YARA\n"); |
443 |
+ mpool_free(new->mempool, new->pwdbs); |
|
443 | 444 |
mpool_free(new->mempool, new->dconf); |
444 | 445 |
mpool_free(new->mempool, new->root); |
445 | 446 |
#ifdef USE_MPOOL |
... | ... |
@@ -230,12 +230,18 @@ struct cli_dbinfo { |
230 | 230 |
struct cli_dbinfo *next; |
231 | 231 |
}; |
232 | 232 |
|
233 |
-struct cli_pwdict { |
|
233 |
+#define CLI_PWDB_COUNT 3 |
|
234 |
+typedef enum { |
|
235 |
+ CLI_PWDB_ANY = 0, |
|
236 |
+ CLI_PWDB_ZIP = 1, |
|
237 |
+ CLI_PWDB_RAR = 2 |
|
238 |
+} cl_pwdb_t; |
|
239 |
+ |
|
240 |
+struct cli_pwdb { |
|
234 | 241 |
char *name; |
235 | 242 |
unsigned char *passwd; |
236 | 243 |
uint16_t length; |
237 |
- cli_file_t container; |
|
238 |
- struct cli_pwdict *next; |
|
244 |
+ struct cli_pwdb *next; |
|
239 | 245 |
}; |
240 | 246 |
|
241 | 247 |
struct cl_engine { |
... | ... |
@@ -295,7 +301,7 @@ struct cl_engine { |
295 | 295 |
struct cli_ftype *ptypes; |
296 | 296 |
|
297 | 297 |
/* Container password storage */ |
298 |
- struct cli_pwdict *pw_dict; |
|
298 |
+ struct cli_pwdb **pwdbs; |
|
299 | 299 |
|
300 | 300 |
/* Ignored signatures */ |
301 | 301 |
struct cli_matcher *ignored; |
... | ... |
@@ -4096,7 +4096,8 @@ static int cli_loadpwdb(FILE *fs, struct cl_engine *engine, unsigned int options |
4096 | 4096 |
char *attribs; |
4097 | 4097 |
char buffer[FILEBUFF]; |
4098 | 4098 |
unsigned int line = 0, skip = 0, pwcnt = 0, tokens_count; |
4099 |
- struct cli_pwdict *new, *ins; |
|
4099 |
+ struct cli_pwdb *new, *ins; |
|
4100 |
+ cl_pwdb_t container; |
|
4100 | 4101 |
struct cli_lsig_tdb tdb; |
4101 | 4102 |
int ret = CL_SUCCESS, pwstype; |
4102 | 4103 |
|
... | ... |
@@ -4152,20 +4153,39 @@ static int cli_loadpwdb(FILE *fs, struct cl_engine *engine, unsigned int options |
4152 | 4152 |
break; |
4153 | 4153 |
} |
4154 | 4154 |
|
4155 |
+ /* check container type */ |
|
4156 |
+ if (!tdb.container) { |
|
4157 |
+ container = CLI_PWDB_ANY; |
|
4158 |
+ } else { |
|
4159 |
+ switch (*(tdb.container)) { |
|
4160 |
+ case CL_TYPE_ANY: |
|
4161 |
+ container = CLI_PWDB_ANY; |
|
4162 |
+ break; |
|
4163 |
+ case CL_TYPE_ZIP: |
|
4164 |
+ container = CLI_PWDB_ZIP; |
|
4165 |
+ break; |
|
4166 |
+ case CL_TYPE_RAR: |
|
4167 |
+ container = CLI_PWDB_RAR; |
|
4168 |
+ break; |
|
4169 |
+ default: |
|
4170 |
+ cli_errmsg("cli_loadpwdb: Invalid conatiner specified to .pwdb signature\n"); |
|
4171 |
+ return CL_EMALFDB; |
|
4172 |
+ } |
|
4173 |
+ } |
|
4174 |
+ FREE_TDB(tdb); |
|
4175 |
+ |
|
4155 | 4176 |
/* check the PWStorageType */ |
4156 | 4177 |
if(!cli_isnumber(tokens[2])) { |
4157 | 4178 |
cli_errmsg("cli_loadpwdb: Invalid value for PWStorageType (third entry)\n"); |
4158 | 4179 |
ret = CL_EMALFDB; |
4159 |
- FREE_TDB(tdb); |
|
4160 | 4180 |
break; |
4161 | 4181 |
} |
4162 | 4182 |
|
4163 | 4183 |
pwstype = atoi(tokens[2]); |
4164 | 4184 |
if((pwstype == 0) || (pwstype == 1)) { |
4165 |
- new = (struct cli_pwdict *) mpool_calloc(engine->mempool, 1, sizeof(struct cli_pwdict)); |
|
4185 |
+ new = (struct cli_pwdb *) mpool_calloc(engine->mempool, 1, sizeof(struct cli_pwdb)); |
|
4166 | 4186 |
if(!new) { |
4167 | 4187 |
ret = CL_EMEM; |
4168 |
- FREE_TDB(tdb); |
|
4169 | 4188 |
break; |
4170 | 4189 |
} |
4171 | 4190 |
|
... | ... |
@@ -4173,7 +4193,6 @@ static int cli_loadpwdb(FILE *fs, struct cl_engine *engine, unsigned int options |
4173 | 4173 |
new->name = cli_mpool_strdup(engine->mempool, tokens[0]); |
4174 | 4174 |
if (!new->name) { |
4175 | 4175 |
ret = CL_EMEM; |
4176 |
- FREE_TDB(tdb); |
|
4177 | 4176 |
mpool_free(engine->mempool, new); |
4178 | 4177 |
break; |
4179 | 4178 |
} |
... | ... |
@@ -4191,33 +4210,14 @@ static int cli_loadpwdb(FILE *fs, struct cl_engine *engine, unsigned int options |
4191 | 4191 |
ret = CL_EMEM; |
4192 | 4192 |
else |
4193 | 4193 |
ret = CL_EMALFDB; |
4194 |
- FREE_TDB(tdb); |
|
4195 |
- mpool_free(engine->mempool, new); |
|
4196 | 4194 |
mpool_free(engine->mempool, new->name); |
4195 |
+ mpool_free(engine->mempool, new); |
|
4197 | 4196 |
break; |
4198 | 4197 |
} |
4199 | 4198 |
|
4200 |
- /* TODO: copy containers in the tdb */ |
|
4201 |
- if (!tdb.container) { |
|
4202 |
- new->container = CL_TYPE_ANY; |
|
4203 |
- } else { |
|
4204 |
- new->container = *(tdb.container); |
|
4205 |
- } |
|
4206 |
- FREE_TDB(tdb); |
|
4207 |
- |
|
4208 | 4199 |
/* add to the engine list, sorted by target type */ |
4209 |
- if(!engine->pw_dict) { |
|
4210 |
- engine->pw_dict = new; |
|
4211 |
- } else if(new->container < engine->pw_dict->container) { |
|
4212 |
- new->next = engine->pw_dict; |
|
4213 |
- engine->pw_dict = new; |
|
4214 |
- } else { |
|
4215 |
- ins = engine->pw_dict; |
|
4216 |
- while(ins->next && (ins->next->container < new->container)) |
|
4217 |
- ins = ins->next; |
|
4218 |
- new->next = ins->next; |
|
4219 |
- ins->next = new; |
|
4220 |
- } |
|
4200 |
+ new->next = engine->pwdbs[container]; |
|
4201 |
+ engine->pwdbs[container] = new; |
|
4221 | 4202 |
} else { |
4222 | 4203 |
cli_dbgmsg("cli_loadpwdb: Unsupported PWStorageType %u\n", pwstype); |
4223 | 4204 |
continue; |
... | ... |
@@ -4846,15 +4846,19 @@ int cl_statchkdir(const struct cl_stat *dbstat) |
4846 | 4846 |
return CL_SUCCESS; |
4847 | 4847 |
} |
4848 | 4848 |
|
4849 |
-void cli_pwfree(const struct cl_engine *engine) |
|
4849 |
+void cli_pwdb_list_free(struct cl_engine *engine, struct cli_pwdb *pwdb) |
|
4850 | 4850 |
{ |
4851 |
- struct cli_pwdict *pw = engine->pw_dict, *pt; |
|
4851 |
+ struct cli_pwdb *thiz, *that; |
|
4852 | 4852 |
|
4853 |
- while(pw) { |
|
4854 |
- pt = pw; |
|
4855 |
- pw = pw->next; |
|
4856 |
- mpool_free(engine->mempool, pt->passwd); |
|
4857 |
- mpool_free(engine->mempool, pt); |
|
4853 |
+ thiz = pwdb; |
|
4854 |
+ while (thiz) { |
|
4855 |
+ that = thiz->next; |
|
4856 |
+ |
|
4857 |
+ mpool_free(engine->mempool, thiz->name); |
|
4858 |
+ mpool_free(engine->mempool, thiz->passwd); |
|
4859 |
+ mpool_free(engine->mempool, thiz); |
|
4860 |
+ |
|
4861 |
+ thiz = that; |
|
4858 | 4862 |
} |
4859 | 4863 |
} |
4860 | 4864 |
|
... | ... |
@@ -5014,6 +5018,13 @@ int cl_engine_free(struct cl_engine *engine) |
5014 | 5014 |
mpool_free(engine->mempool, engine->dconf); |
5015 | 5015 |
} |
5016 | 5016 |
|
5017 |
+ if(engine->pwdbs) { |
|
5018 |
+ for(i = 0; i < CLI_PWDB_COUNT; i++) |
|
5019 |
+ if(engine->pwdbs[i]) |
|
5020 |
+ cli_pwdb_list_free(engine, engine->pwdbs[i]); |
|
5021 |
+ mpool_free(engine->mempool, engine->pwdbs); |
|
5022 |
+ } |
|
5023 |
+ |
|
5017 | 5024 |
if(engine->pua_cats) |
5018 | 5025 |
mpool_free(engine->mempool, engine->pua_cats); |
5019 | 5026 |
|
... | ... |
@@ -5053,8 +5064,6 @@ int cl_engine_free(struct cl_engine *engine) |
5053 | 5053 |
mpool_free(engine->mempool, engine->ignored); |
5054 | 5054 |
} |
5055 | 5055 |
|
5056 |
- cli_pwfree(engine); |
|
5057 |
- |
|
5058 | 5056 |
#ifdef USE_MPOOL |
5059 | 5057 |
if(engine->mempool) mpool_destroy(engine->mempool); |
5060 | 5058 |
#endif |
... | ... |
@@ -5088,7 +5097,7 @@ int cl_engine_compile(struct cl_engine *engine) |
5088 | 5088 |
return ret; |
5089 | 5089 |
|
5090 | 5090 |
/* handle default passwords */ |
5091 |
- if(!engine->pw_dict) |
|
5091 |
+ if(!engine->pwdbs[0] && !engine->pwdbs[1] && !engine->pwdbs[2]) |
|
5092 | 5092 |
if((ret = cli_loadpwdb(NULL, engine, 0, 1, NULL))) |
5093 | 5093 |
return ret; |
5094 | 5094 |
|
... | ... |
@@ -328,7 +328,7 @@ static inline void zupdatekey(uint32_t key[3], unsigned char input) |
328 | 328 |
} |
329 | 329 |
|
330 | 330 |
/* zip init keys */ |
331 |
-static inline void zinitkey(uint32_t key[3], struct cli_pwdict *password) |
|
331 |
+static inline void zinitkey(uint32_t key[3], struct cli_pwdb *password) |
|
332 | 332 |
{ |
333 | 333 |
int i; |
334 | 334 |
|
... | ... |
@@ -357,7 +357,7 @@ static inline int zdecrypt(const uint8_t *src, uint32_t csize, uint32_t usize, c |
357 | 357 |
int i, ret, v = 0; |
358 | 358 |
uint32_t key[3]; |
359 | 359 |
uint8_t eh[12]; /* encryption header buffer */ |
360 |
- struct cli_pwdict *password; |
|
360 |
+ struct cli_pwdb *password, *pass_any, *pass_zip; |
|
361 | 361 |
|
362 | 362 |
if (!ctx || !ctx->engine) |
363 | 363 |
return CL_ENULLARG; |
... | ... |
@@ -368,15 +368,11 @@ static inline int zdecrypt(const uint8_t *src, uint32_t csize, uint32_t usize, c |
368 | 368 |
return CL_SUCCESS; |
369 | 369 |
} |
370 | 370 |
|
371 |
- password = ctx->engine->pw_dict; |
|
371 |
+ pass_any = ctx->engine->pwdbs[CLI_PWDB_ANY]; |
|
372 |
+ pass_zip = ctx->engine->pwdbs[CLI_PWDB_ZIP]; |
|
372 | 373 |
|
373 |
- while (password) { |
|
374 |
- if ((password->container != CL_TYPE_ANY) && (password->container != CL_TYPE_ZIP)) { |
|
375 |
- if ((password->container > CL_TYPE_ZIP) && (password->container > CL_TYPE_ANY)) |
|
376 |
- break; |
|
377 |
- password = password->next; |
|
378 |
- continue; |
|
379 |
- } |
|
374 |
+ while (pass_any || pass_zip) { |
|
375 |
+ password = pass_zip ? pass_zip : pass_any; |
|
380 | 376 |
|
381 | 377 |
zinitkey(key, password); |
382 | 378 |
|
... | ... |
@@ -490,7 +486,10 @@ static inline int zdecrypt(const uint8_t *src, uint32_t csize, uint32_t usize, c |
490 | 490 |
return ret; |
491 | 491 |
} |
492 | 492 |
|
493 |
- password = password->next; |
|
493 |
+ if (pass_zip) |
|
494 |
+ pass_zip = pass_zip->next; |
|
495 |
+ else |
|
496 |
+ pass_any = pass_any->next; |
|
494 | 497 |
} |
495 | 498 |
|
496 | 499 |
cli_dbgmsg("cli_unzip: decrypt - skipping encrypted file, no valid passwords\n"); |