| ... | ... |
@@ -1,3 +1,7 @@ |
| 1 |
+Thu Aug 6 22:26:30 CEST 2009 (tk) |
|
| 2 |
+---------------------------------- |
|
| 3 |
+ * clamd, clamscan, libclamav: drop support for MailFollowURLs (bb#1677) |
|
| 4 |
+ |
|
| 1 | 5 |
Wed Aug 5 18:33:11 CEST 2009 (tk) |
| 2 | 6 |
---------------------------------- |
| 3 | 7 |
* clamd/clamd.c: ignore SIGHUP and SIGUSR2 during initial setup (bb#1671) |
| ... | ... |
@@ -832,11 +832,6 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi |
| 832 | 832 |
logg("Mail files support enabled.\n");
|
| 833 | 833 |
options |= CL_SCAN_MAIL; |
| 834 | 834 |
|
| 835 |
- if(optget(opts, "MailFollowURLs")->enabled) {
|
|
| 836 |
- logg("Mail: URL scanning enabled.\n");
|
|
| 837 |
- options |= CL_SCAN_MAILURL; |
|
| 838 |
- } |
|
| 839 |
- |
|
| 840 | 835 |
if(optget(opts, "ScanPartialMessages")->enabled) {
|
| 841 | 836 |
logg("Mail: RFC1341 handling enabled.\n");
|
| 842 | 837 |
options |= CL_SCAN_PARTIAL_MESSAGE; |
| ... | ... |
@@ -277,7 +277,6 @@ void help(void) |
| 277 | 277 |
mprintf(" --scan-archive[=yes(*)/no] Scan archive files (supported by libclamav)\n");
|
| 278 | 278 |
mprintf(" --detect-broken[=yes/no(*)] Try to detect broken executable files\n");
|
| 279 | 279 |
mprintf(" --block-encrypted[=yes/no(*)] Block encrypted archives\n");
|
| 280 |
- mprintf(" --mail-follow-urls[=yes/no(*)] Download and scan URLs\n");
|
|
| 281 | 280 |
mprintf("\n");
|
| 282 | 281 |
mprintf(" --max-filesize=#n Files larger than this will be skipped and assumed clean\n");
|
| 283 | 282 |
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) |
| 537 | 537 |
if(optget(opts, "scan-html")->enabled) |
| 538 | 538 |
options |= CL_SCAN_HTML; |
| 539 | 539 |
|
| 540 |
- if(optget(opts, "scan-mail")->enabled) {
|
|
| 540 |
+ if(optget(opts, "scan-mail")->enabled) |
|
| 541 | 541 |
options |= CL_SCAN_MAIL; |
| 542 | 542 |
|
| 543 |
- if(optget(opts, "mail-follow-urls")->enabled) |
|
| 544 |
- options |= CL_SCAN_MAILURL; |
|
| 545 |
- } |
|
| 546 |
- |
|
| 547 | 543 |
if(optget(opts, "algorithmic-detection")->enabled) |
| 548 | 544 |
options |= CL_SCAN_ALGORITHMIC; |
| 549 | 545 |
|
| ... | ... |
@@ -71,7 +71,7 @@ |
| 71 | 71 |
\vspace{3cm}
|
| 72 | 72 |
\begin{flushright}
|
| 73 | 73 |
\rule[-1ex]{8cm}{3pt}\\
|
| 74 |
- \huge Clam AntiVirus 0.95.2\\ |
|
| 74 |
+ \huge Clam AntiVirus -devel\\ |
|
| 75 | 75 |
\huge \emph{User Manual}\\
|
| 76 | 76 |
\end{flushright}
|
| 77 | 77 |
|
| ... | ... |
@@ -985,11 +985,6 @@ const char *cl_engine_get_str(const struct cl_engine *engine, |
| 985 | 985 |
(Encrypted.Zip, Encrypted.RAR). |
| 986 | 986 |
\item \textbf{CL\_SCAN\_MAIL}\\
|
| 987 | 987 |
Enable support for mail files. |
| 988 |
- \item \textbf{CL\_SCAN\_MAILURL}\\
|
|
| 989 |
- The mail scanner will download and scan URLs listed in a mail |
|
| 990 |
- body. This flag should not be used on loaded servers. Due to |
|
| 991 |
- potential problems please do not enable it by default but make |
|
| 992 |
- it optional. |
|
| 993 | 988 |
\item \textbf{CL\_SCAN\_OLE2}\\
|
| 994 | 989 |
Enables support for OLE2 containers (used by MS Office and .msi |
| 995 | 990 |
files). |
| ... | ... |
@@ -56,7 +56,7 @@ original version by: Nikos Drakos, CBLU, University of Leeds |
| 56 | 56 |
<BR> |
| 57 | 57 |
<BR> |
| 58 | 58 |
<DIV ALIGN="RIGHT"> |
| 59 |
-<BR> <BIG CLASS="HUGE">Clam AntiVirus 0.95.2 |
|
| 59 |
+<BR> <BIG CLASS="HUGE">Clam AntiVirus -devel |
|
| 60 | 60 |
<BR> <BIG CLASS="HUGE"><SPAN CLASS="textit">User Manual</SPAN> |
| 61 | 61 |
<BR> |
| 62 | 62 |
</BIG></BIG></DIV> |
| ... | ... |
@@ -225,7 +225,7 @@ original version by: Nikos Drakos, CBLU, University of Leeds |
| 225 | 225 |
<BR><HR> |
| 226 | 226 |
<ADDRESS> |
| 227 | 227 |
Tomasz Kojm |
| 228 |
-2009-06-10 |
|
| 228 |
+2009-08-06 |
|
| 229 | 229 |
</ADDRESS> |
| 230 | 230 |
</BODY> |
| 231 | 231 |
</HTML> |
| ... | ... |
@@ -98,7 +98,7 @@ original version by: Nikos Drakos, CBLU, University of Leeds |
| 98 | 98 |
. |
| 99 | 99 |
</PRE> |
| 100 | 100 |
</DD> |
| 101 |
-<DT><A NAME="foot774">... framework</A><A |
|
| 101 |
+<DT><A NAME="foot773">... framework</A><A |
|
| 102 | 102 |
HREF="node10.html#tex2html6"><SUP><SPAN CLASS="arabic">3</SPAN></SUP></A></DT> |
| 103 | 103 |
<DD>See section <A HREF="node15.html#unit-testing">3.6</A> on how to run the unit tests |
| 104 | 104 |
|
| ... | ... |
@@ -56,7 +56,7 @@ original version by: Nikos Drakos, CBLU, University of Leeds |
| 56 | 56 |
<BR> |
| 57 | 57 |
<BR> |
| 58 | 58 |
<DIV ALIGN="RIGHT"> |
| 59 |
-<BR> <BIG CLASS="HUGE">Clam AntiVirus 0.95.2 |
|
| 59 |
+<BR> <BIG CLASS="HUGE">Clam AntiVirus -devel |
|
| 60 | 60 |
<BR> <BIG CLASS="HUGE"><SPAN CLASS="textit">User Manual</SPAN> |
| 61 | 61 |
<BR> |
| 62 | 62 |
</BIG></BIG></DIV> |
| ... | ... |
@@ -225,7 +225,7 @@ original version by: Nikos Drakos, CBLU, University of Leeds |
| 225 | 225 |
<BR><HR> |
| 226 | 226 |
<ADDRESS> |
| 227 | 227 |
Tomasz Kojm |
| 228 |
-2009-06-10 |
|
| 228 |
+2009-08-06 |
|
| 229 | 229 |
</ADDRESS> |
| 230 | 230 |
</BODY> |
| 231 | 231 |
</HTML> |
| ... | ... |
@@ -76,7 +76,7 @@ Requirements</A> |
| 76 | 76 |
<LI>bzip2 and bzip2-devel library |
| 77 | 77 |
</LI> |
| 78 | 78 |
<LI><code>check</code> unit testing framework <A NAME="tex2html6" |
| 79 |
- HREF="footnode.html#foot774"><SUP><SPAN CLASS="arabic">3</SPAN></SUP></A>. |
|
| 79 |
+ HREF="footnode.html#foot773"><SUP><SPAN CLASS="arabic">3</SPAN></SUP></A>. |
|
| 80 | 80 |
|
| 81 | 81 |
</LI> |
| 82 | 82 |
</UL> |
| ... | ... |
@@ -85,7 +85,7 @@ Requirements</A> |
| 85 | 85 |
<BR><HR> |
| 86 | 86 |
<ADDRESS> |
| 87 | 87 |
Tomasz Kojm |
| 88 |
-2009-06-10 |
|
| 88 |
+2009-08-06 |
|
| 89 | 89 |
</ADDRESS> |
| 90 | 90 |
</BODY> |
| 91 | 91 |
</HTML> |
| ... | ... |
@@ -97,13 +97,6 @@ With this flag the library will mark encrypted archives as viruses |
| 97 | 97 |
<BR> |
| 98 | 98 |
Enable support for mail files. |
| 99 | 99 |
</LI> |
| 100 |
-<LI><SPAN CLASS="textbf">CL_SCAN_MAILURL</SPAN> |
|
| 101 |
-<BR> |
|
| 102 |
-The mail scanner will download and scan URLs listed in a mail |
|
| 103 |
- body. This flag should not be used on loaded servers. Due to |
|
| 104 |
- potential problems please do not enable it by default but make |
|
| 105 |
- it optional. |
|
| 106 |
-</LI> |
|
| 107 | 100 |
<LI><SPAN CLASS="textbf">CL_SCAN_OLE2</SPAN> |
| 108 | 101 |
<BR> |
| 109 | 102 |
Enables support for OLE2 containers (used by MS Office and .msi |
| ... | ... |
@@ -220,7 +213,7 @@ Allow heuristic match to take precedence. When enabled, if |
| 220 | 220 |
<!--End of Navigation Panel--> |
| 221 | 221 |
<ADDRESS> |
| 222 | 222 |
Tomasz Kojm |
| 223 |
-2009-06-10 |
|
| 223 |
+2009-08-06 |
|
| 224 | 224 |
</ADDRESS> |
| 225 | 225 |
</BODY> |
| 226 | 226 |
</HTML> |
| ... | ... |
@@ -64,11 +64,11 @@ Mathematics Department, Macquarie University, Sydney. |
| 64 | 64 |
The command line arguments were: <BR> |
| 65 | 65 |
<STRONG>latex2html</STRONG> <TT>-local_icons clamdoc.tex</TT> |
| 66 | 66 |
<P> |
| 67 |
-The translation was initiated by Tomasz Kojm on 2009-06-10 |
|
| 67 |
+The translation was initiated by Tomasz Kojm on 2009-08-06 |
|
| 68 | 68 |
<BR><HR> |
| 69 | 69 |
<ADDRESS> |
| 70 | 70 |
Tomasz Kojm |
| 71 |
-2009-06-10 |
|
| 71 |
+2009-08-06 |
|
| 72 | 72 |
</ADDRESS> |
| 73 | 73 |
</BODY> |
| 74 | 74 |
</HTML> |
| ... | ... |
@@ -280,11 +280,6 @@ Default: yes |
| 280 | 280 |
Enable scanning of mail files. |
| 281 | 281 |
.br |
| 282 | 282 |
Default: yes |
| 283 |
-.TP |
|
| 284 |
-\fBMailFollowURLs BOOL\fR |
|
| 285 |
-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 |
|
| 286 |
-.br |
|
| 287 |
-Default: no |
|
| 288 | 283 |
.TP |
| 289 | 284 |
\fBScanPartialMessages BOOL\fR |
| 290 | 285 |
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). |
| 141 | 141 |
\fB\-\-block\-encrypted[=yes/no(*)]\fR |
| 142 | 142 |
Mark encrypted archives as viruses (Encrypted.Zip, Encrypted.RAR). |
| 143 | 143 |
.TP |
| 144 |
-\fB\-\-mail\-follow\-urls[=yes/no(*)]\fR |
|
| 145 |
-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 |
|
| 146 |
-.TP |
|
| 147 | 144 |
\fB\-\-max\-files=#n\fR |
| 148 | 145 |
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) |
| 149 | 146 |
.TP |
| ... | ... |
@@ -262,12 +262,6 @@ LocalSocket /tmp/clamd.socket |
| 262 | 262 |
# Default: yes |
| 263 | 263 |
#ScanMail yes |
| 264 | 264 |
|
| 265 |
-# If an email contains URLs ClamAV can download and scan them. |
|
| 266 |
-# WARNING: This option may open your system to a DoS attack. |
|
| 267 |
-# Never use it on loaded servers. |
|
| 268 |
-# Default: no |
|
| 269 |
-#MailFollowURLs no |
|
| 270 |
- |
|
| 271 | 265 |
# Scan RFC1341 messages split over many emails. |
| 272 | 266 |
# You will need to periodically clean up $TemporaryDirectory/clamav-partial directory. |
| 273 | 267 |
# WARNING: This option may open your system to a DoS attack. |
| ... | ... |
@@ -93,7 +93,7 @@ typedef enum {
|
| 93 | 93 |
#define CL_SCAN_HTML 0x10 |
| 94 | 94 |
#define CL_SCAN_PE 0x20 |
| 95 | 95 |
#define CL_SCAN_BLOCKBROKEN 0x40 |
| 96 |
-#define CL_SCAN_MAILURL 0x80 |
|
| 96 |
+#define CL_SCAN_MAILURL 0x80 /* ignored */ |
|
| 97 | 97 |
#define CL_SCAN_BLOCKMAX 0x100 /* ignored */ |
| 98 | 98 |
#define CL_SCAN_ALGORITHMIC 0x200 |
| 99 | 99 |
#define CL_SCAN_PHISHING_BLOCKSSL 0x800 /* ssl mismatches, not ssl by itself*/ |
| ... | ... |
@@ -137,16 +137,6 @@ typedef enum {
|
| 137 | 137 |
|
| 138 | 138 |
#define SAVE_TO_DISC /* multipart/message are saved in a temporary file */ |
| 139 | 139 |
|
| 140 |
-#define FOLLOWURLS 5 /* |
|
| 141 |
- * Maximum number of URLs scanned in a message |
|
| 142 |
- * part. Helps to prevent Dialer.gen-45 and |
|
| 143 |
- * Trojan.WinREG.Zapchast which are often |
|
| 144 |
- * dispatched by emails which point to it. If |
|
| 145 |
- * not defined, don't check any URLs |
|
| 146 |
- * It is also used to indicate the number of |
|
| 147 |
- * 301/302 redirects we wish to follow |
|
| 148 |
- */ |
|
| 149 |
- |
|
| 150 | 140 |
#include "htmlnorm.h" |
| 151 | 141 |
|
| 152 | 142 |
#include "phishcheck.h" |
| ... | ... |
@@ -254,29 +244,6 @@ static bool newline_in_header(const char *line); |
| 254 | 254 |
static blob *getHrefs(message *m, tag_arguments_t *hrefs); |
| 255 | 255 |
static void hrefs_done(blob *b, tag_arguments_t *hrefs); |
| 256 | 256 |
static void checkURLs(message *m, mbox_ctx *mctx, mbox_status *rc, int is_html); |
| 257 |
-static void do_checkURLs(mbox_ctx *mctx, tag_arguments_t *hrefs); |
|
| 258 |
- |
|
| 259 |
-#if defined(FOLLOWURLS) && (FOLLOWURLS > 0) |
|
| 260 |
-struct arg {
|
|
| 261 |
- char *url; |
|
| 262 |
- const char *dir; |
|
| 263 |
- char *filename; |
|
| 264 |
- int depth; |
|
| 265 |
-}; |
|
| 266 |
-#define CONNECT_TIMEOUT 5 /* Allow 5 seconds to connect */ |
|
| 267 |
-#ifdef CL_THREAD_SAFE |
|
| 268 |
-static void *getURL(void *a); |
|
| 269 |
-#else |
|
| 270 |
-static void *getURL(struct arg *arg); |
|
| 271 |
-#endif |
|
| 272 |
-static int nonblock_connect(SOCKET sock, const struct sockaddr_in *sin, const char *hostname); |
|
| 273 |
-static int connect_error(SOCKET sock, const char *hostname); |
|
| 274 |
-static int my_r_gethostbyname(const char *hostname, struct hostent *hp, char *buf, size_t len); |
|
| 275 |
- |
|
| 276 |
-#define NONBLOCK_SELECT_MAX_FAILURES 3 |
|
| 277 |
-#define NONBLOCK_MAX_ATTEMPTS 10 |
|
| 278 |
- |
|
| 279 |
-#endif |
|
| 280 | 257 |
|
| 281 | 258 |
/* Maximum line length according to RFC2821 */ |
| 282 | 259 |
#define RFC2821LENGTH 1000 |
| ... | ... |
@@ -2071,7 +2038,7 @@ parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx, unsigned int re |
| 2071 | 2071 |
*/ |
| 2072 | 2072 |
case TEXT: |
| 2073 | 2073 |
/* text/plain has been preprocessed as no encoding */ |
| 2074 |
- if(((mctx->ctx->options&CL_SCAN_MAILURL) && (subtype == HTML)) || doPhishingScan) {
|
|
| 2074 |
+ if(doPhishingScan) {
|
|
| 2075 | 2075 |
/* |
| 2076 | 2076 |
* It would be better to save and scan the |
| 2077 | 2077 |
* 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) |
| 4055 | 4055 |
|
| 4056 | 4056 |
hrefs.scanContents = mctx->ctx->engine->dboptions&CL_DB_PHISHING_URLS && (DCONF_PHISHING & PHISHING_CONF_ENGINE); |
| 4057 | 4057 |
|
| 4058 |
-#if (!defined(FOLLOWURLS)) || (FOLLOWURLS <= 0) |
|
| 4059 | 4058 |
if(!hrefs.scanContents) |
| 4060 | 4059 |
/* |
| 4061 | 4060 |
* Don't waste time extracting hrefs (parsing html), nobody |
| 4062 | 4061 |
* will need it |
| 4063 | 4062 |
*/ |
| 4064 | 4063 |
return; |
| 4065 |
-#endif |
|
| 4066 | 4064 |
|
| 4067 | 4065 |
hrefs.count = 0; |
| 4068 | 4066 |
hrefs.tag = hrefs.value = NULL; |
| ... | ... |
@@ -4082,663 +4047,10 @@ checkURLs(message *mainMessage, mbox_ctx *mctx, mbox_status *rc, int is_html) |
| 4082 | 4082 |
cli_dbgmsg("PH:Phishing found\n");
|
| 4083 | 4083 |
} |
| 4084 | 4084 |
} |
| 4085 |
- if(is_html && (mctx->ctx->options&CL_SCAN_MAILURL) && (*rc != VIRUS)) |
|
| 4086 |
- do_checkURLs(mctx, &hrefs); |
|
| 4087 | 4085 |
} |
| 4088 | 4086 |
hrefs_done(b,&hrefs); |
| 4089 | 4087 |
} |
| 4090 | 4088 |
|
| 4091 |
-#if defined(FOLLOWURLS) && (FOLLOWURLS > 0) |
|
| 4092 |
-static void |
|
| 4093 |
-do_checkURLs(mbox_ctx *mctx, tag_arguments_t *hrefs) |
|
| 4094 |
-{
|
|
| 4095 |
- table_t *t; |
|
| 4096 |
- int i, n; |
|
| 4097 |
- const char *dir; |
|
| 4098 |
-#ifdef CL_THREAD_SAFE |
|
| 4099 |
- pthread_t tid[FOLLOWURLS]; |
|
| 4100 |
- struct arg args[FOLLOWURLS]; |
|
| 4101 |
-#endif |
|
| 4102 |
- |
|
| 4103 |
- t = tableCreate(); |
|
| 4104 |
- if(t == NULL) |
|
| 4105 |
- return; |
|
| 4106 |
- |
|
| 4107 |
- n = 0; |
|
| 4108 |
- dir = mctx->dir; |
|
| 4109 |
- |
|
| 4110 |
- /* |
|
| 4111 |
- * Sort .exes higher up so that there's more chance they'll be |
|
| 4112 |
- * downloaded and scanned |
|
| 4113 |
- */ |
|
| 4114 |
- for(i = FOLLOWURLS; (i < hrefs->count) && (n < FOLLOWURLS); i++) {
|
|
| 4115 |
- char *url = (char *)hrefs->value[i]; |
|
| 4116 |
- char *ptr; |
|
| 4117 |
- |
|
| 4118 |
- if(strncasecmp("http://", url, 7) != 0)
|
|
| 4119 |
- continue; |
|
| 4120 |
- |
|
| 4121 |
- ptr = strrchr(url, '.'); |
|
| 4122 |
- if(ptr == NULL) |
|
| 4123 |
- continue; |
|
| 4124 |
- if(strcasecmp(ptr, ".exe") == 0) {
|
|
| 4125 |
- /* FIXME: Could be swapping with another .exe */ |
|
| 4126 |
- cli_dbgmsg("swap %s %s\n", hrefs->value[n], hrefs->value[i]);
|
|
| 4127 |
- ptr = (char *)hrefs->value[n]; |
|
| 4128 |
- hrefs->value[n++] = (unsigned char *)url; |
|
| 4129 |
- hrefs->value[i] = (unsigned char *)ptr; |
|
| 4130 |
- } |
|
| 4131 |
- } |
|
| 4132 |
- |
|
| 4133 |
- n = 0; |
|
| 4134 |
- |
|
| 4135 |
- for(i = 0; i < hrefs->count; i++) {
|
|
| 4136 |
- const char *url = (const char *)hrefs->value[i]; |
|
| 4137 |
- |
|
| 4138 |
- /* |
|
| 4139 |
- * TODO: If it's an image source, it'd be nice to note beacons |
|
| 4140 |
- * where width="0" height="0", which needs support from |
|
| 4141 |
- * the HTML normalise code |
|
| 4142 |
- */ |
|
| 4143 |
- if(strncasecmp("http://", url, 7) == 0) {
|
|
| 4144 |
-#ifndef CL_THREAD_SAFE |
|
| 4145 |
- struct arg arg; |
|
| 4146 |
-#endif |
|
| 4147 |
- char name[NAME_MAX + 1]; |
|
| 4148 |
- |
|
| 4149 |
- if(tableFind(t, url) == 1) {
|
|
| 4150 |
- cli_dbgmsg("URL %s already downloaded\n", url);
|
|
| 4151 |
- continue; |
|
| 4152 |
- } |
|
| 4153 |
- /* |
|
| 4154 |
- * What about foreign character spoofing? |
|
| 4155 |
- */ |
|
| 4156 |
- if(strchr(url, '%') && strchr(url, '@')) |
|
| 4157 |
- cli_dbgmsg("Possible URL spoofing attempt noticed, but not blocked (%s)\n", url);
|
|
| 4158 |
- |
|
| 4159 |
- if(n == FOLLOWURLS) {
|
|
| 4160 |
- cli_dbgmsg("URL %s will not be scanned (FOLLOWURLS limit %d was reached)\n",
|
|
| 4161 |
- url, FOLLOWURLS); |
|
| 4162 |
- break; |
|
| 4163 |
- } |
|
| 4164 |
- |
|
| 4165 |
- (void)tableInsert(t, url, 1); |
|
| 4166 |
- cli_dbgmsg("Downloading URL %s to be scanned\n", url);
|
|
| 4167 |
- strncpy(name, url, sizeof(name) - 1); |
|
| 4168 |
- name[sizeof(name) - 1] = '\0'; |
|
| 4169 |
- sanitiseName(name); /* bug #538 */ |
|
| 4170 |
- |
|
| 4171 |
-#ifdef CL_THREAD_SAFE |
|
| 4172 |
- args[n].dir = dir; |
|
| 4173 |
- args[n].url = cli_strdup(url); |
|
| 4174 |
- args[n].filename = cli_strdup(name); |
|
| 4175 |
- args[n].depth = 0; |
|
| 4176 |
- if(pthread_create(&tid[n], NULL, getURL, &args[n])) {
|
|
| 4177 |
- cli_warnmsg("thread creation failed\n");
|
|
| 4178 |
- free(args[n].filename); |
|
| 4179 |
- free(args[n].url); |
|
| 4180 |
- break; |
|
| 4181 |
- } |
|
| 4182 |
-#else |
|
| 4183 |
- arg.url = cli_strdup(url); |
|
| 4184 |
- arg.dir = dir; |
|
| 4185 |
- arg.filename = name; |
|
| 4186 |
- arg.depth = 0; |
|
| 4187 |
- getURL(&arg); |
|
| 4188 |
- free(arg.url); |
|
| 4189 |
-#endif |
|
| 4190 |
- ++n; |
|
| 4191 |
- } |
|
| 4192 |
- } |
|
| 4193 |
- tableDestroy(t); |
|
| 4194 |
- |
|
| 4195 |
-#ifdef CL_THREAD_SAFE |
|
| 4196 |
- assert(n <= FOLLOWURLS); |
|
| 4197 |
- cli_dbgmsg("checkURLs: waiting for %d thread(s) to finish\n", n);
|
|
| 4198 |
- while(--n >= 0) {
|
|
| 4199 |
- pthread_join(tid[n], NULL); |
|
| 4200 |
- free(args[n].filename); |
|
| 4201 |
- free(args[n].url); |
|
| 4202 |
- } |
|
| 4203 |
-#endif |
|
| 4204 |
-} |
|
| 4205 |
- |
|
| 4206 |
-#else /*!FOLLOWURLS*/ |
|
| 4207 |
- |
|
| 4208 |
-static void |
|
| 4209 |
-do_checkURLs(mbox_ctx *mctx, tag_arguments_t *hrefs) |
|
| 4210 |
-{
|
|
| 4211 |
-} |
|
| 4212 |
- |
|
| 4213 |
-#endif |
|
| 4214 |
- |
|
| 4215 |
-#if defined(FOLLOWURLS) && (FOLLOWURLS > 0) |
|
| 4216 |
-/* |
|
| 4217 |
- * FIXME: Often WMF exploits work by sending people an email directing them |
|
| 4218 |
- * to a page which displays a picture containing the exploit. This is not |
|
| 4219 |
- * currently found, since only the HTML on the referred page is downloaded. |
|
| 4220 |
- * It would be useful to scan the HTML for references to pictures and |
|
| 4221 |
- * download them for scanning. But that will hit performance so there is |
|
| 4222 |
- * an issue here. |
|
| 4223 |
- */ |
|
| 4224 |
- |
|
| 4225 |
-/* |
|
| 4226 |
- * Simple implementation of a subset of RFC1945 (HTTP/1.0) |
|
| 4227 |
- * TODO: HTTP/1.1 (RFC2068) |
|
| 4228 |
- */ |
|
| 4229 |
-static void * |
|
| 4230 |
-#ifdef CL_THREAD_SAFE |
|
| 4231 |
-getURL(void *a) |
|
| 4232 |
-#else |
|
| 4233 |
-getURL(struct arg *arg) |
|
| 4234 |
-#endif |
|
| 4235 |
-{
|
|
| 4236 |
- FILE *fp; |
|
| 4237 |
-#ifdef CL_THREAD_SAFE |
|
| 4238 |
- struct arg *arg = (struct arg *)a; |
|
| 4239 |
-#endif |
|
| 4240 |
- const char *url = arg->url; |
|
| 4241 |
- const char *dir = arg->dir; |
|
| 4242 |
- const char *filename = arg->filename; |
|
| 4243 |
- SOCKET sd; |
|
| 4244 |
- struct sockaddr_in server; |
|
| 4245 |
-#ifdef HAVE_IN_ADDR_T |
|
| 4246 |
- in_addr_t ip; |
|
| 4247 |
-#else |
|
| 4248 |
- unsigned int ip; |
|
| 4249 |
-#endif |
|
| 4250 |
- in_port_t port; |
|
| 4251 |
- static in_port_t default_port; |
|
| 4252 |
- static int tcp; |
|
| 4253 |
- int doingsite, firstpacket; |
|
| 4254 |
- char *ptr; |
|
| 4255 |
- int via_proxy; |
|
| 4256 |
- const char *proxy; |
|
| 4257 |
- char buf[BUFSIZ + 1], site[BUFSIZ], fout[NAME_MAX + 1]; |
|
| 4258 |
- |
|
| 4259 |
- if(strlen(url) > (sizeof(site) - 1)) {
|
|
| 4260 |
- cli_dbgmsg("Ignoring long URL \"%s\"\n", url);
|
|
| 4261 |
- return NULL; |
|
| 4262 |
- } |
|
| 4263 |
- |
|
| 4264 |
- snprintf(fout, sizeof(fout) - 1, "%s/%s", dir, filename); |
|
| 4265 |
- |
|
| 4266 |
- fp = fopen(fout, "wb"); |
|
| 4267 |
- |
|
| 4268 |
- if(fp == NULL) {
|
|
| 4269 |
- cli_errmsg("Can't open '%s' for writing\n", fout);
|
|
| 4270 |
- return NULL; |
|
| 4271 |
- } |
|
| 4272 |
- cli_dbgmsg("Saving %s to %s\n", url, fout);
|
|
| 4273 |
- |
|
| 4274 |
-#ifndef C_BEOS |
|
| 4275 |
- if(tcp == 0) {
|
|
| 4276 |
- const struct protoent *proto = getprotobyname("tcp");
|
|
| 4277 |
- |
|
| 4278 |
- if(proto == NULL) {
|
|
| 4279 |
- cli_warnmsg("Unknown prototol tcp, check /etc/protocols\n");
|
|
| 4280 |
- fclose(fp); |
|
| 4281 |
- return NULL; |
|
| 4282 |
- } |
|
| 4283 |
- tcp = proto->p_proto; |
|
| 4284 |
-#ifndef C_WINDOWS |
|
| 4285 |
- endprotoent(); |
|
| 4286 |
-#endif |
|
| 4287 |
- } |
|
| 4288 |
-#endif |
|
| 4289 |
- if(default_port == 0) {
|
|
| 4290 |
- const struct servent *servent = getservbyname("http", "tcp");
|
|
| 4291 |
- |
|
| 4292 |
- if(servent) |
|
| 4293 |
- default_port = (in_port_t)ntohs(servent->s_port); |
|
| 4294 |
- else |
|
| 4295 |
- default_port = 80; |
|
| 4296 |
-#if !defined(C_WINDOWS) && !defined(C_BEOS) |
|
| 4297 |
- endservent(); |
|
| 4298 |
-#endif |
|
| 4299 |
- } |
|
| 4300 |
- port = default_port; |
|
| 4301 |
- |
|
| 4302 |
- doingsite = 1; |
|
| 4303 |
- ptr = site; |
|
| 4304 |
- |
|
| 4305 |
- proxy = getenv("http_proxy"); /* FIXME: handle no_proxy */
|
|
| 4306 |
- |
|
| 4307 |
- via_proxy = (proxy && *proxy); |
|
| 4308 |
- |
|
| 4309 |
- if(via_proxy) {
|
|
| 4310 |
- if(strncasecmp(proxy, "http://", 7) != 0) {
|
|
| 4311 |
- cli_warnmsg("Unsupported proxy protocol (proxy = %s)\n",
|
|
| 4312 |
- proxy); |
|
| 4313 |
- fclose(fp); |
|
| 4314 |
- return NULL; |
|
| 4315 |
- } |
|
| 4316 |
- |
|
| 4317 |
- cli_dbgmsg("Getting %s via %s\n", url, proxy);
|
|
| 4318 |
- |
|
| 4319 |
- proxy += 7; |
|
| 4320 |
- while(*proxy) {
|
|
| 4321 |
- if(doingsite && (*proxy == ':')) {
|
|
| 4322 |
- port = 0; |
|
| 4323 |
- while(isdigit(*++proxy)) {
|
|
| 4324 |
- port *= 10; |
|
| 4325 |
- port += *proxy - '0'; |
|
| 4326 |
- } |
|
| 4327 |
- continue; |
|
| 4328 |
- } |
|
| 4329 |
- if(doingsite && (*proxy == '/')) {
|
|
| 4330 |
- proxy++; |
|
| 4331 |
- break; |
|
| 4332 |
- } |
|
| 4333 |
- *ptr++ = *proxy++; |
|
| 4334 |
- } |
|
| 4335 |
- } else {
|
|
| 4336 |
- cli_dbgmsg("Getting %s\n", url);
|
|
| 4337 |
- |
|
| 4338 |
- if(strncasecmp(url, "http://", 7) != 0) {
|
|
| 4339 |
- cli_dbgmsg("Unsupported protocol\n");
|
|
| 4340 |
- fclose(fp); |
|
| 4341 |
- return NULL; |
|
| 4342 |
- } |
|
| 4343 |
- |
|
| 4344 |
- url += 7; |
|
| 4345 |
- while(*url) {
|
|
| 4346 |
- if(doingsite && (*url == ':')) {
|
|
| 4347 |
- port = 0; |
|
| 4348 |
- while(isdigit(*++url)) {
|
|
| 4349 |
- port *= 10; |
|
| 4350 |
- port += *url - '0'; |
|
| 4351 |
- } |
|
| 4352 |
- continue; |
|
| 4353 |
- } |
|
| 4354 |
- if(doingsite && (*url == '/')) {
|
|
| 4355 |
- url++; |
|
| 4356 |
- break; |
|
| 4357 |
- } |
|
| 4358 |
- *ptr++ = *url++; |
|
| 4359 |
- } |
|
| 4360 |
- } |
|
| 4361 |
- *ptr = '\0'; |
|
| 4362 |
- |
|
| 4363 |
- memset((char *)&server, '\0', sizeof(struct sockaddr_in)); |
|
| 4364 |
- server.sin_family = AF_INET; |
|
| 4365 |
- server.sin_port = (in_port_t)htons(port); |
|
| 4366 |
- |
|
| 4367 |
- ip = inet_addr(site); |
|
| 4368 |
-#ifdef INADDR_NONE |
|
| 4369 |
- if(ip == INADDR_NONE) {
|
|
| 4370 |
-#else |
|
| 4371 |
- if(ip == (in_addr_t)-1) {
|
|
| 4372 |
-#endif |
|
| 4373 |
- struct hostent h; |
|
| 4374 |
- |
|
| 4375 |
- if((my_r_gethostbyname(site, &h, buf, sizeof(buf)) != 0) || |
|
| 4376 |
- (h.h_addr_list == NULL) || |
|
| 4377 |
- (h.h_addr == NULL)) {
|
|
| 4378 |
- cli_dbgmsg("Unknown host %s\n", site);
|
|
| 4379 |
- fclose(fp); |
|
| 4380 |
- return NULL; |
|
| 4381 |
- } |
|
| 4382 |
- |
|
| 4383 |
- memcpy((char *)&ip, h.h_addr, sizeof(ip)); |
|
| 4384 |
- } |
|
| 4385 |
- if((sd = socket(AF_INET, SOCK_STREAM, tcp)) < 0) {
|
|
| 4386 |
- fclose(fp); |
|
| 4387 |
- return NULL; |
|
| 4388 |
- } |
|
| 4389 |
- server.sin_addr.s_addr = ip; |
|
| 4390 |
- if(nonblock_connect(sd, &server, url) < 0) {
|
|
| 4391 |
- closesocket(sd); |
|
| 4392 |
- fclose(fp); |
|
| 4393 |
- return NULL; |
|
| 4394 |
- } |
|
| 4395 |
- |
|
| 4396 |
- /* |
|
| 4397 |
- * TODO: consider HTTP/1.1 |
|
| 4398 |
- */ |
|
| 4399 |
- if(via_proxy) |
|
| 4400 |
- snprintf(buf, sizeof(buf) - 1, |
|
| 4401 |
- "GET %s HTTP/1.0\r\nHost: %s\r\nUser-Agent: ClamAV %s\r\n\r\n", |
|
| 4402 |
- url, site, cl_retver()); |
|
| 4403 |
- else |
|
| 4404 |
- snprintf(buf, sizeof(buf) - 1, |
|
| 4405 |
- "GET /%s HTTP/1.0\r\nHost: %s\r\nUser-Agent: ClamAV %s\r\n\r\n", |
|
| 4406 |
- url, site, cl_retver()); |
|
| 4407 |
- |
|
| 4408 |
- /*cli_dbgmsg("%s", buf);*/
|
|
| 4409 |
- |
|
| 4410 |
- if(send(sd, buf, (int)strlen(buf), 0) < 0) {
|
|
| 4411 |
- closesocket(sd); |
|
| 4412 |
- fclose(fp); |
|
| 4413 |
- return NULL; |
|
| 4414 |
- } |
|
| 4415 |
- |
|
| 4416 |
-#ifdef SHUT_WR |
|
| 4417 |
- shutdown(sd, SHUT_WR); |
|
| 4418 |
-#else |
|
| 4419 |
- shutdown(sd, 1); |
|
| 4420 |
-#endif |
|
| 4421 |
- |
|
| 4422 |
- firstpacket = 1; |
|
| 4423 |
- |
|
| 4424 |
- for(;;) {
|
|
| 4425 |
- fd_set set; |
|
| 4426 |
- struct timeval tv; |
|
| 4427 |
- int n; |
|
| 4428 |
- |
|
| 4429 |
- FD_ZERO(&set); |
|
| 4430 |
- FD_SET(sd, &set); |
|
| 4431 |
- |
|
| 4432 |
- tv.tv_sec = 30; /* FIXME: make this customisable */ |
|
| 4433 |
- tv.tv_usec = 0; |
|
| 4434 |
- |
|
| 4435 |
- if(select((int)sd + 1, &set, NULL, NULL, &tv) < 0) {
|
|
| 4436 |
- if(errno == EINTR) |
|
| 4437 |
- continue; |
|
| 4438 |
- closesocket(sd); |
|
| 4439 |
- fclose(fp); |
|
| 4440 |
- return NULL; |
|
| 4441 |
- } |
|
| 4442 |
- if(!FD_ISSET(sd, &set)) {
|
|
| 4443 |
- fclose(fp); |
|
| 4444 |
- closesocket(sd); |
|
| 4445 |
- return NULL; |
|
| 4446 |
- } |
|
| 4447 |
- n = recv(sd, buf, sizeof(buf) - 1, 0); |
|
| 4448 |
- |
|
| 4449 |
- if(n < 0) {
|
|
| 4450 |
- fclose(fp); |
|
| 4451 |
- closesocket(sd); |
|
| 4452 |
- return NULL; |
|
| 4453 |
- } |
|
| 4454 |
- if(n == 0) |
|
| 4455 |
- break; |
|
| 4456 |
- |
|
| 4457 |
- /* |
|
| 4458 |
- * FIXME: Handle header in more than one packet |
|
| 4459 |
- */ |
|
| 4460 |
- if(firstpacket) {
|
|
| 4461 |
- char *statusptr; |
|
| 4462 |
- |
|
| 4463 |
- buf[n] = '\0'; |
|
| 4464 |
- |
|
| 4465 |
- statusptr = cli_strtok(buf, 1, " "); |
|
| 4466 |
- |
|
| 4467 |
- if(statusptr) {
|
|
| 4468 |
- int status = atoi(statusptr); |
|
| 4469 |
- |
|
| 4470 |
- cli_dbgmsg("HTTP status %d\n", status);
|
|
| 4471 |
- |
|
| 4472 |
- free(statusptr); |
|
| 4473 |
- |
|
| 4474 |
- if((status == 301) || (status == 302)) {
|
|
| 4475 |
- char *location; |
|
| 4476 |
- |
|
| 4477 |
- location = strstr(buf, "\nLocation: "); |
|
| 4478 |
- |
|
| 4479 |
- if(location) {
|
|
| 4480 |
- char *end; |
|
| 4481 |
- |
|
| 4482 |
- if (cli_unlink(fout)) return NULL; |
|
| 4483 |
- location += 11; |
|
| 4484 |
- end = location; |
|
| 4485 |
- while(*end && (*end != '\n')) |
|
| 4486 |
- end++; |
|
| 4487 |
- *end = '\0'; |
|
| 4488 |
- if(arg->depth >= FOLLOWURLS) {
|
|
| 4489 |
- cli_dbgmsg("URL %s will not be followed to %s (FOLLOWURLS limit %d was reached)\n",
|
|
| 4490 |
- arg->url, location, FOLLOWURLS); |
|
| 4491 |
- break; |
|
| 4492 |
- } |
|
| 4493 |
- if(strcmp(location, arg->url) == 0) {
|
|
| 4494 |
- cli_dbgmsg("URL %s redirects to itself\n",
|
|
| 4495 |
- location); |
|
| 4496 |
- break; |
|
| 4497 |
- } |
|
| 4498 |
- |
|
| 4499 |
- fclose(fp); |
|
| 4500 |
- closesocket(sd); |
|
| 4501 |
- |
|
| 4502 |
- if(strlen(arg->url) < strlen(location)) {
|
|
| 4503 |
- free(arg->url); |
|
| 4504 |
- arg->url = cli_strdup(location); |
|
| 4505 |
- } else |
|
| 4506 |
- strcpy(arg->url, location); |
|
| 4507 |
- arg->depth++; |
|
| 4508 |
- cli_dbgmsg("Redirecting to %s\n", location);
|
|
| 4509 |
- return getURL(arg); |
|
| 4510 |
- } |
|
| 4511 |
- } |
|
| 4512 |
- } |
|
| 4513 |
- /* |
|
| 4514 |
- * Don't write the HTTP header |
|
| 4515 |
- */ |
|
| 4516 |
- if((ptr = strstr(buf, "\r\n\r\n")) != NULL) {
|
|
| 4517 |
- ptr += 4; |
|
| 4518 |
- n -= (int)(ptr - buf); |
|
| 4519 |
- } else if((ptr = strstr(buf, "\n\n")) != NULL) {
|
|
| 4520 |
- ptr += 2; |
|
| 4521 |
- n -= (int)(ptr - buf); |
|
| 4522 |
- } else |
|
| 4523 |
- ptr = buf; |
|
| 4524 |
- |
|
| 4525 |
- firstpacket = 0; |
|
| 4526 |
- } else |
|
| 4527 |
- ptr = buf; |
|
| 4528 |
- |
|
| 4529 |
- if(n && (fwrite(ptr, n, 1, fp) != 1)) {
|
|
| 4530 |
- cli_warnmsg("Error writing %d bytes to %s\n",
|
|
| 4531 |
- n, fout); |
|
| 4532 |
- break; |
|
| 4533 |
- } |
|
| 4534 |
- } |
|
| 4535 |
- |
|
| 4536 |
- fclose(fp); |
|
| 4537 |
- closesocket(sd); |
|
| 4538 |
- return NULL; |
|
| 4539 |
-} |
|
| 4540 |
- |
|
| 4541 |
-/* |
|
| 4542 |
- * Have a copy here because r_gethostbyname is in shared not libclamav :-( |
|
| 4543 |
- */ |
|
| 4544 |
-static int |
|
| 4545 |
-my_r_gethostbyname(const char *hostname, struct hostent *hp, char *buf, size_t len) |
|
| 4546 |
-{
|
|
| 4547 |
- struct hostent *hp2; |
|
| 4548 |
- int ret = -1; |
|
| 4549 |
-#if !defined(HAVE_GETHOSTBYNAME_R_6) && !defined(HAVE_GETHOSTBYNAME_R_5) && !defined(HAVE_GETHOSTBYNAME_R_3) |
|
| 4550 |
-#ifdef CL_THREAD_SAFE |
|
| 4551 |
- static pthread_mutex_t hostent_mutex = PTHREAD_MUTEX_INITIALIZER; |
|
| 4552 |
-#endif |
|
| 4553 |
-#endif |
|
| 4554 |
- |
|
| 4555 |
- if((hostname == NULL) || (hp == NULL)) |
|
| 4556 |
- return -1; |
|
| 4557 |
- memset(hp, 0, sizeof(struct hostent)); |
|
| 4558 |
-#if defined(HAVE_GETHOSTBYNAME_R_6) |
|
| 4559 |
- /* e.g. Linux */ |
|
| 4560 |
- |
|
| 4561 |
- if(gethostbyname_r(hostname, hp, buf, len, &hp2, &ret) < 0) |
|
| 4562 |
- return ret; |
|
| 4563 |
-#elif defined(HAVE_GETHOSTBYNAME_R_5) |
|
| 4564 |
- /* e.g. BSD, Solaris, Cygwin */ |
|
| 4565 |
- /* |
|
| 4566 |
- * Configure doesn't work on BeOS. We need -lnet to link, but configure |
|
| 4567 |
- * doesn't add it, so you need to do something like |
|
| 4568 |
- * LIBS=-lnet ./configure --enable-cache --disable-clamav |
|
| 4569 |
- */ |
|
| 4570 |
- if(gethostbyname_r(hostname, hp, buf, len, &ret) == NULL) |
|
| 4571 |
- return ret; |
|
| 4572 |
-#elif defined(HAVE_GETHOSTBYNAME_R_3) |
|
| 4573 |
- /* e.g. HP/UX, AIX */ |
|
| 4574 |
- if(gethostbyname_r(hostname, &hp, (struct hostent_data *)buf) < 0) |
|
| 4575 |
- return h_errno; |
|
| 4576 |
-#else |
|
| 4577 |
- /* Single thread the code e.g. VS2005 */ |
|
| 4578 |
-#ifdef CL_THREAD_SAFE |
|
| 4579 |
- pthread_mutex_lock(&hostent_mutex); |
|
| 4580 |
-#endif |
|
| 4581 |
- if((hp2 = gethostbyname(hostname)) == NULL) {
|
|
| 4582 |
-#ifdef CL_THREAD_SAFE |
|
| 4583 |
- pthread_mutex_unlock(&hostent_mutex); |
|
| 4584 |
-#endif |
|
| 4585 |
- return h_errno; |
|
| 4586 |
- } |
|
| 4587 |
- memcpy(hp, hp2, sizeof(struct hostent)); |
|
| 4588 |
-#ifdef CL_THREAD_SAFE |
|
| 4589 |
- pthread_mutex_unlock(&hostent_mutex); |
|
| 4590 |
-#endif |
|
| 4591 |
- |
|
| 4592 |
-#endif |
|
| 4593 |
- return 0; |
|
| 4594 |
-} |
|
| 4595 |
- |
|
| 4596 |
-/* |
|
| 4597 |
- * FIXME: There are lots of copies of this code :-( |
|
| 4598 |
- */ |
|
| 4599 |
-static int |
|
| 4600 |
-nonblock_connect(SOCKET sock, const struct sockaddr_in *sin, const char *hostname) |
|
| 4601 |
-{
|
|
| 4602 |
- int select_failures; /* Max. of unexpected select() failures */ |
|
| 4603 |
- int attempts; |
|
| 4604 |
- struct timeval timeout; /* When we should time out */ |
|
| 4605 |
- int numfd; /* Highest fdset fd plus 1 */ |
|
| 4606 |
- long flags; |
|
| 4607 |
- char err[128]; |
|
| 4608 |
- |
|
| 4609 |
- gettimeofday(&timeout, 0); /* store when we started to connect */ |
|
| 4610 |
- |
|
| 4611 |
- if(hostname == NULL) |
|
| 4612 |
- hostname = "remote"; /* It's only used in debug messages */ |
|
| 4613 |
- |
|
| 4614 |
-#ifdef F_GETFL |
|
| 4615 |
- flags = fcntl(sock, F_GETFL, 0); |
|
| 4616 |
- |
|
| 4617 |
- if(flags == -1L) |
|
| 4618 |
- cli_dbgmsg("getfl: %s\n", cli_strerror(errno, err, sizeof(err)));
|
|
| 4619 |
- else if(fcntl(sock, F_SETFL, (long)(flags | O_NONBLOCK)) < 0) |
|
| 4620 |
- cli_dbgmsg("setfl: %s\n", cli_strerror(errno, err, sizeof(err)));
|
|
| 4621 |
-#else |
|
| 4622 |
- flags = -1L; |
|
| 4623 |
-#endif |
|
| 4624 |
- if(connect(sock, (const struct sockaddr *)sin, sizeof(struct sockaddr_in)) != 0) |
|
| 4625 |
- switch(errno) {
|
|
| 4626 |
- case EALREADY: |
|
| 4627 |
- case EINPROGRESS: |
|
| 4628 |
- cli_dbgmsg("%s: connect: %s\n", hostname,
|
|
| 4629 |
- cli_strerror(errno, err, sizeof(err))); |
|
| 4630 |
- break; /* wait for connection */ |
|
| 4631 |
- case EISCONN: |
|
| 4632 |
- return 0; /* connected */ |
|
| 4633 |
- default: |
|
| 4634 |
- cli_dbgmsg("%s: connect: %s\n",
|
|
| 4635 |
- hostname, cli_strerror(errno, err, sizeof(err))); |
|
| 4636 |
-#ifdef F_SETFL |
|
| 4637 |
- if(flags != -1L) |
|
| 4638 |
- if(fcntl(sock, F_SETFL, flags)) |
|
| 4639 |
- cli_dbgmsg("f_setfl: %s\n", cli_strerror(errno, err, sizeof(err)));
|
|
| 4640 |
-#endif |
|
| 4641 |
- return -1; /* failed */ |
|
| 4642 |
- } |
|
| 4643 |
- else {
|
|
| 4644 |
-#ifdef F_SETFL |
|
| 4645 |
- if(flags != -1L) |
|
| 4646 |
- if(fcntl(sock, F_SETFL, flags)) |
|
| 4647 |
- cli_dbgmsg("f_setfl: %s\n", cli_strerror(errno, err, sizeof(err)));
|
|
| 4648 |
-#endif |
|
| 4649 |
- return connect_error(sock, hostname); |
|
| 4650 |
- } |
|
| 4651 |
- |
|
| 4652 |
- numfd = (int)sock + 1; |
|
| 4653 |
- select_failures = NONBLOCK_SELECT_MAX_FAILURES; |
|
| 4654 |
- attempts = 1; |
|
| 4655 |
- timeout.tv_sec += CONNECT_TIMEOUT; |
|
| 4656 |
- |
|
| 4657 |
- for (;;) {
|
|
| 4658 |
- int n, t; |
|
| 4659 |
- fd_set fds; |
|
| 4660 |
- struct timeval now, waittime; |
|
| 4661 |
- |
|
| 4662 |
- /* Force timeout if we ran out of time */ |
|
| 4663 |
- gettimeofday(&now, 0); |
|
| 4664 |
- t = (now.tv_sec == timeout.tv_sec) ? |
|
| 4665 |
- (now.tv_usec > timeout.tv_usec) : |
|
| 4666 |
- (now.tv_sec > timeout.tv_sec); |
|
| 4667 |
- |
|
| 4668 |
- if(t) {
|
|
| 4669 |
- cli_dbgmsg("%s: connect timeout (%d secs)\n",
|
|
| 4670 |
- hostname, CONNECT_TIMEOUT); |
|
| 4671 |
- break; |
|
| 4672 |
- } |
|
| 4673 |
- |
|
| 4674 |
- /* Calculate how long to wait */ |
|
| 4675 |
- waittime.tv_sec = timeout.tv_sec - now.tv_sec; |
|
| 4676 |
- waittime.tv_usec = timeout.tv_usec - now.tv_usec; |
|
| 4677 |
- if(waittime.tv_usec < 0) {
|
|
| 4678 |
- waittime.tv_sec--; |
|
| 4679 |
- waittime.tv_usec += 1000000; |
|
| 4680 |
- } |
|
| 4681 |
- |
|
| 4682 |
- /* Init fds with 'sock' as the only fd */ |
|
| 4683 |
- FD_ZERO(&fds); |
|
| 4684 |
- FD_SET(sock, &fds); |
|
| 4685 |
- |
|
| 4686 |
- n = select(numfd, 0, &fds, 0, &waittime); |
|
| 4687 |
- if(n < 0) {
|
|
| 4688 |
- cli_dbgmsg("%s: select attempt %d %s\n",
|
|
| 4689 |
- hostname, select_failures, cli_strerror(errno, err, sizeof(err))); |
|
| 4690 |
- if(--select_failures >= 0) |
|
| 4691 |
- continue; /* not timed-out, try again */ |
|
| 4692 |
- break; /* failed */ |
|
| 4693 |
- } |
|
| 4694 |
- |
|
| 4695 |
- cli_dbgmsg("%s: select = %d\n", hostname, n);
|
|
| 4696 |
- |
|
| 4697 |
- if(n) {
|
|
| 4698 |
-#ifdef F_SETFL |
|
| 4699 |
- if(flags != -1L) |
|
| 4700 |
- if(fcntl(sock, F_SETFL, flags)) |
|
| 4701 |
- cli_dbgmsg("f_setfl: %s\n", cli_strerror(errno, err, sizeof(err)));
|
|
| 4702 |
-#endif |
|
| 4703 |
- return connect_error(sock, hostname); |
|
| 4704 |
- } |
|
| 4705 |
- |
|
| 4706 |
- /* timeout */ |
|
| 4707 |
- if(attempts++ == NONBLOCK_MAX_ATTEMPTS) {
|
|
| 4708 |
- cli_dbgmsg("timeout connecting to %s\n", hostname);
|
|
| 4709 |
- break; |
|
| 4710 |
- } |
|
| 4711 |
- } |
|
| 4712 |
- |
|
| 4713 |
-#ifdef F_SETFL |
|
| 4714 |
- if(flags != -1L) |
|
| 4715 |
- if(fcntl(sock, F_SETFL, flags)) |
|
| 4716 |
- cli_dbgmsg("f_setfl: %s\n", cli_strerror(errno, err, sizeof(err)));
|
|
| 4717 |
-#endif |
|
| 4718 |
- return -1; /* failed */ |
|
| 4719 |
-} |
|
| 4720 |
- |
|
| 4721 |
-static int |
|
| 4722 |
-connect_error(SOCKET sock, const char *hostname) |
|
| 4723 |
-{
|
|
| 4724 |
- char err[128]; |
|
| 4725 |
-#ifdef SO_ERROR |
|
| 4726 |
- int optval; |
|
| 4727 |
- socklen_t optlen = sizeof(optval); |
|
| 4728 |
- |
|
| 4729 |
- getsockopt(sock, SOL_SOCKET, SO_ERROR, &optval, &optlen); |
|
| 4730 |
- |
|
| 4731 |
- if(optval) {
|
|
| 4732 |
- cli_dbgmsg("%s: %s\n", hostname, cli_strerror(optval, err, sizeof(err)));
|
|
| 4733 |
- return -1; |
|
| 4734 |
- } |
|
| 4735 |
-#endif |
|
| 4736 |
- |
|
| 4737 |
- return 0; |
|
| 4738 |
-} |
|
| 4739 |
- |
|
| 4740 |
-#endif |
|
| 4741 |
- |
|
| 4742 | 4089 |
#ifdef HAVE_BACKTRACE |
| 4743 | 4090 |
static void |
| 4744 | 4091 |
sigsegv(int sig) |
| ... | ... |
@@ -5096,9 +4408,7 @@ do_multipart(message *mainMessage, message **messages, int i, mbox_status *rc, m |
| 5096 | 5096 |
cli_dbgmsg("Treating inline as attachment\n");
|
| 5097 | 5097 |
} else {
|
| 5098 | 5098 |
const int is_html = (tableFind(mctx->subtypeTable, cptr) == HTML); |
| 5099 |
- if((mctx->ctx->options&CL_SCAN_MAILURL) && is_html) |
|
| 5100 |
- checkURLs(aMessage, mctx, rc, 1); |
|
| 5101 |
- else if(doPhishingScan) |
|
| 5099 |
+ if(doPhishingScan) |
|
| 5102 | 5100 |
checkURLs(aMessage, mctx, rc, is_html); |
| 5103 | 5101 |
messageAddArgument(aMessage, |
| 5104 | 5102 |
"filename=mixedtextportion"); |
| ... | ... |
@@ -74,9 +74,6 @@ static const char *pdf_nextlinestart(const char *ptr, size_t len); |
| 74 | 74 |
static const char *pdf_nextobject(const char *ptr, size_t len); |
| 75 | 75 |
static const char *cli_pmemstr(const char *haystack, size_t hs, const char *needle, size_t ns); |
| 76 | 76 |
|
| 77 |
-/* |
|
| 78 |
- * TODO: handle embedded URLs if (options&CL_SCAN_MAILURL) |
|
| 79 |
- */ |
|
| 80 | 77 |
int |
| 81 | 78 |
cli_pdf(const char *dir, int desc, cli_ctx *ctx, off_t offset) |
| 82 | 79 |
{
|
| ... | ... |
@@ -247,8 +247,6 @@ const struct clam_option clam_options[] = {
|
| 247 | 247 |
|
| 248 | 248 |
{ "ScanMail", "scan-mail", 0, TYPE_BOOL, MATCH_BOOL, 1, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "Enable the built in email scanner.", "yes" },
|
| 249 | 249 |
|
| 250 |
- { "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" },
|
|
| 251 |
- |
|
| 252 | 250 |
{ "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" },
|
| 253 | 251 |
|
| 254 | 252 |
{ "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[] = {
|
| 367 | 367 |
{ "ArchiveMaxCompressionRatio", NULL, 0, TYPE_NUMBER, NULL, -1, NULL, 0, OPT_CLAMD | OPT_DEPRECATED, "", "" },
|
| 368 | 368 |
{ "ArchiveBlockMax", NULL, 0, TYPE_BOOL, MATCH_BOOL, -1, NULL, 0, OPT_CLAMD | OPT_DEPRECATED, "", "" },
|
| 369 | 369 |
{ "ArchiveLimitMemoryUsage", NULL, 0, TYPE_BOOL, MATCH_BOOL, -1, NULL, 0, OPT_CLAMD | OPT_DEPRECATED, "", "" },
|
| 370 |
+ { "MailFollowURLs", "mail-follow-urls", 0, TYPE_BOOL, MATCH_BOOL, -1, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN | OPT_DEPRECATED, "", "" },
|
|
| 370 | 371 |
|
| 371 | 372 |
/* Milter specific options */ |
| 372 | 373 |
|