Merge branch 'master' into 7z

0.96
aCaB 16 years ago
commit fa53c7eaf4
  1. 4
      ChangeLog
  2. 2
      clamd/clamd.c
  3. 5
      clamd/server-th.c
  4. 1
      clamscan/clamscan.c
  5. 6
      clamscan/manager.c
  6. BIN
      docs/clamdoc.pdf
  7. 7
      docs/clamdoc.tex
  8. 4
      docs/html/clamdoc.html
  9. 2
      docs/html/footnode.html
  10. 4
      docs/html/index.html
  11. 2
      docs/html/node1.html
  12. 4
      docs/html/node10.html
  13. 2
      docs/html/node11.html
  14. 2
      docs/html/node12.html
  15. 2
      docs/html/node13.html
  16. 2
      docs/html/node14.html
  17. 2
      docs/html/node15.html
  18. 2
      docs/html/node16.html
  19. 2
      docs/html/node17.html
  20. 2
      docs/html/node18.html
  21. 2
      docs/html/node19.html
  22. 2
      docs/html/node2.html
  23. 2
      docs/html/node20.html
  24. 2
      docs/html/node21.html
  25. 2
      docs/html/node22.html
  26. 2
      docs/html/node23.html
  27. 2
      docs/html/node24.html
  28. 2
      docs/html/node25.html
  29. 2
      docs/html/node26.html
  30. 2
      docs/html/node27.html
  31. 2
      docs/html/node28.html
  32. 2
      docs/html/node29.html
  33. 2
      docs/html/node3.html
  34. 2
      docs/html/node30.html
  35. 2
      docs/html/node31.html
  36. 2
      docs/html/node32.html
  37. 2
      docs/html/node33.html
  38. 2
      docs/html/node34.html
  39. 2
      docs/html/node35.html
  40. 2
      docs/html/node36.html
  41. 2
      docs/html/node37.html
  42. 2
      docs/html/node38.html
  43. 2
      docs/html/node39.html
  44. 2
      docs/html/node4.html
  45. 2
      docs/html/node40.html
  46. 2
      docs/html/node41.html
  47. 2
      docs/html/node42.html
  48. 2
      docs/html/node43.html
  49. 2
      docs/html/node44.html
  50. 2
      docs/html/node45.html
  51. 2
      docs/html/node46.html
  52. 2
      docs/html/node47.html
  53. 2
      docs/html/node48.html
  54. 9
      docs/html/node49.html
  55. 2
      docs/html/node5.html
  56. 2
      docs/html/node50.html
  57. 2
      docs/html/node51.html
  58. 2
      docs/html/node52.html
  59. 2
      docs/html/node53.html
  60. 2
      docs/html/node54.html
  61. 2
      docs/html/node55.html
  62. 2
      docs/html/node56.html
  63. 2
      docs/html/node57.html
  64. 2
      docs/html/node58.html
  65. 2
      docs/html/node59.html
  66. 2
      docs/html/node6.html
  67. 4
      docs/html/node60.html
  68. 2
      docs/html/node7.html
  69. 2
      docs/html/node8.html
  70. 2
      docs/html/node9.html
  71. 5
      docs/man/clamd.conf.5.in
  72. 3
      docs/man/clamscan.1.in
  73. 6
      etc/clamd.conf
  74. 2
      libclamav/clamav.h
  75. 694
      libclamav/mbox.c
  76. 3
      libclamav/pdf.c
  77. 3
      shared/optparser.c

