Browse code

pwdb: restructured storage for time efficiency

Kevin Lin authored on 2015/07/21 04:00:18
Showing 4 changed files
... ...
@@ -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");