git-svn-id: file:///var/lib/svn/clamav-devel/branches/0.88-stable@2795 77e5149b-7576-45b1-b177-96237e5ba77b
Sven Strickroth authored on 2007/02/18 23:41:27... | ... |
@@ -1,3 +1,30 @@ |
1 |
+Tue Apr 4 12:04:07 CEST 2006 |
|
2 |
+----------------------------- |
|
3 |
+ V 0.88.1 |
|
4 |
+ * Bugfixes: |
|
5 |
+ - libclamav/matcher.c: properly handle partial reads in cli_scandesc() |
|
6 |
+ - libclamav/mbox.c: sync with CVS, fixes detection of Worm.Bagle.CT |
|
7 |
+ - freshclam: fix support for LocalIPAddress |
|
8 |
+ Patch by Anton Yuzhaninov <citrin*citrin.ru> |
|
9 |
+ - docs/man: multiple manpage typo fixes |
|
10 |
+ Patch by A. Costa <agcosta*gis.net>) |
|
11 |
+ - shared/output.c: properly handle return value of vsnprintf |
|
12 |
+ Thanks to Anton Yuzhaninov <citrin*rambler-co.ru> |
|
13 |
+ - libclamav/htmlnorm.c: fix typo spotted by Gianluigi Tiesi |
|
14 |
+ <sherpya*netfarm.it> |
|
15 |
+ - sigtool/sigtool.c: fix possible crash in build(), thanks to Sven |
|
16 |
+ - clamd/session.c: remove static timeout (5s) for SESSION |
|
17 |
+ Pointed out by Joseph Benden <joe*thrallingpenguin.com> |
|
18 |
+ - libclamav/pe.c: fix possible integer overflow reported by Damian Put |
|
19 |
+ Note: only exploitable if file size limit (ArchiveMaxFileSize) disabled |
|
20 |
+ - libclamav/scanners.c: properly report archive unpacking errors |
|
21 |
+ Problem spotted by David F. Skoll <dfs*roaringpenguin.com> |
|
22 |
+ - libclamav/others.c: fix possible crash in cli_bitset_test() |
|
23 |
+ Reported by David Luyer <david_luyer*pacific.net.au> |
|
24 |
+ - libclamav/zziplib: fix possible crash on FreeBSD |
|
25 |
+ Reported by Robert Rebbun <robert*desertsurf.com> |
|
26 |
+ - clamav-milter: fall back if sendfile() fails |
|
27 |
+ |
|
1 | 28 |
Mon Jan 9 18:26:21 CET 2006 |
2 | 29 |
---------------------------- |
3 | 30 |
V 0.88 |
... | ... |
@@ -1,9 +1,8 @@ |
1 |
-0.88 |
|
1 |
+0.88.1 |
|
2 |
+------ |
|
2 | 3 |
|
3 |
-A possible heap overflow in the UPX code has been fixed. General improvements |
|
4 |
-include better zip and mail processing, and support for a self-protection mode. |
|
5 |
-The security of the UPX, FSG and Petite modules has been improved, too. |
|
4 |
+This version fixes a number of minor bugs and provides code updates |
|
5 |
+to improve virus detection. |
|
6 | 6 |
|
7 | 7 |
-- |
8 | 8 |
The ClamAV team (http://www.clamav.net/team.html) |
... | ... |
@@ -2,6 +2,16 @@ Note: This README/NEWS file refers to the source tarball. Some things described |
2 | 2 |
here may not be available in binary packages. |
3 | 3 |
-- |
4 | 4 |
|
5 |
+0.88.1 |
|
6 |
+------ |
|
7 |
+ |
|
8 |
+This version fixes a number of minor bugs and provides code updates |
|
9 |
+to improve virus detection. |
|
10 |
+ |
|
11 |
+-- |
|
12 |
+The ClamAV team (http://www.clamav.net/team.html) |
|
13 |
+ |
|
14 |
+ |
|
5 | 15 |
0.88 |
6 | 16 |
---- |
7 | 17 |
|
... | ... |
@@ -198,6 +198,9 @@ |
198 | 198 |
/* Define to 1 if you have the `snprintf' function. */ |
199 | 199 |
#undef HAVE_SNPRINTF |
200 | 200 |
|
201 |
+/* Define to 1 if you have the 'socklen_t' type. */ |
|
202 |
+#undef HAVE_SOCKLEN_T |
|
203 |
+ |
|
201 | 204 |
/* Define to 1 if you have the <stdint.h> header file. */ |
202 | 205 |
#undef HAVE_STDINT_H |
203 | 206 |
|
... | ... |
@@ -23,12 +23,12 @@ |
23 | 23 |
* For installation instructions see the file INSTALL that came with this file |
24 | 24 |
*/ |
25 | 25 |
|
26 |
-#define CM_VERSION "0.87" |
|
27 |
- |
|
28 | 26 |
#if HAVE_CONFIG_H |
29 | 27 |
#include "clamav-config.h" |
30 | 28 |
#endif |
31 | 29 |
|
30 |
+#define CM_VERSION VERSION |
|
31 |
+ |
|
32 | 32 |
#include "defaults.h" |
33 | 33 |
#include "cfgparser.h" |
34 | 34 |
#include "target.h" |
... | ... |
@@ -4173,8 +4173,9 @@ move(const char *oldfile, const char *newfile) |
4173 | 4173 |
int ret; |
4174 | 4174 |
#ifdef C_LINUX |
4175 | 4175 |
struct stat statb; |
4176 |
- int fin, fout; |
|
4176 |
+ int fin, fout, c; |
|
4177 | 4177 |
off_t offset; |
4178 |
+ FILE *fsin, *fsout; |
|
4178 | 4179 |
#else |
4179 | 4180 |
FILE *fin, *fout; |
4180 | 4181 |
int c; |
... | ... |
@@ -4211,12 +4212,27 @@ move(const char *oldfile, const char *newfile) |
4211 | 4211 |
ret = sendfile(fout, fin, &offset, statb.st_size); |
4212 | 4212 |
close(fin); |
4213 | 4213 |
if(ret < 0) { |
4214 |
+ /* fall back if sendfile fails, which shouldn't happen */ |
|
4214 | 4215 |
perror(newfile); |
4215 | 4216 |
close(fout); |
4216 | 4217 |
unlink(newfile); |
4217 |
- return -1; |
|
4218 |
- } |
|
4219 |
- close(fout); |
|
4218 |
+ |
|
4219 |
+ fsin = fopen(oldfile, "r"); |
|
4220 |
+ if(fsin == NULL) |
|
4221 |
+ return -1; |
|
4222 |
+ |
|
4223 |
+ fsout = fopen(newfile, "w"); |
|
4224 |
+ if(fsout == NULL) { |
|
4225 |
+ fclose(fsin); |
|
4226 |
+ return -1; |
|
4227 |
+ } |
|
4228 |
+ while((c = getc(fsin)) != EOF) |
|
4229 |
+ putc(c, fsout); |
|
4230 |
+ |
|
4231 |
+ fclose(fsin); |
|
4232 |
+ fclose(fsout); |
|
4233 |
+ } else |
|
4234 |
+ close(fout); |
|
4220 | 4235 |
#else |
4221 | 4236 |
fin = fopen(oldfile, "r"); |
4222 | 4237 |
if(fin == NULL) |
... | ... |
@@ -205,19 +205,18 @@ int scan(const char *filename, unsigned long int *scanned, const struct cl_node |
205 | 205 |
const char *virname; |
206 | 206 |
|
207 | 207 |
|
208 |
- /* check permissions */ |
|
209 |
- if(access(filename, R_OK)) { |
|
210 |
- mdprintf(odesc, "%s: Access denied. ERROR\n", filename); |
|
211 |
- return -1; |
|
212 |
- } |
|
213 |
- |
|
214 | 208 |
/* stat file */ |
215 |
- |
|
216 | 209 |
if(lstat(filename, &sb) == -1) { |
217 | 210 |
mdprintf(odesc, "%s: lstat() failed. ERROR\n", filename); |
218 | 211 |
return -1; |
219 | 212 |
} |
220 | 213 |
|
214 |
+ /* check permissions */ |
|
215 |
+ if(access(filename, R_OK)) { |
|
216 |
+ mdprintf(odesc, "%s: Access denied. ERROR\n", filename); |
|
217 |
+ return -1; |
|
218 |
+ } |
|
219 |
+ |
|
221 | 220 |
switch(sb.st_mode & S_IFMT) { |
222 | 221 |
case S_IFLNK: |
223 | 222 |
if(!cfgopt(copt, "FollowFileSymlinks")) |
... | ... |
@@ -192,7 +192,11 @@ int dsstream(int sockd, const struct optstruct *opt) |
192 | 192 |
int wsockd, loopw = 60, bread, port, infected = 0; |
193 | 193 |
struct sockaddr_in server; |
194 | 194 |
struct sockaddr_in peer; |
195 |
+#ifdef HAVE_SOCKLEN_T |
|
195 | 196 |
socklen_t peer_size; |
197 |
+#else |
|
198 |
+ int peer_size; |
|
199 |
+#endif |
|
196 | 200 |
char buff[4096], *pt; |
197 | 201 |
|
198 | 202 |
|
... | ... |
@@ -2073,7 +2073,7 @@ fi |
2073 | 2073 |
|
2074 | 2074 |
# Define the identity of the package. |
2075 | 2075 |
PACKAGE=clamav |
2076 |
- VERSION="0.88" |
|
2076 |
+ VERSION="0.88.1" |
|
2077 | 2077 |
|
2078 | 2078 |
|
2079 | 2079 |
cat >>confdefs.h <<_ACEOF |
... | ... |
@@ -14390,6 +14390,76 @@ cat >>confdefs.h <<_ACEOF |
14390 | 14390 |
_ACEOF |
14391 | 14391 |
|
14392 | 14392 |
|
14393 |
+echo "$as_me:$LINENO: checking for socklen_t" >&5 |
|
14394 |
+echo $ECHO_N "checking for socklen_t... $ECHO_C" >&6 |
|
14395 |
+if test "${have_socklen_t+set}" = set; then |
|
14396 |
+ echo $ECHO_N "(cached) $ECHO_C" >&6 |
|
14397 |
+else |
|
14398 |
+ |
|
14399 |
+ cat >conftest.$ac_ext <<_ACEOF |
|
14400 |
+/* confdefs.h. */ |
|
14401 |
+_ACEOF |
|
14402 |
+cat confdefs.h >>conftest.$ac_ext |
|
14403 |
+cat >>conftest.$ac_ext <<_ACEOF |
|
14404 |
+/* end confdefs.h. */ |
|
14405 |
+ |
|
14406 |
+ #include <sys/types.h> |
|
14407 |
+ #include <sys/socket.h> |
|
14408 |
+ |
|
14409 |
+int |
|
14410 |
+main () |
|
14411 |
+{ |
|
14412 |
+ |
|
14413 |
+ socklen_t len; |
|
14414 |
+ getpeername(0, 0, &len); |
|
14415 |
+ |
|
14416 |
+ ; |
|
14417 |
+ return 0; |
|
14418 |
+} |
|
14419 |
+_ACEOF |
|
14420 |
+rm -f conftest.$ac_objext |
|
14421 |
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 |
|
14422 |
+ (eval $ac_compile) 2>conftest.er1 |
|
14423 |
+ ac_status=$? |
|
14424 |
+ grep -v '^ *+' conftest.er1 >conftest.err |
|
14425 |
+ rm -f conftest.er1 |
|
14426 |
+ cat conftest.err >&5 |
|
14427 |
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 |
|
14428 |
+ (exit $ac_status); } && |
|
14429 |
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' |
|
14430 |
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 |
|
14431 |
+ (eval $ac_try) 2>&5 |
|
14432 |
+ ac_status=$? |
|
14433 |
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 |
|
14434 |
+ (exit $ac_status); }; } && |
|
14435 |
+ { ac_try='test -s conftest.$ac_objext' |
|
14436 |
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 |
|
14437 |
+ (eval $ac_try) 2>&5 |
|
14438 |
+ ac_status=$? |
|
14439 |
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 |
|
14440 |
+ (exit $ac_status); }; }; then |
|
14441 |
+ have_socklen_t=yes |
|
14442 |
+else |
|
14443 |
+ echo "$as_me: failed program was:" >&5 |
|
14444 |
+sed 's/^/| /' conftest.$ac_ext >&5 |
|
14445 |
+ |
|
14446 |
+have_socklen_t=no |
|
14447 |
+fi |
|
14448 |
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext |
|
14449 |
+ |
|
14450 |
+fi |
|
14451 |
+ |
|
14452 |
+echo "$as_me:$LINENO: result: $have_socklen_t" >&5 |
|
14453 |
+echo "${ECHO_T}$have_socklen_t" >&6 |
|
14454 |
+ |
|
14455 |
+if test "$have_socklen_t" = "yes"; then |
|
14456 |
+ |
|
14457 |
+cat >>confdefs.h <<\_ACEOF |
|
14458 |
+#define HAVE_SOCKLEN_T 1 |
|
14459 |
+_ACEOF |
|
14460 |
+ |
|
14461 |
+fi |
|
14462 |
+ |
|
14393 | 14463 |
ac_config_files="$ac_config_files libclamav/Makefile clamscan/Makefile database/Makefile docs/Makefile clamd/Makefile clamdscan/Makefile clamav-milter/Makefile freshclam/Makefile sigtool/Makefile etc/Makefile Makefile clamav-config libclamav.pc docs/man/clamd.8 docs/man/clamd.conf.5 docs/man/freshclam.1 docs/man/freshclam.conf.5" |
14394 | 14464 |
cat >confcache <<\_ACEOF |
14395 | 14465 |
# This file is a shell script that caches the results of configure |
... | ... |
@@ -18,7 +18,7 @@ dnl Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
18 | 18 |
|
19 | 19 |
AC_INIT(clamscan/clamscan.c) |
20 | 20 |
AC_CREATE_TARGET_H(target.h) |
21 |
-AM_INIT_AUTOMAKE(clamav, "0.88") |
|
21 |
+AM_INIT_AUTOMAKE(clamav, "0.88.1") |
|
22 | 22 |
AM_CONFIG_HEADER(clamav-config.h) |
23 | 23 |
|
24 | 24 |
LC_CURRENT=1 |
... | ... |
@@ -977,6 +977,25 @@ DEFAULT_FD_SETSIZE=256) |
977 | 977 |
AC_MSG_RESULT($DEFAULT_FD_SETSIZE) |
978 | 978 |
AC_DEFINE_UNQUOTED(DEFAULT_FD_SETSIZE, $DEFAULT_FD_SETSIZE, "default FD_SETSIZE value") |
979 | 979 |
|
980 |
+dnl check for socklen_t |
|
981 |
+AC_MSG_CHECKING([for socklen_t]) |
|
982 |
+AC_CACHE_VAL(have_socklen_t,[ |
|
983 |
+ AC_TRY_COMPILE([ |
|
984 |
+ #include <sys/types.h> |
|
985 |
+ #include <sys/socket.h> |
|
986 |
+ ],[ |
|
987 |
+ socklen_t len; |
|
988 |
+ getpeername(0, 0, &len); |
|
989 |
+ ], |
|
990 |
+ [have_socklen_t=yes], |
|
991 |
+ [have_socklen_t=no]) |
|
992 |
+ ]) |
|
993 |
+AC_MSG_RESULT($have_socklen_t) |
|
994 |
+ |
|
995 |
+if test "$have_socklen_t" = "yes"; then |
|
996 |
+ AC_DEFINE(HAVE_SOCKLEN_T, 1, [Define to 1 if you have the 'socklen_t' type.]) |
|
997 |
+fi |
|
998 |
+ |
|
980 | 999 |
AC_OUTPUT([ |
981 | 1000 |
libclamav/Makefile |
982 | 1001 |
clamscan/Makefile |
... | ... |
@@ -69,7 +69,7 @@ |
69 | 69 |
\vspace{3cm} |
70 | 70 |
\begin{flushright} |
71 | 71 |
\rule[-1ex]{8cm}{3pt}\\ |
72 |
- \huge Clam AntiVirus 0.88\\ |
|
72 |
+ \huge Clam AntiVirus 0.88.1\\ |
|
73 | 73 |
\huge \emph{User Manual}\\ |
74 | 74 |
\end{flushright} |
75 | 75 |
|
... | ... |
@@ -2012,7 +2012,7 @@ level required:MD5 checksum:digital signature:builder name:build time (sec) |
2012 | 2012 |
\url{clamav.ialfa.net} & 210.22.201.152 & People's Republic & Alfa Shen\\ |
2013 | 2013 |
& & of China & \email{<alfa*ialfa.net>}\\ \hline |
2014 | 2014 |
|
2015 |
- \url{clamavdb.ikk.sztaki.hu} & 193.225.86.3 & Hungary & Gabor Kiss\\ |
|
2015 |
+ \url{clamavdb.ikk.sztaki.hu} & 193.225.12.21 & Hungary & Gabor Kiss\\ |
|
2016 | 2016 |
& & & \email{<kissg*debella.ikk.sztaki.hu>}\\ \hline |
2017 | 2017 |
|
2018 | 2018 |
\url{clamav.mirrors.nks.net} & 24.73.112.74 & Florida, USA & James Neal\\ |
... | ... |
@@ -2142,8 +2142,6 @@ level required:MD5 checksum:digital signature:builder name:build time (sec) |
2142 | 2142 |
& & & \email{<ito*begi.net>}\\ \hline |
2143 | 2143 |
\url{clamav.meiwing.com} & 210.245.226.117 & Hong Kong & Thomas Koo\\ |
2144 | 2144 |
& & & \email{<thomas*meiwing.com>}\\ \hline |
2145 |
- \url{clamav.mtcnet.jp} & 221.246.94.244 & Japan & Masahiro Kawai\\ |
|
2146 |
- & & & \email{<kawai*mtcnet.co.jp>}\\ \hline |
|
2147 | 2145 |
\url{clamav.unix.su} & 62.181.41.8 & Russian Federation & Konstantin A. Mikhailov\\ |
2148 | 2146 |
& & & \email{<kam*unix.su>}\\ \hline |
2149 | 2147 |
\end{tabular}} |
... | ... |
@@ -2169,8 +2167,6 @@ level required:MD5 checksum:digital signature:builder name:build time (sec) |
2169 | 2169 |
& & & \email{<pavalos*theshell.com>}\\ \hline |
2170 | 2170 |
\url{clamav.inode.at} & 81.223.20.171 & Austria & Michael Renner\\ |
2171 | 2171 |
& & & \email{<mirror*inode.at>}\\ \hline |
2172 |
- \url{clamav.informatik.fh-furtwangen.de} & 141.28.73.8 & Germany & Sebastian Siewior\\ |
|
2173 |
- & & & \email{<bigeasy*foo.fh-furtwangen.de>}\\ \hline |
|
2174 | 2172 |
\url{clamav.cpss.edu.hk} & 218.189.210.14 & Hong Kong & Wan Pui Wa\\ |
2175 | 2173 |
& & & \email{<puiwa*cpss.edu.hk>}\\ \hline |
2176 | 2174 |
\url{clamav.irontec.com} & 66.111.55.10 & Tampa, & Iker Sagasti Markina\\ |
... | ... |
@@ -2197,13 +2193,13 @@ level required:MD5 checksum:digital signature:builder name:build time (sec) |
2197 | 2197 |
& & & \email{<master*hanbiro.com>}\\ \hline |
2198 | 2198 |
\url{clamav.vtu.lt} & 193.219.149.170 & Lithuania & Eugenijus J.\\ |
2199 | 2199 |
& & & \email{<ejs*ar.vtu.lt>}\\ \hline |
2200 |
- \url{clamav.ftpproxy.org} & 217.110.63.228 & Germany & Andreas Schoenberg\\ |
|
2200 |
+ \url{clamav.ftpproxy.org} & 195.246.234.199 & Germany & Andreas Schoenberg\\ |
|
2201 | 2201 |
& & & \email{<asg*ftpproxy.org>}\\ \hline |
2202 | 2202 |
\url{clamav.iasi.roedu.net} & 192.129.4.120 & Romania & Subredu Manuel\\ |
2203 | 2203 |
& & & \email{<ftpadmin*iasi.roedu.net>}\\ \hline |
2204 | 2204 |
\url{clamav.infonet.ee} & 212.7.0.71 & Estonia & Konstantin Barinov\\ |
2205 | 2205 |
& & & \email{<sbr*infonet.ee>}\\ \hline |
2206 |
- \url{clamav.savework.de} & 81.169.151.96 & Germany & Kai-H. Weutzing\\ |
|
2206 |
+ \url{clamav.savework.de} & 85.214.44.186 & Germany & Kai-H. Weutzing\\ |
|
2207 | 2207 |
& & & \email{<clamavdb*savework.de>}\\ \hline |
2208 | 2208 |
\end{tabular}} |
2209 | 2209 |
\end{center} |
... | ... |
@@ -2216,8 +2212,6 @@ level required:MD5 checksum:digital signature:builder name:build time (sec) |
2216 | 2216 |
|
2217 | 2217 |
\url{clamav.citrin.ru} & 213.248.60.121 & Russia & Anton Yuzhaninov\\ |
2218 | 2218 |
& & & \email{<citrin*citrin.ru>}\\ \hline |
2219 |
- \url{clamav.keystreams.com} & 207.158.28.8 & USA & Roman Volf\\ |
|
2220 |
- & & & \email{<volfman*keystreams.com>}\\ \hline |
|
2221 | 2219 |
\url{clamav.paralax.org} & 83.148.101.196 & Bulgaria & Svetoslav Vesselkoff\\ |
2222 | 2220 |
& & & \email{<soho*paralax.org>}\\ \hline |
2223 | 2221 |
\url{clamav.linux.pt} & 194.65.79.153 & Portugal & Jose Celestino\\ |
... | ... |
@@ -2262,6 +2256,16 @@ level required:MD5 checksum:digital signature:builder name:build time (sec) |
2262 | 2262 |
& & & \email{<fabian*lug-norderstedt.de>}\\ \hline |
2263 | 2263 |
\url{clamav.df.lth.se} & 194.47.250.218 & Sweden & Rune Anderson\\ |
2264 | 2264 |
& & & \email{<rpa*df.lth.se>}\\ \hline |
2265 |
+ \url{clamav.gueth.net} & 217.160.141.39 & Germany & Volker Gueth\\ |
|
2266 |
+ & & & \email{<volker*gueth.net>}\\ \hline |
|
2267 |
+ \url{b.clamav.mirror.fizzelpark.com} & 217.115.136.170 & Germany & Thilo Bangert\\ |
|
2268 |
+ & & & \email{<bangert*fizzelpark.com>}\\ \hline |
|
2269 |
+ \url{clamav.dg.net.ua} & 213.186.196.225 & Ukraine & Oleksandr V. Typlynskyi\\ |
|
2270 |
+ & & & \email{<clamavdb*dg.net.ua>}\\ \hline |
|
2271 |
+ \url{clamav.i24horas.com.br} & 200.242.49.19 & Brazil & Renato Lins\\ |
|
2272 |
+ & & & \email{<renato-clamav*autoservico.com>}\\ \hline |
|
2273 |
+ \url{clamav.gva.es} & 82.159.137.16 & Spain & Jose Antonio Amador\\ |
|
2274 |
+ & & & \email{<jamador*gva.es>}\\ \hline |
|
2265 | 2275 |
\end{tabular}} |
2266 | 2276 |
\end{center} |
2267 | 2277 |
|
... | ... |
@@ -2269,23 +2273,27 @@ level required:MD5 checksum:digital signature:builder name:build time (sec) |
2269 | 2269 |
The following people contributed to our project in some way (providing |
2270 | 2270 |
patches, bug reports, technical support, documentation, good ideas...): |
2271 | 2271 |
\begin{itemize} |
2272 |
+ \item Clint Adams \email{<schizo*debian.org>} |
|
2272 | 2273 |
\item Sergey Y. Afonin \email{<asy*kraft-s.ru>} |
2273 | 2274 |
\item Robert Allerstorfer \email{<roal*anet.at>} |
2274 | 2275 |
\item Claudio Alonso \email{<cfalonso*yahoo.com>} |
2275 | 2276 |
\item Kevin Amorin \email{<kamorin*ccs.neu.edu>} |
2276 | 2277 |
\item Kamil Andrusz \email{<wizz*mniam.net>} |
2278 |
+ \item Tayfun Asker \email{<tasker*metu.edu.tr>} |
|
2277 | 2279 |
\item Jean-Edouard Babin \email{<Jeb*jeb.com.fr>} |
2278 | 2280 |
\item Marc Baudoin \email{<babafou*babafou.eu.org>} |
2279 | 2281 |
\item Scott Beck \email{<sbeck*gossamer-threads.com>} |
2280 | 2282 |
\item Rolf Eike Beer \email{<eike*mail.math.uni-mannheim.de>} |
2281 | 2283 |
\item Rene Bellora \email{<rbellora*tecnoaccion.com.ar>} |
2282 | 2284 |
\item Carlo Marcelo Arenas Belon \email{<carenas*sajinet.com.pe>} |
2285 |
+ \item Joseph Benden \email{<joe*thrallingpenguin.com>} |
|
2283 | 2286 |
\item Hilko Bengen \email{<bengen*vdst-ka.inka.de>} |
2284 | 2287 |
\item Hank Beatty \email{<hbeatty*starband.net>} |
2285 | 2288 |
\item Alexandre Biancalana \email{<ale*seudns.net>} |
2286 | 2289 |
\item Patrick Bihan-Faou \email{<patrick*mindstep.com>} |
2287 | 2290 |
\item Martin Blapp \email{<mb*imp.ch>} |
2288 | 2291 |
\item Dale Blount \email{<dale*velocity.net>} |
2292 |
+ \item Serge van den Boom \email{<svdb*stack.nl>} |
|
2289 | 2293 |
\item Oliver Brandmueller \email{<ob*e-Gitt.NET>} |
2290 | 2294 |
\item Boguslaw Brandys \email{<brandys*o2.pl>} |
2291 | 2295 |
\item Igor Brezac \email{<igor*ipass.net>} |
... | ... |
@@ -2320,6 +2328,7 @@ level required:MD5 checksum:digital signature:builder name:build time (sec) |
2320 | 2320 |
\item Fred van Engen \email{<fred*wooha.org>} |
2321 | 2321 |
\item Jason Englander \email{<jason*englanders.cc>} |
2322 | 2322 |
\item Oden Eriksson \email{<oeriksson*mandrakesoft.com>} |
2323 |
+ \item Daniel Fahlgren \email{<fahlgren*ardendo.se>} |
|
2323 | 2324 |
\item Andy Fiddaman \email{<af*jeamland.org>} |
2324 | 2325 |
\item Edison Figueira Junior \email{<edison*brc.com.br>} |
2325 | 2326 |
\item David Ford \email{<david+cert*blue-labs.org>} |
... | ... |
@@ -2363,6 +2372,7 @@ level required:MD5 checksum:digital signature:builder name:build time (sec) |
2363 | 2363 |
\item Per Jessen \email{<per*computer.org>} |
2364 | 2364 |
\item Dave Jones \email{<dave*kalkbay.co.za>} |
2365 | 2365 |
\item Jesper Juhl \email{<juhl*dif.dk>} |
2366 |
+ \item Kamil Kaczkowski \email{<kamil*kamil.eisp.pl>} |
|
2366 | 2367 |
\item Alex Kah \email{<alex*narfonix.com>} |
2367 | 2368 |
\item Stefan Kaltenbrunner \email{<stefan*kaltenbrunner.cc>} |
2368 | 2369 |
\item Lloyd Kamara \email{<l.kamara*imperial.ac.uk>} |
... | ... |
@@ -2380,6 +2390,7 @@ level required:MD5 checksum:digital signature:builder name:build time (sec) |
2380 | 2380 |
\item Mark Kushinsky \email{<mark*mdspc.com>} |
2381 | 2381 |
\item Mike Lambert \email{<lambert*jeol.com>} |
2382 | 2382 |
\item Thomas Lamy \email{<Thomas.Lamy*in-online.net>} |
2383 |
+ \item Stephane Leclerc \email{<sleclerc*aliastec.net>} |
|
2383 | 2384 |
\item Marty Lee \email{<marty*maui.co.uk>} |
2384 | 2385 |
\item Dennis Leeuw \email{<dleeuw*made-it.com>} |
2385 | 2386 |
\item Martin Lesser \email{<admin-debian*bettercom.de>} |
... | ... |
@@ -2389,6 +2400,7 @@ level required:MD5 checksum:digital signature:builder name:build time (sec) |
2389 | 2389 |
\item Jerome Limozin \email{<jerome*limozin.net>} |
2390 | 2390 |
\item Mike Loewen \email{<mloewen*sturgeon.cac.psu.edu>} |
2391 | 2391 |
\item Roger Lucas \email{<roger*planbit.co.uk>} |
2392 |
+ \item David Luyer \email{<david\_luyer*pacific.net.au>} |
|
2392 | 2393 |
\item Richard Lyons \email{<frob-clamav*webcentral.com.au>} |
2393 | 2394 |
\item David S. Madole \email{<david*madole.net>} |
2394 | 2395 |
\item Thomas Madsen \email{<tm*softcom.dk>} |
... | ... |
@@ -2396,6 +2408,7 @@ level required:MD5 checksum:digital signature:builder name:build time (sec) |
2396 | 2396 |
\item Joe Maimon \email{<jmaimon*ttec.com>} |
2397 | 2397 |
\item David Majorel \email{<dm*lagoon.nc>} |
2398 | 2398 |
\item Andrey V. Malyshev \email{<amal*krasn.ru>} |
2399 |
+ \item Fukuda Manabu \email{<fukuda*cri-mw.co.jp>} |
|
2399 | 2400 |
\item Stefan Martig \email{<sm*officeco.ch>} |
2400 | 2401 |
\item Alexander Marx \email{<mad-ml*madness.at>} |
2401 | 2402 |
\item Andreas Marx (\url{http://www.av-test.org/}) |
... | ... |
@@ -2452,6 +2465,7 @@ level required:MD5 checksum:digital signature:builder name:build time (sec) |
2452 | 2452 |
\item Sergei Pronin \email{<sp*finndesign.fi>} |
2453 | 2453 |
\item Thomas Quinot \email{<thomas*cuivre.fr.eu.org>} |
2454 | 2454 |
\item Ed Ravin \email{<eravin*panix.com>} |
2455 |
+ \item Robert Rebbun \email{<robert*desertsurf.com>} |
|
2455 | 2456 |
\item Brian A. Reiter \email{<breiter*wolfereiter.com>} |
2456 | 2457 |
\item Didi Rieder \email{<adrieder*sbox.tugraz.at>} |
2457 | 2458 |
\item Pavel V. Rochnyack \email{<rpv*fsf.tsu.ru>} |
... | ... |
@@ -2469,9 +2483,11 @@ level required:MD5 checksum:digital signature:builder name:build time (sec) |
2469 | 2469 |
\item Omer Faruk Sen \email{<ofsen*enderunix.org>} |
2470 | 2470 |
\item Sergey \email{<a\_s\_y*sama.ru>} |
2471 | 2471 |
\item Tuomas Silen \email{<tuomas.silen*nodeta.fi>} |
2472 |
+ \item David F. Skoll \email{<dfs*roaringpenguin.com>} |
|
2472 | 2473 |
\item Al Smith \email{<ajs+clamav*aeschi.ch.eu.org>} |
2473 | 2474 |
\item Sergey Smitienko \email{<hunter*comsys.com.ua>} |
2474 | 2475 |
\item Solar Designer \email{<solar*openwall.com>} |
2476 |
+ \item Joerg Sonnenberger \email{<joerg*britannica.bec.de>} |
|
2475 | 2477 |
\item Kevin Spicer \email{<kevin*kevinspicer.co.uk>} |
2476 | 2478 |
\item GertJan Spoelman \email{<cav*gjs.cc>} |
2477 | 2479 |
\item Ole Stanstrup \email{<ole*stanstrup.dk>} |
... | ... |
@@ -2486,6 +2502,7 @@ level required:MD5 checksum:digital signature:builder name:build time (sec) |
2486 | 2486 |
\item Masahiro Teramoto \email{<markun*onohara.to>} |
2487 | 2487 |
\item Daniel Theodoro \email{<dtheodoro*ig.com.br>} |
2488 | 2488 |
\item Ryan Thompson \email{<clamav*sasknow.com>} |
2489 |
+ \item Gianluigi Tiesi \email{<sherpya*netfarm.it>} |
|
2489 | 2490 |
\item Yar Tikhiy \email{<yar*comp.chem.msu.su>} |
2490 | 2491 |
\item Andrew Toller \email{<atoller*connectfree.co.uk>} |
2491 | 2492 |
\item Michael L. Torrie \email{<torriem*chem.byu.edu>} |
... | ... |
@@ -2506,6 +2523,7 @@ level required:MD5 checksum:digital signature:builder name:build time (sec) |
2506 | 2506 |
\item David Wu \email{<dyw*iohk.com>} |
2507 | 2507 |
\item Takumi Yamane \email{<yamtak*b-session.com>} |
2508 | 2508 |
\item Youza Youzovic \email{<youza*post.cz>} |
2509 |
+ \item Anton Yuzhaninov \email{<citrin*rambler-co.ru>} |
|
2509 | 2510 |
\item Leonid Zeitlin \email{<lz*europe.com>} |
2510 | 2511 |
\item ZMan Z. \email{<x86zman*go-a-way.dyndns.org>} |
2511 | 2512 |
\item Andoni Zubimendi \email{<andoni*lpsat.net>} |
... | ... |
@@ -2518,6 +2536,7 @@ level required:MD5 checksum:digital signature:builder name:build time (sec) |
2518 | 2518 |
\item Advance Healthcare Group (\url{http://www.ahgl.com.au/}) |
2519 | 2519 |
\item American Computer \& Electronic Services Corp. (\url{http://www.acesnw.com/}) |
2520 | 2520 |
\item Anonymous donor from Colorado, US |
2521 |
+ \item Peter Ashman |
|
2521 | 2522 |
\item Atlas College (\url{http://www.atlascollege.nl/}) |
2522 | 2523 |
\item AWD Online (\url{http://www.awdonline.com/}) |
2523 | 2524 |
\item BackupAssist Backup Software (\url{http://www.backupassist.com/}) |
... | ... |
@@ -2553,6 +2572,7 @@ level required:MD5 checksum:digital signature:builder name:build time (sec) |
2553 | 2553 |
\item The Free Shopping Cart people (\url{http://www.precisionweb.net/}) |
2554 | 2554 |
\item Paul Freeman |
2555 | 2555 |
\item Jack Fung |
2556 |
+ \item Stephen Gageby |
|
2556 | 2557 |
\item Paolo Galeazzi |
2557 | 2558 |
\item GANDI (\url{http://www.gandi.net/}) |
2558 | 2559 |
\item Jeremy Garcia (\url{http://www.linuxquestions.org/}) |
... | ... |
@@ -2567,6 +2587,7 @@ level required:MD5 checksum:digital signature:builder name:build time (sec) |
2567 | 2567 |
\item Hosting Metro LLC (\url{http://www.hostingmetro.com/}) |
2568 | 2568 |
\item IDEAL Software GmbH (\url{http://www.IdealSoftware.com/}) |
2569 | 2569 |
\item Industry Standard Computers (\url{http://www.ISCnetwork.com/}) |
2570 |
+ \item Interact2Day (\url{http://www.interact2day.com/}) |
|
2570 | 2571 |
\item Invisik Corporation (\url{http://www.invisik.com/}) |
2571 | 2572 |
\item itXcel Internet - Domain Registration (\url{http://www.itxcel.com}) |
2572 | 2573 |
\item Craig Jackson |
... | ... |
@@ -2616,6 +2637,7 @@ level required:MD5 checksum:digital signature:builder name:build time (sec) |
2616 | 2616 |
\item SearchMain (\url{http://www.searchmain.com/}) |
2617 | 2617 |
\item Olivier Silber |
2618 | 2618 |
\item Fernando Augusto Medeiros Silva (\url{http://www.linuxplace.com.br/}) |
2619 |
+ \item Sollentuna Fria Gymnasium, Sweden (\url{http://www.sfg.se/}) |
|
2619 | 2620 |
\item StarBand (\url{http://www.starband.com/}) |
2620 | 2621 |
\item Stroke of Color, Inc. |
2621 | 2622 |
\item Synchro Sistemas de Informacao (\url{http://synchro.com.br/}) |
... | ... |
@@ -146,7 +146,7 @@ Execute the COMMAND when virus is found. In the command string %v will be replac |
146 | 146 |
Default: disabled |
147 | 147 |
.TP |
148 | 148 |
\fBExitOnOOM\fR |
149 |
-Stop deamon when libclamav reports out of memory condition. |
|
149 |
+Stop daemon when libclamav reports out of memory condition. |
|
150 | 150 |
.br |
151 | 151 |
Default: disabled |
152 | 152 |
.TP |
... | ... |
@@ -290,7 +290,7 @@ Scan files on execute. |
290 | 290 |
Default: disabled |
291 | 291 |
.TP |
292 | 292 |
\fBClamukoIncludePath STRING\fR |
293 |
-Set the include paths (all files and directories in them will be scanned). You can have multiple ClamukoIncludePath directives but each directory must be added in a seperate line). |
|
293 |
+Set the include paths (all files and directories in them will be scanned). You can have multiple ClamukoIncludePath directives but each directory must be added in a separate line). |
|
294 | 294 |
.br |
295 | 295 |
Default: disabled |
296 | 296 |
.TP |
... | ... |
@@ -38,7 +38,7 @@ Load virus database from FILE or load all virus database files from DIR. |
38 | 38 |
Save scan report to FILE. |
39 | 39 |
.TP |
40 | 40 |
\fB\-\-tempdir=DIRECTORY\fR |
41 |
-Create temporary files in DIRECTORY. Directory must be writeable for the 'clamav' user or unprivileged user running clamscan. |
|
41 |
+Create temporary files in DIRECTORY. Directory must be writable for the 'clamav' user or unprivileged user running clamscan. |
|
42 | 42 |
.TP |
43 | 43 |
\fB\-\-leave\-temps\fR |
44 | 44 |
Do not remove temporary files. |
... | ... |
@@ -65,7 +65,7 @@ Only print infected files. |
65 | 65 |
Remove infected files. \fBBe careful.\fR |
66 | 66 |
.TP |
67 | 67 |
\fB\-\-move=DIRECTORY\fR |
68 |
-Move infected files into DIRECTORY. Directory must be writeable for the 'clamav' user or unprivileged user running clamscan. |
|
68 |
+Move infected files into DIRECTORY. Directory must be writable for the 'clamav' user or unprivileged user running clamscan. |
|
69 | 69 |
.TP |
70 | 70 |
\fB\-\-no\-mail\fR |
71 | 71 |
Disable scanning of mail files. |
... | ... |
@@ -106,7 +106,7 @@ Set archive recursion level limit. This option protects your system against DoS |
106 | 106 |
\fB\-\-max\-ratio=#n\fR |
107 | 107 |
Set maximum archive compression ratio limit. This option protects your system against DoS attacks (default: 250). |
108 | 108 |
.TP |
109 |
-\fB\-\-max\-dir\-recurion=#n\fR |
|
109 |
+\fB\-\-max\-dir\-recursion=#n\fR |
|
110 | 110 |
Maximum depth directories are scanned at (default: 15). |
111 | 111 |
.TP |
112 | 112 |
\fB\-\-unzip[=FULLPATH]\fR |
... | ... |
@@ -185,7 +185,7 @@ Note: some return codes may only appear in a one file mode (clamscan is started |
185 | 185 |
.TP |
186 | 186 |
57: Can't get absolute path name of current working directory. |
187 | 187 |
.TP |
188 |
-58: I/O error, please check your filesystem. |
|
188 |
+58: I/O error, please check your file system. |
|
189 | 189 |
.TP |
190 | 190 |
59: Can't get information about current user from /etc/passwd. |
191 | 191 |
.TP |
... | ... |
@@ -32,7 +32,7 @@ Write all messages to the standard output (stdout), instead of the standard erro |
32 | 32 |
Save download report in FILE. |
33 | 33 |
.TP |
34 | 34 |
\fB\-\-datadir=DIRECTORY\fR |
35 |
-Install new database in DIRECTORY. The directory must be writeable for the 'clamav' user or unprivileged user running freshclam. |
|
35 |
+Install new database in DIRECTORY. The directory must be writable for the 'clamav' user or unprivileged user running freshclam. |
|
36 | 36 |
.TP |
37 | 37 |
\fB\-u USER, \-\-user USER\fR |
38 | 38 |
Run as USER. By default (when started by root) freshclam drops privileges and works as the 'clamav' user. |
... | ... |
@@ -55,10 +55,10 @@ Notify the daemon about the new database. By default it reads a hardcoded config |
55 | 55 |
Use (local) IP for HTTP downloads. Useful for multi\-homed systems. If binding fails for whatever reason, a warning is issued and freshclam behaves like without this flag. |
56 | 56 |
.TP |
57 | 57 |
\fB\-\-on\-error\-execute=COMMAND\fR |
58 |
-Execute COMMAND if error occured. Remeber, that virus database freshness is the most important thing in anti\-virus system. With this option freshclam can alert you (eg. send SMS) when something is going wrong. |
|
58 |
+Execute COMMAND if error occurred. Remember, that virus database freshness is the most important thing in anti\-virus system. With this option freshclam can alert you (eg. send SMS) when something is going wrong. |
|
59 | 59 |
.TP |
60 | 60 |
\fB\-\-on\-update\-execute=COMMAND\fR |
61 |
-Execute COMMAND after succesful update. |
|
61 |
+Execute COMMAND after successful update. |
|
62 | 62 |
.TP |
63 | 63 |
\fB\-\-on\-outdated\-execute=COMMAND\fR |
64 | 64 |
Execute COMMAND when freshclam reports outdated version. In the command string %v will be replaced by the new version number. |
... | ... |
@@ -77,7 +77,7 @@ Execute COMMAND when freshclam reports outdated version. In the command string % |
77 | 77 |
|
78 | 78 |
\fBfreshclam \-d \-c 2\fR |
79 | 79 |
.SH "RETURN CODES" |
80 |
-0 : Database succesfully updated. |
|
80 |
+0 : Database successfully updated. |
|
81 | 81 |
.TP |
82 | 82 |
1 : Database is up\-to\-date. |
83 | 83 |
.TP |
... | ... |
@@ -107,7 +107,7 @@ Execute COMMAND when freshclam reports outdated version. In the command string % |
107 | 107 |
.TP |
108 | 108 |
61: Can't drop privileges. |
109 | 109 |
.TP |
110 |
-62: Can't initialze logger. |
|
110 |
+62: Can't initialize logger. |
|
111 | 111 |
.SH "FILES" |
112 | 112 |
.LP |
113 | 113 |
@CFGDIR@/freshclam.conf |
... | ... |
@@ -98,7 +98,7 @@ Use \fBIP\fR as client address for downloading databases. Useful for multi homed |
98 | 98 |
Default: Use OS\'es default outgoing IP address. |
99 | 99 |
.TP |
100 | 100 |
\fBNotifyClamd \[STRING\]\fR |
101 |
-Notify a running clamd(8) to reload it\'s database after a download has occured. Optionally a clamd.conf(5) file location may be given to tell freshclam(1) how to communicate with clamd(8). |
|
101 |
+Notify a running clamd(8) to reload its database after a download has occurred. Optionally a clamd.conf(5) file location may be given to tell freshclam(1) how to communicate with clamd(8). |
|
102 | 102 |
.br . |
103 | 103 |
Default: The default is to not notify clamd. See clamd.conf(5)\'s option SelfCheck for how clamd(8) handles database updates in this case. |
104 | 104 |
.TP |
... | ... |
@@ -14,9 +14,9 @@ Example |
14 | 14 |
#LogFile /tmp/clamd.log |
15 | 15 |
|
16 | 16 |
# By default the log file is locked for writing - the lock protects against |
17 |
-# running clamd multiple times (if want to run another clamd, please |
|
18 |
-# copy the configuration file, change the LogFile variable, and run |
|
19 |
-# the daemon with --config-file option). |
|
17 |
+# running clamd multiple times (if you want to run another clamd instance, |
|
18 |
+# please # copy the configuration file, change the LogFile variable, and run |
|
19 |
+# the daemon with the --config-file option). |
|
20 | 20 |
# This option disables log file locking. |
21 | 21 |
# Default: disabled |
22 | 22 |
#LogFileUnlock |
... | ... |
@@ -148,8 +148,8 @@ int downloadmanager(const struct cfgstruct *copt, const struct optstruct *opt, c |
148 | 148 |
} |
149 | 149 |
#endif /* HAVE_RESOLV_H */ |
150 | 150 |
|
151 |
- if(optl(opt, "localip")) { |
|
152 |
- localip = getargl(opt, "localip"); |
|
151 |
+ if(optl(opt, "local-address")) { |
|
152 |
+ localip = getargl(opt, "local-address"); |
|
153 | 153 |
} else if((cpt = cfgopt(copt, "LocalIPAddress"))) { |
154 | 154 |
localip = cpt->strarg; |
155 | 155 |
} |
... | ... |
@@ -497,6 +497,17 @@ int wwwconnect(const char *server, const char *proxy, int pport, char *ip, char |
497 | 497 |
|
498 | 498 |
name.sin_family = AF_INET; |
499 | 499 |
|
500 |
+#ifdef PF_INET |
|
501 |
+ socketfd = socket(PF_INET, SOCK_STREAM, 0); |
|
502 |
+#else |
|
503 |
+ socketfd = socket(AF_INET, SOCK_STREAM, 0); |
|
504 |
+#endif |
|
505 |
+ |
|
506 |
+ if(socketfd < 0) { |
|
507 |
+ mprintf("@Can't create new socket\n"); |
|
508 |
+ return -1; |
|
509 |
+ } |
|
510 |
+ |
|
500 | 511 |
if (localip) { |
501 | 512 |
if ((he = gethostbyname(localip)) == NULL) { |
502 | 513 |
char *herr; |
... | ... |
@@ -585,6 +596,7 @@ int wwwconnect(const char *server, const char *proxy, int pport, char *ip, char |
585 | 585 |
break; |
586 | 586 |
} |
587 | 587 |
mprintf("@Can't get information about %s: %s\n", hostpt, herr); |
588 |
+ close(socketfd); |
|
588 | 589 |
return -1; |
589 | 590 |
} |
590 | 591 |
|
... | ... |
@@ -602,21 +614,15 @@ int wwwconnect(const char *server, const char *proxy, int pport, char *ip, char |
602 | 602 |
name.sin_addr = *((struct in_addr *) host->h_addr_list[i]); |
603 | 603 |
name.sin_port = htons(port); |
604 | 604 |
|
605 |
-#ifdef PF_INET |
|
606 |
- socketfd = socket(PF_INET, SOCK_STREAM, 0); |
|
607 |
-#else |
|
608 |
- socketfd = socket(AF_INET, SOCK_STREAM, 0); |
|
609 |
-#endif |
|
610 |
- |
|
611 | 605 |
if(connect(socketfd, (struct sockaddr *) &name, sizeof(struct sockaddr_in)) == -1) { |
612 | 606 |
mprintf("Can't connect to port %d of host %s (IP: %s)\n", port, hostpt, ipaddr); |
613 |
- close(socketfd); |
|
614 | 607 |
continue; |
608 |
+ } else { |
|
609 |
+ return socketfd; |
|
615 | 610 |
} |
616 |
- |
|
617 |
- return socketfd; |
|
618 | 611 |
} |
619 | 612 |
|
613 |
+ close(socketfd); |
|
620 | 614 |
return -2; |
621 | 615 |
} |
622 | 616 |
|
... | ... |
@@ -61,7 +61,7 @@ int main(int argc, char **argv) |
61 | 61 |
{"no-dns", 0, 0, 0}, |
62 | 62 |
{"checks", 1, 0, 'c'}, |
63 | 63 |
{"http-proxy", 1, 0, 0}, |
64 |
- {"client-address", 1, 0, 'a'}, |
|
64 |
+ {"local-address", 1, 0, 'a'}, |
|
65 | 65 |
{"proxy-user", 1, 0, 0}, |
66 | 66 |
{"daemon-notify", 2, 0, 0}, |
67 | 67 |
{"on-update-execute", 1, 0, 0}, |
... | ... |
@@ -84,7 +84,7 @@ am_libclamav_la_OBJECTS = matcher-ac.lo matcher-bm.lo matcher.lo \ |
84 | 84 |
text.lo ole2_extract.lo vba_extract.lo msexpand.lo pe.lo \ |
85 | 85 |
cabd.lo lzxd.lo mszipd.lo qtmd.lo system.lo upx.lo htmlnorm.lo \ |
86 | 86 |
chmunpack.lo rebuildpe.lo petite.lo fsg.lo line.lo untar.lo \ |
87 |
- special.lo binhex.lo is_tar.lo tnef.lo |
|
87 |
+ special.lo binhex.lo is_tar.lo tnef.lo uuencode.lo |
|
88 | 88 |
libclamav_la_OBJECTS = $(am_libclamav_la_OBJECTS) |
89 | 89 |
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) |
90 | 90 |
depcomp = $(SHELL) $(top_srcdir)/depcomp |
... | ... |
@@ -316,7 +316,9 @@ libclamav_la_SOURCES = \ |
316 | 316 |
is_tar.c \ |
317 | 317 |
is_tar.h \ |
318 | 318 |
tnef.c \ |
319 |
- tnef.h |
|
319 |
+ tnef.h \ |
|
320 |
+ uuencode.c \ |
|
321 |
+ uuencode.h |
|
320 | 322 |
|
321 | 323 |
lib_LTLIBRARIES = libclamav.la |
322 | 324 |
all: all-am |
... | ... |
@@ -428,6 +430,7 @@ distclean-compile: |
428 | 428 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unrarlib.Plo@am__quote@ |
429 | 429 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/untar.Plo@am__quote@ |
430 | 430 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upx.Plo@am__quote@ |
431 |
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uuencode.Plo@am__quote@ |
|
431 | 432 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vba_extract.Plo@am__quote@ |
432 | 433 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zzip-dir.Plo@am__quote@ |
433 | 434 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zzip-err.Plo@am__quote@ |
... | ... |
@@ -1092,7 +1092,7 @@ static int cli_html_normalise(int fd, m_area_t *m_area, const char *dirname, tag |
1092 | 1092 |
ptr++; |
1093 | 1093 |
} |
1094 | 1094 |
} else if (*ptr == '\"') { |
1095 |
- if (!escape && (quoted=DOUBLE_QUOTED)) { |
|
1095 |
+ if (!escape && (quoted==DOUBLE_QUOTED)) { |
|
1096 | 1096 |
state = HTML_RFC2397_FINISH; |
1097 | 1097 |
ptr++; |
1098 | 1098 |
} else { |
... | ... |
@@ -245,7 +245,8 @@ int cli_validatesig(unsigned short target, unsigned short ftype, const char *off |
245 | 245 |
int cli_scandesc(int desc, const char **virname, unsigned long int *scanned, const struct cl_node *root, short otfrec, unsigned short ftype) |
246 | 246 |
{ |
247 | 247 |
char *buffer, *buff, *endbl, *pt; |
248 |
- int bytes, buffsize, length, ret, *partcnt, type = CL_CLEAN; |
|
248 |
+ int bytes, ret, *partcnt, type = CL_CLEAN; |
|
249 |
+ unsigned int buffersize, length, shift = 0; |
|
249 | 250 |
unsigned long int *partoff, offset = 0; |
250 | 251 |
MD5_CTX ctx; |
251 | 252 |
unsigned char digest[16]; |
... | ... |
@@ -258,9 +259,9 @@ int cli_scandesc(int desc, const char **virname, unsigned long int *scanned, con |
258 | 258 |
} |
259 | 259 |
|
260 | 260 |
/* prepare the buffer */ |
261 |
- buffsize = root->maxpatlen + SCANBUFF; |
|
262 |
- if(!(buffer = (char *) cli_calloc(buffsize, sizeof(char)))) { |
|
263 |
- cli_dbgmsg("cli_scandesc(): unable to cli_calloc(%d)\n", buffsize); |
|
261 |
+ buffersize = root->maxpatlen + SCANBUFF; |
|
262 |
+ if(!(buffer = (char *) cli_calloc(buffersize, sizeof(char)))) { |
|
263 |
+ cli_dbgmsg("cli_scandesc(): unable to cli_calloc(%d)\n", buffersize); |
|
264 | 264 |
return CL_EMEM; |
265 | 265 |
} |
266 | 266 |
|
... | ... |
@@ -288,14 +289,15 @@ int cli_scandesc(int desc, const char **virname, unsigned long int *scanned, con |
288 | 288 |
*/ |
289 | 289 |
|
290 | 290 |
pt = buff; |
291 |
- length = SCANBUFF; |
|
292 |
- while((bytes = cli_readn(desc, buff, SCANBUFF)) > 0) { |
|
291 |
+ while((bytes = cli_readn(desc, buff + shift, SCANBUFF - shift)) > 0) { |
|
293 | 292 |
|
294 | 293 |
if(scanned) |
295 | 294 |
*scanned += bytes / CL_COUNT_PRECISION; |
296 | 295 |
|
297 |
- if(bytes < SCANBUFF) |
|
298 |
- length -= SCANBUFF - bytes; |
|
296 |
+ length = shift + bytes; |
|
297 |
+ if(pt == buffer) |
|
298 |
+ length += root->maxpatlen; |
|
299 |
+ |
|
299 | 300 |
|
300 | 301 |
if(cli_bm_scanbuff(pt, length, virname, root, offset, ftype, desc) == CL_VIRUS || |
301 | 302 |
(ret = cli_ac_scanbuff(pt, length, virname, root, partcnt, otfrec, offset, partoff, ftype, desc)) == CL_VIRUS) { |
... | ... |
@@ -314,20 +316,22 @@ int cli_scandesc(int desc, const char **virname, unsigned long int *scanned, con |
314 | 314 |
type = ret; |
315 | 315 |
} |
316 | 316 |
|
317 |
- if(bytes == SCANBUFF) { |
|
317 |
+ if(root->md5_hlist) |
|
318 |
+ MD5_Update(&ctx, buff + shift, bytes); |
|
319 |
+ |
|
320 |
+ if(bytes + shift == SCANBUFF) { |
|
318 | 321 |
memmove(buffer, endbl, root->maxpatlen); |
322 |
+ offset += SCANBUFF; |
|
319 | 323 |
|
320 |
- if(pt == buffer) { |
|
321 |
- offset += SCANBUFF; |
|
322 |
- } else { |
|
323 |
- offset += SCANBUFF - root->maxpatlen; |
|
324 |
+ if(pt == buff) { |
|
324 | 325 |
pt = buffer; |
325 |
- length = buffsize; |
|
326 |
+ offset -= root->maxpatlen; |
|
326 | 327 |
} |
327 |
- } |
|
328 | 328 |
|
329 |
- if(root->md5_hlist) |
|
330 |
- MD5_Update(&ctx, buff, bytes); |
|
329 |
+ shift = 0; |
|
330 |
+ } else { |
|
331 |
+ shift += bytes; |
|
332 |
+ } |
|
331 | 333 |
} |
332 | 334 |
|
333 | 335 |
free(buffer); |
... | ... |
@@ -1,5 +1,5 @@ |
1 | 1 |
/* |
2 |
- * Copyright (C) 2002 Nigel Horne <njh@bandsman.co.uk> |
|
2 |
+ * Copyright (C) 2002-2006 Nigel Horne <njh@bandsman.co.uk> |
|
3 | 3 |
* |
4 | 4 |
* This program is free software; you can redistribute it and/or modify |
5 | 5 |
* it under the terms of the GNU General Public License as published by |
... | ... |
@@ -15,7 +15,7 @@ |
15 | 15 |
* along with this program; if not, write to the Free Software |
16 | 16 |
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
17 | 17 |
*/ |
18 |
-static char const rcsid[] = "$Id: mbox.c,v 1.238+fixes 2005/04/19 09:20:55 nigelhorne Exp $"; |
|
18 |
+static char const rcsid[] = "$Id: mbox.c,v 1.279 2006/02/06 02:36:39 nigelhorne Exp $"; |
|
19 | 19 |
|
20 | 20 |
#if HAVE_CONFIG_H |
21 | 21 |
#include "clamav-config.h" |
... | ... |
@@ -39,10 +39,7 @@ static char const rcsid[] = "$Id: mbox.c,v 1.238+fixes 2005/04/19 09:20:55 nigel |
39 | 39 |
#include <strings.h> |
40 | 40 |
#include <ctype.h> |
41 | 41 |
#include <time.h> |
42 |
-#include <unistd.h> |
|
43 | 42 |
#include <fcntl.h> |
44 |
-#include <sys/stat.h> |
|
45 |
-#include <sys/types.h> |
|
46 | 43 |
#include <sys/param.h> |
47 | 44 |
#include <clamav.h> |
48 | 45 |
#include <dirent.h> |
... | ... |
@@ -66,6 +63,7 @@ static char const rcsid[] = "$Id: mbox.c,v 1.238+fixes 2005/04/19 09:20:55 nigel |
66 | 66 |
#include "defaults.h" |
67 | 67 |
#include "str.h" |
68 | 68 |
#include "filetypes.h" |
69 |
+#include "uuencode.h" |
|
69 | 70 |
|
70 | 71 |
#ifdef CL_DEBUG |
71 | 72 |
#if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 |
... | ... |
@@ -98,6 +96,10 @@ static void print_trace(int use_syslog); |
98 | 98 |
|
99 | 99 |
typedef enum { FALSE = 0, TRUE = 1 } bool; |
100 | 100 |
|
101 |
+#ifndef isblank |
|
102 |
+#define isblank(c) (((c) == ' ') || ((c) == '\t')) |
|
103 |
+#endif |
|
104 |
+ |
|
101 | 105 |
#define SAVE_TO_DISC /* multipart/message are saved in a temporary file */ |
102 | 106 |
|
103 | 107 |
/* |
... | ... |
@@ -121,7 +123,7 @@ typedef enum { FALSE = 0, TRUE = 1 } bool; |
121 | 121 |
#ifdef WITH_CURL |
122 | 122 |
#define FOLLOWURLS 5 /* |
123 | 123 |
* Maximum number of URLs scanned in a message |
124 |
- * part. Helps to find Dialier.gen-45. If |
|
124 |
+ * part. Helps to find Dialer.gen-45. If |
|
125 | 125 |
* not defined, don't check any URLs |
126 | 126 |
*/ |
127 | 127 |
#endif |
... | ... |
@@ -138,14 +140,11 @@ typedef enum { FALSE = 0, TRUE = 1 } bool; |
138 | 138 |
#include <curl/curl.h> |
139 | 139 |
|
140 | 140 |
/* |
141 |
- * Needs curl >= 7.11 (I've heard that 7.9 can cause crashes and 7.10 is |
|
141 |
+ * Needs curl >= 7.11 (I've heard that 7.9 can cause crashes and I have seen |
|
142 |
+ * 7.10 segfault, later versions can be flakey as well) |
|
142 | 143 |
* untested) |
143 | 144 |
*/ |
144 |
-#if (LIBCURL_VERSION_MAJOR < 7) |
|
145 |
-#undef WITH_CURL /* also undef FOLLOWURLS? */ |
|
146 |
-#endif |
|
147 |
- |
|
148 |
-#if (LIBCURL_VERSION_MAJOR == 7) && (LIBCURL_VERSION_MINOR < 10) |
|
145 |
+#if (LIBCURL_VERSION_NUM < 0x070B00) |
|
149 | 146 |
#undef WITH_CURL /* also undef FOLLOWURLS? */ |
150 | 147 |
#endif |
151 | 148 |
|
... | ... |
@@ -187,11 +186,7 @@ static char *rfc822comments(const char *in, char *out); |
187 | 187 |
static int rfc1341(message *m, const char *dir); |
188 | 188 |
#endif |
189 | 189 |
static bool usefulHeader(int commandNumber, const char *cmd); |
190 |
-static int uufasttrack(message *m, const char *firstline, const char *dir, FILE *fin); |
|
191 | 190 |
static char *getline_from_mbox(char *buffer, size_t len, FILE *fin); |
192 |
-#ifdef NEW_WORLD |
|
193 |
-static const char *cli_pmemstr(const char *haystack, size_t hs, const char *needle, size_t ns); |
|
194 |
-#endif |
|
195 | 191 |
|
196 | 192 |
static void checkURLs(message *m, const char *dir); |
197 | 193 |
#ifdef WITH_CURL |
... | ... |
@@ -208,7 +203,7 @@ static void *getURL(struct arg *arg); |
208 | 208 |
#endif |
209 | 209 |
|
210 | 210 |
/* Maximum line length according to RFC821 */ |
211 |
-#define LINE_LENGTH 1000 |
|
211 |
+#define RFC2821LENGTH 1000 |
|
212 | 212 |
|
213 | 213 |
/* Hashcodes for our hash tables */ |
214 | 214 |
#define CONTENT_TYPE 1 |
... | ... |
@@ -299,21 +294,48 @@ static pthread_mutex_t tables_mutex = PTHREAD_MUTEX_INITIALIZER; |
299 | 299 |
|
300 | 300 |
#ifdef NEW_WORLD |
301 | 301 |
|
302 |
+#undef PARTIAL_DIR |
|
303 |
+ |
|
302 | 304 |
#if HAVE_MMAP |
303 | 305 |
#if HAVE_SYS_MMAN_H |
304 | 306 |
#include <sys/mman.h> |
305 | 307 |
#else /* HAVE_SYS_MMAN_H */ |
306 | 308 |
#undef HAVE_MMAP |
307 | 309 |
#endif |
310 |
+#else /*HAVE_MMAP*/ |
|
311 |
+#undef NEW_WORLD |
|
312 |
+#endif |
|
308 | 313 |
#endif |
309 | 314 |
|
315 |
+#ifdef NEW_WORLD |
|
316 |
+/* |
|
317 |
+ * Files larger than this are scanned with the old method, should be |
|
318 |
+ * StreamMaxLength, I guess |
|
319 |
+ * If NW_MAX_FILE_SIZE is not defined, all files go through the |
|
320 |
+ * new method. This definition is for machines very tight on RAM, or |
|
321 |
+ * with large StreamMaxLength values |
|
322 |
+ */ |
|
323 |
+#define MAX_ALLOCATION 134217728 /* see libclamav/others.c */ |
|
324 |
+#define NW_MAX_FILE_SIZE MAX_ALLOCATION |
|
325 |
+ |
|
310 | 326 |
struct scanlist { |
311 |
- char *start; |
|
312 |
- size_t size; |
|
313 |
- encoding_type decoder; /* only BASE64 and QUOTEDPRINTABLE for now */ |
|
314 |
- struct scanlist *next; |
|
327 |
+ const char *start; |
|
328 |
+ size_t size; |
|
329 |
+ encoding_type decoder; /* only BASE64 and QUOTEDPRINTABLE for now */ |
|
330 |
+ struct scanlist *next; |
|
315 | 331 |
}; |
316 | 332 |
|
333 |
+static struct map { |
|
334 |
+ const char *offset; /* sorted */ |
|
335 |
+ const char *word; |
|
336 |
+ struct map *next; |
|
337 |
+} *map, *tail; |
|
338 |
+ |
|
339 |
+static void create_map(const char *begin, const char *end); |
|
340 |
+static void add_to_map(const char *offset, const char *word); |
|
341 |
+static const char *find_in_map(const char *offset, const char *word); |
|
342 |
+static void free_map(void); |
|
343 |
+ |
|
317 | 344 |
/* |
318 | 345 |
* This could be the future. Instead of parsing and decoding it just decodes. |
319 | 346 |
* |
... | ... |
@@ -331,16 +353,21 @@ struct scanlist { |
331 | 331 |
* because the scan can proceed to the end of the file rather than the end |
332 | 332 |
* of the attachment which can mean than later emails are scanned many times |
333 | 333 |
* |
334 |
- * TODO: Also all those pmemstr()s are slow, so we need to reduce the number |
|
335 |
- * and size of data scanned each time, and we fall through to |
|
336 |
- * cli_parse_mbox() too often |
|
334 |
+ * FIXME: quoted printable doesn't know when to stop, so size related virus |
|
335 |
+ * matching breaks |
|
336 |
+ * |
|
337 |
+ * TODO: Fall through to cli_parse_mbox() too often |
|
338 |
+ * |
|
339 |
+ * TODO: Add support for systems without mmap() |
|
340 |
+ * |
|
341 |
+ * TODO: partial_dir fall through |
|
337 | 342 |
*/ |
338 | 343 |
int |
339 | 344 |
cli_mbox(const char *dir, int desc, unsigned int options) |
340 | 345 |
{ |
341 |
- char *start, *ptr, *line, *p, *q; |
|
342 |
- const char *last; |
|
343 |
- size_t size, s; |
|
346 |
+ char *start, *ptr, *line; |
|
347 |
+ const char *last, *p, *q; |
|
348 |
+ size_t size; |
|
344 | 349 |
struct stat statb; |
345 | 350 |
message *m; |
346 | 351 |
fileblob *fb; |
... | ... |
@@ -360,10 +387,15 @@ cli_mbox(const char *dir, int desc, unsigned int options) |
360 | 360 |
if(size == 0) |
361 | 361 |
return CL_CLEAN; |
362 | 362 |
|
363 |
- if(size > 10*1024*1024) |
|
364 |
- return cli_parse_mbox(dir, desc, options); /* should be StreamMaxLength, I guess */ |
|
363 |
+#ifdef NW_MAX_FILE_SIZE |
|
364 |
+ if(size > NW_MAX_FILE_SIZE) |
|
365 |
+ return cli_parse_mbox(dir, desc, options); |
|
366 |
+#endif |
|
365 | 367 |
|
366 |
- cli_warnmsg("NEW_WORLD is new code - use at your own risk.\n"); |
|
368 |
+ /*cli_warnmsg("NEW_WORLD is new code - use at your own risk.\n");*/ |
|
369 |
+#ifdef PARTIAL_DIR |
|
370 |
+ cli_warnmsg("PARTIAL_DIR doesn't work in the NEW_WORLD yet\n"); |
|
371 |
+#endif |
|
367 | 372 |
|
368 | 373 |
start = mmap(NULL, size, PROT_READ, MAP_PRIVATE, desc, 0); |
369 | 374 |
if(start == MAP_FAILED) |
... | ... |
@@ -371,26 +403,27 @@ cli_mbox(const char *dir, int desc, unsigned int options) |
371 | 371 |
|
372 | 372 |
cli_dbgmsg("mmap'ed mbox\n"); |
373 | 373 |
|
374 |
- /* last points to the last *valid* address in the array */ |
|
375 |
- last = &start[size - 1]; |
|
376 |
- |
|
377 | 374 |
ptr = cli_malloc(size); |
378 | 375 |
if(ptr) { |
379 |
- wasAlloced = 1; |
|
380 | 376 |
memcpy(ptr, start, size); |
381 | 377 |
munmap(start, size); |
382 | 378 |
start = ptr; |
383 |
- last = &start[size - 1]; |
|
379 |
+ wasAlloced = 1; |
|
384 | 380 |
} else |
385 | 381 |
wasAlloced = 0; |
386 | 382 |
|
387 |
- /* |
|
388 |
- * Would be nice to have a case insensitive cli_memstr() |
|
389 |
- */ |
|
383 |
+ /* last points to the last *valid* address in the array */ |
|
384 |
+ last = &start[size - 1]; |
|
385 |
+ |
|
386 |
+ create_map(start, last); |
|
387 |
+ |
|
390 | 388 |
scanelem = scanlist = NULL; |
391 | 389 |
q = start; |
392 |
- s = size; |
|
393 |
- while((p = (char *)cli_pmemstr(q, s, "base64", 6)) != NULL) { |
|
390 |
+ /* |
|
391 |
+ * FIXME: mismatch of const char * and char * here and in later calls |
|
392 |
+ * to find_in_map() |
|
393 |
+ */ |
|
394 |
+ while((p = find_in_map(q, "base64")) != NULL) { |
|
394 | 395 |
cli_dbgmsg("Found base64\n"); |
395 | 396 |
if(scanelem) { |
396 | 397 |
scanelem->next = cli_malloc(sizeof(struct scanlist)); |
... | ... |
@@ -399,25 +432,22 @@ cli_mbox(const char *dir, int desc, unsigned int options) |
399 | 399 |
scanlist = scanelem = cli_malloc(sizeof(struct scanlist)); |
400 | 400 |
scanelem->next = NULL; |
401 | 401 |
scanelem->decoder = BASE64; |
402 |
- s -= (p - q) + 6; |
|
403 | 402 |
q = scanelem->start = &p[6]; |
404 |
- if(((p = (char *)cli_pmemstr(q, s, "\nFrom ", 6)) != NULL) || |
|
405 |
- ((p = (char *)cli_pmemstr(q, s, "base64", 6)) != NULL) || |
|
406 |
- ((p = (char *)cli_pmemstr(q, s, "quoted-printable", 16)) != NULL)) { |
|
403 |
+ if(((p = find_in_map(q, "\nFrom ")) != NULL) || |
|
404 |
+ ((p = find_in_map(q, "base64")) != NULL) || |
|
405 |
+ ((p = find_in_map(q, "quoted-printable")) != NULL)) { |
|
407 | 406 |
scanelem->size = (size_t)(p - q); |
408 | 407 |
q = p; |
409 |
- s -= scanelem->size; |
|
410 | 408 |
} else { |
411 | 409 |
scanelem->size = (size_t)(last - scanelem->start) + 1; |
412 | 410 |
break; |
413 | 411 |
} |
414 |
- cli_dbgmsg("base64: last %u q %u s %u\n", (unsigned int)last, (unsigned int)q, s); |
|
412 |
+ cli_dbgmsg("base64: last %u q %u\n", (unsigned int)last, (unsigned int)q); |
|
415 | 413 |
assert(scanelem->size <= size); |
416 |
- assert(&q[s - 1] <= last); |
|
417 | 414 |
} |
415 |
+ |
|
418 | 416 |
q = start; |
419 |
- s = size; |
|
420 |
- while((p = (char *)cli_pmemstr(q, s, "quoted-printable", 16)) != NULL) { |
|
417 |
+ while((p = find_in_map(q, "quoted-printable")) != NULL) { |
|
421 | 418 |
if(p != q) |
422 | 419 |
switch(p[-1]) { |
423 | 420 |
case ' ': |
... | ... |
@@ -425,14 +455,17 @@ cli_mbox(const char *dir, int desc, unsigned int options) |
425 | 425 |
case '=': /* wrong but allow it */ |
426 | 426 |
break; |
427 | 427 |
default: |
428 |
- s -= (p - q) + 16; |
|
429 | 428 |
q = &p[16]; |
430 | 429 |
cli_dbgmsg("Ignore quoted-printable false positive\n"); |
431 |
- cli_dbgmsg("s = %u\n", s); |
|
432 | 430 |
continue; /* false positive */ |
433 | 431 |
} |
434 | 432 |
|
435 | 433 |
cli_dbgmsg("Found quoted-printable\n"); |
434 |
+#ifdef notdef |
|
435 |
+ /* |
|
436 |
+ * The problem with quoted printable is recognising when to stop |
|
437 |
+ * parsing |
|
438 |
+ */ |
|
436 | 439 |
if(scanelem) { |
437 | 440 |
scanelem->next = cli_malloc(sizeof(struct scanlist)); |
438 | 441 |
scanelem = scanelem->next; |
... | ... |
@@ -440,40 +473,55 @@ cli_mbox(const char *dir, int desc, unsigned int options) |
440 | 440 |
scanlist = scanelem = cli_malloc(sizeof(struct scanlist)); |
441 | 441 |
scanelem->next = NULL; |
442 | 442 |
scanelem->decoder = QUOTEDPRINTABLE; |
443 |
- s -= (p - q) + 16; |
|
444 | 443 |
q = scanelem->start = &p[16]; |
445 |
- cli_dbgmsg("qp: last %u q %u s %u\n", (unsigned int)last, (unsigned int)q, s); |
|
446 |
- if(((p = (char *)cli_pmemstr(q, s, "\nFrom ", 6)) != NULL) || |
|
447 |
- ((p = (char *)cli_pmemstr(q, s, "quoted-printable", 16)) != NULL) || |
|
448 |
- ((p = (char *)cli_pmemstr(q, s, "base64", 6)) != NULL)) { |
|
444 |
+ cli_dbgmsg("qp: last %u q %u\n", (unsigned int)last, (unsigned int)q); |
|
445 |
+ if(((p = find_in_map(q, "\nFrom ")) != NULL) || |
|
446 |
+ ((p = find_in_map(q, "quoted-printable")) != NULL) || |
|
447 |
+ ((p = find_in_map(q, "base64")) != NULL)) { |
|
449 | 448 |
scanelem->size = (size_t)(p - q); |
450 | 449 |
q = p; |
451 |
- s -= scanelem->size; |
|
452 | 450 |
cli_dbgmsg("qp: scanelem->size = %u\n", scanelem->size); |
453 | 451 |
} else { |
454 | 452 |
scanelem->size = (size_t)(last - scanelem->start) + 1; |
455 | 453 |
break; |
456 | 454 |
} |
457 | 455 |
assert(scanelem->size <= size); |
458 |
- assert(&q[s - 1] <= last); |
|
456 |
+#else |
|
457 |
+ if(wasAlloced) |
|
458 |
+ free(start); |
|
459 |
+ else |
|
460 |
+ munmap(start, size); |
|
461 |
+ |
|
462 |
+ free_map(); |
|
463 |
+ return cli_parse_mbox(dir, desc, options); |
|
464 |
+#endif |
|
459 | 465 |
} |
460 | 466 |
|
461 | 467 |
if(scanlist == NULL) { |
462 | 468 |
const struct tableinit *tableinit; |
463 | 469 |
bool anyHeadersFound = FALSE; |
464 | 470 |
bool hasuuencode = FALSE; |
471 |
+ cli_file_t type; |
|
465 | 472 |
|
466 | 473 |
/* FIXME: message: There could of course be no decoder needed... */ |
467 | 474 |
for(tableinit = rfc821headers; tableinit->key; tableinit++) |
468 |
- if(cli_pmemstr(start, size, tableinit->key, strlen(tableinit->key))) { |
|
475 |
+ if(find_in_map(start, tableinit->key)) { |
|
469 | 476 |
anyHeadersFound = TRUE; |
470 | 477 |
break; |
471 | 478 |
} |
472 | 479 |
|
473 |
- if((!anyHeadersFound) && cli_pmemstr(start, size, "\nbegin ", 7)) |
|
480 |
+ if((!anyHeadersFound) && find_in_map(start, "\nbegin ")) |
|
474 | 481 |
/* uuencoded part */ |
475 | 482 |
hasuuencode = TRUE; |
476 | 483 |
|
484 |
+ free_map(); |
|
485 |
+ |
|
486 |
+ type = cli_filetype(start, size); |
|
487 |
+ |
|
488 |
+ if((type == CL_TYPE_UNKNOWN_TEXT) && |
|
489 |
+ (strncmp(start, "Microsoft Mail Internet Headers", 31) == 0)) |
|
490 |
+ type = CL_TYPE_MAIL; |
|
491 |
+ |
|
477 | 492 |
if(wasAlloced) |
478 | 493 |
free(start); |
479 | 494 |
else |
... | ... |
@@ -481,21 +529,47 @@ cli_mbox(const char *dir, int desc, unsigned int options) |
481 | 481 |
|
482 | 482 |
if(anyHeadersFound || hasuuencode) { |
483 | 483 |
/* TODO: reduce the number of falls through here */ |
484 |
- cli_warnmsg("cli_mbox: uuencode or unknown encoder\n"); |
|
485 |
- return cli_parse_mbox(dir, desc, options); |
|
484 |
+ if(hasuuencode) |
|
485 |
+ cli_dbgmsg("New world - fall back to old uudecoder, type %d\n", type); |
|
486 |
+ else |
|
487 |
+ cli_dbgmsg("cli_mbox: unknown encoder, type %d\n", type); |
|
488 |
+ if(type == CL_TYPE_MAIL) |
|
489 |
+ return cli_parse_mbox(dir, desc, options); |
|
490 |
+ cli_dbgmsg("Unknown filetype %d, return CLEAN\n", type); |
|
491 |
+ return CL_CLEAN; |
|
486 | 492 |
} |
487 | 493 |
|
488 |
- cli_warnmsg("cli_mbox: I believe it's plain text which must be clean\n"); |
|
494 |
+ /* The message could be a plain text phish */ |
|
495 |
+ if((type == CL_TYPE_MAIL) && (!(options&CL_DB_NOPHISHING))) |
|
496 |
+ return cli_parse_mbox(dir, desc, options); |
|
497 |
+ cli_dbgmsg("cli_mbox: I believe it's plain text which must be clean\n"); |
|
489 | 498 |
return CL_CLEAN; |
490 | 499 |
} |
500 |
+ free_map(); |
|
501 |
+ |
|
502 |
+#if 0 |
|
503 |
+ if(wasAlloced) { |
|
504 |
+ const char *max = NULL; |
|
505 |
+ |
|
506 |
+ for(scanelem = scanlist; scanelem; scanelem = scanelem->next) { |
|
507 |
+ const char *end = &scanelem->start[scanelem->size]; |
|
508 |
+ |
|
509 |
+ if(end > max) |
|
510 |
+ max = end; |
|
511 |
+ } |
|
512 |
+ |
|
513 |
+ if(max < last) |
|
514 |
+ printf("could free %d bytes\n", (int)(last - max)); |
|
515 |
+ } |
|
516 |
+#endif |
|
491 | 517 |
|
492 | 518 |
for(scanelem = scanlist; scanelem; scanelem = scanelem->next) { |
493 | 519 |
if(scanelem->decoder == BASE64) { |
494 |
- char *b64start = scanelem->start; |
|
495 |
- long b64size = scanelem->size; |
|
520 |
+ const char *b64start = scanelem->start; |
|
521 |
+ size_t b64size = scanelem->size; |
|
496 | 522 |
|
497 | 523 |
cli_dbgmsg("b64size = %lu\n", b64size); |
498 |
- while(*b64start != '\n') { |
|
524 |
+ while((*b64start != '\n') && (*b64start != '\r')) { |
|
499 | 525 |
b64start++; |
500 | 526 |
b64size--; |
501 | 527 |
} |
... | ... |
@@ -506,14 +580,33 @@ cli_mbox(const char *dir, int desc, unsigned int options) |
506 | 506 |
if(*b64start == ';') { |
507 | 507 |
b64start++; |
508 | 508 |
b64size--; |
509 |
- } else if(*b64start == '\n') { |
|
510 |
- b64start++; |
|
511 |
- b64size--; |
|
512 |
- if((*b64start == '\n') || (*b64start == '\r')) { |
|
513 |
- b64start++; |
|
514 |
- b64size--; |
|
515 |
- break; |
|
516 |
- } |
|
509 |
+ } else if((memcmp(b64start, "\n\n", 2) == 0) || |
|
510 |
+ (memcmp(b64start, "\r\r", 2) == 0)) { |
|
511 |
+ b64start += 2; |
|
512 |
+ b64size -= 2; |
|
513 |
+ break; |
|
514 |
+ } else if(memcmp(b64start, "\r\n\r\n", 4) == 0) { |
|
515 |
+ b64start += 4; |
|
516 |
+ b64size -= 4; |
|
517 |
+ break; |
|
518 |
+ } else if(memcmp(b64start, "\n \n", 3) == 0) { |
|
519 |
+ /* |
|
520 |
+ * Some viruses are broken and have |
|
521 |
+ * one space character at the end of |
|
522 |
+ * the headers |
|
523 |
+ */ |
|
524 |
+ b64start += 3; |
|
525 |
+ b64size -= 3; |
|
526 |
+ break; |
|
527 |
+ } else if(memcmp(b64start, "\r\n \r\n", 5) == 0) { |
|
528 |
+ /* |
|
529 |
+ * Some viruses are broken and have |
|
530 |
+ * one space character at the end of |
|
531 |
+ * the headers |
|
532 |
+ */ |
|
533 |
+ b64start += 5; |
|
534 |
+ b64size -= 5; |
|
535 |
+ break; |
|
517 | 536 |
} |
518 | 537 |
b64start++; |
519 | 538 |
b64size--; |
... | ... |
@@ -527,17 +620,27 @@ cli_mbox(const char *dir, int desc, unsigned int options) |
527 | 527 |
} |
528 | 528 |
|
529 | 529 |
if(b64size > 0L) { |
530 |
+ int lastline; |
|
530 | 531 |
cli_dbgmsg("cli_mbox: decoding %ld base64 bytes\n", b64size); |
531 | 532 |
|
532 | 533 |
line = NULL; |
533 | 534 |
|
534 | 535 |
m = messageCreate(); |
535 |
- if(m == NULL) |
|
536 |
+ if(m == NULL) { |
|
537 |
+ if(wasAlloced) |
|
538 |
+ free(start); |
|
539 |
+ else |
|
540 |
+ munmap(start, size); |
|
541 |
+ |
|
536 | 542 |
return CL_EMEM; |
543 |
+ } |
|
537 | 544 |
messageSetEncoding(m, "base64"); |
538 | 545 |
|
546 |
+ lastline = 0; |
|
547 |
+ |
|
539 | 548 |
do { |
540 | 549 |
int length = 0; |
550 |
+ char *newline, *equal; |
|
541 | 551 |
|
542 | 552 |
/*printf("%ld: ", b64size); fflush(stdout);*/ |
543 | 553 |
|
... | ... |
@@ -548,23 +651,33 @@ cli_mbox(const char *dir, int desc, unsigned int options) |
548 | 548 |
|
549 | 549 |
/*printf("%d: ", length); fflush(stdout);*/ |
550 | 550 |
|
551 |
- line = cli_realloc(line, length + 1); |
|
551 |
+ newline = cli_realloc(line, length + 1); |
|
552 |
+ if(newline == NULL) |
|
553 |
+ break; |
|
554 |
+ line = newline; |
|
552 | 555 |
|
553 | 556 |
memcpy(line, b64start, length); |
554 | 557 |
line[length] = '\0'; |
555 | 558 |
|
559 |
+ equal = strchr(line, '='); |
|
560 |
+ if(equal) { |
|
561 |
+ lastline++; |
|
562 |
+ *equal = '\0'; |
|
563 |
+ } |
|
556 | 564 |
/*puts(line);*/ |
557 | 565 |
|
558 | 566 |
if(messageAddStr(m, line) < 0) |
559 | 567 |
break; |
560 | 568 |
|
561 | 569 |
if((b64size > 0) && (*ptr == '\r')) { |
562 |
- ptr++; |
|
570 |
+ b64start = ++ptr; |
|
571 |
+ --b64size; |
|
572 |
+ } |
|
573 |
+ if((b64size > 0) && (*ptr == '\n')) { |
|
574 |
+ b64start = ++ptr; |
|
563 | 575 |
--b64size; |
564 | 576 |
} |
565 |
- b64start = ++ptr; |
|
566 |
- --b64size; |
|
567 |
- if(strchr(line, '=')) |
|
577 |
+ if(lastline) |
|
568 | 578 |
break; |
569 | 579 |
} while(b64size > 0L); |
570 | 580 |
|
... | ... |
@@ -578,8 +691,8 @@ cli_mbox(const char *dir, int desc, unsigned int options) |
578 | 578 |
ret = -1; |
579 | 579 |
} |
580 | 580 |
} else if(scanelem->decoder == QUOTEDPRINTABLE) { |
581 |
- char *quotedstart = scanelem->start; |
|
582 |
- long quotedsize = scanelem->size; |
|
581 |
+ const char *quotedstart = scanelem->start; |
|
582 |
+ size_t quotedsize = scanelem->size; |
|
583 | 583 |
|
584 | 584 |
cli_dbgmsg("quotedsize = %lu\n", quotedsize); |
585 | 585 |
while(*quotedstart != '\n') { |
... | ... |
@@ -593,7 +706,7 @@ cli_mbox(const char *dir, int desc, unsigned int options) |
593 | 593 |
if(*quotedstart == ';') { |
594 | 594 |
quotedstart++; |
595 | 595 |
quotedsize--; |
596 |
- } else if(*quotedstart == '\n') { |
|
596 |
+ } else if((*quotedstart == '\n') || (*quotedstart == '\r')) { |
|
597 | 597 |
quotedstart++; |
598 | 598 |
quotedsize--; |
599 | 599 |
if((*quotedstart == '\n') || (*quotedstart == '\r')) { |
... | ... |
@@ -615,14 +728,21 @@ cli_mbox(const char *dir, int desc, unsigned int options) |
615 | 615 |
cli_dbgmsg("cli_mbox: decoding %ld quoted-printable bytes\n", quotedsize); |
616 | 616 |
|
617 | 617 |
m = messageCreate(); |
618 |
- if(m == NULL) |
|
618 |
+ if(m == NULL) { |
|
619 |
+ if(wasAlloced) |
|
620 |
+ free(start); |
|
621 |
+ else |
|
622 |
+ munmap(start, size); |
|
623 |
+ |
|
619 | 624 |
return CL_EMEM; |
625 |
+ } |
|
620 | 626 |
messageSetEncoding(m, "quoted-printable"); |
621 | 627 |
|
622 | 628 |
line = NULL; |
623 | 629 |
|
624 | 630 |
do { |
625 | 631 |
int length = 0; |
632 |
+ char *newline; |
|
626 | 633 |
|
627 | 634 |
/*printf("%ld: ", quotedsize); fflush(stdout);*/ |
628 | 635 |
|
... | ... |
@@ -633,7 +753,10 @@ cli_mbox(const char *dir, int desc, unsigned int options) |
633 | 633 |
|
634 | 634 |
/*printf("%d: ", length); fflush(stdout);*/ |
635 | 635 |
|
636 |
- line = cli_realloc(line, length + 1); |
|
636 |
+ newline = cli_realloc(line, length + 1); |
|
637 |
+ if(newline == NULL) |
|
638 |
+ break; |
|
639 |
+ line = newline; |
|
637 | 640 |
|
638 | 641 |
memcpy(line, quotedstart, length); |
639 | 642 |
line[length] = '\0'; |
... | ... |
@@ -644,11 +767,13 @@ cli_mbox(const char *dir, int desc, unsigned int options) |
644 | 644 |
break; |
645 | 645 |
|
646 | 646 |
if((quotedsize > 0) && (*ptr == '\r')) { |
647 |
- ptr++; |
|
647 |
+ quotedstart = ++ptr; |
|
648 |
+ --quotedsize; |
|
649 |
+ } |
|
650 |
+ if((quotedsize > 0) && (*ptr == '\n')) { |
|
651 |
+ quotedstart = ++ptr; |
|
648 | 652 |
--quotedsize; |
649 | 653 |
} |
650 |
- quotedstart = ++ptr; |
|
651 |
- --quotedsize; |
|
652 | 654 |
} while(quotedsize > 0L); |
653 | 655 |
|
654 | 656 |
free(line); |
... | ... |
@@ -682,11 +807,86 @@ cli_mbox(const char *dir, int desc, unsigned int options) |
682 | 682 |
if(ret == 0) |
683 | 683 |
return CL_CLEAN; /* a lie - but it gets things going */ |
684 | 684 |
|
685 |
+ cli_dbgmsg("New world - don't know what to do - fall back to old world\n"); |
|
685 | 686 |
/* Fall back for now */ |
686 | 687 |
lseek(desc, 0L, SEEK_SET); |
687 | 688 |
return cli_parse_mbox(dir, desc, options); |
688 | 689 |
} |
689 |
-#else |
|
690 |
+ |
|
691 |
+static void |
|
692 |
+create_map(const char *begin, const char *end) |
|
693 |
+{ |
|
694 |
+ const struct wordlist { |
|
695 |
+ const char *word; |
|
696 |
+ int len; |
|
697 |
+ } wordlist[] = { |
|
698 |
+ { "base64", 6 }, |
|
699 |
+ { "quoted-printable", 16 }, |
|
700 |
+ { "\nbegin ", 7 }, |
|
701 |
+ { "\nFrom ", 7 }, |
|
702 |
+ { NULL, 0 } |
|
703 |
+ }; |
|
704 |
+ |
|
705 |
+ if(map) { |
|
706 |
+ cli_warnmsg("create_map called without free_map\n"); |
|
707 |
+ free_map(); |
|
708 |
+ } |
|
709 |
+ while(begin < end) { |
|
710 |
+ const struct wordlist *word; |
|
711 |
+ |
|
712 |
+ for(word = wordlist; word->word; word++) { |
|
713 |
+ if((end - begin) < word->len) |
|
714 |
+ continue; |
|
715 |
+ if(strncasecmp(begin, word->word, word->len) == 0) { |
|
716 |
+ add_to_map(begin, word->word); |
|
717 |
+ break; |
|
718 |
+ } |
|
719 |
+ } |
|
720 |
+ begin++; |
|
721 |
+ } |
|
722 |
+} |
|
723 |
+ |
|
724 |
+/* To sort map, assume 'offset' is presented in sorted order */ |
|
725 |
+static void |
|
726 |
+add_to_map(const char *offset, const char *word) |
|
727 |
+{ |
|
728 |
+ if(map) { |
|
729 |
+ tail->next = cli_malloc(sizeof(struct map)); /* FIXME: verify */ |
|
730 |
+ tail = tail->next; |
|
731 |
+ } else |
|
732 |
+ map = tail = cli_malloc(sizeof(struct map)); /* FIXME: verify */ |
|
733 |
+ |
|
734 |
+ tail->offset = offset; |
|
735 |
+ tail->word = word; |
|
736 |
+ tail->next = NULL; |
|
737 |
+} |
|
738 |
+ |
|
739 |
+static const char * |
|
740 |
+find_in_map(const char *offset, const char *word) |
|
741 |
+{ |
|
742 |
+ const struct map *item; |
|
743 |
+ |
|
744 |
+ for(item = map; item; item = item->next) |
|
745 |
+ if(item->offset >= offset) |
|
746 |
+ if(strcasecmp(word, item->word) == 0) |
|
747 |
+ return item->offset; |
|
748 |
+ |
|
749 |
+ return NULL; |
|
750 |
+} |
|
751 |
+ |
|
752 |
+static void |
|
753 |
+free_map(void) |
|
754 |
+{ |
|
755 |
+ while(map) { |
|
756 |
+ struct map *next = map->next; |
|
757 |
+ |
|
758 |
+ free(map); |
|
759 |
+ map = next; |
|
760 |
+ } |
|
761 |
+ map = NULL; |
|
762 |
+} |
|
763 |
+ |
|
764 |
+#else /*!NEW_WORLD*/ |
|
690 | 765 |
int |
691 | 766 |
cli_mbox(const char *dir, int desc, unsigned int options) |
692 | 767 |
{ |
... | ... |
@@ -711,6 +911,8 @@ cli_mbox(const char *dir, int desc, unsigned int options) |
711 | 711 |
* TODO: ensure parseEmailHeaders is always called before parseEmailBody |
712 | 712 |
* TODO: create parseEmail which calls parseEmailHeaders then parseEmailBody |
713 | 713 |
* TODO: Look into TNEF. Is there anything that needs to be done here? |
714 |
+ * TODO: Handle unepected NUL bytes in header lines which stop strcmp()s: |
|
715 |
+ * e.g. \0Content-Type: application/binary; |
|
714 | 716 |
*/ |
715 | 717 |
static int |
716 | 718 |
cli_parse_mbox(const char *dir, int desc, unsigned int options) |
... | ... |
@@ -718,7 +920,7 @@ cli_parse_mbox(const char *dir, int desc, unsigned int options) |
718 | 718 |
int retcode, i; |
719 | 719 |
message *body; |
720 | 720 |
FILE *fd; |
721 |
- char buffer[LINE_LENGTH + 1]; |
|
721 |
+ char buffer[RFC2821LENGTH + 1]; |
|
722 | 722 |
#ifdef HAVE_BACKTRACE |
723 | 723 |
void (*segv)(int); |
724 | 724 |
#endif |
... | ... |
@@ -728,7 +930,11 @@ cli_parse_mbox(const char *dir, int desc, unsigned int options) |
728 | 728 |
int tmpfd; |
729 | 729 |
#endif |
730 | 730 |
|
731 |
+#ifdef NEW_WORLD |
|
732 |
+ cli_dbgmsg("fall back to old world\n"); |
|
733 |
+#else |
|
731 | 734 |
cli_dbgmsg("in mbox()\n"); |
735 |
+#endif |
|
732 | 736 |
|
733 | 737 |
i = dup(desc); |
734 | 738 |
if((fd = fdopen(i, "rb")) == NULL) { |
... | ... |
@@ -806,7 +1012,7 @@ cli_parse_mbox(const char *dir, int desc, unsigned int options) |
806 | 806 |
* message is stopped, and giving a better indication of which message |
807 | 807 |
* within the mailbox is infected |
808 | 808 |
*/ |
809 |
- if(strncmp(buffer, "From ", 5) == 0) { |
|
809 |
+ if((strncmp(buffer, "From ", 5) == 0) && isalnum(buffer[5])) { |
|
810 | 810 |
/* |
811 | 811 |
* Have been asked to check a UNIX style mbox file, which |
812 | 812 |
* may contain more than one e-mail message to decode |
... | ... |
@@ -845,7 +1051,7 @@ cli_parse_mbox(const char *dir, int desc, unsigned int options) |
845 | 845 |
|
846 | 846 |
do { |
847 | 847 |
cli_chomp(buffer); |
848 |
- if(lastLineWasEmpty && (strncmp(buffer, "From ", 5) == 0)) { |
|
848 |
+ if(lastLineWasEmpty && (strncmp(buffer, "From ", 5) == 0) && isalnum(buffer[5])) { |
|
849 | 849 |
cli_dbgmsg("Deal with email number %d\n", messagenumber++); |
850 | 850 |
/* |
851 | 851 |
* End of a message in the mail box |
... | ... |
@@ -882,9 +1088,9 @@ cli_parse_mbox(const char *dir, int desc, unsigned int options) |
882 | 882 |
* Fast track visa to uudecode. |
883 | 883 |
* TODO: binhex, yenc |
884 | 884 |
*/ |
885 |
- if(uufasttrack(m, buffer, dir, fd) < 0) |
|
885 |
+ if(uudecodeFile(m, buffer, dir, fd) < 0) |
|
886 | 886 |
if(messageAddStr(m, buffer) < 0) |
887 |
- break; |
|
887 |
+ break; |
|
888 | 888 |
} else |
889 | 889 |
if(messageAddStr(m, buffer) < 0) |
890 | 890 |
break; |
... | ... |
@@ -970,7 +1176,7 @@ parseEmailFile(FILE *fin, const table_t *rfc821, const char *firstLine, const ch |
970 | 970 |
int commandNumber = -1; |
971 | 971 |
char *fullline = NULL, *boundary = NULL; |
972 | 972 |
size_t fulllinelength = 0; |
973 |
- char buffer[LINE_LENGTH+1]; |
|
973 |
+ char buffer[RFC2821LENGTH + 1]; |
|
974 | 974 |
|
975 | 975 |
cli_dbgmsg("parseEmailFile\n"); |
976 | 976 |
|
... | ... |
@@ -1005,7 +1211,7 @@ parseEmailFile(FILE *fin, const table_t *rfc821, const char *firstLine, const ch |
1005 | 1005 |
boundary = NULL; |
1006 | 1006 |
} |
1007 | 1007 |
if(inHeader) { |
1008 |
- cli_dbgmsg("parseEmailFile: check '%s' contMarker %d fullline 0x%p\n", |
|
1008 |
+ cli_dbgmsg("parseEmailFile: check '%s' contMarker %d fullline %p\n", |
|
1009 | 1009 |
buffer ? buffer : "", (int)contMarker, fullline); |
1010 | 1010 |
if(line && isspace(line[0])) { |
1011 | 1011 |
char copy[sizeof(buffer)]; |
... | ... |
@@ -1060,12 +1266,12 @@ parseEmailFile(FILE *fin, const table_t *rfc821, const char *firstLine, const ch |
1060 | 1060 |
int lookahead; |
1061 | 1061 |
|
1062 | 1062 |
if(fullline == NULL) { |
1063 |
- char cmd[LINE_LENGTH + 1], out[LINE_LENGTH + 1]; |
|
1063 |
+ char cmd[RFC2821LENGTH + 1], out[RFC2821LENGTH + 1]; |
|
1064 | 1064 |
|
1065 | 1065 |
/* |
1066 | 1066 |
* Continuation of line we're ignoring? |
1067 | 1067 |
*/ |
1068 |
- if((line[0] == '\t') || (line[0] == ' ') || contMarker) { |
|
1068 |
+ if(isblank(line[0])) { |
|
1069 | 1069 |
contMarker = continuationMarker(line); |
1070 | 1070 |
continue; |
1071 | 1071 |
} |
... | ... |
@@ -1098,7 +1304,10 @@ parseEmailFile(FILE *fin, const table_t *rfc821, const char *firstLine, const ch |
1098 | 1098 |
fulllinelength = strlen(line) + 1; |
1099 | 1099 |
} else if(line != NULL) { |
1100 | 1100 |
fulllinelength += strlen(line); |
1101 |
- fullline = cli_realloc(fullline, fulllinelength); |
|
1101 |
+ ptr = cli_realloc(fullline, fulllinelength); |
|
1102 |
+ if(ptr == NULL) |
|
1103 |
+ continue; |
|
1104 |
+ fullline = ptr; |
|
1102 | 1105 |
strcat(fullline, line); |
1103 | 1106 |
} |
1104 | 1107 |
|
... | ... |
@@ -1123,7 +1332,7 @@ parseEmailFile(FILE *fin, const table_t *rfc821, const char *firstLine, const ch |
1123 | 1123 |
* |
1124 | 1124 |
* Add all the arguments on the line |
1125 | 1125 |
*/ |
1126 |
- if((lookahead == '\t') || (lookahead == ' ')) |
|
1126 |
+ if(isblank(lookahead)) |
|
1127 | 1127 |
continue; |
1128 | 1128 |
} |
1129 | 1129 |
|
... | ... |
@@ -1154,7 +1363,7 @@ parseEmailFile(FILE *fin, const table_t *rfc821, const char *firstLine, const ch |
1154 | 1154 |
* Fast track visa to uudecode. |
1155 | 1155 |
* TODO: binhex, yenc |
1156 | 1156 |
*/ |
1157 |
- if(uufasttrack(ret, line, dir, fin) < 0) |
|
1157 |
+ if(uudecodeFile(ret, line, dir, fin) < 0) |
|
1158 | 1158 |
if(messageAddStr(ret, line) < 0) |
1159 | 1159 |
break; |
1160 | 1160 |
} else |
... | ... |
@@ -1246,12 +1455,12 @@ parseEmailHeaders(const message *m, const table_t *rfc821) |
1246 | 1246 |
int quotes; |
1247 | 1247 |
|
1248 | 1248 |
if(fullline == NULL) { |
1249 |
- char cmd[LINE_LENGTH + 1]; |
|
1249 |
+ char cmd[RFC2821LENGTH + 1]; |
|
1250 | 1250 |
|
1251 | 1251 |
/* |
1252 | 1252 |
* Continuation of line we're ignoring? |
1253 | 1253 |
*/ |
1254 |
- if((buffer[0] == '\t') || (buffer[0] == ' ')) |
|
1254 |
+ if(isblank(buffer[0])) |
|
1255 | 1255 |
continue; |
1256 | 1256 |
|
1257 | 1257 |
/* |
... | ... |
@@ -1284,7 +1493,10 @@ parseEmailHeaders(const message *m, const table_t *rfc821) |
1284 | 1284 |
fulllinelength = strlen(buffer) + 1; |
1285 | 1285 |
} else if(buffer) { |
1286 | 1286 |
fulllinelength += strlen(buffer); |
1287 |
- fullline = cli_realloc(fullline, fulllinelength); |
|
1287 |
+ ptr = cli_realloc(fullline, fulllinelength); |
|
1288 |
+ if(ptr == NULL) |
|
1289 |
+ continue; |
|
1290 |
+ fullline = ptr; |
|
1288 | 1291 |
strcat(fullline, buffer); |
1289 | 1292 |
} |
1290 | 1293 |
|
... | ... |
@@ -1298,11 +1510,8 @@ parseEmailHeaders(const message *m, const table_t *rfc821) |
1298 | 1298 |
* |
1299 | 1299 |
* Add all the arguments on the line |
1300 | 1300 |
*/ |
1301 |
- switch(lineGetData(t->t_next->t_line)[0]) { |
|
1302 |
- case ' ': |
|
1303 |
- case '\t': |
|
1304 |
- continue; |
|
1305 |
- } |
|
1301 |
+ if(isblank(lineGetData(t->t_next->t_line)[0])) |
|
1302 |
+ continue; |
|
1306 | 1303 |
|
1307 | 1304 |
quotes = 0; |
1308 | 1305 |
for(qptr = fullline; *qptr; qptr++) |
... | ... |
@@ -1541,19 +1750,11 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t |
1541 | 1541 |
if(boundaryStart(lineGetData(t_line->t_line), boundary)) |
1542 | 1542 |
break; |
1543 | 1543 |
/* |
1544 |
- * Found a uuencoded/binhex file before |
|
1544 |
+ * Found a binhex file before |
|
1545 | 1545 |
* the first multipart |
1546 | 1546 |
* TODO: check yEnc |
1547 | 1547 |
*/ |
1548 |
- if(uuencodeBegin(mainMessage) == t_line) { |
|
1549 |
- if(messageGetEncoding(mainMessage) == NOENCODING) { |
|
1550 |
- messageSetEncoding(mainMessage, "x-uuencode"); |
|
1551 |
- fb = messageToFileblob(mainMessage, dir); |
|
1552 |
- |
|
1553 |
- if(fb) |
|
1554 |
- fileblobDestroy(fb); |
|
1555 |
- } |
|
1556 |
- } else if(binhexBegin(mainMessage) == t_line) { |
|
1548 |
+ if(binhexBegin(mainMessage) == t_line) { |
|
1557 | 1549 |
if(messageGetEncoding(mainMessage) == NOENCODING) { |
1558 | 1550 |
messageSetEncoding(mainMessage, "x-binhex"); |
1559 | 1551 |
fb = messageToFileblob(mainMessage, dir); |
... | ... |
@@ -1588,7 +1789,7 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t |
1588 | 1588 |
mimeType = NOMIME; |
1589 | 1589 |
/* |
1590 | 1590 |
* The break means that we will still |
1591 |
- * check if the file contains a uuencoded file |
|
1591 |
+ * check if the file contains a yEnc/binhex file |
|
1592 | 1592 |
*/ |
1593 | 1593 |
break; |
1594 | 1594 |
} |
... | ... |
@@ -1639,12 +1840,12 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t |
1639 | 1639 |
cli_dbgmsg("Empty part\n"); |
1640 | 1640 |
/* |
1641 | 1641 |
* Remove this part unless there's |
1642 |
- * a uuencoded portion somewhere in |
|
1642 |
+ * a binhex portion somewhere in |
|
1643 | 1643 |
* the complete message that we may |
1644 | 1644 |
* throw away by mistake if the MIME |
1645 | 1645 |
* encoding information is incorrect |
1646 | 1646 |
*/ |
1647 |
- if(uuencodeBegin(mainMessage) == NULL) { |
|
1647 |
+ if(binhexBegin(mainMessage) == NULL) { |
|
1648 | 1648 |
messageDestroy(aMessage); |
1649 | 1649 |
--multiparts; |
1650 | 1650 |
} |
... | ... |
@@ -1654,8 +1855,8 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t |
1654 | 1654 |
do { |
1655 | 1655 |
const char *line = lineGetData(t_line->t_line); |
1656 | 1656 |
|
1657 |
- /*cli_dbgmsg("inMimeHead %d inhead %d boundary '%s' line '%s' next '%s'\n", |
|
1658 |
- inMimeHead, inhead, boundary, line, |
|
1657 |
+ /*cli_dbgmsg("multipart %d: inMimeHead %d inhead %d boundary '%s' line '%s' next '%s'\n", |
|
1658 |
+ multiparts, inMimeHead, inhead, boundary, line, |
|
1659 | 1659 |
t_line->t_next && t_line->t_next->t_line ? lineGetData(t_line->t_next->t_line) : "(null)");*/ |
1660 | 1660 |
|
1661 | 1661 |
if(inMimeHead) { /* continuation line */ |
... | ... |
@@ -1778,7 +1979,7 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t |
1778 | 1778 |
|
1779 | 1779 |
inMimeHead = FALSE; |
1780 | 1780 |
|
1781 |
- assert(strlen(line) <= LINE_LENGTH); |
|
1781 |
+ assert(strlen(line) <= RFC2821LENGTH); |
|
1782 | 1782 |
|
1783 | 1783 |
fullline = rfc822comments(line, NULL); |
1784 | 1784 |
if(fullline == NULL) |
... | ... |
@@ -2045,9 +2246,9 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t |
2045 | 2045 |
case NOMIME: |
2046 | 2046 |
cli_dbgmsg("No mime headers found in multipart part %d\n", i); |
2047 | 2047 |
if(mainMessage) { |
2048 |
- if(uuencodeBegin(aMessage)) { |
|
2049 |
- cli_dbgmsg("Found uuencoded message in multipart/mixed mainMessage\n"); |
|
2050 |
- messageSetEncoding(mainMessage, "x-uuencode"); |
|
2048 |
+ if(binhexBegin(aMessage)) { |
|
2049 |
+ cli_dbgmsg("Found binhex message in multipart/mixed mainMessage\n"); |
|
2050 |
+ messageSetEncoding(mainMessage, "x-bunhex"); |
|
2051 | 2051 |
fb = messageToFileblob(mainMessage, dir); |
2052 | 2052 |
|
2053 | 2053 |
if(fb) |
... | ... |
@@ -2057,16 +2258,7 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t |
2057 | 2057 |
messageDestroy(mainMessage); |
2058 | 2058 |
mainMessage = NULL; |
2059 | 2059 |
} else if(aMessage) { |
2060 |
- if(uuencodeBegin(aMessage)) { |
|
2061 |
- cli_dbgmsg("Found uuencoded message in multipart/mixed non mime part\n"); |
|
2062 |
- messageSetEncoding(aMessage, "x-uuencode"); |
|
2063 |
- fb = messageToFileblob(aMessage, dir); |
|
2064 |
- |
|
2065 |
- if(fb) |
|
2066 |
- fileblobDestroy(fb); |
|
2067 |
- assert(aMessage == messages[i]); |
|
2068 |
- messageReset(messages[i]); |
|
2069 |
- } else if(binhexBegin(aMessage)) { |
|
2060 |
+ if(binhexBegin(aMessage)) { |
|
2070 | 2061 |
cli_dbgmsg("Found binhex message in multipart/mixed non mime part\n"); |
2071 | 2062 |
messageSetEncoding(aMessage, "x-binhex"); |
2072 | 2063 |
fb = messageToFileblob(aMessage, dir); |
... | ... |
@@ -2082,8 +2274,7 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t |
2082 | 2082 |
/* |
2083 | 2083 |
* No plain text version |
2084 | 2084 |
*/ |
2085 |
- messageAddStr(aMessage, "No plain text alternative"); |
|
2086 |
- assert(messageGetBody(aMessage) != NULL); |
|
2085 |
+ cli_dbgmsg("No plain text alternative"); |
|
2087 | 2086 |
break; |
2088 | 2087 |
case TEXT: |
2089 | 2088 |
dtype = messageGetDispositionType(aMessage); |
... | ... |
@@ -2097,10 +2288,7 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t |
2097 | 2097 |
mainMessage = NULL; |
2098 | 2098 |
cptr = messageGetMimeSubtype(aMessage); |
2099 | 2099 |
cli_dbgmsg("Mime subtype \"%s\"\n", cptr); |
2100 |
- if(uuencodeBegin(aMessage)) { |
|
2101 |
- cli_dbgmsg("Found uuencoded message in multipart/mixed text portion\n"); |
|
2102 |
- messageSetEncoding(aMessage, "x-uuencode"); |
|
2103 |
- } else if((tableFind(subtypeTable, cptr) == PLAIN) && |
|
2100 |
+ if((tableFind(subtypeTable, cptr) == PLAIN) && |
|
2104 | 2101 |
(messageGetEncoding(aMessage) == NOENCODING)) { |
2105 | 2102 |
char *filename; |
2106 | 2103 |
/* |
... | ... |
@@ -2265,7 +2453,7 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t |
2265 | 2265 |
cli_warnmsg("PGP encoded attachment not scanned\n"); |
2266 | 2266 |
rc = 2; |
2267 | 2267 |
} else |
2268 |
- cli_warnmsg("Unknown encryption protocol '%s' - if you believe this file contains a virus, report it to bugs@clamav.net\n"); |
|
2268 |
+ cli_warnmsg("Unknown encryption protocol '%s' - if you believe this file contains a virus, submit it to www.clamav.net\n", protocol); |
|
2269 | 2269 |
free(protocol); |
2270 | 2270 |
} else |
2271 | 2271 |
cli_dbgmsg("Encryption method missing protocol name\n"); |
... | ... |
@@ -2347,7 +2535,7 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t |
2347 | 2347 |
/* TODO */ |
2348 | 2348 |
cli_warnmsg("Attempt to send Content-type message/external-body trapped"); |
2349 | 2349 |
else |
2350 |
- cli_warnmsg("Unsupported message format `%s' - if you believe this file contains a virus, report it to bugs@clamav.net\n", mimeSubtype); |
|
2350 |
+ cli_warnmsg("Unsupported message format `%s' - if you believe this file contains a virus, submit it to www.clamav.net\n", mimeSubtype); |
|
2351 | 2351 |
|
2352 | 2352 |
|
2353 | 2353 |
if(mainMessage && (mainMessage != messageIn)) |
... | ... |
@@ -2534,21 +2722,7 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t |
2534 | 2534 |
*/ |
2535 | 2535 |
const text *t_line; |
2536 | 2536 |
|
2537 |
- if((t_line = uuencodeBegin(mainMessage)) != NULL) { |
|
2538 |
- cli_dbgmsg("Found uuencoded file\n"); |
|
2539 |
- |
|
2540 |
- /* |
|
2541 |
- * Main part contains uuencoded section |
|
2542 |
- */ |
|
2543 |
- messageSetEncoding(mainMessage, "x-uuencode"); |
|
2544 |
- |
|
2545 |
- if((fb = messageToFileblob(mainMessage, dir)) != NULL) { |
|
2546 |
- if((cptr = fileblobGetFilename(fb)) != NULL) |
|
2547 |
- cli_dbgmsg("Saving uuencoded message %s\n", cptr); |
|
2548 |
- fileblobDestroy(fb); |
|
2549 |
- } |
|
2550 |
- rc = 1; |
|
2551 |
- } else if((encodingLine(mainMessage) != NULL) && |
|
2537 |
+ if((encodingLine(mainMessage) != NULL) && |
|
2552 | 2538 |
((t_line = bounceBegin(mainMessage)) != NULL)) { |
2553 | 2539 |
const text *t, *start; |
2554 | 2540 |
/* |
... | ... |
@@ -2571,7 +2745,7 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t |
2571 | 2571 |
* won't be scanned |
2572 | 2572 |
*/ |
2573 | 2573 |
for(t = start = t_line; t; t = t->t_next) { |
2574 |
- char cmd[LINE_LENGTH + 1]; |
|
2574 |
+ char cmd[RFC2821LENGTH + 1]; |
|
2575 | 2575 |
const char *txt = lineGetData(t->t_line); |
2576 | 2576 |
|
2577 | 2577 |
if(txt == NULL) |
... | ... |
@@ -2613,8 +2787,6 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t |
2613 | 2613 |
} else { |
2614 | 2614 |
bool saveIt; |
2615 | 2615 |
|
2616 |
- cli_dbgmsg("Not found uuencoded file\n"); |
|
2617 |
- |
|
2618 | 2616 |
if(messageGetMimeType(mainMessage) == MESSAGE) |
2619 | 2617 |
/* |
2620 | 2618 |
* Quick peek, if the encapsulated |
... | ... |
@@ -2692,7 +2864,7 @@ boundaryStart(const char *line, const char *boundary) |
2692 | 2692 |
{ |
2693 | 2693 |
char *ptr, *out; |
2694 | 2694 |
int rc; |
2695 |
- char buf[LINE_LENGTH + 1]; |
|
2695 |
+ char buf[RFC2821LENGTH + 1]; |
|
2696 | 2696 |
|
2697 | 2697 |
if(line == NULL) |
2698 | 2698 |
return 0; /* empty line */ |
... | ... |
@@ -3268,7 +3440,7 @@ rfc2047(const char *in) |
3268 | 3268 |
encoding = tolower(encoding); |
3269 | 3269 |
|
3270 | 3270 |
if((encoding != 'q') && (encoding != 'b')) { |
3271 |
- cli_warnmsg("Unsupported RFC2047 encoding type '%c' - if you believe this file contains a virus that was missed, report it to bugs@clamav.net\n", encoding); |
|
3271 |
+ cli_warnmsg("Unsupported RFC2047 encoding type '%c' - if you believe this file contains a virus, submit it to www.clamav.net\n", encoding); |
|
3272 | 3272 |
free(out); |
3273 | 3273 |
out = NULL; |
3274 | 3274 |
break; |
... | ... |
@@ -3390,9 +3562,11 @@ rfc1341(message *m, const char *dir) |
3390 | 3390 |
oldfilename = (char *)messageFindArgument(m, "name"); |
3391 | 3391 |
|
3392 | 3392 |
arg = cli_malloc(10 + strlen(id) + strlen(number)); |
3393 |
- sprintf(arg, "filename=%s%s", id, number); |
|
3394 |
- messageAddArgument(m, arg); |
|
3395 |
- free(arg); |
|
3393 |
+ if(arg) { |
|
3394 |
+ sprintf(arg, "filename=%s%s", id, number); |
|
3395 |
+ messageAddArgument(m, arg); |
|
3396 |
+ free(arg); |
|
3397 |
+ } |
|
3396 | 3398 |
|
3397 | 3399 |
if(oldfilename) { |
3398 | 3400 |
cli_warnmsg("Must reset to %s\n", oldfilename); |
... | ... |
@@ -3422,6 +3596,7 @@ rfc1341(message *m, const char *dir) |
3422 | 3422 |
if((n == t) && ((dd = opendir(pdir)) != NULL)) { |
3423 | 3423 |
FILE *fout; |
3424 | 3424 |
char outname[NAME_MAX + 1]; |
3425 |
+ time_t now; |
|
3425 | 3426 |
|
3426 | 3427 |
snprintf(outname, sizeof(outname) - 1, "%s/%s", dir, id); |
3427 | 3428 |
|
... | ... |
@@ -3436,6 +3611,7 @@ rfc1341(message *m, const char *dir) |
3436 | 3436 |
return -1; |
3437 | 3437 |
} |
3438 | 3438 |
|
3439 |
+ time(&now); |
|
3439 | 3440 |
for(n = 1; n <= t; n++) { |
3440 | 3441 |
char filename[NAME_MAX + 1]; |
3441 | 3442 |
const struct dirent *dent; |
... | ... |
@@ -3456,20 +3632,31 @@ rfc1341(message *m, const char *dir) |
3456 | 3456 |
while((dent = readdir(dd))) { |
3457 | 3457 |
#endif |
3458 | 3458 |
FILE *fin; |
3459 |
- char buffer[BUFSIZ]; |
|
3459 |
+ char buffer[BUFSIZ], fullname[NAME_MAX + 1]; |
|
3460 | 3460 |
int nblanks; |
3461 | 3461 |
extern short cli_leavetemps_flag; |
3462 |
+ struct stat statb; |
|
3462 | 3463 |
|
3463 | 3464 |
if(dent->d_ino == 0) |
3464 | 3465 |
continue; |
3465 | 3466 |
|
3466 |
- if(strncmp(filename, dent->d_name, strlen(filename)) != 0) |
|
3467 |
+ snprintf(fullname, sizeof(fullname) - 1, |
|
3468 |
+ "%s/%s", pdir, dent->d_name); |
|
3469 |
+ |
|
3470 |
+ if(strncmp(filename, dent->d_name, strlen(filename)) != 0) { |
|
3471 |
+ if(!cli_leavetemps_flag) |
|
3472 |
+ continue; |
|
3473 |
+ if(stat(fullname, &statb) < 0) |
|
3474 |
+ continue; |
|
3475 |
+ if(now - statb.st_mtime > (time_t)(7 * 24 * 3600)) |
|
3476 |
+ if(unlink(fullname) >= 0) |
|
3477 |
+ cli_warnmsg("removed old RFC1341 file %s\n", fullname); |
|
3467 | 3478 |
continue; |
3479 |
+ } |
|
3468 | 3480 |
|
3469 |
- sprintf(filename, "%s/%s", pdir, dent->d_name); |
|
3470 |
- fin = fopen(filename, "rb"); |
|
3481 |
+ fin = fopen(fullname, "rb"); |
|
3471 | 3482 |
if(fin == NULL) { |
3472 |
- cli_errmsg("Can't open '%s' for reading", filename); |
|
3483 |
+ cli_errmsg("Can't open '%s' for reading", fullname); |
|
3473 | 3484 |
fclose(fout); |
3474 | 3485 |
unlink(outname); |
3475 | 3486 |
free(id); |
... | ... |
@@ -3496,7 +3683,7 @@ rfc1341(message *m, const char *dir) |
3496 | 3496 |
|
3497 | 3497 |
/* don't unlink if leave temps */ |
3498 | 3498 |
if(!cli_leavetemps_flag) |
3499 |
- unlink(filename); |
|
3499 |
+ unlink(fullname); |
|
3500 | 3500 |
break; |
3501 | 3501 |
} |
3502 | 3502 |
rewinddir(dd); |
... | ... |
@@ -3568,6 +3755,11 @@ checkURLs(message *m, const char *dir) |
3568 | 3568 |
for(i = 0; i < hrefs.count; i++) { |
3569 | 3569 |
const char *url = (const char *)hrefs.value[i]; |
3570 | 3570 |
|
3571 |
+ /* |
|
3572 |
+ * TODO: If it's an image source, it'd be nice to note beacons |
|
3573 |
+ * where width="0" height="0", which needs support from |
|
3574 |
+ * the HTML normalise code |
|
3575 |
+ */ |
|
3571 | 3576 |
if(strncasecmp("http://", url, 7) == 0) { |
3572 | 3577 |
char *ptr; |
3573 | 3578 |
#ifdef WITH_CURL |
... | ... |
@@ -3588,10 +3780,21 @@ checkURLs(message *m, const char *dir) |
3588 | 3588 |
cli_dbgmsg("URL %s already downloaded\n", url); |
3589 | 3589 |
continue; |
3590 | 3590 |
} |
3591 |
+ /* |
|
3592 |
+ * What about foreign character spoofing? |
|
3593 |
+ * It would be useful be able to check if url |
|
3594 |
+ * is the same as the text displayed, e.g. |
|
3595 |
+ * <a href="http://dodgy.biz">www.paypal.com</a> |
|
3596 |
+ * but that needs support from HTML normalise |
|
3597 |
+ */ |
|
3598 |
+ if(strchr(url, '%') && strchr(url, '@')) |
|
3599 |
+ cli_warnmsg("Possible URL spoofing attempt noticed, but not yet handled (%s)\n", url); |
|
3600 |
+ |
|
3591 | 3601 |
if(n == FOLLOWURLS) { |
3592 |
- cli_warnmsg("Not all URLs will be scanned\n"); |
|
3602 |
+ cli_warnmsg("URL %s will not be scanned\n", url); |
|
3593 | 3603 |
break; |
3594 | 3604 |
} |
3605 |
+ |
|
3595 | 3606 |
(void)tableInsert(t, url, 1); |
3596 | 3607 |
cli_dbgmsg("Downloading URL %s to be scanned\n", url); |
3597 | 3608 |
strncpy(name, url, sizeof(name) - 1); |
... | ... |
@@ -3619,18 +3822,12 @@ checkURLs(message *m, const char *dir) |
3619 | 3619 |
*/ |
3620 | 3620 |
len = sizeof(cmd) - 26 - strlen(dir) - strlen(name); |
3621 | 3621 |
#ifdef CL_DEBUG |
3622 |
- snprintf(cmd, sizeof(cmd) - 1, "GET -t10 %.*s >%s/%s", len, url, dir, name); |
|
3622 |
+ snprintf(cmd, sizeof(cmd) - 1, "GET -t10 \"%.*s\" >%s/%s", len, url, dir, name); |
|
3623 | 3623 |
#else |
3624 |
- snprintf(cmd, sizeof(cmd) - 1, "GET -t10 %.*s >%s/%s 2>/dev/null", len, url, dir, name); |
|
3624 |
+ snprintf(cmd, sizeof(cmd) - 1, "GET -t10 \"%.*s\" >%s/%s 2>/dev/null", len, url, dir, name); |
|
3625 | 3625 |
#endif |
3626 | 3626 |
cmd[sizeof(cmd) - 1] = '\0'; |
3627 | 3627 |
|
3628 |
-#ifndef WITH_CURL |
|
3629 |
- for(ptr = cmd; *ptr; ptr++) |
|
3630 |
- if(strchr(";&", *ptr)) |
|
3631 |
- *ptr = '_'; |
|
3632 |
-#endif |
|
3633 |
- |
|
3634 | 3628 |
cli_dbgmsg("%s\n", cmd); |
3635 | 3629 |
#ifdef CL_THREAD_SAFE |
3636 | 3630 |
pthread_mutex_lock(&system_mutex); |
... | ... |
@@ -3666,6 +3863,16 @@ checkURLs(message *m, const char *dir) |
3666 | 3666 |
html_tag_arg_free(&hrefs); |
3667 | 3667 |
} |
3668 | 3668 |
|
3669 |
+/* |
|
3670 |
+ * Includes some Win32 patches by Gianluigi Tiesi <sherpya@netfarm.it> |
|
3671 |
+ * |
|
3672 |
+ * FIXME: Often WMF exploits work by sending people an email directing them |
|
3673 |
+ * to a page which displays a picture containing the exploit. This is not |
|
3674 |
+ * currently found, since only the HTML on the referred page is downloaded. |
|
3675 |
+ * It would be useful to scan the HTML for references to pictures and |
|
3676 |
+ * download them for scanning. But that will hit performance so there is |
|
3677 |
+ * an issue here. |
|
3678 |
+ */ |
|
3669 | 3679 |
#ifdef WITH_CURL |
3670 | 3680 |
static void * |
3671 | 3681 |
#ifdef CL_THREAD_SAFE |
... | ... |
@@ -3687,17 +3894,20 @@ getURL(struct arg *arg) |
3687 | 3687 |
const char *filename = arg->filename; |
3688 | 3688 |
char fout[NAME_MAX + 1]; |
3689 | 3689 |
#ifdef CURLOPT_ERRORBUFFER |
3690 |
- char errorbuffer[128]; |
|
3690 |
+ char errorbuffer[CURL_ERROR_SIZE]; |
|
3691 |
+#elif (LIBCURL_VERSION_NUM >= 0x070C00) |
|
3692 |
+ CURLcode res = CURLE_OK; |
|
3691 | 3693 |
#endif |
3692 | 3694 |
|
3693 | 3695 |
#ifdef CL_THREAD_SAFE |
3694 | 3696 |
pthread_mutex_lock(&init_mutex); |
3695 | 3697 |
#endif |
3696 | 3698 |
if(!initialised) { |
3697 |
- if(curl_global_init(CURL_GLOBAL_NOTHING) != 0) { |
|
3699 |
+ if(curl_global_init(CURL_GLOBAL_ALL) != 0) { |
|
3698 | 3700 |
#ifdef CL_THREAD_SAFE |
3699 | 3701 |
pthread_mutex_unlock(&init_mutex); |
3700 | 3702 |
#endif |
3703 |
+ cli_errmsg("curl_global_init failed"); |
|
3701 | 3704 |
return NULL; |
3702 | 3705 |
} |
3703 | 3706 |
initialised = 1; |
... | ... |
@@ -3708,17 +3918,22 @@ getURL(struct arg *arg) |
3708 | 3708 |
|
3709 | 3709 |
/* easy isn't the word I'd use... */ |
3710 | 3710 |
curl = curl_easy_init(); |
3711 |
- if(curl == NULL) |
|
3711 |
+ if(curl == NULL) { |
|
3712 |
+ cli_errmsg("curl_easy_init failed"); |
|
3712 | 3713 |
return NULL; |
3714 |
+ } |
|
3713 | 3715 |
|
3714 | 3716 |
(void)curl_easy_setopt(curl, CURLOPT_USERAGENT, "www.clamav.net"); |
3715 | 3717 |
|
3716 |
- if(curl_easy_setopt(curl, CURLOPT_URL, url) != 0) |
|
3718 |
+ if(curl_easy_setopt(curl, CURLOPT_URL, url) != 0) { |
|
3719 |
+ cli_errmsg("%s: curl_easy_setopt failed", url); |
|
3720 |
+ curl_easy_cleanup(curl); |
|
3717 | 3721 |
return NULL; |
3722 |
+ } |
|
3718 | 3723 |
|
3719 | 3724 |
snprintf(fout, NAME_MAX, "%s/%s", dir, filename); |
3720 | 3725 |
|
3721 |
- fp = fopen(fout, "w"); |
|
3726 |
+ fp = fopen(fout, "wb"); |
|
3722 | 3727 |
|
3723 | 3728 |
if(fp == NULL) { |
3724 | 3729 |
cli_errmsg("Can't open '%s' for writing", fout); |
... | ... |
@@ -3765,10 +3980,6 @@ getURL(struct arg *arg) |
3765 | 3765 |
*/ |
3766 | 3766 |
curl_easy_setopt(curl, CURLOPT_USERPWD, "username:password"); |
3767 | 3767 |
|
3768 |
-#ifdef CURLOPT_ERRORBUFFER |
|
3769 |
- curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorbuffer); |
|
3770 |
-#endif |
|
3771 |
- |
|
3772 | 3768 |
/* |
3773 | 3769 |
* FIXME: valgrind reports "pthread_mutex_unlock: mutex is not locked" |
3774 | 3770 |
* from gethostbyaddr_r within this. It may be a bug in libcurl |
... | ... |
@@ -3777,24 +3988,31 @@ getURL(struct arg *arg) |
3777 | 3777 |
* Conditional jump or move depends on uninitialised value(s) and |
3778 | 3778 |
* quit. But the program seems to work OK without valgrind... |
3779 | 3779 |
* Perhaps Curl_resolv() isn't thread safe? |
3780 |
+ * |
|
3781 |
+ * I have seen segfaults in version 7.12.3. Version 7.14 seems OK. |
|
3780 | 3782 |
*/ |
3781 | 3783 |
/* |
3782 | 3784 |
* On some C libraries (notably with FC3, glibc-2.3.3-74) you get a |
3783 |
- * memory leak * here in getaddrinfo(), see |
|
3785 |
+ * memory leak here in getaddrinfo(), see |
|
3784 | 3786 |
* https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=139559 |
3785 | 3787 |
*/ |
3786 |
- |
|
3787 |
- if(curl_easy_perform(curl) != CURLE_OK) { |
|
3788 | 3788 |
#ifdef CURLOPT_ERRORBUFFER |
3789 |
+ curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorbuffer); |
|
3790 |
+ |
|
3791 |
+ if(curl_easy_perform(curl) != CURLE_OK) |
|
3789 | 3792 |
cli_warnmsg("URL %s failed to download: %s\n", url, errorbuffer); |
3793 |
+#elif (LIBCURL_VERSION_NUM >= 0x070C00) |
|
3794 |
+ if((res = curl_easy_perform(curl)) != CURLE_OK) |
|
3795 |
+ cli_warnmsg("URL %s failed to download: %s\n", url, |
|
3796 |
+ curl_easy_strerror(res)); |
|
3790 | 3797 |
#else |
3798 |
+ if(curl_easy_perform(curl) != CURLE_OK) |
|
3791 | 3799 |
cli_warnmsg("URL %s failed to download\n", url); |
3792 | 3800 |
#endif |
3793 |
- } |
|
3794 | 3801 |
|
3795 | 3802 |
fclose(fp); |
3796 |
- curl_slist_free_all(headers); |
|
3797 | 3803 |
curl_easy_cleanup(curl); |
3804 |
+ curl_slist_free_all(headers); |
|
3798 | 3805 |
|
3799 | 3806 |
return NULL; |
3800 | 3807 |
} |
... | ... |
@@ -3866,52 +4084,6 @@ usefulHeader(int commandNumber, const char *cmd) |
3866 | 3866 |
} |
3867 | 3867 |
|
3868 | 3868 |
/* |
3869 |
- * Save the uuencoded part of the file as it is read in since there's no need |
|
3870 |
- * to include it in the parse tree. Saves memory and parse time. |
|
3871 |
- * Return < 0 for failure |
|
3872 |
- */ |
|
3873 |
-static int |
|
3874 |
-uufasttrack(message *m, const char *firstline, const char *dir, FILE *fin) |
|
3875 |
-{ |
|
3876 |
- fileblob *fb = fileblobCreate(); |
|
3877 |
- char buffer[LINE_LENGTH + 1]; |
|
3878 |
- char *filename = cli_strtok(firstline, 2, " "); |
|
3879 |
- |
|
3880 |
- if(filename == NULL) |
|
3881 |
- return -1; |
|
3882 |
- |
|
3883 |
- fileblobSetFilename(fb, dir, filename); |
|
3884 |
- cli_dbgmsg("Fast track uudecode %s\n", filename); |
|
3885 |
- free(filename); |
|
3886 |
- |
|
3887 |
- while(fgets(buffer, sizeof(buffer) - 1, fin) != NULL) { |
|
3888 |
- unsigned char data[1024]; |
|
3889 |
- const unsigned char *uptr; |
|
3890 |
- size_t len; |
|
3891 |
- |
|
3892 |
- cli_chomp(buffer); |
|
3893 |
- if(strcasecmp(buffer, "end") == 0) |
|
3894 |
- break; |
|
3895 |
- if(buffer[0] == '\0') |
|
3896 |
- break; |
|
3897 |
- |
|
3898 |
- uptr = decodeLine(m, UUENCODE, buffer, data, sizeof(data)); |
|
3899 |
- if(uptr == NULL) |
|
3900 |
- break; |
|
3901 |
- |
|
3902 |
- len = (size_t)(uptr - data); |
|
3903 |
- if((len > 62) || (len == 0)) |
|
3904 |
- break; |
|
3905 |
- |
|
3906 |
- if(fileblobAddData(fb, data, len) < 0) |
|
3907 |
- break; |
|
3908 |
- } |
|
3909 |
- |
|
3910 |
- fileblobDestroy(fb); |
|
3911 |
- return 1; |
|
3912 |
-} |
|
3913 |
- |
|
3914 |
-/* |
|
3915 | 3869 |
* Like fgets but cope with end of line by "\n", "\r\n", "\n\r", "\r" |
3916 | 3870 |
*/ |
3917 | 3871 |
static char * |
... | ... |
@@ -3943,7 +4115,7 @@ getline_from_mbox(char *buffer, size_t len, FILE *fin) |
3943 | 3943 |
ungetc(c, fin); |
3944 | 3944 |
break; |
3945 | 3945 |
default: |
3946 |
- *buffer++ = c; |
|
3946 |
+ *buffer++ = (char)c; |
|
3947 | 3947 |
continue; |
3948 | 3948 |
case EOF: |
3949 | 3949 |
break; |
... | ... |
@@ -3955,56 +4127,17 @@ getline_from_mbox(char *buffer, size_t len, FILE *fin) |
3955 | 3955 |
break; |
3956 | 3956 |
} |
3957 | 3957 |
break; |
3958 |
- } while(--len > 0); |
|
3958 |
+ } while(--len > 1); |
|
3959 | 3959 |
|
3960 | 3960 |
if(len == 0) { |
3961 |
- /* probably, the email breaks RFC821 */ |
|
3962 |
- cli_dbgmsg("getline_from_mbox: buffer overflow stopped\n"); |
|
3961 |
+ /* the email probably breaks RFC821 */ |
|
3962 |
+ cli_warnmsg("getline_from_mbox: buffer overflow stopped - line lost\n"); |
|
3963 | 3963 |
return NULL; |
3964 | 3964 |
} |
3965 |
+ if(len == 1) |
|
3966 |
+ /* over flows will have appear on separate lines */ |
|
3967 |
+ cli_dbgmsg("getline_from_mbox: buffer overflow stopped - line recovered\n"); |
|
3965 | 3968 |
*buffer = '\0'; |
3966 | 3969 |
|
3967 | 3970 |
return ret; |
3968 | 3971 |
} |
3969 |
- |
|
3970 |
-#ifdef NEW_WORLD |
|
3971 |
-/* |
|
3972 |
- * like cli_memstr - but returns the location of the match |
|
3973 |
- * FIXME: need a case insensitive version |
|
3974 |
- */ |
|
3975 |
-static const char * |
|
3976 |
-cli_pmemstr(const char *haystack, size_t hs, const char *needle, size_t ns) |
|
3977 |
-{ |
|
3978 |
- const char *pt, *hay; |
|
3979 |
- size_t n; |
|
3980 |
- |
|
3981 |
- if(haystack == needle) |
|
3982 |
- return haystack; |
|
3983 |
- |
|
3984 |
- if(hs < ns) |
|
3985 |
- return NULL; |
|
3986 |
- |
|
3987 |
- if(memcmp(haystack, needle, ns) == 0) |
|
3988 |
- return haystack; |
|
3989 |
- |
|
3990 |
- pt = hay = haystack; |
|
3991 |
- n = hs; |
|
3992 |
- |
|
3993 |
- while((pt = memchr(hay, needle[0], n)) != NULL) { |
|
3994 |
- n -= (int) pt - (int) hay; |
|
3995 |
- if(n < ns) |
|
3996 |
- break; |
|
3997 |
- |
|
3998 |
- if(memcmp(pt, needle, ns) == 0) |
|
3999 |
- return pt; |
|
4000 |
- |
|
4001 |
- if(hay == pt) { |
|
4002 |
- n--; |
|
4003 |
- hay++; |
|
4004 |
- } else |
|
4005 |
- hay = pt; |
|
4006 |
- } |
|
4007 |
- |
|
4008 |
- return NULL; |
|
4009 |
-} |
|
4010 |
-#endif |
... | ... |
@@ -74,8 +74,6 @@ pthread_mutex_t cli_gentemp_mutex = PTHREAD_MUTEX_INITIALIZER; |
74 | 74 |
|
75 | 75 |
#define CL_FLEVEL 7 /* don't touch it */ |
76 | 76 |
|
77 |
-#define MAX_ALLOCATION 134217728 |
|
78 |
- |
|
79 | 77 |
short cli_debug_flag = 0, cli_leavetemps_flag = 0; |
80 | 78 |
|
81 | 79 |
static unsigned char oldmd5buff[16] = { 16, 38, 97, 12, 8, 4, 72, 196, 217, 144, 33, 124, 18, 11, 17, 253 }; |
... | ... |
@@ -306,15 +304,15 @@ void *cli_malloc(size_t size) |
306 | 306 |
void *alloc; |
307 | 307 |
|
308 | 308 |
|
309 |
- if(!size || size > MAX_ALLOCATION) { |
|
310 |
- cli_errmsg("Attempt to allocate %d bytes. Please report to bugs@clamav.net\n", size); |
|
309 |
+ if(!size || size > CLI_MAX_ALLOCATION) { |
|
310 |
+ cli_errmsg("Attempt to allocate %u bytes. Please report to bugs@clamav.net\n", size); |
|
311 | 311 |
return NULL; |
312 | 312 |
} |
313 | 313 |
|
314 | 314 |
alloc = malloc(size); |
315 | 315 |
|
316 | 316 |
if(!alloc) { |
317 |
- cli_errmsg("cli_malloc(): Can't allocate memory (%d bytes).\n", size); |
|
317 |
+ cli_errmsg("cli_malloc(): Can't allocate memory (%u bytes).\n", size); |
|
318 | 318 |
perror("malloc_problem"); |
319 | 319 |
/* _exit(1); */ |
320 | 320 |
return NULL; |
... | ... |
@@ -326,15 +324,15 @@ void *cli_calloc(size_t nmemb, size_t size) |
326 | 326 |
void *alloc; |
327 | 327 |
|
328 | 328 |
|
329 |
- if(!size || size > MAX_ALLOCATION) { |
|
330 |
- cli_errmsg("Attempt to allocate %d bytes. Please report to bugs@clamav.net\n", size); |
|
329 |
+ if(!size || size > CLI_MAX_ALLOCATION) { |
|
330 |
+ cli_errmsg("Attempt to allocate %u bytes. Please report to bugs@clamav.net\n", size); |
|
331 | 331 |
return NULL; |
332 | 332 |
} |
333 | 333 |
|
334 | 334 |
alloc = calloc(nmemb, size); |
335 | 335 |
|
336 | 336 |
if(!alloc) { |
337 |
- cli_errmsg("cli_calloc(): Can't allocate memory (%d bytes).\n", nmemb * size); |
|
337 |
+ cli_errmsg("cli_calloc(): Can't allocate memory (%u bytes).\n", nmemb * size); |
|
338 | 338 |
perror("calloc_problem"); |
339 | 339 |
/* _exit(1); */ |
340 | 340 |
return NULL; |
... | ... |
@@ -346,15 +344,15 @@ void *cli_realloc(void *ptr, size_t size) |
346 | 346 |
void *alloc; |
347 | 347 |
|
348 | 348 |
|
349 |
- if(!size || size > MAX_ALLOCATION) { |
|
350 |
- cli_errmsg("Attempt to allocate %d bytes. Please report to bugs@clamav.net\n", size); |
|
349 |
+ if(!size || size > CLI_MAX_ALLOCATION) { |
|
350 |
+ cli_errmsg("Attempt to allocate %u bytes. Please report to bugs@clamav.net\n", size); |
|
351 | 351 |
return NULL; |
352 | 352 |
} |
353 | 353 |
|
354 | 354 |
alloc = realloc(ptr, size); |
355 | 355 |
|
356 | 356 |
if(!alloc) { |
357 |
- cli_errmsg("cli_realloc(): Can't re-allocate memory to %d byte.\n", size); |
|
357 |
+ cli_errmsg("cli_realloc(): Can't re-allocate memory to %u byte.\n", size); |
|
358 | 358 |
perror("realloc_problem"); |
359 | 359 |
return NULL; |
360 | 360 |
} else return alloc; |
... | ... |
@@ -700,6 +698,10 @@ int cli_bitset_test(bitset_t *bs, unsigned long bit_offset) |
700 | 700 |
|
701 | 701 |
char_offset = bit_offset / BITS_PER_CHAR; |
702 | 702 |
bit_offset = bit_offset % BITS_PER_CHAR; |
703 |
- |
|
703 |
+ |
|
704 |
+ if (char_offset >= bs->length) { |
|
705 |
+ return FALSE; |
|
706 |
+ } |
|
707 |
+ |
|
704 | 708 |
return (bs->bitset[char_offset] & ((unsigned char)1 << bit_offset)); |
705 | 709 |
} |
... | ... |
@@ -27,6 +27,12 @@ |
27 | 27 |
(bb_size > 0 && sb_size > 0 && sb_size <= bb_size \ |
28 | 28 |
&& sb >= bb && sb + sb_size <= bb + bb_size && sb + sb_size > bb) |
29 | 29 |
|
30 |
+#define CLI_ISCONTAINED2(bb, bb_size, sb, sb_size) \ |
|
31 |
+ (bb_size > 0 && sb_size >= 0 && sb_size <= bb_size \ |
|
32 |
+ && sb >= bb && sb + sb_size <= bb + bb_size && sb + sb_size >= bb) |
|
33 |
+ |
|
34 |
+#define CLI_MAX_ALLOCATION 134217728 |
|
35 |
+ |
|
30 | 36 |
typedef struct bitset_tag { |
31 | 37 |
unsigned char *bitset; |
32 | 38 |
unsigned long length; |
... | ... |
@@ -315,16 +315,18 @@ int cli_scanpe(int desc, const char **virname, unsigned long int *scanned, const |
315 | 315 |
} |
316 | 316 |
|
317 | 317 |
nsections = EC16(file_hdr.NumberOfSections); |
318 |
- if(nsections < 1) { |
|
318 |
+ if(nsections < 1 || nsections > 99) { |
|
319 | 319 |
if(DETECT_BROKEN) { |
320 | 320 |
if(virname) |
321 | 321 |
*virname = "Broken.Executable"; |
322 | 322 |
return CL_VIRUS; |
323 | 323 |
} |
324 |
- cli_warnmsg("PE file contains no sections\n"); |
|
324 |
+ if(nsections) |
|
325 |
+ cli_warnmsg("PE file contains %d sections\n", nsections); |
|
326 |
+ else |
|
327 |
+ cli_warnmsg("PE file contains no sections\n"); |
|
325 | 328 |
return CL_CLEAN; |
326 | 329 |
} |
327 |
- |
|
328 | 330 |
cli_dbgmsg("NumberOfSections: %d\n", nsections); |
329 | 331 |
|
330 | 332 |
timestamp = (time_t) EC32(file_hdr.TimeDateStamp); |
... | ... |
@@ -591,7 +593,7 @@ int cli_scanpe(int desc, const char **virname, unsigned long int *scanned, const |
591 | 591 |
uint32_t newesi, newedi, newebx, newedx; |
592 | 592 |
|
593 | 593 |
if(limits && limits->maxfilesize && (ssize > limits->maxfilesize || dsize > limits->maxfilesize)) { |
594 |
- cli_dbgmsg("FSG: Sizes exceeded (ssize: %d, dsize: %d, max: %lu)\n", ssize, dsize , limits->maxfilesize); |
|
594 |
+ cli_dbgmsg("FSG: Sizes exceeded (ssize: %u, dsize: %u, max: %lu)\n", ssize, dsize , limits->maxfilesize); |
|
595 | 595 |
free(section_hdr); |
596 | 596 |
if(BLOCKMAX) { |
597 | 597 |
*virname = "PE.FSG.ExceededFileSize"; |
... | ... |
@@ -745,7 +747,7 @@ int cli_scanpe(int desc, const char **virname, unsigned long int *scanned, const |
745 | 745 |
|
746 | 746 |
|
747 | 747 |
if(limits && limits->maxfilesize && (ssize > limits->maxfilesize || dsize > limits->maxfilesize)) { |
748 |
- cli_dbgmsg("FSG: Sizes exceeded (ssize: %d, dsize: %d, max: %lu)\n", ssize, dsize, limits->maxfilesize); |
|
748 |
+ cli_dbgmsg("FSG: Sizes exceeded (ssize: %u, dsize: %u, max: %lu)\n", ssize, dsize, limits->maxfilesize); |
|
749 | 749 |
free(section_hdr); |
750 | 750 |
if(BLOCKMAX) { |
751 | 751 |
*virname = "PE.FSG.ExceededFileSize"; |
... | ... |
@@ -965,7 +967,7 @@ int cli_scanpe(int desc, const char **virname, unsigned long int *scanned, const |
965 | 965 |
} |
966 | 966 |
|
967 | 967 |
if(limits && limits->maxfilesize && (ssize > limits->maxfilesize || dsize > limits->maxfilesize)) { |
968 |
- cli_dbgmsg("FSG: Sizes exceeded (ssize: %d, dsize: %d, max: %lu)\n", ssize, dsize, limits->maxfilesize); |
|
968 |
+ cli_dbgmsg("FSG: Sizes exceeded (ssize: %u, dsize: %u, max: %lu)\n", ssize, dsize, limits->maxfilesize); |
|
969 | 969 |
free(section_hdr); |
970 | 970 |
if(BLOCKMAX) { |
971 | 971 |
*virname = "PE.FSG.ExceededFileSize"; |
... | ... |
@@ -1155,7 +1157,7 @@ int cli_scanpe(int desc, const char **virname, unsigned long int *scanned, const |
1155 | 1155 |
dsize = EC32(section_hdr[i].VirtualSize) + EC32(section_hdr[i + 1].VirtualSize); |
1156 | 1156 |
|
1157 | 1157 |
if(limits && limits->maxfilesize && (ssize > limits->maxfilesize || dsize > limits->maxfilesize)) { |
1158 |
- cli_dbgmsg("UPX: Sizes exceeded (ssize: %d, dsize: %d, max: %lu)\n", ssize, dsize , limits->maxfilesize); |
|
1158 |
+ cli_dbgmsg("UPX: Sizes exceeded (ssize: %u, dsize: %u, max: %lu)\n", ssize, dsize , limits->maxfilesize); |
|
1159 | 1159 |
free(section_hdr); |
1160 | 1160 |
if(BLOCKMAX) { |
1161 | 1161 |
*virname = "PE.UPX.ExceededFileSize"; |
... | ... |
@@ -1177,6 +1179,13 @@ int cli_scanpe(int desc, const char **virname, unsigned long int *scanned, const |
1177 | 1177 |
return CL_EMEM; |
1178 | 1178 |
} |
1179 | 1179 |
|
1180 |
+ if(dsize > CLI_MAX_ALLOCATION) { |
|
1181 |
+ cli_errmsg("UPX: Too big value of dsize\n"); |
|
1182 |
+ free(section_hdr); |
|
1183 |
+ free(src); |
|
1184 |
+ return CL_EMEM; |
|
1185 |
+ } |
|
1186 |
+ |
|
1180 | 1187 |
if((dest = (char *) cli_calloc(dsize + 1024 + nsections * 40, sizeof(char))) == NULL) { |
1181 | 1188 |
free(section_hdr); |
1182 | 1189 |
free(src); |
... | ... |
@@ -1349,7 +1358,7 @@ int cli_scanpe(int desc, const char **virname, unsigned long int *scanned, const |
1349 | 1349 |
dsize = max - min; |
1350 | 1350 |
|
1351 | 1351 |
if(limits && limits->maxfilesize && dsize > limits->maxfilesize) { |
1352 |
- cli_dbgmsg("Petite: Size exceeded (dsize: %d, max: %lu)\n", dsize, limits->maxfilesize); |
|
1352 |
+ cli_dbgmsg("Petite: Size exceeded (dsize: %u, max: %lu)\n", dsize, limits->maxfilesize); |
|
1353 | 1353 |
free(section_hdr); |
1354 | 1354 |
if(BLOCKMAX) { |
1355 | 1355 |
*virname = "PE.Petite.ExceededFileSize"; |
... | ... |
@@ -1,5 +1,5 @@ |
1 | 1 |
/* |
2 |
- * Copyright (C) 2002 - 2005 Tomasz Kojm <tkojm@clamav.net> |
|
2 |
+ * Copyright (C) 2002 - 2006 Tomasz Kojm <tkojm@clamav.net> |
|
3 | 3 |
* |
4 | 4 |
* This program is free software; you can redistribute it and/or modify |
5 | 5 |
* it under the terms of the GNU General Public License as published by |
... | ... |
@@ -1350,7 +1350,7 @@ static int cli_scanmail(int desc, const char **virname, unsigned long int *scann |
1350 | 1350 |
|
1351 | 1351 |
static int cli_scanraw(int desc, const char **virname, unsigned long int *scanned, const struct cl_node *root, const struct cl_limits *limits, unsigned int options, unsigned int arec, unsigned int mrec, cli_file_t type) |
1352 | 1352 |
{ |
1353 |
- int typerec = 0, ret = CL_CLEAN; |
|
1353 |
+ int typerec = 0, ret = CL_CLEAN, nret = CL_CLEAN; |
|
1354 | 1354 |
|
1355 | 1355 |
|
1356 | 1356 |
if(type == CL_TYPE_UNKNOWN_TEXT) |
... | ... |
@@ -1375,17 +1375,18 @@ static int cli_scanraw(int desc, const char **virname, unsigned long int *scanne |
1375 | 1375 |
switch(ret) { |
1376 | 1376 |
case CL_TYPE_HTML: |
1377 | 1377 |
if(SCAN_HTML) |
1378 |
- if(cli_scanhtml(desc, virname, scanned, root, limits, options, arec, mrec) == CL_VIRUS) |
|
1378 |
+ if((nret = cli_scanhtml(desc, virname, scanned, root, limits, options, arec, mrec)) == CL_VIRUS) |
|
1379 | 1379 |
return CL_VIRUS; |
1380 | 1380 |
break; |
1381 | 1381 |
|
1382 | 1382 |
case CL_TYPE_MAIL: |
1383 | 1383 |
if(SCAN_MAIL) |
1384 |
- if(cli_scanmail(desc, virname, scanned, root, limits, options, arec, mrec) == CL_VIRUS) |
|
1384 |
+ if((nret = cli_scanmail(desc, virname, scanned, root, limits, options, arec, mrec)) == CL_VIRUS) |
|
1385 | 1385 |
return CL_VIRUS; |
1386 | 1386 |
break; |
1387 | 1387 |
} |
1388 | 1388 |
ret == CL_TYPE_MAIL ? mrec-- : arec--; |
1389 |
+ ret = nret; |
|
1389 | 1390 |
} |
1390 | 1391 |
|
1391 | 1392 |
return ret; |
... | ... |
@@ -1549,7 +1550,7 @@ int cli_magic_scandesc(int desc, const char **virname, unsigned long int *scanne |
1549 | 1549 |
type == CL_TYPE_MAIL ? mrec-- : arec--; |
1550 | 1550 |
|
1551 | 1551 |
if(type != CL_TYPE_DATA && ret != CL_VIRUS && !root->sdb) { |
1552 |
- if((ret = cli_scanraw(desc, virname, scanned, root, limits, options, arec, mrec, type) == CL_VIRUS)) |
|
1552 |
+ if(cli_scanraw(desc, virname, scanned, root, limits, options, arec, mrec, type) == CL_VIRUS) |
|
1553 | 1553 |
return CL_VIRUS; |
1554 | 1554 |
} |
1555 | 1555 |
|
... | ... |
@@ -24,7 +24,7 @@ |
24 | 24 |
#include "clamav-config.h" |
25 | 25 |
#endif |
26 | 26 |
|
27 |
-static char const rcsid[] = "$Id: tnef.c,v 1.26 2005/07/11 15:01:40 nigelhorne Exp $"; |
|
27 |
+static char const rcsid[] = "$Id: tnef.c,v 1.31 2006/03/14 11:39:43 nigelhorne Exp $"; |
|
28 | 28 |
|
29 | 29 |
#include <stdio.h> |
30 | 30 |
#include <fcntl.h> |
... | ... |
@@ -38,8 +38,8 @@ static char const rcsid[] = "$Id: tnef.c,v 1.26 2005/07/11 15:01:40 nigelhorne E |
38 | 38 |
#endif |
39 | 39 |
#include "blob.h" |
40 | 40 |
|
41 |
-static int tnef_message(FILE *fp, uint16_t type, uint16_t tag, int32_t length); |
|
42 |
-static int tnef_attachment(FILE *fp, uint16_t type, uint16_t tag, int32_t length, const char *dir, fileblob **fbref); |
|
41 |
+static int tnef_message(FILE *fp, uint16_t type, uint16_t tag, int32_t length, off_t fsize); |
|
42 |
+static int tnef_attachment(FILE *fp, uint16_t type, uint16_t tag, int32_t length, const char *dir, fileblob **fbref, off_t fsize); |
|
43 | 43 |
static int tnef_header(FILE *fp, uint8_t *part, uint16_t *type, uint16_t *tag, int32_t *length); |
44 | 44 |
|
45 | 45 |
#define TNEF_SIGNATURE 0x223E9f78 |
... | ... |
@@ -73,9 +73,17 @@ cli_tnef(const char *dir, int desc) |
73 | 73 |
fileblob *fb; |
74 | 74 |
int i, ret, alldone; |
75 | 75 |
FILE *fp; |
76 |
+ off_t fsize; |
|
77 |
+ struct stat statb; |
|
76 | 78 |
|
77 | 79 |
lseek(desc, 0L, SEEK_SET); |
78 | 80 |
|
81 |
+ if(fstat(desc, &statb) < 0) { |
|
82 |
+ cli_errmsg("Can't fstat descriptor %d\n", desc); |
|
83 |
+ return CL_EIO; |
|
84 |
+ } |
|
85 |
+ fsize = statb.st_size; |
|
86 |
+ |
|
79 | 87 |
i = dup(desc); |
80 | 88 |
if((fp = fdopen(i, "rb")) == NULL) { |
81 | 89 |
cli_errmsg("Can't open descriptor %d\n", desc); |
... | ... |
@@ -102,9 +110,9 @@ cli_tnef(const char *dir, int desc) |
102 | 102 |
alldone = 0; |
103 | 103 |
|
104 | 104 |
do { |
105 |
- uint8_t part; |
|
106 |
- uint16_t type, tag; |
|
107 |
- int32_t length; |
|
105 |
+ uint8_t part = 0; |
|
106 |
+ uint16_t type = 0, tag = 0; |
|
107 |
+ int32_t length = 0; |
|
108 | 108 |
|
109 | 109 |
switch(tnef_header(fp, &part, &type, &tag, &length)) { |
110 | 110 |
case 0: |
... | ... |
@@ -121,6 +129,13 @@ cli_tnef(const char *dir, int desc) |
121 | 121 |
alldone = 1; |
122 | 122 |
break; |
123 | 123 |
} |
124 |
+ if(length == 0) |
|
125 |
+ continue; |
|
126 |
+ if(length < 0) { |
|
127 |
+ cli_warnmsg("Corrupt TNEF header detected - length %d\n", length); |
|
128 |
+ ret = CL_EFORMAT; |
|
129 |
+ break; |
|
130 |
+ } |
|
124 | 131 |
if(alldone) |
125 | 132 |
break; |
126 | 133 |
switch(part) { |
... | ... |
@@ -131,7 +146,7 @@ cli_tnef(const char *dir, int desc) |
131 | 131 |
fb = NULL; |
132 | 132 |
} |
133 | 133 |
fb = fileblobCreate(); |
134 |
- if(tnef_message(fp, type, tag, length) != 0) { |
|
134 |
+ if(tnef_message(fp, type, tag, length, fsize) != 0) { |
|
135 | 135 |
cli_errmsg("Error reading TNEF message\n"); |
136 | 136 |
ret = CL_EFORMAT; |
137 | 137 |
alldone = 1; |
... | ... |
@@ -139,7 +154,7 @@ cli_tnef(const char *dir, int desc) |
139 | 139 |
break; |
140 | 140 |
case LVL_ATTACHMENT: |
141 | 141 |
cli_dbgmsg("TNEF - found attachment\n"); |
142 |
- if(tnef_attachment(fp, type, tag, length, dir, &fb) != 0) { |
|
142 |
+ if(tnef_attachment(fp, type, tag, length, dir, &fb, fsize) != 0) { |
|
143 | 143 |
cli_errmsg("Error reading TNEF message\n"); |
144 | 144 |
ret = CL_EFORMAT; |
145 | 145 |
alldone = 1; |
... | ... |
@@ -149,7 +164,7 @@ cli_tnef(const char *dir, int desc) |
149 | 149 |
break; |
150 | 150 |
default: |
151 | 151 |
cli_warnmsg("TNEF - unknown level %d tag 0x%x\n", (int)part, (int)tag); |
152 |
- |
|
152 |
+ |
|
153 | 153 |
/* |
154 | 154 |
* Dump the file incase it was part of an |
155 | 155 |
* email that's about to be deleted |
... | ... |
@@ -188,7 +203,7 @@ cli_tnef(const char *dir, int desc) |
188 | 188 |
if(fb) { |
189 | 189 |
cli_dbgmsg("cli_tnef: flushing final data\n"); |
190 | 190 |
if(fileblobGetFilename(fb) == NULL) { |
191 |
- cli_dbgmsg("Saving TNEF portion with an unknown name"); |
|
191 |
+ cli_dbgmsg("Saving TNEF portion with an unknown name\n"); |
|
192 | 192 |
fileblobSetFilename(fb, dir, "tnef"); |
193 | 193 |
} |
194 | 194 |
fileblobDestroy(fb); |
... | ... |
@@ -200,10 +215,10 @@ cli_tnef(const char *dir, int desc) |
200 | 200 |
} |
201 | 201 |
|
202 | 202 |
static int |
203 |
-tnef_message(FILE *fp, uint16_t type, uint16_t tag, int32_t length) |
|
203 |
+tnef_message(FILE *fp, uint16_t type, uint16_t tag, int32_t length, off_t fsize) |
|
204 | 204 |
{ |
205 | 205 |
uint16_t i16; |
206 |
- /* off_t offset; */ |
|
206 |
+ off_t offset; |
|
207 | 207 |
#if CL_DEBUG |
208 | 208 |
uint32_t i32; |
209 | 209 |
char *string; |
... | ... |
@@ -211,7 +226,7 @@ tnef_message(FILE *fp, uint16_t type, uint16_t tag, int32_t length) |
211 | 211 |
|
212 | 212 |
cli_dbgmsg("message tag 0x%x, type 0x%x, length %d\n", tag, type, length); |
213 | 213 |
|
214 |
- /* offset = ftell(fp); */ |
|
214 |
+ offset = ftell(fp); |
|
215 | 215 |
|
216 | 216 |
/* |
217 | 217 |
* a lot of this stuff should be only discovered in debug mode... |
... | ... |
@@ -261,27 +276,31 @@ tnef_message(FILE *fp, uint16_t type, uint16_t tag, int32_t length) |
261 | 261 |
|
262 | 262 |
/*cli_dbgmsg("%lu %lu\n", (long)(offset + length), ftell(fp));*/ |
263 | 263 |
|
264 |
- /* fseek(fp, offset + length, SEEK_SET); */ |
|
264 |
+ if(!CLI_ISCONTAINED2(0, fsize, (off_t)offset, (off_t)length)) { |
|
265 |
+ cli_errmsg("TNEF: Incorrect length field\n"); |
|
266 |
+ return -1; |
|
267 |
+ } |
|
268 |
+ if(fseek(fp, offset + length, SEEK_SET) < 0) |
|
269 |
+ return -1; |
|
265 | 270 |
|
266 | 271 |
/* Checksum - TODO, verify */ |
267 |
- /* if(fread(&i16, sizeof(uint16_t), 1, fp) != 1) |
|
272 |
+ if(fread(&i16, sizeof(uint16_t), 1, fp) != 1) |
|
268 | 273 |
return -1; |
269 |
- */ |
|
270 | 274 |
|
271 | 275 |
return 0; |
272 | 276 |
} |
273 | 277 |
|
274 | 278 |
static int |
275 |
-tnef_attachment(FILE *fp, uint16_t type, uint16_t tag, int32_t length, const char *dir, fileblob **fbref) |
|
279 |
+tnef_attachment(FILE *fp, uint16_t type, uint16_t tag, int32_t length, const char *dir, fileblob **fbref, off_t fsize) |
|
276 | 280 |
{ |
277 | 281 |
uint32_t todo; |
278 | 282 |
uint16_t i16; |
279 |
-/* off_t offset; */ |
|
283 |
+ off_t offset; |
|
280 | 284 |
char *string; |
281 | 285 |
|
282 | 286 |
cli_dbgmsg("attachment tag 0x%x, type 0x%x, length %d\n", tag, type, length); |
283 | 287 |
|
284 |
- /* offset = ftell(fp); */ |
|
288 |
+ offset = ftell(fp); |
|
285 | 289 |
|
286 | 290 |
switch(tag) { |
287 | 291 |
case attATTACHTITLE: |
... | ... |
@@ -337,12 +356,16 @@ tnef_attachment(FILE *fp, uint16_t type, uint16_t tag, int32_t length, const cha |
337 | 337 |
|
338 | 338 |
/*cli_dbgmsg("%lu %lu\n", (long)(offset + length), ftell(fp));*/ |
339 | 339 |
|
340 |
- /* fseek(fp, (long)(offset + length), SEEK_SET); */ /* shouldn't be needed */ |
|
340 |
+ if(!CLI_ISCONTAINED2(0, fsize, (off_t)offset, (off_t)length)) { |
|
341 |
+ cli_errmsg("TNEF: Incorrect length field\n"); |
|
342 |
+ return -1; |
|
343 |
+ } |
|
344 |
+ if(fseek(fp, (long)(offset + length), SEEK_SET) < 0) /* shouldn't be needed */ |
|
345 |
+ return -1; |
|
341 | 346 |
|
342 | 347 |
/* Checksum - TODO, verify */ |
343 |
- /* if(fread(&i16, sizeof(uint16_t), 1, fp) != 1) |
|
348 |
+ if(fread(&i16, sizeof(uint16_t), 1, fp) != 1) |
|
344 | 349 |
return -1; |
345 |
- */ |
|
346 | 350 |
|
347 | 351 |
return 0; |
348 | 352 |
} |
... | ... |
@@ -362,8 +385,8 @@ tnef_header(FILE *fp, uint8_t *part, uint16_t *type, uint16_t *tag, int32_t *len |
362 | 362 |
return -1; |
363 | 363 |
|
364 | 364 |
i32 = host32(i32); |
365 |
- *tag = i32 & 0xFFFF; |
|
366 |
- *type = (i32 & 0xFFFF0000) >> 16; |
|
365 |
+ *tag = (uint16_t)(i32 & 0xFFFF); |
|
366 |
+ *type = (uint16_t)((i32 & 0xFFFF0000) >> 16); |
|
367 | 367 |
|
368 | 368 |
if(fread(&i32, sizeof(uint32_t), 1, fp) != 1) |
369 | 369 |
return -1; |
370 | 370 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,140 @@ |
0 |
+/* |
|
1 |
+ * Copyright (C) 2006 Nigel Horne <njh@bandsman.co.uk> |
|
2 |
+ * |
|
3 |
+ * This program is free software; you can redistribute it and/or modify |
|
4 |
+ * it under the terms of the GNU General Public License as published by |
|
5 |
+ * the Free Software Foundation; either version 2 of the License, or |
|
6 |
+ * (at your option) any later version. |
|
7 |
+ * |
|
8 |
+ * This program is distributed in the hope that it will be useful, |
|
9 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
10 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
11 |
+ * GNU General Public License for more details. |
|
12 |
+ * |
|
13 |
+ * You should have received a copy of the GNU General Public License |
|
14 |
+ * along with this program; if not, write to the Free Software |
|
15 |
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
|
16 |
+ */ |
|
17 |
+static char const rcsid[] = "$Id: uuencode.c,v 1.2 2006/01/23 10:35:38 nigelhorne Exp $"; |
|
18 |
+ |
|
19 |
+#include "clamav.h" |
|
20 |
+ |
|
21 |
+#if HAVE_CONFIG_H |
|
22 |
+#include "clamav-config.h" |
|
23 |
+#endif |
|
24 |
+ |
|
25 |
+#include <strings.h> |
|
26 |
+#include <stdio.h> |
|
27 |
+#include <memory.h> |
|
28 |
+#include <sys/stat.h> |
|
29 |
+#include "others.h" |
|
30 |
+#include "mbox.h" |
|
31 |
+#include "blob.h" |
|
32 |
+#include "line.h" |
|
33 |
+#include "text.h" |
|
34 |
+#include "message.h" |
|
35 |
+#include "uuencode.h" |
|
36 |
+#include "str.h" |
|
37 |
+ |
|
38 |
+/* Maximum line length according to RFC821 */ |
|
39 |
+#define RFC2821LENGTH 1000 |
|
40 |
+ |
|
41 |
+int |
|
42 |
+cli_uuencode(const char *dir, int desc) |
|
43 |
+{ |
|
44 |
+ FILE *fin; |
|
45 |
+ int i; |
|
46 |
+ message *m; |
|
47 |
+ char buffer[RFC2821LENGTH + 1]; |
|
48 |
+ |
|
49 |
+ i = dup(desc); |
|
50 |
+ if((fin = fdopen(i, "rb")) == NULL) { |
|
51 |
+ cli_errmsg("Can't open descriptor %d\n", desc); |
|
52 |
+ close(i); |
|
53 |
+ return CL_EOPEN; |
|
54 |
+ } |
|
55 |
+ if(fgets(buffer, sizeof(buffer) - 1, fin) == NULL) { |
|
56 |
+ /* empty message */ |
|
57 |
+ fclose(fin); |
|
58 |
+ return CL_CLEAN; |
|
59 |
+ } |
|
60 |
+ if(!isuuencodebegin(buffer)) { |
|
61 |
+ fclose(fin); |
|
62 |
+ cli_errmsg("Message is not in uuencoded format\n"); |
|
63 |
+ return CL_EFORMAT; |
|
64 |
+ } |
|
65 |
+ |
|
66 |
+ m = messageCreate(); |
|
67 |
+ if(m == NULL) { |
|
68 |
+ fclose(fin); |
|
69 |
+ return CL_EMEM; |
|
70 |
+ } |
|
71 |
+ |
|
72 |
+ cli_dbgmsg("found uuencode file\n"); |
|
73 |
+ |
|
74 |
+ if(uudecodeFile(m, buffer, dir, fin) < 0) { |
|
75 |
+ messageDestroy(m); |
|
76 |
+ fclose(fin); |
|
77 |
+ cli_errmsg("Message is not in uuencoded format\n"); |
|
78 |
+ return CL_EFORMAT; |
|
79 |
+ } |
|
80 |
+ messageDestroy(m); |
|
81 |
+ |
|
82 |
+ fclose(fin); |
|
83 |
+ |
|
84 |
+ return CL_CLEAN; /* a lie - but it gets things going */ |
|
85 |
+} |
|
86 |
+ |
|
87 |
+/* |
|
88 |
+ * Save the uuencoded part of the file as it is read in since there's no need |
|
89 |
+ * to include it in the parse tree. Saves memory and parse time. |
|
90 |
+ * Return < 0 for failure |
|
91 |
+ */ |
|
92 |
+int |
|
93 |
+uudecodeFile(message *m, const char *firstline, const char *dir, FILE *fin) |
|
94 |
+{ |
|
95 |
+ fileblob *fb; |
|
96 |
+ char buffer[RFC2821LENGTH + 1]; |
|
97 |
+ char *filename = cli_strtok(firstline, 2, " "); |
|
98 |
+ |
|
99 |
+ if(filename == NULL) |
|
100 |
+ return -1; |
|
101 |
+ |
|
102 |
+ fb = fileblobCreate(); |
|
103 |
+ if(fb == NULL) { |
|
104 |
+ free(filename); |
|
105 |
+ return -1; |
|
106 |
+ } |
|
107 |
+ |
|
108 |
+ fileblobSetFilename(fb, dir, filename); |
|
109 |
+ cli_dbgmsg("uudecode %s\n", filename); |
|
110 |
+ free(filename); |
|
111 |
+ |
|
112 |
+ while(fgets(buffer, sizeof(buffer) - 1, fin) != NULL) { |
|
113 |
+ unsigned char data[1024]; |
|
114 |
+ const unsigned char *uptr; |
|
115 |
+ size_t len; |
|
116 |
+ |
|
117 |
+ cli_chomp(buffer); |
|
118 |
+ if(strcasecmp(buffer, "end") == 0) |
|
119 |
+ break; |
|
120 |
+ if(buffer[0] == '\0') |
|
121 |
+ break; |
|
122 |
+ |
|
123 |
+ uptr = decodeLine(m, UUENCODE, buffer, data, sizeof(data)); |
|
124 |
+ if(uptr == NULL) |
|
125 |
+ break; |
|
126 |
+ |
|
127 |
+ len = (size_t)(uptr - data); |
|
128 |
+ if((len > 62) || (len == 0)) |
|
129 |
+ break; |
|
130 |
+ |
|
131 |
+ if(fileblobAddData(fb, data, len) < 0) |
|
132 |
+ break; |
|
133 |
+ } |
|
134 |
+ |
|
135 |
+ fileblobDestroy(fb); |
|
136 |
+ |
|
137 |
+ return 1; |
|
138 |
+} |
|
139 |
+ |
0 | 140 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,25 @@ |
0 |
+/* |
|
1 |
+ * Copyright (C) 2006 Nigel Horne <njh@bandsman.co.uk> |
|
2 |
+ * |
|
3 |
+ * This program is free software; you can redistribute it and/or modify |
|
4 |
+ * it under the terms of the GNU General Public License as published by |
|
5 |
+ * the Free Software Foundation; either version 2 of the License, or |
|
6 |
+ * (at your option) any later version. |
|
7 |
+ * |
|
8 |
+ * This program is distributed in the hope that it will be useful, |
|
9 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
10 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
11 |
+ * GNU General Public License for more details. |
|
12 |
+ * |
|
13 |
+ * You should have received a copy of the GNU General Public License |
|
14 |
+ * along with this program; if not, write to the Free Software |
|
15 |
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
|
16 |
+ */ |
|
17 |
+ |
|
18 |
+#ifndef __UUENCODE_H |
|
19 |
+#define __UUENCODE_H |
|
20 |
+ |
|
21 |
+int cli_uuencode(const char *dir, int desc); |
|
22 |
+int uudecodeFile(message *m, const char *firstline, const char *dir, FILE *fin); |
|
23 |
+ |
|
24 |
+#endif |
... | ... |
@@ -208,7 +208,7 @@ zzip_file_open(ZZIP_DIR * dir, zzip_char_t* name, int o_mode, int d_off) |
208 | 208 |
/* memset(zfp, 0, sizeof *fp); cleared in zzip_file_close() */ |
209 | 209 |
}else |
210 | 210 |
{ |
211 |
- if (! (fp = (ZZIP_FILE *)calloc(1, sizeof(*fp)))) |
|
211 |
+ if (! (fp = (ZZIP_FILE *)cli_calloc(1, sizeof(*fp)))) |
|
212 | 212 |
{ err = ZZIP_OUTOFMEM; goto error; } |
213 | 213 |
} |
214 | 214 |
|
... | ... |
@@ -220,7 +220,7 @@ zzip_file_open(ZZIP_DIR * dir, zzip_char_t* name, int o_mode, int d_off) |
220 | 220 |
{ fp->buf32k = dir->cache.buf32k; dir->cache.buf32k = NULL; } |
221 | 221 |
else |
222 | 222 |
{ |
223 |
- if (! (fp->buf32k = (char *)malloc(ZZIP_32K))) |
|
223 |
+ if (! (fp->buf32k = (char *)cli_malloc(ZZIP_32K))) |
|
224 | 224 |
{ err = ZZIP_OUTOFMEM; goto error; } |
225 | 225 |
} |
226 | 226 |
|
... | ... |
@@ -710,7 +710,7 @@ zzip_open_shared_io (ZZIP_FILE* stream, |
710 | 710 |
int fd = os->open(filename, o_flags); /* io->open */ |
711 | 711 |
if (fd != -1) |
712 | 712 |
{ |
713 |
- ZZIP_FILE* fp = calloc (1, sizeof(ZZIP_FILE)); |
|
713 |
+ ZZIP_FILE* fp = cli_calloc (1, sizeof(ZZIP_FILE)); |
|
714 | 714 |
if (!fp) { os->close(fd); return 0; } /* io->close */ |
715 | 715 |
|
716 | 716 |
fp->fd = fd; |
... | ... |
@@ -973,7 +973,7 @@ zzip_seek(ZZIP_FILE * fp, zzip_off_t offset, int whence) |
973 | 973 |
{ /* method == 8, inflate */ |
974 | 974 |
char *buf; |
975 | 975 |
/*FIXME: use a static buffer! */ |
976 |
- buf = (char *)malloc(ZZIP_32K); |
|
976 |
+ buf = (char *)cli_malloc(ZZIP_32K); |
|
977 | 977 |
if (! buf) return -1; |
978 | 978 |
|
979 | 979 |
while (read_size > 0) |
... | ... |
@@ -26,9 +26,9 @@ |
26 | 26 |
#include <stdlib.h> |
27 | 27 |
#include <string.h> |
28 | 28 |
#include <fcntl.h> |
29 |
-#ifdef ZZIP_HAVE_SYS_STAT_H |
|
29 |
+#include <sys/types.h> |
|
30 | 30 |
#include <sys/stat.h> |
31 |
-#endif |
|
31 |
+#include <unistd.h> |
|
32 | 32 |
|
33 | 33 |
/* |
34 | 34 |
#include "__mmap.h" |
... | ... |
@@ -185,7 +185,7 @@ __zzip_find_disk_trailer(int fd, zzip_off_t filesize, |
185 | 185 |
auto char buffer[2*ZZIP_BUFSIZ]; |
186 | 186 |
char* buf = buffer; |
187 | 187 |
#else |
188 |
- char* buf = malloc(2*ZZIP_BUFSIZ); |
|
188 |
+ char* buf = cli_malloc(2*ZZIP_BUFSIZ); |
|
189 | 189 |
#endif |
190 | 190 |
zzip_off_t offset = 0; |
191 | 191 |
zzip_off_t maplen = 0; /* mmap(),read(),getpagesize() use size_t !! */ |
... | ... |
@@ -349,12 +349,23 @@ __zzip_parse_root_directory(int fd, |
349 | 349 |
long offset; /* offset from start of root directory */ |
350 | 350 |
char* fd_map = 0; |
351 | 351 |
int32_t fd_gap = 0; |
352 |
+ struct stat sb; |
|
352 | 353 |
uint16_t u_entries = ZZIP_GET16(trailer->z_entries); |
353 | 354 |
uint32_t u_rootsize = ZZIP_GET32(trailer->z_rootsize); |
354 | 355 |
uint32_t u_rootseek = ZZIP_GET32(trailer->z_rootseek); |
355 | 356 |
__correct_rootseek (u_rootseek, u_rootsize, trailer); |
356 | 357 |
|
357 |
- hdr0 = (struct zzip_dir_hdr*) malloc(u_rootsize); |
|
358 |
+ if(fstat(fd, &sb) == -1) { |
|
359 |
+ cli_errmsg("zziplib: Can't fstat file descriptor %d\n", fd); |
|
360 |
+ return ZZIP_DIR_STAT; |
|
361 |
+ } |
|
362 |
+ |
|
363 |
+ if(u_rootsize > sb.st_size) { |
|
364 |
+ cli_errmsg("zziplib: Incorrect root size\n"); |
|
365 |
+ return ZZIP_CORRUPTED; |
|
366 |
+ } |
|
367 |
+ |
|
368 |
+ hdr0 = (struct zzip_dir_hdr*) cli_malloc(u_rootsize); |
|
358 | 369 |
if (!hdr0) |
359 | 370 |
return ZZIP_DIRSIZE; |
360 | 371 |
hdr = hdr0; __debug_dir_hdr (hdr); |
... | ... |
@@ -533,7 +544,7 @@ ZZIP_DIR* |
533 | 533 |
zzip_dir_alloc_ext_io (zzip_strings_t* ext, const zzip_plugin_io_t io) |
534 | 534 |
{ |
535 | 535 |
ZZIP_DIR* dir; |
536 |
- if ((dir = (ZZIP_DIR *)calloc(1, sizeof(*dir))) == NULL) |
|
536 |
+ if ((dir = (ZZIP_DIR *)cli_calloc(1, sizeof(*dir))) == NULL) |
|
537 | 537 |
return 0; |
538 | 538 |
|
539 | 539 |
/* dir->fileext is currently unused - so what, still initialize it */ |
... | ... |
@@ -34,14 +34,14 @@ |
34 | 34 |
|
35 | 35 |
struct cfgstruct *parsecfg(const char *cfgfile, int messages) |
36 | 36 |
{ |
37 |
- char buff[LINE_LENGTH], *name, *arg; |
|
37 |
+ char buff[LINE_LENGTH], *name, *arg, *c; |
|
38 | 38 |
FILE *fs; |
39 | 39 |
int line = 0, i, found, ctype, calc; |
40 | 40 |
struct cfgstruct *copt = NULL; |
41 | 41 |
struct cfgoption *pt; |
42 | 42 |
|
43 | 43 |
struct cfgoption cfg_options[] = { |
44 |
- {"LogFile", OPT_STR}, |
|
44 |
+ {"LogFile", OPT_FULLSTR}, |
|
45 | 45 |
{"LogFileUnlock", OPT_NOARG}, |
46 | 46 |
{"LogFileMaxSize", OPT_COMPSIZE}, |
47 | 47 |
{"LogTime", OPT_NOARG}, |
... | ... |
@@ -49,8 +49,8 @@ struct cfgstruct *parsecfg(const char *cfgfile, int messages) |
49 | 49 |
{"LogVerbose", OPT_NOARG}, /* clamd + freshclam */ |
50 | 50 |
{"LogSyslog", OPT_NOARG}, |
51 | 51 |
{"LogFacility", OPT_STR}, |
52 |
- {"PidFile", OPT_STR}, |
|
53 |
- {"TemporaryDirectory", OPT_STR}, |
|
52 |
+ {"PidFile", OPT_FULLSTR}, |
|
53 |
+ {"TemporaryDirectory", OPT_FULLSTR}, |
|
54 | 54 |
{"DisableDefaultScanOptions", OPT_NOARG}, |
55 | 55 |
{"ScanPE", OPT_NOARG}, |
56 | 56 |
{"DetectBrokenExecutables", OPT_NOARG}, |
... | ... |
@@ -67,11 +67,11 @@ struct cfgstruct *parsecfg(const char *cfgfile, int messages) |
67 | 67 |
{"ArchiveLimitMemoryUsage", OPT_NOARG}, |
68 | 68 |
{"ArchiveBlockEncrypted", OPT_NOARG}, |
69 | 69 |
{"ArchiveBlockMax", OPT_NOARG}, |
70 |
- {"DataDirectory", OPT_STR}, /* obsolete */ |
|
71 |
- {"DatabaseDirectory", OPT_STR}, /* clamd + freshclam */ |
|
70 |
+ {"DataDirectory", OPT_FULLSTR}, /* obsolete */ |
|
71 |
+ {"DatabaseDirectory", OPT_FULLSTR}, /* clamd + freshclam */ |
|
72 | 72 |
{"TCPAddr", OPT_STR}, |
73 | 73 |
{"TCPSocket", OPT_NUM}, |
74 |
- {"LocalSocket", OPT_STR}, |
|
74 |
+ {"LocalSocket", OPT_FULLSTR}, |
|
75 | 75 |
{"MaxConnectionQueueLength", OPT_NUM}, |
76 | 76 |
{"StreamMaxLength", OPT_COMPSIZE}, |
77 | 77 |
{"StreamMinPort", OPT_NUM}, |
... | ... |
@@ -102,7 +102,7 @@ struct cfgstruct *parsecfg(const char *cfgfile, int messages) |
102 | 102 |
{"ClamukoScanArchive", OPT_NOARG}, |
103 | 103 |
{"DatabaseOwner", OPT_STR}, /* freshclam */ |
104 | 104 |
{"Checks", OPT_NUM}, /* freshclam */ |
105 |
- {"UpdateLogFile", OPT_STR}, /* freshclam */ |
|
105 |
+ {"UpdateLogFile", OPT_FULLSTR}, /* freshclam */ |
|
106 | 106 |
{"DNSDatabaseInfo", OPT_STR}, /* freshclam */ |
107 | 107 |
{"DatabaseMirror", OPT_STR}, /* freshclam */ |
108 | 108 |
{"MaxAttempts", OPT_NUM}, /* freshclam */ |
... | ... |
@@ -166,6 +166,8 @@ struct cfgstruct *parsecfg(const char *cfgfile, int messages) |
166 | 166 |
free(arg); |
167 | 167 |
arg = strstr(buff, " "); |
168 | 168 |
arg = strdup(++arg); |
169 |
+ if((c = strpbrk(arg, "\n\r"))) |
|
170 |
+ *c = '\0'; |
|
169 | 171 |
copt = regcfg(copt, name, arg, 0); |
170 | 172 |
break; |
171 | 173 |
case OPT_NUM: |
... | ... |
@@ -52,9 +52,9 @@ |
52 | 52 |
pthread_mutex_t logg_mutex = PTHREAD_MUTEX_INITIALIZER; |
53 | 53 |
#endif |
54 | 54 |
|
55 |
-FILE *logg_fd = NULL; |
|
55 |
+FILE *logg_fs = NULL; |
|
56 | 56 |
|
57 |
-short int logg_verbose = 0, logg_lock = 0, logg_time = 0; |
|
57 |
+short int logg_verbose = 0, logg_lock = 1, logg_time = 0; |
|
58 | 58 |
int logg_size = 0; |
59 | 59 |
const char *logg_file = NULL; |
60 | 60 |
#if defined(USE_SYSLOG) && !defined(C_AIX) |
... | ... |
@@ -71,10 +71,16 @@ int mdprintf(int desc, const char *str, ...) |
71 | 71 |
int bytes; |
72 | 72 |
|
73 | 73 |
va_start(args, str); |
74 |
- bytes = vsnprintf(buff, 512, str, args); |
|
74 |
+ bytes = vsnprintf(buff, sizeof(buff), str, args); |
|
75 | 75 |
va_end(args); |
76 |
- write(desc, buff, bytes); |
|
77 |
- return bytes; |
|
76 |
+ |
|
77 |
+ if(bytes == -1) |
|
78 |
+ return bytes; |
|
79 |
+ |
|
80 |
+ if(bytes >= sizeof(buff)) |
|
81 |
+ bytes = sizeof(buff) - 1; |
|
82 |
+ |
|
83 |
+ return send(desc, buff, bytes, 0); |
|
78 | 84 |
} |
79 | 85 |
|
80 | 86 |
void logg_close(void) { |
... | ... |
@@ -82,9 +88,9 @@ void logg_close(void) { |
82 | 82 |
#ifdef CL_THREAD_SAFE |
83 | 83 |
pthread_mutex_lock(&logg_mutex); |
84 | 84 |
#endif |
85 |
- if (logg_fd) { |
|
86 |
- fclose(logg_fd); |
|
87 |
- logg_fd = NULL; |
|
85 |
+ if (logg_fs) { |
|
86 |
+ fclose(logg_fs); |
|
87 |
+ logg_fs = NULL; |
|
88 | 88 |
} |
89 | 89 |
#ifdef CL_THREAD_SAFE |
90 | 90 |
pthread_mutex_unlock(&logg_mutex); |
... | ... |
@@ -115,9 +121,9 @@ int logg(const char *str, ...) |
115 | 115 |
#ifdef CL_THREAD_SAFE |
116 | 116 |
pthread_mutex_lock(&logg_mutex); |
117 | 117 |
#endif |
118 |
- if(!logg_fd) { |
|
118 |
+ if(!logg_fs) { |
|
119 | 119 |
old_umask = umask(0037); |
120 |
- if((logg_fd = fopen(logg_file, "a")) == NULL) { |
|
120 |
+ if((logg_fs = fopen(logg_file, "a")) == NULL) { |
|
121 | 121 |
umask(old_umask); |
122 | 122 |
#ifdef CL_THREAD_SAFE |
123 | 123 |
pthread_mutex_unlock(&logg_mutex); |
... | ... |
@@ -129,7 +135,7 @@ int logg(const char *str, ...) |
129 | 129 |
if(logg_lock) { |
130 | 130 |
memset(&fl, 0, sizeof(fl)); |
131 | 131 |
fl.l_type = F_WRLCK; |
132 |
- if(fcntl(fileno(logg_fd), F_SETLK, &fl) == -1) { |
|
132 |
+ if(fcntl(fileno(logg_fs), F_SETLK, &fl) == -1) { |
|
133 | 133 |
#ifdef CL_THREAD_SAFE |
134 | 134 |
pthread_mutex_unlock(&logg_mutex); |
135 | 135 |
#endif |
... | ... |
@@ -146,7 +152,7 @@ int logg(const char *str, ...) |
146 | 146 |
pt = ctime(&currtime); |
147 | 147 |
timestr = mcalloc(strlen(pt), sizeof(char)); |
148 | 148 |
strncpy(timestr, pt, strlen(pt) - 1); |
149 |
- fprintf(logg_fd, "%s -> ", timestr); |
|
149 |
+ fprintf(logg_fs, "%s -> ", timestr); |
|
150 | 150 |
free(timestr); |
151 | 151 |
} |
152 | 152 |
|
... | ... |
@@ -154,10 +160,10 @@ int logg(const char *str, ...) |
154 | 154 |
if(stat(logg_file, &sb) != -1) { |
155 | 155 |
if(sb.st_size > logg_size) { |
156 | 156 |
logg_file = NULL; |
157 |
- fprintf(logg_fd, "Log size = %d, maximal = %d\n", (int) sb.st_size, logg_size); |
|
158 |
- fprintf(logg_fd, "LOGGING DISABLED (Maximal log file size exceeded).\n"); |
|
159 |
- fclose(logg_fd); |
|
160 |
- logg_fd = NULL; |
|
157 |
+ fprintf(logg_fs, "Log size = %d, maximal = %d\n", (int) sb.st_size, logg_size); |
|
158 |
+ fprintf(logg_fs, "LOGGING DISABLED (Maximal log file size exceeded).\n"); |
|
159 |
+ fclose(logg_fs); |
|
160 |
+ logg_fs = NULL; |
|
161 | 161 |
#ifdef CL_THREAD_SAFE |
162 | 162 |
pthread_mutex_unlock(&logg_mutex); |
163 | 163 |
#endif |
... | ... |
@@ -168,18 +174,18 @@ int logg(const char *str, ...) |
168 | 168 |
|
169 | 169 |
|
170 | 170 |
if(*str == '!') { |
171 |
- fprintf(logg_fd, "ERROR: "); |
|
172 |
- vfprintf(logg_fd, str + 1, args); |
|
171 |
+ fprintf(logg_fs, "ERROR: "); |
|
172 |
+ vfprintf(logg_fs, str + 1, args); |
|
173 | 173 |
} else if(*str == '^') { |
174 |
- fprintf(logg_fd, "WARNING: "); |
|
175 |
- vfprintf(logg_fd, str + 1, args); |
|
174 |
+ fprintf(logg_fs, "WARNING: "); |
|
175 |
+ vfprintf(logg_fs, str + 1, args); |
|
176 | 176 |
} else if(*str == '*') { |
177 | 177 |
if(logg_verbose) |
178 |
- vfprintf(logg_fd, str + 1, args); |
|
179 |
- } else vfprintf(logg_fd, str, args); |
|
178 |
+ vfprintf(logg_fs, str + 1, args); |
|
179 |
+ } else vfprintf(logg_fs, str, args); |
|
180 | 180 |
|
181 | 181 |
|
182 |
- fflush(logg_fd); |
|
182 |
+ fflush(logg_fs); |
|
183 | 183 |
|
184 | 184 |
#ifdef CL_THREAD_SAFE |
185 | 185 |
pthread_mutex_unlock(&logg_mutex); |
... | ... |
@@ -188,28 +194,18 @@ int logg(const char *str, ...) |
188 | 188 |
|
189 | 189 |
#if defined(USE_SYSLOG) && !defined(C_AIX) |
190 | 190 |
if(logg_syslog) { |
191 |
- |
|
192 |
- /* due to a problem with superfluous control characters (which |
|
193 |
- * vsnprintf() handles correctly) in (v)syslog we have to remove |
|
194 |
- * them in a final string |
|
195 |
- * |
|
196 |
- * FIXME: substitute %% instead of _ |
|
197 |
- */ |
|
198 | 191 |
vsnprintf(vbuff, 1024, str, argscpy); |
199 | 192 |
vbuff[1024] = 0; |
200 | 193 |
|
201 |
- while((pt = strchr(vbuff, '%'))) |
|
202 |
- *pt = '_'; |
|
203 |
- |
|
204 | 194 |
if(vbuff[0] == '!') { |
205 |
- syslog(LOG_ERR, vbuff + 1); |
|
195 |
+ syslog(LOG_ERR, "%s", vbuff + 1); |
|
206 | 196 |
} else if(vbuff[0] == '^') { |
207 |
- syslog(LOG_WARNING, vbuff + 1); |
|
197 |
+ syslog(LOG_WARNING, "%s", vbuff + 1); |
|
208 | 198 |
} else if(vbuff[0] == '*') { |
209 | 199 |
if(logg_verbose) { |
210 |
- syslog(LOG_DEBUG, vbuff + 1); |
|
200 |
+ syslog(LOG_DEBUG, "%s", vbuff + 1); |
|
211 | 201 |
} |
212 |
- } else syslog(LOG_INFO, vbuff); |
|
202 |
+ } else syslog(LOG_INFO, "%s", vbuff); |
|
213 | 203 |
|
214 | 204 |
} |
215 | 205 |
#endif |
... | ... |
@@ -237,7 +237,7 @@ int build(struct optstruct *opt) |
237 | 237 |
int ret, realno = 0, bytes, itmp; |
238 | 238 |
unsigned int no = 0; |
239 | 239 |
struct stat foo; |
240 |
- char buffer[FILEBUFF], *tarfile = NULL, *gzfile = NULL, header[512], |
|
240 |
+ char buffer[FILEBUFF], *tarfile = NULL, *gzfile = NULL, header[513], |
|
241 | 241 |
smbuff[30], *pt, *dbdir; |
242 | 242 |
struct cl_node *root = NULL; |
243 | 243 |
FILE *tar, *cvd, *fd; |