git-svn: trunk@76
Tomasz Kojm authored on 2003/10/08 19:40:53... | ... |
@@ -1,3 +1,8 @@ |
1 |
+Wed Oct 8 12:39:26 CEST 2003 (tk) |
|
2 |
+---------------------------------- |
|
3 |
+ * clamd: (!!!) fixed race condition in database reloading code |
|
4 |
+ * libclamav: finished support for cvd files |
|
5 |
+ |
|
1 | 6 |
Sun Oct 5 18:30:40 BST 2003 (njh) |
2 | 7 |
---------------------------------- |
3 | 8 |
* clamav-milter: Used to always remove old UNIX domain sockets, now |
... | ... |
@@ -25,6 +25,10 @@ |
25 | 25 |
#define _GNU_SOURCE |
26 | 26 |
#include "getopt.h" |
27 | 27 |
|
28 |
+#if defined(C_LINUX) && defined(CL_DEBUG) |
|
29 |
+#include <sys/resource.h> |
|
30 |
+#endif |
|
31 |
+ |
|
28 | 32 |
#include "options.h" |
29 | 33 |
#include "others.h" |
30 | 34 |
|
... | ... |
@@ -44,7 +48,14 @@ int main(int argc, char **argv) |
44 | 44 |
{0, 0, 0, 0} |
45 | 45 |
}; |
46 | 46 |
|
47 |
+#if defined(C_LINUX) && defined(CL_DEBUG) |
|
48 |
+ /* njh@bandsman.co.uk: create a dump if needed */ |
|
49 |
+ struct rlimit rlim; |
|
47 | 50 |
|
51 |
+ rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY; |
|
52 |
+ if(setrlimit(RLIMIT_CORE, &rlim) < 0) |
|
53 |
+ perror("setrlimit"); |
|
54 |
+#endif |
|
48 | 55 |
opt=(struct optstruct*)mmalloc(sizeof(struct optstruct)); |
49 | 56 |
opt->optlist = NULL; |
50 | 57 |
|
... | ... |
@@ -68,21 +68,6 @@ void *threadscanner(void *arg) |
68 | 68 |
sigfillset(&sigset); |
69 | 69 |
pthread_sigmask(SIG_SETMASK, &sigset, NULL); |
70 | 70 |
|
71 |
- if(reload) { |
|
72 |
- logg("*Session(%d): database reloading (waiting).\n", tharg->sid); |
|
73 |
- ths[tharg->sid].reload = 1; |
|
74 |
- while(reload && maxwait--) /* wait during reloading */ |
|
75 |
- sleep(1); |
|
76 |
- |
|
77 |
- if(!maxwait && reload) { |
|
78 |
- logg("!Database reloading failed, time exceeded. Forcing quit.\n"); |
|
79 |
- kill(progpid, SIGTERM); |
|
80 |
- } |
|
81 |
- |
|
82 |
- ths[tharg->sid].reload = 0; |
|
83 |
- logg("*Session(%d): database reloaded.\n", tharg->sid); |
|
84 |
- } |
|
85 |
- |
|
86 | 71 |
if((bread = read(ths[tharg->sid].desc, buff, 1024)) == -1) { |
87 | 72 |
logg("!Session(%d): read() failed.\n", tharg->sid); |
88 | 73 |
THREXIT; |
... | ... |
@@ -140,8 +125,9 @@ void *threadwatcher(void *arg) |
140 | 140 |
struct cl_stat dbstat; |
141 | 141 |
|
142 | 142 |
|
143 |
- /* ignore all signals */ |
|
143 |
+ /* ignore all signals (except for SIGSEGV) */ |
|
144 | 144 |
sigfillset(&sigset); |
145 |
+ sigdelset(&sigset, SIGSEGV); |
|
145 | 146 |
pthread_sigmask(SIG_SETMASK, &sigset, NULL); |
146 | 147 |
|
147 | 148 |
#ifdef C_LINUX |
... | ... |
@@ -282,8 +268,15 @@ void *threadwatcher(void *arg) |
282 | 282 |
|
283 | 283 |
timer++; |
284 | 284 |
|
285 |
- /* reload the database(s) */ |
|
285 |
+ /* reload the database */ |
|
286 | 286 |
if(reload) { |
287 |
+ |
|
288 |
+ /* make sure the main thread doesn't start new threads */ |
|
289 |
+ do { |
|
290 |
+ usleep(200000); |
|
291 |
+ } while(!main_accept && !main_reload); |
|
292 |
+ |
|
293 |
+ /* wait until all working threads are finished */ |
|
287 | 294 |
do { |
288 | 295 |
need_wait = 0; |
289 | 296 |
for(j = 0; j < threads; j++) |
... | ... |
@@ -291,8 +284,7 @@ void *threadwatcher(void *arg) |
291 | 291 |
if(time(NULL) - ths[j].start > timeout) { |
292 | 292 |
do_loop = 1; |
293 | 293 |
break; |
294 |
- } else if(!ths[j].reload) |
|
295 |
- need_wait = 1; |
|
294 |
+ } else need_wait = 1; |
|
296 | 295 |
} |
297 | 296 |
|
298 | 297 |
#ifdef CLAMUKO |
... | ... |
@@ -317,6 +309,7 @@ void *threadwatcher(void *arg) |
317 | 317 |
/* some threads must be stopped in the next iteration, |
318 | 318 |
* reload is still == 1 |
319 | 319 |
*/ |
320 |
+ logg("Database reload: some threads must be stopped in the next iteration.\n"); |
|
320 | 321 |
do_loop = 0; |
321 | 322 |
continue; |
322 | 323 |
} |
... | ... |
@@ -342,6 +335,8 @@ void *threadwatcher(void *arg) |
342 | 342 |
} else { |
343 | 343 |
cl_buildtrie(*thwarg->root); |
344 | 344 |
/* check integrity */ |
345 |
+ if(!testsignature(*thwarg->root)) |
|
346 |
+ logg("!Unable to detect test signature.\n"); |
|
345 | 347 |
|
346 | 348 |
logg("Database correctly reloaded (%d viruses)\n", virnum); |
347 | 349 |
} |
... | ... |
@@ -517,7 +512,9 @@ int acceptloop(int socketd, struct cl_node *root, const struct cfgstruct *copt) |
517 | 517 |
sigaddset(&sigact.sa_mask, SIGHUP); |
518 | 518 |
sigaction(SIGINT, &sigact, NULL); |
519 | 519 |
sigaction(SIGTERM, &sigact, NULL); |
520 |
+#ifndef CL_DEBUG |
|
520 | 521 |
sigaction(SIGSEGV, &sigact, NULL); |
522 |
+#endif |
|
521 | 523 |
sigaction(SIGHUP, &sigact, NULL); |
522 | 524 |
|
523 | 525 |
/* we need to save program's PID, because under Linux each thread |
... | ... |
@@ -551,14 +548,16 @@ int acceptloop(int socketd, struct cl_node *root, const struct cfgstruct *copt) |
551 | 551 |
} |
552 | 552 |
|
553 | 553 |
|
554 |
+ main_accept = 1; |
|
554 | 555 |
if((acceptd = accept(socketd, NULL, NULL)) == -1) { |
555 | 556 |
logg("!accept() failed.\n"); |
556 | 557 |
/* exit ? */ |
557 | 558 |
continue; |
558 | 559 |
} |
559 |
- |
|
560 |
+ main_accept = 0; |
|
560 | 561 |
|
561 | 562 |
if(reload) { /* do not start new threads */ |
563 |
+ main_reload = 1; |
|
562 | 564 |
logg("*Main thread: database reloading (waiting).\n"); |
563 | 565 |
maxwait = CL_DEFAULT_MAXWHILEWAIT; |
564 | 566 |
while(reload && maxwait--) |
... | ... |
@@ -572,6 +571,7 @@ int acceptloop(int socketd, struct cl_node *root, const struct cfgstruct *copt) |
572 | 572 |
} |
573 | 573 |
|
574 | 574 |
logg("*Main thread: database reloaded.\n"); |
575 |
+ main_reload = 0; |
|
575 | 576 |
} |
576 | 577 |
|
577 | 578 |
tharg = (struct thrarg *) mcalloc(1, sizeof(struct thrarg)); |
... | ... |
@@ -581,9 +581,7 @@ int acceptloop(int socketd, struct cl_node *root, const struct cfgstruct *copt) |
581 | 581 |
tharg->limits = &limits; |
582 | 582 |
tharg->options = options; |
583 | 583 |
|
584 |
- //pthread_mutex_lock(&ths[i].mutex); |
|
585 | 584 |
ths[i].desc = acceptd; |
586 |
- ths[i].reload = 0; |
|
587 | 585 |
ths[i].active = 1; |
588 | 586 |
pthread_create(&ths[i].id, &thattr, threadscanner, tharg); |
589 | 587 |
ths[i].start = time(NULL); |
... | ... |
@@ -612,6 +610,7 @@ void sighandler(int sig) |
612 | 612 |
exit(0); |
613 | 613 |
break; /* not reached */ |
614 | 614 |
|
615 |
+#ifndef CL_DEBUG |
|
615 | 616 |
case SIGSEGV: |
616 | 617 |
logg("Segmentation fault :-( Bye..\n"); |
617 | 618 |
|
... | ... |
@@ -622,7 +621,7 @@ void sighandler(int sig) |
622 | 622 |
pthread_kill(watcherid, 9); |
623 | 623 |
exit(11); /* probably not reached at all */ |
624 | 624 |
break; /* not reached */ |
625 |
- |
|
625 |
+#endif |
|
626 | 626 |
case SIGHUP: |
627 | 627 |
sighup = 1; |
628 | 628 |
logg("SIGHUP catched: log file re-opened.\n"); |
... | ... |
@@ -34,7 +34,6 @@ struct thrarg { |
34 | 34 |
struct thrsession { |
35 | 35 |
pthread_mutex_t mutex; |
36 | 36 |
short int active; |
37 |
- short int reload; |
|
38 | 37 |
pthread_t id; |
39 | 38 |
time_t start; |
40 | 39 |
int desc; |
... | ... |
@@ -49,7 +48,7 @@ struct thrwarg { |
49 | 49 |
|
50 | 50 |
short int progexit; /* exit steering variable */ |
51 | 51 |
int progpid; /* clamd pid */ |
52 |
-short int reload, clamuko_reload; |
|
52 |
+short int reload, clamuko_reload, main_accept, main_reload; |
|
53 | 53 |
|
54 | 54 |
int acceptloop(int socketd, struct cl_node *root, const struct cfgstruct *copt); |
55 | 55 |
void sighandler(int sig); |
... | ... |
@@ -999,6 +999,7 @@ Optional Features: |
999 | 999 |
--disable-libtool-lock avoid locking (might break parallel builds) |
1000 | 1000 |
--disable-bzip2 Disable bzip2 support. |
1001 | 1001 |
--enable-milter Build clamav-milter (if milter library found) |
1002 |
+ --disable-dsig Disable digital signature support. |
|
1002 | 1003 |
--disable-pthreads Disable POSIX threads support |
1003 | 1004 |
--disable-cr Don't link with C reentrant library (BSD) |
1004 | 1005 |
--disable-urandom Disable test for /dev/urandom |
... | ... |
@@ -1901,7 +1902,7 @@ fi |
1901 | 1901 |
|
1902 | 1902 |
# Define the identity of the package. |
1903 | 1903 |
PACKAGE=clamav |
1904 |
- VERSION=20030829 |
|
1904 |
+ VERSION="devel-`date +%Y%m%d`" |
|
1905 | 1905 |
|
1906 | 1906 |
|
1907 | 1907 |
cat >>confdefs.h <<_ACEOF |
... | ... |
@@ -4534,7 +4535,7 @@ test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes |
4534 | 4534 |
case $host in |
4535 | 4535 |
*-*-irix6*) |
4536 | 4536 |
# Find out which ABI we are using. |
4537 |
- echo '#line 4537 "configure"' > conftest.$ac_ext |
|
4537 |
+ echo '#line 4538 "configure"' > conftest.$ac_ext |
|
4538 | 4538 |
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 |
4539 | 4539 |
(eval $ac_compile) 2>&5 |
4540 | 4540 |
ac_status=$? |
... | ... |
@@ -5070,7 +5071,7 @@ chmod -w . |
5070 | 5070 |
save_CFLAGS="$CFLAGS" |
5071 | 5071 |
CFLAGS="$CFLAGS -o out/conftest2.$ac_objext" |
5072 | 5072 |
compiler_c_o=no |
5073 |
-if { (eval echo configure:5073: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then |
|
5073 |
+if { (eval echo configure:5074: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then |
|
5074 | 5074 |
# The compiler can only warn and ignore the option if not recognized |
5075 | 5075 |
# So say no if there are warnings |
5076 | 5076 |
if test -s out/conftest.err; then |
... | ... |
@@ -6863,7 +6864,7 @@ else |
6863 | 6863 |
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 |
6864 | 6864 |
lt_status=$lt_dlunknown |
6865 | 6865 |
cat > conftest.$ac_ext <<EOF |
6866 |
-#line 6866 "configure" |
|
6866 |
+#line 6867 "configure" |
|
6867 | 6867 |
#include "confdefs.h" |
6868 | 6868 |
|
6869 | 6869 |
#if HAVE_DLFCN_H |
... | ... |
@@ -6961,7 +6962,7 @@ else |
6961 | 6961 |
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 |
6962 | 6962 |
lt_status=$lt_dlunknown |
6963 | 6963 |
cat > conftest.$ac_ext <<EOF |
6964 |
-#line 6964 "configure" |
|
6964 |
+#line 6965 "configure" |
|
6965 | 6965 |
#include "confdefs.h" |
6966 | 6966 |
|
6967 | 6967 |
#if HAVE_DLFCN_H |
... | ... |
@@ -8733,6 +8734,84 @@ else |
8733 | 8733 |
have_milter="no" |
8734 | 8734 |
fi; |
8735 | 8735 |
|
8736 |
+want_dsig="yes" |
|
8737 |
+# Check whether --enable-dsig or --disable-dsig was given. |
|
8738 |
+if test "${enable_dsig+set}" = set; then |
|
8739 |
+ enableval="$enable_dsig" |
|
8740 |
+ want_dsig="no" |
|
8741 |
+fi; |
|
8742 |
+ |
|
8743 |
+if test "$want_dsig" = "yes" |
|
8744 |
+then |
|
8745 |
+ echo "$as_me:$LINENO: checking for __gmpz_init in -lgmp" >&5 |
|
8746 |
+echo $ECHO_N "checking for __gmpz_init in -lgmp... $ECHO_C" >&6 |
|
8747 |
+if test "${ac_cv_lib_gmp___gmpz_init+set}" = set; then |
|
8748 |
+ echo $ECHO_N "(cached) $ECHO_C" >&6 |
|
8749 |
+else |
|
8750 |
+ ac_check_lib_save_LIBS=$LIBS |
|
8751 |
+LIBS="-lgmp $LIBS" |
|
8752 |
+cat >conftest.$ac_ext <<_ACEOF |
|
8753 |
+#line $LINENO "configure" |
|
8754 |
+#include "confdefs.h" |
|
8755 |
+ |
|
8756 |
+/* Override any gcc2 internal prototype to avoid an error. */ |
|
8757 |
+#ifdef __cplusplus |
|
8758 |
+extern "C" |
|
8759 |
+#endif |
|
8760 |
+/* We use char because int might match the return type of a gcc2 |
|
8761 |
+ builtin and then its argument prototype would still apply. */ |
|
8762 |
+char __gmpz_init (); |
|
8763 |
+#ifdef F77_DUMMY_MAIN |
|
8764 |
+# ifdef __cplusplus |
|
8765 |
+ extern "C" |
|
8766 |
+# endif |
|
8767 |
+ int F77_DUMMY_MAIN() { return 1; } |
|
8768 |
+#endif |
|
8769 |
+int |
|
8770 |
+main () |
|
8771 |
+{ |
|
8772 |
+__gmpz_init (); |
|
8773 |
+ ; |
|
8774 |
+ return 0; |
|
8775 |
+} |
|
8776 |
+_ACEOF |
|
8777 |
+rm -f conftest.$ac_objext conftest$ac_exeext |
|
8778 |
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 |
|
8779 |
+ (eval $ac_link) 2>&5 |
|
8780 |
+ ac_status=$? |
|
8781 |
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 |
|
8782 |
+ (exit $ac_status); } && |
|
8783 |
+ { ac_try='test -s conftest$ac_exeext' |
|
8784 |
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 |
|
8785 |
+ (eval $ac_try) 2>&5 |
|
8786 |
+ ac_status=$? |
|
8787 |
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 |
|
8788 |
+ (exit $ac_status); }; }; then |
|
8789 |
+ ac_cv_lib_gmp___gmpz_init=yes |
|
8790 |
+else |
|
8791 |
+ echo "$as_me: failed program was:" >&5 |
|
8792 |
+cat conftest.$ac_ext >&5 |
|
8793 |
+ac_cv_lib_gmp___gmpz_init=no |
|
8794 |
+fi |
|
8795 |
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext |
|
8796 |
+LIBS=$ac_check_lib_save_LIBS |
|
8797 |
+fi |
|
8798 |
+echo "$as_me:$LINENO: result: $ac_cv_lib_gmp___gmpz_init" >&5 |
|
8799 |
+echo "${ECHO_T}$ac_cv_lib_gmp___gmpz_init" >&6 |
|
8800 |
+if test $ac_cv_lib_gmp___gmpz_init = yes; then |
|
8801 |
+ LIBCLAMAV_LIBS="$LIBCLAMAV_LIBS -lgmp"; cat >>confdefs.h <<\_ACEOF |
|
8802 |
+#define HAVE_GMP 1 |
|
8803 |
+_ACEOF |
|
8804 |
+ |
|
8805 |
+else |
|
8806 |
+ echo "WARNING: GNU MP 3 or newer NOT FOUND - digital signature support will be disabled !"; want_dsig="no" |
|
8807 |
+fi |
|
8808 |
+ |
|
8809 |
+fi |
|
8810 |
+ |
|
8811 |
+ |
|
8812 |
+ |
|
8813 |
+ |
|
8736 | 8814 |
if test "${ac_cv_header_syslog_h+set}" = set; then |
8737 | 8815 |
echo "$as_me:$LINENO: checking for syslog.h" >&5 |
8738 | 8816 |
echo $ECHO_N "checking for syslog.h... $ECHO_C" >&6 |
... | ... |
@@ -19,8 +19,7 @@ AC_INIT(clamscan/clamscan.c) |
19 | 19 |
AC_CREATE_TARGET_H(target.h) |
20 | 20 |
AC_CANONICAL_SYSTEM |
21 | 21 |
|
22 |
-AM_INIT_AUTOMAKE(clamav, 20030829) |
|
23 |
-dnl AM_INIT_AUTOMAKE(clamav, `date +%Y%m%d`) |
|
22 |
+AM_INIT_AUTOMAKE(clamav, "devel-`date +%Y%m%d`") |
|
24 | 23 |
LC_CURRENT=1 |
25 | 24 |
LC_REVISION=3 |
26 | 25 |
LC_AGE=0 |
... | ... |
@@ -81,6 +80,19 @@ AC_ARG_ENABLE(milter, |
81 | 81 |
[ --enable-milter Build clamav-milter (if milter library found)], |
82 | 82 |
,have_milter="no") |
83 | 83 |
|
84 |
+want_dsig="yes" |
|
85 |
+AC_ARG_ENABLE(dsig, |
|
86 |
+[ --disable-dsig Disable digital signature support.], |
|
87 |
+want_dsig="no",) |
|
88 |
+ |
|
89 |
+if test "$want_dsig" = "yes" |
|
90 |
+then |
|
91 |
+ AC_CHECK_LIB(gmp, __gmpz_init, [LIBCLAMAV_LIBS="$LIBCLAMAV_LIBS -lgmp"; AC_DEFINE(HAVE_GMP)], [echo "WARNING: GNU MP 3 or newer NOT FOUND - digital signature support will be disabled !"; want_dsig="no"]) |
|
92 |
+fi |
|
93 |
+ |
|
94 |
+ |
|
95 |
+ |
|
96 |
+ |
|
84 | 97 |
AC_CHECK_HEADER(syslog.h,AC_DEFINE(CLAMD_USE_SYSLOG),) |
85 | 98 |
|
86 | 99 |
dnl AC_CHECK_LIB(c, strtok_r,, AC_DEFINE(NO_STRTOK_R)) |
... | ... |
@@ -1,5 +1,5 @@ |
1 | 1 |
# |
2 |
-# Copyright (C) 2002 Tomasz Kojm <zolw@konarski.edu.pl> |
|
2 |
+# Copyright (C) 2002, 2003 Tomasz Kojm <zolw@konarski.edu.pl> |
|
3 | 3 |
# |
4 | 4 |
# This program is free software; you can redistribute it and/or modify |
5 | 5 |
# it under the terms of the GNU General Public License as published by |
... | ... |
@@ -16,7 +16,7 @@ |
16 | 16 |
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
17 | 17 |
|
18 | 18 |
|
19 |
-CFLAGS = -Wall |
|
19 |
+CFLAGS = -Wall -pedantic |
|
20 | 20 |
|
21 | 21 |
INCLUDES = -I.. -I@srcdir@/zziplib |
22 | 22 |
|
... | ... |
@@ -35,6 +35,9 @@ libclamav_la_SOURCES = \ |
35 | 35 |
others.h \ |
36 | 36 |
readdb.c \ |
37 | 37 |
cvd.c \ |
38 |
+ cvd.h \ |
|
39 |
+ dsig.c \ |
|
40 |
+ dsig.h \ |
|
38 | 41 |
str.c \ |
39 | 42 |
str.h \ |
40 | 43 |
defaults.h \ |
... | ... |
@@ -15,7 +15,7 @@ |
15 | 15 |
@SET_MAKE@ |
16 | 16 |
|
17 | 17 |
# |
18 |
-# Copyright (C) 2002 Tomasz Kojm <zolw@konarski.edu.pl> |
|
18 |
+# Copyright (C) 2002, 2003 Tomasz Kojm <zolw@konarski.edu.pl> |
|
19 | 19 |
# |
20 | 20 |
# This program is free software; you can redistribute it and/or modify |
21 | 21 |
# it under the terms of the GNU General Public License as published by |
... | ... |
@@ -114,7 +114,7 @@ am__include = @am__include@ |
114 | 114 |
am__quote = @am__quote@ |
115 | 115 |
install_sh = @install_sh@ |
116 | 116 |
|
117 |
-CFLAGS = -Wall |
|
117 |
+CFLAGS = -Wall -pedantic |
|
118 | 118 |
|
119 | 119 |
INCLUDES = -I.. -I@srcdir@/zziplib |
120 | 120 |
|
... | ... |
@@ -133,6 +133,9 @@ libclamav_la_SOURCES = \ |
133 | 133 |
others.h \ |
134 | 134 |
readdb.c \ |
135 | 135 |
cvd.c \ |
136 |
+ cvd.h \ |
|
137 |
+ dsig.c \ |
|
138 |
+ dsig.h \ |
|
136 | 139 |
str.c \ |
137 | 140 |
str.h \ |
138 | 141 |
defaults.h \ |
... | ... |
@@ -178,7 +181,7 @@ LTLIBRARIES = $(lib_LTLIBRARIES) |
178 | 178 |
|
179 | 179 |
libclamav_la_DEPENDENCIES = |
180 | 180 |
am_libclamav_la_OBJECTS = matcher.lo md5.lo others.lo readdb.lo cvd.lo \ |
181 |
- str.lo scanners.lo unrarlib.lo zzip-dir.lo zzip-err.lo \ |
|
181 |
+ dsig.lo str.lo scanners.lo unrarlib.lo zzip-dir.lo zzip-err.lo \ |
|
182 | 182 |
zzip-file.lo zzip-info.lo zzip-io.lo zzip-stat.lo zzip-zip.lo \ |
183 | 183 |
strc.lo blob.lo mbox.lo message.lo strrcpy.lo table.lo text.lo |
184 | 184 |
libclamav_la_OBJECTS = $(am_libclamav_la_OBJECTS) |
... | ... |
@@ -191,16 +194,17 @@ LIBS = @LIBS@ |
191 | 191 |
depcomp = $(SHELL) $(top_srcdir)/depcomp |
192 | 192 |
am__depfiles_maybe = depfiles |
193 | 193 |
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/blob.Plo ./$(DEPDIR)/cvd.Plo \ |
194 |
-@AMDEP_TRUE@ ./$(DEPDIR)/matcher.Plo ./$(DEPDIR)/mbox.Plo \ |
|
195 |
-@AMDEP_TRUE@ ./$(DEPDIR)/md5.Plo ./$(DEPDIR)/message.Plo \ |
|
196 |
-@AMDEP_TRUE@ ./$(DEPDIR)/others.Plo ./$(DEPDIR)/readdb.Plo \ |
|
197 |
-@AMDEP_TRUE@ ./$(DEPDIR)/scanners.Plo ./$(DEPDIR)/str.Plo \ |
|
198 |
-@AMDEP_TRUE@ ./$(DEPDIR)/strc.Plo ./$(DEPDIR)/strrcpy.Plo \ |
|
199 |
-@AMDEP_TRUE@ ./$(DEPDIR)/table.Plo ./$(DEPDIR)/text.Plo \ |
|
200 |
-@AMDEP_TRUE@ ./$(DEPDIR)/unrarlib.Plo ./$(DEPDIR)/zzip-dir.Plo \ |
|
201 |
-@AMDEP_TRUE@ ./$(DEPDIR)/zzip-err.Plo ./$(DEPDIR)/zzip-file.Plo \ |
|
202 |
-@AMDEP_TRUE@ ./$(DEPDIR)/zzip-info.Plo ./$(DEPDIR)/zzip-io.Plo \ |
|
203 |
-@AMDEP_TRUE@ ./$(DEPDIR)/zzip-stat.Plo ./$(DEPDIR)/zzip-zip.Plo |
|
194 |
+@AMDEP_TRUE@ ./$(DEPDIR)/dsig.Plo ./$(DEPDIR)/matcher.Plo \ |
|
195 |
+@AMDEP_TRUE@ ./$(DEPDIR)/mbox.Plo ./$(DEPDIR)/md5.Plo \ |
|
196 |
+@AMDEP_TRUE@ ./$(DEPDIR)/message.Plo ./$(DEPDIR)/others.Plo \ |
|
197 |
+@AMDEP_TRUE@ ./$(DEPDIR)/readdb.Plo ./$(DEPDIR)/scanners.Plo \ |
|
198 |
+@AMDEP_TRUE@ ./$(DEPDIR)/str.Plo ./$(DEPDIR)/strc.Plo \ |
|
199 |
+@AMDEP_TRUE@ ./$(DEPDIR)/strrcpy.Plo ./$(DEPDIR)/table.Plo \ |
|
200 |
+@AMDEP_TRUE@ ./$(DEPDIR)/text.Plo ./$(DEPDIR)/unrarlib.Plo \ |
|
201 |
+@AMDEP_TRUE@ ./$(DEPDIR)/zzip-dir.Plo ./$(DEPDIR)/zzip-err.Plo \ |
|
202 |
+@AMDEP_TRUE@ ./$(DEPDIR)/zzip-file.Plo ./$(DEPDIR)/zzip-info.Plo \ |
|
203 |
+@AMDEP_TRUE@ ./$(DEPDIR)/zzip-io.Plo ./$(DEPDIR)/zzip-stat.Plo \ |
|
204 |
+@AMDEP_TRUE@ ./$(DEPDIR)/zzip-zip.Plo |
|
204 | 205 |
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ |
205 | 206 |
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) |
206 | 207 |
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \ |
... | ... |
@@ -264,6 +268,7 @@ distclean-compile: |
264 | 264 |
|
265 | 265 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blob.Plo@am__quote@ |
266 | 266 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvd.Plo@am__quote@ |
267 |
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dsig.Plo@am__quote@ |
|
267 | 268 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/matcher.Plo@am__quote@ |
268 | 269 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mbox.Plo@am__quote@ |
269 | 270 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Plo@am__quote@ |
... | ... |
@@ -49,14 +49,17 @@ extern "C" |
49 | 49 |
#define CL_EACCES 200 /* access denied */ |
50 | 50 |
#define CL_ENULLARG 300 /* null argument error */ |
51 | 51 |
|
52 |
-#define CL_ETMPFILE -1 /* tmpfile() failed */ |
|
53 |
-#define CL_EFSYNC -2 /* fsync() failed */ |
|
54 |
-#define CL_EMEM -3 /* memory allocation error */ |
|
55 |
-#define CL_EOPEN -4 /* file open error */ |
|
56 |
-#define CL_EMALFDB -5 /* malformed database */ |
|
57 |
-#define CL_EPATSHORT -6 /* pattern too short */ |
|
58 |
-#define CL_ETMPDIR -7 /* mkdir() failed */ |
|
59 |
-#define CL_ECVDEXTR -8 /* CVD extraction failure */ |
|
52 |
+#define CL_ETMPFILE -1 /* tmpfile() failed */ |
|
53 |
+#define CL_EFSYNC -2 /* fsync() failed */ |
|
54 |
+#define CL_EMEM -3 /* memory allocation error */ |
|
55 |
+#define CL_EOPEN -4 /* file open error */ |
|
56 |
+#define CL_EMALFDB -5 /* malformed database */ |
|
57 |
+#define CL_EPATSHORT -6 /* pattern too short */ |
|
58 |
+#define CL_ETMPDIR -7 /* mkdir() failed */ |
|
59 |
+#define CL_ECVD -8 /* not a CVD file (or broken) */ |
|
60 |
+#define CL_ECVDEXTR -9 /* CVD extraction failure */ |
|
61 |
+#define CL_EMD5 -10 /* MD5 verification error */ |
|
62 |
+#define CL_EDSIG -11 /* digital signature verification error */ |
|
60 | 63 |
|
61 | 64 |
/* options */ |
62 | 65 |
#define CL_RAW 00 |
... | ... |
@@ -18,7 +18,6 @@ |
18 | 18 |
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
19 | 19 |
*/ |
20 | 20 |
|
21 |
- |
|
22 | 21 |
#include <stdio.h> |
23 | 22 |
#include <string.h> |
24 | 23 |
#include <stdlib.h> |
... | ... |
@@ -28,6 +27,8 @@ |
28 | 28 |
#include <zlib.h> |
29 | 29 |
|
30 | 30 |
#include "clamav.h" |
31 |
+#include "others.h" |
|
32 |
+#include "dsig.h" |
|
31 | 33 |
|
32 | 34 |
#define TAR_BLOCKSIZE 512 |
33 | 35 |
|
... | ... |
@@ -133,12 +134,15 @@ int cli_untgz(int fd, const char *destdir) |
133 | 133 |
} |
134 | 134 |
} |
135 | 135 |
|
136 |
+ if(outfile) |
|
137 |
+ fclose(outfile); |
|
138 |
+ |
|
136 | 139 |
return 0; |
137 | 140 |
} |
138 | 141 |
|
139 | 142 |
char *cli_cut(const char *line, int field) |
140 | 143 |
{ |
141 |
- int length, counter = 0, i, j = 0, k; |
|
144 |
+ int length, counter = 0, i, j = 0; |
|
142 | 145 |
char *buffer; |
143 | 146 |
|
144 | 147 |
length = strlen(line); |
... | ... |
@@ -161,10 +165,25 @@ char *cli_cut(const char *line, int field) |
161 | 161 |
return (char *) cli_realloc(buffer, strlen(buffer) + 1); |
162 | 162 |
} |
163 | 163 |
|
164 |
-struct cl_cvd *cli_cvdhead(const char *head) |
|
164 |
+struct cl_cvd *cli_cvdhead(FILE *fd) |
|
165 | 165 |
{ |
166 |
- char *pt; |
|
166 |
+ char *pt, head[513]; |
|
167 | 167 |
struct cl_cvd *cvd; |
168 |
+ int i; |
|
169 |
+ |
|
170 |
+ |
|
171 |
+ if(fread(head, 1, 512, fd) != 512) { |
|
172 |
+ cli_errmsg("Can't read CVD head from stream\n"); |
|
173 |
+ return NULL; |
|
174 |
+ } |
|
175 |
+ |
|
176 |
+ head[512] = 0; |
|
177 |
+ for(i = 511; i > 0 && (head[i] == ' ' || head[i] == 10); head[i] = 0, i--); |
|
178 |
+ |
|
179 |
+ if(strncmp(head, "ClamAV-VDB:", 11)) { |
|
180 |
+ cli_errmsg("Not a CVD file.\n"); |
|
181 |
+ return NULL; |
|
182 |
+ } |
|
168 | 183 |
|
169 | 184 |
cvd = (struct cl_cvd *) cli_calloc(1, sizeof(struct cl_cvd)); |
170 | 185 |
cvd->time = cli_cut(head, 2); |
... | ... |
@@ -190,30 +209,14 @@ struct cl_cvd *cli_cvdhead(const char *head) |
190 | 190 |
|
191 | 191 |
struct cl_cvd *cl_cvdhead(const char *file) |
192 | 192 |
{ |
193 |
- char head[257]; |
|
194 | 193 |
FILE *fd; |
195 |
- int i; |
|
196 |
- |
|
197 | 194 |
|
198 | 195 |
if((fd = fopen(file, "rb")) == NULL) { |
199 | 196 |
cli_errmsg("Can't open CVD file %s\n", file); |
200 | 197 |
return NULL; |
201 | 198 |
} |
202 | 199 |
|
203 |
- if(fread(head, 1, 256, fd) != 256) { |
|
204 |
- cli_errmsg("Can't read CVD head from %s\n", file); |
|
205 |
- return NULL; |
|
206 |
- } |
|
207 |
- head[256] = 0; |
|
208 |
- |
|
209 |
- for(i = 255; i > 0 && !isalnum(head[i]); head[i] = 0, i--); |
|
210 |
- |
|
211 |
- if(strncmp(head, "ClamAV-VDB:", 11)) { |
|
212 |
- cli_errmsg("%s is not a CVD file.\n"); |
|
213 |
- return NULL; |
|
214 |
- } |
|
215 |
- |
|
216 |
- return cli_cvdhead(head); |
|
200 |
+ return cli_cvdhead(fd); |
|
217 | 201 |
} |
218 | 202 |
|
219 | 203 |
void cl_cvdfree(struct cl_cvd *cvd) |
... | ... |
@@ -225,28 +228,62 @@ void cl_cvdfree(struct cl_cvd *cvd) |
225 | 225 |
free(cvd); |
226 | 226 |
} |
227 | 227 |
|
228 |
+int cli_cvdverify(FILE *fd) |
|
229 |
+{ |
|
230 |
+ struct cl_cvd *head; |
|
231 |
+ char *md5; |
|
232 |
+ |
|
233 |
+ if((head = cli_cvdhead(fd)) == NULL) |
|
234 |
+ return CL_ECVD; |
|
235 |
+ |
|
236 |
+ //fseek(fd, 512, SEEK_SET); |
|
237 |
+ |
|
238 |
+ md5 = cli_md5stream(fd); |
|
239 |
+ |
|
240 |
+ cli_dbgmsg("MD5(.tar.gz) = %s\n", md5); |
|
241 |
+ |
|
242 |
+ if(strncmp(md5, head->md5, 32)) { |
|
243 |
+ cli_dbgmsg("MD5 verification error.\n"); |
|
244 |
+ return CL_EMD5; |
|
245 |
+ } |
|
246 |
+ |
|
247 |
+#ifdef HAVE_GMP |
|
248 |
+ if(cli_versig(md5, head->dsig)) { |
|
249 |
+ cli_dbgmsg("Digital signature verification error.\n"); |
|
250 |
+ return CL_EDSIG; |
|
251 |
+ } |
|
252 |
+#endif |
|
253 |
+ |
|
254 |
+ return 0; |
|
255 |
+} |
|
256 |
+ |
|
257 |
+struct cl_cvd *cl_cvdverify(const char *file) |
|
258 |
+{ |
|
259 |
+ FILE *fd; |
|
260 |
+ |
|
261 |
+ if((fd = fopen(file, "rb")) == NULL) { |
|
262 |
+ cli_errmsg("Can't open CVD file %s\n", file); |
|
263 |
+ return NULL; |
|
264 |
+ } |
|
265 |
+ |
|
266 |
+ return cli_cvdverify(fd); |
|
267 |
+} |
|
268 |
+ |
|
228 | 269 |
int cli_cvdload(FILE *fd, struct cl_node **root, int *virnum) |
229 | 270 |
{ |
230 |
- char head[257], *dir, *tmp, buffer[BUFFSIZE]; |
|
231 |
- int bytes; |
|
232 |
- struct cl_cvd *cvd; |
|
271 |
+ char *dir, *tmp, buffer[BUFFSIZE]; |
|
272 |
+ int bytes, ret; |
|
233 | 273 |
const char *tmpdir; |
234 | 274 |
FILE *tmpd; |
235 | 275 |
|
236 | 276 |
cli_dbgmsg("in cli_cvdload()\n"); |
237 | 277 |
|
238 |
- if(fread(head, 1, 256, fd) != 256) { |
|
239 |
- cli_errmsg("Can't read CVD head.\n"); |
|
240 |
- return -1; |
|
241 |
- } |
|
242 |
- head[256] = 0; |
|
243 |
- |
|
244 |
- cvd = cli_cvdhead(head); |
|
245 |
- |
|
246 |
- /* verify md5/dsig */ |
|
278 |
+ /* verify */ |
|
247 | 279 |
|
280 |
+ if((ret = cli_cvdverify(fd))) |
|
281 |
+ return ret; |
|
248 | 282 |
|
249 |
- /* unpack */ |
|
283 |
+ fseek(fd, 512, SEEK_SET); |
|
250 | 284 |
|
251 | 285 |
tmpdir = getenv("TMPDIR"); |
252 | 286 |
|
... | ... |
@@ -270,8 +307,8 @@ int cli_cvdload(FILE *fd, struct cl_node **root, int *virnum) |
270 | 270 |
} |
271 | 271 |
*/ |
272 | 272 |
|
273 |
- /* FIXME: it seems there is some problem with current position after |
|
274 |
- * gzdopen() in cli_untgz(). Temporarily we need this wrapper: |
|
273 |
+ /* FIXME: it seems there is some problem with current position indicator |
|
274 |
+ * after gzdopen() call in cli_untgz(). Temporarily we need this wrapper: |
|
275 | 275 |
*/ |
276 | 276 |
|
277 | 277 |
/* start */ |
... | ... |
@@ -91,7 +91,7 @@ int cl_loaddb(const char *filename, struct cl_node **root, int *virnum) |
91 | 91 |
|
92 | 92 |
/* check for CVD file */ |
93 | 93 |
fgets(buffer, 12, fd); |
94 |
- fseek(fd, 0L, SEEK_SET); |
|
94 |
+ rewind(fd); |
|
95 | 95 |
|
96 | 96 |
if(!strncmp(buffer, "ClamAV-VDB:", 11)) { |
97 | 97 |
cli_dbgmsg("%s: CVD file detected\n", filename); |
... | ... |
@@ -205,6 +205,7 @@ int cl_loaddbdir(const char *dirname, struct cl_node **root, int *virnum) |
205 | 205 |
} |
206 | 206 |
sprintf(dbfile, "%s/%s", dirname, dent->d_name); |
207 | 207 |
if((ret = cl_loaddb(dbfile, root, virnum))) { |
208 |
+ cli_dbgmsg("cl_loaddbdir(): error loading database %s\n", dbfile); |
|
208 | 209 |
free(dbfile); |
209 | 210 |
closedir(dd); |
210 | 211 |
return ret; |
... | ... |
@@ -1,4 +1,4 @@ |
1 |
-/* THIS CODE REALLY SUCKS */ |
|
1 |
+/* THIS CODE SUCKS */ |
|
2 | 2 |
|
3 | 3 |
/* |
4 | 4 |
* Copyright (C) 2002, 2003 Tomasz Kojm <zolw@konarski.edu.pl> |
... | ... |
@@ -148,6 +148,9 @@ void sigtool(struct optstruct *opt) |
148 | 148 |
if(optl(opt, "stdout")) mprintf_stdout = 1; |
149 | 149 |
else mprintf_stdout = 0; |
150 | 150 |
|
151 |
+ if(optl(opt, "debug")) |
|
152 |
+ cl_debug(); |
|
153 |
+ |
|
151 | 154 |
if(optc(opt, 'V')) { |
152 | 155 |
mprintf("sigtool / ClamAV version "VERSION"\n"); |
153 | 156 |
exit(0); |
... | ... |
@@ -402,7 +405,7 @@ int build(struct optstruct *opt) |
402 | 402 |
exit(1); |
403 | 403 |
} |
404 | 404 |
|
405 |
- if(stat("viruses.db", &foo) == -1 || stat("viruses.db2", &foo) == -1) { |
|
405 |
+ if(stat("viruses.db", &foo) == -1 && stat("viruses.db2", &foo) == -1) { |
|
406 | 406 |
mprintf("Virus database not found in current working directory.\n"); |
407 | 407 |
exit(1); |
408 | 408 |
} |
... | ... |
@@ -518,12 +521,12 @@ int build(struct optstruct *opt) |
518 | 518 |
//strcat(header, ":"); |
519 | 519 |
|
520 | 520 |
/* fill up with spaces */ |
521 |
- if(strlen(header) > 256) { |
|
521 |
+ if(strlen(header) > 512) { |
|
522 | 522 |
mprintf("!Generated signature is too long.\n"); |
523 | 523 |
exit(1); |
524 | 524 |
} |
525 | 525 |
|
526 |
- while(strlen(header) < 256) |
|
526 |
+ while(strlen(header) < 512) |
|
527 | 527 |
strcat(header, " "); |
528 | 528 |
|
529 | 529 |
/* build the final database */ |
... | ... |
@@ -534,7 +537,7 @@ int build(struct optstruct *opt) |
534 | 534 |
exit(1); |
535 | 535 |
} |
536 | 536 |
|
537 |
- fwrite(header, 1, 256, cvd); |
|
537 |
+ fwrite(header, 1, 512, cvd); |
|
538 | 538 |
|
539 | 539 |
if((tar = fopen(gzfile, "rb")) == NULL) { |
540 | 540 |
mprintf("!Can't open file %s for reading.\n", gzfile); |
... | ... |
@@ -559,9 +562,11 @@ void cvdinfo(struct optstruct *opt) |
559 | 559 |
{ |
560 | 560 |
struct cl_cvd *cvd; |
561 | 561 |
char *pt; |
562 |
+ int ret; |
|
562 | 563 |
|
563 |
- if((cvd = cl_cvdhead(getargc(opt, 'i'))) == NULL) { |
|
564 |
- mprintf("!Can't read CVD header from %s\n", getargc(opt, 'i')); |
|
564 |
+ pt = getargc(opt, 'i'); |
|
565 |
+ if((cvd = cl_cvdhead(pt)) == NULL) { |
|
566 |
+ mprintf("!Can't read CVD header from %s\n", pt); |
|
565 | 567 |
exit(1); |
566 | 568 |
} |
567 | 569 |
|
... | ... |
@@ -572,9 +577,17 @@ void cvdinfo(struct optstruct *opt) |
572 | 572 |
mprintf("Builder: %s\n", cvd->builder); |
573 | 573 |
mprintf("MD5: %s\n", cvd->md5); |
574 | 574 |
|
575 |
- // pt = cl_md5file( DODAC WERYFIKACJE |
|
576 | 575 |
mprintf("Digital signature: %s\n", cvd->dsig); |
577 | 576 |
|
577 |
+#ifndef HAVE_GMP |
|
578 |
+ mprintf("Digital signature support not compiled in.\n"); |
|
579 |
+#endif |
|
580 |
+ |
|
581 |
+ if((ret = cl_cvdverify(pt))) |
|
582 |
+ mprintf("!Verification: %s\n", cl_strerror(ret)); |
|
583 |
+ else |
|
584 |
+ mprintf("Verification OK.\n"); |
|
585 |
+ |
|
578 | 586 |
// wyczysc cvd |
579 | 587 |
} |
580 | 588 |
|
... | ... |
@@ -587,6 +600,7 @@ void help(void) |
587 | 587 |
mprintf(" --help -h show help\n"); |
588 | 588 |
mprintf(" --version -V print version number and exit\n"); |
589 | 589 |
mprintf(" --quiet be quiet, output only error messages\n"); |
590 |
+ mprintf(" --debug enable debug messages\n"); |
|
590 | 591 |
mprintf(" --stdout write to stdout instead of stderr\n"); |
591 | 592 |
mprintf(" (this help is always written to stdout)\n"); |
592 | 593 |
mprintf(" --hex-dump convert data from stdin to hex\n"); |
... | ... |
@@ -594,8 +608,8 @@ void help(void) |
594 | 594 |
mprintf(" --command -c scanner command string, with options\n"); |
595 | 595 |
mprintf(" --string -s 'virus found' string in scan. output\n"); |
596 | 596 |
mprintf(" --file -f infected file\n"); |
597 |
- mprintf("\n DATABASE DEVELOPING:\n\n"); |
|
597 |
+ mprintf(" --info FILE -i FILE print database information\n"); |
|
598 | 598 |
mprintf(" --build NAME -b NAME Build database\n"); |
599 |
- |
|
599 |
+ |
|
600 | 600 |
exit(0); |
601 | 601 |
} |