@ -1,3 +1,7 @@
Thu Aug 6 22:26:30 CEST 2009 (tk)
----------------------------------
* clamd, clamscan, libclamav: drop support for MailFollowURLs (bb#1677)
Wed Aug 5 18:33:11 CEST 2009 (tk)
----------------------------------
* clamd/clamd.c: ignore SIGHUP and SIGUSR2 during initial setup (bb#1671)

@ -42,8 +42,8 @@
#else
#include <pwd.h>
#include <grp.h>
#include <signal.h>
#endif
#include <signal.h>
#if defined(USE_SYSLOG) && !defined(C_AIX)
#include <syslog.h>

@ -832,11 +832,6 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
logg("Mail files support enabled.\n");
options |= CL_SCAN_MAIL;
if(optget(opts, "MailFollowURLs")->enabled) {
logg("Mail: URL scanning enabled.\n");
options |= CL_SCAN_MAILURL;
}
if(optget(opts, "ScanPartialMessages")->enabled) {
logg("Mail: RFC1341 handling enabled.\n");
options |= CL_SCAN_PARTIAL_MESSAGE;

@ -277,7 +277,6 @@ void help(void)
mprintf(" --scan-archive[=yes(*)/no] Scan archive files (supported by libclamav)\n");
mprintf(" --detect-broken[=yes/no(*)] Try to detect broken executable files\n");
mprintf(" --block-encrypted[=yes/no(*)] Block encrypted archives\n");
mprintf(" --mail-follow-urls[=yes/no(*)] Download and scan URLs\n");
mprintf("\n");
mprintf(" --max-filesize=#n Files larger than this will be skipped and assumed clean\n");
mprintf(" --max-scansize=#n The maximum amount of data to scan for each container file (**)\n");

@ -537,13 +537,9 @@ int scanmanager(const struct optstruct *opts)
if(optget(opts, "scan-html")->enabled)
options |= CL_SCAN_HTML;
if(optget(opts, "scan-mail")->enabled) {
if(optget(opts, "scan-mail")->enabled)
options |= CL_SCAN_MAIL;
if(optget(opts, "mail-follow-urls")->enabled)
options |= CL_SCAN_MAILURL;
}
if(optget(opts, "algorithmic-detection")->enabled)
options |= CL_SCAN_ALGORITHMIC;

Binary file not shown.

@ -71,7 +71,7 @@
\vspace{3cm}
\begin{flushright}
\rule[-1ex]{8cm}{3pt}\\
\huge Clam AntiVirus 0.95.2\\
\huge Clam AntiVirus -devel\\
\huge \emph{User Manual}\\
\end{flushright}
@ -985,11 +985,6 @@ const char *cl_engine_get_str(const struct cl_engine *engine,
(Encrypted.Zip, Encrypted.RAR).
\item \textbf{CL\_SCAN\_MAIL}\\
Enable support for mail files.
\item \textbf{CL\_SCAN\_MAILURL}\\
The mail scanner will download and scan URLs listed in a mail
body. This flag should not be used on loaded servers. Due to
potential problems please do not enable it by default but make
it optional.
\item \textbf{CL\_SCAN\_OLE2}\\
Enables support for OLE2 containers (used by MS Office and .msi
files).

@ -56,7 +56,7 @@ original version by: Nikos Drakos, CBLU, University of Leeds
<BR>
<BR>
<DIV ALIGN="RIGHT">
<BR> <BIG CLASS="HUGE">Clam AntiVirus 0.95.2
<BR> <BIG CLASS="HUGE">Clam AntiVirus -devel
<BR> <BIG CLASS="HUGE"><SPAN CLASS="textit">User Manual</SPAN>
<BR>
</BIG></BIG></DIV>
@ -225,7 +225,7 @@ original version by: Nikos Drakos, CBLU, University of Leeds
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -98,7 +98,7 @@ original version by: Nikos Drakos, CBLU, University of Leeds
.
</PRE>
</DD>
<DT><A NAME="foot774">... framework</A><A
<DT><A NAME="foot773">... framework</A><A
HREF="node10.html#tex2html6"><SUP><SPAN CLASS="arabic">3</SPAN></SUP></A></DT>
<DD>See section <A HREF="node15.html#unit-testing">3.6</A> on how to run the unit tests

@ -56,7 +56,7 @@ original version by: Nikos Drakos, CBLU, University of Leeds
<BR>
<BR>
<DIV ALIGN="RIGHT">
<BR> <BIG CLASS="HUGE">Clam AntiVirus 0.95.2
<BR> <BIG CLASS="HUGE">Clam AntiVirus -devel
<BR> <BIG CLASS="HUGE"><SPAN CLASS="textit">User Manual</SPAN>
<BR>
</BIG></BIG></DIV>
@ -225,7 +225,7 @@ original version by: Nikos Drakos, CBLU, University of Leeds
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -188,7 +188,7 @@ ClamAV and Clam AntiVirus are trademarks of Sourcefire, Inc.
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -76,7 +76,7 @@ Requirements</A>
<LI>bzip2 and bzip2-devel library
</LI>
<LI><code>check</code> unit testing framework <A NAME="tex2html6"
HREF="footnode.html#foot774"><SUP><SPAN CLASS="arabic">3</SPAN></SUP></A>.
HREF="footnode.html#foot773"><SUP><SPAN CLASS="arabic">3</SPAN></SUP></A>.
</LI>
</UL>
@ -85,7 +85,7 @@ Requirements</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -75,7 +75,7 @@ Installing on shell account</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -69,7 +69,7 @@ Adding new system user and group</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -75,7 +75,7 @@ Compilation of base package</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -65,7 +65,7 @@ Compilation with clamav-milter enabled</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -142,7 +142,7 @@ All 4 tests passed
<!--End of Navigation Panel-->
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -96,7 +96,7 @@ $ CK_FORK=no ./libtool --mode=execute valgrind unit_tests/check-clamav
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -87,7 +87,7 @@ Configuration</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -79,7 +79,7 @@ clamd</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -90,7 +90,7 @@ On-access scanning</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -79,7 +79,7 @@ Introduction</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -67,7 +67,7 @@ clamav-milter</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -75,7 +75,7 @@ Testing</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -140,7 +140,7 @@ N * * * * /usr/local/bin/freshclam --quiet
<!--End of Navigation Panel-->
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -77,7 +77,7 @@ Closest mirrors</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -108,7 +108,7 @@ The only private data that is transferred is an IP address, which is used
<!--End of Navigation Panel-->
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -80,7 +80,7 @@ Usage</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -230,7 +230,7 @@ Scan stream: clamd will return a new port number you should
<!--End of Navigation Panel-->
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -76,7 +76,7 @@ Clam<SPAN CLASS="textbf">d</SPAN>scan</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -92,7 +92,7 @@ SIGTERM signal. In other case you can lose access
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -70,7 +70,7 @@ Output format</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -183,7 +183,7 @@ Features</A>
<!--End of Navigation Panel-->
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -79,7 +79,7 @@ clamscan</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -83,7 +83,7 @@ Error messages are printed in the following format:
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -135,7 +135,7 @@ LibClamAV</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -65,7 +65,7 @@ Licence</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -79,7 +79,7 @@ Supported formats</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -87,7 +87,7 @@ Executables</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -62,7 +62,7 @@ Mail files</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -92,7 +92,7 @@ Archives and compressed files</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -73,7 +73,7 @@ Documents</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -62,7 +62,7 @@ Data Loss Prevention</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -86,7 +86,7 @@ Alternatively you can try asking on the <code>#clamav</code> IRC channel - launc
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -75,7 +75,7 @@ Others</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -69,7 +69,7 @@ API</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -63,7 +63,7 @@ Header file</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -86,7 +86,7 @@ Initialization</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -122,7 +122,7 @@ Load CVD files directly without unpacking them into a temporary
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -69,7 +69,7 @@ Error handling</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -74,7 +74,7 @@ Engine structure</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -79,7 +79,7 @@ const char *cl_engine_get_str(const struct cl_engine *engine,
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -103,7 +103,7 @@ Database reloading</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -97,13 +97,6 @@ With this flag the library will mark encrypted archives as viruses
<BR>
Enable support for mail files.
</LI>
<LI><SPAN CLASS="textbf">CL_SCAN_MAILURL</SPAN>
<BR>
The mail scanner will download and scan URLs listed in a mail
body. This flag should not be used on loaded servers. Due to
potential problems please do not enable it by default but make
it optional.
</LI>
<LI><SPAN CLASS="textbf">CL_SCAN_OLE2</SPAN>
<BR>
Enables support for OLE2 containers (used by MS Office and .msi
@ -220,7 +213,7 @@ Allow heuristic match to take precedence. When enabled, if
<!--End of Navigation Panel-->
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -65,7 +65,7 @@ Virus submitting</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -63,7 +63,7 @@ Memory</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -65,7 +65,7 @@ Forking daemons</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -67,7 +67,7 @@ clamav-config</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -65,7 +65,7 @@ Example</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -82,7 +82,7 @@ Verification OK.
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -613,7 +613,7 @@ Contributors</A>
<!--End of Navigation Panel-->
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -459,7 +459,7 @@ Donors</A>
<!--End of Navigation Panel-->
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -63,7 +63,7 @@ Graphics</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -62,7 +62,7 @@ OpenAntiVirus</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -134,7 +134,7 @@ Role: coder
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -71,7 +71,7 @@ Base package</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -64,11 +64,11 @@ Mathematics Department, Macquarie University, Sydney.
The command line arguments were: <BR>
<STRONG>latex2html</STRONG> <TT>-local_icons clamdoc.tex</TT>
<P>
The translation was initiated by Tomasz Kojm on 2009-06-10
The translation was initiated by Tomasz Kojm on 2009-08-06
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -80,7 +80,7 @@ Supported platforms</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -61,7 +61,7 @@ Binary packages</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -81,7 +81,7 @@ Installation</A>
<BR><HR>
<ADDRESS>
Tomasz Kojm
2009-06-10
2009-08-06
</ADDRESS>
</BODY>
</HTML>

@ -280,11 +280,6 @@ Default: yes
Enable scanning of mail files.
.br
Default: yes
.TP
\fBMailFollowURLs BOOL\fR
If an email contains URLs ClamAV can download and scan them. \fBWARNING: This option may open your system to a DoS attack. Never use it on loaded servers.\fR
.br
Default: no
.TP
\fBScanPartialMessages BOOL\fR
Scan RFC1341 messages split over many emails. You will need to periodically clean up $TemporaryDirectory/clamav-partial directory. \fBWARNING: This option may open your system to a DoS attack. Never use it on loaded servers.\fR

@ -141,9 +141,6 @@ Mark broken executables as viruses (Broken.Executable).
\fB\-\-block\-encrypted[=yes/no(*)]\fR
Mark encrypted archives as viruses (Encrypted.Zip, Encrypted.RAR).
.TP
\fB\-\-mail\-follow\-urls[=yes/no(*)]\fR
If an email contains URLs ClamAV can download and scan them. \fBWARNING: This option may open your system to a DoS attack. Never use it on loaded servers.\fR
.TP
\fB\-\-max\-files=#n\fR
Extract at most #n files from each scanned file (when this is an archive, a document or another kind of container). This option protects your system against DoS attacks (default: 10000)
.TP

@ -262,12 +262,6 @@ LocalSocket /tmp/clamd.socket
# Default: yes
#ScanMail yes
# If an email contains URLs ClamAV can download and scan them.
# WARNING: This option may open your system to a DoS attack.
# Never use it on loaded servers.
# Default: no
#MailFollowURLs no
# Scan RFC1341 messages split over many emails.
# You will need to periodically clean up $TemporaryDirectory/clamav-partial directory.
# WARNING: This option may open your system to a DoS attack.

@ -93,7 +93,7 @@ typedef enum {
#define CL_SCAN_HTML 0x10
#define CL_SCAN_PE 0x20
#define CL_SCAN_BLOCKBROKEN 0x40
#define CL_SCAN_MAILURL 0x80
#define CL_SCAN_MAILURL 0x80 /* ignored */
#define CL_SCAN_BLOCKMAX 0x100 /* ignored */
#define CL_SCAN_ALGORITHMIC 0x200
#define CL_SCAN_PHISHING_BLOCKSSL 0x800 /* ssl mismatches, not ssl by itself*/

@ -137,16 +137,6 @@ typedef enum {
#define SAVE_TO_DISC /* multipart/message are saved in a temporary file */
#define FOLLOWURLS 5 /*
* Maximum number of URLs scanned in a message
* part. Helps to prevent Dialer.gen-45 and
* Trojan.WinREG.Zapchast which are often
* dispatched by emails which point to it. If
* not defined, don't check any URLs
* It is also used to indicate the number of
* 301/302 redirects we wish to follow
*/
#include "htmlnorm.h"
#include "phishcheck.h"
@ -254,29 +244,6 @@ static bool newline_in_header(const char *line);
static blob *getHrefs(message *m, tag_arguments_t *hrefs);
static void hrefs_done(blob *b, tag_arguments_t *hrefs);
static void checkURLs(message *m, mbox_ctx *mctx, mbox_status *rc, int is_html);
static void do_checkURLs(mbox_ctx *mctx, tag_arguments_t *hrefs);
#if defined(FOLLOWURLS) && (FOLLOWURLS > 0)
struct arg {
char *url;
const char *dir;
char *filename;
int depth;
};
#define CONNECT_TIMEOUT 5 /* Allow 5 seconds to connect */
#ifdef CL_THREAD_SAFE
static void *getURL(void *a);
#else
static void *getURL(struct arg *arg);
#endif
static int nonblock_connect(SOCKET sock, const struct sockaddr_in *sin, const char *hostname);
static int connect_error(SOCKET sock, const char *hostname);
static int my_r_gethostbyname(const char *hostname, struct hostent *hp, char *buf, size_t len);
#define NONBLOCK_SELECT_MAX_FAILURES 3
#define NONBLOCK_MAX_ATTEMPTS 10
#endif
/* Maximum line length according to RFC2821 */
#define RFC2821LENGTH 1000
@ -2071,7 +2038,7 @@ parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx, unsigned int re
*/
case TEXT:
/* text/plain has been preprocessed as no encoding */
if(((mctx->ctx->options&CL_SCAN_MAILURL) && (subtype == HTML)) || doPhishingScan) {
if(doPhishingScan) {
/*
* It would be better to save and scan the
* file and only checkURLs if it's found to be
@ -4055,14 +4022,12 @@ checkURLs(message *mainMessage, mbox_ctx *mctx, mbox_status *rc, int is_html)
hrefs.scanContents = mctx->ctx->engine->dboptions&CL_DB_PHISHING_URLS && (DCONF_PHISHING & PHISHING_CONF_ENGINE);
#if (!defined(FOLLOWURLS)) || (FOLLOWURLS <= 0)
if(!hrefs.scanContents)
/*
* Don't waste time extracting hrefs (parsing html), nobody
* will need it
*/
return;
#endif
hrefs.count = 0;
hrefs.tag = hrefs.value = NULL;
@ -4082,663 +4047,10 @@ checkURLs(message *mainMessage, mbox_ctx *mctx, mbox_status *rc, int is_html)
cli_dbgmsg("PH:Phishing found\n");
}
}
if(is_html && (mctx->ctx->options&CL_SCAN_MAILURL) && (*rc != VIRUS))
do_checkURLs(mctx, &hrefs);
}
hrefs_done(b,&hrefs);
}
#if defined(FOLLOWURLS) && (FOLLOWURLS > 0)
static void
do_checkURLs(mbox_ctx *mctx, tag_arguments_t *hrefs)
{
table_t *t;
int i, n;
const char *dir;
#ifdef CL_THREAD_SAFE
pthread_t tid[FOLLOWURLS];
struct arg args[FOLLOWURLS];
#endif
t = tableCreate();
if(t == NULL)
return;
n = 0;
dir = mctx->dir;
/*
* Sort .exes higher up so that there's more chance they'll be
* downloaded and scanned
*/
for(i = FOLLOWURLS; (i < hrefs->count) && (n < FOLLOWURLS); i++) {
char *url = (char *)hrefs->value[i];
char *ptr;
if(strncasecmp("http://", url, 7) != 0)
continue;
ptr = strrchr(url, '.');
if(ptr == NULL)
continue;
if(strcasecmp(ptr, ".exe") == 0) {
/* FIXME: Could be swapping with another .exe */
cli_dbgmsg("swap %s %s\n", hrefs->value[n], hrefs->value[i]);
ptr = (char *)hrefs->value[n];
hrefs->value[n++] = (unsigned char *)url;
hrefs->value[i] = (unsigned char *)ptr;
}
}
n = 0;
for(i = 0; i < hrefs->count; i++) {
const char *url = (const char *)hrefs->value[i];
/*
* TODO: If it's an image source, it'd be nice to note beacons
* where width="0" height="0", which needs support from
* the HTML normalise code
*/
if(strncasecmp("http://", url, 7) == 0) {
#ifndef CL_THREAD_SAFE
struct arg arg;
#endif
char name[NAME_MAX + 1];
if(tableFind(t, url) == 1) {
cli_dbgmsg("URL %s already downloaded\n", url);
continue;
}
/*
* What about foreign character spoofing?
*/
if(strchr(url, '%') && strchr(url, '@'))
cli_dbgmsg("Possible URL spoofing attempt noticed, but not blocked (%s)\n", url);
if(n == FOLLOWURLS) {
cli_dbgmsg("URL %s will not be scanned (FOLLOWURLS limit %d was reached)\n",
url, FOLLOWURLS);
break;
}
(void)tableInsert(t, url, 1);
cli_dbgmsg("Downloading URL %s to be scanned\n", url);
strncpy(name, url, sizeof(name) - 1);
name[sizeof(name) - 1] = '\0';
sanitiseName(name); /* bug #538 */
#ifdef CL_THREAD_SAFE
args[n].dir = dir;
args[n].url = cli_strdup(url);
args[n].filename = cli_strdup(name);
args[n].depth = 0;
if(pthread_create(&tid[n], NULL, getURL, &args[n])) {
cli_warnmsg("thread creation failed\n");
free(args[n].filename);
free(args[n].url);
break;
}
#else
arg.url = cli_strdup(url);
arg.dir = dir;
arg.filename = name;
arg.depth = 0;
getURL(&arg);
free(arg.url);
#endif
++n;
}
}
tableDestroy(t);
#ifdef CL_THREAD_SAFE
assert(n <= FOLLOWURLS);
cli_dbgmsg("checkURLs: waiting for %d thread(s) to finish\n", n);
while(--n >= 0) {
pthread_join(tid[n], NULL);
free(args[n].filename);
free(args[n].url);
}
#endif
}
#else /*!FOLLOWURLS*/
static void
do_checkURLs(mbox_ctx *mctx, tag_arguments_t *hrefs)
{
}
#endif
#if defined(FOLLOWURLS) && (FOLLOWURLS > 0)
/*
* FIXME: Often WMF exploits work by sending people an email directing them
* to a page which displays a picture containing the exploit. This is not
* currently found, since only the HTML on the referred page is downloaded.
* It would be useful to scan the HTML for references to pictures and
* download them for scanning. But that will hit performance so there is
* an issue here.
*/
/*
* Simple implementation of a subset of RFC1945 (HTTP/1.0)
* TODO: HTTP/1.1 (RFC2068)
*/
static void *
#ifdef CL_THREAD_SAFE
getURL(void *a)
#else
getURL(struct arg *arg)
#endif
{
FILE *fp;
#ifdef CL_THREAD_SAFE
struct arg *arg = (struct arg *)a;
#endif
const char *url = arg->url;
const char *dir = arg->dir;
const char *filename = arg->filename;
SOCKET sd;
struct sockaddr_in server;
#ifdef HAVE_IN_ADDR_T
in_addr_t ip;
#else
unsigned int ip;
#endif
in_port_t port;
static in_port_t default_port;
static int tcp;
int doingsite, firstpacket;
char *ptr;
int via_proxy;
const char *proxy;
char buf[BUFSIZ + 1], site[BUFSIZ], fout[NAME_MAX + 1];
if(strlen(url) > (sizeof(site) - 1)) {
cli_dbgmsg("Ignoring long URL \"%s\"\n", url);
return NULL;
}
snprintf(fout, sizeof(fout) - 1, "%s/%s", dir, filename);
fp = fopen(fout, "wb");
if(fp == NULL) {
cli_errmsg("Can't open '%s' for writing\n", fout);
return NULL;
}
cli_dbgmsg("Saving %s to %s\n", url, fout);
#ifndef C_BEOS
if(tcp == 0) {
const struct protoent *proto = getprotobyname("tcp");
if(proto == NULL) {
cli_warnmsg("Unknown prototol tcp, check /etc/protocols\n");
fclose(fp);
return NULL;
}
tcp = proto->p_proto;
#ifndef C_WINDOWS
endprotoent();
#endif
}
#endif
if(default_port == 0) {
const struct servent *servent = getservbyname("http", "tcp");
if(servent)
default_port = (in_port_t)ntohs(servent->s_port);
else
default_port = 80;
#if !defined(C_WINDOWS) && !defined(C_BEOS)
endservent();
#endif
}
port = default_port;
doingsite = 1;
ptr = site;
proxy = getenv("http_proxy"); /* FIXME: handle no_proxy */
via_proxy = (proxy && *proxy);
if(via_proxy) {
if(strncasecmp(proxy, "http://", 7) != 0) {
cli_warnmsg("Unsupported proxy protocol (proxy = %s)\n",
proxy);
fclose(fp);
return NULL;
}
cli_dbgmsg("Getting %s via %s\n", url, proxy);
proxy += 7;
while(*proxy) {
if(doingsite && (*proxy == ':')) {
port = 0;
while(isdigit(*++proxy)) {
port *= 10;
port += *proxy - '0';
}
continue;
}
if(doingsite && (*proxy == '/')) {
proxy++;
break;
}
*ptr++ = *proxy++;
}
} else {
cli_dbgmsg("Getting %s\n", url);
if(strncasecmp(url, "http://", 7) != 0) {
cli_dbgmsg("Unsupported protocol\n");
fclose(fp);
return NULL;
}
url += 7;
while(*url) {
if(doingsite && (*url == ':')) {
port = 0;
while(isdigit(*++url)) {
port *= 10;
port += *url - '0';
}
continue;
}
if(doingsite && (*url == '/')) {
url++;
break;
}
*ptr++ = *url++;
}
}
*ptr = '\0';
memset((char *)&server, '\0', sizeof(struct sockaddr_in));
server.sin_family = AF_INET;
server.sin_port = (in_port_t)htons(port);
ip = inet_addr(site);
#ifdef INADDR_NONE
if(ip == INADDR_NONE) {
#else
if(ip == (in_addr_t)-1) {
#endif
struct hostent h;
if((my_r_gethostbyname(site, &h, buf, sizeof(buf)) != 0) ||
(h.h_addr_list == NULL) ||
(h.h_addr == NULL)) {
cli_dbgmsg("Unknown host %s\n", site);
fclose(fp);
return NULL;
}
memcpy((char *)&ip, h.h_addr, sizeof(ip));
}
if((sd = socket(AF_INET, SOCK_STREAM, tcp)) < 0) {
fclose(fp);
return NULL;
}
server.sin_addr.s_addr = ip;
if(nonblock_connect(sd, &server, url) < 0) {
closesocket(sd);
fclose(fp);
return NULL;
}
/*
* TODO: consider HTTP/1.1
*/
if(via_proxy)
snprintf(buf, sizeof(buf) - 1,
"GET %s HTTP/1.0\r\nHost: %s\r\nUser-Agent: ClamAV %s\r\n\r\n",
url, site, cl_retver());
else
snprintf(buf, sizeof(buf) - 1,
"GET /%s HTTP/1.0\r\nHost: %s\r\nUser-Agent: ClamAV %s\r\n\r\n",
url, site, cl_retver());
/*cli_dbgmsg("%s", buf);*/
if(send(sd, buf, (int)strlen(buf), 0) < 0) {
closesocket(sd);
fclose(fp);
return NULL;
}
#ifdef SHUT_WR
shutdown(sd, SHUT_WR);
#else
shutdown(sd, 1);
#endif
firstpacket = 1;
for(;;) {
fd_set set;
struct timeval tv;
int n;
FD_ZERO(&set);
FD_SET(sd, &set);
tv.tv_sec = 30; /* FIXME: make this customisable */
tv.tv_usec = 0;
if(select((int)sd + 1, &set, NULL, NULL, &tv) < 0) {
if(errno == EINTR)
continue;
closesocket(sd);
fclose(fp);
return NULL;
}
if(!FD_ISSET(sd, &set)) {
fclose(fp);
closesocket(sd);
return NULL;
}
n = recv(sd, buf, sizeof(buf) - 1, 0);
if(n < 0) {
fclose(fp);
closesocket(sd);
return NULL;
}
if(n == 0)
break;
/*
* FIXME: Handle header in more than one packet
*/
if(firstpacket) {
char *statusptr;
buf[n] = '\0';
statusptr = cli_strtok(buf, 1, " ");
if(statusptr) {
int status = atoi(statusptr);
cli_dbgmsg("HTTP status %d\n", status);
free(statusptr);
if((status == 301) || (status == 302)) {
char *location;
location = strstr(buf, "\nLocation: ");
if(location) {
char *end;
if (cli_unlink(fout)) return NULL;
location += 11;
end = location;
while(*end && (*end != '\n'))
end++;
*end = '\0';
if(arg->depth >= FOLLOWURLS) {
cli_dbgmsg("URL %s will not be followed to %s (FOLLOWURLS limit %d was reached)\n",
arg->url, location, FOLLOWURLS);
break;
}
if(strcmp(location, arg->url) == 0) {
cli_dbgmsg("URL %s redirects to itself\n",
location);
break;
}
fclose(fp);
closesocket(sd);
if(strlen(arg->url) < strlen(location)) {
free(arg->url);
arg->url = cli_strdup(location);
} else
strcpy(arg->url, location);
arg->depth++;
cli_dbgmsg("Redirecting to %s\n", location);
return getURL(arg);
}
}
}
/*
* Don't write the HTTP header
*/
if((ptr = strstr(buf, "\r\n\r\n")) != NULL) {
ptr += 4;
n -= (int)(ptr - buf);
} else if((ptr = strstr(buf, "\n\n")) != NULL) {
ptr += 2;
n -= (int)(ptr - buf);
} else
ptr = buf;
firstpacket = 0;
} else
ptr = buf;
if(n && (fwrite(ptr, n, 1, fp) != 1)) {
cli_warnmsg("Error writing %d bytes to %s\n",
n, fout);
break;
}
}
fclose(fp);
closesocket(sd);
return NULL;
}
/*
* Have a copy here because r_gethostbyname is in shared not libclamav :-(
*/
static int
my_r_gethostbyname(const char *hostname, struct hostent *hp, char *buf, size_t len)
{
struct hostent *hp2;
int ret = -1;
#if !defined(HAVE_GETHOSTBYNAME_R_6) && !defined(HAVE_GETHOSTBYNAME_R_5) && !defined(HAVE_GETHOSTBYNAME_R_3)
#ifdef CL_THREAD_SAFE
static pthread_mutex_t hostent_mutex = PTHREAD_MUTEX_INITIALIZER;
#endif
#endif
if((hostname == NULL) || (hp == NULL))
return -1;
memset(hp, 0, sizeof(struct hostent));
#if defined(HAVE_GETHOSTBYNAME_R_6)
/* e.g. Linux */
if(gethostbyname_r(hostname, hp, buf, len, &hp2, &ret) < 0)
return ret;
#elif defined(HAVE_GETHOSTBYNAME_R_5)
/* e.g. BSD, Solaris, Cygwin */
/*
* Configure doesn't work on BeOS. We need -lnet to link, but configure
* doesn't add it, so you need to do something like
* LIBS=-lnet ./configure --enable-cache --disable-clamav
*/
if(gethostbyname_r(hostname, hp, buf, len, &ret) == NULL)
return ret;
#elif defined(HAVE_GETHOSTBYNAME_R_3)
/* e.g. HP/UX, AIX */
if(gethostbyname_r(hostname, &hp, (struct hostent_data *)buf) < 0)
return h_errno;
#else
/* Single thread the code e.g. VS2005 */
#ifdef CL_THREAD_SAFE
pthread_mutex_lock(&hostent_mutex);
#endif
if((hp2 = gethostbyname(hostname)) == NULL) {
#ifdef CL_THREAD_SAFE
pthread_mutex_unlock(&hostent_mutex);
#endif
return h_errno;
}
memcpy(hp, hp2, sizeof(struct hostent));
#ifdef CL_THREAD_SAFE
pthread_mutex_unlock(&hostent_mutex);
#endif
#endif
return 0;
}
/*
* FIXME: There are lots of copies of this code :-(
*/
static int
nonblock_connect(SOCKET sock, const struct sockaddr_in *sin, const char *hostname)
{
int select_failures; /* Max. of unexpected select() failures */
int attempts;
struct timeval timeout; /* When we should time out */
int numfd; /* Highest fdset fd plus 1 */
long flags;
char err[128];
gettimeofday(&timeout, 0); /* store when we started to connect */
if(hostname == NULL)
hostname = "remote"; /* It's only used in debug messages */
#ifdef F_GETFL
flags = fcntl(sock, F_GETFL, 0);
if(flags == -1L)
cli_dbgmsg("getfl: %s\n", cli_strerror(errno, err, sizeof(err)));
else if(fcntl(sock, F_SETFL, (long)(flags | O_NONBLOCK)) < 0)
cli_dbgmsg("setfl: %s\n", cli_strerror(errno, err, sizeof(err)));
#else
flags = -1L;
#endif
if(connect(sock, (const struct sockaddr *)sin, sizeof(struct sockaddr_in)) != 0)
switch(errno) {
case EALREADY:
case EINPROGRESS:
cli_dbgmsg("%s: connect: %s\n", hostname,
cli_strerror(errno, err, sizeof(err)));
break; /* wait for connection */
case EISCONN:
return 0; /* connected */
default:
cli_dbgmsg("%s: connect: %s\n",
hostname, cli_strerror(errno, err, sizeof(err)));
#ifdef F_SETFL
if(flags != -1L)
if(fcntl(sock, F_SETFL, flags))
cli_dbgmsg("f_setfl: %s\n", cli_strerror(errno, err, sizeof(err)));
#endif
return -1; /* failed */
}
else {
#ifdef F_SETFL
if(flags != -1L)
if(fcntl(sock, F_SETFL, flags))
cli_dbgmsg("f_setfl: %s\n", cli_strerror(errno, err, sizeof(err)));
#endif
return connect_error(sock, hostname);
}
numfd = (int)sock + 1;
select_failures = NONBLOCK_SELECT_MAX_FAILURES;
attempts = 1;
timeout.tv_sec += CONNECT_TIMEOUT;
for (;;) {
int n, t;
fd_set fds;
struct timeval now, waittime;
/* Force timeout if we ran out of time */
gettimeofday(&now, 0);
t = (now.tv_sec == timeout.tv_sec) ?
(now.tv_usec > timeout.tv_usec) :
(now.tv_sec > timeout.tv_sec);
if(t) {
cli_dbgmsg("%s: connect timeout (%d secs)\n",
hostname, CONNECT_TIMEOUT);
break;
}
/* Calculate how long to wait */
waittime.tv_sec = timeout.tv_sec - now.tv_sec;
waittime.tv_usec = timeout.tv_usec - now.tv_usec;
if(waittime.tv_usec < 0) {
waittime.tv_sec--;
waittime.tv_usec += 1000000;
}
/* Init fds with 'sock' as the only fd */
FD_ZERO(&fds);
FD_SET(sock, &fds);
n = select(numfd, 0, &fds, 0, &waittime);
if(n < 0) {
cli_dbgmsg("%s: select attempt %d %s\n",
hostname, select_failures, cli_strerror(errno, err, sizeof(err)));
if(--select_failures >= 0)
continue; /* not timed-out, try again */
break; /* failed */
}
cli_dbgmsg("%s: select = %d\n", hostname, n);
if(n) {
#ifdef F_SETFL
if(flags != -1L)
if(fcntl(sock, F_SETFL, flags))
cli_dbgmsg("f_setfl: %s\n", cli_strerror(errno, err, sizeof(err)));
#endif
return connect_error(sock, hostname);
}
/* timeout */
if(attempts++ == NONBLOCK_MAX_ATTEMPTS) {
cli_dbgmsg("timeout connecting to %s\n", hostname);
break;
}
}
#ifdef F_SETFL
if(flags != -1L)
if(fcntl(sock, F_SETFL, flags))
cli_dbgmsg("f_setfl: %s\n", cli_strerror(errno, err, sizeof(err)));
#endif
return -1; /* failed */
}
static int
connect_error(SOCKET sock, const char *hostname)
{
char err[128];
#ifdef SO_ERROR
int optval;
socklen_t optlen = sizeof(optval);
getsockopt(sock, SOL_SOCKET, SO_ERROR, &optval, &optlen);
if(optval) {
cli_dbgmsg("%s: %s\n", hostname, cli_strerror(optval, err, sizeof(err)));
return -1;
}
#endif
return 0;
}
#endif
#ifdef HAVE_BACKTRACE
static void
sigsegv(int sig)
@ -5096,9 +4408,7 @@ do_multipart(message *mainMessage, message **messages, int i, mbox_status *rc, m
cli_dbgmsg("Treating inline as attachment\n");
} else {
const int is_html = (tableFind(mctx->subtypeTable, cptr) == HTML);
if((mctx->ctx->options&CL_SCAN_MAILURL) && is_html)
checkURLs(aMessage, mctx, rc, 1);
else if(doPhishingScan)
if(doPhishingScan)
checkURLs(aMessage, mctx, rc, is_html);
messageAddArgument(aMessage,
"filename=mixedtextportion");

@ -74,9 +74,6 @@ static const char *pdf_nextlinestart(const char *ptr, size_t len);
static const char *pdf_nextobject(const char *ptr, size_t len);
static const char *cli_pmemstr(const char *haystack, size_t hs, const char *needle, size_t ns);
/*
* TODO: handle embedded URLs if (options&CL_SCAN_MAILURL)
*/
int
cli_pdf(const char *dir, int desc, cli_ctx *ctx, off_t offset)
{

@ -247,8 +247,6 @@ const struct clam_option clam_options[] = {
{ "ScanMail", "scan-mail", 0, TYPE_BOOL, MATCH_BOOL, 1, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "Enable the built in email scanner.", "yes" },
{ "MailFollowURLs", "mail-follow-urls", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "If an email contains URLs ClamAV can download and scan them.\nWARNING: This option may open your system to a DoS attack. Please don't use\nthis feature on highly loaded servers.", "no" },
{ "ScanPartialMessages", NULL, 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD, "Scan RFC1341 messages split over many emails. You will need to\nperiodically clean up $TemporaryDirectory/clamav-partial directory.\nWARNING: This option may open your system to a DoS attack. Please don't use\nthis feature on highly loaded servers.", "no" },
{ "PhishingSignatures", "phishing-sigs", 0, TYPE_BOOL, MATCH_BOOL, 1, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "With this option enabled ClamAV will try to detect phishing attempts by using\nsignatures.", "yes" },
@ -367,6 +365,7 @@ const struct clam_option clam_options[] = {
{ "ArchiveMaxCompressionRatio", NULL, 0, TYPE_NUMBER, NULL, -1, NULL, 0, OPT_CLAMD | OPT_DEPRECATED, "", "" },
{ "ArchiveBlockMax", NULL, 0, TYPE_BOOL, MATCH_BOOL, -1, NULL, 0, OPT_CLAMD | OPT_DEPRECATED, "", "" },
{ "ArchiveLimitMemoryUsage", NULL, 0, TYPE_BOOL, MATCH_BOOL, -1, NULL, 0, OPT_CLAMD | OPT_DEPRECATED, "", "" },
{ "MailFollowURLs", "mail-follow-urls", 0, TYPE_BOOL, MATCH_BOOL, -1, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN | OPT_DEPRECATED, "", "" },
/* Milter specific options */

Loading…
Cancel
Save