git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@1400 77e5149b-7576-45b1-b177-96237e5ba77b
Tomasz Kojm authored on 2005/03/18 10:27:45... | ... |
@@ -121,10 +121,10 @@ struct cli_md5_node { |
121 | 121 |
struct cli_md5_node *next; |
122 | 122 |
}; |
123 | 123 |
|
124 |
-struct cli_zip_node { |
|
125 |
- int compr, csize, size, encrypted, crc32, fileno, maxdepth; |
|
124 |
+struct cli_meta_node { |
|
125 |
+ int method, csize, size, encrypted, crc32, fileno, maxdepth; |
|
126 | 126 |
char *filename, *virname; |
127 |
- struct cli_zip_node *next; |
|
127 |
+ struct cli_meta_node *next; |
|
128 | 128 |
}; |
129 | 129 |
|
130 | 130 |
struct cl_node { |
... | ... |
@@ -143,7 +143,11 @@ struct cl_node { |
143 | 143 |
struct cli_md5_node **md5_hlist; |
144 | 144 |
|
145 | 145 |
/* Zip metadata */ |
146 |
- struct cli_zip_node *zip_mlist; |
|
146 |
+ struct cli_meta_node *zip_mlist; |
|
147 |
+ |
|
148 |
+ /* RAR metadata */ |
|
149 |
+ struct cli_meta_node *rar_mlist; |
|
150 |
+ |
|
147 | 151 |
}; |
148 | 152 |
|
149 | 153 |
struct cl_limits { |
... | ... |
@@ -390,7 +390,7 @@ void cl_free(struct cl_node *root) |
390 | 390 |
{ |
391 | 391 |
int i; |
392 | 392 |
struct cli_md5_node *md5pt, *md5h; |
393 |
- struct cli_zip_node *zippt, *ziph; |
|
393 |
+ struct cli_meta_node *metapt, *metah; |
|
394 | 394 |
|
395 | 395 |
if(!root) { |
396 | 396 |
cli_errmsg("cl_free: root == NULL\n"); |
... | ... |
@@ -432,14 +432,24 @@ void cl_free(struct cl_node *root) |
432 | 432 |
free(root->md5_hlist); |
433 | 433 |
} |
434 | 434 |
|
435 |
- zippt = root->zip_mlist; |
|
436 |
- while(zippt) { |
|
437 |
- ziph = zippt; |
|
438 |
- zippt = zippt->next; |
|
439 |
- free(ziph->virname); |
|
440 |
- if(ziph->filename) |
|
441 |
- free(ziph->filename); |
|
442 |
- free(ziph); |
|
435 |
+ metapt = root->zip_mlist; |
|
436 |
+ while(metapt) { |
|
437 |
+ metah = metapt; |
|
438 |
+ metapt = metapt->next; |
|
439 |
+ free(metah->virname); |
|
440 |
+ if(metah->filename) |
|
441 |
+ free(metah->filename); |
|
442 |
+ free(metah); |
|
443 |
+ } |
|
444 |
+ |
|
445 |
+ metapt = root->rar_mlist; |
|
446 |
+ while(metapt) { |
|
447 |
+ metah = metapt; |
|
448 |
+ metapt = metapt->next; |
|
449 |
+ free(metah->virname); |
|
450 |
+ if(metah->filename) |
|
451 |
+ free(metah->filename); |
|
452 |
+ free(metah); |
|
443 | 453 |
} |
444 | 454 |
|
445 | 455 |
free(root); |
... | ... |
@@ -705,11 +705,11 @@ static int cli_loadhdb(FILE *fd, struct cl_node **root, unsigned int *signo, uns |
705 | 705 |
return 0; |
706 | 706 |
} |
707 | 707 |
|
708 |
-static int cli_loadzmd(FILE *fd, struct cl_node **root, unsigned int *signo) |
|
708 |
+static int cli_loadmd(FILE *fd, struct cl_node **root, unsigned int *signo, int type) |
|
709 | 709 |
{ |
710 | 710 |
char buffer[FILEBUFF], *pt; |
711 | 711 |
int line = 0, comments = 0, ret = 0; |
712 |
- struct cli_zip_node *new; |
|
712 |
+ struct cli_meta_node *new; |
|
713 | 713 |
|
714 | 714 |
|
715 | 715 |
if(!*root) { |
... | ... |
@@ -728,7 +728,7 @@ static int cli_loadzmd(FILE *fd, struct cl_node **root, unsigned int *signo) |
728 | 728 |
|
729 | 729 |
cli_chomp(buffer); |
730 | 730 |
|
731 |
- new = (struct cli_zip_node *) cli_calloc(1, sizeof(struct cli_zip_node)); |
|
731 |
+ new = (struct cli_meta_node *) cli_calloc(1, sizeof(struct cli_meta_node)); |
|
732 | 732 |
if(!new) { |
733 | 733 |
ret = CL_EMEM; |
734 | 734 |
break; |
... | ... |
@@ -817,9 +817,9 @@ static int cli_loadzmd(FILE *fd, struct cl_node **root, unsigned int *signo) |
817 | 817 |
break; |
818 | 818 |
} else { |
819 | 819 |
if(!strcmp(pt, "*")) |
820 |
- new->compr = -1; |
|
820 |
+ new->method = -1; |
|
821 | 821 |
else |
822 |
- new->compr = atoi(pt); |
|
822 |
+ new->method = atoi(pt); |
|
823 | 823 |
free(pt); |
824 | 824 |
} |
825 | 825 |
|
... | ... |
@@ -851,8 +851,13 @@ static int cli_loadzmd(FILE *fd, struct cl_node **root, unsigned int *signo) |
851 | 851 |
free(pt); |
852 | 852 |
} |
853 | 853 |
|
854 |
- new->next = (*root)->zip_mlist; |
|
855 |
- (*root)->zip_mlist = new; |
|
854 |
+ if(type == 1) { |
|
855 |
+ new->next = (*root)->zip_mlist; |
|
856 |
+ (*root)->zip_mlist = new; |
|
857 |
+ } else { |
|
858 |
+ new->next = (*root)->rar_mlist; |
|
859 |
+ (*root)->rar_mlist = new; |
|
860 |
+ } |
|
856 | 861 |
} |
857 | 862 |
|
858 | 863 |
if(!line) { |
... | ... |
@@ -907,7 +912,10 @@ int cl_loaddb(const char *filename, struct cl_node **root, unsigned int *signo) |
907 | 907 |
ret = cli_loadndb(fd, root, signo); |
908 | 908 |
|
909 | 909 |
} else if(cli_strbcasestr(filename, ".zmd")) { |
910 |
- ret = cli_loadzmd(fd, root, signo); |
|
910 |
+ ret = cli_loadmd(fd, root, signo, 1); |
|
911 |
+ |
|
912 |
+ } else if(cli_strbcasestr(filename, ".rmd")) { |
|
913 |
+ ret = cli_loadmd(fd, root, signo, 2); |
|
911 | 914 |
|
912 | 915 |
} else { |
913 | 916 |
cli_dbgmsg("cl_loaddb: unknown extension - assuming old database format\n"); |
... | ... |
@@ -958,9 +966,10 @@ int cl_loaddbdir(const char *dirname, struct cl_node **root, unsigned int *signo |
958 | 958 |
cli_strbcasestr(dent->d_name, ".db2") || |
959 | 959 |
cli_strbcasestr(dent->d_name, ".db3") || |
960 | 960 |
cli_strbcasestr(dent->d_name, ".hdb") || |
961 |
- cli_strbcasestr(dent->d_name, ".fp") || |
|
961 |
+ cli_strbcasestr(dent->d_name, ".fp") || |
|
962 | 962 |
cli_strbcasestr(dent->d_name, ".ndb") || |
963 | 963 |
cli_strbcasestr(dent->d_name, ".zmd") || |
964 |
+ cli_strbcasestr(dent->d_name, ".rmd") || |
|
964 | 965 |
cli_strbcasestr(dent->d_name, ".cvd"))) { |
965 | 966 |
|
966 | 967 |
dbfile = (char *) cli_calloc(strlen(dent->d_name) + strlen(dirname) + 2, sizeof(char)); |
... | ... |
@@ -1040,6 +1049,7 @@ int cl_statinidir(const char *dirname, struct cl_stat *dbstat) |
1040 | 1040 |
cli_strbcasestr(dent->d_name, ".fp") || |
1041 | 1041 |
cli_strbcasestr(dent->d_name, ".ndb") || |
1042 | 1042 |
cli_strbcasestr(dent->d_name, ".zmd") || |
1043 |
+ cli_strbcasestr(dent->d_name, ".rmd") || |
|
1043 | 1044 |
cli_strbcasestr(dent->d_name, ".cvd"))) { |
1044 | 1045 |
|
1045 | 1046 |
dbstat->no++; |
... | ... |
@@ -1110,6 +1120,7 @@ int cl_statchkdir(const struct cl_stat *dbstat) |
1110 | 1110 |
cli_strbcasestr(dent->d_name, ".fp") || |
1111 | 1111 |
cli_strbcasestr(dent->d_name, ".ndb") || |
1112 | 1112 |
cli_strbcasestr(dent->d_name, ".zmd") || |
1113 |
+ cli_strbcasestr(dent->d_name, ".rmd") || |
|
1113 | 1114 |
cli_strbcasestr(dent->d_name, ".cvd"))) { |
1114 | 1115 |
|
1115 | 1116 |
fname = cli_calloc(strlen(dbstat->dir) + strlen(dent->d_name) + 2, sizeof(char)); |
... | ... |
@@ -120,23 +120,23 @@ static void cli_unlock_mutex(void *mtx) |
120 | 120 |
static int cli_scanrar(int desc, const char **virname, long int *scanned, const struct cl_node *root, const struct cl_limits *limits, unsigned int options, int *arec, int *mrec) |
121 | 121 |
{ |
122 | 122 |
FILE *tmp = NULL; |
123 |
- int files = 0, fd, ret = CL_CLEAN, afiles; |
|
123 |
+ int files = 0, fd, ret = CL_CLEAN, afiles, encrypted; |
|
124 | 124 |
ArchiveList_struct *rarlist = NULL; |
125 | 125 |
ArchiveList_struct *rarlist_head = NULL; |
126 | 126 |
char *rar_data_ptr; |
127 | 127 |
unsigned long rar_data_size; |
128 |
+ struct cli_meta_node *mdata; |
|
128 | 129 |
|
129 | 130 |
|
130 | 131 |
cli_dbgmsg("in scanrar()\n"); |
131 | 132 |
|
132 |
- |
|
133 | 133 |
#ifdef CL_THREAD_SAFE |
134 | 134 |
pthread_cleanup_push(cli_unlock_mutex, &cli_scanrar_mutex); |
135 | 135 |
pthread_mutex_lock(&cli_scanrar_mutex); |
136 | 136 |
cli_scanrar_inuse = 1; |
137 | 137 |
#endif |
138 | 138 |
|
139 |
- if(! (afiles = urarlib_list(desc, (ArchiveList_struct *) &rarlist))) { |
|
139 |
+ if(!(afiles = urarlib_list(desc, (ArchiveList_struct *) &rarlist))) { |
|
140 | 140 |
#ifdef CL_THREAD_SAFE |
141 | 141 |
pthread_mutex_unlock(&cli_scanrar_mutex); |
142 | 142 |
cli_scanrar_inuse = 0; |
... | ... |
@@ -149,8 +149,52 @@ static int cli_scanrar(int desc, const char **virname, long int *scanned, const |
149 | 149 |
rarlist_head = rarlist; |
150 | 150 |
|
151 | 151 |
while(rarlist) { |
152 |
+ |
|
153 |
+ files++; |
|
154 |
+ encrypted = rarlist->item.Flags & 0x04; |
|
155 |
+ |
|
156 |
+ cli_dbgmsg("RAR: %s, crc32: 0x%x, encrypted: %d, compressed: %u, normal: %u, method: %d, ratio: %d (max: %d)\n", rarlist->item.Name, rarlist->item.FileCRC, encrypted, rarlist->item.PackSize, rarlist->item.UnpSize, rarlist->item.Method, rarlist->item.PackSize ? (rarlist->item.UnpSize / rarlist->item.PackSize) : 0, limits ? limits->maxratio : -1); |
|
157 |
+ |
|
158 |
+ /* Scan metadata */ |
|
159 |
+ mdata = root->rar_mlist; |
|
160 |
+ if(mdata) do { |
|
161 |
+ if(mdata->encrypted != encrypted) |
|
162 |
+ continue; |
|
163 |
+ |
|
164 |
+ if(mdata->crc32 && mdata->crc32 != rarlist->item.FileCRC) |
|
165 |
+ continue; |
|
166 |
+ |
|
167 |
+ if(mdata->csize > 0 && mdata->csize != rarlist->item.PackSize) |
|
168 |
+ continue; |
|
169 |
+ |
|
170 |
+ if(mdata->size >= 0 && mdata->size != rarlist->item.UnpSize) |
|
171 |
+ continue; |
|
172 |
+ |
|
173 |
+ if(mdata->method >= 0 && mdata->method != rarlist->item.Method) |
|
174 |
+ continue; |
|
175 |
+ |
|
176 |
+ if(mdata->fileno && mdata->fileno != files) |
|
177 |
+ continue; |
|
178 |
+ |
|
179 |
+ if(mdata->maxdepth && *arec > mdata->maxdepth) |
|
180 |
+ continue; |
|
181 |
+ |
|
182 |
+ /* TODO add support for regex */ |
|
183 |
+ /*if(mdata->filename && !strstr(zdirent.d_name, mdata->filename))*/ |
|
184 |
+ if(mdata->filename && strcmp(rarlist->item.Name, mdata->filename)) |
|
185 |
+ continue; |
|
186 |
+ |
|
187 |
+ break; /* matched */ |
|
188 |
+ |
|
189 |
+ } while((mdata = mdata->next)); |
|
190 |
+ |
|
191 |
+ if(mdata) { |
|
192 |
+ *virname = mdata->virname; |
|
193 |
+ ret = CL_VIRUS; |
|
194 |
+ break; |
|
195 |
+ } |
|
196 |
+ |
|
152 | 197 |
if(DETECT_ENCRYPTED && (rarlist->item.Flags & 0x04)) { |
153 |
- files++; |
|
154 | 198 |
cli_dbgmsg("RAR: Encrypted files found in archive.\n"); |
155 | 199 |
lseek(desc, 0, SEEK_SET); |
156 | 200 |
ret = cli_scandesc(desc, virname, scanned, root, 0, 0); |
... | ... |
@@ -166,7 +210,6 @@ static int cli_scanrar(int desc, const char **virname, long int *scanned, const |
166 | 166 |
if((rarlist->item.Flags & 0x03) != 0) { |
167 | 167 |
cli_dbgmsg("RAR: Skipping %s (splitted)\n", rarlist->item.Name); |
168 | 168 |
rarlist = rarlist->next; |
169 |
- files++; |
|
170 | 169 |
continue; |
171 | 170 |
} |
172 | 171 |
|
... | ... |
@@ -184,7 +227,6 @@ static int cli_scanrar(int desc, const char **virname, long int *scanned, const |
184 | 184 |
if(limits->maxfilesize && (rarlist->item.UnpSize > (unsigned int) limits->maxfilesize)) { |
185 | 185 |
cli_dbgmsg("RAR: %s: Size exceeded (%u, max: %lu)\n", rarlist->item.Name, (unsigned int) rarlist->item.UnpSize, limits->maxfilesize); |
186 | 186 |
rarlist = rarlist->next; |
187 |
- files++; |
|
188 | 187 |
if(BLOCKMAX) { |
189 | 188 |
*virname = "RAR.ExceededFileSize"; |
190 | 189 |
ret = CL_VIRUS; |
... | ... |
@@ -206,7 +248,6 @@ static int cli_scanrar(int desc, const char **virname, long int *scanned, const |
206 | 206 |
|
207 | 207 |
if(rarlist->item.FileAttr & RAR_FENTRY_ATTR_DIRECTORY) { |
208 | 208 |
rarlist = rarlist->next; |
209 |
- files++; |
|
210 | 209 |
continue; |
211 | 210 |
} |
212 | 211 |
|
... | ... |
@@ -273,7 +314,6 @@ static int cli_scanrar(int desc, const char **virname, long int *scanned, const |
273 | 273 |
fclose(tmp); |
274 | 274 |
tmp = NULL; |
275 | 275 |
rarlist = rarlist->next; |
276 |
- files++; |
|
277 | 276 |
} |
278 | 277 |
|
279 | 278 |
urarlib_freelist(rarlist_head); |
... | ... |
@@ -298,7 +338,7 @@ static int cli_scanzip(int desc, const char **virname, long int *scanned, const |
298 | 298 |
char *buff; |
299 | 299 |
int fd, bytes, files = 0, ret = CL_CLEAN, encrypted; |
300 | 300 |
struct stat source; |
301 |
- struct cli_zip_node *mdata; |
|
301 |
+ struct cli_meta_node *mdata; |
|
302 | 302 |
zzip_error_t err; |
303 | 303 |
|
304 | 304 |
|
... | ... |
@@ -331,7 +371,7 @@ static int cli_scanzip(int desc, const char **virname, long int *scanned, const |
331 | 331 |
|
332 | 332 |
encrypted = zdirent.d_flags; |
333 | 333 |
|
334 |
- cli_dbgmsg("Zip: %s, crc32: 0x%x, encrypted: %d, compressed: %u, normal: %u, ratio: %d (max: %d)\n", zdirent.d_name, zdirent.d_crc32, encrypted, zdirent.d_csize, zdirent.st_size, zdirent.d_csize ? (zdirent.st_size / zdirent.d_csize) : 0, limits ? limits->maxratio : -1); |
|
334 |
+ cli_dbgmsg("Zip: %s, crc32: 0x%x, encrypted: %d, compressed: %u, normal: %u, method: %d, ratio: %d (max: %d)\n", zdirent.d_name, zdirent.d_crc32, encrypted, zdirent.d_csize, zdirent.st_size, zdirent.d_compr, zdirent.d_csize ? (zdirent.st_size / zdirent.d_csize) : 0, limits ? limits->maxratio : -1); |
|
335 | 335 |
|
336 | 336 |
if(!zdirent.st_size) { |
337 | 337 |
if(zdirent.d_crc32) { |
... | ... |
@@ -358,7 +398,7 @@ static int cli_scanzip(int desc, const char **virname, long int *scanned, const |
358 | 358 |
if(mdata->size >= 0 && mdata->size != zdirent.st_size) |
359 | 359 |
continue; |
360 | 360 |
|
361 |
- if(mdata->compr >= 0 && mdata->compr != zdirent.d_compr) |
|
361 |
+ if(mdata->method >= 0 && mdata->method != zdirent.d_compr) |
|
362 | 362 |
continue; |
363 | 363 |
|
364 | 364 |
if(mdata->fileno && mdata->fileno != files) |
... | ... |
@@ -251,7 +251,7 @@ int build(struct optstruct *opt) |
251 | 251 |
exit(1); |
252 | 252 |
} |
253 | 253 |
|
254 |
- if(stat("main.db", &foo) == -1 && stat("daily.db", &foo) == -1 && stat("main.hdb", &foo) == -1 && stat("daily.hdb", &foo) == -1 && stat("main.ndb", &foo) == -1 && stat("daily.ndb", &foo) == -1 && stat("main.zmd", &foo) == -1 && stat("daily.zmd", &foo) == -1) { |
|
254 |
+ if(stat("main.db", &foo) == -1 && stat("daily.db", &foo) == -1 && stat("main.hdb", &foo) == -1 && stat("daily.hdb", &foo) == -1 && stat("main.ndb", &foo) == -1 && stat("daily.ndb", &foo) == -1 && stat("main.zmd", &foo) == -1 && stat("main.rmd", &foo) == -1 && stat("daily.zmd", &foo) == -1 && stat("daily.rmd", &foo) == -1) { |
|
255 | 255 |
mprintf("Virus database not found in current working directory.\n"); |
256 | 256 |
exit(1); |
257 | 257 |
} |
... | ... |
@@ -271,7 +271,7 @@ int build(struct optstruct *opt) |
271 | 271 |
mprintf("WARNING: There are no signatures in the database(s).\n"); |
272 | 272 |
} else { |
273 | 273 |
mprintf("Signatures: %d\n", no); |
274 |
- realno = countlines("main.db") + countlines("daily.db") + countlines("main.hdb") + countlines("daily.hdb") + countlines("main.ndb") + countlines("daily.ndb") + countlines("main.zmd") + countlines("daily.zmd"); |
|
274 |
+ realno = countlines("main.db") + countlines("daily.db") + countlines("main.hdb") + countlines("daily.hdb") + countlines("main.ndb") + countlines("daily.ndb") + countlines("main.zmd") + countlines("daily.zmd") + countlines("main.rmd") + countlines("daily.rmd"); |
|
275 | 275 |
if(realno != no) { |
276 | 276 |
mprintf("!Signatures in database: %d. Loaded: %d.\n", realno, no); |
277 | 277 |
mprintf("Please check the current directory and remove unnecessary databases\n"); |
... | ... |
@@ -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", "main.fp", "daily.fp", 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.rmd", "daily.rmd", "main.fp", "daily.fp", NULL }; |
|
292 | 292 |
args[2] = tarfile; |
293 | 293 |
execv("/bin/tar", args); |
294 | 294 |
mprintf("!Can't execute tar\n"); |
... | ... |
@@ -705,7 +705,7 @@ int listdb(const char *filename) |
705 | 705 |
free(start); |
706 | 706 |
} |
707 | 707 |
|
708 |
- } else if(cli_strbcasestr(filename, ".ndb") || cli_strbcasestr(filename, ".zmd")) { |
|
708 |
+ } else if(cli_strbcasestr(filename, ".ndb") || cli_strbcasestr(filename, ".zmd") || cli_strbcasestr(filename, ".rmd")) { |
|
709 | 709 |
|
710 | 710 |
while(fgets(buffer, FILEBUFF, fd)) { |
711 | 711 |
line++; |
... | ... |
@@ -755,6 +755,7 @@ int listdir(const char *dirname) |
755 | 755 |
cli_strbcasestr(dent->d_name, ".hdb") || |
756 | 756 |
cli_strbcasestr(dent->d_name, ".ndb") || |
757 | 757 |
cli_strbcasestr(dent->d_name, ".zmd") || |
758 |
+ cli_strbcasestr(dent->d_name, ".rmd") || |
|
758 | 759 |
cli_strbcasestr(dent->d_name, ".cvd"))) { |
759 | 760 |
|
760 | 761 |
dbfile = (char *) mcalloc(strlen(dent->d_name) + strlen(dirname) + 2, sizeof(char)); |