Browse code

bb #1570: DMG TOC and striping (not reassembly yet), and libxml2 check

David Raynor authored on 2013/09/13 23:40:58
Showing 26 changed files
... ...
@@ -318,6 +318,9 @@ VERSION = @VERSION@
318 318
 VERSIONSCRIPTFLAG = @VERSIONSCRIPTFLAG@
319 319
 WERR_CFLAGS = @WERR_CFLAGS@
320 320
 WERR_CFLAGS_MILTER = @WERR_CFLAGS_MILTER@
321
+XML2_CONFIG = @XML2_CONFIG@
322
+XML_CPPFLAGS = @XML_CPPFLAGS@
323
+XML_LIBS = @XML_LIBS@
321 324
 abs_builddir = @abs_builddir@
322 325
 abs_srcdir = @abs_srcdir@
323 326
 abs_top_builddir = @abs_top_builddir@
... ...
@@ -20,6 +20,195 @@ You have another version of autoconf.  It may work, but is not guaranteed to.
20 20
 If you have problems, you may need to regenerate the build system entirely.
21 21
 To do so, use the procedure documented by the package, typically `autoreconf'.])])
22 22
 
23
+# Configure paths for LIBXML2
24
+# Mike Hommey 2004-06-19
25
+# use CPPFLAGS instead of CFLAGS
26
+# Toshio Kuratomi 2001-04-21
27
+# Adapted from:
28
+# Configure paths for GLIB
29
+# Owen Taylor     97-11-3
30
+
31
+dnl AM_PATH_XML2([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
32
+dnl Test for XML, and define XML_CPPFLAGS and XML_LIBS
33
+dnl
34
+AC_DEFUN([AM_PATH_XML2],[ 
35
+AC_ARG_WITH(xml-prefix,
36
+            [  --with-xml-prefix=PFX   Prefix where libxml is installed (optional)],
37
+            xml_config_prefix="$withval", xml_config_prefix="")
38
+AC_ARG_WITH(xml-exec-prefix,
39
+            [  --with-xml-exec-prefix=PFX Exec prefix where libxml is installed (optional)],
40
+            xml_config_exec_prefix="$withval", xml_config_exec_prefix="")
41
+AC_ARG_ENABLE(xmltest,
42
+              [  --disable-xmltest       Do not try to compile and run a test LIBXML program],,
43
+              enable_xmltest=yes)
44
+
45
+  if test x$xml_config_exec_prefix != x ; then
46
+     xml_config_args="$xml_config_args"
47
+     if test x${XML2_CONFIG+set} != xset ; then
48
+        XML2_CONFIG=$xml_config_exec_prefix/bin/xml2-config
49
+     fi
50
+  fi
51
+  if test x$xml_config_prefix != x ; then
52
+     xml_config_args="$xml_config_args --prefix=$xml_config_prefix"
53
+     if test x${XML2_CONFIG+set} != xset ; then
54
+        XML2_CONFIG=$xml_config_prefix/bin/xml2-config
55
+     fi
56
+  fi
57
+
58
+  AC_PATH_PROG(XML2_CONFIG, xml2-config, no)
59
+  min_xml_version=ifelse([$1], ,2.0.0,[$1])
60
+  AC_MSG_CHECKING(for libxml - version >= $min_xml_version)
61
+  no_xml=""
62
+  if test "$XML2_CONFIG" = "no" ; then
63
+    no_xml=yes
64
+  else
65
+    XML_CPPFLAGS=`$XML2_CONFIG $xml_config_args --cflags`
66
+    XML_LIBS=`$XML2_CONFIG $xml_config_args --libs`
67
+    xml_config_major_version=`$XML2_CONFIG $xml_config_args --version | \
68
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
69
+    xml_config_minor_version=`$XML2_CONFIG $xml_config_args --version | \
70
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
71
+    xml_config_micro_version=`$XML2_CONFIG $xml_config_args --version | \
72
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
73
+    if test "x$enable_xmltest" = "xyes" ; then
74
+      ac_save_CPPFLAGS="$CPPFLAGS"
75
+      ac_save_LIBS="$LIBS"
76
+      CPPFLAGS="$CPPFLAGS $XML_CPPFLAGS"
77
+      LIBS="$XML_LIBS $LIBS"
78
+dnl
79
+dnl Now check if the installed libxml is sufficiently new.
80
+dnl (Also sanity checks the results of xml2-config to some extent)
81
+dnl
82
+      rm -f conf.xmltest
83
+      AC_TRY_RUN([
84
+#include <stdlib.h>
85
+#include <stdio.h>
86
+#include <string.h>
87
+#include <libxml/xmlversion.h>
88
+
89
+int 
90
+main()
91
+{
92
+  int xml_major_version, xml_minor_version, xml_micro_version;
93
+  int major, minor, micro;
94
+  char *tmp_version;
95
+
96
+  system("touch conf.xmltest");
97
+
98
+  /* Capture xml2-config output via autoconf/configure variables */
99
+  /* HP/UX 9 (%@#!) writes to sscanf strings */
100
+  tmp_version = (char *)strdup("$min_xml_version");
101
+  if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3) {
102
+     printf("%s, bad version string from xml2-config\n", "$min_xml_version");
103
+     exit(1);
104
+   }
105
+   free(tmp_version);
106
+
107
+   /* Capture the version information from the header files */
108
+   tmp_version = (char *)strdup(LIBXML_DOTTED_VERSION);
109
+   if (sscanf(tmp_version, "%d.%d.%d", &xml_major_version, &xml_minor_version, &xml_micro_version) != 3) {
110
+     printf("%s, bad version string from libxml includes\n", "LIBXML_DOTTED_VERSION");
111
+     exit(1);
112
+   }
113
+   free(tmp_version);
114
+
115
+ /* Compare xml2-config output to the libxml headers */
116
+  if ((xml_major_version != $xml_config_major_version) ||
117
+      (xml_minor_version != $xml_config_minor_version) ||
118
+      (xml_micro_version != $xml_config_micro_version))
119
+    {
120
+      printf("*** libxml header files (version %d.%d.%d) do not match\n",
121
+         xml_major_version, xml_minor_version, xml_micro_version);
122
+      printf("*** xml2-config (version %d.%d.%d)\n",
123
+         $xml_config_major_version, $xml_config_minor_version, $xml_config_micro_version);
124
+      return 1;
125
+    } 
126
+/* Compare the headers to the library to make sure we match */
127
+  /* Less than ideal -- doesn't provide us with return value feedback, 
128
+   * only exits if there's a serious mismatch between header and library.
129
+   */
130
+    LIBXML_TEST_VERSION;
131
+
132
+    /* Test that the library is greater than our minimum version */
133
+    if ((xml_major_version > major) ||
134
+        ((xml_major_version == major) && (xml_minor_version > minor)) ||
135
+        ((xml_major_version == major) && (xml_minor_version == minor) &&
136
+        (xml_micro_version >= micro)))
137
+      {
138
+        return 0;
139
+       }
140
+     else
141
+      {
142
+        printf("\n*** An old version of libxml (%d.%d.%d) was found.\n",
143
+               xml_major_version, xml_minor_version, xml_micro_version);
144
+        printf("*** You need a version of libxml newer than %d.%d.%d. The latest version of\n",
145
+           major, minor, micro);
146
+        printf("*** libxml is always available from ftp://ftp.xmlsoft.org.\n");
147
+        printf("***\n");
148
+        printf("*** If you have already installed a sufficiently new version, this error\n");
149
+        printf("*** probably means that the wrong copy of the xml2-config shell script is\n");
150
+        printf("*** being found. The easiest way to fix this is to remove the old version\n");
151
+        printf("*** of LIBXML, but you can also set the XML2_CONFIG environment to point to the\n");
152
+        printf("*** correct copy of xml2-config. (In this case, you will have to\n");
153
+        printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n");
154
+        printf("*** so that the correct libraries are found at run-time))\n");
155
+    }
156
+  return 1;
157
+}
158
+],, no_xml=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
159
+       CPPFLAGS="$ac_save_CPPFLAGS"
160
+       LIBS="$ac_save_LIBS"
161
+     fi
162
+  fi
163
+
164
+  if test "x$no_xml" = x ; then
165
+     AC_MSG_RESULT(yes (version $xml_config_major_version.$xml_config_minor_version.$xml_config_micro_version))
166
+     ifelse([$2], , :, [$2])     
167
+  else
168
+     AC_MSG_RESULT(no)
169
+     if test "$XML2_CONFIG" = "no" ; then
170
+       echo "*** The xml2-config script installed by LIBXML could not be found"
171
+       echo "*** If libxml was installed in PREFIX, make sure PREFIX/bin is in"
172
+       echo "*** your path, or set the XML2_CONFIG environment variable to the"
173
+       echo "*** full path to xml2-config."
174
+     else
175
+       if test -f conf.xmltest ; then
176
+        :
177
+       else
178
+          echo "*** Could not run libxml test program, checking why..."
179
+          CPPFLAGS="$CPPFLAGS $XML_CPPFLAGS"
180
+          LIBS="$LIBS $XML_LIBS"
181
+          AC_TRY_LINK([
182
+#include <libxml/xmlversion.h>
183
+#include <stdio.h>
184
+],      [ LIBXML_TEST_VERSION; return 0;],
185
+        [ echo "*** The test program compiled, but did not run. This usually means"
186
+          echo "*** that the run-time linker is not finding LIBXML or finding the wrong"
187
+          echo "*** version of LIBXML. If it is not finding LIBXML, you'll need to set your"
188
+          echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
189
+          echo "*** to the installed location  Also, make sure you have run ldconfig if that"
190
+          echo "*** is required on your system"
191
+          echo "***"
192
+          echo "*** If you have an old version installed, it is best to remove it, although"
193
+          echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" ],
194
+        [ echo "*** The test program failed to compile or link. See the file config.log for the"
195
+          echo "*** exact error that occured. This usually means LIBXML was incorrectly installed"
196
+          echo "*** or that you have moved LIBXML since it was installed. In the latter case, you"
197
+          echo "*** may want to edit the xml2-config script: $XML2_CONFIG" ])
198
+          CPPFLAGS="$ac_save_CPPFLAGS"
199
+          LIBS="$ac_save_LIBS"
200
+       fi
201
+     fi
202
+
203
+     XML_CPPFLAGS=""
204
+     XML_LIBS=""
205
+     ifelse([$3], , :, [$3])
206
+  fi
207
+  AC_SUBST(XML_CPPFLAGS)
208
+  AC_SUBST(XML_LIBS)
209
+  rm -f conf.xmltest
210
+])
211
+
23 212
 # Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software
24 213
 # Foundation, Inc.
25 214
 #
... ...
@@ -232,6 +232,9 @@
232 232
 /* Define to '1' if you have the curses.h library */
233 233
 #undef HAVE_LIBPDCURSES
234 234
 
235
+/* Define to 1 if you have the 'libxml2' library (-lxml2). */
236
+#undef HAVE_LIBXML2
237
+
235 238
 /* Define to 1 if you have the `z' library (-lz). */
236 239
 #undef HAVE_LIBZ
237 240
 
... ...
@@ -287,6 +287,9 @@ VERSION = @VERSION@
287 287
 VERSIONSCRIPTFLAG = @VERSIONSCRIPTFLAG@
288 288
 WERR_CFLAGS = @WERR_CFLAGS@
289 289
 WERR_CFLAGS_MILTER = @WERR_CFLAGS_MILTER@
290
+XML2_CONFIG = @XML2_CONFIG@
291
+XML_CPPFLAGS = @XML_CPPFLAGS@
292
+XML_LIBS = @XML_LIBS@
290 293
 abs_builddir = @abs_builddir@
291 294
 abs_srcdir = @abs_srcdir@
292 295
 abs_top_builddir = @abs_top_builddir@
... ...
@@ -223,6 +223,9 @@ VERSION = @VERSION@
223 223
 VERSIONSCRIPTFLAG = @VERSIONSCRIPTFLAG@
224 224
 WERR_CFLAGS = @WERR_CFLAGS@
225 225
 WERR_CFLAGS_MILTER = @WERR_CFLAGS_MILTER@
226
+XML2_CONFIG = @XML2_CONFIG@
227
+XML_CPPFLAGS = @XML_CPPFLAGS@
228
+XML_LIBS = @XML_LIBS@
226 229
 abs_builddir = @abs_builddir@
