Browse code

Critical fixes.

git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@76 77e5149b-7576-45b1-b177-96237e5ba77b

Tomasz Kojm authored on 2003/10/08 19:40:53
Showing 13 changed files
... ...
@@ -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;
... ...
@@ -39,6 +39,7 @@ int main(int argc, char **argv)
39 39
 	static struct option long_options[] = {
40 40
 	    {"help", 0, 0, 'h'},
41 41
 	    {"quiet", 0, 0, 0},
42
+	    {"debug", 0, 0, 0},
42 43
 	    {"verbose", 0, 0, 'v'},
43 44
 	    {"stdout", 0, 0, 0},
44 45
 	    {"version", 0, 0, 'V'},
... ...
@@ -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
 }