... | ... |
@@ -316,6 +316,7 @@ |
316 | 316 |
\begin{verbatim} |
317 | 317 |
$ ./configure --enable-milter |
318 | 318 |
\end{verbatim} |
319 |
+ See section /ref{sec:clamavmilter} for more details on clamav-milter. |
|
319 | 320 |
|
320 | 321 |
\subsection{Running unit tests}\label{unit-testing} |
321 | 322 |
ClamAV includes unit tests that allow you to test that the compiled binaries work correctly on your platform. |
... | ... |
@@ -391,8 +392,36 @@ $ CK_FORK=no ./libtool --mode=execute valgrind unit_tests/check-clamav |
391 | 391 |
\end{verbatim} |
392 | 392 |
\end{itemize} |
393 | 393 |
|
394 |
+ \subsection{Obtain Latest ClamAV anti-virus signature databases} |
|
395 |
+ Before you can run ClamAV in daemon mode (clamd), 'clamdscan', |
|
396 |
+ or 'clamscan' which is ClamAV's command line virus scanner, |
|
397 |
+ you must have ClamAV Virus Database (.cvd) file(s) installed |
|
398 |
+ in the appropriate location on your system. The default |
|
399 |
+ location for these database files are /usr/local/share/clamav |
|
400 |
+ (in Linux/Unix). |
|
401 |
+ \\\\ |
|
402 |
+ Here is a listing of currently available ClamAV Virus Database Files: |
|
403 |
+ \\\\ |
|
404 |
+ bytecode.cvd (signatures to detect bytecode in files) |
|
405 |
+ main.cvd (main ClamAV virus database file) |
|
406 |
+ daily.cvd (daily update file for ClamAV virus databases) |
|
407 |
+ safebrowsing.cvd (virus signatures for safe browsing) |
|
408 |
+ \\\\ |
|
409 |
+ These files can be downloaded via HTTP from the main ClamAV website |
|
410 |
+ or via the 'freshclam' utility on a periodic basis. Using 'freshclam' |
|
411 |
+ is the preferred method of keeping the ClamAV virus database files |
|
412 |
+ up to date without manual intervention (see section \ref{conf:freshclam} for |
|
413 |
+ information on how to configure 'freshclam' for automatic updating and section |
|
414 |
+ \ref{sec:freshclam} for additional details on freshclam). |
|
415 |
+ |
|
394 | 416 |
\section{Configuration} |
395 | 417 |
|
418 |
+ \subsubsection{clamconf} |
|
419 |
+ Before proceeding with the steps below, you should |
|
420 |
+ run the 'clamconf' command, which gives important information |
|
421 |
+ about your ClamAV configuration. See section \ref{sec:clamconf} |
|
422 |
+ for more details. |
|
423 |
+ |
|
396 | 424 |
\subsection{clamd} |
397 | 425 |
Before you start using the daemon you have to edit the configuration file |
398 | 426 |
(in other case \verb+clamd+ won't run): |
... | ... |
@@ -437,14 +466,31 @@ $ CK_FORK=no ./libtool --mode=execute valgrind unit_tests/check-clamav |
437 | 437 |
Now configure Clamuko in \verb+clamd.conf+ and read the \ref{clamuko} |
438 | 438 |
section. |
439 | 439 |
|
440 |
- \subsection{clamav-milter} |
|
440 |
+ \subsection{clamav-milter}\label{sec:clamavmilter} |
|
441 | 441 |
ClamAV $\ge0.95$ includes a new, redesigned clamav-milter. The most notable |
442 | 442 |
difference is that the internal mode has been dropped and now a working |
443 | 443 |
clamd companion is required. The second important difference is that now |
444 |
- the milter has got its own configuration and log files. To compile ClamAV |
|
445 |
- with the clamav-milter just run \verb+./configure+ \verb+--enable-milter+ |
|
446 |
- and make as usual. Please consult your MTA's manual on how to connect it |
|
447 |
- with the milter. |
|
444 |
+ the milter has got its own configuration and log files. |
|
445 |
+ |
|
446 |
+ To compile ClamAV with the clamav-milter just run \verb+./configure+ |
|
447 |
+ \verb+--enable-milter+ and make as usual. In order to use the |
|
448 |
+ '--enable-milter' option with 'configure', your system MUST have the milter |
|
449 |
+ library installed. If you use the '--enable-milter' option without the |
|
450 |
+ library being installed, you will most likely see output like this during |
|
451 |
+ 'configure': |
|
452 |
+ \begin{verbatim} |
|
453 |
+ checking for libiconv_open in -liconv... no |
|
454 |
+ checking for iconv... yes |
|
455 |
+ checking whether in_port_t is defined... yes |
|
456 |
+ checking for in_addr_t definition... yes |
|
457 |
+ checking for mi_stop in -lmilter... no |
|
458 |
+ checking for library containing strlcpy... no |
|
459 |
+ checking for mi_stop in -lmilter... no |
|
460 |
+ configure: error: Cannot find libmilter |
|
461 |
+ \end{verbatim} |
|
462 |
+ At which point the 'configure' script will stop processing. |
|
463 |
+ \\\\ |
|
464 |
+ Please consult your MTA's manual on how to connect ClamAV with the milter. |
|
448 | 465 |
|
449 | 466 |
\subsection{Testing} |
450 | 467 |
Try to scan recursively the source directory: |
... | ... |
@@ -462,7 +508,7 @@ $ CK_FORK=no ./libtool --mode=execute valgrind unit_tests/check-clamav |
462 | 462 |
Please note that the scanned files must be accessible by the user running |
463 | 463 |
\verb+clamd+ or you will get an error. |
464 | 464 |
|
465 |
- \subsection{Setting up auto-updating} |
|
465 |
+ \subsection{Setting up auto-updating}\label{conf:freshclam} |
|
466 | 466 |
\verb+freshclam+ is the automatic database update tool for Clam AntiVirus. |
467 | 467 |
It can work in two modes: |
468 | 468 |
\begin{itemize} |
... | ... |
@@ -704,6 +750,108 @@ N * * * * /usr/local/bin/freshclam --quiet |
704 | 704 |
more better and safe idea is to use the \textbf{samba-vscan} module. |
705 | 705 |
NFS is not supported because Dazuko doesn't intercept NFS access calls. |
706 | 706 |
|
707 |
+ \subsection{Clamdtop} |
|
708 |
+ \verb+clamdtop+ is a tool to monitor one or multiple instances of clamd. It |
|
709 |
+ has a (color) ncurses interface, that shows the jobs in clamd's queue, |
|
710 |
+ memory usage, and information about the loaded signature database. |
|
711 |
+ You can specify on the command-line to which clamd(s) it should connect |
|
712 |
+ to. By default it will attempt to connect to the local clamd as defined |
|
713 |
+ in clamd.conf. |
|
714 |
+ \\\\ |
|
715 |
+ For more detailed help, type 'man clamdtop' or 'clamdtop --help'. |
|
716 |
+ |
|
717 |
+ \subsection{Clamscan} |
|
718 |
+ \verb+clamscan+ is ClamAV's command line virus scanner. It can be used to |
|
719 |
+ scan files and/or directories for viruses. In order for clamscan |
|
720 |
+ to work proper, the ClamAV virus database files must be installed on |
|
721 |
+ the system you are using clamscan on. |
|
722 |
+ \\\\ |
|
723 |
+ The general usage of clamscan is: clamscan [options] [file/directory/-] |
|
724 |
+ \\\\ |
|
725 |
+ For more detailed help, type 'man clamscan' or 'clamscan --help'. |
|
726 |
+ |
|
727 |
+ \subsection{ClamBC} |
|
728 |
+ \verb+clambc+ is Clam Anti-Virus' bytecode testing tool. It can be |
|
729 |
+ used to test files which contain bytecode. For more detailed help, |
|
730 |
+ type 'man clambc' or 'clambc --help'. |
|
731 |
+ |
|
732 |
+ \subsection{Freshclam}\ref{sec:freshclam} |
|
733 |
+ \verb+freshclam+ is ClamAV's virus database update tool and reads it's |
|
734 |
+ configuration from the file 'freshclam.conf' (this may be |
|
735 |
+ overriden by command line options). Here is a sample usage including cdiffs: |
|
736 |
+ \begin{verbatim} |
|
737 |
+ $ freshclam |
|
738 |
+ |
|
739 |
+ ClamAV update process started at Mon Oct 7 08:15:10 2013 |
|
740 |
+ main.cld is up to date (version: 55, sigs: 2424225, f-level: 60, builder: neo) |
|
741 |
+ Downloading daily-17945.cdiff [100%] |
|
742 |
+ Downloading daily-17946.cdiff [100%] |
|
743 |
+ Downloading daily-17947.cdiff [100%] |
|
744 |
+ daily.cld updated (version: 17947, sigs: 406951, f-level: 63, builder: neo) |
|
745 |
+ Downloading bytecode-227.cdiff [100%] |
|
746 |
+ Downloading bytecode-228.cdiff [100%] |
|
747 |
+ bytecode.cld updated (version: 228, sigs: 43, f-level: 63, builder: neo) |
|
748 |
+ Database updated (2831219 signatures) from database.clamav.net (IP: 64.6.100.177) |
|
749 |
+ \end{verbatim} |
|
750 |
+ For more detailed help, type 'man clamscan' or 'clamscan --help'. |
|
751 |
+ |
|
752 |
+ \subsection{Clamconf}\label{sec:clamconf} |
|
753 |
+ \verb+clamconf+ is the Clam Anti-Virus configuration utility. It is used |
|
754 |
+ for displaying values of configurations options in ClamAV, which |
|
755 |
+ will show the contents of clamd.conf (or tell you if it is not |
|
756 |
+ properly configured), the contents of freshclam.conf, and display |
|
757 |
+ information about software settings, database, platform, and build |
|
758 |
+ information. Here is a sample clamconf output: |
|
759 |
+ \begin{verbatim} |
|
760 |
+ $ clamconf |
|
761 |
+ |
|
762 |
+ Checking configuration files in /etc/clamav |
|
763 |
+ |
|
764 |
+ Config file: clamd.conf |
|
765 |
+ ----------------------- |
|
766 |
+ ERROR: Please edit the example config file /etc/clamav/clamd.conf |
|
767 |
+ |
|
768 |
+ Config file: freshclam.conf |
|
769 |
+ --------------------------- |
|
770 |
+ ERROR: Please edit the example config file /etc/clamav/freshclam.conf |
|
771 |
+ |
|
772 |
+ clamav-milter.conf not found |
|
773 |
+ |
|
774 |
+ Software settings |
|
775 |
+ ----------------- |
|
776 |
+ Version: 0.97.6 |
|
777 |
+ Optional features supported: MEMPOOL IPv6 CLAMUKO AUTOIT_EA06 BZIP2 RAR JIT |
|
778 |
+ |
|
779 |
+ Database information |
|
780 |
+ -------------------- |
|
781 |
+ Database directory: /usr/local/share/clamav |
|
782 |
+ WARNING: freshclam.conf and clamd.conf point to different database directories |
|
783 |
+ print_dbs: Can't open directory /usr/local/share/clamav |
|
784 |
+ |
|
785 |
+ Platform information |
|
786 |
+ -------------------- |
|
787 |
+ uname: Linux 2.6.32-279.el6.x86_64 #1 SMP Fri Jun 22 12:19:21 UTC 2012 x86_64 |
|
788 |
+ OS: linux-gnu, ARCH: x86_64, CPU: x86_64 |
|
789 |
+ Full OS version: ``CentOS release 6.3 (Final)'' |
|
790 |
+ zlib version: 1.2.3 (1.2.3), compile flags: a9 |
|
791 |
+ Triple: x86_64-unknown-linux-gnu |
|
792 |
+ CPU: amdfam10, Little-endian |
|
793 |
+ platform id: 0x0a2143430804040607040406 |
|
794 |
+ |
|
795 |
+ Build information |
|
796 |
+ ----------------- |
|
797 |
+ GNU C: 4.4.6 20120305 (Red Hat 4.4.6-4) (4.4.6) |
|
798 |
+ GNU C++: 4.4.6 20120305 (Red Hat 4.4.6-4) (4.4.6) |
|
799 |
+ CPPFLAGS: |
|
800 |
+ CFLAGS: -g -O2 -fno-strict-aliasing |
|
801 |
+ CXXFLAGS: |
|
802 |
+ LDFLAGS: |
|
803 |
+ Configure: '--enable-check' '--sysconfdir=/etc/clamav' |
|
804 |
+ --enable-ltdl-convenience |
|
805 |
+ sizeof(void*) = 8 |
|
806 |
+ \end{verbatim} |
|
807 |
+ For more detailed help, type 'man clamconf' or 'clamconf --help'. |
|
808 |
+ |
|
707 | 809 |
\subsection{Output format} |
708 | 810 |
|
709 | 811 |
\subsubsection{clamscan} |
... | ... |
@@ -723,7 +871,7 @@ N * * * * /usr/local/bin/freshclam --quiet |
723 | 723 |
\verb+FOUND+ strings. In case of archives the scanner depends on libclamav |
724 | 724 |
and only prints the first virus found within an archive: |
725 | 725 |
\begin{verbatim} |
726 |
- zolw@localhost:/tmp$ clamscan malware.zip |
|
726 |
+ $ clamscan malware.zip |
|
727 | 727 |
malware.zip: Worm.Mydoom.U FOUND |
728 | 728 |
\end{verbatim} |
729 | 729 |
When using the --allmatch(-z) flag, clamscan may print multiple virus |
... | ... |
@@ -732,7 +880,7 @@ N * * * * /usr/local/bin/freshclam --quiet |
732 | 732 |
\subsubsection{clamd} |
733 | 733 |
The output format of \verb+clamd+ is very similar to \verb+clamscan+. |
734 | 734 |
\begin{verbatim} |
735 |
- zolw@localhost:~$ telnet localhost 3310 |
|
735 |
+ $ telnet localhost 3310 |
|
736 | 736 |
Trying 127.0.0.1... |
737 | 737 |
Connected to localhost. |
738 | 738 |
Escape character is '^]'. |
... | ... |
@@ -823,8 +971,14 @@ N * * * * /usr/local/bin/freshclam --quiet |
823 | 823 |
decoding and normalization is only performed for HTML files. |
824 | 824 |
|
825 | 825 |
\subsubsection{Data Loss Prevention} |
826 |
- Libclamav includes a DLP module which can detect credit card and |
|
827 |
- social security numbers inside text files. |
|
826 |
+ Libclamav includes a DLP module which can detect the following |
|
827 |
+ credit card issuers: AMEX, VISA, MasterCard, Discover, Diner's Club, |
|
828 |
+ and JCB and U.S. social security numbers inside text files. |
|
829 |
+ \\\\ |
|
830 |
+ Future versions of Libclamav may include additional features to |
|
831 |
+ detect other credit cards and other forms of PII (Personally |
|
832 |
+ Identifiable Information) which may be transmitted without the |
|
833 |
+ benefit of being encrypted. |
|
828 | 834 |
|
829 | 835 |
\subsubsection{Others} |
830 | 836 |
Libclamav can handle various obfuscators, encoders, files vulnerable to |
... | ... |
@@ -1115,9 +1269,9 @@ const char *cl_engine_get_str(const struct cl_engine *engine, |
1115 | 1115 |
\subsubsection{clamav-config} |
1116 | 1116 |
Use \verb+clamav-config+ to check compilation information for libclamav. |
1117 | 1117 |
\begin{verbatim} |
1118 |
- zolw@localhost:~$ clamav-config --libs |
|
1118 |
+ $ clamav-config --libs |
|
1119 | 1119 |
-L/usr/local/lib -lz -lbz2 -lgmp -lpthread |
1120 |
- zolw@localhost:~$ clamav-config --cflags |
|
1120 |
+ $ clamav-config --cflags |
|
1121 | 1121 |
-I/usr/local/include -g -O2 |
1122 | 1122 |
\end{verbatim} |
1123 | 1123 |
|
... | ... |
@@ -1139,7 +1293,7 @@ level required:MD5 checksum:digital signature:builder name:build time (sec) |
1139 | 1139 |
\end{verbatim} |
1140 | 1140 |
\verb+sigtool --info+ displays detailed information on CVD files: |
1141 | 1141 |
\begin{verbatim} |
1142 |
-zolw@localhost:/usr/local/share/clamav$ sigtool -i daily.cvd |
|
1142 |
+$ sigtool -i daily.cvd |
|
1143 | 1143 |
File: daily.cvd |
1144 | 1144 |
Build time: 10 Mar 2008 10:45 +0000 |
1145 | 1145 |
Version: 6191 |
... | ... |
@@ -64,6 +64,9 @@ Initialization</A> |
64 | 64 |
struct cl_engine *cl_engine_new(void); |
65 | 65 |
int cl_engine_free(struct cl_engine *engine); |
66 | 66 |
</PRE> |
67 |
+ At this time, <code>cl_init()</code> only supports the <code>CL_INIT_DEFAULT</code> option |
|
68 |
+ which intializes libclamav with the default settings. |
|
69 |
+ |
|
67 | 70 |
<code>cl_init()</code> and <code>cl_engine_free()</code> return <code>CL_SUCCESS</code> |
68 | 71 |
on success or another code on error. <code>cl_engine_new()</code> return |
69 | 72 |
a pointer or NULL if there's not enough memory to allocate a new |
... | ... |
@@ -222,8 +222,8 @@ Example |
222 | 222 |
#DetectPUA yes |
223 | 223 |
|
224 | 224 |
# Exclude a specific PUA category. This directive can be used multiple times. |
225 |
-# See http://www.clamav.net/support/pua for the complete list of PUA |
|
226 |
-# categories. |
|
225 |
+# See https://github.com/vrtadmin/clamav-faq/blob/master/faq/faq-pua.md for |
|
226 |
+# the complete list of PUA categories. |
|
227 | 227 |
# Default: Load all categories (if DetectPUA is activated) |
228 | 228 |
#ExcludePUA NetTool |
229 | 229 |
#ExcludePUA PWTool |
... | ... |
@@ -172,10 +172,10 @@ am_libclamav_la_OBJECTS = libclamav_la-matcher-ac.lo \ |
172 | 172 |
libclamav_la-macho.lo libclamav_la-ishield.lo \ |
173 | 173 |
libclamav_la-bytecode_api.lo libclamav_la-bytecode_api_decl.lo \ |
174 | 174 |
libclamav_la-cache.lo libclamav_la-bytecode_detect.lo \ |
175 |
- libclamav_la-events.lo libclamav_la-dmg.lo libclamav_la-xar.lo \ |
|
176 |
- libclamav_la-xz_iface.lo libclamav_la-sf_base64decode.lo \ |
|
177 |
- libclamav_la-hfsplus.lo libclamav_la-swf.lo \ |
|
178 |
- libclamav_la-jpeg.lo libclamav_la-png.lo \ |
|
175 |
+ libclamav_la-events.lo libclamav_la-adc.lo libclamav_la-dmg.lo \ |
|
176 |
+ libclamav_la-xar.lo libclamav_la-xz_iface.lo \ |
|
177 |
+ libclamav_la-sf_base64decode.lo libclamav_la-hfsplus.lo \ |
|
178 |
+ libclamav_la-swf.lo libclamav_la-jpeg.lo libclamav_la-png.lo \ |
|
179 | 179 |
libclamav_la-iso9660.lo libclamav_la-arc4.lo \ |
180 | 180 |
libclamav_la-rijndael.lo libclamav_la-crtmgr.lo \ |
181 | 181 |
libclamav_la-asn1.lo libclamav_la-fp_add.lo \ |
... | ... |
@@ -697,11 +697,11 @@ libclamav_la_SOURCES = clamav.h matcher-ac.c matcher-ac.h matcher-bm.c \ |
697 | 697 |
bcfeatures.h bytecode_api.c bytecode_api_decl.c bytecode_api.h \ |
698 | 698 |
bytecode_api_impl.h bytecode_hooks.h cache.c cache.h \ |
699 | 699 |
bytecode_detect.c bytecode_detect.h builtin_bytecodes.h \ |
700 |
- events.c events.h dmg.c dmg.h xar.c xar.h xz_iface.c \ |
|
701 |
- xz_iface.h sf_base64decode.c sf_base64decode.h hfsplus.c \ |
|
702 |
- hfsplus.h swf.c swf.h jpeg.c jpeg.h png.c png.h iso9660.c \ |
|
703 |
- iso9660.h arc4.c arc4.h rijndael.c rijndael.h crtmgr.c \ |
|
704 |
- crtmgr.h asn1.c asn1.h bignum.h bignum_fast.h \ |
|
700 |
+ events.c events.h adc.c adc.h dmg.c dmg.h xar.c xar.h \ |
|
701 |
+ xz_iface.c xz_iface.h sf_base64decode.c sf_base64decode.h \ |
|
702 |
+ hfsplus.c hfsplus.h swf.c swf.h jpeg.c jpeg.h png.c png.h \ |
|
703 |
+ iso9660.c iso9660.h arc4.c arc4.h rijndael.c rijndael.h \ |
|
704 |
+ crtmgr.c crtmgr.h asn1.c asn1.h bignum.h bignum_fast.h \ |
|
705 | 705 |
tomsfastmath/addsub/fp_add.c tomsfastmath/addsub/fp_add_d.c \ |
706 | 706 |
tomsfastmath/addsub/fp_addmod.c tomsfastmath/addsub/fp_cmp.c \ |
707 | 707 |
tomsfastmath/addsub/fp_cmp_d.c \ |
... | ... |
@@ -911,6 +911,7 @@ distclean-compile: |
911 | 911 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-XzCrc64.Plo@am__quote@ |
912 | 912 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-XzDec.Plo@am__quote@ |
913 | 913 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-XzIn.Plo@am__quote@ |
914 |
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-adc.Plo@am__quote@ |
|
914 | 915 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-arc4.Plo@am__quote@ |
915 | 916 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-asn1.Plo@am__quote@ |
916 | 917 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-aspack.Plo@am__quote@ |
... | ... |
@@ -1907,6 +1908,13 @@ libclamav_la-events.lo: events.c |
1907 | 1907 |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
1908 | 1908 |
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-events.lo `test -f 'events.c' || echo '$(srcdir)/'`events.c |
1909 | 1909 |
|
1910 |
+libclamav_la-adc.lo: adc.c |
|
1911 |
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-adc.lo -MD -MP -MF $(DEPDIR)/libclamav_la-adc.Tpo -c -o libclamav_la-adc.lo `test -f 'adc.c' || echo '$(srcdir)/'`adc.c |
|
1912 |
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-adc.Tpo $(DEPDIR)/libclamav_la-adc.Plo |
|
1913 |
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='adc.c' object='libclamav_la-adc.lo' libtool=yes @AMDEPBACKSLASH@ |
|
1914 |
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
|
1915 |
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-adc.lo `test -f 'adc.c' || echo '$(srcdir)/'`adc.c |
|
1916 |
+ |
|
1910 | 1917 |
libclamav_la-dmg.lo: dmg.c |
1911 | 1918 |
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-dmg.lo -MD -MP -MF $(DEPDIR)/libclamav_la-dmg.Tpo -c -o libclamav_la-dmg.lo `test -f 'dmg.c' || echo '$(srcdir)/'`dmg.c |
1912 | 1919 |
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-dmg.Tpo $(DEPDIR)/libclamav_la-dmg.Plo |
1913 | 1920 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,291 @@ |
0 |
+/* |
|
1 |
+ * Copyright (C) 2013 Sourcefire, Inc. |
|
2 |
+ * |
|
3 |
+ * Authors: David Raynor <draynor@sourcefire.com> |
|
4 |
+ * |
|
5 |
+ * This program is free software; you can redistribute it and/or modify |
|
6 |
+ * it under the terms of the GNU General Public License version 2 as |
|
7 |
+ * published by the Free Software Foundation. |
|
8 |
+ * |
|
9 |
+ * This program is distributed in the hope that it will be useful, |
|
10 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
+ * GNU General Public License for more details. |
|
13 |
+ * |
|
14 |
+ * You should have received a copy of the GNU General Public License |
|
15 |
+ * along with this program; if not, write to the Free Software |
|
16 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
|
17 |
+ * MA 02110-1301, USA. |
|
18 |
+ */ |
|
19 |
+ |
|
20 |
+#if HAVE_CONFIG_H |
|
21 |
+#include "clamav-config.h" |
|
22 |
+#endif |
|
23 |
+ |
|
24 |
+#include <stdio.h> |
|
25 |
+#include <errno.h> |
|
26 |
+#if HAVE_STRING_H |
|
27 |
+#include <string.h> |
|
28 |
+#endif |
|
29 |
+ |
|
30 |
+#include "cltypes.h" |
|
31 |
+#include "others.h" |
|
32 |
+#include "adc.h" |
|
33 |
+ |
|
34 |
+/* #define DEBUG_ADC */ |
|
35 |
+ |
|
36 |
+#ifdef DEBUG_ADC |
|
37 |
+# define adc_dbgmsg(...) cli_dbgmsg( __VA_ARGS__ ) |
|
38 |
+#else |
|
39 |
+# define adc_dbgmsg(...) ; |
|
40 |
+#endif |
|
41 |
+ |
|
42 |
+/* Initialize values and collect buffer |
|
43 |
+ * NOTE: buffer size must be larger than largest lookback offset */ |
|
44 |
+int adc_decompressInit(adc_stream *strm) |
|
45 |
+{ |
|
46 |
+ if (strm == NULL) { |
|
47 |
+ return ADC_IO_ERROR; |
|
48 |
+ } |
|
49 |
+ if (strm->state != ADC_STATE_UNINIT) { |
|
50 |
+ return ADC_DATA_ERROR; |
|
51 |
+ } |
|
52 |
+ |
|
53 |
+ /* Have to buffer maximum backward lookup */ |
|
54 |
+ strm->buffer = (uint8_t *)calloc(ADC_BUFF_SIZE, 1); |
|
55 |
+ if (strm->buffer == NULL) { |
|
56 |
+ return ADC_MEM_ERROR; |
|
57 |
+ } |
|
58 |
+ strm->buffered = 0; |
|
59 |
+ strm->state = ADC_STATE_GETTYPE; |
|
60 |
+ strm->length = 0; |
|
61 |
+ strm->offset = 0; |
|
62 |
+ strm->curr = strm->buffer; |
|
63 |
+ |
|
64 |
+ return ADC_OK; |
|
65 |
+} |
|
66 |
+ |
|
67 |
+/* Decompress routine |
|
68 |
+ * NOTE: Reaching end of input buffer does not mean end of output. |
|
69 |
+ * It may fill the output buffer but have more to output. |
|
70 |
+ * It will only return ADC_STREAM_END if output buffer is not full. |
|
71 |
+ * It will return ADC_DATA_ERROR if it ends in the middle of a phrase |
|
72 |
+ * (i.e. in the middle of a lookback code or data run) |
|
73 |
+ */ |
|
74 |
+int adc_decompress(adc_stream *strm) |
|
75 |
+{ |
|
76 |
+ uint8_t bData; |
|
77 |
+ uint8_t didNothing = 1; |
|
78 |
+ |
|
79 |
+ /* first, the error returns based on strm */ |
|
80 |
+ if ((strm == NULL) || (strm->next_in == NULL) || (strm->next_out == NULL)) { |
|
81 |
+ return ADC_IO_ERROR; |
|
82 |
+ } |
|
83 |
+ if (strm->state == ADC_STATE_UNINIT) { |
|
84 |
+ return ADC_DATA_ERROR; |
|
85 |
+ } |
|
86 |
+ |
|
87 |
+ cli_dbgmsg("adc_decompress: avail_in %lu avail_out %lu state %u\n", strm->avail_in, strm->avail_out, strm->state); |
|
88 |
+ |
|
89 |
+ while (strm->avail_out) { |
|
90 |
+ /* Exit if needs more in bytes and none available */ |
|
91 |
+ int needsInput; |
|
92 |
+ switch (strm->state) { |
|
93 |
+ case ADC_STATE_SHORTLOOK: |
|
94 |
+ case ADC_STATE_LONGLOOK: |
|
95 |
+ needsInput = 0; |
|
96 |
+ break; |
|
97 |
+ default: |
|
98 |
+ needsInput = 1; |
|
99 |
+ break; |
|
100 |
+ } |
|
101 |
+ if (needsInput && (strm->avail_in == 0)) { |
|
102 |
+ break; |
|
103 |
+ } |
|
104 |
+ else { |
|
105 |
+ didNothing = 0; |
|
106 |
+ } |
|
107 |
+ |
|
108 |
+ /* Find or execute statecode */ |
|
109 |
+ switch (strm->state) { |
|
110 |
+ case ADC_STATE_GETTYPE: { |
|
111 |
+ /* Grab action code */ |
|
112 |
+ bData = *(strm->next_in); |
|
113 |
+ strm->next_in++; |
|
114 |
+ strm->avail_in--; |
|
115 |
+ if (bData & 0x80) { |
|
116 |
+ strm->state = ADC_STATE_RAWDATA; |
|
117 |
+ strm->offset = 0; |
|
118 |
+ strm->length = (bData & 0x7F) + 1; |
|
119 |
+ } |
|
120 |
+ else if (bData & 0x40) { |
|
121 |
+ strm->state = ADC_STATE_LONGOP2; |
|
122 |
+ strm->offset = 0; |
|
123 |
+ strm->length = (bData & 0x3F) + 4; |
|
124 |
+ } |
|
125 |
+ else { |
|
126 |
+ strm->state = ADC_STATE_SHORTOP; |
|
127 |
+ strm->offset = (bData & 0x3) * 0x100; |
|
128 |
+ strm->length = ((bData & 0x3C) >> 2) + 3; |
|
129 |
+ } |
|
130 |
+ adc_dbgmsg("adc_decompress: GETTYPE bData %x state %u offset %u length %u\n", |
|
131 |
+ bData, strm->state, strm->offset, strm->length); |
|
132 |
+ break; |
|
133 |
+ } |
|
134 |
+ case ADC_STATE_LONGOP2: { |
|
135 |
+ /* Grab first offset byte */ |
|
136 |
+ bData = *(strm->next_in); |
|
137 |
+ strm->next_in++; |
|
138 |
+ strm->avail_in--; |
|
139 |
+ strm->offset = bData * 0x100; |
|
140 |
+ strm->state = ADC_STATE_LONGOP1; |
|
141 |
+ adc_dbgmsg("adc_decompress: LONGOP2 bData %x state %u offset %u length %u\n", |
|
142 |
+ bData, strm->state, strm->offset, strm->length); |
|
143 |
+ break; |
|
144 |
+ } |
|
145 |
+ case ADC_STATE_LONGOP1: { |
|
146 |
+ /* Grab second offset byte */ |
|
147 |
+ bData = *(strm->next_in); |
|
148 |
+ strm->next_in++; |
|
149 |
+ strm->avail_in--; |
|
150 |
+ strm->offset += bData + 1; |
|
151 |
+ strm->state = ADC_STATE_LONGLOOK; |
|
152 |
+ adc_dbgmsg("adc_decompress: LONGOP1 bData %x state %u offset %u length %u\n", |
|
153 |
+ bData, strm->state, strm->offset, strm->length); |
|
154 |
+ break; |
|
155 |
+ } |
|
156 |
+ case ADC_STATE_SHORTOP: { |
|
157 |
+ /* Grab offset byte */ |
|
158 |
+ bData = *(strm->next_in); |
|
159 |
+ strm->next_in++; |
|
160 |
+ strm->avail_in--; |
|
161 |
+ strm->offset += bData + 1; |
|
162 |
+ strm->state = ADC_STATE_SHORTLOOK; |
|
163 |
+ adc_dbgmsg("adc_decompress: SHORTOP bData %x state %u offset %u length %u\n", |
|
164 |
+ bData, strm->state, strm->offset, strm->length); |
|
165 |
+ break; |
|
166 |
+ } |
|
167 |
+ |
|
168 |
+ case ADC_STATE_RAWDATA: { |
|
169 |
+ /* Grab data */ |
|
170 |
+ adc_dbgmsg("adc_decompress: RAWDATA offset %u length %u\n", strm->offset, strm->length); |
|
171 |
+ while ((strm->avail_in > 0) && (strm->avail_out > 0) && (strm->length > 0)) { |
|
172 |
+ bData = *(strm->next_in); |
|
173 |
+ strm->next_in++; |
|
174 |
+ strm->avail_in--; |
|
175 |
+ /* store to output */ |
|
176 |
+ *(strm->next_out) = bData; |
|
177 |
+ strm->next_out++; |
|
178 |
+ strm->avail_out--; |
|
179 |
+ /* store to buffer */ |
|
180 |
+ if (strm->curr >= (strm->buffer + ADC_BUFF_SIZE)) { |
|
181 |
+ strm->curr = strm->buffer; |
|
182 |
+ } |
|
183 |
+ *(strm->curr) = bData; |
|
184 |
+ strm->curr++; |
|
185 |
+ if (strm->buffered < ADC_BUFF_SIZE) { |
|
186 |
+ strm->buffered++; |
|
187 |
+ } |
|
188 |
+ strm->length--; |
|
189 |
+ } |
|
190 |
+ if (strm->length == 0) { |
|
191 |
+ /* adc_dbgmsg("adc_decompress: RAWDATADONE buffered %u avail_in %u avail_out %u \n", |
|
192 |
+ strm->buffered, strm->avail_in, strm->avail_out); */ |
|
193 |
+ strm->state = ADC_STATE_GETTYPE; |
|
194 |
+ } |
|
195 |
+ break; |
|
196 |
+ } |
|
197 |
+ |
|
198 |
+ case ADC_STATE_SHORTLOOK: |
|
199 |
+ case ADC_STATE_LONGLOOK: { |
|
200 |
+ /* Copy data */ |
|
201 |
+ adc_dbgmsg("adc_decompress: LOOKBACK offset %u length %u avail_in %u avail_out %u\n", |
|
202 |
+ strm->offset, strm->length, strm->avail_in, strm->avail_out); |
|
203 |
+ while ((strm->avail_out > 0) && (strm->length > 0)) { |
|
204 |
+ /* state validation first */ |
|
205 |
+ if (strm->offset > 0x10000) { |
|
206 |
+ cli_dbgmsg("adc_decompress: bad LOOKBACK offset %u\n", strm->offset); |
|
207 |
+ return ADC_DATA_ERROR; |
|
208 |
+ } |
|
209 |
+ else if ((strm->state == ADC_STATE_SHORTLOOK) && (strm->offset > 0x400)) { |
|
210 |
+ cli_dbgmsg("adc_decompress: bad LOOKBACK offset %u\n", strm->offset); |
|
211 |
+ return ADC_DATA_ERROR; |
|
212 |
+ } |
|
213 |
+ if (strm->offset > strm->buffered) { |
|
214 |
+ cli_dbgmsg("adc_decompress: too large LOOKBACK offset %u\n", strm->offset); |
|
215 |
+ return ADC_DATA_ERROR; |
|
216 |
+ } |
|
217 |
+ /* retrieve byte */ |
|
218 |
+ if (strm->curr >= (strm->buffer + ADC_BUFF_SIZE)) { |
|
219 |
+ strm->curr = strm->buffer; |
|
220 |
+ } |
|
221 |
+ if (strm->curr > (strm->buffer + strm->offset)) { |
|
222 |
+ bData = *(uint8_t *)(strm->curr - strm->offset); |
|
223 |
+ } |
|
224 |
+ else { |
|
225 |
+ bData = *(uint8_t *)(strm->curr + ADC_BUFF_SIZE - strm->offset); |
|
226 |
+ } |
|
227 |
+ /* store to output */ |
|
228 |
+ *(strm->next_out) = bData; |
|
229 |
+ strm->next_out++; |
|
230 |
+ strm->avail_out--; |
|
231 |
+ /* store to buffer */ |
|
232 |
+ *(strm->curr) = bData; |
|
233 |
+ strm->curr++; |
|
234 |
+ if (strm->buffered < ADC_BUFF_SIZE) { |
|
235 |
+ strm->buffered++; |
|
236 |
+ } |
|
237 |
+ strm->length--; |
|
238 |
+ } |
|
239 |
+ if (strm->length == 0) { |
|
240 |
+ strm->state = ADC_STATE_GETTYPE; |
|
241 |
+ /* adc_dbgmsg("adc_decompress: LOOKBACKDONE buffered %u avail_in %u avail_out %u \n", |
|
242 |
+ strm->buffered, strm->avail_in, strm->avail_out); */ |
|
243 |
+ } |
|
244 |
+ break; |
|
245 |
+ } |
|
246 |
+ |
|
247 |
+ default: { |
|
248 |
+ /* bad state */ |
|
249 |
+ cli_errmsg("adc_decompress: invalid state %u\n", strm->state); |
|
250 |
+ return ADC_DATA_ERROR; |
|
251 |
+ } |
|
252 |
+ } /* end switch */ |
|
253 |
+ } /* end while */ |
|
254 |
+ |
|
255 |
+ /* There really isn't a terminator, just end of data */ |
|
256 |
+ if (didNothing && strm->avail_out) { |
|
257 |
+ if (strm->state == ADC_STATE_GETTYPE) { |
|
258 |
+ /* Nothing left to do */ |
|
259 |
+ return ADC_STREAM_END; |
|
260 |
+ } |
|
261 |
+ else { |
|
262 |
+ /* Ended mid phrase */ |
|
263 |
+ cli_dbgmsg("adc_decompress: stream ended mid-phrase, state %u\n", strm->state); |
|
264 |
+ return ADC_DATA_ERROR; |
|
265 |
+ } |
|
266 |
+ } |
|
267 |
+ return ADC_OK; |
|
268 |
+} |
|
269 |
+ |
|
270 |
+/* Cleanup routine, frees buffer */ |
|
271 |
+int adc_decompressEnd(adc_stream *strm) |
|
272 |
+{ |
|
273 |
+ if (strm == NULL) { |
|
274 |
+ return ADC_IO_ERROR; |
|
275 |
+ } |
|
276 |
+ if (strm->state == ADC_STATE_UNINIT) { |
|
277 |
+ return ADC_DATA_ERROR; |
|
278 |
+ } |
|
279 |
+ |
|
280 |
+ if (strm->buffer != NULL) { |
|
281 |
+ free(strm->buffer); |
|
282 |
+ } |
|
283 |
+ strm->buffered = 0; |
|
284 |
+ strm->state = ADC_STATE_UNINIT; |
|
285 |
+ strm->length = 0; |
|
286 |
+ strm->offset = 0; |
|
287 |
+ |
|
288 |
+ return ADC_OK; |
|
289 |
+} |
|
290 |
+ |
0 | 291 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,55 @@ |
0 |
+ |
|
1 |
+ |
|
2 |
+#ifndef CLAM_ADC_H |
|
3 |
+#define CLAM_ADC_H |
|
4 |
+ |
|
5 |
+struct adc_stream { |
|
6 |
+ uint8_t *next_in; |
|
7 |
+ size_t avail_in; |
|
8 |
+ size_t total_in; |
|
9 |
+ |
|
10 |
+ uint8_t *next_out; |
|
11 |
+ size_t avail_out; |
|
12 |
+ size_t total_out; |
|
13 |
+ |
|
14 |
+ /* internals */ |
|
15 |
+ uint8_t *buffer; |
|
16 |
+ uint8_t *curr; |
|
17 |
+ |
|
18 |
+ uint32_t buffered; |
|
19 |
+ uint16_t state; |
|
20 |
+ uint16_t length; |
|
21 |
+ uint32_t offset; |
|
22 |
+}; |
|
23 |
+typedef struct adc_stream adc_stream; |
|
24 |
+ |
|
25 |
+#define ADC_BUFF_SIZE 65536 |
|
26 |
+ |
|
27 |
+#define ADC_MEM_ERROR -1 |
|
28 |
+#define ADC_DATA_ERROR -2 |
|
29 |
+#define ADC_IO_ERROR -3 |
|
30 |
+#define ADC_OK 0 |
|
31 |
+#define ADC_STREAM_END 1 |
|
32 |
+ |
|
33 |
+enum adc_state { |
|
34 |
+ ADC_STATE_UNINIT = 0, |
|
35 |
+ ADC_STATE_GETTYPE = 1, |
|
36 |
+ ADC_STATE_RAWDATA = 2, |
|
37 |
+ ADC_STATE_SHORTOP = 3, |
|
38 |
+ ADC_STATE_LONGOP2 = 4, |
|
39 |
+ ADC_STATE_LONGOP1 = 5, |
|
40 |
+ ADC_STATE_SHORTLOOK = 6, |
|
41 |
+ ADC_STATE_LONGLOOK = 7 |
|
42 |
+}; |
|
43 |
+ |
|
44 |
+/* Compression phrases |
|
45 |
+ * store phrase - 1 byte header + data, first byte 0x80-0xFF, max length 0x80 (7 bits + 1), no offset |
|
46 |
+ * short phrase - 2 byte header + data, first byte 0x00-0x3F, max length 0x12 (4 bits + 3), max offset 0x3FF (10 bits) |
|
47 |
+ * long phrase - 3 byte header + data, first byte 0x40-0x7F, max length 0x43 (6 bits + 4), max offset 0xFFFF (16 bits) |
|
48 |
+ */ |
|
49 |
+ |
|
50 |
+int adc_decompressInit(adc_stream *strm); |
|
51 |
+int adc_decompress(adc_stream *strm); |
|
52 |
+int adc_decompressEnd(adc_stream *strm); |
|
53 |
+ |
|
54 |
+#endif |
... | ... |
@@ -54,9 +54,10 @@ |
54 | 54 |
#include "dmg.h" |
55 | 55 |
#include "scanners.h" |
56 | 56 |
#include "sf_base64decode.h" |
57 |
+#include "adc.h" |
|
57 | 58 |
|
58 |
-// #define DEBUG_DMG_PARSE |
|
59 |
-// #define DEBUG_DMG_BZIP |
|
59 |
+/* #define DEBUG_DMG_PARSE */ |
|
60 |
+/* #define DEBUG_DMG_BZIP */ |
|
60 | 61 |
|
61 | 62 |
#ifdef DEBUG_DMG_PARSE |
62 | 63 |
# define dmg_parsemsg(...) cli_dbgmsg( __VA_ARGS__) |
... | ... |
@@ -710,10 +711,84 @@ static int dmg_stripe_store(cli_ctx *ctx, int fd, uint32_t index, struct dmg_mis |
710 | 710 |
/* Stripe handling: ADC block (type 0x80000004) */ |
711 | 711 |
static int dmg_stripe_adc(cli_ctx *ctx, int fd, uint32_t index, struct dmg_mish_with_stripes *mish_set) |
712 | 712 |
{ |
713 |
- /* Temporary stub */ |
|
714 |
- cli_dbgmsg("dmg_stripe_adc: stripe " STDu32 "\n", index); |
|
715 |
- /* Return as format error to prevent scan for now */ |
|
716 |
- return CL_EFORMAT; |
|
713 |
+ int ret = CL_CLEAN, adcret; |
|
714 |
+ adc_stream strm; |
|
715 |
+ size_t off = mish_set->stripes[index].dataOffset; |
|
716 |
+ size_t len = mish_set->stripes[index].dataLength; |
|
717 |
+ uint64_t size_so_far = 0; |
|
718 |
+ uint64_t expected_len = mish_set->stripes[index].sectorCount * DMG_SECTOR_SIZE; |
|
719 |
+ uint8_t obuf[BUFSIZ]; |
|
720 |
+ |
|
721 |
+ cli_dbgmsg("dmg_stripe_adc: stripe " STDu32 " initial len " STDu64 " expected len " STDu64 "\n", |
|
722 |
+ index, len, expected_len); |
|
723 |
+ if (len == 0) |
|
724 |
+ return CL_CLEAN; |
|
725 |
+ |
|
726 |
+ memset(&strm, 0, sizeof(strm)); |
|
727 |
+ strm.next_in = (void*)fmap_need_off_once(*ctx->fmap, off, len); |
|
728 |
+ if (!strm.next_in) { |
|
729 |
+ cli_warnmsg("dmg_stripe_adc: fmap need failed on stripe " STDu32 "\n", index); |
|
730 |
+ return CL_EMAP; |
|
731 |
+ } |
|
732 |
+ strm.avail_in = len; |
|
733 |
+ strm.next_out = obuf; |
|
734 |
+ strm.avail_out = sizeof(obuf); |
|
735 |
+ |
|
736 |
+ adcret = adc_decompressInit(&strm); |
|
737 |
+ if(adcret != ADC_OK) { |
|
738 |
+ cli_warnmsg("dmg_stripe_adc: adc_decompressInit failed\n"); |
|
739 |
+ return CL_EMEM; |
|
740 |
+ } |
|
741 |
+ |
|
742 |
+ while(adcret == ADC_OK) { |
|
743 |
+ int written; |
|
744 |
+ if (size_so_far > expected_len) { |
|
745 |
+ cli_warnmsg("dmg_stripe_adc: expected size exceeded!\n"); |
|
746 |
+ adc_decompressEnd(&strm); |
|
747 |
+ return CL_EFORMAT; |
|
748 |
+ } |
|
749 |
+ adcret = adc_decompress(&strm); |
|
750 |
+ switch(adcret) { |
|
751 |
+ case ADC_OK: |
|
752 |
+ if(strm.avail_out == 0) { |
|
753 |
+ if ((written=cli_writen(fd, obuf, sizeof(obuf)))!=sizeof(obuf)) { |
|
754 |
+ cli_errmsg("dmg_stripe_adc: failed write to output file\n"); |
|
755 |
+ adc_decompressEnd(&strm); |
|
756 |
+ return CL_EWRITE; |
|
757 |
+ } |
|
758 |
+ size_so_far += written; |
|
759 |
+ strm.next_out = obuf; |
|
760 |
+ strm.avail_out = sizeof(obuf); |
|
761 |
+ } |
|
762 |
+ continue; |
|
763 |
+ case ADC_STREAM_END: |
|
764 |
+ default: |
|
765 |
+ written = sizeof(obuf) - strm.avail_out; |
|
766 |
+ if (written) { |
|
767 |
+ if ((cli_writen(fd, obuf, written))!=written) { |
|
768 |
+ cli_errmsg("dmg_stripe_adc: failed write to output file\n"); |
|
769 |
+ adc_decompressEnd(&strm); |
|
770 |
+ return CL_EWRITE; |
|
771 |
+ } |
|
772 |
+ size_so_far += written; |
|
773 |
+ strm.next_out = obuf; |
|
774 |
+ strm.avail_out = sizeof(obuf); |
|
775 |
+ } |
|
776 |
+ if (adcret == Z_STREAM_END) |
|
777 |
+ break; |
|
778 |
+ cli_dbgmsg("dmg_stripe_adc: after writing " STDu64 " bytes, " |
|
779 |
+ "got error %d decompressing stripe " STDu32 "\n", |
|
780 |
+ size_so_far, adcret, index); |
|
781 |
+ adc_decompressEnd(&strm); |
|
782 |
+ return CL_EFORMAT; |
|
783 |
+ } |
|
784 |
+ break; |
|
785 |
+ } |
|
786 |
+ |
|
787 |
+ adc_decompressEnd(&strm); |
|
788 |
+ cli_dbgmsg("dmg_stripe_adc: stripe " STDu32 " actual len " STDu64 " expected len " STDu64 "\n", |
|
789 |
+ index, size_so_far, expected_len); |
|
790 |
+ return CL_CLEAN; |
|
717 | 791 |
} |
718 | 792 |
|
719 | 793 |
/* Stripe handling: deflate block (type 0x80000005) */ |
... | ... |
@@ -651,6 +651,8 @@ static int hfsplus_walk_catalog(cli_ctx *ctx, hfsPlusVolumeHeader *volHeader, hf |
651 | 651 |
} |
652 | 652 |
memcpy(&fileRec, &(nodeBuf[recordStart+keylen+2]), sizeof(hfsPlusCatalogFile)); |
653 | 653 |
|
654 |
+ /* Only scan files */ |
|
655 |
+ fileRec.permissions.fileMode = be16_to_host(fileRec.permissions.fileMode); |
|
654 | 656 |
if ((fileRec.permissions.fileMode & HFS_MODE_TYPEMASK) == HFS_MODE_FILE) { |
655 | 657 |
/* Convert forks and scan */ |
656 | 658 |
forkdata_to_host(&(fileRec.dataFork)); |
... | ... |
@@ -658,36 +660,41 @@ static int hfsplus_walk_catalog(cli_ctx *ctx, hfsPlusVolumeHeader *volHeader, hf |
658 | 658 |
if (fileRec.dataFork.logicalSize) { |
659 | 659 |
ret = hfsplus_scanfile(ctx, volHeader, extHeader, &(fileRec.dataFork), dirname); |
660 | 660 |
} |
661 |
+ /* Check return code */ |
|
662 |
+ if (ret == CL_VIRUS) { |
|
663 |
+ has_alerts = 1; |
|
664 |
+ if (SCAN_ALL) { |
|
665 |
+ /* Continue scanning in SCAN_ALL mode */ |
|
666 |
+ cli_dbgmsg("hfsplus_walk_catalog: data fork alert, continuing"); |
|
667 |
+ ret = CL_CLEAN; |
|
668 |
+ } |
|
669 |
+ } |
|
661 | 670 |
if (ret != CL_CLEAN) { |
662 | 671 |
cli_dbgmsg("hfsplus_walk_catalog: data fork retcode %d", ret); |
663 |
- if (ret == CL_VIRUS) { |
|
664 |
- has_alerts = 1; |
|
665 |
- if (SCAN_ALL) { |
|
666 |
- /* Continue scanning in SCAN_ALL mode */ |
|
667 |
- ret = CL_CLEAN; |
|
668 |
- } |
|
669 |
- } |
|
670 | 672 |
break; |
671 | 673 |
} |
674 |
+ /* Scan resource fork */ |
|
672 | 675 |
forkdata_to_host(&(fileRec.resourceFork)); |
673 | 676 |
forkdata_print("resource fork:", &(fileRec.resourceFork)); |
674 | 677 |
if (fileRec.resourceFork.logicalSize) { |
675 | 678 |
ret = hfsplus_scanfile(ctx, volHeader, extHeader, &(fileRec.resourceFork), dirname); |
676 | 679 |
} |
680 |
+ /* Check return code */ |
|
681 |
+ if (ret == CL_VIRUS) { |
|
682 |
+ has_alerts = 1; |
|
683 |
+ if (SCAN_ALL) { |
|
684 |
+ /* Continue scanning in SCAN_ALL mode */ |
|
685 |
+ cli_dbgmsg("hfsplus_walk_catalog: resource fork alert, continuing"); |
|
686 |
+ ret = CL_CLEAN; |
|
687 |
+ } |
|
688 |
+ } |
|
677 | 689 |
if (ret != CL_CLEAN) { |
678 | 690 |
cli_dbgmsg("hfsplus_walk_catalog: resource fork retcode %d", ret); |
679 |
- if (ret == CL_VIRUS) { |
|
680 |
- has_alerts = 1; |
|
681 |
- if (SCAN_ALL) { |
|
682 |
- /* Continue scanning in SCAN_ALL mode */ |
|
683 |
- ret = CL_CLEAN; |
|
684 |
- } |
|
685 |
- } |
|
686 | 691 |
break; |
687 | 692 |
} |
688 | 693 |
} |
689 | 694 |
else { |
690 |
- cli_dbgmsg("hfsplus_walk_catalog: record mode is not File\n"); |
|
695 |
+ cli_dbgmsg("hfsplus_walk_catalog: record mode %o is not File\n", fileRec.permissions.fileMode); |
|
691 | 696 |
} |
692 | 697 |
} |
693 | 698 |
/* if return code, exit loop, message already logged */ |
... | ... |
@@ -452,12 +452,6 @@ struct MP *mpool_create() { |
452 | 452 |
sz = align_to_pagesize(&mp, MIN_FRAGSIZE); |
453 | 453 |
mp.u.mpm.usize = sizeof(struct MPMAP); |
454 | 454 |
mp.u.mpm.size = sz - sizeof(mp); |
455 |
-#ifndef _WIN32 |
|
456 |
- if ((mpool_p = (struct MP *)mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_PRIVATE|ANONYMOUS_MAP, -1, 0)) == MAP_FAILED) |
|
457 |
-#else |
|
458 |
- if(!(mpool_p = (struct MP *)VirtualAlloc(NULL, sz, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE))) |
|
459 |
-#endif |
|
460 |
- return NULL; |
|
461 | 455 |
if (FRAGSBITS > 255) { |
462 | 456 |
cli_errmsg("At most 255 frags possible!\n"); |
463 | 457 |
return NULL; |
... | ... |
@@ -466,6 +460,12 @@ struct MP *mpool_create() { |
466 | 466 |
cli_errmsg("fragsz[0] too small!\n"); |
467 | 467 |
return NULL; |
468 | 468 |
} |
469 |
+#ifndef _WIN32 |
|
470 |
+ if ((mpool_p = (struct MP *)mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_PRIVATE|ANONYMOUS_MAP, -1, 0)) == MAP_FAILED) |
|
471 |
+#else |
|
472 |
+ if(!(mpool_p = (struct MP *)VirtualAlloc(NULL, sz, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE))) |
|
473 |
+#endif |
|
474 |
+ return NULL; |
|
469 | 475 |
#ifdef CL_DEBUG |
470 | 476 |
memset(mpool_p, ALLOCPOISON, sz); |
471 | 477 |
#endif |
... | ... |
@@ -2909,7 +2909,36 @@ int cl_load(const char *path, struct cl_engine *engine, unsigned int *signo, uns |
2909 | 2909 |
} |
2910 | 2910 |
|
2911 | 2911 |
if(CLAMSTAT(path, &sb) == -1) { |
2912 |
- cli_errmsg("cl_load(): Can't get status of %s\n", path); |
|
2912 |
+ switch (errno) { |
|
2913 |
+#if defined(EACCES) |
|
2914 |
+ case EACCES: |
|
2915 |
+ cli_errmsg("cl_load(): Access denied for path: %s\n", path); |
|
2916 |
+ break; |
|
2917 |
+#endif |
|
2918 |
+#if defined(ENOENT) |
|
2919 |
+ case ENOENT: |
|
2920 |
+ cli_errmsg("cl_load(): No such file or directory: %s\n", path); |
|
2921 |
+ break; |
|
2922 |
+#endif |
|
2923 |
+#if defined(ELOOP) |
|
2924 |
+ case ELOOP: |
|
2925 |
+ cli_errmsg("cl_load(): Too many symbolic links encountered in path: %s\n", path); |
|
2926 |
+ break; |
|
2927 |
+#endif |
|
2928 |
+#if defined(EOVERFLOW) |
|
2929 |
+ case EOVERFLOW: |
|
2930 |
+ cli_errmsg("cl_load(): File size is too large to be recognized. Path: %s\n", path); |
|
2931 |
+ break; |
|
2932 |
+#endif |
|
2933 |
+#if defined(EIO) |
|
2934 |
+ case EIO: |
|
2935 |
+ cli_errmsg("cl_load(): An I/O error occurred while reading from path: %s\n", path); |
|
2936 |
+ break; |
|
2937 |
+#endif |
|
2938 |
+ default: |
|
2939 |
+ cli_errmsg("cl_load: Can't get status of: %s\n", path); |
|
2940 |
+ break; |
|
2941 |
+ } |
|
2913 | 2942 |
return CL_ESTAT; |
2914 | 2943 |
} |
2915 | 2944 |
|
... | ... |
@@ -282,6 +282,7 @@ |
282 | 282 |
<ClCompile Include="..\libclamav\7z\Bra.c" /> |
283 | 283 |
<ClCompile Include="..\libclamav\7z\Bra86.c" /> |
284 | 284 |
<ClCompile Include="..\libclamav\7z\LzmaDec.c" /> |
285 |
+ <ClCompile Include="..\libclamav\adc.c" /> |
|
285 | 286 |
<ClCompile Include="..\libclamav\aspack.c" /> |
286 | 287 |
<ClCompile Include="..\libclamav\autoit.c" /> |
287 | 288 |
<ClCompile Include="..\libclamav\binhex.c" /> |
... | ... |
@@ -470,4 +471,4 @@ |
470 | 470 |
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> |
471 | 471 |
<ImportGroup Label="ExtensionTargets"> |
472 | 472 |
</ImportGroup> |
473 |
-</Project> |
|
474 | 473 |
\ No newline at end of file |
474 |
+</Project> |
... | ... |
@@ -51,6 +51,9 @@ |
51 | 51 |
<ClCompile Include="..\libclamav\bytecode_api_decl.c"> |
52 | 52 |
<Filter>Source Files</Filter> |
53 | 53 |
</ClCompile> |
54 |
+ <ClCompile Include="..\libclamav\adc.c"> |
|
55 |
+ <Filter>Source Files</Filter> |
|
56 |
+ </ClCompile> |
|
54 | 57 |
<ClCompile Include="..\libclamav\aspack.c"> |
55 | 58 |
<Filter>Source Files</Filter> |
56 | 59 |
</ClCompile> |
... | ... |
@@ -841,4 +844,4 @@ |
841 | 841 |
<Filter>Source Files\libxml2</Filter> |
842 | 842 |
</ClCompile> |
843 | 843 |
</ItemGroup> |
844 |
-</Project> |
|
845 | 844 |
\ No newline at end of file |
845 |
+</Project> |