... | ... |
@@ -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 |
|