[Pkg-clamav-commits] [SCM] Debian repository for ClamAV branch, debian/unstable, updated. debian/0.95+dfsg-1-6156-g094ec9b
Tomasz Kojm
tkojm at clamav.net
Sun Apr 4 01:16:22 UTC 2010
The following commit has been merged in the debian/unstable branch:
commit de351ee1bc741f5b06a7007904efd1164e9e414b
Author: Tomasz Kojm <tkojm at clamav.net>
Date: Mon Jan 25 13:28:19 2010 +0100
libclamav: handle digitally signed .info files
diff --git a/ChangeLog b/ChangeLog
index d865865..2f211de 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+Mon Jan 25 13:27:44 CET 2010 (tk)
+---------------------------------
+ * libclamav: handle digitally signed .info files
+
Fri Jan 22 11:49:07 CET 2010 (acab)
-----------------------------------
* libclamav: fix shifts >= width (bb#1778)
diff --git a/libclamav/clamav.h b/libclamav/clamav.h
index b81672a..6bb1f1c 100644
--- a/libclamav/clamav.h
+++ b/libclamav/clamav.h
@@ -82,6 +82,7 @@ typedef enum {
#define CL_DB_DIRECTORY 0x800 /* internal */
#define CL_DB_OFFICIAL_ONLY 0x1000
#define CL_DB_BYTECODE 0x2000
+#define CL_DB_SIGNED 0x4000
/* recommended db settings */
#define CL_DB_STDOPT (CL_DB_PHISHING | CL_DB_PHISHING_URLS | CL_DB_BYTECODE)
diff --git a/libclamav/cvd.c b/libclamav/cvd.c
index b5bf583..bfbece7 100644
--- a/libclamav/cvd.c
+++ b/libclamav/cvd.c
@@ -42,10 +42,12 @@
#include "cvd.h"
#include "readdb.h"
#include "default.h"
-#include "md5.h"
+#include "sha256.h"
#define TAR_BLOCKSIZE 512
+#define DB_NOCHECK 0x80000 /* FIXME: temporary */
+
static int cli_untgz(int fd, const char *destdir)
{
char *path, osize[13], name[101], type;
@@ -188,7 +190,7 @@ static int cli_tgzload(int fd, struct cl_engine *engine, unsigned int *signo, un
unsigned int type, size, pad, compr = 1;
off_t off;
struct cli_dbinfo *db;
- unsigned char hash[16];
+ unsigned char hash[32];
#define CLOSE_DBIO \
if(compr) \
@@ -298,9 +300,8 @@ static int cli_tgzload(int fd, struct cl_engine *engine, unsigned int *signo, un
dbio->readsize = dbio->size < dbio->bufsize ? dbio->size : dbio->bufsize - 1;
dbio->bufpt = NULL;
dbio->readpt = dbio->buf;
- cli_md5_init(&dbio->md5ctx);
+ sha256_init(&dbio->sha256ctx);
dbio->bread = 0;
- dbio->secure = 0;
/* cli_dbgmsg("cli_tgzload: Loading %s, size: %u\n", name, size); */
if(compr)
@@ -308,8 +309,7 @@ static int cli_tgzload(int fd, struct cl_engine *engine, unsigned int *signo, un
else
off = ftell(dbio->fs);
- /*if((!dbinfo && cli_strbcasestr(name, ".info")) || (dbinfo && CLI_DBEXT(name))) {*/
- if(CLI_DBEXT(name)) {
+ if((!dbinfo && !(options & DB_NOCHECK) && cli_strbcasestr(name, ".info")) || ((dbinfo || (options & DB_NOCHECK)) && CLI_DBEXT(name))) {
ret = cli_load(name, engine, signo, options, dbio);
if(ret) {
cli_errmsg("cli_tgzload: Can't load %s\n", name);
@@ -317,11 +317,12 @@ static int cli_tgzload(int fd, struct cl_engine *engine, unsigned int *signo, un
CLOSE_DBIO;
return CL_EMALFDB;
}
- /*
if(!dbinfo) {
- free(dbio->buf);
- CLOSE_DBIO;
- return CL_SUCCESS;
+ if(!(options & DB_NOCHECK)) { /* FIXME: temporary */
+ free(dbio->buf);
+ CLOSE_DBIO;
+ return CL_SUCCESS;
+ }
} else {
db = dbinfo;
while(db && strcmp(db->name, name))
@@ -333,8 +334,14 @@ static int cli_tgzload(int fd, struct cl_engine *engine, unsigned int *signo, un
return CL_EMALFDB;
}
if(dbio->bread) {
- cli_md5_final(hash, &dbio->md5ctx);
- if(memcmp(db->hash, hash, 16)) {
+ if(db->size != dbio->bread) {
+ cli_errmsg("cli_tgzload: File %s not correctly loaded\n", name);
+ free(dbio->buf);
+ CLOSE_DBIO;
+ return CL_EMALFDB;
+ }
+ sha256_final(&dbio->sha256ctx, hash);
+ if(memcmp(db->hash, hash, 32)) {
cli_errmsg("cli_tgzload: Invalid checksum for file %s\n", name);
free(dbio->buf);
CLOSE_DBIO;
@@ -342,7 +349,6 @@ static int cli_tgzload(int fd, struct cl_engine *engine, unsigned int *signo, un
}
}
}
- */
}
pad = size % TAR_BLOCKSIZE ? (TAR_BLOCKSIZE - (size % TAR_BLOCKSIZE)) : 0;
if(compr) {
@@ -594,27 +600,30 @@ int cli_cvdload(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigne
}
cfd = fileno(fs);
- /* use only operations on file descriptors, and not on the FILE* from here on
- * if we seek the FILE*, the underlying descriptor may not seek as expected
- * (for example on OpenBSD, cygwin, etc.).
- * So seek the descriptor directly.
- */
- if(lseek(cfd, 512, SEEK_SET) == -1) {
- cli_errmsg("cli_cvdload(): lseek(fs, 512, SEEK_SET) failed\n");
- return CL_ESEEK;
- }
+ if(strstr(dbname, "main.")) /* FIXME: temporary */
+ options |= DB_NOCHECK;
+ else
+ ret = cli_tgzload(cfd, engine, signo, options | CL_DB_OFFICIAL, &dbio, NULL);
/*
- ret = cli_tgzload(cfd, engine, signo, options | CL_DB_OFFICIAL, &dbio, NULL);
if(ret != CL_SUCCESS)
return ret;
-
- * TODO: check CVD header
- dbinfo = engine->dbinfo ? engine->dbinfo->next : NULL;
- if(!dbinfo)
- return CL_EMALFDB;
+ options |= CL_DB_SIGNED;
*/
+ if(ret != CL_SUCCESS)
+ options |= DB_NOCHECK;
+ if(!(options & DB_NOCHECK)) { /* FIXME: temporary */
+ dbinfo = engine->dbinfo;
+ if(!dbinfo || !dbinfo->cvd || (dbinfo->cvd->version != cvd.version) || (dbinfo->cvd->sigs != cvd.sigs) || (dbinfo->cvd->fl != cvd.fl) || (dbinfo->cvd->stime != cvd.stime)) {
+ cli_errmsg("cli_cvdload: Corrupted CVD header\n");
+ return CL_EMALFDB;
+ }
+ dbinfo = engine->dbinfo ? engine->dbinfo->next : NULL;
+ if(!dbinfo)
+ return CL_EMALFDB;
+ options |= CL_DB_SIGNED;
+ }
ret = cli_tgzload(cfd, engine, signo, options | CL_DB_OFFICIAL, &dbio, dbinfo);
while(engine->dbinfo) {
diff --git a/libclamav/cvd.h b/libclamav/cvd.h
index d3701ca..9b0c09c 100644
--- a/libclamav/cvd.h
+++ b/libclamav/cvd.h
@@ -25,7 +25,7 @@
#include <zlib.h>
#include "clamav.h"
-#include "md5.h"
+#include "sha256.h"
struct cli_dbio {
gzFile *gzs;
@@ -33,8 +33,7 @@ struct cli_dbio {
unsigned int size, bread;
char *buf, *bufpt, *readpt;
unsigned int usebuf, bufsize, readsize;
- unsigned secure;
- cli_md5_ctx md5ctx; /* TODO: replace with sha256 */
+ SHA256_CTX sha256ctx;
};
int cli_cvdload(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigned int options, unsigned int cld, const char *dbname);
diff --git a/libclamav/readdb.c b/libclamav/readdb.c
index 887c28a..2a2e6ea 100644
--- a/libclamav/readdb.c
+++ b/libclamav/readdb.c
@@ -56,6 +56,8 @@
#include "cltypes.h"
#include "default.h"
#include "md5.h"
+#include "sha256.h"
+#include "dsig.h"
#include "phishcheck.h"
#include "phish_whitelist.h"
@@ -351,7 +353,7 @@ char *cli_dbgets(char *buff, unsigned int size, FILE *fs, struct cli_dbio *dbio)
dbio->bufpt = dbio->buf;
dbio->size -= bread;
dbio->bread += bread;
- cli_md5_update(&dbio->md5ctx, dbio->readpt, bread);
+ sha256_update(&dbio->sha256ctx, dbio->readpt, bread);
}
nl = strchr(dbio->bufpt, '\n');
if(nl) {
@@ -403,7 +405,7 @@ char *cli_dbgets(char *buff, unsigned int size, FILE *fs, struct cli_dbio *dbio)
bs = strlen(buff);
dbio->size -= bs;
dbio->bread += bs;
- cli_md5_update(&dbio->md5ctx, buff, bs);
+ sha256_update(&dbio->sha256ctx, buff, bs);
return pt;
}
}
@@ -1341,12 +1343,7 @@ static int cli_loadcbc(FILE *fs, struct cl_engine *engine, unsigned int *signo,
cli_dbgmsg("bytecode: trusting all bytecode!\n");
break;
case CL_BYTECODE_TRUST_SIGNED:
- if (dbio && (!engine->dbinfo || !engine->dbinfo->cvd
- || !engine->dbinfo->cvd->dsig)) {
- cli_errmsg("CVD without signed .info?\n");
- return CL_EMALFDB;
- }
- security_trust = dbio ? 1 : 0;
+ security_trust = !!(options & CL_DB_SIGNED);
break;
default:
security_trust = 0;
@@ -1522,21 +1519,39 @@ static int cli_loadftm(FILE *fs, struct cl_engine *engine, unsigned int options,
return CL_SUCCESS;
}
-#define IGN_INFO_TOKENS 2
+#define INFO_NSTR "11088894983048545473659556106627194923928941791795047620591658697413581043322715912172496806525381055880964520618400224333320534660299233983755341740679502866829909679955734391392668378361221524205396631090105151641270857277080310734320951653700508941717419168723942507890702904702707587451621691050754307850383399865346487203798464178537392211402786481359824461197231102895415093770394216666324484593935762408468516826633192140826667923494822045805347809932848454845886971706424360558667862775876072059437703365380209101697738577515476935085469455279994113145977994084618328482151013142393373316337519977244732747977"
+#define INFO_ESTR "100002049"
+#define INFO_TOKENS 3
static int cli_loadinfo(FILE *fs, struct cl_engine *engine, unsigned int options, struct cli_dbio *dbio)
{
- const char *tokens[IGN_INFO_TOKENS + 1];
+ const char *tokens[INFO_TOKENS + 1];
char buffer[FILEBUFF];
- unsigned int line = 0, tokens_count;
+ unsigned int line = 0, tokens_count, len;
+ unsigned char hash[32];
struct cli_dbinfo *last = NULL, *new;
- int ret = CL_SUCCESS;
+ int ret = CL_SUCCESS, dsig = 0;
+ SHA256_CTX ctx;
+ sha256_init(&ctx);
while(cli_dbgets(buffer, FILEBUFF, fs, dbio)) {
line++;
- if(!strncmp(buffer, "DSIG:", 5))
- continue; /* TODO */
+ if(!strncmp(buffer, "DSIG:", 5)) {
+ dsig = 1;
+ sha256_final(&ctx, hash);
+ if(cli_versig2(hash, buffer + 5, INFO_NSTR, INFO_ESTR) != CL_SUCCESS) {
+ cli_errmsg("cli_loadinfo: Incorrect digital signature\n");
+ ret = CL_EMALFDB;
+ }
+ break;
+ }
+ len = strlen(buffer);
+ if(dbio->usebuf && buffer[len - 1] != '\n' && len + 1 < FILEBUFF) {
+ /* cli_dbgets in buffered mode strips \n */
+ buffer[len] = '\n';
+ buffer[len + 1] = 0;
+ }
+ sha256_update(&ctx, buffer, strlen(buffer));
cli_chomp(buffer);
-
if(!strncmp("ClamAV-VDB:", buffer, 11)) {
if(engine->dbinfo) { /* shouldn't be initialized at this point */
cli_errmsg("cli_loadinfo: engine->dbinfo already initialized\n");
@@ -1562,8 +1577,8 @@ static int cli_loadinfo(FILE *fs, struct cl_engine *engine, unsigned int options
ret = CL_EMALFDB;
break;
}
- tokens_count = cli_strtokenize(buffer, ':', IGN_INFO_TOKENS + 1, tokens);
- if(tokens_count > IGN_INFO_TOKENS) {
+ tokens_count = cli_strtokenize(buffer, ':', INFO_TOKENS + 1, tokens);
+ if(tokens_count != INFO_TOKENS) {
ret = CL_EMALFDB;
break;
}
@@ -1579,20 +1594,31 @@ static int cli_loadinfo(FILE *fs, struct cl_engine *engine, unsigned int options
break;
}
- /* TODO: hash will be replaced with sha256 */
- if(strlen(tokens[1]) != 32 || !(new->hash = cli_mpool_hex2str(engine->mempool, tokens[1]))) {
- cli_errmsg("cli_loadinfo: Malformed MD5 string at line %u\n", line);
+ if(!cli_isnumber(tokens[1])) {
+ cli_errmsg("cli_loadinfo: Invalid value in the size field\n");
mpool_free(engine->mempool, new->name);
mpool_free(engine->mempool, new);
ret = CL_EMALFDB;
break;
}
+ new->size = atoi(tokens[1]);
- new->size = 0; /* TODO */
+ if(strlen(tokens[2]) != 64 || !(new->hash = cli_mpool_hex2str(engine->mempool, tokens[2]))) {
+ cli_errmsg("cli_loadinfo: Malformed SHA256 string at line %u\n", line);
+ mpool_free(engine->mempool, new->name);
+ mpool_free(engine->mempool, new);
+ ret = CL_EMALFDB;
+ break;
+ }
last->next = new;
last = new;
}
+ if(!dsig) {
+ cli_errmsg("cli_loadinfo: Digital signature not found\n");
+ return CL_EMALFDB;
+ }
+
if(ret) {
cli_errmsg("cli_loadinfo: Problem parsing database at line %u\n", line);
return ret;
diff --git a/unit_tests/check_bytecode.c b/unit_tests/check_bytecode.c
index 6c7968e..09acda0 100644
--- a/unit_tests/check_bytecode.c
+++ b/unit_tests/check_bytecode.c
@@ -60,7 +60,7 @@ static void runtest(const char *file, uint64_t expected, int fail, int nojit)
bcs.all_bcs = &bc;
bcs.count = 1;
- rc = cli_bytecode_load(&bc, f, NULL);
+ rc = cli_bytecode_load(&bc, f, NULL, 1);
fail_unless(rc == CL_SUCCESS, "cli_bytecode_load failed");
fclose(f);
--
Debian repository for ClamAV
More information about the Pkg-clamav-commits
mailing list