[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:04:46 UTC 2010


The following commit has been merged in the debian/unstable branch:
commit a6d4c62ee5039d2dc9f7d35e18c9b0334ef6cdaf
Author: Tomasz Kojm <tkojm at clamav.net>
Date:   Fri Sep 11 16:05:50 2009 +0200

    libclamav/matcher-ac.c: initial limited support for word boundary (bb#1631)

diff --git a/ChangeLog b/ChangeLog
index e4e7863..85b56f5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+Fri Sep 11 16:05:00 CEST 2009 (tk)
+----------------------------------
+ * libclamav/matcher-ac.c: initial limited support for word boundary (bb#1631)
+
 Thu Sep 10 20:16:45 CEST 2009 (tk)
 ----------------------------------
  * libclamav/matcher-ac.c: alternatives can now be negated: !(aa|bb|cc)
diff --git a/libclamav/matcher-ac.c b/libclamav/matcher-ac.c
index 16879fb..00efb69 100644
--- a/libclamav/matcher-ac.c
+++ b/libclamav/matcher-ac.c
@@ -45,12 +45,18 @@
 
 #include "mpool.h"
 
+#define AC_SPECIAL_ALT_CHAR	1
+#define AC_SPECIAL_ALT_STR	2
+#define AC_SPECIAL_LINE_START	3
+#define AC_SPECIAL_LINE_END	4
+#define AC_SPECIAL_BOUNDARY	5
+
 int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern)
 {
 	struct cli_ac_node *pt, *next;
 	struct cli_ac_patt *ph;
 	void *newtable;
-	struct cli_ac_alt *a1, *a2;
+	struct cli_ac_special *a1, *a2;
 	uint8_t i, match;
 	uint16_t len = MIN(root->ac_maxdepth, pattern->length);
 
@@ -131,27 +137,31 @@ int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern)
     while(ph) {
 	if((ph->length == pattern->length) && (ph->prefix_length == pattern->prefix_length) && (ph->ch[0] == pattern->ch[0]) && (ph->ch[1] == pattern->ch[1])) {
 	    if(!memcmp(ph->pattern, pattern->pattern, ph->length * sizeof(uint16_t)) && !memcmp(ph->prefix, pattern->prefix, ph->prefix_length * sizeof(uint16_t))) {
-		if(!ph->alt && !pattern->alt) {
+		if(!ph->special && !pattern->special) {
 		    match = 1;
-		} else if(ph->alt == pattern->alt) {
+		} else if(ph->special == pattern->special) {
 		    match = 1;
-		    for(i = 0; i < ph->alt; i++) {
-			a1 = ph->alttable[i];
-			a2 = pattern->alttable[i];
+		    for(i = 0; i < ph->special; i++) {
+			a1 = ph->special_table[i];
+			a2 = pattern->special_table[i];
 
 			if(a1->num != a2->num) {
 			    match = 0;
 			    break;
 			}
-			if(a1->chmode != a2->chmode) {
+			if(a1->negative != a2->negative) {
 			    match = 0;
 			    break;
-			} else if(a1->chmode) {
+			}
+			if(a1->type != a2->type) {
+			    match = 0;
+			    break;
+			} else if(a1->type == AC_SPECIAL_ALT_CHAR) {
 			    if(memcmp(a1->str, a2->str, a1->num)) {
 				match = 0;
 				break;
 			    }
-			} else {
+			} else if(a1->type == AC_SPECIAL_ALT_STR) {
 			    while(a1 && a2) {
 				if((a1->len != a2->len) || memcmp(a1->str, a2->str, a1->len))
 				    break;
@@ -350,22 +360,22 @@ int cli_ac_init(struct cli_matcher *root, uint8_t mindepth, uint8_t maxdepth)
 }
 
 #ifdef USE_MPOOL
-#define mpool_ac_free_alt(a, b) ac_free_alt(a, b)
-static void ac_free_alt(mpool_t *mempool, struct cli_ac_patt *p)
+#define mpool_ac_free_special(a, b) ac_free_special(a, b)
+static void ac_free_special(mpool_t *mempool, struct cli_ac_patt *p)
 #else
-#define mpool_ac_free_alt(a, b) ac_free_alt(b)
-static void ac_free_alt(struct cli_ac_patt *p)
+#define mpool_ac_free_special(a, b) ac_free_special(b)
+static void ac_free_special(struct cli_ac_patt *p)
 #endif
 {
-	uint16_t i;
-	struct cli_ac_alt *a1, *a2;
+	unsigned int i;
+	struct cli_ac_special *a1, *a2;
 
 
-    if(!p->alt)
+    if(!p->special)
 	return;
 
-    for(i = 0; i < p->alt; i++) {
-	a1 = p->alttable[i];
+    for(i = 0; i < p->special; i++) {
+	a1 = p->special_table[i];
 	while(a1) {
 	    a2 = a1;
 	    a1 = a1->next;
@@ -374,7 +384,7 @@ static void ac_free_alt(struct cli_ac_patt *p)
 	    mpool_free(mempool, a2);
 	}
     }
-    mpool_free(mempool, p->alttable);
+    mpool_free(mempool, p->special_table);
 }
 
 void cli_ac_free(struct cli_matcher *root)
@@ -387,8 +397,8 @@ void cli_ac_free(struct cli_matcher *root)
 	patt = root->ac_pattable[i];
 	mpool_free(root->mempool, patt->prefix ? patt->prefix : patt->pattern);
 	mpool_free(root->mempool, patt->virname);
-	if(patt->alt)
-	    mpool_ac_free_alt(root->mempool, patt);
+	if(patt->special)
+	    mpool_ac_free_special(root->mempool, patt);
 	mpool_free(root->mempool, patt);
     }
     if(root->ac_pattable)
@@ -650,62 +660,75 @@ int cli_ac_chklsig(const char *expr, const char *end, uint32_t *lsigcnt, unsigne
  *        more than one of them can match at the current position.
  */
 
-#define AC_MATCH_CHAR(p,b)						\
-    switch(wc = p & CLI_MATCH_WILDCARD) {				\
-	case CLI_MATCH_CHAR:						\
-	    if((unsigned char) p != b)					\
-		match = 0;						\
-	    break;							\
-									\
-	case CLI_MATCH_IGNORE:						\
-	    break;							\
-									\
-	case CLI_MATCH_ALTERNATIVE:					\
-	    alt = pattern->alttable[altcnt];				\
-	    match = alt->negative;					\
-	    if(alt->chmode) {						\
-		for(j = 0; j < alt->num; j++) {				\
-		    if(alt->str[j] == b) {				\
-			match = !alt->negative;				\
-			break;						\
-		    } else if(alt->str[j] > b)				\
-			break;						\
-		}							\
-	    } else {							\
-		while(alt) {						\
-		    if(bp + alt->len <= length) {			\
-			if(!memcmp(&buffer[bp], alt->str, alt->len)) {	\
-			    match = !alt->negative;			\
-			    bp += alt->len - 1;				\
-			    break;					\
-			}						\
-		    }							\
-		    alt = alt->next;					\
-		}							\
-	    }								\
-	    altcnt++;							\
-	    break;							\
-									\
-	case CLI_MATCH_NIBBLE_HIGH:					\
-	    if((unsigned char) (p & 0x00f0) != (b & 0xf0))		\
-		match = 0;						\
-	    break;							\
-									\
-	case CLI_MATCH_NIBBLE_LOW:					\
-	    if((unsigned char) (p & 0x000f) != (b & 0x0f))		\
-		match = 0;						\
-	    break;							\
-									\
-	default:							\
-	    cli_errmsg("ac_findmatch: Unknown wildcard 0x%x\n", wc);	\
-	    match = 0;							\
+#define AC_MATCH_CHAR(p,b)								\
+    switch(wc = p & CLI_MATCH_WILDCARD) {						\
+	case CLI_MATCH_CHAR:								\
+	    if((unsigned char) p != b)							\
+		match = 0;								\
+	    break;									\
+											\
+	case CLI_MATCH_IGNORE:								\
+	    break;									\
+											\
+	case CLI_MATCH_SPECIAL:								\
+	    special = pattern->special_table[specialcnt];				\
+	    match = special->negative;							\
+	    switch(special->type) {							\
+		case AC_SPECIAL_ALT_CHAR:						\
+		    for(j = 0; j < special->num; j++) {					\
+			if(special->str[j] == b) {					\
+			    match = !special->negative;					\
+			    break;							\
+			} else if(special->str[j] > b)					\
+			    break;							\
+		    }									\
+		    break;								\
+											\
+		case AC_SPECIAL_ALT_STR:						\
+		    while(special) {							\
+			if(bp + special->len <= length) {				\
+			    if(!memcmp(&buffer[bp], special->str, special->len)) {	\
+				match = !special->negative;				\
+				bp += special->len - 1;					\
+				break;							\
+			    }								\
+			}								\
+			special = special->next;					\
+		    }									\
+		    break;								\
+											\
+		case AC_SPECIAL_BOUNDARY:						\
+		    if(memchr("\x22\x27\x20\x2f\x3d\x2d\x5f\x3e\x0a\x0d", b, 10))	\
+			match = !special->negative;					\
+		    break;								\
+											\
+		default:								\
+		    cli_errmsg("ac_findmatch: Unknown special\n");			\
+		    match = 0;								\
+	    }										\
+	    specialcnt++;								\
+	    break;									\
+											\
+	case CLI_MATCH_NIBBLE_HIGH:							\
+	    if((unsigned char) (p & 0x00f0) != (b & 0xf0))				\
+		match = 0;								\
+	    break;									\
+											\
+	case CLI_MATCH_NIBBLE_LOW:							\
+	    if((unsigned char) (p & 0x000f) != (b & 0x0f))				\
+		match = 0;								\
+	    break;									\
+											\
+	default:									\
+	    cli_errmsg("ac_findmatch: Unknown wildcard 0x%x\n", wc);			\
+	    match = 0;									\
     }
 
 inline static int ac_findmatch(const unsigned char *buffer, uint32_t offset, uint32_t length, const struct cli_ac_patt *pattern, uint32_t *end)
 {
 	uint32_t bp, match;
-	uint16_t wc, i, j, altcnt = pattern->alt_pattern;
-	struct cli_ac_alt *alt;
+	uint16_t wc, i, j, specialcnt = pattern->special_pattern;
+	struct cli_ac_special *special;
 
 
     if((offset + pattern->length > length) || (pattern->prefix_length > offset))
@@ -738,7 +761,7 @@ inline static int ac_findmatch(const unsigned char *buffer, uint32_t offset, uin
     }
 
     if(pattern->prefix) {
-	altcnt = 0;
+	specialcnt = 0;
 	bp = offset - pattern->prefix_length;
 	match = 1;
 	for(i = 0; i < pattern->prefix_length; i++) {
@@ -1169,7 +1192,7 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex
 	char *pt, *pt2, *hex = NULL, *hexcpy = NULL;
 	uint16_t i, j, ppos = 0, pend, *dec, nzpos = 0;
 	uint8_t wprefix = 0, zprefix = 1, plen = 0, nzplen = 0;
-	struct cli_ac_alt *newalt, *altpt, **newtable;
+	struct cli_ac_special *newspecial, *specialpt, **newtable;
 	int ret, error = CL_SUCCESS;
 
 
@@ -1304,15 +1327,15 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex
 		error = CL_EMALFDB;
 		break;
 	    }
-	    newalt = (struct cli_ac_alt *) mpool_calloc(root->mempool, 1, sizeof(struct cli_ac_alt));
-	    if(!newalt) {
-		cli_errmsg("cli_ac_addsig: Can't allocate newalt\n");
+	    newspecial = (struct cli_ac_special *) mpool_calloc(root->mempool, 1, sizeof(struct cli_ac_special));
+	    if(!newspecial) {
+		cli_errmsg("cli_ac_addsig: Can't allocate newspecial\n");
 		error = CL_EMEM;
 		break;
 	    }
 	    if(pt >= hexcpy + 2) {
 		if(pt[-2] == '!') {
-		    newalt->negative = 1;
+		    newspecial->negative = 1;
 		    pt[-2] = 0;
 		}
 	    }
@@ -1320,89 +1343,105 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex
 	    strcat(hexnew, "()");
 
 	    if(!(start = strchr(pt, ')'))) {
-		mpool_free(root->mempool, newalt);
+		mpool_free(root->mempool, newspecial);
 		error = CL_EMALFDB;
 		break;
 	    }
 	    *start++ = 0;
-
-	    new->alt++;
-	    newtable = (struct cli_ac_alt **) mpool_realloc(root->mempool, new->alttable, new->alt * sizeof(struct cli_ac_alt *));
+	    if(!strlen(pt)) {
+		cli_errmsg("cli_ac_addsig: Empty block\n");
+		error = CL_EMALFDB;
+		break;
+	    }
+	    new->special++;
+	    newtable = (struct cli_ac_special **) mpool_realloc(root->mempool, new->special_table, new->special * sizeof(struct cli_ac_special *));
 	    if(!newtable) {
-		new->alt--;
-		mpool_free(root->mempool, newalt);
-		cli_errmsg("cli_ac_addsig: Can't realloc new->alttable\n");
+		new->special--;
+		mpool_free(root->mempool, newspecial);
+		cli_errmsg("cli_ac_addsig: Can't realloc new->special_table\n");
 		error = CL_EMEM;
 		break;
 	    }
-	    newtable[new->alt - 1] = newalt;
-	    new->alttable = newtable;
-
-	    for(i = 0; i < strlen(pt); i++)
-		if(pt[i] == '|')
-		    newalt->num++;
-
-            if(!newalt->num) {
-                error = CL_EMALFDB;
-                break;
-            } else
-                newalt->num++;
-
-	    if(3 * newalt->num - 1 == (uint16_t) strlen(pt)) {
-		newalt->chmode = 1;
-		newalt->str = (unsigned char *) mpool_malloc(root->mempool, newalt->num);
-		if(!newalt->str) {
-		    cli_errmsg("cli_ac_addsig: Can't allocate newalt->str\n");
-		    error = CL_EMEM;
-		    break;
-		}
-	    }
+	    newtable[new->special - 1] = newspecial;
+	    new->special_table = newtable;
+
+	    if(!strcmp(pt, "B")) {
+		newspecial->type = AC_SPECIAL_BOUNDARY;
+	    /* TODO
+	    } else if(strcmp(pt, "S")) {
+		newspecial->type = AC_SPECIAL_LINE_START;
+	    } else if(strcmp(pt, "E")) {
+		newspecial->type = AC_SPECIAL_LINE_END;
+	    } else if(strcmp(pt, "W")) {
+		newspecial->type = AC_SPECIAL_WHITE;
+	    */
+	    } else {
+		for(i = 0; i < strlen(pt); i++)
+		    if(pt[i] == '|')
+			newspecial->num++;
 
-	    for(i = 0; i < newalt->num; i++) {
-		if(!(h = cli_strtok(pt, i, "|"))) {
+		if(!newspecial->num) {
 		    error = CL_EMALFDB;
 		    break;
+		} else
+		    newspecial->num++;
+
+		if(3 * newspecial->num - 1 == (uint16_t) strlen(pt)) {
+		    newspecial->type = AC_SPECIAL_ALT_CHAR;
+		    newspecial->str = (unsigned char *) mpool_malloc(root->mempool, newspecial->num);
+		    if(!newspecial->str) {
+			cli_errmsg("cli_ac_addsig: Can't allocate newspecial->str\n");
+			error = CL_EMEM;
+			break;
+		    }
+		} else {
+		    newspecial->type = AC_SPECIAL_ALT_STR;
 		}
 
-		if(!(c = cli_mpool_hex2str(root->mempool, h))) {
-		    free(h);
-		    error = CL_EMALFDB;
-		    break;
-		}
+		for(i = 0; i < newspecial->num; i++) {
+		    if(!(h = cli_strtok(pt, i, "|"))) {
+			error = CL_EMALFDB;
+			break;
+		    }
 
-		if(newalt->chmode) {
-		    newalt->str[i] = *c;
-		    mpool_free(root->mempool, c);
-		} else {
-		    if(i) {
-			altpt = newalt;
-			while(altpt->next)
-			    altpt = altpt->next;
-
-			altpt->next = (struct cli_ac_alt *) mpool_calloc(root->mempool, 1, sizeof(struct cli_ac_alt));
-			if(!altpt->next) {
-			    cli_errmsg("cli_ac_addsig: Can't allocate altpt->next\n");
-			    error = CL_EMEM;
-			    free(c);
-			    free(h);
-			    break;
-			}
+		    if(!(c = cli_mpool_hex2str(root->mempool, h))) {
+			free(h);
+			error = CL_EMALFDB;
+			break;
+		    }
 
-			altpt->next->str = (unsigned char *) c;
-			altpt->next->len = strlen(h) / 2;
+		    if(newspecial->type == AC_SPECIAL_ALT_CHAR) {
+			newspecial->str[i] = *c;
+			mpool_free(root->mempool, c);
 		    } else {
-			newalt->str = (unsigned char *) c;
-			newalt->len = strlen(h) / 2;
+			if(i) {
+			    specialpt = newspecial;
+			    while(specialpt->next)
+				specialpt = specialpt->next;
+
+			    specialpt->next = (struct cli_ac_special *) mpool_calloc(root->mempool, 1, sizeof(struct cli_ac_special));
+			    if(!specialpt->next) {
+				cli_errmsg("cli_ac_addsig: Can't allocate specialpt->next\n");
+				error = CL_EMEM;
+				free(c);
+				free(h);
+				break;
+			    }
+			    specialpt->next->str = (unsigned char *) c;
+			    specialpt->next->len = strlen(h) / 2;
+			} else {
+			    newspecial->str = (unsigned char *) c;
+			    newspecial->len = strlen(h) / 2;
+			}
 		    }
+		    free(h);
 		}
+		if(newspecial->type == AC_SPECIAL_ALT_CHAR)
+		    cli_qsort(newspecial->str, newspecial->num, sizeof(unsigned char), qcompare);
 
-		free(h);
+		if(error)
+		    break;
 	    }
-	    if(newalt->chmode)
-		cli_qsort(newalt->str, newalt->num, sizeof(unsigned char), qcompare);
-
-	    if(error)
-		break;
 	}
 
 	if(start)
@@ -1412,9 +1451,9 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex
 	free(hexcpy);
 
 	if(error) {
-	    if(new->alt) {
+	    if(new->special) {
 		free(hex);
-		mpool_ac_free_alt(root->mempool, new);
+		mpool_ac_free_special(root->mempool, new);
 	    }
 	    mpool_free(root->mempool, new);
 	    return error;
@@ -1423,8 +1462,8 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex
 
     new->pattern = cli_mpool_hex2ui(root->mempool, hex ? hex : hexsig);
     if(new->pattern == NULL) {
-	if(new->alt)
-	    mpool_ac_free_alt(root->mempool, new);
+	if(new->special)
+	    mpool_ac_free_special(root->mempool, new);
 	mpool_free(root->mempool, new);
 	free(hex);
 	return CL_EMALFDB;
@@ -1473,7 +1512,7 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex
 
 	if(plen < root->ac_mindepth) {
 	    cli_errmsg("cli_ac_addsig: Can't find a static subpattern of length %u\n", root->ac_mindepth);
-	    mpool_ac_free_alt(root->mempool, new);
+	    mpool_ac_free_special(root->mempool, new);
 	    mpool_free(root->mempool, new->pattern);
 	    mpool_free(root->mempool, new);
 	    return CL_EMALFDB;
@@ -1485,8 +1524,8 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex
 	new->length -= ppos;
 
 	for(i = 0; i < new->prefix_length; i++)
-	    if((new->prefix[i] & CLI_MATCH_WILDCARD) == CLI_MATCH_ALTERNATIVE)
-		new->alt_pattern++;
+	    if((new->prefix[i] & CLI_MATCH_WILDCARD) == CLI_MATCH_SPECIAL)
+		new->special_pattern++;
     }
 
     if(new->length > root->maxpatlen)
@@ -1495,7 +1534,7 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex
     new->virname = cli_mpool_virname(root->mempool, (char *) virname, options & CL_DB_OFFICIAL);
     if(!new->virname) {
 	mpool_free(root->mempool, new->prefix ? new->prefix : new->pattern);
-	mpool_ac_free_alt(root->mempool, new);
+	mpool_ac_free_special(root->mempool, new);
 	mpool_free(root->mempool, new);
 	return CL_EMEM;
     }
@@ -1506,7 +1545,7 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex
     ret = cli_caloff(offset, NULL, -1, root->type, new->offdata, &new->offset_min, &new->offset_max);
     if(ret != CL_SUCCESS) {
 	mpool_free(root->mempool, new->prefix ? new->prefix : new->pattern);
-	mpool_ac_free_alt(root->mempool, new);
+	mpool_ac_free_special(root->mempool, new);
 	mpool_free(root->mempool, new->virname);
 	mpool_free(root->mempool, new);
 	return ret;
@@ -1515,7 +1554,7 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex
     if((ret = cli_ac_addpatt(root, new))) {
 	mpool_free(root->mempool, new->prefix ? new->prefix : new->pattern);
 	mpool_free(root->mempool, new->virname);
-	mpool_ac_free_alt(root->mempool, new);
+	mpool_ac_free_special(root->mempool, new);
 	mpool_free(root->mempool, new);
 	return ret;
     }
diff --git a/libclamav/matcher-ac.h b/libclamav/matcher-ac.h
index 4bcbd6e..ad0b9ab 100644
--- a/libclamav/matcher-ac.h
+++ b/libclamav/matcher-ac.h
@@ -38,11 +38,11 @@ struct cli_ac_data {
     uint32_t *offset;
 };
 
-struct cli_ac_alt {
+struct cli_ac_special {
     unsigned char *str;
-    struct cli_ac_alt *next;
+    struct cli_ac_special *next;
     uint16_t len, num;
-    uint8_t chmode, negative;
+    uint8_t type, negative;
 };
 
 struct cli_ac_patt {
@@ -55,8 +55,8 @@ struct cli_ac_patt {
     void *customdata;
     uint16_t ch_mindist[2];
     uint16_t ch_maxdist[2];
-    uint16_t parts, partno, alt, alt_pattern;
-    struct cli_ac_alt **alttable;
+    uint16_t parts, partno, special, special_pattern;
+    struct cli_ac_special **special_table;
     struct cli_ac_patt *next, *next_same;
     uint8_t depth;
     uint16_t rtype, type;
diff --git a/libclamav/matcher.h b/libclamav/matcher.h
index 79c686f..0385838 100644
--- a/libclamav/matcher.h
+++ b/libclamav/matcher.h
@@ -39,7 +39,7 @@
 #define CLI_MATCH_WILDCARD	0xff00
 #define CLI_MATCH_CHAR		0x0000
 #define CLI_MATCH_IGNORE	0x0100
-#define CLI_MATCH_ALTERNATIVE	0x0200
+#define CLI_MATCH_SPECIAL	0x0200
 #define CLI_MATCH_NIBBLE_HIGH	0x0300
 #define CLI_MATCH_NIBBLE_LOW	0x0400
 
diff --git a/libclamav/str.c b/libclamav/str.c
index d0d38b3..8097026 100644
--- a/libclamav/str.c
+++ b/libclamav/str.c
@@ -92,7 +92,7 @@ int cli_realhex2ui(const char *hex, uint16_t *ptr, unsigned int len) {
 	    val |= CLI_MATCH_NIBBLE_LOW;
 
 	} else if(hex[i] == '(') {
-	    val |= CLI_MATCH_ALTERNATIVE;
+	    val |= CLI_MATCH_SPECIAL;
 
 	} else {
 	    if((c = cli_hex2int(hex[i])) >= 0) {

-- 
Debian repository for ClamAV



More information about the Pkg-clamav-commits mailing list