Browse code

sigtool: create digitally signed .info files libclamav: temporarily disable .info checking - needs to be updated to the new format; sigtool/signd must be updated on SI

Tomasz Kojm authored on 2010/01/22 07:02:15
Showing 3 changed files
... ...
@@ -1,3 +1,7 @@
1
+Thu Jan 21 23:01:34 CET 2010 (tk)
2
+---------------------------------
3
+ * sigtool: create digitally signed .info files
4
+
1 5
 Wed Jan 20 23:53:36 CET 2010 (acab)
2 6
 -----------------------------------
3 7
  * libclamav/pe.c: fix handling of 15h byte skew in upx-lzma (bb#1591)
... ...
@@ -307,7 +307,8 @@ static int cli_tgzload(int fd, struct cl_engine *engine, unsigned int *signo, un
307 307
 	else
308 308
 	    off = ftell(dbio->fs);
309 309
 
310
-	if((!dbinfo && cli_strbcasestr(name, ".info")) || (dbinfo && CLI_DBEXT(name))) {
310
+	/*if((!dbinfo && cli_strbcasestr(name, ".info")) || (dbinfo && CLI_DBEXT(name))) {*/
311
+	if(CLI_DBEXT(name)) {
311 312
 	    ret = cli_load(name, engine, signo, options, dbio);
312 313
 	    if(ret) {
313 314
 		cli_errmsg("cli_tgzload: Can't load %s\n", name);
... ...
@@ -315,6 +316,7 @@ static int cli_tgzload(int fd, struct cl_engine *engine, unsigned int *signo, un
315 315
 		CLOSE_DBIO;
316 316
 		return CL_EMALFDB;
317 317
 	    }
318
+	    /*
318 319
 	    if(!dbinfo) {
319 320
 		free(dbio->buf);
320 321
 		CLOSE_DBIO;
... ...
@@ -330,7 +332,6 @@ static int cli_tgzload(int fd, struct cl_engine *engine, unsigned int *signo, un
330 330
 		    return CL_EMALFDB;
331 331
 		}
332 332
 		if(dbio->bread) {
333
-		    /* TODO: compare sizes; replace with sha256 */
334 333
 		    cli_md5_final(hash, &dbio->md5ctx);
335 334
 		    if(memcmp(db->hash, hash, 16)) {
336 335
 			cli_errmsg("cli_tgzload: Invalid checksum for file %s\n", name);
... ...
@@ -340,6 +341,7 @@ static int cli_tgzload(int fd, struct cl_engine *engine, unsigned int *signo, un
340 340
 		    }
341 341
 		}
342 342
 	    }
343
+	    */
343 344
 	}
344 345
 	pad = size % TAR_BLOCKSIZE ? (TAR_BLOCKSIZE - (size % TAR_BLOCKSIZE)) : 0;
345 346
 	if(compr) {
... ...
@@ -601,13 +603,16 @@ int cli_cvdload(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigne
601 601
 	return CL_ESEEK;
602 602
     }
603 603
 
604
+    /*
604 605
     ret = cli_tgzload(cfd, engine, signo, options | CL_DB_OFFICIAL, &dbio, NULL);
605 606
     if(ret != CL_SUCCESS)
606 607
 	return ret;
607
-    /* TODO: check CVD header */
608
+
609
+    * TODO: check CVD header 
608 610
     dbinfo = engine->dbinfo ? engine->dbinfo->next : NULL;
609 611
     if(!dbinfo)
610 612
 	return CL_EMALFDB;
613
+    */
611 614
 
612 615
     ret = cli_tgzload(cfd, engine, signo, options | CL_DB_OFFICIAL, &dbio, dbinfo);
613 616
 
... ...
@@ -304,7 +304,7 @@ static char *getdsig(const char *host, const char *user, const unsigned char *da
304 304
 	    return NULL;
305 305
 	}
306 306
 #endif
307
-	if(scanf("%as", &pt) == EOF) {
307
+	if(scanf("%as", &pt) == EOF || !pt) {
308 308
 	    mprintf("!getdsig: Can't get password\n");
309 309
 #ifdef HAVE_TERMIOS_H
310 310
 	    tcsetattr(0, TCSAFLUSH, &old);
... ...
@@ -346,9 +346,11 @@ static char *getdsig(const char *host, const char *user, const unsigned char *da
346 346
     memset(cmd, 0, sizeof(cmd));
347 347
 
348 348
     if(mode == 1)
349
+	snprintf(cmd, sizeof(cmd) - datalen, "ClamSign:%s:%s:", user, pass);
350
+    else if(mode == 2)
349 351
 	snprintf(cmd, sizeof(cmd) - datalen, "ClamSignPSS:%s:%s:", user, pass);
350 352
     else
351
-	snprintf(cmd, sizeof(cmd) - datalen, "ClamSign:%s:%s:", user, pass);
353
+	snprintf(cmd, sizeof(cmd) - datalen, "ClamSignPSS2:%s:%s:", user, pass);
352 354
 
353 355
     len = strlen(cmd);
354 356
     pt = cmd + len;
... ...
@@ -389,13 +391,44 @@ static char *getdsig(const char *host, const char *user, const unsigned char *da
389 389
     return strdup(pt);
390 390
 }
391 391
 
392
-static int writeinfo(const char *dbname, const char *header)
392
+static char *sha256file(const char *file, unsigned int *size)
393 393
 {
394 394
 	FILE *fh;
395
-	unsigned int i;
396
-	char file[32], *md5;
395
+	unsigned int i, bytes;
396
+	unsigned char digest[32], buffer[FILEBUFF];
397
+	char *sha;
398
+	SHA256_CTX ctx;
397 399
 
398 400
 
401
+    sha256_init(&ctx);
402
+    if(!(fh = fopen(file, "r"))) {
403
+	mprintf("!sha256file: Can't open file %s\n", file);
404
+	return NULL;
405
+    }
406
+    if(size)
407
+	*size = 0;
408
+    while((bytes = fread(buffer, 1, sizeof(buffer), fh))) {
409
+	sha256_update(&ctx, buffer, bytes);
410
+	if(size)
411
+	    *size += bytes;
412
+    }
413
+    sha256_final(&ctx, digest);
414
+    sha = (char *) malloc(65);
415
+    if(!sha)
416
+	return NULL;
417
+    for(i = 0; i < 32; i++)
418
+	sprintf(sha + i * 2, "%02x", digest[i]);
419
+    return sha;
420
+}
421
+
422
+static int writeinfo(const char *dbname, const char *builder, const char *header, const struct optstruct *opts)
423
+{
424
+	FILE *fh;
425
+	unsigned int i, bytes;
426
+	char file[32], *pt;
427
+	unsigned char digest[32], buffer[FILEBUFF];
428
+	SHA256_CTX ctx;
429
+
399 430
     snprintf(file, sizeof(file), "%s.info", dbname);
400 431
     if(!access(file, R_OK)) {
401 432
 	if(unlink(file) == -1) {
... ...
@@ -404,7 +437,7 @@ static int writeinfo(const char *dbname, const char *header)
404 404
 	}
405 405
     }
406 406
 
407
-    if(!(fh = fopen(file, "w"))) {
407
+    if(!(fh = fopen(file, "w+"))) {
408 408
 	mprintf("!writeinfo: Can't create file %s\n", file);
409 409
 	return -1;
410 410
     }
... ...
@@ -417,21 +450,33 @@ static int writeinfo(const char *dbname, const char *header)
417 417
 
418 418
     for(i = 0; dblist[i].name; i++) {
419 419
 	if(!cli_strbcasestr(dblist[i].name, ".info") && strstr(dblist[i].name, dbname) && !access(dblist[i].name, R_OK)) {
420
-	    if(!(md5 = cli_md5file(dblist[i].name))) {
421
-		mprintf("!writeinfo: Can't generate MD5 checksum for %s\n", file);
420
+	    if(!(pt = sha256file(dblist[i].name, &bytes))) {
421
+		mprintf("!writeinfo: Can't generate SHA256 for %s\n", file);
422 422
 		fclose(fh);
423 423
 		return -1;
424 424
 	    }
425
-	    if(fprintf(fh, "%s:%s\n", dblist[i].name, md5) < 0) {
425
+	    if(fprintf(fh, "%s:%u:%s\n", dblist[i].name, bytes, pt) < 0) {
426 426
 		mprintf("!writeinfo: Can't write to info file\n");
427 427
 		fclose(fh);
428
-		free(md5);
428
+		free(pt);
429 429
 		return -1;
430 430
 	    }
431
-	    free(md5);
431
+	    free(pt);
432 432
 	}
433 433
     }
434 434
 
435
+    rewind(fh);
436
+    sha256_init(&ctx);
437
+    while((bytes = fread(buffer, 1, sizeof(buffer), fh)))
438
+	sha256_update(&ctx, buffer, bytes);
439
+    sha256_final(&ctx, digest);
440
+    if(!(pt = getdsig(optget(opts, "server")->strarg, builder, digest, 32, 3))) {
441
+	mprintf("!writeinfo: Can't get digital signature from remote server\n");
442
+	fclose(fh);
443
+	return -1;
444
+    }
445
+    fprintf(fh, "DSIG:%s", pt);
446
+    free(pt);
435 447
     fclose(fh);
436 448
     return 0;
437 449
 }
... ...
@@ -535,7 +580,7 @@ static int script2cdiff(const char *script, const char *builder, const struct op
535 535
     fclose(cdiffh);
536 536
     sha256_final(&ctx, digest);
537 537
 
538
-    if(!(pt = getdsig(optget(opts, "server")->strarg, builder, digest, 32, 1))) {
538
+    if(!(pt = getdsig(optget(opts, "server")->strarg, builder, digest, 32, 2))) {
539 539
 	mprintf("!script2cdiff: Can't get digital signature from remote server\n");
540 540
 	unlink(cdiff);
541 541
 	free(cdiff);
... ...
@@ -691,7 +736,7 @@ static int build(const struct optstruct *opts)
691 691
 	builder[sizeof(builder)-1]='\0';
692 692
     } else {
693 693
 	mprintf("Builder name: ");
694
-	if(scanf("%as", &pt) == EOF) {
694
+	if(scanf("%as", &pt) == EOF || !pt) {
695 695
 	    mprintf("!build: Can't get builder name\n");
696 696
 	    return -1;
697 697
 	}
... ...
@@ -706,7 +751,7 @@ static int build(const struct optstruct *opts)
706 706
     /* add current time */
707 707
     sprintf(header + strlen(header), ":%u", (unsigned int) timet);
708 708
 
709
-    if(writeinfo(dbname, header) == -1) {
709
+    if(writeinfo(dbname, builder, header, opts) == -1) {
710 710
 	mprintf("!build: Can't generate info file\n");
711 711
 	return -1;
712 712
     }
... ...
@@ -763,7 +808,7 @@ static int build(const struct optstruct *opts)
763 763
     sprintf(header + strlen(header), "%s:", pt);
764 764
     free(pt);
765 765
 
766
-    if(!(pt = getdsig(optget(opts, "server")->strarg, builder, buffer, 16, 0))) {
766
+    if(!(pt = getdsig(optget(opts, "server")->strarg, builder, buffer, 16, 1))) {
767 767
 	mprintf("!build: Can't get digital signature from remote server\n");
768 768
 	fclose(fh);
769 769
 	unlink(tarfile);
... ...
@@ -1294,11 +1339,12 @@ static int vbadump(const struct optstruct *opts)
1294 1294
     return 0;
1295 1295
 }
1296 1296
 
1297
-static int comparemd5(const char *dbname)
1297
+static int comparesha(const char *dbname)
1298 1298
 {
1299
-	char info[32], buff[256], *md5, *pt;
1299
+	char info[32], buff[FILEBUFF], *sha;
1300
+	const char *tokens[3];
1300 1301
 	FILE *fh;
1301
-	int ret = 0;
1302
+	int ret = 0, tokens_count;
1302 1303
 
1303 1304
 
1304 1305
     snprintf(info, sizeof(info), "%s.info", getdbname(dbname));
... ...
@@ -1316,24 +1362,26 @@ static int comparemd5(const char *dbname)
1316 1316
 
1317 1317
     while(fgets(buff, sizeof(buff), fh)) {
1318 1318
 	cli_chomp(buff);
1319
-	if(!(pt = strchr(buff, ':'))) {
1319
+	tokens_count = cli_strtokenize(buff, ':', 3, tokens);
1320
+	if(tokens_count != 3) {
1321
+	    if(!strcmp(tokens[0], "DSIG"))
1322
+		continue;
1320 1323
 	    mprintf("!verifydiff: Incorrect format of %s\n", info);
1321 1324
 	    ret = -1;
1322 1325
 	    break;
1323 1326
 	}
1324
-	*pt++ = 0;
1325
-	if(!(md5 = cli_md5file(buff))) {
1327
+	if(!(sha = sha256file(tokens[0], NULL))) {
1326 1328
 	    mprintf("!verifydiff: Can't generate MD5 for %s\n", buff);
1327 1329
 	    ret = -1;
1328 1330
 	    break;
1329 1331
 	}
1330
-	if(strcmp(pt, md5)) {
1332
+	if(strcmp(sha, tokens[2])) {
1331 1333
 	    mprintf("!verifydiff: %s has incorrect checksum\n", buff);
1332 1334
 	    ret = -1;
1333
-	    free(md5);
1335
+	    free(sha);
1334 1336
 	    break;
1335 1337
 	}
1336
-	free(md5);
1338
+	free(sha);
1337 1339
     }
1338 1340
 
1339 1341
     fclose(fh);
... ...
@@ -1367,7 +1415,7 @@ static int rundiff(const struct optstruct *opts)
1367 1367
     close(fd);
1368 1368
 
1369 1369
     if(!ret)
1370
-	ret = comparemd5(diff);
1370
+	ret = comparesha(diff);
1371 1371
 
1372 1372
     return ret;
1373 1373
 }
... ...
@@ -1611,7 +1659,7 @@ static int verifydiff(const char *diff, const char *cvd, const char *incdir)
1611 1611
     }
1612 1612
     close(fd);
1613 1613
 
1614
-    ret = comparemd5(diff);
1614
+    ret = comparesha(diff);
1615 1615
 
1616 1616
     if(chdir(cwd) == -1)
1617 1617
 	mprintf("^verifydiff: Can't chdir to %s\n", cwd);