227 230
 abs_srcdir = @abs_srcdir@
228 231
 abs_top_builddir = @abs_top_builddir@
... ...
@@ -241,6 +241,9 @@ VERSION = @VERSION@
241 241
 VERSIONSCRIPTFLAG = @VERSIONSCRIPTFLAG@
242 242
 WERR_CFLAGS = @WERR_CFLAGS@
243 243
 WERR_CFLAGS_MILTER = @WERR_CFLAGS_MILTER@
244
+XML2_CONFIG = @XML2_CONFIG@
245
+XML_CPPFLAGS = @XML_CPPFLAGS@
246
+XML_LIBS = @XML_LIBS@
244 247
 abs_builddir = @abs_builddir@
245 248
 abs_srcdir = @abs_srcdir@
246 249
 abs_top_builddir = @abs_top_builddir@
... ...
@@ -254,6 +254,9 @@ VERSION = @VERSION@
254 254
 VERSIONSCRIPTFLAG = @VERSIONSCRIPTFLAG@
255 255
 WERR_CFLAGS = @WERR_CFLAGS@
256 256
 WERR_CFLAGS_MILTER = @WERR_CFLAGS_MILTER@
257
+XML2_CONFIG = @XML2_CONFIG@
258
+XML_CPPFLAGS = @XML_CPPFLAGS@
259
+XML_LIBS = @XML_LIBS@
257 260
 abs_builddir = @abs_builddir@
258 261
 abs_srcdir = @abs_srcdir@
259 262
 abs_top_builddir = @abs_top_builddir@
... ...
@@ -252,6 +252,9 @@ VERSION = @VERSION@
252 252
 VERSIONSCRIPTFLAG = @VERSIONSCRIPTFLAG@
253 253
 WERR_CFLAGS = @WERR_CFLAGS@
254 254
 WERR_CFLAGS_MILTER = @WERR_CFLAGS_MILTER@
255
+XML2_CONFIG = @XML2_CONFIG@
256
+XML_CPPFLAGS = @XML_CPPFLAGS@
257
+XML_LIBS = @XML_LIBS@
255 258
 abs_builddir = @abs_builddir@
256 259
 abs_srcdir = @abs_srcdir@
257 260
 abs_top_builddir = @abs_top_builddir@
... ...
@@ -258,6 +258,9 @@ VERSION = @VERSION@
258 258
 VERSIONSCRIPTFLAG = @VERSIONSCRIPTFLAG@
259 259
 WERR_CFLAGS = @WERR_CFLAGS@
260 260
 WERR_CFLAGS_MILTER = @WERR_CFLAGS_MILTER@
261
+XML2_CONFIG = @XML2_CONFIG@
262
+XML_CPPFLAGS = @XML_CPPFLAGS@
263
+XML_LIBS = @XML_LIBS@
261 264
 abs_builddir = @abs_builddir@
262 265
 abs_srcdir = @abs_srcdir@
263 266
 abs_top_builddir = @abs_top_builddir@
... ...
@@ -243,6 +243,9 @@ VERSION = @VERSION@
243 243
 VERSIONSCRIPTFLAG = @VERSIONSCRIPTFLAG@
244 244
 WERR_CFLAGS = @WERR_CFLAGS@
245 245
 WERR_CFLAGS_MILTER = @WERR_CFLAGS_MILTER@
246
+XML2_CONFIG = @XML2_CONFIG@
247
+XML_CPPFLAGS = @XML_CPPFLAGS@
248
+XML_LIBS = @XML_LIBS@
246 249
 abs_builddir = @abs_builddir@
247 250
 abs_srcdir = @abs_srcdir@
248 251
 abs_top_builddir = @abs_top_builddir@
... ...
@@ -666,6 +666,11 @@ CLAMD_LIBS
666 666
 LIBCLAMAV_LIBS
667 667
 CFGDIR
668 668
 DBDIR
669
+XML_LIBS
670
+XML_CPPFLAGS
671
+XML2_CONFIG
672
+ENABLE_XML_FALSE
673
+ENABLE_XML_TRUE
669 674
 ENABLE_UNRAR_FALSE
670 675
 ENABLE_UNRAR_TRUE
671 676
 LIBBZ2_PREFIX
... ...
@@ -854,6 +859,10 @@ enable_zlib_vcheck
854 854
 enable_bzip2
855 855
 with_libbz2_prefix
856 856
 enable_unrar
857
+enable_xml
858
+with_xml_prefix
859
+with_xml_exec_prefix
860
+enable_xmltest
857 861
 enable_getaddrinfo
858 862
 enable_ipv6
859 863
 enable_dns
... ...
@@ -1531,7 +1540,9 @@ Optional Features:
1531 1531
                           (and sometimes confusing) to the casual installer
1532 1532
   --disable-zlib-vcheck	  do not check for buggy zlib version
1533 1533
   --disable-bzip2	  disable bzip2 support
1534
-  --disable-unrar	  don't build libclamunrar and libclamunrar_iface
1534
+  --disable-unrar	  do not build libclamunrar and libclamunrar_iface
1535
+  --disable-xml	  disable DMG and XAR support
1536
+  --disable-xmltest       Do not try to compile and run a test LIBXML program
1535 1537
   --disable-getaddrinfo          disable support for getaddrinfo
1536 1538
   --disable-ipv6          disable IPv6 support
1537 1539
   --disable-dns           disable support for database verification through
... ...
@@ -1539,7 +1550,7 @@ Optional Features:
1539 1539
   --disable-fanotify	  disable fanotify support (Linux only)
1540 1540
   --enable-milter	  build clamav-milter
1541 1541
   --disable-pthreads      disable POSIX threads support
1542
-  --disable-cr		  don't link with C reentrant library (BSD)
1542
+  --disable-cr		  do not link with C reentrant library (BSD)
1543 1543
   --enable-id-check	  use id utility instead of /etc/passwd parsing
1544 1544
   --enable-yp-check	  use ypmatch utility instead of /etc/passwd parsing
1545 1545
   --disable-clamav	  disable test for clamav user/group
... ...
@@ -1574,6 +1585,8 @@ Optional Packages:
1574 1574
 			  /usr/local or /usr if not found in /usr/local)
1575 1575
   --with-libbz2-prefix[=DIR]  search for libbz2 in DIR/include and DIR/lib
1576 1576
   --without-libbz2-prefix     don't search for libbz2 in includedir and libdir
1577
+  --with-xml-prefix=PFX   Prefix where libxml is installed (optional)
1578
+  --with-xml-exec-prefix=PFX Exec prefix where libxml is installed (optional)
1577 1579
   --with-iconv supports iconv() (default=auto)
1578 1580
   --with-user=uid	  name of the clamav user (default=clamav)
1579 1581
   --with-group=gid	  name of the clamav group (default=clamav)
... ...
@@ -16988,6 +17001,298 @@ else
16988 16988
 fi
16989 16989
 
16990 16990
 
