| ... | ... |
@@ -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);
|