git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@1380 77e5149b-7576-45b1-b177-96237e5ba77b
Tomasz Kojm authored on 2005/03/07 08:40:57... | ... |
@@ -148,6 +148,40 @@ static long int cli_caloff(const char *offstr, int fd) |
148 | 148 |
return -1; |
149 | 149 |
} |
150 | 150 |
|
151 |
+int cli_checkfp(int fd, const struct cl_node *root) |
|
152 |
+{ |
|
153 |
+ struct cli_md5_node *md5_node; |
|
154 |
+ char *digest; |
|
155 |
+ |
|
156 |
+ |
|
157 |
+ if(root->md5_hlist) { |
|
158 |
+ |
|
159 |
+ if(!(digest = cli_md5digest(fd))) { |
|
160 |
+ cli_errmsg("cli_checkfp(): Can't generate MD5 checksum\n"); |
|
161 |
+ return 0; |
|
162 |
+ } |
|
163 |
+ |
|
164 |
+ if((md5_node = cli_vermd5(digest, root)) && md5_node->fp) { |
|
165 |
+ struct stat sb; |
|
166 |
+ |
|
167 |
+ if(fstat(fd, &sb)) |
|
168 |
+ return CL_EIO; |
|
169 |
+ |
|
170 |
+ if(sb.st_size != md5_node->size) { |
|
171 |
+ cli_warnmsg("Detected false positive MD5 match. Please report.\n"); |
|
172 |
+ } else { |
|
173 |
+ cli_dbgmsg("Eliminated false positive match (fp sig: %s)\n", md5_node->virname); |
|
174 |
+ free(digest); |
|
175 |
+ return 1; |
|
176 |
+ } |
|
177 |
+ } |
|
178 |
+ |
|
179 |
+ free(digest); |
|
180 |
+ } |
|
181 |
+ |
|
182 |
+ return 0; |
|
183 |
+} |
|
184 |
+ |
|
151 | 185 |
int cli_validatesig(unsigned short target, unsigned short ftype, const char *offstr, unsigned long int fileoff, int desc, const char *virname) |
152 | 186 |
{ |
153 | 187 |
|
... | ... |
@@ -258,7 +292,12 @@ int cli_scandesc(int desc, const char **virname, long int *scanned, const struct |
258 | 258 |
free(buffer); |
259 | 259 |
free(partcnt); |
260 | 260 |
free(partoff); |
261 |
- return CL_VIRUS; |
|
261 |
+ |
|
262 |
+ lseek(desc, 0, SEEK_SET); |
|
263 |
+ if(cli_checkfp(desc, root)) |
|
264 |
+ return CL_CLEAN; |
|
265 |
+ else |
|
266 |
+ return CL_VIRUS; |
|
262 | 267 |
|
263 | 268 |
} else if(otfrec && ret >= CL_TYPENO) { |
264 | 269 |
if(ret >= type) |
... | ... |
@@ -297,7 +336,7 @@ int cli_scandesc(int desc, const char **virname, long int *scanned, const struct |
297 | 297 |
cli_dbgmsg("Calculated MD5 checksum: %s\n", md5str); |
298 | 298 |
} |
299 | 299 |
|
300 |
- if((md5_node = cli_vermd5(digest, root))) { |
|
300 |
+ if((md5_node = cli_vermd5(digest, root)) && !md5_node->fp) { |
|
301 | 301 |
struct stat sb; |
302 | 302 |
|
303 | 303 |
if(fstat(desc, &sb)) |
... | ... |
@@ -27,4 +27,6 @@ int cli_scanbuff(const char *buffer, unsigned int length, const char **virname, |
27 | 27 |
|
28 | 28 |
int cli_validatesig(unsigned short target, unsigned short ftype, const char *offstr, unsigned long int fileoff, int desc, const char *virname); |
29 | 29 |
|
30 |
+int cli_checkfp(int fd, const struct cl_node *root); |
|
31 |
+ |
|
30 | 32 |
#endif |
... | ... |
@@ -192,6 +192,27 @@ const char *cl_perror(int clerror) |
192 | 192 |
return cl_strerror(clerror); |
193 | 193 |
} |
194 | 194 |
|
195 |
+unsigned char *cli_md5digest(int desc) |
|
196 |
+{ |
|
197 |
+ unsigned char *digest; |
|
198 |
+ char buff[FILEBUFF]; |
|
199 |
+ MD5_CTX ctx; |
|
200 |
+ int bytes; |
|
201 |
+ |
|
202 |
+ |
|
203 |
+ if(!(digest = cli_malloc(16))) |
|
204 |
+ return NULL; |
|
205 |
+ |
|
206 |
+ MD5_Init(&ctx); |
|
207 |
+ |
|
208 |
+ while((bytes = cli_readn(desc, buff, FILEBUFF))) |
|
209 |
+ MD5_Update(&ctx, buff, bytes); |
|
210 |
+ |
|
211 |
+ MD5_Final(digest, &ctx); |
|
212 |
+ |
|
213 |
+ return digest; |
|
214 |
+} |
|
215 |
+ |
|
195 | 216 |
char *cli_md5stream(FILE *fs, unsigned char *digcpy) |
196 | 217 |
{ |
197 | 218 |
unsigned char digest[16]; |
... | ... |
@@ -30,6 +30,7 @@ void *cli_malloc(size_t nmemb); |
30 | 30 |
void *cli_calloc(size_t nmemb, size_t size); |
31 | 31 |
void *cli_realloc(void *ptr, size_t size); |
32 | 32 |
int cli_rmdirs(const char *dirname); |
33 |
+unsigned char *cli_md5digest(int desc); |
|
33 | 34 |
char *cli_md5stream(FILE *fs, unsigned char *digcpy); |
34 | 35 |
char *cli_md5file(const char *filename); |
35 | 36 |
int cli_readn(int fd, void *buff, unsigned int count); |
... | ... |
@@ -612,7 +612,7 @@ static int cli_loadndb(FILE *fd, struct cl_node **root, unsigned int *signo) |
612 | 612 |
return 0; |
613 | 613 |
} |
614 | 614 |
|
615 |
-static int cli_loadhdb(FILE *fd, struct cl_node **root, unsigned int *signo) |
|
615 |
+static int cli_loadhdb(FILE *fd, struct cl_node **root, unsigned int *signo, unsigned short fp) |
|
616 | 616 |
{ |
617 | 617 |
char buffer[FILEBUFF], *pt; |
618 | 618 |
int line = 0, ret = 0; |
... | ... |
@@ -636,6 +636,8 @@ static int cli_loadhdb(FILE *fd, struct cl_node **root, unsigned int *signo) |
636 | 636 |
break; |
637 | 637 |
} |
638 | 638 |
|
639 |
+ new->fp = fp; |
|
640 |
+ |
|
639 | 641 |
if(!(pt = cli_strtok(buffer, 0, ":"))) { |
640 | 642 |
free(new); |
641 | 643 |
ret = CL_EMALFDB; |
... | ... |
@@ -893,7 +895,10 @@ int cl_loaddb(const char *filename, struct cl_node **root, unsigned int *signo) |
893 | 893 |
ret = cli_cvdload(fd, root, signo, warn); |
894 | 894 |
|
895 | 895 |
} else if(cli_strbcasestr(filename, ".hdb")) { |
896 |
- ret = cli_loadhdb(fd, root, signo); |
|
896 |
+ ret = cli_loadhdb(fd, root, signo, 0); |
|
897 |
+ |
|
898 |
+ } else if(cli_strbcasestr(filename, ".fp")) { |
|
899 |
+ ret = cli_loadhdb(fd, root, signo, 1); |
|
897 | 900 |
|
898 | 901 |
} else if(cli_strbcasestr(filename, ".ndb")) { |
899 | 902 |
ret = cli_loadndb(fd, root, signo); |
... | ... |
@@ -950,6 +955,7 @@ int cl_loaddbdir(const char *dirname, struct cl_node **root, unsigned int *signo |
950 | 950 |
cli_strbcasestr(dent->d_name, ".db2") || |
951 | 951 |
cli_strbcasestr(dent->d_name, ".db3") || |
952 | 952 |
cli_strbcasestr(dent->d_name, ".hdb") || |
953 |
+ cli_strbcasestr(dent->d_name, ".fp") || |
|
953 | 954 |
cli_strbcasestr(dent->d_name, ".ndb") || |
954 | 955 |
cli_strbcasestr(dent->d_name, ".zmd") || |
955 | 956 |
cli_strbcasestr(dent->d_name, ".cvd"))) { |
... | ... |
@@ -1028,6 +1034,7 @@ int cl_statinidir(const char *dirname, struct cl_stat *dbstat) |
1028 | 1028 |
cli_strbcasestr(dent->d_name, ".db2") || |
1029 | 1029 |
cli_strbcasestr(dent->d_name, ".db3") || |
1030 | 1030 |
cli_strbcasestr(dent->d_name, ".hdb") || |
1031 |
+ cli_strbcasestr(dent->d_name, ".fp") || |
|
1031 | 1032 |
cli_strbcasestr(dent->d_name, ".ndb") || |
1032 | 1033 |
cli_strbcasestr(dent->d_name, ".zmd") || |
1033 | 1034 |
cli_strbcasestr(dent->d_name, ".cvd"))) { |
... | ... |
@@ -1097,6 +1104,7 @@ int cl_statchkdir(const struct cl_stat *dbstat) |
1097 | 1097 |
cli_strbcasestr(dent->d_name, ".db2") || |
1098 | 1098 |
cli_strbcasestr(dent->d_name, ".db3") || |
1099 | 1099 |
cli_strbcasestr(dent->d_name, ".hdb") || |
1100 |
+ cli_strbcasestr(dent->d_name, ".fp") || |
|
1100 | 1101 |
cli_strbcasestr(dent->d_name, ".ndb") || |
1101 | 1102 |
cli_strbcasestr(dent->d_name, ".zmd") || |
1102 | 1103 |
cli_strbcasestr(dent->d_name, ".cvd"))) { |
... | ... |
@@ -288,7 +288,7 @@ int build(struct optstruct *opt) |
288 | 288 |
exit(1); |
289 | 289 |
case 0: |
290 | 290 |
{ |
291 |
- char *args[] = { "tar", "-cvf", NULL, "COPYING", "main.db", "daily.db", "Notes", "viruses.db3", "main.hdb", "daily.hdb", "main.ndb", "daily.ndb", "main.zmd", "daily.zmd", NULL }; |
|
291 |
+ char *args[] = { "tar", "-cvf", NULL, "COPYING", "main.db", "daily.db", "Notes", "viruses.db3", "main.hdb", "daily.hdb", "main.ndb", "daily.ndb", "main.zmd", "daily.zmd", "main.fp", "daily.fp", NULL }; |
|
292 | 292 |
args[2] = tarfile; |
293 | 293 |
execv("/bin/tar", args); |
294 | 294 |
mprintf("!Can't execute tar\n"); |