16991
+want_xml="yes"
16992
+# Check whether --enable-xml was given.
16993
+if test "${enable_xml+set}" = set; then :
16994
+  enableval=$enable_xml; want_xml=$enableval
16995
+else
16996
+  want_xml="yes"
16997
+fi
16998
+
16999
+ if test "$want_xml" = "yes"; then
17000
+  ENABLE_XML_TRUE=
17001
+  ENABLE_XML_FALSE='#'
17002
+else
17003
+  ENABLE_XML_TRUE='#'
17004
+  ENABLE_XML_FALSE=
17005
+fi
17006
+
17007
+
17008
+if test "$want_xml" = "yes"
17009
+then
17010
+
17011
+
17012
+# Check whether --with-xml-prefix was given.
17013
+if test "${with_xml_prefix+set}" = set; then :
17014
+  withval=$with_xml_prefix; xml_config_prefix="$withval"
17015
+else
17016
+  xml_config_prefix=""
17017
+fi
17018
+
17019
+
17020
+# Check whether --with-xml-exec-prefix was given.
17021
+if test "${with_xml_exec_prefix+set}" = set; then :
17022
+  withval=$with_xml_exec_prefix; xml_config_exec_prefix="$withval"
17023
+else
17024
+  xml_config_exec_prefix=""
17025
+fi
17026
+
17027
+# Check whether --enable-xmltest was given.
17028
+if test "${enable_xmltest+set}" = set; then :
17029
+  enableval=$enable_xmltest;
17030
+else
17031
+  enable_xmltest=yes
17032
+fi
17033
+
17034
+
17035
+  if test x$xml_config_exec_prefix != x ; then
17036
+     xml_config_args="$xml_config_args"
17037
+     if test x${XML2_CONFIG+set} != xset ; then
17038
+        XML2_CONFIG=$xml_config_exec_prefix/bin/xml2-config
17039
+     fi
17040
+  fi
17041
+  if test x$xml_config_prefix != x ; then
17042
+     xml_config_args="$xml_config_args --prefix=$xml_config_prefix"
17043
+     if test x${XML2_CONFIG+set} != xset ; then
17044
+        XML2_CONFIG=$xml_config_prefix/bin/xml2-config
17045
+     fi
17046
+  fi
17047
+
17048
+  # Extract the first word of "xml2-config", so it can be a program name with args.
17049
+set dummy xml2-config; ac_word=$2
17050
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
17051
+$as_echo_n "checking for $ac_word... " >&6; }
17052
+if ${ac_cv_path_XML2_CONFIG+:} false; then :
17053
+  $as_echo_n "(cached) " >&6
17054
+else
17055
+  case $XML2_CONFIG in
17056
+  [\\/]* | ?:[\\/]*)
17057
+  ac_cv_path_XML2_CONFIG="$XML2_CONFIG" # Let the user override the test with a path.
17058
+  ;;
17059
+  *)
17060
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
17061
+for as_dir in $PATH
17062
+do
17063
+  IFS=$as_save_IFS
17064
+  test -z "$as_dir" && as_dir=.
17065
+    for ac_exec_ext in '' $ac_executable_extensions; do
17066
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
17067
+    ac_cv_path_XML2_CONFIG="$as_dir/$ac_word$ac_exec_ext"
17068
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
17069
+    break 2
17070
+  fi
17071
+done
17072
+  done
17073
+IFS=$as_save_IFS
17074
+
17075
+  test -z "$ac_cv_path_XML2_CONFIG" && ac_cv_path_XML2_CONFIG="no"
17076
+  ;;
17077
+esac
17078
+fi
17079
+XML2_CONFIG=$ac_cv_path_XML2_CONFIG
17080
+if test -n "$XML2_CONFIG"; then
17081
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XML2_CONFIG" >&5
17082
+$as_echo "$XML2_CONFIG" >&6; }
17083
+else
17084
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
17085
+$as_echo "no" >&6; }
17086
+fi
17087
+
17088
+
17089
+  min_xml_version=2.5.0
17090
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libxml - version >= $min_xml_version" >&5
17091
+$as_echo_n "checking for libxml - version >= $min_xml_version... " >&6; }
17092
+  no_xml=""
17093
+  if test "$XML2_CONFIG" = "no" ; then
17094
+    no_xml=yes
17095
+  else
17096
+    XML_CPPFLAGS=`$XML2_CONFIG $xml_config_args --cflags`
17097
+    XML_LIBS=`$XML2_CONFIG $xml_config_args --libs`
17098
+    xml_config_major_version=`$XML2_CONFIG $xml_config_args --version | \
17099
+           sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1/'`
17100
+    xml_config_minor_version=`$XML2_CONFIG $xml_config_args --version | \
17101
+           sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\2/'`
17102
+    xml_config_micro_version=`$XML2_CONFIG $xml_config_args --version | \
17103
+           sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/'`
17104
+    if test "x$enable_xmltest" = "xyes" ; then
17105
+      ac_save_CPPFLAGS="$CPPFLAGS"
17106
+      ac_save_LIBS="$LIBS"
17107
+      CPPFLAGS="$CPPFLAGS $XML_CPPFLAGS"
17108
+      LIBS="$XML_LIBS $LIBS"
17109
+      rm -f conf.xmltest
17110
+      if test "$cross_compiling" = yes; then :
17111
+  echo $ac_n "cross compiling; assumed OK... $ac_c"
17112
+else
17113
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
17114
+/* end confdefs.h.  */
17115
+
17116
+#include <stdlib.h>
17117
+#include <stdio.h>
17118
+#include <string.h>
17119
+#include <libxml/xmlversion.h>
17120
+
17121
+int
17122
+main()
17123
+{
17124
+  int xml_major_version, xml_minor_version, xml_micro_version;
17125
+  int major, minor, micro;
17126
+  char *tmp_version;
17127
+
17128
+  system("touch conf.xmltest");
17129
+
17130
+  /* Capture xml2-config output via autoconf/configure variables */
17131
+  /* HP/UX 9 (%@#!) writes to sscanf strings */
17132
+  tmp_version = (char *)strdup("$min_xml_version");
17133
+  if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3) {
17134
+     printf("%s, bad version string from xml2-config\n", "$min_xml_version");
17135
+     exit(1);
17136
+   }
17137
+   free(tmp_version);
17138
+
17139
+   /* Capture the version information from the header files */
17140
+   tmp_version = (char *)strdup(LIBXML_DOTTED_VERSION);
17141
+   if (sscanf(tmp_version, "%d.%d.%d", &xml_major_version, &xml_minor_version, &xml_micro_version) != 3) {
17142
+     printf("%s, bad version string from libxml includes\n", "LIBXML_DOTTED_VERSION");
17143
+     exit(1);
17144
+   }
17145
+   free(tmp_version);
17146
+
17147
+ /* Compare xml2-config output to the libxml headers */
17148
+  if ((xml_major_version != $xml_config_major_version) ||
17149
+      (xml_minor_version != $xml_config_minor_version) ||
17150
+      (xml_micro_version != $xml_config_micro_version))
17151
+    {
17152
+      printf("*** libxml header files (version %d.%d.%d) do not match\n",
17153
+         xml_major_version, xml_minor_version, xml_micro_version);
17154
+      printf("*** xml2-config (version %d.%d.%d)\n",
17155
+         $xml_config_major_version, $xml_config_minor_version, $xml_config_micro_version);
17156
+      return 1;
17157
+    }
17158
+/* Compare the headers to the library to make sure we match */
17159
+  /* Less than ideal -- doesn't provide us with return value feedback,
17160
+   * only exits if there's a serious mismatch between header and library.
17161
+   */
17162
+    LIBXML_TEST_VERSION;
17163
+
17164
+    /* Test that the library is greater than our minimum version */
17165
+    if ((xml_major_version > major) ||
17166
+        ((xml_major_version == major) && (xml_minor_version > minor)) ||
17167
+        ((xml_major_version == major) && (xml_minor_version == minor) &&
17168
+        (xml_micro_version >= micro)))
17169
+      {
17170
+        return 0;
17171
+       }
17172
+     else
17173
+      {
17174
+        printf("\n*** An old version of libxml (%d.%d.%d) was found.\n",
17175
+               xml_major_version, xml_minor_version, xml_micro_version);
17176
+        printf("*** You need a version of libxml newer than %d.%d.%d. The latest version of\n",
17177
+           major, minor, micro);
17178
+        printf("*** libxml is always available from ftp://ftp.xmlsoft.org.\n");
17179
+        printf("***\n");
17180
+        printf("*** If you have already installed a sufficiently new version, this error\n");
17181
+        printf("*** probably means that the wrong copy of the xml2-config shell script is\n");
17182
+        printf("*** being found. The easiest way to fix this is to remove the old version\n");
17183
+        printf("*** of LIBXML, but you can also set the XML2_CONFIG environment to point to the\n");
17184
+        printf("*** correct copy of xml2-config. (In this case, you will have to\n");
17185
+        printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n");
17186
+        printf("*** so that the correct libraries are found at run-time))\n");
17187
+    }
17188
+  return 1;
17189
+}
17190
+
17191
+_ACEOF
17192
+if ac_fn_c_try_run "$LINENO"; then :
17193
+
17194
+else
17195
+  no_xml=yes
17196
+fi
17197
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
17198
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
17199
+fi
17200
+
17201
+       CPPFLAGS="$ac_save_CPPFLAGS"
17202
+       LIBS="$ac_save_LIBS"
17203
+     fi
17204
+  fi
17205
+
17206
+  if test "x$no_xml" = x ; then
17207
+     { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes (version $xml_config_major_version.$xml_config_minor_version.$xml_config_micro_version)" >&5
17208
+$as_echo "yes (version $xml_config_major_version.$xml_config_minor_version.$xml_config_micro_version)" >&6; }
17209
+     :
17210
+  else
17211
+     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
17212
+$as_echo "no" >&6; }
17213
+     if test "$XML2_CONFIG" = "no" ; then
17214
+       echo "*** The xml2-config script installed by LIBXML could not be found"
17215
+       echo "*** If libxml was installed in PREFIX, make sure PREFIX/bin is in"
17216
+       echo "*** your path, or set the XML2_CONFIG environment variable to the"
17217
+       echo "*** full path to xml2-config."
17218
+     else
17219
+       if test -f conf.xmltest ; then
17220
+        :
17221
+       else
17222
+          echo "*** Could not run libxml test program, checking why..."
17223
+          CPPFLAGS="$CPPFLAGS $XML_CPPFLAGS"
17224
+          LIBS="$LIBS $XML_LIBS"
17225
+          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
17226
+/* end confdefs.h.  */
17227
+
17228
+#include <libxml/xmlversion.h>
17229
+#include <stdio.h>
17230
+
17231
+int
17232
+main ()
17233
+{
17234
+ LIBXML_TEST_VERSION; return 0;
17235
+  ;
17236
+  return 0;
17237
+}
17238
+_ACEOF
17239
+if ac_fn_c_try_link "$LINENO"; then :
17240
+   echo "*** The test program compiled, but did not run. This usually means"
17241
+          echo "*** that the run-time linker is not finding LIBXML or finding the wrong"
17242
+          echo "*** version of LIBXML. If it is not finding LIBXML, you'll need to set your"
17243
+          echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
17244
+          echo "*** to the installed location  Also, make sure you have run ldconfig if that"
17245
+          echo "*** is required on your system"
17246
+          echo "***"
17247
+          echo "*** If you have an old version installed, it is best to remove it, although"
17248
+          echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"
17249
+else
17250
+   echo "*** The test program failed to compile or link. See the file config.log for the"
17251
+          echo "*** exact error that occured. This usually means LIBXML was incorrectly installed"
17252
+          echo "*** or that you have moved LIBXML since it was installed. In the latter case, you"
17253
+          echo "*** may want to edit the xml2-config script: $XML2_CONFIG"
17254
+fi
17255
+rm -f core conftest.err conftest.$ac_objext \
17256
+    conftest$ac_exeext conftest.$ac_ext
17257
+          CPPFLAGS="$ac_save_CPPFLAGS"
17258
+          LIBS="$ac_save_LIBS"
17259
+       fi
17260
+     fi
17261
+
17262
+     XML_CPPFLAGS=""
17263
+     XML_LIBS=""
17264
+     :
17265
+  fi
17266
+
17267
+
17268
+  rm -f conf.xmltest
17269
+
17270
+
17271
+$as_echo "#define HAVE_LIBXML2 1" >>confdefs.h
17272
+
17273
+else
17274
+    XML_CPPFLAGS=""
17275
+    XML_LIBS=""
17276
+
17277
+
17278
+
17279
+$as_echo "#define HAVE_LIBXML2 0" >>confdefs.h
17280
+
17281
+fi
17282
+
16991 17283
 # Check whether --enable-getaddrinfo was given.
16992 17284
 if test "${enable_getaddrinfo+set}" = set; then :
16993 17285
   enableval=$enable_getaddrinfo; want_getaddrinfo=$enableval
... ...
@@ -18405,7 +18710,7 @@ $as_echo_n "checking for $clamav_user using ypmatch... " >&6; }
18405 18405
     then
18406 18406
 	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
18407 18407
 $as_echo "no" >&6; }
18408
-	as_fn_error $? "User $clamav_user (and/or group $clamav_group) doesn't exist. Please read the documentation !" "$LINENO" 5
18408
+	as_fn_error $? "User $clamav_user (and/or group $clamav_group) does not exist. Please read the documentation !" "$LINENO" 5
18409 18409
     else
18410 18410
 	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes, user $clamav_user and group $clamav_group" >&5
18411 18411
 $as_echo "yes, user $clamav_user and group $clamav_group" >&6; }
... ...
@@ -21112,6 +21417,10 @@ if test -z "${ENABLE_UNRAR_TRUE}" && test -z "${ENABLE_UNRAR_FALSE}"; then
21112 21112
   as_fn_error $? "conditional \"ENABLE_UNRAR\" was never defined.
21113 21113
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
21114 21114
 fi
21115
+if test -z "${ENABLE_XML_TRUE}" && test -z "${ENABLE_XML_FALSE}"; then
21116
+  as_fn_error $? "conditional \"ENABLE_XML\" was never defined.
21117
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
21118
+fi
21115 21119
 if test -z "${BUILD_CLAMD_TRUE}" && test -z "${BUILD_CLAMD_FALSE}"; then
21116 21120
   as_fn_error $? "conditional \"BUILD_CLAMD\" was never defined.
21117 21121
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
... ...
@@ -23720,6 +24029,10 @@ if test -z "${ENABLE_UNRAR_TRUE}" && test -z "${ENABLE_UNRAR_FALSE}"; then
23720 23720
   as_fn_error $? "conditional \"ENABLE_UNRAR\" was never defined.
23721 23721
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
23722 23722
 fi
23723
+if test -z "${ENABLE_XML_TRUE}" && test -z "${ENABLE_XML_FALSE}"; then
23724
+  as_fn_error $? "conditional \"ENABLE_XML\" was never defined.
23725
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
23726
+fi
23723 23727
 if test -z "${BUILD_CLAMD_TRUE}" && test -z "${BUILD_CLAMD_FALSE}"; then
23724 23728
   as_fn_error $? "conditional \"BUILD_CLAMD\" was never defined.
23725 23729
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
... ...
@@ -26383,6 +26696,24 @@ else
26383 26383
   $as_echo "$want_unrar ($want_unrar)"
26384 26384
 fi
26385 26385
 
26386
+if test "x$XML_LIBS" = "x"; then
26387
+    xml_libs="no"
26388
+else
26389
+    xml_libs="yes"
26390
+fi
26391
+
26392
+
26393
+   $as_echo_n "              dmg and xar : "
26394
+   if test "x" = "xno"; then :
26395
+  $as_echo "$xml_libs (disabled)"
26396
+elif test "x" = "xyes"; then :
26397
+  $as_echo "$xml_libs"
26398
+elif test "x" = "x"; then :
26399
+  $as_echo "$xml_libs"
26400
+else
26401
+  $as_echo "$xml_libs ()"
26402
+fi
26403
+
26386 26404
 
26387 26405
 # Yep, downgrading the compiler avoids the bug too:
26388 26406
 # 4.0.x, and 4.1.0 are the known buggy versions
... ...
@@ -649,10 +649,28 @@ then
649 649
 fi
650 650
 
