|
|
|
@ -71,7 +71,7 @@ |
|
|
|
|
\vspace{3cm} |
|
|
|
|
\begin{flushright} |
|
|
|
|
\rule[-1ex]{8cm}{3pt}\\ |
|
|
|
|
\huge Clam AntiVirus 0.94.2\\ |
|
|
|
|
\huge Clam AntiVirus 0.95rc1\\ |
|
|
|
|
\huge \emph{User Manual}\\ |
|
|
|
|
\end{flushright} |
|
|
|
|
|
|
|
|
@ -83,8 +83,8 @@ |
|
|
|
|
\noindent |
|
|
|
|
\begin{boxedminipage}[b]{\textwidth} |
|
|
|
|
ClamAV User Manual, |
|
|
|
|
\copyright \ 2007 - 2008 Sourcefire, Inc. |
|
|
|
|
\copyright \ 2002 - 2007 Tomasz Kojm\\ |
|
|
|
|
\copyright \ 2007 - 2009 Sourcefire, Inc. |
|
|
|
|
Authors: Tomasz Kojm\\ |
|
|
|
|
This document is distributed under the terms of the GNU General |
|
|
|
|
Public License v2.\\ |
|
|
|
|
|
|
|
|
@ -127,7 +127,7 @@ |
|
|
|
|
\item{POSIX compliant, portable} |
|
|
|
|
\item{Fast scanning} |
|
|
|
|
\item{Supports on-access scanning (Linux and FreeBSD only)} |
|
|
|
|
\item{Detects over 450.000 viruses, worms and trojans, including |
|
|
|
|
\item{Detects over 500.000 viruses, worms and trojans, including |
|
|
|
|
Microsoft Office macro viruses, mobile malware, and other threats} |
|
|
|
|
\item{Scans within archives and compressed files (also protects |
|
|
|
|
against archive bombs), built-in support includes: |
|
|
|
@ -237,16 +237,6 @@ |
|
|
|
|
The following packages are optional but \textbf{highly recommended}: |
|
|
|
|
\begin{itemize} |
|
|
|
|
\item bzip2 and bzip2-devel library |
|
|
|
|
\item GNU MP 3\\ |
|
|
|
|
It's very important to install the GMP package because it allows |
|
|
|
|
\verb+freshclam+ to verify the digital signatures of the virus |
|
|
|
|
databases and scripted updates. If freshclam was compiled without GMP |
|
|
|
|
support it will display "SECURITY WARNING: NO SUPPORT FOR DIGITAL |
|
|
|
|
SIGNATURES" on every update. You can download GNU MP at |
|
|
|
|
\url{http://www.swox.com/gmp/}\\ |
|
|
|
|
A note for Solaris/SPARC users: you must set the \emph{ABI} system |
|
|
|
|
variable to 32 (e.g. \verb+setenv ABI 32+) before running the |
|
|
|
|
configuration script of GMP. |
|
|
|
|
\item \verb+check+ unit testing framework \footnote{See section \ref{unit-testing} on how to run the unit tests}. |
|
|
|
|
\end{itemize} |
|
|
|
|
|
|
|
|
@ -323,7 +313,7 @@ |
|
|
|
|
When \verb+make check+ is finished, you should get a message similar to this: |
|
|
|
|
\begin{verbatim} |
|
|
|
|
================== |
|
|
|
|
All 5 tests passed |
|
|
|
|
All 8 tests passed |
|
|
|
|
================== |
|
|
|
|
\end{verbatim} |
|
|
|
|
|
|
|
|
@ -331,7 +321,7 @@ All 5 tests passed |
|
|
|
|
See the next section on how to report a bug when a unit test fails. |
|
|
|
|
\begin{verbatim} |
|
|
|
|
======================================== |
|
|
|
|
1 of 5 tests failed |
|
|
|
|
1 of 8 tests failed |
|
|
|
|
Please report to http://bugs.clamav.net/ |
|
|
|
|
======================================== |
|
|
|
|
\end{verbatim} |
|
|
|
@ -423,27 +413,13 @@ $ CK_FORK=no ./libtool --mode=execute valgrind unit_tests/check-clamav |
|
|
|
|
section. |
|
|
|
|
|
|
|
|
|
\subsection{clamav-milter} |
|
|
|
|
Nigel Horne's \verb+clamav-milter+ is a very efficient email scanner |
|
|
|
|
designed for Sendmail. It's written entirely in C and only depends on |
|
|
|
|
\verb+libclamav+ or \verb+clamd+. You can find detailed installation |
|
|
|
|
instructions in the \verb+INSTALL+ file that comes with the clamav-milter |
|
|
|
|
sources. Basically, to connect it with Sendmail add the following lines to |
|
|
|
|
\verb+/etc/mail/sendmail.mc+: |
|
|
|
|
\begin{verbatim} |
|
|
|
|
INPUT_MAIL_FILTER(`clmilter',`S=local:/var/run/clamav/clmilter.sock, |
|
|
|
|
F=, T=S:4m;R:4m')dnl |
|
|
|
|
define(`confINPUT_MAIL_FILTERS', `clmilter') |
|
|
|
|
\end{verbatim} |
|
|
|
|
If you're running it in \verb+--external+ mode, check entry in |
|
|
|
|
\verb+clamd.conf+ of the form: |
|
|
|
|
\begin{verbatim} |
|
|
|
|
LocalSocket /var/run/clamav/clamd.sock |
|
|
|
|
\end{verbatim} |
|
|
|
|
Start clamav-milter |
|
|
|
|
\begin{verbatim} |
|
|
|
|
/usr/local/sbin/clamav-milter -lo /var/run/clamav/clmilter.sock |
|
|
|
|
\end{verbatim} |
|
|
|
|
and restart sendmail. |
|
|
|
|
ClamAV 0.95 includes a new, redesigned clamav-milter. The most notable |
|
|
|
|
difference is that the internal mode has been dropped and now a working |
|
|
|
|
clamd companion is required. The second important difference is that now |
|
|
|
|
the milter has got its own configuration and log files. To compile ClamAV |
|
|
|
|
with the clamav-milter just run \verb+./configure+ \verb+--enable-milter+ |
|
|
|
|
and make as usual. Please consult your MTA's manual on how to connect it |
|
|
|
|
with the milter. |
|
|
|
|
|
|
|
|
|
\subsection{Testing} |
|
|
|
|
Try to scan recursively the source directory: |
|
|
|
@ -525,6 +501,29 @@ N * * * * /usr/local/bin/freshclam --quiet |
|
|
|
|
mirror fails for some reason. The full list of two-letters country codes |
|
|
|
|
is available at \url{http://www.iana.org/cctld/cctld-whois.htm} |
|
|
|
|
|
|
|
|
|
\subsection{ClamAV Active Malware Report} |
|
|
|
|
|
|
|
|
|
The ClamAV Active Malware Report that was introduced in ClamAV 0.94.1 uses |
|
|
|
|
freshclam to send summary data to our server about the malware that has |
|
|
|
|
been detected. This data is then used to generate real-time reports on |
|
|
|
|
active malware. These reports, along with geographical and historic trends, |
|
|
|
|
will be published on \url{http://www.clamav.net/}. |
|
|
|
|
|
|
|
|
|
The more data that we receive from ClamAV users, the more reports, and the |
|
|
|
|
better the quality of the reports, will be. To enable the submission of |
|
|
|
|
data to us for use in the Active Malware Report, enable |
|
|
|
|
SubmitDetectionStats in freshclam.conf, and LogTime and LogFile in |
|
|
|
|
clamd.conf. You should only enable this feature if you're running clamd |
|
|
|
|
to scan incoming data in your environment. |
|
|
|
|
|
|
|
|
|
The only private data that is transferred is an IP address, which is used |
|
|
|
|
to create the geographical data. The size of the data that is sent is small; |
|
|
|
|
it contains just the filename, malware name and time of detection. The data |
|
|
|
|
is sent in sets of 10 records, up to 50 records per session. For example, |
|
|
|
|
if you have 45 new records, then freshclam will submit 40; if 78 then it |
|
|
|
|
will submit the latest 50 entries; and if you have 9 records no statistics |
|
|
|
|
will be sent. |
|
|
|
|
|
|
|
|
|
\section{Usage} |
|
|
|
|
|
|
|
|
|
\subsection{Clam daemon}\label{clamd} |
|
|
|
@ -557,20 +556,73 @@ N * * * * /usr/local/bin/freshclam --quiet |
|
|
|
|
\item \textbf{MULTISCAN file/directory}\\ |
|
|
|
|
Scan file in a standard way or scan directory (recursively) using |
|
|
|
|
multiple threads (to make the scanning faster on SMP machines). |
|
|
|
|
\item \textbf{STREAM}\\ |
|
|
|
|
Scan stream: \verb+clamd+ will return a new port number you should |
|
|
|
|
\item \textbf{INSTREAM}\\ |
|
|
|
|
\emph{It is mandatory to prefix this command with \textbf{n} or |
|
|
|
|
\textbf{z}.}\\ |
|
|
|
|
Scan a stream of data. The stream is sent to clamd in chunks, |
|
|
|
|
after INSTREAM, on the same socket on which the command |
|
|
|
|
was sent. This avoids the overhead of establishing new TCP |
|
|
|
|
connections and problems with NAT. The format of the chunk is: |
|
|
|
|
\verb+<length><data>+ where \verb+<length>+ is the size of the |
|
|
|
|
following data in bytes expressed as a 4 byte unsigned integer in |
|
|
|
|
network byte order and \verb+<data>+ is the actual chunk. Streaming |
|
|
|
|
is terminated by sending a zero-length chunk. Note: do not exceed |
|
|
|
|
StreamMaxLength as defined in clamd.conf, otherwise clamd will |
|
|
|
|
reply with \emph{INSTREAM size limit exceeded} and close the |
|
|
|
|
connection. |
|
|
|
|
\item \textbf{FILDES}\\ |
|
|
|
|
\emph{It is mandatory to newline terminate this command, or prefix |
|
|
|
|
with \textbf{n} or \textbf{z}. This command only works on UNIX |
|
|
|
|
domain sockets.}\\ |
|
|
|
|
Scan a file descriptor. After issuing a FILDES command a subsequent |
|
|
|
|
rfc2292/bsd4.4 style packet (with at least one dummy character) is |
|
|
|
|
sent to clamd carrying the file descriptor to be scanned inside the |
|
|
|
|
ancillary data. Alternatively the file descriptor may be sent in |
|
|
|
|
the same packet, including the extra character. |
|
|
|
|
\item \textbf{STATS}\\ |
|
|
|
|
\emph{It is mandatory to newline terminate this command, or prefix |
|
|
|
|
with \textbf{n} or \textbf{z}, it is recommended to only use the |
|
|
|
|
\textbf{z} prefix.}\\ |
|
|
|
|
On this command clamd provides statistics about the scan queue, |
|
|
|
|
contents of scan queue, and memory usage. The exact reply format is |
|
|
|
|
subject to changes in future releases. |
|
|
|
|
\item \textbf{IDSESSION, END}\\ |
|
|
|
|
\emph{It is mandatory to prefix this command with \textbf{n} or |
|
|
|
|
\textbf{z}, also all commands inside \textbf{IDSESSION} must be |
|
|
|
|
prefixed.}\\ |
|
|
|
|
Start/end a clamd session. Within a session multiple |
|
|
|
|
SCAN, INSTREAM, FILDES, VERSION, STATS commands can be sent on the |
|
|
|
|
same socket without opening new connections. Replies from clamd |
|
|
|
|
will be in the form \verb+<id>: <response>+ where \verb+<id>+ is |
|
|
|
|
the request number (in ASCII, starting from 1) and \verb+<response>+ |
|
|
|
|
is the usual clamd reply. The reply lines have the same delimiter |
|
|
|
|
as the corresponding command had. Clamd will process the commands |
|
|
|
|
asynchronously, and reply as soon as it has finished processing. |
|
|
|
|
Clamd requires clients to read all the replies it sent, before |
|
|
|
|
sending more commands to prevent send() deadlocks. The recommended |
|
|
|
|
way to implement a client that uses IDSESSION is with non-blocking |
|
|
|
|
sockets, and a select()/poll() loop: whenever send would block, |
|
|
|
|
sleep in select/poll until either you can write more data, or read |
|
|
|
|
more replies. \emph{Note that using non-blocking sockets without |
|
|
|
|
the select/poll loop and alternating recv()/send() doesn't comply |
|
|
|
|
with clamd's requirements.} If clamd detects that a client has |
|
|
|
|
deadlocked, it will close the connection. Note that clamd may |
|
|
|
|
close an IDSESSION connection too if the client doesn't follow the |
|
|
|
|
protocol's requirements. |
|
|
|
|
\item \textbf{STREAM} (deprecated, use \textbf{INSTREAM} instead)\\ |
|
|
|
|
Scan stream: clamd will return a new port number you should |
|
|
|
|
connect to and send data to scan. |
|
|
|
|
\item \textbf{SESSION, END}\\ |
|
|
|
|
Start/end a \verb+clamd+ session - you can do multiple commands |
|
|
|
|
per TCP session (WARNING: due to the \verb+clamd+ implementation the |
|
|
|
|
\textbf{RELOAD} command will break the session). |
|
|
|
|
\end{itemize} |
|
|
|
|
It's recommended to prefix clamd commands with the letter \verb+n+ |
|
|
|
|
(eg. \verb+nSCAN+) to indicate that the command will be delimited by |
|
|
|
|
a newline character and that clamd should continue reading command data |
|
|
|
|
until a newline is read. The newline delimiter assures that the complete |
|
|
|
|
command and its entire argument will be processed as a single command.\\ |
|
|
|
|
|
|
|
|
|
It's recommended to prefix clamd commands with the letter \textbf{z} |
|
|
|
|
(eg. zSCAN) to indicate that the command will be delimited by a NULL |
|
|
|
|
character and that clamd should continue reading command data until a NULL |
|
|
|
|
character is read. The null delimiter assures that the complete command |
|
|
|
|
and its entire argument will be processed as a single command. Alternatively |
|
|
|
|
commands may be prefixed with the letter \textbf{n} (e.g. nSCAN) to use |
|
|
|
|
a newline character as the delimiter. Clamd replies will honour the |
|
|
|
|
requested terminator in turn. If clamd doesn't recognize the command, or |
|
|
|
|
the command doesn't follow the requirements specified below, it will reply |
|
|
|
|
with an error message, and close the connection. |
|
|
|
|
\noindent |
|
|
|
|
Clamd can handle the following signals: |
|
|
|
|
\begin{itemize} |
|
|
|
@ -591,8 +643,9 @@ N * * * * /usr/local/bin/freshclam --quiet |
|
|
|
|
\item although it accepts the same command line options as |
|
|
|
|
\verb+clamscan+ most of them are ignored because they must be |
|
|
|
|
enabled directly in \verb+clamd+, i.e. \verb+clamd.conf+ |
|
|
|
|
\item scanned files must be accessible for \verb+clamd+ |
|
|
|
|
\item it can't use external unpackers |
|
|
|
|
\item in TCP mode scanned files must be accessible for \verb+clamd+, |
|
|
|
|
if you enabled LocalSocket in clamd.conf then clamdscan will |
|
|
|
|
try to workaround this limitation by using FILDES |
|
|
|
|
\end{itemize} |
|
|
|
|
|
|
|
|
|
\subsection{Clamuko}\label{clamuko} |
|
|
|
@ -644,21 +697,6 @@ N * * * * /usr/local/bin/freshclam --quiet |
|
|
|
|
zolw@localhost:/tmp$ clamscan malware.zip |
|
|
|
|
malware.zip: Worm.Mydoom.U FOUND |
|
|
|
|
\end{verbatim} |
|
|
|
|
\emph{\textbf{TIP:} You can force clamscan to list all infected |
|
|
|
|
files in an archive using --no-archive (this option disables |
|
|
|
|
transparent decompressors built into libclamav) and enabling external |
|
|
|
|
decompressors: --unzip --unrar...}.\\[4pt] |
|
|
|
|
\begin{verbatim} |
|
|
|
|
zolw@localhost:/tmp$ clamscan --no-archive --unzip malware.zip |
|
|
|
|
Archive: /tmp/malware.zip |
|
|
|
|
inflating: test1.exe |
|
|
|
|
inflating: test2.exe |
|
|
|
|
inflating: test3.exe |
|
|
|
|
/tmp/clamav-77e7bfdbb2d3872b/test1.exe: Worm.Mydoom.U FOUND |
|
|
|
|
/tmp/clamav-77e7bfdbb2d3872b/test2.exe: Trojan.Taskkill.A FOUND |
|
|
|
|
/tmp/clamav-77e7bfdbb2d3872b/test3.exe: Worm.Nyxem.D FOUND |
|
|
|
|
/tmp/malware.zip: Infected.Archive FOUND |
|
|
|
|
\end{verbatim} |
|
|
|
|
|
|
|
|
|
\subsubsection{clamd} |
|
|
|
|
The output format of \verb+clamd+ is very similar to \verb+clamscan+. |
|
|
|
@ -736,6 +774,7 @@ N * * * * /usr/local/bin/freshclam --quiet |
|
|
|
|
\item BinHex |
|
|
|
|
\item SIS (SymbianOS packages) |
|
|
|
|
\item AutoIt |
|
|
|
|
\item NSIS |
|
|
|
|
\end{itemize} |
|
|
|
|
|
|
|
|
|
\subsubsection{Documents} |
|
|
|
@ -747,6 +786,10 @@ N * * * * /usr/local/bin/freshclam --quiet |
|
|
|
|
\item HTML |
|
|
|
|
\end{itemize} |
|
|
|
|
|
|
|
|
|
\subsubsection{Data Loss Prevention} |
|
|
|
|
Libclamav includes a DLP module which can detect credit card and |
|
|
|
|
social security numbers inside text files. |
|
|
|
|
|
|
|
|
|
\subsubsection{Others} |
|
|
|
|
Libclamav can handle various obfuscators, encoders, files vulnerable to |
|
|
|
|
security risks such as: |
|
|
|
@ -766,23 +809,39 @@ N * * * * /usr/local/bin/freshclam --quiet |
|
|
|
|
#include <clamav.h> |
|
|
|
|
\end{verbatim} |
|
|
|
|
|
|
|
|
|
\subsection{Initialization} |
|
|
|
|
Before using libclamav, you should call \verb+cl_init()+ to initialize |
|
|
|
|
it. When it's done, you're ready to create a new scan engine by calling |
|
|
|
|
\verb+cl_engine_new()+. To free resources allocated by the engine use |
|
|
|
|
\verb+cl_engine_free()+. Function prototypes: |
|
|
|
|
\begin{verbatim} |
|
|
|
|
int cl_init(unsigned int options); |
|
|
|
|
struct cl_engine *cl_engine_new(void); |
|
|
|
|
int cl_engine_free(struct cl_engine *engine); |
|
|
|
|
\end{verbatim} |
|
|
|
|
\verb+cl_init()+ and \verb+cl_engine_free()+ return \verb+CL_SUCCESS+ |
|
|
|
|
on success or another code on error. \verb+cl_engine_new()+ return |
|
|
|
|
a pointer or NULL if there's not enough memory to allocate a new |
|
|
|
|
engine structure. |
|
|
|
|
|
|
|
|
|
\subsubsection{Database loading} |
|
|
|
|
The following set of functions provides an interface for loading |
|
|
|
|
the virus database: |
|
|
|
|
\begin{verbatim} |
|
|
|
|
const char *cl_retdbdir(void); |
|
|
|
|
|
|
|
|
|
int cl_load(const char *path, struct cl_engine **engine, |
|
|
|
|
int cl_load(const char *path, struct cl_engine *engine, |
|
|
|
|
unsigned int *signo, unsigned int options); |
|
|
|
|
\end{verbatim} |
|
|
|
|
\verb+cl_retdbdir+ returns the default (hardcoded) path to the directory |
|
|
|
|
\verb+cl_retdbdir()+ returns the default (hardcoded) path to the directory |
|
|
|
|
with ClamAV databases. |
|
|
|
|
\verb+cl_load+ loads a single database file or all databases from a |
|
|
|
|
directory (if \verb+path+ points to a directory). The second argument |
|
|
|
|
is used for passing in the engine structure which should be previously |
|
|
|
|
initialized with NULL. A number of loaded signatures will be \textbf{added} |
|
|
|
|
to \verb+signo+ \footnote{Remember to initialize the virus counter |
|
|
|
|
variable with 0.}. The last argument can pass the following flags: |
|
|
|
|
\verb+cl_load()+ loads a single database file or all databases from a |
|
|
|
|
given directory (when \verb+path+ points to a directory). The second |
|
|
|
|
argument is used for passing in the pointer to the engine that should |
|
|
|
|
be previously allocated with \verb+cl_engine_new()+. A number of loaded |
|
|
|
|
signatures will be \textbf{added} to \verb+signo+ \footnote{Remember to |
|
|
|
|
initialize the virus counter variable with 0.}. The last argument can |
|
|
|
|
pass the following flags: |
|
|
|
|
\begin{itemize} |
|
|
|
|
\item \textbf{CL\_DB\_STDOPT}\\ |
|
|
|
|
This is an alias for a recommended set of scan options. |
|
|
|
@ -796,48 +855,74 @@ N * * * * /usr/local/bin/freshclam --quiet |
|
|
|
|
Load CVD files directly without unpacking them into a temporary |
|
|
|
|
directory. |
|
|
|
|
\end{itemize} |
|
|
|
|
\verb+cl_load+ returns 0 (\verb+CL_SUCCESS+) on success and a negative |
|
|
|
|
value on failure. |
|
|
|
|
\verb+cl_load()+ returns \verb+CL_SUCCESS+ on success and another code on |
|
|
|
|
failure. |
|
|
|
|
\begin{verbatim} |
|
|
|
|
... |
|
|
|
|
struct cl_engine *engine = NULL; |
|
|
|
|
struct cl_engine *engine; |
|
|
|
|
unsigned int sigs = 0; |
|
|
|
|
int ret; |
|
|
|
|
|
|
|
|
|
ret = cl_load(cl_retdbdir(), &engine, &sigs, CL_DB_STDOPT); |
|
|
|
|
if((ret = cl_init()) != CL_SUCCESS) { |
|
|
|
|
printf("cl_init() error: %s\n", cl_strerror(ret)); |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(!(engine = cl_engine_new())) { |
|
|
|
|
printf("Can't create new engine\n"); |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ret = cl_load(cl_retdbdir(), engine, &sigs, CL_DB_STDOPT); |
|
|
|
|
\end{verbatim} |
|
|
|
|
|
|
|
|
|
\subsubsection{Error handling} |
|
|
|
|
Use \verb+cl_strerror+ to convert error codes into human readable messages. |
|
|
|
|
The function returns a statically allocated string: |
|
|
|
|
Use \verb+cl_strerror()+ to convert error codes into human readable |
|
|
|
|
messages. The function returns a statically allocated string: |
|
|
|
|
\begin{verbatim} |
|
|
|
|
if(ret) { |
|
|
|
|
if(ret != CL_SUCCESS) { |
|
|
|
|
printf("cl_load() error: %s\n", cl_strerror(ret)); |
|
|
|
|
exit(1); |
|
|
|
|
cl_engine_free(engine); |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
\end{verbatim} |
|
|
|
|
|
|
|
|
|
\subsubsection{Engine structure} |
|
|
|
|
When all required databases are loaded you should prepare the detection |
|
|
|
|
engine by calling \verb+cl_build+. In the case of failure you should |
|
|
|
|
free the memory occupied by the engine with \verb+cl_free+: |
|
|
|
|
engine by calling \verb+cl_engine_compile()+. In case of failure you |
|
|
|
|
should still free the memory allocated to the engine with |
|
|
|
|
\verb+cl_engine_free()+: |
|
|
|
|
\begin{verbatim} |
|
|
|
|
int cl_build(struct cl_engine *engine); |
|
|
|
|
void cl_free(struct cl_engine *engine); |
|
|
|
|
int cl_engine_compile(struct cl_engine *engine); |
|
|
|
|
\end{verbatim} |
|
|
|
|
In our example: |
|
|
|
|
\begin{verbatim} |
|
|
|
|
if((ret = cl_build(engine))) { |
|
|
|
|
printf("cl_build() error: %s\n", cl_strerror(ret)); |
|
|
|
|
cl_free(engine); |
|
|
|
|
exit(1); |
|
|
|
|
if((ret = cl_engine_compile(engine)) != CL_SUCCESS) { |
|
|
|
|
printf("cl_engine_compile() error: %s\n", cl_strerror(ret)); |
|
|
|
|
cl_engine_free(engine); |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
\end{verbatim} |
|
|
|
|
|
|
|
|
|
\subsection{Limits} |
|
|
|
|
When you create a new engine with \verb+cl_engine_new()+, it will have |
|
|
|
|
all internal settings set to default values as recommended by the |
|
|
|
|
ClamAV authors. It's possible to check and modify the values using |
|
|
|
|
this couple of functions: |
|
|
|
|
\begin{verbatim} |
|
|
|
|
int cl_engine_set(struct cl_engine *engine, |
|
|
|
|
enum cl_engine_field field, const void *val); |
|
|
|
|
|
|
|
|
|
int cl_engine_get(const struct cl_engine *engine, |
|
|
|
|
enum cl_engine_field fi eld, void *val); |
|
|
|
|
\end{verbatim} |
|
|
|
|
Please don't modify the default values unless you know what you're doing. |
|
|
|
|
Refer to ClamAV sources (clamscan, clamd) for examples. |
|
|
|
|
|
|
|
|
|
\subsection{Database reloading} |
|
|
|
|
The most important thing is to keep the internal instance of the database |
|
|
|
|
up to date. You can watch database changes with the \verb+cl_stat+ |
|
|
|
|
family of functions. |
|
|
|
|
It's very important to keep the internal instance of the database up to |
|
|
|
|
date. You can watch database changes with the \verb+cl_stat..()+ family |
|
|
|
|
of functions. |
|
|
|
|
\begin{verbatim} |
|
|
|
|
int cl_statinidir(const char *dirname, struct cl_stat *dbstat); |
|
|
|
|
int cl_statchkdir(const struct cl_stat *dbstat); |
|
|
|
@ -860,42 +945,26 @@ N * * * * /usr/local/bin/freshclam --quiet |
|
|
|
|
cl_statinidir(cl_retdbdir(), &dbstat); |
|
|
|
|
} |
|
|
|
|
\end{verbatim} |
|
|
|
|
Remember to reset the \verb+cl_stat+ structure after reload. |
|
|
|
|
Remember to reset the \verb+cl_stat+ structure after each reload. |
|
|
|
|
|
|
|
|
|
\subsubsection{Data scan functions} |
|
|
|
|
It's possible to scan a file or descriptor using: |
|
|
|
|
\begin{verbatim} |
|
|
|
|
int cl_scanfile(const char *filename, const char **virname, |
|
|
|
|
unsigned long int *scanned, const struct cl_engine *engine, |
|
|
|
|
const struct cl_limits *limits, unsigned int options); |
|
|
|
|
unsigned int options); |
|
|
|
|
|
|
|
|
|
int cl_scandesc(int desc, const char **virname, unsigned |
|
|
|
|
long int *scanned, const struct cl_engine *engine, const |
|
|
|
|
struct cl_limits *limits, unsigned int options); |
|
|
|
|
long int *scanned, const struct cl_engine *engine, |
|
|
|
|
unsigned int options); |
|
|
|
|
\end{verbatim} |
|
|
|
|
Both functions will store a virus name under the pointer \verb+virname+, |
|
|
|
|
the virus name is part of the engine structure and must not be released |
|
|
|
|
directly. If the third argument (\verb+scanned+) is not NULL, the |
|
|
|
|
functions will increase its value with the size of scanned data (in |
|
|
|
|
\verb+CL_COUNT_PRECISION+ units). Both functions have support for archive |
|
|
|
|
limits in order to protect against Denial of Service attacks. |
|
|
|
|
\begin{verbatim} |
|
|
|
|
struct cl_limits { |
|
|
|
|
unsigned long int maxscansize; /* during the scanning of archives this |
|
|
|
|
* size will never be exceeded |
|
|
|
|
*/ |
|
|
|
|
unsigned long int maxfilesize; /* compressed files will only be |
|
|
|
|
* decompressed and scanned up to this size |
|
|
|
|
*/ |
|
|
|
|
unsigned int maxreclevel; /* maximum recursion level for archives */ |
|
|
|
|
unsigned int maxfiles; /* maximum number of files to be scanned |
|
|
|
|
* within a single archive |
|
|
|
|
*/ |
|
|
|
|
unsigned short archivememlim; /* limit memory usage for some unpackers */ |
|
|
|
|
}; |
|
|
|
|
\end{verbatim} |
|
|
|
|
The last argument (\verb+options+) configures the scan engine and supports |
|
|
|
|
the following flags (that can be combined using bit operators): |
|
|
|
|
\verb+CL_COUNT_PRECISION+ units). |
|
|
|
|
The last argument (\verb+options+) specified the scan options and supports |
|
|
|
|
the following flags (which can be combined using bit operators): |
|
|
|
|
\begin{itemize} |
|
|
|
|
\item \textbf{CL\_SCAN\_STDOPT}\\ |
|
|
|
|
This is an alias for a recommended set of scan options. You |
|
|
|
@ -938,22 +1007,34 @@ struct cl_limits { |
|
|
|
|
Phishing module: always block SSL mismatches in URLs. |
|
|
|
|
\item \textbf{CL\_SCAN\_PHISHING\_BLOCKCLOAK}\\ |
|
|
|
|
Phishing module: always block cloaked URLs. |
|
|
|
|
\item \textbf{CL\_SCAN\_STRUCTURED}\\ |
|
|
|
|
Enable the DLP module which scans for credit card and SSN |
|
|
|
|
numbers. |
|
|
|
|
\item \textbf{CL\_SCAN\_STRUCTURED\_SSN\_NORMAL}\\ |
|
|
|
|
Search for SSNs formatted as xx-yy-zzzz. |
|
|
|
|
\item \textbf{CL\_SCAN\_STRUCTURED\_SSN\_STRIPPED}\\ |
|
|
|
|
Search for SSNs formatted as xxyyzzzz. |
|
|
|
|
\item \textbf{CL\_SCAN\_PARTIAL\_MESSAGE}\\ |
|
|
|
|
Scan RFC1341 messages split over many emails. You will need to |
|
|
|
|
periodically clean up \verb+$TemporaryDirectory/clamav-partial+ |
|
|
|
|
directory. |
|
|
|
|
\item \textbf{CL\_SCAN\_HEURISTIC\_PRECEDENCE}\\ |
|
|
|
|
Allow heuristic match to take precedence. When enabled, if |
|
|
|
|
a heuristic scan (such as phishingScan) detects a possible |
|
|
|
|
virus/phish it will stop scan immediately. Recommended, saves CPU |
|
|
|
|
scan-time. When disabled, virus/phish detected by heuristic scans |
|
|
|
|
will be reported only at the end of a scan. If an archive |
|
|
|
|
contains both a heuristically detected virus/phishing, and a real |
|
|
|
|
malware, the real malware will be reported. |
|
|
|
|
\end{itemize} |
|
|
|
|
All functions return 0 (\verb+CL_CLEAN+) when the file seems clean, |
|
|
|
|
All functions return \verb+CL_CLEAN+ when the file seems clean, |
|
|
|
|
\verb+CL_VIRUS+ when a virus is detected and another value on failure. |
|
|
|
|
\begin{verbatim} |
|
|
|
|
... |
|
|
|
|
struct cl_limits limits; |
|
|
|
|
const char *virname; |
|
|
|
|
|
|
|
|
|
memset(&limits, 0, sizeof(struct cl_limits)); |
|
|
|
|
limits.maxfiles = 10000; |
|
|
|
|
limits.maxscansize = 100 * 1048576; /* 100 MB */ |
|
|
|
|
limits.maxfilesize = 10 * 1048576; /* 10 MB */ |
|
|
|
|
limits.maxreclevel = 16; |
|
|
|
|
|
|
|
|
|
if((ret = cl_scanfile("/tmp/test.exe", &virname, NULL, engine, |
|
|
|
|
&limits, CL_STDOPT)) == CL_VIRUS) { |
|
|
|
|
CL_STDOPT)) == CL_VIRUS) { |
|
|
|
|
printf("Virus detected: %s\n", virname); |
|
|
|
|
} else { |
|
|
|
|
printf("No virus detected.\n"); |
|
|
|
@ -964,7 +1045,8 @@ struct cl_limits { |
|
|
|
|
|
|
|
|
|
\subsubsection{Memory} |
|
|
|
|
Because the engine structure occupies a few megabytes of system memory, you |
|
|
|
|
should release it with \verb+cl_free+ if you no longer need to scan files. |
|
|
|
|
should release it with \verb+cl_engine_free()+ if you no longer need to |
|
|
|
|
scan files. |
|
|
|
|
|
|
|
|
|
\subsubsection{Forking daemons} |
|
|
|
|
If you're using libclamav with a forking daemon you should call |
|
|
|
@ -983,9 +1065,9 @@ struct cl_limits { |
|
|
|
|
\end{verbatim} |
|
|
|
|
|
|
|
|
|
\subsubsection{Example} |
|
|
|
|
You will find an example scanner application in the clamav sources |
|
|
|
|
(/example). Don't forget that all programs based on libclamav must be |
|
|
|
|
linked against it: |
|
|
|
|
You will find an example scanner application in the clamav source |
|
|
|
|
package (/example). Provided you have ClamAV already installed, execute |
|
|
|
|
the following to compile it: |
|
|
|
|
\begin{verbatim} |
|
|
|
|
gcc -Wall ex1.c -o ex1 -lclamav |
|
|
|
|
\end{verbatim} |
|
|
|
|