From 7b88a5ce44f52abb13390c6c105bdd58a590a626 Mon Sep 17 00:00:00 2001
From: Rene Mayrhofer <rene@mayrhofer.eu.org>
Date: Sun, 22 Mar 2009 10:06:21 +0000
Subject: - New upstream version.

---
 NEWS                                               |  17 +-
 configure                                          | 227 ++++++++++--
 configure.in                                       |  11 +-
 debian/changelog                                   |   8 +
 src/charon/config/attributes/attribute_manager.c   |  16 +-
 src/charon/config/proposal.c                       |  64 ++--
 src/charon/config/proposal.h                       |   7 +-
 src/charon/config/traffic_selector.c               |  59 +---
 src/charon/config/traffic_selector.h               |   7 +-
 src/charon/credentials/credential_manager.c        |  18 +-
 src/charon/daemon.c                                |  10 +-
 src/charon/plugins/eap_mschapv2/eap_mschapv2.c     |   4 +-
 src/charon/plugins/nm/nm_service.c                 |  80 +++--
 src/charon/plugins/sql/pool.c                      |   4 +-
 src/charon/plugins/sql/sql_attribute.c             |   2 +-
 src/charon/plugins/stroke/stroke_attribute.c       |   1 +
 src/charon/plugins/stroke/stroke_cred.c            |   7 +-
 src/charon/plugins/stroke/stroke_list.c            |  42 ++-
 src/charon/sa/ike_sa.c                             |  11 +-
 src/libstrongswan/Makefile.am                      |   4 +
 src/libstrongswan/Makefile.in                      |  62 ++--
 src/libstrongswan/asn1/asn1.c                      |  19 +-
 src/libstrongswan/chunk.c                          |  43 +--
 src/libstrongswan/chunk.h                          |  10 +-
 src/libstrongswan/enum.c                           |  38 +-
 src/libstrongswan/enum.h                           |  13 +-
 src/libstrongswan/library.c                        |  28 +-
 src/libstrongswan/library.h                        |   4 +-
 src/libstrongswan/plugins/des/des_crypter.c        |  14 +-
 src/libstrongswan/plugins/x509/x509_ac.c           |   2 +-
 src/libstrongswan/plugins/x509/x509_cert.c         |   4 +-
 src/libstrongswan/plugins/x509/x509_crl.c          |   4 +-
 .../plugins/x509/x509_ocsp_response.c              |   6 +-
 src/libstrongswan/printf_hook.c                    | 381 ++++++++++++++++++++-
 src/libstrongswan/printf_hook.h                    | 107 +++++-
 src/libstrongswan/utils.c                          | 152 ++------
 src/libstrongswan/utils.h                          |  23 +-
 src/libstrongswan/utils/hashtable.c                |   6 +-
 src/libstrongswan/utils/host.c                     |  67 ++--
 src/libstrongswan/utils/host.h                     |   9 +-
 src/libstrongswan/utils/identification.c           |  40 +--
 src/libstrongswan/utils/identification.h           |  13 +-
 src/libstrongswan/utils/leak_detective.c           |   3 +-
 src/libstrongswan/utils/linked_list.c              |  12 +-
 src/pluto/asn1.c                                   |  16 +-
 src/pluto/connections.c                            |   4 +-
 src/pluto/ipsec_doi.c                              |  21 +-
 src/pluto/state.c                                  |  11 +-
 src/pluto/vendor.c                                 |   5 +-
 src/pluto/vendor.h                                 |   3 +-
 testing/INSTALL                                    |   6 +-
 testing/testing.conf                               |   6 +-
 testing/tests/ikev1/dpd-restart/description.txt    |  13 +
 testing/tests/ikev1/dpd-restart/evaltest.dat       |  10 +
 .../ikev1/dpd-restart/hosts/carol/etc/ipsec.conf   |  25 ++
 .../ikev1/dpd-restart/hosts/moon/etc/ipsec.conf    |  29 ++
 testing/tests/ikev1/dpd-restart/posttest.dat       |   5 +
 testing/tests/ikev1/dpd-restart/pretest.dat        |   5 +
 testing/tests/ikev1/dpd-restart/test.conf          |  21 ++
 testing/tests/ikev2/ip-pool-db/description.txt     |   2 +-
 .../tests/ikev2/ip-two-pools-db/description.txt    |   4 +-
 .../tests/ikev2/ip-two-pools-mixed/description.txt |   9 +
 .../tests/ikev2/ip-two-pools-mixed/evaltest.dat    |  17 +
 .../hosts/alice/etc/init.d/iptables                |  78 +++++
 .../ip-two-pools-mixed/hosts/alice/etc/ipsec.conf  |  23 ++
 .../hosts/alice/etc/strongswan.conf                |   5 +
 .../ip-two-pools-mixed/hosts/carol/etc/ipsec.conf  |  23 ++
 .../hosts/carol/etc/strongswan.conf                |   5 +
 .../hosts/moon/etc/init.d/iptables                 |  91 +++++
 .../ip-two-pools-mixed/hosts/moon/etc/ipsec.conf   |  27 ++
 .../hosts/moon/etc/strongswan.conf                 |  14 +
 .../tests/ikev2/ip-two-pools-mixed/posttest.dat    |   9 +
 testing/tests/ikev2/ip-two-pools-mixed/pretest.dat |  13 +
 testing/tests/ikev2/ip-two-pools-mixed/test.conf   |  21 ++
 74 files changed, 1561 insertions(+), 619 deletions(-)
 create mode 100644 testing/tests/ikev1/dpd-restart/description.txt
 create mode 100644 testing/tests/ikev1/dpd-restart/evaltest.dat
 create mode 100755 testing/tests/ikev1/dpd-restart/hosts/carol/etc/ipsec.conf
 create mode 100755 testing/tests/ikev1/dpd-restart/hosts/moon/etc/ipsec.conf
 create mode 100644 testing/tests/ikev1/dpd-restart/posttest.dat
 create mode 100644 testing/tests/ikev1/dpd-restart/pretest.dat
 create mode 100644 testing/tests/ikev1/dpd-restart/test.conf
 create mode 100644 testing/tests/ikev2/ip-two-pools-mixed/description.txt
 create mode 100644 testing/tests/ikev2/ip-two-pools-mixed/evaltest.dat
 create mode 100755 testing/tests/ikev2/ip-two-pools-mixed/hosts/alice/etc/init.d/iptables
 create mode 100755 testing/tests/ikev2/ip-two-pools-mixed/hosts/alice/etc/ipsec.conf
 create mode 100644 testing/tests/ikev2/ip-two-pools-mixed/hosts/alice/etc/strongswan.conf
 create mode 100755 testing/tests/ikev2/ip-two-pools-mixed/hosts/carol/etc/ipsec.conf
 create mode 100644 testing/tests/ikev2/ip-two-pools-mixed/hosts/carol/etc/strongswan.conf
 create mode 100755 testing/tests/ikev2/ip-two-pools-mixed/hosts/moon/etc/init.d/iptables
 create mode 100755 testing/tests/ikev2/ip-two-pools-mixed/hosts/moon/etc/ipsec.conf
 create mode 100644 testing/tests/ikev2/ip-two-pools-mixed/hosts/moon/etc/strongswan.conf
 create mode 100644 testing/tests/ikev2/ip-two-pools-mixed/posttest.dat
 create mode 100644 testing/tests/ikev2/ip-two-pools-mixed/pretest.dat
 create mode 100644 testing/tests/ikev2/ip-two-pools-mixed/test.conf

diff --git a/NEWS b/NEWS
index 73bec5e27..4709b07df 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,20 @@
+strongswan-4.2.13
+-----------------
+
+- Fixed a use-after-free bug in the DPD timeout section of the
+  IKEv1 pluto daemon which sporadically caused a segfault.
+
+- Fixed a crash in the IKEv2 charon daemon occuring with
+  mixed RAM-based and SQL-based virtual IP address pools. 
+
+- Fixed ASN.1 parsing of algorithmIdentifier objects where the
+  parameters field is optional.
+
+- Ported nm plugin to NetworkManager 7.1.
+
+
 strongswan-4.2.12
-'----------------
+-----------------
 
 - Support of the EAP-MSCHAPv2 protocol enabled by the option
   --enable-eap-mschapv2. Requires the MD4 hash algorithm enabled
diff --git a/configure b/configure
index 6c018dc76..59692f4a3 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.61 for strongSwan 4.2.12.
+# Generated by GNU Autoconf 2.61 for strongSwan 4.2.13.
 #
 # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
 # 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
@@ -721,8 +721,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
 # Identity of this package.
 PACKAGE_NAME='strongSwan'
 PACKAGE_TARNAME='strongswan'
-PACKAGE_VERSION='4.2.12'
-PACKAGE_STRING='strongSwan 4.2.12'
+PACKAGE_VERSION='4.2.13'
+PACKAGE_STRING='strongSwan 4.2.13'
 PACKAGE_BUGREPORT=''
 
 # Factoring default headers for most tests.
@@ -1011,6 +1011,8 @@ USE_LIBSTRONGSWAN_TRUE
 USE_LIBSTRONGSWAN_FALSE
 USE_FILE_CONFIG_TRUE
 USE_FILE_CONFIG_FALSE
+USE_VSTR_TRUE
+USE_VSTR_FALSE
 LIBOBJS
 LTLIBOBJS'
 ac_subst_files=''