651 651
 AC_ARG_ENABLE([unrar],
652
-[  --disable-unrar	  don't build libclamunrar and libclamunrar_iface ],
652
+[  --disable-unrar	  do not build libclamunrar and libclamunrar_iface ],
653 653
 want_unrar=$enableval, want_unrar="yes")
654 654
 AM_CONDITIONAL([ENABLE_UNRAR],[test "$want_unrar" = "yes"])
655 655
 
656
+want_xml="yes"
657
+AC_ARG_ENABLE([xml],
658
+[  --disable-xml	  disable DMG and XAR support],
659
+want_xml=$enableval, want_xml="yes")
660
+AM_CONDITIONAL([ENABLE_XML],[test "$want_xml" = "yes"])
661
+
662
+if test "$want_xml" = "yes"
663
+then
664
+    AM_PATH_XML2(2.5.0)
665
+    AC_DEFINE([HAVE_LIBXML2],1,[Define to 1 if you have the 'libxml2' library (-lxml2).])
666
+else
667
+    XML_CPPFLAGS=""
668
+    XML_LIBS=""
669
+    AC_SUBST(XML_CPPFLAGS)
670
+    AC_SUBST(XML_LIBS)
671
+    AC_DEFINE([HAVE_LIBXML2],0,[Define to 1 if you have the 'libxml2' library (-lxml2).])
672
+fi
673
+
656 674
 AC_ARG_ENABLE([getaddrinfo],
657 675
 [  --disable-getaddrinfo          disable support for getaddrinfo],
658 676
 want_getaddrinfo=$enableval, want_getaddrinfo="yes")
... ...
@@ -796,7 +814,7 @@ AC_ARG_ENABLE([pthreads],
796 796
 have_pthreads=$enableval,)
797 797
 
798 798
 AC_ARG_ENABLE([cr],
799
-[  --disable-cr		  don't link with C reentrant library (BSD) ],
799
+[  --disable-cr		  do not link with C reentrant library (BSD) ],
800 800
 use_cr=$enableval,)
801 801
 
802 802
 AC_ARG_ENABLE([id-check],
... ...
@@ -1301,7 +1319,7 @@ then
1301 1301
     if test -z "$clamavuser" || test -z "$clamavgroup"
1302 1302
     then
1303 1303
 	AC_MSG_RESULT(no)
1304
-	AC_MSG_ERROR([User $clamav_user (and/or group $clamav_group) doesn't exist. Please read the documentation !])
1304
+	AC_MSG_ERROR([User $clamav_user (and/or group $clamav_group) does not exist. Please read the documentation !])
1305 1305
     else
1306 1306
 	AC_MSG_RESULT([yes, user $clamav_user and group $clamav_group])
1307 1307
         CLAMAVUSER="$clamav_user"
... ...
@@ -1709,6 +1727,12 @@ CL_MSG_STATUS([autoit_ea06 ],[$have_autoitea06],[])
1709 1709
 CL_MSG_STATUS([bzip2       ],[$bzip_check],[$want_bzip2])
1710 1710
 CL_MSG_STATUS([zlib        ],[$ZLIB_HOME],[yes])
1711 1711
 CL_MSG_STATUS([unrar       ],[$want_unrar],[$want_unrar])
1712
+if test "x$XML_LIBS" = "x"; then
1713
+    xml_libs="no"
1714
+else
1715
+    xml_libs="yes"
1716
+fi
1717
+CL_MSG_STATUS([dmg and xar ],[$xml_libs],[])
1712 1718
 
1713 1719
 # Yep, downgrading the compiler avoids the bug too:
1714 1720
 # 4.0.x, and 4.1.0 are the known buggy versions
... ...
@@ -209,6 +209,9 @@ VERSION = @VERSION@
209 209
 VERSIONSCRIPTFLAG = @VERSIONSCRIPTFLAG@
210 210
 WERR_CFLAGS = @WERR_CFLAGS@
211 211
 WERR_CFLAGS_MILTER = @WERR_CFLAGS_MILTER@
212
+XML2_CONFIG = @XML2_CONFIG@
213
+XML_CPPFLAGS = @XML_CPPFLAGS@
214
+XML_LIBS = @XML_LIBS@
212 215
 abs_builddir = @abs_builddir@
213 216
 abs_srcdir = @abs_srcdir@
214 217
 abs_top_builddir = @abs_top_builddir@
... ...
@@ -242,6 +242,9 @@ VERSION = @VERSION@
242 242
 VERSIONSCRIPTFLAG = @VERSIONSCRIPTFLAG@
243 243
 WERR_CFLAGS = @WERR_CFLAGS@
244 244
 WERR_CFLAGS_MILTER = @WERR_CFLAGS_MILTER@
245
+XML2_CONFIG = @XML2_CONFIG@
246
+XML_CPPFLAGS = @XML_CPPFLAGS@
247
+XML_LIBS = @XML_LIBS@
245 248
 abs_builddir = @abs_builddir@
246 249
 abs_srcdir = @abs_srcdir@
247 250
 abs_top_builddir = @abs_top_builddir@
... ...
@@ -239,6 +239,9 @@ VERSION = @VERSION@
239 239
 VERSIONSCRIPTFLAG = @VERSIONSCRIPTFLAG@
240 240
 WERR_CFLAGS = @WERR_CFLAGS@
241 241
 WERR_CFLAGS_MILTER = @WERR_CFLAGS_MILTER@
242
+XML2_CONFIG = @XML2_CONFIG@
243
+XML_CPPFLAGS = @XML_CPPFLAGS@
244
+XML_LIBS = @XML_LIBS@
242 245
 abs_builddir = @abs_builddir@
243 246
 abs_srcdir = @abs_srcdir@
244 247
 abs_top_builddir = @abs_top_builddir@
... ...
@@ -245,6 +245,9 @@ VERSION = @VERSION@
245 245
 VERSIONSCRIPTFLAG = @VERSIONSCRIPTFLAG@
246 246
 WERR_CFLAGS = @WERR_CFLAGS@
247 247
 WERR_CFLAGS_MILTER = @WERR_CFLAGS_MILTER@
248
+XML2_CONFIG = @XML2_CONFIG@
249
+XML_CPPFLAGS = @XML_CPPFLAGS@
250
+XML_LIBS = @XML_LIBS@
248 251
 abs_builddir = @abs_builddir@
249 252
 abs_srcdir = @abs_srcdir@
250 253
 abs_top_builddir = @abs_top_builddir@
... ...
@@ -320,8 +323,8 @@ freshclam_SOURCES = \
320 320
     $(top_srcdir)/shared/tar.h \
321 321
     $(top_srcdir)/shared/clamdcom.c \
322 322
     $(top_srcdir)/shared/clamdcom.h \
323
-    freshclamcodes.h \
324 323
     freshclam.c \
324
+    freshclamcodes.h \
325 325
     manager.c \
326 326
     manager.h \
327 327
     notify.c \
... ...
@@ -133,8 +133,8 @@ libclamav_nocxx_la_SOURCES = bytecode_nojit.c
133 133
 
134 134
 libclamav_la_LIBADD = @LIBLTDL@ $(IFACELIBADD) $(LLVMLIBADD) libclamav_internal_utils.la @LIBCLAMAV_LIBS@ @THREAD_LIBS@ @LIBM@
135 135
 libclamav_la_DEPENDENCIES =  @LTDLDEPS@ $(IFACEDEP) $(LLVMDEP) libclamav_internal_utils.la
136
-libclamav_la_CFLAGS =$(AM_CFLAGS) -DSEARCH_LIBDIR=\"$(libdir)\"
137
-libclamav_la_LDFLAGS = @TH_SAFE@ -version-info @LIBCLAMAV_VERSION@ -no-undefined
136
+libclamav_la_CFLAGS =$(AM_CFLAGS) $(XML_CPPFLAGS) -DSEARCH_LIBDIR=\"$(libdir)\"
137
+libclamav_la_LDFLAGS = @TH_SAFE@ $(XML_LIBS) -version-info @LIBCLAMAV_VERSION@ -no-undefined
138 138
 
139 139
 if VERSIONSCRIPT
140 140
 libclamav_la_LDFLAGS += -Wl,@VERSIONSCRIPTFLAG@,@top_srcdir@/libclamav/libclamav.map
... ...
@@ -375,6 +375,8 @@ libclamav_la_SOURCES = \
375 375
 	dmg.h \
376 376
 	xar.c \
377 377
 	xar.h \
378
+	sf_base64decode.c \
379
+	sf_base64decode.h \
378 380
 	swf.c \
379 381
 	swf.h \
380 382
 	jpeg.c \
... ...
@@ -185,7 +185,8 @@ am_libclamav_la_OBJECTS = libclamav_la-matcher-ac.lo \
185 185
 	libclamav_la-ishield.lo libclamav_la-bytecode_api.lo \
186 186
 	libclamav_la-bytecode_api_decl.lo libclamav_la-cache.lo \
187 187
 	libclamav_la-bytecode_detect.lo libclamav_la-events.lo \
188
-	libclamav_la-dmg.lo libclamav_la-xar.lo libclamav_la-swf.lo \
188
+	libclamav_la-dmg.lo libclamav_la-xar.lo \
189
+	libclamav_la-sf_base64decode.lo libclamav_la-swf.lo \
189 190
 	libclamav_la-jpeg.lo libclamav_la-png.lo \
190 191
 	libclamav_la-iso9660.lo libclamav_la-arc4.lo \
191 192
 	libclamav_la-rijndael.lo libclamav_la-crtmgr.lo \
... ...
@@ -507,6 +508,9 @@ VERSION = @VERSION@
507 507
 VERSIONSCRIPTFLAG = @VERSIONSCRIPTFLAG@
508 508
 WERR_CFLAGS = @WERR_CFLAGS@
509 509
 WERR_CFLAGS_MILTER = @WERR_CFLAGS_MILTER@
510
+XML2_CONFIG = @XML2_CONFIG@
511
+XML_CPPFLAGS = @XML_CPPFLAGS@
512
+XML_LIBS = @XML_LIBS@
510 513
 abs_builddir = @abs_builddir@
511 514
 abs_srcdir = @abs_srcdir@
512 515
 abs_top_builddir = @abs_top_builddir@
... ...
@@ -661,9 +665,9 @@ libclamav_internal_utils_nothreads_la_CFLAGS = $(AM_CFLAGS) -DCL_NOTHREADS
661 661
 libclamav_nocxx_la_SOURCES = bytecode_nojit.c
662 662
 libclamav_la_LIBADD = @LIBLTDL@ $(IFACELIBADD) $(LLVMLIBADD) libclamav_internal_utils.la @LIBCLAMAV_LIBS@ @THREAD_LIBS@ @LIBM@
663 663
 libclamav_la_DEPENDENCIES = @LTDLDEPS@ $(IFACEDEP) $(LLVMDEP) libclamav_internal_utils.la
664
-libclamav_la_CFLAGS = $(AM_CFLAGS) -DSEARCH_LIBDIR=\"$(libdir)\"
665
-libclamav_la_LDFLAGS = @TH_SAFE@ -version-info @LIBCLAMAV_VERSION@ \
666
-	-no-undefined $(am__append_6)
664
+libclamav_la_CFLAGS = $(AM_CFLAGS) $(XML_CPPFLAGS) -DSEARCH_LIBDIR=\"$(libdir)\"
665
+libclamav_la_LDFLAGS = @TH_SAFE@ $(XML_LIBS) -version-info \
666
+	@LIBCLAMAV_VERSION@ -no-undefined $(am__append_6)
667 667
 include_HEADERS = clamav.h
668 668
 libclamav_la_SOURCES = clamav.h matcher-ac.c matcher-ac.h matcher-bm.c \
669 669
 	matcher-bm.h matcher-hash.c matcher-hash.h matcher.c matcher.h \
... ...
@@ -708,12 +712,13 @@ libclamav_la_SOURCES = clamav.h matcher-ac.c matcher-ac.h matcher-bm.c \
708 708
 	bcfeatures.h bytecode_api.c bytecode_api_decl.c bytecode_api.h \
709 709
 	bytecode_api_impl.h bytecode_hooks.h cache.c cache.h \
710 710
 	bytecode_detect.c bytecode_detect.h builtin_bytecodes.h \
711
-	events.c events.h dmg.c dmg.h xar.c xar.h swf.c swf.h jpeg.c \
712
-	jpeg.h png.c png.h iso9660.c iso9660.h arc4.c arc4.h \
713
-	rijndael.c rijndael.h crtmgr.c crtmgr.h asn1.c asn1.h bignum.h \
714
-	bignum_fast.h tomsfastmath/addsub/fp_add.c \
715
-	tomsfastmath/addsub/fp_add_d.c tomsfastmath/addsub/fp_addmod.c \
716
-	tomsfastmath/addsub/fp_cmp.c tomsfastmath/addsub/fp_cmp_d.c \
711
+	events.c events.h dmg.c dmg.h xar.c xar.h sf_base64decode.c \
712
+	sf_base64decode.h swf.c swf.h jpeg.c jpeg.h png.c png.h \
713
+	iso9660.c iso9660.h arc4.c arc4.h rijndael.c rijndael.h \
714
+	crtmgr.c crtmgr.h asn1.c asn1.h bignum.h bignum_fast.h \
715
+	tomsfastmath/addsub/fp_add.c tomsfastmath/addsub/fp_add_d.c \
716
+	tomsfastmath/addsub/fp_addmod.c tomsfastmath/addsub/fp_cmp.c \
717
+	tomsfastmath/addsub/fp_cmp_d.c \
717 718
 	tomsfastmath/addsub/fp_cmp_mag.c tomsfastmath/addsub/fp_sub.c \
718 719
 	tomsfastmath/addsub/fp_sub_d.c tomsfastmath/addsub/fp_submod.c \
719 720
 	tomsfastmath/addsub/s_fp_add.c tomsfastmath/addsub/s_fp_sub.c \
... ...
@@ -1066,6 +1071,7 @@ distclean-compile:
1066 1066
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-s_fp_add.Plo@am__quote@
1067 1067
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-s_fp_sub.Plo@am__quote@
1068 1068
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-scanners.Plo@am__quote@
1069
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-sf_base64decode.Plo@am__quote@
1069 1070
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-sha1.Plo@am__quote@
1070 1071
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-sha256.Plo@am__quote@
1071 1072
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-sis.Plo@am__quote@
... ...
@@ -1856,6 +1862,13 @@ libclamav_la-xar.lo: xar.c
1856 1856
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
1857 1857
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-xar.lo `test -f 'xar.c' || echo '$(srcdir)/'`xar.c
1858 1858
 
1859
+libclamav_la-sf_base64decode.lo: sf_base64decode.c
1860
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-sf_base64decode.lo -MD -MP -MF $(DEPDIR)/libclamav_la-sf_base64decode.Tpo -c -o libclamav_la-sf_base64decode.lo `test -f 'sf_base64decode.c' || echo '$(srcdir)/'`sf_base64decode.c
1861
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-sf_base64decode.Tpo $(DEPDIR)/libclamav_la-sf_base64decode.Plo
1862
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='sf_base64decode.c' object='libclamav_la-sf_base64decode.lo' libtool=yes @AMDEPBACKSLASH@
1863
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
1864
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-sf_base64decode.lo `test -f 'sf_base64decode.c' || echo '$(srcdir)/'`sf_base64decode.c
1865
+
1859 1866
 libclamav_la-swf.lo: swf.c
1860 1867
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-swf.lo -MD -MP -MF $(DEPDIR)/libclamav_la-swf.Tpo -c -o libclamav_la-swf.lo `test -f 'swf.c' || echo '$(srcdir)/'`swf.c
1861 1868
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-swf.Tpo $(DEPDIR)/libclamav_la-swf.Plo
... ...
@@ -23,23 +23,78 @@
23 23
 #endif
24 24
 
25 25
 #include <stdio.h>
26
+#include <errno.h>
27
+#if HAVE_STRING_H
28
+#include <string.h>
29
+#endif
26 30
 #include <ctype.h>
31
+#include <fcntl.h>
32
+#if HAVE_SYS_PARAM_H
33
+#include <sys/param.h>  /* for NAME_MAX */
34
+#endif
35
+
36
+#if HAVE_LIBZ
37
+#include <zlib.h>
38
+#endif
39
+#if HAVE_BZLIB_H
40
+#include <bzlib.h>
41
+#ifdef NOBZ2PREFIX
42
+#define BZ2_bzDecompress bzDecompress
43
+#define BZ2_bzDecompressEnd bzDecompressEnd
44
+#define BZ2_bzDecompressInit bzDecompressInit
45
+#endif
46
+#endif
47
+
48
+#include <libxml/tree.h>
49
+#include <libxml/parser.h>
50
+#include <libxml/xmlreader.h>
27 51
 
28 52
 #include "cltypes.h"
29 53
 #include "others.h"
30 54
 #include "dmg.h"
31 55
 #include "scanners.h"
56
+#include "sf_base64decode.h"
57
+
58
+// #define DEBUG_DMG_PARSE
59
+
60
+#ifdef DEBUG_DMG_PARSE
61
+#  define dmg_parsemsg(...) cli_dbgmsg( __VA_ARGS__)
62
+#else
63
+#  define dmg_parsemsg(...) ;
64
+#endif
65
+
66
+enum dmgReadState {
67
+    DMG_FIND_BASE_PLIST = 0,
68
+    DMG_FIND_BASE_DICT = 1,
69
+    DMG_FIND_KEY_RESOURCE_FORK = 2,
70
+    DMG_FIND_DICT_RESOURCE_FORK = 3,
71
+    DMG_FIND_KEY_BLKX = 4,
72
+    DMG_FIND_BLKX_CONTAINER = 5,
73
+    DMG_FIND_KEY_DATA = 6,
74
+    DMG_FIND_DATA_MISH = 7,
75
+    DMG_MAX_STATE = 8
76
+};
77
+
78
+static int dmg_extract_xml(cli_ctx *, char *, struct dmg_koly_block *);
79
+#if HAVE_LIBXML2
80
+static int dmg_decode_mish(cli_ctx *, unsigned int *, xmlChar *, struct dmg_mish_with_stripes *);
81
+#endif
82
+static int cmp_mish_stripes(const void * stripe_a, const void * stripe_b);
83
+static int dmg_track_sectors(uint64_t *, uint8_t *, uint32_t, uint32_t, uint64_t);
84
+static int dmg_handle_mish(cli_ctx *, unsigned int, char *, uint64_t, struct dmg_mish_with_stripes *);
32 85
 
33 86
 int cli_scandmg(cli_ctx *ctx)
34 87
 {
35 88
     struct dmg_koly_block hdr;
36
-    int ret, conv;
37
-    size_t maplen;
89
+    int ret, namelen, ofd;
90
+    size_t maplen, nread;
91
+    off_t pos = 0;
92
+    char *dirname, *tmpfile;
93
+    const char *outdata;
94
+    unsigned int file = 0;
38 95
 
39
-    char name[513];
40
-    unsigned int file = 0, trailer = 0;
96
+    unsigned int trailer = 0;
41 97
     uint32_t filesize, namesize, hdr_namesize;
42
-    off_t pos = 0;
43 98
 
44 99
     if (!ctx || !ctx->fmap) {
45 100
         cli_errmsg("cli_scandmg: Invalid context\n");
... ...
@@ -69,8 +124,614 @@ int cli_scandmg(cli_ctx *ctx)
69 69
         return CL_EFORMAT;
70 70
     }
71 71
 
72
-    /* TODO: the rest of the unpacking */
72
+    hdr.xmlOffset = be64_to_host(hdr.xmlOffset);
73
+    hdr.xmlLength = be64_to_host(hdr.xmlLength);
74
+    if (hdr.xmlLength > (uint64_t)INT_MAX) {
75
+        cli_dbgmsg("cli_scandmg: The embedded XML is way larger than necessary, and probably corrupt or tampered with.\n");
76
+        return CL_EFORMAT;
77
+    }
78
+    if ((hdr.xmlOffset > (uint64_t)maplen) || (hdr.xmlLength > (uint64_t)maplen)
79
+        || (hdr.xmlOffset + hdr.xmlLength) > (uint64_t)maplen) {
80
+        cli_dbgmsg("cli_scandmg: XML out of range for this file\n");
81
+        return CL_EFORMAT;
82
+    }
83
+    cli_dbgmsg("cli_scandmg: XML offset %lu len %d\n", (unsigned long)hdr.xmlOffset, (int)hdr.xmlLength);
84
+
85
+    /* Create temp folder for contents */
86
+    if (!(dirname = cli_gentemp(ctx->engine->tmpdir))) {
87
+        return CL_ETMPDIR;
88
+    }
89
+    if (mkdir(dirname, 0700)) {
90
+        cli_errmsg("cli_scandmg: Cannot create temporary directory %s\n", dirname);
91
+        free(dirname);
92
+        return CL_ETMPDIR;
93
+    }
94
+    cli_dbgmsg("cli_scandmg: Extracting into %s\n", dirname);
95
+
96
+    /* Dump XML to tempfile, if needed */
97
+    if (ctx->engine->keeptmp) {
98
+        int xret;
99
+        xret = dmg_extract_xml(ctx, dirname, &hdr);
100
+
101
+        if (xret != CL_SUCCESS) {
102
+            /* Printed err detail inside dmg_extract_xml */
103
+            free(dirname);
104
+            return xret;
105
+        }
106
+    }
73 107
 
108
+    /* scan XML with cli_map_scandesc */
109
+    ret = cli_map_scandesc(*ctx->fmap, (off_t)hdr.xmlOffset, (size_t)hdr.xmlLength, ctx);
110
+    if (ret != CL_CLEAN) {
111
+        cli_dbgmsg("cli_scandmg: retcode from scanning TOC xml: %s\n", cl_strerror(ret));
112
+        if (!ctx->engine->keeptmp)
113
+            cli_rmdirs(dirname);
114
+        free(dirname);
115
+        return ret;
116
+    }
117
+
118
+    /* page data from map */
119
+    outdata = fmap_need_off_once_len(*ctx->fmap, hdr.xmlOffset, hdr.xmlLength, &nread);
120
+    if (!outdata || (nread != hdr.xmlLength)) {
121
+        cli_errmsg("cli_scandmg: Failed getting XML from map, len %d\n", (int)hdr.xmlLength);
122
+        if (!ctx->engine->keeptmp)
123
+            cli_rmdirs(dirname);
124
+        free(dirname);
125
+        return CL_EMAP;
126
+    }
127
+
128
+    /* time to walk the tree */
129
+    /* plist -> dict -> (key:resource_fork) dict -> (key:blkx) array -> dict */
130
+    /* each of those bottom level dict should have 4 parts */
131
+    /* [ Attributes, Data, ID, Name ], where Data is Base64 mish block */
132
+
133
+/* This is the block where we require libxml2 */
134
+#if HAVE_LIBXML2
135
+
136
+/* XML_PARSE_NOENT | XML_PARSE_NONET | XML_PARSE_COMPACT */
137
+#define DMG_XML_PARSE_OPTS (1 << 1 | 1 << 11 | 1 << 16)
138
+
139
+    xmlTextReaderPtr reader = xmlReaderForMemory(outdata, (int)hdr.xmlLength, "toc.xml", NULL, DMG_XML_PARSE_OPTS);
140
+    if (!reader) {
141
+        cli_dbgmsg("cli_scandmg: Failed parsing XML!\n");
142
+        if (!ctx->engine->keeptmp)
143
+            cli_rmdirs(dirname);
144
+        free(dirname);
145
+        return CL_EFORMAT;
146
+    }
147
+
148
+    enum dmgReadState state = DMG_FIND_BASE_PLIST;
149
+    int stateDepth[DMG_MAX_STATE];
150
+    stateDepth[DMG_FIND_BASE_PLIST] = -1;
151
+
152
+    // May need to check for (xmlTextReaderIsEmptyElement(reader) == 0)
153
+
154
+    /* Break loop if have return code or reader can't read any more */
155
+    while ((ret == CL_CLEAN) && (xmlTextReaderRead(reader) == 1)) {
156
+        xmlReaderTypes nodeType;
157
+        nodeType = xmlTextReaderNodeType(reader);
158
+
159
+        if (nodeType == XML_READER_TYPE_ELEMENT) {
160
+            // New element, do name check
161
+            xmlChar *nodeName;
162
+            int depth;
163
+
164
+            depth = xmlTextReaderDepth(reader);
165
+            if (depth < 0) {
166
+                break;
167
+            }
168
+            if ((depth > 50) && SCAN_ALGO) {
169
+                // Possible heuristic, should limit runaway
170
+                cli_dbgmsg("cli_scandmg: Excessive nesting in DMG TOC.\n");
171
+                break;
172
+            }
173
+            nodeName = xmlTextReaderLocalName(reader);
174
+            if (!nodeName)
175
+                continue;
176
+            dmg_parsemsg("read: name %s depth %d\n", nodeName, depth);
177
+
178
+            if ((state == DMG_FIND_DATA_MISH)
179
+                    && (depth == stateDepth[state-1])) {
180
+                xmlChar * textValue;
181
+                struct dmg_mish_with_stripes mish_set;
182
+                /* Reset state early, for continue cases */
183
+                stateDepth[DMG_FIND_KEY_DATA] = -1;
184
+                state--;
185
+                if (xmlStrcmp(nodeName, "data") != 0) {
186
+                    cli_dbgmsg("cli_scandmg: Not blkx data element\n");
187
+                    xmlFree(nodeName);
188
+                    continue;
189
+                }
190
+                dmg_parsemsg("read: Found blkx data element\n");
191
+                /* Pull out data content from text */
192
+                if (xmlTextReaderIsEmptyElement(reader)) {
193
+                    cli_dbgmsg("cli_scandmg: blkx data element is empty\n");
194
+                    xmlFree(nodeName);
195
+                    continue;
196
+                }
197
+                if (xmlTextReaderRead(reader) != 1) {
198
+                    xmlFree(nodeName);
199
+                    break;
200
+                }   
201
+                if (xmlTextReaderNodeType(reader) != XML_READER_TYPE_TEXT) {
202
+                    cli_dbgmsg("cli_scandmg: Next node not text\n");
203
+                    xmlFree(nodeName);
204
+                    continue;
205
+                }
206
+                textValue = xmlTextReaderValue(reader);
207
+                if (textValue == NULL) {
208
+                    xmlFree(nodeName);
209
+                    continue;
210
+                }
211
+                /* Have encoded mish block */
212
+                ret = dmg_decode_mish(ctx, &file, textValue, &mish_set);
213
+                xmlFree(textValue);
214
+                if (ret == CL_EFORMAT) {
215
+                    /* Didn't decode, or not a mish block */
216
+                    ret = CL_CLEAN;
217
+                    xmlFree(nodeName);
218
+                    continue;
219
+                }
220
+                else if (ret != CL_CLEAN) {
221
+                    xmlFree(nodeName);
222
+                    continue;
223
+                }
224
+                /* Handle & scan mish block */
225
+                ret = dmg_handle_mish(ctx, file, dirname, hdr.xmlOffset, &mish_set);
226
+                free(mish_set.mish);
227
+            }
228
+            if ((state == DMG_FIND_KEY_DATA)
229
+                    && (depth > stateDepth[state-1])
230
+                    && (xmlStrcmp(nodeName, "key") == 0)) {
231
+                xmlChar * textValue;
232
+                dmg_parsemsg("read: Found key - checking for Data\n");
233
+                if (xmlTextReaderRead(reader) != 1) {
234
+                    xmlFree(nodeName);
235
+                    break;
236
+                }   
237
+                if (xmlTextReaderNodeType(reader) != XML_READER_TYPE_TEXT) {
238
+                    cli_dbgmsg("cli_scandmg: Key node no text\n");
239
+                    xmlFree(nodeName);
240
+                    continue;
241
+                }
242
+                textValue = xmlTextReaderValue(reader);
243
+                if (textValue == NULL) {
244
+                    cli_dbgmsg("cli_scandmg: no value from xmlTextReaderValue\n");
245
+                    xmlFree(nodeName);
246
+                    continue;
247
+                }
248
+                if (xmlStrcmp(textValue, "Data") == 0) {
249
+                    dmg_parsemsg("read: Matched data\n");
250
+                    stateDepth[DMG_FIND_KEY_DATA] = depth;
251
+                    state++;
252
+                }
253
+                else {
254
+                    dmg_parsemsg("read: text value is %s\n", textValue);
255
+                }
256
+                xmlFree(textValue);
257
+            }
258
+            if ((state == DMG_FIND_BLKX_CONTAINER)
259
+                    && (depth == stateDepth[state-1])) {
260
+                if (xmlStrcmp(nodeName, "array") == 0) {
261
+                    dmg_parsemsg("read: Found array blkx\n");
262
+                    stateDepth[DMG_FIND_BLKX_CONTAINER] = depth;
263
+                    state++;
264
+                }
265
+                else if (xmlStrcmp(nodeName, "dict") == 0) {
266
+                    dmg_parsemsg("read: Found dict blkx\n");
267
+                    stateDepth[DMG_FIND_BLKX_CONTAINER] = depth;
268
+                    state++;
269
+                }
270
+                else {
271
+                    cli_dbgmsg("cli_scandmg: Bad blkx, not container\n");
272
+                    stateDepth[DMG_FIND_KEY_BLKX] = -1;
273
+                    state--;
274
+                }
275
+            }
276
+            if ((state == DMG_FIND_KEY_BLKX)
277
+                    && (depth == stateDepth[state-1] + 1)
278
+                    && (xmlStrcmp(nodeName, "key") == 0)) {
279
+                xmlChar * textValue;
280
+                dmg_parsemsg("read: Found key - checking for blkx\n");
281
+                if (xmlTextReaderRead(reader) != 1) {
282
+                    xmlFree(nodeName);
283
+                    break;
284
+                }   
285
+                if (xmlTextReaderNodeType(reader) != XML_READER_TYPE_TEXT) {
286
+                    cli_dbgmsg("cli_scandmg: Key node no text\n");
287
+                    xmlFree(nodeName);
288
+                    continue;
289
+                }
290
+                textValue = xmlTextReaderValue(reader);
291
+                if (textValue == NULL) {
292
+                    cli_dbgmsg("cli_scandmg: no value from xmlTextReaderValue\n");
293
+                    xmlFree(nodeName);
294
+                    continue;
295
+                }
296
+                if (xmlStrcmp(textValue, "blkx") == 0) {
297
+                    cli_dbgmsg("cli_scandmg: Matched blkx\n");
298
+                    stateDepth[DMG_FIND_KEY_BLKX] = depth;
299
+                    state++;
300
+                }
301
+                else {
302
+                    cli_dbgmsg("cli_scandmg: wanted blkx, text value is %s\n", textValue);
303
+                }
304
+                xmlFree(textValue);
305
+            }
306
+            if ((state == DMG_FIND_DICT_RESOURCE_FORK)
307
+                    && (depth == stateDepth[state-1])) {
308
+                if (xmlStrcmp(nodeName, "dict") == 0) {
309
+                    dmg_parsemsg("read: Found resource-fork dict\n");
310
+                    stateDepth[DMG_FIND_DICT_RESOURCE_FORK] = depth;
311
+                    state++;
312
+                }
313
+                else {
314
+                    dmg_parsemsg("read: Not resource-fork dict\n");
315
+                    stateDepth[DMG_FIND_KEY_RESOURCE_FORK] = -1;
316
+                    state--;
317
+                }
318
+            }
319
+            if ((state == DMG_FIND_KEY_RESOURCE_FORK)
320
+                    && (depth == stateDepth[state-1] + 1)
321
+                    && (xmlStrcmp(nodeName, "key") == 0)) {
322
+                dmg_parsemsg("read: Found resource-fork key\n");
323
+                stateDepth[DMG_FIND_KEY_RESOURCE_FORK] = depth;
324
+                state++;
325
+            }
326
+            if ((state == DMG_FIND_BASE_DICT)
327
+                    && (depth == stateDepth[state-1] + 1)
328
+                    && (xmlStrcmp(nodeName, "dict") == 0)) {
329
+                dmg_parsemsg("read: Found dict start\n");
330
+                stateDepth[DMG_FIND_BASE_DICT] = depth;
331
+                state++;
332
+            }
333
+            if ((state == DMG_FIND_BASE_PLIST) && (xmlStrcmp(nodeName, "plist") == 0)) {
334
+                dmg_parsemsg("read: Found plist start\n");
335
+                stateDepth[DMG_FIND_BASE_PLIST] = depth;
336
+                state++;
337
+            }
338
+            xmlFree(nodeName);
339
+        }
340
+        else if ((nodeType == XML_READER_TYPE_END_ELEMENT) && (state > DMG_FIND_BASE_PLIST)) {
341
+            int significantEnd = 0;
342
+            int depth = xmlTextReaderDepth(reader);
343
+            if (depth < 0) {
344
+                break;
345
+            }
346
+            else if (depth < stateDepth[state-1]) {
347
+                significantEnd = 1;
348
+            }
349
+            else if ((depth == stateDepth[state-1])
350
+                    && (state-1 == DMG_FIND_BLKX_CONTAINER)) {
351
+                /* Special case, ending blkx container */
352
+                significantEnd = 1;
353
+            }
354
+            if (significantEnd) {
355
+                dmg_parsemsg("read: significant end tag, state %d\n", state);
356
+                stateDepth[state-1] = -1;
357
+                state--;
358
+                if ((state-1 == DMG_FIND_KEY_RESOURCE_FORK)
359
+                        || (state-1 == DMG_FIND_KEY_BLKX)) {
360
+                    /* Keys end their own tag (validly) and the next state depends on the following tag */
361
+                    // cli_dbgmsg("read: significant end tag ending prior key state\n");
362
+                    stateDepth[state-1] = -1;
363
+                    state--;
364
+                }
365
+            }
366
+            else {
367
+                dmg_parsemsg("read: not significant end tag, state %d depth %d prior depth %d\n", state, depth, stateDepth[state-1]);
368
+            }
369
+        }
370
+    }
371
+
372
+#else
373
+
374
+    cli_dbgmsg("cli_scandmg: libxml2 support is compiled out. It is required for full DMG support.\n");
375
+
376
+#endif
377
+
378
+    /* Cleanup */
379
+    if (!ctx->engine->keeptmp)
380
+        cli_rmdirs(dirname);
381
+    free(dirname);
382
+    return ret;
383
+}
384
+
385
+#if HAVE_LIBXML2
386
+/* Transform the base64-encoded string into the binary structure
387
+ * After this, the base64 string (from xml) can be released
388
+ * If mish_set->mish is set by this function, it must be freed by the caller */
389
+static int dmg_decode_mish(cli_ctx *ctx, unsigned int *mishblocknum, xmlChar *mish_base64,
390
+        struct dmg_mish_with_stripes *mish_set)
391
+{
392
+    int ret = CL_CLEAN;
393
+    size_t base64_len, buff_size, decoded_len;
394
+    uint8_t *decoded;
395
+    const uint8_t mish_magic[4] = { 0x6d, 0x69, 0x73, 0x68 };
396
+
397
+    (*mishblocknum)++;
398
+    base64_len = strlen(mish_base64);
399
+    cli_dbgmsg("dmg_decode_mish: len of encoded block %u is %lu\n", *mishblocknum, base64_len);
400
+
401
+    /* speed vs memory, could walk the encoded data and skip whitespace in calculation */
402
+    buff_size = 3 * base64_len / 4 + 4;
403
+    cli_dbgmsg("dmg_decode_mish: buffer for mish block %u is %lu\n", *mishblocknum, (unsigned long)buff_size);
404
+    decoded = cli_malloc(buff_size);
405
+    if (!decoded)
406
+        return CL_EMEM;
407
+
408
+    if (sf_base64decode((uint8_t *)mish_base64, base64_len, decoded, buff_size - 1, &decoded_len)) {
409
+        cli_dbgmsg("dmg_decode_mish: failed base64 decoding on mish block %u\n", *mishblocknum);
410
+        free(decoded);
411
+        return CL_EFORMAT;
412
+    }
413
+    cli_dbgmsg("dmg_decode_mish: len of decoded mish block %u is %lu\n", *mishblocknum, (unsigned long)decoded_len);
414
+    
415
+    if (decoded_len < sizeof(struct dmg_mish_block)) {
416
+        cli_dbgmsg("dmg_decode_mish: block %u too short for valid mish block\n", *mishblocknum);
417
+        free(decoded);
418
+        return CL_EFORMAT;
419
+    }
420
+    /* mish check: magic is mish, have to check after conversion from base64
421
+     * mish base64 is bWlzaA [but last character can change last two bytes]
422
+     * won't see that in practice much (affects value of version field) */
423
+    if (memcmp(decoded, mish_magic, 4)) {
424
+        cli_dbgmsg("dmg_decode_mish: block %u does not have mish magic\n", *mishblocknum);
425
+        free(decoded);
426
+        return CL_EFORMAT;
427
+    }
428
+
429
+    mish_set->mish = (struct dmg_mish_block *)decoded;
430
+    mish_set->mish->startSector = be64_to_host(mish_set->mish->startSector);
431
+    mish_set->mish->sectorCount = be64_to_host(mish_set->mish->sectorCount);
432
+    mish_set->mish->dataOffset = be64_to_host(mish_set->mish->dataOffset);
433
+    // mish_set->mish->bufferCount = be32_to_host(mish_set->mish->bufferCount);
434
+    mish_set->mish->blockDataCount = be32_to_host(mish_set->mish->blockDataCount);
435
+
436
+    cli_dbgmsg("dmg_decode_mish: startSector = %lu\n", mish_set->mish->startSector);
437
+    cli_dbgmsg("dmg_decode_mish: sectorCount = %lu\n", mish_set->mish->sectorCount);
438
+    cli_dbgmsg("dmg_decode_mish: dataOffset = %lu\n", mish_set->mish->dataOffset);
439
+    // cli_dbgmsg("dmg_decode_mish: bufferCount = %lu\n", mish_set->mish->bufferCount);
440
+    cli_dbgmsg("dmg_decode_mish: blockDataCount = %lu\n", mish_set->mish->blockDataCount);
441
+
442
+    /* decoded length should be mish block + blockDataCount * 40 */
443
+    if (decoded_len < (sizeof(struct dmg_mish_block)
444
+         + mish_set->mish->blockDataCount * sizeof(struct dmg_block_data))) {
445
+        cli_dbgmsg("dmg_decode_mish: mish block %u too small\n", *mishblocknum);
446
+        free(decoded);
447
+        mish_set->mish = NULL;
448
+        return CL_EFORMAT;
449
+    }
450
+    else if (decoded_len > (sizeof(struct dmg_mish_block)
451
+         + mish_set->mish->blockDataCount * sizeof(struct dmg_block_data))) {
452
+        cli_dbgmsg("dmg_decode_mish: mish block %u bigger than needed, continuing\n", *mishblocknum);
453
+    }
454
+
455
+    mish_set->stripes = (struct dmg_block_data *)(decoded + sizeof(struct dmg_mish_block));
74 456
     return CL_CLEAN;
75 457
 }
458
+#endif
459
+
460
+/* Comparator for stripe sorting */
461
+static int cmp_mish_stripes(const void * stripe_a, const void * stripe_b)
462
+{
463
+    const struct dmg_block_data *a = stripe_a, *b = stripe_b;
464
+    return a->startSector - b->startSector;
465
+}
466
+
467
+/* Safely track sector sizes for output estimate */
468
+static int dmg_track_sectors(uint64_t *total, uint8_t *data_to_write,
469
+    uint32_t stripeNum, uint32_t stripeType, uint64_t stripeCount)
470
+{
471
+    int ret = CL_CLEAN, usable = 0;
472
+
473
+    switch (stripeType) {
474
+        case DMG_STRIPE_STORED:
475
+            *data_to_write = 1;
476
+            usable = 1;
477
+            break;
478
+        case DMG_STRIPE_ADC:
479
+            *data_to_write = 1;
480
+            usable = 1;
481
+            break;
482
+        case DMG_STRIPE_DEFLATE:
483
+#if HAVE_LIBZ
484
+            *data_to_write = 1;
485
+            usable = 1;
486
+#else
487
+            cli_warnmsg("dmg_track_sectors: Need zlib decompression to properly scan this file.\n");
488
+            return CL_EFORMAT;
489
+#endif
490
+            break;
491
+        case DMG_STRIPE_BZ:
492
+#if HAVE_BZLIB_H
493
+            *data_to_write = 1;
494
+            usable = 1;
495
+#else
496
+            cli_warnmsg("dmg_track_sectors: Need bzip2 decompression to properly scan this file.\n");
497
+            return CL_EFORMAT;
498
+#endif
499
+            break;
500
+        case DMG_STRIPE_EMPTY:
501
+        case DMG_STRIPE_ZEROES:
502
+            /* Usable, but only zeroes is not worth scanning on its own */
503
+            usable = 1;
504
+            break;
505
+        case DMG_STRIPE_SKIP:
506
+        case DMG_STRIPE_END:
507
+            /* These should be sectorCount 0 */
508
+            break;
509
+        default:
510
+            if (stripeCount) {
511
+                /* Continue for now */
512
+                cli_dbgmsg("dmg_track_sectors: unknown type on stripe %lu, will skip\n", stripeNum);
513
+            }
514
+            else {
515
+                /* Continue, no sectors missed  */
516
+                cli_dbgmsg("dmg_track_sectors: unknown type on empty stripe %lu\n", stripeNum);
517
+            }
518
+            break;
519
+    }
520
+
521
+    if (usable) {
522
+        /* Check for wrap */
523
+        if (*total < (*total + stripeCount)) {
524
+            *total = *total + stripeCount;
525
+        }
526
+        else if (stripeCount) {
527
+            cli_dbgmsg("dmg_track_sectors: *total would wrap uint64, suspicious\n");
528
+            ret = CL_EFORMAT;
529
+        }
530
+        else {
531
+            /* Can continue */
532
+            cli_dbgmsg("dmg_track_sectors: unexpected zero sectorCount on stripe %lu\n", stripeNum);
533
+        }
534
+    }
535
+
536
+    return ret;
537
+}
538
+
539
+/* Given mish data, reconstruct the partition details */
540
+static int dmg_handle_mish(cli_ctx *ctx, unsigned int mishblocknum, char *dir,
541
+        uint64_t xmlOffset, struct dmg_mish_with_stripes *mish_set)
542
+{
543
+    struct dmg_block_data *blocklist = mish_set->stripes;
544
+    uint64_t totalSectors = 0;
545
+    uint32_t i;
546
+    unsigned long projected_size;
547
+    int ret = CL_CLEAN, ofd;
548
+    uint8_t sorted = 1, writeable_data = 0;
549
+    char outfile[NAME_MAX + 1];
550
+
551
+    /* First loop, fix endian-ness and check if already sorted */
552
+    for (i = 0; i < mish_set->mish->blockDataCount; i++) {
553
+        blocklist[i].type = be32_to_host(blocklist[i].type);
554
+        // blocklist[i].reserved = be32_to_host(blocklist[i].reserved);
555
+        blocklist[i].startSector = be64_to_host(blocklist[i].startSector);
556
+        blocklist[i].sectorCount = be64_to_host(blocklist[i].sectorCount);
557
+        blocklist[i].dataOffset = be64_to_host(blocklist[i].dataOffset);
558
+        blocklist[i].dataLength = be64_to_host(blocklist[i].dataLength);
559
+        cli_dbgmsg("mish %lu block %u type %lx start %lu count %lu source %lu length %lu\n", mishblocknum, i,
560
+            blocklist[i].type, blocklist[i].startSector, blocklist[i].sectorCount,
561
+            blocklist[i].dataOffset, blocklist[i].dataLength);
562
+        if ((blocklist[i].dataOffset > xmlOffset) || 
563
+               (blocklist[i].dataOffset + blocklist[i].dataLength > xmlOffset)) {
564
+            cli_dbgmsg("dmg_handle_mish: invalid stripe offset and/or length\n");
565
+            return CL_EFORMAT;
566
+        }
567
+        if ((i > 0) && sorted && (blocklist[i].startSector < blocklist[i-1].startSector)) {
568
+            cli_dbgmsg("dmg_handle_mish: stripes not in order, will have to sort\n");
569
+            sorted = 0;
570
+        }
571
+        if (dmg_track_sectors(&totalSectors, &writeable_data, i, blocklist[i].type, blocklist[i].sectorCount)) {
572
+            /* reason was logged from dmg_track_sector_count */
573
+            return CL_EFORMAT;
574
+        }
575
+    }
576
+
577
+    if (!sorted) {
578
+        cli_qsort(blocklist, mish_set->mish->blockDataCount, sizeof(struct dmg_block_data), cmp_mish_stripes);
579
+    }
580
+    cli_dbgmsg("dmg_handle_mish: stripes in order!\n");
581
+
582
+    /* Size checks */
583
+    if ((writeable_data == 0) || (totalSectors == 0)) {
584
+        cli_dbgmsg("dmg_handle_mish: no data to output\n");
585
+        return CL_CLEAN;
586
+    }
587
+    else if (totalSectors > (ULONG_MAX / DMG_SECTOR_SIZE)) {
588
+        /* cli_checklimits only takes unsigned long for now */
589
+        cli_warnmsg("dmg_handle_mish: mish block %u too big to handle (for now)", mishblocknum);
590
+        return CL_CLEAN;
591
+    }
592
+    projected_size = (unsigned long)(totalSectors * DMG_SECTOR_SIZE);
593
+    ret = cli_checklimits("cli_scandmg", ctx, projected_size, 0, 0);
594
+    if (ret != CL_CLEAN) {
595
+        /* limits exceeded */
596
+        return ret;
597
+    }
598
+
599
+    /* Prepare for file */
600
+    snprintf(outfile, sizeof(outfile)-1, "%s"PATHSEP"dmg%02u", dir, mishblocknum);
601
+    outfile[sizeof(outfile)-1] = '\0';
602
+    ofd = open(outfile, O_RDWR|O_CREAT|O_EXCL|O_TRUNC|O_BINARY, 0600);
603
+    if (ofd < 0) {
604
+        char err[128];
605
+        cli_errmsg("cli_scandmg: Can't create temporary file %s: %s\n", 
606
+            outfile, cli_strerror(errno, err, sizeof(err)));
607
+        return CL_ETMPFILE;
608
+    }
609
+    cli_dbgmsg("dmg_handle_mish: extracting block %u to %s\n", mishblocknum, outfile);
610
+
611
+    for(i=0; i < mish_set->mish->blockDataCount && ret == CL_CLEAN; i++) {
612
+        switch (blocklist[i].type) {
613
+            case DMG_STRIPE_EMPTY:
614
+            case DMG_STRIPE_ZEROES:
615
+                cli_dbgmsg("dmg_handle_mish: stripe %lu, zero block\n", (unsigned long)i);
616
+                break;
617
+            case DMG_STRIPE_STORED:
618
+                cli_dbgmsg("dmg_handle_mish: stripe %lu, stored data block\n", (unsigned long)i);
619
+                break;
620
+            case DMG_STRIPE_ADC:
621
+                cli_dbgmsg("dmg_handle_mish: stripe %lu, ADC data block\n", (unsigned long)i);
622
+                break;
623
+            case DMG_STRIPE_DEFLATE:
624
+                cli_dbgmsg("dmg_handle_mish: stripe %lu, zlib block\n", (unsigned long)i);
625
+                break;
626
+            case DMG_STRIPE_BZ:
627
+                cli_dbgmsg("dmg_handle_mish: stripe %lu, bzip block\n", (unsigned long)i);
628
+                break;
629
+            case DMG_STRIPE_SKIP:
630
+            case DMG_STRIPE_END:
631
+            default:
632
+                cli_dbgmsg("dmg_handle_mish: stripe %lu, skipped\n", (unsigned long)i);
633
+                break;
634
+        }
635
+    }
636
+
637
+    // ret = cli_magic_scandesc(ofd, ctx);
638
+    close(ofd);
639
+    if (!ctx->engine->keeptmp)
640
+        if (cli_unlink(outfile)) return CL_EUNLINK;
641
+    
642
+    return ret;
643
+}
644
+
645
+static int dmg_extract_xml(cli_ctx *ctx, char *dir, struct dmg_koly_block *hdr)
646
+{
647
+    char * xmlfile;
648
+    const char *outdata;
649
+    size_t namelen, nread;
650
+    int ofd;
651
+
652
+    /* Prep TOC XML for output */
653
+    outdata = fmap_need_off_once_len(*ctx->fmap, hdr->xmlOffset, hdr->xmlLength, &nread);
654
+    if (!outdata || (nread != hdr->xmlLength)) {
655
+        cli_errmsg("cli_scandmg: Failed getting XML from map, len %ld\n", hdr->xmlLength);
656
+        return CL_EMAP;
657
+    }
658
+
659
+    namelen = strlen(dir) + 1 + 7 + 1;
660
+    if (!(xmlfile = cli_malloc(namelen))) {
661
+        return CL_EMEM;
662
+    }
663
+    snprintf(xmlfile, namelen, "%s"PATHSEP"toc.xml", dir);
664
+    cli_dbgmsg("cli_scandmg: Extracting XML as %s\n", xmlfile);
665
+
666
+    /* Write out TOC XML */
667
+    if ((ofd = open(xmlfile, O_CREAT|O_RDWR|O_EXCL|O_TRUNC|O_BINARY, S_IRWXU)) < 0) {
668
+        return CL_ETMPFILE;
669
+    }
670
+
671
+    if (cli_writen(ofd, outdata, hdr->xmlLength) != hdr->xmlLength) {
672
+        cli_errmsg("cli_scandmg: Not all bytes written!\n");
673
+        close(ofd);
674
+        free(xmlfile);
675
+        return CL_EWRITE;
676
+    }
677
+
678
+    close(ofd);
679
+    free(xmlfile);
680
+    return CL_SUCCESS;
681
+}
76 682
 
... ...
@@ -28,6 +28,21 @@
28 28
 #include "cltypes.h"
29 29
 #include "others.h"
30 30
 
31
+/* Simple stripe types */
32
+#define DMG_STRIPE_EMPTY   0x00000000
33
+#define DMG_STRIPE_STORED  0x00000001
34
+#define DMG_STRIPE_ZEROES  0x00000002
35
+/* Compressed stripe type */
36
+#define DMG_STRIPE_ADC     0x80000004
37
+#define DMG_STRIPE_DEFLATE 0x80000005
38
+#define DMG_STRIPE_BZ      0x80000006
39
+/* Stripe types that are only seen with sector count zero */
40
+#define DMG_STRIPE_SKIP    0x7FFFFFFE
41
+#define DMG_STRIPE_END     0xFFFFFFFF
42
+
43
+/* So far, this has been constant */
44
+#define DMG_SECTOR_SIZE   512
45
+
31 46
 #ifndef HAVE_ATTRIB_PACKED
32 47
 #define __attribute__(x)
33 48
 #endif
... ...
@@ -72,19 +87,34 @@ struct dmg_koly_block {
72 72
 
73 73
 /* 204-byte block, still big-endian */
74 74
 struct dmg_mish_block {
75
-    uint32_t magic;
76
-    uint32_t version;
75
+    uint32_t magic  __attribute__ ((packed));
76
+    uint32_t version  __attribute__ ((packed));
77 77
 
78
-    uint64_t startSector;
79
-    uint64_t sectorCount;
80
-    uint64_t dataOffset;
81
-    uint32_t bufferCount;
82
-    uint32_t descriptorBlocks;
78
+    uint64_t startSector  __attribute__ ((packed));
79
+    uint64_t sectorCount  __attribute__ ((packed));
80
+    uint64_t dataOffset  __attribute__ ((packed));
81
+    uint32_t bufferCount  __attribute__ ((packed));
82
+    uint32_t descriptorBlocks  __attribute__ ((packed));
83 83
 
84 84
     uint8_t  reserved[24];
85 85
 
86
-    uint32_t checksum[34];
87
-    uint64_t blockDescriptorCount;
86
+    uint32_t checksum[34]  __attribute__ ((packed));
87
+    uint32_t blockDataCount  __attribute__ ((packed));
88
+};
89
+
90
+/* 40-byte block, big-endian */
91
+struct dmg_block_data {
92
+    uint32_t type  __attribute__ ((packed));
93
+    uint32_t reserved  __attribute__ ((packed));
94
+    uint64_t startSector  __attribute__ ((packed));
95
+    uint64_t sectorCount  __attribute__ ((packed));
96
+    uint64_t dataOffset  __attribute__ ((packed));
97
+    uint64_t dataLength  __attribute__ ((packed));
98
+};
99
+
100
+struct dmg_mish_with_stripes {
101
+    struct dmg_mish_block *mish;
102
+    struct dmg_block_data *stripes;
88 103
 };
89 104
 
90 105
 #ifdef HAVE_PRAGMA_PACK
91 106
new file mode 100644
... ...
@@ -0,0 +1,128 @@
0
+/*
1
+ ** Copyright (C) 1998-2013 Sourcefire, Inc.
2
+ **
3
+ ** Written by Patrick Mullen <pmullen@sourcefire.com>
4
+ ** 9/11/2013 - Changed uint32_t to size_t
5
+ **
6
+ ** This program is free software; you can redistribute it and/or modify
7
+ ** it under the terms of the GNU General Public License Version 2 as
8
+ ** published by the Free Software Foundation.  You may not use, modify or
9
+ ** distribute this program under any other version of the GNU General
10
+ ** Public License.
11
+ **
12
+ ** This program is distributed in the hope that it will be useful,
13
+ ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
+ ** GNU General Public License for more details.
16
+ **
17
+ ** You should have received a copy of the GNU General Public License
18
+ ** along with this program; if not, write to the Free Software
19
+ ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20
+ */
21
+
22
+#ifdef HAVE_CONFIG_H
23
+#include "clamav-config.h"
24
+#endif
25
+
26
+#include "sf_base64decode.h"
27
+
28
+uint8_t sf_decode64tab[256] = {
29
+        100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
30
+        100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
31
+        100,100,100,100,100,100,100,100,100,100,100,62 ,100,100,100, 63,
32
+         52, 53, 54, 55, 56, 57, 58, 59, 60, 61,100,100,100, 99,100,100,
33
+        100,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
34
+         15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,100,100,100,100,100,
35
+        100, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
36
+         41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,100,100,100,100,100,
37
+        100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
38
+        100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
39
+        100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
40
+        100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
41
+        100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
42
+        100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
43
+        100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
44
+        100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100};
45
+
46
+/* base64decode assumes the input data terminates with '=' and/or at the end of the input buffer
47
+ * at inbuf_size.  If extra characters exist within inbuf before inbuf_size is reached, it will
48
+ * happily decode what it can and skip over what it can't.  This is consistent with other decoders
49
+ * out there.  So, either terminate the string, set inbuf_size correctly, or at least be sure the
50
+ * data is valid up until the point you care about.  Note base64 data does NOT have to end with
51
+ * '=' and won't if the number of bytes of input data is evenly divisible by 3.
52
+*/
53
+int sf_base64decode(uint8_t *inbuf, size_t inbuf_size, uint8_t *outbuf, size_t outbuf_size, size_t *bytes_written)
54
+{
55
+   uint8_t *cursor, *endofinbuf;
56
+   uint8_t *outbuf_ptr;
57
+   uint8_t base64data[4], *base64data_ptr; /* temporary holder for current base64 chunk */
58
+   uint8_t tableval_a, tableval_b, tableval_c, tableval_d;
59
+
60
+   size_t n;
61
+   size_t max_base64_chars;  /* The max number of decoded base64 chars that fit into outbuf */
62
+
63
+   int error = 0;
64
+
65
+   /* This algorithm will waste up to 4 bytes but we really don't care.
66
+      At the end we're going to copy the exact number of bytes requested. */
67
+   max_base64_chars = (outbuf_size / 3) * 4 + 4; /* 4 base64 bytes gives 3 data bytes, plus
68
+                                                    an extra 4 to take care of any rounding */
69
+
70
+   base64data_ptr = base64data;
71
+   endofinbuf = inbuf + inbuf_size;
72
+
73
+   /* Strip non-base64 chars from inbuf and decode */
74
+   n = 0;
75
+   *bytes_written = 0;
76
+   cursor = inbuf;
77
+   outbuf_ptr = outbuf;
78
+   while((cursor < endofinbuf) && (n < max_base64_chars)) {
79
+      if(sf_decode64tab[*cursor] != 100) {
80
+         *base64data_ptr++ = *cursor;
81
+         n++;  /* Number of base64 bytes we've stored */
82
+         if(!(n % 4)) {
83
+            /* We have four databytes upon which to operate */
84
+
85
+            if((base64data[0] == '=') || (base64data[1] == '=')) {
86
+               /* Error in input data */
87
+               error = 1;
88
+               break;
89
+            }
90
+
91
+            /* retrieve values from lookup table */
92
+            tableval_a = sf_decode64tab[base64data[0]];
93
+            tableval_b = sf_decode64tab[base64data[1]];
94
+            tableval_c = sf_decode64tab[base64data[2]];
95
+            tableval_d = sf_decode64tab[base64data[3]];
96
+
97
+            if(*bytes_written < outbuf_size) {
98
+               *outbuf_ptr++ = (tableval_a << 2) | (tableval_b >> 4);
99
+               (*bytes_written)++;
100
+            }
101
+
102
+            if((base64data[2] != '=') && (*bytes_written < outbuf_size)) {
103
+               *outbuf_ptr++ = (tableval_b << 4) | (tableval_c >> 2);
104
+               (*bytes_written)++;
105
+            }  else {
106
+               break;
107
+            }
108
+
109
+            if((base64data[3] != '=') && (*bytes_written < outbuf_size)) {
110
+               *outbuf_ptr++ = (tableval_c << 6) | tableval_d;
111
+               (*bytes_written)++;
112
+            }  else {
113
+               break;
114
+            }
115
+
116
+            /* Reset our decode pointer for the next group of four */
117
+            base64data_ptr = base64data;
118
+         }
119
+      }
120
+      cursor++;
121
+   }
122
+
123
+   if(error)
124
+      return(-1);
125
+   else
126
+      return(0);
127
+}
0 128
new file mode 100644
... ...
@@ -0,0 +1,31 @@
0
+/*
1
+ ** Copyright (C) 1998-2013 Sourcefire, Inc.
2
+ **
3
+ ** Written by Patrick Mullen <pmullen@sourcefire.com>
4
+ ** 9/11/2013 - Changed uint32_t to size_t
5
+ **
6
+ ** This program is free software; you can redistribute it and/or modify
7
+ ** it under the terms of the GNU General Public License Version 2 as
8
+ ** published by the Free Software Foundation.  You may not use, modify or
9
+ ** distribute this program under any other version of the GNU General
10
+ ** Public License.
11
+ **
12
+ ** This program is distributed in the hope that it will be useful,
13
+ ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
+ ** GNU General Public License for more details.
16
+ **
17
+ ** You should have received a copy of the GNU General Public License
18
+ ** along with this program; if not, write to the Free Software
19
+ ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20
+ */
21
+
22
+#ifndef _SF_BASE64DECODE_H_
23
+#define _SF_BASE64DECODE_H_
24
+
25
+#include <stdio.h>
26
+#include "cltypes.h"
27
+
28
+int sf_base64decode(uint8_t*, size_t, uint8_t*, size_t, size_t*); 
29
+
30
+#endif
... ...
@@ -321,6 +321,9 @@ VERSION = @VERSION@
321 321
 VERSIONSCRIPTFLAG = @VERSIONSCRIPTFLAG@
322 322
 WERR_CFLAGS = @WERR_CFLAGS@
323 323
 WERR_CFLAGS_MILTER = @WERR_CFLAGS_MILTER@
324
+XML2_CONFIG = @XML2_CONFIG@
325
+XML_CPPFLAGS = @XML_CPPFLAGS@
326
+XML_LIBS = @XML_LIBS@
324 327
 abs_builddir = @abs_builddir@
325 328
 abs_srcdir = @abs_srcdir@
326 329
 abs_top_builddir = @abs_top_builddir@
... ...
@@ -242,6 +242,9 @@ VERSION = @VERSION@
242 242
 VERSIONSCRIPTFLAG = @VERSIONSCRIPTFLAG@
243 243
 WERR_CFLAGS = @WERR_CFLAGS@
244 244
 WERR_CFLAGS_MILTER = @WERR_CFLAGS_MILTER@
245
+XML2_CONFIG = @XML2_CONFIG@
246
+XML_CPPFLAGS = @XML_CPPFLAGS@
247
+XML_LIBS = @XML_LIBS@
245 248
 abs_builddir = @abs_builddir@
246 249
 abs_srcdir = @abs_srcdir@
247 250
 abs_top_builddir = @abs_top_builddir@
... ...
@@ -190,6 +190,9 @@ VERSION = @VERSION@
190 190
 VERSIONSCRIPTFLAG = @VERSIONSCRIPTFLAG@
191 191
 WERR_CFLAGS = @WERR_CFLAGS@
192 192
 WERR_CFLAGS_MILTER = @WERR_CFLAGS_MILTER@
193
+XML2_CONFIG = @XML2_CONFIG@
194
+XML_CPPFLAGS = @XML_CPPFLAGS@
195
+XML_LIBS = @XML_LIBS@
193 196
 abs_builddir = @abs_builddir@
194 197
 abs_srcdir = @abs_srcdir@
195 198
 abs_top_builddir = @abs_top_builddir@
... ...
@@ -375,6 +375,9 @@ VERSION = @VERSION@
375 375
 VERSIONSCRIPTFLAG = @VERSIONSCRIPTFLAG@
376 376
 WERR_CFLAGS = @WERR_CFLAGS@
377 377
 WERR_CFLAGS_MILTER = @WERR_CFLAGS_MILTER@
378
+XML2_CONFIG = @XML2_CONFIG@
379
+XML_CPPFLAGS = @XML_CPPFLAGS@
380
+XML_LIBS = @XML_LIBS@
378 381
 abs_builddir = @abs_builddir@
379 382
 abs_srcdir = @abs_srcdir@
380 383
 abs_top_builddir = @abs_top_builddir@