@@ -1534,7 +1536,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures strongSwan 4.2.12 to adapt to many kinds of systems.
+\`configure' configures strongSwan 4.2.13 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1604,7 +1606,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of strongSwan 4.2.12:";;
+     short | recursive ) echo "Configuration of strongSwan 4.2.13:";;
    esac
   cat <<\_ACEOF
 
@@ -1854,7 +1856,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-strongSwan configure 4.2.12
+strongSwan configure 4.2.13
 generated by GNU Autoconf 2.61
 
 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1868,7 +1870,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by strongSwan $as_me 4.2.12, which was
+It was created by strongSwan $as_me 4.2.13, which was
 generated by GNU Autoconf 2.61.  Invocation command line was
 
   $ $0 $@
@@ -2558,7 +2560,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='strongswan'
- VERSION='4.2.12'
+ VERSION='4.2.13'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -6396,13 +6398,13 @@ if test "${lt_cv_nm_interface+set}" = set; then
 else
   lt_cv_nm_interface="BSD nm"
   echo "int some_variable = 0;" > conftest.$ac_ext
-  (eval echo "\"\$as_me:6399: $ac_compile\"" >&5)
+  (eval echo "\"\$as_me:6401: $ac_compile\"" >&5)
   (eval "$ac_compile" 2>conftest.err)
   cat conftest.err >&5
-  (eval echo "\"\$as_me:6402: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+  (eval echo "\"\$as_me:6404: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
   (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
   cat conftest.err >&5
-  (eval echo "\"\$as_me:6405: output\"" >&5)
+  (eval echo "\"\$as_me:6407: output\"" >&5)
   cat conftest.out >&5
   if $GREP 'External.*some_variable' conftest.out > /dev/null; then
     lt_cv_nm_interface="MS dumpbin"
@@ -7512,7 +7514,7 @@ ia64-*-hpux*)
   ;;
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 7515 "configure"' > conftest.$ac_ext
+  echo '#line 7517 "configure"' > conftest.$ac_ext
   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -8885,11 +8887,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:8888: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:8890: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:8892: \$? = $ac_status" >&5
+   echo "$as_me:8894: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -9209,11 +9211,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:9212: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:9214: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:9216: \$? = $ac_status" >&5
+   echo "$as_me:9218: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -9314,11 +9316,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:9317: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:9319: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:9321: \$? = $ac_status" >&5
+   echo "$as_me:9323: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -9369,11 +9371,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:9372: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:9374: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:9376: \$? = $ac_status" >&5
+   echo "$as_me:9378: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -12130,7 +12132,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 12133 "configure"
+#line 12135 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -12230,7 +12232,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 12233 "configure"
+#line 12235 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -13919,6 +13921,164 @@ fi
 
 
 
+{ echo "$as_me:$LINENO: checking for register_printf_function" >&5
+echo $ECHO_N "checking for register_printf_function... $ECHO_C" >&6; }
+if test "${ac_cv_func_register_printf_function+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define register_printf_function to an innocuous variant, in case <limits.h> declares register_printf_function.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define register_printf_function innocuous_register_printf_function
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char register_printf_function (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef register_printf_function
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char register_printf_function ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_register_printf_function || defined __stub___register_printf_function
+choke me
+#endif
+
+int
+main ()
+{
+return register_printf_function ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_func_register_printf_function=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_func_register_printf_function=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_func_register_printf_function" >&5
+echo "${ECHO_T}$ac_cv_func_register_printf_function" >&6; }
+if test $ac_cv_func_register_printf_function = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_PRINTF_HOOKS 1
+_ACEOF
+
+else
+
+		{ echo "$as_me:$LINENO: printf does not support custom format specifiers!" >&5
+echo "$as_me: printf does not support custom format specifiers!" >&6;}
+		{ echo "$as_me:$LINENO: checking for main in -lvstr" >&5
+echo $ECHO_N "checking for main in -lvstr... $ECHO_C" >&6; }
+if test "${ac_cv_lib_vstr_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lvstr  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+return main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_vstr_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_lib_vstr_main=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_vstr_main" >&5
+echo "${ECHO_T}$ac_cv_lib_vstr_main" >&6; }
+if test $ac_cv_lib_vstr_main = yes; then
+  LIBS="$LIBS"; vstr=true
+else
+  { { echo "$as_me:$LINENO: error: Vstr string library not found" >&5
+echo "$as_me: error: Vstr string library not found" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+ac_cv_lib_vstr=ac_cv_lib_vstr_main
+
+
+fi
+
+
 if test x$gmp = xtrue; then
 	{ echo "$as_me:$LINENO: checking for main in -lgmp" >&5
 echo $ECHO_N "checking for main in -lgmp... $ECHO_C" >&6; }
@@ -17102,6 +17262,14 @@ else
   USE_FILE_CONFIG_FALSE=
 fi
 
+ if test x$vstr = xtrue; then
+  USE_VSTR_TRUE=
+  USE_VSTR_FALSE='#'
+else
+  USE_VSTR_TRUE='#'
+  USE_VSTR_FALSE=
+fi
+
 
 
 if test x$me = xtrue; then
@@ -17687,6 +17855,13 @@ echo "$as_me: error: conditional \"USE_FILE_CONFIG\" was never defined.
 Usually this means the macro was only invoked conditionally." >&2;}
    { (exit 1); exit 1; }; }
 fi
+if test -z "${USE_VSTR_TRUE}" && test -z "${USE_VSTR_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"USE_VSTR\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"USE_VSTR\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
 
 : ${CONFIG_STATUS=./config.status}
 ac_clean_files_save=$ac_clean_files
@@ -17987,7 +18162,7 @@ exec 6>&1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by strongSwan $as_me 4.2.12, which was
+This file was extended by strongSwan $as_me 4.2.13, which was
 generated by GNU Autoconf 2.61.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -18034,7 +18209,7 @@ Report bugs to <bug-autoconf@gnu.org>."
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
 ac_cs_version="\\
-strongSwan config.status 4.2.12
+strongSwan config.status 4.2.13
 configured by $0, generated by GNU Autoconf 2.61,
   with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
 
@@ -18851,11 +19026,13 @@ USE_LIBSTRONGSWAN_TRUE!$USE_LIBSTRONGSWAN_TRUE$ac_delim
 USE_LIBSTRONGSWAN_FALSE!$USE_LIBSTRONGSWAN_FALSE$ac_delim
 USE_FILE_CONFIG_TRUE!$USE_FILE_CONFIG_TRUE$ac_delim
 USE_FILE_CONFIG_FALSE!$USE_FILE_CONFIG_FALSE$ac_delim
+USE_VSTR_TRUE!$USE_VSTR_TRUE$ac_delim
+USE_VSTR_FALSE!$USE_VSTR_FALSE$ac_delim
 LIBOBJS!$LIBOBJS$ac_delim
 LTLIBOBJS!$LTLIBOBJS$ac_delim
 _ACEOF
 
-  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 58; then
+  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 60; then
     break
   elif $ac_last_try; then
     { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
diff --git a/configure.in b/configure.in
index b0405130e..81909c078 100644
--- a/configure.in
+++ b/configure.in
@@ -16,7 +16,7 @@ dnl ===========================
 dnl  initialize & set some vars
 dnl ===========================
 
-AC_INIT(strongSwan,4.2.12)
+AC_INIT(strongSwan,4.2.13)
 AM_INIT_AUTOMAKE(tar-ustar)
 AC_C_BIGENDIAN
 AC_SUBST(confdir, '${sysconfdir}')
@@ -740,6 +740,14 @@ AC_TRY_RUN(
 [AC_MSG_RESULT([no])],
 [AC_MSG_RESULT([no])])
 
+AC_CHECK_FUNC(
+	[register_printf_function],
+	[AC_DEFINE(HAVE_PRINTF_HOOKS)],
+	[
+		AC_MSG_NOTICE([printf does not support custom format specifiers!])
+		AC_HAVE_LIBRARY([vstr],[LIBS="$LIBS"]; vstr=true,[AC_MSG_ERROR([Vstr string library not found])])
+	])
+
 if test x$gmp = xtrue; then
 	AC_HAVE_LIBRARY([gmp],[LIBS="$LIBS"],[AC_MSG_ERROR([GNU Multi Precision library gmp not found])])
 	AC_MSG_CHECKING([gmp.h version >= 4.1.4])
@@ -981,6 +989,7 @@ AM_CONDITIONAL(USE_CHARON, test x$charon = xtrue)
 AM_CONDITIONAL(USE_TOOLS, test x$tools = xtrue)
 AM_CONDITIONAL(USE_LIBSTRONGSWAN, test x$charon = xtrue -o x$tools = xtrue)
 AM_CONDITIONAL(USE_FILE_CONFIG, test x$pluto = xtrue -o x$stroke = xtrue)
+AM_CONDITIONAL(USE_VSTR, test x$vstr = xtrue)
 
 dnl ==============================
 dnl  set global definitions
diff --git a/debian/changelog b/debian/changelog
index 098436a8b..d2e7a6740 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,11 @@
+strongswan (4.2.13-1) unstable; urgency=low
+
+  * New upstream release. This is now compatible with network-manager 0.7
+    in Debian, so start building the strongswan-side support. The actual
+    plugin will need to be another source package.
+
+ -- Rene Mayrhofer <rmayr@debian.org>  Sun, 22 Mar 2009 10:59:31 +0100
+
 strongswan (4.2.12-1) unstable; urgency=low
 
   * New upstream release. Starting with this version, the strongswan
diff --git a/src/charon/config/attributes/attribute_manager.c b/src/charon/config/attributes/attribute_manager.c
index b919c4261..a069c954a 100644
--- a/src/charon/config/attributes/attribute_manager.c
+++ b/src/charon/config/attributes/attribute_manager.c
@@ -17,6 +17,7 @@
 
 #include "attribute_manager.h"
 
+#include <daemon.h>
 #include <utils/linked_list.h>
 #include <utils/mutex.h>
 
@@ -53,7 +54,7 @@ static host_t* acquire_address(private_attribute_manager_t *this,
 	enumerator_t *enumerator;
 	attribute_provider_t *current;
 	host_t *host = NULL;
-
+	
 	this->lock->read_lock(this->lock);
 	enumerator = this->providers->create_enumerator(this->providers);
 	while (enumerator->enumerate(enumerator, &current))
@@ -67,6 +68,10 @@ static host_t* acquire_address(private_attribute_manager_t *this,
 	enumerator->destroy(enumerator);
 	this->lock->unlock(this->lock);
 	
+	if (!host)
+	{
+		DBG1(DBG_CFG, "acquiring address from pool '%s' failed", pool);
+	}
 	return host;
 }
 
@@ -78,18 +83,25 @@ static void release_address(private_attribute_manager_t *this,
 {
 	enumerator_t *enumerator;
 	attribute_provider_t *current;
-
+	bool found = FALSE;
+	
 	this->lock->read_lock(this->lock);
 	enumerator = this->providers->create_enumerator(this->providers);
 	while (enumerator->enumerate(enumerator, &current))
 	{
 		if (current->release_address(current, pool, address, id))
 		{
+			found = TRUE;
 			break;
 		}
 	}
 	enumerator->destroy(enumerator);
 	this->lock->unlock(this->lock);
+	
+	if (!found)
+	{
+		DBG1(DBG_CFG, "releasing address to pool '%s' failed", pool);
+	}
 }
 
 /**
diff --git a/src/charon/config/proposal.c b/src/charon/config/proposal.c
index 8fcbdc960..92ef34b75 100644
--- a/src/charon/config/proposal.c
+++ b/src/charon/config/proposal.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2008-2009 Tobias Brunner
  * Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
@@ -13,7 +13,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * $Id: proposal.c 4685 2008-11-22 16:14:55Z martin $
+ * $Id: proposal.c 4936 2009-03-12 18:07:32Z tobias $
  */
 
 #include <string.h>
@@ -803,10 +803,10 @@ static status_t add_string_algo(private_proposal_t *this, chunk_t alg)
 }
 
 /**
- * print all algorithms of a kind to stream
+ * print all algorithms of a kind to buffer
  */
-static int print_alg(private_proposal_t *this, FILE *stream, u_int kind,
-					 void *names, bool *first)
+static int print_alg(private_proposal_t *this, char **dst, int *len,
+					 u_int kind, void *names, bool *first)
 {
 	enumerator_t *enumerator;
 	size_t written = 0;
@@ -817,16 +817,16 @@ static int print_alg(private_proposal_t *this, FILE *stream, u_int kind,
 	{
 		if (*first)
 		{
-			written += fprintf(stream, "%N", names, alg);
+			written += print_in_hook(*dst, *len, "%N", names, alg);
 			*first = FALSE;
 		}
 		else
 		{
-			written += fprintf(stream, "/%N", names, alg);
+			written += print_in_hook(*dst, *len, "/%N", names, alg);
 		}
 		if (size)
 		{
-			written += fprintf(stream, "-%d", size);
+			written += print_in_hook(*dst, *len, "-%d", size);
 		}
 	}
 	enumerator->destroy(enumerator);
@@ -834,10 +834,10 @@ static int print_alg(private_proposal_t *this, FILE *stream, u_int kind,
 }
 
 /**
- * output handler in printf()
+ * Described in header.
  */
-static int print(FILE *stream, const struct printf_info *info,
-				 const void *const *args)
+int proposal_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
+						 const void *const *args)
 {
 	private_proposal_t *this = *((private_proposal_t**)(args[0]));
 	linked_list_t *list = *((linked_list_t**)(args[0]));
@@ -847,64 +847,42 @@ static int print(FILE *stream, const struct printf_info *info,
 	
 	if (this == NULL)
 	{
-		return fprintf(stream, "(null)");
+		return print_in_hook(dst, len, "(null)");
 	}
 	
-	if (info->alt)
+	if (spec->hash)
 	{
 		enumerator = list->create_enumerator(list);
 		while (enumerator->enumerate(enumerator, &this))
 		{	/* call recursivly */
 			if (first)
 			{
-				written += fprintf(stream, "%P", this);
+				written += print_in_hook(dst, len, "%P", this);
 				first = FALSE;
 			}
 			else
 			{
-				written += fprintf(stream, ", %P", this);
+				written += print_in_hook(dst, len, ", %P", this);
 			}
 		}
 		enumerator->destroy(enumerator);
 		return written;
 	}
 	
-	written = fprintf(stream, "%N:", protocol_id_names, this->protocol);
-	written += print_alg(this, stream, ENCRYPTION_ALGORITHM,
+	written = print_in_hook(dst, len, "%N:", protocol_id_names, this->protocol);
+	written += print_alg(this, &dst, &len, ENCRYPTION_ALGORITHM,
 						 encryption_algorithm_names, &first);
-	written += print_alg(this, stream, INTEGRITY_ALGORITHM,
+	written += print_alg(this, &dst, &len, INTEGRITY_ALGORITHM,
 						 integrity_algorithm_names, &first);
-	written += print_alg(this, stream, PSEUDO_RANDOM_FUNCTION,
+	written += print_alg(this, &dst, &len, PSEUDO_RANDOM_FUNCTION,
 						 pseudo_random_function_names, &first);
-	written += print_alg(this, stream, DIFFIE_HELLMAN_GROUP,
+	written += print_alg(this, &dst, &len, DIFFIE_HELLMAN_GROUP,
 						 diffie_hellman_group_names, &first);
-	written += print_alg(this, stream, EXTENDED_SEQUENCE_NUMBERS,
+	written += print_alg(this, &dst, &len, EXTENDED_SEQUENCE_NUMBERS,
 						 extended_sequence_numbers_names, &first);
 	return written;
 }
 
-/**
- * arginfo handler for printf() proposal
- */
-static int arginfo(const struct printf_info *info, size_t n, int *argtypes)
-{
-	if (n > 0)
-	{
-		argtypes[0] = PA_POINTER;
-	}
-	return 1;
-}
-
-/**
- * return printf hook functions for a proposal
- */
-printf_hook_functions_t proposal_get_printf_hooks()
-{
-	printf_hook_functions_t hooks = {print, arginfo};
-	
-	return hooks;
-}
-
 /**
  * Implements proposal_t.destroy.
  */
diff --git a/src/charon/config/proposal.h b/src/charon/config/proposal.h
index fb7dc9dfa..ea01120f9 100644
--- a/src/charon/config/proposal.h
+++ b/src/charon/config/proposal.h
@@ -12,7 +12,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * $Id: proposal.h 4062 2008-06-12 11:42:19Z martin $
+ * $Id: proposal.h 4936 2009-03-12 18:07:32Z tobias $
  */
 
 /**
@@ -233,13 +233,14 @@ proposal_t *proposal_create_default(protocol_id_t protocol);
 proposal_t *proposal_create_from_string(protocol_id_t protocol, const char *algs);
 
 /**
- * Get printf hooks for a proposal.
+ * printf hook function for proposal_t.
  *
  * Arguments are: 
  *    proposal_t *proposal
  * With the #-specifier, arguments are:
  *    linked_list_t *list containing proposal_t*
  */
-printf_hook_functions_t proposal_get_printf_hooks();
+int proposal_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
+						 const void *const *args);
 
 #endif /* PROPOSAL_H_ @} */
diff --git a/src/charon/config/traffic_selector.c b/src/charon/config/traffic_selector.c
index 7442fc7ef..b3bab900d 100644
--- a/src/charon/config/traffic_selector.c
+++ b/src/charon/config/traffic_selector.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007 Tobias Brunner
+ * Copyright (C) 2007-2009 Tobias Brunner
  * Copyright (C) 2005-2007 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
@@ -14,14 +14,13 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * $Id: traffic_selector.c 4860 2009-02-11 13:09:52Z martin $
+ * $Id: traffic_selector.c 4936 2009-03-12 18:07:32Z tobias $
  */
 
 #include <arpa/inet.h>
 #include <string.h>
 #include <netdb.h>
 #include <stdio.h>
-#include <printf.h>
 
 #include "traffic_selector.h"
 
@@ -157,10 +156,10 @@ static u_int8_t calc_netbits(private_traffic_selector_t *this)
 static private_traffic_selector_t *traffic_selector_create(u_int8_t protocol, ts_type_t type, u_int16_t from_port, u_int16_t to_port);
 
 /**
- * output handler in printf()
+ * Described in header.
  */
-static int print(FILE *stream, const struct printf_info *info,
-				 const void *const *args)
+int traffic_selector_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
+								 const void *const *args)
 {
 	private_traffic_selector_t *this = *((private_traffic_selector_t**)(args[0]));
 	linked_list_t *list = *((linked_list_t**)(args[0]));
@@ -175,16 +174,16 @@ static int print(FILE *stream, const struct printf_info *info,
 	
 	if (this == NULL)
 	{
-		return fprintf(stream, "(null)");
+		return print_in_hook(dst, len, "(null)");
 	}
 	
-	if (info->alt)
+	if (spec->hash)
 	{
 		iterator = list->create_iterator(list, TRUE);
 		while (iterator->iterate(iterator, (void**)&this))
 		{
 			/* call recursivly */
-			written += fprintf(stream, "%R ", this);
+			written += print_in_hook(dst, len, "%R ", this);
 		}
 		iterator->destroy(iterator);
 		return written;
@@ -196,7 +195,7 @@ static int print(FILE *stream, const struct printf_info *info,
 		memeq(this->from, from, this->type == TS_IPV4_ADDR_RANGE ? 4 : 16) && 
 		memeq(this->to, to, this->type == TS_IPV4_ADDR_RANGE ? 4 : 16))
 	{
-		written += fprintf(stream, "dynamic");
+		written += print_in_hook(dst, len, "dynamic");
 	}
 	else
 	{
@@ -209,7 +208,7 @@ static int print(FILE *stream, const struct printf_info *info,
 			inet_ntop(AF_INET6, &this->from6, addr_str, sizeof(addr_str));
 		}
 		mask = calc_netbits(this);
-		written += fprintf(stream, "%s/%d", addr_str, mask);
+		written += print_in_hook(dst, len, "%s/%d", addr_str, mask);
 	}
 	
 	/* check if we have protocol and/or port selectors */
@@ -221,7 +220,7 @@ static int print(FILE *stream, const struct printf_info *info,
 		return written;
 	}
 
-	written += fprintf(stream, "[");
+	written += print_in_hook(dst, len, "[");
 
 	/* build protocol string */
 	if (has_proto)
@@ -230,18 +229,18 @@ static int print(FILE *stream, const struct printf_info *info,
 
 		if (proto)
 		{
-			written += fprintf(stream, "%s", proto->p_name);
+			written += print_in_hook(dst, len, "%s", proto->p_name);
 			serv_proto = proto->p_name;
 		}
 		else
 		{
-			written += fprintf(stream, "%d", this->protocol);
+			written += print_in_hook(dst, len, "%d", this->protocol);
 		}
 	}
 	
 	if (has_proto && has_ports)
 	{
-		written += fprintf(stream, "/");
+		written += print_in_hook(dst, len, "/");
 	}
 
 	/* build port string */
@@ -253,46 +252,24 @@ static int print(FILE *stream, const struct printf_info *info,
 
 			if (serv)
 			{
-				written += fprintf(stream, "%s", serv->s_name);
+				written += print_in_hook(dst, len, "%s", serv->s_name);
 			}
 			else
 			{
-				written += fprintf(stream, "%d", this->from_port);
+				written += print_in_hook(dst, len, "%d", this->from_port);
 			}
 		}
 		else
 		{
-			written += fprintf(stream, "%d-%d", this->from_port, this->to_port);
+			written += print_in_hook(dst, len, "%d-%d", this->from_port, this->to_port);
 		}
 	}
 	
-	written += fprintf(stream, "]");
+	written += print_in_hook(dst, len, "]");
 
 	return written;
 }
 
-/**
- * arginfo handler for printf() traffic selector
- */
-static int arginfo(const struct printf_info *info, size_t n, int *argtypes)
-{
-	if (n > 0)
-	{
-		argtypes[0] = PA_POINTER;
-	}
-	return 1;
-}
-
-/**
- * return printf hook functions for a chunk
- */
-printf_hook_functions_t traffic_selector_get_printf_hooks()
-{
-	printf_hook_functions_t hooks = {print, arginfo};
-	
-	return hooks;
-}
-
 /**
  * implements traffic_selector_t.get_subset
  */
diff --git a/src/charon/config/traffic_selector.h b/src/charon/config/traffic_selector.h
index 69c04c605..fcec4e50b 100644
--- a/src/charon/config/traffic_selector.h
+++ b/src/charon/config/traffic_selector.h
@@ -14,7 +14,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * $Id: traffic_selector.h 4860 2009-02-11 13:09:52Z martin $
+ * $Id: traffic_selector.h 4936 2009-03-12 18:07:32Z tobias $
  */
 
 /**
@@ -291,13 +291,14 @@ traffic_selector_t *traffic_selector_create_dynamic(u_int8_t protocol,
 									u_int16_t from_port, u_int16_t to_port);
 
 /**
- * Get printf hooks for a traffic selector.
+ * printf hook function for traffic_selector_t.
  *
  * Arguments are: 
  *    traffic_selector_t *ts
  * With the #-specifier, arguments are:
  *    linked_list_t *list containing traffic_selector_t*
  */
-printf_hook_functions_t traffic_selector_get_printf_hooks();
+int traffic_selector_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
+								 const void *const *args);
 
 #endif /* TRAFFIC_SELECTOR_H_ @} */
diff --git a/src/charon/credentials/credential_manager.c b/src/charon/credentials/credential_manager.c
index 309115280..2841086b2 100644
--- a/src/charon/credentials/credential_manager.c
+++ b/src/charon/credentials/credential_manager.c
@@ -12,7 +12,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * $Id: credential_manager.c 4591 2008-11-05 16:12:54Z martin $
+ * $Id: credential_manager.c 4936 2009-03-12 18:07:32Z tobias $
  */
 
 #include <pthread.h>
@@ -572,7 +572,7 @@ static certificate_t *get_better_ocsp(private_credential_manager_t *this,
 		case VALIDATION_REVOKED:
 			/* subject has been revoked by a valid OCSP response */
 			DBG1(DBG_CFG, "certificate was revoked on %T, reason: %N",
-				 		  &revocation, crl_reason_names, reason);
+				 		  &revocation, TRUE, crl_reason_names, reason);
 			revoked = TRUE;
 			break;
 		case VALIDATION_GOOD:
@@ -593,7 +593,7 @@ static certificate_t *get_better_ocsp(private_credential_manager_t *this,
 		best = cand;
 		if (best->get_validity(best, NULL, NULL, &valid_until))
 		{
-			DBG1(DBG_CFG, "  ocsp response is valid: until %#T",
+			DBG1(DBG_CFG, "  ocsp response is valid: until %T",
 							 &valid_until, FALSE);
 			*valid = VALIDATION_GOOD;
 			if (cache)
@@ -603,7 +603,7 @@ static certificate_t *get_better_ocsp(private_credential_manager_t *this,
 		}
 		else
 		{
-			DBG1(DBG_CFG, "  ocsp response is stale: since %#T",
+			DBG1(DBG_CFG, "  ocsp response is stale: since %T",
 							 &valid_until, FALSE);
 			*valid = VALIDATION_STALE;
 		}
@@ -791,7 +791,7 @@ static certificate_t *get_better_crl(private_credential_manager_t *this,
 		if (chunk_equals(serial, subject->get_serial(subject)))
 		{
 			DBG1(DBG_CFG, "certificate was revoked on %T, reason: %N",
-				 &revocation, crl_reason_names, reason);
+				 &revocation, TRUE, crl_reason_names, reason);
 			*valid = VALIDATION_REVOKED;
 			enumerator->destroy(enumerator);
 			DESTROY_IF(best);
@@ -807,7 +807,7 @@ static certificate_t *get_better_crl(private_credential_manager_t *this,
 		best = cand;
 		if (best->get_validity(best, NULL, NULL, &valid_until))
 		{
-			DBG1(DBG_CFG, "  crl is valid: until %#T", &valid_until, FALSE);
+			DBG1(DBG_CFG, "  crl is valid: until %T", &valid_until, FALSE);
 			*valid = VALIDATION_GOOD;
 			if (cache)
 			{	/* we cache non-stale crls only, as a stale crls are refetched */
@@ -816,7 +816,7 @@ static certificate_t *get_better_crl(private_credential_manager_t *this,
 		}
 		else
 		{
-			DBG1(DBG_CFG, "  crl is stale: since %#T", &valid_until, FALSE);
+			DBG1(DBG_CFG, "  crl is stale: since %T", &valid_until, FALSE);
 			*valid = VALIDATION_STALE;
 		}
 	}
@@ -938,13 +938,13 @@ static bool check_certificate(private_credential_manager_t *this,
 	if (!subject->get_validity(subject, NULL, &not_before, &not_after))
 	{
 		DBG1(DBG_CFG, "subject certificate invalid (valid from %T to %T)",
-			 &not_before, &not_after);
+			 &not_before, TRUE, &not_after, TRUE);
 		return FALSE;
 	}
 	if (!issuer->get_validity(issuer, NULL, &not_before, &not_after))
 	{
 		DBG1(DBG_CFG, "issuer certificate invalid (valid from %T to %T)",
-			 &not_before, &not_after);
+			 &not_before, TRUE, &not_after, TRUE);
 		return FALSE;
 	}
 	if (issuer->get_type(issuer) == CERT_X509 &&
diff --git a/src/charon/daemon.c b/src/charon/daemon.c
index 78cbeec83..6dcb39a89 100644
--- a/src/charon/daemon.c
+++ b/src/charon/daemon.c
@@ -1,5 +1,5 @@
 /* 
- * Copyright (C) 2006-2007 Tobias Brunner
+ * Copyright (C) 2006-2009 Tobias Brunner
  * Copyright (C) 2006 Daniel Roethlisberger
  * Copyright (C) 2005-2008 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -644,9 +644,13 @@ int main(int argc, char *argv[])
 	/* initialize library */
 	library_init(STRONGSWAN_CONF);
 	lib->printf_hook->add_handler(lib->printf_hook, 'R',
-								  traffic_selector_get_printf_hooks());
+								  traffic_selector_printf_hook,
+								  PRINTF_HOOK_ARGTYPE_POINTER,
+								  PRINTF_HOOK_ARGTYPE_END);
 	lib->printf_hook->add_handler(lib->printf_hook, 'P',
-								  proposal_get_printf_hooks());
+								  proposal_printf_hook,
+								  PRINTF_HOOK_ARGTYPE_POINTER,
+								  PRINTF_HOOK_ARGTYPE_END);
 	private_charon = daemon_create();
 	charon = (daemon_t*)private_charon;
 	
diff --git a/src/charon/plugins/eap_mschapv2/eap_mschapv2.c b/src/charon/plugins/eap_mschapv2/eap_mschapv2.c
index 47dac47d4..07ca48e6f 100644
--- a/src/charon/plugins/eap_mschapv2/eap_mschapv2.c
+++ b/src/charon/plugins/eap_mschapv2/eap_mschapv2.c
@@ -12,7 +12,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * $Id: eap_mschapv2.c 4888 2009-02-19 14:32:13Z tobias $
+ * $Id: eap_mschapv2.c 4896 2009-02-24 13:39:50Z martin $
  */
 
 #include "eap_mschapv2.h"
@@ -643,7 +643,7 @@ static status_t process_peer_challenge(private_eap_mschapv2_t *this,
 	rng->destroy(rng);
 			
 	shared = charon->credentials->get_shared(charon->credentials,
-											 SHARED_EAP, this->server, this->peer);
+											 SHARED_EAP, this->peer, this->server);
 	if (shared == NULL)
 	{
 		DBG1(DBG_IKE, "no EAP key found for hosts '%D' - '%D'",
diff --git a/src/charon/plugins/nm/nm_service.c b/src/charon/plugins/nm/nm_service.c
index 1f2b6f723..72744b784 100644
--- a/src/charon/plugins/nm/nm_service.c
+++ b/src/charon/plugins/nm/nm_service.c
@@ -83,8 +83,8 @@ static void signal_ipv4_config(NMVPNPlugin *plugin,
  */
 static void signal_failure(NMVPNPlugin *plugin)
 {
-	/* TODO: NM does not handle this failure!? 
-	nm_vpn_plugin_failure(plugin, NM_VPN_PLUGIN_FAILURE_LOGIN_FAILED); */
+	/* TODO: NM does not handle this failure!? */
+	nm_vpn_plugin_failure(plugin, NM_VPN_PLUGIN_FAILURE_LOGIN_FAILED); 
 	nm_vpn_plugin_set_state(plugin, NM_VPN_SERVICE_STATE_STOPPED);
 }
 
@@ -144,7 +144,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
 	nm_creds_t *creds;
 	NMSettingVPN *settings;
 	identification_t *user = NULL, *gateway;
-	char *address, *str;
+	const char *address, *str;
 	bool virtual, encap, ipcomp;
 	ike_cfg_t *ike_cfg;
 	peer_cfg_t *peer_cfg;
@@ -164,20 +164,20 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
 	
 	DBG4(DBG_CFG, "received NetworkManager connection: %s",
 		 nm_setting_to_string(NM_SETTING(settings)));
-	address = g_hash_table_lookup(settings->data, "address");
+	address = nm_setting_vpn_get_data_item(settings, "address");
 	if (!address || !*address)
 	{
 		g_set_error(err, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
 				    "Gateway address missing.");
 		return FALSE;
 	}
-	str = g_hash_table_lookup(settings->data, "virtual");
+	str = nm_setting_vpn_get_data_item(settings, "virtual");
 	virtual = str && streq(str, "yes");
-	str = g_hash_table_lookup(settings->data, "encap");
+	str = nm_setting_vpn_get_data_item(settings, "encap");
 	encap = str && streq(str, "yes");
-	str = g_hash_table_lookup(settings->data, "ipcomp");
+	str = nm_setting_vpn_get_data_item(settings, "ipcomp");
 	ipcomp = str && streq(str, "yes");
-	str = g_hash_table_lookup(settings->data, "method");
+	str = nm_setting_vpn_get_data_item(settings, "method");
 	if (str)
 	{
 		if (streq(str, "psk"))
@@ -202,7 +202,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
 	creds->clear(creds);
 	
 	/* gateway cert */
-	str = g_hash_table_lookup(settings->data, "certificate");
+	str = nm_setting_vpn_get_data_item(settings, "certificate");
 	if (str)
 	{
 		cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
@@ -220,20 +220,20 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
 	if (auth_class == AUTH_CLASS_EAP)
 	{
 		/* username/password authentication ... */
-		str = g_hash_table_lookup(settings->data, "user");
+		str = nm_setting_vpn_get_data_item(settings, "user");
 		if (str)
 		{
 			user = identification_create_from_encoding(ID_KEY_ID,
 											chunk_create(str, strlen(str)));
-			str = g_hash_table_lookup(settings->secrets, "password");
-			creds->set_username_password(creds, user, str);
+			str = nm_setting_vpn_get_secret(settings, "password");
+			creds->set_username_password(creds, user, (char*)str);
 		}
 	}
 	
 	if (auth_class == AUTH_CLASS_PUBKEY)
 	{
 		/* ... or certificate/private key authenitcation */
-		str = g_hash_table_lookup(settings->data, "usercert");
+		str = nm_setting_vpn_get_data_item(settings, "usercert");
 		if (str)
 		{
 			public_key_t *public;
@@ -241,10 +241,16 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
 			
 			cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
 									  BUILD_FROM_FILE, str, BUILD_END);	
-									  
+			if (!cert)
+			{
+				g_set_error(err, NM_VPN_PLUGIN_ERROR,
+							NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+							"Loading peer certificate failed.");
+				return FALSE;
+			}
 			/* try agent */  
-			str = g_hash_table_lookup(settings->secrets, "agent");
-			if (agent && str && cert)
+			str = nm_setting_vpn_get_secret(settings, "agent");
+			if (agent && str)
 			{
 				public = cert->get_public_key(cert);
 				if (public)
@@ -256,25 +262,38 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
 												 BUILD_END);
 					public->destroy(public);
 				}
+				if (!private)
+				{
+					g_set_error(err, NM_VPN_PLUGIN_ERROR,
+								NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+								"Connecting to SSH agent failed.");
+				}
 			}
 			/* ... or key file */  
-			str = g_hash_table_lookup(settings->data, "userkey");
-			if (!agent && str && cert)
+			str = nm_setting_vpn_get_data_item(settings, "userkey");
+			if (!agent && str)
 			{
 				chunk_t secret, chunk;
 				bool pgp = FALSE;
 				
-				secret.ptr = g_hash_table_lookup(settings->secrets, "password");
+				secret.ptr = (char*)nm_setting_vpn_get_secret(settings,
+																 "password");
 				if (secret.ptr)
 				{
 					secret.len = strlen(secret.ptr);
 				}
-				if (pem_asn1_load_file(str, &secret, &chunk, &pgp))
+				if (pem_asn1_load_file((char*)str, &secret, &chunk, &pgp))
 				{
 					private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY,
 								KEY_RSA, BUILD_BLOB_ASN1_DER, chunk, BUILD_END);
 					free(chunk.ptr);
 				}
+				if (!private)
+				{
+					g_set_error(err, NM_VPN_PLUGIN_ERROR,
+								NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+								"Loading private key failed.");
+				}
 			}
 			if (private)
 			{
@@ -285,8 +304,6 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
 			else
 			{
 				DESTROY_IF(cert);
-				g_set_error(err, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
-							"Loading user certificate/private key failed.");
 				return FALSE;
 			}
 		}
@@ -302,7 +319,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
 	/**
 	 * Set up configurations
 	 */
-	ike_cfg = ike_cfg_create(TRUE, encap, "0.0.0.0", address);
+	ike_cfg = ike_cfg_create(TRUE, encap, "0.0.0.0", (char*)address);
 	ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
 	peer_cfg = peer_cfg_create(CONFIG_NAME, 2, ike_cfg,
 					user, gateway->clone(gateway),
@@ -367,40 +384,40 @@ static gboolean need_secrets(NMVPNPlugin *plugin, NMConnection *connection,
 							 char **setting_name, GError **error)
 {
 	NMSettingVPN *settings;
-	char *method, *path;
+	const char *method, *path;
 	chunk_t secret = chunk_empty, key;
 	bool pgp = FALSE;
 	
 	settings = NM_SETTING_VPN(nm_connection_get_setting(connection,
 														NM_TYPE_SETTING_VPN));
-	method = g_hash_table_lookup(settings->data, "method");
+	method = nm_setting_vpn_get_data_item(settings, "method");
 	if (method)
 	{
 		if (streq(method, "eap"))
 		{
-			if (g_hash_table_lookup(settings->secrets, "password"))
+			if (nm_setting_vpn_get_secret(settings, "password"))
 			{
 				return FALSE;
 			}
 		}
 		else if (streq(method, "agent"))
 		{
-			if (g_hash_table_lookup(settings->secrets, "agent"))
+			if (nm_setting_vpn_get_secret(settings, "agent"))
 			{
 				return FALSE;
 			}
 		}
 		else if (streq(method, "key"))
 		{
-			path = g_hash_table_lookup(settings->data, "userkey");
+			path = nm_setting_vpn_get_data_item(settings, "userkey");
 			if (path)
 			{
-				secret.ptr = g_hash_table_lookup(settings->secrets, "password");
+				secret.ptr = (char*)nm_setting_vpn_get_secret(settings, "password");
 				if (secret.ptr)
 				{
 					secret.len = strlen(secret.ptr);
 				}
-				if (pem_asn1_load_file(path, &secret, &key, &pgp))
+				if (pem_asn1_load_file((char*)path, &secret, &key, &pgp))
 				{
 					free(key.ptr);
 					return FALSE;
@@ -434,6 +451,9 @@ static gboolean disconnect(NMVPNPlugin *plugin, GError **err)
 		}
 	}
 	enumerator->destroy(enumerator);
+	
+	g_set_error(err, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_GENERAL,
+				"Connection not found.");
 	return FALSE;
 }
 
diff --git a/src/charon/plugins/sql/pool.c b/src/charon/plugins/sql/pool.c
index 8f5dc54dd..9761e88e9 100644
--- a/src/charon/plugins/sql/pool.c
+++ b/src/charon/plugins/sql/pool.c
@@ -554,10 +554,10 @@ static void leases(char *filter, bool utc)
 			printf("%-7s ", "expired");
 		}
 		
-		printf(" %#T  ", &acquired, utc);
+		printf(" %T  ", &acquired, utc);
 		if (released)
 		{
-			printf("%#T  ", &released, utc);
+			printf("%T  ", &released, utc);
 		}
 		else
 		{
diff --git a/src/charon/plugins/sql/sql_attribute.c b/src/charon/plugins/sql/sql_attribute.c
index cd6f7c0cd..826aa8318 100644
--- a/src/charon/plugins/sql/sql_attribute.c
+++ b/src/charon/plugins/sql/sql_attribute.c
@@ -89,7 +89,7 @@ static u_int get_pool(private_sql_attribute_t *this, char *name, u_int *timeout)
 		e->destroy(e);
 		return pool;
 	}
-	DBG1(DBG_CFG, "ip pool '%s' not found");
+	DESTROY_IF(e);
 	return 0;
 }
 
diff --git a/src/charon/plugins/stroke/stroke_attribute.c b/src/charon/plugins/stroke/stroke_attribute.c
index 7591a1e27..f850b5320 100644
--- a/src/charon/plugins/stroke/stroke_attribute.c
+++ b/src/charon/plugins/stroke/stroke_attribute.c
@@ -307,6 +307,7 @@ static bool release_address(private_stroke_attribute_t *this,
 				{
 					DBG1(DBG_CFG, "lease %H of %D went offline", address, id);
 					pool->offline->put(pool->offline, id, (void*)offset);
+					found = TRUE;
 				}
 			}
 		}
diff --git a/src/charon/plugins/stroke/stroke_cred.c b/src/charon/plugins/stroke/stroke_cred.c
index 07e0ca768..434aec22b 100644
--- a/src/charon/plugins/stroke/stroke_cred.c
+++ b/src/charon/plugins/stroke/stroke_cred.c
@@ -804,7 +804,7 @@ static void load_secrets(private_stroke_cred_t *this)
 		}
 		else if (match("PIN", &token))
 		{
-			chunk_t sc = chunk_empty;
+			chunk_t sc = chunk_empty, secret = chunk_empty;
 			char smartcard[32], keyid[22], pin[32];
 			private_key_t *key;
 			u_int slot;
@@ -847,13 +847,13 @@ static void load_secrets(private_stroke_cred_t *this)
 				DBG1(DBG_CFG, "line %d: expected PIN", line_nr);
 				goto error;
 			}
-			ugh = extract_secret(&chunk, &line);
+			ugh = extract_secret(&secret, &line);
 			if (ugh != NULL)
 			{
 				DBG1(DBG_CFG, "line %d: malformed PIN: %s", line_nr, ugh);
 				goto error;
 			}
-			snprintf(pin, sizeof(pin), "%.*s", chunk.len, chunk.ptr);
+			snprintf(pin, sizeof(pin), "%.*s", secret.len, secret.ptr);
 			pin[sizeof(pin) - 1] = '\0';
 			
 			/* we assume an RSA key */
@@ -867,6 +867,7 @@ static void load_secrets(private_stroke_cred_t *this)
 				this->private->insert_last(this->private, key);
 			}
 			memset(pin, 0, sizeof(pin));
+			chunk_clear(&secret);
 		}
 		else if ((match("PSK", &token) && (type = SHARED_IKE)) ||
 				 (match("EAP", &token) && (type = SHARED_EAP)) ||
diff --git a/src/charon/plugins/stroke/stroke_list.c b/src/charon/plugins/stroke/stroke_list.c
index 8042875c9..94b3def3a 100644
--- a/src/charon/plugins/stroke/stroke_list.c
+++ b/src/charon/plugins/stroke/stroke_list.c
@@ -88,7 +88,7 @@ static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all)
 		time_t established;
 		
 		established = ike_sa->get_statistic(ike_sa, STAT_ESTABLISHED);
-		fprintf(out, " %#V ago", &now, &established);
+		fprintf(out, " %V ago", &now, &established);
 	}
 	
 	fprintf(out, ", %H[%D]...%H[%D]\n",
@@ -116,11 +116,11 @@ static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all)
 			
 			if (rekey)
 			{
-				fprintf(out, ", rekeying in %#V", &rekey, &now);
+				fprintf(out, ", rekeying in %V", &rekey, &now);
 			}
 			if (reauth)
 			{
-				fprintf(out, ", %N reauthentication in %#V", auth_class_names,
+				fprintf(out, ", %N reauthentication in %V", auth_class_names,
 						get_auth_class(ike_sa->get_peer_cfg(ike_sa)),
 						&reauth, &now);
 			}
@@ -212,7 +212,7 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
 			rekey = child_sa->get_lifetime(child_sa, FALSE);
 			if (rekey)
 			{
-				fprintf(out, "in %#V", &now, &rekey);
+				fprintf(out, "in %V", &now, &rekey);
 			}
 			else
 			{
@@ -265,12 +265,12 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo
 		char *plugin, *pool;
 		host_t *host;
 		u_int32_t dpd;
-		time_t uptime = time(NULL) - this->uptime;
+		time_t now = time(NULL);
 		bool first = TRUE;
 		u_int size, online, offline;
 		
 		fprintf(out, "Performance:\n");
-		fprintf(out, "  uptime: %V, since %#T\n", &uptime, &this->uptime, FALSE);
+		fprintf(out, "  uptime: %V, since %T\n", &now, &this->uptime, &this->uptime, FALSE);
 		fprintf(out, "  worker threads: %d idle of %d,",
 				charon->processor->get_idle_threads(charon->processor),
 				charon->processor->get_total_threads(charon->processor));
@@ -290,6 +290,10 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo
 		enumerator = this->attribute->create_pool_enumerator(this->attribute);
 		while (enumerator->enumerate(enumerator, &pool, &size, &online, &offline))
 		{
+			if (name && !streq(name, pool))
+			{
+				continue;
+			}
 			if (first)
 			{
 				first = FALSE;
@@ -655,26 +659,26 @@ static void stroke_list_certs(linked_list_t *list, char *label,
 
 			/* list validity */
 			cert->get_validity(cert, &now, &notBefore, &notAfter);
-			fprintf(out, "  validity:  not before %#T, ", &notBefore, utc);
+			fprintf(out, "  validity:  not before %T, ", &notBefore, utc);
 			if (now < notBefore)
 			{
-				fprintf(out, "not valid yet (valid in %#V)\n", &now, &notBefore);
+				fprintf(out, "not valid yet (valid in %V)\n", &now, &notBefore);
 			}
 			else
 			{
 				fprintf(out, "ok\n");
 			}
-			fprintf(out, "             not after  %#T, ", &notAfter, utc);
+			fprintf(out, "             not after  %T, ", &notAfter, utc);
 			if (now > notAfter)
 			{
-				fprintf(out, "expired (%#V ago)\n", &now, &notAfter);
+				fprintf(out, "expired (%V ago)\n", &now, &notAfter);
 			}
 			else
 			{
 				fprintf(out, "ok");
 				if (now > notAfter - CERT_WARNING_INTERVAL * 60 * 60 * 24)
 				{
-					fprintf(out, " (expires in %#V)", &now, &notAfter);
+					fprintf(out, " (expires in %V)", &now, &notAfter);
 				}
 				fprintf(out, " \n");
 			}
@@ -755,18 +759,18 @@ static void stroke_list_acerts(linked_list_t *list, bool utc, FILE *out)
 
 		/* list validity */
 		cert->get_validity(cert, &now, &thisUpdate, &nextUpdate);
-		fprintf(out, "  updates:   this %#T\n",  &thisUpdate, utc);
-		fprintf(out, "             next %#T, ", &nextUpdate, utc);
+		fprintf(out, "  updates:   this %T\n",  &thisUpdate, utc);
+		fprintf(out, "             next %T, ", &nextUpdate, utc);
 		if (now > nextUpdate)
 		{
-			fprintf(out, "expired (%#V ago)\n", &now, &nextUpdate);
+			fprintf(out, "expired (%V ago)\n", &now, &nextUpdate);
 		}
 		else
 		{
 			fprintf(out, "ok");
 			if (now > nextUpdate - AC_WARNING_INTERVAL * 60 * 60 * 24)
 			{
-				fprintf(out, " (expires in %#V)", &now, &nextUpdate);
+				fprintf(out, " (expires in %V)", &now, &nextUpdate);
 			}
 			fprintf(out, " \n");
 		}
@@ -828,18 +832,18 @@ static void stroke_list_crls(linked_list_t *list, bool utc, FILE *out)
 
 		/* list validity */
 		cert->get_validity(cert, &now, &thisUpdate, &nextUpdate);
-		fprintf(out, "  updates:   this %#T\n",  &thisUpdate, utc);
-		fprintf(out, "             next %#T, ", &nextUpdate, utc);
+		fprintf(out, "  updates:   this %T\n",  &thisUpdate, utc);
+		fprintf(out, "             next %T, ", &nextUpdate, utc);
 		if (now > nextUpdate)
 		{
-			fprintf(out, "expired (%#V ago)\n", &now, &nextUpdate);
+			fprintf(out, "expired (%V ago)\n", &now, &nextUpdate);
 		}
 		else
 		{
 			fprintf(out, "ok");
 			if (now > nextUpdate - CRL_WARNING_INTERVAL * 60 * 60 * 24)
 			{
-				fprintf(out, " (expires in %#V)", &now, &nextUpdate);
+				fprintf(out, " (expires in %V)", &now, &nextUpdate);
 			}
 			fprintf(out, " \n");
 		}
diff --git a/src/charon/sa/ike_sa.c b/src/charon/sa/ike_sa.c
index 82dd479ca..6acbc6eef 100644
--- a/src/charon/sa/ike_sa.c
+++ b/src/charon/sa/ike_sa.c
@@ -15,12 +15,11 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * $Id: ike_sa.c 4808 2008-12-16 15:48:36Z martin $
+ * $Id: ike_sa.c 4945 2009-03-16 14:23:36Z martin $
  */
 
 #include <sys/time.h>
 #include <string.h>
-#include <printf.h>
 #include <sys/stat.h>
 #include <errno.h>
 #include <time.h>
@@ -1103,6 +1102,12 @@ static void resolve_hosts(private_ike_sa_t *this)
 			{
 				host->set_port(host, IKEV2_UDP_PORT);
 			}
+			else
+			{	/* fallback to address family specific %any(6), if configured */
+				host = host_create_from_dns(
+									this->ike_cfg->get_my_addr(this->ike_cfg),
+									0, IKEV2_UDP_PORT);
+			}
 		}
 	}
 	if (host)
@@ -1743,7 +1748,7 @@ static status_t reauth(private_ike_sa_t *this)
 		{
 			time_t now = time(NULL);
 			
-			DBG1(DBG_IKE, "IKE_SA will timeout in %#V",
+			DBG1(DBG_IKE, "IKE_SA will timeout in %V",
 				 &now, &this->stats[STAT_DELETE]);
 			return FAILED;
 		}
diff --git a/src/libstrongswan/Makefile.am b/src/libstrongswan/Makefile.am
index 110c2ef16..1d0f837ef 100644
--- a/src/libstrongswan/Makefile.am
+++ b/src/libstrongswan/Makefile.am
@@ -74,6 +74,10 @@ if USE_INTEGRITY_TEST
   fips/fips_canister_end.c
 endif
 
+if USE_VSTR
+  libstrongswan_la_LIBADD += -lvstr
+endif
+
 EXTRA_DIST = asn1/oid.txt asn1/oid.pl
 BUILT_SOURCES = asn1/oid.c asn1/oid.h
 MAINTAINERCLEANFILES = asn1/oid.c asn1/oid.h
diff --git a/src/libstrongswan/Makefile.in b/src/libstrongswan/Makefile.in
index ba90d987b..ed13138e4 100644
--- a/src/libstrongswan/Makefile.in
+++ b/src/libstrongswan/Makefile.in
@@ -35,27 +35,28 @@ host_triplet = @host@
 @USE_LEAK_DETECTIVE_TRUE@am__append_1 = -DLEAK_DETECTIVE
 @USE_LEAK_DETECTIVE_TRUE@am__append_2 = utils/leak_detective.c utils/leak_detective.h
 @USE_LOCK_PROFILER_TRUE@am__append_3 = -DLOCK_PROFILER
-@USE_AES_TRUE@am__append_4 = plugins/aes
-@USE_DES_TRUE@am__append_5 = plugins/des
-@USE_MD4_TRUE@am__append_6 = plugins/md4
-@USE_MD5_TRUE@am__append_7 = plugins/md5
-@USE_SHA1_TRUE@am__append_8 = plugins/sha1
-@USE_SHA2_TRUE@am__append_9 = plugins/sha2
-@USE_FIPS_PRF_TRUE@am__append_10 = plugins/fips_prf
-@USE_GMP_TRUE@am__append_11 = plugins/gmp
-@USE_RANDOM_TRUE@am__append_12 = plugins/random
-@USE_HMAC_TRUE@am__append_13 = plugins/hmac
-@USE_XCBC_TRUE@am__append_14 = plugins/xcbc
-@USE_X509_TRUE@am__append_15 = plugins/x509
-@USE_PUBKEY_TRUE@am__append_16 = plugins/pubkey
-@USE_CURL_TRUE@am__append_17 = plugins/curl
-@USE_LDAP_TRUE@am__append_18 = plugins/ldap
-@USE_MYSQL_TRUE@am__append_19 = plugins/mysql
-@USE_SQLITE_TRUE@am__append_20 = plugins/sqlite
-@USE_PADLOCK_TRUE@am__append_21 = plugins/padlock
-@USE_OPENSSL_TRUE@am__append_22 = plugins/openssl
-@USE_AGENT_TRUE@am__append_23 = plugins/agent
-@USE_INTEGRITY_TEST_TRUE@am__append_24 = fips
+@USE_VSTR_TRUE@am__append_4 = -lvstr
+@USE_AES_TRUE@am__append_5 = plugins/aes
+@USE_DES_TRUE@am__append_6 = plugins/des
+@USE_MD4_TRUE@am__append_7 = plugins/md4
+@USE_MD5_TRUE@am__append_8 = plugins/md5
+@USE_SHA1_TRUE@am__append_9 = plugins/sha1
+@USE_SHA2_TRUE@am__append_10 = plugins/sha2
+@USE_FIPS_PRF_TRUE@am__append_11 = plugins/fips_prf
+@USE_GMP_TRUE@am__append_12 = plugins/gmp
+@USE_RANDOM_TRUE@am__append_13 = plugins/random
+@USE_HMAC_TRUE@am__append_14 = plugins/hmac
+@USE_XCBC_TRUE@am__append_15 = plugins/xcbc
+@USE_X509_TRUE@am__append_16 = plugins/x509
+@USE_PUBKEY_TRUE@am__append_17 = plugins/pubkey
+@USE_CURL_TRUE@am__append_18 = plugins/curl
+@USE_LDAP_TRUE@am__append_19 = plugins/ldap
+@USE_MYSQL_TRUE@am__append_20 = plugins/mysql
+@USE_SQLITE_TRUE@am__append_21 = plugins/sqlite
+@USE_PADLOCK_TRUE@am__append_22 = plugins/padlock
+@USE_OPENSSL_TRUE@am__append_23 = plugins/openssl
+@USE_AGENT_TRUE@am__append_24 = plugins/agent
+@USE_INTEGRITY_TEST_TRUE@am__append_25 = fips
 subdir = src/libstrongswan
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -73,7 +74,8 @@ am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
 am__installdirs = "$(DESTDIR)$(libdir)"
 libLTLIBRARIES_INSTALL = $(INSTALL)
 LTLIBRARIES = $(lib_LTLIBRARIES)
-libstrongswan_la_DEPENDENCIES =
+am__DEPENDENCIES_1 =
+libstrongswan_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
 am__libstrongswan_la_SOURCES_DIST = library.c library.h chunk.c \
 	chunk.h debug.c debug.h enum.c enum.h settings.h settings.c \
 	printf_hook.c printf_hook.h asn1/asn1.c asn1/asn1.h \
@@ -451,7 +453,7 @@ lib_LTLIBRARIES = libstrongswan.la
 @USE_INTEGRITY_TEST_TRUE@	plugins/plugin_loader.h \
 @USE_INTEGRITY_TEST_TRUE@	plugins/plugin.h $(am__append_2) \
 @USE_INTEGRITY_TEST_TRUE@	fips/fips_canister_end.c
-libstrongswan_la_LIBADD = -lpthread -ldl
+libstrongswan_la_LIBADD = -lpthread -ldl $(am__append_4)
 INCLUDES = -I$(top_srcdir)/src/libstrongswan
 AM_CFLAGS = -DIPSEC_DIR=\"${ipsecdir}\" \
 	-DIPSEC_PLUGINDIR=\"${plugindir}\" $(am__append_1) \
@@ -462,13 +464,13 @@ MAINTAINERCLEANFILES = asn1/oid.c asn1/oid.h
 
 # build plugins with their own Makefile
 #######################################
-SUBDIRS = . $(am__append_4) $(am__append_5) $(am__append_6) \
-	$(am__append_7) $(am__append_8) $(am__append_9) \
-	$(am__append_10) $(am__append_11) $(am__append_12) \
-	$(am__append_13) $(am__append_14) $(am__append_15) \
-	$(am__append_16) $(am__append_17) $(am__append_18) \
-	$(am__append_19) $(am__append_20) $(am__append_21) \
-	$(am__append_22) $(am__append_23) $(am__append_24)
+SUBDIRS = . $(am__append_5) $(am__append_6) $(am__append_7) \
+	$(am__append_8) $(am__append_9) $(am__append_10) \
+	$(am__append_11) $(am__append_12) $(am__append_13) \
+	$(am__append_14) $(am__append_15) $(am__append_16) \
+	$(am__append_17) $(am__append_18) $(am__append_19) \
+	$(am__append_20) $(am__append_21) $(am__append_22) \
+	$(am__append_23) $(am__append_24) $(am__append_25)
 all: $(BUILT_SOURCES)
 	$(MAKE) $(AM_MAKEFLAGS) all-recursive
 
diff --git a/src/libstrongswan/asn1/asn1.c b/src/libstrongswan/asn1/asn1.c
index 6122aa9f8..1359dcd2d 100644
--- a/src/libstrongswan/asn1/asn1.c
+++ b/src/libstrongswan/asn1/asn1.c
@@ -14,7 +14,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * $Id: asn1.c 4776 2008-12-09 15:00:30Z martin $
+ * $Id: asn1.c 4942 2009-03-13 20:22:24Z andreas $
  */
 
 #include <stdio.h>
@@ -397,7 +397,7 @@ void asn1_debug_simple_object(chunk_t object, asn1_t type, bool private)
 			{
 				time_t time = asn1_to_time(&object, type);
 
-				DBG2("  '%T'", &time);
+				DBG2("  '%T'", &time, TRUE);
 			}
 			return;
 		default:
@@ -452,13 +452,6 @@ bool asn1_parse_simple_object(chunk_t *object, asn1_t type, u_int level, const c
  * ASN.1 definition of an algorithmIdentifier
  */
 static const asn1Object_t algorithmIdentifierObjects[] = {
-	{ 0, "algorithmIdentifier",	ASN1_SEQUENCE,	ASN1_NONE }, /* 0 */
-	{ 1,   "algorithm",			ASN1_OID,		ASN1_BODY }, /* 1 */
-	{ 1,   "parameters",		ASN1_EOC,		ASN1_RAW  }, /* 2 */
-	{ 0, "exit",				ASN1_EOC,		ASN1_EXIT }
-};
-/* parameters are optional in case of ecdsa-with-SHA1 as algorithm (RFC 3279) */
-static const asn1Object_t algorithmIdentifierObjectsOptional[] = {
 	{ 0, "algorithmIdentifier",	ASN1_SEQUENCE,	ASN1_NONE         }, /* 0 */
 	{ 1,   "algorithm",			ASN1_OID,		ASN1_BODY         }, /* 1 */
 	{ 1,   "parameters",		ASN1_EOC,		ASN1_RAW|ASN1_OPT }, /* 2 */
@@ -477,14 +470,8 @@ int asn1_parse_algorithmIdentifier(chunk_t blob, int level0, chunk_t *parameters
 	chunk_t object;
 	int objectID;
 	int alg = OID_UNKNOWN;
-	const asn1Object_t *objects = algorithmIdentifierObjectsOptional;
-	
-	if (parameters != NULL)
-	{
-		objects = algorithmIdentifierObjects;
-	}
 	
-	parser = asn1_parser_create(objects, blob);
+	parser = asn1_parser_create(algorithmIdentifierObjects, blob);
 	parser->set_top_level(parser, level0);
 	
 	while (parser->iterate(parser, &objectID, &object))
diff --git a/src/libstrongswan/chunk.c b/src/libstrongswan/chunk.c
index 681581af9..331ef4436 100644
--- a/src/libstrongswan/chunk.c
+++ b/src/libstrongswan/chunk.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2008-2009 Tobias Brunner
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
@@ -14,7 +14,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * $Id: chunk.c 4784 2008-12-10 13:43:51Z tobias $
+ * $Id: chunk.c 4936 2009-03-12 18:07:32Z tobias $
  */
 
 #include <stdio.h>
@@ -25,7 +25,6 @@
 #include "chunk.h"
 
 #include <debug.h>
-#include <printf_hook.h>
 
 /* required for chunk_hash */
 #undef get16bits
@@ -520,21 +519,20 @@ u_int32_t chunk_hash(chunk_t chunk)
 }
 
 /**
- * output handler in printf() for chunks
+ * Described in header.
  */
-static int chunk_print(FILE *stream, const struct printf_info *info,
-					   const void *const *args)
+int chunk_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
+					  const void *const *args)
 {
 	chunk_t *chunk = *((chunk_t**)(args[0]));
 	bool first = TRUE;
 	chunk_t copy = *chunk;
 	int written = 0;
-	printf_hook_functions_t mem = mem_get_printf_hooks();
 	
-	if (!info->alt)
+	if (!spec->hash)
 	{
 		const void *new_args[] = {&chunk->ptr, &chunk->len};
-		return mem.print(stream, info, new_args);
+		return mem_printf_hook(dst, len, spec, new_args);
 	}
 	
 	while (copy.len > 0)
@@ -545,33 +543,10 @@ static int chunk_print(FILE *stream, const struct printf_info *info,
 		}
 		else
 		{
-			written += fprintf(stream, ":");
+			written += print_in_hook(dst, len, ":");
 		}
-		written += fprintf(stream, "%02x", *copy.ptr++);
+		written += print_in_hook(dst, len, "%02x", *copy.ptr++);
 		copy.len--;
 	}
 	return written;
 }
-
-/**
- * arginfo handler for printf() mem ranges
- */
-static int chunk_arginfo(const struct printf_info *info, size_t n, int *argtypes)
-{
-	if (n > 0)
-	{
-		argtypes[0] = PA_POINTER;
-	}
-	return 1;
-}
-
-/**
- * return printf hook functions for a chunk
- */
-printf_hook_functions_t chunk_get_printf_hooks()
-{
-	printf_hook_functions_t hooks = {chunk_print, chunk_arginfo};
-	
-	return hooks;
-}
-
diff --git a/src/libstrongswan/chunk.h b/src/libstrongswan/chunk.h
index 2986e0db3..5eb8f8d8a 100644
--- a/src/libstrongswan/chunk.h
+++ b/src/libstrongswan/chunk.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2008-2009 Tobias Brunner
  * Copyright (C) 2005-2008 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
@@ -14,7 +14,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * $Id: chunk.h 4841 2009-01-15 01:52:44Z andreas $
+ * $Id: chunk.h 4936 2009-03-12 18:07:32Z tobias $
  */
 
 /**
@@ -240,11 +240,13 @@ u_int32_t chunk_hash(chunk_t chunk);
 u_int32_t chunk_hash_inc(chunk_t chunk, u_int32_t hash);
 
 /**
- * Get printf hooks for a chunk.
+ * printf hook function for chunk_t.
  *
  * Arguments are: 
  *    chunk_t *chunk
+ * Use #-modifier to print a compact version
  */
-printf_hook_functions_t chunk_get_printf_hooks();
+int chunk_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
+					  const void *const *args);
 
 #endif /* CHUNK_H_ @}*/
diff --git a/src/libstrongswan/enum.c b/src/libstrongswan/enum.c
index 5eb283807..32524d225 100644
--- a/src/libstrongswan/enum.c
+++ b/src/libstrongswan/enum.c
@@ -12,7 +12,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * $Id: enum.c 3589 2008-03-13 14:14:44Z martin $
+ * $Id: enum.c 4936 2009-03-12 18:07:32Z tobias $
  */
 
 #include <stddef.h>
@@ -20,8 +20,6 @@
 
 #include "enum.h"
 
-#include <printf_hook.h>
-
 /**
  * get the name of an enum value in a enum_name_t list
  */
@@ -39,10 +37,10 @@ static char *enum_name(enum_name_t *e, int val)
 }
 
 /**
- * output handler in printf() for enum names
+ * Described in header.
  */
-static int print(FILE *stream, const struct printf_info *info,
-					  const void *const *args)
+int enum_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
+					 const void *const *args)
 {
 	enum_name_t *ed = *((enum_name_t**)(args[0]));
 	int val = *((int*)(args[1]));
@@ -51,34 +49,10 @@ static int print(FILE *stream, const struct printf_info *info,
 
 	if (name == NULL)
 	{
-		return fprintf(stream, "(%d)", val);
+		return print_in_hook(dst, len, "(%d)", val);
 	}
 	else
 	{
-		return fprintf(stream, "%s", name);
-	}
-}
-
-/**
- * arginfo handler for printf() hook
- */
-static int arginfo(const struct printf_info *info, size_t n, int *argtypes)
-{
-	if (n > 1)
-	{
-		argtypes[0] = PA_POINTER;
-		argtypes[1] = PA_INT;
+		return print_in_hook(dst, len, "%s", name);
 	}
-	return 2;
 }
-
-/**
- * return printf hook functions
- */
-printf_hook_functions_t enum_get_printf_hooks()
-{
-	printf_hook_functions_t hooks = {print, arginfo};
-	
-	return hooks;
-}
-
diff --git a/src/libstrongswan/enum.h b/src/libstrongswan/enum.h
index 5e44293c0..4a594a4a9 100644
--- a/src/libstrongswan/enum.h
+++ b/src/libstrongswan/enum.h
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2009 Tobias Brunner
  * Copyright (C) 2006-2008 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
@@ -12,7 +13,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * $Id: enum.h 3589 2008-03-13 14:14:44Z martin $
+ * $Id: enum.h 4936 2009-03-12 18:07:32Z tobias $
  */
 
 /**
@@ -108,12 +109,12 @@ struct enum_name_t {
 #define ENUM(name, first, last, ...) ENUM_BEGIN(name, first, last, __VA_ARGS__); ENUM_END(name, last)
 
 /**
- * Get printf hook functions for enum_names_t.
+ * printf hook function for enum_names_t.
  *
- * The handler takes the arguments: enum_names_t *names, int value
- *
- * @return 		printf hook functions
+ * Arguments are: 
+ *    enum_names_t *names, int value
  */
-printf_hook_functions_t enum_get_printf_hooks();
+int enum_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
+					 const void *const *args);
 
 #endif /* ENUM_H_ @}*/
diff --git a/src/libstrongswan/library.c b/src/libstrongswan/library.c
index 07d08fa51..cb8d43052 100644
--- a/src/libstrongswan/library.c
+++ b/src/libstrongswan/library.c
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2009 Tobias Brunner
  * Copyright (C) 2008 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
@@ -12,7 +13,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * $Id: library.c 4311 2008-08-28 16:27:48Z martin $
+ * $Id: library.c 4936 2009-03-12 18:07:32Z tobias $
  */
 
 #include "library.h"
@@ -95,13 +96,24 @@ void library_init(char *settings)
 	pfh = printf_hook_create();
 	this->public.printf_hook = pfh;
 	
-	pfh->add_handler(pfh, 'b', mem_get_printf_hooks());
-	pfh->add_handler(pfh, 'B', chunk_get_printf_hooks());
-	pfh->add_handler(pfh, 'D', identification_get_printf_hooks());
-	pfh->add_handler(pfh, 'H', host_get_printf_hooks());
-	pfh->add_handler(pfh, 'N', enum_get_printf_hooks());
-	pfh->add_handler(pfh, 'T', time_get_printf_hooks());
-	pfh->add_handler(pfh, 'V', time_delta_get_printf_hooks());
+	pfh->add_handler(pfh, 'b', mem_printf_hook,
+					 PRINTF_HOOK_ARGTYPE_POINTER, PRINTF_HOOK_ARGTYPE_INT,
+					 PRINTF_HOOK_ARGTYPE_END);
+	pfh->add_handler(pfh, 'B', chunk_printf_hook,
+					 PRINTF_HOOK_ARGTYPE_POINTER, PRINTF_HOOK_ARGTYPE_END);
+	pfh->add_handler(pfh, 'D', identification_printf_hook,
+					 PRINTF_HOOK_ARGTYPE_POINTER, PRINTF_HOOK_ARGTYPE_END);
+	pfh->add_handler(pfh, 'H', host_printf_hook,
+					 PRINTF_HOOK_ARGTYPE_POINTER, PRINTF_HOOK_ARGTYPE_END);
+	pfh->add_handler(pfh, 'N', enum_printf_hook,
+					 PRINTF_HOOK_ARGTYPE_POINTER, PRINTF_HOOK_ARGTYPE_INT,
+					 PRINTF_HOOK_ARGTYPE_END);
+	pfh->add_handler(pfh, 'T', time_printf_hook,
+					 PRINTF_HOOK_ARGTYPE_POINTER, PRINTF_HOOK_ARGTYPE_INT,
+					 PRINTF_HOOK_ARGTYPE_END);
+	pfh->add_handler(pfh, 'V', time_delta_printf_hook,
+					 PRINTF_HOOK_ARGTYPE_POINTER, PRINTF_HOOK_ARGTYPE_POINTER,
+					 PRINTF_HOOK_ARGTYPE_END);
 	
 	this->public.crypto = crypto_factory_create();
 	this->public.creds = credential_factory_create();
diff --git a/src/libstrongswan/library.h b/src/libstrongswan/library.h
index 34a981054..1445b28cd 100644
--- a/src/libstrongswan/library.h
+++ b/src/libstrongswan/library.h
@@ -12,7 +12,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * $Id: library.h 4311 2008-08-28 16:27:48Z martin $
+ * $Id: library.h 4936 2009-03-12 18:07:32Z tobias $
  */
 
 /**
@@ -57,10 +57,10 @@
 #ifndef LIBRARY_H_
 #define LIBRARY_H_
 
+#include <printf_hook.h>
 #include <utils.h>
 #include <chunk.h>
 #include <settings.h>
-#include <printf_hook.h>
 #include <plugins/plugin_loader.h>
 #include <crypto/crypto_factory.h>
 #include <credentials/credential_factory.h>
diff --git a/src/libstrongswan/plugins/des/des_crypter.c b/src/libstrongswan/plugins/des/des_crypter.c
index a0b147c63..b0b18a2c1 100644
--- a/src/libstrongswan/plugins/des/des_crypter.c
+++ b/src/libstrongswan/plugins/des/des_crypter.c
@@ -57,7 +57,7 @@
  * copied and put under another distribution licence
  * [including the GNU Public Licence.]
  *
- * $Id: des_crypter.c 4887 2009-02-19 14:29:25Z tobias $
+ * $Id: des_crypter.c 4938 2009-03-12 18:38:13Z tobias $
  */
 
 #include "des_crypter.h"
@@ -1128,10 +1128,8 @@ static void des_ecb_encrypt(des_cblock *input, des_cblock *output, long length,
 	{
 		for (l-=8; l>=0; l-=8)
 		{
-			c2l(in,tin0);
-			c2l(in,tin1);
-			tin[0]=tin0;
-			tin[1]=tin1;
+			c2l(in,tin0); tin[0]=tin0;
+			c2l(in,tin1); tin[1]=tin1;
 			des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
 			tout0=tin[0]; l2c(tout0,out);
 			tout1=tin[1]; l2c(tout1,out);
@@ -1153,14 +1151,16 @@ static void des_ecb_encrypt(des_cblock *input, des_cblock *output, long length,
 			c2l(in,tin0); tin[0]=tin0;
 			c2l(in,tin1); tin[1]=tin1;
 			des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
-			l2c(tout0,out);
-			l2c(tout1,out);
+			tout0=tin[0]; l2c(tout0,out);
+			tout1=tin[1]; l2c(tout1,out);
 		}
 		if (l != -8)
 		{
 			c2l(in,tin0); tin[0]=tin0;
 			c2l(in,tin1); tin[1]=tin1;
 			des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
+			tout0=tin[0];
+			tout1=tin[1];
 			l2cn(tout0,tout1,out,l+8);
 		}
 	}
diff --git a/src/libstrongswan/plugins/x509/x509_ac.c b/src/libstrongswan/plugins/x509/x509_ac.c
index fbb7707a1..2168f9bc7 100644
--- a/src/libstrongswan/plugins/x509/x509_ac.c
+++ b/src/libstrongswan/plugins/x509/x509_ac.c
@@ -870,7 +870,7 @@ static bool is_newer(private_x509_ac_t *this, ac_t *that)
 	this_cert->get_validity(this_cert, &now, &this_update, NULL);
 	that_cert->get_validity(that_cert, &now, &that_update, NULL);
 	new = this_update > that_update;
-	DBG1("  attr cert from %#T is %s - existing attr_cert from %#T %s",
+	DBG1("  attr cert from %T is %s - existing attr_cert from %T %s",
 			&this_update, FALSE, new ? "newer":"not newer",
 			&that_update, FALSE, new ? "replaced":"retained");
 	return new;
diff --git a/src/libstrongswan/plugins/x509/x509_cert.c b/src/libstrongswan/plugins/x509/x509_cert.c
index e618f31d8..4c6b45394 100644
--- a/src/libstrongswan/plugins/x509/x509_cert.c
+++ b/src/libstrongswan/plugins/x509/x509_cert.c
@@ -17,7 +17,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * $Id: x509_cert.c 4767 2008-12-08 19:15:38Z martin $
+ * $Id: x509_cert.c 4936 2009-03-12 18:07:32Z tobias $
  */
 
 #define _GNU_SOURCE
@@ -1010,7 +1010,7 @@ static bool is_newer(certificate_t *this, certificate_t *that)
 	this->get_validity(this, &now, &this_update, NULL);
 	that->get_validity(that, &now, &that_update, NULL);
 	new = this_update > that_update;
-	DBG1("  certificate from %#T is %s - existing certificate from %#T %s",
+	DBG1("  certificate from %T is %s - existing certificate from %T %s",
 				&this_update, FALSE, new ? "newer":"not newer",
 				&that_update, FALSE, new ? "replaced":"retained");
 	return new;
diff --git a/src/libstrongswan/plugins/x509/x509_crl.c b/src/libstrongswan/plugins/x509/x509_crl.c
index 8375d88ef..fd14dfebd 100644
--- a/src/libstrongswan/plugins/x509/x509_crl.c
+++ b/src/libstrongswan/plugins/x509/x509_crl.c
@@ -12,7 +12,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * $Id: x509_crl.c 4576 2008-11-05 08:32:38Z martin $
+ * $Id: x509_crl.c 4936 2009-03-12 18:07:32Z tobias $
  */
 
 #include "x509_crl.h"
@@ -539,7 +539,7 @@ static bool is_newer(private_x509_crl_t *this, crl_t *that)
 		this_cert->get_validity(this_cert, &now, &this_update, NULL);
 		that_cert->get_validity(that_cert, &now, &that_update, NULL);
 		new = this_update > that_update;
-		DBG1("  crl from %#T is %s - existing crl from %#T %s",
+		DBG1("  crl from %T is %s - existing crl from %T %s",
 				&this_update, FALSE, new ? "newer":"not newer",
 				&that_update, FALSE, new ? "replaced":"retained");
 	}
diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_response.c b/src/libstrongswan/plugins/x509/x509_ocsp_response.c
index 01f35864d..6bb59d8e6 100644
--- a/src/libstrongswan/plugins/x509/x509_ocsp_response.c
+++ b/src/libstrongswan/plugins/x509/x509_ocsp_response.c
@@ -1,7 +1,7 @@
 /**
  * Copyright (C) 2008 Martin Willi
  * Copyright (C) 2007 Andreas Steffen
- * Hochschule f�r Technik Rapperswil
+ * Hochschule fuer Technik Rapperswil
  * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -14,7 +14,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * $Id: x509_ocsp_response.c 4317 2008-09-02 11:00:13Z martin $
+ * $Id: x509_ocsp_response.c 4936 2009-03-12 18:07:32Z tobias $
  */
 
 #include "x509_ocsp_response.h"
@@ -806,7 +806,7 @@ static bool is_newer(certificate_t *this, certificate_t *that)
 	this->get_validity(this, &now, &this_update, NULL);
 	that->get_validity(that, &now, &that_update, NULL);
 	new = this_update > that_update;
-	DBG1("  ocsp response from %#T is %s - existing ocsp response from %#T %s",
+	DBG1("  ocsp response from %T is %s - existing ocsp response from %T %s",
 				&this_update, FALSE, new ? "newer":"not newer",
 				&that_update, FALSE, new ? "replaced":"retained");
 	return new;
diff --git a/src/libstrongswan/printf_hook.c b/src/libstrongswan/printf_hook.c
index d0046928f..ceace27da 100644
--- a/src/libstrongswan/printf_hook.c
+++ b/src/libstrongswan/printf_hook.c
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2009 Tobias Brunner
  * Copyright (C) 2006-2008 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
@@ -12,14 +13,23 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * $Id: printf_hook.c 3589 2008-03-13 14:14:44Z martin $
+ * $Id: printf_hook.c 4975 2009-03-19 08:54:39Z martin $
  */
 
 #include "printf_hook.h"
 
 #include <utils.h>
+#include <debug.h>
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
 
 typedef struct private_printf_hook_t private_printf_hook_t;
+typedef struct printf_hook_handler_t printf_hook_handler_t;
+
+#define PRINTF_BUF_LEN 8192
+#define ARGS_MAX 3
 
 /**
  * private data of printf_hook
@@ -32,13 +42,340 @@ struct private_printf_hook_t {
 	printf_hook_t public;
 };
 
+/**
+ * struct with information about a registered handler
+ */
+struct printf_hook_handler_t {
+	
+	/**
+	 * callback function
+	 */
+	printf_hook_function_t hook;
+	
+	/**
+	 * number of arguments
+	 */
+	int numargs;
+	
+	/**
+	 * types of the arguments
+	 */
+	int argtypes[ARGS_MAX];
+
+#ifndef HAVE_PRINTF_HOOKS
+	/**
+	 * name required for Vstr
+	 */
+	char *name;
+#endif
+};
+
+/* A-Z | 6 other chars | a-z */
+#define NUM_HANDLERS 58
+static printf_hook_handler_t *printf_hooks[NUM_HANDLERS];
+
+#define SPEC_TO_INDEX(spec) ((int)(spec) - (int)'A')
+#define IS_VALID_SPEC(spec) (SPEC_TO_INDEX(spec) > -1 && SPEC_TO_INDEX(spec) < NUM_HANDLERS)
+
+#ifdef HAVE_PRINTF_HOOKS
+
+/**
+ * Printf hook print function. This is actually of type "printf_function",
+ * however glibc does it typedef to function, but uclibc to a pointer.
+ * So we redefine it here.
+ */
+static int custom_print(FILE *stream, const struct printf_info *info,
+						const void *const *args)
+{
+	int written;
+	char buf[PRINTF_BUF_LEN];
+	printf_hook_spec_t spec;
+	printf_hook_handler_t *handler = printf_hooks[SPEC_TO_INDEX(info->spec)];
+	
+	spec.hash = info->alt;
+	spec.minus = info->left;
+	spec.width = info->width;
+	
+	written = handler->hook(buf, sizeof(buf), &spec, args);
+	if (written > 0)
+	{
+		ignore_result(fwrite(buf, 1, written, stream));
+	}
+	return written;
+}
+
+/**
+ * Printf hook arginfo function, which is actually of type
+ * "printf_arginfo_function".
+ */
+static int custom_arginfo(const struct printf_info *info, size_t n, int *argtypes)
+{
+	int i;
+	printf_hook_handler_t *handler = printf_hooks[SPEC_TO_INDEX(info->spec)];
+	
+	if (handler->numargs <= n)
+	{
+		for (i = 0; i < handler->numargs; ++i)
+		{
+			argtypes[i] = handler->argtypes[i];
+		}
+	}
+	return handler->numargs;
+}
+
+#else
+
+#include <errno.h>
+#include <unistd.h> /* for STDOUT_FILENO */
+
+/**
+ * Vstr custom format specifier callback function.
+ */
+static int custom_fmt_cb(Vstr_base *base, size_t pos, Vstr_fmt_spec *fmt_spec)
+{
+	int i, written;
+	char buf[PRINTF_BUF_LEN];
+	const void *args[ARGS_MAX];
+	printf_hook_spec_t spec;
+	printf_hook_handler_t *handler = printf_hooks[SPEC_TO_INDEX(fmt_spec->name[0])];
+	
+	for (i = 0; i < handler->numargs; i++)
+	{
+		switch(handler->argtypes[i])
+		{
+			case PRINTF_HOOK_ARGTYPE_INT:
+				args[i] = VSTR_FMT_CB_ARG_PTR(fmt_spec, i);
+				break;
+			case PRINTF_HOOK_ARGTYPE_POINTER:
+				args[i] = &VSTR_FMT_CB_ARG_PTR(fmt_spec, i);
+				break;
+		}
+	}
+	
+	spec.hash = fmt_spec->fmt_hash;
+	spec.minus = fmt_spec->fmt_minus;
+	spec.width = fmt_spec->fmt_field_width;
+	
+	written = handler->hook(buf, sizeof(buf), &spec, args);
+	if (written > 0)
+	{
+		vstr_add_buf(base, pos, buf, written);
+	}
+	return TRUE;
+}
+
+/**
+ * Add a custom format handler to the given Vstr_conf object 
+ */
+static void vstr_fmt_add_handler(Vstr_conf *conf, printf_hook_handler_t *handler)
+{
+	int *at = handler->argtypes;
+	switch(handler->numargs)
+	{
+		case 1:
+			vstr_fmt_add(conf, handler->name, custom_fmt_cb, at[0], VSTR_TYPE_FMT_END);
+			break;
+		case 2:
+			vstr_fmt_add(conf, handler->name, custom_fmt_cb, at[0], at[1], VSTR_TYPE_FMT_END);
+			break;
+		case 3:
+			vstr_fmt_add(conf, handler->name, custom_fmt_cb, at[0], at[1], at[2], VSTR_TYPE_FMT_END);
+			break;
+	}
+}
+
+/**
+ * Management of thread-specific Vstr_conf objects
+ */
+#include <pthread.h>
+
+static pthread_key_t vstr_conf_key;
+static pthread_once_t vstr_conf_key_once = PTHREAD_ONCE_INIT;
+
+static void init_vstr_conf_key(void)
+{
+	pthread_key_create(&vstr_conf_key, (void*)vstr_free_conf);
+}
+
+static Vstr_conf *create_vstr_conf()
+{
+	int i;
+	Vstr_conf *conf = vstr_make_conf();
+	vstr_cntl_conf(conf, VSTR_CNTL_CONF_SET_FMT_CHAR_ESC, '%');
+	vstr_cntl_conf(conf, VSTR_CNTL_CONF_SET_TYPE_GRPALLOC_CACHE,
+						 VSTR_TYPE_CNTL_CONF_GRPALLOC_CSTR);
+	vstr_cntl_conf(conf, VSTR_CNTL_CONF_SET_NUM_BUF_SZ, PRINTF_BUF_LEN);
+	for (i = 0; i < NUM_HANDLERS; ++i)
+	{
+		printf_hook_handler_t *handler = printf_hooks[i];
+		if (handler)
+		{
+			vstr_fmt_add_handler(conf, handler);
+		}
+	}
+	return conf;
+}
+
+static inline Vstr_conf *get_vstr_conf()
+{
+	Vstr_conf *conf;
+	pthread_once(&vstr_conf_key_once, init_vstr_conf_key);
+	conf = (Vstr_conf*)pthread_getspecific(vstr_conf_key);
+	if (!conf)
+	{
+		conf = create_vstr_conf();
+		pthread_setspecific(vstr_conf_key, conf);
+	}
+	return conf;
+}
+
+/**
+ * Wrapper functions for printf and alike
+ */
+int vstr_wrapper_printf(const char *format, ...)
+{
+	int written;
+	va_list args;
+	va_start(args, format);
+	written = vstr_wrapper_vprintf(format, args);
+	va_end(args);
+	return written;
+}
+int vstr_wrapper_fprintf(FILE *stream, const char *format, ...)
+{
+	int written;
+	va_list args;
+	va_start(args, format);
+	written = vstr_wrapper_vfprintf(stream, format, args);
+	va_end(args);
+	return written;
+}
+int vstr_wrapper_sprintf(char *str, const char *format, ...)
+{
+	int written;
+	va_list args;
+	va_start(args, format);
+	written = vstr_wrapper_vsprintf(str, format, args);
+	va_end(args);
+	return written;
+}
+int vstr_wrapper_snprintf(char *str, size_t size, const char *format, ...)
+{
+	int written;
+	va_list args;
+	va_start(args, format);
+	written = vstr_wrapper_vsnprintf(str, size, format, args);
+	va_end(args);
+	return written;
+}
+static inline int vstr_wrapper_vprintf_internal(int fd, const char *format,
+												va_list args)
+{
+	int written;
+	Vstr_conf *conf = get_vstr_conf();
+	Vstr_base *s = vstr_make_base(conf);
+	vstr_add_vfmt(s, 0, format, args);
+	written = s->len;
+	while (s->len)
+	{
+		if (!vstr_sc_write_fd(s, 1, s->len, fd, NULL))
+		{
+			if (errno != EAGAIN && errno != EINTR)
+			{
+				written -= s->len;
+				break;
+			}
+		}
+	}
+	vstr_free_base(s);
+	return written;
+}
+int vstr_wrapper_vprintf(const char *format, va_list args)
+{
+	return vstr_wrapper_vprintf_internal(STDOUT_FILENO, format, args);
+}
+int vstr_wrapper_vfprintf(FILE *stream, const char *format, va_list args)
+{
+	return vstr_wrapper_vprintf_internal(fileno(stream), format, args);
+}
+static inline int vstr_wrapper_vsnprintf_internal(char *str, size_t size,
+												  const char *format,
+												  va_list args)
+{
+	int written;
+	Vstr_conf *conf = get_vstr_conf();
+	Vstr_base *s = vstr_make_base(conf);
+	vstr_add_vfmt(s, 0, format, args);
+	written = s->len;
+	vstr_export_cstr_buf(s, 1, s->len, str, (size > 0) ? size : s->len + 1);
+	vstr_free_base(s);
+	return written;
+}
+int vstr_wrapper_vsprintf(char *str, const char *format, va_list args)
+{
+	return vstr_wrapper_vsnprintf_internal(str, 0, format, args);
+}
+int vstr_wrapper_vsnprintf(char *str, size_t size, const char *format,
+						   va_list args)
+{
+	return (size > 0) ? vstr_wrapper_vsnprintf_internal(str, size, format, args) : 0;
+}
+
+#endif
+
 /**
  * Implementation of printf_hook_t.add_handler.
  */
-static void add_handler(private_printf_hook_t *this, char spec, 
-						printf_hook_functions_t hook)
+static void add_handler(private_printf_hook_t *this, char spec,
+						printf_hook_function_t hook, ...)
 {
-	register_printf_function(spec, hook.print, hook.arginfo);
+	int i = -1;
+	printf_hook_handler_t *handler;
+	printf_hook_argtype_t argtype;
+	va_list args;
+	
+	if (!IS_VALID_SPEC(spec))
+	{
+		DBG1("'%c' is not a valid printf hook specifier, not registered!", spec);
+		return;
+	}
+	
+	handler = malloc_thing(printf_hook_handler_t); 
+	handler->hook = hook;
+	
+	va_start(args, hook);
+	while ((argtype = va_arg(args, printf_hook_argtype_t)) != PRINTF_HOOK_ARGTYPE_END)
+	{
+		if (++i >= ARGS_MAX)
+		{
+			DBG1("Too many arguments for printf hook with specifier '%c', not registered!", spec);
+			va_end(args);
+			free(handler);
+			return;
+		}
+		handler->argtypes[i] = argtype;
+	}
+	va_end(args);
+	
+	handler->numargs = i + 1;
+	
+	if (handler->numargs > 0)
+	{
+#ifdef HAVE_PRINTF_HOOKS
+		register_printf_function(spec, custom_print, custom_arginfo);
+#else
+		Vstr_conf *conf = get_vstr_conf();
+		handler->name = malloc(2);
+		handler->name[0] = spec;
+		handler->name[1] = '\0';
+		vstr_fmt_add_handler(conf, handler);
+#endif
+		printf_hooks[SPEC_TO_INDEX(spec)] = handler;
+	}
+	else
+	{
+		free(handler);
+	}
 }
 
 /**
@@ -46,6 +383,30 @@ static void add_handler(private_printf_hook_t *this, char spec,
  */
 static void destroy(private_printf_hook_t *this)
 {
+	int i;
+#ifndef HAVE_PRINTF_HOOKS
+	Vstr_conf *conf = get_vstr_conf();
+#endif
+	
+	for (i = 0; i < NUM_HANDLERS; ++i)
+	{
+		printf_hook_handler_t *handler = printf_hooks[i];
+		if (handler)
+		{
+#ifndef HAVE_PRINTF_HOOKS
+			vstr_fmt_del(conf, handler->name);
+			free(handler->name);
+#endif
+			free(handler);
+		}
+	}
+	
+#ifndef HAVE_PRINTF_HOOKS
+	/* freeing the Vstr_conf of the main thread */
+	pthread_key_delete(vstr_conf_key);
+	vstr_free_conf(conf);
+	vstr_exit();
+#endif
 	free(this);
 }
 
@@ -56,9 +417,19 @@ printf_hook_t *printf_hook_create()
 {
 	private_printf_hook_t *this = malloc_thing(private_printf_hook_t);
 	
-	this->public.add_handler = (void(*)(printf_hook_t*, char, printf_hook_functions_t))add_handler;
+	this->public.add_handler = (void(*)(printf_hook_t*, char, printf_hook_function_t, ...))add_handler;
 	this->public.destroy = (void(*)(printf_hook_t*))destroy;
 	
+	memset(printf_hooks, 0, sizeof(printf_hooks));
+	
+#ifndef HAVE_PRINTF_HOOKS
+	if (!vstr_init())
+	{
+		DBG1("failed to initialize Vstr library!");
+		free(this);
+		return NULL;
+	}
+#endif
 	
 	return &this->public;
 }
diff --git a/src/libstrongswan/printf_hook.h b/src/libstrongswan/printf_hook.h
index 416db1a7f..d2edbdd22 100644
--- a/src/libstrongswan/printf_hook.h
+++ b/src/libstrongswan/printf_hook.h
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2009 Tobias Brunner
  * Copyright (C) 2006-2008 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
@@ -12,7 +13,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * $Id: printf_hook.h 3749 2008-04-04 11:37:19Z martin $
+ * $Id: printf_hook.h 4936 2009-03-12 18:07:32Z tobias $
  */
 
 /**
@@ -24,30 +25,103 @@
 #define PRINTF_HOOK_H_
 
 typedef struct printf_hook_t printf_hook_t;
-typedef struct printf_hook_functions_t printf_hook_functions_t;
+typedef struct printf_hook_spec_t printf_hook_spec_t;
+typedef enum printf_hook_argtype_t printf_hook_argtype_t;
+
+#ifdef HAVE_PRINTF_HOOKS
 
 #include <printf.h>
 
+enum printf_hook_argtype_t {
+	PRINTF_HOOK_ARGTYPE_END = PA_LAST,
+	PRINTF_HOOK_ARGTYPE_INT = PA_INT,
+	PRINTF_HOOK_ARGTYPE_POINTER = PA_POINTER,
+};
+
+#else
+
+#include <vstr.h>
+
+enum printf_hook_argtype_t {
+	PRINTF_HOOK_ARGTYPE_END = VSTR_TYPE_FMT_END,
+	PRINTF_HOOK_ARGTYPE_INT = VSTR_TYPE_FMT_INT,
+	PRINTF_HOOK_ARGTYPE_POINTER = VSTR_TYPE_FMT_PTR_VOID,
+};
+
 /**
- * Printf hook function set.
- *
- * A printf hook has two functions, one to print the string, one to read
- * in the number of arguments. See <printf.h>.
+ * Redefining printf and alike
+ */
+#include <stdio.h>
+#include <stdarg.h>
+
+int vstr_wrapper_printf(const char *format, ...);
+int vstr_wrapper_fprintf(FILE *stream, const char *format, ...);
+int vstr_wrapper_sprintf(char *str, const char *format, ...);
+int vstr_wrapper_snprintf(char *str, size_t size, const char *format, ...);
+
+int vstr_wrapper_vprintf(const char *format, va_list ap);
+int vstr_wrapper_vfprintf(FILE *stream, const char *format, va_list ap);
+int vstr_wrapper_vsprintf(char *str, const char *format, va_list ap);
+int vstr_wrapper_vsnprintf(char *str, size_t size, const char *format, va_list ap);
+
+#define printf vstr_wrapper_printf
+#define fprintf vstr_wrapper_fprintf
+#define sprintf vstr_wrapper_sprintf
+#define snprintf vstr_wrapper_snprintf
+
+#define vprintf vstr_wrapper_vprintf
+#define vfprintf vstr_wrapper_vfprintf
+#define vsprintf vstr_wrapper_vsprintf
+#define vsnprintf vstr_wrapper_vsnprintf
+
+#endif
+
+/**
+ * Callback function type for printf hooks.
+ * 
+ * @param dst		destination buffer
+ * @param len		length of the buffer
+ * @param spec		format specifier
+ * @param args		arguments array
+ * @return 			number of characters written
+ */
+typedef int (*printf_hook_function_t)(char *dst, size_t len,
+									  printf_hook_spec_t *spec,
+									  const void *const *args);
+
+/**
+ * Helper macro to be used in printf hook callbacks.
+ * buf and buflen get modified.
  */
-struct printf_hook_functions_t {
+#define print_in_hook(buf, buflen, fmt, ...) ({\
+	int _written = snprintf(buf, buflen, fmt, ##__VA_ARGS__);\
+	if (_written < 0 || _written >= buflen)\
+	{\
+		_written = buflen - 1;\
+	}\
+	buf += _written;\
+	buflen -= _written;\
+	_written;\
+})
 
+/**
+ * Properties of the format specifier
+ */
+struct printf_hook_spec_t {
+	/**
+	 * TRUE if a '#' was used in the format specifier
+	 */
+	int hash;
+	
 	/**
-	 * Printf hook print function. This is actually of type "printf_function",
-	 * however glibc does it typedef to function, but uclibc to a pointer.
-	 * So we redefine it here.
+	 * TRUE if a '-' was used in the format specifier
 	 */
-	int (*print)(FILE *, const struct printf_info *info, const void *const *args);
+	int minus;
 	
 	/**
-	 * Printf hook arginfo function, which is actually of type
-	 * "printf_arginfo_function".
+	 * The width as given in the format specifier.
 	 */
-	int (*arginfo)(const struct printf_info *info, size_t n, int *argtypes);
+	int width;
 };
 
 /**
@@ -59,10 +133,11 @@ struct printf_hook_t {
 	 * Register a printf handler.
 	 *
 	 * @param spec		printf hook format character
-	 * @param hook		hook functions
+	 * @param hook		hook function
+	 * @param ...		list of PRINTF_HOOK_ARGTYPE_*, MUST end with PRINTF_HOOK_ARGTYPE_END
 	 */
 	void (*add_handler)(printf_hook_t *this, char spec,
-						printf_hook_functions_t hook);
+						printf_hook_function_t hook, ...);
 	
 	/**
      * Destroy a printf_hook instance.
diff --git a/src/libstrongswan/utils.c b/src/libstrongswan/utils.c
index 4e6a09c4f..be0e8e9e5 100644
--- a/src/libstrongswan/utils.c
+++ b/src/libstrongswan/utils.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2008-2009 Tobias Brunner
  * Copyright (C) 2005-2008 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
@@ -13,7 +13,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * $Id: utils.c 4742 2008-12-03 09:45:58Z tobias $
+ * $Id: utils.c 4936 2009-03-12 18:07:32Z tobias $
  */
 
 #include "utils.h"
@@ -187,27 +187,23 @@ bool ref_put(refcount_t *ref)
 #endif /* HAVE_GCC_ATOMIC_OPERATIONS */
 
 /**
- * output handler in printf() for time_t
+ * Described in header.
  */
-static int time_print(FILE *stream, const struct printf_info *info,
-					  const void *const *args)
+int time_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
+					 const void *const *args)
 {
 	static const char* months[] = {
 		"Jan", "Feb", "Mar", "Apr", "May", "Jun",
 		"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
 	};
 	time_t *time = *((time_t**)(args[0]));
-	bool utc = TRUE;
+	bool utc = *((bool*)(args[1]));;
 	struct tm t;
 	
-	if (info->alt)
-	{
-		utc = *((bool*)(args[1]));
-	}
 	if (time == UNDEFINED_TIME)
 	{
-		return fprintf(stream, "--- -- --:--:--%s----",
-					   info->alt ? " UTC " : " ");
+		return print_in_hook(dst, len, "--- -- --:--:--%s----",
+							 utc ? " UTC " : " ");
 	}
 	if (utc)
 	{
@@ -217,54 +213,22 @@ static int time_print(FILE *stream, const struct printf_info *info,
 	{
 		localtime_r(time, &t);
 	}
-	return fprintf(stream, "%s %02d %02d:%02d:%02d%s%04d",
-				   months[t.tm_mon], t.tm_mday, t.tm_hour, t.tm_min,
-				   t.tm_sec, utc ? " UTC " : " ", t.tm_year + 1900);
-}
-
-/**
- * arginfo handler for printf() time
- */
-static int time_arginfo(const struct printf_info *info, size_t n, int *argtypes)
-{
-	if (info->alt)
-	{
-		if (n > 1)
-		{
-			argtypes[0] = PA_POINTER;
-			argtypes[1] = PA_INT;
-		}
-		return 2;
-	}
-	
-	if (n > 0)
-	{
-		argtypes[0] = PA_POINTER;
-	}
-	return 1;
+	return print_in_hook(dst, len, "%s %02d %02d:%02d:%02d%s%04d",
+						 months[t.tm_mon], t.tm_mday, t.tm_hour, t.tm_min,
+						 t.tm_sec, utc ? " UTC " : " ", t.tm_year + 1900);
 }
 
 /**
- * output handler in printf() for time deltas
+ * Described in header.
  */
-static int time_delta_print(FILE *stream, const struct printf_info *info,
-							const void *const *args)
+int time_delta_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
+						   const void *const *args)
 {
 	char* unit = "second";
-	time_t *arg1, *arg2;
-	time_t delta;
+	time_t *arg1 = *((time_t**)(args[0]));
+	time_t *arg2 = *((time_t**)(args[1]));
+	time_t delta = abs(*arg1 - *arg2);
 	
-	arg1 = *((time_t**)(args[0]));
-	if (info->alt)
-	{
-		arg2 = *((time_t**)(args[1]));
-		delta = abs(*arg1 - *arg2);
-	}
-	else
-	{
-		delta = *arg1;
-	}
-
 	if (delta > 2 * 60 * 60 * 24)
 	{
 		delta /= 60 * 60 * 24;
@@ -280,29 +244,7 @@ static int time_delta_print(FILE *stream, const struct printf_info *info,
 		delta /= 60;
 		unit = "minute";
 	}
-	return fprintf(stream, "%d %s%s", delta, unit, (delta == 1)? "":"s");
-}
-
-/**
- * arginfo handler for printf() time deltas
- */
-int time_delta_arginfo(const struct printf_info *info, size_t n, int *argtypes)
-{
-	if (info->alt)
-	{
-		if (n > 1)
-		{
-			argtypes[0] = PA_POINTER;
-			argtypes[1] = PA_POINTER;
-		}
-		return 2;
-	}
-	
-	if (n > 0)
-	{
-		argtypes[0] = PA_POINTER;
-	}
-	return 1;
+	return print_in_hook(dst, len, "%d %s%s", delta, unit, (delta == 1)? "":"s");
 }
 
 /**
@@ -313,10 +255,10 @@ int time_delta_arginfo(const struct printf_info *info, size_t n, int *argtypes)
 static char hexdig_upper[] = "0123456789ABCDEF";
 
 /**
- * output handler in printf() for mem ranges
+ * Described in header.
  */
-static int mem_print(FILE *stream, const struct printf_info *info,
-					 const void *const *args)
+int mem_printf_hook(char *dst, size_t dstlen,
+					printf_hook_spec_t *spec, const void *const *args)
 {
 	char *bytes = *((void**)(args[0]));
 	int len = *((size_t*)(args[1]));
@@ -330,7 +272,7 @@ static int mem_print(FILE *stream, const struct printf_info *info,
 	int i = 0;
 	int written = 0;
 	
-	written += fprintf(stream, "=> %d bytes @ %p", len, bytes);
+	written += print_in_hook(dst, dstlen, "=> %d bytes @ %p", len, bytes);
 	
 	while (bytes_pos < bytes_roof)
 	{
@@ -343,7 +285,6 @@ static int mem_print(FILE *stream, const struct printf_info *info,
 		if (++bytes_pos == bytes_roof || i == BYTES_PER_LINE) 
 		{
 			int padding = 3 * (BYTES_PER_LINE - i);
-			int written;
 			
 			while (padding--)
 			{
@@ -352,9 +293,8 @@ static int mem_print(FILE *stream, const struct printf_info *info,
 			*buffer_pos++ = '\0';
 			ascii_buffer[i] = '\0';
 			
-			written += fprintf(stream, "\n%4d: %s  %s",
-							   line_start, buffer, ascii_buffer);
-
+			written += print_in_hook(dst, dstlen, "\n%4d: %s  %s",
+								     line_start, buffer, ascii_buffer);
 			
 			buffer_pos = buffer;
 			line_start += BYTES_PER_LINE;
@@ -367,47 +307,3 @@ static int mem_print(FILE *stream, const struct printf_info *info,
 	}
 	return written;
 }
-
-/**
- * arginfo handler for printf() mem ranges
- */
-int mem_arginfo(const struct printf_info *info, size_t n, int *argtypes)
-{
-	if (n > 1)
-	{
-		argtypes[0] = PA_POINTER;
-		argtypes[1] = PA_INT;
-	}
-	return 2;
-}
-
-/**
- * return printf hook functions for a time
- */
-printf_hook_functions_t time_get_printf_hooks()
-{
-	printf_hook_functions_t hooks = {time_print, time_arginfo};
-	
-	return hooks;
-}
-
-/**
- * return printf hook functions for a time delta
- */
-printf_hook_functions_t time_delta_get_printf_hooks()
-{
-	printf_hook_functions_t hooks = {time_delta_print, time_delta_arginfo};
-	
-	return hooks;
-}
-
-/**
- * return printf hook functions for mem ranges
- */
-printf_hook_functions_t mem_get_printf_hooks()
-{
-	printf_hook_functions_t hooks = {mem_print, mem_arginfo};
-	
-	return hooks;
-}
-
diff --git a/src/libstrongswan/utils.h b/src/libstrongswan/utils.h
index b26a17b01..01d01576e 100644
--- a/src/libstrongswan/utils.h
+++ b/src/libstrongswan/utils.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2008-2009 Tobias Brunner
  * Copyright (C) 2008 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
@@ -13,7 +13,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * $Id: utils.h 4742 2008-12-03 09:45:58Z tobias $
+ * $Id: utils.h 4936 2009-03-12 18:07:32Z tobias $
  */
 
 /**
@@ -285,31 +285,30 @@ bool ref_put(refcount_t *ref);
 #endif /* HAVE_GCC_ATOMIC_OPERATIONS */
 
 /**
- * Get printf hooks for time.
+ * printf hook for time_t.
  *
  * Arguments are: 
- *    time_t* time
- * Arguments using #-specificer
  *    time_t* time, bool utc
  */
-printf_hook_functions_t time_get_printf_hooks();
+int time_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
+					 const void *const *args);
 
 /**
- * Get printf hooks for time deltas.
+ * printf hook for time_t deltas.
  *
  * Arguments are: 
- *    time_t* delta
- * Arguments using #-specificer
  *    time_t* begin, time_t* end
  */
-printf_hook_functions_t time_delta_get_printf_hooks();
+int time_delta_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
+						   const void *const *args);
 
 /**
- * Get printf hooks for time deltas.
+ * printf hook for memory areas.
  *
  * Arguments are: 
  *    u_char *ptr, int len
  */
-printf_hook_functions_t mem_get_printf_hooks();
+int mem_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
+					const void *const *args);
 
 #endif /* UTILS_H_ @}*/
diff --git a/src/libstrongswan/utils/hashtable.c b/src/libstrongswan/utils/hashtable.c
index 892d08b6c..27a7a66c1 100644
--- a/src/libstrongswan/utils/hashtable.c
+++ b/src/libstrongswan/utils/hashtable.c
@@ -12,7 +12,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * $Id: hashtable.c 4812 2008-12-17 09:56:05Z tobias $
+ * $Id: hashtable.c 4936 2009-03-12 18:07:32Z tobias $
  */
 
 #include <utils/linked_list.h>
@@ -282,7 +282,7 @@ static void *get(private_hashtable_t *this, void *key)
 /**
  * Implementation of hashtable_t.remove
  */
-static void *remove(private_hashtable_t *this, void *key)
+static void *remove_(private_hashtable_t *this, void *key)
 {
 	void *value = NULL;
 	linked_list_t *list;
@@ -414,7 +414,7 @@ hashtable_t *hashtable_create(hashtable_hash_t hash, hashtable_equals_t equals,
 
 	this->public.put = (void*(*)(hashtable_t*,void*,void*))put;
 	this->public.get = (void*(*)(hashtable_t*,void*))get; 
-	this->public.remove = (void*(*)(hashtable_t*,void*))remove;
+	this->public.remove = (void*(*)(hashtable_t*,void*))remove_;
 	this->public.get_count = (u_int(*)(hashtable_t*))get_count;
 	this->public.create_enumerator = (enumerator_t*(*)(hashtable_t*))create_enumerator;
 	this->public.destroy = (void(*)(hashtable_t*))destroy;
diff --git a/src/libstrongswan/utils/host.c b/src/libstrongswan/utils/host.c
index 719c5a529..a40c42c49 100644
--- a/src/libstrongswan/utils/host.c
+++ b/src/libstrongswan/utils/host.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006-2007 Tobias Brunner
+ * Copyright (C) 2006-2009 Tobias Brunner
  * Copyright (C) 2006 Daniel Roethlisberger
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -15,13 +15,12 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * $Id: host.c 4856 2009-02-05 22:13:48Z andreas $
+ * $Id: host.c 4977 2009-03-19 09:16:03Z martin $
  */
 
 #define _GNU_SOURCE
 #include <netdb.h>
 #include <string.h>
-#include <printf.h>
 
 #include "host.h"
 
@@ -106,10 +105,10 @@ static bool is_anyaddr(private_host_t *this)
 }
 
 /**
- * output handler in printf()
+ * Described in header.
  */
-static int print(FILE *stream, const struct printf_info *info,
-				 const void *const *args)
+int host_printf_hook(char *dst, size_t dstlen, printf_hook_spec_t *spec,
+					 const void *const *args)
 {
 	private_host_t *this = *((private_host_t**)(args[0]));
 	char buffer[INET6_ADDRSTRLEN + 16];
@@ -120,7 +119,8 @@ static int print(FILE *stream, const struct printf_info *info,
 	}
 	else if (is_anyaddr(this))
 	{
-		snprintf(buffer, sizeof(buffer), "%%any");
+		snprintf(buffer, sizeof(buffer), "%%any%s",
+				 this->address.sa_family == AF_INET6 ? "6" : "");
 	}
 	else
 	{
@@ -145,7 +145,7 @@ static int print(FILE *stream, const struct printf_info *info,
 					snprintf(buffer, sizeof(buffer),
 							 "(address conversion failed)");
 				}
-				else if (info->alt)
+				else if (spec->hash)
 				{
 					len = strlen(buffer);
 					snprintf(buffer + len, sizeof(buffer) - len,
@@ -157,34 +157,11 @@ static int print(FILE *stream, const struct printf_info *info,
 				break;
 		}
 	}
-	if (info->left)
+	if (spec->minus)
 	{
-		return fprintf(stream, "%-*s", info->width, buffer);
+		return print_in_hook(dst, dstlen, "%-*s", spec->width, buffer);
 	}
-	return fprintf(stream, "%*s", info->width, buffer);
-}
-
-
-/**
- * arginfo handler for printf() hosts
- */
-int arginfo(const struct printf_info *info, size_t n, int *argtypes)
-{
-	if (n > 0)
-	{
-		argtypes[0] = PA_POINTER;
-	}
-	return 1;
-}
-
-/**
- * return printf hook functions for a host
- */
-printf_hook_functions_t host_get_printf_hooks()
-{
-	printf_hook_functions_t hooks = {print, arginfo};
-	
-	return hooks;
+	return print_in_hook(dst, dstlen, "%*s", spec->width, buffer);
 }
 
 /**
@@ -387,6 +364,18 @@ static private_host_t *host_create_empty(void)
 	return this;
 }
 
+/*
+ * Create a %any host with port
+ */
+static host_t *host_create_any_port(int family, u_int16_t port)
+{
+	host_t *this;
+	
+	this = host_create_any(family);
+	this->set_port(this, port);
+	return this;
+}
+
 /*
  * Described in header.
  */
@@ -396,7 +385,11 @@ host_t *host_create_from_string(char *string, u_int16_t port)
 	
 	if (streq(string, "%any"))
 	{
-		return host_create_any(AF_INET);
+		return host_create_any_port(AF_INET, port);
+	}
+	if (streq(string, "%any6"))
+	{
+		return host_create_any_port(AF_INET6, port);
 	}
 	
 	this = host_create_empty();
@@ -451,11 +444,11 @@ host_t *host_create_from_dns(char *string, int af, u_int16_t port)
 
 	if (streq(string, "%any"))
 	{
-		return host_create_any(af ? af : AF_INET);
+		return host_create_any_port(af ? af : AF_INET, port);
 	}
 	if (streq(string, "%any6"))
 	{
-		return host_create_any(af ? af : AF_INET6);
+		return host_create_any_port(af ? af : AF_INET6, port);
 	}
 	else if (strchr(string, ':'))
 	{
diff --git a/src/libstrongswan/utils/host.h b/src/libstrongswan/utils/host.h
index 667cc6bcc..5f00872b8 100644
--- a/src/libstrongswan/utils/host.h
+++ b/src/libstrongswan/utils/host.h
@@ -1,7 +1,7 @@
 /*
- * Copyright (C) 2005-2008 Martin Willi
- * Copyright (C) 2006-2007 Tobias Brunner
+ * Copyright (C) 2006-2009 Tobias Brunner
  * Copyright (C) 2006 Daniel Roethlisberger
+ * Copyright (C) 2005-2008 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
  *
@@ -198,12 +198,13 @@ host_t *host_create_from_sockaddr(sockaddr_t *sockaddr);
 host_t *host_create_any(int family);
 
 /**
- * Get printf hooks for a host.
+ * printf hook function for host_t.
  *
  * Arguments are: 
  *    host_t *host
  * Use #-modifier to include port number
  */
-printf_hook_functions_t host_get_printf_hooks();
+int host_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
+					 const void *const *args);
 
 #endif /* HOST_H_ @}*/
diff --git a/src/libstrongswan/utils/identification.c b/src/libstrongswan/utils/identification.c
index 529e62509..ff97f3610 100644
--- a/src/libstrongswan/utils/identification.c
+++ b/src/libstrongswan/utils/identification.c
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2009 Tobias Brunner
  * Copyright (C) 2005-2008 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
@@ -13,7 +14,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * $Id: identification.c 4856 2009-02-05 22:13:48Z andreas $
+ * $Id: identification.c 4936 2009-03-12 18:07:32Z tobias $
  */
 
 #define _GNU_SOURCE
@@ -23,7 +24,6 @@
 #include <string.h>
 #include <stdio.h>
 #include <ctype.h>
-#include <printf.h>
 
 #include "identification.h"
 
@@ -879,10 +879,10 @@ static id_match_t matches_dn(private_identification_t *this,
 }
 
 /**
- * output handler in printf()
+ * Described in header.
  */
-static int print(FILE *stream, const struct printf_info *info,
-						 const void *const *args)
+int identification_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
+							   const void *const *args)
 {
 	private_identification_t *this = *((private_identification_t**)(args[0]));
 	char buf[BUF_LEN];
@@ -890,7 +890,7 @@ static int print(FILE *stream, const struct printf_info *info,
 	
 	if (this == NULL)
 	{
-		return fprintf(stream, "%*s", info->width, "(null)");
+		return print_in_hook(dst, len, "%*s", spec->width, "(null)");
 	}
 	
 	switch (this->type)
@@ -940,33 +940,11 @@ static int print(FILE *stream, const struct printf_info *info,
 			snprintf(buf, sizeof(buf), "(unknown ID type: %d)", this->type);
 			break;
 	}
-	if (info->left)
-	{
-		return fprintf(stream, "%-*s", info->width, buf);
-	}
-	return fprintf(stream, "%*s", info->width, buf);
-}
-
-/**
- * arginfo handler
- */
-static int arginfo(const struct printf_info *info, size_t n, int *argtypes)
-{
-	if (n > 0)
+	if (spec->minus)
 	{
-		argtypes[0] = PA_POINTER;
+		return print_in_hook(dst, len, "%-*s", spec->width, buf);
 	}
-	return 1;
-}
-
-/**
- * Get printf hook functions
- */
-printf_hook_functions_t identification_get_printf_hooks()
-{
-	printf_hook_functions_t hook = {print, arginfo};
-	
-	return hook;
+	return print_in_hook(dst, len, "%*s", spec->width, buf);
 }
 
 /**
diff --git a/src/libstrongswan/utils/identification.h b/src/libstrongswan/utils/identification.h
index 3b895961d..070984490 100644
--- a/src/libstrongswan/utils/identification.h
+++ b/src/libstrongswan/utils/identification.h
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2009 Tobias Brunner
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
@@ -13,7 +14,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * $Id: identification.h 4344 2008-09-17 02:17:01Z andreas $
+ * $Id: identification.h 4936 2009-03-12 18:07:32Z tobias $
  */
  
 /**
@@ -274,10 +275,12 @@ identification_t * identification_create_from_string(char *string);
 identification_t * identification_create_from_encoding(id_type_t type, chunk_t encoded);
 
 /**
- * Get the printf hook functions.
- * 
- * @return			printf hook functions
+ * printf hook function for identification_t.
+ *
+ * Arguments are: 
+ *    identification_t *identification
  */
-printf_hook_functions_t identification_get_printf_hooks();
+int identification_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
+							   const void *const *args);
 
 #endif /* IDENTIFICATION_H_ @} */
diff --git a/src/libstrongswan/utils/leak_detective.c b/src/libstrongswan/utils/leak_detective.c
index 4c56c9596..0e0866fec 100644
--- a/src/libstrongswan/utils/leak_detective.c
+++ b/src/libstrongswan/utils/leak_detective.c
@@ -12,7 +12,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * $Id: leak_detective.c 4796 2008-12-12 09:10:52Z martin $
+ * $Id: leak_detective.c 4936 2009-03-12 18:07:32Z tobias $
  */
 	
 #define _GNU_SOURCE
@@ -29,7 +29,6 @@
 #include <syslog.h>
 #include <pthread.h>
 #include <netdb.h>
-#include <printf.h>
 #include <locale.h>
 
 #include "leak_detective.h"
diff --git a/src/libstrongswan/utils/linked_list.c b/src/libstrongswan/utils/linked_list.c
index 068d13f99..bfe30b0df 100644
--- a/src/libstrongswan/utils/linked_list.c
+++ b/src/libstrongswan/utils/linked_list.c
@@ -14,7 +14,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * $Id: linked_list.c 4580 2008-11-05 11:55:17Z martin $
+ * $Id: linked_list.c 4936 2009-03-12 18:07:32Z tobias $
  */
 
 #include <stdlib.h>
@@ -224,7 +224,7 @@ static void iterator_reset(private_iterator_t *this)
 /**
  * Implementation of iterator_t.remove.
  */
-static status_t remove_(private_iterator_t *this)
+static status_t iterator_remove(private_iterator_t *this)
 {
 	element_t *new_current;
 
@@ -514,8 +514,8 @@ static status_t remove_last(private_linked_list_t *this, void **item)
 /**
  * Implementation of linked_list_t.remove.
  */
-static int remove(private_linked_list_t *this, void *item,
-				  bool (*compare)(void *,void*))
+static int remove_(private_linked_list_t *this, void *item,
+				   bool (*compare)(void *,void*))
 {
 	element_t *current = this->first;
 	int removed = 0;
@@ -727,7 +727,7 @@ static iterator_t *create_iterator(private_linked_list_t *linked_list, bool forw
 	this->public.insert_before = (void (*) (iterator_t*, void *item)) insert_before;
 	this->public.insert_after = (void (*) (iterator_t*, void *item)) insert_after;
 	this->public.replace = (status_t (*) (iterator_t*, void **, void *)) replace;
-	this->public.remove = (status_t (*) (iterator_t*)) remove_;
+	this->public.remove = (status_t (*) (iterator_t*)) iterator_remove;
 	this->public.reset = (void (*) (iterator_t*)) iterator_reset;
 	this->public.destroy = (void (*) (iterator_t*)) iterator_destroy;
 	
@@ -756,7 +756,7 @@ linked_list_t *linked_list_create()
 	this->public.insert_last = (void (*) (linked_list_t *, void *item))insert_last;
 	this->public.remove_first = (status_t (*) (linked_list_t *, void **item))remove_first;
 	this->public.remove_last = (status_t (*) (linked_list_t *, void **item))remove_last;
-	this->public.remove = (int(*)(linked_list_t*, void *item, bool (*compare)(void *,void*)))remove;
+	this->public.remove = (int(*)(linked_list_t*, void *item, bool (*compare)(void *,void*)))remove_;
 	this->public.remove_at = (void(*)(linked_list_t*, enumerator_t *enumerator))remove_at;
 	this->public.invoke_offset = (void (*)(linked_list_t*,size_t,...))invoke_offset;
 	this->public.invoke_function = (void (*)(linked_list_t*,linked_list_invoke_t,...))invoke_function;
diff --git a/src/pluto/asn1.c b/src/pluto/asn1.c
index 7436d4d1a..bd27f6a78 100644
--- a/src/pluto/asn1.c
+++ b/src/pluto/asn1.c
@@ -11,7 +11,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * RCSID $Id: asn1.c 3451 2008-02-05 19:27:05Z andreas $
+ * RCSID $Id: asn1.c 4942 2009-03-13 20:22:24Z andreas $
  */
 
 #include <stdlib.h>
@@ -75,17 +75,19 @@ const chunk_t ASN1_rsaEncryption_id = strchunk(ASN1_rsaEncryption_id_str);
 const chunk_t ASN1_md5WithRSA_id = strchunk(ASN1_md5WithRSA_id_str);
 const chunk_t ASN1_sha1WithRSA_id = strchunk(ASN1_sha1WithRSA_id_str);
 
-/* ASN.1 definiton of an algorithmIdentifier */
+/* ASN.1 definition of an algorithmIdentifier */
 
 static const asn1Object_t algorithmIdentifierObjects[] = {
-  { 0, "algorithmIdentifier",	ASN1_SEQUENCE,	   ASN1_NONE }, /* 0 */
-  { 1,   "algorithm",		ASN1_OID,	   ASN1_BODY }, /* 1 */
-  { 1,   "parameters",		ASN1_EOC,	   ASN1_RAW  }  /* 2 */
+  { 0, "algorithmIdentifier",	ASN1_SEQUENCE,	ASN1_NONE }, /* 0 */
+  { 1,   "algorithm",		ASN1_OID,	ASN1_BODY }, /* 1 */
+  { 1,   "parameters",		ASN1_EOC,	ASN1_OPT |
+						ASN1_RAW  }, /* 2 */
+  { 1,   "end opt",		ASN1_EOC,	ASN1_END  }  /* 3 */
 };
 
 #define ALGORITHM_ID_ALG		1
 #define ALGORITHM_ID_PARAMETERS		2
-#define ALGORITHM_ID_ROOF		3
+#define ALGORITHM_ID_ROOF		4
 
 /*
  * return the ASN.1 encoded algorithm identifier
@@ -723,7 +725,7 @@ parse_algorithmIdentifier(chunk_t blob, int level0, chunk_t *parameters)
     while (objectID < ALGORITHM_ID_ROOF)
     {
 	if (!extract_object(algorithmIdentifierObjects, &objectID, &object, &level, &ctx))
-	     return OID_UNKNOWN;
+	     return alg;
 
 	switch (objectID)
 	{
diff --git a/src/pluto/connections.c b/src/pluto/connections.c
index 13a004794..cd118cb34 100644
--- a/src/pluto/connections.c
+++ b/src/pluto/connections.c
@@ -11,7 +11,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * RCSID $Id: connections.c 3686 2008-03-28 11:48:14Z martin $
+ * RCSID $Id: connections.c 4924 2009-03-10 21:13:18Z andreas $
  */
 
 #include <string.h>
@@ -2995,6 +2995,8 @@ terminate_connection(const char *nm)
 	    c->policy &= ~POLICY_UP;
 	    flush_pending_by_connection(c);
 	    delete_states_by_connection(c, FALSE);
+	    if (c->kind == CK_INSTANCE)
+		delete_connection(c, FALSE);
 	    reset_cur_connection();
 	}
 	c = n;
diff --git a/src/pluto/ipsec_doi.c b/src/pluto/ipsec_doi.c
index 88536e6d6..52b59be31 100644
--- a/src/pluto/ipsec_doi.c
+++ b/src/pluto/ipsec_doi.c
@@ -12,7 +12,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * RCSID $Id: ipsec_doi.c 3686 2008-03-28 11:48:14Z martin $
+ * RCSID $Id: ipsec_doi.c 4924 2009-03-10 21:13:18Z andreas $
  */
 
 #include <stdio.h>
@@ -5592,6 +5592,7 @@ dpd_timeout(struct state *st)
     struct state *newest_phase1_st;
     struct connection *c = st->st_connection;
     int action = st->st_connection->dpd_action;
+    char cname[BUF_LEN];
 
     passert(action == DPD_ACTION_HOLD
 	 || action == DPD_ACTION_CLEAR
@@ -5622,20 +5623,30 @@ dpd_timeout(struct state *st)
 	 * leak traffic.  Also, being in %trap means new packets will
 	 * force an initiation of the conn again.
 	 */
-	loglog(RC_LOG_SERIOUS, "DPD: Putting connection into %%trap");
+	loglog(RC_LOG_SERIOUS, "DPD: Putting connection \"%s\" into %%trap", c->name);
+	if (c->kind == CK_INSTANCE)
+	    delete_connection(c, TRUE);
 	break;
     case DPD_ACTION_CLEAR:
 	/* dpdaction=clear - Wipe the SA & eroute - everything */
-        loglog(RC_LOG_SERIOUS, "DPD: Clearing connection");
+        loglog(RC_LOG_SERIOUS, "DPD: Clearing connection \"%s\"", c->name);
         unroute_connection(c);
+	if (c->kind == CK_INSTANCE)
+	    delete_connection(c, TRUE);
 	break;
     case DPD_ACTION_RESTART:
 	/* dpdaction=restart - Restart connection,
 	 * except if roadwarrior connection
 	 */
-	loglog(RC_LOG_SERIOUS, "DPD: Restarting connection");
+	loglog(RC_LOG_SERIOUS, "DPD: Restarting connection \"%s\"", c->name);
 	unroute_connection(c);
-	initiate_connection(c->name, NULL_FD);
+
+	/* caching the connection name before deletion */
+	strncpy(cname, c->name, BUF_LEN);
+
+	if (c->kind == CK_INSTANCE)
+	    delete_connection(c, TRUE);
+	initiate_connection(cname, NULL_FD);
 	break;
     default:
 	loglog(RC_LOG_SERIOUS, "DPD: unknown action");
diff --git a/src/pluto/state.c b/src/pluto/state.c
index c62e28e99..5372e86f5 100644
--- a/src/pluto/state.c
+++ b/src/pluto/state.c
@@ -12,7 +12,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * RCSID $Id: state.c 3252 2007-10-06 21:24:50Z andreas $
+ * RCSID $Id: state.c 4924 2009-03-10 21:13:18Z andreas $
  */
 
 #include <stdio.h>
@@ -464,12 +464,7 @@ delete_states_by_connection(struct connection *c, bool relations)
 	passert(sr->routing != RT_ROUTED_TUNNEL);
 	sr = sr->next;
     }
-
-    if (ck == CK_INSTANCE)
-    {
-	c->kind = ck;
-	delete_connection(c, relations);
-    }
+    c->kind = ck;
 }
 
 /* Walk through the state table, and delete each state whose phase 1 (IKE)
@@ -506,6 +501,8 @@ delete_states_by_peer(ip_address *peer)
 			 , peerstr
 			 , c->name);
 		    delete_states_by_connection(c, TRUE);
+		    if (c->kind == CK_INSTANCE)
+	    		delete_connection(c, TRUE);
 		    break;	/* can only delete it once */
 		}
 	    }
diff --git a/src/pluto/vendor.c b/src/pluto/vendor.c
index d4d8fcb1a..cf2136b44 100644
--- a/src/pluto/vendor.c
+++ b/src/pluto/vendor.c
@@ -11,7 +11,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * RCSID $Id: vendor.c 4846 2009-01-21 03:14:52Z andreas $
+ * RCSID $Id: vendor.c 4893 2009-02-21 17:53:10Z andreas $
  */
 
 #include <stdlib.h>
@@ -206,7 +206,8 @@ static struct vid_struct _vid_tab[] = {
 	/*
 	 * strongSwan
 	 */
-	DEC_MD5_VID(STRONGSWAN,       "strongSwan 4.2.12")
+	DEC_MD5_VID(STRONGSWAN,       "strongSwan 4.2.13")
+	DEC_MD5_VID(STRONGSWAN_4_2_12,"strongSwan 4.2.12")
 	DEC_MD5_VID(STRONGSWAN_4_2_11,"strongSwan 4.2.11")
 	DEC_MD5_VID(STRONGSWAN_4_2_10,"strongSwan 4.2.10")
 	DEC_MD5_VID(STRONGSWAN_4_2_9, "strongSwan 4.2.9")
diff --git a/src/pluto/vendor.h b/src/pluto/vendor.h
index 20711fe4e..f049af1ef 100644
--- a/src/pluto/vendor.h
+++ b/src/pluto/vendor.h
@@ -11,7 +11,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * RCSID $Id: vendor.h 4846 2009-01-21 03:14:52Z andreas $
+ * RCSID $Id: vendor.h 4893 2009-02-21 17:53:10Z andreas $
  */
 
 #ifndef _VENDOR_H_
@@ -128,6 +128,7 @@ enum known_vendorid {
   VID_STRONGSWAN_4_2_9		=109,
   VID_STRONGSWAN_4_2_10		=110,
   VID_STRONGSWAN_4_2_11		=111,
+  VID_STRONGSWAN_4_2_12		=112,
 
   /* 101 - 200 : NAT-Traversal */
   VID_NATT_STENBERG_01		=151,
diff --git a/testing/INSTALL b/testing/INSTALL
index d09383328..27a2ddc64 100644
--- a/testing/INSTALL
+++ b/testing/INSTALL
@@ -53,7 +53,7 @@ are required for the strongSwan testing environment:
     * A vanilla Linux kernel on which the UML kernel will be based on.
       We recommend the use of
 
-      http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.28.tar.bz2
+      http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.28.6.tar.bz2
 
     * The Linux kernel 2.6.28 does not require any patches for the uml guest kernel
       to successfully start up.
@@ -68,7 +68,7 @@ are required for the strongSwan testing environment:
 
     * The latest strongSwan distribution
 
-      http://download.strongswan.org/strongswan-4.2.12.tar.bz2
+      http://download.strongswan.org/strongswan-4.2.13.tar.bz2
 
 
 3. Creating the environment
@@ -143,5 +143,5 @@ README document.
 
 -----------------------------------------------------------------------------
 
-This file is RCSID $Id: INSTALL 4846 2009-01-21 03:14:52Z andreas $
+This file is RCSID $Id: INSTALL 4893 2009-02-21 17:53:10Z andreas $
 
diff --git a/testing/testing.conf b/testing/testing.conf
index 5871734d2..28b043905 100755
--- a/testing/testing.conf
+++ b/testing/testing.conf
@@ -14,14 +14,14 @@
 # or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 # for more details.
 #
-# RCSID $Id: testing.conf 4889 2009-02-19 22:02:28Z andreas $
+# RCSID $Id: testing.conf 4893 2009-02-21 17:53:10Z andreas $
 
 # Root directory of testing
 UMLTESTDIR=~/strongswan-testing
 
 # Bzipped kernel sources
 # (file extension .tar.bz2 required)
-KERNEL=$UMLTESTDIR/linux-2.6.28.tar.bz2
+KERNEL=$UMLTESTDIR/linux-2.6.28.6.tar.bz2
 
 # Extract kernel version
 KERNELVERSION=`basename $KERNEL .tar.bz2 | sed -e 's/linux-//'`
@@ -33,7 +33,7 @@ KERNELCONFIG=$UMLTESTDIR/.config-2.6.28
 #UMLPATCH=$UMLTESTDIR/uml-2.6.26.patch.bz2
 
 # Bzipped source of strongSwan
-STRONGSWAN=$UMLTESTDIR/strongswan-4.2.12.tar.bz2
+STRONGSWAN=$UMLTESTDIR/strongswan-4.2.13.tar.bz2
 
 # strongSwan compile options (use "yes" or "no")
 USE_LIBCURL="yes"
diff --git a/testing/tests/ikev1/dpd-restart/description.txt b/testing/tests/ikev1/dpd-restart/description.txt
new file mode 100644
index 000000000..0a309cf52
--- /dev/null
+++ b/testing/tests/ikev1/dpd-restart/description.txt
@@ -0,0 +1,13 @@
+The peer <b>carol</b> and <b>moon</b> both have dynamic IP addresses, so that the remote end
+is defined symbolically by <b>right=%&lt;hostname&gt;</b>. The ipsec starter resolves the
+fully-qualified hostname into the current IP address via a DNS lookup (simulated by an
+/etc/hosts entry). Since the peer IP addresses are expected to change over time, the option
+<b>rightallowany=yes</b> will allow an IKE main mode rekeying to arrive from an arbitrary
+IP address under the condition that the peer identity remains unchanged. When this happens
+the old tunnel is replaced by an IPsec connection to the new origin.
+<p>
+In this scenario <b>moon</b> first initiates a tunnel to <b>carol</b>. After some time
+the responder <b>carol</b> disconnects (simulated by iptables blocking IKE and ESP traffic).
+<b>moon</b> detects via Dead Peer Detection (DPD) that the connection is down and tries to
+reconnect. After a few seconds the firewall is opened again and the connection is 
+reestablished.
diff --git a/testing/tests/ikev1/dpd-restart/evaltest.dat b/testing/tests/ikev1/dpd-restart/evaltest.dat
new file mode 100644
index 000000000..016524dd9
--- /dev/null
+++ b/testing/tests/ikev1/dpd-restart/evaltest.dat
@@ -0,0 +1,10 @@
+moon::ipsec status::STATE_MAIN_I4 (ISAKMP SA established)::YES
+carol::iptables -I INPUT 1 -i eth0 -s PH_IP_MOON -j DROP::no output expected::NO
+moon::sleep 35::no output expected::NO
+carol::iptables -D INPUT 1::no output expected::NO
+moon::cat /var/log/auth.log::inserting event EVENT_DPD::YES
+moon::cat /var/log/auth.log::DPD: No response from peer - declaring peer dead::YES
+moon::cat /var/log/auth.log::DPD: Terminating all SAs using this connection::YES
+moon::cat /var/log/auth.log::DPD: Restarting connection::YES
+moon::sleep 5::no output expected::NO
+moon::ipsec status::STATE_MAIN_I4 (ISAKMP SA established)::YES
diff --git a/testing/tests/ikev1/dpd-restart/hosts/carol/etc/ipsec.conf b/testing/tests/ikev1/dpd-restart/hosts/carol/etc/ipsec.conf
new file mode 100755
index 000000000..e6938e79a
--- /dev/null
+++ b/testing/tests/ikev1/dpd-restart/hosts/carol/etc/ipsec.conf
@@ -0,0 +1,25 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+	plutodebug=control
+	crlcheckinterval=180
+	strictcrlpolicy=no
+	charonstart=no
+
+conn %default
+	ikelifetime=60m
+	keylife=20m
+	rekeymargin=3m
+	keyingtries=1
+
+conn moon 
+	left=%defaultroute
+	leftnexthop=%direct
+	leftsourceip=PH_IP_CAROL1
+	leftcert=carolCert.pem
+	leftid=carol@strongswan.org
+	leftfirewall=yes
+	right=%moon.strongswan.org
+	rightsubnet=10.1.0.0/16
+	rightid=@moon.strongswan.org
+	auto=add
diff --git a/testing/tests/ikev1/dpd-restart/hosts/moon/etc/ipsec.conf b/testing/tests/ikev1/dpd-restart/hosts/moon/etc/ipsec.conf
new file mode 100755
index 000000000..ae9b35e97
--- /dev/null
+++ b/testing/tests/ikev1/dpd-restart/hosts/moon/etc/ipsec.conf
@@ -0,0 +1,29 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+	plutodebug=control
+	crlcheckinterval=180
+	strictcrlpolicy=no
+	charonstart=no
+
+conn %default
+	ikelifetime=60m
+	keylife=20m
+	rekeymargin=3m
+	keyingtries=1
+        dpdaction=restart
+        dpddelay=5
+        dpdtimeout=25
+
+conn carol
+	left=%defaultroute
+	leftnexthop=%direct
+	leftsubnet=10.1.0.0/16
+	leftsourceip=PH_IP_MOON1
+	leftcert=moonCert.pem
+	leftid=@moon.strongswan.org
+	leftfirewall=yes
+	right=%carol.strongswan.org
+	rightid=carol@strongswan.org
+	rightsubnet=PH_IP_CAROL1/32
+	auto=start
diff --git a/testing/tests/ikev1/dpd-restart/posttest.dat b/testing/tests/ikev1/dpd-restart/posttest.dat
new file mode 100644
index 000000000..e092608cb
--- /dev/null
+++ b/testing/tests/ikev1/dpd-restart/posttest.dat
@@ -0,0 +1,5 @@
+carol::ipsec stop
+moon::ipsec stop
+moon::/etc/init.d/iptables stop 2> /dev/null
+carol::/etc/init.d/iptables stop 2> /dev/null
+carol::ip addr del PH_IP_CAROL1/32 dev eth0
diff --git a/testing/tests/ikev1/dpd-restart/pretest.dat b/testing/tests/ikev1/dpd-restart/pretest.dat
new file mode 100644
index 000000000..caf89d6c6
--- /dev/null
+++ b/testing/tests/ikev1/dpd-restart/pretest.dat
@@ -0,0 +1,5 @@
+moon::/etc/init.d/iptables start 2> /dev/null
+carol::/etc/init.d/iptables start 2> /dev/null
+carol::ipsec start
+moon::ipsec start
+moon::sleep 4
diff --git a/testing/tests/ikev1/dpd-restart/test.conf b/testing/tests/ikev1/dpd-restart/test.conf
new file mode 100644
index 000000000..4d648102b
--- /dev/null
+++ b/testing/tests/ikev1/dpd-restart/test.conf
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# This configuration file provides information on the
+# UML instances used for this test
+
+# All UML instances that are required for this test
+#
+UMLHOSTS="alice moon carol winnetou dave"
+
+# Corresponding block diagram
+#
+DIAGRAM="a-m-c-w-d.png"
+
+# UML instances on which tcpdump is to be started
+#
+TCPDUMPHOSTS="moon alice"
+
+# UML instances on which IPsec is started
+# Used for IPsec logging purposes
+#
+IPSECHOSTS="moon carol"
diff --git a/testing/tests/ikev2/ip-pool-db/description.txt b/testing/tests/ikev2/ip-pool-db/description.txt
index 5cc500c98..7bc4ef3ab 100644
--- a/testing/tests/ikev2/ip-pool-db/description.txt
+++ b/testing/tests/ikev2/ip-pool-db/description.txt
@@ -2,7 +2,7 @@ The roadwarriors <b>carol</b> and <b>dave</b> set up a connection each to gatewa
 Both <b>carol</b> and <b>dave</b> request a <b>virtual IP</b> via the IKEv2 configuration payload
 by using the <b>leftsourceip=%config</b> parameter. The gateway <b>moon</b> assigns virtual IP
 addresses from a pool named <b>bigpool</b> that was created in an SQL database by the command
-<b>ipsec pool --name bigpool --start 10.3.0.1 --end 10.3.255.254 --timeout 0</b>.
+<b>ipsec pool --name bigpool --start 10.3.0.1 --end 10.3.3.232 --timeout 0</b>.
 <p>
 <b>leftfirewall=yes</b> automatically inserts iptables-based firewall rules that let pass the
 tunneled traffic. In order to test the tunnels, <b>carol</b> and <b>dave</b> then ping the client
diff --git a/testing/tests/ikev2/ip-two-pools-db/description.txt b/testing/tests/ikev2/ip-two-pools-db/description.txt
index 14a3f17b5..188b4349e 100644
--- a/testing/tests/ikev2/ip-two-pools-db/description.txt
+++ b/testing/tests/ikev2/ip-two-pools-db/description.txt
@@ -1,9 +1,9 @@
 The hosts <b>alice</b>, <b>venus</b>, <b>carol</b>, and <b>dave</b> set up tunnel connections
 to gateway <b>moon</b> in a <b>hub-and-spoke</b> fashion. Each host requests a <b>virtual IP</b> 
 with the <b>leftsourceip=%config</b> parameter. Gateway <b>moon</b> assigns virtual
-IP addresses from a pool named <b>extpool</b> [10.3.0.1..10.3.255.254] to hosts connecting
+IP addresses from a pool named <b>extpool</b> [10.3.0.1..10.3.1.244] to hosts connecting
 to the <b>eth0</b> (PH_IP_MOON) interface and virtual IP addresses from a pool named <b>intpool</b>
-[10.4.0.1..10.4.255.254] to hosts connecting to the <b>eth1</b> (PH_IP_MOON1) interface.
+[10.4.0.1..10.4.1.244] to hosts connecting to the <b>eth1</b> (PH_IP_MOON1) interface.
 Thus <b>carol</b> and <b>dave</b> are assigned <b>PH_IP_CAROL1</b> and <b>PH_IP_DAVE1</b>,
 respectively, whereas <b>alice</b> and <b>venus</b> get <b>10.4.0.1</b> and <b>10.4.0.2</b>,
 respectively.
diff --git a/testing/tests/ikev2/ip-two-pools-mixed/description.txt b/testing/tests/ikev2/ip-two-pools-mixed/description.txt
new file mode 100644
index 000000000..d771d006d
--- /dev/null
+++ b/testing/tests/ikev2/ip-two-pools-mixed/description.txt
@@ -0,0 +1,9 @@
+The hosts <b>alice</b> and <b>carol</b> set up a tunnel connection each to gateway <b>moon</b>.
+Both hosts request a <b>virtual IP</b> via the IKEv2 configuration payload by using the
+<b>leftsourceip=%config</b> parameter. Gateway <b>moon</b> assigns virtual IP
+addresses from a simple pool defined by <b>rightsourceip=10.3.0.0/28</b> to hosts connecting
+to the <b>eth0</b> (PH_IP_MOON) interface and virtual IP addresses from an SQLite-based pool
+named <b>intpool</b> [10.4.0.1..10.4.1.244] to hosts connecting to the <b>eth1</b> (PH_IP_MOON1) interface.
+<p>
+Thus <b>carol</b> is assigned <b>PH_IP_CAROL1</b> whereas <b>alice</b> gets <b>10.4.0.1</b> and 
+both ping the gateway <b>moon</b>.
diff --git a/testing/tests/ikev2/ip-two-pools-mixed/evaltest.dat b/testing/tests/ikev2/ip-two-pools-mixed/evaltest.dat
new file mode 100644
index 000000000..1505de751
--- /dev/null
+++ b/testing/tests/ikev2/ip-two-pools-mixed/evaltest.dat
@@ -0,0 +1,17 @@
+carol::ipsec status::home.*INSTALLED::YES
+alice::ipsec status::home.*INSTALLED::YES
+moon::ipsec status::ext.*ESTABLISHED.*carol@strongswan.org::YES
+moon::ipsec status::int.*ESTABLISHED.*alice@strongswan.org::YES
+moon::cat /var/log/daemon.log::adding virtual IP address pool.*ext.*10.3.0.0/28::YES
+moon::ipsec leases ext::1/15, 1 online::YES
+moon::ipsec leases ext 10.3.0.1::carol@strongswan.org::YES
+moon::ipsec pool --status 2> /dev/null::intpool.*10.4.0.1.*10.4.1.244.*static.*1::YES
+moon::ipsec pool --leases --filter pool=intpool,addr=10.4.0.1,id=alice@strongswan.org 2> /dev/null::online::YES
+carol::cat /var/log/daemon.log::installing new virtual IP 10.3.0.1::YES
+alice::cat /var/log/daemon.log::installing new virtual IP 10.4.0.1::YES
+carol::ping -c 1 PH_IP_MOON::64 bytes from PH_IP_MOON: icmp_seq=1::YES
+alice::ping -c 1 PH_IP_MOON1::64 bytes from PH_IP_MOON1: icmp_seq=1::YES
+carol::tcpdump::IP carol.strongswan.org > moon.strongswan.org: ESP::YES
+carol::tcpdump::IP moon.strongswan.org > carol.strongswan.org: ESP::YES
+alice::tcpdump::IP alice.strongswan.org > moon1.strongswan.org: ESP::YES
+alice::tcpdump::IP moon1.strongswan.org > alice.strongswan.org: ESP::YES
diff --git a/testing/tests/ikev2/ip-two-pools-mixed/hosts/alice/etc/init.d/iptables b/testing/tests/ikev2/ip-two-pools-mixed/hosts/alice/etc/init.d/iptables
new file mode 100755
index 000000000..97b773645
--- /dev/null
+++ b/testing/tests/ikev2/ip-two-pools-mixed/hosts/alice/etc/init.d/iptables
@@ -0,0 +1,78 @@
+#!/sbin/runscript
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+opts="start stop reload"
+
+depend() {
+	before net
+	need logger
+}
+
+start() {
+	ebegin "Starting firewall"
+
+	# default policy is DROP
+	/sbin/iptables -P INPUT DROP
+	/sbin/iptables -P OUTPUT DROP
+	/sbin/iptables -P FORWARD DROP
+
+        # allow ESP 
+        iptables -A INPUT  -i eth0 -p 50 -j ACCEPT
+        iptables -A OUTPUT -o eth0 -p 50 -j ACCEPT
+
+	# allow IKE
+        iptables -A INPUT  -i eth0 -p udp --sport 500 --dport 500 -j ACCEPT
+        iptables -A OUTPUT -o eth0 -p udp --dport 500 --sport 500 -j ACCEPT
+			
+	# allow MOBIKE 
+	iptables -A INPUT  -i eth0 -p udp --sport 4500 --dport 4500 -j ACCEPT
+	iptables -A OUTPUT -o eth0 -p udp --dport 4500 --sport 4500 -j ACCEPT
+
+
+	# allow crl fetch from winnetou
+	iptables -A INPUT  -i eth0 -p tcp --sport 80 -s PH_IP_WINNETOU -j ACCEPT
+	iptables -A OUTPUT -o eth0 -p tcp --dport 80 -d PH_IP_WINNETOU -j ACCEPT
+
+	# allow ssh
+	iptables -A INPUT  -p tcp --dport 22 -j ACCEPT
+	iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+	eend $?
+}
+
+stop() {
+	ebegin "Stopping firewall"
+		for a in `cat /proc/net/ip_tables_names`; do
+			/sbin/iptables -F -t $a
+			/sbin/iptables -X -t $a
+	
+			if [ $a == nat ]; then
+				/sbin/iptables -t nat -P PREROUTING ACCEPT
+				/sbin/iptables -t nat -P POSTROUTING ACCEPT
+				/sbin/iptables -t nat -P OUTPUT ACCEPT
+			elif [ $a == mangle ]; then
+				/sbin/iptables -t mangle -P PREROUTING ACCEPT
+				/sbin/iptables -t mangle -P INPUT ACCEPT
+				/sbin/iptables -t mangle -P FORWARD ACCEPT
+				/sbin/iptables -t mangle -P OUTPUT ACCEPT
+				/sbin/iptables -t mangle -P POSTROUTING ACCEPT
+			elif [ $a == filter ]; then
+				/sbin/iptables -t filter -P INPUT ACCEPT
+				/sbin/iptables -t filter -P FORWARD ACCEPT
+				/sbin/iptables -t filter -P OUTPUT ACCEPT
+			fi
+		done
+	eend $?
+}
+
+reload() {
+	ebegin "Flushing firewall"
+		for a in `cat /proc/net/ip_tables_names`; do
+			/sbin/iptables -F -t $a
+			/sbin/iptables -X -t $a
+		done;
+        eend $?
+	start
+}
+
diff --git a/testing/tests/ikev2/ip-two-pools-mixed/hosts/alice/etc/ipsec.conf b/testing/tests/ikev2/ip-two-pools-mixed/hosts/alice/etc/ipsec.conf
new file mode 100755
index 000000000..f5ce1687e
--- /dev/null
+++ b/testing/tests/ikev2/ip-two-pools-mixed/hosts/alice/etc/ipsec.conf
@@ -0,0 +1,23 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+        crlcheckinterval=180
+	strictcrlpolicy=no
+	plutostart=no
+
+conn %default
+	ikelifetime=60m
+	keylife=20m
+	rekeymargin=3m
+	keyingtries=1
+	keyexchange=ikev2
+		
+conn home 
+	left=%defaultroute
+	leftsourceip=%config
+	leftcert=aliceCert.pem
+	leftid=alice@strongswan.org
+	leftfirewall=yes
+	right=PH_IP_MOON1
+	rightid=@moon.strongswan.org
+	auto=add
diff --git a/testing/tests/ikev2/ip-two-pools-mixed/hosts/alice/etc/strongswan.conf b/testing/tests/ikev2/ip-two-pools-mixed/hosts/alice/etc/strongswan.conf
new file mode 100644
index 000000000..40eb84b8a
--- /dev/null
+++ b/testing/tests/ikev2/ip-two-pools-mixed/hosts/alice/etc/strongswan.conf
@@ -0,0 +1,5 @@
+# /etc/strongswan.conf - strongSwan configuration file
+
+charon {
+  load = curl aes des sha1 sha2 md5 gmp random x509 pubkey hmac xcbc stroke kernel-netlink updown
+}
diff --git a/testing/tests/ikev2/ip-two-pools-mixed/hosts/carol/etc/ipsec.conf b/testing/tests/ikev2/ip-two-pools-mixed/hosts/carol/etc/ipsec.conf
new file mode 100755
index 000000000..e647f1e36
--- /dev/null
+++ b/testing/tests/ikev2/ip-two-pools-mixed/hosts/carol/etc/ipsec.conf
@@ -0,0 +1,23 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+	crlcheckinterval=180
+	strictcrlpolicy=no
+	plutostart=no
+
+conn %default
+	ikelifetime=60m
+	keylife=20m
+	rekeymargin=3m
+	keyingtries=1
+	keyexchange=ikev2
+
+conn home
+	left=PH_IP_CAROL
+	leftsourceip=%config
+	leftcert=carolCert.pem
+	leftid=carol@strongswan.org
+	leftfirewall=yes
+	right=PH_IP_MOON
+	rightid=@moon.strongswan.org
+	auto=add
diff --git a/testing/tests/ikev2/ip-two-pools-mixed/hosts/carol/etc/strongswan.conf b/testing/tests/ikev2/ip-two-pools-mixed/hosts/carol/etc/strongswan.conf
new file mode 100644
index 000000000..40eb84b8a
--- /dev/null
+++ b/testing/tests/ikev2/ip-two-pools-mixed/hosts/carol/etc/strongswan.conf
@@ -0,0 +1,5 @@
+# /etc/strongswan.conf - strongSwan configuration file
+
+charon {
+  load = curl aes des sha1 sha2 md5 gmp random x509 pubkey hmac xcbc stroke kernel-netlink updown
+}
diff --git a/testing/tests/ikev2/ip-two-pools-mixed/hosts/moon/etc/init.d/iptables b/testing/tests/ikev2/ip-two-pools-mixed/hosts/moon/etc/init.d/iptables
new file mode 100755
index 000000000..bb9d03acd
--- /dev/null
+++ b/testing/tests/ikev2/ip-two-pools-mixed/hosts/moon/etc/init.d/iptables
@@ -0,0 +1,91 @@
+#!/sbin/runscript
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+opts="start stop reload"
+
+depend() {
+	before net
+	need logger
+}
+
+start() {
+	ebegin "Starting firewall"
+
+	# enable IP forwarding
+	echo 1 > /proc/sys/net/ipv4/ip_forward
+	
+	# default policy is DROP
+	/sbin/iptables -P INPUT DROP
+	/sbin/iptables -P OUTPUT DROP
+	/sbin/iptables -P FORWARD DROP
+
+	# allow esp
+	iptables -A INPUT  -i eth0 -p 50 -j ACCEPT
+	iptables -A OUTPUT -o eth0 -p 50 -j ACCEPT
+        iptables -A INPUT  -i eth1 -p 50 -j ACCEPT
+        iptables -A OUTPUT -o eth1 -p 50 -j ACCEPT
+
+	# allow IKE
+	iptables -A INPUT  -i eth0 -p udp --sport 500 --dport 500 -j ACCEPT
+	iptables -A OUTPUT -o eth0 -p udp --dport 500 --sport 500 -j ACCEPT
+        iptables -A INPUT  -i eth1 -p udp --sport 500 --dport 500 -j ACCEPT
+        iptables -A OUTPUT -o eth1 -p udp --dport 500 --sport 500 -j ACCEPT
+
+	# allow MobIKE
+	iptables -A INPUT  -i eth0 -p udp --sport 4500 --dport 4500 -j ACCEPT
+	iptables -A OUTPUT -o eth0 -p udp --dport 4500 --sport 4500 -j ACCEPT
+        iptables -A INPUT  -i eth1 -p udp --sport 4500 --dport 4500 -j ACCEPT
+        iptables -A OUTPUT -o eth1 -p udp --dport 4500 --sport 4500 -j ACCEPT
+
+	# allow crl fetch from winnetou
+	iptables -A INPUT  -i eth0 -p tcp --sport 80 -s PH_IP_WINNETOU -j ACCEPT
+	iptables -A OUTPUT -o eth0 -p tcp --dport 80 -d PH_IP_WINNETOU -j ACCEPT
+	iptables -A FORWARD -i eth0 -o eth1 -p tcp --sport 80 -s PH_IP_WINNETOU -j ACCEPT
+	iptables -A FORWARD -o eth0 -i eth1 -p tcp --dport 80 -d PH_IP_WINNETOU -j ACCEPT
+
+	# masquerade crl fetches to winnetou
+	iptables -t nat -A POSTROUTING -o eth0 -s 10.1.0.0/16 -d PH_IP_WINNETOU -j MASQUERADE
+
+	# allow ssh
+	iptables -A INPUT  -p tcp --dport 22 -j ACCEPT
+	iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+	eend $?
+}
+
+stop() {
+	ebegin "Stopping firewall"
+		for a in `cat /proc/net/ip_tables_names`; do
+			/sbin/iptables -F -t $a
+			/sbin/iptables -X -t $a
+	
+			if [ $a == nat ]; then
+				/sbin/iptables -t nat -P PREROUTING ACCEPT
+				/sbin/iptables -t nat -P POSTROUTING ACCEPT
+				/sbin/iptables -t nat -P OUTPUT ACCEPT
+			elif [ $a == mangle ]; then
+				/sbin/iptables -t mangle -P PREROUTING ACCEPT
+				/sbin/iptables -t mangle -P INPUT ACCEPT
+				/sbin/iptables -t mangle -P FORWARD ACCEPT
+				/sbin/iptables -t mangle -P OUTPUT ACCEPT
+				/sbin/iptables -t mangle -P POSTROUTING ACCEPT
+			elif [ $a == filter ]; then
+				/sbin/iptables -t filter -P INPUT ACCEPT
+				/sbin/iptables -t filter -P FORWARD ACCEPT
+				/sbin/iptables -t filter -P OUTPUT ACCEPT
+			fi
+		done
+	eend $?
+}
+
+reload() {
+	ebegin "Flushing firewall"
+		for a in `cat /proc/net/ip_tables_names`; do
+			/sbin/iptables -F -t $a
+			/sbin/iptables -X -t $a
+		done;
+        eend $?
+	start
+}
+
diff --git a/testing/tests/ikev2/ip-two-pools-mixed/hosts/moon/etc/ipsec.conf b/testing/tests/ikev2/ip-two-pools-mixed/hosts/moon/etc/ipsec.conf
new file mode 100755
index 000000000..d80bb5305
--- /dev/null
+++ b/testing/tests/ikev2/ip-two-pools-mixed/hosts/moon/etc/ipsec.conf
@@ -0,0 +1,27 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+	crlcheckinterval=180
+	strictcrlpolicy=no
+	plutostart=no
+
+conn %default
+	ikelifetime=60m
+	keylife=20m
+	rekeymargin=3m
+	keyingtries=1
+	keyexchange=ikev2
+	leftcert=moonCert.pem
+	leftid=@moon.strongswan.org
+	leftfirewall=yes
+	right=%any
+
+conn int 
+	left=PH_IP_MOON1
+	rightsourceip=%intpool
+	auto=add
+
+conn ext 
+	left=PH_IP_MOON
+	rightsourceip=10.3.0.0/28
+	auto=add
diff --git a/testing/tests/ikev2/ip-two-pools-mixed/hosts/moon/etc/strongswan.conf b/testing/tests/ikev2/ip-two-pools-mixed/hosts/moon/etc/strongswan.conf
new file mode 100644
index 000000000..1b5257ccc
--- /dev/null
+++ b/testing/tests/ikev2/ip-two-pools-mixed/hosts/moon/etc/strongswan.conf
@@ -0,0 +1,14 @@
+# /etc/strongswan.conf - strongSwan configuration file
+
+charon {
+  plugins {
+    sql {
+      database = sqlite:///etc/ipsec.d/ipsec.db 
+    }
+  }
+  load = curl aes des sha1 sha2 md5 gmp random x509 pubkey hmac xcbc stroke sqlite sql kernel-netlink updown
+}
+
+pool {
+  load = sqlite
+}
diff --git a/testing/tests/ikev2/ip-two-pools-mixed/posttest.dat b/testing/tests/ikev2/ip-two-pools-mixed/posttest.dat
new file mode 100644
index 000000000..db5e6237f
--- /dev/null
+++ b/testing/tests/ikev2/ip-two-pools-mixed/posttest.dat
@@ -0,0 +1,9 @@
+carol::ipsec stop
+alice::ipsec stop
+moon::ipsec stop
+moon::/etc/init.d/iptables stop 2> /dev/null
+carol::/etc/init.d/iptables stop 2> /dev/null
+alice::/etc/init.d/iptables stop 2> /dev/null
+moon::conntrack -F
+moon::ipsec pool --del intpool 2> /dev/null
+moon::rm /etc/ipsec.d/ipsec.*
diff --git a/testing/tests/ikev2/ip-two-pools-mixed/pretest.dat b/testing/tests/ikev2/ip-two-pools-mixed/pretest.dat
new file mode 100644
index 000000000..b579464f2
--- /dev/null
+++ b/testing/tests/ikev2/ip-two-pools-mixed/pretest.dat
@@ -0,0 +1,13 @@
+moon::cat /etc/ipsec.d/tables.sql > /etc/ipsec.d/ipsec.sql
+moon::cat /etc/ipsec.d/ipsec.sql | sqlite3 /etc/ipsec.d/ipsec.db
+moon::ipsec pool --add intpool --start 10.4.0.1 --end 10.4.1.244 --timeout  0 2> /dev/null
+moon::/etc/init.d/iptables start 2> /dev/null
+carol::/etc/init.d/iptables start 2> /dev/null
+alice::/etc/init.d/iptables start 2> /dev/null
+carol::ipsec start
+moon::ipsec start
+alice::ipsec start
+carol::sleep 2 
+carol::ipsec up home
+alice::ipsec up home
+alice::sleep 1
diff --git a/testing/tests/ikev2/ip-two-pools-mixed/test.conf b/testing/tests/ikev2/ip-two-pools-mixed/test.conf
new file mode 100644
index 000000000..329774c0a
--- /dev/null
+++ b/testing/tests/ikev2/ip-two-pools-mixed/test.conf
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# This configuration file provides information on the
+# UML instances used for this test
+
+# All UML instances that are required for this test
+#
+UMLHOSTS="alice moon carol winnetou"
+
+# Corresponding block diagram
+#
+DIAGRAM="a-m-c-w.png"
+
+# UML instances on which tcpdump is to be started
+#
+TCPDUMPHOSTS="alice carol"
+
+# UML instances on which IPsec is started
+# Used for IPsec logging purposes
+#
+IPSECHOSTS="alice moon carol"
-- 
cgit v1.2.3