]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
Bye bye Pluto!
authorTobias Brunner <tobias@strongswan.org>
Tue, 15 May 2012 14:59:00 +0000 (16:59 +0200)
committerTobias Brunner <tobias@strongswan.org>
Mon, 11 Jun 2012 15:33:32 +0000 (17:33 +0200)
Charon will take over IKEv1 duties from here.  This also removes
libfreeswan and whack.

180 files changed:
Android.mk.in
configure.in
src/Makefile.am
src/checksum/Makefile.am
src/libfreeswan/Android.mk [deleted file]
src/libfreeswan/Makefile.am [deleted file]
src/libfreeswan/addrtoa.c [deleted file]
src/libfreeswan/addrtot.c [deleted file]
src/libfreeswan/addrtypeof.c [deleted file]
src/libfreeswan/anyaddr.3 [deleted file]
src/libfreeswan/anyaddr.c [deleted file]
src/libfreeswan/atoaddr.3 [deleted file]
src/libfreeswan/atoaddr.c [deleted file]
src/libfreeswan/atoasr.3 [deleted file]
src/libfreeswan/atoasr.c [deleted file]
src/libfreeswan/atosubnet.c [deleted file]
src/libfreeswan/atoul.3 [deleted file]
src/libfreeswan/atoul.c [deleted file]
src/libfreeswan/copyright.c [deleted file]
src/libfreeswan/datatot.c [deleted file]
src/libfreeswan/freeswan.h [deleted file]
src/libfreeswan/goodmask.3 [deleted file]
src/libfreeswan/goodmask.c [deleted file]
src/libfreeswan/initaddr.3 [deleted file]
src/libfreeswan/initaddr.c [deleted file]
src/libfreeswan/initsaid.c [deleted file]
src/libfreeswan/initsubnet.3 [deleted file]
src/libfreeswan/initsubnet.c [deleted file]
src/libfreeswan/internal.h [deleted file]
src/libfreeswan/ipsec_param.h [deleted file]
src/libfreeswan/pfkey.h [deleted file]
src/libfreeswan/pfkey_v2_build.c [deleted file]
src/libfreeswan/pfkey_v2_debug.c [deleted file]
src/libfreeswan/pfkey_v2_ext_bits.c [deleted file]
src/libfreeswan/pfkey_v2_parse.c [deleted file]
src/libfreeswan/pfkeyv2.h [deleted file]
src/libfreeswan/portof.3 [deleted file]
src/libfreeswan/portof.c [deleted file]
src/libfreeswan/rangetoa.c [deleted file]
src/libfreeswan/rangetosubnet.3 [deleted file]
src/libfreeswan/rangetosubnet.c [deleted file]
src/libfreeswan/sameaddr.3 [deleted file]
src/libfreeswan/sameaddr.c [deleted file]
src/libfreeswan/satot.c [deleted file]
src/libfreeswan/subnetof.3 [deleted file]
src/libfreeswan/subnetof.c [deleted file]
src/libfreeswan/subnettoa.c [deleted file]
src/libfreeswan/subnettot.c [deleted file]
src/libfreeswan/subnettypeof.c [deleted file]
src/libfreeswan/ttoaddr.3 [deleted file]
src/libfreeswan/ttoaddr.c [deleted file]
src/libfreeswan/ttodata.3 [deleted file]
src/libfreeswan/ttodata.c [deleted file]
src/libfreeswan/ttoprotoport.c [deleted file]
src/libfreeswan/ttosa.3 [deleted file]
src/libfreeswan/ttosa.c [deleted file]
src/libfreeswan/ttosubnet.c [deleted file]
src/libfreeswan/ttoul.3 [deleted file]
src/libfreeswan/ttoul.c [deleted file]
src/libfreeswan/ultoa.c [deleted file]
src/libfreeswan/ultot.c [deleted file]
src/pluto/.gitignore [deleted file]
src/pluto/Android.mk [deleted file]
src/pluto/Makefile.am [deleted file]
src/pluto/ac.c [deleted file]
src/pluto/ac.h [deleted file]
src/pluto/adns.c [deleted file]
src/pluto/adns.h [deleted file]
src/pluto/alg_info.c [deleted file]
src/pluto/alg_info.h [deleted file]
src/pluto/builder.c [deleted file]
src/pluto/builder.h [deleted file]
src/pluto/ca.c [deleted file]
src/pluto/ca.h [deleted file]
src/pluto/certs.c [deleted file]
src/pluto/certs.h [deleted file]
src/pluto/connections.c [deleted file]
src/pluto/connections.h [deleted file]
src/pluto/constants.c [deleted file]
src/pluto/constants.h [deleted file]
src/pluto/cookie.c [deleted file]
src/pluto/cookie.h [deleted file]
src/pluto/crl.c [deleted file]
src/pluto/crl.h [deleted file]
src/pluto/crypto.c [deleted file]
src/pluto/crypto.h [deleted file]
src/pluto/db_ops.c [deleted file]
src/pluto/db_ops.h [deleted file]
src/pluto/defs.c [deleted file]
src/pluto/defs.h [deleted file]
src/pluto/demux.c [deleted file]
src/pluto/demux.h [deleted file]
src/pluto/dnskey.c [deleted file]
src/pluto/dnskey.h [deleted file]
src/pluto/event_queue.c [deleted file]
src/pluto/event_queue.h [deleted file]
src/pluto/fetch.c [deleted file]
src/pluto/fetch.h [deleted file]
src/pluto/foodgroups.c [deleted file]
src/pluto/foodgroups.h [deleted file]
src/pluto/ike_alg.c [deleted file]
src/pluto/ike_alg.h [deleted file]
src/pluto/ipsec_doi.c [deleted file]
src/pluto/ipsec_doi.h [deleted file]
src/pluto/kameipsec.h [deleted file]
src/pluto/kernel.c [deleted file]
src/pluto/kernel.h [deleted file]
src/pluto/kernel_alg.c [deleted file]
src/pluto/kernel_alg.h [deleted file]
src/pluto/kernel_pfkey.c [deleted file]
src/pluto/kernel_pfkey.h [deleted file]
src/pluto/keys.c [deleted file]
src/pluto/keys.h [deleted file]
src/pluto/lex.c [deleted file]
src/pluto/lex.h [deleted file]
src/pluto/log.c [deleted file]
src/pluto/log.h [deleted file]
src/pluto/modecfg.c [deleted file]
src/pluto/modecfg.h [deleted file]
src/pluto/myid.c [deleted file]
src/pluto/myid.h [deleted file]
src/pluto/nat_traversal.c [deleted file]
src/pluto/nat_traversal.h [deleted file]
src/pluto/ocsp.c [deleted file]
src/pluto/ocsp.h [deleted file]
src/pluto/packet.c [deleted file]
src/pluto/packet.h [deleted file]
src/pluto/pkcs7.c [deleted file]
src/pluto/pkcs7.h [deleted file]
src/pluto/plugin_list.c [deleted file]
src/pluto/plugin_list.h [deleted file]
src/pluto/plugins/xauth/Makefile.am [deleted file]
src/pluto/plugins/xauth/xauth_default_provider.c [deleted file]
src/pluto/plugins/xauth/xauth_default_provider.h [deleted file]
src/pluto/plugins/xauth/xauth_default_verifier.c [deleted file]
src/pluto/plugins/xauth/xauth_default_verifier.h [deleted file]
src/pluto/plugins/xauth/xauth_plugin.c [deleted file]
src/pluto/plugins/xauth/xauth_plugin.h [deleted file]
src/pluto/pluto.8 [deleted file]
src/pluto/pluto.c [deleted file]
src/pluto/pluto.h [deleted file]
src/pluto/plutomain.c [deleted file]
src/pluto/rcv_whack.c [deleted file]
src/pluto/rcv_whack.h [deleted file]
src/pluto/routing.txt [deleted file]
src/pluto/rsaref/pkcs11.h [deleted file]
src/pluto/rsaref/pkcs11f.h [deleted file]
src/pluto/rsaref/pkcs11t.h [deleted file]
src/pluto/rsaref/unix.h [deleted file]
src/pluto/server.c [deleted file]
src/pluto/server.h [deleted file]
src/pluto/smartcard.c [deleted file]
src/pluto/smartcard.h [deleted file]
src/pluto/spdb.c [deleted file]
src/pluto/spdb.h [deleted file]
src/pluto/state.c [deleted file]
src/pluto/state.h [deleted file]
src/pluto/timer.c [deleted file]
src/pluto/timer.h [deleted file]
src/pluto/vendor.c [deleted file]
src/pluto/vendor.h [deleted file]
src/pluto/virtual.c [deleted file]
src/pluto/virtual.h [deleted file]
src/pluto/whack_attribute.c [deleted file]
src/pluto/whack_attribute.h [deleted file]
src/pluto/x509.c [deleted file]
src/pluto/x509.h [deleted file]
src/pluto/xauth/xauth_manager.c [deleted file]
src/pluto/xauth/xauth_manager.h [deleted file]
src/pluto/xauth/xauth_provider.h [deleted file]
src/pluto/xauth/xauth_verifier.h [deleted file]
src/starter/Android.mk
src/starter/Makefile.am
src/starter/confread.c
src/starter/files.h
src/whack/.gitignore [deleted file]
src/whack/Android.mk [deleted file]
src/whack/Makefile.am [deleted file]
src/whack/whack.c [deleted file]
src/whack/whack.h [deleted file]

index 57fa8b1f4ab202d46af08342c7506d9de2b95dab..2563b7a3dc02e5db69421b9b4742495b3c7399b1 100644 (file)
@@ -6,12 +6,10 @@ include $(CLEAR_VARS)
 #   build/target/product/core.mk
 # possible executables are
 #   starter - allows to control and configure the daemons from the command line
-#   charon - the IKEv2 daemon
-#   pluto - the IKEv1 daemon
+#   charon - the IKE daemon
 
-# if you enable starter and/or pluto (see above) uncomment the proper lines here
+# if you enable starter (see above) uncomment this line too
 # strongswan_BUILD_STARTER := true
-# strongswan_BUILD_PLUTO := true
 
 # this is the list of plugins that are built into libstrongswan and charon
 # also these plugins are loaded by default (if not changed in strongswan.conf)
@@ -19,20 +17,10 @@ strongswan_CHARON_PLUGINS := openssl fips-prf random pubkey pkcs1 \
        pem xcbc hmac kernel-netlink socket-default android \
        stroke eap-identity eap-mschapv2 eap-md5
 
-ifneq ($(strongswan_BUILD_PLUTO),)
-# if both daemons are enabled we use raw sockets in charon
-strongswan_CHARON_PLUGINS := $(subst socket-default,socket-raw, \
-                               $(strongswan_CHARON_PLUGINS))
-# plugins loaded by pluto
-strongswan_PLUTO_PLUGINS := openssl fips-prf random pubkey pkcs1 \
-       pem xcbc hmac kernel-netlink xauth
-endif
-
 strongswan_STARTER_PLUGINS := kernel-netlink
 
 # list of all plugins - used to enable them with the function below
 strongswan_PLUGINS := $(sort $(strongswan_CHARON_PLUGINS) \
-                            $(strongswan_PLUTO_PLUGINS) \
                             $(strongswan_STARTER_PLUGINS))
 
 # helper macros to only add source files for plugins included in the list above
@@ -115,18 +103,10 @@ strongswan_BUILD := \
 
 ifneq ($(strongswan_BUILD_STARTER),)
 strongswan_BUILD += \
-       libfreeswan \
        starter \
        stroke \
        ipsec
 endif
 
-ifneq ($(strongswan_BUILD_PLUTO),)
-strongswan_BUILD += \
-       libfreeswan \
-       pluto \
-       whack
-endif
-
 include $(addprefix $(LOCAL_PATH)/src/,$(addsuffix /Android.mk, \
                $(sort $(strongswan_BUILD))))
index 7d0cdbbad02a342fc7dfa36fb29dee08a8cdebfe..edf7ce073edcf44fe1cdd226154bc9a2b1d3ff8b 100644 (file)
@@ -164,12 +164,9 @@ ARG_ENABL_SET([manager],        [enable web management console (proof of concept
 ARG_ENABL_SET([mediation],      [enable IKEv2 Mediation Extension.])
 ARG_ENABL_SET([integrity-test], [enable integrity testing of libstrongswan and plugins.])
 ARG_DISBL_SET([load-warning],   [disable the charon/pluto plugin load option warning in starter.])
-ARG_ENABL_SET([pluto],          [enable the IKEv1 keying daemon pluto.])
 ARG_DISBL_SET([ikev1],          [disable IKEv1 protocol support in charon.])
 ARG_DISBL_SET([ikev2],          [disable IKEv2 protocol support in charon.])
 ARG_DISBL_SET([xauth],          [disable xauth plugin.])
-ARG_DISBL_SET([threads],        [disable the use of threads in pluto. Charon always uses threads.])
-ARG_DISBL_SET([adns],           [disable the use of adns in pluto (disables opportunistic encryption).])
 ARG_DISBL_SET([charon],         [disable the IKEv1/IKEv2 keying daemon charon.])
 ARG_DISBL_SET([tools],          [disable additional utilities (openac, scepclient and pki).])
 ARG_DISBL_SET([scripts],        [disable additional utilities (found in directory scripts).])
@@ -303,16 +300,6 @@ if test x$medcli = xtrue; then
        mediation=true
 fi
 
-if test x$pluto = xtrue; then
-       if test x$socket_raw = xfalse; then
-               AC_MSG_NOTICE([Enforcing --enable-socket-raw, as pluto is enabled])
-               socket_raw=true
-               if test x$socket_default_given = xfalse; then
-                       socket_default=false
-               fi
-       fi
-fi
-
 dnl ===========================================
 dnl  check required libraries and header files
 dnl ===========================================
@@ -789,7 +776,6 @@ m4_include(m4/macros/add-plugin.m4)
 
 # plugin lists for all components
 charon_plugins=
-pluto_plugins=
 starter_plugins=
 pool_plugins=
 attest_plugins=
@@ -802,59 +788,57 @@ medsrv_plugins=
 nm_plugins=
 
 # location specific lists for checksumming,
-# for src/libcharon, src/pluto, src/libhydra and src/libstrongswan
+# for src/libcharon, src/libhydra and src/libstrongswan
 c_plugins=
-p_plugins=
 h_plugins=
 s_plugins=
 
-ADD_PLUGIN([test-vectors],         [s charon pluto openac scepclient pki])
-ADD_PLUGIN([curl],                 [s charon pluto scepclient scripts nm])
-ADD_PLUGIN([soup],                 [s charon pluto scripts nm])
-ADD_PLUGIN([ldap],                 [s charon pluto scepclient scripts nm])
-ADD_PLUGIN([mysql],                [s charon pluto pool manager medsrv attest])
-ADD_PLUGIN([sqlite],               [s charon pluto pool manager medsrv attest])
+ADD_PLUGIN([test-vectors],         [s charon openac scepclient pki])
+ADD_PLUGIN([curl],                 [s charon scepclient scripts nm])
+ADD_PLUGIN([soup],                 [s charon scripts nm])
+ADD_PLUGIN([ldap],                 [s charon scepclient scripts nm])
+ADD_PLUGIN([mysql],                [s charon pool manager medsrv attest])
+ADD_PLUGIN([sqlite],               [s charon pool manager medsrv attest])
 ADD_PLUGIN([pkcs11],               [s charon pki nm])
-ADD_PLUGIN([aes],                  [s charon pluto openac scepclient pki scripts nm])
-ADD_PLUGIN([des],                  [s charon pluto openac scepclient pki scripts nm])
-ADD_PLUGIN([blowfish],             [s charon pluto openac scepclient pki scripts nm])
-ADD_PLUGIN([sha1],                 [s charon pluto openac scepclient pki scripts medsrv attest nm])
-ADD_PLUGIN([sha2],                 [s charon pluto openac scepclient pki scripts medsrv attest nm])
+ADD_PLUGIN([aes],                  [s charon openac scepclient pki scripts nm])
+ADD_PLUGIN([des],                  [s charon openac scepclient pki scripts nm])
+ADD_PLUGIN([blowfish],             [s charon openac scepclient pki scripts nm])
+ADD_PLUGIN([sha1],                 [s charon openac scepclient pki scripts medsrv attest nm])
+ADD_PLUGIN([sha2],                 [s charon openac scepclient pki scripts medsrv attest nm])
 ADD_PLUGIN([md4],                  [s charon openac manager scepclient pki nm])
-ADD_PLUGIN([md5],                  [s charon pluto openac scepclient pki scripts attest nm])
-ADD_PLUGIN([random],               [s charon pluto openac scepclient pki scripts medsrv attest nm])
+ADD_PLUGIN([md5],                  [s charon openac scepclient pki scripts attest nm])
+ADD_PLUGIN([random],               [s charon openac scepclient pki scripts medsrv attest nm])
 ADD_PLUGIN([nonce],                [s charon nm])
-ADD_PLUGIN([x509],                 [s charon pluto openac scepclient pki scripts attest nm])
+ADD_PLUGIN([x509],                 [s charon openac scepclient pki scripts attest nm])
 ADD_PLUGIN([revocation],           [s charon nm])
 ADD_PLUGIN([constraints],          [s charon nm])
 ADD_PLUGIN([pubkey],               [s charon])
-ADD_PLUGIN([pkcs1],                [s charon pluto openac scepclient pki scripts manager medsrv attest nm])
-ADD_PLUGIN([pkcs8],                [s charon pluto openac scepclient pki scripts manager medsrv attest nm])
-ADD_PLUGIN([pgp],                  [s charon pluto])
-ADD_PLUGIN([dnskey],               [s pluto])
-ADD_PLUGIN([pem],                  [s charon pluto openac scepclient pki scripts manager medsrv attest nm])
+ADD_PLUGIN([pkcs1],                [s charon openac scepclient pki scripts manager medsrv attest nm])
+ADD_PLUGIN([pkcs8],                [s charon openac scepclient pki scripts manager medsrv attest nm])
+ADD_PLUGIN([pgp],                  [s charon])
+ADD_PLUGIN([dnskey],               [s charon])
+ADD_PLUGIN([pem],                  [s charon openac scepclient pki scripts manager medsrv attest nm])
 ADD_PLUGIN([padlock],              [s charon])
-ADD_PLUGIN([openssl],              [s charon pluto openac scepclient pki scripts manager medsrv attest nm])
-ADD_PLUGIN([gcrypt],               [s charon pluto openac scepclient pki scripts manager medsrv attest nm])
-ADD_PLUGIN([af-alg],               [s charon pluto openac scepclient pki scripts medsrv attest nm])
+ADD_PLUGIN([openssl],              [s charon openac scepclient pki scripts manager medsrv attest nm])
+ADD_PLUGIN([gcrypt],               [s charon openac scepclient pki scripts manager medsrv attest nm])
+ADD_PLUGIN([af-alg],               [s charon openac scepclient pki scripts medsrv attest nm])
 ADD_PLUGIN([fips-prf],             [s charon nm])
-ADD_PLUGIN([gmp],                  [s charon pluto openac scepclient pki scripts manager medsrv attest nm])
+ADD_PLUGIN([gmp],                  [s charon openac scepclient pki scripts manager medsrv attest nm])
 ADD_PLUGIN([agent],                [s charon nm])
 ADD_PLUGIN([xcbc],                 [s charon nm])
 ADD_PLUGIN([cmac],                 [s charon nm])
-ADD_PLUGIN([hmac],                 [s charon pluto scripts nm])
+ADD_PLUGIN([hmac],                 [s charon scripts nm])
 ADD_PLUGIN([ctr],                  [s charon scripts nm])
 ADD_PLUGIN([ccm],                  [s charon scripts nm])
 ADD_PLUGIN([gcm],                  [s charon scripts nm])
-ADD_PLUGIN([xauth],                [p pluto])
-ADD_PLUGIN([attr],                 [h charon pluto])
-ADD_PLUGIN([attr-sql],             [h charon pluto])
+ADD_PLUGIN([attr],                 [h charon])
+ADD_PLUGIN([attr-sql],             [h charon])
 ADD_PLUGIN([load-tester],          [c charon])
-ADD_PLUGIN([kernel-pfkey],         [h charon pluto starter nm])
-ADD_PLUGIN([kernel-pfroute],       [h charon pluto starter nm])
-ADD_PLUGIN([kernel-klips],         [h charon pluto starter])
-ADD_PLUGIN([kernel-netlink],       [h charon pluto starter nm])
-ADD_PLUGIN([resolve],              [h charon pluto])
+ADD_PLUGIN([kernel-pfkey],         [h charon starter nm])
+ADD_PLUGIN([kernel-pfroute],       [h charon starter nm])
+ADD_PLUGIN([kernel-klips],         [h charon starter])
+ADD_PLUGIN([kernel-netlink],       [h charon starter nm])
+ADD_PLUGIN([resolve],              [h charon])
 ADD_PLUGIN([socket-default],       [c charon nm])
 ADD_PLUGIN([socket-raw],           [c charon nm])
 ADD_PLUGIN([socket-dynamic],       [c charon])
@@ -907,7 +891,6 @@ ADD_PLUGIN([addrblock],            [c charon])
 ADD_PLUGIN([unit-tester],          [c charon])
 
 AC_SUBST(charon_plugins)
-AC_SUBST(pluto_plugins)
 AC_SUBST(starter_plugins)
 AC_SUBST(pool_plugins)
 AC_SUBST(attest_plugins)
@@ -1039,10 +1022,6 @@ AM_CONDITIONAL(USE_KERNEL_PFKEY, test x$kernel_pfkey = xtrue)
 AM_CONDITIONAL(USE_KERNEL_PFROUTE, test x$kernel_pfroute = xtrue)
 AM_CONDITIONAL(USE_RESOLVE, test x$resolve = xtrue)
 
-dnl pluto plugins
-dnl =============
-AM_CONDITIONAL(USE_XAUTH, test x$xauth = xtrue)
-
 dnl other options
 dnl =============
 AM_CONDITIONAL(USE_SMARTCARD, test x$smartcard = xtrue)
@@ -1058,7 +1037,6 @@ AM_CONDITIONAL(USE_MANAGER, test x$manager = xtrue)
 AM_CONDITIONAL(USE_ME, test x$mediation = xtrue)
 AM_CONDITIONAL(USE_INTEGRITY_TEST, test x$integrity_test = xtrue)
 AM_CONDITIONAL(USE_LOAD_WARNING, test x$load_warning = xtrue)
-AM_CONDITIONAL(USE_PLUTO, test x$pluto = xtrue)
 AM_CONDITIONAL(USE_IKEV1, test x$ikev1 = xtrue)
 AM_CONDITIONAL(USE_IKEV2, test x$ikev2 = xtrue)
 AM_CONDITIONAL(USE_THREADS, test x$threads = xtrue)
@@ -1068,13 +1046,13 @@ AM_CONDITIONAL(USE_NM, test x$nm = xtrue)
 AM_CONDITIONAL(USE_TOOLS, test x$tools = xtrue)
 AM_CONDITIONAL(USE_SCRIPTS, test x$scripts = xtrue)
 AM_CONDITIONAL(USE_CONFTEST, test x$conftest = xtrue)
-AM_CONDITIONAL(USE_LIBSTRONGSWAN, test x$charon = xtrue -o x$pluto = xtrue -o x$tools = xtrue -o x$conftest = xtrue -o x$fast = xtrue -o x$imcv = xtrue -o x$nm = xtrue)
-AM_CONDITIONAL(USE_LIBHYDRA, test x$charon = xtrue -o x$pluto = xtrue -o x$nm = xtrue)
+AM_CONDITIONAL(USE_LIBSTRONGSWAN, test x$charon = xtrue -o x$tools = xtrue -o x$conftest = xtrue -o x$fast = xtrue -o x$imcv = xtrue -o x$nm = xtrue)
+AM_CONDITIONAL(USE_LIBHYDRA, test x$charon = xtrue -o x$nm = xtrue)
 AM_CONDITIONAL(USE_LIBCHARON, test x$charon = xtrue -o x$conftest = xtrue -o x$nm = xtrue)
 AM_CONDITIONAL(USE_LIBTNCIF, test x$tnc_tnccs = xtrue -o x$imcv = xtrue)
 AM_CONDITIONAL(USE_LIBTNCCS, test x$tnc_tnccs = xtrue)
-AM_CONDITIONAL(USE_FILE_CONFIG, test x$pluto = xtrue -o x$stroke = xtrue)
-AM_CONDITIONAL(USE_IPSEC_SCRIPT, test x$pluto = xtrue -o x$stroke = xtrue -o x$tools = xtrue -o x$conftest = xtrue)
+AM_CONDITIONAL(USE_FILE_CONFIG, test x$stroke = xtrue)
+AM_CONDITIONAL(USE_IPSEC_SCRIPT, test x$stroke = xtrue -o x$tools = xtrue -o x$conftest = xtrue)
 AM_CONDITIONAL(USE_LIBCAP, test x$capabilities = xlibcap)
 AM_CONDITIONAL(USE_VSTR, test x$vstr = xtrue)
 AM_CONDITIONAL(USE_SIMAKA, test x$simaka = xtrue)
@@ -1162,7 +1140,6 @@ AC_OUTPUT(
        src/libhydra/plugins/kernel_pfkey/Makefile
        src/libhydra/plugins/kernel_pfroute/Makefile
        src/libhydra/plugins/resolve/Makefile
-       src/libfreeswan/Makefile
        src/libsimaka/Makefile
        src/libtls/Makefile
        src/libradius/Makefile
@@ -1176,9 +1153,6 @@ AC_OUTPUT(
        src/libimcv/plugins/imv_test/Makefile
        src/libimcv/plugins/imc_scanner/Makefile
        src/libimcv/plugins/imv_scanner/Makefile
-       src/pluto/Makefile
-       src/pluto/plugins/xauth/Makefile
-       src/whack/Makefile
        src/charon/Makefile
        src/charon-nm/Makefile
        src/libcharon/Makefile
index 0c19ea3a6289b257d177194e553c247271b9f718..452036b8b687a1a8dc41eb089fc8748e3924fb0c 100644 (file)
@@ -41,17 +41,13 @@ if USE_LIBCHARON
 endif
 
 if USE_FILE_CONFIG
-  SUBDIRS += libfreeswan starter
+  SUBDIRS += starter
 endif
 
 if USE_IPSEC_SCRIPT
   SUBDIRS += ipsec _copyright
 endif
 
-if USE_PLUTO
-  SUBDIRS += pluto whack
-endif
-
 if USE_CHARON
   SUBDIRS += charon
 endif
@@ -69,7 +65,7 @@ if USE_UPDOWN
 endif
 
 if USE_TOOLS
-  SUBDIRS += libfreeswan openac scepclient pki
+  SUBDIRS += openac scepclient pki
 endif
 
 if USE_CONFTEST
index 58292a45a2b93129ab16418b8f7ac5aec76ebb8d..0d0da5acf44bf3ebc2f1fb0dfd65d9c42b03d022 100644 (file)
@@ -79,11 +79,6 @@ if !MONOLITHIC
 endif
 endif
 
-if USE_PLUTO
-  exes += $(top_builddir)/src/pluto/.libs/pluto
-  AM_CFLAGS += -DP_PLUGINS=\""${p_plugins}\""
-endif
-
 if USE_TOOLS
   exes += $(top_builddir)/src/openac/.libs/openac
   exes += $(top_builddir)/src/pki/.libs/pki
diff --git a/src/libfreeswan/Android.mk b/src/libfreeswan/Android.mk
deleted file mode 100644 (file)
index a834d48..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-# copy-n-paste from Makefile.am
-LOCAL_SRC_FILES := \
-addrtoa.c addrtot.c addrtypeof.c anyaddr.c atoaddr.c atoasr.c \
-atosubnet.c atoul.c copyright.c datatot.c freeswan.h \
-goodmask.c initaddr.c initsaid.c initsubnet.c internal.h ipsec_param.h \
-pfkey_v2_build.c pfkey_v2_debug.c \
-pfkey_v2_ext_bits.c pfkey_v2_parse.c portof.c rangetoa.c \
-pfkey.h pfkeyv2.h rangetosubnet.c sameaddr.c \
-satot.c subnetof.c subnettoa.c subnettot.c \
-subnettypeof.c ttoaddr.c ttodata.c ttoprotoport.c ttosa.c ttosubnet.c ttoul.c \
-ultoa.c ultot.c
-
-# build libfreeswan ------------------------------------------------------------
-
-LOCAL_C_INCLUDES += \
-       $(libvstr_PATH) \
-       $(strongswan_PATH)/src/include \
-       $(strongswan_PATH)/src/libstrongswan \
-       $(strongswan_PATH)/src/libhydra \
-       $(strongswan_PATH)/src/pluto
-
-LOCAL_CFLAGS := $(strongswan_CFLAGS)
-
-LOCAL_MODULE := libfreeswan
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_ARM_MODE := arm
-
-LOCAL_PRELINK_MODULE := false
-
-LOCAL_SHARED_LIBRARIES += libstrongswan
-
-include $(BUILD_SHARED_LIBRARY)
-
diff --git a/src/libfreeswan/Makefile.am b/src/libfreeswan/Makefile.am
deleted file mode 100644 (file)
index b38343d..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-noinst_LIBRARIES = libfreeswan.a
-libfreeswan_a_SOURCES = \
-addrtoa.c addrtot.c addrtypeof.c anyaddr.c atoaddr.c atoasr.c \
-atosubnet.c atoul.c copyright.c datatot.c freeswan.h \
-goodmask.c initaddr.c initsaid.c initsubnet.c internal.h ipsec_param.h \
-pfkey_v2_build.c pfkey_v2_debug.c \
-pfkey_v2_ext_bits.c pfkey_v2_parse.c portof.c rangetoa.c \
-pfkey.h pfkeyv2.h rangetosubnet.c sameaddr.c \
-satot.c subnetof.c subnettoa.c subnettot.c \
-subnettypeof.c ttoaddr.c ttodata.c ttoprotoport.c ttosa.c ttosubnet.c ttoul.c \
-ultoa.c ultot.c
-
-INCLUDES = \
--I$(top_srcdir)/src/libstrongswan \
--I$(top_srcdir)/src/libhydra \
--I$(top_srcdir)/src/pluto
-
-dist_man3_MANS = anyaddr.3 atoaddr.3 atoasr.3 atoul.3 goodmask.3 initaddr.3 initsubnet.3 \
-                 portof.3 rangetosubnet.3 sameaddr.3 subnetof.3 \
-                 ttoaddr.3 ttodata.3 ttosa.3 ttoul.3
-
-EXTRA_DIST = Android.mk
diff --git a/src/libfreeswan/addrtoa.c b/src/libfreeswan/addrtoa.c
deleted file mode 100644 (file)
index e1c71da..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * addresses to ASCII
- * Copyright (C) 1998, 1999  Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
- * License for more details.
- */
-#include "internal.h"
-#include "freeswan.h"
-
-#define        NBYTES  4               /* bytes in an address */
-#define        PERBYTE 4               /* three digits plus a dot or NUL */
-#define        BUFLEN  (NBYTES*PERBYTE)
-
-#if BUFLEN != ADDRTOA_BUF
-#error "ADDRTOA_BUF in freeswan.h inconsistent with addrtoa() code"
-#endif
-
-/*
- - addrtoa - convert binary address to ASCII dotted decimal
- */
-size_t                         /* space needed for full conversion */
-addrtoa(addr, format, dst, dstlen)
-struct in_addr addr;
-int format;                    /* character */
-char *dst;                     /* need not be valid if dstlen is 0 */
-size_t dstlen;
-{
-       unsigned long a = ntohl(addr.s_addr);
-       int i;
-       size_t n;
-       unsigned long byte;
-       char buf[BUFLEN];
-       char *p;
-
-       switch (format) {
-       case 0:
-               break;
-       default:
-               return 0;
-               break;
-       }
-
-       p = buf;
-       for (i = NBYTES-1; i >= 0; i--) {
-               byte = (a >> (i*8)) & 0xff;
-               p += ultoa(byte, 10, p, PERBYTE);
-               if (i != 0)
-                       *(p-1) = '.';
-       }
-       n = p - buf;
-
-       if (dstlen > 0) {
-               if (n > dstlen)
-                       buf[dstlen - 1] = '\0';
-               strcpy(dst, buf);
-       }
-       return n;
-}
diff --git a/src/libfreeswan/addrtot.c b/src/libfreeswan/addrtot.c
deleted file mode 100644 (file)
index d1a3387..0000000
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * addresses to text
- * Copyright (C) 2000  Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
- * License for more details.
- */
-#include <sys/socket.h>
-
-#include "internal.h"
-#include "freeswan.h"
-
-#define        IP4BYTES        4       /* bytes in an IPv4 address */
-#define        PERBYTE         4       /* three digits plus a dot or NUL */
-#define        IP6BYTES        16      /* bytes in an IPv6 address */
-
-/* forwards */
-static size_t normal4(const unsigned char *s, size_t len, char *b, char **dp);
-static size_t normal6(const unsigned char *s, size_t len, char *b, char **dp, int squish);
-static size_t reverse4(const unsigned char *s, size_t len, char *b, char **dp);
-static size_t reverse6(const unsigned char *s, size_t len, char *b, char **dp);
-
-/*
- - addrtot - convert binary address to text (dotted decimal or IPv6 string)
- */
-size_t                         /* space needed for full conversion */
-addrtot(src, format, dst, dstlen)
-const ip_address *src;
-int format;                    /* character */
-char *dst;                     /* need not be valid if dstlen is 0 */
-size_t dstlen;
-{
-       const unsigned char *b;
-       size_t n;
-       char buf[1+ADDRTOT_BUF+1];      /* :address: */
-       char *p;
-       int t = addrtypeof(src);
-#      define  TF(t, f)        (((t)<<8) | (f))
-
-       n = addrbytesptr(src, &b);
-       if (n == 0)
-               return 0;
-
-       switch (TF(t, format)) {
-       case TF(AF_INET, 0):
-               n = normal4(b, n, buf, &p);
-               break;
-       case TF(AF_INET6, 0):
-               n = normal6(b, n, buf, &p, 1);
-               break;
-       case TF(AF_INET, 'Q'):
-               n = normal4(b, n, buf, &p);
-               break;
-       case TF(AF_INET6, 'Q'):
-               n = normal6(b, n, buf, &p, 0);
-               break;
-       case TF(AF_INET, 'r'):
-               n = reverse4(b, n, buf, &p);
-               break;
-       case TF(AF_INET6, 'r'):
-               n = reverse6(b, n, buf, &p);
-               break;
-       default:                /* including (AF_INET, 'R') */
-               return 0;
-               break;
-       }
-
-       if (dstlen > 0) {
-               if (dstlen < n)
-                       p[dstlen - 1] = '\0';
-               strcpy(dst, p);
-       }
-       return n;
-}
-
-/*
- - normal4 - normal IPv4 address-text conversion
- */
-static size_t                  /* size of text, including NUL */
-normal4(srcp, srclen, buf, dstp)
-const unsigned char *srcp;
-size_t srclen;
-char *buf;                     /* guaranteed large enough */
-char **dstp;                   /* where to put result pointer */
-{
-       int i;
-       char *p;
-
-       if (srclen != IP4BYTES) /* "can't happen" */
-               return 0;
-       p = buf;
-       for (i = 0; i < IP4BYTES; i++) {
-               p += ultot(srcp[i], 10, p, PERBYTE);
-               if (i != IP4BYTES - 1)
-                       *(p-1) = '.';   /* overwrites the NUL */
-       }
-       *dstp = buf;
-       return p - buf;
-}
-
-/*
- - normal6 - normal IPv6 address-text conversion
- */
-static size_t                  /* size of text, including NUL */
-normal6(srcp, srclen, buf, dstp, squish)
-const unsigned char *srcp;
-size_t srclen;
-char *buf;                     /* guaranteed large enough, plus 2 */
-char **dstp;                   /* where to put result pointer */
-int    squish;                  /* whether to squish out 0:0 */
-{
-       int i;
-       unsigned long piece;
-       char *p;
-       char *q;
-
-       if (srclen != IP6BYTES) /* "can't happen" */
-               return 0;
-       p = buf;
-       *p++ = ':';
-       for (i = 0; i < IP6BYTES/2; i++) {
-               piece = (srcp[2*i] << 8) + srcp[2*i + 1];
-               p += ultot(piece, 16, p, 5);    /* 5 = abcd + NUL */
-               *(p-1) = ':';   /* overwrites the NUL */
-       }
-       *p = '\0';
-       q = strstr(buf, ":0:0:");
-       if (squish && q != NULL) {      /* zero squishing is possible */
-               p = q + 1;
-               while (*p == '0' && *(p+1) == ':')
-                       p += 2;
-               q++;
-               *q++ = ':';     /* overwrite first 0 */
-               while (*p != '\0')
-                       *q++ = *p++;
-               *q = '\0';
-               if (!(*(q-1) == ':' && *(q-2) == ':'))
-                       *--q = '\0';    /* strip final : unless :: */
-               p = buf;
-               if (!(*p == ':' && *(p+1) == ':'))
-                       p++;    /* skip initial : unless :: */
-       } else {
-               q = p;
-               *--q = '\0';    /* strip final : */
-               p = buf + 1;    /* skip initial : */
-       }
-       *dstp = p;
-       return q - p + 1;
-}
-
-/*
- - reverse4 - IPv4 reverse-lookup conversion
- */
-static size_t                  /* size of text, including NUL */
-reverse4(srcp, srclen, buf, dstp)
-const unsigned char *srcp;
-size_t srclen;
-char *buf;                     /* guaranteed large enough */
-char **dstp;                   /* where to put result pointer */
-{
-       int i;
-       char *p;
-
-       if (srclen != IP4BYTES) /* "can't happen" */
-               return 0;
-       p = buf;
-       for (i = IP4BYTES-1; i >= 0; i--) {
-               p += ultot(srcp[i], 10, p, PERBYTE);
-               *(p-1) = '.';   /* overwrites the NUL */
-       }
-       strcpy(p, "IN-ADDR.ARPA.");
-       *dstp = buf;
-       return strlen(buf) + 1;
-}
-
-/*
- - reverse6 - IPv6 reverse-lookup conversion (RFC 1886)
- * A trifle inefficient, really shouldn't use ultot...
- */
-static size_t                  /* size of text, including NUL */
-reverse6(srcp, srclen, buf, dstp)
-const unsigned char *srcp;
-size_t srclen;
-char *buf;                     /* guaranteed large enough */
-char **dstp;                   /* where to put result pointer */
-{
-       int i;
-       unsigned long piece;
-       char *p;
-
-       if (srclen != IP6BYTES) /* "can't happen" */
-               return 0;
-       p = buf;
-       for (i = IP6BYTES-1; i >= 0; i--) {
-               piece = srcp[i];
-               p += ultot(piece&0xf, 16, p, 2);
-               *(p-1) = '.';
-               p += ultot(piece>>4, 16, p, 2);
-               *(p-1) = '.';
-       }
-       strcpy(p, "IP6.ARPA.");
-       *dstp = buf;
-       return strlen(buf) + 1;
-}
-
-/*
- - reverse6 - modern IPv6 reverse-lookup conversion (RFC 2874)
- * this version removed as it was obsoleted in the end.
- */
-
-#ifdef ADDRTOT_MAIN
-
-#include <stdio.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-void regress(void);
-
-int
-main(int argc, char *argv[])
-{
-       if (argc < 2) {
-               fprintf(stderr, "Usage: %s {addr|net/mask|begin...end|-r}\n",
-                                                               argv[0]);
-               exit(2);
-       }
-
-       if (strcmp(argv[1], "-r") == 0) {
-               regress();
-               fprintf(stderr, "regress() returned?!?\n");
-               exit(1);
-       }
-       exit(0);
-}
-
-struct rtab {
-       char *input;
-        char  format;
-       char *output;                   /* NULL means error expected */
-} rtab[] = {
-       {"1.2.3.0",                     0, "1.2.3.0"},
-       {"1:2::3:4",                    0, "1:2::3:4"},
-       {"1:2::3:4",                   'Q', "1:2:0:0:0:0:3:4"},
-       {"1:2:0:0:3:4:0:0",             0, "1:2::3:4:0:0"},
-       {"1.2.3.4",                    'r' , "4.3.2.1.IN-ADDR.ARPA."},
-       /*                                    0 1 2 3 4 5 6 7 8 9 a b c d e f 0 1 2 3 4 5 6 7 8 9 a b c d e f */
-       {"1:2::3:4",                   'r', "4.0.0.0.3.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.1.0.0.0.IP6.ARPA."},
-        {NULL,                         0, NULL}
-};
-
-void
-regress()
-{
-       struct rtab *r;
-       int status = 0;
-       ip_address a;
-       char in[100];
-       char buf[100];
-       const char *oops;
-       size_t n;
-
-       for (r = rtab; r->input != NULL; r++) {
-               strcpy(in, r->input);
-
-               /* convert it *to* internal format */
-               oops = ttoaddr(in, strlen(in), 0, &a);
-
-               /* now convert it back */
-
-               n = addrtot(&a, r->format, buf, sizeof(buf));
-
-               if (n == 0 && r->output == NULL)
-                       {}              /* okay, error expected */
-
-               else if (n == 0) {
-                       printf("`%s' atoasr failed\n", r->input);
-                       status = 1;
-
-               } else if (r->output == NULL) {
-                       printf("`%s' atoasr succeeded unexpectedly '%c'\n",
-                                                       r->input, r->format);
-                       status = 1;
-               } else {
-                 if (strcasecmp(r->output, buf) != 0) {
-                   printf("`%s' '%c' gave `%s', expected `%s'\n",
-                          r->input, r->format, buf, r->output);
-                   status = 1;
-                 }
-               }
-       }
-       exit(status);
-}
-
-#endif /* ADDRTOT_MAIN */
diff --git a/src/libfreeswan/addrtypeof.c b/src/libfreeswan/addrtypeof.c
deleted file mode 100644 (file)
index ee3cc99..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * extract parts of an ip_address
- * Copyright (C) 2000  Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
- * License for more details.
- */
-#include <sys/socket.h>
-
-#include "internal.h"
-#include "freeswan.h"
-
-/*
- - addrtypeof - get the type of an ip_address
- */
-int
-addrtypeof(src)
-const ip_address *src;
-{
-       return src->u.v4.sin_family;
-}
-
-/*
- - addrbytesptr - get pointer to the address bytes of an ip_address
- */
-size_t                         /* 0 for error */
-addrbytesptr(src, dstp)
-const ip_address *src;
-const unsigned char **dstp;    /* NULL means just a size query */
-{
-       const unsigned char *p;
-       size_t n;
-
-       switch (src->u.v4.sin_family) {
-       case AF_INET:
-               p = (const unsigned char *)&src->u.v4.sin_addr.s_addr;
-               n = 4;
-               break;
-       case AF_INET6:
-               p = (const unsigned char *)&src->u.v6.sin6_addr;
-               n = 16;
-               break;
-       default:
-               return 0;
-               break;
-       }
-
-       if (dstp != NULL)
-               *dstp = p;
-       return n;
-}
-
-/*
- - addrlenof - get length of the address bytes of an ip_address
- */
-size_t                         /* 0 for error */
-addrlenof(src)
-const ip_address *src;
-{
-       return addrbytesptr(src, NULL);
-}
-
-/*
- - addrbytesof - get the address bytes of an ip_address
- */
-size_t                         /* 0 for error */
-addrbytesof(src, dst, dstlen)
-const ip_address *src;
-unsigned char *dst;
-size_t dstlen;
-{
-       const unsigned char *p;
-       size_t n;
-       size_t ncopy;
-
-       n = addrbytesptr(src, &p);
-       if (n == 0)
-               return 0;
-
-       if (dstlen > 0) {
-               ncopy = n;
-               if (ncopy > dstlen)
-                       ncopy = dstlen;
-               memcpy(dst, p, ncopy);
-       }
-       return n;
-}
diff --git a/src/libfreeswan/anyaddr.3 b/src/libfreeswan/anyaddr.3
deleted file mode 100644 (file)
index 58789cf..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-.TH IPSEC_ANYADDR 3 "8 Sept 2000"
-.SH NAME
-ipsec anyaddr \- get "any" address
-.br
-ipsec isanyaddr \- test address for equality to "any" address
-.br
-ipsec unspecaddr \- get "unspecified" address
-.br
-ipsec isunspecaddr \- test address for equality to "unspecified" address
-.br
-ipsec loopbackaddr \- get loopback address
-.br
-ipsec isloopbackaddr \- test address for equality to loopback address
-.SH SYNOPSIS
-.B "#include <freeswan.h>
-.sp
-.B "const char *anyaddr(int af, ip_address *dst);"
-.br
-.B "int isanyaddr(const ip_address *src);"
-.br
-.B "const char *unspecaddr(int af, ip_address *dst);"
-.br
-.B "int isunspecaddr(const ip_address *src);"
-.br
-.B "const char *loopbackaddr(int af, ip_address *dst);"
-.br
-.B "int isloopbackaddr(const ip_address *src);"
-.SH DESCRIPTION
-These functions fill in, and test for, special values of the
-.I ip_address
-type.
-.PP
-.I Anyaddr
-fills in the destination
-.I *dst
-with the ``any'' address of address family
-.IR af
-(normally
-.B AF_INET
-or
-.BR AF_INET6 ).
-The IPv4 ``any'' address is the one embodied in the old
-.B INADDR_ANY
-macro.
-.PP
-.I Isanyaddr
-returns
-.B 1
-if the
-.I src
-address equals the ``any'' address,
-and
-.B 0
-otherwise.
-.PP
-Similarly,
-.I unspecaddr
-supplies, and
-.I isunspecaddr
-tests for,
-the ``unspecified'' address,
-which may be the same as the ``any'' address.
-.PP
-Similarly,
-.I loopbackaddr
-supplies, and
-.I islookbackaddr
-tests for,
-the loopback address.
-.PP
-.IR Anyaddr ,
-.IR unspecaddr ,
-and
-.I loopbackaddr
-return
-.B NULL
-for success and
-a pointer to a string-literal error message for failure;
-see DIAGNOSTICS.
-.SH SEE ALSO
-inet(3), ipsec_addrtot(3), ipsec_sameaddr(3)
-.SH DIAGNOSTICS
-Fatal errors in the address-supplying functions are:
-unknown address family.
-.SH HISTORY
-Written for the FreeS/WAN project by Henry Spencer.
diff --git a/src/libfreeswan/anyaddr.c b/src/libfreeswan/anyaddr.c
deleted file mode 100644 (file)
index 5b7691b..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * special addresses
- * Copyright (C) 2000  Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
- * License for more details.
- */
-#include <sys/socket.h>
-
-#include "internal.h"
-#include "freeswan.h"
-
-/* OpenSolaris defines strange versions of these macros */
-#ifdef __sun
-#undef IN6ADDR_ANY_INIT
-#define        IN6ADDR_ANY_INIT                {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }}}
-
-#undef IN6ADDR_LOOPBACK_INIT
-#define        IN6ADDR_LOOPBACK_INIT   {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }}}
-#endif
-
-static struct in6_addr v6any = IN6ADDR_ANY_INIT;
-static struct in6_addr v6loop = IN6ADDR_LOOPBACK_INIT;
-
-/*
- - anyaddr - initialize to the any-address value
- */
-err_t                          /* NULL for success, else string literal */
-anyaddr(af, dst)
-int af;                                /* address family */
-ip_address *dst;
-{
-       uint32_t v4any = htonl(INADDR_ANY);
-
-       switch (af) {
-       case AF_INET:
-               return initaddr((unsigned char *)&v4any, sizeof(v4any), af, dst);
-               break;
-       case AF_INET6:
-               return initaddr((unsigned char *)&v6any, sizeof(v6any), af, dst);
-               break;
-       default:
-               return "unknown address family in anyaddr/unspecaddr";
-               break;
-       }
-}
-
-/*
- - unspecaddr - initialize to the unspecified-address value
- */
-err_t                          /* NULL for success, else string literal */
-unspecaddr(af, dst)
-int af;                                /* address family */
-ip_address *dst;
-{
-       return anyaddr(af, dst);
-}
-
-/*
- - loopbackaddr - initialize to the loopback-address value
- */
-err_t                          /* NULL for success, else string literal */
-loopbackaddr(af, dst)
-int af;                                /* address family */
-ip_address *dst;
-{
-       uint32_t v4loop = htonl(INADDR_LOOPBACK);
-
-       switch (af) {
-       case AF_INET:
-               return initaddr((unsigned char *)&v4loop, sizeof(v4loop), af, dst);
-               break;
-       case AF_INET6:
-               return initaddr((unsigned char *)&v6loop, sizeof(v6loop), af, dst);
-               break;
-       default:
-               return "unknown address family in loopbackaddr";
-               break;
-       }
-}
-
-/*
- - isanyaddr - test for the any-address value
- */
-int
-isanyaddr(src)
-const ip_address *src;
-{
-       uint32_t v4any = htonl(INADDR_ANY);
-       int cmp;
-
-       switch (src->u.v4.sin_family) {
-       case AF_INET:
-               cmp = memcmp(&src->u.v4.sin_addr.s_addr, &v4any, sizeof(v4any));
-               break;
-       case AF_INET6:
-               cmp = memcmp(&src->u.v6.sin6_addr, &v6any, sizeof(v6any));
-               break;
-       default:
-               return 0;
-               break;
-       }
-
-       return (cmp == 0) ? 1 : 0;
-}
-
-/*
- - isunspecaddr - test for the unspecified-address value
- */
-int
-isunspecaddr(src)
-const ip_address *src;
-{
-       return isanyaddr(src);
-}
-
-/*
- - isloopbackaddr - test for the loopback-address value
- */
-int
-isloopbackaddr(src)
-const ip_address *src;
-{
-       uint32_t v4loop = htonl(INADDR_LOOPBACK);
-       int cmp;
-
-       switch (src->u.v4.sin_family) {
-       case AF_INET:
-               cmp = memcmp(&src->u.v4.sin_addr.s_addr, &v4loop, sizeof(v4loop));
-               break;
-       case AF_INET6:
-               cmp = memcmp(&src->u.v6.sin6_addr, &v6loop, sizeof(v6loop));
-               break;
-       default:
-               return 0;
-               break;
-       }
-
-       return (cmp == 0) ? 1 : 0;
-}
diff --git a/src/libfreeswan/atoaddr.3 b/src/libfreeswan/atoaddr.3
deleted file mode 100644 (file)
index 10da269..0000000
+++ /dev/null
@@ -1,291 +0,0 @@
-.TH IPSEC_ATOADDR 3 "11 June 2001"
-.SH NAME
-ipsec atoaddr, addrtoa \- convert Internet addresses to and from ASCII
-.br
-ipsec atosubnet, subnettoa \- convert subnet/mask ASCII form to and from addresses
-.SH SYNOPSIS
-.B "#include <freeswan.h>
-.sp
-.B "const char *atoaddr(const char *src, size_t srclen,"
-.ti +1c
-.B "struct in_addr *addr);"
-.br
-.B "size_t addrtoa(struct in_addr addr, int format,"
-.ti +1c
-.B "char *dst, size_t dstlen);"
-.sp
-.B "const char *atosubnet(const char *src, size_t srclen,"
-.ti +1c
-.B "struct in_addr *addr, struct in_addr *mask);"
-.br
-.B "size_t subnettoa(struct in_addr addr, struct in_addr mask,"
-.ti +1c
-.B "int format, char *dst, size_t dstlen);"
-.SH DESCRIPTION
-These functions are obsolete; see
-.IR ipsec_ttoaddr (3)
-for their replacements.
-.PP
-.I Atoaddr
-converts an ASCII name or dotted-decimal address into a binary address
-(in network byte order).
-.I Addrtoa
-does the reverse conversion, back to an ASCII dotted-decimal address.
-.I Atosubnet
-and
-.I subnettoa
-do likewise for the ``address/mask'' ASCII form used to write a
-specification of a subnet.
-.PP
-An address is specified in ASCII as a
-dotted-decimal address (e.g.
-.BR 1.2.3.4 ),
-an eight-digit network-order hexadecimal number with the usual C prefix (e.g.
-.BR 0x01020304 ,
-which is synonymous with
-.BR 1.2.3.4 ),
-an eight-digit host-order hexadecimal number with a
-.B 0h
-prefix (e.g.
-.BR 0h01020304 ,
-which is synonymous with
-.B 1.2.3.4
-on a big-endian host and
-.B 4.3.2.1
-on a little-endian host),
-a DNS name to be looked up via
-.IR getaddrinfo (3),
-or an old-style network name to be looked up via
-.IR getnetbyname (3).
-.PP
-A dotted-decimal address may be incomplete, in which case
-ASCII-to-binary conversion implicitly appends
-as many instances of
-.B .0
-as necessary to bring it up to four components.
-The components of a dotted-decimal address are always taken as
-decimal, and leading zeros are ignored.
-For example,
-.B 10
-is synonymous with
-.BR 10.0.0.0 ,
-and
-.B 128.009.000.032
-is synonymous with
-.BR 128.9.0.32
-(the latter example is verbatim from RFC 1166).
-The result of
-.I addrtoa
-is always complete and does not contain leading zeros.
-.PP
-The letters in
-a hexadecimal address may be uppercase or lowercase or any mixture thereof.
-Use of hexadecimal addresses is
-.B strongly
-.BR discouraged ;
-they are included only to save hassles when dealing with
-the handful of perverted programs which already print 
-network addresses in hexadecimal.
-.PP
-DNS names may be complete (optionally terminated with a ``.'')
-or incomplete, and are looked up as specified by local system configuration
-(see
-.IR resolver (5)).
-The first value returned by
-.IR getaddrinfo (3)
-is used,
-so with current DNS implementations,
-the result when the name corresponds to more than one address is
-difficult to predict.
-Name lookup resorts to
-.IR getnetbyname (3)
-only if
-.IR getaddrinfo (3)
-fails.
-.PP
-A subnet specification is of the form \fInetwork\fB/\fImask\fR.
-The
-.I network
-and
-.I mask
-can be any form acceptable to
-.IR atoaddr .
-In addition, the
-.I mask
-can be a decimal integer (leading zeros ignored) giving a bit count,
-in which case
-it stands for a mask with that number of high bits on and all others off
-(e.g.,
-.B 24
-means
-.BR 255.255.255.0 ).
-In any case, the mask must be contiguous
-(a sequence of high bits on and all remaining low bits off).
-As a special case, the subnet specification
-.B %default
-is a synonym for
-.BR 0.0.0.0/0 .
-.PP
-.I Atosubnet
-ANDs the mask with the address before returning,
-so that any non-network bits in the address are turned off
-(e.g.,
-.B 10.1.2.3/24
-is synonymous with
-.BR 10.1.2.0/24 ).
-.I Subnettoa
-generates the decimal-integer-bit-count
-form of the mask,
-with no leading zeros,
-unless the mask is non-contiguous.
-.PP
-The
-.I srclen
-parameter of
-.I atoaddr
-and
-.I atosubnet
-specifies the length of the ASCII string pointed to by
-.IR src ;
-it is an error for there to be anything else
-(e.g., a terminating NUL) within that length.
-As a convenience for cases where an entire NUL-terminated string is
-to be converted,
-a
-.I srclen
-value of
-.B 0
-is taken to mean
-.BR strlen(src) .
-.PP
-The
-.I dstlen
-parameter of
-.I addrtoa
-and
-.I subnettoa
-specifies the size of the
-.I dst
-parameter;
-under no circumstances are more than
-.I dstlen
-bytes written to
-.IR dst .
-A result which will not fit is truncated.
-.I Dstlen
-can be zero, in which case
-.I dst
-need not be valid and no result is written,
-but the return value is unaffected;
-in all other cases, the (possibly truncated) result is NUL-terminated.
-The
-.I freeswan.h
-header file defines constants,
-.B ADDRTOA_BUF
-and
-.BR SUBNETTOA_BUF ,
-which are the sizes of buffers just large enough for worst-case results.
-.PP
-The
-.I format
-parameter of
-.I addrtoa
-and
-.I subnettoa
-specifies what format is to be used for the conversion.
-The value
-.B 0
-(not the ASCII character
-.BR '0' ,
-but a zero value)
-specifies a reasonable default,
-and is in fact the only format currently available.
-This parameter is a hedge against future needs.
-.PP
-The ASCII-to-binary functions return NULL for success and
-a pointer to a string-literal error message for failure;
-see DIAGNOSTICS.
-The binary-to-ASCII functions return
-.B 0
-for a failure, and otherwise
-always return the size of buffer which would 
-be needed to
-accommodate the full conversion result, including terminating NUL;
-it is the caller's responsibility to check this against the size of
-the provided buffer to determine whether truncation has occurred.
-.SH SEE ALSO
-inet(3)
-.SH DIAGNOSTICS
-Fatal errors in
-.I atoaddr
-are:
-empty input;
-attempt to allocate temporary storage for a very long name failed;
-name lookup failed;
-syntax error in dotted-decimal form;
-dotted-decimal component too large to fit in 8 bits.
-.PP
-Fatal errors in
-.I atosubnet
-are:
-no
-.B /
-in
-.IR src ;
-.I atoaddr
-error in conversion of
-.I network
-or
-.IR mask ;
-bit-count mask too big;
-mask non-contiguous.
-.PP
-Fatal errors in
-.I addrtoa
-and
-.I subnettoa
-are:
-unknown format.
-.SH HISTORY
-Written for the FreeS/WAN project by Henry Spencer.
-.SH BUGS
-The interpretation of incomplete dotted-decimal addresses
-(e.g.
-.B 10/24
-means
-.BR 10.0.0.0/24 )
-differs from that of some older conversion
-functions, e.g. those of
-.IR inet (3).
-The behavior of the older functions has never been
-particularly consistent or particularly useful.
-.PP
-Ignoring leading zeros in dotted-decimal components and bit counts
-is arguably the most useful behavior in this application,
-but it might occasionally cause confusion with the historical use of leading 
-zeros to denote octal numbers.
-.PP
-It is barely possible that somebody, somewhere,
-might have a legitimate use for non-contiguous subnet masks.
-.PP
-.IR Getnetbyname (3)
-is a historical dreg.
-.PP
-The restriction of ASCII-to-binary error reports to literal strings
-(so that callers don't need to worry about freeing them or copying them)
-does limit the precision of error reporting.
-.PP
-The ASCII-to-binary error-reporting convention lends itself
-to slightly obscure code,
-because many readers will not think of NULL as signifying success.
-A good way to make it clearer is to write something like:
-.PP
-.RS
-.nf
-.B "const char *error;"
-.sp
-.B "error = atoaddr( /* ... */ );"
-.B "if (error != NULL) {"
-.B "        /* something went wrong */"
-.fi
-.RE
diff --git a/src/libfreeswan/atoaddr.c b/src/libfreeswan/atoaddr.c
deleted file mode 100644 (file)
index a364380..0000000
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * conversion from ASCII forms of addresses to internal ones
- * Copyright (C) 1998, 1999  Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
- * License for more details.
- */
-#include <sys/socket.h>
-
-#include "internal.h"
-#include "freeswan.h"
-
-/*
- * Define NOLEADINGZEROS to interpret 032 as an error, not as 32.  There
- * is deliberately no way to interpret it as 26 (i.e., as octal).
- */
-
-/*
- * Legal characters in a domain name.  Underscore technically is not,
- * but is a common misunderstanding.
- */
-static const char namechars[] = "abcdefghijklmnopqrstuvwxyz0123456789"
-                               "ABCDEFGHIJKLMNOPQRSTUVWXYZ-_.";
-
-static const char *try8hex(const char *, size_t, struct in_addr *);
-static const char *try8hosthex(const char *, size_t, struct in_addr *);
-static const char *trydotted(const char *, size_t, struct in_addr *);
-static const char *getbyte(const char **, const char *, int *);
-
-/*
- - atoaddr - convert ASCII name or dotted-decimal address to binary address
- */
-const char *                   /* NULL for success, else string literal */
-atoaddr(src, srclen, addrp)
-const char *src;
-size_t srclen;                 /* 0 means "apply strlen" */
-struct in_addr *addrp;
-{
-       struct addrinfo hints, *res;
-       struct netent *ne = NULL;
-       const char *oops, *msg = NULL;
-#      define  HEXLEN  10      /* strlen("0x11223344") */
-#      ifndef ATOADDRBUF
-#      define  ATOADDRBUF      100
-#      endif
-       char namebuf[ATOADDRBUF];
-       char *p = namebuf;
-       char *q;
-       int error;
-
-       if (srclen == 0)
-               srclen = strlen(src);
-       if (srclen == 0)
-               return "empty string";
-
-       /* might it be hex? */
-       if (srclen == HEXLEN && *src == '0' && CIEQ(*(src+1), 'x'))
-               return try8hex(src+2, srclen-2, addrp);
-       if (srclen == HEXLEN && *src == '0' && CIEQ(*(src+1), 'h'))
-               return try8hosthex(src+2, srclen-2, addrp);
-
-       /* try it as dotted decimal */
-       oops = trydotted(src, srclen, addrp);
-       if (oops == NULL)
-               return NULL;            /* it worked */
-       if (*oops != '?')
-               return oops;            /* it *was* probably meant as a d.q. */
-
-       /* try it as a name -- first, NUL-terminate it */
-       if (srclen > sizeof(namebuf)-1) {
-               p = (char *) MALLOC(srclen+1);
-               if (p == NULL)
-                       return "unable to allocate temporary space for name";
-       }
-       p[0] = '\0';
-       strncat(p, src, srclen);
-
-       /* next, check that it's a vaguely legal name */
-       for (q = p; *q != '\0'; q++)
-       {
-               if (!isprint(*q))
-               {
-                       msg = "unprintable character in name";
-                       goto error;
-               }
-       }
-       if (strspn(p, namechars) != srclen)
-       {
-               msg = "illegal (non-DNS-name) character in name";
-               goto error;
-       }
-
-       /* try as host name, failing that as /etc/networks network name */
-       memset(&hints, 0, sizeof(hints));
-       hints.ai_family = AF_INET;
-       error = getaddrinfo(p, NULL, &hints, &res);
-       if (error != 0)
-       {
-               ne = getnetbyname(p);
-               if (ne == NULL)
-               {
-                       msg = "name lookup failed";
-                       goto error;
-               }
-               addrp->s_addr = htonl(ne->n_net);
-       }
-       else
-       {
-               struct sockaddr_in *in = (struct sockaddr_in*)res->ai_addr;
-               memcpy(&addrp->s_addr, &in->sin_addr.s_addr, sizeof(addrp->s_addr));
-               freeaddrinfo(res);
-       }
-
-error:
-       if (p != namebuf)
-       {
-               FREE(p);
-       }
-
-       return msg;
-}
-
-/*
- - try8hosthex - try conversion as an eight-digit host-order hex number
- */
-const char *                   /* NULL for success, else string literal */
-try8hosthex(src, srclen, addrp)
-const char *src;
-size_t srclen;                 /* should be 8 */
-struct in_addr *addrp;
-{
-       const char *oops;
-       unsigned long addr;
-
-       if (srclen != 8)
-               return "internal error, try8hex called with bad length";
-
-       oops = atoul(src, srclen, 16, &addr);
-       if (oops != NULL)
-               return oops;
-
-       addrp->s_addr = addr;
-       return NULL;
-}
-
-/*
- - try8hex - try conversion as an eight-digit network-order hex number
- */
-const char *                   /* NULL for success, else string literal */
-try8hex(src, srclen, addrp)
-const char *src;
-size_t srclen;                 /* should be 8 */
-struct in_addr *addrp;
-{
-       const char *oops;
-
-       oops = try8hosthex(src, srclen, addrp);
-       if (oops != NULL)
-               return oops;
-
-       addrp->s_addr = htonl(addrp->s_addr);
-       return NULL;
-}
-
-/*
- - trydotted - try conversion as dotted decimal
- *
- * If the first char of a complaint is '?', that means "didn't look like
- * dotted decimal at all".
- */
-const char *                   /* NULL for success, else string literal */
-trydotted(src, srclen, addrp)
-const char *src;
-size_t srclen;
-struct in_addr *addrp;
-{
-       const char *stop = src + srclen;        /* just past end */
-       int byte;
-       const char *oops;
-       unsigned long addr;
-       int i;
-#      define  NBYTES  4
-#      define  BYTE    8
-
-       addr = 0;
-       for (i = 0; i < NBYTES && src < stop; i++) {
-               oops = getbyte(&src, stop, &byte);
-               if (oops != NULL) {
-                       if (*oops != '?')
-                               return oops;    /* bad number */
-                       if (i > 1)
-                               return oops+1;  /* failed number */
-                       return oops;            /* with leading '?' */
-               }
-               addr = (addr << BYTE) | byte;
-               if (i < 3 && src < stop && *src++ != '.') {
-                       if (i == 0)
-                               return "?syntax error in dotted-decimal address";
-                       else
-                               return "syntax error in dotted-decimal address";
-               }
-       }
-       addr <<= (NBYTES - i) * BYTE;
-       if (src != stop)
-               return "extra garbage on end of dotted-decimal address";
-
-       addrp->s_addr = htonl(addr);
-       return NULL;
-}
-
-/*
- - getbyte - try to scan a byte in dotted decimal
- * A subtlety here is that all this arithmetic on ASCII digits really is
- * highly portable -- ANSI C guarantees that digits 0-9 are contiguous.
- * It's easier to just do it ourselves than set up for a call to atoul().
- *
- * If the first char of a complaint is '?', that means "didn't look like a
- * number at all".
- */
-const char *                   /* NULL for success, else string literal */
-getbyte(srcp, stop, retp)
-const char **srcp;             /* *srcp is updated */
-const char *stop;              /* first untouchable char */
-int *retp;                     /* return-value pointer */
-{
-       char c;
-       const char *p;
-       int no;
-
-       if (*srcp >= stop)
-               return "?empty number in dotted-decimal address";
-
-       if (stop - *srcp >= 3 && **srcp == '0' && CIEQ(*(*srcp+1), 'x'))
-               return "hex numbers not supported in dotted-decimal addresses";
-#ifdef NOLEADINGZEROS
-       if (stop - *srcp >= 2 && **srcp == '0' && isdigit(*(*srcp+1)))
-               return "octal numbers not supported in dotted-decimal addresses";
-#endif /* NOLEADINGZEROS */
-
-       /* must be decimal, if it's numeric at all */
-       no = 0;
-       p = *srcp;
-       while (p < stop && no <= 255 && (c = *p) >= '0' && c <= '9') {
-               no = no*10 + (c - '0');
-               p++;
-       }
-       if (p == *srcp)
-               return "?non-numeric component in dotted-decimal address";
-       *srcp = p;
-       if (no > 255)
-               return "byte overflow in dotted-decimal address";
-       *retp = no;
-       return NULL;
-}
diff --git a/src/libfreeswan/atoasr.3 b/src/libfreeswan/atoasr.3
deleted file mode 100644 (file)
index 0b9a5fe..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-.TH IPSEC_ATOASR 3 "11 June 2001"
-.SH NAME
-ipsec atoasr \- convert ASCII to Internet address, subnet, or range
-.br
-ipsec rangetoa \- convert Internet address range to ASCII
-.SH SYNOPSIS
-.B "#include <freeswan.h>
-.sp
-.B "const char *atoasr(const char *src, size_t srclen,"
-.ti +1c
-.B "char *type, struct in_addr *addrs);"
-.br
-.B "size_t rangetoa(struct in_addr *addrs, int format,
-.ti +1c
-.B "char *dst, size_t dstlen);"
-.SH DESCRIPTION
-These functions are obsolete;
-there is no current equivalent,
-because so far they have not proved useful.
-.PP
-.I Atoasr
-converts an ASCII address, subnet, or address range
-into a suitable combination of binary addresses
-(in network byte order).
-.I Rangetoa
-converts an address range back into ASCII,
-using dotted-decimal form for the addresses
-(the other reverse conversions are handled by
-.IR ipsec_addrtoa (3)
-and
-.IR ipsec_subnettoa (3)).
-.PP
-A single address can be any form acceptable to
-.IR ipsec_atoaddr (3):
-dotted decimal, DNS name, or hexadecimal number.
-A subnet
-specification uses the form \fInetwork\fB/\fImask\fR
-interpreted by
-.IR ipsec_atosubnet (3).
-.PP
-An address range is two
-.IR ipsec_atoaddr (3)
-addresses separated by a
-.B ...
-delimiter.
-If there are four dots rather than three, the first is taken as
-part of the begin address,
-e.g. for a complete DNS name which ends with
-.B .
-to suppress completion attempts.
-The begin address of a range must be
-less than or equal to the end address.
-.PP
-The
-.I srclen
-parameter of
-.I atoasr
-specifies the length of the ASCII string pointed to by
-.IR src ;
-it is an error for there to be anything else
-(e.g., a terminating NUL) within that length.
-As a convenience for cases where an entire NUL-terminated string is
-to be converted,
-a
-.I srclen
-value of
-.B 0
-is taken to mean
-.BR strlen(src) .
-.PP
-The
-.I type
-parameter of
-.I atoasr
-must point to a
-.B char
-variable used to record which form was found.
-The
-.I addrs
-parameter must point to a two-element array of
-.B "struct in_addr"
-which receives the results.
-The values stored into
-.BR *type ,
-and the corresponding values in the array, are:
-.PP
-.ta 3c +2c +3c
-       *type   addrs[0]        addrs[1]
-.sp 0.8
-address        \&\fB'a'\fR     address -
-.br
-subnet \&\fB's'\fR     network mask
-.br
-range  \&\fB'r'\fR     begin   end
-.PP
-The
-.I dstlen
-parameter of
-.I rangetoa
-specifies the size of the
-.I dst
-parameter;
-under no circumstances are more than
-.I dstlen
-bytes written to
-.IR dst .
-A result which will not fit is truncated.
-.I Dstlen
-can be zero, in which case
-.I dst
-need not be valid and no result is written,
-but the return value is unaffected;
-in all other cases, the (possibly truncated) result is NUL-terminated.
-The
-.I freeswan.h
-header file defines a constant,
-.BR RANGETOA_BUF ,
-which is the size of a buffer just large enough for worst-case results.
-.PP
-The
-.I format
-parameter of
-.I rangetoa
-specifies what format is to be used for the conversion.
-The value
-.B 0
-(not the ASCII character
-.BR '0' ,
-but a zero value)
-specifies a reasonable default,
-and is in fact the only format currently available.
-This parameter is a hedge against future needs.
-.PP
-.I Atoasr
-returns NULL for success and
-a pointer to a string-literal error message for failure;
-see DIAGNOSTICS.
-.I Rangetoa
-returns
-.B 0
-for a failure, and otherwise
-always returns the size of buffer which would 
-be needed to
-accommodate the full conversion result, including terminating NUL;
-it is the caller's responsibility to check this against the size of
-the provided buffer to determine whether truncation has occurred.
-.SH SEE ALSO
-ipsec_atoaddr(3), ipsec_atosubnet(3)
-.SH DIAGNOSTICS
-Fatal errors in
-.I atoasr
-are:
-empty input;
-error in
-.IR ipsec_atoaddr (3)
-or
-.IR ipsec_atosubnet (3)
-during conversion;
-begin address of range exceeds end address.
-.PP
-Fatal errors in
-.I rangetoa
-are:
-unknown format.
-.SH HISTORY
-Written for the FreeS/WAN project by Henry Spencer.
-.SH BUGS
-The restriction of error reports to literal strings
-(so that callers don't need to worry about freeing them or copying them)
-does limit the precision of error reporting.
-.PP
-The error-reporting convention lends itself
-to slightly obscure code,
-because many readers will not think of NULL as signifying success.
-A good way to make it clearer is to write something like:
-.PP
-.RS
-.nf
-.B "const char *error;"
-.sp
-.B "error = atoasr( /* ... */ );"
-.B "if (error != NULL) {"
-.B "        /* something went wrong */"
-.fi
-.RE
diff --git a/src/libfreeswan/atoasr.c b/src/libfreeswan/atoasr.c
deleted file mode 100644 (file)
index ad62ef4..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * convert from ASCII form of address/subnet/range to binary
- * Copyright (C) 1998, 1999  Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
- * License for more details.
- */
-#include "internal.h"
-#include "freeswan.h"
-
-/*
- - atoasr - convert ASCII to address, subnet, or range
- */
-const char *                   /* NULL for success, else string literal */
-atoasr(src, srclen, typep, addrsp)
-const char *src;
-size_t srclen;                 /* 0 means "apply strlen" */
-char *typep;                   /* return type code:  'a', 's', 'r' */
-struct in_addr addrsp[2];
-{
-       const char *punct;
-       const char *stop;
-       const char *oops;
-
-       if (srclen == 0)
-               srclen = strlen(src);
-       if (srclen == 0)
-               return "empty string";
-
-       /* subnet is easy to spot */
-       punct = memchr(src, '/', srclen);
-       if (punct != NULL) {
-               *typep = 's';
-               return atosubnet(src, srclen, &addrsp[0], &addrsp[1]);
-       }
-
-       /* try for a range */
-       stop = src + srclen;
-       for (punct = src; (punct = memchr(punct, '.', stop - punct)) != NULL;
-                                                                       punct++)
-               if (stop - punct > 3 && *(punct+1) == '.' && *(punct+2) == '.')
-                       break;                  /* NOTE BREAK OUT */
-       if (punct == NULL) {
-               /* didn't find the range delimiter, must be plain address */
-               *typep = 'a';
-               return atoaddr(src, srclen, &addrsp[0]);
-       }
-
-       /* looks like a range */
-       *typep = 'r';
-       if (stop - punct > 4 && *(punct+3) == '.')
-               punct++;                /* first dot is trailing dot of name */
-       oops = atoaddr(src, punct - src, &addrsp[0]);
-       if (oops != NULL)
-               return oops;
-       oops = atoaddr(punct+3, stop - (punct+3), &addrsp[1]);
-       if (oops != NULL)
-               return oops;
-       if (ntohl(addrsp[0].s_addr) > ntohl(addrsp[1].s_addr))
-               return "invalid range, begin > end";
-       return NULL;
-}
-
-
-
-#ifdef ATOASR_MAIN
-
-#include <stdio.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-void regress(void);
-
-int
-main(int argc, char *argv[])
-{
-       struct in_addr a[2];
-       char buf[100];
-       const char *oops;
-       size_t n;
-       char type;
-
-       if (argc < 2) {
-               fprintf(stderr, "Usage: %s {addr|net/mask|begin...end|-r}\n",
-                                                               argv[0]);
-               exit(2);
-       }
-
-       if (strcmp(argv[1], "-r") == 0) {
-               regress();
-               fprintf(stderr, "regress() returned?!?\n");
-               exit(1);
-       }
-
-       oops = atoasr(argv[1], 0, &type, a);
-       if (oops != NULL) {
-               fprintf(stderr, "%s: conversion failed: %s\n", argv[0], oops);
-               exit(1);
-       }
-       switch (type) {
-       case 'a':
-               n = addrtoa(a[0], 0, buf, sizeof(buf));
-               break;
-       case 's':
-               n = subnettoa(a[0], a[1], 0, buf, sizeof(buf));
-               break;
-       case 'r':
-               n = rangetoa(a, 0, buf, sizeof(buf));
-               break;
-       default:
-               fprintf(stderr, "%s: unknown type '%c'\n", argv[0], type);
-               exit(1);
-               break;
-       }
-       if (n > sizeof(buf)) {
-               fprintf(stderr, "%s: reverse conversion of ", argv[0]);
-               fprintf(stderr, "%s ", inet_ntoa(a[0]));
-               fprintf(stderr, "%s", inet_ntoa(a[1]));
-               fprintf(stderr, " failed: need %ld bytes, have only %ld\n",
-                                               (long)n, (long)sizeof(buf));
-               exit(1);
-       }
-       printf("%s\n", buf);
-
-       exit(0);
-}
-
-struct rtab {
-       char *input;
-       char *output;                   /* NULL means error expected */
-} rtab[] = {
-       {"1.2.3.0",                     "1.2.3.0"},
-       {"1.2.3.0/255.255.255.0",       "1.2.3.0/24"},
-       {"1.2.3.0...1.2.3.5",           "1.2.3.0...1.2.3.5"},
-       {"1.2.3.4.5",                   NULL},
-       {"1.2.3.4/",                    NULL},
-       {"1.2.3.4...",                  NULL},
-       {"1.2.3.4....",                 NULL},
-       {"localhost/32",                        "127.0.0.1/32"},
-       {"localhost...127.0.0.3",       "127.0.0.1...127.0.0.3"},
-       {"127.0.0.0...localhost",       "127.0.0.0...127.0.0.1"},
-       {"127.0.0.3...localhost",       NULL},
-       {NULL,                          NULL}
-};
-
-void
-regress(void)
-{
-       struct rtab *r;
-       int status = 0;
-       struct in_addr a[2];
-       char in[100];
-       char buf[100];
-       const char *oops;
-       size_t n;
-       char type;
-
-       for (r = rtab; r->input != NULL; r++) {
-               strcpy(in, r->input);
-               oops = atoasr(in, 0, &type, a);
-               if (oops != NULL && r->output == NULL)
-                       {}              /* okay, error expected */
-               else if (oops != NULL) {
-                       printf("`%s' atoasr failed: %s\n", r->input, oops);
-                       status = 1;
-               } else if (r->output == NULL) {
-                       printf("`%s' atoasr succeeded unexpectedly '%c'\n",
-                                                       r->input, type);
-                       status = 1;
-               } else {
-                       switch (type) {
-                       case 'a':
-                               n = addrtoa(a[0], 0, buf, sizeof(buf));
-                               break;
-                       case 's':
-                               n = subnettoa(a[0], a[1], 0, buf, sizeof(buf));
-                               break;
-                       case 'r':
-                               n = rangetoa(a, 0, buf, sizeof(buf));
-                               break;
-                       default:
-                               fprintf(stderr, "`%s' unknown type '%c'\n",
-                                                       r->input, type);
-                               n = 0;
-                               status = 1;
-                               break;
-                       }
-                       if (n > sizeof(buf)) {
-                               printf("`%s' '%c' reverse failed:  need %ld\n",
-                                               r->input, type, (long)n);
-                               status = 1;
-                       } else if (n > 0 && strcmp(r->output, buf) != 0) {
-                               printf("`%s' '%c' gave `%s', expected `%s'\n",
-                                       r->input, type, buf, r->output);
-                               status = 1;
-                       }
-               }
-       }
-       exit(status);
-}
-
-#endif /* ATOASR_MAIN */
diff --git a/src/libfreeswan/atosubnet.c b/src/libfreeswan/atosubnet.c
deleted file mode 100644 (file)
index 8b2bfa1..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * convert from ASCII form of subnet specification to binary
- * Copyright (C) 1998, 1999  Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
- * License for more details.
- */
-#include "internal.h"
-#include "freeswan.h"
-
-#ifndef DEFAULTSUBNET
-#define        DEFAULTSUBNET   "%default"
-#endif
-
-/*
- - atosubnet - convert ASCII "addr/mask" to address and mask
- * Mask can be integer bit count.
- */
-const char *                   /* NULL for success, else string literal */
-atosubnet(src, srclen, addrp, maskp)
-const char *src;
-size_t srclen;                 /* 0 means "apply strlen" */
-struct in_addr *addrp;
-struct in_addr *maskp;
-{
-       const char *slash;
-       const char *mask;
-       size_t mlen;
-       const char *oops;
-       unsigned long bc;
-       static char def[] = DEFAULTSUBNET;
-#      define  DEFLEN  (sizeof(def) - 1)       /* -1 for NUL */
-       static char defis[] = "0/0";
-#      define  DEFILEN (sizeof(defis) - 1)
-
-       if (srclen == 0)
-               srclen = strlen(src);
-       if (srclen == 0)
-               return "empty string";
-
-       if (srclen == DEFLEN && strncmp(src, def, srclen) == 0) {
-               src = defis;
-               srclen = DEFILEN;
-       }
-
-       slash = memchr(src, '/', srclen);
-       if (slash == NULL)
-               return "no / in subnet specification";
-       mask = slash + 1;
-       mlen = srclen - (mask - src);
-
-       oops = atoaddr(src, slash-src, addrp);
-       if (oops != NULL)
-               return oops;
-
-       oops = atoul(mask, mlen, 10, &bc);
-       if (oops == NULL) {
-               /* atoul succeeded, it's a bit-count mask */
-               if (bc > ABITS)
-                       return "bit-count mask too large";
-#ifdef NOLEADINGZEROS
-               if (mlen > 1 && *mask == '0')
-                       return "octal not allowed in mask";
-#endif /* NOLEADINGZEROS */
-               *maskp = bitstomask((int)bc);
-       } else {
-               oops = atoaddr(mask, mlen, maskp);
-               if (oops != NULL)
-                       return oops;
-               if (!goodmask(*maskp))
-                       return "non-contiguous mask";
-       }
-
-       addrp->s_addr &= maskp->s_addr;
-       return NULL;
-}
-
-
-
-#ifdef ATOSUBNET_MAIN
-
-#include <stdio.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-void regress(void);
-
-int
-main(int argc, char *argv[])
-{
-       struct in_addr a;
-       struct in_addr m;
-       char buf[100];
-       const char *oops;
-       size_t n;
-
-       if (argc < 2) {
-               fprintf(stderr, "Usage: %s {addr/mask|-r}\n", argv[0]);
-               exit(2);
-       }
-
-       if (strcmp(argv[1], "-r") == 0) {
-               regress();
-               fprintf(stderr, "regress() returned?!?\n");
-               exit(1);
-       }
-
-       oops = atosubnet(argv[1], 0, &a, &m);
-       if (oops != NULL) {
-               fprintf(stderr, "%s: conversion failed: %s\n", argv[0], oops);
-               exit(1);
-       }
-       n = subnettoa(a, m, 0, buf, sizeof(buf));
-       if (n > sizeof(buf)) {
-               fprintf(stderr, "%s: reverse conversion of ", argv[0]);
-               fprintf(stderr, "%s/", inet_ntoa(a));
-               fprintf(stderr, "%s", inet_ntoa(m));
-               fprintf(stderr, " failed: need %ld bytes, have only %ld\n",
-                                               (long)n, (long)sizeof(buf));
-               exit(1);
-       }
-       printf("%s\n", buf);
-
-       exit(0);
-}
-
-struct rtab {
-       char *input;
-       char *output;                   /* NULL means error expected */
-} rtab[] = {
-       {"1.2.3.0/255.255.255.0",       "1.2.3.0/24"},
-       {"1.2.3.0/24",                  "1.2.3.0/24"},
-       {"1.2.3.1/255.255.255.240",     "1.2.3.0/28"},
-       {"1.2.3.1/32",                  "1.2.3.1/32"},
-       {"1.2.3.1/0",                   "0.0.0.0/0"},
-/*     "1.2.3.1/255.255.127.0",        "1.2.3.0/255.255.127.0",        */
-       {"1.2.3.1/255.255.127.0",       NULL},
-       {"128.009.000.032/32",          "128.9.0.32/32"},
-       {"128.0x9.0.32/32",             NULL},
-       {"0x80090020/32",               "128.9.0.32/32"},
-       {"0x800x0020/32",               NULL},
-       {"128.9.0.32/0xffFF0000",       "128.9.0.0/16"},
-       {"128.9.0.32/0xff0000FF",       NULL},
-       {"128.9.0.32/0x0000ffFF",       NULL},
-       {"128.9.0.32/0x00ffFF0000",     NULL},
-       {"128.9.0.32/0xffFF",           NULL},
-       {"128.9.0.32.27/32",            NULL},
-       {"128.9.0k32/32",               NULL},
-       {"328.9.0.32/32",               NULL},
-       {"128.9..32/32",                NULL},
-       {"10/8",                        "10.0.0.0/8"},
-       {"10.0/8",                      "10.0.0.0/8"},
-       {"10.0.0/8",                    "10.0.0.0/8"},
-       {"10.0.1/24",                   "10.0.1.0/24"},
-       {"_",                           NULL},
-       {"_/_",                         NULL},
-       {"1.2.3.1",                     NULL},
-       {"1.2.3.1/_",                   NULL},
-       {"1.2.3.1/24._",                NULL},
-       {"1.2.3.1/99",                  NULL},
-       {"localhost/32",                "127.0.0.1/32"},
-       {"%default",                    "0.0.0.0/0"},
-       {NULL,                          NULL}
-};
-
-void
-regress()
-{
-       struct rtab *r;
-       int status = 0;
-       struct in_addr a;
-       struct in_addr m;
-       char in[100];
-       char buf[100];
-       const char *oops;
-       size_t n;
-
-       for (r = rtab; r->input != NULL; r++) {
-               strcpy(in, r->input);
-               oops = atosubnet(in, 0, &a, &m);
-               if (oops != NULL && r->output == NULL)
-                       {}              /* okay, error expected */
-               else if (oops != NULL) {
-                       printf("`%s' atosubnet failed: %s\n", r->input, oops);
-                       status = 1;
-               } else if (r->output == NULL) {
-                       printf("`%s' atosubnet succeeded unexpectedly\n",
-                                                               r->input);
-                       status = 1;
-               } else {
-                       n = subnettoa(a, m, 0, buf, sizeof(buf));
-                       if (n > sizeof(buf)) {
-                               printf("`%s' subnettoa failed:  need %ld\n",
-                                                       r->input, (long)n);
-                               status = 1;
-                       } else if (strcmp(r->output, buf) != 0) {
-                               printf("`%s' gave `%s', expected `%s'\n",
-                                               r->input, buf, r->output);
-                               status = 1;
-                       }
-               }
-       }
-       exit(status);
-}
-
-#endif /* ATOSUBNET_MAIN */
diff --git a/src/libfreeswan/atoul.3 b/src/libfreeswan/atoul.3
deleted file mode 100644 (file)
index 6737b6b..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-.TH IPSEC_ATOUL 3 "11 June 2001"
-.SH NAME
-ipsec atoul, ultoa \- convert unsigned-long numbers to and from ASCII
-.SH SYNOPSIS
-.B "#include <freeswan.h>
-.sp
-.B "const char *atoul(const char *src, size_t srclen,"
-.ti +1c
-.B "int base, unsigned long *n);"
-.br
-.B "size_t ultoa(unsigned long n, int base, char *dst,"
-.ti +1c
-.B "size_t dstlen);"
-.SH DESCRIPTION
-These functions are obsolete; see
-.IR ipsec_ttoul (3)
-for their replacements.
-.PP
-.I Atoul
-converts an ASCII number into a binary
-.B "unsigned long"
-value.
-.I Ultoa
-does the reverse conversion, back to an ASCII version.
-.PP
-Numbers are specified in ASCII as
-decimal (e.g.
-.BR 123 ),
-octal with a leading zero (e.g.
-.BR 012 ,
-which has value 10),
-or hexadecimal with a leading
-.B 0x
-(e.g.
-.BR 0x1f ,
-which has value 31)
-in either upper or lower case.
-.PP
-The
-.I srclen
-parameter of
-.I atoul
-specifies the length of the ASCII string pointed to by
-.IR src ;
-it is an error for there to be anything else
-(e.g., a terminating NUL) within that length.
-As a convenience for cases where an entire NUL-terminated string is
-to be converted,
-a
-.I srclen
-value of
-.B 0
-is taken to mean
-.BR strlen(src) .
-.PP
-The
-.I base
-parameter of
-.I atoul
-can be
-.BR 8 ,
-.BR 10 ,
-or
-.BR 16 ,
-in which case the number supplied is assumed to be of that form
-(and in the case of
-.BR 16 ,
-to lack any
-.B 0x
-prefix).
-It can also be
-.BR 0 ,
-in which case the number is examined for a leading zero
-or a leading
-.B 0x
-to determine its base,
-or
-.B 13
-(halfway between 10 and 16),
-which has the same effect as
-.B 0
-except that a non-hexadecimal
-number is considered decimal regardless of any leading zero.
-.PP
-The
-.I dstlen
-parameter of
-.I ultoa
-specifies the size of the
-.I dst
-parameter;
-under no circumstances are more than
-.I dstlen
-bytes written to
-.IR dst .
-A result which will not fit is truncated.
-.I Dstlen
-can be zero, in which case
-.I dst
-need not be valid and no result is written,
-but the return value is unaffected;
-in all other cases, the (possibly truncated) result is NUL-terminated.
-.PP
-The
-.I base
-parameter of
-.I ultoa
-must be
-.BR 8 ,
-.BR 10 ,
-or
-.BR 16 .
-.PP
-.I Atoul
-returns NULL for success and
-a pointer to a string-literal error message for failure;
-see DIAGNOSTICS.
-.I Ultoa
-returns the size of buffer which would 
-be needed to
-accommodate the full conversion result, including terminating NUL;
-it is the caller's responsibility to check this against the size of
-the provided buffer to determine whether truncation has occurred.
-.SH SEE ALSO
-atol(3), strtoul(3)
-.SH DIAGNOSTICS
-Fatal errors in
-.I atoul
-are:
-empty input;
-unknown
-.IR base ;
-non-digit character found;
-number too large for an
-.BR "unsigned long" .
-.SH HISTORY
-Written for the FreeS/WAN project by Henry Spencer.
-.SH BUGS
-There is no provision for reporting an invalid
-.I base
-parameter given to
-.IR ultoa .
-.PP
-The restriction of error reports to literal strings
-(so that callers don't need to worry about freeing them or copying them)
-does limit the precision of error reporting.
-.PP
-The error-reporting convention lends itself to slightly obscure code,
-because many readers will not think of NULL as signifying success.
-A good way to make it clearer is to write something like:
-.PP
-.RS
-.nf
-.B "const char *error;"
-.sp
-.B "error = atoul( /* ... */ );"
-.B "if (error != NULL) {"
-.B "        /* something went wrong */"
-.fi
-.RE
diff --git a/src/libfreeswan/atoul.c b/src/libfreeswan/atoul.c
deleted file mode 100644 (file)
index d8e1528..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * convert from ASCII form of unsigned long to binary
- * Copyright (C) 1998, 1999  Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
- * License for more details.
- */
-#include "internal.h"
-#include "freeswan.h"
-
-/*
- - atoul - convert ASCII substring to unsigned long number
- */
-const char *                   /* NULL for success, else string literal */
-atoul(src, srclen, base, resultp)
-const char *src;
-size_t srclen;                 /* 0 means strlen(src) */
-int base;                      /* 0 means figure it out */
-unsigned long *resultp;
-{
-       const char *stop;
-       static char hex[] = "0123456789abcdef";
-       static char uchex[] = "0123456789ABCDEF";
-       int d;
-       char c;
-       char *p;
-       unsigned long r;
-       unsigned long rlimit;
-       int dlimit;
-
-       if (srclen == 0)
-               srclen = strlen(src);
-       if (srclen == 0)
-               return "empty string";
-
-       if (base == 0 || base == 13) {
-               if (srclen > 2 && *src == '0' && CIEQ(*(src+1), 'x'))
-                       return atoul(src+2, srclen-2, 16, resultp);
-               if (srclen > 1 && *src == '0' && base != 13)
-                       return atoul(src+1, srclen-1, 8, resultp);
-               return atoul(src, srclen, 10, resultp);
-       }
-       if (base != 8 && base != 10 && base != 16)
-               return "unsupported number base";
-
-       r = 0;
-       stop = src + srclen;
-       if (base == 16) {
-               while (src < stop) {
-                       c = *src++;
-                       p = strchr(hex, c);
-                       if (p != NULL)
-                               d = p - hex;
-                       else {
-                               p = strchr(uchex, c);
-                               if (p == NULL)
-                                       return "non-hex-digit in hex number";
-                               d = p - uchex;
-                       }
-                       r = (r << 4) | d;
-               }
-               /* defer length check to catch invalid digits first */
-               if (srclen > sizeof(unsigned long) * 2)
-                       return "hex number too long";
-       } else {
-               rlimit = ULONG_MAX / base;
-               dlimit = (int)(ULONG_MAX - rlimit*base);
-               while (src < stop) {
-                       c = *src++;
-                       d = c - '0';
-                       if (d < 0 || d >= base)
-                               return "non-digit in number";
-                       if (r > rlimit || (r == rlimit && d > dlimit))
-                               return "unsigned-long overflow";
-                       r = r*base + d;
-               }
-       }
-
-       *resultp = r;
-       return NULL;
-}
diff --git a/src/libfreeswan/copyright.c b/src/libfreeswan/copyright.c
deleted file mode 100644 (file)
index e55e849..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * return IPsec copyright notice
- * Copyright (C) 2001, 2002  Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
- * License for more details.
- */
-#include "internal.h"
-#include "freeswan.h"
-
-static const char *co[] = {
- "Copyright (C) 1999-2009  Henry Spencer, Richard Guy Briggs,",
- "    D. Hugh Redelmeier, Sandy Harris, Claudia Schmeing,",
- "    Michael Richardson, Angelos D. Keromytis, John Ioannidis,",
- "",
- "    Ken Bantoft, Stephen J. Bevan, JuanJo Ciarlante, Mathieu Lafon,",
- "    Stephane Laroche, Kai Martius, Stephan Scholz, Tuomo Soini, Herbert Xu,",
- "",
- "    Martin Berner, Marco Bertossa, David Buechi, Ueli Galizzi,",
- "    Christoph Gysin, Andreas Hess, Patric Lichtsteiner, Michael Meier,",
- "    Andreas Schleiss, Ariane Seiler, Mario Strasser, Lukas Suter,",
- "    Roger Wegmann, Simon Zwahlen,",
- "    ZHW Zuercher Hochschule Winterthur (Switzerland).",
- "",
- "    Philip Boetschi, Tobias Brunner, Sansar Choinyambuu, Adrian Doerig,",
- "    Andreas Eigenmann, Fabian Hartmann, Noah Heusser, Jan Hutter,",
- "    Thomas Kallenberg, Daniel Roethlisberger, Joel Stillhart, Martin Willi,",
- "    Daniel Wydler, Andreas Steffen,",
- "    HSR Hochschule fuer Technik Rapperswil (Switzerland).",
- "",
- "This program is free software; you can redistribute it and/or modify it",
- "under the terms of the GNU General Public License as published by the",
- "Free Software Foundation; either version 2 of the License, or (at your",
- "option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.",
- "",
- "This program is distributed in the hope that it will be useful, but",
- "WITHOUT ANY WARRANTY; without even the implied warranty of",
- "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General",
- "Public License (file COPYING in the distribution) for more details.",
- NULL
-};
-
-/*
- - ipsec_copyright_notice - return copyright notice, as a vector of strings
- */
-const char **
-ipsec_copyright_notice()
-{
-       return co;
-}
diff --git a/src/libfreeswan/datatot.c b/src/libfreeswan/datatot.c
deleted file mode 100644 (file)
index e3b9d64..0000000
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * convert from binary data (e.g. key) to text form
- * Copyright (C) 2000  Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
- * License for more details.
- */
-#include "internal.h"
-#include "freeswan.h"
-
-static void convert(const char *src, size_t nreal, int format, char *out);
-
-/*
- - datatot - convert data bytes to text
- */
-size_t                         /* true length (with NUL) for success */
-datatot(src, srclen, format, dst, dstlen)
-const char *src;
-size_t srclen;
-int format;                    /* character indicating what format */
-char *dst;                     /* need not be valid if dstlen is 0 */
-size_t dstlen;
-{
-       size_t inblocksize;     /* process this many bytes at a time */
-       size_t outblocksize;    /* producing this many */
-       size_t breakevery;      /* add a _ every this many (0 means don't) */
-       size_t sincebreak;      /* output bytes since last _ */
-       char breakchar;         /* character used to break between groups */
-       char inblock[10];       /* enough for any format */
-       char outblock[10];      /* enough for any format */
-       char fake[1];           /* fake output area for dstlen == 0 */
-       size_t needed;          /* return value */
-       char *stop;             /* where the terminating NUL will go */
-       size_t ntodo;           /* remaining input */
-       size_t nreal;
-       char *out;
-       char *prefix;
-
-       breakevery = 0;
-       breakchar = '_';
-
-       switch (format) {
-       case 0:
-       case 'h':
-               format = 'x';
-               breakevery = 8;
-               /* FALLTHROUGH */
-       case 'x':
-               inblocksize = 1;
-               outblocksize = 2;
-               prefix = "0x";
-               break;
-       case ':':
-               breakevery = 2;
-               breakchar = ':';
-               /* FALLTHROUGH */
-       case 16:
-               inblocksize = 1;
-               outblocksize = 2;
-               prefix = "";
-               format = 'x';
-               break;
-       case 's':
-               inblocksize = 3;
-               outblocksize = 4;
-               prefix = "0s";
-               break;
-       case 64:                /* beware, equals ' ' */
-               inblocksize = 3;
-               outblocksize = 4;
-               prefix = "";
-               format = 's';
-               break;
-       default:
-               return 0;
-               break;
-       }
-       assert(inblocksize < sizeof(inblock));
-       assert(outblocksize < sizeof(outblock));
-       assert(breakevery % outblocksize == 0);
-
-       if (srclen == 0)
-               return 0;
-       ntodo = srclen;
-
-       if (dstlen == 0) {      /* dispose of awkward special case */
-               dst = fake;
-               dstlen = 1;
-       }
-       stop = dst + dstlen - 1;
-
-       nreal = strlen(prefix);
-       needed = nreal;                 /* for starters */
-       if (dstlen <= nreal) {          /* prefix won't fit */
-               strncpy(dst, prefix, dstlen - 1);
-               dst += dstlen - 1;
-       } else {
-               strcpy(dst, prefix);
-               dst += nreal;
-       }
-       assert(dst <= stop);
-       sincebreak = 0;
-
-       while (ntodo > 0) {
-               if (ntodo < inblocksize) {      /* incomplete input */
-                       memset(inblock, 0, sizeof(inblock));
-                       memcpy(inblock, src, ntodo);
-                       src = inblock;
-                       nreal = ntodo;
-                       ntodo = inblocksize;
-               } else
-                       nreal = inblocksize;
-               out = (outblocksize > stop - dst) ? outblock : dst;
-
-               convert(src, nreal, format, out);
-               needed += outblocksize;
-               sincebreak += outblocksize;
-               if (dst < stop) {
-                       if (out != dst) {
-                               assert(outblocksize > stop - dst);
-                               memcpy(dst, out, stop - dst);
-                               dst = stop;
-                       } else
-                               dst += outblocksize;
-               }
-
-               src += inblocksize;
-               ntodo -= inblocksize;
-               if (breakevery != 0 && sincebreak >= breakevery && ntodo > 0) {
-                       if (dst < stop)
-                               *dst++ = breakchar;
-                       needed++;
-                       sincebreak = 0;
-               }
-       }
-
-       assert(dst <= stop);
-       *dst++ = '\0';
-       needed++;
-
-       return needed;
-}
-
-/*
- - convert - convert one input block to one output block
- */
-static void
-convert(src, nreal, format, out)
-const char *src;
-size_t nreal;                  /* how much of the input block is real */
-int format;
-char *out;
-{
-       static char hex[] = "0123456789abcdef";
-       static char base64[] =  "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-                               "abcdefghijklmnopqrstuvwxyz"
-                               "0123456789+/";
-       unsigned char c;
-       unsigned char c1, c2, c3;
-
-       assert(nreal > 0);
-       switch (format) {
-       case 'x':
-               assert(nreal == 1);
-               c = (unsigned char)*src;
-               *out++ = hex[c >> 4];
-               *out++ = hex[c & 0xf];
-               break;
-       case 's':
-               c1 = (unsigned char)*src++;
-               c2 = (unsigned char)*src++;
-               c3 = (unsigned char)*src++;
-               *out++ = base64[c1 >> 2];       /* top 6 bits of c1 */
-               c = (c1 & 0x3) << 4;            /* bottom 2 of c1... */
-               c |= c2 >> 4;                   /* ...top 4 of c2 */
-               *out++ = base64[c];
-               if (nreal == 1)
-                       *out++ = '=';
-               else {
-                       c = (c2 & 0xf) << 2;    /* bottom 4 of c2... */
-                       c |= c3 >> 6;           /* ...top 2 of c3 */
-                       *out++ = base64[c];
-               }
-               if (nreal <= 2)
-                       *out++ = '=';
-               else
-                       *out++ = base64[c3 & 0x3f];     /* bottom 6 of c3 */
-               break;
-       default:
-               assert(nreal == 0);     /* unknown format */
-               break;
-       }
-}
-
-/*
- - datatoa - convert data to ASCII
- * backward-compatibility synonym for datatot
- */
-size_t                         /* true length (with NUL) for success */
-datatoa(src, srclen, format, dst, dstlen)
-const char *src;
-size_t srclen;
-int format;                    /* character indicating what format */
-char *dst;                     /* need not be valid if dstlen is 0 */
-size_t dstlen;
-{
-       return datatot(src, srclen, format, dst, dstlen);
-}
-
-/*
- - bytestoa - convert data bytes to ASCII
- * backward-compatibility synonym for datatot
- */
-size_t                         /* true length (with NUL) for success */
-bytestoa(src, srclen, format, dst, dstlen)
-const char *src;
-size_t srclen;
-int format;                    /* character indicating what format */
-char *dst;                     /* need not be valid if dstlen is 0 */
-size_t dstlen;
-{
-       return datatot(src, srclen, format, dst, dstlen);
-}
diff --git a/src/libfreeswan/freeswan.h b/src/libfreeswan/freeswan.h
deleted file mode 100644 (file)
index 724165b..0000000
+++ /dev/null
@@ -1,371 +0,0 @@
-#ifndef _FREESWAN_H
-/*
- * header file for FreeS/WAN library functions
- * Copyright (C) 1998, 1999, 2000  Henry Spencer.
- * Copyright (C) 1999, 2000, 2001  Richard Guy Briggs
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
- * License for more details.
- */
-#define        _FREESWAN_H     /* seen it, no need to see it again */
-
-#  include <sys/types.h>
-#  include <stdio.h>
-#  include <netinet/in.h>
-
-#  define DEBUG_NO_STATIC static
-
-#include <ipsec_param.h>
-#include <utils.h>
-
-/*
- * We assume header files have IPv6 (i.e. kernel version >= 2.1.0)
- */
-#define NET_21
-
-#ifndef IPPROTO_COMP
-#  define IPPROTO_COMP 108
-#endif /* !IPPROTO_COMP */
-
-#ifndef IPPROTO_INT
-#  define IPPROTO_INT 61
-#endif /* !IPPROTO_INT */
-
-#ifdef CONFIG_IPSEC_DEBUG
-#  define DEBUG_NO_STATIC
-#else /* CONFIG_IPSEC_DEBUG */
-#  define DEBUG_NO_STATIC static
-#endif /* CONFIG_IPSEC_DEBUG */
-
-#define ESPINUDP_WITH_NON_IKE   1  /* draft-ietf-ipsec-nat-t-ike-00/01 */
-#define ESPINUDP_WITH_NON_ESP   2  /* draft-ietf-ipsec-nat-t-ike-02    */
-
-/*
- * Basic data types for the address-handling functions.
- * ip_address and ip_subnet are supposed to be opaque types; do not
- * use their definitions directly, they are subject to change!
- */
-
-/* then the main types */
-typedef struct {
-       union {
-               struct sockaddr_in v4;
-               struct sockaddr_in6 v6;
-       } u;
-} ip_address;
-typedef struct {
-       ip_address addr;
-       int maskbits;
-} ip_subnet;
-
-/* and the SA ID stuff */
-typedef u_int32_t ipsec_spi_t;
-typedef struct {               /* to identify an SA, we need: */
-        ip_address dst;                /* A. destination host */
-        ipsec_spi_t spi;       /* B. 32-bit SPI, assigned by dest. host */
-#              define  SPI_PASS        256     /* magic values... */
-#              define  SPI_DROP        257     /* ...for use... */
-#              define  SPI_REJECT      258     /* ...with SA_INT */
-#              define  SPI_HOLD        259
-#              define  SPI_TRAP        260
-#              define  SPI_TRAPSUBNET  261
-       int proto;              /* C. protocol */
-#              define  SA_ESP  50      /* IPPROTO_ESP */
-#              define  SA_AH   51      /* IPPROTO_AH */
-#              define  SA_IPIP 4       /* IPPROTO_IPIP */
-#              define  SA_COMP 108     /* IPPROTO_COMP */
-#              define  SA_INT  61      /* IANA reserved for internal use */
-} ip_said;
-struct sa_id {                 /* old v4-only version */
-        struct in_addr dst;
-        ipsec_spi_t spi;
-       int proto;
-};
-
-/* misc */
-struct prng {                  /* pseudo-random-number-generator guts */
-       unsigned char sbox[256];
-       int i, j;
-       unsigned long count;
-};
-
-
-/*
- * definitions for user space, taken from freeswan/ipsec_sa.h
- */
-typedef uint32_t IPsecSAref_t;
-
-#define IPSEC_SA_REF_TABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH)
-
-#define IPSEC_SA_REF_FIELD_WIDTH (8 * sizeof(IPsecSAref_t))
-
-#define IPsecSAref2NFmark(x) ((x) << (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH))
-#define NFmark2IPsecSAref(x) ((x) >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH))
-
-#define IPSEC_SAREF_NULL (~((IPsecSAref_t)0))
-
-/* GCC magic for use in function definitions! */
-#ifdef GCC_LINT
-# define PRINTF_LIKE(n) __attribute__ ((format(printf, n, n+1)))
-# define NEVER_RETURNS __attribute__ ((noreturn))
-# define UNUSED __attribute__ ((unused))
-# define BLANK_FORMAT " "      /* GCC_LINT whines about empty formats */
-#else
-# define PRINTF_LIKE(n)        /* ignore */
-# define NEVER_RETURNS /* ignore */
-# define UNUSED /* ignore */
-# define BLANK_FORMAT ""
-#endif
-
-
-
-
-
-/*
- * new IPv6-compatible functions
- */
-
-/* text conversions */
-err_t ttoul(const char *src, size_t srclen, int format, unsigned long *dst);
-size_t ultot(unsigned long src, int format, char *buf, size_t buflen);
-#define        ULTOT_BUF       (22+1)  /* holds 64 bits in octal */
-err_t ttoaddr(const char *src, size_t srclen, int af, ip_address *dst);
-err_t tnatoaddr(const char *src, size_t srclen, int af, ip_address *dst);
-size_t addrtot(const ip_address *src, int format, char *buf, size_t buflen);
-/* RFC 1886 old IPv6 reverse-lookup format is the bulkiest */
-#define        ADDRTOT_BUF     (32*2 + 3 + 1 + 3 + 1 + 1)
-err_t ttosubnet(const char *src, size_t srclen, int af, ip_subnet *dst);
-size_t subnettot(const ip_subnet *src, int format, char *buf, size_t buflen);
-#define        SUBNETTOT_BUF   (ADDRTOT_BUF + 1 + 3)
-err_t ttosa(const char *src, size_t srclen, ip_said *dst);
-size_t satot(const ip_said *src, int format, char *bufptr, size_t buflen);
-#define        SATOT_BUF       (5 + ULTOA_BUF + 1 + ADDRTOT_BUF)
-err_t ttodata(const char *src, size_t srclen, int base, char *buf,
-                                               size_t buflen, size_t *needed);
-err_t ttodatav(const char *src, size_t srclen, int base,
-              char *buf,  size_t buflen, size_t *needed,
-              char *errp, size_t errlen, unsigned int flags);
-#define        TTODATAV_BUF    40      /* ttodatav's largest non-literal message */
-#define TTODATAV_IGNORESPACE  (1<<1)  /* ignore spaces in base64 encodings*/
-#define TTODATAV_SPACECOUNTS  0       /* do not ignore spaces in base64   */
-
-size_t datatot(const char *src, size_t srclen, int format, char *buf,
-                                                               size_t buflen);
-err_t ttoprotoport(char *src, size_t src_len, u_int8_t *proto, u_int16_t *port,
-                                                       bool *has_port_wildcard);
-
-/* initializations */
-void initsaid(const ip_address *addr, ipsec_spi_t spi, int proto, ip_said *dst);
-err_t loopbackaddr(int af, ip_address *dst);
-err_t unspecaddr(int af, ip_address *dst);
-err_t anyaddr(int af, ip_address *dst);
-err_t initaddr(const unsigned char *src, size_t srclen, int af, ip_address *dst);
-err_t initsubnet(const ip_address *addr, int maskbits, int clash, ip_subnet *dst);
-err_t addrtosubnet(const ip_address *addr, ip_subnet *dst);
-
-/* misc. conversions and related */
-err_t rangetosubnet(const ip_address *from, const ip_address *to, ip_subnet *dst);
-int addrtypeof(const ip_address *src);
-int subnettypeof(const ip_subnet *src);
-size_t addrlenof(const ip_address *src);
-size_t addrbytesptr(const ip_address *src, const unsigned char **dst);
-size_t addrbytesof(const ip_address *src, unsigned char *dst, size_t dstlen);
-int masktocount(const ip_address *src);
-void networkof(const ip_subnet *src, ip_address *dst);
-void maskof(const ip_subnet *src, ip_address *dst);
-
-/* tests */
-int sameaddr(const ip_address *a, const ip_address *b);
-int addrcmp(const ip_address *a, const ip_address *b);
-int samesubnet(const ip_subnet *a, const ip_subnet *b);
-int addrinsubnet(const ip_address *a, const ip_subnet *s);
-int subnetinsubnet(const ip_subnet *a, const ip_subnet *b);
-int subnetishost(const ip_subnet *s);
-int samesaid(const ip_said *a, const ip_said *b);
-int sameaddrtype(const ip_address *a, const ip_address *b);
-int samesubnettype(const ip_subnet *a, const ip_subnet *b);
-int isanyaddr(const ip_address *src);
-int isunspecaddr(const ip_address *src);
-int isloopbackaddr(const ip_address *src);
-
-/* low-level grot */
-int portof(const ip_address *src);
-void setportof(int port, ip_address *dst);
-struct sockaddr *sockaddrof(ip_address *src);
-size_t sockaddrlenof(const ip_address *src);
-
-/* odds and ends */
-const char **ipsec_copyright_notice(void);
-
-const char *dns_string_rr(int rr, char *buf, int bufsize);
-const char *dns_string_datetime(time_t seconds,
-                               char *buf,
-                               int bufsize);
-
-
-/*
- * old functions, to be deleted eventually
- */
-
-/* unsigned long */
-const char *                   /* NULL for success, else string literal */
-atoul(
-       const char *src,
-       size_t srclen,          /* 0 means strlen(src) */
-       int base,               /* 0 means figure it out */
-       unsigned long *resultp
-);
-size_t                         /* space needed for full conversion */
-ultoa(
-       unsigned long n,
-       int base,
-       char *dst,
-       size_t dstlen
-);
-#define        ULTOA_BUF       21      /* just large enough for largest result, */
-                               /* assuming 64-bit unsigned long! */
-
-/* Internet addresses */
-const char *                   /* NULL for success, else string literal */
-atoaddr(
-       const char *src,
-       size_t srclen,          /* 0 means strlen(src) */
-       struct in_addr *addr
-);
-size_t                         /* space needed for full conversion */
-addrtoa(
-       struct in_addr addr,
-       int format,             /* character; 0 means default */
-       char *dst,
-       size_t dstlen
-);
-#define        ADDRTOA_BUF     16      /* just large enough for largest result */
-
-/* subnets */
-const char *                   /* NULL for success, else string literal */
-atosubnet(
-       const char *src,
-       size_t srclen,          /* 0 means strlen(src) */
-       struct in_addr *addr,
-       struct in_addr *mask
-);
-size_t                         /* space needed for full conversion */
-subnettoa(
-       struct in_addr addr,
-       struct in_addr mask,
-       int format,             /* character; 0 means default */
-       char *dst,
-       size_t dstlen
-);
-#define        SUBNETTOA_BUF   32      /* large enough for worst case result */
-
-/* ranges */
-const char *                   /* NULL for success, else string literal */
-atoasr(
-       const char *src,
-       size_t srclen,          /* 0 means strlen(src) */
-       char *type,             /* 'a', 's', 'r' */
-       struct in_addr *addrs   /* two-element array */
-);
-size_t                         /* space needed for full conversion */
-rangetoa(
-       struct in_addr *addrs,  /* two-element array */
-       int format,             /* character; 0 means default */
-       char *dst,
-       size_t dstlen
-);
-#define        RANGETOA_BUF    34      /* large enough for worst case result */
-
-/* generic data, e.g. keys */
-const char *                   /* NULL for success, else string literal */
-atobytes(
-       const char *src,
-       size_t srclen,          /* 0 means strlen(src) */
-       char *dst,
-       size_t dstlen,
-       size_t *lenp            /* NULL means don't bother telling me */
-);
-size_t                         /* 0 failure, else true size */
-bytestoa(
-       const char *src,
-       size_t srclen,
-       int format,             /* character; 0 means default */
-       char *dst,
-       size_t dstlen
-);
-
-/* old versions of generic-data functions; deprecated */
-size_t                         /* 0 failure, else true size */
-atodata(
-       const char *src,
-       size_t srclen,          /* 0 means strlen(src) */
-       char *dst,
-       size_t dstlen
-);
-size_t                         /* 0 failure, else true size */
-datatoa(
-       const char *src,
-       size_t srclen,
-       int format,             /* character; 0 means default */
-       char *dst,
-       size_t dstlen
-);
-
-/* part extraction and special addresses */
-struct in_addr
-subnetof(
-       struct in_addr addr,
-       struct in_addr mask
-);
-struct in_addr
-hostof(
-       struct in_addr addr,
-       struct in_addr mask
-);
-struct in_addr
-broadcastof(
-       struct in_addr addr,
-       struct in_addr mask
-);
-
-/* mask handling */
-int
-goodmask(
-       struct in_addr mask
-);
-int
-masktobits(
-       struct in_addr mask
-);
-struct in_addr
-bitstomask(
-       int n
-);
-
-/*
- * Debugging levels for pfkey_lib_debug
- */
-#define PF_KEY_DEBUG_PARSE_NONE    0
-#define PF_KEY_DEBUG_PARSE_PROBLEM 1
-#define PF_KEY_DEBUG_PARSE_STRUCT  2
-#define PF_KEY_DEBUG_PARSE_FLOW    4
-#define PF_KEY_DEBUG_PARSE_MAX     7
-
-extern unsigned int pfkey_lib_debug;  /* bits selecting what to report */
-
-/*
- * pluto and lwdnsq need to know the maximum size of the commands to,
- * and replies from lwdnsq.
- */
-
-#define LWDNSQ_CMDBUF_LEN      1024
-#define LWDNSQ_RESULT_LEN_MAX  4096
-
-#endif /* _FREESWAN_H */
diff --git a/src/libfreeswan/goodmask.3 b/src/libfreeswan/goodmask.3
deleted file mode 100644 (file)
index b76d431..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-.TH IPSEC_GOODMASK 3 "11 June 2001"
-.SH NAME
-ipsec goodmask \- is this Internet subnet mask a valid one?
-.br
-ipsec masktobits \- convert Internet subnet mask to bit count
-.br
-ipsec bitstomask \- convert bit count to Internet subnet mask
-.SH SYNOPSIS
-.B "#include <freeswan.h>
-.sp
-.B "int goodmask(struct in_addr mask);"
-.br
-.B "int masktobits(struct in_addr mask);"
-.br
-.B "struct in_addr bitstomask(int n);"
-.SH DESCRIPTION
-These functions are obsolete;
-see
-.IR ipsec_masktocount (3)
-for a partial replacement.
-.PP
-.I Goodmask
-reports whether the subnet
-.I mask
-is a valid one,
-i.e. consists of a (possibly empty) sequence of
-.BR 1 s
-followed by a (possibly empty) sequence of
-.BR 0 s.
-.I Masktobits
-takes a (valid) subnet mask and returns the number of
-.B 1
-bits in it.
-.I Bitstomask
-reverses this,
-returning the subnet mask corresponding to bit count
-.IR n .
-.PP
-All masks are in network byte order.
-.SH SEE ALSO
-inet(3), ipsec_atosubnet(3)
-.SH DIAGNOSTICS
-.I Masktobits
-returns
-.B \-1
-for an invalid mask.
-.I Bitstomask
-returns an all-zeros mask for a negative or out-of-range
-.IR n .
-.SH HISTORY
-Written for the FreeS/WAN project by Henry Spencer.
-.SH BUGS
-The error-reporting convention of
-.I bitstomask
-is less than ideal;
-zero is sometimes a legitimate mask.
diff --git a/src/libfreeswan/goodmask.c b/src/libfreeswan/goodmask.c
deleted file mode 100644 (file)
index 66edae2..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * minor utilities for subnet-mask manipulation
- * Copyright (C) 1998, 1999  Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
- * License for more details.
- */
-#include "internal.h"
-#include "freeswan.h"
-
-/*
- - goodmask - is this a good (^1*0*$) subnet mask?
- * You are not expected to understand this.  See Henry S. Warren Jr,
- * "Functions realizable with word-parallel logical and two's-complement
- * addition instructions", CACM 20.6 (June 1977), p.439.
- */
-int                            /* predicate */
-goodmask(mask)
-struct in_addr mask;
-{
-       unsigned long x = ntohl(mask.s_addr);
-       /* clear rightmost contiguous string of 1-bits */
-#      define  CRCS1B(x)       (((x|(x-1))+1)&x)
-#      define  TOPBIT          (1UL << 31)
-
-       /* either zero, or has one string of 1-bits which is left-justified */
-       if (x == 0 || (CRCS1B(x) == 0 && (x&TOPBIT)))
-               return 1;
-       return 0;
-}
-
-/*
- - masktobits - how many bits in this mask?
- * The algorithm is essentially a binary search, but highly optimized
- * for this particular task.
- */
-int                            /* -1 means !goodmask() */
-masktobits(mask)
-struct in_addr mask;
-{
-       unsigned long m = ntohl(mask.s_addr);
-       int masklen;
-
-       if (!goodmask(mask))
-               return -1;
-
-       if (m&0x00000001UL)
-               return 32;
-       masklen = 0;
-       if (m&(0x0000ffffUL<<1)) {      /* <<1 for 1-origin numbering */
-               masklen |= 0x10;
-               m <<= 16;
-       }
-       if (m&(0x00ff0000UL<<1)) {
-               masklen |= 0x08;
-               m <<= 8;
-       }
-       if (m&(0x0f000000UL<<1)) {
-               masklen |= 0x04;
-               m <<= 4;
-       }
-       if (m&(0x30000000UL<<1)) {
-               masklen |= 0x02;
-               m <<= 2;
-       }
-       if (m&(0x40000000UL<<1))
-               masklen |= 0x01;
-
-       return masklen;
-}
-
-/*
- - bitstomask - return a mask with this many high bits on
- */
-struct in_addr
-bitstomask(n)
-int n;
-{
-       struct in_addr result;
-
-       if (n > 0 && n <= ABITS)
-               result.s_addr = htonl(~((1UL << (ABITS - n)) - 1));
-       else if (n == 0)
-               result.s_addr = 0;
-       else
-               result.s_addr = 0;      /* best error report we can do */
-       return result;
-}
diff --git a/src/libfreeswan/initaddr.3 b/src/libfreeswan/initaddr.3
deleted file mode 100644 (file)
index 071e507..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-.TH IPSEC_INITADDR 3 "11 Sept 2000"
-.SH NAME
-ipsec initaddr \- initialize an ip_address
-.br
-ipsec addrtypeof \- get address type of an ip_address
-.br
-ipsec addrlenof \- get length of address within an ip_address
-.br
-ipsec addrbytesof \- get copy of address within an ip_address
-.br
-ipsec addrbytesptr \- get pointer to address within an ip_address
-.SH SYNOPSIS
-.B "#include <freeswan.h>"
-.sp
-.B "const char *initaddr(const char *src, size_t srclen,"
-.ti +1c
-.B "int af, ip_address *dst);"
-.br
-.B "int addrtypeof(const ip_address *src);"
-.br
-.B "size_t addrlenof(const ip_address *src);"
-.br
-.B "size_t addrbytesof(const ip_address *src,"
-.ti +1c
-.B "unsigned char *dst, size_t dstlen);"
-.br
-.B "size_t addrbytesptr(const ip_address *src,"
-.ti +1c
-.B "const unsigned char **dst);"
-.SH DESCRIPTION
-The
-.B <freeswan.h>
-library uses an internal type
-.I ip_address
-to contain one of the (currently two) types of IP address.
-These functions provide basic tools for creating and examining this type.
-.PP
-.I Initaddr
-initializes a variable
-.I *dst
-of type
-.I ip_address
-from an address
-(in network byte order,
-indicated by a pointer
-.I src
-and a length
-.IR srclen )
-and an address family
-.I af
-(typically
-.B AF_INET
-or
-.BR AF_INET6 ).
-The length must be consistent with the address family.
-.PP
-.I Addrtypeof
-returns the address type of an address,
-normally
-.B AF_INET
-or
-.BR AF_INET6 .
-(The
-.B <freeswan.h>
-header file arranges to include the necessary headers for these
-names to be known.)
-.PP
-.I Addrlenof
-returns the size (in bytes) of the address within an
-.IR ip_address ,
-to permit storage allocation etc.
-.PP
-.I Addrbytesof
-copies the address within the
-.I ip_address
-.I src
-to the buffer indicated by the pointer
-.I dst
-and the length
-.IR dstlen ,
-and returns the address length (in bytes).
-If the address will not fit,
-as many bytes as will fit are copied;
-the returned length is still the full length.
-It is the caller's responsibility to check the
-returned value to ensure that there was enough room.
-.PP
-.I Addrbytesptr
-sets
-.I *dst
-to a pointer to the internal address within the
-.IR ip_address ,
-and returns the address length (in bytes).
-If
-.I dst
-is
-.BR NULL ,
-it just returns the address length.
-The pointer points to
-.B const
-to discourage misuse.
-.PP
-.I Initaddr
-returns
-.B NULL
-for success and
-a pointer to a string-literal error message for failure;
-see DIAGNOSTICS.
-.PP
-The functions which return
-.I size_t
-return
-.B 0
-for a failure.
-.SH SEE ALSO
-inet(3), ipsec_ttoaddr(3)
-.SH DIAGNOSTICS
-An unknown address family is a fatal error for any of these functions
-except
-.IR addrtypeof .
-An address-size mismatch is a fatal error for
-.IR initaddr .
-.SH HISTORY
-Written for the FreeS/WAN project by Henry Spencer.
-.SH BUGS
-.I Addrtypeof
-should probably have been named
-.IR addrfamilyof .
diff --git a/src/libfreeswan/initaddr.c b/src/libfreeswan/initaddr.c
deleted file mode 100644 (file)
index c84006f..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * initialize address structure
- * Copyright (C) 2000  Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
- * License for more details.
- */
-#include <sys/socket.h>
-
-#include "internal.h"
-#include "freeswan.h"
-
-/*
- - initaddr - initialize ip_address from bytes
- */
-err_t                          /* NULL for success, else string literal */
-initaddr(src, srclen, af, dst)
-const unsigned char *src;
-size_t srclen;
-int af;                                /* address family */
-ip_address *dst;
-{
-       switch (af) {
-       case AF_INET:
-               if (srclen != 4)
-                       return "IPv4 address must be exactly 4 bytes";
-               dst->u.v4.sin_family = af;
-               dst->u.v4.sin_port = 0;         /* unused */
-               memcpy((char *)&dst->u.v4.sin_addr.s_addr, src, srclen);
-               break;
-       case AF_INET6:
-               if (srclen != 16)
-                       return "IPv6 address must be exactly 16 bytes";
-               dst->u.v6.sin6_family = af;
-               dst->u.v6.sin6_flowinfo = 0;            /* unused */
-               dst->u.v6.sin6_port = 0;                /* unused */
-               memcpy((char *)&dst->u.v6.sin6_addr, src, srclen);
-               break;
-       default:
-               return "unknown address family in initaddr";
-               break;
-       }
-       return NULL;
-}
diff --git a/src/libfreeswan/initsaid.c b/src/libfreeswan/initsaid.c
deleted file mode 100644 (file)
index 4e4bc9a..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * initialize SA ID structure
- * Copyright (C) 2000  Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
- * License for more details.
- */
-#include "internal.h"
-#include "freeswan.h"
-
-/*
- - initsaid - initialize SA ID from bits
- */
-void
-initsaid(addr, spi, proto, dst)
-const ip_address *addr;
-ipsec_spi_t spi;
-int proto;
-ip_said *dst;
-{
-       dst->dst = *addr;
-       dst->spi = spi;
-       dst->proto = proto;
-}
diff --git a/src/libfreeswan/initsubnet.3 b/src/libfreeswan/initsubnet.3
deleted file mode 100644 (file)
index 3545fd4..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-.TH IPSEC_INITSUBNET 3 "12 March 2002"
-.SH NAME
-ipsec initsubnet \- initialize an ip_subnet
-.br
-ipsec addrtosubnet \- initialize a singleton ip_subnet
-.br
-ipsec subnettypeof \- get address type of an ip_subnet
-.br
-ipsec masktocount \- convert subnet mask to bit count
-.br
-ipsec networkof \- get base address of an ip_subnet
-.br
-ipsec maskof \- get subnet mask of an ip_subnet
-.SH SYNOPSIS
-.B "#include <freeswan.h>"
-.sp
-.B "const char *initsubnet(const ip_address *addr,"
-.ti +1c
-.B "int maskbits, int clash, ip_subnet *dst);"
-.br
-.B "const char *addrtosubnet(const ip_address *addr,"
-.ti +1c
-.B "ip_subnet *dst);"
-.sp
-.B "int subnettypeof(const ip_subnet *src);"
-.br
-.B "int masktocount(const ip_address *src);"
-.br
-.B "void networkof(const ip_subnet *src, ip_address *dst);"
-.br
-.B "void maskof(const ip_subnet *src, ip_address *dst);"
-.SH DESCRIPTION
-The
-.B <freeswan.h>
-library uses an internal type
-.I ip_subnet
-to contain a description of an IP subnet
-(base address plus mask).
-These functions provide basic tools for creating and examining this type.
-.PP
-.I Initsubnet
-initializes a variable
-.I *dst
-of type
-.I ip_subnet
-from a base address and
-a count of mask bits.
-The
-.I clash
-parameter specifies what to do if the base address includes
-.B 1
-bits outside the prefix specified by the mask
-(that is, in the ``host number'' part of the address):
-.RS
-.IP '0' 5
-zero out host-number bits
-.IP 'x'
-non-zero host-number bits are an error
-.RE
-.PP
-.I Initsubnet
-returns
-.B NULL
-for success and
-a pointer to a string-literal error message for failure;
-see DIAGNOSTICS.
-.PP
-.I Addrtosubnet
-initializes an
-.I ip_subnet
-variable
-.I *dst
-to a ``singleton subnet'' containing the single address
-.IR *addr .
-It returns
-.B NULL
-for success and
-a pointer to a string-literal error message for failure.
-.PP
-.I Subnettypeof
-returns the address type of a subnet,
-normally
-.B AF_INET
-or
-.BR AF_INET6 .
-(The
-.B <freeswan.h>
-header file arranges to include the necessary headers for these
-names to be known.)
-.PP
-.I Masktocount
-converts a subnet mask, expressed as an address, to a bit count
-suitable for use with
-.IR initsubnet .
-It returns
-.B \-1
-for error; see DIAGNOSTICS.
-.PP
-.I Networkof
-fills in
-.I *dst
-with the base address of subnet
-.IR src .
-.PP
-.I Maskof
-fills in
-.I *dst
-with the subnet mask of subnet
-.IR src ,
-expressed as an address.
-.SH SEE ALSO
-inet(3), ipsec_ttosubnet(3), ipsec_rangetosubnet(3)
-.SH DIAGNOSTICS
-Fatal errors in
-.I initsubnet
-are:
-unknown address family;
-unknown
-.I clash
-value;
-impossible mask bit count;
-non-zero host-number bits and
-.I clash
-is
-.BR 'x' .
-Fatal errors in
-.I addrtosubnet
-are:
-unknown address family.
-Fatal errors in
-.I masktocount
-are:
-unknown address family;
-mask bits not contiguous.
-.SH HISTORY
-Written for the FreeS/WAN project by Henry Spencer.
diff --git a/src/libfreeswan/initsubnet.c b/src/libfreeswan/initsubnet.c
deleted file mode 100644 (file)
index 27fadda..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * initialize subnet structure
- * Copyright (C) 2000, 2002  Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
- * License for more details.
- */
-#include "internal.h"
-#include "freeswan.h"
-
-/*
- - initsubnet - initialize ip_subnet from address and count
- *
- * The only hard part is checking for host-part bits turned on.
- */
-err_t                          /* NULL for success, else string literal */
-initsubnet(addr, count, clash, dst)
-const ip_address *addr;
-int count;
-int clash;                     /* '0' zero host-part bits, 'x' die on them */
-ip_subnet *dst;
-{
-       unsigned char *p;
-       int n;
-       int c;
-       unsigned m;
-       int die;
-
-       dst->addr = *addr;
-       n = addrbytesptr(&dst->addr, (const unsigned char **)&p);
-       if (n == 0)
-               return "unknown address family";
-
-       switch (clash) {
-       case '0':
-               die = 0;
-               break;
-       case 'x':
-               die = 1;
-               break;
-       default:
-               return "unknown clash-control value in initsubnet";
-               break;
-       }
-
-       c = count / 8;
-       if (c > n)
-               return "impossible mask count";
-       p += c;
-       n -= c;
-
-       m = 0xff;
-       c = count % 8;
-       if (n > 0 && c != 0)    /* partial byte */
-               m >>= c;
-       for (; n > 0; n--) {
-               if ((*p & m) != 0) {
-                       if (die)
-                               return "improper subnet, host-part bits on";
-                       *p &= ~m;
-               }
-               m = 0xff;
-               p++;
-       }
-
-       dst->maskbits = count;
-       return NULL;
-}
-
-/*
- - addrtosubnet - initialize ip_subnet from a single address
- */
-err_t                          /* NULL for success, else string literal */
-addrtosubnet(addr, dst)
-const ip_address *addr;
-ip_subnet *dst;
-{
-       int n;
-
-       dst->addr = *addr;
-       n = addrbytesptr(&dst->addr, (const unsigned char **)NULL);
-       if (n == 0)
-               return "unknown address family";
-       dst->maskbits = n*8;
-       return NULL;
-}
diff --git a/src/libfreeswan/internal.h b/src/libfreeswan/internal.h
deleted file mode 100644 (file)
index 832c8a5..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * internal definitions for use within the library; do not export!
- * Copyright (C) 1998, 1999  Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
- * License for more details.
- */
-
-#ifndef ABITS
-#define        ABITS   32      /* bits in an IPv4 address */
-#endif
-
-/* case-independent ASCII character equality comparison */
-#define        CIEQ(c1, c2)    ( ((c1)&~040) == ((c2)&~040) )
-
-/* syntax for passthrough SA */
-#ifndef PASSTHROUGHNAME
-#define        PASSTHROUGHNAME "%passthrough"
-#define        PASSTHROUGH4NAME        "%passthrough4"
-#define        PASSTHROUGH6NAME        "%passthrough6"
-#define        PASSTHROUGHIS   "tun0@0.0.0.0"
-#define        PASSTHROUGH4IS  "tun0@0.0.0.0"
-#define        PASSTHROUGH6IS  "tun0@::"
-#define        PASSTHROUGHTYPE "tun"
-#define        PASSTHROUGHSPI  0
-#define        PASSTHROUGHDST  0
-#endif
-
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <ctype.h>
-#include <assert.h>
-#include <limits.h>
-#include <netdb.h>
-#include <stdlib.h>
-#define        MALLOC(n)       malloc(n)
-#define        FREE(p)         free(p)
-
diff --git a/src/libfreeswan/ipsec_param.h b/src/libfreeswan/ipsec_param.h
deleted file mode 100644 (file)
index 93426b8..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * @(#) FreeSWAN tunable paramaters
- *
- * Copyright (C) 2001  Richard Guy Briggs  <rgb@freeswan.org>
- *                 and Michael Richardson  <mcr@freeswan.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-/*
- * This file provides a set of #define's which may be tuned by various
- * people/configurations. It keeps all compile-time tunables in one place.
- *
- * This file should be included before all other IPsec kernel-only files.
- *
- */
-
-#ifndef _IPSEC_PARAM_H_
-
-/*
- * This is for the SA reference table. This number is related to the
- * maximum number of SAs that KLIPS can concurrently deal with, plus enough
- * space for keeping expired SAs around.
- *
- * TABLE_MAX_WIDTH is the number of bits that we will use.
- * MAIN_TABLE_WIDTH is the number of bits used for the primary index table.
- *
- */
-#ifndef IPSEC_SA_REF_TABLE_IDX_WIDTH
-# define IPSEC_SA_REF_TABLE_IDX_WIDTH 16
-#endif
-
-#ifndef IPSEC_SA_REF_MAINTABLE_IDX_WIDTH
-# define IPSEC_SA_REF_MAINTABLE_IDX_WIDTH 4
-#endif
-
-#ifndef IPSEC_SA_REF_FREELIST_NUM_ENTRIES
-# define IPSEC_SA_REF_FREELIST_NUM_ENTRIES 256
-#endif
-
-#ifndef IPSEC_SA_REF_CODE
-# define IPSEC_SA_REF_CODE 1
-#endif
-
-#define _IPSEC_PARAM_H_
-#endif /* _IPSEC_PARAM_H_ */
diff --git a/src/libfreeswan/pfkey.h b/src/libfreeswan/pfkey.h
deleted file mode 100644 (file)
index 993678c..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * FreeS/WAN specific PF_KEY headers
- * Copyright (C) 1999, 2000, 2001  Richard Guy Briggs.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef __NET_IPSEC_PF_KEY_H
-#define __NET_IPSEC_PF_KEY_H
-
-extern void (*pfkey_debug_func)(const char *message, ...);
-
-extern uint8_t satype2proto(uint8_t satype);
-extern uint8_t proto2satype(uint8_t proto);
-extern char* satype2name(uint8_t satype);
-extern char* proto2name(uint8_t proto);
-
-struct key_opt
-{
-       uint32_t        key_pid;        /* process ID */
-       struct sock     *sk;
-};
-
-#define key_pid(sk) ((struct key_opt*)&((sk)->protinfo))->key_pid
-
-#define IPSEC_PFKEYv2_ALIGN (sizeof(uint64_t)/sizeof(uint8_t))
-#define BITS_PER_OCTET 8
-#define OCTETBITS 8
-#define PFKEYBITS 64
-#define DIVUP(x,y) ((x + y -1) / y) /* divide, rounding upwards */
-#define ALIGN_N(x,y) (DIVUP(x,y) * y) /* align on y boundary */
-
-#define PFKEYv2_MAX_MSGSIZE 4096
-
-/*
- * PF_KEYv2 permitted and required extensions in and out bitmaps
- */
-struct pf_key_ext_parsers_def {
-       int  (*parser)(struct sadb_ext*);
-       char  *parser_name;
-};
-
-
-extern unsigned int extensions_bitmaps[2/*in/out*/][2/*perm/req*/][SADB_MAX + 1/*ext*/];
-#define EXT_BITS_IN 0
-#define EXT_BITS_OUT 1
-#define EXT_BITS_PERM 0
-#define EXT_BITS_REQ 1
-
-extern void pfkey_extensions_init(struct sadb_ext *extensions[SADB_EXT_MAX + 1]);
-extern void pfkey_extensions_free(struct sadb_ext *extensions[SADB_EXT_MAX + 1]);
-extern void pfkey_msg_free(struct sadb_msg **pfkey_msg);
-
-extern int pfkey_msg_parse(struct sadb_msg *pfkey_msg,
-                          struct pf_key_ext_parsers_def *ext_parsers[],
-                          struct sadb_ext **extensions,
-                          int dir);
-
-/*
- * PF_KEYv2 build function prototypes
- */
-
-int
-pfkey_msg_hdr_build(struct sadb_ext**  pfkey_ext,
-                   uint8_t             msg_type,
-                   uint8_t             satype,
-                   uint8_t             msg_errno,
-                   uint32_t            seq,
-                   uint32_t            pid);
-
-int
-pfkey_sa_ref_build(struct sadb_ext **  pfkey_ext,
-              uint16_t                 exttype,
-              uint32_t                 spi, /* in network order */
-              uint8_t                  replay_window,
-              uint8_t                  sa_state,
-              uint8_t                  auth,
-              uint8_t                  encrypt,
-              uint32_t                 flags,
-              uint32_t/*IPsecSAref_t*/ ref);
-
-int
-pfkey_sa_build(struct sadb_ext **      pfkey_ext,
-              uint16_t                 exttype,
-              uint32_t                 spi, /* in network order */
-              uint8_t                  replay_window,
-              uint8_t                  sa_state,
-              uint8_t                  auth,
-              uint8_t                  encrypt,
-              uint32_t                 flags);
-
-int
-pfkey_lifetime_build(struct sadb_ext **        pfkey_ext,
-                    uint16_t           exttype,
-                    uint32_t           allocations,
-                    uint64_t           bytes,
-                    uint64_t           addtime,
-                    uint64_t           usetime,
-                    uint32_t           packets);
-
-int
-pfkey_address_build(struct sadb_ext**  pfkey_ext,
-                   uint16_t            exttype,
-                   uint8_t             proto,
-                   uint8_t             prefixlen,
-                   struct sockaddr*    address);
-
-int
-pfkey_key_build(struct sadb_ext**      pfkey_ext,
-               uint16_t                exttype,
-               uint16_t                key_bits,
-               char*                   key);
-
-int
-pfkey_ident_build(struct sadb_ext**    pfkey_ext,
-                 uint16_t              exttype,
-                 uint16_t              ident_type,
-                 uint64_t              ident_id,
-                 uint8_t               ident_len,
-                 char*                 ident_string);
-
-int
-pfkey_x_nat_t_type_build(struct sadb_ext**  pfkey_ext,
-            uint8_t         type);
-int
-pfkey_x_nat_t_port_build(struct sadb_ext**  pfkey_ext,
-            uint16_t         exttype,
-            uint16_t         port);
-
-int
-pfkey_sens_build(struct sadb_ext**     pfkey_ext,
-                uint32_t               dpd,
-                uint8_t                sens_level,
-                uint8_t                sens_len,
-                uint64_t*              sens_bitmap,
-                uint8_t                integ_level,
-                uint8_t                integ_len,
-                uint64_t*              integ_bitmap);
-
-int
-pfkey_x_protocol_build(struct sadb_ext **, uint8_t);
-
-
-int
-pfkey_prop_build(struct sadb_ext**     pfkey_ext,
-                uint8_t                replay,
-                unsigned int           comb_num,
-                struct sadb_comb*      comb);
-
-int
-pfkey_supported_build(struct sadb_ext**        pfkey_ext,
-                     uint16_t          exttype,
-                     unsigned int      alg_num,
-                     struct sadb_alg*  alg);
-
-int
-pfkey_spirange_build(struct sadb_ext** pfkey_ext,
-                    uint16_t           exttype,
-                    uint32_t           min,
-                    uint32_t           max);
-
-int
-pfkey_x_kmprivate_build(struct sadb_ext**      pfkey_ext);
-
-int
-pfkey_x_satype_build(struct sadb_ext** pfkey_ext,
-                    uint8_t            satype);
-
-int
-pfkey_x_debug_build(struct sadb_ext**  pfkey_ext,
-                   uint32_t            tunnel,
-                   uint32_t            netlink,
-                   uint32_t            xform,
-                   uint32_t            eroute,
-                   uint32_t            spi,
-                   uint32_t            radij,
-                   uint32_t            esp,
-                   uint32_t            ah,
-                   uint32_t            rcv,
-                   uint32_t            pfkey,
-                   uint32_t            ipcomp,
-                   uint32_t            verbose);
-
-int
-pfkey_msg_build(struct sadb_msg**      pfkey_msg,
-               struct sadb_ext*        extensions[],
-               int                     dir);
-
-/* in pfkey_v2_debug.c - routines to decode numbers -> strings */
-const char *
-pfkey_v2_sadb_ext_string(int extnum);
-
-const char *
-pfkey_v2_sadb_type_string(int sadb_type);
-
-
-#endif /* __NET_IPSEC_PF_KEY_H */
diff --git a/src/libfreeswan/pfkey_v2_build.c b/src/libfreeswan/pfkey_v2_build.c
deleted file mode 100644 (file)
index c0bb369..0000000
+++ /dev/null
@@ -1,1388 +0,0 @@
-/*
- * RFC2367 PF_KEYv2 Key management API message parser
- * Copyright (C) 1999, 2000, 2001  Richard Guy Briggs.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-/*
- *             Template from klips/net/ipsec/ipsec/ipsec_parser.c.
- */
-
-char pfkey_v2_build_c_version[] = "";
-
-# include <sys/types.h>
-# include <sys/socket.h>
-# include <stdlib.h>
-# include <errno.h>
-# include <string.h> /* memset */
-
-# include <freeswan.h>
-unsigned int pfkey_lib_debug = 0;
-
-void (*pfkey_debug_func)(const char *message, ...) PRINTF_LIKE(1);
-
-#define DEBUGGING(args...)  if(pfkey_lib_debug) { \
-                              if(pfkey_debug_func != NULL) { \
-                                (*pfkey_debug_func)("pfkey_lib_debug:" args); \
-                              } else { \
-                                printf("pfkey_lib_debug:" args); \
-                              } }
-# define MALLOC(size) malloc(size)
-# define FREE(obj) free(obj)
-
-#include <pfkeyv2.h>
-#include <pfkey.h>
-
-#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
-
-void
-pfkey_extensions_init(struct sadb_ext *extensions[SADB_EXT_MAX + 1])
-{
-       int i;
-
-       for (i = 0; i != SADB_EXT_MAX + 1; i++) {
-               extensions[i] = NULL;
-       }
-}
-
-void
-pfkey_extensions_free(struct sadb_ext *extensions[SADB_EXT_MAX + 1])
-{
-       int i;
-
-       if (!extensions) {
-               return;
-       }
-
-       if (extensions[0]) {
-               memset(extensions[0], 0, sizeof(struct sadb_msg));
-               FREE(extensions[0]);
-               extensions[0] = NULL;
-       }
-
-       for (i = 1; i != SADB_EXT_MAX + 1; i++) {
-               if(extensions[i]) {
-                       memset(extensions[i], 0, extensions[i]->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
-                       FREE(extensions[i]);
-                       extensions[i] = NULL;
-               }
-       }
-}
-
-void
-pfkey_msg_free(struct sadb_msg **pfkey_msg)
-{
-       if (*pfkey_msg) {
-               memset(*pfkey_msg, 0, (*pfkey_msg)->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
-               FREE(*pfkey_msg);
-               *pfkey_msg = NULL;
-       }
-}
-
-/* Default extension builders taken from the KLIPS code */
-
-int
-pfkey_msg_hdr_build(struct sadb_ext**  pfkey_ext,
-                   uint8_t             msg_type,
-                   uint8_t             satype,
-                   uint8_t             msg_errno,
-                   uint32_t            seq,
-                   uint32_t            pid)
-{
-       int error = 0;
-       struct sadb_msg *pfkey_msg = (struct sadb_msg *)*pfkey_ext;
-
-       DEBUGGING(
-               "pfkey_msg_hdr_build:\n");
-       DEBUGGING(
-               "pfkey_msg_hdr_build: "
-               "on_entry &pfkey_ext=0p%p pfkey_ext=0p%p *pfkey_ext=0p%p.\n",
-               &pfkey_ext,
-               pfkey_ext,
-               *pfkey_ext);
-       /* sanity checks... */
-       if (pfkey_msg) {
-               DEBUGGING(
-                       "pfkey_msg_hdr_build: "
-                       "why is pfkey_msg already pointing to something?\n");
-               SENDERR(EINVAL);
-       }
-
-       if (!msg_type) {
-               DEBUGGING(
-                       "pfkey_msg_hdr_build: "
-                       "msg type not set, must be non-zero..\n");
-               SENDERR(EINVAL);
-       }
-
-       if (msg_type > SADB_MAX) {
-               DEBUGGING(
-                       "pfkey_msg_hdr_build: "
-                       "msg type too large:%d.\n",
-                       msg_type);
-               SENDERR(EINVAL);
-       }
-
-       if (satype > SADB_SATYPE_MAX) {
-               DEBUGGING(
-                       "pfkey_msg_hdr_build: "
-                       "satype %d > max %d\n",
-                       satype, SADB_SATYPE_MAX);
-               SENDERR(EINVAL);
-       }
-
-       pfkey_msg = (struct sadb_msg*)MALLOC(sizeof(struct sadb_msg));
-       *pfkey_ext = (struct sadb_ext*)pfkey_msg;
-
-       if (pfkey_msg == NULL) {
-               DEBUGGING(
-                       "pfkey_msg_hdr_build: "
-                       "memory allocation failed\n");
-               SENDERR(ENOMEM);
-       }
-       memset(pfkey_msg, 0, sizeof(struct sadb_msg));
-
-       pfkey_msg->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
-
-       pfkey_msg->sadb_msg_type = msg_type;
-       pfkey_msg->sadb_msg_satype = satype;
-
-       pfkey_msg->sadb_msg_version = PF_KEY_V2;
-       pfkey_msg->sadb_msg_errno = msg_errno;
-       pfkey_msg->sadb_msg_reserved = 0;
-       pfkey_msg->sadb_msg_seq = seq;
-       pfkey_msg->sadb_msg_pid = pid;
-       DEBUGGING(
-               "pfkey_msg_hdr_build: "
-               "on_exit &pfkey_ext=0p%p pfkey_ext=0p%p *pfkey_ext=0p%p.\n",
-               &pfkey_ext,
-               pfkey_ext,
-               *pfkey_ext);
-errlab:
-       return error;
-}
-
-int
-pfkey_sa_ref_build(struct sadb_ext **          pfkey_ext,
-                  uint16_t                     exttype,
-                  uint32_t                     spi,
-                  uint8_t                      replay_window,
-                  uint8_t                      sa_state,
-                  uint8_t                      auth,
-                  uint8_t                      encrypt,
-                  uint32_t                     flags,
-                  uint32_t/*IPsecSAref_t*/     ref)
-{
-       int error = 0;
-       struct sadb_sa *pfkey_sa = (struct sadb_sa *)*pfkey_ext;
-
-       DEBUGGING(
-                   "pfkey_sa_build: "
-                   "spi=%08x replay=%d sa_state=%d auth=%d encrypt=%d flags=%d\n",
-                   ntohl(spi), /* in network order */
-                   replay_window,
-                   sa_state,
-                   auth,
-                   encrypt,
-                   flags);
-       /* sanity checks... */
-       if (pfkey_sa) {
-               DEBUGGING(
-                       "pfkey_sa_build: "
-                       "why is pfkey_sa already pointing to something?\n");
-               SENDERR(EINVAL);
-       }
-
-       if (exttype != SADB_EXT_SA
-       &&  exttype != SADB_X_EXT_SA2) {
-               DEBUGGING(
-                       "pfkey_sa_build: "
-                       "invalid exttype=%d.\n",
-                       exttype);
-               SENDERR(EINVAL);
-       }
-
-       if (replay_window > 64) {
-               DEBUGGING(
-                       "pfkey_sa_build: "
-                       "replay window size: %d -- must be 0 <= size <= 64\n",
-                       replay_window);
-               SENDERR(EINVAL);
-       }
-
-       if (auth > SADB_AALG_MAX) {
-               DEBUGGING(
-                       "pfkey_sa_build: "
-                       "auth=%d > SADB_AALG_MAX=%d.\n",
-                       auth,
-                       SADB_AALG_MAX);
-               SENDERR(EINVAL);
-       }
-
-       if (encrypt > SADB_EALG_MAX) {
-               DEBUGGING(
-                       "pfkey_sa_build: "
-                       "encrypt=%d > SADB_EALG_MAX=%d.\n",
-                       encrypt,
-                       SADB_EALG_MAX);
-               SENDERR(EINVAL);
-       }
-
-       if (sa_state > SADB_SASTATE_MAX) {
-               DEBUGGING(
-                       "pfkey_sa_build: "
-                       "sa_state=%d exceeds MAX=%d.\n",
-                       sa_state,
-                       SADB_SASTATE_MAX);
-               SENDERR(EINVAL);
-       }
-
-       if (sa_state == SADB_SASTATE_DEAD) {
-               DEBUGGING(
-                       "pfkey_sa_build: "
-                       "sa_state=%d is DEAD=%d is not allowed.\n",
-                       sa_state,
-                       SADB_SASTATE_DEAD);
-               SENDERR(EINVAL);
-       }
-
-       if ((IPSEC_SAREF_NULL != ref) && (ref >= (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH))) {
-               DEBUGGING(
-                         "pfkey_sa_build: "
-                         "SAref=%d must be (SAref == IPSEC_SAREF_NULL(%d) || SAref < IPSEC_SA_REF_TABLE_NUM_ENTRIES(%d)).\n",
-                         ref,
-                         IPSEC_SAREF_NULL,
-                         IPSEC_SA_REF_TABLE_NUM_ENTRIES);
-               SENDERR(EINVAL);
-       }
-
-       pfkey_sa = (struct sadb_sa*)MALLOC(sizeof(struct sadb_sa));
-       *pfkey_ext = (struct sadb_ext*)pfkey_sa;
-
-       if (pfkey_sa == NULL) {
-               DEBUGGING(
-                       "pfkey_sa_build: "
-                       "memory allocation failed\n");
-               SENDERR(ENOMEM);
-       }
-       memset(pfkey_sa, 0, sizeof(struct sadb_sa));
-
-       pfkey_sa->sadb_sa_len = sizeof(*pfkey_sa) / IPSEC_PFKEYv2_ALIGN;
-       pfkey_sa->sadb_sa_exttype = exttype;
-       pfkey_sa->sadb_sa_spi = spi;
-       pfkey_sa->sadb_sa_replay = replay_window;
-       pfkey_sa->sadb_sa_state = sa_state;
-       pfkey_sa->sadb_sa_auth = auth;
-       pfkey_sa->sadb_sa_encrypt = encrypt;
-       pfkey_sa->sadb_sa_flags = flags;
-       pfkey_sa->sadb_x_sa_ref = ref;
-
-errlab:
-       return error;
-}
-
-int
-pfkey_sa_build(struct sadb_ext **      pfkey_ext,
-              uint16_t                 exttype,
-              uint32_t                 spi,
-              uint8_t                  replay_window,
-              uint8_t                  sa_state,
-              uint8_t                  auth,
-              uint8_t                  encrypt,
-              uint32_t                 flags)
-{
-       return pfkey_sa_ref_build(pfkey_ext,
-                          exttype,
-                          spi,
-                          replay_window,
-                          sa_state,
-                          auth,
-                          encrypt,
-                          flags,
-                          IPSEC_SAREF_NULL);
-}
-
-int
-pfkey_lifetime_build(struct sadb_ext **        pfkey_ext,
-                    uint16_t           exttype,
-                    uint32_t           allocations,
-                    uint64_t           bytes,
-                    uint64_t           addtime,
-                    uint64_t           usetime,
-                    uint32_t           packets)
-{
-       int error = 0;
-       struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)*pfkey_ext;
-
-       DEBUGGING(
-               "pfkey_lifetime_build:\n");
-       /* sanity checks... */
-       if (pfkey_lifetime) {
-               DEBUGGING(
-                       "pfkey_lifetime_build: "
-                       "why is pfkey_lifetime already pointing to something?\n");
-               SENDERR(EINVAL);
-       }
-
-       if (exttype != SADB_EXT_LIFETIME_CURRENT
-       &&  exttype != SADB_EXT_LIFETIME_HARD
-       &&  exttype != SADB_EXT_LIFETIME_SOFT) {
-               DEBUGGING(
-                       "pfkey_lifetime_build: "
-                       "invalid exttype=%d.\n",
-                       exttype);
-               SENDERR(EINVAL);
-       }
-
-       pfkey_lifetime = (struct sadb_lifetime*)MALLOC(sizeof(struct sadb_lifetime));
-       *pfkey_ext = (struct sadb_ext*)pfkey_lifetime;
-
-       if (pfkey_lifetime == NULL) {
-               DEBUGGING(
-                       "pfkey_lifetime_build: "
-                       "memory allocation failed\n");
-               SENDERR(ENOMEM);
-       }
-       memset(pfkey_lifetime, 0, sizeof(struct sadb_lifetime));
-
-       pfkey_lifetime->sadb_lifetime_len = sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN;
-       pfkey_lifetime->sadb_lifetime_exttype = exttype;
-       pfkey_lifetime->sadb_lifetime_allocations = allocations;
-       pfkey_lifetime->sadb_lifetime_bytes = bytes;
-       pfkey_lifetime->sadb_lifetime_addtime = addtime;
-       pfkey_lifetime->sadb_lifetime_usetime = usetime;
-       pfkey_lifetime->sadb_x_lifetime_packets = packets;
-
-errlab:
-       return error;
-}
-
-int
-pfkey_address_build(struct sadb_ext**  pfkey_ext,
-                   uint16_t            exttype,
-                   uint8_t             proto,
-                   uint8_t             prefixlen,
-                   struct sockaddr*    address)
-{
-       int error = 0;
-       int saddr_len = 0;
-       char ipaddr_txt[ADDRTOT_BUF + 6/*extra for port number*/];
-       struct sadb_address *pfkey_address = (struct sadb_address *)*pfkey_ext;
-
-       DEBUGGING(
-               "pfkey_address_build: "
-               "exttype=%d proto=%d prefixlen=%d\n",
-               exttype,
-               proto,
-               prefixlen);
-       /* sanity checks... */
-       if (pfkey_address) {
-               DEBUGGING(
-                       "pfkey_address_build: "
-                       "why is pfkey_address already pointing to something?\n");
-               SENDERR(EINVAL);
-       }
-
-       if (!address)  {
-                       DEBUGGING("pfkey_address_build: "
-                                 "address is NULL\n");
-                       SENDERR(EINVAL);
-       }
-
-       switch(exttype) {
-       case SADB_EXT_ADDRESS_SRC:
-       case SADB_EXT_ADDRESS_DST:
-       case SADB_EXT_ADDRESS_PROXY:
-       case SADB_X_EXT_ADDRESS_DST2:
-       case SADB_X_EXT_ADDRESS_SRC_FLOW:
-       case SADB_X_EXT_ADDRESS_DST_FLOW:
-       case SADB_X_EXT_ADDRESS_SRC_MASK:
-       case SADB_X_EXT_ADDRESS_DST_MASK:
-       case SADB_X_EXT_NAT_T_OA:
-               break;
-       default:
-               DEBUGGING(
-                       "pfkey_address_build: "
-                       "unrecognised ext_type=%d.\n",
-                       exttype);
-               SENDERR(EINVAL);
-       }
-
-       switch (address->sa_family) {
-       case AF_INET:
-               DEBUGGING(
-                       "pfkey_address_build: "
-                       "found address family AF_INET.\n");
-               saddr_len = sizeof(struct sockaddr_in);
-               sprintf(ipaddr_txt, "%d.%d.%d.%d:%d"
-                       , (((struct sockaddr_in*)address)->sin_addr.s_addr >>  0) & 0xFF
-                       , (((struct sockaddr_in*)address)->sin_addr.s_addr >>  8) & 0xFF
-                       , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 16) & 0xFF
-                       , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 24) & 0xFF
-                       , ntohs(((struct sockaddr_in*)address)->sin_port));
-               break;
-       case AF_INET6:
-               DEBUGGING(
-                       "pfkey_address_build: "
-                       "found address family AF_INET6.\n");
-               saddr_len = sizeof(struct sockaddr_in6);
-               sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x-%x"
-                       , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr[0])
-                       , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr[1])
-                       , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr[2])
-                       , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr[3])
-                       , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr[4])
-                       , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr[5])
-                       , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr[6])
-                       , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr[7])
-                       , ntohs(((struct sockaddr_in6*)address)->sin6_port));
-               break;
-       default:
-               DEBUGGING(
-                       "pfkey_address_build: "
-                       "address->sa_family=%d not supported.\n",
-                       address->sa_family);
-               SENDERR(EPFNOSUPPORT);
-       }
-
-       DEBUGGING(
-               "pfkey_address_build: "
-               "found address=%s.\n",
-               ipaddr_txt);
-       if (prefixlen != 0) {
-               DEBUGGING(
-                       "pfkey_address_build: "
-                       "address prefixes not supported yet.\n");
-               SENDERR(EAFNOSUPPORT); /* not supported yet */
-       }
-
-       pfkey_address = (struct sadb_address*)
-               MALLOC(ALIGN_N(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN));
-       *pfkey_ext = (struct sadb_ext*)pfkey_address;
-
-       if (pfkey_address == NULL) {
-               DEBUGGING(
-                       "pfkey_lifetime_build: "
-                       "memory allocation failed\n");
-               SENDERR(ENOMEM);
-       }
-       memset(pfkey_address,
-              0,
-              ALIGN_N(sizeof(struct sadb_address) + saddr_len,
-                    IPSEC_PFKEYv2_ALIGN));
-
-       pfkey_address->sadb_address_len = DIVUP(sizeof(struct sadb_address) + saddr_len,
-                                               IPSEC_PFKEYv2_ALIGN);
-
-       pfkey_address->sadb_address_exttype = exttype;
-       pfkey_address->sadb_address_proto = proto;
-       pfkey_address->sadb_address_prefixlen = prefixlen;
-       pfkey_address->sadb_address_reserved = 0;
-
-       memcpy((char*)pfkey_address + sizeof(struct sadb_address),
-              address,
-              saddr_len);
-
-#if 0
-       for (i = 0; i < sizeof(struct sockaddr_in) - offsetof(struct sockaddr_in, sin_zero); i++) {
-               pfkey_address_s_ska.sin_zero[i] = 0;
-       }
-#endif
-       DEBUGGING(
-               "pfkey_address_build: "
-               "successful.\n");
-
- errlab:
-       return error;
-}
-
-int
-pfkey_key_build(struct sadb_ext**      pfkey_ext,
-               uint16_t                exttype,
-               uint16_t                key_bits,
-               char*                   key)
-{
-       int error = 0;
-       struct sadb_key *pfkey_key = (struct sadb_key *)*pfkey_ext;
-
-       DEBUGGING(
-               "pfkey_key_build:\n");
-       /* sanity checks... */
-       if (pfkey_key) {
-               DEBUGGING(
-                       "pfkey_key_build: "
-                       "why is pfkey_key already pointing to something?\n");
-               SENDERR(EINVAL);
-       }
-
-       if (!key_bits) {
-               DEBUGGING(
-                       "pfkey_key_build: "
-                       "key_bits is zero, it must be non-zero.\n");
-               SENDERR(EINVAL);
-       }
-
-       if ( !((exttype == SADB_EXT_KEY_AUTH) || (exttype == SADB_EXT_KEY_ENCRYPT))) {
-               DEBUGGING(
-                       "pfkey_key_build: "
-                       "unsupported extension type=%d.\n",
-                       exttype);
-               SENDERR(EINVAL);
-       }
-
-       pfkey_key = (struct sadb_key*)
-               MALLOC(sizeof(struct sadb_key) +
-                       DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN);
-       *pfkey_ext = (struct sadb_ext*)pfkey_key;
-
-       if (pfkey_key == NULL) {
-               DEBUGGING(
-                       "pfkey_key_build: "
-                       "memory allocation failed\n");
-               SENDERR(ENOMEM);
-       }
-       memset(pfkey_key,
-              0,
-              sizeof(struct sadb_key) +
-              DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN);
-
-       pfkey_key->sadb_key_len = DIVUP(sizeof(struct sadb_key) * IPSEC_PFKEYv2_ALIGN + key_bits,
-                                       64);
-       pfkey_key->sadb_key_exttype = exttype;
-       pfkey_key->sadb_key_bits = key_bits;
-       pfkey_key->sadb_key_reserved = 0;
-       memcpy((char*)pfkey_key + sizeof(struct sadb_key),
-              key,
-              DIVUP(key_bits, 8));
-
-errlab:
-       return error;
-}
-
-int
-pfkey_ident_build(struct sadb_ext**    pfkey_ext,
-                 uint16_t              exttype,
-                 uint16_t              ident_type,
-                 uint64_t              ident_id,
-                 uint8_t               ident_len,
-                 char*                 ident_string)
-{
-       int error = 0;
-       struct sadb_ident *pfkey_ident = (struct sadb_ident *)*pfkey_ext;
-       int data_len = ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
-
-       DEBUGGING(
-               "pfkey_ident_build:\n");
-       /* sanity checks... */
-       if (pfkey_ident) {
-               DEBUGGING(
-                       "pfkey_ident_build: "
-                       "why is pfkey_ident already pointing to something?\n");
-               SENDERR(EINVAL);
-       }
-
-       if ( !((exttype == SADB_EXT_IDENTITY_SRC) ||
-              (exttype == SADB_EXT_IDENTITY_DST))) {
-               DEBUGGING(
-                       "pfkey_ident_build: "
-                       "unsupported extension type=%d.\n",
-                       exttype);
-               SENDERR(EINVAL);
-       }
-
-       if (ident_type == SADB_IDENTTYPE_RESERVED) {
-               DEBUGGING(
-                       "pfkey_ident_build: "
-                       "ident_type must be non-zero.\n");
-               SENDERR(EINVAL);
-       }
-
-       if (ident_type > SADB_IDENTTYPE_MAX) {
-               DEBUGGING(
-                       "pfkey_ident_build: "
-                       "identtype=%d out of range.\n",
-                       ident_type);
-               SENDERR(EINVAL);
-       }
-
-       if ((ident_type == SADB_IDENTTYPE_PREFIX ||
-           ident_type == SADB_IDENTTYPE_FQDN) &&
-          !ident_string) {
-               DEBUGGING(
-                       "pfkey_ident_build: "
-                       "string required to allocate size of extension.\n");
-               SENDERR(EINVAL);
-       }
-
-#if 0
-       if (ident_type == SADB_IDENTTYPE_USERFQDN) {
-       }
-#endif
-
-       pfkey_ident = (struct sadb_ident*)
-               MALLOC(ident_len * IPSEC_PFKEYv2_ALIGN);
-       *pfkey_ext = (struct sadb_ext*)pfkey_ident;
-
-       if (pfkey_ident == NULL) {
-               DEBUGGING(
-                       "pfkey_ident_build: "
-                       "memory allocation failed\n");
-               SENDERR(ENOMEM);
-       }
-       memset(pfkey_ident, 0, ident_len * IPSEC_PFKEYv2_ALIGN);
-
-       pfkey_ident->sadb_ident_len = ident_len;
-       pfkey_ident->sadb_ident_exttype = exttype;
-       pfkey_ident->sadb_ident_type = ident_type;
-       pfkey_ident->sadb_ident_reserved = 0;
-       pfkey_ident->sadb_ident_id = ident_id;
-       memcpy((char*)pfkey_ident + sizeof(struct sadb_ident),
-              ident_string,
-              data_len);
-
-errlab:
-       return error;
-}
-
-int
-pfkey_sens_build(struct sadb_ext**     pfkey_ext,
-                uint32_t               dpd,
-                uint8_t                sens_level,
-                uint8_t                sens_len,
-                uint64_t*              sens_bitmap,
-                uint8_t                integ_level,
-                uint8_t                integ_len,
-                uint64_t*              integ_bitmap)
-{
-       int error = 0;
-       struct sadb_sens *pfkey_sens = (struct sadb_sens *)*pfkey_ext;
-       int i;
-       uint64_t* bitmap;
-
-       DEBUGGING(
-               "pfkey_sens_build:\n");
-       /* sanity checks... */
-       if (pfkey_sens) {
-               DEBUGGING(
-                       "pfkey_sens_build: "
-                       "why is pfkey_sens already pointing to something?\n");
-               SENDERR(EINVAL);
-       }
-
-       DEBUGGING(
-               "pfkey_sens_build: "
-               "Sorry, I can't build exttype=%d yet.\n",
-               (*pfkey_ext)->sadb_ext_type);
-       SENDERR(EINVAL); /* don't process these yet */
-
-       pfkey_sens = (struct sadb_sens*)
-               MALLOC(sizeof(struct sadb_sens) +
-                       (sens_len + integ_len) * sizeof(uint64_t));
-       *pfkey_ext = (struct sadb_ext*)pfkey_sens;
-
-       if (pfkey_sens == NULL) {
-               DEBUGGING(
-                       "pfkey_sens_build: "
-                       "memory allocation failed\n");
-               SENDERR(ENOMEM);
-       }
-       memset(pfkey_sens,
-              0,
-              sizeof(struct sadb_sens) +
-              (sens_len + integ_len) * sizeof(uint64_t));
-
-       pfkey_sens->sadb_sens_len = (sizeof(struct sadb_sens) +
-                   (sens_len + integ_len) * sizeof(uint64_t)) / IPSEC_PFKEYv2_ALIGN;
-       pfkey_sens->sadb_sens_exttype = SADB_EXT_SENSITIVITY;
-       pfkey_sens->sadb_sens_dpd = dpd;
-       pfkey_sens->sadb_sens_sens_level = sens_level;
-       pfkey_sens->sadb_sens_sens_len = sens_len;
-       pfkey_sens->sadb_sens_integ_level = integ_level;
-       pfkey_sens->sadb_sens_integ_len = integ_len;
-       pfkey_sens->sadb_sens_reserved = 0;
-
-       bitmap = (uint64_t*)((char*)pfkey_ext + sizeof(struct sadb_sens));
-       for (i = 0; i < sens_len; i++) {
-               *bitmap = sens_bitmap[i];
-               bitmap++;
-       }
-       for (i = 0; i < integ_len; i++) {
-               *bitmap = integ_bitmap[i];
-               bitmap++;
-       }
-
-errlab:
-       return error;
-}
-
-int
-pfkey_prop_build(struct sadb_ext**     pfkey_ext,
-                uint8_t                replay,
-                unsigned int           comb_num,
-                struct sadb_comb*      comb)
-{
-       int error = 0;
-       int i;
-       struct sadb_prop *pfkey_prop = (struct sadb_prop *)*pfkey_ext;
-       struct sadb_comb *combp;
-
-       DEBUGGING(
-               "pfkey_prop_build:\n");
-       /* sanity checks... */
-       if (pfkey_prop) {
-               DEBUGGING(
-                       "pfkey_prop_build: "
-                       "why is pfkey_prop already pointing to something?\n");
-               SENDERR(EINVAL);
-       }
-
-       pfkey_prop = (struct sadb_prop*)
-               MALLOC(sizeof(struct sadb_prop) +
-                       comb_num * sizeof(struct sadb_comb));
-
-       *pfkey_ext = (struct sadb_ext*)pfkey_prop;
-
-       if (pfkey_prop == NULL) {
-               DEBUGGING(
-                       "pfkey_prop_build: "
-                       "memory allocation failed\n");
-               SENDERR(ENOMEM);
-       }
-       memset(pfkey_prop,
-              0,
-              sizeof(struct sadb_prop) +
-                   comb_num * sizeof(struct sadb_comb));
-
-       pfkey_prop->sadb_prop_len = (sizeof(struct sadb_prop) +
-                   comb_num * sizeof(struct sadb_comb)) / IPSEC_PFKEYv2_ALIGN;
-
-       pfkey_prop->sadb_prop_exttype = SADB_EXT_PROPOSAL;
-       pfkey_prop->sadb_prop_replay = replay;
-
-       for (i=0; i<3; i++) {
-               pfkey_prop->sadb_prop_reserved[i] = 0;
-       }
-
-       combp = (struct sadb_comb*)((char*)*pfkey_ext + sizeof(struct sadb_prop));
-       for (i = 0; i < comb_num; i++) {
-               memcpy (combp, &(comb[i]), sizeof(struct sadb_comb));
-               combp++;
-       }
-
-#if 0
-  uint8_t sadb_comb_auth;
-  uint8_t sadb_comb_encrypt;
-  uint16_t sadb_comb_flags;
-  uint16_t sadb_comb_auth_minbits;
-  uint16_t sadb_comb_auth_maxbits;
-  uint16_t sadb_comb_encrypt_minbits;
-  uint16_t sadb_comb_encrypt_maxbits;
-  uint32_t sadb_comb_reserved;
-  uint32_t sadb_comb_soft_allocations;
-  uint32_t sadb_comb_hard_allocations;
-  uint64_t sadb_comb_soft_bytes;
-  uint64_t sadb_comb_hard_bytes;
-  uint64_t sadb_comb_soft_addtime;
-  uint64_t sadb_comb_hard_addtime;
-  uint64_t sadb_comb_soft_usetime;
-  uint64_t sadb_comb_hard_usetime;
-  uint32_t sadb_comb_soft_packets;
-  uint32_t sadb_comb_hard_packets;
-#endif
-errlab:
-       return error;
-}
-
-int
-pfkey_supported_build(struct sadb_ext**        pfkey_ext,
-                     uint16_t          exttype,
-                     unsigned int      alg_num,
-                     struct sadb_alg*  alg)
-{
-       int error = 0;
-       unsigned int i;
-       struct sadb_supported *pfkey_supported = (struct sadb_supported *)*pfkey_ext;
-       struct sadb_alg *pfkey_alg;
-
-       /* sanity checks... */
-       if (pfkey_supported) {
-               DEBUGGING(
-                       "pfkey_supported_build: "
-                       "why is pfkey_supported already pointing to something?\n");
-               SENDERR(EINVAL);
-       }
-
-       if ( !((exttype == SADB_EXT_SUPPORTED_AUTH) || (exttype == SADB_EXT_SUPPORTED_ENCRYPT))) {
-               DEBUGGING(
-                       "pfkey_supported_build: "
-                       "unsupported extension type=%d.\n",
-                       exttype);
-               SENDERR(EINVAL);
-       }
-
-       pfkey_supported = (struct sadb_supported*)
-               MALLOC(sizeof(struct sadb_supported) +
-                       alg_num * sizeof(struct sadb_alg));
-
-       *pfkey_ext = (struct sadb_ext*)pfkey_supported;
-
-       if (pfkey_supported == NULL) {
-               DEBUGGING(
-                       "pfkey_supported_build: "
-                       "memory allocation failed\n");
-               SENDERR(ENOMEM);
-       }
-       memset(pfkey_supported,
-              0,
-              sizeof(struct sadb_supported) +
-                                              alg_num *
-                                              sizeof(struct sadb_alg));
-
-       pfkey_supported->sadb_supported_len = (sizeof(struct sadb_supported) +
-                                              alg_num *
-                                              sizeof(struct sadb_alg)) /
-                                               IPSEC_PFKEYv2_ALIGN;
-       pfkey_supported->sadb_supported_exttype = exttype;
-       pfkey_supported->sadb_supported_reserved = 0;
-
-       pfkey_alg = (struct sadb_alg*)((char*)pfkey_supported + sizeof(struct sadb_supported));
-       for(i = 0; i < alg_num; i++) {
-               memcpy (pfkey_alg, &(alg[i]), sizeof(struct sadb_alg));
-               pfkey_alg->sadb_alg_reserved = 0;
-               pfkey_alg++;
-       }
-
-#if 0
-       DEBUGGING(
-               "pfkey_supported_build: "
-               "Sorry, I can't build exttype=%d yet.\n",
-               (*pfkey_ext)->sadb_ext_type);
-       SENDERR(EINVAL); /* don't process these yet */
-
-  uint8_t sadb_alg_id;
-  uint8_t sadb_alg_ivlen;
-  uint16_t sadb_alg_minbits;
-  uint16_t sadb_alg_maxbits;
-  uint16_t sadb_alg_reserved;
-#endif
-errlab:
-       return error;
-}
-
-int
-pfkey_spirange_build(struct sadb_ext** pfkey_ext,
-                    uint16_t           exttype,
-                    uint32_t           min, /* in network order */
-                    uint32_t           max) /* in network order */
-{
-       int error = 0;
-       struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)*pfkey_ext;
-
-       /* sanity checks... */
-       if (pfkey_spirange) {
-               DEBUGGING(
-                       "pfkey_spirange_build: "
-                       "why is pfkey_spirange already pointing to something?\n");
-               SENDERR(EINVAL);
-       }
-
-        if (ntohl(max) < ntohl(min)) {
-               DEBUGGING(
-                       "pfkey_spirange_build: "
-                       "minspi=%08x must be < maxspi=%08x.\n",
-                       ntohl(min),
-                       ntohl(max));
-                SENDERR(EINVAL);
-        }
-
-       if (ntohl(min) <= 255) {
-               DEBUGGING(
-                       "pfkey_spirange_build: "
-                       "minspi=%08x must be > 255.\n",
-                       ntohl(min));
-               SENDERR(EEXIST);
-       }
-
-       pfkey_spirange = (struct sadb_spirange*)
-               MALLOC(sizeof(struct sadb_spirange));
-       *pfkey_ext = (struct sadb_ext*)pfkey_spirange;
-
-       if (pfkey_spirange == NULL) {
-               DEBUGGING(
-                       "pfkey_spirange_build: "
-                       "memory allocation failed\n");
-               SENDERR(ENOMEM);
-       }
-       memset(pfkey_spirange,
-              0,
-              sizeof(struct sadb_spirange));
-
-        pfkey_spirange->sadb_spirange_len = sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN;
-
-       pfkey_spirange->sadb_spirange_exttype = SADB_EXT_SPIRANGE;
-       pfkey_spirange->sadb_spirange_min = min;
-       pfkey_spirange->sadb_spirange_max = max;
-       pfkey_spirange->sadb_spirange_reserved = 0;
- errlab:
-       return error;
-}
-
-int
-pfkey_x_kmprivate_build(struct sadb_ext**      pfkey_ext)
-{
-       int error = 0;
-       struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)*pfkey_ext;
-
-       /* sanity checks... */
-       if (pfkey_x_kmprivate) {
-               DEBUGGING(
-                       "pfkey_x_kmprivate_build: "
-                       "why is pfkey_x_kmprivate already pointing to something?\n");
-               SENDERR(EINVAL);
-       }
-
-       pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0;
-
-       DEBUGGING(
-               "pfkey_x_kmprivate_build: "
-               "Sorry, I can't build exttype=%d yet.\n",
-               (*pfkey_ext)->sadb_ext_type);
-       SENDERR(EINVAL); /* don't process these yet */
-
-       pfkey_x_kmprivate = (struct sadb_x_kmprivate*)
-               MALLOC(sizeof(struct sadb_x_kmprivate));
-       *pfkey_ext = (struct sadb_ext*)pfkey_x_kmprivate;
-
-       if (pfkey_x_kmprivate == NULL) {
-               DEBUGGING(
-                       "pfkey_x_kmprivate_build: "
-                       "memory allocation failed\n");
-               SENDERR(ENOMEM);
-       }
-       memset(pfkey_x_kmprivate,
-              0,
-              sizeof(struct sadb_x_kmprivate));
-
-        pfkey_x_kmprivate->sadb_x_kmprivate_len =
-               sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN;
-
-        pfkey_x_kmprivate->sadb_x_kmprivate_exttype = SADB_X_EXT_KMPRIVATE;
-        pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0;
-errlab:
-       return error;
-}
-
-int
-pfkey_x_satype_build(struct sadb_ext** pfkey_ext,
-                    uint8_t            satype)
-{
-       int error = 0;
-       int i;
-       struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)*pfkey_ext;
-
-       DEBUGGING(
-               "pfkey_x_satype_build:\n");
-       /* sanity checks... */
-       if (pfkey_x_satype) {
-               DEBUGGING(
-                       "pfkey_x_satype_build: "
-                       "why is pfkey_x_satype already pointing to something?\n");
-               SENDERR(EINVAL);
-       }
-
-       if (!satype) {
-               DEBUGGING(
-                       "pfkey_x_satype_build: "
-                       "SA type not set, must be non-zero.\n");
-               SENDERR(EINVAL);
-       }
-
-       if (satype > SADB_SATYPE_MAX) {
-               DEBUGGING(
-                       "pfkey_x_satype_build: "
-                       "satype %d > max %d\n",
-                       satype, SADB_SATYPE_MAX);
-               SENDERR(EINVAL);
-       }
-
-       pfkey_x_satype = (struct sadb_x_satype*)
-            MALLOC(sizeof(struct sadb_x_satype));
-
-       *pfkey_ext = (struct sadb_ext*)pfkey_x_satype;
-
-       if (pfkey_x_satype == NULL) {
-               DEBUGGING(
-                       "pfkey_x_satype_build: "
-                       "memory allocation failed\n");
-               SENDERR(ENOMEM);
-       }
-       memset(pfkey_x_satype,
-              0,
-              sizeof(struct sadb_x_satype));
-
-        pfkey_x_satype->sadb_x_satype_len = sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN;
-
-       pfkey_x_satype->sadb_x_satype_exttype = SADB_X_EXT_SATYPE2;
-       pfkey_x_satype->sadb_x_satype_satype = satype;
-       for (i=0; i<3; i++) {
-               pfkey_x_satype->sadb_x_satype_reserved[i] = 0;
-       }
-
-errlab:
-       return error;
-}
-
-int
-pfkey_x_debug_build(struct sadb_ext**  pfkey_ext,
-                   uint32_t            tunnel,
-                   uint32_t            netlink,
-                   uint32_t            xform,
-                   uint32_t            eroute,
-                   uint32_t            spi,
-                   uint32_t            radij,
-                   uint32_t            esp,
-                   uint32_t            ah,
-                   uint32_t            rcv,
-                   uint32_t            pfkey,
-                   uint32_t            ipcomp,
-                   uint32_t            verbose)
-{
-       int error = 0;
-       int i;
-       struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)*pfkey_ext;
-
-       DEBUGGING(
-               "pfkey_x_debug_build:\n");
-       /* sanity checks... */
-       if (pfkey_x_debug) {
-               DEBUGGING(
-                       "pfkey_x_debug_build: "
-                       "why is pfkey_x_debug already pointing to something?\n");
-               SENDERR(EINVAL);
-       }
-
-       DEBUGGING(
-               "pfkey_x_debug_build: "
-               "tunnel=%x netlink=%x xform=%x eroute=%x spi=%x radij=%x esp=%x ah=%x rcv=%x pfkey=%x ipcomp=%x verbose=%x?\n",
-               tunnel, netlink, xform, eroute, spi, radij, esp, ah, rcv, pfkey, ipcomp, verbose);
-
-       pfkey_x_debug = (struct sadb_x_debug*)
-               MALLOC(sizeof(struct sadb_x_debug));
-       *pfkey_ext = (struct sadb_ext*)pfkey_x_debug;
-
-       if (pfkey_x_debug == NULL) {
-               DEBUGGING(
-                       "pfkey_x_debug_build: "
-                       "memory allocation failed\n");
-               SENDERR(ENOMEM);
-       }
-#if 0
-       memset(pfkey_x_debug,
-              0,
-              sizeof(struct sadb_x_debug));
-#endif
-
-        pfkey_x_debug->sadb_x_debug_len = sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN;
-       pfkey_x_debug->sadb_x_debug_exttype = SADB_X_EXT_DEBUG;
-
-       pfkey_x_debug->sadb_x_debug_tunnel = tunnel;
-       pfkey_x_debug->sadb_x_debug_netlink = netlink;
-       pfkey_x_debug->sadb_x_debug_xform = xform;
-       pfkey_x_debug->sadb_x_debug_eroute = eroute;
-       pfkey_x_debug->sadb_x_debug_spi = spi;
-       pfkey_x_debug->sadb_x_debug_radij = radij;
-       pfkey_x_debug->sadb_x_debug_esp = esp;
-       pfkey_x_debug->sadb_x_debug_ah = ah;
-       pfkey_x_debug->sadb_x_debug_rcv = rcv;
-       pfkey_x_debug->sadb_x_debug_pfkey = pfkey;
-       pfkey_x_debug->sadb_x_debug_ipcomp = ipcomp;
-       pfkey_x_debug->sadb_x_debug_verbose = verbose;
-
-       for (i=0; i<4; i++) {
-               pfkey_x_debug->sadb_x_debug_reserved[i] = 0;
-       }
-
-errlab:
-       return error;
-}
-
-int
-pfkey_x_nat_t_type_build(struct sadb_ext**     pfkey_ext,
-                   uint8_t         type)
-{
-       int error = 0;
-       int i;
-       struct sadb_x_nat_t_type *pfkey_x_nat_t_type = (struct sadb_x_nat_t_type *)*pfkey_ext;
-
-       DEBUGGING(
-               "pfkey_x_nat_t_type_build:\n");
-       /* sanity checks... */
-       if (pfkey_x_nat_t_type) {
-               DEBUGGING(
-                       "pfkey_x_nat_t_type_build: "
-                       "why is pfkey_x_nat_t_type already pointing to something?\n");
-               SENDERR(EINVAL);
-       }
-
-       DEBUGGING(
-               "pfkey_x_nat_t_type_build: "
-               "type=%d\n", type);
-
-       pfkey_x_nat_t_type = (struct sadb_x_nat_t_type*)
-               MALLOC(sizeof(struct sadb_x_nat_t_type));
-
-       *pfkey_ext = (struct sadb_ext*)pfkey_x_nat_t_type;
-       if (pfkey_x_nat_t_type == NULL) {
-               DEBUGGING(
-                       "pfkey_x_nat_t_type_build: "
-                       "memory allocation failed\n");
-               SENDERR(ENOMEM);
-       }
-
-       pfkey_x_nat_t_type->sadb_x_nat_t_type_len = sizeof(struct sadb_x_nat_t_type) / IPSEC_PFKEYv2_ALIGN;
-       pfkey_x_nat_t_type->sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE;
-       pfkey_x_nat_t_type->sadb_x_nat_t_type_type = type;
-       for (i=0; i<3; i++) {
-               pfkey_x_nat_t_type->sadb_x_nat_t_type_reserved[i] = 0;
-       }
-
-errlab:
-       return error;
-}
-
-int
-pfkey_x_nat_t_port_build(struct sadb_ext**     pfkey_ext,
-                   uint16_t         exttype,
-                   uint16_t         port)
-{
-       int error = 0;
-       struct sadb_x_nat_t_port *pfkey_x_nat_t_port = (struct sadb_x_nat_t_port *)*pfkey_ext;
-
-       DEBUGGING(
-               "pfkey_x_nat_t_port_build:\n");
-       /* sanity checks... */
-       if (pfkey_x_nat_t_port) {
-               DEBUGGING(
-                       "pfkey_x_nat_t_port_build: "
-                       "why is pfkey_x_nat_t_port already pointing to something?\n");
-               SENDERR(EINVAL);
-       }
-
-       switch (exttype) {
-       case SADB_X_EXT_NAT_T_SPORT:
-       case SADB_X_EXT_NAT_T_DPORT:
-               break;
-       default:
-               DEBUGGING(
-                       "pfkey_nat_t_port_build: "
-                       "unrecognised ext_type=%d.\n",
-                       exttype);
-               SENDERR(EINVAL);
-       }
-
-       DEBUGGING(
-               "pfkey_x_nat_t_port_build: "
-               "ext=%d, port=%d\n", exttype, port);
-
-       pfkey_x_nat_t_port = (struct sadb_x_nat_t_port*)
-               MALLOC(sizeof(struct sadb_x_nat_t_port));
-       *pfkey_ext = (struct sadb_ext*)pfkey_x_nat_t_port;
-
-       if (pfkey_x_nat_t_port == NULL) {
-               DEBUGGING(
-                       "pfkey_x_nat_t_port_build: "
-                       "memory allocation failed\n");
-               SENDERR(ENOMEM);
-       }
-
-       pfkey_x_nat_t_port->sadb_x_nat_t_port_len = sizeof(struct sadb_x_nat_t_port) / IPSEC_PFKEYv2_ALIGN;
-       pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype = exttype;
-       pfkey_x_nat_t_port->sadb_x_nat_t_port_port = port;
-       pfkey_x_nat_t_port->sadb_x_nat_t_port_reserved = 0;
-
-errlab:
-       return error;
-}
-
-int pfkey_x_protocol_build(struct sadb_ext **pfkey_ext,
-                          uint8_t protocol)
-{
-       int error = 0;
-       struct sadb_protocol * p = (struct sadb_protocol *)*pfkey_ext;
-       DEBUGGING("pfkey_x_protocol_build: protocol=%u\n", protocol);
-       /* sanity checks... */
-       if  (p != 0) {
-               DEBUGGING("pfkey_x_protocol_build: bogus protocol pointer\n");
-               SENDERR(EINVAL);
-       }
-       if ((p = (struct sadb_protocol*)MALLOC(sizeof(*p))) == 0) {
-               DEBUGGING("pfkey_build: memory allocation failed\n");
-               SENDERR(ENOMEM);
-       }
-       *pfkey_ext = (struct sadb_ext *)p;
-       p->sadb_protocol_len = sizeof(*p) / sizeof(uint64_t);
-       p->sadb_protocol_exttype = SADB_X_EXT_PROTOCOL;
-       p->sadb_protocol_proto = protocol;
-       p->sadb_protocol_flags = 0;
-       p->sadb_protocol_reserved2 = 0;
- errlab:
-       return error;
-}
-
-
-#if I_DONT_THINK_THIS_WILL_BE_USEFUL
-int (*ext_default_builders[SADB_EXT_MAX +1])(struct sadb_msg*, struct sadb_ext*)
- =
-{
-       NULL, /* pfkey_msg_build, */
-       pfkey_sa_build,
-       pfkey_lifetime_build,
-       pfkey_lifetime_build,
-       pfkey_lifetime_build,
-       pfkey_address_build,
-       pfkey_address_build,
-       pfkey_address_build,
-       pfkey_key_build,
-       pfkey_key_build,
-       pfkey_ident_build,
-       pfkey_ident_build,
-       pfkey_sens_build,
-       pfkey_prop_build,
-       pfkey_supported_build,
-       pfkey_supported_build,
-       pfkey_spirange_build,
-       pfkey_x_kmprivate_build,
-       pfkey_x_satype_build,
-       pfkey_sa_build,
-       pfkey_address_build,
-       pfkey_address_build,
-       pfkey_address_build,
-       pfkey_address_build,
-       pfkey_address_build,
-       pfkey_x_ext_debug_build
-};
-#endif
-
-int
-pfkey_msg_build(struct sadb_msg **pfkey_msg, struct sadb_ext *extensions[], int dir)
-{
-       int error = 0;
-       unsigned ext;
-       unsigned total_size;
-       struct sadb_ext *pfkey_ext;
-       int extensions_seen = 0;
-       struct sadb_ext *extensions_check[SADB_EXT_MAX + 1];
-
-       if (!extensions[0]) {
-               DEBUGGING(
-                       "pfkey_msg_build: "
-                       "extensions[0] must be specified (struct sadb_msg).\n");
-               SENDERR(EINVAL);
-       }
-
-       total_size = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
-       for (ext = 1; ext <= SADB_EXT_MAX; ext++) {
-               if(extensions[ext]) {
-                       total_size += (extensions[ext])->sadb_ext_len;
-               }
-        }
-
-       if (!(*pfkey_msg = (struct sadb_msg*)MALLOC(total_size * IPSEC_PFKEYv2_ALIGN))) {
-               DEBUGGING(
-                       "pfkey_msg_build: "
-                       "memory allocation failed\n");
-               SENDERR(ENOMEM);
-       }
-
-       DEBUGGING(
-               "pfkey_msg_build: "
-               "pfkey_msg=0p%p allocated %lu bytes, &(extensions[0])=0p%p\n",
-               *pfkey_msg,
-               (unsigned long)(total_size * IPSEC_PFKEYv2_ALIGN),
-               &(extensions[0]));
-       memcpy(*pfkey_msg,
-              extensions[0],
-              sizeof(struct sadb_msg));
-       (*pfkey_msg)->sadb_msg_len = total_size;
-       (*pfkey_msg)->sadb_msg_reserved = 0;
-       extensions_seen =  1 ;
-
-       pfkey_ext = (struct sadb_ext*)(((char*)(*pfkey_msg)) + sizeof(struct sadb_msg));
-
-       for (ext = 1; ext <= SADB_EXT_MAX; ext++) {
-               /* copy from extension[ext] to buffer */
-               if (extensions[ext]) {
-                       /* Is this type of extension permitted for this type of message? */
-                       if (!(extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type] &
-                            1<<ext)) {
-                               DEBUGGING(
-                                       "pfkey_msg_build: "
-                                       "ext type %d not permitted, exts_perm=%08x, 1<<type=%08x\n",
-                                       ext,
-                                       extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type],
-                                       1<<ext);
-                               SENDERR(EINVAL);
-                       }
-                       DEBUGGING(
-                               "pfkey_msg_build: "
-                               "copying %lu bytes from extensions[%u]=0p%p to=0p%p\n",
-                               (unsigned long)(extensions[ext]->sadb_ext_len * IPSEC_PFKEYv2_ALIGN),
-                               ext,
-                               extensions[ext],
-                               pfkey_ext);
-                       memcpy(pfkey_ext,
-                              extensions[ext],
-                              (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
-                       {
-                               char *pfkey_ext_c = (char *)pfkey_ext;
-
-                               pfkey_ext_c += (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN;
-                               pfkey_ext = (struct sadb_ext *)pfkey_ext_c;
-                       }
-                       /* Mark that we have seen this extension and remember the header location */
-                       extensions_seen |= ( 1 << ext );
-               }
-       }
-
-       /* check required extensions */
-       DEBUGGING(
-               "pfkey_msg_build: "
-               "extensions permitted=%08x, seen=%08x, required=%08x.\n",
-               extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type],
-               extensions_seen,
-               extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]);
-
-       if ((extensions_seen &
-           extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) !=
-           extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) {
-               DEBUGGING(
-                       "pfkey_msg_build: "
-                       "required extensions missing:%08x.\n",
-                       extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type] -
-                       (extensions_seen &
-                        extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) );
-               SENDERR(EINVAL);
-       }
-
-       error = pfkey_msg_parse(*pfkey_msg, NULL, extensions_check, dir);
-       if (error) {
-               DEBUGGING(
-                       "pfkey_msg_build: "
-                       "Trouble parsing newly built pfkey message, error=%d.\n",
-                       error);
-               SENDERR(-error);
-       }
-
-errlab:
-
-       return error;
-}
diff --git a/src/libfreeswan/pfkey_v2_debug.c b/src/libfreeswan/pfkey_v2_debug.c
deleted file mode 100644 (file)
index 0762d8f..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * @(#) pfkey version 2 debugging messages
- *
- * Copyright (C) 2001  Richard Guy Briggs  <rgb@freeswan.org>
- *                 and Michael Richardson  <mcr@freeswan.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-# include <sys/types.h>
-# include <errno.h>
-
-#include "freeswan.h"
-#include "pfkeyv2.h"
-#include "pfkey.h"
-
-/*
- * This file provides ASCII translations of PF_KEY magic numbers.
- *
- */
-
-static char *pfkey_sadb_ext_strings[]={
-  "reserved",                     /* SADB_EXT_RESERVED             0 */
-  "security-association",         /* SADB_EXT_SA                   1 */
-  "lifetime-current",             /* SADB_EXT_LIFETIME_CURRENT     2 */
-  "lifetime-hard",                /* SADB_EXT_LIFETIME_HARD        3 */
-  "lifetime-soft",                /* SADB_EXT_LIFETIME_SOFT        4 */
-  "source-address",               /* SADB_EXT_ADDRESS_SRC          5 */
-  "destination-address",          /* SADB_EXT_ADDRESS_DST          6 */
-  "proxy-address",                /* SADB_EXT_ADDRESS_PROXY        7 */
-  "authentication-key",           /* SADB_EXT_KEY_AUTH             8 */
-  "cipher-key",                   /* SADB_EXT_KEY_ENCRYPT          9 */
-  "source-identity",              /* SADB_EXT_IDENTITY_SRC         10 */
-  "destination-identity",         /* SADB_EXT_IDENTITY_DST         11 */
-  "sensitivity-label",            /* SADB_EXT_SENSITIVITY          12 */
-  "proposal",                     /* SADB_EXT_PROPOSAL             13 */
-  "supported-auth",               /* SADB_EXT_SUPPORTED_AUTH       14 */
-  "supported-cipher",             /* SADB_EXT_SUPPORTED_ENCRYPT    15 */
-  "spi-range",                    /* SADB_EXT_SPIRANGE             16 */
-  "X-kmpprivate",                 /* SADB_X_EXT_KMPRIVATE          17 */
-  "X-satype2",                    /* SADB_X_EXT_SATYPE2            18 */
-  "X-security-association",       /* SADB_X_EXT_SA2                19 */
-  "X-destination-address2",       /* SADB_X_EXT_ADDRESS_DST2       20 */
-  "X-source-flow-address",        /* SADB_X_EXT_ADDRESS_SRC_FLOW   21 */
-  "X-dest-flow-address",          /* SADB_X_EXT_ADDRESS_DST_FLOW   22 */
-  "X-source-mask",                /* SADB_X_EXT_ADDRESS_SRC_MASK   23 */
-  "X-dest-mask",                  /* SADB_X_EXT_ADDRESS_DST_MASK   24 */
-  "X-set-debug",                  /* SADB_X_EXT_DEBUG              25 */
-  "X-protocol",                   /* SADB_X_EXT_PROTOCOL           26 */
-  "X-NAT-T-type",                 /* SADB_X_EXT_NAT_T_TYPE         27 */
-  "X-NAT-T-sport",                /* SADB_X_EXT_NAT_T_SPORT        28 */
-  "X-NAT-T-dport",                /* SADB_X_EXT_NAT_T_DPORT        29 */
-  "X-NAT-T-OA",                   /* SADB_X_EXT_NAT_T_OA           30 */
-};
-
-const char *
-pfkey_v2_sadb_ext_string(int ext)
-{
-  if(ext <= SADB_EXT_MAX) {
-    return pfkey_sadb_ext_strings[ext];
-  } else {
-    return "unknown-ext";
-  }
-}
-
-
-static char *pfkey_sadb_type_strings[]={
-       "reserved",                     /* SADB_RESERVED            */
-       "getspi",                       /* SADB_GETSPI              */
-       "update",                       /* SADB_UPDATE              */
-       "add",                          /* SADB_ADD                 */
-       "delete",                       /* SADB_DELETE              */
-       "get",                          /* SADB_GET                 */
-       "acquire",                      /* SADB_ACQUIRE             */
-       "register",                     /* SADB_REGISTER            */
-       "expire",                       /* SADB_EXPIRE              */
-       "flush",                        /* SADB_FLUSH               */
-       "dump",                         /* SADB_DUMP                */
-       "x-promisc",                    /* SADB_X_PROMISC           */
-       "x-pchange",                    /* SADB_X_PCHANGE           */
-       "x-groupsa",                    /* SADB_X_GRPSA             */
-       "x-addflow(eroute)",            /* SADB_X_ADDFLOW           */
-       "x-delflow(eroute)",            /* SADB_X_DELFLOW           */
-       "x-debug",                      /* SADB_X_DEBUG             */
-       "x-nat-t-new-mapping",          /* SADB_X_NAT_T_NEW_MAPPING */
-};
-
-const char *
-pfkey_v2_sadb_type_string(int sadb_type)
-{
-  if(sadb_type <= SADB_MAX) {
-    return pfkey_sadb_type_strings[sadb_type];
-  } else {
-    return "unknown-sadb-type";
-  }
-}
diff --git a/src/libfreeswan/pfkey_v2_ext_bits.c b/src/libfreeswan/pfkey_v2_ext_bits.c
deleted file mode 100644 (file)
index 49b4aa5..0000000
+++ /dev/null
@@ -1,692 +0,0 @@
-/*
- * RFC2367 PF_KEYv2 Key management API message parser
- * Copyright (C) 1999, 2000, 2001  Richard Guy Briggs.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-/*
- *             Template from klips/net/ipsec/ipsec/ipsec_parse.c.
- */
-
-char pfkey_v2_ext_bits_c_version[] = "";
-
-# include <sys/types.h>
-# include <errno.h>
-
-#include <freeswan.h>
-#include <pfkeyv2.h>
-#include <pfkey.h>
-
-unsigned int extensions_bitmaps[2/*in/out*/][2/*perm/req*/][SADB_MAX + 1/*ext*/] = {
-
-/* INBOUND EXTENSIONS */
-{
-
-/* PERMITTED IN */
-{
-/* SADB_RESERVED */
-0
-,
-/* SADB_GETSPI */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-| 1<<SADB_EXT_ADDRESS_PROXY
-| 1<<SADB_EXT_SPIRANGE
-,
-/* SADB_UPDATE */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_LIFETIME_CURRENT
-| 1<<SADB_EXT_LIFETIME_HARD
-| 1<<SADB_EXT_LIFETIME_SOFT
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-| 1<<SADB_EXT_ADDRESS_PROXY
-| 1<<SADB_EXT_KEY_AUTH
-| 1<<SADB_EXT_KEY_ENCRYPT
-| 1<<SADB_EXT_IDENTITY_SRC
-| 1<<SADB_EXT_IDENTITY_DST
-| 1<<SADB_EXT_SENSITIVITY
-| 1<<SADB_X_EXT_NAT_T_SPORT
-| 1<<SADB_X_EXT_NAT_T_DPORT
-,
-/* SADB_ADD */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_LIFETIME_HARD
-| 1<<SADB_EXT_LIFETIME_SOFT
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-| 1<<SADB_EXT_ADDRESS_PROXY
-| 1<<SADB_EXT_KEY_AUTH
-| 1<<SADB_EXT_KEY_ENCRYPT
-| 1<<SADB_EXT_IDENTITY_SRC
-| 1<<SADB_EXT_IDENTITY_DST
-| 1<<SADB_EXT_SENSITIVITY
-| 1<<SADB_X_EXT_NAT_T_TYPE
-| 1<<SADB_X_EXT_NAT_T_SPORT
-| 1<<SADB_X_EXT_NAT_T_DPORT
-| 1<<SADB_X_EXT_NAT_T_OA
-,
-/* SADB_DELETE */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-,
-/* SADB_GET */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-,
-/* SADB_ACQUIRE */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-| 1<<SADB_EXT_ADDRESS_PROXY
-| 1<<SADB_EXT_IDENTITY_SRC
-| 1<<SADB_EXT_IDENTITY_DST
-| 1<<SADB_EXT_SENSITIVITY
-| 1<<SADB_EXT_PROPOSAL
-,
-/* SADB_REGISTER */
-1<<SADB_EXT_RESERVED
-,
-/* SADB_EXPIRE */
-0
-,
-/* SADB_FLUSH */
-1<<SADB_EXT_RESERVED
-,
-/* SADB_DUMP */
-1<<SADB_EXT_RESERVED
-,
-/* SADB_X_PROMISC */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_LIFETIME_CURRENT
-| 1<<SADB_EXT_LIFETIME_HARD
-| 1<<SADB_EXT_LIFETIME_SOFT
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-| 1<<SADB_EXT_ADDRESS_PROXY
-| 1<<SADB_EXT_KEY_AUTH
-| 1<<SADB_EXT_KEY_ENCRYPT
-| 1<<SADB_EXT_IDENTITY_SRC
-| 1<<SADB_EXT_IDENTITY_DST
-| 1<<SADB_EXT_SENSITIVITY
-| 1<<SADB_EXT_PROPOSAL
-| 1<<SADB_EXT_SUPPORTED_AUTH
-| 1<<SADB_EXT_SUPPORTED_ENCRYPT
-| 1<<SADB_EXT_SPIRANGE
-| 1<<SADB_X_EXT_KMPRIVATE
-| 1<<SADB_X_EXT_SATYPE2
-| 1<<SADB_X_EXT_SA2
-| 1<<SADB_X_EXT_ADDRESS_DST2
-,
-/* SADB_X_PCHANGE */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_LIFETIME_CURRENT
-| 1<<SADB_EXT_LIFETIME_HARD
-| 1<<SADB_EXT_LIFETIME_SOFT
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-| 1<<SADB_EXT_ADDRESS_PROXY
-| 1<<SADB_EXT_KEY_AUTH
-| 1<<SADB_EXT_KEY_ENCRYPT
-| 1<<SADB_EXT_IDENTITY_SRC
-| 1<<SADB_EXT_IDENTITY_DST
-| 1<<SADB_EXT_SENSITIVITY
-| 1<<SADB_EXT_PROPOSAL
-| 1<<SADB_EXT_SUPPORTED_AUTH
-| 1<<SADB_EXT_SUPPORTED_ENCRYPT
-| 1<<SADB_EXT_SPIRANGE
-| 1<<SADB_X_EXT_KMPRIVATE
-| 1<<SADB_X_EXT_SATYPE2
-| 1<<SADB_X_EXT_SA2
-| 1<<SADB_X_EXT_ADDRESS_DST2
-,
-/* SADB_X_GRPSA */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_ADDRESS_DST
-| 1<<SADB_X_EXT_SATYPE2
-| 1<<SADB_X_EXT_SA2
-| 1<<SADB_X_EXT_ADDRESS_DST2
-,
-/* SADB_X_ADDFLOW */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
-| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
-| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
-| 1<<SADB_X_EXT_ADDRESS_DST_MASK
-| 1<<SADB_EXT_IDENTITY_SRC
-| 1<<SADB_EXT_IDENTITY_DST
-| 1<<SADB_X_EXT_PROTOCOL
-,
-/* SADB_X_DELFLOW */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
-| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
-| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
-| 1<<SADB_X_EXT_ADDRESS_DST_MASK
-| 1<<SADB_EXT_IDENTITY_SRC
-| 1<<SADB_EXT_IDENTITY_DST
-| 1<<SADB_X_EXT_PROTOCOL
-,
-/* SADB_X_DEBUG */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_X_EXT_DEBUG
-,
-/* SADB_X_NAT_T_NEW_MAPPING */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-| 1<<SADB_X_EXT_NAT_T_SPORT
-| 1<<SADB_X_EXT_NAT_T_DPORT
-},
-
-/* REQUIRED IN */
-{
-/* SADB_RESERVED */
-0
-,
-/* SADB_GETSPI */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-| 1<<SADB_EXT_SPIRANGE
-,
-/* SADB_UPDATE */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-/*| 1<<SADB_EXT_KEY_AUTH*/
-/*| 1<<SADB_EXT_KEY_ENCRYPT*/
-,
-/* SADB_ADD */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-/*| 1<<SADB_EXT_KEY_AUTH*/
-/*| 1<<SADB_EXT_KEY_ENCRYPT*/
-,
-/* SADB_DELETE */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-,
-/* SADB_GET */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-,
-/* SADB_ACQUIRE */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-| 1<<SADB_EXT_PROPOSAL
-,
-/* SADB_REGISTER */
-1<<SADB_EXT_RESERVED
-,
-/* SADB_EXPIRE */
-0
-,
-/* SADB_FLUSH */
-1<<SADB_EXT_RESERVED
-,
-/* SADB_DUMP */
-1<<SADB_EXT_RESERVED
-,
-/* SADB_X_PROMISC */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_LIFETIME_CURRENT
-| 1<<SADB_EXT_LIFETIME_HARD
-| 1<<SADB_EXT_LIFETIME_SOFT
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-| 1<<SADB_EXT_ADDRESS_PROXY
-| 1<<SADB_EXT_KEY_AUTH
-| 1<<SADB_EXT_KEY_ENCRYPT
-| 1<<SADB_EXT_IDENTITY_SRC
-| 1<<SADB_EXT_IDENTITY_DST
-| 1<<SADB_EXT_SENSITIVITY
-| 1<<SADB_EXT_PROPOSAL
-| 1<<SADB_EXT_SUPPORTED_AUTH
-| 1<<SADB_EXT_SUPPORTED_ENCRYPT
-| 1<<SADB_EXT_SPIRANGE
-| 1<<SADB_X_EXT_KMPRIVATE
-| 1<<SADB_X_EXT_SATYPE2
-| 1<<SADB_X_EXT_SA2
-| 1<<SADB_X_EXT_ADDRESS_DST2
-,
-/* SADB_X_PCHANGE */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_LIFETIME_CURRENT
-| 1<<SADB_EXT_LIFETIME_HARD
-| 1<<SADB_EXT_LIFETIME_SOFT
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-| 1<<SADB_EXT_ADDRESS_PROXY
-| 1<<SADB_EXT_KEY_AUTH
-| 1<<SADB_EXT_KEY_ENCRYPT
-| 1<<SADB_EXT_IDENTITY_SRC
-| 1<<SADB_EXT_IDENTITY_DST
-| 1<<SADB_EXT_SENSITIVITY
-| 1<<SADB_EXT_PROPOSAL
-| 1<<SADB_EXT_SUPPORTED_AUTH
-| 1<<SADB_EXT_SUPPORTED_ENCRYPT
-| 1<<SADB_EXT_SPIRANGE
-| 1<<SADB_X_EXT_KMPRIVATE
-| 1<<SADB_X_EXT_SATYPE2
-| 1<<SADB_X_EXT_SA2
-| 1<<SADB_X_EXT_ADDRESS_DST2
-,
-/* SADB_X_GRPSA */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_ADDRESS_DST
-/*| 1<<SADB_X_EXT_SATYPE2*/
-/*| 1<<SADB_X_EXT_SA2*/
-/*| 1<<SADB_X_EXT_ADDRESS_DST2*/
-,
-/* SADB_X_ADDFLOW */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_ADDRESS_DST
-| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
-| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
-| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
-| 1<<SADB_X_EXT_ADDRESS_DST_MASK
-,
-/* SADB_X_DELFLOW */
-1<<SADB_EXT_RESERVED
-/*| 1<<SADB_EXT_SA*/
-#if 0 /* SADB_X_CLREROUTE doesn't need all these... */
-| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
-| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
-| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
-| 1<<SADB_X_EXT_ADDRESS_DST_MASK
-#endif
-,
-/* SADB_X_DEBUG */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_X_EXT_DEBUG
-,
-/* SADB_X_NAT_T_NEW_MAPPING */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-| 1<<SADB_X_EXT_NAT_T_SPORT
-| 1<<SADB_X_EXT_NAT_T_DPORT
-}
-
-},
-
-/* OUTBOUND EXTENSIONS */
-{
-
-/* PERMITTED OUT */
-{
-/* SADB_RESERVED */
-0
-,
-/* SADB_GETSPI */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-,
-/* SADB_UPDATE */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_LIFETIME_CURRENT
-| 1<<SADB_EXT_LIFETIME_HARD
-| 1<<SADB_EXT_LIFETIME_SOFT
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-| 1<<SADB_EXT_ADDRESS_PROXY
-| 1<<SADB_EXT_IDENTITY_SRC
-| 1<<SADB_EXT_IDENTITY_DST
-| 1<<SADB_EXT_SENSITIVITY
-,
-/* SADB_ADD */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_LIFETIME_HARD
-| 1<<SADB_EXT_LIFETIME_SOFT
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-| 1<<SADB_EXT_IDENTITY_SRC
-| 1<<SADB_EXT_IDENTITY_DST
-| 1<<SADB_EXT_SENSITIVITY
-| 1<<SADB_X_EXT_NAT_T_TYPE
-| 1<<SADB_X_EXT_NAT_T_SPORT
-| 1<<SADB_X_EXT_NAT_T_DPORT
-| 1<<SADB_X_EXT_NAT_T_OA
-,
-/* SADB_DELETE */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-,
-/* SADB_GET */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_LIFETIME_CURRENT
-| 1<<SADB_EXT_LIFETIME_HARD
-| 1<<SADB_EXT_LIFETIME_SOFT
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-| 1<<SADB_EXT_ADDRESS_PROXY
-| 1<<SADB_EXT_KEY_AUTH
-| 1<<SADB_EXT_KEY_ENCRYPT
-| 1<<SADB_EXT_IDENTITY_SRC
-| 1<<SADB_EXT_IDENTITY_DST
-| 1<<SADB_EXT_SENSITIVITY
-,
-/* SADB_ACQUIRE */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-| 1<<SADB_EXT_ADDRESS_PROXY
-| 1<<SADB_EXT_IDENTITY_SRC
-| 1<<SADB_EXT_IDENTITY_DST
-| 1<<SADB_EXT_SENSITIVITY
-| 1<<SADB_EXT_PROPOSAL
-,
-/* SADB_REGISTER */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SUPPORTED_AUTH
-| 1<<SADB_EXT_SUPPORTED_ENCRYPT
-,
-/* SADB_EXPIRE */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_LIFETIME_CURRENT
-| 1<<SADB_EXT_LIFETIME_HARD
-| 1<<SADB_EXT_LIFETIME_SOFT
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-,
-/* SADB_FLUSH */
-1<<SADB_EXT_RESERVED
-,
-/* SADB_DUMP */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_LIFETIME_CURRENT
-| 1<<SADB_EXT_LIFETIME_HARD
-| 1<<SADB_EXT_LIFETIME_SOFT
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-| 1<<SADB_EXT_ADDRESS_PROXY
-| 1<<SADB_EXT_KEY_AUTH
-| 1<<SADB_EXT_KEY_ENCRYPT
-| 1<<SADB_EXT_IDENTITY_SRC
-| 1<<SADB_EXT_IDENTITY_DST
-| 1<<SADB_EXT_SENSITIVITY
-,
-/* SADB_X_PROMISC */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_LIFETIME_CURRENT
-| 1<<SADB_EXT_LIFETIME_HARD
-| 1<<SADB_EXT_LIFETIME_SOFT
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-| 1<<SADB_EXT_ADDRESS_PROXY
-| 1<<SADB_EXT_KEY_AUTH
-| 1<<SADB_EXT_KEY_ENCRYPT
-| 1<<SADB_EXT_IDENTITY_SRC
-| 1<<SADB_EXT_IDENTITY_DST
-| 1<<SADB_EXT_SENSITIVITY
-| 1<<SADB_EXT_PROPOSAL
-| 1<<SADB_EXT_SUPPORTED_AUTH
-| 1<<SADB_EXT_SUPPORTED_ENCRYPT
-| 1<<SADB_EXT_SPIRANGE
-| 1<<SADB_X_EXT_KMPRIVATE
-| 1<<SADB_X_EXT_SATYPE2
-| 1<<SADB_X_EXT_SA2
-| 1<<SADB_X_EXT_ADDRESS_DST2
-,
-/* SADB_X_PCHANGE */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_LIFETIME_CURRENT
-| 1<<SADB_EXT_LIFETIME_HARD
-| 1<<SADB_EXT_LIFETIME_SOFT
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-| 1<<SADB_EXT_ADDRESS_PROXY
-| 1<<SADB_EXT_KEY_AUTH
-| 1<<SADB_EXT_KEY_ENCRYPT
-| 1<<SADB_EXT_IDENTITY_SRC
-| 1<<SADB_EXT_IDENTITY_DST
-| 1<<SADB_EXT_SENSITIVITY
-| 1<<SADB_EXT_PROPOSAL
-| 1<<SADB_EXT_SUPPORTED_AUTH
-| 1<<SADB_EXT_SUPPORTED_ENCRYPT
-| 1<<SADB_EXT_SPIRANGE
-| 1<<SADB_X_EXT_KMPRIVATE
-| 1<<SADB_X_EXT_SATYPE2
-| 1<<SADB_X_EXT_SA2
-| 1<<SADB_X_EXT_ADDRESS_DST2
-,
-/* SADB_X_GRPSA */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_ADDRESS_DST
-| 1<<SADB_X_EXT_SATYPE2
-| 1<<SADB_X_EXT_SA2
-| 1<<SADB_X_EXT_ADDRESS_DST2
-,
-/* SADB_X_ADDFLOW */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
-| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
-| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
-| 1<<SADB_X_EXT_ADDRESS_DST_MASK
-| 1<<SADB_X_EXT_PROTOCOL
-,
-/* SADB_X_DELFLOW */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
-| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
-| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
-| 1<<SADB_X_EXT_ADDRESS_DST_MASK
-| 1<<SADB_X_EXT_PROTOCOL
-,
-/* SADB_X_DEBUG */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_X_EXT_DEBUG
-,
-/* SADB_X_NAT_T_NEW_MAPPING */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-| 1<<SADB_X_EXT_NAT_T_SPORT
-| 1<<SADB_X_EXT_NAT_T_DPORT
-},
-
-/* REQUIRED OUT */
-{
-/* SADB_RESERVED */
-0
-,
-/* SADB_GETSPI */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-,
-/* SADB_UPDATE */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-,
-/* SADB_ADD */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-,
-/* SADB_DELETE */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-,
-/* SADB_GET */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-/* | 1<<SADB_EXT_KEY_AUTH */
-/* | 1<<SADB_EXT_KEY_ENCRYPT */
-,
-/* SADB_ACQUIRE */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-| 1<<SADB_EXT_PROPOSAL
-,
-/* SADB_REGISTER */
-1<<SADB_EXT_RESERVED
-/* | 1<<SADB_EXT_SUPPORTED_AUTH
-   | 1<<SADB_EXT_SUPPORTED_ENCRYPT */
-,
-/* SADB_EXPIRE */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_LIFETIME_CURRENT
-/* | 1<<SADB_EXT_LIFETIME_HARD
-   | 1<<SADB_EXT_LIFETIME_SOFT */
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-,
-/* SADB_FLUSH */
-1<<SADB_EXT_RESERVED
-,
-/* SADB_DUMP */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-| 1<<SADB_EXT_KEY_AUTH
-| 1<<SADB_EXT_KEY_ENCRYPT
-,
-/* SADB_X_PROMISC */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_LIFETIME_CURRENT
-| 1<<SADB_EXT_LIFETIME_HARD
-| 1<<SADB_EXT_LIFETIME_SOFT
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-| 1<<SADB_EXT_ADDRESS_PROXY
-| 1<<SADB_EXT_KEY_AUTH
-| 1<<SADB_EXT_KEY_ENCRYPT
-| 1<<SADB_EXT_IDENTITY_SRC
-| 1<<SADB_EXT_IDENTITY_DST
-| 1<<SADB_EXT_SENSITIVITY
-| 1<<SADB_EXT_PROPOSAL
-| 1<<SADB_EXT_SUPPORTED_AUTH
-| 1<<SADB_EXT_SUPPORTED_ENCRYPT
-| 1<<SADB_EXT_SPIRANGE
-| 1<<SADB_X_EXT_KMPRIVATE
-| 1<<SADB_X_EXT_SATYPE2
-| 1<<SADB_X_EXT_SA2
-| 1<<SADB_X_EXT_ADDRESS_DST2
-,
-/* SADB_X_PCHANGE */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_LIFETIME_CURRENT
-| 1<<SADB_EXT_LIFETIME_HARD
-| 1<<SADB_EXT_LIFETIME_SOFT
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-| 1<<SADB_EXT_ADDRESS_PROXY
-| 1<<SADB_EXT_KEY_AUTH
-| 1<<SADB_EXT_KEY_ENCRYPT
-| 1<<SADB_EXT_IDENTITY_SRC
-| 1<<SADB_EXT_IDENTITY_DST
-| 1<<SADB_EXT_SENSITIVITY
-| 1<<SADB_EXT_PROPOSAL
-| 1<<SADB_EXT_SUPPORTED_AUTH
-| 1<<SADB_EXT_SUPPORTED_ENCRYPT
-| 1<<SADB_EXT_SPIRANGE
-| 1<<SADB_X_EXT_KMPRIVATE
-| 1<<SADB_X_EXT_SATYPE2
-| 1<<SADB_X_EXT_SA2
-| 1<<SADB_X_EXT_ADDRESS_DST2
-,
-/* SADB_X_GRPSA */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_ADDRESS_DST
-,
-/* SADB_X_ADDFLOW */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_ADDRESS_DST
-| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
-| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
-| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
-| 1<<SADB_X_EXT_ADDRESS_DST_MASK
-,
-/* SADB_X_DELFLOW */
-1<<SADB_EXT_RESERVED
-/*| 1<<SADB_EXT_SA*/
-| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
-| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
-| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
-| 1<<SADB_X_EXT_ADDRESS_DST_MASK
-,
-/* SADB_X_DEBUG */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_X_EXT_DEBUG
-,
-/* SADB_X_NAT_T_NEW_MAPPING */
-1<<SADB_EXT_RESERVED
-| 1<<SADB_EXT_SA
-| 1<<SADB_EXT_ADDRESS_SRC
-| 1<<SADB_EXT_ADDRESS_DST
-| 1<<SADB_X_EXT_NAT_T_SPORT
-| 1<<SADB_X_EXT_NAT_T_DPORT
-}
-}
-};
diff --git a/src/libfreeswan/pfkey_v2_parse.c b/src/libfreeswan/pfkey_v2_parse.c
deleted file mode 100644 (file)
index 8fec9d1..0000000
+++ /dev/null
@@ -1,1539 +0,0 @@
-/*
- * RFC2367 PF_KEYv2 Key management API message parser
- * Copyright (C) 1999, 2000, 2001  Richard Guy Briggs.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-/*
- *             Template from klips/net/ipsec/ipsec/ipsec_parser.c.
- */
-
-char pfkey_v2_parse_c_version[] = "";
-
-# include <sys/types.h>
-# include <sys/socket.h>
-# include <errno.h>
-
-# include <freeswan.h>
-# include <constants.h>
-# include <defs.h>  /* for PRINTF_LIKE */
-# include <log.h>  /* for debugging and DBG_log */
-
-# ifdef PLUTO
-#  define DEBUGGING(level, args...)  { DBG_log("pfkey_lib_debug:" args);  }
-# else
-#  define DEBUGGING(level, args...)  if(pfkey_lib_debug & level) { printf("pfkey_lib_debug:" args); } else { ; }
-# endif
-
-#include <pfkeyv2.h>
-#include <pfkey.h>
-
-
-#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
-
-static struct {
-       uint8_t proto;
-       uint8_t satype;
-       char* name;
-} satype_tbl[] = {
-       { SA_ESP,       SADB_SATYPE_ESP,        "ESP"  },
-       { SA_AH,        SADB_SATYPE_AH,         "AH"   },
-       { SA_IPIP,      SADB_X_SATYPE_IPIP,     "IPIP" },
-       { SA_COMP,      SADB_X_SATYPE_COMP,     "COMP" },
-       { SA_INT,       SADB_X_SATYPE_INT,      "INT" },
-       { 0,            0,                      "UNKNOWN" }
-};
-
-uint8_t
-satype2proto(uint8_t satype)
-{
-       int i =0;
-
-       while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) {
-               i++;
-       }
-       return satype_tbl[i].proto;
-}
-
-uint8_t
-proto2satype(uint8_t proto)
-{
-       int i = 0;
-
-       while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) {
-               i++;
-       }
-       return satype_tbl[i].satype;
-}
-
-char*
-satype2name(uint8_t satype)
-{
-       int i = 0;
-
-       while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) {
-               i++;
-       }
-       return satype_tbl[i].name;
-}
-
-char*
-proto2name(uint8_t proto)
-{
-       int i = 0;
-
-       while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) {
-               i++;
-       }
-       return satype_tbl[i].name;
-}
-
-/* Default extension parsers taken from the KLIPS code */
-
-DEBUG_NO_STATIC int
-pfkey_sa_parse(struct sadb_ext *pfkey_ext)
-{
-       int error = 0;
-       struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext;
-#if 0
-       struct sadb_sa sav2;
-#endif
-
-       DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
-                 "pfkey_sa_parse: entry\n");
-       /* sanity checks... */
-       if(!pfkey_sa) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                         "pfkey_sa_parse: "
-                         "NULL pointer passed in.\n");
-               SENDERR(EINVAL);
-       }
-
-#if 0
-       /* check if this structure is short, and if so, fix it up.
-        * XXX this is NOT the way to do things.
-        */
-       if(pfkey_sa->sadb_sa_len == sizeof(struct sadb_sa_v1)/IPSEC_PFKEYv2_ALIGN) {
-
-               /* yes, so clear out a temporary structure, and copy first */
-               memset(&sav2, 0, sizeof(sav2));
-               memcpy(&sav2, pfkey_sa, sizeof(struct sadb_sa_v1));
-               sav2.sadb_x_sa_ref=-1;
-               sav2.sadb_sa_len = sizeof(struct sadb_sa) / IPSEC_PFKEYv2_ALIGN;
-
-               pfkey_sa = &sav2;
-       }
-#endif
-
-
-       if(pfkey_sa->sadb_sa_len != sizeof(struct sadb_sa) / IPSEC_PFKEYv2_ALIGN) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                         "pfkey_sa_parse: "
-                         "length wrong pfkey_sa->sadb_sa_len=%d sizeof(struct sadb_sa)=%d.\n",
-                         pfkey_sa->sadb_sa_len,
-                         (int)sizeof(struct sadb_sa));
-               SENDERR(EINVAL);
-       }
-
-       if(pfkey_sa->sadb_sa_encrypt > SADB_EALG_MAX) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                         "pfkey_sa_parse: "
-                         "pfkey_sa->sadb_sa_encrypt=%d > SADB_EALG_MAX=%d.\n",
-                         pfkey_sa->sadb_sa_encrypt,
-                         SADB_EALG_MAX);
-               SENDERR(EINVAL);
-       }
-
-       if(pfkey_sa->sadb_sa_auth > SADB_AALG_MAX) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                         "pfkey_sa_parse: "
-                         "pfkey_sa->sadb_sa_auth=%d > SADB_AALG_MAX=%d.\n",
-                         pfkey_sa->sadb_sa_auth,
-                         SADB_AALG_MAX);
-               SENDERR(EINVAL);
-       }
-
-       if(pfkey_sa->sadb_sa_state > SADB_SASTATE_MAX) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                         "pfkey_sa_parse: "
-                         "state=%d exceeds MAX=%d.\n",
-                         pfkey_sa->sadb_sa_state,
-                         SADB_SASTATE_MAX);
-               SENDERR(EINVAL);
-       }
-
-       if(pfkey_sa->sadb_sa_state == SADB_SASTATE_DEAD) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                         "pfkey_sa_parse: "
-                         "state=%d is DEAD=%d.\n",
-                         pfkey_sa->sadb_sa_state,
-                         SADB_SASTATE_DEAD);
-               SENDERR(EINVAL);
-       }
-
-       if(pfkey_sa->sadb_sa_replay > 64) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                         "pfkey_sa_parse: "
-                         "replay window size: %d -- must be 0 <= size <= 64\n",
-                         pfkey_sa->sadb_sa_replay);
-               SENDERR(EINVAL);
-       }
-
-       if(! ((pfkey_sa->sadb_sa_exttype ==  SADB_EXT_SA) ||
-             (pfkey_sa->sadb_sa_exttype ==  SADB_X_EXT_SA2)))
-       {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                         "pfkey_sa_parse: "
-                         "unknown exttype=%d, expecting SADB_EXT_SA=%d or SADB_X_EXT_SA2=%d.\n",
-                         pfkey_sa->sadb_sa_exttype,
-                         SADB_EXT_SA,
-                         SADB_X_EXT_SA2);
-               SENDERR(EINVAL);
-       }
-
-       if((IPSEC_SAREF_NULL != pfkey_sa->sadb_x_sa_ref) && (pfkey_sa->sadb_x_sa_ref >= (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH))) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                         "pfkey_sa_parse: "
-                         "SAref=%d must be (SAref == IPSEC_SAREF_NULL(%d) || SAref < IPSEC_SA_REF_TABLE_NUM_ENTRIES(%d)).\n",
-                         pfkey_sa->sadb_x_sa_ref,
-                         IPSEC_SAREF_NULL,
-                         IPSEC_SA_REF_TABLE_NUM_ENTRIES);
-               SENDERR(EINVAL);
-       }
-
-       DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
-                 "pfkey_sa_parse: "
-                 "successfully found len=%d exttype=%d(%s) spi=%08lx replay=%d state=%d auth=%d encrypt=%d flags=%d ref=%d.\n",
-                 pfkey_sa->sadb_sa_len,
-                 pfkey_sa->sadb_sa_exttype,
-                 pfkey_v2_sadb_ext_string(pfkey_sa->sadb_sa_exttype),
-                 (long unsigned int)ntohl(pfkey_sa->sadb_sa_spi),
-                 pfkey_sa->sadb_sa_replay,
-                 pfkey_sa->sadb_sa_state,
-                 pfkey_sa->sadb_sa_auth,
-                 pfkey_sa->sadb_sa_encrypt,
-                 pfkey_sa->sadb_sa_flags,
-                 pfkey_sa->sadb_x_sa_ref);
-
- errlab:
-       return error;
-}
-
-DEBUG_NO_STATIC int
-pfkey_lifetime_parse(struct sadb_ext  *pfkey_ext)
-{
-       int error = 0;
-       struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext;
-
-       DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
-                 "pfkey_lifetime_parse:enter\n");
-       /* sanity checks... */
-       if(!pfkey_lifetime) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                         "pfkey_lifetime_parse: "
-                         "NULL pointer passed in.\n");
-               SENDERR(EINVAL);
-       }
-
-       if(pfkey_lifetime->sadb_lifetime_len !=
-          sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                         "pfkey_lifetime_parse: "
-                         "length wrong pfkey_lifetime->sadb_lifetime_len=%d sizeof(struct sadb_lifetime)=%d.\n",
-                         pfkey_lifetime->sadb_lifetime_len,
-                         (int)sizeof(struct sadb_lifetime));
-               SENDERR(EINVAL);
-       }
-
-       if((pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_HARD) &&
-          (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_SOFT) &&
-          (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_CURRENT)) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                         "pfkey_lifetime_parse: "
-                         "unexpected ext_type=%d.\n",
-                         pfkey_lifetime->sadb_lifetime_exttype);
-               SENDERR(EINVAL);
-       }
-
-       DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
-                 "pfkey_lifetime_parse: "
-                 "life_type=%d(%s) alloc=%u bytes=%u add=%u use=%u pkts=%u.\n",
-                 pfkey_lifetime->sadb_lifetime_exttype,
-                 pfkey_v2_sadb_ext_string(pfkey_lifetime->sadb_lifetime_exttype),
-                 pfkey_lifetime->sadb_lifetime_allocations,
-                 (unsigned)pfkey_lifetime->sadb_lifetime_bytes,
-                 (unsigned)pfkey_lifetime->sadb_lifetime_addtime,
-                 (unsigned)pfkey_lifetime->sadb_lifetime_usetime,
-                 pfkey_lifetime->sadb_x_lifetime_packets);
-errlab:
-       return error;
-}
-
-DEBUG_NO_STATIC int
-pfkey_address_parse(struct sadb_ext *pfkey_ext)
-{
-       int error = 0;
-       int saddr_len = 0;
-       struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext;
-       struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address));
-       char ipaddr_txt[ADDRTOT_BUF];
-
-       DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
-               "pfkey_address_parse:enter\n");
-       /* sanity checks... */
-       if(!pfkey_address) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                       "pfkey_address_parse: "
-                       "NULL pointer passed in.\n");
-               SENDERR(EINVAL);
-       }
-
-       if(pfkey_address->sadb_address_len <
-          (sizeof(struct sadb_address) + sizeof(struct sockaddr))/
-          IPSEC_PFKEYv2_ALIGN) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                         "pfkey_address_parse: "
-                         "size wrong 1 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n",
-                         pfkey_address->sadb_address_len,
-                         (int)sizeof(struct sadb_address),
-                         (int)sizeof(struct sockaddr));
-               SENDERR(EINVAL);
-       }
-
-       if(pfkey_address->sadb_address_reserved) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                         "pfkey_address_parse: "
-                         "res=%d, must be zero.\n",
-                         pfkey_address->sadb_address_reserved);
-               SENDERR(EINVAL);
-       }
-
-       switch(pfkey_address->sadb_address_exttype) {
-       case SADB_EXT_ADDRESS_SRC:
-       case SADB_EXT_ADDRESS_DST:
-       case SADB_EXT_ADDRESS_PROXY:
-       case SADB_X_EXT_ADDRESS_DST2:
-       case SADB_X_EXT_ADDRESS_SRC_FLOW:
-       case SADB_X_EXT_ADDRESS_DST_FLOW:
-       case SADB_X_EXT_ADDRESS_SRC_MASK:
-       case SADB_X_EXT_ADDRESS_DST_MASK:
-       case SADB_X_EXT_NAT_T_OA:
-               break;
-       default:
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                       "pfkey_address_parse: "
-                       "unexpected ext_type=%d.\n",
-                       pfkey_address->sadb_address_exttype);
-               SENDERR(EINVAL);
-       }
-
-       switch(s->sa_family) {
-       case AF_INET:
-               saddr_len = sizeof(struct sockaddr_in);
-               sprintf(ipaddr_txt, "%d.%d.%d.%d"
-                       , (((struct sockaddr_in*)s)->sin_addr.s_addr >>  0) & 0xFF
-                       , (((struct sockaddr_in*)s)->sin_addr.s_addr >>  8) & 0xFF
-                       , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 16) & 0xFF
-                       , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 24) & 0xFF);
-               DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
-                         "pfkey_address_parse: "
-                         "found exttype=%u(%s) family=%d(AF_INET) address=%s proto=%u port=%u.\n",
-                         pfkey_address->sadb_address_exttype,
-                         pfkey_v2_sadb_ext_string(pfkey_address->sadb_address_exttype),
-                         s->sa_family,
-                         ipaddr_txt,
-                         pfkey_address->sadb_address_proto,
-                         ntohs(((struct sockaddr_in*)s)->sin_port));
-               break;
-       case AF_INET6:
-               saddr_len = sizeof(struct sockaddr_in6);
-               sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x"
-                       , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr[0])
-                       , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr[1])
-                       , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr[2])
-                       , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr[3])
-                       , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr[4])
-                       , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr[5])
-                       , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr[6])
-                       , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr[7]));
-               DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
-                         "pfkey_address_parse: "
-                         "found exttype=%u(%s) family=%d(AF_INET6) address=%s proto=%u port=%u.\n",
-                         pfkey_address->sadb_address_exttype,
-                         pfkey_v2_sadb_ext_string(pfkey_address->sadb_address_exttype),
-                         s->sa_family,
-                         ipaddr_txt,
-                         pfkey_address->sadb_address_proto,
-                         ((struct sockaddr_in6*)s)->sin6_port);
-               break;
-       default:
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                       "pfkey_address_parse: "
-                       "s->sa_family=%d not supported.\n",
-                       s->sa_family);
-               SENDERR(EPFNOSUPPORT);
-       }
-
-       if(pfkey_address->sadb_address_len !=
-          DIVUP(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN)) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                         "pfkey_address_parse: "
-                         "size wrong 2 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n",
-                         pfkey_address->sadb_address_len,
-                         (int)sizeof(struct sadb_address),
-                         saddr_len);
-               SENDERR(EINVAL);
-       }
-
-       if(pfkey_address->sadb_address_prefixlen != 0) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                       "pfkey_address_parse: "
-                       "address prefixes not supported yet.\n");
-               SENDERR(EAFNOSUPPORT); /* not supported yet */
-       }
-
-       /* XXX check if port!=0 */
-
-       DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
-               "pfkey_address_parse: successful.\n");
- errlab:
-       return error;
-}
-
-DEBUG_NO_STATIC int
-pfkey_key_parse(struct sadb_ext *pfkey_ext)
-{
-       int error = 0;
-       struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext;
-
-       DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
-               "pfkey_key_parse:enter\n");
-       /* sanity checks... */
-
-       if(!pfkey_key) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                       "pfkey_key_parse: "
-                       "NULL pointer passed in.\n");
-               SENDERR(EINVAL);
-       }
-
-       if(pfkey_key->sadb_key_len < sizeof(struct sadb_key) / IPSEC_PFKEYv2_ALIGN) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                         "pfkey_key_parse: "
-                         "size wrong ext_len=%d, key_ext_len=%d.\n",
-                         pfkey_key->sadb_key_len,
-                         (int)sizeof(struct sadb_key));
-               SENDERR(EINVAL);
-       }
-
-       if(!pfkey_key->sadb_key_bits) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                       "pfkey_key_parse: "
-                       "key length set to zero, must be non-zero.\n");
-               SENDERR(EINVAL);
-       }
-
-       if(pfkey_key->sadb_key_len !=
-          DIVUP(sizeof(struct sadb_key) * OCTETBITS + pfkey_key->sadb_key_bits,
-                PFKEYBITS)) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                       "pfkey_key_parse: "
-                       "key length=%d does not agree with extension length=%d.\n",
-                       pfkey_key->sadb_key_bits,
-                       pfkey_key->sadb_key_len);
-               SENDERR(EINVAL);
-       }
-
-       if(pfkey_key->sadb_key_reserved) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                       "pfkey_key_parse: "
-                       "res=%d, must be zero.\n",
-                       pfkey_key->sadb_key_reserved);
-               SENDERR(EINVAL);
-       }
-
-       if(! ( (pfkey_key->sadb_key_exttype == SADB_EXT_KEY_AUTH) ||
-              (pfkey_key->sadb_key_exttype == SADB_EXT_KEY_ENCRYPT))) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                       "pfkey_key_parse: "
-                       "expecting extension type AUTH or ENCRYPT, got %d.\n",
-                       pfkey_key->sadb_key_exttype);
-               SENDERR(EINVAL);
-       }
-
-       DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
-                 "pfkey_key_parse: "
-                 "success, found len=%d exttype=%d(%s) bits=%d reserved=%d.\n",
-                 pfkey_key->sadb_key_len,
-                 pfkey_key->sadb_key_exttype,
-                 pfkey_v2_sadb_ext_string(pfkey_key->sadb_key_exttype),
-                 pfkey_key->sadb_key_bits,
-                 pfkey_key->sadb_key_reserved);
-
-errlab:
-       return error;
-}
-
-DEBUG_NO_STATIC int
-pfkey_ident_parse(struct sadb_ext *pfkey_ext)
-{
-       int error = 0;
-       struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext;
-
-       /* sanity checks... */
-       if(pfkey_ident->sadb_ident_len < sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                         "pfkey_ident_parse: "
-                         "size wrong ext_len=%d, key_ext_len=%d.\n",
-                         pfkey_ident->sadb_ident_len,
-                         (int)sizeof(struct sadb_ident));
-               SENDERR(EINVAL);
-       }
-
-       if(pfkey_ident->sadb_ident_type > SADB_IDENTTYPE_MAX) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                       "pfkey_ident_parse: "
-                       "ident_type=%d out of range, must be less than %d.\n",
-                       pfkey_ident->sadb_ident_type,
-                       SADB_IDENTTYPE_MAX);
-               SENDERR(EINVAL);
-       }
-
-       if(pfkey_ident->sadb_ident_reserved) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                       "pfkey_ident_parse: "
-                       "res=%d, must be zero.\n",
-                       pfkey_ident->sadb_ident_reserved);
-               SENDERR(EINVAL);
-       }
-
-       /* string terminator/padding must be zero */
-       if(pfkey_ident->sadb_ident_len > sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) {
-               if(*((char*)pfkey_ident + pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1)) {
-                       DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                               "pfkey_ident_parse: "
-                               "string padding must be zero, last is 0x%02x.\n",
-                               *((char*)pfkey_ident +
-                                 pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1));
-                       SENDERR(EINVAL);
-               }
-       }
-
-       if( ! ((pfkey_ident->sadb_ident_exttype == SADB_EXT_IDENTITY_SRC) ||
-              (pfkey_ident->sadb_ident_exttype == SADB_EXT_IDENTITY_DST))) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                       "pfkey_key_parse: "
-                       "expecting extension type IDENTITY_SRC or IDENTITY_DST, got %d.\n",
-                       pfkey_ident->sadb_ident_exttype);
-               SENDERR(EINVAL);
-       }
-
-errlab:
-       return error;
-}
-
-DEBUG_NO_STATIC int
-pfkey_sens_parse(struct sadb_ext *pfkey_ext)
-{
-       int error = 0;
-       struct sadb_sens *pfkey_sens = (struct sadb_sens *)pfkey_ext;
-
-       /* sanity checks... */
-       if(pfkey_sens->sadb_sens_len < sizeof(struct sadb_sens) / IPSEC_PFKEYv2_ALIGN) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                         "pfkey_sens_parse: "
-                         "size wrong ext_len=%d, key_ext_len=%d.\n",
-                         pfkey_sens->sadb_sens_len,
-                         (int)sizeof(struct sadb_sens));
-               SENDERR(EINVAL);
-       }
-
-       DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-               "pfkey_sens_parse: "
-               "Sorry, I can't parse exttype=%d yet.\n",
-               pfkey_ext->sadb_ext_type);
-#if 0
-       SENDERR(EINVAL); /* don't process these yet */
-#endif
-
-errlab:
-       return error;
-}
-
-DEBUG_NO_STATIC int
-pfkey_prop_parse(struct sadb_ext *pfkey_ext)
-{
-       int error = 0;
-       int i, num_comb;
-       struct sadb_prop *pfkey_prop = (struct sadb_prop *)pfkey_ext;
-       struct sadb_comb *pfkey_comb = (struct sadb_comb *)((char*)pfkey_ext + sizeof(struct sadb_prop));
-
-       /* sanity checks... */
-       if((pfkey_prop->sadb_prop_len < sizeof(struct sadb_prop) / IPSEC_PFKEYv2_ALIGN) ||
-          (((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) % sizeof(struct sadb_comb))) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                         "pfkey_prop_parse: "
-                         "size wrong ext_len=%d, prop_ext_len=%d comb_ext_len=%d.\n",
-                         pfkey_prop->sadb_prop_len,
-                         (int)sizeof(struct sadb_prop),
-                         (int)sizeof(struct sadb_comb));
-               SENDERR(EINVAL);
-       }
-
-       if(pfkey_prop->sadb_prop_replay > 64) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                       "pfkey_prop_parse: "
-                       "replay window size: %d -- must be 0 <= size <= 64\n",
-                       pfkey_prop->sadb_prop_replay);
-               SENDERR(EINVAL);
-       }
-
-       for(i=0; i<3; i++) {
-               if(pfkey_prop->sadb_prop_reserved[i]) {
-                       DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                               "pfkey_prop_parse: "
-                               "res[%d]=%d, must be zero.\n",
-                               i, pfkey_prop->sadb_prop_reserved[i]);
-                       SENDERR(EINVAL);
-               }
-       }
-
-       num_comb = ((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) / sizeof(struct sadb_comb);
-
-       for(i = 0; i < num_comb; i++) {
-               if(pfkey_comb->sadb_comb_auth > SADB_AALG_MAX) {
-                       DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                               "pfkey_prop_parse: "
-                               "pfkey_comb[%d]->sadb_comb_auth=%d > SADB_AALG_MAX=%d.\n",
-                               i,
-                               pfkey_comb->sadb_comb_auth,
-                               SADB_AALG_MAX);
-                       SENDERR(EINVAL);
-               }
-
-               if(pfkey_comb->sadb_comb_auth) {
-                       if(!pfkey_comb->sadb_comb_auth_minbits) {
-                               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                                       "pfkey_prop_parse: "
-                                       "pfkey_comb[%d]->sadb_comb_auth_minbits=0, fatal.\n",
-                                       i);
-                               SENDERR(EINVAL);
-                       }
-                       if(!pfkey_comb->sadb_comb_auth_maxbits) {
-                               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                                       "pfkey_prop_parse: "
-                                       "pfkey_comb[%d]->sadb_comb_auth_maxbits=0, fatal.\n",
-                                       i);
-                               SENDERR(EINVAL);
-                       }
-                       if(pfkey_comb->sadb_comb_auth_minbits > pfkey_comb->sadb_comb_auth_maxbits) {
-                               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                                       "pfkey_prop_parse: "
-                                       "pfkey_comb[%d]->sadb_comb_auth_minbits=%d > maxbits=%d, fatal.\n",
-                                       i,
-                                       pfkey_comb->sadb_comb_auth_minbits,
-                                       pfkey_comb->sadb_comb_auth_maxbits);
-                               SENDERR(EINVAL);
-                       }
-               } else {
-                       if(pfkey_comb->sadb_comb_auth_minbits) {
-                               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                                       "pfkey_prop_parse: "
-                                       "pfkey_comb[%d]->sadb_comb_auth_minbits=%d != 0, fatal.\n",
-                                       i,
-                                       pfkey_comb->sadb_comb_auth_minbits);
-                               SENDERR(EINVAL);
-                       }
-                       if(pfkey_comb->sadb_comb_auth_maxbits) {
-                               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                                       "pfkey_prop_parse: "
-                                       "pfkey_comb[%d]->sadb_comb_auth_maxbits=%d != 0, fatal.\n",
-                                       i,
-                                       pfkey_comb->sadb_comb_auth_maxbits);
-                               SENDERR(EINVAL);
-                       }
-               }
-
-               if(pfkey_comb->sadb_comb_encrypt > SADB_EALG_MAX) {
-                       DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                               "pfkey_comb_parse: "
-                               "pfkey_comb[%d]->sadb_comb_encrypt=%d > SADB_EALG_MAX=%d.\n",
-                               i,
-                               pfkey_comb->sadb_comb_encrypt,
-                               SADB_EALG_MAX);
-                       SENDERR(EINVAL);
-               }
-
-               if(pfkey_comb->sadb_comb_encrypt) {
-                       if(!pfkey_comb->sadb_comb_encrypt_minbits) {
-                               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                                       "pfkey_prop_parse: "
-                                       "pfkey_comb[%d]->sadb_comb_encrypt_minbits=0, fatal.\n",
-                                       i);
-                               SENDERR(EINVAL);
-                       }
-                       if(!pfkey_comb->sadb_comb_encrypt_maxbits) {
-                               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                                       "pfkey_prop_parse: "
-                                       "pfkey_comb[%d]->sadb_comb_encrypt_maxbits=0, fatal.\n",
-                                       i);
-                               SENDERR(EINVAL);
-                       }
-                       if(pfkey_comb->sadb_comb_encrypt_minbits > pfkey_comb->sadb_comb_encrypt_maxbits) {
-                               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                                       "pfkey_prop_parse: "
-                                       "pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d > maxbits=%d, fatal.\n",
-                                       i,
-                                       pfkey_comb->sadb_comb_encrypt_minbits,
-                                       pfkey_comb->sadb_comb_encrypt_maxbits);
-                               SENDERR(EINVAL);
-                       }
-               } else {
-                       if(pfkey_comb->sadb_comb_encrypt_minbits) {
-                               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                                       "pfkey_prop_parse: "
-                                       "pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d != 0, fatal.\n",
-                                       i,
-                                       pfkey_comb->sadb_comb_encrypt_minbits);
-                               SENDERR(EINVAL);
-                       }
-                       if(pfkey_comb->sadb_comb_encrypt_maxbits) {
-                               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                                       "pfkey_prop_parse: "
-                                       "pfkey_comb[%d]->sadb_comb_encrypt_maxbits=%d != 0, fatal.\n",
-                                       i,
-                                       pfkey_comb->sadb_comb_encrypt_maxbits);
-                               SENDERR(EINVAL);
-                       }
-               }
-
-               /* XXX do sanity check on flags */
-
-               if(pfkey_comb->sadb_comb_hard_allocations && pfkey_comb->sadb_comb_soft_allocations > pfkey_comb->sadb_comb_hard_allocations) {
-                       DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                                 "pfkey_prop_parse: "
-                                 "pfkey_comb[%d]->sadb_comb_soft_allocations=%d > hard_allocations=%d, fatal.\n",
-                                 i,
-                                 pfkey_comb->sadb_comb_soft_allocations,
-                                 pfkey_comb->sadb_comb_hard_allocations);
-                       SENDERR(EINVAL);
-               }
-
-               if(pfkey_comb->sadb_comb_hard_bytes && pfkey_comb->sadb_comb_soft_bytes > pfkey_comb->sadb_comb_hard_bytes) {
-                       DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                                 "pfkey_prop_parse: "
-                                 "pfkey_comb[%d]->sadb_comb_soft_bytes=%Ld > hard_bytes=%Ld, fatal.\n",
-                                 i,
-                                 (unsigned long long int)pfkey_comb->sadb_comb_soft_bytes,
-                                 (unsigned long long int)pfkey_comb->sadb_comb_hard_bytes);
-                       SENDERR(EINVAL);
-               }
-
-               if(pfkey_comb->sadb_comb_hard_addtime && pfkey_comb->sadb_comb_soft_addtime > pfkey_comb->sadb_comb_hard_addtime) {
-                       DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                                 "pfkey_prop_parse: "
-                                 "pfkey_comb[%d]->sadb_comb_soft_addtime=%Ld > hard_addtime=%Ld, fatal.\n",
-                                 i,
-                                 (unsigned long long int)pfkey_comb->sadb_comb_soft_addtime,
-                                 (unsigned long long int)pfkey_comb->sadb_comb_hard_addtime);
-                       SENDERR(EINVAL);
-               }
-
-               if(pfkey_comb->sadb_comb_hard_usetime && pfkey_comb->sadb_comb_soft_usetime > pfkey_comb->sadb_comb_hard_usetime) {
-                       DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                                 "pfkey_prop_parse: "
-                                 "pfkey_comb[%d]->sadb_comb_soft_usetime=%Ld > hard_usetime=%Ld, fatal.\n",
-                                 i,
-                                 (unsigned long long int)pfkey_comb->sadb_comb_soft_usetime,
-                                 (unsigned long long int)pfkey_comb->sadb_comb_hard_usetime);
-                       SENDERR(EINVAL);
-               }
-
-               if(pfkey_comb->sadb_x_comb_hard_packets && pfkey_comb->sadb_x_comb_soft_packets > pfkey_comb->sadb_x_comb_hard_packets) {
-                       DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                               "pfkey_prop_parse: "
-                               "pfkey_comb[%d]->sadb_x_comb_soft_packets=%d > hard_packets=%d, fatal.\n",
-                               i,
-                               pfkey_comb->sadb_x_comb_soft_packets,
-                               pfkey_comb->sadb_x_comb_hard_packets);
-                       SENDERR(EINVAL);
-               }
-
-               if(pfkey_comb->sadb_comb_reserved) {
-                       DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                               "pfkey_prop_parse: "
-                               "comb[%d].res=%d, must be zero.\n",
-                               i,
-                               pfkey_comb->sadb_comb_reserved);
-                       SENDERR(EINVAL);
-               }
-               pfkey_comb++;
-       }
-
-errlab:
-       return error;
-}
-
-DEBUG_NO_STATIC int
-pfkey_supported_parse(struct sadb_ext *pfkey_ext)
-{
-       int error = 0;
-       unsigned int i, num_alg;
-       struct sadb_supported *pfkey_supported = (struct sadb_supported *)pfkey_ext;
-       struct sadb_alg *pfkey_alg = (struct sadb_alg*)((char*)pfkey_ext + sizeof(struct sadb_supported));
-
-       /* sanity checks... */
-       if((pfkey_supported->sadb_supported_len <
-          sizeof(struct sadb_supported) / IPSEC_PFKEYv2_ALIGN) ||
-          (((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) -
-            sizeof(struct sadb_supported)) % sizeof(struct sadb_alg))) {
-
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                         "pfkey_supported_parse: "
-                         "size wrong ext_len=%d, supported_ext_len=%d alg_ext_len=%d.\n",
-                         pfkey_supported->sadb_supported_len,
-                         (int)sizeof(struct sadb_supported),
-                         (int)sizeof(struct sadb_alg));
-               SENDERR(EINVAL);
-       }
-
-       if(pfkey_supported->sadb_supported_reserved) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                       "pfkey_supported_parse: "
-                       "res=%d, must be zero.\n",
-                       pfkey_supported->sadb_supported_reserved);
-               SENDERR(EINVAL);
-       }
-
-       num_alg = ((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_supported)) / sizeof(struct sadb_alg);
-
-       for(i = 0; i < num_alg; i++) {
-               /* process algo description */
-               if(pfkey_alg->sadb_alg_reserved) {
-                       DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                               "pfkey_supported_parse: "
-                               "alg[%d], id=%d, ivlen=%d, minbits=%d, maxbits=%d, res=%d, must be zero.\n",
-                               i,
-                               pfkey_alg->sadb_alg_id,
-                               pfkey_alg->sadb_alg_ivlen,
-                               pfkey_alg->sadb_alg_minbits,
-                               pfkey_alg->sadb_alg_maxbits,
-                               pfkey_alg->sadb_alg_reserved);
-                       SENDERR(EINVAL);
-               }
-
-               /* XXX can alg_id auth/enc be determined from info given?
-                  Yes, but OpenBSD's method does not iteroperate with rfc2367.
-                  rgb, 2000-04-06 */
-
-               switch(pfkey_supported->sadb_supported_exttype) {
-               case SADB_EXT_SUPPORTED_AUTH:
-                       if(pfkey_alg->sadb_alg_id > SADB_AALG_MAX) {
-                               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                                       "pfkey_supported_parse: "
-                                       "alg[%d], alg_id=%d > SADB_AALG_MAX=%d, fatal.\n",
-                                       i,
-                                       pfkey_alg->sadb_alg_id,
-                                       SADB_AALG_MAX);
-                               SENDERR(EINVAL);
-                       }
-                       break;
-               case SADB_EXT_SUPPORTED_ENCRYPT:
-                       if(pfkey_alg->sadb_alg_id > SADB_EALG_MAX) {
-                               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                                       "pfkey_supported_parse: "
-                                       "alg[%d], alg_id=%d > SADB_EALG_MAX=%d, fatal.\n",
-                                       i,
-                                       pfkey_alg->sadb_alg_id,
-                                       SADB_EALG_MAX);
-                               SENDERR(EINVAL);
-                       }
-                       break;
-               default:
-                       DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                               "pfkey_supported_parse: "
-                               "alg[%d], alg_id=%d > SADB_EALG_MAX=%d, fatal.\n",
-                               i,
-                               pfkey_alg->sadb_alg_id,
-                               SADB_EALG_MAX);
-                       SENDERR(EINVAL);
-               }
-               pfkey_alg++;
-       }
-
- errlab:
-       return error;
-}
-
-DEBUG_NO_STATIC int
-pfkey_spirange_parse(struct sadb_ext *pfkey_ext)
-{
-       int error = 0;
-       struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)pfkey_ext;
-
-       /* sanity checks... */
-        if(pfkey_spirange->sadb_spirange_len !=
-          sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                         "pfkey_spirange_parse: "
-                         "size wrong ext_len=%d, key_ext_len=%d.\n",
-                         pfkey_spirange->sadb_spirange_len,
-                         (int)sizeof(struct sadb_spirange));
-                SENDERR(EINVAL);
-        }
-
-        if(pfkey_spirange->sadb_spirange_reserved) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                       "pfkey_spirange_parse: "
-                       "reserved=%d must be set to zero.\n",
-                       pfkey_spirange->sadb_spirange_reserved);
-                SENDERR(EINVAL);
-        }
-
-        if(ntohl(pfkey_spirange->sadb_spirange_max) < ntohl(pfkey_spirange->sadb_spirange_min)) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                       "pfkey_spirange_parse: "
-                       "minspi=%08x must be < maxspi=%08x.\n",
-                       ntohl(pfkey_spirange->sadb_spirange_min),
-                       ntohl(pfkey_spirange->sadb_spirange_max));
-                SENDERR(EINVAL);
-        }
-
-       if(ntohl(pfkey_spirange->sadb_spirange_min) <= 255) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                       "pfkey_spirange_parse: "
-                       "minspi=%08x must be > 255.\n",
-                       ntohl(pfkey_spirange->sadb_spirange_min));
-               SENDERR(EEXIST);
-       }
-
-       DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
-                 "pfkey_spirange_parse: "
-                 "ext_len=%u ext_type=%u(%s) min=%u max=%u res=%u.\n",
-                 pfkey_spirange->sadb_spirange_len,
-                 pfkey_spirange->sadb_spirange_exttype,
-                 pfkey_v2_sadb_ext_string(pfkey_spirange->sadb_spirange_exttype),
-                 pfkey_spirange->sadb_spirange_min,
-                 pfkey_spirange->sadb_spirange_max,
-                 pfkey_spirange->sadb_spirange_reserved);
- errlab:
-       return error;
-}
-
-DEBUG_NO_STATIC int
-pfkey_x_kmprivate_parse(struct sadb_ext *pfkey_ext)
-{
-       int error = 0;
-       struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)pfkey_ext;
-
-       /* sanity checks... */
-       if(pfkey_x_kmprivate->sadb_x_kmprivate_len <
-          sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                         "pfkey_x_kmprivate_parse: "
-                         "size wrong ext_len=%d, key_ext_len=%d.\n",
-                         pfkey_x_kmprivate->sadb_x_kmprivate_len,
-                         (int)sizeof(struct sadb_x_kmprivate));
-               SENDERR(EINVAL);
-       }
-
-       if(pfkey_x_kmprivate->sadb_x_kmprivate_reserved) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                         "pfkey_x_kmprivate_parse: "
-                         "reserved=%d must be set to zero.\n",
-                         pfkey_x_kmprivate->sadb_x_kmprivate_reserved);
-               SENDERR(EINVAL);
-       }
-
-       DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                 "pfkey_x_kmprivate_parse: "
-                 "Sorry, I can't parse exttype=%d yet.\n",
-                 pfkey_ext->sadb_ext_type);
-       SENDERR(EINVAL); /* don't process these yet */
-
-errlab:
-       return error;
-}
-
-DEBUG_NO_STATIC int
-pfkey_x_satype_parse(struct sadb_ext *pfkey_ext)
-{
-       int error = 0;
-       int i;
-       struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext;
-
-       DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
-               "pfkey_x_satype_parse: enter\n");
-       /* sanity checks... */
-       if(pfkey_x_satype->sadb_x_satype_len !=
-          sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                         "pfkey_x_satype_parse: "
-                         "size wrong ext_len=%d, key_ext_len=%d.\n",
-                         pfkey_x_satype->sadb_x_satype_len,
-                         (int)sizeof(struct sadb_x_satype));
-               SENDERR(EINVAL);
-       }
-
-       if(!pfkey_x_satype->sadb_x_satype_satype) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                       "pfkey_x_satype_parse: "
-                       "satype is zero, must be non-zero.\n");
-               SENDERR(EINVAL);
-       }
-
-       if(pfkey_x_satype->sadb_x_satype_satype > SADB_SATYPE_MAX) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                       "pfkey_x_satype_parse: "
-                       "satype %d > max %d, invalid.\n",
-                       pfkey_x_satype->sadb_x_satype_satype, SADB_SATYPE_MAX);
-               SENDERR(EINVAL);
-       }
-
-       if(!(satype2proto(pfkey_x_satype->sadb_x_satype_satype))) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                       "pfkey_x_satype_parse: "
-                       "proto lookup from satype=%d failed.\n",
-                       pfkey_x_satype->sadb_x_satype_satype);
-               SENDERR(EINVAL);
-       }
-
-       for(i = 0; i < 3; i++) {
-               if(pfkey_x_satype->sadb_x_satype_reserved[i]) {
-                       DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                               "pfkey_x_satype_parse: "
-                               "reserved[%d]=%d must be set to zero.\n",
-                               i, pfkey_x_satype->sadb_x_satype_reserved[i]);
-                       SENDERR(EINVAL);
-               }
-       }
-
-       DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
-                 "pfkey_x_satype_parse: "
-                 "len=%u ext=%u(%s) satype=%u(%s) res=%u,%u,%u.\n",
-                 pfkey_x_satype->sadb_x_satype_len,
-                 pfkey_x_satype->sadb_x_satype_exttype,
-                 pfkey_v2_sadb_ext_string(pfkey_x_satype->sadb_x_satype_exttype),
-                 pfkey_x_satype->sadb_x_satype_satype,
-                 satype2name(pfkey_x_satype->sadb_x_satype_satype),
-                 pfkey_x_satype->sadb_x_satype_reserved[0],
-                 pfkey_x_satype->sadb_x_satype_reserved[1],
-                 pfkey_x_satype->sadb_x_satype_reserved[2]);
-errlab:
-       return error;
-}
-
-DEBUG_NO_STATIC int
-pfkey_x_ext_debug_parse(struct sadb_ext *pfkey_ext)
-{
-       int error = 0;
-       int i;
-       struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext;
-
-       DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
-               "pfkey_x_debug_parse: enter\n");
-       /* sanity checks... */
-       if(pfkey_x_debug->sadb_x_debug_len !=
-          sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                         "pfkey_x_debug_parse: "
-                         "size wrong ext_len=%d, key_ext_len=%d.\n",
-                         pfkey_x_debug->sadb_x_debug_len,
-                         (int)sizeof(struct sadb_x_debug));
-               SENDERR(EINVAL);
-       }
-
-       for(i = 0; i < 4; i++) {
-               if(pfkey_x_debug->sadb_x_debug_reserved[i]) {
-                       DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                               "pfkey_x_debug_parse: "
-                               "reserved[%d]=%d must be set to zero.\n",
-                               i, pfkey_x_debug->sadb_x_debug_reserved[i]);
-                       SENDERR(EINVAL);
-               }
-       }
-
-errlab:
-       return error;
-}
-
-DEBUG_NO_STATIC int
-pfkey_x_ext_protocol_parse(struct sadb_ext *pfkey_ext)
-{
-       int error = 0;
-       struct sadb_protocol *p = (struct sadb_protocol *)pfkey_ext;
-
-       DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, "pfkey_x_protocol_parse:\n");
-       /* sanity checks... */
-
-       if (p->sadb_protocol_len != sizeof(*p)/IPSEC_PFKEYv2_ALIGN) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                         "pfkey_x_protocol_parse: size wrong ext_len=%d, key_ext_len=%d.\n",
-                         p->sadb_protocol_len, (int)sizeof(*p));
-               SENDERR(EINVAL);
-       }
-
-       if (p->sadb_protocol_reserved2 != 0) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                         "pfkey_protocol_parse: res=%d, must be zero.\n",
-                         p->sadb_protocol_reserved2);
-               SENDERR(EINVAL);
-       }
-
- errlab:
-       return error;
-}
-
-DEBUG_NO_STATIC int
-pfkey_x_ext_nat_t_type_parse(struct sadb_ext *pfkey_ext)
-{
-       return 0;
-}
-
-DEBUG_NO_STATIC int
-pfkey_x_ext_nat_t_port_parse(struct sadb_ext *pfkey_ext)
-{
-       return 0;
-}
-
-#define DEFINEPARSER(NAME) static struct pf_key_ext_parsers_def NAME##_def={NAME, #NAME};
-
-DEFINEPARSER(pfkey_sa_parse);
-DEFINEPARSER(pfkey_lifetime_parse);
-DEFINEPARSER(pfkey_address_parse);
-DEFINEPARSER(pfkey_key_parse);
-DEFINEPARSER(pfkey_ident_parse);
-DEFINEPARSER(pfkey_sens_parse);
-DEFINEPARSER(pfkey_prop_parse);
-DEFINEPARSER(pfkey_supported_parse);
-DEFINEPARSER(pfkey_spirange_parse);
-DEFINEPARSER(pfkey_x_kmprivate_parse);
-DEFINEPARSER(pfkey_x_satype_parse);
-DEFINEPARSER(pfkey_x_ext_debug_parse);
-DEFINEPARSER(pfkey_x_ext_protocol_parse);
-DEFINEPARSER(pfkey_x_ext_nat_t_type_parse);
-DEFINEPARSER(pfkey_x_ext_nat_t_port_parse);
-
-struct pf_key_ext_parsers_def *ext_default_parsers[]=
-{
-       NULL,                 /* pfkey_msg_parse, */
-       &pfkey_sa_parse_def,
-       &pfkey_lifetime_parse_def,
-       &pfkey_lifetime_parse_def,
-       &pfkey_lifetime_parse_def,
-       &pfkey_address_parse_def,
-       &pfkey_address_parse_def,
-       &pfkey_address_parse_def,
-       &pfkey_key_parse_def,
-       &pfkey_key_parse_def,
-       &pfkey_ident_parse_def,
-       &pfkey_ident_parse_def,
-       &pfkey_sens_parse_def,
-       &pfkey_prop_parse_def,
-       &pfkey_supported_parse_def,
-       &pfkey_supported_parse_def,
-       &pfkey_spirange_parse_def,
-       &pfkey_x_kmprivate_parse_def,
-       &pfkey_x_satype_parse_def,
-       &pfkey_sa_parse_def,
-       &pfkey_address_parse_def,
-       &pfkey_address_parse_def,
-       &pfkey_address_parse_def,
-       &pfkey_address_parse_def,
-       &pfkey_address_parse_def,
-       &pfkey_x_ext_debug_parse_def,
-       &pfkey_x_ext_protocol_parse_def ,
-       &pfkey_x_ext_nat_t_type_parse_def,
-       &pfkey_x_ext_nat_t_port_parse_def,
-       &pfkey_x_ext_nat_t_port_parse_def,
-       &pfkey_address_parse_def
-};
-
-int
-pfkey_msg_parse(struct sadb_msg *pfkey_msg,
-               struct pf_key_ext_parsers_def *ext_parsers[],
-               struct sadb_ext *extensions[],
-               int dir)
-{
-       int error = 0;
-       int remain;
-       struct sadb_ext *pfkey_ext;
-       int extensions_seen = 0;
-
-       DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
-                 "pfkey_msg_parse: "
-                 "parsing message ver=%d, type=%d(%s), errno=%d, satype=%d(%s), len=%d, res=%d, seq=%d, pid=%d.\n",
-                 pfkey_msg->sadb_msg_version,
-                 pfkey_msg->sadb_msg_type,
-                 pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type),
-                 pfkey_msg->sadb_msg_errno,
-                 pfkey_msg->sadb_msg_satype,
-                 satype2name(pfkey_msg->sadb_msg_satype),
-                 pfkey_msg->sadb_msg_len,
-                 pfkey_msg->sadb_msg_reserved,
-                 pfkey_msg->sadb_msg_seq,
-                 pfkey_msg->sadb_msg_pid);
-
-       if(ext_parsers == NULL) ext_parsers = ext_default_parsers;
-
-       pfkey_extensions_init(extensions);
-
-       remain = pfkey_msg->sadb_msg_len;
-       remain -= sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
-
-       pfkey_ext = (struct sadb_ext*)((char*)pfkey_msg +
-                                      sizeof(struct sadb_msg));
-
-       extensions[0] = (struct sadb_ext *) pfkey_msg;
-
-
-       if(pfkey_msg->sadb_msg_version != PF_KEY_V2) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                       "pfkey_msg_parse: "
-                       "not PF_KEY_V2 msg, found %d, should be %d.\n",
-                       pfkey_msg->sadb_msg_version,
-                       PF_KEY_V2);
-               SENDERR(EINVAL);
-       }
-
-       if(!pfkey_msg->sadb_msg_type) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                       "pfkey_msg_parse: "
-                       "msg type not set, must be non-zero..\n");
-               SENDERR(EINVAL);
-       }
-
-       if(pfkey_msg->sadb_msg_type > SADB_MAX) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                       "pfkey_msg_parse: "
-                       "msg type=%d > max=%d.\n",
-                       pfkey_msg->sadb_msg_type,
-                       SADB_MAX);
-               SENDERR(EINVAL);
-       }
-
-       switch(pfkey_msg->sadb_msg_type) {
-       case SADB_GETSPI:
-       case SADB_UPDATE:
-       case SADB_ADD:
-       case SADB_DELETE:
-       case SADB_GET:
-       case SADB_X_GRPSA:
-       case SADB_X_ADDFLOW:
-               if(!satype2proto(pfkey_msg->sadb_msg_satype)) {
-                       DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                                 "pfkey_msg_parse: "
-                                 "satype %d conversion to proto failed for msg_type %d (%s).\n",
-                                 pfkey_msg->sadb_msg_satype,
-                                 pfkey_msg->sadb_msg_type,
-                                 pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
-                       SENDERR(EINVAL);
-               } else {
-                       DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                                 "pfkey_msg_parse: "
-                                 "satype %d(%s) conversion to proto gives %d for msg_type %d(%s).\n",
-                                 pfkey_msg->sadb_msg_satype,
-                                 satype2name(pfkey_msg->sadb_msg_satype),
-                                 satype2proto(pfkey_msg->sadb_msg_satype),
-                                 pfkey_msg->sadb_msg_type,
-                                 pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
-               }
-               /* fall through */
-       case SADB_ACQUIRE:
-       case SADB_REGISTER:
-       case SADB_EXPIRE:
-               if(!pfkey_msg->sadb_msg_satype) {
-                       DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                                 "pfkey_msg_parse: "
-                                 "satype is zero, must be non-zero for msg_type %d(%s).\n",
-                                 pfkey_msg->sadb_msg_type,
-                                 pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
-                       SENDERR(EINVAL);
-               }
-       default:
-               break;
-       }
-
-       /* errno must not be set in downward messages */
-       /* this is not entirely true... a response to an ACQUIRE could return an error */
-       if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type != SADB_ACQUIRE) && pfkey_msg->sadb_msg_errno) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                           "pfkey_msg_parse: "
-                           "errno set to %d.\n",
-                           pfkey_msg->sadb_msg_errno);
-               SENDERR(EINVAL);
-       }
-
-       DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
-                 "pfkey_msg_parse: "
-                 "remain=%d, ext_type=%d(%s), ext_len=%d.\n",
-                 remain,
-                 pfkey_ext->sadb_ext_type,
-                 pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
-                 pfkey_ext->sadb_ext_len);
-
-       DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
-               "pfkey_msg_parse: "
-               "extensions permitted=%08x, required=%08x.\n",
-               extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
-               extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]);
-
-       extensions_seen = 1;
-
-       while( (remain * IPSEC_PFKEYv2_ALIGN) >= sizeof(struct sadb_ext) ) {
-               /* Is there enough message left to support another extension header? */
-               if(remain < pfkey_ext->sadb_ext_len) {
-                       DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                               "pfkey_msg_parse: "
-                               "remain %d less than ext len %d.\n",
-                               remain, pfkey_ext->sadb_ext_len);
-                       SENDERR(EINVAL);
-               }
-
-               DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
-                       "pfkey_msg_parse: "
-                       "parsing ext type=%d(%s) remain=%d.\n",
-                       pfkey_ext->sadb_ext_type,
-                       pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
-                       remain);
-
-               /* Is the extension header type valid? */
-               if((pfkey_ext->sadb_ext_type > SADB_EXT_MAX) || (!pfkey_ext->sadb_ext_type)) {
-                       DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                               "pfkey_msg_parse: "
-                               "ext type %d(%s) invalid, SADB_EXT_MAX=%d.\n",
-                               pfkey_ext->sadb_ext_type,
-                               pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
-                               SADB_EXT_MAX);
-                       SENDERR(EINVAL);
-               }
-
-               /* Have we already seen this type of extension? */
-               if((extensions_seen & ( 1 << pfkey_ext->sadb_ext_type )) != 0)
-               {
-                       DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                               "pfkey_msg_parse: "
-                               "ext type %d(%s) already seen.\n",
-                               pfkey_ext->sadb_ext_type,
-                               pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
-                       SENDERR(EINVAL);
-               }
-
-               /* Do I even know about this type of extension? */
-               if(ext_parsers[pfkey_ext->sadb_ext_type]==NULL) {
-                       DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                               "pfkey_msg_parse: "
-                               "ext type %d(%s) unknown, ignoring.\n",
-                               pfkey_ext->sadb_ext_type,
-                               pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
-                       goto next_ext;
-               }
-
-               /* Is this type of extension permitted for this type of message? */
-               if(!(extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type] &
-                    1<<pfkey_ext->sadb_ext_type)) {
-                       DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                               "pfkey_msg_parse: "
-                               "ext type %d(%s) not permitted, exts_perm_in=%08x, 1<<type=%08x\n",
-                               pfkey_ext->sadb_ext_type,
-                               pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
-                               extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
-                               1<<pfkey_ext->sadb_ext_type);
-                       SENDERR(EINVAL);
-               }
-
-               DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
-                         "pfkey_msg_parse: "
-                         "remain=%d ext_type=%d(%s) ext_len=%d parsing ext 0p%p with parser %s.\n",
-                         remain,
-                         pfkey_ext->sadb_ext_type,
-                         pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
-                         pfkey_ext->sadb_ext_len,
-                         pfkey_ext,
-                         ext_parsers[pfkey_ext->sadb_ext_type]->parser_name);
-
-               /* Parse the extension */
-               if((error =
-                   (*ext_parsers[pfkey_ext->sadb_ext_type]->parser)(pfkey_ext))) {
-                       DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                               "pfkey_msg_parse: "
-                               "extension parsing for type %d(%s) failed with error %d.\n",
-                               pfkey_ext->sadb_ext_type,
-                               pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
-                               error);
-                       SENDERR(-error);
-               }
-               DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
-                       "pfkey_msg_parse: "
-                       "Extension %d(%s) parsed.\n",
-                       pfkey_ext->sadb_ext_type,
-                       pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
-
-               /* Mark that we have seen this extension and remember the header location */
-               extensions_seen |= ( 1 << pfkey_ext->sadb_ext_type );
-               extensions[pfkey_ext->sadb_ext_type] = pfkey_ext;
-
-       next_ext:
-               /* Calculate how much message remains */
-               remain -= pfkey_ext->sadb_ext_len;
-
-               if(!remain) {
-                       break;
-               }
-               /* Find the next extension header */
-               pfkey_ext = (struct sadb_ext*)((char*)pfkey_ext +
-                       pfkey_ext->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
-       }
-
-       if(remain) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                       "pfkey_msg_parse: "
-                       "unexpected remainder of %d.\n",
-                       remain);
-               /* why is there still something remaining? */
-               SENDERR(EINVAL);
-       }
-
-       /* check required extensions */
-       DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
-               "pfkey_msg_parse: "
-               "extensions permitted=%08x, seen=%08x, required=%08x.\n",
-               extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
-               extensions_seen,
-               extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]);
-
-       /* don't check further if it is an error return message since it
-          may not have a body */
-       if(pfkey_msg->sadb_msg_errno) {
-               SENDERR(-error);
-       }
-
-       if((extensions_seen &
-           extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]) !=
-          extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                       "pfkey_msg_parse: "
-                       "required extensions missing:%08x.\n",
-                       extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type] -
-                       (extensions_seen &
-                        extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]));
-               SENDERR(EINVAL);
-       }
-
-       if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type == SADB_X_DELFLOW)
-          && ((extensions_seen & SADB_X_EXT_ADDRESS_DELFLOW)
-              != SADB_X_EXT_ADDRESS_DELFLOW)
-          && (((extensions_seen & (1<<SADB_EXT_SA)) != (1<<SADB_EXT_SA))
-          || ((((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_flags
-               & SADB_X_SAFLAGS_CLEARFLOW)
-              != SADB_X_SAFLAGS_CLEARFLOW))) {
-               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                       "pfkey_msg_parse: "
-                       "required SADB_X_DELFLOW extensions missing: either %08x must be present or %08x must be present with SADB_X_SAFLAGS_CLEARFLOW set.\n",
-                       SADB_X_EXT_ADDRESS_DELFLOW
-                       - (extensions_seen & SADB_X_EXT_ADDRESS_DELFLOW),
-                       (1<<SADB_EXT_SA) - (extensions_seen & (1<<SADB_EXT_SA)));
-               SENDERR(EINVAL);
-       }
-
-       switch(pfkey_msg->sadb_msg_type) {
-       case SADB_ADD:
-       case SADB_UPDATE:
-               /* check maturity */
-               if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state !=
-                  SADB_SASTATE_MATURE) {
-                       DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                               "pfkey_msg_parse: "
-                               "state=%d for add or update should be MATURE=%d.\n",
-                               ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
-                               SADB_SASTATE_MATURE);
-                       SENDERR(EINVAL);
-               }
-
-               /* check AH and ESP */
-               switch(((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype) {
-               case SADB_SATYPE_AH:
-                       if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
-                            ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_auth !=
-                            SADB_AALG_NONE)) {
-                               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                                       "pfkey_msg_parse: "
-                                       "auth alg is zero, must be non-zero for AH SAs.\n");
-                               SENDERR(EINVAL);
-                       }
-                       if(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt !=
-                          SADB_EALG_NONE) {
-                               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                                       "pfkey_msg_parse: "
-                                       "AH handed encalg=%d, must be zero.\n",
-                                       ((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt);
-                               SENDERR(EINVAL);
-                       }
-                       break;
-               case SADB_SATYPE_ESP:
-                       if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
-                            ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt !=
-                            SADB_EALG_NONE)) {
-                               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                                       "pfkey_msg_parse: "
-                                       "encrypt alg=%d is zero, must be non-zero for ESP=%d SAs.\n",
-                                       ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt,
-                                       ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
-                               SENDERR(EINVAL);
-                       }
-                       if((((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt ==
-                           SADB_EALG_NULL) &&
-                          (((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth ==
-                           SADB_AALG_NONE) ) {
-                               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                                       "pfkey_msg_parse: "
-                                       "ESP handed encNULL+authNONE, illegal combination.\n");
-                               SENDERR(EINVAL);
-                       }
-                       break;
-               case SADB_X_SATYPE_COMP:
-                       if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
-                            ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt !=
-                            SADB_EALG_NONE)) {
-                               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                                       "pfkey_msg_parse: "
-                                       "encrypt alg=%d is zero, must be non-zero for COMP=%d SAs.\n",
-                                       ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt,
-                                       ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
-                               SENDERR(EINVAL);
-                       }
-                       if(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth !=
-                          SADB_AALG_NONE) {
-                               DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                                       "pfkey_msg_parse: "
-                                       "COMP handed auth=%d, must be zero.\n",
-                                       ((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth);
-                               SENDERR(EINVAL);
-                       }
-                       break;
-               default:
-                       break;
-               }
-               if(ntohl(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_spi) <= 255) {
-                       DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-                               "pfkey_msg_parse: "
-                               "spi=%08x must be > 255.\n",
-                               ntohl(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_spi));
-                       SENDERR(EINVAL);
-               }
-       default:
-               break;
-       }
-errlab:
-
-       return error;
-}
diff --git a/src/libfreeswan/pfkeyv2.h b/src/libfreeswan/pfkeyv2.h
deleted file mode 100644 (file)
index 725997e..0000000
+++ /dev/null
@@ -1,368 +0,0 @@
-/*
-RFC 2367               PF_KEY Key Management API               July 1998
-
-
-Appendix D: Sample Header File
-
-This file defines structures and symbols for the PF_KEY Version 2
-key management interface. It was written at the U.S. Naval Research
-Laboratory. This file is in the public domain. The authors ask that
-you leave this credit intact on any copies of this file.
-*/
-#ifndef __PFKEY_V2_H
-#define __PFKEY_V2_H 1
-
-#define PF_KEY_V2 2
-#define PFKEYV2_REVISION        199806L
-
-#define SADB_RESERVED             0
-#define SADB_GETSPI               1
-#define SADB_UPDATE               2
-#define SADB_ADD                  3
-#define SADB_DELETE               4
-#define SADB_GET                  5
-#define SADB_ACQUIRE              6
-#define SADB_REGISTER             7
-#define SADB_EXPIRE               8
-#define SADB_FLUSH                9
-#define SADB_DUMP                10
-#define SADB_X_PROMISC           11
-#define SADB_X_PCHANGE           12
-#define SADB_X_GRPSA             13
-#define SADB_X_ADDFLOW           14
-#define SADB_X_DELFLOW           15
-#define SADB_X_DEBUG             16
-#define SADB_X_NAT_T_NEW_MAPPING 17
-#define SADB_MAX                 17
-
-struct sadb_msg {
-  uint8_t sadb_msg_version;
-  uint8_t sadb_msg_type;
-  uint8_t sadb_msg_errno;
-  uint8_t sadb_msg_satype;
-  uint16_t sadb_msg_len;
-  uint16_t sadb_msg_reserved;
-  uint32_t sadb_msg_seq;
-  uint32_t sadb_msg_pid;
-};
-
-struct sadb_ext {
-  uint16_t sadb_ext_len;
-  uint16_t sadb_ext_type;
-};
-
-struct sadb_sa {
-  uint16_t sadb_sa_len;
-  uint16_t sadb_sa_exttype;
-  uint32_t sadb_sa_spi;
-  uint8_t sadb_sa_replay;
-  uint8_t sadb_sa_state;
-  uint8_t sadb_sa_auth;
-  uint8_t sadb_sa_encrypt;
-  uint32_t sadb_sa_flags;
-  uint32_t /*IPsecSAref_t*/ sadb_x_sa_ref; /* 32 bits */
-  uint8_t sadb_x_reserved[4];
-};
-
-struct sadb_sa_v1 {
-  uint16_t sadb_sa_len;
-  uint16_t sadb_sa_exttype;
-  uint32_t sadb_sa_spi;
-  uint8_t sadb_sa_replay;
-  uint8_t sadb_sa_state;
-  uint8_t sadb_sa_auth;
-  uint8_t sadb_sa_encrypt;
-  uint32_t sadb_sa_flags;
-};
-
-struct sadb_lifetime {
-  uint16_t sadb_lifetime_len;
-  uint16_t sadb_lifetime_exttype;
-  uint32_t sadb_lifetime_allocations;
-  uint64_t sadb_lifetime_bytes;
-  uint64_t sadb_lifetime_addtime;
-  uint64_t sadb_lifetime_usetime;
-  uint32_t sadb_x_lifetime_packets;
-  uint32_t sadb_x_lifetime_reserved;
-};
-
-struct sadb_address {
-  uint16_t sadb_address_len;
-  uint16_t sadb_address_exttype;
-  uint8_t sadb_address_proto;
-  uint8_t sadb_address_prefixlen;
-  uint16_t sadb_address_reserved;
-};
-
-struct sadb_key {
-  uint16_t sadb_key_len;
-  uint16_t sadb_key_exttype;
-  uint16_t sadb_key_bits;
-  uint16_t sadb_key_reserved;
-};
-
-struct sadb_ident {
-  uint16_t sadb_ident_len;
-  uint16_t sadb_ident_exttype;
-  uint16_t sadb_ident_type;
-  uint16_t sadb_ident_reserved;
-  uint64_t sadb_ident_id;
-};
-
-struct sadb_sens {
-  uint16_t sadb_sens_len;
-  uint16_t sadb_sens_exttype;
-  uint32_t sadb_sens_dpd;
-  uint8_t sadb_sens_sens_level;
-  uint8_t sadb_sens_sens_len;
-  uint8_t sadb_sens_integ_level;
-  uint8_t sadb_sens_integ_len;
-  uint32_t sadb_sens_reserved;
-};
-
-struct sadb_prop {
-  uint16_t sadb_prop_len;
-  uint16_t sadb_prop_exttype;
-  uint8_t sadb_prop_replay;
-  uint8_t sadb_prop_reserved[3];
-};
-
-struct sadb_comb {
-  uint8_t sadb_comb_auth;
-  uint8_t sadb_comb_encrypt;
-  uint16_t sadb_comb_flags;
-  uint16_t sadb_comb_auth_minbits;
-  uint16_t sadb_comb_auth_maxbits;
-  uint16_t sadb_comb_encrypt_minbits;
-  uint16_t sadb_comb_encrypt_maxbits;
-  uint32_t sadb_comb_reserved;
-  uint32_t sadb_comb_soft_allocations;
-  uint32_t sadb_comb_hard_allocations;
-  uint64_t sadb_comb_soft_bytes;
-  uint64_t sadb_comb_hard_bytes;
-  uint64_t sadb_comb_soft_addtime;
-  uint64_t sadb_comb_hard_addtime;
-  uint64_t sadb_comb_soft_usetime;
-  uint64_t sadb_comb_hard_usetime;
-  uint32_t sadb_x_comb_soft_packets;
-  uint32_t sadb_x_comb_hard_packets;
-};
-
-struct sadb_supported {
-  uint16_t sadb_supported_len;
-  uint16_t sadb_supported_exttype;
-  uint32_t sadb_supported_reserved;
-};
-
-struct sadb_alg {
-  uint8_t sadb_alg_id;
-  uint8_t sadb_alg_ivlen;
-  uint16_t sadb_alg_minbits;
-  uint16_t sadb_alg_maxbits;
-  uint16_t sadb_alg_reserved;
-};
-
-struct sadb_spirange {
-  uint16_t sadb_spirange_len;
-  uint16_t sadb_spirange_exttype;
-  uint32_t sadb_spirange_min;
-  uint32_t sadb_spirange_max;
-  uint32_t sadb_spirange_reserved;
-};
-
-struct sadb_x_kmprivate {
-  uint16_t sadb_x_kmprivate_len;
-  uint16_t sadb_x_kmprivate_exttype;
-  uint32_t sadb_x_kmprivate_reserved;
-};
-
-struct sadb_x_satype {
-  uint16_t sadb_x_satype_len;
-  uint16_t sadb_x_satype_exttype;
-  uint8_t sadb_x_satype_satype;
-  uint8_t sadb_x_satype_reserved[3];
-};
-
-struct sadb_x_policy {
-  uint16_t sadb_x_policy_len;
-  uint16_t sadb_x_policy_exttype;
-  uint16_t sadb_x_policy_type;
-  uint8_t sadb_x_policy_dir;
-  uint8_t sadb_x_policy_reserved;
-  uint32_t sadb_x_policy_id;
-  uint32_t sadb_x_policy_reserved2;
-};
-
-struct sadb_x_debug {
-  uint16_t sadb_x_debug_len;
-  uint16_t sadb_x_debug_exttype;
-  uint32_t sadb_x_debug_tunnel;
-  uint32_t sadb_x_debug_netlink;
-  uint32_t sadb_x_debug_xform;
-  uint32_t sadb_x_debug_eroute;
-  uint32_t sadb_x_debug_spi;
-  uint32_t sadb_x_debug_radij;
-  uint32_t sadb_x_debug_esp;
-  uint32_t sadb_x_debug_ah;
-  uint32_t sadb_x_debug_rcv;
-  uint32_t sadb_x_debug_pfkey;
-  uint32_t sadb_x_debug_ipcomp;
-  uint32_t sadb_x_debug_verbose;
-  uint8_t sadb_x_debug_reserved[4];
-};
-
-struct sadb_x_nat_t_type {
-  uint16_t sadb_x_nat_t_type_len;
-  uint16_t sadb_x_nat_t_type_exttype;
-  uint8_t sadb_x_nat_t_type_type;
-  uint8_t sadb_x_nat_t_type_reserved[3];
-};
-struct sadb_x_nat_t_port {
-  uint16_t sadb_x_nat_t_port_len;
-  uint16_t sadb_x_nat_t_port_exttype;
-  uint16_t sadb_x_nat_t_port_port;
-  uint16_t sadb_x_nat_t_port_reserved;
-};
-
-/*
- * A protocol structure for passing through the transport level
- * protocol.  It contains more fields than are actually used/needed
- * but it is this way to be compatible with the structure used in
- * OpenBSD (http://www.openbsd.org/cgi-bin/cvsweb/src/sys/net/pfkeyv2.h)
- */
-struct sadb_protocol {
-  uint16_t sadb_protocol_len;
-  uint16_t sadb_protocol_exttype;
-  uint8_t  sadb_protocol_proto;
-  uint8_t  sadb_protocol_direction;
-  uint8_t  sadb_protocol_flags;
-  uint8_t  sadb_protocol_reserved2;
-};
-
-#define SADB_EXT_RESERVED             0
-#define SADB_EXT_SA                   1
-#define SADB_EXT_LIFETIME_CURRENT     2
-#define SADB_EXT_LIFETIME_HARD        3
-#define SADB_EXT_LIFETIME_SOFT        4
-#define SADB_EXT_ADDRESS_SRC          5
-#define SADB_EXT_ADDRESS_DST          6
-#define SADB_EXT_ADDRESS_PROXY        7
-#define SADB_EXT_KEY_AUTH             8
-#define SADB_EXT_KEY_ENCRYPT          9
-#define SADB_EXT_IDENTITY_SRC         10
-#define SADB_EXT_IDENTITY_DST         11
-#define SADB_EXT_SENSITIVITY          12
-#define SADB_EXT_PROPOSAL             13
-#define SADB_EXT_SUPPORTED_AUTH       14
-#define SADB_EXT_SUPPORTED_ENCRYPT    15
-#define SADB_EXT_SPIRANGE             16
-#define SADB_X_EXT_KMPRIVATE          17
-#define SADB_X_EXT_SATYPE2            18
-#ifdef KERNEL26_HAS_KAME_DUPLICATES
-#define SADB_X_EXT_POLICY             18
-#endif
-#define SADB_X_EXT_SA2                19
-#define SADB_X_EXT_ADDRESS_DST2       20
-#define SADB_X_EXT_ADDRESS_SRC_FLOW   21
-#define SADB_X_EXT_ADDRESS_DST_FLOW   22
-#define SADB_X_EXT_ADDRESS_SRC_MASK   23
-#define SADB_X_EXT_ADDRESS_DST_MASK   24
-#define SADB_X_EXT_DEBUG              25
-#define SADB_X_EXT_PROTOCOL           26
-#define SADB_X_EXT_NAT_T_TYPE         27
-#define SADB_X_EXT_NAT_T_SPORT        28
-#define SADB_X_EXT_NAT_T_DPORT        29
-#define SADB_X_EXT_NAT_T_OA           30
-#define SADB_EXT_MAX                  30
-
-/* SADB_X_DELFLOW required over and above SADB_X_SAFLAGS_CLEARFLOW */
-#define SADB_X_EXT_ADDRESS_DELFLOW \
-       ( (1<<SADB_X_EXT_ADDRESS_SRC_FLOW) \
-       | (1<<SADB_X_EXT_ADDRESS_DST_FLOW) \
-       | (1<<SADB_X_EXT_ADDRESS_SRC_MASK) \
-       | (1<<SADB_X_EXT_ADDRESS_DST_MASK))
-
-#define SADB_SATYPE_UNSPEC    0
-#define SADB_SATYPE_AH        2
-#define SADB_SATYPE_ESP       3
-#define SADB_SATYPE_RSVP      5
-#define SADB_SATYPE_OSPFV2    6
-#define SADB_SATYPE_RIPV2     7
-#define SADB_SATYPE_MIP       8
-#define SADB_X_SATYPE_IPIP    9
-#ifdef KERNEL26_HAS_KAME_DUPLICATES
-#define SADB_X_SATYPE_IPCOMP  9   /* ICK! */
-#endif
-#define SADB_X_SATYPE_COMP    10
-#define SADB_X_SATYPE_INT     11
-#define SADB_SATYPE_MAX       11
-
-#define SADB_SASTATE_LARVAL   0
-#define SADB_SASTATE_MATURE   1
-#define SADB_SASTATE_DYING    2
-#define SADB_SASTATE_DEAD     3
-#define SADB_SASTATE_MAX      3
-
-#define SADB_SAFLAGS_PFS                       1
-#define SADB_X_SAFLAGS_REPLACEFLOW     2
-#define SADB_X_SAFLAGS_CLEARFLOW       4
-#define SADB_X_SAFLAGS_INFLOW          8
-
-/* Authentication algorithms */
-#define SADB_AALG_NONE                         0
-#define SADB_AALG_MD5HMAC                      2
-#define SADB_AALG_SHA1HMAC                     3
-#define SADB_X_AALG_SHA2_256HMAC       5
-#define SADB_X_AALG_SHA2_384HMAC       6
-#define SADB_X_AALG_SHA2_512HMAC       7
-#define SADB_X_AALG_RIPEMD160HMAC      8
-#define SADB_X_AALG_AES_XCBC_MAC       9
-#define SADB_X_AALG_NULL                       251     /* kame */
-#define SADB_X_AALG_SHA2_256_96HMAC    252
-#define SADB_AALG_MAX                          252
-
-/* Encryption algorithms */
-#define SADB_EALG_NONE                         0
-#define SADB_EALG_DESCBC                       2
-#define SADB_EALG_3DESCBC                      3
-#define SADB_X_EALG_CASTCBC                    6
-#define SADB_X_EALG_BLOWFISHCBC                7
-#define SADB_EALG_NULL                         11
-#define SADB_X_EALG_AESCBC                     12
-#define SADB_X_EALG_AESCTR                     13
-#define SADB_X_EALG_AES_CCM_ICV8       14
-#define SADB_X_EALG_AES_CCM_ICV12      15
-#define SADB_X_EALG_AES_CCM_ICV16      16
-#define SADB_X_EALG_AES_GCM_ICV8       18
-#define SADB_X_EALG_AES_GCM_ICV12      19
-#define SADB_X_EALG_AES_GCM_ICV16      20
-#define SADB_X_EALG_CAMELLIACBC                22
-#define SADB_X_EALG_NULL_AES_GMAC      23
-#define SADB_EALG_MAX                  253 /* last EALG */
-/* private allocations should use 249-255 (RFC2407) */
-#define SADB_X_EALG_SERPENTCBC  252     /* draft-ietf-ipsec-ciph-aes-cbc-00 */
-#define SADB_X_EALG_TWOFISHCBC  253     /* draft-ietf-ipsec-ciph-aes-cbc-00 */
-
-/* Compression algorithms */
-#define SADB_X_CALG_NONE               0
-#define SADB_X_CALG_OUI                        1
-#define SADB_X_CALG_DEFLATE            2
-#define SADB_X_CALG_LZS                        3
-#define SADB_X_CALG_LZJH               4
-#define SADB_X_CALG_MAX                        4
-
-#define SADB_X_TALG_NONE          0
-#define SADB_X_TALG_IPv4_in_IPv4  1
-#define SADB_X_TALG_IPv6_in_IPv4  2
-#define SADB_X_TALG_IPv4_in_IPv6  3
-#define SADB_X_TALG_IPv6_in_IPv6  4
-#define SADB_X_TALG_MAX           4
-
-/* Identity Extension values */
-#define SADB_IDENTTYPE_RESERVED        0
-#define SADB_IDENTTYPE_PREFIX  1
-#define SADB_IDENTTYPE_FQDN    2
-#define SADB_IDENTTYPE_USERFQDN        3
-#define SADB_IDENTTYPE_MAX     3
-
-#endif /* __PFKEY_V2_H */
diff --git a/src/libfreeswan/portof.3 b/src/libfreeswan/portof.3
deleted file mode 100644 (file)
index 112def5..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-.TH IPSEC_PORTOF 3 "8 Sept 2000"
-.SH NAME
-ipsec portof \- get port field of an ip_address
-.br
-ipsec setportof \- set port field of an ip_address
-.br
-ipsec sockaddrof \- get pointer to internal sockaddr of an ip_address
-.br
-ipsec sockaddrlenof \- get length of internal sockaddr of an ip_address
-.SH SYNOPSIS
-.B "#include <freeswan.h>"
-.sp
-.B "int portof(const ip_address *src);"
-.br
-.B "void setportof(int port, ip_address *dst);"
-.br
-.B "struct sockaddr *sockaddrof(ip_address *src);"
-.br
-.B "size_t sockaddrlenof(const ip_address *src);"
-.SH DESCRIPTION
-The
-.B <freeswan.h>
-internal type
-.I ip_address
-contains one of the
-.I sockaddr
-types internally.
-\fIReliance on this feature is discouraged\fR,
-but it may occasionally be necessary.
-These functions provide low-level tools for this purpose.
-.PP
-.I Portof
-and
-.I setportof
-respectively read and write the port-number field of the internal
-.IR sockaddr .
-The values are in network byte order.
-.PP
-.I Sockaddrof
-returns a pointer to the internal
-.IR sockaddr ,
-for passing to other functions.
-.PP
-.I Sockaddrlenof
-reports the size of the internal
-.IR sockaddr ,
-for use in storage allocation.
-.SH SEE ALSO
-inet(3), ipsec_initaddr(3)
-.SH DIAGNOSTICS
-.I Portof
-returns
-.BR \-1 ,
-.I sockaddrof
-returns
-.BR NULL ,
-and
-.I sockaddrlenof
-returns
-.B 0
-if an unknown address family is found within the
-.IR ip_address .
-.SH HISTORY
-Written for the FreeS/WAN project by Henry Spencer.
-.SH BUGS
-These functions all depend on low-level details of the
-.I ip_address
-type, which are in principle subject to change.
-Avoid using them unless really necessary.
diff --git a/src/libfreeswan/portof.c b/src/libfreeswan/portof.c
deleted file mode 100644 (file)
index c44b839..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * low-level ip_address ugliness
- * Copyright (C) 2000  Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
- * License for more details.
- */
-#include <sys/socket.h>
-
-#include "internal.h"
-#include "freeswan.h"
-
-/*
- - portof - get the port field of an ip_address
- */
-int                            /* network order */
-portof(src)
-const ip_address *src;
-{
-       switch (src->u.v4.sin_family) {
-       case AF_INET:
-               return src->u.v4.sin_port;
-               break;
-       case AF_INET6:
-               return src->u.v6.sin6_port;
-               break;
-       default:
-               return -1;      /* "can't happen" */
-               break;
-       }
-}
-
-/*
- - setportof - set the port field of an ip_address
- */
-void
-setportof(port, dst)
-int port;                      /* network order */
-ip_address *dst;
-{
-       switch (dst->u.v4.sin_family) {
-       case AF_INET:
-               dst->u.v4.sin_port = port;
-               break;
-       case AF_INET6:
-               dst->u.v6.sin6_port = port;
-               break;
-       }
-}
-
-/*
- - sockaddrof - get a pointer to the sockaddr hiding inside an ip_address
- */
-struct sockaddr *
-sockaddrof(src)
-ip_address *src;
-{
-       switch (src->u.v4.sin_family) {
-       case AF_INET:
-               return (struct sockaddr *)&src->u.v4;
-               break;
-       case AF_INET6:
-               return (struct sockaddr *)&src->u.v6;
-               break;
-       default:
-               return NULL;    /* "can't happen" */
-               break;
-       }
-}
-
-/*
- - sockaddrlenof - get length of the sockaddr hiding inside an ip_address
- */
-size_t                         /* 0 for error */
-sockaddrlenof(src)
-const ip_address *src;
-{
-       switch (src->u.v4.sin_family) {
-       case AF_INET:
-               return sizeof(src->u.v4);
-               break;
-       case AF_INET6:
-               return sizeof(src->u.v6);
-               break;
-       default:
-               return 0;
-               break;
-       }
-}
diff --git a/src/libfreeswan/rangetoa.c b/src/libfreeswan/rangetoa.c
deleted file mode 100644 (file)
index 7045582..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * convert binary form of address range to ASCII
- * Copyright (C) 1998, 1999  Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
- * License for more details.
- */
-#include "internal.h"
-#include "freeswan.h"
-
-/*
- - rangetoa - convert address range to ASCII
- */
-size_t                         /* space needed for full conversion */
-rangetoa(addrs, format, dst, dstlen)
-struct in_addr addrs[2];
-int format;                    /* character */
-char *dst;                     /* need not be valid if dstlen is 0 */
-size_t dstlen;
-{
-       size_t len;
-       size_t rest;
-       int n;
-       char *p;
-
-       switch (format) {
-       case 0:
-               break;
-       default:
-               return 0;
-               break;
-       }
-
-       len = addrtoa(addrs[0], 0, dst, dstlen);
-       if (len < dstlen)
-               for (p = dst + len - 1, n = 3; len < dstlen && n > 0;
-                                                               p++, len++, n--)
-                       *p = '.';
-       else
-               p = NULL;
-       if (len < dstlen)
-               rest = dstlen - len;
-       else {
-               if (dstlen > 0)
-                       *(dst + dstlen - 1) = '\0';
-               rest = 0;
-       }
-
-       len += addrtoa(addrs[1], 0, p, rest);
-
-       return len;
-}
diff --git a/src/libfreeswan/rangetosubnet.3 b/src/libfreeswan/rangetosubnet.3
deleted file mode 100644 (file)
index 100b42b..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-.TH IPSEC_RANGETOSUBNET 3 "8 Sept 2000"
-.SH NAME
-ipsec rangetosubnet \- convert address range to subnet
-.SH SYNOPSIS
-.B "#include <freeswan.h>"
-.sp
-.B "const char *rangetosubnet(const ip_address *start,"
-.ti +1c
-.B "const ip_address *stop, ip_subnet *dst);"
-.SH DESCRIPTION
-.I Rangetosubnet
-accepts two IP addresses which define an address range,
-from
-.I start
-to
-.I stop
-inclusive,
-and converts this to a subnet if possible.
-The addresses must both be IPv4 or both be IPv6,
-and the address family of the resulting subnet is the same.
-.PP
-.I Rangetosubnet
-returns NULL for success and
-a pointer to a string-literal error message for failure;
-see DIAGNOSTICS.
-.SH SEE ALSO
-ipsec_initsubnet(3), ipsec_ttosubnet(3)
-.SH DIAGNOSTICS
-Fatal errors in
-.I rangetosubnet
-are:
-mixed address families;
-unknown address family;
-.I start
-and
-.I stop
-do not define a subnet.
-.SH HISTORY
-Written for the FreeS/WAN project by Henry Spencer.
-.SH BUGS
-The restriction of error reports to literal strings
-(so that callers don't need to worry about freeing them or copying them)
-does limit the precision of error reporting.
-.PP
-The error-reporting convention lends itself
-to slightly obscure code,
-because many readers will not think of NULL as signifying success.
-A good way to make it clearer is to write something like:
-.PP
-.RS
-.nf
-.B "const char *error;"
-.sp
-.B "error = rangetosubnet( /* ... */ );"
-.B "if (error != NULL) {"
-.B "        /* something went wrong */"
-.fi
-.RE
diff --git a/src/libfreeswan/rangetosubnet.c b/src/libfreeswan/rangetosubnet.c
deleted file mode 100644 (file)
index 2a98930..0000000
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * express an address range as a subnet (if possible)
- * Copyright (C) 2000  Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
- * License for more details.
- */
-#include "internal.h"
-#include "freeswan.h"
-
-/*
- - rangetosubnet - turn an address range into a subnet, if possible
- *
- * A range which is a valid subnet will have a network part which is the
- * same in the from value and the to value, followed by a host part which
- * is all 0 in the from value and all 1 in the to value.
- */
-err_t
-rangetosubnet(from, to, dst)
-const ip_address *from;
-const ip_address *to;
-ip_subnet *dst;
-{
-       unsigned const char *fp;
-       unsigned const char *tp;
-       unsigned fb;
-       unsigned tb;
-       unsigned const char *f;
-       unsigned const char *t;
-       size_t n;
-       size_t n2;
-       int i;
-       int nnet;
-       unsigned m;
-
-       if (addrtypeof(from) != addrtypeof(to))
-               return "mismatched address types";
-       n = addrbytesptr(from, &fp);
-       if (n == 0)
-               return "unknown address type";
-       n2 = addrbytesptr(to, &tp);
-       if (n != n2)
-               return "internal size mismatch in rangetosubnet";
-
-       f = fp;
-       t = tp;
-       nnet = 0;
-       for (i = n; i > 0 && *f == *t; i--, f++, t++)
-               nnet += 8;
-       if (i > 0 && !(*f == 0x00 && *t == 0xff)) {     /* mid-byte bdry. */
-               fb = *f++;
-               tb = *t++;
-               i--;
-               m = 0x80;
-               while ((fb&m) == (tb&m)) {
-                       fb &= ~m;
-                       tb |= m;
-                       m >>= 1;
-                       nnet++;
-               }
-               if (fb != 0x00 || tb != 0xff)
-                       return "not a valid subnet";
-       }
-       for (; i > 0 && *f == 0x00 && *t == 0xff; i--, f++, t++)
-               continue;
-
-       if (i != 0)
-               return "invalid subnet";
-
-       return initsubnet(from, nnet, 'x', dst);
-}
-
-
-
-#ifdef RANGETOSUBNET_MAIN
-
-#include <stdio.h>
-
-void regress(void);
-
-int
-main(int argc, char *argv[])
-{
-       ip_address start;
-       ip_address stop;
-       ip_subnet sub;
-       char buf[100];
-       const char *oops;
-       size_t n;
-       int af;
-       int i;
-
-       if (argc == 2 && strcmp(argv[1], "-r") == 0) {
-               regress();
-               fprintf(stderr, "regress() returned?!?\n");
-               exit(1);
-       }
-
-       if (argc < 3) {
-               fprintf(stderr, "Usage: %s [-6] start stop\n", argv[0]);
-               fprintf(stderr, "   or: %s -r\n", argv[0]);
-               exit(2);
-       }
-
-       af = AF_INET;
-       i = 1;
-       if (strcmp(argv[i], "-6") == 0) {
-               af = AF_INET6;
-               i++;
-       }
-
-       oops = ttoaddr(argv[i], 0, af, &start);
-       if (oops != NULL) {
-               fprintf(stderr, "%s: start conversion failed: %s\n", argv[0], oops);
-               exit(1);
-       }
-       oops = ttoaddr(argv[i+1], 0, af, &stop);
-       if (oops != NULL) {
-               fprintf(stderr, "%s: stop conversion failed: %s\n", argv[0], oops);
-               exit(1);
-       }
-       oops = rangetosubnet(&start, &stop, &sub);
-       if (oops != NULL) {
-               fprintf(stderr, "%s: rangetosubnet failed: %s\n", argv[0], oops);
-               exit(1);
-       }
-       n = subnettot(&sub, 0, buf, sizeof(buf));
-       if (n > sizeof(buf)) {
-               fprintf(stderr, "%s: reverse conversion", argv[0]);
-               fprintf(stderr, " failed: need %ld bytes, have only %ld\n",
-                                               (long)n, (long)sizeof(buf));
-               exit(1);
-       }
-       printf("%s\n", buf);
-
-       exit(0);
-}
-
-struct rtab {
-       int family;
-       char *start;
-       char *stop;
-       char *output;                   /* NULL means error expected */
-} rtab[] = {
-       {4, "1.2.3.0",          "1.2.3.255",            "1.2.3.0/24"},
-       {4, "1.2.3.0",          "1.2.3.7",              "1.2.3.0/29"},
-       {4, "1.2.3.240",        "1.2.3.255",            "1.2.3.240/28"},
-       {4, "0.0.0.0",          "255.255.255.255",      "0.0.0.0/0"},
-       {4, "1.2.3.4",          "1.2.3.4",              "1.2.3.4/32"},
-       {4, "1.2.3.0",          "1.2.3.254",            NULL},
-       {4, "1.2.3.0",          "1.2.3.126",            NULL},
-       {4, "1.2.3.0",          "1.2.3.125",            NULL},
-       {4, "1.2.0.0",          "1.2.255.255",          "1.2.0.0/16"},
-       {4, "1.2.0.0",          "1.2.0.255",            "1.2.0.0/24"},
-       {4, "1.2.255.0",                "1.2.255.255",  "1.2.255.0/24"},
-       {4, "1.2.255.0",                "1.2.254.255",  NULL},
-       {4, "1.2.255.1",                "1.2.255.255",  NULL},
-       {4, "1.2.0.1",          "1.2.255.255",          NULL},
-       {6, "1:2:3:4:5:6:7:0",  "1:2:3:4:5:6:7:ffff",   "1:2:3:4:5:6:7:0/112"},
-       {6, "1:2:3:4:5:6:7:0",  "1:2:3:4:5:6:7:fff",    "1:2:3:4:5:6:7:0/116"},
-       {6, "1:2:3:4:5:6:7:f0", "1:2:3:4:5:6:7:ff",     "1:2:3:4:5:6:7:f0/124"},
-       {4, NULL,               NULL,                   NULL},
-};
-
-void
-regress()
-{
-       struct rtab *r;
-       int status = 0;
-       ip_address start;
-       ip_address stop;
-       ip_subnet sub;
-       char buf[100];
-       const char *oops;
-       size_t n;
-       int af;
-
-       for (r = rtab; r->start != NULL; r++) {
-               af = (r->family == 4) ? AF_INET : AF_INET6;
-               oops = ttoaddr(r->start, 0, af, &start);
-               if (oops != NULL) {
-                       printf("surprise failure converting `%s'\n", r->start);
-                       exit(1);
-               }
-               oops = ttoaddr(r->stop, 0, af, &stop);
-               if (oops != NULL) {
-                       printf("surprise failure converting `%s'\n", r->stop);
-                       exit(1);
-               }
-               oops = rangetosubnet(&start, &stop, &sub);
-               if (oops != NULL && r->output == NULL)
-                       {}              /* okay, error expected */
-               else if (oops != NULL) {
-                       printf("`%s'-`%s' rangetosubnet failed: %s\n",
-                                               r->start, r->stop, oops);
-                       status = 1;
-               } else if (r->output == NULL) {
-                       printf("`%s'-`%s' rangetosubnet succeeded unexpectedly\n",
-                                                       r->start, r->stop);
-                       status = 1;
-               } else {
-                       n = subnettot(&sub, 0, buf, sizeof(buf));
-                       if (n > sizeof(buf)) {
-                               printf("`%s'-`%s' subnettot failed:  need %ld\n",
-                                               r->start, r->stop, (long)n);
-                               status = 1;
-                       } else if (strcmp(r->output, buf) != 0) {
-                               printf("`%s'-`%s' gave `%s', expected `%s'\n",
-                                       r->start, r->stop, buf, r->output);
-                               status = 1;
-                       }
-               }
-       }
-       exit(status);
-}
-
-#endif /* RANGETOSUBNET_MAIN */
diff --git a/src/libfreeswan/sameaddr.3 b/src/libfreeswan/sameaddr.3
deleted file mode 100644 (file)
index 62886bf..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-.TH IPSEC_ANYADDR 3 "28 Nov 2000"
-.SH NAME
-ipsec sameaddr \- are two addresses the same?
-.br
-ipsec addrcmp \- ordered comparison of addresses
-.br
-ipsec samesubnet \- are two subnets the same?
-.br
-ipsec addrinsubnet \- is an address within a subnet?
-.br
-ipsec subnetinsubnet \- is a subnet within another subnet?
-.br
-ipsec subnetishost \- is a subnet a single host?
-.br
-ipsec samesaid \- are two SA IDs the same?
-.br
-ipsec sameaddrtype \- are two addresses of the same address family?
-.br
-ipsec samesubnettype \- are two subnets of the same address family?
-.SH SYNOPSIS
-.B "#include <freeswan.h>
-.sp
-.B "int sameaddr(const ip_address *a, const ip_address *b);"
-.br
-.B "int addrcmp(const ip_address *a, const ip_address *b);"
-.br
-.B "int samesubnet(const ip_subnet *a, const ip_subnet *b);"
-.br
-.B "int addrinsubnet(const ip_address *a, const ip_subnet *s);"
-.br
-.B "int subnetinsubnet(const ip_subnet *a, const ip_subnet *b);"
-.br
-.B "int subnetishost(const ip_subnet *s);"
-.br
-.B "int samesaid(const ip_said *a, const ip_said *b);"
-.br
-.B "int sameaddrtype(const ip_address *a, const ip_address *b);"
-.br
-.B "int samesubnettype(const ip_subnet *a, const ip_subnet *b);"
-.SH DESCRIPTION
-These functions do various comparisons and tests on the
-.I ip_address
-type and
-.I ip_subnet
-types.
-.PP
-.I Sameaddr
-returns
-non-zero
-if addresses
-.I a
-and
-.IR b
-are identical,
-and
-.B 0
-otherwise.
-Addresses of different families are never identical.
-.PP
-.I Addrcmp
-returns
-.BR \-1 ,
-.BR 0 ,
-or
-.BR 1
-respectively
-if address
-.I a
-is less than, equal to, or greater than
-.IR b .
-If they are not of the same address family,
-they are never equal;
-the ordering reported in this case is arbitrary
-(and probably not useful) but consistent.
-.PP
-.I Samesubnet
-returns
-non-zero
-if subnets
-.I a
-and
-.IR b
-are identical,
-and
-.B 0
-otherwise.
-Subnets of different address families are never identical.
-.PP
-.I Addrinsubnet
-returns
-non-zero
-if address
-.I a
-is within subnet
-.IR s
-and
-.B 0
-otherwise.
-An address is never within a
-subnet of a different address family.
-.PP
-.I Subnetinsubnet
-returns
-non-zero
-if subnet
-.I a
-is a subset of subnet
-.IR b
-and
-.B 0
-otherwise.
-A subnet is deemed to be a subset of itself.
-A subnet is never a subset of another
-subnet if their address families differ.
-.PP
-.I Subnetishost
-returns
-non-zero
-if subnet
-.I s
-is in fact only a single host,
-and
-.B 0
-otherwise.
-.PP
-.I Samesaid
-returns
-non-zero
-if SA IDs
-.I a
-and
-.IR b
-are identical,
-and
-.B 0
-otherwise.
-.PP
-.I Sameaddrtype
-returns
-non-zero
-if addresses
-.I a
-and
-.IR b
-are of the same address family,
-and
-.B 0
-otherwise.
-.PP
-.I Samesubnettype
-returns
-non-zero
-if subnets
-.I a
-and
-.IR b
-are of the same address family,
-and
-.B 0
-otherwise.
-.SH SEE ALSO
-inet(3), ipsec_initaddr(3)
-.SH HISTORY
-Written for the FreeS/WAN project by Henry Spencer.
diff --git a/src/libfreeswan/sameaddr.c b/src/libfreeswan/sameaddr.c
deleted file mode 100644 (file)
index 47daaa4..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * comparisons
- * Copyright (C) 2000  Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
- * License for more details.
- */
-#include "internal.h"
-#include "freeswan.h"
-
-static int samenbits(const ip_address *a, const ip_address *b, int n);
-
-/*
- - addrcmp - compare two addresses
- * Caution, the order of the tests is subtle:  doing type test before
- * size test can yield cases where a<b, b<c, but a>c.
- */
-int                            /* like memcmp */
-addrcmp(a, b)
-const ip_address *a;
-const ip_address *b;
-{
-       int at = addrtypeof(a);
-       int bt = addrtypeof(b);
-       const unsigned char *ap;
-       const unsigned char *bp;
-       size_t as = addrbytesptr(a, &ap);
-       size_t bs = addrbytesptr(b, &bp);
-       size_t n = (as < bs) ? as : bs;         /* min(as, bs) */
-       int c = memcmp(ap, bp, n);
-
-       if (c != 0)             /* bytes differ */
-               return (c < 0) ? -1 : 1;
-       if (as != bs)           /* comparison incomplete:  lexical order */
-               return (as < bs) ? -1 : 1;
-       if (at != bt)           /* bytes same but not same type:  break tie */
-               return (at < bt) ? -1 : 1;
-       return 0;
-}
-
-/*
- - sameaddr - are two addresses the same?
- */
-int
-sameaddr(a, b)
-const ip_address *a;
-const ip_address *b;
-{
-       return (addrcmp(a, b) == 0) ? 1 : 0;
-}
-
-/*
- - samesubnet - are two subnets the same?
- */
-int
-samesubnet(a, b)
-const ip_subnet *a;
-const ip_subnet *b;
-{
-       if (!sameaddr(&a->addr, &b->addr))      /* also does type check */
-               return 0;
-       if (a->maskbits != b->maskbits)
-               return 0;
-       return 1;
-}
-
-/*
- - subnetishost - is a subnet in fact a single host?
- */
-int
-subnetishost(a)
-const ip_subnet *a;
-{
-       return (a->maskbits == addrlenof(&a->addr)*8) ? 1 : 0;
-}
-
-/*
- - samesaid - are two SA IDs the same?
- */
-int
-samesaid(a, b)
-const ip_said *a;
-const ip_said *b;
-{
-       if (a->spi != b->spi)   /* test first, most likely to be different */
-               return 0;
-       if (!sameaddr(&a->dst, &b->dst))
-               return 0;
-       if (a->proto != b->proto)
-               return 0;
-       return 1;
-}
-
-/*
- - sameaddrtype - do two addresses have the same type?
- */
-int
-sameaddrtype(a, b)
-const ip_address *a;
-const ip_address *b;
-{
-       return (addrtypeof(a) == addrtypeof(b)) ? 1 : 0;
-}
-
-/*
- - samesubnettype - do two subnets have the same type?
- */
-int
-samesubnettype(a, b)
-const ip_subnet *a;
-const ip_subnet *b;
-{
-       return (subnettypeof(a) == subnettypeof(b)) ? 1 : 0;
-}
-
-/*
- - addrinsubnet - is this address in this subnet?
- */
-int
-addrinsubnet(a, s)
-const ip_address *a;
-const ip_subnet *s;
-{
-       if (addrtypeof(a) != subnettypeof(s))
-               return 0;
-       if (!samenbits(a, &s->addr, s->maskbits))
-               return 0;
-       return 1;
-}
-
-/*
- - subnetinsubnet - is one subnet within another?
- */
-int
-subnetinsubnet(a, b)
-const ip_subnet *a;
-const ip_subnet *b;
-{
-       if (subnettypeof(a) != subnettypeof(b))
-               return 0;
-       if (a->maskbits < b->maskbits)  /* a is bigger than b */
-               return 0;
-       if (!samenbits(&a->addr, &b->addr, b->maskbits))
-               return 0;
-       return 1;
-}
-
-/*
- - samenbits - do two addresses have the same first n bits?
- */
-static int
-samenbits(a, b, nbits)
-const ip_address *a;
-const ip_address *b;
-int nbits;
-{
-       const unsigned char *ap;
-       const unsigned char *bp;
-       size_t n;
-       int m;
-
-       if (addrtypeof(a) != addrtypeof(b))
-               return 0;       /* arbitrary */
-       n = addrbytesptr(a, &ap);
-       if (n == 0)
-               return 0;       /* arbitrary */
-       (void) addrbytesptr(b, &bp);
-       if (nbits > n*8)
-               return 0;       /* "can't happen" */
-
-       for (; nbits >= 8 && *ap == *bp; nbits -= 8, ap++, bp++)
-               continue;
-       if (nbits >= 8)
-               return 0;
-       if (nbits > 0) {        /* partial byte */
-               m = ~(0xff >> nbits);
-               if ((*ap & m) != (*bp & m))
-                       return 0;
-       }
-       return 1;
-}
diff --git a/src/libfreeswan/satot.c b/src/libfreeswan/satot.c
deleted file mode 100644 (file)
index a3feb15..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * convert from binary form of SA ID to text
- * Copyright (C) 2000, 2001  Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
- * License for more details.
- */
-#include <sys/socket.h>
-
-#include "internal.h"
-#include "freeswan.h"
-
-static struct typename {
-       char type;
-       char *name;
-} typenames[] = {
-       { SA_AH,        "ah" },
-       { SA_ESP,       "esp" },
-       { SA_IPIP,      "tun" },
-       { SA_COMP,      "comp" },
-       { SA_INT,       "int" },
-       { 0,            NULL }
-};
-
-/*
- - satot - convert SA to text "ah507@1.2.3.4"
- */
-size_t                         /* space needed for full conversion */
-satot(sa, format, dst, dstlen)
-const ip_said *sa;
-int format;                    /* character */
-char *dst;                     /* need not be valid if dstlen is 0 */
-size_t dstlen;
-{
-       size_t len = 0;         /* 0 means "not recognized yet" */
-       int base;
-       int showversion;        /* use delimiter to show IP version? */
-       struct typename *tn;
-       char *p;
-       char *pre;
-       char buf[10+1+ULTOT_BUF+ADDRTOT_BUF];
-       char unk[10];
-
-       switch (format) {
-       case 0:
-               base = 16;
-               showversion = 1;
-               break;
-       case 'f':
-               base = 17;
-               showversion = 1;
-               break;
-       case 'x':
-               base = 'x';
-               showversion = 0;
-               break;
-       case 'd':
-               base = 10;
-               showversion = 0;
-               break;
-       default:
-               return 0;
-               break;
-       }
-
-       pre = NULL;
-       for (tn = typenames; tn->name != NULL; tn++)
-               if (sa->proto == tn->type) {
-                       pre = tn->name;
-                       break;                  /* NOTE BREAK OUT */
-               }
-       if (pre == NULL) {              /* unknown protocol */
-               strncpy(unk, "unk", sizeof(unk));
-               (void) ultot((unsigned char)sa->proto, 10, unk+strlen(unk),
-                                               sizeof(unk)-strlen(unk));
-               pre = unk;
-       }
-
-       if (strcmp(pre, PASSTHROUGHTYPE) == 0 &&
-                                       sa->spi == PASSTHROUGHSPI &&
-                                       isunspecaddr(&sa->dst)) {
-               strncpy(buf, (addrtypeof(&sa->dst) == AF_INET) ?
-                                                       PASSTHROUGH4NAME :
-                                                       PASSTHROUGH6NAME, sizeof(buf));
-               len = strlen(buf);
-       }
-
-       if (sa->proto == SA_INT && addrtypeof(&sa->dst) == AF_INET &&
-                                               isunspecaddr(&sa->dst)) {
-               switch (ntohl(sa->spi)) {
-               case SPI_PASS:  p = "%pass";    break;
-               case SPI_DROP:  p = "%drop";    break;
-               case SPI_REJECT:        p = "%reject";  break;
-               case SPI_HOLD:  p = "%hold";    break;
-               case SPI_TRAP:  p = "%trap";    break;
-               case SPI_TRAPSUBNET:    p = "%trapsubnet";      break;
-               default:        p = NULL;       break;
-               }
-               if (p != NULL) {
-                       strncpy(buf, p, sizeof(buf));
-                       len = strlen(buf);
-               }
-       }
-
-       if (len == 0) {                 /* general case needed */
-               strncpy(buf, pre, sizeof(buf));
-               len = strlen(buf);
-               if (showversion) {
-                       *(buf+len) = (addrtypeof(&sa->dst) == AF_INET) ? '.' :
-                                                                       ':';
-                       len++;
-                       *(buf+len) = '\0';
-               }
-               len += ultot(ntohl(sa->spi), base, buf+len, sizeof(buf)-len);
-               *(buf+len-1) = '@';
-               len += addrtot(&sa->dst, 0, buf+len, sizeof(buf)-len);
-       }
-
-       if (dst != NULL) {
-               if (len > dstlen)
-                       *(buf+dstlen-1) = '\0';
-               strncpy(dst, buf, dstlen);
-       }
-       return len;
-}
diff --git a/src/libfreeswan/subnetof.3 b/src/libfreeswan/subnetof.3
deleted file mode 100644 (file)
index aacc76d..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-.TH IPSEC_SUBNETOF 3 "11 June 2001"
-.SH NAME
-ipsec subnetof \- given Internet address and subnet mask, return subnet number
-.br
-ipsec hostof \- given Internet address and subnet mask, return host part
-.br
-ipsec broadcastof \- given Internet address and subnet mask, return broadcast address
-.SH SYNOPSIS
-.B "#include <freeswan.h>
-.sp
-.B "struct in_addr subnetof(struct in_addr addr,"
-.ti +1c
-.B "struct in_addr mask);"
-.br
-.B "struct in_addr hostof(struct in_addr addr,"
-.ti +1c
-.B "struct in_addr mask);"
-.br
-.B "struct in_addr broadcastof(struct in_addr addr,"
-.ti +1c
-.B "struct in_addr mask);"
-.SH DESCRIPTION
-These functions are obsolete; see
-.IR ipsec_networkof (3)
-for their replacements.
-.PP
-.I Subnetof
-takes an Internet
-.I address
-and a subnet
-.I mask
-and returns the network part of the address
-(all in network byte order).
-.I Hostof
-similarly returns the host part, and
-.I broadcastof
-returns the broadcast address (all-1s convention) for the network.
-.PP
-These functions are provided to hide the Internet bit-munging inside
-an API, in hopes of easing the eventual transition to IPv6.
-.SH SEE ALSO
-inet(3), ipsec_atosubnet(3)
-.SH HISTORY
-Written for the FreeS/WAN project by Henry Spencer.
-.SH BUGS
-Calling functions for this is more costly than doing it yourself.
diff --git a/src/libfreeswan/subnetof.c b/src/libfreeswan/subnetof.c
deleted file mode 100644 (file)
index ec9b8ec..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * minor network-address manipulation utilities
- * Copyright (C) 1998, 1999  Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
- * License for more details.
- */
-#include "internal.h"
-#include "freeswan.h"
-
-/*
- - subnetof - given address and mask, return subnet part
- */
-struct in_addr
-subnetof(addr, mask)
-struct in_addr addr;
-struct in_addr mask;
-{
-       struct in_addr result;
-
-       result.s_addr = addr.s_addr & mask.s_addr;
-       return result;
-}
-
-/*
- - hostof - given address and mask, return host part
- */
-struct in_addr
-hostof(addr, mask)
-struct in_addr addr;
-struct in_addr mask;
-{
-       struct in_addr result;
-
-       result.s_addr = addr.s_addr & ~mask.s_addr;
-       return result;
-}
-
-/*
- - broadcastof - given (network) address and mask, return broadcast address
- */
-struct in_addr
-broadcastof(addr, mask)
-struct in_addr addr;
-struct in_addr mask;
-{
-       struct in_addr result;
-
-       result.s_addr = addr.s_addr | ~mask.s_addr;
-       return result;
-}
diff --git a/src/libfreeswan/subnettoa.c b/src/libfreeswan/subnettoa.c
deleted file mode 100644 (file)
index 694fa40..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * convert binary form of subnet description to ASCII
- * Copyright (C) 1998, 1999  Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
- * License for more details.
- */
-#include "internal.h"
-#include "freeswan.h"
-
-/*
- - subnettoa - convert address and mask to ASCII "addr/mask"
- * Output expresses the mask as a bit count if possible, else dotted decimal.
- */
-size_t                         /* space needed for full conversion */
-subnettoa(addr, mask, format, dst, dstlen)
-struct in_addr addr;
-struct in_addr mask;
-int format;                    /* character */
-char *dst;                     /* need not be valid if dstlen is 0 */
-size_t dstlen;
-{
-       size_t len;
-       size_t rest;
-       int n;
-       char *p;
-
-       switch (format) {
-       case 0:
-               break;
-       default:
-               return 0;
-               break;
-       }
-
-       len = addrtoa(addr, 0, dst, dstlen);
-       if (len < dstlen) {
-               dst[len - 1] = '/';
-               p = dst + len;
-               rest = dstlen - len;
-       } else {
-               p = NULL;
-               rest = 0;
-       }
-
-       n = masktobits(mask);
-       if (n >= 0)
-               len += ultoa((unsigned long)n, 10, p, rest);
-       else
-               len += addrtoa(mask, 0, p, rest);
-
-       return len;
-}
diff --git a/src/libfreeswan/subnettot.c b/src/libfreeswan/subnettot.c
deleted file mode 100644 (file)
index 64d511b..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * convert binary form of subnet description to text
- * Copyright (C) 2000  Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
- * License for more details.
- */
-#include "internal.h"
-#include "freeswan.h"
-
-/*
- - subnettot - convert subnet to text "addr/bitcount"
- */
-size_t                         /* space needed for full conversion */
-subnettot(sub, format, dst, dstlen)
-const ip_subnet *sub;
-int format;                    /* character */
-char *dst;                     /* need not be valid if dstlen is 0 */
-size_t dstlen;
-{
-       size_t len;
-       size_t rest;
-       char *p;
-
-       switch (format) {
-       case 0:
-               break;
-       default:
-               return 0;
-               break;
-       }
-
-       len = addrtot(&sub->addr, format, dst, dstlen);
-       if (len < dstlen) {
-               dst[len - 1] = '/';
-               p = dst + len;
-               rest = dstlen - len;
-       } else {
-               p = NULL;
-               rest = 0;
-       }
-
-
-       len += ultoa((unsigned long)sub->maskbits, 10, p, rest);
-
-       return len;
-}
diff --git a/src/libfreeswan/subnettypeof.c b/src/libfreeswan/subnettypeof.c
deleted file mode 100644 (file)
index 96c283c..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * extract parts of an ip_subnet, and related
- * Copyright (C) 2000  Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
- * License for more details.
- */
-#include "internal.h"
-#include "freeswan.h"
-
-/*
- - subnettypeof - get the address type of an ip_subnet
- */
-int
-subnettypeof(src)
-const ip_subnet *src;
-{
-       return src->addr.u.v4.sin_family;
-}
-
-/*
- - networkof - get the network address of a subnet
- */
-void
-networkof(src, dst)
-const ip_subnet *src;
-ip_address *dst;
-{
-       *dst = src->addr;
-}
-
-/*
- - maskof - get the mask of a subnet, as an address
- */
-void
-maskof(src, dst)
-const ip_subnet *src;
-ip_address *dst;
-{
-       int b;
-       unsigned char buf[16];
-       size_t n = addrlenof(&src->addr);
-       unsigned char *p;
-
-       if (src->maskbits > n*8 || n > sizeof(buf))
-               return;         /* "can't happen" */
-
-       p = buf;
-       for (b = src->maskbits; b >= 8; b -= 8)
-               *p++ = 0xff;
-       if (b != 0)
-               *p++ = (0xff << (8 - b)) & 0xff;
-       while (p - buf < n)
-               *p++ = 0;
-
-       (void) initaddr(buf, n, addrtypeof(&src->addr), dst);
-}
-
-/*
- - masktocount - convert a mask, expressed as an address, to a bit count
- */
-int                            /* -1 if not valid mask */
-masktocount(src)
-const ip_address *src;
-{
-       int b;
-       unsigned const char *bp;
-       size_t n;
-       unsigned const char *p;
-       unsigned const char *stop;
-
-       n = addrbytesptr(src, &bp);
-       if (n == 0)
-               return -1;
-
-       p = bp;
-       stop = bp + n;
-
-       n = 0;
-       while (p < stop && *p == 0xff) {
-               p++;
-               n += 8;
-       }
-       if (p < stop && *p != 0) {      /* boundary in mid-byte */
-               b = *p++;
-               while (b&0x80) {
-                       b <<= 1;
-                       n++;
-               }
-               if ((b&0xff) != 0)
-                       return -1;      /* bits not contiguous */
-       }
-       while (p < stop && *p == 0)
-               p++;
-
-       if (p != stop)
-               return -1;
-
-       return n;
-}
diff --git a/src/libfreeswan/ttoaddr.3 b/src/libfreeswan/ttoaddr.3
deleted file mode 100644 (file)
index d43d2b1..0000000
+++ /dev/null
@@ -1,374 +0,0 @@
-.TH IPSEC_TTOADDR 3 "28 Sept 2001"
-.SH NAME
-ipsec ttoaddr, tnatoaddr, addrtot \- convert Internet addresses to and from text
-.br
-ipsec ttosubnet, subnettot \- convert subnet/mask text form to and from addresses
-.SH SYNOPSIS
-.B "#include <freeswan.h>
-.sp
-.B "const char *ttoaddr(const char *src, size_t srclen,"
-.ti +1c
-.B "int af, ip_address *addr);"
-.br
-.B "const char *tnatoaddr(const char *src, size_t srclen,"
-.ti +1c
-.B "int af, ip_address *addr);"
-.br
-.B "size_t addrtot(const ip_address *addr, int format,"
-.ti +1c
-.B "char *dst, size_t dstlen);"
-.sp
-.B "const char *ttosubnet(const char *src, size_t srclen,"
-.ti +1c
-.B "int af, ip_subnet *dst);"
-.br
-.B "size_t subnettot(const ip_subnet *sub, int format,"
-.ti +1c
-.B "char *dst, size_t dstlen);"
-.SH DESCRIPTION
-.I Ttoaddr
-converts a text-string name or numeric address into a binary address
-(in network byte order).
-.I Tnatoaddr
-does the same conversion,
-but the only text forms it accepts are
-the ``official'' forms of
-numeric address (dotted-decimal for IPv4, colon-hex for IPv6).
-.I Addrtot
-does the reverse conversion, from binary address back to a text form.
-.I Ttosubnet
-and
-.I subnettot
-do likewise for the ``address/mask'' form used to write a
-specification of a subnet.
-.PP
-An IPv4 address is specified in text as a
-dotted-decimal address (e.g.
-.BR 1.2.3.4 ),
-an eight-digit network-order hexadecimal number with the usual C prefix (e.g.
-.BR 0x01020304 ,
-which is synonymous with
-.BR 1.2.3.4 ),
-an eight-digit host-order hexadecimal number with a
-.B 0h
-prefix (e.g.
-.BR 0h01020304 ,
-which is synonymous with
-.B 1.2.3.4
-on a big-endian host and
-.B 4.3.2.1
-on a little-endian host),
-a DNS name to be looked up via
-.IR getaddrinfo (3),
-or an old-style network name to be looked up via
-.IR getnetbyname (3).
-.PP
-A dotted-decimal address may be incomplete, in which case
-text-to-binary conversion implicitly appends
-as many instances of
-.B .0
-as necessary to bring it up to four components.
-The components of a dotted-decimal address are always taken as
-decimal, and leading zeros are ignored.
-For example,
-.B 10
-is synonymous with
-.BR 10.0.0.0 ,
-and
-.B 128.009.000.032
-is synonymous with
-.BR 128.9.0.32
-(the latter example is verbatim from RFC 1166).
-The result of applying
-.I addrtot
-to an IPv4 address is always complete and does not contain leading zeros.
-.PP
-Use of hexadecimal addresses is
-.B strongly
-.BR discouraged ;
-they are included only to save hassles when dealing with
-the handful of perverted programs which already print 
-network addresses in hexadecimal.
-.PP
-An IPv6 address is specified in text with
-colon-hex notation (e.g.
-.BR 0:56:78ab:22:33:44:55:66 ),
-colon-hex with
-.B ::
-abbreviating at most one subsequence of multiple zeros (e.g.
-.BR 99:ab::54:068 ,
-which is synonymous with
-.BR 99:ab:0:0:0:0:54:68 ),
-or a DNS name to be looked up via
-.IR getaddrinfo (3).
-The result of applying
-.I addrtot
-to an IPv6 address will use
-.B ::
-abbreviation if possible,
-and will not contain leading zeros.
-.PP
-The letters in hexadecimal
-may be uppercase or lowercase or any mixture thereof.
-.PP
-DNS names may be complete (optionally terminated with a ``.'')
-or incomplete, and are looked up as specified by local system configuration
-(see
-.IR resolver (5)).
-The first value returned by
-.IR getaddrinfo (3)
-is used,
-so with current DNS implementations,
-the result when the name corresponds to more than one address is
-difficult to predict.
-IPv4 name lookup resorts to
-.IR getnetbyname (3)
-only if
-.IR getaddrinfo (3)
-fails.
-.PP
-A subnet specification is of the form \fInetwork\fB/\fImask\fR.
-The
-.I network
-and
-.I mask
-can be any form acceptable to
-.IR ttoaddr .
-In addition, and preferably, the
-.I mask
-can be a decimal integer (leading zeros ignored) giving a bit count,
-in which case
-it stands for a mask with that number of high bits on and all others off
-(e.g.,
-.B 24
-in IPv4 means
-.BR 255.255.255.0 ).
-In any case, the mask must be contiguous
-(a sequence of high bits on and all remaining low bits off).
-As a special case, the subnet specification
-.B %default
-is a synonym for
-.B 0.0.0.0/0
-or
-.B ::/0
-in IPv4 or IPv6 respectively.
-.PP
-.I Ttosubnet
-ANDs the mask with the address before returning,
-so that any non-network bits in the address are turned off
-(e.g.,
-.B 10.1.2.3/24
-is synonymous with
-.BR 10.1.2.0/24 ).
-.I Subnettot
-always generates the decimal-integer-bit-count
-form of the mask,
-with no leading zeros.
-.PP
-The
-.I srclen
-parameter of
-.I ttoaddr
-and
-.I ttosubnet
-specifies the length of the text string pointed to by
-.IR src ;
-it is an error for there to be anything else
-(e.g., a terminating NUL) within that length.
-As a convenience for cases where an entire NUL-terminated string is
-to be converted,
-a
-.I srclen
-value of
-.B 0
-is taken to mean
-.BR strlen(src) .
-.PP
-The
-.I af
-parameter of
-.I ttoaddr
-and
-.I ttosubnet
-specifies the address family of interest.
-It should be either
-.B AF_INET
-or
-.BR AF_INET6 .
-.PP
-The
-.I dstlen
-parameter of
-.I addrtot
-and
-.I subnettot
-specifies the size of the
-.I dst
-parameter;
-under no circumstances are more than
-.I dstlen
-bytes written to
-.IR dst .
-A result which will not fit is truncated.
-.I Dstlen
-can be zero, in which case
-.I dst
-need not be valid and no result is written,
-but the return value is unaffected;
-in all other cases, the (possibly truncated) result is NUL-terminated.
-The
-.I freeswan.h
-header file defines constants,
-.B ADDRTOT_BUF
-and
-.BR SUBNETTOT_BUF ,
-which are the sizes of buffers just large enough for worst-case results.
-.PP
-The
-.I format
-parameter of
-.I addrtot
-and
-.I subnettot
-specifies what format is to be used for the conversion.
-The value
-.B 0
-(not the character
-.BR '0' ,
-but a zero value)
-specifies a reasonable default,
-and is in fact the only format currently available in
-.IR subnettot .
-.I Addrtot
-also accepts format values
-.B 'r'
-(signifying a text form suitable for DNS reverse lookups,
-e.g.
-.B 4.3.2.1.IN-ADDR.ARPA.
-for IPv4 and
-RFC 2874 format for IPv6),
-and
-.B 'R'
-(signifying an alternate reverse-lookup form,
-an error for IPv4 and RFC 1886 format for IPv6).
-Reverse-lookup names always end with a ``.''.
-.PP
-The text-to-binary functions return NULL for success and
-a pointer to a string-literal error message for failure;
-see DIAGNOSTICS.
-The binary-to-text functions return
-.B 0
-for a failure, and otherwise
-always return the size of buffer which would 
-be needed to
-accommodate the full conversion result, including terminating NUL;
-it is the caller's responsibility to check this against the size of
-the provided buffer to determine whether truncation has occurred.
-.SH SEE ALSO
-inet(3)
-.SH DIAGNOSTICS
-Fatal errors in
-.I ttoaddr
-are:
-empty input;
-unknown address family;
-attempt to allocate temporary storage for a very long name failed;
-name lookup failed;
-syntax error in dotted-decimal or colon-hex form;
-dotted-decimal or colon-hex component too large.
-.PP
-Fatal errors in
-.I ttosubnet
-are:
-no
-.B /
-in
-.IR src ;
-.I ttoaddr
-error in conversion of
-.I network
-or
-.IR mask ;
-bit-count mask too big;
-mask non-contiguous.
-.PP
-Fatal errors in
-.I addrtot
-and
-.I subnettot
-are:
-unknown format.
-.SH HISTORY
-Written for the FreeS/WAN project by Henry Spencer.
-.SH BUGS
-The interpretation of incomplete dotted-decimal addresses
-(e.g.
-.B 10/24
-means
-.BR 10.0.0.0/24 )
-differs from that of some older conversion
-functions, e.g. those of
-.IR inet (3).
-The behavior of the older functions has never been
-particularly consistent or particularly useful.
-.PP
-Ignoring leading zeros in dotted-decimal components and bit counts
-is arguably the most useful behavior in this application,
-but it might occasionally cause confusion with the historical use of leading 
-zeros to denote octal numbers.
-.PP
-.I Ttoaddr
-does not support the mixed colon-hex-dotted-decimal
-convention used to embed an IPv4 address in an IPv6 address.
-.PP
-.I Addrtot
-always uses the
-.B ::
-abbreviation (which can appear only once in an address) for the
-.I first
-sequence of multiple zeros in an IPv6 address.
-One can construct addresses (unlikely ones) in which this is suboptimal.
-.PP
-.I Addrtot
-.B 'r'
-conversion of an IPv6 address uses lowercase hexadecimal,
-not the uppercase used in RFC 2874's examples.
-It takes careful reading of RFCs 2874, 2673, and 2234 to realize
-that lowercase is technically legitimate here,
-and there may be software which botches this
-and hence would have trouble with lowercase hex.
-.PP
-Possibly
-.I subnettot
-ought to recognize the
-.B %default
-case and generate that string as its output.
-Currently it doesn't.
-.PP
-It is barely possible that somebody, somewhere,
-might have a legitimate use for non-contiguous subnet masks.
-.PP
-.IR Getnetbyname (3)
-is a historical dreg.
-.PP
-.I Tnatoaddr
-probably should enforce completeness of dotted-decimal addresses.
-.PP
-The restriction of text-to-binary error reports to literal strings
-(so that callers don't need to worry about freeing them or copying them)
-does limit the precision of error reporting.
-.PP
-The text-to-binary error-reporting convention lends itself
-to slightly obscure code,
-because many readers will not think of NULL as signifying success.
-A good way to make it clearer is to write something like:
-.PP
-.RS
-.nf
-.B "const char *error;"
-.sp
-.B "error = ttoaddr( /* ... */ );"
-.B "if (error != NULL) {"
-.B "        /* something went wrong */"
-.fi
-.RE
diff --git a/src/libfreeswan/ttoaddr.c b/src/libfreeswan/ttoaddr.c
deleted file mode 100644 (file)
index 234c9d8..0000000
+++ /dev/null
@@ -1,471 +0,0 @@
-/*
- * conversion from text forms of addresses to internal ones
- * Copyright (C) 2000  Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
- * License for more details.
- */
-#include <sys/socket.h>
-
-#include "internal.h"
-#include "freeswan.h"
-
-/*
- * Legal ASCII characters in a domain name.  Underscore technically is not,
- * but is a common misunderstanding.  Non-ASCII characters are simply
- * exempted from checking at the moment, to allow for UTF-8 encoded stuff;
- * the purpose of this check is merely to catch blatant errors.
- */
-static const char namechars[] = "abcdefghijklmnopqrstuvwxyz0123456789"
-                               "ABCDEFGHIJKLMNOPQRSTUVWXYZ-_.";
-#define        ISASCII(c)      (((c) & 0x80) == 0)
-
-static err_t tryname(const char *, size_t, int, int, ip_address *);
-static err_t tryhex(const char *, size_t, int, ip_address *);
-static err_t trydotted(const char *, size_t, ip_address *);
-static err_t getbyte(const char **, const char *, int *);
-static err_t colon(const char *, size_t, ip_address *);
-static err_t getpiece(const char **, const char *, unsigned *);
-
-/*
- - ttoaddr - convert text name or dotted-decimal address to binary address
- */
-err_t                          /* NULL for success, else string literal */
-ttoaddr(src, srclen, af, dst)
-const char *src;
-size_t srclen;                 /* 0 means "apply strlen" */
-int af;                                /* address family */
-ip_address *dst;
-{
-       err_t oops;
-#      define  HEXLEN  10      /* strlen("0x11223344") */
-       int nultermd;
-
-       if (srclen == 0) {
-               srclen = strlen(src);
-               if (srclen == 0)
-                       return "empty string";
-               nultermd = 1;
-       } else
-               nultermd = 0;   /* at least, not *known* to be terminated */
-
-       switch (af) {
-       case AF_INET:
-       case AF_INET6:
-       case 0:                  /* guess */
-               break;
-
-       default:
-               return "invalid address family";
-       }
-
-       if (af == AF_INET && srclen == HEXLEN && *src == '0') {
-               if (*(src+1) == 'x' || *(src+1) == 'X')
-                       return tryhex(src+2, srclen-2, 'x', dst);
-               if (*(src+1) == 'h' || *(src+1) == 'H')
-                       return tryhex(src+2, srclen-2, 'h', dst);
-       }
-
-       if (memchr(src, ':', srclen) != NULL) {
-           if(af == 0)
-           {
-               af = AF_INET6;
-           }
-
-               if (af != AF_INET6)
-                       return "non-ipv6 address may not contain `:'";
-               return colon(src, srclen, dst);
-       }
-
-       if (af == 0 || af == AF_INET) {
-               oops = trydotted(src, srclen, dst);
-               if (oops == NULL)
-                       return NULL;            /* it worked */
-               if (*oops != '?')
-                       return oops;            /* probably meant as d-d */
-       }
-
-       return tryname(src, srclen, nultermd, af, dst);
-}
-
-/*
- - tnatoaddr - convert text numeric address (only) to binary address
- */
-err_t                          /* NULL for success, else string literal */
-tnatoaddr(src, srclen, af, dst)
-const char *src;
-size_t srclen;                 /* 0 means "apply strlen" */
-int af;                                /* address family */
-ip_address *dst;
-{
-       err_t oops;
-
-       if (srclen == 0) {
-               srclen = strlen(src);
-               if (srclen == 0)
-                       return "empty string";
-       }
-
-       switch (af) {
-       case 0:  /* guess */
-               oops = colon(src, srclen, dst);
-               if(oops == NULL)
-               {
-                   return NULL;
-               }
-               oops = trydotted(src, srclen, dst);
-               if(oops == NULL)
-               {
-                   return NULL;
-               }
-               return "does not appear to be either IPv4 or IPv6 numeric address";
-               break;
-
-       case AF_INET6:
-               return colon(src, srclen, dst);
-               break;
-       case AF_INET:
-               oops = trydotted(src, srclen, dst);
-               if (oops == NULL)
-                       return NULL;            /* it worked */
-               if (*oops != '?')
-                       return oops;            /* probably meant as d-d */
-               return "does not appear to be numeric address";
-               break;
-       default:
-               return "unknown address family in tnatoaddr";
-               break;
-       }
-}
-
-/*
- - tryname - try it as a name
- * Slightly complicated by lack of reliable NUL termination in source.
- */
-static err_t
-tryname(src, srclen, nultermd, af, dst)
-const char *src;
-size_t srclen;
-int nultermd;                  /* is it known to be NUL-terminated? */
-int af;
-ip_address *dst;
-{
-       struct addrinfo hints, *res;
-       struct netent *ne = NULL;
-       char namebuf[100];      /* enough for most DNS names */
-       const char *cp;
-       char *p = namebuf;
-       unsigned char *addr = NULL;
-       size_t n;
-       int error;
-       err_t err = NULL;
-
-       for (cp = src, n = srclen; n > 0; cp++, n--)
-               if (ISASCII(*cp) && strchr(namechars, *cp) == NULL)
-                       return "illegal (non-DNS-name) character in name";
-
-       if (nultermd)
-               cp = src;
-       else {
-               if (srclen+1 > sizeof(namebuf)) {
-                       p = (char *) MALLOC(srclen+1);
-                       if (p == NULL)
-                               return "unable to get temporary space for name";
-               }
-               p[0] = '\0';    /* strncpy semantics are wrong */
-               strncat(p, src, srclen);
-               cp = (const char *)p;
-       }
-
-       memset(&hints, 0, sizeof(hints));
-       hints.ai_family = af;
-       error = getaddrinfo(cp, NULL, &hints, &res);
-       if (error != 0)
-       {       /* getaddrinfo failed, try getnetbyname */
-               if (af == AF_INET)
-               {
-                       ne = getnetbyname(cp);
-                       if (ne != NULL)
-                       {
-                               ne->n_net = htonl(ne->n_net);
-                               addr = (unsigned char*)&ne->n_net;
-                               err = initaddr(addr, sizeof(ne->n_net), af, dst);
-                       }
-               }
-       }
-       else
-       {
-               struct addrinfo *r = res;
-               while (r)
-               {
-                       size_t addr_len;
-                       switch (r->ai_family)
-                       {
-                               case AF_INET:
-                               {
-                                       struct sockaddr_in *in = (struct sockaddr_in*)r->ai_addr;
-                                       addr_len = 4;
-                                       addr = (unsigned char*)&in->sin_addr.s_addr;
-                                       break;
-                               }
-                               case AF_INET6:
-                               {
-                                       struct sockaddr_in6 *in6 = (struct sockaddr_in6*)r->ai_addr;
-                                       addr_len = 16;
-                                       addr = (unsigned char*)&in6->sin6_addr.s6_addr;
-                                       break;
-                               }
-                               default:
-                               {       /* unknown family, try next result */
-                                       r = r->ai_next;
-                                       continue;
-                               }
-                       }
-                       err = initaddr(addr, addr_len, r->ai_family, dst);
-                       break;
-               }
-               freeaddrinfo(res);
-       }
-
-       if (p != namebuf)
-       {
-               FREE(p);
-       }
-
-       if (addr == NULL)
-       {
-               return "does not look numeric and name lookup failed";
-       }
-
-       return err;
-}
-
-/*
- - tryhex - try conversion as an eight-digit hex number (AF_INET only)
- */
-static err_t
-tryhex(src, srclen, flavor, dst)
-const char *src;
-size_t srclen;                 /* should be 8 */
-int flavor;                    /* 'x' for network order, 'h' for host order */
-ip_address *dst;
-{
-       err_t oops;
-       unsigned long ul;
-       union {
-               uint32_t addr;
-               unsigned char buf[4];
-       } u;
-
-       if (srclen != 8)
-               return "internal error, tryhex called with bad length";
-
-       oops = ttoul(src, srclen, 16, &ul);
-       if (oops != NULL)
-               return oops;
-
-       u.addr = (flavor == 'h') ? ul : htonl(ul);
-       return initaddr(u.buf, sizeof(u.buf), AF_INET, dst);
-}
-
-/*
- - trydotted - try conversion as dotted decimal (AF_INET only)
- *
- * If the first char of a complaint is '?', that means "didn't look like
- * dotted decimal at all".
- */
-static err_t
-trydotted(src, srclen, dst)
-const char *src;
-size_t srclen;
-ip_address *dst;
-{
-       const char *stop = src + srclen;        /* just past end */
-       int byte;
-       err_t oops;
-#      define  NBYTES  4
-       unsigned char buf[NBYTES];
-       int i;
-
-       memset(buf, 0, sizeof(buf));
-       for (i = 0; i < NBYTES && src < stop; i++) {
-               oops = getbyte(&src, stop, &byte);
-               if (oops != NULL) {
-                       if (*oops != '?')
-                               return oops;    /* bad number */
-                       if (i > 1)
-                               return oops+1;  /* failed number */
-                       return oops;            /* with leading '?' */
-               }
-               buf[i] = byte;
-               if (i < 3 && src < stop && *src++ != '.') {
-                       if (i == 0)
-                               return "?syntax error in dotted-decimal address";
-                       else
-                               return "syntax error in dotted-decimal address";
-               }
-       }
-       if (src != stop)
-               return "extra garbage on end of dotted-decimal address";
-
-       return initaddr(buf, sizeof(buf), AF_INET, dst);
-}
-
-/*
- - getbyte - try to scan a byte in dotted decimal
- * A subtlety here is that all this arithmetic on ASCII digits really is
- * highly portable -- ANSI C guarantees that digits 0-9 are contiguous.
- * It's easier to just do it ourselves than set up for a call to ttoul().
- *
- * If the first char of a complaint is '?', that means "didn't look like a
- * number at all".
- */
-err_t
-getbyte(srcp, stop, retp)
-const char **srcp;             /* *srcp is updated */
-const char *stop;              /* first untouchable char */
-int *retp;                     /* return-value pointer */
-{
-       char c;
-       const char *p;
-       int no;
-
-       if (*srcp >= stop)
-               return "?empty number in dotted-decimal address";
-
-       no = 0;
-       p = *srcp;
-       while (p < stop && no <= 255 && (c = *p) >= '0' && c <= '9') {
-               no = no*10 + (c - '0');
-               p++;
-       }
-       if (p == *srcp)
-               return "?non-numeric component in dotted-decimal address";
-       *srcp = p;
-       if (no > 255)
-               return "byte overflow in dotted-decimal address";
-       *retp = no;
-       return NULL;
-}
-
-/*
- - colon - convert IPv6 "numeric" address
- */
-static err_t
-colon(src, srclen, dst)
-const char *src;
-size_t srclen;                 /* known to be >0 */
-ip_address *dst;
-{
-       const char *stop = src + srclen;        /* just past end */
-       unsigned piece = 0;
-       int gapat;              /* where was empty piece seen */
-       err_t oops;
-#      define  NPIECES 8
-       unsigned char buf[NPIECES*2];   /* short may have wrong byte order */
-       int i;
-       int j;
-#      define  IT      "IPv6 numeric address"
-       int naftergap;
-
-       /* leading or trailing :: becomes single empty field */
-       if (*src == ':') {              /* legal only if leading :: */
-               if (srclen == 1 || *(src+1) != ':')
-                       return "illegal leading `:' in " IT;
-               if (srclen == 2) {
-                       unspecaddr(AF_INET6, dst);
-                       return NULL;
-               }
-               src++;          /* past first but not second */
-               srclen--;
-       }
-       if (*(stop-1) == ':') {         /* legal only if trailing :: */
-               if (srclen == 1 || *(stop-2) != ':')
-                       return "illegal trailing `:' in " IT;
-               srclen--;               /* leave one */
-       }
-
-       gapat = -1;
-       for (i = 0; i < NPIECES && src < stop; i++) {
-               oops = getpiece(&src, stop, &piece);
-               if (oops != NULL && *oops == ':') {     /* empty field */
-                       if (gapat >= 0)
-                               return "more than one :: in " IT;
-                       gapat = i;
-               } else if (oops != NULL)
-                       return oops;
-               buf[2*i] = piece >> 8;
-               buf[2*i + 1] = piece & 0xff;
-               if (i < NPIECES-1) {    /* there should be more input */
-                       if (src == stop && gapat < 0)
-                               return IT " ends prematurely";
-                       if (src != stop && *src++ != ':')
-                               return "syntax error in " IT;
-               }
-       }
-       if (src != stop)
-               return "extra garbage on end of " IT;
-
-       if (gapat < 0 && i < NPIECES)   /* should have been caught earlier */
-               return "incomplete " IT " (internal error)";
-       if (gapat >= 0 && i == NPIECES)
-               return "non-abbreviating empty field in " IT;
-       if (gapat >= 0) {
-               naftergap = i - (gapat + 1);
-               for (i--, j = NPIECES-1; naftergap > 0; i--, j--, naftergap--) {
-                       buf[2*j] = buf[2*i];
-                       buf[2*j + 1] = buf[2*i + 1];
-               }
-               for (; j >= gapat; j--)
-                       buf[2*j] = buf[2*j + 1] = 0;
-       }
-
-       return initaddr(buf, sizeof(buf), AF_INET6, dst);
-}
-
-/*
- - getpiece - try to scan one 16-bit piece of an IPv6 address
- */
-err_t                          /* ":" means "empty field seen" */
-getpiece(srcp, stop, retp)
-const char **srcp;             /* *srcp is updated */
-const char *stop;              /* first untouchable char */
-unsigned *retp;                        /* return-value pointer */
-{
-       const char *p;
-#      define  NDIG    4
-       int d;
-       unsigned long ret;
-       err_t oops;
-
-       if (*srcp >= stop || **srcp == ':') {   /* empty field */
-               *retp = 0;
-               return ":";
-       }
-
-       p = *srcp;
-       d = 0;
-       while (p < stop && d < NDIG && isxdigit(*p)) {
-               p++;
-               d++;
-       }
-       if (d == 0)
-               return "non-hex field in IPv6 numeric address";
-       if (p < stop && d == NDIG && isxdigit(*p))
-               return "field in IPv6 numeric address longer than 4 hex digits";
-
-       oops = ttoul(*srcp, d, 16, &ret);
-       if (oops != NULL)       /* shouldn't happen, really... */
-               return oops;
-
-       *srcp = p;
-       *retp = ret;
-       return NULL;
-}
diff --git a/src/libfreeswan/ttodata.3 b/src/libfreeswan/ttodata.3
deleted file mode 100644 (file)
index 8f4b1ec..0000000
+++ /dev/null
@@ -1,280 +0,0 @@
-.TH IPSEC_TTODATA 3 "16 August 2003"
-.SH NAME
-ipsec ttodata, datatot \- convert binary data bytes from and to text formats
-.SH SYNOPSIS
-.B "#include <freeswan.h>"
-.sp
-.B "const char *ttodata(const char *src, size_t srclen,"
-.ti +1c
-.B "int base, char *dst, size_t dstlen, size_t *lenp);"
-.br
-.B "const char *ttodatav(const char *src, size_t srclen,"
-.ti +1c
-.B "int base, char *dst, size_t dstlen, size_t *lenp,"
-.ti +1c
-.B "char *errp, size_t errlen, int flags);"
-.br
-.B "size_t datatot(const char *src, size_t srclen,"
-.ti +1c
-.B "int format, char *dst, size_t dstlen);"
-.SH DESCRIPTION
-.IR Ttodata ,
-.IR ttodatav ,
-and
-.I datatot
-convert arbitrary binary data (e.g. encryption or authentication keys)
-from and to more-or-less human-readable text formats.
-.PP
-Currently supported formats are hexadecimal, base64, and characters.
-.PP
-A hexadecimal text value begins with a
-.B 0x
-(or
-.BR 0X )
-prefix and continues with two-digit groups
-of hexadecimal digits (0-9, and a-f or A-F),
-each group encoding the value of one binary byte, high-order digit first.
-A single
-.B _
-(underscore)
-between consecutive groups is ignored, permitting punctuation to improve 
-readability; doing this every eight digits seems about right.
-.PP
-A base64 text value begins with a
-.B 0s
-(or
-.BR 0S )
-prefix 
-and continues with four-digit groups of base64 digits (A-Z, a-z, 0-9, +, and /),
-each group encoding the value of three binary bytes as described in
-section 6.8 of RFC 2045.
-If
-.B flags
-has the
-.B TTODATAV_IGNORESPACE
-bit on, blanks are ignore (after the prefix).
-Note that the last one or two digits of a base64 group can be
-.B =
-to indicate that fewer than three binary bytes are encoded.
-.PP
-A character text value begins with a
-.B 0t
-(or
-.BR 0T )
-prefix
-and continues with text characters, each being the value of one binary byte. 
-.PP
-All these functions basically copy data from
-.I src
-(whose size is specified by
-.IR srclen )
-to
-.I dst
-(whose size is specified by
-.IR dstlen ),
-doing the conversion en route.
-If the result will not fit in
-.IR dst ,
-it is truncated;
-under no circumstances are more than
-.I dstlen
-bytes of result written to
-.IR dst .
-.I Dstlen
-can be zero, in which case
-.I dst
-need not be valid and no result bytes are written at all.
-.PP
-The
-.I base
-parameter of
-.I ttodata
-and
-.I ttodatav
-specifies what format the input is in;
-normally it should be
-.B 0
-to signify that this gets figured out from the prefix.
-Values of
-.BR 16 ,
-.BR 64 ,
-and
-.BR 256
-respectively signify hexadecimal, base64, and character-text formats
-without prefixes.
-.PP
-The
-.I format
-parameter of
-.IR datatot ,
-a single character used as a type code,
-specifies which text format is wanted.
-The value
-.B 0
-(not ASCII
-.BR '0' ,
-but a zero value) specifies a reasonable default.
-Other currently-supported values are:
-.RS 2
-.TP 4
-.B 'x'
-continuous lower-case hexadecimal with a
-.B 0x
-prefix
-.TP
-.B 'h'
-lower-case hexadecimal with a
-.B 0x
-prefix and a
-.B _
-every eight digits
-.TP
-.B ':'
-lower-case hexadecimal with no prefix and a
-.B :
-(colon) every two digits
-.TP
-.B 16
-lower-case hexadecimal with no prefix or
-.B _
-.TP
-.B 's'
-continuous base64 with a
-.B 0s
-prefix
-.TP
-.B 64
-continuous base64 with no prefix
-.RE
-.PP
-The default format is currently
-.BR 'h' .
-.PP
-.I Ttodata
-returns NULL for success and
-a pointer to a string-literal error message for failure;
-see DIAGNOSTICS.
-On success,
-if and only if
-.I lenp
-is non-NULL,
-.B *lenp
-is set to the number of bytes required to contain the full untruncated result.
-It is the caller's responsibility to check this against
-.I dstlen
-to determine whether he has obtained a complete result.
-The
-.B *lenp
-value is correct even if
-.I dstlen
-is zero, which offers a way to determine how much space would be needed
-before having to allocate any.
-.PP
-.I Ttodatav
-is just like
-.I ttodata
-except that in certain cases,
-if
-.I errp
-is non-NULL,
-the buffer pointed to by
-.I errp
-(whose length is given by
-.IR errlen )
-is used to hold a more detailed error message.
-The return value is NULL for success,
-and is either
-.I errp
-or a pointer to a string literal for failure.
-If the size of the error-message buffer is
-inadequate for the desired message,
-.I ttodatav
-will fall back on returning a pointer to a literal string instead.
-The
-.I freeswan.h
-header file defines a constant
-.B TTODATAV_BUF
-which is the size of a buffer large enough for worst-case results.
-.PP
-The normal return value of
-.IR datatot
-is the number of bytes required
-to contain the full untruncated result.
-It is the caller's responsibility to check this against
-.I dstlen
-to determine whether he has obtained a complete result.
-The return value is correct even if
-.I dstlen
-is zero, which offers a way to determine how much space would be needed
-before having to allocate any.
-A return value of
-.B 0
-signals a fatal error of some kind
-(see DIAGNOSTICS).
-.PP
-A zero value for
-.I srclen
-in
-.I ttodata
-(but not
-.IR datatot !)
-is synonymous with
-.BR strlen(src) .
-A non-zero
-.I srclen
-in
-.I ttodata
-must not include the terminating NUL.
-.PP
-Unless
-.I dstlen
-is zero,
-the result supplied by
-.I datatot
-is always NUL-terminated,
-and its needed-size return value includes space for the terminating NUL.
-.PP
-Several obsolete variants of these functions
-.RI ( atodata ,
-.IR datatoa ,
-.IR atobytes ,
-and
-.IR bytestoa )
-are temporarily also supported.
-.SH SEE ALSO
-sprintf(3), ipsec_atoaddr(3)
-.SH DIAGNOSTICS
-Fatal errors in
-.I ttodata
-and
-.I ttodatav
-are:
-unknown characters in the input;
-unknown or missing prefix;
-unknown base;
-incomplete digit group;
-non-zero padding in a base64 less-than-three-bytes digit group;
-zero-length input.
-.PP
-Fatal errors in
-.I datatot
-are:
-unknown format code;
-zero-length input.
-.SH HISTORY
-Written for the FreeS/WAN project by Henry Spencer.
-.SH BUGS
-.I Datatot
-should have a format code to produce character-text output.
-.PP
-The
-.B 0s
-and
-.B 0t
-prefixes are the author's inventions and are not a standard
-of any kind.
-They have been chosen to avoid collisions with existing practice
-(some C implementations use
-.B 0b
-for binary)
-and possible confusion with unprefixed hexadecimal.
diff --git a/src/libfreeswan/ttodata.c b/src/libfreeswan/ttodata.c
deleted file mode 100644 (file)
index ef37177..0000000
+++ /dev/null
@@ -1,720 +0,0 @@
-/*
- * convert from text form of arbitrary data (e.g., keys) to binary
- * Copyright (C) 2000  Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
- * License for more details.
- */
-#include "internal.h"
-#include "freeswan.h"
-
-/* converters and misc */
-static int unhex(const char *, char *, size_t);
-static int unb64(const char *, char *, size_t);
-static int untext(const char *, char *, size_t);
-static const char *badch(const char *, int, char *, size_t);
-
-/* internal error codes for converters */
-#define        SHORT   (-2)            /* internal buffer too short */
-#define        BADPAD  (-3)            /* bad base64 padding */
-#define        BADCH0  (-4)            /* invalid character 0 */
-#define        BADCH1  (-5)            /* invalid character 1 */
-#define        BADCH2  (-6)            /* invalid character 2 */
-#define        BADCH3  (-7)            /* invalid character 3 */
-#define        BADOFF(code) (BADCH0-(code))
-
-/*
- - ttodatav - convert text to data, with verbose error reports
- * If some of this looks slightly odd, it's because it has changed
- * repeatedly (from the original atodata()) without a major rewrite.
- */
-const char *                   /* NULL on success, else literal or errp */
-ttodatav(src, srclen, base, dst, dstlen, lenp, errp, errlen, flags)
-const char *src;
-size_t srclen;                 /* 0 means apply strlen() */
-int base;                      /* 0 means figure it out */
-char *dst;                     /* need not be valid if dstlen is 0 */
-size_t dstlen;
-size_t *lenp;                  /* where to record length (NULL is nowhere) */
-char *errp;                    /* error buffer */
-size_t errlen;
-unsigned int flags;
-{
-       size_t ingroup; /* number of input bytes converted at once */
-       char buf[4];            /* output from conversion */
-       int nbytes;             /* size of output */
-       int (*decode)(const char *, char *, size_t);
-       char *stop;
-       int ndone;
-       int i;
-       int underscoreok;
-       int skipSpace = 0;
-
-       if (srclen == 0)
-               srclen = strlen(src);
-       if (dstlen == 0)
-               dst = buf;      /* point it somewhere valid */
-       stop = dst + dstlen;
-
-       if (base == 0) {
-               if (srclen < 2)
-                       return "input too short to be valid";
-               if (*src++ != '0')
-                       return "input does not begin with format prefix";
-               switch (*src++) {
-               case 'x':
-               case 'X':
-                       base = 16;
-                       break;
-               case 's':
-               case 'S':
-                       base = 64;
-                       break;
-               case 't':
-               case 'T':
-                       base = 256;
-                       break;
-               default:
-                       return "unknown format prefix";
-               }
-               srclen -= 2;
-       }
-       switch (base) {
-       case 16:
-               decode = unhex;
-               underscoreok = 1;
-               ingroup = 2;
-               break;
-       case 64:
-               decode = unb64;
-               underscoreok = 0;
-               ingroup = 4;
-               if(flags & TTODATAV_IGNORESPACE) {
-                       skipSpace = 1;
-               }
-               break;
-
-       case 256:
-               decode = untext;
-               ingroup = 1;
-               underscoreok = 0;
-               break;
-       default:
-               return "unknown base";
-       }
-
-       /* proceed */
-       ndone = 0;
-       while (srclen > 0) {
-               char stage[4];  /* staging area for group */
-               size_t sl = 0;
-
-               /* Grab ingroup characters into stage,
-                * squeezing out blanks if we are supposed to ignore them.
-                */
-               for (sl = 0; sl < ingroup; src++, srclen--) {
-                       if (srclen == 0)
-                               return "input ends in mid-byte, perhaps truncated";
-                       else if (!(skipSpace && (*src == ' ' || *src == '\t')))
-                               stage[sl++] = *src;
-               }
-
-               nbytes = (*decode)(stage, buf, sizeof(buf));
-               switch (nbytes) {
-               case BADCH0:
-               case BADCH1:
-               case BADCH2:
-               case BADCH3:
-                       return badch(stage, nbytes, errp, errlen);
-               case SHORT:
-                       return "internal buffer too short (\"can't happen\")";
-               case BADPAD:
-                       return "bad (non-zero) padding at end of base64 input";
-               }
-               if (nbytes <= 0)
-                       return "unknown internal error";
-               for (i = 0; i < nbytes; i++) {
-                       if (dst < stop)
-                               *dst++ = buf[i];
-                       ndone++;
-               }
-               while (srclen >= 1 && skipSpace && (*src == ' ' || *src == '\t')){
-                       src++;
-                       srclen--;
-               }
-               if (underscoreok && srclen > 1 && *src == '_') {
-                       /* srclen > 1 means not last character */
-                       src++;
-                       srclen--;
-               }
-       }
-
-       if (ndone == 0)
-               return "no data bytes specified by input";
-       if (lenp != NULL)
-               *lenp = ndone;
-       return NULL;
-}
-
-/*
- - ttodata - convert text to data
- */
-const char *                   /* NULL on success, else literal */
-ttodata(src, srclen, base, dst, dstlen, lenp)
-const char *src;
-size_t srclen;                 /* 0 means apply strlen() */
-int base;                      /* 0 means figure it out */
-char *dst;                     /* need not be valid if dstlen is 0 */
-size_t dstlen;
-size_t *lenp;                  /* where to record length (NULL is nowhere) */
-{
-       return ttodatav(src, srclen, base, dst, dstlen, lenp, (char *)NULL,
-                       (size_t)0, TTODATAV_SPACECOUNTS);
-}
-
-/*
- - atodata - convert ASCII to data
- * backward-compatibility interface
- */
-size_t                         /* 0 for failure, true length for success */
-atodata(src, srclen, dst, dstlen)
-const char *src;
-size_t srclen;
-char *dst;
-size_t dstlen;
-{
-       size_t len;
-       const char *err;
-
-       err = ttodata(src, srclen, 0, dst, dstlen, &len);
-       if (err != NULL)
-               return 0;
-       return len;
-}
-
-/*
- - atobytes - convert ASCII to data bytes
- * another backward-compatibility interface
- */
-const char *
-atobytes(src, srclen, dst, dstlen, lenp)
-const char *src;
-size_t srclen;
-char *dst;
-size_t dstlen;
-size_t *lenp;
-{
-       return ttodata(src, srclen, 0, dst, dstlen, lenp);
-}
-
-/*
- - unhex - convert two ASCII hex digits to byte
- */
-static int             /* number of result bytes, or error code */
-unhex(src, dst, dstlen)
-const char *src;       /* known to be full length */
-char *dst;
-size_t dstlen;         /* not large enough is a failure */
-{
-       char *p;
-       unsigned byte;
-       static char hex[] = "0123456789abcdef";
-
-       if (dstlen < 1)
-               return SHORT;
-
-       p = strchr(hex, *src);
-       if (p == NULL)
-               p = strchr(hex, tolower(*src));
-       if (p == NULL)
-               return BADCH0;
-       byte = (p - hex) << 4;
-       src++;
-
-       p = strchr(hex, *src);
-       if (p == NULL)
-               p = strchr(hex, tolower(*src));
-       if (p == NULL)
-               return BADCH1;
-       byte |= (p - hex);
-
-       *dst = byte;
-       return 1;
-}
-
-/*
- - unb64 - convert four ASCII base64 digits to three bytes
- * Note that a base64 digit group is padded out with '=' if it represents
- * less than three bytes:  one byte is dd==, two is ddd=, three is dddd.
- */
-static int             /* number of result bytes, or error code */
-unb64(src, dst, dstlen)
-const char *src;       /* known to be full length */
-char *dst;
-size_t dstlen;
-{
-       char *p;
-       unsigned byte1;
-       unsigned byte2;
-       static char base64[] =
-       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-       if (dstlen < 3)
-               return SHORT;
-
-       p = strchr(base64, *src++);
-
-       if (p == NULL)
-               return BADCH0;
-       byte1 = (p - base64) << 2;      /* first six bits */
-
-       p = strchr(base64, *src++);
-       if (p == NULL) {
-               return BADCH1;
-       }
-
-       byte2 = p - base64;             /* next six:  two plus four */
-       *dst++ = byte1 | (byte2 >> 4);
-       byte1 = (byte2 & 0xf) << 4;
-
-       p = strchr(base64, *src++);
-       if (p == NULL) {
-               if (*(src-1) == '=' && *src == '=') {
-                       if (byte1 != 0)         /* bad padding */
-                               return BADPAD;
-                       return 1;
-               }
-               return BADCH2;
-       }
-
-       byte2 = p - base64;             /* next six:  four plus two */
-       *dst++ = byte1 | (byte2 >> 2);
-       byte1 = (byte2 & 0x3) << 6;
-
-       p = strchr(base64, *src++);
-       if (p == NULL) {
-               if (*(src-1) == '=') {
-                       if (byte1 != 0)         /* bad padding */
-                               return BADPAD;
-                       return 2;
-               }
-               return BADCH3;
-       }
-       byte2 = p - base64;             /* last six */
-       *dst++ = byte1 | byte2;
-
-       return 3;
-}
-
-/*
- - untext - convert one ASCII character to byte
- */
-static int             /* number of result bytes, or error code */
-untext(src, dst, dstlen)
-const char *src;       /* known to be full length */
-char *dst;
-size_t dstlen;         /* not large enough is a failure */
-{
-       if (dstlen < 1)
-               return SHORT;
-
-       *dst = *src;
-       return 1;
-}
-
-/*
- - badch - produce a nice complaint about an unknown character
- *
- * If the compiler complains that the array bigenough[] has a negative
- * size, that means the TTODATAV_BUF constant has been set too small.
- */
-static const char *            /* literal or errp */
-badch(src, errcode, errp, errlen)
-const char *src;
-int errcode;
-char *errp;                    /* might be NULL */
-size_t errlen;
-{
-       static const char pre[] = "unknown character (`";
-       static const char suf[] = "') in input";
-       char buf[5];
-#      define  REQD    (sizeof(pre) - 1 + sizeof(buf) - 1 + sizeof(suf))
-       struct sizecheck {
-               char bigenough[TTODATAV_BUF - REQD];    /* see above */
-       };
-       char ch;
-
-       if (errp == NULL || errlen < REQD)
-               return "unknown character in input";
-       strcpy(errp, pre);
-       ch = *(src + BADOFF(errcode));
-       if (isprint(ch)) {
-               buf[0] = ch;
-               buf[1] = '\0';
-       } else {
-               buf[0] = '\\';
-               buf[1] = ((ch & 0700) >> 6) + '0';
-               buf[2] = ((ch & 0070) >> 3) + '0';
-               buf[3] = ((ch & 0007) >> 0) + '0';
-               buf[4] = '\0';
-       }
-       strcat(errp, buf);
-       strcat(errp, suf);
-       return (const char *)errp;
-}
-
-
-
-#ifdef TTODATA_MAIN
-
-#include <stdio.h>
-
-struct artab;
-static void check(struct artab *r, char *buf, size_t n, err_t oops, int *status);
-static void regress(char *pgm);
-static void hexout(const char *s, size_t len, FILE *f);
-
-/*
- - main - convert first argument to hex, or run regression
- */
-int
-main(int argc, char *argv[])
-{
-       char buf[1024];
-       char buf2[1024];
-       char err[512];
-       size_t n;
-       size_t i;
-       char *p = buf;
-       char *p2 = buf2;
-       char *pgm = argv[0];
-       const char *oops;
-
-       if (argc < 2) {
-               fprintf(stderr, "Usage: %s {0x<hex>|0s<base64>|-r}\n", pgm);
-               exit(2);
-       }
-
-       if (strcmp(argv[1], "-r") == 0) {
-               regress(pgm);   /* should not return */
-               fprintf(stderr, "%s: regress() returned?!?\n", pgm);
-               exit(1);
-       }
-
-       oops = ttodatav(argv[1], 0, 0, buf, sizeof(buf), &n,
-                       err, sizeof(err), TTODATAV_IGNORESPACE);
-       if (oops != NULL) {
-               fprintf(stderr, "%s: ttodata error `%s' in `%s'\n", pgm,
-                                                               oops, argv[1]);
-               exit(1);
-       }
-
-       if (n > sizeof(buf)) {
-               p = (char *)malloc((size_t)n);
-               if (p == NULL) {
-                       fprintf(stderr,
-                               "%s: unable to malloc %d bytes for result\n",
-                               pgm, n);
-                       exit(1);
-               }
-               oops = ttodata(argv[1], 0, 0, p, n, &n);
-               if (oops != NULL) {
-                       fprintf(stderr, "%s: error `%s' in ttodata retry?!?\n",
-                                                               pgm, oops);
-                       exit(1);
-               }
-       }
-
-       hexout(p, n, stdout);
-       printf("\n");
-
-       i = datatot(buf, n, 'h', buf2, sizeof(buf2));
-       if (i == 0) {
-               fprintf(stderr, "%s: datatot reports error in `%s'\n", pgm,
-                                                               argv[1]);
-               exit(1);
-       }
-
-       if (i > sizeof(buf2)) {
-               p2 = (char *)malloc((size_t)i);
-               if (p == NULL) {
-                       fprintf(stderr,
-                               "%s: unable to malloc %d bytes for result\n",
-                               pgm, i);
-                       exit(1);
-               }
-               i = datatot(buf, n, 'h', p2, i);
-               if (i == 0) {
-                       fprintf(stderr, "%s: error in datatoa retry?!?\n", pgm);
-                       exit(1);
-               }
-       }
-
-       printf("%s\n", p2);
-
-       exit(0);
-}
-
-/*
- - hexout - output an arbitrary-length string in hex
- */
-static void
-hexout(s, len, f)
-const char *s;
-size_t len;
-FILE *f;
-{
-       size_t i;
-
-       fprintf(f, "0x");
-       for (i = 0; i < len; i++)
-               fprintf(f, "%02x", (unsigned char)s[i]);
-}
-
-struct artab {
-       int base;
-#          define IGNORESPACE_BIAS 1000
-       char *ascii;            /* NULL for end */
-       char *data;             /* NULL for error expected */
-} atodatatab[] = {
-       { 0, "",                        NULL, },
-       { 0, "0",                       NULL, },
-       { 0, "0x",              NULL, },
-       { 0, "0xa",             NULL, },
-       { 0, "0xab",            "\xab", },
-       { 0, "0xabc",           NULL, },
-       { 0, "0xabcd",          "\xab\xcd", },
-       { 0, "0x0123456789",    "\x01\x23\x45\x67\x89", },
-       { 0, "0x01x",           NULL, },
-       { 0, "0xabcdef",                "\xab\xcd\xef", },
-       { 0, "0xABCDEF",                "\xab\xcd\xef", },
-       { 0, "0XaBc0eEd81f",    "\xab\xc0\xee\xd8\x1f", },
-       { 0, "0XaBc0_eEd8",     "\xab\xc0\xee\xd8", },
-       { 0, "0XaBc0_",         NULL, },
-       { 0, "0X_aBc0",         NULL, },
-       { 0, "0Xa_Bc0",         NULL, },
-       { 16, "aBc0eEd8",       "\xab\xc0\xee\xd8", },
-       { 0, "0s",              NULL, },
-       { 0, "0sA",             NULL, },
-       { 0, "0sBA",            NULL, },
-       { 0, "0sCBA",           NULL, },
-       { 0, "0sDCBA",          "\x0c\x20\x40", },
-       { 0, "0SDCBA",          "\x0c\x20\x40", },
-       { 0, "0sDA==",          "\x0c", },
-       { 0, "0sDC==",          NULL, },
-       { 0, "0sDCA=",          "\x0c\x20", },
-       { 0, "0sDCB=",          NULL, },
-       { 0, "0sDCAZ",          "\x0c\x20\x19", },
-       { 0, "0sDCAa",          "\x0c\x20\x1a", },
-       { 0, "0sDCAz",          "\x0c\x20\x33", },
-       { 0, "0sDCA0",          "\x0c\x20\x34", },
-       { 0, "0sDCA9",          "\x0c\x20\x3d", },
-       { 0, "0sDCA+",          "\x0c\x20\x3e", },
-       { 0, "0sDCA/",          "\x0c\x20\x3f", },
-       { 0, "0sAbraCadabra+",  "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
-       { IGNORESPACE_BIAS + 0, "0s AbraCadabra+",      "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
-       { IGNORESPACE_BIAS + 0, "0sA braCadabra+",      "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
-       { IGNORESPACE_BIAS + 0, "0sAb raCadabra+",      "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
-       { IGNORESPACE_BIAS + 0, "0sAbr aCadabra+",      "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
-       { IGNORESPACE_BIAS + 0, "0sAbra Cadabra+",      "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
-       { IGNORESPACE_BIAS + 0, "0sAbraC adabra+",      "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
-       { IGNORESPACE_BIAS + 0, "0sAbraCa dabra+",      "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
-       { IGNORESPACE_BIAS + 0, "0sAbraCad abra+",      "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
-       { IGNORESPACE_BIAS + 0, "0sAbraCada bra+",      "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
-       { IGNORESPACE_BIAS + 0, "0sAbraCadab ra+",      "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
-       { IGNORESPACE_BIAS + 0, "0sAbraCadabr a+",      "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
-       { IGNORESPACE_BIAS + 0, "0sAbraCadabra +",      "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
-       { IGNORESPACE_BIAS + 0, "0sAbraCadabra+ ",      "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
-       { 0, "0t",              NULL, },
-       { 0, "0tabc_xyz",               "abc_xyz", },
-       { 256, "abc_xyz",               "abc_xyz", },
-       { 0, NULL,              NULL, },
-};
-
-struct drtab {
-       char *data;     /* input; NULL for end */
-       char format;
-       int buflen;     /* -1 means big buffer */
-       int outlen;     /* -1 means strlen(ascii)+1 */
-       char *ascii;    /* NULL for error expected */
-} datatoatab[] = {
-       { "",                   'x',    -1,     -1,     NULL, },
-       { "",                   'X',    -1,     -1,     NULL, },
-       { "",                   'n',    -1,     -1,     NULL, },
-       { "0",                  'x',    -1,     -1,     "0x30", },
-       { "0",                  'x',    0,      5,      "---", },
-       { "0",                  'x',    1,      5,      "", },
-       { "0",                  'x',    2,      5,      "0", },
-       { "0",                  'x',    3,      5,      "0x", },
-       { "0",                  'x',    4,      5,      "0x3", },
-       { "0",                  'x',    5,      5,      "0x30", },
-       { "0",                  'x',    6,      5,      "0x30", },
-       { "\xab\xcd",           'x',    -1,     -1,     "0xabcd", },
-       { "\x01\x23\x45\x67\x89",       'x',    -1,     -1,     "0x0123456789", },
-       { "\xab\xcd\xef",               'x',    -1,     -1,     "0xabcdef", },
-       { "\xab\xc0\xee\xd8\x1f",       'x',    -1,     -1,     "0xabc0eed81f", },
-       { "\x01\x02",           'h',    -1,     -1,     "0x0102", },
-       { "\x01\x02\x03\x04\x05\x06",   'h',    -1, -1, "0x01020304_0506", },
-       { "\xab\xc0\xee\xd8\x1f",       16,     -1,     -1,     "abc0eed81f", },
-       { "\x0c\x20\x40",               's',    -1,     -1,     "0sDCBA", },
-       { "\x0c\x20\x40",               's',    0,      7,      "---", },
-       { "\x0c\x20\x40",               's',    1,      7,      "", },
-       { "\x0c\x20\x40",               's',    2,      7,      "0", },
-       { "\x0c\x20\x40",               's',    3,      7,      "0s", },
-       { "\x0c\x20\x40",               's',    4,      7,      "0sD", },
-       { "\x0c\x20\x40",               's',    5,      7,      "0sDC", },
-       { "\x0c\x20\x40",               's',    6,      7,      "0sDCB", },
-       { "\x0c\x20\x40",               's',    7,      7,      "0sDCBA", },
-       { "\x0c\x20\x40",               's',    8,      7,      "0sDCBA", },
-       { "\x0c",                       's',    -1,     -1,     "0sDA==", },
-       { "\x0c\x20",           's',    -1,     -1,     "0sDCA=", },
-       { "\x0c\x20\x19",               's',    -1,     -1,     "0sDCAZ", },
-       { "\x0c\x20\x1a",               's',    -1,     -1,     "0sDCAa", },
-       { "\x0c\x20\x33",               's',    -1,     -1,     "0sDCAz", },
-       { "\x0c\x20\x34",               's',    -1,     -1,     "0sDCA0", },
-       { "\x0c\x20\x3d",               's',    -1,     -1,     "0sDCA9", },
-       { "\x0c\x20\x3e",               's',    -1,     -1,     "0sDCA+", },
-       { "\x0c\x20\x3f",               's',    -1,     -1,     "0sDCA/", },
-       { "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", 's', -1, -1, "0sAbraCadabra+", },
-       { "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", 64, -1, -1, "AbraCadabra+", },
-       { NULL,                 'x',    -1,     -1,     NULL, },
-};
-
-/*
- - regress - regression-test ttodata() and datatot()
- */
-static void
-check(r, buf, n, oops, status)
-struct artab *r;
-char *buf;
-size_t n;
-err_t oops;
-int *status;
-{
-       if (oops != NULL && r->data == NULL)
-               {}                      /* error expected */
-       else if (oops != NULL) {
-               printf("`%s' gave error `%s', expecting %d `", r->ascii,
-                                               oops, strlen(r->data));
-               hexout(r->data, strlen(r->data), stdout);
-               printf("'\n");
-               *status = 1;
-       } else if (r->data == NULL) {
-               printf("`%s' gave %d `", r->ascii, n);
-               hexout(buf, n, stdout);
-               printf("', expecting error\n");
-               *status = 1;
-       } else if (n != strlen(r->data)) {
-               printf("length wrong in `%s': got %d `", r->ascii, n);
-               hexout(buf, n, stdout);
-               printf("', expecting %d `", strlen(r->data));
-               hexout(r->data, strlen(r->data), stdout);
-               printf("'\n");
-               *status = 1;
-       } else if (memcmp(buf, r->data, n) != 0) {
-               printf("`%s' gave %d `", r->ascii, n);
-               hexout(buf, n, stdout);
-               printf("', expecting %d `", strlen(r->data));
-               hexout(r->data, strlen(r->data), stdout);
-               printf("'\n");
-               *status = 1;
-       }
-       fflush(stdout);
-}
-
-static void                    /* should not return at all, in fact */
-regress(pgm)
-char *pgm;
-{
-       struct artab *r;
-       struct drtab *dr;
-       char buf[100];
-       size_t n;
-       int status = 0;
-
-       for (r = atodatatab; r->ascii != NULL; r++) {
-               int base = r->base;
-               int xbase = 0;
-
-               if ((base == 0 || base == IGNORESPACE_BIAS + 0) && r->ascii[0] == '0') {
-                       switch (r->ascii[1]) {
-                       case 'x':
-                       case 'X':
-                               xbase = 16;
-                               break;
-                       case 's':
-                       case 'S':
-                               xbase = 64;
-                               break;
-                       case 't':
-                       case 'T':
-                               xbase = 256;
-                               break;
-                       }
-               }
-
-               if (base >= IGNORESPACE_BIAS) {
-                       base = base - IGNORESPACE_BIAS;
-                       check(r, buf, n, ttodatav(r->ascii, 0, base, buf, sizeof(buf), &n, NULL, 0, TTODATAV_IGNORESPACE), &status);
-                       if (xbase != 0)
-                               check(r, buf, n, ttodatav(r->ascii+2, 0, xbase, buf, sizeof(buf), &n, NULL, 0, TTODATAV_IGNORESPACE), &status);
-               } else {
-                       check(r, buf, n, ttodata(r->ascii, 0, base, buf, sizeof(buf), &n), &status);
-                       if (base == 64 || xbase == 64)
-                               check(r, buf, n, ttodatav(r->ascii, 0, base, buf, sizeof(buf), &n, NULL, 0, TTODATAV_IGNORESPACE), &status);
-                       if (xbase != 0) {
-                               check(r, buf, n, ttodata(r->ascii+2, 0, xbase, buf, sizeof(buf), &n), &status);
-                               if (base == 64 || xbase == 64)
-                                       check(r, buf, n, ttodatav(r->ascii+2, 0, xbase, buf, sizeof(buf), &n, NULL, 0, TTODATAV_IGNORESPACE), &status);
-                       }
-               }
-       }
-       for (dr = datatoatab; dr->data != NULL; dr++) {
-               size_t should;
-
-               strcpy(buf, "---");
-               n = datatot(dr->data, strlen(dr->data), dr->format, buf,
-                               (dr->buflen == -1) ? sizeof(buf) : dr->buflen);
-               should = (dr->ascii == NULL) ? 0 : strlen(dr->ascii) + 1;
-               if (dr->outlen != -1)
-                       should = dr->outlen;
-               if (n == 0 && dr->ascii == NULL)
-                       {}                      /* error expected */
-               else if (n == 0) {
-                       printf("`");
-                       hexout(dr->data, strlen(dr->data), stdout);
-                       printf("' %c gave error, expecting %d `%s'\n",
-                               dr->format, should, dr->ascii);
-                       status = 1;
-               } else if (dr->ascii == NULL) {
-                       printf("`");
-                       hexout(dr->data, strlen(dr->data), stdout);
-                       printf("' %c gave %d `%.*s', expecting error\n",
-                               dr->format, n, (int)n, buf);
-                       status = 1;
-               } else if (n != should) {
-                       printf("length wrong in `");
-                       hexout(dr->data, strlen(dr->data), stdout);
-                       printf("': got %d `%s'", n, buf);
-                       printf(", expecting %d `%s'\n", should, dr->ascii);
-                       status = 1;
-               } else if (strcmp(buf, dr->ascii) != 0) {
-                       printf("`");
-                       hexout(dr->data, strlen(dr->data), stdout);
-                       printf("' gave %d `%s'", n, buf);
-                       printf(", expecting %d `%s'\n", should, dr->ascii);
-                       status = 1;
-               }
-               fflush(stdout);
-       }
-       exit(status);
-}
-
-#endif /* TTODATA_MAIN */
diff --git a/src/libfreeswan/ttoprotoport.c b/src/libfreeswan/ttoprotoport.c
deleted file mode 100644 (file)
index e75b206..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * conversion from protocol/port string to protocol and port
- * Copyright (C) 2002 Mario Strasser <mast@gmx.net>,
- *                    Zuercher Hochschule Winterthur,
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include "internal.h"
-#include "freeswan.h"
-
-/*
- * ttoprotoport - converts from protocol/port string to protocol and port
- */
-err_t
-ttoprotoport(src, src_len, proto, port, has_port_wildcard)
-char *src;             /* input string */
-size_t src_len;                /* length of input string, use strlen() if 0 */
-u_int8_t *proto;       /* extracted protocol number */
-u_int16_t *port;       /* extracted port number if it exists */
-bool *has_port_wildcard;       /* set if port is %any */
-{
-    char *end, *service_name;
-    char proto_name[16];
-    int proto_len;
-    long int l;
-    struct protoent *protocol;
-    struct servent *service;
-
-    /* get the length of the string */
-    if (!src_len) src_len = strlen(src);
-
-    /* locate delimiter '/' between protocol and port */
-    end = strchr(src, '/');
-    if (end != NULL) {
-      proto_len = end - src;
-      service_name = end + 1;
-    } else {
-      proto_len = src_len;
-      service_name = src + src_len;
-    }
-
-   /* copy protocol name*/
-    memset(proto_name, '\0', sizeof(proto_name));
-    memcpy(proto_name, src, proto_len);
-
-    /* extract protocol by trying to resolve it by name */
-    protocol = getprotobyname(proto_name);
-    if (protocol != NULL) {
-       *proto = protocol->p_proto;
-    }
-    else  /* failed, now try it by number */
-    {
-       l = strtol(proto_name, &end, 0);
-
-       if (*proto_name && *end)
-           return "<protocol> is neither a number nor a valid name";
-
-       if (l < 0 || l > 0xff)
-            return "<protocol> must be between 0 and 255";
-
-       *proto = (u_int8_t)l;
-    }
-
-    /* is there a port wildcard? */
-    *has_port_wildcard = (strcmp(service_name, "%any") == 0);
-
-    if (*has_port_wildcard)
-    {
-       *port = 0;
-       return NULL;
-    }
-
-    /* extract port by trying to resolve it by name */
-    service = getservbyname(service_name, NULL);
-    if (service != NULL) {
-        *port = ntohs(service->s_port);
-    }
-    else /* failed, now try it by number */
-    {
-       l = strtol(service_name, &end, 0);
-
-       if (*service_name && *end)
-           return "<port> is neither a number nor a valid name";
-
-       if (l < 0 || l > 0xffff)
-           return "<port> must be between 0 and 65535";
-
-       *port = (u_int16_t)l;
-    }
-    return NULL;
-}
-
diff --git a/src/libfreeswan/ttosa.3 b/src/libfreeswan/ttosa.3
deleted file mode 100644 (file)
index f9ea36a..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-.TH IPSEC_TTOSA 3 "26 Nov 2001"
-.SH NAME
-ipsec ttosa, satot \- convert IPsec Security Association IDs to and from text
-.br
-ipsec initsaid \- initialize an SA ID
-.SH SYNOPSIS
-.B "#include <freeswan.h>
-.sp
-.B "typedef struct {"
-.ti +1c
-.B "ip_address dst;"
-.ti +1c
-.B "ipsec_spi_t spi;"
-.ti +1c
-.B "int proto;"
-.br
-.B "} ip_said;"
-.sp
-.B "const char *ttosa(const char *src, size_t srclen,"
-.ti +1c
-.B "ip_said *sa);
-.br
-.B "size_t satot(const ip_said *sa, int format,"
-.ti +1c
-.B "char *dst, size_t dstlen);"
-.br
-.B "void initsaid(const ip_address *addr, ipsec_spi_t spi,"
-.ti +1c
-.B "int proto, ip_said *dst);"
-.SH DESCRIPTION
-.I Ttosa
-converts an ASCII Security Association (SA) specifier into an
-.B ip_said
-structure (containing
-a destination-host address
-in network byte order,
-an SPI number in network byte order, and
-a protocol code).
-.I Satot
-does the reverse conversion, back to a text SA specifier.
-.I Initsaid
-initializes an
-.B ip_said
-from separate items of information.
-.PP
-An SA is specified in text with a mail-like syntax, e.g.
-.BR esp.5a7@1.2.3.4 .
-An SA specifier contains
-a protocol prefix (currently
-.BR ah ,
-.BR esp ,
-.BR tun ,
-.BR comp ,
-or
-.BR int ),
-a single character indicating the address family
-.RB ( .
-for IPv4,
-.B :
-for IPv6),
-an unsigned integer SPI number in hexadecimal (with no
-.B 0x
-prefix),
-and an IP address.
-The IP address can be any form accepted by
-.IR ipsec_ttoaddr (3),
-e.g. dotted-decimal IPv4 address,
-colon-hex IPv6 address,
-or DNS name.
-.PP
-As a special case, the SA specifier
-.B %passthrough4
-or
-.B %passthrough6
-signifies the special SA used to indicate that packets should be
-passed through unaltered.
-(At present, these are synonyms for
-.B tun.0@0.0.0.0
-and
-.B tun:0@::
-respectively,
-but that is subject to change without notice.)
-.B %passthrough
-is a historical synonym for
-.BR %passthrough4 . 
-These forms are known to both
-.I ttosa
-and
-.IR satot ,
-so the internal representation is never visible.
-.PP
-Similarly, the SA specifiers
-.BR %pass ,
-.BR %drop ,
-.BR %reject ,
-.BR %hold ,
-.BR %trap ,
-and
-.BR %trapsubnet
-signify special ``magic'' SAs used to indicate that packets should be
-passed, dropped, rejected (dropped with ICMP notification),
-held,
-and trapped (sent up to
-.IR ipsec_pluto (8),
-with either of two forms of
-.B %hold
-automatically installed)
-respectively.
-These forms too are known to both routines,
-so the internal representation of the magic SAs should never be visible.
-.PP
-The
-.B <freeswan.h>
-header file supplies the
-.B ip_said
-structure, as well as a data type
-.B ipsec_spi_t
-which is an unsigned 32-bit integer.
-(There is no consistency between kernel and user on what such a type
-is called, hence the header hides the differences.)
-.PP
-The protocol code uses the same numbers that IP does.
-For user convenience, given the difficulty in acquiring the exact set of
-protocol names used by the kernel,
-.B <freeswan.h>
-defines the names
-.BR SA_ESP ,
-.BR SA_AH ,
-.BR SA_IPIP ,
-and
-.BR SA_COMP
-to have the same values as the kernel names
-.BR IPPROTO_ESP ,
-.BR IPPROTO_AH ,
-.BR IPPROTO_IPIP ,
-and
-.BR IPPROTO_COMP .
-.PP
-.B <freeswan.h>
-also defines
-.BR SA_INT
-to have the value
-.BR 61
-(reserved by IANA for ``any host internal protocol'')
-and
-.BR SPI_PASS ,
-.BR SPI_DROP ,
-.BR SPI_REJECT ,
-.BR SPI_HOLD ,
-and
-.B SPI_TRAP
-to have the values 256-260 (in \fIhost\fR byte order) respectively.
-These are used in constructing the magic SAs
-(which always have address
-.BR 0.0.0.0 ).
-.PP
-If
-.I satot
-encounters an unknown protocol code, e.g. 77,
-it yields output using a prefix
-showing the code numerically, e.g. ``unk77''.
-This form is
-.I not
-recognized by
-.IR ttosa .
-.PP
-The
-.I srclen
-parameter of
-.I ttosa
-specifies the length of the string pointed to by
-.IR src ;
-it is an error for there to be anything else
-(e.g., a terminating NUL) within that length.
-As a convenience for cases where an entire NUL-terminated string is
-to be converted,
-a
-.I srclen
-value of
-.B 0
-is taken to mean
-.BR strlen(src) .
-.PP
-The
-.I dstlen
-parameter of
-.I satot
-specifies the size of the
-.I dst
-parameter;
-under no circumstances are more than
-.I dstlen
-bytes written to
-.IR dst .
-A result which will not fit is truncated.
-.I Dstlen
-can be zero, in which case
-.I dst
-need not be valid and no result is written,
-but the return value is unaffected;
-in all other cases, the (possibly truncated) result is NUL-terminated.
-The
-.B <freeswan.h>
-header file defines a constant,
-.BR SATOT_BUF ,
-which is the size of a buffer just large enough for worst-case results.
-.PP
-The
-.I format
-parameter of
-.I satot
-specifies what format is to be used for the conversion.
-The value
-.B 0
-(not the ASCII character
-.BR '0' ,
-but a zero value)
-specifies a reasonable default
-(currently
-lowercase protocol prefix, lowercase hexadecimal SPI,
-dotted-decimal or colon-hex address).
-The value
-.B 'f'
-is similar except that the SPI is padded with
-.BR 0 s
-to a fixed 32-bit width, to ease aligning displayed tables.
-.PP
-.I Ttosa
-returns
-.B NULL
-for success and
-a pointer to a string-literal error message for failure;
-see DIAGNOSTICS.
-.I Satot
-returns
-.B 0
-for a failure, and otherwise
-always returns the size of buffer which would 
-be needed to
-accommodate the full conversion result, including terminating NUL;
-it is the caller's responsibility to check this against the size of
-the provided buffer to determine whether truncation has occurred.
-.PP
-There is also, temporarily, support for some obsolete
-forms of SA specifier which lack the address-family indicator.
-.SH SEE ALSO
-ipsec_ttoul(3), ipsec_ttoaddr(3), ipsec_samesaid(3), inet(3)
-.SH DIAGNOSTICS
-Fatal errors in
-.I ttosa
-are:
-empty input;
-input too small to be a legal SA specifier;
-no
-.B @
-in input;
-unknown protocol prefix;
-conversion error in
-.I ttoul
-or
-.IR ttoaddr .
-.PP
-Fatal errors in
-.I satot
-are:
-unknown format.
-.SH HISTORY
-Written for the FreeS/WAN project by Henry Spencer.
-.SH BUGS
-The restriction of text-to-binary error reports to literal strings
-(so that callers don't need to worry about freeing them or copying them)
-does limit the precision of error reporting.
-.PP
-The text-to-binary error-reporting convention lends itself
-to slightly obscure code,
-because many readers will not think of NULL as signifying success.
-A good way to make it clearer is to write something like:
-.PP
-.RS
-.nf
-.B "const char *error;"
-.sp
-.B "error = ttosa( /* ... */ );"
-.B "if (error != NULL) {"
-.B "        /* something went wrong */"
-.fi
-.RE
diff --git a/src/libfreeswan/ttosa.c b/src/libfreeswan/ttosa.c
deleted file mode 100644 (file)
index 9873231..0000000
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * convert from text form of SA ID to binary
- * Copyright (C) 2000, 2001  Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
- * License for more details.
- */
-#include <sys/socket.h>
-
-#include "internal.h"
-#include "freeswan.h"
-
-static struct satype {
-       char *prefix;
-       size_t prelen;          /* strlen(prefix) */
-       int proto;
-} satypes[] = {
-       { "ah",         2,      SA_AH   },
-       { "esp",        3,      SA_ESP  },
-       { "tun",        3,      SA_IPIP },
-       { "comp",       4,      SA_COMP },
-       { "int",        3,      SA_INT  },
-       { NULL,         0,      0,      }
-};
-
-static struct magic {
-       char *name;
-       char *really;
-} magic[] = {
-       { PASSTHROUGHNAME,      PASSTHROUGH4IS          },
-       { PASSTHROUGH4NAME,     PASSTHROUGH4IS          },
-       { PASSTHROUGH6NAME,     PASSTHROUGH6IS          },
-       { "%pass",              "int256@0.0.0.0"        },
-       { "%drop",              "int257@0.0.0.0"        },
-       { "%reject",            "int258@0.0.0.0"        },
-       { "%hold",              "int259@0.0.0.0"        },
-       { "%trap",              "int260@0.0.0.0"        },
-       { "%trapsubnet",        "int261@0.0.0.0"        },
-       { NULL,                 NULL                    }
-};
-
-/*
- - ttosa - convert text "ah507@10.0.0.1" to SA identifier
- */
-err_t                          /* NULL for success, else string literal */
-ttosa(src, srclen, sa)
-const char *src;
-size_t srclen;                 /* 0 means "apply strlen" */
-ip_said *sa;
-{
-       const char *at;
-       const char *addr;
-       size_t alen;
-       const char *spi = NULL;
-       struct satype *sat;
-       unsigned long ul;
-       const char *oops;
-       struct magic *mp;
-       size_t nlen;
-#      define  MINLEN  5       /* ah0@0 is as short as it can get */
-       int af;
-       int base;
-
-       if (srclen == 0)
-               srclen = strlen(src);
-       if (srclen == 0)
-               return "empty string";
-       if (srclen < MINLEN)
-               return "string too short to be SA identifier";
-       if (*src == '%') {
-               for (mp = magic; mp->name != NULL; mp++) {
-                       nlen = strlen(mp->name);
-                       if (srclen == nlen && memcmp(src, mp->name, nlen) == 0)
-                               break;
-               }
-               if (mp->name == NULL)
-                       return "unknown % keyword";
-               src = mp->really;
-               srclen = strlen(src);
-       }
-
-       at = memchr(src, '@', srclen);
-       if (at == NULL)
-               return "no @ in SA specifier";
-
-       for (sat = satypes; sat->prefix != NULL; sat++)
-               if (sat->prelen < srclen &&
-                               strncmp(src, sat->prefix, sat->prelen) == 0) {
-                       sa->proto = sat->proto;
-                       spi = src + sat->prelen;
-                       break;                  /* NOTE BREAK OUT */
-               }
-       if (sat->prefix == NULL)
-               return "SA specifier lacks valid protocol prefix";
-
-       if (spi >= at)
-               return "no SPI in SA specifier";
-       switch (*spi) {
-       case '.':
-               af = AF_INET;
-               spi++;
-               base = 16;
-               break;
-       case ':':
-               af = AF_INET6;
-               spi++;
-               base = 16;
-               break;
-       default:
-               af = AF_UNSPEC;         /* not known yet */
-               base = 0;
-               break;
-       }
-       if (spi >= at)
-               return "no SPI found in SA specifier";
-       oops = ttoul(spi, at - spi, base, &ul);
-       if (oops != NULL)
-               return oops;
-       sa->spi = htonl(ul);
-
-       addr = at + 1;
-       alen = srclen - (addr - src);
-       if (af == AF_UNSPEC)
-               af = (memchr(addr, ':', alen) != NULL) ? AF_INET6 : AF_INET;
-       oops = ttoaddr(addr, alen, af, &sa->dst);
-       if (oops != NULL)
-               return oops;
-
-       return NULL;
-}
-
-
-
-#ifdef TTOSA_MAIN
-
-#include <stdio.h>
-
-void regress(void);
-
-int
-main(int argc, char *argv[])
-{
-       ip_said sa;
-       char buf[100];
-       char buf2[100];
-       const char *oops;
-       size_t n;
-
-       if (argc < 2) {
-               fprintf(stderr, "Usage: %s {ahnnn@aaa|-r}\n", argv[0]);
-               exit(2);
-       }
-
-       if (strcmp(argv[1], "-r") == 0) {
-               regress();
-               fprintf(stderr, "regress() returned?!?\n");
-               exit(1);
-       }
-
-       oops = ttosa(argv[1], 0, &sa);
-       if (oops != NULL) {
-               fprintf(stderr, "%s: conversion failed: %s\n", argv[0], oops);
-               exit(1);
-       }
-       n = satot(&sa, 0, buf, sizeof(buf));
-       if (n > sizeof(buf)) {
-               fprintf(stderr, "%s: reverse conv of `%d'", argv[0], sa.proto);
-               fprintf(stderr, "%lx@", (long unsigned int)sa.spi);
-               (void) addrtot(&sa.dst, 0, buf2, sizeof(buf2));
-               fprintf(stderr, "%s", buf2);
-               fprintf(stderr, " failed: need %ld bytes, have only %ld\n",
-                                               (long)n, (long)sizeof(buf));
-               exit(1);
-       }
-       printf("%s\n", buf);
-
-       exit(0);
-}
-
-struct rtab {
-       int format;
-#              define  FUDGE   0x1000
-       char *input;
-       char *output;                   /* NULL means error expected */
-} rtab[] = {
-       {0, "esp257@1.2.3.0",           "esp.101@1.2.3.0"},
-       {0, "ah0x20@1.2.3.4",           "ah.20@1.2.3.4"},
-       {0, "tun20@1.2.3.4",            "tun.14@1.2.3.4"},
-       {0, "comp20@1.2.3.4",           "comp.14@1.2.3.4"},
-       {0, "esp257@::1",               "esp:101@::1"},
-       {0, "esp257@0bc:12de::1",       "esp:101@bc:12de::1"},
-       {0, "esp78@1049:1::8007:2040",  "esp:4e@1049:1::8007:2040"},
-       {0, "esp0x78@1049:1::8007:2040",        "esp:78@1049:1::8007:2040"},
-       {0, "ah78@1049:1::8007:2040",   "ah:4e@1049:1::8007:2040"},
-       {0, "ah0x78@1049:1::8007:2040", "ah:78@1049:1::8007:2040"},
-       {0, "tun78@1049:1::8007:2040",  "tun:4e@1049:1::8007:2040"},
-       {0, "tun0x78@1049:1::8007:2040",        "tun:78@1049:1::8007:2040"},
-       {0, "duk99@3ffe:370:400:ff::9001:3001", NULL},
-       {0, "esp78x@1049:1::8007:2040", NULL},
-       {0, "esp0x78@1049:1:0xfff::8007:2040",  NULL},
-       {0, "es78@1049:1::8007:2040",   NULL},
-       {0, "",                         NULL},
-       {0, "_",                                NULL},
-       {0, "ah2.2",                    NULL},
-       {0, "goo2@1.2.3.4",             NULL},
-       {0, "esp9@1.2.3.4",             "esp.9@1.2.3.4"},
-       {'f', "esp0xa9@1.2.3.4",                "esp.000000a9@1.2.3.4"},
-       {0, "espp9@1.2.3.4",            NULL},
-       {0, "es9@1.2.3.4",              NULL},
-       {0, "ah@1.2.3.4",               NULL},
-       {0, "esp7x7@1.2.3.4",           NULL},
-       {0, "esp77@1.0x2.3.4",          NULL},
-       {0, PASSTHROUGHNAME,            PASSTHROUGH4NAME},
-       {0, PASSTHROUGH6NAME,           PASSTHROUGH6NAME},
-       {0, "%pass",                    "%pass"},
-       {0, "int256@0.0.0.0",           "%pass"},
-       {0, "%drop",                    "%drop"},
-       {0, "int257@0.0.0.0",           "%drop"},
-       {0, "%reject",                  "%reject"},
-       {0, "int258@0.0.0.0",           "%reject"},
-       {0, "%hold",                    "%hold"},
-       {0, "int259@0.0.0.0",           "%hold"},
-       {0, "%trap",                    "%trap"},
-       {0, "int260@0.0.0.0",           "%trap"},
-       {0, "%trapsubnet",              "%trapsubnet"},
-       {0, "int261@0.0.0.0",           "%trapsubnet"},
-       {0, "int262@0.0.0.0",           "int.106@0.0.0.0"},
-       {FUDGE, "esp9@1.2.3.4",         "unk77.9@1.2.3.4"},
-       {0, NULL,                       NULL}
-};
-
-void
-regress(void)
-{
-       struct rtab *r;
-       int status = 0;
-       ip_said sa;
-       char in[100];
-       char buf[100];
-       const char *oops;
-       size_t n;
-
-       for (r = rtab; r->input != NULL; r++) {
-               strcpy(in, r->input);
-               oops = ttosa(in, 0, &sa);
-               if (oops != NULL && r->output == NULL)
-                       {}              /* okay, error expected */
-               else if (oops != NULL) {
-                       printf("`%s' ttosa failed: %s\n", r->input, oops);
-                       status = 1;
-               } else if (r->output == NULL) {
-                       printf("`%s' ttosa succeeded unexpectedly\n",
-                                                               r->input);
-                       status = 1;
-               } else {
-                       if (r->format&FUDGE)
-                               sa.proto = 77;
-                       n = satot(&sa, (char)r->format, buf, sizeof(buf));
-                       if (n > sizeof(buf)) {
-                               printf("`%s' satot failed:  need %ld\n",
-                                                       r->input, (long)n);
-                               status = 1;
-                       } else if (strcmp(r->output, buf) != 0) {
-                               printf("`%s' gave `%s', expected `%s'\n",
-                                               r->input, buf, r->output);
-                               status = 1;
-                       }
-               }
-       }
-       exit(status);
-}
-
-#endif /* TTOSA_MAIN */
diff --git a/src/libfreeswan/ttosubnet.c b/src/libfreeswan/ttosubnet.c
deleted file mode 100644 (file)
index a18a3f3..0000000
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * convert from text form of subnet specification to binary
- * Copyright (C) 2000  Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
- * License for more details.
- */
-#include <sys/socket.h>
-
-#include "internal.h"
-#include "freeswan.h"
-
-#ifndef DEFAULTSUBNET
-#define        DEFAULTSUBNET   "%default"
-#endif
-
-/*
- - ttosubnet - convert text "addr/mask" to address and mask
- * Mask can be integer bit count.
- */
-err_t
-ttosubnet(src, srclen, af, dst)
-const char *src;
-size_t srclen;                 /* 0 means "apply strlen" */
-int af;                                /* AF_INET or AF_INET6 */
-ip_subnet *dst;
-{
-       const char *slash;
-       const char *colon;
-       const char *mask;
-       size_t mlen;
-       const char *oops;
-       unsigned long bc;
-       static char def[] = DEFAULTSUBNET;
-#      define  DEFLEN  (sizeof(def) - 1)       /* -1 for NUL */
-       static char defis4[] = "0/0";
-#      define  DEFIS4LEN       (sizeof(defis4) - 1)
-       static char defis6[] = "::/0";
-#      define  DEFIS6LEN       (sizeof(defis6) - 1)
-       ip_address addrtmp;
-       ip_address masktmp;
-       int nbits;
-       int i;
-
-       if (srclen == 0)
-               srclen = strlen(src);
-       if (srclen == 0)
-               return "empty string";
-
-       switch (af) {
-       case AF_INET:
-               nbits = 32;
-               break;
-       case AF_INET6:
-               nbits = 128;
-               break;
-       default:
-               return "unknown address family in ttosubnet";
-               break;
-       }
-
-       if (srclen == DEFLEN && strncmp(src, def, srclen) == 0) {
-               src = (af == AF_INET) ? defis4 : defis6;
-               srclen = (af == AF_INET) ? DEFIS4LEN : DEFIS6LEN;
-       }
-
-       slash = memchr(src, '/', srclen);
-       if (slash == NULL)
-               return "no / in subnet specification";
-       mask = slash + 1;
-       mlen = srclen - (mask - src);
-
-       oops = ttoaddr(src, slash-src, af, &addrtmp);
-       if (oops != NULL)
-               return oops;
-
-       /* extract port */
-       colon = memchr(mask, ':', mlen);
-       if (colon == 0)
-       {
-               setportof(0, &addrtmp);
-       }
-       else
-       {
-               long port;
-
-               oops =  ttoul(colon+1, mlen-(colon-mask+1), 10, &port);
-               if (oops != NULL)
-                       return oops;
-               setportof(htons(port), &addrtmp);
-               mlen = colon - mask;
-       }
-
-       /*extract mask */
-       oops = ttoul(mask, mlen, 10, &bc);
-       if (oops == NULL) {
-               /* ttoul succeeded, it's a bit-count mask */
-               if (bc > nbits)
-                       return "subnet mask bit count too large";
-               i = bc;
-       } else {
-               oops = ttoaddr(mask, mlen, af, &masktmp);
-               if (oops != NULL)
-                       return oops;
-               i = masktocount(&masktmp);
-               if (i < 0)
-                       return "non-contiguous or otherwise erroneous mask";
-       }
-
-       return initsubnet(&addrtmp, i, '0', dst);
-}
-
-
-
-#ifdef TTOSUBNET_MAIN
-
-#include <stdio.h>
-
-void regress(void);
-
-int main(int argc, char *argv[])
-{
-       ip_subnet s;
-       char buf[100];
-       char buf2[100];
-       const char *oops;
-       size_t n;
-       int af;
-       char *p;
-
-       if (argc < 2) {
-               fprintf(stderr, "Usage: %s [-6] addr/mask\n", argv[0]);
-               fprintf(stderr, "   or: %s -r\n", argv[0]);
-               exit(2);
-       }
-
-       if (strcmp(argv[1], "-r") == 0) {
-               regress();
-               fprintf(stderr, "regress() returned?!?\n");
-               exit(1);
-       }
-
-       af = AF_INET;
-       p = argv[1];
-       if (strcmp(argv[1], "-6") == 0) {
-               af = AF_INET6;
-               p = argv[2];
-       } else if (strchr(argv[1], ':') != NULL)
-               af = AF_INET6;
-
-       oops = ttosubnet(p, 0, af, &s);
-       if (oops != NULL) {
-               fprintf(stderr, "%s: conversion failed: %s\n", argv[0], oops);
-               exit(1);
-       }
-       n = subnettot(&s, 0, buf, sizeof(buf));
-       if (n > sizeof(buf)) {
-               fprintf(stderr, "%s: reverse conversion of ", argv[0]);
-               (void) addrtot(&s.addr, 0, buf2, sizeof(buf2));
-               fprintf(stderr, "%s/", buf2);
-               fprintf(stderr, "%d", s.maskbits);
-               fprintf(stderr, " failed: need %ld bytes, have only %ld\n",
-                                               (long)n, (long)sizeof(buf));
-               exit(1);
-       }
-       printf("%s\n", buf);
-
-       exit(0);
-}
-
-struct rtab {
-       int family;
-       char *input;
-       char *output;                   /* NULL means error expected */
-} rtab[] = {
-       {4, "1.2.3.0/255.255.255.0",    "1.2.3.0/24"},
-       {4, "1.2.3.0/24",               "1.2.3.0/24"},
-       {4, "1.2.3.0/24:10",            "1.2.3.0/24:10"},
-       {4, "1.2.3.0/24:-1",            NULL},
-       {4, "1.2.3.0/24:none",          NULL},
-       {4, "1.2.3.0/24:",              NULL},
-       {4, "1.2.3.0/24:0x10",          "1.2.3.0/24:16"},
-       {4, "1.2.3.0/24:0X10",          "1.2.3.0/24:16"},
-       {4, "1.2.3.0/24:010",           "1.2.3.0/24:8"},
-       {4, "1.2.3.1/255.255.255.240",  "1.2.3.0/28"},
-       {4, "1.2.3.1/32",               "1.2.3.1/32"},
-       {4, "1.2.3.1/0",                        "0.0.0.0/0"},
-/*     {4, "1.2.3.1/255.255.127.0",    "1.2.3.0/255.255.127.0"},       */
-       {4, "1.2.3.1/255.255.127.0",    NULL},
-       {4, "128.009.000.032/32",       "128.9.0.32/32"},
-       {4, "128.0x9.0.32/32",          NULL},
-       {4, "0x80090020/32",            "128.9.0.32/32"},
-       {4, "0x800x0020/32",            NULL},
-       {4, "128.9.0.32/0xffFF0000",    "128.9.0.0/16"},
-       {4, "128.9.0.32/0xff0000FF",    NULL},
-       {4, "128.9.0.32/0x0000ffFF",    NULL},
-       {4, "128.9.0.32/0x00ffFF0000",  NULL},
-       {4, "128.9.0.32/0xffFF",        NULL},
-       {4, "128.9.0.32.27/32",         NULL},
-       {4, "128.9.0k32/32",            NULL},
-       {4, "328.9.0.32/32",            NULL},
-       {4, "128.9..32/32",             NULL},
-       {4, "10/8",                     "10.0.0.0/8"},
-       {4, "10.0/8",                   "10.0.0.0/8"},
-       {4, "10.0.0/8",                 "10.0.0.0/8"},
-       {4, "10.0.1/24",                        "10.0.1.0/24"},
-       {4, "_",                                NULL},
-       {4, "_/_",                      NULL},
-       {4, "1.2.3.1",                  NULL},
-       {4, "1.2.3.1/_",                        NULL},
-       {4, "1.2.3.1/24._",             NULL},
-       {4, "1.2.3.1/99",               NULL},
-       {4, "localhost/32",             "127.0.0.1/32"},
-       {4, "%default",                 "0.0.0.0/0"},
-       {6, "3049:1::8007:2040/0",      "::/0"},
-       {6, "3049:1::8007:2040/128",    "3049:1::8007:2040/128"},
-       {6, "3049:1::192.168.0.1/128", NULL},   /*"3049:1::c0a8:1/128",*/
-       {6, "3049:1::8007::2040/128",   NULL},
-       {6, "3049:1::8007:2040/ffff::0",        "3049::/16"},
-       {6, "3049:1::8007:2040/64",     "3049:1::/64"},
-       {6, "3049:1::8007:2040/ffff::", "3049::/16"},
-       {6, "3049:1::8007:2040/0000:ffff::0",   NULL},
-       {6, "3049:1::8007:2040/ff1f::0",        NULL},
-       {6, "3049:1::8007:x:2040/128",  NULL},
-       {6, "3049:1t::8007:2040/128",   NULL},
-       {6, "3049:1::80071:2040/128",   NULL},
-       {6, "::/21",                    "::/21"},
-       {6, "::1/128",                  "::1/128"},
-       {6, "1::/21",                   "1::/21"},
-       {6, "1::2/128",                 "1::2/128"},
-       {6, "1:0:0:0:0:0:0:2/128",      "1::2/128"},
-       {6, "1:0:0:0:3:0:0:2/128",      "1::3:0:0:2/128"},
-       {6, "1:0:0:3:0:0:0:2/128",      "1::3:0:0:0:2/128"},
-       {6, "1:0:3:0:0:0:0:2/128",      "1:0:3::2/128"},
-       {6, "abcd:ef01:2345:6789:0:00a:000:20/128",     "abcd:ef01:2345:6789:0:a:0:20/128"},
-       {6, "3049:1::8007:2040/ffff:ffff:",     NULL},
-       {6, "3049:1::8007:2040/ffff:88::",      NULL},
-       {6, "3049:12::9000:3200/ffff:fff0::",   "3049:10::/28"},
-       {6, "3049:12::9000:3200/28",    "3049:10::/28"},
-       {6, "3049:12::9000:3200/ff00:::",       NULL},
-       {6, "3049:12::9000:3200/ffff:::",       NULL},
-       {6, "3049:12::9000:3200/128_",  NULL},
-       {6, "3049:12::9000:3200/",      NULL},
-       {6, "%default",                 "::/0"},
-        {4, NULL,                      NULL}
-};
-
-void
-regress(void)
-{
-       struct rtab *r;
-       int status = 0;
-       ip_subnet s;
-       char in[100];
-       char buf[100];
-       const char *oops;
-       size_t n;
-       int af;
-
-       for (r = rtab; r->input != NULL; r++) {
-               af = (r->family == 4) ? AF_INET : AF_INET6;
-               strcpy(in, r->input);
-               oops = ttosubnet(in, 0, af, &s);
-               if (oops != NULL && r->output == NULL)
-                       {}              /* okay, error expected */
-               else if (oops != NULL) {
-                       printf("`%s' ttosubnet failed: %s\n", r->input, oops);
-                       status = 1;
-               } else if (r->output == NULL) {
-                       printf("`%s' ttosubnet succeeded unexpectedly\n",
-                                                               r->input);
-                       status = 1;
-               } else {
-                       n = subnettot(&s, 0, buf, sizeof(buf));
-                       if (n > sizeof(buf)) {
-                               printf("`%s' subnettot failed:  need %ld\n",
-                                                       r->input, (long)n);
-                               status = 1;
-                       } else if (strcmp(r->output, buf) != 0) {
-                               printf("`%s' gave `%s', expected `%s'\n",
-                                               r->input, buf, r->output);
-                               status = 1;
-                       }
-               }
-       }
-       exit(status);
-}
-
-#endif /* TTOSUBNET_MAIN */
diff --git a/src/libfreeswan/ttoul.3 b/src/libfreeswan/ttoul.3
deleted file mode 100644 (file)
index ffd9fb3..0000000
+++ /dev/null
@@ -1,191 +0,0 @@
-.TH IPSEC_TTOUL 3 "16 Aug 2000"
-.SH NAME
-ipsec ttoul, ultot \- convert unsigned-long numbers to and from text
-.SH SYNOPSIS
-.B "#include <freeswan.h>
-.sp
-.B "const char *ttoul(const char *src, size_t srclen,"
-.ti +1c
-.B "int base, unsigned long *n);"
-.br
-.B "size_t ultot(unsigned long n, int format, char *dst,"
-.ti +1c
-.B "size_t dstlen);"
-.SH DESCRIPTION
-.I Ttoul
-converts a text-string number into a binary
-.B "unsigned long"
-value.
-.I Ultot
-does the reverse conversion, back to a text version.
-.PP
-Numbers are specified in text as
-decimal (e.g.
-.BR 123 ),
-octal with a leading zero (e.g.
-.BR 012 ,
-which has value 10),
-or hexadecimal with a leading
-.B 0x
-(e.g.
-.BR 0x1f ,
-which has value 31)
-in either upper or lower case.
-.PP
-The
-.I srclen
-parameter of
-.I ttoul
-specifies the length of the string pointed to by
-.IR src ;
-it is an error for there to be anything else
-(e.g., a terminating NUL) within that length.
-As a convenience for cases where an entire NUL-terminated string is
-to be converted,
-a
-.I srclen
-value of
-.B 0
-is taken to mean
-.BR strlen(src) .
-.PP
-The
-.I base
-parameter of
-.I ttoul
-can be
-.BR 8 ,
-.BR 10 ,
-or
-.BR 16 ,
-in which case the number supplied is assumed to be of that form
-(and in the case of
-.BR 16 ,
-to lack any
-.B 0x
-prefix).
-It can also be
-.BR 0 ,
-in which case the number is examined for a leading zero
-or a leading
-.B 0x
-to determine its base.
-.PP
-The
-.I dstlen
-parameter of
-.I ultot
-specifies the size of the
-.I dst
-parameter;
-under no circumstances are more than
-.I dstlen
-bytes written to
-.IR dst .
-A result which will not fit is truncated.
-.I Dstlen
-can be zero, in which case
-.I dst
-need not be valid and no result is written,
-but the return value is unaffected;
-in all other cases, the (possibly truncated) result is NUL-terminated.
-The
-.I freeswan.h
-header file defines a constant,
-.BR ULTOT_BUF ,
-which is the size of a buffer just large enough for worst-case results.
-.PP
-The
-.I format
-parameter of
-.I ultot
-must be one of:
-.RS
-.IP \fB'o'\fR 4
-octal conversion with leading
-.B 0
-.IP \fB\ 8\fR
-octal conversion with no leading
-.B 0
-.IP \fB'd'\fR
-decimal conversion
-.IP \fB10\fR
-same as
-.B d
-.IP \fB'x'\fR
-hexadecimal conversion, including leading
-.B 0x
-.IP \fB16\fR
-hexadecimal conversion with no leading
-.B 0x
-.IP \fB17\fR
-like
-.B 16
-except padded on left with
-.BR 0 s
-to eight digits (full width of a 32-bit number)
-.RE
-.PP
-.I Ttoul
-returns NULL for success and
-a pointer to a string-literal error message for failure;
-see DIAGNOSTICS.
-.I Ultot
-returns
-.B 0
-for a failure, and otherwise
-returns the size of buffer which would 
-be needed to
-accommodate the full conversion result, including terminating NUL
-(it is the caller's responsibility to check this against the size of
-the provided buffer to determine whether truncation has occurred).
-.SH SEE ALSO
-atol(3), strtoul(3)
-.SH DIAGNOSTICS
-Fatal errors in
-.I ttoul
-are:
-empty input;
-unknown
-.IR base ;
-non-digit character found;
-number too large for an
-.BR "unsigned long" .
-.PP
-Fatal errors in
-.I ultot
-are:
-unknown
-.IR format .
-.SH HISTORY
-Written for the FreeS/WAN project by Henry Spencer.
-.SH BUGS
-Conversion of
-.B 0
-with format
-.B o
-yields
-.BR 00 .
-.PP
-.I Ultot
-format
-.B 17
-is a bit of a kludge.
-.PP
-The restriction of error reports to literal strings
-(so that callers don't need to worry about freeing them or copying them)
-does limit the precision of error reporting.
-.PP
-The error-reporting convention lends itself to slightly obscure code,
-because many readers will not think of NULL as signifying success.
-A good way to make it clearer is to write something like:
-.PP
-.RS
-.nf
-.B "const char *error;"
-.sp
-.B "error = ttoul( /* ... */ );"
-.B "if (error != NULL) {"
-.B "        /* something went wrong */"
-.fi
-.RE
diff --git a/src/libfreeswan/ttoul.c b/src/libfreeswan/ttoul.c
deleted file mode 100644 (file)
index 7524789..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * convert from text form of unsigned long to binary
- * Copyright (C) 2000  Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
- * License for more details.
- */
-#include "internal.h"
-#include "freeswan.h"
-
-/*
- - ttoul - convert text substring to unsigned long number
- */
-const char *                   /* NULL for success, else string literal */
-ttoul(src, srclen, base, resultp)
-const char *src;
-size_t srclen;                 /* 0 means strlen(src) */
-int base;                      /* 0 means figure it out */
-unsigned long *resultp;
-{
-       const char *stop;
-       static char hex[] = "0123456789abcdef";
-       static char uchex[] = "0123456789ABCDEF";
-       int d;
-       char c;
-       char *p;
-       unsigned long r;
-       unsigned long rlimit;
-       int dlimit;
-
-       if (srclen == 0)
-               srclen = strlen(src);
-       if (srclen == 0)
-               return "empty string";
-
-       if (base == 0) {
-               if (srclen > 2 && *src == '0' &&
-                                       (*(src+1) == 'x' || *(src+1) == 'X'))
-                       return ttoul(src+2, srclen-2, 16, resultp);
-               if (srclen > 1 && *src == '0')
-                       return ttoul(src+1, srclen-1, 8, resultp);
-               return ttoul(src, srclen, 10, resultp);
-       }
-       if (base != 8 && base != 10 && base != 16)
-               return "unsupported number base";
-
-       r = 0;
-       stop = src + srclen;
-       if (base == 16) {
-               while (src < stop) {
-                       c = *src++;
-                       p = strchr(hex, c);
-                       if (p != NULL)
-                               d = p - hex;
-                       else {
-                               p = strchr(uchex, c);
-                               if (p == NULL)
-                                       return "non-hex digit in hex number";
-                               d = p - uchex;
-                       }
-                       r = (r << 4) | d;
-               }
-               /* defer length check to catch invalid digits first */
-               if (srclen > sizeof(unsigned long) * 2)
-                       return "hex number too long";
-       } else {
-               rlimit = ULONG_MAX / base;
-               dlimit = (int)(ULONG_MAX - rlimit*base);
-               while (src < stop) {
-                       c = *src++;
-                       d = c - '0';
-                       if (d < 0 || d >= base)
-                               return "non-digit in number";
-                       if (r > rlimit || (r == rlimit && d > dlimit))
-                               return "unsigned-long overflow";
-                       r = r*base + d;
-               }
-       }
-
-       *resultp = r;
-       return NULL;
-}
diff --git a/src/libfreeswan/ultoa.c b/src/libfreeswan/ultoa.c
deleted file mode 100644 (file)
index 16ddd2c..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * convert unsigned long to ASCII
- * Copyright (C) 1998, 1999  Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
- * License for more details.
- */
-#include "internal.h"
-#include "freeswan.h"
-
-/*
- - ultoa - convert unsigned long to decimal ASCII
- */
-size_t                         /* length required for full conversion */
-ultoa(n, base, dst, dstlen)
-unsigned long n;
-int base;
-char *dst;                     /* need not be valid if dstlen is 0 */
-size_t dstlen;
-{
-       char buf[3*sizeof(unsigned long) + 1];
-       char *bufend = buf + sizeof(buf);
-       size_t len;
-       char *p;
-       static char hex[] = "0123456789abcdef";
-
-       p = bufend;
-       *--p = '\0';
-       if (base == 10) {
-               do {
-                       *--p = n%10 + '0';
-                       n /= 10;
-               } while (n != 0);
-       } else if (base == 16) {
-               do {
-                       *--p = hex[n&0xf];
-                       n >>= 4;
-               } while (n != 0);
-               *--p = 'x';
-               *--p = '0';
-       } else if (base == 8) {
-               do {
-                       *--p = (n&07) + '0';
-                       n >>= 3;
-               } while (n != 0);
-               *--p = '0';
-       } else
-               *--p = '?';
-
-       len = bufend - p;
-
-       if (dstlen > 0) {
-               if (len > dstlen)
-                       *(p + dstlen - 1) = '\0';
-               strcpy(dst, p);
-       }
-       return len;
-}
diff --git a/src/libfreeswan/ultot.c b/src/libfreeswan/ultot.c
deleted file mode 100644 (file)
index 6685f8f..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * convert unsigned long to text
- * Copyright (C) 2000  Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
- * License for more details.
- */
-#include "internal.h"
-#include "freeswan.h"
-
-/*
- - ultot - convert unsigned long to text
- */
-size_t                         /* length required for full conversion */
-ultot(n, base, dst, dstlen)
-unsigned long n;
-int base;
-char *dst;                     /* need not be valid if dstlen is 0 */
-size_t dstlen;
-{
-       char buf[3*sizeof(unsigned long) + 1];
-       char *bufend = buf + sizeof(buf);
-       size_t len;
-       char *p;
-       static char hex[] = "0123456789abcdef";
-#      define  HEX32   (32/4)
-
-       p = bufend;
-       *--p = '\0';
-       switch (base) {
-       case 10:
-       case 'd':
-               do {
-                       *--p = n%10 + '0';
-                       n /= 10;
-               } while (n != 0);
-               break;
-       case 16:
-       case 17:
-       case 'x':
-               do {
-                       *--p = hex[n&0xf];
-                       n >>= 4;
-               } while (n != 0);
-               if (base == 17)
-                       while (bufend - p < HEX32 + 1)
-                               *--p = '0';
-               if (base == 'x') {
-                       *--p = 'x';
-                       *--p = '0';
-               }
-               break;
-       case 8:
-       case 'o':
-               do {
-                       *--p = (n&07) + '0';
-                       n >>= 3;
-               } while (n != 0);
-               if (base == 'o')
-                       *--p = '0';
-               break;
-       default:
-               return 0;
-               break;
-       }
-
-       len = bufend - p;
-       if (dstlen > 0) {
-               if (len > dstlen)
-                       *(p + dstlen - 1) = '\0';
-               strcpy(dst, p);
-       }
-       return len;
-}
diff --git a/src/pluto/.gitignore b/src/pluto/.gitignore
deleted file mode 100644 (file)
index 8aa8745..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-pluto
-_pluto_adns
diff --git a/src/pluto/Android.mk b/src/pluto/Android.mk
deleted file mode 100644 (file)
index 618f79c..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-# copy-n-paste from Makefile.am
-LOCAL_SRC_FILES := \
-ac.c ac.h \
-alg_info.c alg_info.h \
-ca.c ca.h \
-certs.c certs.h \
-connections.c connections.h \
-constants.c constants.h \
-cookie.c cookie.h \
-crl.c crl.h \
-crypto.c crypto.h \
-db_ops.c db_ops.h \
-defs.c defs.h \
-demux.c demux.h \
-event_queue.c event_queue.h \
-fetch.c fetch.h \
-foodgroups.c foodgroups.h \
-ike_alg.c ike_alg.h \
-ipsec_doi.c ipsec_doi.h \
-kameipsec.h \
-kernel.c kernel.h \
-kernel_alg.c kernel_alg.h \
-kernel_pfkey.c kernel_pfkey.h \
-keys.c keys.h \
-lex.c lex.h \
-log.c log.h \
-myid.c myid.h \
-modecfg.c modecfg.h \
-nat_traversal.c nat_traversal.h \
-ocsp.c ocsp.h \
-packet.c packet.h \
-pkcs7.c pkcs7.h \
-plugin_list.c plugin_list.h \
-pluto.c pluto.h \
-plutomain.c \
-rcv_whack.c rcv_whack.h \
-server.c server.h \
-smartcard.c smartcard.h \
-spdb.c spdb.h \
-state.c state.h \
-timer.c timer.h \
-vendor.c vendor.h \
-virtual.c virtual.h \
-whack_attribute.c whack_attribute.h \
-xauth/xauth_manager.c xauth/xauth_manager.h \
-xauth/xauth_provider.h xauth/xauth_verifier.h \
-x509.c x509.h \
-builder.c builder.h \
-rsaref/pkcs11t.h rsaref/pkcs11.h rsaref/unix.h rsaref/pkcs11f.h
-
-LOCAL_SRC_FILES += $(call add_plugin, xauth)
-
-# build pluto ------------------------------------------------------------------
-
-LOCAL_C_INCLUDES += \
-       $(libvstr_PATH) \
-       $(strongswan_PATH)/src/libhydra \
-       $(strongswan_PATH)/src/libstrongswan \
-       $(strongswan_PATH)/src/libfreeswan \
-       $(strongswan_PATH)/src/whack
-
-LOCAL_CFLAGS := $(strongswan_CFLAGS) \
-       -DPLUTO -DVENDORID -DXAUTH_VID -DCISCO_QUIRKS \
-       -DTHREADS -DKERNEL26_HAS_KAME_DUPLICATES \
-       -DPLUGINS='"$(strongswan_PLUTO_PLUGINS)"'
-
-LOCAL_MODULE := pluto
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_ARM_MODE := arm
-
-LOCAL_PRELINK_MODULE := false
-
-LOCAL_SHARED_LIBRARIES += libstrongswan libhydra libfreeswan libcutils
-
-include $(BUILD_EXECUTABLE)
diff --git a/src/pluto/Makefile.am b/src/pluto/Makefile.am
deleted file mode 100644 (file)
index 3fd0e03..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-# Makefile.am was ported from the old Makefile the most
-# painless way. Only the most important options are included,
-# further work may be necessary here...
-
-ipsec_PROGRAMS = pluto
-
-if USE_ADNS
-ipsec_PROGRAMS += _pluto_adns
-endif
-
-pluto_SOURCES = \
-ac.c ac.h \
-alg_info.c alg_info.h \
-ca.c ca.h \
-certs.c certs.h \
-connections.c connections.h \
-constants.c constants.h \
-cookie.c cookie.h \
-crl.c crl.h \
-crypto.c crypto.h \
-db_ops.c db_ops.h \
-defs.c defs.h \
-demux.c demux.h \
-event_queue.c event_queue.h \
-fetch.c fetch.h \
-foodgroups.c foodgroups.h \
-ike_alg.c ike_alg.h \
-ipsec_doi.c ipsec_doi.h \
-kameipsec.h \
-kernel.c kernel.h \
-kernel_alg.c kernel_alg.h \
-kernel_pfkey.c kernel_pfkey.h \
-keys.c keys.h \
-lex.c lex.h \
-log.c log.h \
-myid.c myid.h \
-modecfg.c modecfg.h \
-nat_traversal.c nat_traversal.h \
-ocsp.c ocsp.h \
-packet.c packet.h \
-pkcs7.c pkcs7.h \
-plugin_list.c plugin_list.h \
-pluto.c pluto.h \
-plutomain.c \
-rcv_whack.c rcv_whack.h \
-server.c server.h \
-smartcard.c smartcard.h \
-spdb.c spdb.h \
-state.c state.h \
-timer.c timer.h \
-vendor.c vendor.h \
-virtual.c virtual.h \
-whack_attribute.c whack_attribute.h \
-xauth/xauth_manager.c xauth/xauth_manager.h \
-xauth/xauth_provider.h xauth/xauth_verifier.h \
-x509.c x509.h \
-builder.c builder.h \
-rsaref/pkcs11t.h rsaref/pkcs11.h rsaref/unix.h rsaref/pkcs11f.h
-
-if USE_ADNS
-pluto_SOURCES += \
-dnskey.c dnskey.h
-
-_pluto_adns_SOURCES = \
-adns.c adns.h
-endif
-
-plutomain.o :  $(top_builddir)/config.status
-
-LIBSTRONGSWANDIR=$(top_builddir)/src/libstrongswan
-LIBFREESWANDIR=$(top_builddir)/src/libfreeswan
-LIBHYDRADIR=$(top_builddir)/src/libhydra
-
-INCLUDES = \
--I${linux_headers} \
--I$(top_srcdir)/src/libstrongswan \
--I$(top_srcdir)/src/libfreeswan \
--I$(top_srcdir)/src/libhydra \
--I$(top_srcdir)/src/whack
-
-AM_CFLAGS = -rdynamic \
--DIPSEC_DIR=\"${ipsecdir}\" \
--DIPSEC_CONFDIR=\"${sysconfdir}\" \
--DIPSEC_PIDDIR=\"${piddir}\" \
--DSHARED_SECRETS_FILE=\"${sysconfdir}/ipsec.secrets\" \
--DPLUGINS=\""${pluto_plugins}\"" \
--DPKCS11_DEFAULT_LIB=\"${default_pkcs11}\" \
--DKERNEL26_HAS_KAME_DUPLICATES \
--DPLUTO -DDEBUG
-
-pluto_LDADD = \
-$(LIBSTRONGSWANDIR)/libstrongswan.la \
-$(LIBFREESWANDIR)/libfreeswan.a \
-$(LIBHYDRADIR)/libhydra.la \
--lresolv $(PTHREADLIB) $(DLLIB)
-
-if USE_ADNS
-_pluto_adns_LDADD = \
-$(LIBFREESWANDIR)/libfreeswan.a \
--lresolv $(DLLIB)
-endif
-
-dist_man_MANS = pluto.8
-
-EXTRA_DIST = Android.mk
-
-# compile options
-#################
-
-# This compile option activates the sending of a strongSwan VID
-if USE_VENDORID
-  AM_CFLAGS += -DVENDORID
-endif
-
-# This compile option activates the sending of the XAUTH VID
-if USE_XAUTH_VID
-  AM_CFLAGS += -DXAUTH_VID
-endif
-
-# This compile option activates the support of the Cisco VPN client
-if USE_CISCO_QUIRKS
-  AM_CFLAGS += -DCISCO_QUIRKS
-endif
-
-# This compile option activates NAT traversal with IPSec transport mode
-if USE_NAT_TRANSPORT
-  AM_CFLAGS += -DI_KNOW_TRANSPORT_MODE_HAS_SECURITY_CONCERN_BUT_I_WANT_IT
-endif
-
-# This compile option activates smartcard support
-if USE_SMARTCARD
-  AM_CFLAGS += -DSMARTCARD
-endif
-
-if USE_LIBCAP
-  pluto_LDADD += -lcap
-endif
-
-if USE_THREADS
-  AM_CFLAGS += -DTHREADS
-endif
-
-if USE_ADNS
-  AM_CFLAGS += -DADNS
-endif
-
-# build optional plugins
-########################
-
-SUBDIRS = .
-
-if USE_XAUTH
-  SUBDIRS += plugins/xauth
-endif
-
diff --git a/src/pluto/ac.c b/src/pluto/ac.c
deleted file mode 100644 (file)
index cd8007a..0000000
+++ /dev/null
@@ -1,298 +0,0 @@
-/* Support of X.509 attribute certificates
- * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
- * Copyright (C) 2003 Martin Berner, Lukas Suter
- * Copyright (C) 2009 Andreas Steffen
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <sys/stat.h>
-#include <time.h>
-
-#include <debug.h>
-#include <utils/enumerator.h>
-#include <utils/linked_list.h>
-#include <credentials/certificates/ac.h>
-
-#include "ac.h"
-#include "ca.h"
-#include "certs.h"
-#include "fetch.h"
-#include "log.h"
-
-/**
- * Chained list of X.509 attribute certificates
- */
-static linked_list_t *acerts   = NULL;
-
-/**
- * Initialize the linked list of attribute certificates
- */
-void ac_initialize(void)
-{
-       acerts = linked_list_create();
-}
-
-/**
- * Free the linked list of attribute certificates
- */
-void ac_finalize(void)
-{
-       if (acerts)
-       {
-               acerts->destroy_offset(acerts, offsetof(certificate_t, destroy));
-       }
-}
-
-/**
- *  Get a X.509 attribute certificate for a given holder
- */
-certificate_t* ac_get_cert(identification_t *issuer, chunk_t serial)
-{
-       enumerator_t *enumerator;
-       certificate_t *cert, *found = NULL;
-
-       enumerator = acerts->create_enumerator(acerts);
-       while (enumerator->enumerate(enumerator, &cert))
-       {
-               ac_t *ac = (ac_t*)cert;
-
-               if (issuer->equals(issuer, ac->get_holderIssuer(ac)) &&
-                         chunk_equals(serial, ac->get_holderSerial(ac)))
-               {
-                       found = cert;
-                       break;
-               }
-       }
-       enumerator->destroy(enumerator);
-       return found;
-}
-
-/**
- * Verifies a X.509 attribute certificate
- */
-bool ac_verify_cert(certificate_t *cert, bool strict)
-{
-       ac_t *ac = (ac_t*)cert;
-       identification_t *subject = cert->get_subject(cert);
-       identification_t *issuer  = cert->get_issuer(cert);
-       chunk_t authKeyID = ac->get_authKeyIdentifier(ac);
-       cert_t *aacert;
-       time_t notBefore, valid_until;
-
-       DBG1(DBG_LIB, "holder: '%Y'", subject);
-       DBG1(DBG_LIB, "issuer: '%Y'", issuer);
-
-       if (!cert->get_validity(cert, NULL, NULL, &valid_until))
-       {
-               DBG1(DBG_LIB, "attribute certificate is invalid (valid from %T to %T)",
-                        &notBefore, FALSE, &valid_until, FALSE);
-               return FALSE;
-       }
-       DBG1(DBG_LIB, "attribute certificate is valid until %T", &valid_until,
-                FALSE);
-
-       lock_authcert_list("verify_x509acert");
-       aacert = get_authcert(issuer, authKeyID, X509_AA);
-       unlock_authcert_list("verify_x509acert");
-
-       if (aacert == NULL)
-       {
-               DBG1(DBG_LIB, "issuer aacert not found");
-               return FALSE;
-       }
-       DBG2(DBG_LIB, "issuer aacert found");
-
-       if (!cert->issued_by(cert, aacert->cert))
-       {
-               DBG1(DBG_LIB, "attribute certificate signature is invalid");
-               return FALSE;
-       }
-       DBG1(DBG_LIB, "attribute certificate signature is valid");
-
-       return verify_x509cert(aacert, strict, &valid_until);
-}
-
-/**
- *  Add a X.509 attribute certificate to the chained list
- */
-static void ac_add_cert(certificate_t *cert)
-{
-       ac_t *ac = (ac_t*)cert;
-       identification_t *hIssuer = ac->get_holderIssuer(ac);
-       chunk_t hSerial = ac->get_holderSerial(ac);
-
-       enumerator_t *enumerator;
-       certificate_t *cert_old;
-
-       enumerator = acerts->create_enumerator(acerts);
-       while (enumerator->enumerate(enumerator, &cert_old))
-       {
-               ac_t *ac_old = (ac_t*)cert_old;
-
-               if (hIssuer->equals(hIssuer, ac_old->get_holderIssuer(ac_old)) &&
-                          chunk_equals(hSerial, ac_old->get_holderSerial(ac_old)))
-               {
-                       if (certificate_is_newer(cert, cert_old))
-                       {
-                               acerts->remove_at(acerts, enumerator);
-                               cert_old->destroy(cert_old);
-                       }
-                       else
-                       {
-                               cert->destroy(cert);
-                               cert = NULL;
-                       }
-                       break;
-               }
-       }
-       enumerator->destroy(enumerator);
-
-       if (cert)
-       {
-               acerts->insert_last(acerts, cert);
-       }
-}
-
-/**
- * Check if at least one peer attribute matches a connection attribute
- */
-bool match_group_membership(ietf_attributes_t *peer_attributes, char *conn,
-                                                       ietf_attributes_t *conn_attributes)
-{
-       bool match;
-
-       if (conn_attributes == NULL)
-       {
-               return TRUE;
-       }
-
-       match = conn_attributes->matches(conn_attributes, peer_attributes);
-       DBG1(DBG_LIB, "%s: peer with attributes '%s' is %sa member of the "
-                "groups '%s'", conn, peer_attributes->get_string(peer_attributes),
-                match ? "" : "not ", conn_attributes->get_string(conn_attributes));
-
-       return match;
-}
-
-/**
- * Loads X.509 attribute certificates
- */
-void ac_load_certs(void)
-{
-       enumerator_t *enumerator;
-       struct stat st;
-       char *file;
-
-       DBG1(DBG_LIB, "loading attribute certificates from '%s'", A_CERT_PATH);
-
-       enumerator = enumerator_create_directory(A_CERT_PATH);
-       if (!enumerator)
-       {
-               return;
-       }
-
-       while (enumerator->enumerate(enumerator, NULL, &file, &st))
-       {
-               certificate_t *cert;
-
-               if (!S_ISREG(st.st_mode))
-               {
-                       /* skip special file */
-                       continue;
-               }
-               cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509_AC,
-                                                                 BUILD_FROM_FILE, file, BUILD_END);
-               if (cert)
-               {
-                       DBG1(DBG_LIB, "  loaded attribute certificate from '%s'", file);
-                       ac_add_cert(cert);
-               }
-       }
-       enumerator->destroy(enumerator);
-}
-
-/**
- *  List all X.509 attribute certificates in the chained list
- */
-void ac_list_certs(bool utc)
-{
-       enumerator_t *enumerator;
-       certificate_t *cert;
-       time_t now;
-
-       /* determine the current time */
-       time(&now);
-
-       if (acerts->get_count(acerts) > 0)
-       {
-               whack_log(RC_COMMENT, " ");
-               whack_log(RC_COMMENT, "List of X.509 Attribute Certificates:");
-       }
-
-       enumerator = acerts->create_enumerator(acerts);
-       while (enumerator->enumerate(enumerator, &cert))
-       {
-               ac_t *ac = (ac_t*)cert;
-               identification_t *entityName, *holderIssuer, *issuer;
-               chunk_t holderSerial, serial, authKeyID;
-               time_t notBefore, notAfter;
-               ietf_attributes_t *groups;
-
-               whack_log(RC_COMMENT, " ");
-
-               entityName = cert->get_subject(cert);
-               if (entityName)
-               {
-                       whack_log(RC_COMMENT, "  holder:   \"%Y\"", entityName);
-               }
-
-               holderIssuer = ac->get_holderIssuer(ac);
-               if (holderIssuer)
-               {
-                       whack_log(RC_COMMENT, "  hissuer:  \"%Y\"", holderIssuer);
-               }
-
-               holderSerial = chunk_skip_zero(ac->get_holderSerial(ac));
-               if (holderSerial.ptr)
-               {
-                       whack_log(RC_COMMENT, "  hserial:   %#B", &holderSerial);
-               }
-
-               groups = ac->get_groups(ac);
-               if (groups)
-               {
-                       whack_log(RC_COMMENT, "  groups:    %s", groups->get_string(groups));
-                       groups->destroy(groups);
-               }
-
-               issuer = cert->get_issuer(cert);
-               whack_log(RC_COMMENT, "  issuer:   \"%Y\"", issuer);
-
-               serial = chunk_skip_zero(ac->get_serial(ac));
-               whack_log(RC_COMMENT, "  serial:    %#B", &serial);
-
-               cert->get_validity(cert, &now, &notBefore, &notAfter);
-               whack_log(RC_COMMENT, "  validity:  not before %T %s",
-                               &notBefore, utc,
-                               (notBefore < now)?"ok":"fatal (not valid yet)");
-               whack_log(RC_COMMENT, "             not after  %T %s", &notAfter, utc,
-                               check_expiry(notAfter, ACERT_WARNING_INTERVAL, TRUE));
-
-               authKeyID = ac->get_authKeyIdentifier(ac);
-               if (authKeyID.ptr)
-               {
-                       whack_log(RC_COMMENT, "  authkey:   %#B", &authKeyID);
-               }
-       }
-       enumerator->destroy(enumerator);
-}
-
diff --git a/src/pluto/ac.h b/src/pluto/ac.h
deleted file mode 100644 (file)
index d4e0c15..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Support of X.509 attribute certificates
- * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
- * Copyright (C) 2003 Martin Berner, Lukas Suter
- * Copyright (C) 2009 Andreas Steffen
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef _AC_H
-#define _AC_H
-
-#include <utils/identification.h>
-#include <credentials/certificates/certificate.h>
-#include <credentials/ietf_attributes/ietf_attributes.h>
-
-/* access structure for an X.509 attribute certificate */
-
-extern void ac_initialize(void);
-extern void ac_finalize(void);
-extern void ac_load_certs(void);
-extern void ac_list_certs(bool utc);
-
-extern certificate_t* ac_get_cert(identification_t *issuer, chunk_t serial);
-
-extern bool ac_verify_cert(certificate_t *ac, bool strict);
-
-extern bool match_group_membership(ietf_attributes_t *peer_attributes,
-                                                                  char *conn,
-                                                                  ietf_attributes_t *conn_attributes);
-
-#endif /* _AC_H */
diff --git a/src/pluto/adns.c b/src/pluto/adns.c
deleted file mode 100644 (file)
index 76b4592..0000000
+++ /dev/null
@@ -1,610 +0,0 @@
-/* Pluto Asynchronous DNS Helper Program -- for internal use only!
- * Copyright (C) 2002  D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-/* This program executes as multiple processes.  The Master process
- * receives queries (struct adns_query messages) from Pluto and distributes
- * them amongst Worker processes.  These Worker processes are created
- * by the Master whenever a query arrives and no existing Worker is free.
- * At most MAX_WORKERS will be created; after that, the Master will queue
- * queries until a Worker becomes free.  When a Worker has an answer from
- * the resolver, it sends the answer as a struct adns_answer message to the
- * Master.  The Master then forwards the answer to Pluto, noting that
- * the Worker is free to accept another query.
- *
- * The protocol is simple: Pluto sends a sequence of queries and receives
- * a sequence of answers.  select(2) is used by Pluto and by the Master
- * process to decide when to read, but writes are done without checking
- * for readiness.  Communications is via pipes.  Since only one process
- * can write to each pipe, messages will not be interleaved.  Fixed length
- * records are used for simplicity.
- *
- * Pluto needs a way to indicate to the Master when to shut down
- * and the Master needs to indicate this to each worker.  EOF on the pipe
- * signifies this.
- *
- * The interfaces between these components are considered private to
- * Pluto.  This allows us to get away with less checking.  This is a
- * reason to use pipes instead of TCP/IP.
- *
- * Although the code uses plain old UNIX processes, it could be modified
- * to use threads.  That might reduce resource requirements.  It would
- * preclude running on systems without thread-safe resolvers.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <syslog.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <netinet/in.h>
-#include <arpa/nameser.h>
-#include <resolv.h>
-#include <netdb.h>      /* ??? for h_errno */
-
-#include <freeswan.h>
-
-/* GCC magic! */
-#ifdef GCC_LINT
-# define UNUSED __attribute__ ((unused))
-#else
-# define UNUSED /* ignore */
-#endif
-
-#include "constants.h"
-#include "adns.h"       /* needs <resolv.h> */
-
-/* shared by all processes */
-
-static const char *name;        /* program name, for messages */
-
-static bool debug = FALSE;
-
-/* Read a variable-length record from a pipe (and no more!).
- * First bytes must be a size_t containing the length.
- * HES_CONTINUE if record read
- * HES_OK if EOF
- * HES_IO_ERROR_IN if errno tells the tale.
- * Others are errors.
- */
-static enum helper_exit_status
-read_pipe(int fd, unsigned char *stuff, size_t minlen, size_t maxlen)
-{
-       size_t n = 0;
-       size_t goal = minlen;
-
-       do {
-               ssize_t m = read(fd, stuff + n, goal - n);
-
-               if (m == -1)
-               {
-                       if (errno != EINTR)
-                       {
-                               syslog(LOG_ERR, "Input error on pipe: %s", strerror(errno));
-                               return HES_IO_ERROR_IN;
-                       }
-               }
-               else if (m == 0)
-               {
-                       return HES_OK;      /* treat empty message as EOF */
-               }
-               else
-               {
-                       n += m;
-                       if (n >= sizeof(size_t))
-                       {
-                               goal = *(size_t *)(void *)stuff;
-                               if (goal < minlen || maxlen < goal)
-                               {
-                                       if (debug)
-                                               fprintf(stderr, "%lu : [%lu, %lu]\n"
-                                                       , (unsigned long)goal
-                                                       , (unsigned long)minlen, (unsigned long)maxlen);
-                                       return HES_BAD_LEN;
-                               }
-                       }
-               }
-       } while (n < goal);
-
-       return HES_CONTINUE;
-}
-
-/* Write a variable-length record to a pipe.
- * First bytes must be a size_t containing the length.
- * HES_CONTINUE if record written
- * Others are errors.
- */
-static enum helper_exit_status
-write_pipe(int fd, const unsigned char *stuff)
-{
-       size_t len = *(const size_t *)(const void *)stuff;
-       size_t n = 0;
-
-       do {
-               ssize_t m = write(fd, stuff + n, len - n);
-
-               if (m == -1)
-               {
-                       /* error, but ignore and retry if EINTR */
-                       if (errno != EINTR)
-                       {
-                               syslog(LOG_ERR, "Output error from master: %s", strerror(errno));
-                               return HES_IO_ERROR_OUT;
-                       }
-               }
-               else
-               {
-                       n += m;
-               }
-       } while (n != len);
-       return HES_CONTINUE;
-}
-
-/**************** worker process ****************/
-
-/* The interface in RHL6.x and BIND distribution 8.2.2 are different,
- * so we build some of our own :-(
- */
-
-/* Support deprecated interface to allow for older releases of the resolver.
- * Fake new interface!
- * See resolver(3) bind distribution (should be in RHL6.1, but isn't).
- * __RES was 19960801 in RHL6.2, an old resolver.
- */
-
-#if (__RES) <= 19960801
-# define OLD_RESOLVER   1
-#endif
-
-#ifdef OLD_RESOLVER
-
-# define res_ninit(statp) res_init()
-# define res_nquery(statp, dname, class, type, answer, anslen) \
-       res_query(dname, class, type, answer, anslen)
-# define res_nclose(statp) res_close()
-
-static struct __res_state *statp = &_res;
-
-#else /* !OLD_RESOLVER */
-
-static struct __res_state my_res_state /* = { 0 } */;
-static res_state statp = &my_res_state;
-
-#endif /* !OLD_RESOLVER */
-
-static int
-worker(int qfd, int afd)
-{
-       {
-               int r = res_ninit(statp);
-
-               if (r != 0)
-               {
-                       syslog(LOG_ERR, "cannot initialize resolver");
-                       return HES_RES_INIT;
-               }
-#ifndef OLD_RESOLVER
-               statp->options |= RES_ROTATE;
-#endif
-               statp->options |= RES_DEBUG;
-       }
-
-       for (;;)
-       {
-               struct adns_query q;
-               struct adns_answer a;
-
-               enum helper_exit_status r = read_pipe(qfd, (unsigned char *)&q
-                       , sizeof(q), sizeof(q));
-
-               if (r != HES_CONTINUE)
-                       return r;   /* some kind of exit */
-
-               if (q.qmagic != ADNS_Q_MAGIC)
-               {
-                       syslog(LOG_ERR, "error in input from master: bad magic");
-                       return HES_BAD_MAGIC;
-               }
-
-               a.amagic = ADNS_A_MAGIC;
-               a.serial = q.serial;
-               a.continuation = NULL;
-
-               a.result = res_nquery(statp, q.name_buf, C_IN, q.type, a.ans, sizeof(a.ans));
-               a.h_errno_val = h_errno;
-
-               a.len = offsetof(struct adns_answer, ans) + (a.result < 0? 0 : a.result);
-
-#ifdef DEBUG
-               if (((q.debugging & IMPAIR_DELAY_ADNS_KEY_ANSWER) && q.type == T_KEY)
-               || ((q.debugging & IMPAIR_DELAY_ADNS_TXT_ANSWER) && q.type == T_TXT))
-                       sleep(30);  /* delay the answer */
-#endif
-
-               /* write answer, possibly a bit at a time */
-               r = write_pipe(afd, (const unsigned char *)&a);
-
-               if (r != HES_CONTINUE)
-                       return r;   /* some kind of exit */
-       }
-}
-
-/**************** master process ****************/
-
-bool eof_from_pluto = FALSE;
-#define PLUTO_QFD       0       /* queries come on stdin */
-#define PLUTO_AFD       1       /* answers go out on stdout */
-
-#ifndef MAX_WORKERS
-# define MAX_WORKERS 10 /* number of in-flight queries */
-#endif
-
-struct worker_info {
-       int qfd;    /* query pipe's file descriptor */
-       int afd;    /* answer pipe's file descriptor */
-       pid_t pid;
-       bool busy;
-       void *continuation; /* of outstanding request */
-};
-
-static struct worker_info wi[MAX_WORKERS];
-static struct worker_info *wi_roof = wi;
-
-/* request FIFO */
-
-struct query_list {
-       struct query_list *next;
-       struct adns_query aq;
-};
-
-static struct query_list *oldest_query = NULL;
-static struct query_list *newest_query; /* undefined when oldest == NULL */
-static struct query_list *free_queries = NULL;
-
-static bool
-spawn_worker(void)
-{
-       int qfds[2];
-       int afds[2];
-       pid_t p;
-
-       if (pipe(qfds) != 0 || pipe(afds) != 0)
-       {
-               syslog(LOG_ERR, "pipe(2) failed: %s", strerror(errno));
-               exit(HES_PIPE);
-       }
-
-       wi_roof->qfd = qfds[1];     /* write end of query pipe */
-       wi_roof->afd = afds[0];     /* read end of answer pipe */
-
-       p = fork();
-       if (p == -1)
-       {
-               /* fork failed: ignore if at least one worker exists */
-               if (wi_roof == wi)
-               {
-                       syslog(LOG_ERR, "fork(2) error creating first worker: %s", strerror(errno));
-                       exit(HES_FORK);
-               }
-               close(qfds[0]);
-               close(qfds[1]);
-               close(afds[0]);
-               close(afds[1]);
-               return FALSE;
-       }
-       else if (p == 0)
-       {
-               /* child */
-               struct worker_info *w;
-
-               close(PLUTO_QFD);
-               close(PLUTO_AFD);
-               /* close all master pipes, including ours */
-               for (w = wi; w <= wi_roof; w++)
-               {
-                       close(w->qfd);
-                       close(w->afd);
-               }
-               exit(worker(qfds[0], afds[1]));
-       }
-       else
-       {
-               /* parent */
-               struct worker_info *w = wi_roof++;
-
-               w->pid = p;
-               w->busy = FALSE;
-               close(qfds[0]);
-               close(afds[1]);
-               return TRUE;
-       }
-}
-
-static void
-send_eof(struct worker_info *w)
-{
-       pid_t p;
-       int status;
-
-       close(w->qfd);
-       w->qfd = NULL_FD;
-
-       close(w->afd);
-       w->afd = NULL_FD;
-
-       /* reap child */
-       p = waitpid(w->pid, &status, 0);
-       /* ignore result -- what could we do with it? */
-}
-
-static void
-forward_query(struct worker_info *w)
-{
-       struct query_list *q = oldest_query;
-
-       if (q == NULL)
-       {
-               if (eof_from_pluto)
-                       send_eof(w);
-       }
-       else
-       {
-               enum helper_exit_status r
-                       = write_pipe(w->qfd, (const unsigned char *) &q->aq);
-
-               if (r != HES_CONTINUE)
-                       exit(r);
-
-               w->busy = TRUE;
-
-               oldest_query = q->next;
-               q->next = free_queries;
-               free_queries = q;
-       }
-}
-
-static void
-query(void)
-{
-       struct query_list *q = free_queries;
-       enum helper_exit_status r;
-
-       /* find an unused queue entry */
-       if (q == NULL)
-       {
-               q = malloc(sizeof(*q));
-               if (q == NULL)
-               {
-                       syslog(LOG_ERR, "malloc(3) failed");
-                       exit(HES_MALLOC);
-               }
-       }
-       else
-       {
-               free_queries = q->next;
-       }
-
-       r = read_pipe(PLUTO_QFD, (unsigned char *)&q->aq
-               , sizeof(q->aq), sizeof(q->aq));
-
-       if (r == HES_OK)
-       {
-               /* EOF: we're done, except for unanswered queries */
-               struct worker_info *w;
-
-               eof_from_pluto = TRUE;
-               q->next = free_queries;
-               free_queries = q;
-
-               /* Send bye-bye to unbusy processes.
-                * Note that if there are queued queries, there won't be
-                * any non-busy workers.
-                */
-               for (w = wi; w != wi_roof; w++)
-                       if (!w->busy)
-                               send_eof(w);
-       }
-       else if (r != HES_CONTINUE)
-       {
-               exit(r);
-       }
-       else if (q->aq.qmagic != ADNS_Q_MAGIC)
-       {
-               syslog(LOG_ERR, "error in query from Pluto: bad magic");
-               exit(HES_BAD_MAGIC);
-       }
-       else
-       {
-               struct worker_info *w;
-
-               /* got a query */
-
-               /* add it to FIFO */
-               q->next = NULL;
-               if (oldest_query == NULL)
-                       oldest_query = q;
-               else
-                       newest_query->next = q;
-               newest_query = q;
-
-               /* See if any worker available */
-               for (w = wi; ; w++)
-               {
-                       if (w == wi_roof)
-                       {
-                               /* no free worker */
-                               if (w == wi + MAX_WORKERS)
-                                       break;      /* no more to be created */
-                               /* make a new one */
-                               if (!spawn_worker())
-                                       break;      /* cannot create one at this time */
-                       }
-                       if (!w->busy)
-                       {
-                               /* assign first to free worker */
-                               forward_query(w);
-                               break;
-                       }
-               }
-       }
-       return;
-}
-
-static void
-answer(struct worker_info *w)
-{
-       struct adns_answer a;
-       enum helper_exit_status r = read_pipe(w->afd, (unsigned char *)&a
-               , offsetof(struct adns_answer, ans), sizeof(a));
-
-       if (r == HES_OK)
-       {
-               /* unexpected EOF */
-               syslog(LOG_ERR, "unexpected EOF from worker");
-               exit(HES_IO_ERROR_IN);
-       }
-       else if (r != HES_CONTINUE)
-       {
-               exit(r);
-       }
-       else if (a.amagic != ADNS_A_MAGIC)
-       {
-               syslog(LOG_ERR, "Input from worker error: bad magic");
-               exit(HES_BAD_MAGIC);
-       }
-       else if (a.continuation != w->continuation)
-       {
-               /* answer doesn't match query */
-               syslog(LOG_ERR, "Input from worker error: continuation mismatch");
-               exit(HES_SYNC);
-       }
-       else
-       {
-               /* pass the answer on to Pluto */
-               enum helper_exit_status r
-                       = write_pipe(PLUTO_AFD, (const unsigned char *) &a);
-
-               if (r != HES_CONTINUE)
-                       exit(r);
-               w->busy = FALSE;
-               forward_query(w);
-       }
-}
-
-/* assumption: input limited; accept blocking on output */
-static int
-master(void)
-{
-       for (;;)
-       {
-               fd_set readfds;
-               int maxfd = PLUTO_QFD;          /* approximate lower bound */
-               int ndes = 0;
-               struct worker_info *w;
-
-               FD_ZERO(&readfds);
-               if (!eof_from_pluto)
-               {
-                       FD_SET(PLUTO_QFD, &readfds);
-                       ndes++;
-               }
-               for (w = wi; w != wi_roof; w++)
-               {
-                       if (w->busy)
-                       {
-                               FD_SET(w->afd, &readfds);
-                               ndes++;
-                               if (maxfd < w->afd)
-                                       maxfd = w->afd;
-                       }
-               }
-
-               if (ndes == 0)
-                       return HES_OK;      /* done! */
-
-               do {
-                       ndes = select(maxfd + 1, &readfds, NULL, NULL, NULL);
-               } while (ndes == -1 && errno == EINTR);
-               if (ndes == -1)
-               {
-                       syslog(LOG_ERR, "select(2) error: %s", strerror(errno));
-                       exit(HES_IO_ERROR_SELECT);
-               }
-               else if (ndes > 0)
-               {
-                       if (FD_ISSET(PLUTO_QFD, &readfds))
-                       {
-                               query();
-                               ndes--;
-                       }
-                       for (w = wi; ndes > 0 && w != wi_roof; w++)
-                       {
-                               if (w->busy && FD_ISSET(w->afd, &readfds))
-                               {
-                                       answer(w);
-                                       ndes--;
-                               }
-                       }
-               }
-       }
-}
-
-/* Not to be invoked by strangers -- user hostile.
- * Mandatory args: query-fd answer-fd
- * Optional arg: -d, signifying "debug".
- */
-
-static void
-adns_usage(const char *fmt, const char *arg)
-{
-       const char **sp = ipsec_copyright_notice();
-
-       fprintf(stderr, "INTERNAL TO PLUTO: DO NOT EXECUTE\n");
-
-       fprintf(stderr, fmt, arg);
-       fprintf(stderr, "\nstrongSwan "VERSION"\n");
-
-       for (; *sp != NULL; sp++)
-               fprintf(stderr, "%s\n", *sp);
-
-       syslog(LOG_ERR, fmt, arg);
-       exit(HES_INVOCATION);
-}
-
-int
-main(int argc UNUSED, char **argv)
-{
-       int i = 1;
-
-       name = argv[0];
-
-       while (i < argc)
-       {
-               if (streq(argv[i], "-d"))
-               {
-                       i++;
-                       debug = TRUE;
-               }
-               else
-               {
-                       adns_usage("unexpected argument \"%s\"", argv[i]);
-                       /*NOTREACHED*/
-               }
-       }
-
-       return master();
-}
diff --git a/src/pluto/adns.h b/src/pluto/adns.h
deleted file mode 100644 (file)
index dfbcbaf..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/* Pluto Asynchronous DNS Helper Program's Header
- * Copyright (C) 2002  D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef ADNS
-
-/* dummy struct to make compilers happy */
-struct adns_query {
-};
-
-#else /* rest of file */
-
-/* The interface in RHL6.x and BIND distribution 8.2.2 are different,
- * so we build some of our own :-(
- */
-
-# ifndef NS_MAXDNAME
-#   define NS_MAXDNAME MAXDNAME /* I hope this is long enough for IPv6 */
-# endif
-
-# ifndef NS_PACKETSZ
-#   define NS_PACKETSZ PACKETSZ
-# endif
-
-/* protocol version */
-
-#define ADNS_Q_MAGIC (((((('d' << 8) + 'n') << 8) + 's') << 8) + 4)
-#define ADNS_A_MAGIC (((((('d' << 8) + 'n') << 8) + 's') << 8) + 128 + 4)
-
-/* note: both struct adns_query and struct adns_answer must start with
- * size_t len;
- */
-
-struct adns_query {
-       size_t len;
-       unsigned int qmagic;
-       unsigned long serial;
-       lset_t debugging;   /* only used #ifdef DEBUG, but don't want layout to change */
-       u_char name_buf[NS_MAXDNAME + 2];
-       int type;   /* T_KEY or T_TXT */
-};
-
-struct adns_answer {
-       size_t len;
-       unsigned int amagic;
-       unsigned long serial;
-       struct adns_continuation *continuation;
-       int result;
-       int h_errno_val;
-       u_char ans[NS_PACKETSZ * 10];   /* very probably bigger than necessary */
-};
-
-enum helper_exit_status {
-       HES_CONTINUE = -1,  /* not an exit */
-       HES_OK = 0, /* all's well that ends well (perhaps EOF) */
-       HES_INVOCATION,     /* improper invocation */
-       HES_IO_ERROR_SELECT,        /* IO error in select() */
-       HES_MALLOC, /* malloc failed */
-       HES_IO_ERROR_IN,    /* error reading pipe */
-       HES_IO_ERROR_OUT,   /* error reading pipe */
-       HES_PIPE,   /* pipe(2) failed */
-       HES_SYNC,   /* answer from worker doesn't match query */
-       HES_FORK,   /* fork(2) failed */
-       HES_RES_INIT,       /* resolver initialization failed */
-       HES_BAD_LEN,        /* implausible .len field */
-       HES_BAD_MAGIC,      /* .magic field wrong */
-};
-#endif /* ADNS */
diff --git a/src/pluto/alg_info.c b/src/pluto/alg_info.c
deleted file mode 100644 (file)
index fe27c10..0000000
+++ /dev/null
@@ -1,683 +0,0 @@
-/*
- * Algorithm info parsing and creation functions
- * Copyright (C) JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
- * Copyright (C) 2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include <ctype.h>
-#include <freeswan.h>
-#include <pfkeyv2.h>
-
-#include <utils.h>
-#include <utils/lexparser.h>
-#include <crypto/diffie_hellman.h>
-#include <crypto/transform.h>
-#include <crypto/proposal/proposal_keywords.h>
-
-
-#include "alg_info.h"
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "whack.h"
-#include "crypto.h"
-#include "kernel_alg.h"
-#include "ike_alg.h"
-
-/*
- * sadb/ESP aa attrib converters
- */
-int alg_info_esp_aa2sadb(int auth)
-{
-       int sadb_aalg = 0;
-
-       switch(auth)
-       {
-               case AUTH_ALGORITHM_HMAC_MD5:
-               case AUTH_ALGORITHM_HMAC_SHA1:
-                       sadb_aalg = auth + 1;
-                       break;
-               default:
-                       sadb_aalg = auth;
-       }
-       return sadb_aalg;
-}
-
-int alg_info_esp_sadb2aa(int sadb_aalg)
-{
-       int auth = 0;
-
-       switch(sadb_aalg)
-       {
-               case SADB_AALG_MD5HMAC:
-               case SADB_AALG_SHA1HMAC:
-                       auth = sadb_aalg - 1;
-                       break;
-               default:
-                       auth = sadb_aalg;
-       }
-       return auth;
-}
-
-void alg_info_free(struct alg_info *alg_info)
-{
-       free(alg_info);
-}
-
-/*
- * Raw add routine: only checks for no duplicates
- */
-static void __alg_info_esp_add(struct alg_info_esp *alg_info, int ealg_id,
-                                                          unsigned ek_bits, int aalg_id, unsigned ak_bits)
-{
-       struct esp_info *esp_info = alg_info->esp;
-       unsigned cnt = alg_info->alg_info_cnt, i;
-
-       /* check for overflows */
-       passert(cnt < countof(alg_info->esp));
-
-       /* dont add duplicates */
-       for (i = 0; i < cnt; i++)
-       {
-               if (esp_info[i].esp_ealg_id == ealg_id
-               && (!ek_bits || esp_info[i].esp_ealg_keylen == ek_bits)
-               && esp_info[i].esp_aalg_id == aalg_id
-               && (!ak_bits || esp_info[i].esp_aalg_keylen == ak_bits))
-               {
-                       return;
-               }
-       }
-
-       esp_info[cnt].esp_ealg_id = ealg_id;
-       esp_info[cnt].esp_ealg_keylen = ek_bits;
-       esp_info[cnt].esp_aalg_id = aalg_id;
-       esp_info[cnt].esp_aalg_keylen = ak_bits;
-
-       /* sadb values */
-       esp_info[cnt].encryptalg = ealg_id;
-       esp_info[cnt].authalg = alg_info_esp_aa2sadb(aalg_id);
-       alg_info->alg_info_cnt++;
-
-       DBG(DBG_CRYPT,
-               DBG_log("esp alg added: %s_%d/%s, cnt=%d",
-                               enum_show(&esp_transform_names, ealg_id), ek_bits,
-                               enum_show(&auth_alg_names, aalg_id),
-                               alg_info->alg_info_cnt)
-       )
-}
-
-/**
- * Returns true if the given alg is an authenticated encryption algorithm
- */
-static bool is_authenticated_encryption(int ealg_id)
-{
-       switch (ealg_id)
-       {
-               case ESP_AES_CCM_8:
-               case ESP_AES_CCM_12:
-               case ESP_AES_CCM_16:
-               case ESP_AES_GCM_8:
-               case ESP_AES_GCM_12:
-               case ESP_AES_GCM_16:
-               case ESP_AES_GMAC:
-                       return TRUE;
-       }
-       return FALSE;
-}
-
-/*
- * Add ESP alg info _with_ logic (policy):
- */
-static void alg_info_esp_add(struct alg_info *alg_info, int ealg_id,
-                                                        int ek_bits, int aalg_id, int ak_bits)
-{
-       /* Policy: default to 3DES */
-       if (ealg_id == 0)
-       {
-               ealg_id = ESP_3DES;
-       }
-       if (ealg_id > 0)
-       {
-               if (is_authenticated_encryption(ealg_id))
-               {
-                       __alg_info_esp_add((struct alg_info_esp *)alg_info,
-                                                               ealg_id, ek_bits,
-                                                               AUTH_ALGORITHM_NONE, 0);
-               }
-               else if (aalg_id > 0)
-               {
-                       __alg_info_esp_add((struct alg_info_esp *)alg_info,
-                                                               ealg_id, ek_bits,
-                                                               aalg_id, ak_bits);
-               }
-               else
-               {
-                       /* Policy: default to SHA-1 and MD5 */
-                       __alg_info_esp_add((struct alg_info_esp *)alg_info,
-                                                               ealg_id, ek_bits,
-                                                               AUTH_ALGORITHM_HMAC_SHA1, ak_bits);
-                       __alg_info_esp_add((struct alg_info_esp *)alg_info,
-                                                               ealg_id, ek_bits,
-                                                               AUTH_ALGORITHM_HMAC_MD5, ak_bits);
-               }
-       }
-}
-
-static void __alg_info_ike_add (struct alg_info_ike *alg_info, int ealg_id,
-                                                               unsigned ek_bits, int aalg_id, unsigned ak_bits,
-                                                               int modp_id)
-{
-       struct ike_info *ike_info = alg_info->ike;
-       unsigned cnt = alg_info->alg_info_cnt;
-       unsigned i;
-
-       /* check for overflows */
-       passert(cnt < countof(alg_info->ike));
-
-       /* dont add duplicates */
-   for (i = 0; i < cnt; i++)
-   {
-               if (ike_info[i].ike_ealg == ealg_id
-               && (!ek_bits || ike_info[i].ike_eklen == ek_bits)
-               &&  ike_info[i].ike_halg == aalg_id
-               && (!ak_bits || ike_info[i].ike_hklen == ak_bits)
-               &&  ike_info[i].ike_modp==modp_id)
-                       return;
-       }
-
-       ike_info[cnt].ike_ealg = ealg_id;
-       ike_info[cnt].ike_eklen = ek_bits;
-       ike_info[cnt].ike_halg = aalg_id;
-       ike_info[cnt].ike_hklen = ak_bits;
-       ike_info[cnt].ike_modp = modp_id;
-       alg_info->alg_info_cnt++;
-
-       DBG(DBG_CRYPT,
-               DBG_log("ikg alg added: %s_%d/%s/%s, cnt=%d",
-                               enum_show(&oakley_enc_names, ealg_id), ek_bits,
-                               enum_show(&oakley_hash_names, aalg_id),
-                               enum_show(&oakley_group_names, modp_id),
-                               alg_info->alg_info_cnt)
-       )
-}
-
-/*
- * Proposals will be built by looping over default_ike_groups array and
- * merging alg_info (ike_info) contents
- */
-
-static int default_ike_groups[] = {
-       MODP_1536_BIT,
-       MODP_1024_BIT
-};
-
-/*
- *      Add IKE alg info _with_ logic (policy):
- */
-static void alg_info_ike_add (struct alg_info *alg_info, int ealg_id,
-                                                         int ek_bits, int aalg_id, int ak_bits, int modp_id)
-{
-       int i = 0;
-       int n_groups = countof(default_ike_groups);
-
-       /* if specified modp_id avoid loop over default_ike_groups */
-       if (modp_id)
-       {
-               n_groups=0;
-               goto in_loop;
-       }
-
-       for (; n_groups--; i++)
-       {
-               modp_id = default_ike_groups[i];
-in_loop:
-               /* Policy: default to 3DES */
-               if (ealg_id == 0)
-               {
-                       ealg_id = OAKLEY_3DES_CBC;
-               }
-               if (ealg_id > 0)
-               {
-                       if (aalg_id > 0)
-                       {
-                               __alg_info_ike_add((struct alg_info_ike *)alg_info,
-                                                                  ealg_id, ek_bits,
-                                                                  aalg_id, ak_bits,
-                                                                  modp_id);
-                       }
-                       else
-                       {
-                               /* Policy: default to MD5 and SHA */
-                               __alg_info_ike_add((struct alg_info_ike *)alg_info,
-                                                                  ealg_id, ek_bits,
-                                                                  OAKLEY_MD5, ak_bits,
-                                                                  modp_id);
-                               __alg_info_ike_add((struct alg_info_ike *)alg_info,
-                                                                  ealg_id, ek_bits,
-                                                                  OAKLEY_SHA, ak_bits,
-                                                                  modp_id);
-                       }
-               }
-       }
-}
-
-static status_t alg_info_add(chunk_t alg, unsigned protoid,
-                                                        int *ealg, size_t *ealg_keysize,
-                                                        int *aalg, size_t *aalg_keysize, int *dh_group)
-{
-       const proposal_token_t *token = proposal_get_token(alg.ptr, alg.len);
-
-       if (token == NULL)
-       {
-               return FAILED;
-       }
-       switch (token->type)
-       {
-               case ENCRYPTION_ALGORITHM:
-                       if (*ealg != 0)
-                       {
-                               return FAILED;
-                       }
-                       *ealg = (protoid == PROTO_ISAKMP) ?
-                                        oakley_from_encryption_algorithm(token->algorithm) :
-                                        esp_from_encryption_algorithm(token->algorithm);
-                       if (*ealg == 0)
-                       {
-                               return FAILED;
-                       }
-                       *ealg_keysize = token->keysize;
-                       break;
-               case INTEGRITY_ALGORITHM:
-                       if (*aalg != 0)
-                       {
-                               return FAILED;
-                       }
-                       *aalg = (protoid == PROTO_ISAKMP) ?
-                                        oakley_from_integrity_algorithm(token->algorithm) :
-                                        esp_from_integrity_algorithm(token->algorithm);
-                       if (*aalg == 0)
-                       {
-                               return FAILED;
-                       }
-                       *aalg_keysize = token->keysize;
-                       break;
-               case DIFFIE_HELLMAN_GROUP:
-                       if (protoid == PROTO_ISAKMP)
-                       {
-                               if (*dh_group != 0)
-                               {
-                                       return FAILED;
-                               }
-                               *dh_group = token->algorithm;
-                       }
-                       break;
-               default:
-                       return FAILED;
-       }
-       return SUCCESS;
-}
-
-
-static status_t alg_info_parse_str(struct alg_info *alg_info, char *alg_str)
-{
-       char *strict, *single;
-       status_t status = SUCCESS;
-
-       strict = alg_str + strlen(alg_str) - 1;
-       if (*strict == '!')
-       {
-               alg_info->alg_info_flags |= ALG_INFO_F_STRICT;
-               *strict = '\0';
-       }
-       while ((single = strsep(&alg_str, ",")))
-       {
-               chunk_t string = { (u_char *)single, strlen(single) };
-               int ealg = 0;
-               int aalg = 0;
-               int dh_group = 0;
-               size_t ealg_keysize = 0;
-               size_t aalg_keysize = 0;
-
-               eat_whitespace(&string);
-
-               if (string.len > 0)
-               {
-                       chunk_t alg;
-
-                       /* get all token, separated by '-' */
-                       while (extract_token(&alg, '-', &string))
-                       {
-                               status |= alg_info_add(alg, alg_info->alg_info_protoid,
-                                                                          &ealg, &ealg_keysize,
-                                                                          &aalg, &aalg_keysize, &dh_group);
-                       }
-                       if (string.len)
-                       {
-                               status |= alg_info_add(string, alg_info->alg_info_protoid,
-                                                                          &ealg, &ealg_keysize,
-                                                                          &aalg, &aalg_keysize, &dh_group);
-                       }
-               }
-               if (status == SUCCESS)
-
-               {
-                       switch (alg_info->alg_info_protoid)
-                       {
-                               case PROTO_IPSEC_ESP:
-                                       alg_info_esp_add(alg_info, ealg, ealg_keysize,
-                                                                                          aalg, aalg_keysize);
-                                       break;
-                               case PROTO_ISAKMP:
-                                       alg_info_ike_add(alg_info, ealg, ealg_keysize,
-                                                                                          aalg, aalg_keysize,
-                                                                                          dh_group);
-                                       break;
-                               default:
-                                       break;
-                       }
-               }
-       }
-       return status;
-}
-
-struct alg_info_esp *alg_info_esp_create_from_str(char *alg_str)
-{
-       struct alg_info_esp *alg_info_esp;
-       char esp_buf[BUF_LEN];
-       char *pfs_name;
-       status_t status = SUCCESS;
-       /*
-        * alg_info storage should be sized dynamically
-        * but this may require 2passes to know
-        * transform count in advance.
-        */
-       alg_info_esp = malloc_thing (struct alg_info_esp);
-       zero(alg_info_esp);
-
-       pfs_name=strchr(alg_str, ';');
-       if (pfs_name)
-       {
-               memcpy(esp_buf, alg_str, pfs_name-alg_str);
-               esp_buf[pfs_name-alg_str] = 0;
-               alg_str = esp_buf;
-               pfs_name++;
-
-               /* if pfs strings AND first char is not '0' */
-               if (*pfs_name && pfs_name[0] != '0')
-               {
-                       const proposal_token_t *token;
-
-                       token = proposal_get_token(pfs_name, strlen(pfs_name));
-                       if (token == NULL || token->type != DIFFIE_HELLMAN_GROUP)
-                       {
-                               /* Bomb if pfsgroup not found */
-                               DBG(DBG_CRYPT,
-                                       DBG_log("alg_info_esp_create_from_str(): pfsgroup \"%s\" not found"
-                                               , pfs_name)
-                               )
-                               status = FAILED;
-                               goto out;
-                       }
-                       alg_info_esp->esp_pfsgroup = token->algorithm;
-               }
-       }
-       else
-       {
-               alg_info_esp->esp_pfsgroup = 0;
-       }
-       alg_info_esp->alg_info_protoid = PROTO_IPSEC_ESP;
-       status = alg_info_parse_str((struct alg_info *)alg_info_esp, alg_str);
-
-out:
-       if (status == SUCCESS)
-       {
-               alg_info_esp->ref_cnt = 1;
-               return alg_info_esp;
-       }
-       else
-       {
-               free(alg_info_esp);
-               return NULL;
-       }
-}
-
-struct alg_info_ike *alg_info_ike_create_from_str(char *alg_str)
-{
-       struct alg_info_ike *alg_info_ike;
-       /*
-        * alg_info storage should be sized dynamically
-        * but this may require 2passes to know
-        * transform count in advance.
-        */
-       alg_info_ike = malloc_thing (struct alg_info_ike);
-       zero(alg_info_ike);
-       alg_info_ike->alg_info_protoid = PROTO_ISAKMP;
-
-       if (alg_info_parse_str((struct alg_info *)alg_info_ike, alg_str) == SUCCESS)
-       {
-               alg_info_ike->ref_cnt = 1;
-               return alg_info_ike;
-       }
-       else
-       {
-               free(alg_info_ike);
-               return NULL;
-       }
-}
-
-/*
- *      alg_info struct can be shared by
- *      several connections instances,
- *      handle free() with ref_cnts
- */
-void
-alg_info_addref(struct alg_info *alg_info)
-{
-       if (alg_info != NULL)
-       {
-               alg_info->ref_cnt++;
-       }
-}
-
-void
-alg_info_delref(struct alg_info **alg_info_p)
-{
-       struct alg_info *alg_info = *alg_info_p;
-
-       if (alg_info != NULL)
-       {
-               passert(alg_info->ref_cnt != 0);
-               alg_info->ref_cnt--;
-               if (alg_info->ref_cnt == 0)
-               {
-                       alg_info_free(alg_info);
-               }
-               *alg_info_p = NULL;
-       }
-}
-
-/* snprint already parsed transform list (alg_info) */
-int
-alg_info_snprint(char *buf, int buflen, struct alg_info *alg_info)
-{
-       char *ptr = buf;
-       int np = 0;
-       struct esp_info *esp_info;
-       struct ike_info *ike_info;
-       int cnt;
-
-       switch (alg_info->alg_info_protoid) {
-       case PROTO_IPSEC_ESP:
-               {
-                       struct alg_info_esp *alg_info_esp = (struct alg_info_esp *)alg_info;
-
-                       ALG_INFO_ESP_FOREACH(alg_info_esp, esp_info, cnt)
-                       {
-                               np = snprintf(ptr, buflen, "%s",
-                                               enum_show(&esp_transform_names, esp_info->esp_ealg_id));
-                               ptr += np;
-                               buflen -= np;
-                               if (esp_info->esp_ealg_keylen)
-                               {
-                                       np = snprintf(ptr, buflen, "_%zu", esp_info->esp_ealg_keylen);
-                                       ptr += np;
-                                       buflen -= np;
-                               }
-                               np = snprintf(ptr, buflen, "/%s, ",
-                                               enum_show(&auth_alg_names, esp_info->esp_aalg_id));
-                               ptr += np;
-                               buflen -= np;
-                               if (buflen < 0)
-                                       goto out;
-                       }
-                       if (alg_info_esp->esp_pfsgroup)
-                       {
-                               np = snprintf(ptr, buflen, "; pfsgroup=%s; ",
-                                               enum_show(&oakley_group_names, alg_info_esp->esp_pfsgroup));
-                               ptr += np;
-                               buflen -= np;
-                               if (buflen < 0)
-                                       goto out;
-                       }
-                       break;
-               }
-
-       case PROTO_ISAKMP:
-               ALG_INFO_IKE_FOREACH((struct alg_info_ike *)alg_info, ike_info, cnt)
-               {
-                       np = snprintf(ptr, buflen, "%s",
-                                       enum_show(&oakley_enc_names, ike_info->ike_ealg));
-                       ptr += np;
-                       buflen -= np;
-                       if (ike_info->ike_eklen)
-                       {
-                               np = snprintf(ptr, buflen, "_%zu", ike_info->ike_eklen);
-                               ptr += np;
-                               buflen -= np;
-                       }
-                       np = snprintf(ptr, buflen, "/%s/%s, ",
-                                       enum_show(&oakley_hash_names, ike_info->ike_halg),
-                                       enum_show(&oakley_group_names, ike_info->ike_modp));
-                       ptr += np;
-                       buflen -= np;
-                       if (buflen < 0)
-                               goto out;
-               }
-               break;
-       default:
-               np = snprintf(buf, buflen, "INVALID protoid=%d\n"
-                               , alg_info->alg_info_protoid);
-               ptr += np;
-               buflen -= np;
-               goto out;
-   }
-
-   np = snprintf(ptr, buflen, "%s"
-                       , alg_info->alg_info_flags & ALG_INFO_F_STRICT?
-                       "strict":"");
-   ptr += np;
-   buflen -= np;
-out:
-       if (buflen < 0)
-       {
-               loglog(RC_LOG_SERIOUS
-                       , "buffer space exhausted in alg_info_snprint_ike(), buflen=%d"
-                       , buflen);
-       }
-
-       return ptr - buf;
-}
-
-int alg_info_snprint_esp(char *buf, int buflen, struct alg_info_esp *alg_info)
-{
-       char *ptr = buf;
-
-       int cnt = alg_info->alg_info_cnt;
-       struct esp_info *esp_info = alg_info->esp;
-
-       while (cnt--)
-       {
-               if (kernel_alg_esp_enc_ok(esp_info->esp_ealg_id, 0, NULL)
-               &&  kernel_alg_esp_auth_ok(esp_info->esp_aalg_id, NULL))
-               {
-                       u_int eklen = (esp_info->esp_ealg_keylen)
-                                       ? esp_info->esp_ealg_keylen
-                                       : kernel_alg_esp_enc_keylen(esp_info->esp_ealg_id)
-                                                       * BITS_PER_BYTE;
-
-                       u_int aklen = esp_info->esp_aalg_keylen
-                                       ? esp_info->esp_aalg_keylen
-                                       : kernel_alg_esp_auth_keylen(esp_info->esp_aalg_id)
-                                                       * BITS_PER_BYTE;
-
-                       int ret = snprintf(ptr, buflen, "%d_%03d-%d_%03d, ",
-                                                  esp_info->esp_ealg_id, eklen,
-                                                  esp_info->esp_aalg_id, aklen);
-                       ptr += ret;
-                       buflen -= ret;
-                       if (buflen < 0)
-                               break;
-               }
-               esp_info++;
-       }
-       return ptr - buf;
-}
-
-int alg_info_snprint_ike(char *buf, int buflen, struct alg_info_ike *alg_info)
-{
-       char *ptr = buf;
-
-       int cnt = alg_info->alg_info_cnt;
-       struct ike_info *ike_info = alg_info->ike;
-
-       while (cnt--)
-       {
-               struct encrypt_desc *enc_desc = ike_alg_get_crypter(ike_info->ike_ealg);
-               struct hash_desc *hash_desc = ike_alg_get_hasher(ike_info->ike_halg);
-               struct dh_desc *dh_desc = ike_alg_get_dh_group(ike_info->ike_modp);
-
-               if (enc_desc &&  hash_desc && dh_desc)
-               {
-
-                       u_int eklen = (ike_info->ike_eklen)
-                                               ? ike_info->ike_eklen
-                                               : enc_desc->keydeflen;
-
-                       u_int aklen = (ike_info->ike_hklen)
-                                               ? ike_info->ike_hklen
-                                               : hash_desc->hash_digest_size * BITS_PER_BYTE;
-
-                       int ret = snprintf(ptr, buflen, "%d_%03d-%d_%03d-%d, ",
-                                                  ike_info->ike_ealg, eklen,
-                                                  ike_info->ike_halg, aklen,
-                                                  ike_info->ike_modp);
-                       ptr += ret;
-                       buflen -= ret;
-                       if (buflen < 0)
-                               break;
-               }
-               ike_info++;
-       }
-       return ptr - buf;
-}
-
diff --git a/src/pluto/alg_info.h b/src/pluto/alg_info.h
deleted file mode 100644 (file)
index 85b88dd..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/* Algorithm info parsing and creation functions
- * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef ALG_INFO_H
-#define ALG_INFO_H
-
-struct esp_info {
-               u_int8_t transid;       /* ESP transform */
-               u_int16_t auth;         /* AUTH */
-               size_t enckeylen;       /* keylength for ESP transform */
-               size_t authkeylen;      /* keylength for AUTH */
-               u_int8_t encryptalg;    /* normally  encryptalg=transid */
-               u_int8_t authalg;       /* normally  authalg=auth+1 */
-};
-
-struct ike_info {
-               u_int16_t ike_ealg;     /* high 16 bit nums for reserved */
-               u_int8_t ike_halg;
-               size_t ike_eklen;
-               size_t ike_hklen;
-               u_int16_t ike_modp;
-};
-
-#define ALG_INFO_COMMON \
-               int alg_info_cnt;               \
-               int ref_cnt;                    \
-               unsigned alg_info_flags;        \
-               unsigned alg_info_protoid
-
-struct alg_info {
-               ALG_INFO_COMMON;
-};
-
-struct alg_info_esp {
-               ALG_INFO_COMMON;
-               struct esp_info esp[64];
-               int esp_pfsgroup;
-};
-
-struct alg_info_ike {
-               ALG_INFO_COMMON;
-               struct ike_info ike[64];
-};
-#define esp_ealg_id transid
-#define esp_aalg_id auth
-#define esp_ealg_keylen enckeylen       /* bits */
-#define esp_aalg_keylen authkeylen      /* bits */
-
-/*      alg_info_flags bits */
-#define ALG_INFO_F_STRICT       0x01
-
-extern int alg_info_esp_aa2sadb(int auth);
-extern int alg_info_esp_sadb2aa(int sadb_aalg);
-extern void alg_info_free(struct alg_info *alg_info);
-extern void alg_info_addref(struct alg_info *alg_info);
-extern void alg_info_delref(struct alg_info **alg_info);
-extern struct alg_info_esp* alg_info_esp_create_from_str(char *alg_str);
-extern struct alg_info_ike* alg_info_ike_create_from_str(char *alg_str);
-extern int alg_info_parse(const char *str);
-extern int alg_info_snprint(char *buf, int buflen, struct alg_info *alg_info);
-extern int alg_info_snprint_esp(char *buf, int buflen
-       , struct alg_info_esp *alg_info);
-extern int alg_info_snprint_ike(char *buf, int buflen
-       , struct alg_info_ike *alg_info);
-#define ALG_INFO_ESP_FOREACH(ai, ai_esp, i) \
-               for (i=(ai)->alg_info_cnt,ai_esp=(ai)->esp; i--; ai_esp++)
-#define ALG_INFO_IKE_FOREACH(ai, ai_ike, i) \
-               for (i=(ai)->alg_info_cnt,ai_ike=(ai)->ike; i--; ai_ike++)
-#endif /* ALG_INFO_H */
diff --git a/src/pluto/builder.c b/src/pluto/builder.c
deleted file mode 100644 (file)
index a6e05a3..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/* Pluto certificate/CRL/AC builder hooks.
- * Copyright (C) 2002-2009 Andreas Steffen
- * Copyright (C) 2009 Martin Willi
- * HSR Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include "builder.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <time.h>
-
-#include <freeswan.h>
-
-#include <library.h>
-#include <credentials/certificates/certificate.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "certs.h"
-#include "crl.h"
-
-/**
- * Load a certificate
- */
-static cert_t *builder_load_cert(certificate_type_t type, va_list args)
-{
-       x509_flag_t flags = 0;
-       chunk_t blob = chunk_empty;
-       bool pgp = FALSE;
-
-       while (TRUE)
-       {
-               switch (va_arg(args, builder_part_t))
-               {
-                       case BUILD_BLOB_PGP:
-                               pgp = TRUE;
-                               /* FALL */
-                       case BUILD_BLOB_ASN1_DER:
-                               blob = va_arg(args, chunk_t);
-                               continue;
-                       case BUILD_X509_FLAG:
-                               flags |= va_arg(args, x509_flag_t);
-                               continue;
-                       case BUILD_END:
-                               break;
-                       default:
-                               return NULL;
-               }
-               break;
-       }
-       if (blob.ptr)
-       {
-               cert_t *cert = malloc_thing(cert_t);
-
-               *cert = cert_empty;
-
-               if (pgp)
-               {
-                       cert->cert = lib->creds->create(lib->creds,
-                                                                                  CRED_CERTIFICATE, CERT_GPG,
-                                                                                  BUILD_BLOB_PGP, blob,
-                                                                                  BUILD_END);
-               }
-               else
-               {
-                       cert->cert = lib->creds->create(lib->creds,
-                                                                                  CRED_CERTIFICATE, CERT_X509,
-                                                                                  BUILD_BLOB_ASN1_DER, blob,
-                                                                                  BUILD_X509_FLAG, flags,
-                                                                                  BUILD_END);
-               }
-               if (cert->cert)
-               {
-                       return cert;
-               }
-               plog("  error in X.509 certificate");
-               cert_free(cert);
-       }
-       return NULL;
-}
-
-/**
- * Load a CRL
- */
-static x509crl_t *builder_load_crl(certificate_type_t type, va_list args)
-{
-       chunk_t blob = chunk_empty;
-       x509crl_t *crl;
-
-       while (TRUE)
-       {
-               switch (va_arg(args, builder_part_t))
-               {
-                       case BUILD_BLOB_ASN1_DER:
-                               blob = va_arg(args, chunk_t);
-                               continue;
-                       case BUILD_END:
-                               break;
-                       default:
-                               return NULL;
-               }
-               break;
-       }
-       if (blob.ptr)
-       {
-               crl = malloc_thing(x509crl_t);
-               crl->next = NULL;
-               crl->distributionPoints = linked_list_create();
-               crl->crl = lib->creds->create(lib->creds,
-                                                                         CRED_CERTIFICATE, CERT_X509_CRL,
-                                                                         BUILD_BLOB_ASN1_DER, blob,
-                                                                         BUILD_END);
-               if (crl->crl)
-               {
-                       return crl;
-               }
-               plog("  error in X.509 crl");
-               free_crl(crl);
-       }
-       return NULL;
-}
-
-void init_builder(void)
-{
-       lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_PLUTO_CERT, FALSE,
-                                                       (builder_function_t)builder_load_cert);
-       lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_PLUTO_CRL, FALSE,
-                                                       (builder_function_t)builder_load_crl);
-}
-
-void free_builder(void)
-{
-       lib->creds->remove_builder(lib->creds, (builder_function_t)builder_load_cert);
-       lib->creds->remove_builder(lib->creds, (builder_function_t)builder_load_crl);
-}
-
diff --git a/src/pluto/builder.h b/src/pluto/builder.h
deleted file mode 100644 (file)
index 784751b..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Pluto certificate/CRL/AC builder hooks.
- * Copyright (C) 2009 Martin Willi
- * HSR Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef _BUILDER_H
-#define _BUILDER_H
-
-/* register credential builder hooks */
-extern void init_builder();
-/* unregister credential builder hooks */
-extern void free_builder();
-
-#endif /* _BUILDER_H */
diff --git a/src/pluto/ca.c b/src/pluto/ca.c
deleted file mode 100644 (file)
index 827b981..0000000
+++ /dev/null
@@ -1,712 +0,0 @@
-/* Certification Authority (CA) support for IKE authentication
- * Copyright (C) 2002-2004 Andreas Steffen, Zuercher Hochschule Winterthur
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <debug.h>
-#include <utils/enumerator.h>
-#include <credentials/certificates/x509.h>
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "x509.h"
-#include "ca.h"
-#include "certs.h"
-#include "whack.h"
-#include "fetch.h"
-#include "smartcard.h"
-
-/* chained list of X.509 authority certificates (ca, aa, and ocsp) */
-
-static cert_t *x509authcerts = NULL;
-
-/* chained list of X.509 certification authority information records */
-
-static ca_info_t *ca_infos = NULL;
-
-/*
- * Checks if CA a is trusted by CA b
- */
-bool trusted_ca(identification_t *a, identification_t *b, int *pathlen)
-{
-       bool match = FALSE;
-
-       /* no CA b specified -> any CA a is accepted */
-       if (b == NULL)
-       {
-               *pathlen = (a == NULL) ? 0 : X509_MAX_PATH_LEN;
-               return TRUE;
-       }
-
-       /* no CA a specified -> trust cannot be established */
-       if (a == NULL)
-       {
-               *pathlen = X509_MAX_PATH_LEN;
-               return FALSE;
-       }
-
-       *pathlen = 0;
-
-       /* CA a equals CA b -> we have a match */
-       if (a->equals(a, b))
-       {
-               return TRUE;
-       }
-
-       /* CA a might be a subordinate CA of b */
-       lock_authcert_list("trusted_ca");
-
-       while ((*pathlen)++ < X509_MAX_PATH_LEN)
-       {
-               certificate_t *certificate;
-               identification_t *issuer;
-               cert_t *cacert;
-
-               cacert = get_authcert(a, chunk_empty, X509_CA);
-               if (cacert == NULL)
-               {
-                       break;
-               }
-               certificate = cacert->cert;
-
-               /* is the certificate self-signed? */
-               {
-                       x509_t *x509 = (x509_t*)certificate;
-
-                       if (x509->get_flags(x509) & X509_SELF_SIGNED)
-                       {
-                               break;
-                       }
-               }
-
-               /* does the issuer of CA a match CA b? */
-               issuer = certificate->get_issuer(certificate);
-               match = b->equals(b, issuer);
-
-               /* we have a match and exit the loop */
-               if (match)
-               {
-                       break;
-               }
-               /* go one level up in the CA chain */
-               a = issuer;
-       }
-
-       unlock_authcert_list("trusted_ca");
-       return match;
-}
-
-/*
- * does our CA match one of the requested CAs?
- */
-bool match_requested_ca(linked_list_t *requested_ca, identification_t *our_ca,
-                                               int *our_pathlen)
-{
-       identification_t *ca;
-       enumerator_t *enumerator;
-
-       /* if no ca is requested than any ca will match */
-       if (requested_ca == NULL || requested_ca->get_count(requested_ca) == 0)
-       {
-               *our_pathlen = 0;
-               return TRUE;
-       }
-
-       *our_pathlen = X509_MAX_PATH_LEN + 1;
-
-       enumerator = requested_ca->create_enumerator(requested_ca);
-       while (enumerator->enumerate(enumerator, &ca))
-       {
-               int pathlen;
-
-               if (trusted_ca(our_ca, ca, &pathlen) && pathlen < *our_pathlen)
-               {
-                       *our_pathlen = pathlen;
-               }
-       }
-       enumerator->destroy(enumerator);
-
-       if (*our_pathlen > X509_MAX_PATH_LEN)
-       {
-               *our_pathlen = X509_MAX_PATH_LEN;
-               return FALSE;
-       }
-       else
-       {
-               return TRUE;
-       }
-}
-
-/*
- *  free the first authority certificate in the chain
- */
-static void free_first_authcert(void)
-{
-       cert_t *first = x509authcerts;
-
-       x509authcerts = first->next;
-       cert_free(first);
-}
-
-/*
- *  free  all CA certificates
- */
-void free_authcerts(void)
-{
-       lock_authcert_list("free_authcerts");
-
-       while (x509authcerts != NULL)
-       {
-               free_first_authcert();
-       }
-       unlock_authcert_list("free_authcerts");
-}
-
-/*
- *  get a X.509 authority certificate with a given subject or keyid
- */
-cert_t* get_authcert(identification_t *subject, chunk_t keyid,
-                                                x509_flag_t auth_flags)
-{
-       cert_t *cert, *prev_cert = NULL;
-
-       /* the authority certificate list is empty */
-       if (x509authcerts == NULL)
-       {
-               return NULL;
-       }
-
-       for (cert = x509authcerts; cert != NULL; prev_cert = cert, cert = cert->next)
-       {
-               certificate_t *certificate = cert->cert;
-               x509_t *x509 = (x509_t*)certificate;
-
-               /* skip non-matching types of authority certificates */
-               if (!(x509->get_flags(x509) & auth_flags))
-               {
-                       continue;
-               }
-
-               /* compare the keyid with the certificate's subjectKeyIdentifier */
-               if (keyid.ptr)
-               {
-                       chunk_t subjectKeyId;
-
-                       subjectKeyId = x509->get_subjectKeyIdentifier(x509);
-                       if (subjectKeyId.ptr && !chunk_equals(keyid, subjectKeyId))
-                       {
-                               continue;
-                       }
-               }
-
-               /* compare the subjectDistinguishedNames */
-               if (!(subject && certificate->has_subject(certificate, subject)) &&
-                        (subject || !keyid.ptr))
-               {
-                       continue;
-               }
-
-               /* found the authcert */
-               if (cert != x509authcerts)
-               {
-                       /* bring the certificate up front */
-                       prev_cert->next = cert->next;
-                       cert->next = x509authcerts;
-                       x509authcerts = cert;
-               }
-               return cert;
-       }
-       return NULL;
-}
-
-/*
- * add an authority certificate to the chained list
- */
-cert_t* add_authcert(cert_t *cert, x509_flag_t auth_flags)
-{
-       certificate_t *certificate = cert->cert;
-       x509_t *x509 = (x509_t*)certificate;
-       cert_t *old_cert;
-
-       lock_authcert_list("add_authcert");
-
-       old_cert = get_authcert(certificate->get_subject(certificate),
-                                                       x509->get_subjectKeyIdentifier(x509),
-                                                       auth_flags);
-       if (old_cert)
-       {
-               if (certificate->equals(certificate, old_cert->cert))
-               {
-                       DBG(DBG_CONTROL | DBG_PARSING ,
-                               DBG_log("  authcert is already present and identical")
-                       )
-                       unlock_authcert_list("add_authcert");
-
-                       cert_free(cert);
-                       return old_cert;
-               }
-               else
-               {
-                       /* cert is already present but will be replaced by new cert */
-                       free_first_authcert();
-                       DBG(DBG_CONTROL | DBG_PARSING ,
-                               DBG_log("  existing authcert deleted")
-                       )
-               }
-       }
-
-       /* add new authcert to chained list */
-       cert->next = x509authcerts;
-       x509authcerts = cert;
-       cert_share(cert);  /* set count to one */
-       DBG(DBG_CONTROL | DBG_PARSING,
-               DBG_log("  authcert inserted")
-       )
-       unlock_authcert_list("add_authcert");
-       return cert;
-}
-
-/*
- *  Loads authority certificates
- */
-void load_authcerts(char *type, char *path, x509_flag_t auth_flags)
-{
-       enumerator_t *enumerator;
-       struct stat st;
-       char *file;
-
-       DBG1(DBG_LIB, "loading %s certificates from '%s'", type, path);
-
-       enumerator = enumerator_create_directory(path);
-       if (!enumerator)
-       {
-               DBG1(DBG_LIB, "  reading directory '%s' failed", path);
-               return;
-       }
-
-       while (enumerator->enumerate(enumerator, NULL, &file, &st))
-       {
-               cert_t *cert;
-
-               if (!S_ISREG(st.st_mode))
-               {
-                       /* skip special file */
-                       continue;
-               }
-               cert = load_cert(file, type, auth_flags);
-               if (cert)
-               {
-                       add_authcert(cert, auth_flags);
-               }
-       }
-       enumerator->destroy(enumerator);
-}
-
-/*
- *  list all X.509 authcerts with given auth flags in a chained list
- */
-void list_authcerts(const char *caption, x509_flag_t auth_flags, bool utc)
-{
-       lock_authcert_list("list_authcerts");
-       list_x509cert_chain(caption, x509authcerts, auth_flags, utc);
-       unlock_authcert_list("list_authcerts");
-}
-
-/*
- * get a cacert with a given subject or keyid from an alternative list
- */
-static const cert_t* get_alt_cacert(identification_t *subject, chunk_t keyid,
-                                                                               const cert_t *cert)
-{
-       if (cert == NULL)
-       {
-               return NULL;
-       }
-       for (; cert != NULL; cert = cert->next)
-       {
-               certificate_t *certificate = cert->cert;
-
-               /* compare the keyid with the certificate's subjectKeyIdentifier */
-               if (keyid.ptr)
-               {
-                       x509_t *x509 = (x509_t*)certificate;
-                       chunk_t subjectKeyId;
-
-                       subjectKeyId = x509->get_subjectKeyIdentifier(x509);
-                       if (subjectKeyId.ptr && !chunk_equals(keyid, subjectKeyId))
-                       {
-                               continue;
-                       }
-               }
-
-               /* compare the subjectDistinguishedNames */
-               if (!certificate->has_subject(certificate, subject))
-               {
-                       continue;
-               }
-
-               /* we found the cacert */
-               return cert;
-       }
-       return NULL;
-}
-
-/* establish trust into a candidate authcert by going up the trust chain.
- * validity and revocation status are not checked.
- */
-bool trust_authcert_candidate(const cert_t *cert, const cert_t *alt_chain)
-{
-       int pathlen;
-
-       lock_authcert_list("trust_authcert_candidate");
-
-       for (pathlen = 0; pathlen < X509_MAX_PATH_LEN; pathlen++)
-       {
-               certificate_t *certificate = cert->cert;
-               x509_t *x509 = (x509_t*)certificate;
-               identification_t *subject = certificate->get_subject(certificate);
-               identification_t *issuer = certificate->get_issuer(certificate);
-               chunk_t authKeyID = x509->get_authKeyIdentifier(x509);
-               const cert_t *authcert = NULL;
-
-               DBG(DBG_CONTROL,
-                       DBG_log("subject: '%Y'", subject);
-                       DBG_log("issuer:  '%Y'", issuer);
-                       if (authKeyID.ptr != NULL)
-                       {
-                               DBG_log("authkey:  %#B", &authKeyID);
-                       }
-               )
-
-               /* search in alternative chain first */
-               authcert = get_alt_cacert(issuer, authKeyID, alt_chain);
-
-               if (authcert != NULL)
-               {
-                       DBG(DBG_CONTROL,
-                               DBG_log("issuer cacert found in alternative chain")
-                       )
-               }
-               else
-               {
-                       /* search in trusted chain */
-                       authcert = get_authcert(issuer, authKeyID, X509_CA);
-
-                       if (authcert != NULL)
-                       {
-                               DBG(DBG_CONTROL,
-                                       DBG_log("issuer cacert found")
-                               )
-                       }
-                       else
-                       {
-                               plog("issuer cacert not found");
-                               unlock_authcert_list("trust_authcert_candidate");
-                               return FALSE;
-                       }
-               }
-
-               if (!certificate->issued_by(certificate, authcert->cert))
-               {
-                       plog("certificate signature is invalid");
-                       unlock_authcert_list("trust_authcert_candidate");
-                       return FALSE;
-               }
-               DBG(DBG_CONTROL,
-                       DBG_log("certificate signature is valid")
-               )
-
-               /* check if cert is a self-signed root ca */
-               if (pathlen > 0 && (x509->get_flags(x509) & X509_SELF_SIGNED))
-               {
-                       DBG(DBG_CONTROL,
-                               DBG_log("reached self-signed root ca")
-                       )
-                       unlock_authcert_list("trust_authcert_candidate");
-                       return TRUE;
-               }
-
-               /* go up one step in the trust chain */
-               cert = authcert;
-       }
-       plog("maximum ca path length of %d levels exceeded", X509_MAX_PATH_LEN);
-       unlock_authcert_list("trust_authcert_candidate");
-       return FALSE;
-}
-
-/*
- *  get a CA info record with a given authName or authKeyID
- */
-ca_info_t* get_ca_info(identification_t *name, chunk_t keyid)
-{
-       ca_info_t *ca= ca_infos;
-
-       while (ca != NULL)
-       {
-               if ((keyid.ptr) ? same_keyid(keyid, ca->authKeyID)
-                       : name->equals(name, ca->authName))
-               {
-                       return ca;
-               }
-               ca = ca->next;
-       }
-       return NULL;
-}
-
-
-/*
- *  free the dynamic memory used by a ca_info record
- */
-static void
-free_ca_info(ca_info_t* ca_info)
-{
-       if (ca_info == NULL)
-       {
-               return;
-       }
-       ca_info->crluris->destroy_function(ca_info->crluris, free);
-       DESTROY_IF(ca_info->authName);
-       free(ca_info->name);
-       free(ca_info->ldaphost);
-       free(ca_info->ldapbase);
-       free(ca_info->ocspuri);
-       free(ca_info->authKeyID.ptr);
-       free(ca_info);
-}
-
-/*
- *  free  all CA certificates
- */
-void free_ca_infos(void)
-{
-       while (ca_infos != NULL)
-       {
-               ca_info_t *ca = ca_infos;
-
-               ca_infos = ca_infos->next;
-               free_ca_info(ca);
-       }
-}
-
-/*
- * find a CA information record by name and optionally delete it
- */
-bool find_ca_info_by_name(const char *name, bool delete)
-{
-       ca_info_t **ca_p = &ca_infos;
-       ca_info_t *ca = *ca_p;
-
-       while (ca != NULL)
-       {
-               /* is there already an entry? */
-               if (streq(name, ca->name))
-               {
-                       if (delete)
-                       {
-                               lock_ca_info_list("find_ca_info_by_name");
-                               *ca_p = ca->next;
-                               free_ca_info(ca);
-                               plog("deleting ca description \"%s\"", name);
-                               unlock_ca_info_list("find_ca_info_by_name");
-                       }
-                       return TRUE;
-               }
-               ca_p = &ca->next;
-               ca = *ca_p;
-       }
-       return FALSE;
-}
-
-/*
- * Create an empty ca_info_t record
- */
-ca_info_t* create_ca_info(void)
-{
-       ca_info_t *ca_info = malloc_thing(ca_info_t);
-
-       memset(ca_info, 0, sizeof(ca_info_t));
-       ca_info->crluris = linked_list_create();
-
-       return ca_info;
-}
-
-/**
- * Adds a CA description to a chained list
- */
-void add_ca_info(const whack_message_t *msg)
-{
-       smartcard_t *sc = NULL;
-       cert_t *cert = NULL;
-       bool cached_cert = FALSE;
-
-       if (find_ca_info_by_name(msg->name, FALSE))
-       {
-               loglog(RC_DUPNAME, "attempt to redefine ca record \"%s\"", msg->name);
-               return;
-       }
-
-       if (scx_on_smartcard(msg->cacert))
-       {
-               /* load CA cert from smartcard */
-               cert = scx_load_cert(msg->cacert, &sc, &cached_cert);
-       }
-       else
-       {
-               /* load CA cert from file */
-               cert = load_ca_cert(msg->cacert);
-       }
-
-       if (cert)
-       {
-               certificate_t *certificate = cert->cert;
-               x509_t *x509 = (x509_t*)certificate;
-               identification_t *subject = certificate->get_subject(certificate);
-               chunk_t subjectKeyID = x509->get_subjectKeyIdentifier(x509);
-               ca_info_t *ca = NULL;
-
-               /* does the authname already exist? */
-               ca = get_ca_info(subject, subjectKeyID);
-
-               if (ca != NULL)
-               {
-                       /* ca_info is already present */
-                       loglog(RC_DUPNAME, "  duplicate ca information in record \"%s\" found,"
-                                                          "ignoring \"%s\"", ca->name, msg->name);
-                       cert_free(cert);
-                       return;
-               }
-
-               plog("added ca description \"%s\"", msg->name);
-
-               /* create and initialize new ca_info record */
-               ca = create_ca_info();
-
-               /* name */
-               ca->name = clone_str(msg->name);
-
-               /* authName */
-               ca->authName = subject->clone(subject);
-               DBG(DBG_CONTROL,
-                       DBG_log("authname: '%Y'", subject)
-               )
-
-               /* authKeyID */
-               if (subjectKeyID.ptr)
-               {
-                       ca->authKeyID = chunk_clone(subjectKeyID);
-                       DBG(DBG_CONTROL | DBG_PARSING ,
-                               DBG_log("authkey:  %#B", &subjectKeyID)
-                       )
-               }
-
-               /* ldaphost */
-               ca->ldaphost = clone_str(msg->ldaphost);
-
-               /* ldapbase */
-               ca->ldapbase = clone_str(msg->ldapbase);
-
-               /* ocspuri */
-               if (msg->ocspuri != NULL)
-               {
-                       if (strncasecmp(msg->ocspuri, "http", 4) == 0)
-                               ca->ocspuri = clone_str(msg->ocspuri);
-                       else
-                               plog("  ignoring ocspuri with unknown protocol");
-               }
-
-               /* add crl uris */
-               add_distribution_point(ca->crluris, msg->crluri);
-               add_distribution_point(ca->crluris, msg->crluri2);
-
-               /* strictrlpolicy */
-               ca->strictcrlpolicy = msg->whack_strict;
-
-               /* insert ca_info record into the chained list */
-               lock_ca_info_list("add_ca_info");
-
-               ca->next = ca_infos;
-               ca_infos = ca;
-
-               unlock_ca_info_list("add_ca_info");
-
-               /* add cacert to list of authcerts */
-               cert = add_authcert(cert, X509_CA);
-               if (!cached_cert && sc != NULL)
-               {
-                       if (sc->last_cert != NULL)
-                       {
-                               sc->last_cert->count--;
-                       }
-                       sc->last_cert = cert;
-                       cert_share(sc->last_cert);
-               }
-               if (sc != NULL)
-                       time(&sc->last_load);
-       }
-}
-
-/*
- * list all ca_info records in the chained list
- */
-void list_ca_infos(bool utc)
-{
-       ca_info_t *ca = ca_infos;
-
-       if (ca != NULL)
-       {
-               whack_log(RC_COMMENT, " ");
-               whack_log(RC_COMMENT, "List of X.509 CA Information Records:");
-       }
-
-       while (ca != NULL)
-       {
-               /* strictpolicy per CA not supported yet
-                *
-               whack_log(RC_COMMENT, "%T, \"%s\", strictcrlpolicy: %s"
-                               , &ca->installed, utc, ca->name
-                               , ca->strictcrlpolicy? "yes":"no");
-               */
-               whack_log(RC_COMMENT, " ");
-               whack_log(RC_COMMENT, "  authname: \"%Y\"", ca->authName);
-               if (ca->ldaphost)
-               {
-                       whack_log(RC_COMMENT, "  ldaphost: '%s'", ca->ldaphost);
-               }
-               if (ca->ldapbase)
-               {
-                       whack_log(RC_COMMENT, "  ldapbase: '%s'", ca->ldapbase);
-               }
-               if (ca->ocspuri)
-               {
-                       whack_log(RC_COMMENT, "  ocspuri:  '%s'", ca->ocspuri);
-               }
-
-               list_distribution_points(ca->crluris);
-
-               if (ca->authKeyID.ptr)
-               {
-                       whack_log(RC_COMMENT, "  authkey:   %#B", &ca->authKeyID);
-               }
-               ca = ca->next;
-       }
-}
-
diff --git a/src/pluto/ca.h b/src/pluto/ca.h
deleted file mode 100644 (file)
index d964a69..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Certification Authority (CA) support for IKE authentication
- * Copyright (C) 2002-2004 Andreas Steffen, Zuercher Hochschule Winterthur
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef _CA_H
-#define _CA_H
-
-#include <utils/linked_list.h>
-#include <utils/identification.h>
-
-#include "certs.h"
-#include "whack.h"
-
-/* CA info structures */
-
-typedef struct ca_info ca_info_t;
-
-struct ca_info {
-       ca_info_t        *next;
-       char             *name;
-       identification_t *authName;
-       chunk_t           authKeyID;
-       char             *ldaphost;
-       char             *ldapbase;
-       char             *ocspuri;
-       linked_list_t    *crluris;
-       bool              strictcrlpolicy;
-};
-
-extern bool trusted_ca(identification_t *a, identification_t *b, int *pathlen);
-extern bool match_requested_ca(linked_list_t *requested_ca,
-                                                          identification_t *our_ca, int *our_pathlen);
-extern cert_t* get_authcert(identification_t *subject, chunk_t keyid,
-                                                               x509_flag_t auth_flags);
-extern void load_authcerts(char *type, char *path, x509_flag_t auth_flags);
-extern cert_t* add_authcert(cert_t *cert, x509_flag_t auth_flags);
-extern void free_authcerts(void);
-extern void list_authcerts(const char *caption, x509_flag_t auth_flags, bool utc);
-extern bool trust_authcert_candidate(const cert_t *cert, const cert_t *alt_chain);
-extern ca_info_t* get_ca_info(identification_t *name, chunk_t keyid);
-extern bool find_ca_info_by_name(const char *name, bool delete);
-extern void add_ca_info(const whack_message_t *msg);
-extern void delete_ca_info(const char *name);
-extern void free_ca_infos(void);
-extern void list_ca_infos(bool utc);
-
-#endif /* _CA_H */
-
diff --git a/src/pluto/certs.c b/src/pluto/certs.c
deleted file mode 100644 (file)
index e866022..0000000
+++ /dev/null
@@ -1,268 +0,0 @@
-/* Certificate support for IKE authentication
- * Copyright (C) 2002-2009 Andreas Steffen
- *
- * HSR - Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <time.h>
-
-#include <freeswan.h>
-
-#include <library.h>
-#include <asn1/asn1.h>
-#include <credentials/certificates/certificate.h>
-#include <credentials/certificates/pgp_certificate.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "certs.h"
-#include "whack.h"
-#include "fetch.h"
-#include "keys.h"
-#include "builder.h"
-
-/**
- * Initialization
- */
-const cert_t cert_empty = {
-       NULL   , /* cert */
-       NULL   , /* *next */
-         0    , /* count */
-       FALSE    /* smartcard */
-};
-
-/**
- * Chained lists of X.509 and PGP end entity certificates
- */
-static cert_t *certs = NULL;
-
-/**
- *  Free a pluto certificate
- */
-void cert_free(cert_t *cert)
-{
-       if (cert)
-       {
-               certificate_t *certificate = cert->cert;
-
-               if (certificate)
-               {
-                       certificate->destroy(certificate);
-               }
-               free(cert);
-       }
-}
-
-/**
- *  Add a pluto end entity certificate to the chained list
- */
-cert_t* cert_add(cert_t *cert)
-{
-       certificate_t *certificate = cert->cert;
-       cert_t *c;
-
-       lock_certs_and_keys("cert_add");
-
-       for (c = certs; c != NULL; c = c->next)
-       {
-               if (certificate->equals(certificate, c->cert))
-               {       /* already in chain, free cert */
-                       unlock_certs_and_keys("cert_add");
-                       cert_free(cert);
-                       return c;
-               }
-       }
-
-       /* insert new cert at the root of the chain */
-       cert->next = certs;
-       certs = cert;
-       DBG(DBG_CONTROL | DBG_PARSING,
-               DBG_log("  cert inserted")
-       )
-       unlock_certs_and_keys("cert_add");
-       return cert;
-}
-
-/**
- *  Loads a X.509 or OpenPGP certificate
- */
-cert_t* load_cert(char *filename, const char *label, x509_flag_t flags)
-{
-       cert_t *cert;
-
-       cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_PLUTO_CERT,
-                                                         BUILD_FROM_FILE, filename,
-                                                         BUILD_X509_FLAG, flags,
-                                                         BUILD_END);
-       if (cert)
-       {
-               plog("  loaded %s certificate from '%s'", label, filename);
-       }
-       return cert;
-}
-
-/**
- *  Loads a host certificate
- */
-cert_t* load_host_cert(char *filename)
-{
-       char *path = concatenate_paths(HOST_CERT_PATH, filename);
-
-       return load_cert(path, "host", X509_NONE);
-}
-
-/**
- *  Loads a CA certificate
- */
-cert_t* load_ca_cert(char *filename)
-{
-       char *path = concatenate_paths(CA_CERT_PATH, filename);
-
-       return load_cert(path, "CA", X509_NONE);
-}
-
-/**
- * for each link pointing to the certificate increase the count by one
- */
-void cert_share(cert_t *cert)
-{
-       if (cert != NULL)
-       {
-               cert->count++;
-       }
-}
-
-/*  release of a certificate decreases the count by one
- *  the certificate is freed when the counter reaches zero
- */
-void cert_release(cert_t *cert)
-{
-       if (cert && --cert->count == 0)
-       {
-               cert_t **pp = &certs;
-               while (*pp != cert)
-               {
-                       pp = &(*pp)->next;
-               }
-               *pp = cert->next;
-               cert_free(cert);
-       }
-}
-
-/**
- * Get a X.509 certificate with a given issuer found at a certain position
- */
-cert_t* get_x509cert(identification_t *issuer, chunk_t keyid, cert_t *chain)
-{
-       cert_t *cert = chain ? chain->next : certs;
-
-       while (cert)
-       {
-               certificate_t *certificate = cert->cert;
-               x509_t *x509 = (x509_t*)certificate;
-               chunk_t authKeyID = x509->get_authKeyIdentifier(x509);
-
-               if (keyid.ptr ? same_keyid(keyid, authKeyID) :
-                       certificate->has_issuer(certificate, issuer))
-               {
-                       return cert;
-               }
-               cert = cert->next;
-       }
-       return NULL;
-}
-
-/**
- *  List all PGP end certificates in a chained list
- */
-void list_pgp_end_certs(bool utc)
-{
-       cert_t *cert = certs;
-       time_t now = time(NULL);
-       bool first = TRUE;
-
-
-       while (cert != NULL)
-       {
-               certificate_t *certificate = cert->cert;
-
-               if (certificate->get_type(certificate) == CERT_GPG)
-               {
-                       time_t created, until;
-                       public_key_t *key;
-                       identification_t *userid = certificate->get_subject(certificate);
-                       pgp_certificate_t *pgp_cert = (pgp_certificate_t*)certificate;
-                       chunk_t fingerprint = pgp_cert->get_fingerprint(pgp_cert);
-
-                       if (first)
-                       {
-                               whack_log(RC_COMMENT, " ");
-                               whack_log(RC_COMMENT, "List of PGP End Entity Certificates:");
-                               first = false;
-                       }
-                       whack_log(RC_COMMENT, " ");
-                       whack_log(RC_COMMENT, "  userid:   '%Y'", userid);
-                       whack_log(RC_COMMENT, "  digest:    %#B", &fingerprint);
-
-                       /* list validity */
-                       certificate->get_validity(certificate, &now, &created, &until);
-                       whack_log(RC_COMMENT, "  created:   %T", &created, utc);
-                       whack_log(RC_COMMENT, "  until:     %T %s%s", &until, utc,
-                                       check_expiry(until, CA_CERT_WARNING_INTERVAL, TRUE),
-                                       (until == TIME_32_BIT_SIGNED_MAX) ? " (expires never)":"");
-
-                       key = certificate->get_public_key(certificate);
-                       if (key)
-                       {
-                               chunk_t keyid;
-
-                               whack_log(RC_COMMENT, "  pubkey:    %N %4d bits%s",
-                                               key_type_names, key->get_type(key),
-                                               key->get_keysize(key),
-                                               has_private_key(cert)? ", has private key" : "");
-                               if (key->get_fingerprint(key, KEYID_PUBKEY_INFO_SHA1, &keyid))
-                               {
-                                       whack_log(RC_COMMENT, "  keyid:     %#B", &keyid);
-                               }
-                               if (key->get_fingerprint(key, KEYID_PUBKEY_SHA1, &keyid))
-                               {
-                                       whack_log(RC_COMMENT, "  subjkey:   %#B", &keyid);
-                               }
-                       }
-               }
-               cert = cert->next;
-       }
-}
-
-/**
- * List all X.509 end certificates in a chained list
- */
-void list_x509_end_certs(bool utc)
-{
-       list_x509cert_chain("End Entity", certs, X509_NONE, utc);
-}
-
-/**
- *  list all X.509 and OpenPGP end certificates
- */
-void cert_list(bool utc)
-{
-       list_x509_end_certs(utc);
-       list_pgp_end_certs(utc);
-}
-
diff --git a/src/pluto/certs.h b/src/pluto/certs.h
deleted file mode 100644 (file)
index b31c4c3..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/* Certificate support for IKE authentication
- * Copyright (C) 2002-2009 Andreas Steffen
- *
- * HSR - Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef _CERTS_H
-#define _CERTS_H
-
-#include <credentials/keys/private_key.h>
-#include <credentials/certificates/certificate.h>
-#include <credentials/certificates/x509.h>
-
-#include <freeswan.h>
-
-#include "defs.h"
-
-/* path definitions for private keys, end certs,
- * cacerts, attribute certs and crls
- */
-#define PRIVATE_KEY_PATH  IPSEC_CONFDIR "/ipsec.d/private"
-#define HOST_CERT_PATH    IPSEC_CONFDIR "/ipsec.d/certs"
-#define CA_CERT_PATH      IPSEC_CONFDIR "/ipsec.d/cacerts"
-#define A_CERT_PATH       IPSEC_CONFDIR "/ipsec.d/acerts"
-#define AA_CERT_PATH      IPSEC_CONFDIR "/ipsec.d/aacerts"
-#define OCSP_CERT_PATH    IPSEC_CONFDIR "/ipsec.d/ocspcerts"
-#define CRL_PATH          IPSEC_CONFDIR "/ipsec.d/crls"
-#define REQ_PATH          IPSEC_CONFDIR "/ipsec.d/reqs"
-
-/* advance warning of imminent expiry of
- * cacerts, public keys, and crls
- */
-#define CA_CERT_WARNING_INTERVAL        30 /* days */
-#define OCSP_CERT_WARNING_INTERVAL      30 /* days */
-#define PUBKEY_WARNING_INTERVAL          7 /* days */
-#define CRL_WARNING_INTERVAL             7 /* days */
-#define ACERT_WARNING_INTERVAL           1 /* day */
-
-/* access structure for a pluto certificate */
-
-typedef struct cert_t cert_t;
-
-struct cert_t {
-       certificate_t  *cert;
-       cert_t         *next;
-       int             count;
-       bool            smartcard;
-};
-
-/* used for initialization */
-extern const cert_t cert_empty;
-
-/*  do not send certificate requests
- *  flag set in plutomain.c and used in ipsec_doi.c
- */
-extern bool no_cr_send;
-
-extern cert_t* load_cert(char *filename, const char *label, x509_flag_t flags);
-extern cert_t* load_host_cert(char *filename);
-extern cert_t* load_ca_cert(char *filename);
-extern cert_t* cert_add(cert_t *cert);
-extern void cert_free(cert_t *cert);
-extern void cert_share(cert_t *cert);
-extern void cert_release(cert_t *cert);
-extern void cert_list(bool utc);
-extern cert_t* get_x509cert(identification_t *issuer, chunk_t keyid, cert_t* chain);
-
-#endif /* _CERTS_H */
-
-
diff --git a/src/pluto/connections.c b/src/pluto/connections.c
deleted file mode 100644 (file)
index 27cec40..0000000
+++ /dev/null
@@ -1,4507 +0,0 @@
-/* information about connections between hosts and clients
- * Copyright (C) 1998-2002  D. Hugh Redelmeier.
- * Copyright (C) 2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <string.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <resolv.h>
-#include <arpa/nameser.h>       /* missing from <resolv.h> on old systems */
-#include <sys/queue.h>
-
-#include <freeswan.h>
-#include "kameipsec.h"
-
-#include <hydra.h>
-#include <credentials/certificates/ac.h>
-#include <credentials/keys/private_key.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "myid.h"
-#include "x509.h"
-#include "ca.h"
-#include "crl.h"
-#include "certs.h"
-#include "ac.h"
-#include "smartcard.h"
-#include "fetch.h"
-#include "connections.h"
-#include "foodgroups.h"
-#include "demux.h"
-#include "state.h"
-#include "timer.h"
-#include "ipsec_doi.h"  /* needs demux.h and state.h */
-#include "server.h"
-#include "kernel.h"
-#include "log.h"
-#include "keys.h"
-#include "adns.h"       /* needs <resolv.h> */
-#include "dnskey.h"     /* needs keys.h and adns.h */
-#include "whack.h"
-#include "alg_info.h"
-#include "ike_alg.h"
-#include "kernel_alg.h"
-#include "nat_traversal.h"
-#include "virtual.h"
-#include "whack_attribute.h"
-#include "modecfg.h"
-
-static void flush_pending_by_connection(connection_t *c);  /* forward */
-
-static connection_t *connections = NULL;
-
-/* struct host_pair: a nexus of information about a pair of hosts.
- * A host is an IP address, UDP port pair.  This is a debatable choice:
- * - should port be considered (no choice of port in standard)?
- * - should ID be considered (hard because not always known)?
- * - should IP address matter on our end (we don't know our end)?
- * Only oriented connections are registered.
- * Unoriented connections are kept on the unoriented_connections
- * linked list (using hp_next).  For them, host_pair is NULL.
- */
-
-struct host_pair {
-       struct {
-               ip_address addr;
-               u_int16_t port; /* host order */
-       } me, him;
-       bool initial_connection_sent;
-       connection_t *connections;     /* connections with this pair */
-       struct pending *pending;    /* awaiting Keying Channel */
-       struct host_pair *next;
-};
-
-static struct host_pair *host_pairs = NULL;
-
-static connection_t *unoriented_connections = NULL;
-
-/**
- * Check if an id was instantiated by assigning to it the current IP address
- */
-bool his_id_was_instantiated(const connection_t *c)
-{
-       if (c->kind != CK_INSTANCE)
-       {
-               return FALSE;
-       }
-       if (id_is_ipaddr(c->spd.that.id))
-       {
-               identification_t *host;
-               bool equal;
-
-               host = identification_create_from_sockaddr((sockaddr_t*)&c->spd.that.host_addr);
-               equal = host->equals(host, c->spd.that.id);
-               host->destroy(host);
-               return equal;
-       }
-       else
-       {
-               return TRUE;
-       }
-}
-
-/**
- * Check to see that IDs of peers match
- */
-bool same_peer_ids(const connection_t *c, const connection_t *d,
-                                  identification_t *his_id)
-{
-       return d->spd.this.id->equals(d->spd.this.id, c->spd.this.id) &&
-                  d->spd.that.id->equals(d->spd.that.id,
-                                                                 his_id ? his_id : c->spd.that.id);
-}
-
-static struct host_pair *find_host_pair(const ip_address *myaddr,
-                                                                               u_int16_t myport,
-                                                                               const ip_address *hisaddr,
-                                                                               u_int16_t hisport)
-{
-       struct host_pair *p, *prev;
-
-       /* default hisaddr to an appropriate any */
-       if (hisaddr == NULL)
-               hisaddr = aftoinfo(addrtypeof(myaddr))->any;
-
-       if (nat_traversal_enabled)
-       {
-               /**
-                * port is not relevant in host_pair. with nat_traversal we
-                * always use pluto_port (500)
-                */
-               myport = pluto_port;
-               hisport = pluto_port;
-       }
-
-       for (prev = NULL, p = host_pairs; p != NULL; prev = p, p = p->next)
-       {
-               if (sameaddr(&p->me.addr, myaddr) && p->me.port == myport
-               &&  sameaddr(&p->him.addr, hisaddr) && p->him.port == hisport)
-               {
-                       if (prev)
-                       {
-                               prev->next = p->next;   /* remove p from list */
-                               p->next = host_pairs;   /* and stick it on front */
-                               host_pairs = p;
-                       }
-                       break;
-               }
-       }
-       return p;
-}
-
-/* find head of list of connections with this pair of hosts */
-static connection_t *find_host_pair_connections(const ip_address *myaddr,
-                                                                                                        u_int16_t myport,
-                                                                                                        const ip_address *hisaddr,
-                                                                                                               u_int16_t hisport)
-{
-       struct host_pair *hp = find_host_pair(myaddr, myport, hisaddr, hisport);
-
-       if (nat_traversal_enabled && hp && hisaddr)
-       {
-               connection_t *c;
-
-               for (c = hp->connections; c != NULL; c = c->hp_next)
-               {
-                       if (c->spd.this.host_port == myport && c->spd.that.host_port == hisport)
-                               return c;
-               }
-               return NULL;
-       }
-       return hp == NULL? NULL : hp->connections;
-}
-
-static void connect_to_host_pair(connection_t *c)
-{
-       if (oriented(*c))
-       {
-               struct host_pair *hp;
-
-               ip_address his_addr = (c->spd.that.allow_any)
-                                                         ? *aftoinfo(addrtypeof(&c->spd.that.host_addr))->any
-                                                         : c->spd.that.host_addr;
-
-               hp = find_host_pair(&c->spd.this.host_addr, c->spd.this.host_port
-                       , &his_addr, c->spd.that.host_port);
-
-               if (hp == NULL)
-               {
-                       /* no suitable host_pair -- build one */
-                       hp = malloc_thing(struct host_pair);
-                       hp->me.addr = c->spd.this.host_addr;
-                       hp->him.addr = his_addr;
-                       hp->me.port = nat_traversal_enabled ? pluto_port : c->spd.this.host_port;
-                       hp->him.port = nat_traversal_enabled ? pluto_port : c->spd.that.host_port;
-                       hp->initial_connection_sent = FALSE;
-                       hp->connections = NULL;
-                       hp->pending = NULL;
-                       hp->next = host_pairs;
-                       host_pairs = hp;
-               }
-               c->host_pair = hp;
-               c->hp_next = hp->connections;
-               hp->connections = c;
-       }
-       else
-       {
-               /* since this connection isn't oriented, we place it
-                * in the unoriented_connections list instead.
-                */
-               c->host_pair = NULL;
-               c->hp_next = unoriented_connections;
-               unoriented_connections = c;
-       }
-}
-
-/* find a connection by name.
- * If strict, don't accept a CK_INSTANCE.
- * Move the winner (if any) to the front.
- * If none is found, and strict, a diagnostic is logged to whack.
- */
-connection_t *con_by_name(const char *nm, bool strict)
-{
-       connection_t *p, *prev;
-
-       for (prev = NULL, p = connections; ; prev = p, p = p->ac_next)
-       {
-               if (p == NULL)
-               {
-                       if (strict)
-                               whack_log(RC_UNKNOWN_NAME
-                                       , "no connection named \"%s\"", nm);
-                       break;
-               }
-               if (streq(p->name, nm)
-               && (!strict || p->kind != CK_INSTANCE))
-               {
-                       if (prev)
-                       {
-                               prev->ac_next = p->ac_next;     /* remove p from list */
-                               p->ac_next = connections;       /* and stick it on front */
-                               connections = p;
-                       }
-                       break;
-               }
-       }
-       return p;
-}
-
-void release_connection(connection_t *c, bool relations)
-{
-       if (c->kind == CK_INSTANCE)
-       {
-               /* This does everything we need.
-                * Note that we will be called recursively by delete_connection,
-                * but kind will be CK_GOING_AWAY.
-                */
-               delete_connection(c, relations);
-       }
-       else
-       {
-               flush_pending_by_connection(c);
-               delete_states_by_connection(c, relations);
-               unroute_connection(c);
-       }
-}
-
-/* Delete a connection */
-
-#define list_rm(etype, enext, e, ehead) { \
-               etype **ep; \
-               for (ep = &(ehead); *ep != (e); ep = &(*ep)->enext) \
-                       passert(*ep != NULL);    /* we must not come up empty-handed */ \
-               *ep = (e)->enext; \
-       }
-
-
-void delete_connection(connection_t *c, bool relations)
-{
-       modecfg_attribute_t *ca;
-       connection_t *old_cur_connection;
-       identification_t *client_id;
-
-       old_cur_connection = cur_connection == c? NULL : cur_connection;
-#ifdef DEBUG
-       lset_t old_cur_debugging = cur_debugging;
-#endif
-
-       set_cur_connection(c);
-
-       /* Must be careful to avoid circularity:
-        * we mark c as going away so it won't get deleted recursively.
-        */
-       passert(c->kind != CK_GOING_AWAY);
-       if (c->kind == CK_INSTANCE)
-       {
-               plog("deleting connection \"%s\" instance with peer %s {isakmp=#%lu/ipsec=#%lu}"
-                        , c->name
-                        , ip_str(&c->spd.that.host_addr)
-                        , c->newest_isakmp_sa, c->newest_ipsec_sa);
-               c->kind = CK_GOING_AWAY;
-       }
-       else
-       {
-               plog("deleting connection");
-       }
-       release_connection(c, relations);   /* won't delete c */
-
-       if (c->kind == CK_GROUP)
-       {
-               delete_group(c);
-       }
-
-       /* free up any logging resources */
-       perpeer_logfree(c);
-
-       /* find and delete c from connections list */
-       list_rm(connection_t, ac_next, c, connections);
-       cur_connection = old_cur_connection;
-
-       /* find and delete c from the host pair list */
-       if (c->host_pair == NULL)
-       {
-               if (c->ikev1)
-               {
-                       list_rm(connection_t, hp_next, c, unoriented_connections);
-               }
-       }
-       else
-       {
-               struct host_pair *hp = c->host_pair;
-
-               list_rm(connection_t, hp_next, c, hp->connections);
-               c->host_pair = NULL;    /* redundant, but safe */
-
-               /* if there are no more connections with this host_pair
-                * and we haven't even made an initial contact, let's delete
-                * this guy in case we were created by an attempted DOS attack.
-                */
-               if (hp->connections == NULL
-               && !hp->initial_connection_sent)
-               {
-                       passert(hp->pending == NULL);       /* ??? must deal with this! */
-                       list_rm(struct host_pair, next, hp, host_pairs);
-                       free(hp);
-               }
-       }
-       if (c->kind != CK_GOING_AWAY)
-       {
-               free(c->spd.that.virt);
-       }
-
-       client_id = (c->xauth_identity) ? c->xauth_identity : c->spd.that.id;
-
-       /* release virtual IP address lease if any */
-       if (c->spd.that.modecfg && c->spd.that.pool &&
-               !c->spd.that.host_srcip->is_anyaddr(c->spd.that.host_srcip))
-       {
-               hydra->attributes->release_address(hydra->attributes, c->spd.that.pool,
-                                                                                  c->spd.that.host_srcip, client_id);
-       }
-
-       /* release requested attributes if any */
-       if (c->requested)
-       {
-               c->requested->destroy_function(c->requested,
-                                                                         (void*)modecfg_attribute_destroy);
-       }
-
-       /* release other attributes if any */
-       if (c->attributes)
-       {
-               while (c->attributes->remove_last(c->attributes, (void **)&ca) == SUCCESS)
-               {
-                       hydra->attributes->release(hydra->attributes, ca->handler,
-                                                                          client_id, ca->type, ca->value);
-                       modecfg_attribute_destroy(ca);
-               }
-               c->attributes->destroy(c->attributes);
-       }
-
-       if (c->kind != CK_GOING_AWAY)
-       {
-               whack_attr->del_pool(whack_attr, c->name);
-       }
-
-       /* free internal data */
-#ifdef DEBUG
-       cur_debugging = old_cur_debugging;
-#endif
-       free(c->name);
-       DESTROY_IF(c->xauth_identity);
-       DESTROY_IF(c->spd.this.id);
-       DESTROY_IF(c->spd.this.ca);
-       DESTROY_IF(c->spd.this.groups);
-       DESTROY_IF(c->spd.this.host_srcip);
-       free(c->spd.this.updown);
-       free(c->spd.this.pool);
-       DESTROY_IF(c->spd.that.id);
-       DESTROY_IF(c->spd.that.ca);
-       DESTROY_IF(c->spd.that.groups);
-       DESTROY_IF(c->spd.that.host_srcip);
-       free(c->spd.that.updown);
-       free(c->spd.that.pool);
-       if (c->requested_ca)
-       {
-               c->requested_ca->destroy_offset(c->requested_ca,
-                                                                               offsetof(identification_t, destroy));
-       }
-#ifdef ADNS
-       gw_delref(&c->gw_info);
-#endif
-       lock_certs_and_keys("delete_connection");
-       cert_release(c->spd.this.cert);
-       scx_release(c->spd.this.sc);
-       cert_release(c->spd.that.cert);
-       scx_release(c->spd.that.sc);
-       unlock_certs_and_keys("delete_connection");
-
-       alg_info_delref((struct alg_info **)&c->alg_info_esp);
-       alg_info_delref((struct alg_info **)&c->alg_info_ike);
-
-       free(c);
-}
-
-/* Delete connections with the specified name */
-void delete_connections_by_name(const char *name, bool strict)
-{
-       connection_t *c = con_by_name(name, strict);
-
-       for (; c != NULL; c = con_by_name(name, FALSE))
-               delete_connection(c, FALSE);
-}
-
-void delete_every_connection(void)
-{
-       while (connections)
-       {
-               delete_connection(connections, TRUE);
-       }
-}
-
-void release_dead_interfaces(void)
-{
-       struct host_pair *hp;
-
-       for (hp = host_pairs; hp != NULL; hp = hp->next)
-       {
-               connection_t **pp
-                       , *p;
-
-               for (pp = &hp->connections; (p = *pp) != NULL; )
-               {
-                       if (p->interface->change == IFN_DELETE)
-                       {
-                               /* this connection's interface is going away */
-                               enum connection_kind k = p->kind;
-
-                               release_connection(p, TRUE);
-
-                               if (k <= CK_PERMANENT)
-                               {
-                                       /* The connection should have survived release:
-                                        * move it to the unoriented_connections list.
-                                        */
-                                       passert(p == *pp);
-
-                                       p->interface = NULL;
-
-                                       *pp = p->hp_next;   /* advance *pp */
-                                       p->host_pair = NULL;
-                                       p->hp_next = unoriented_connections;
-                                       unoriented_connections = p;
-                               }
-                               else
-                               {
-                                       /* The connection should have vanished,
-                                        * but the previous connection remains.
-                                        */
-                                       passert(p != *pp);
-                               }
-                       }
-                       else
-                       {
-                               pp = &p->hp_next;       /* advance pp */
-                       }
-               }
-       }
-}
-
-/* adjust orientations of connections to reflect newly added interfaces */
-void check_orientations(void)
-{
-       /* try to orient all the unoriented connections */
-       {
-               connection_t *c = unoriented_connections;
-
-               unoriented_connections = NULL;
-
-               while (c)
-               {
-                       connection_t *nxt = c->hp_next;
-
-                       (void)orient(c);
-                       connect_to_host_pair(c);
-                       c = nxt;
-               }
-       }
-
-       /* Check that no oriented connection has become double-oriented.
-        * In other words, the far side must not match one of our new interfaces.
-        */
-       {
-               struct iface *i;
-
-               for (i = interfaces; i != NULL; i = i->next)
-               {
-                       if (i->change == IFN_ADD)
-                       {
-                               struct host_pair *hp;
-
-                               for (hp = host_pairs; hp != NULL; hp = hp->next)
-                               {
-                                       if (sameaddr(&hp->him.addr, &i->addr)
-                                               && hp->him.port == pluto_port)
-                                       {
-                                               /* bad news: the whole chain of connections
-                                                * hanging off this host pair has both sides
-                                                * matching an interface.
-                                                * We'll get rid of them, using orient and
-                                                * connect_to_host_pair.  But we'll be lazy
-                                                * and not ditch the host_pair itself (the
-                                                * cost of leaving it is slight and cannot
-                                                * be induced by a foe).
-                                                */
-                                               connection_t *c = hp->connections;
-
-                                               hp->connections = NULL;
-                                               while (c)
-                                               {
-                                                       connection_t *nxt = c->hp_next;
-
-                                                       c->interface = NULL;
-                                                       (void)orient(c);
-                                                       connect_to_host_pair(c);
-                                                       c = nxt;
-                                               }
-                                       }
-                               }
-                       }
-               }
-       }
-}
-
-static err_t default_end(struct end *e, ip_address *dflt_nexthop)
-{
-       err_t ugh = NULL;
-       int af = addrtypeof(&e->host_addr);
-
-       if (af != AF_INET && af != AF_INET6)
-       {
-               return "unknown address family in default_end";
-       }
-
-       /* default ID to IP (but only if not NO_IP -- WildCard) */
-       if (e->id->get_type(e->id) == ID_ANY && !isanyaddr(&e->host_addr))
-       {
-               e->id->destroy(e->id);
-               e->id = identification_create_from_sockaddr((sockaddr_t*)&e->host_addr);
-               e->has_id_wildcards = FALSE;
-       }
-
-       /* default nexthop to other side */
-       if (isanyaddr(&e->host_nexthop))
-       {
-               e->host_nexthop = *dflt_nexthop;
-       }
-
-       /* default client to subnet containing only self
-        * XXX This may mean that the client's address family doesn't match
-        * tunnel_addr_family.
-        */
-       if (!e->has_client)
-       {
-               ugh = addrtosubnet(&e->host_addr, &e->client);
-       }
-       return ugh;
-}
-
-/* Format the topology of a connection end, leaving out defaults.
- * Largest left end looks like: client === host : port [ host_id ] --- hop
- * Note: if that==NULL, skip nexthop
- * Returns strlen of formated result (length excludes NUL at end).
- */
-size_t format_end(char *buf, size_t buf_len, const struct end *this,
-                                const struct end *that, bool is_left, lset_t policy)
-{
-       char client[BUF_LEN];
-       const char *client_sep = "";
-       char protoport[sizeof(":255/65535")];
-       const char *host = NULL;
-       char host_space[ADDRTOT_BUF];
-       char host_port[sizeof(":65535")];
-       char host_id[BUF_LEN + 2];
-       char hop[ADDRTOT_BUF];
-       const char *hop_sep = "";
-       const char *open_brackets  = "";
-       const char *close_brackets = "";
-
-       if (isanyaddr(&this->host_addr))
-       {
-               switch (policy & (POLICY_GROUP | POLICY_OPPO))
-               {
-               case POLICY_GROUP:
-                       host = "%group";
-                       break;
-               case POLICY_OPPO:
-                       host = "%opportunistic";
-                       break;
-               case POLICY_GROUP | POLICY_OPPO:
-                       host = "%opportunisticgroup";
-                       break;
-               default:
-                       host = "%any";
-                       break;
-               }
-       }
-
-       client[0] = '\0';
-
-       if (is_virtual_end(this) && isanyaddr(&this->host_addr))
-       {
-               host = "%virtual";
-       }
-
-       /* [client===] */
-       if (this->has_client)
-       {
-               ip_address client_net, client_mask;
-
-               networkof(&this->client, &client_net);
-               maskof(&this->client, &client_mask);
-               client_sep = "===";
-
-               /* {client_subnet_wildcard} */
-               if (this->has_client_wildcard)
-               {
-                       open_brackets  = "{";
-                       close_brackets = "}";
-               }
-
-               if (isanyaddr(&client_net) && isanyaddr(&client_mask)
-               && (policy & (POLICY_GROUP | POLICY_OPPO)))
-               {
-                       client_sep = "";    /* boring case */
-               }
-               else if (subnetisnone(&this->client))
-               {
-                       strncpy(client, "?", sizeof(client));
-               }
-               else
-               {
-                       subnettot(&this->client, 0, client, sizeof(client));
-               }
-       }
-       else if (this->modecfg && this->host_srcip->is_anyaddr(this->host_srcip))
-       {
-               /* we are mode config client, or a server with a pool */
-               client_sep = "===";
-               client[0] = '%';
-               strncpy(client+1, this->pool ?: "modecfg", sizeof(client)-1);
-       }
-
-       /* host */
-       if (host == NULL)
-       {
-               addrtot(&this->host_addr, 0, host_space, sizeof(host_space));
-               host = host_space;
-       }
-
-       host_port[0] = '\0';
-       if (this->host_port != IKE_UDP_PORT)
-       {
-               snprintf(host_port, sizeof(host_port), ":%u", this->host_port);
-       }
-
-       /* payload portocol and port */
-       protoport[0] = '\0';
-       if (this->has_port_wildcard)
-       {
-               snprintf(protoport, sizeof(protoport), ":%u/%%any", this->protocol);
-       }
-       else if (this->port || this->protocol)
-       {
-               snprintf(protoport, sizeof(protoport), ":%u/%u", this->protocol
-                       , this->port);
-       }
-
-       /* id */
-       snprintf(host_id, sizeof(host_id), "[%Y]", this->id);
-
-       /* [---hop] */
-       hop[0] = '\0';
-       hop_sep = "";
-       if (that && !sameaddr(&this->host_nexthop, &that->host_addr))
-       {
-               addrtot(&this->host_nexthop, 0, hop, sizeof(hop));
-               hop_sep = "---";
-       }
-
-       if (is_left)
-       {
-               snprintf(buf, buf_len, "%s%s%s%s%s%s%s%s%s%s%s"
-                       , open_brackets, client, close_brackets, client_sep
-                       , this->allow_any? "%":""
-                       , host, host_port, host_id, protoport
-                       , hop_sep, hop);
-       }
-       else
-       {
-               snprintf(buf, buf_len, "%s%s%s%s%s%s%s%s%s%s%s"
-                       , hop, hop_sep
-                       , this->allow_any? "%":""
-                       , host, host_port, host_id, protoport, client_sep
-                       , open_brackets, client, close_brackets);
-       }
-       return strlen(buf);
-}
-
-/* format topology of a connection.
- * Two symmetric ends separated by ...
- */
-#define CONNECTION_BUF  (2 * (END_BUF - 1) + 4)
-
-static size_t format_connection(char *buf, size_t buf_len,
-                                                               const connection_t *c,
-                                                               struct spd_route *sr)
-{
-       size_t w = format_end(buf, buf_len, &sr->this, &sr->that, TRUE, LEMPTY);
-
-       w += snprintf(buf + w, buf_len - w, "...");
-       return w + format_end(buf + w, buf_len - w, &sr->that, &sr->this, FALSE, c->policy);
-}
-
-static void unshare_connection_strings(connection_t *c)
-{
-       c->name = clone_str(c->name);
-       if (c->xauth_identity)
-       {
-               c->xauth_identity = c->xauth_identity->clone(c->xauth_identity);
-       }
-       c->spd.this.id = c->spd.this.id->clone(c->spd.this.id);
-       c->spd.this.pool = clone_str(c->spd.this.pool);
-       c->spd.this.updown = clone_str(c->spd.this.updown);
-       c->spd.this.host_srcip = c->spd.this.host_srcip->clone(c->spd.this.host_srcip);
-       scx_share(c->spd.this.sc);
-       cert_share(c->spd.this.cert);
-       if (c->spd.this.ca)
-       {
-               c->spd.this.ca = c->spd.this.ca->clone(c->spd.this.ca);
-       }
-       if (c->spd.this.groups)
-       {
-               c->spd.this.groups = c->spd.this.groups->get_ref(c->spd.this.groups);
-       }
-       c->spd.that.id = c->spd.that.id->clone(c->spd.that.id);
-       c->spd.that.pool = clone_str(c->spd.that.pool);
-       c->spd.that.updown = clone_str(c->spd.that.updown);
-       c->spd.that.host_srcip = c->spd.that.host_srcip->clone(c->spd.that.host_srcip);
-       scx_share(c->spd.that.sc);
-       cert_share(c->spd.that.cert);
-       if (c->spd.that.ca)
-       {
-               c->spd.that.ca = c->spd.that.ca->clone(c->spd.that.ca);
-       }
-       if (c->spd.that.groups)
-       {
-               c->spd.that.groups = c->spd.that.groups->get_ref(c->spd.that.groups);
-       }
-
-       /* increment references to algo's */
-       alg_info_addref((struct alg_info *)c->alg_info_esp);
-       alg_info_addref((struct alg_info *)c->alg_info_ike);
-}
-
-static void load_end_certificate(char *filename, struct end *dst)
-{
-       time_t notBefore, notAfter;
-       cert_t *cert = NULL;
-       certificate_t *certificate;
-       bool cached_cert = FALSE;
-
-       /* initialize end certificate */
-       dst->cert = NULL;
-
-       /* initialize smartcard info record */
-       dst->sc = NULL;
-
-       if (filename)
-       {
-               if (scx_on_smartcard(filename))
-               {
-                       /* load cert from smartcard */
-                       cert = scx_load_cert(filename, &dst->sc, &cached_cert);
-               }
-               else
-               {
-                       /* load cert from file */
-                       cert = load_host_cert(filename);
-               }
-       }
-
-       if (cert)
-       {
-               certificate = cert->cert;
-
-               if (dst->id->get_type(dst->id) == ID_ANY ||
-                       !certificate->has_subject(certificate, dst->id))
-               {
-                       plog( "  id '%Y' not confirmed by certificate, defaulting to '%Y'",
-                                dst->id, certificate->get_subject(certificate));
-                       dst->id->destroy(dst->id);
-                       dst->id = certificate->get_subject(certificate);
-                       dst->id = dst->id->clone(dst->id);
-               }
-
-               if (cached_cert)
-               {
-                       dst->cert = cert;
-               }
-               else
-               {
-                       if (!certificate->get_validity(certificate, NULL, &notBefore, &notAfter))
-                       {
-                               plog("certificate is invalid (valid from %T to %T)",
-                                        &notBefore, FALSE, &notAfter, FALSE);
-                               cert_free(cert);
-                               return;
-                       }
-                       DBG(DBG_CONTROL,
-                               DBG_log("certificate is valid")
-                       )
-                       add_public_key_from_cert(cert, notAfter, DAL_LOCAL);
-                       dst->cert = cert_add(cert);
-               }
-               certificate = dst->cert->cert;
-
-               /* if no CA is defined, use issuer as default */
-               if (dst->ca == NULL && certificate->get_type(certificate) == CERT_X509)
-               {
-                       identification_t *issuer;
-
-                       issuer = certificate->get_issuer(certificate);
-                       dst->ca = issuer->clone(issuer);
-               }
-
-               /* cache the certificate that was last retrieved from the smartcard */
-               if (dst->sc)
-               {
-                       if (!dst->sc->last_cert ||
-                           !certificate->equals(certificate, dst->sc->last_cert->cert))
-                       {
-                               lock_certs_and_keys("load_end_certificates");
-                               cert_release(dst->sc->last_cert);
-                               dst->sc->last_cert = dst->cert;
-                               cert_share(dst->cert);
-                               unlock_certs_and_keys("load_end_certificates");
-                       }
-                       time(&dst->sc->last_load);
-               }
-       }
-       scx_share(dst->sc);
-       cert_share(dst->cert);
-}
-
-static bool extract_end(struct end *dst, const whack_end_t *src,
-                                               const char *name, bool is_left)
-{
-       bool same_ca = FALSE;
-
-       dst->is_left = is_left;
-       dst->id = identification_create_from_string(src->id);
-       dst->ca = NULL;
-
-       /* decode CA distinguished name, if any */
-       if (src->ca)
-       {
-               if streq(src->ca, "%same")
-               {
-                       same_ca = TRUE;
-               }
-               else if (!streq(src->ca, "%any"))
-               {
-                       dst->ca = identification_create_from_string(src->ca);
-                       if (dst->ca->get_type(dst->ca) != ID_DER_ASN1_DN)
-                       {
-                               plog("bad CA string '%s', ignored", src->ca);
-                               dst->ca->destroy(dst->ca);
-                               dst->ca = NULL;
-                       }
-               }
-       }
-
-       /* load local end certificate and extract ID, if any */
-       load_end_certificate(src->cert, dst);
-
-       /* does id has wildcards? */
-       dst->has_id_wildcards = dst->id->contains_wildcards(dst->id);
-
-       /* decode group attributes, if any */
-       if (src->groups)
-       {
-               dst->groups = ietf_attributes_create_from_string(src->groups);
-       }
-
-       /* the rest is simple copying of corresponding fields */
-       dst->host_addr = src->host_addr;
-       dst->host_nexthop = src->host_nexthop;
-       dst->host_srcip = host_create_from_sockaddr((sockaddr_t*)&src->host_srcip);
-       dst->has_natip = src->has_natip;
-       dst->client = src->client;
-       dst->protocol = src->protocol;
-       dst->port = src->port;
-       dst->has_port_wildcard = src->has_port_wildcard;
-       dst->key_from_DNS_on_demand = src->key_from_DNS_on_demand;
-       dst->has_client = src->has_client;
-       dst->has_client_wildcard = src->has_client_wildcard;
-       dst->modecfg = src->modecfg;
-       dst->hostaccess = src->hostaccess;
-       dst->allow_any = src->allow_any;
-       dst->sendcert = src->sendcert;
-       dst->updown = clone_str(src->updown);
-       dst->host_port = src->host_port;
-
-       /* if the sourceip netmask is zero a named pool exists */
-       if (src->sourceip_mask == 0)
-       {
-               dst->pool = clone_str(src->sourceip);
-       }
-
-       /* if host sourceip is defined but no client is present
-        * behind the host then set client to sourceip/32
-        */
-       if (!dst->host_srcip->is_anyaddr(dst->host_srcip) &&
-               !dst->has_natip && !dst->has_client)
-       {
-               ip_address addr;
-               err_t ugh;
-
-               addr = *(ip_address*)dst->host_srcip->get_sockaddr(dst->host_srcip);
-               ugh = addrtosubnet(&addr, &dst->client);
-
-               if (ugh)
-               {
-                       plog("could not assign host sourceip to client subnet");
-               }
-               else
-               {
-                       dst->has_client = TRUE;
-               }
-       }
-       return same_ca;
-}
-
-static bool check_connection_end(const whack_end_t *this,
-                                                                const whack_end_t *that,
-                                                                const whack_message_t *wm)
-{
-       if (wm->addr_family != addrtypeof(&this->host_addr)
-       || wm->addr_family != addrtypeof(&this->host_nexthop)
-       || (this->has_client? wm->tunnel_addr_family : wm->addr_family)
-         != subnettypeof(&this->client)
-       || subnettypeof(&this->client) != subnettypeof(&that->client))
-       {
-               /* this should have been diagnosed by whack, so we need not be clear
-                * !!! overloaded use of RC_CLASH
-                */
-               loglog(RC_CLASH, "address family inconsistency in connection");
-               return FALSE;
-       }
-
-       if (isanyaddr(&that->host_addr))
-       {
-               /* other side is wildcard: we must check if other conditions met */
-               if (isanyaddr(&this->host_addr))
-               {
-                       loglog(RC_ORIENT, "connection must specify host IP address for our side");
-                       return FALSE;
-               }
-       }
-
-       if (this->virt && (!isanyaddr(&this->host_addr) || this->has_client))
-       {
-               loglog(RC_CLASH,
-                       "virtual IP must only be used with %%any and without client");
-               return FALSE;
-       }
-
-       return TRUE;        /* happy */
-}
-
-connection_t *find_connection_by_reqid(uint32_t reqid)
-{
-       connection_t *c;
-
-       reqid &= ~3;
-       for (c = connections; c != NULL; c = c->ac_next)
-       {
-               if (c->spd.reqid == reqid)
-               {
-                       return c;
-               }
-       }
-
-       return NULL;
-}
-
-static uint32_t gen_reqid(void)
-{
-       uint32_t start;
-       static uint32_t reqid = IPSEC_MANUAL_REQID_MAX & ~3;
-
-       start = reqid;
-       do {
-               reqid += 4;
-               if (reqid == 0)
-               {
-                       reqid = (IPSEC_MANUAL_REQID_MAX & ~3) + 4;
-               }
-               if (!find_connection_by_reqid(reqid))
-               {
-                       return reqid;
-               }
-       } while (reqid != start);
-
-       exit_log("unable to allocate reqid");
-       return 0; /* never reached ... */
-}
-
-void add_connection(const whack_message_t *wm)
-{
-       if (con_by_name(wm->name, FALSE) != NULL)
-       {
-               loglog(RC_DUPNAME, "attempt to redefine connection \"%s\"", wm->name);
-       }
-       else if (wm->right.protocol != wm->left.protocol)
-       {
-               /* this should haven been diagnosed by whack
-                * !!! overloaded use of RC_CLASH
-                */
-               loglog(RC_CLASH, "the protocol must be the same for leftport and rightport");
-       }
-       else if (check_connection_end(&wm->right, &wm->left, wm)
-       && check_connection_end(&wm->left, &wm->right, wm))
-       {
-               bool same_rightca, same_leftca;
-               connection_t *c = malloc_thing(connection_t);
-
-               zero(c);
-               c->name   = clone_str(wm->name);
-               c->ikev1  = wm->ikev1;
-               c->policy = wm->policy;
-
-               if ((c->policy & POLICY_COMPRESS) && !can_do_IPcomp)
-               {
-                       loglog(RC_COMMENT
-                               , "ignoring --compress in \"%s\" because kernel does not support IPCOMP"
-                               , c->name);
-               }
-
-               if (wm->esp)
-               {
-                        DBG(DBG_CONTROL,
-                               DBG_log("from whack: got --esp=%s", wm->esp ? wm->esp: "NULL")
-                       )
-                       c->alg_info_esp = alg_info_esp_create_from_str(wm->esp? wm->esp : "");
-
-                       DBG(DBG_CRYPT|DBG_CONTROL,
-                               static char buf[BUF_LEN]="<NULL>";
-
-                               if (c->alg_info_esp)
-                               {
-                                       alg_info_snprint(buf, sizeof(buf)
-                                                       ,(struct alg_info *)c->alg_info_esp);
-                               }
-                               DBG_log("esp proposal: %s", buf);
-                       )
-                       if (c->alg_info_esp)
-                       {
-                               if (c->alg_info_esp->alg_info_cnt == 0)
-                               {
-                                        loglog(RC_LOG_SERIOUS, "got 0 esp transforms");
-                               }
-                       }
-                       else
-                       {
-                               loglog(RC_LOG_SERIOUS, "syntax error in esp string");
-                       }
-               }
-
-               if (wm->ike)
-               {
-                       DBG(DBG_CONTROL,
-                               DBG_log("from whack: got --ike=%s", wm->ike ? wm->ike: "NULL")
-                       )
-                       c->alg_info_ike= alg_info_ike_create_from_str(wm->ike? wm->ike : "");
-
-                       DBG(DBG_CRYPT|DBG_CONTROL,
-                               static char buf[BUF_LEN]="<NULL>";
-
-                               if (c->alg_info_ike)
-                               {
-                                       alg_info_snprint(buf, sizeof(buf)
-                                                       , (struct alg_info *)c->alg_info_ike);
-                               }
-                               DBG_log("ike proposal: %s", buf);
-                       )
-                       if (c->alg_info_ike)
-                       {
-                               if (c->alg_info_ike->alg_info_cnt == 0)
-                               {
-                                       loglog(RC_LOG_SERIOUS, "got 0 ike transforms");
-                               }
-                       }
-                       else
-                       {
-                               loglog(RC_LOG_SERIOUS, "syntax error in ike string");
-                       }
-               }
-
-               if (wm->xauth_identity)
-               {
-                       c->xauth_identity
-                                       = identification_create_from_string(wm->xauth_identity);
-               }
-
-               c->sa_ike_life_seconds = wm->sa_ike_life_seconds;
-               c->sa_ipsec_life_seconds = wm->sa_ipsec_life_seconds;
-               c->sa_rekey_margin = wm->sa_rekey_margin;
-               c->sa_rekey_fuzz = wm->sa_rekey_fuzz;
-               c->sa_keying_tries = wm->sa_keying_tries;
-
-               /* RFC 3706 DPD */
-               c->dpd_delay = wm->dpd_delay;
-               c->dpd_timeout = wm->dpd_timeout;
-               c->dpd_action = wm->dpd_action;
-
-               c->addr_family = wm->addr_family;
-               c->tunnel_addr_family = wm->tunnel_addr_family;
-
-               c->requested_ca = NULL;
-               same_leftca  = extract_end(&c->spd.this, &wm->left, wm->name, TRUE);
-               same_rightca = extract_end(&c->spd.that, &wm->right, wm->name, FALSE);
-
-               if (same_rightca && c->spd.this.ca)
-               {
-                       c->spd.that.ca = c->spd.this.ca->clone(c->spd.this.ca);
-               }
-               else if (same_leftca && c->spd.that.ca)
-               {
-                       c->spd.this.ca = c->spd.that.ca->clone(c->spd.that.ca);
-               }
-
-               default_end(&c->spd.this, &c->spd.that.host_addr);
-               default_end(&c->spd.that, &c->spd.this.host_addr);
-
-               /* force any wildcard host IP address, any wildcard subnet
-                * or any wildcard ID to that end
-                */
-               if (isanyaddr(&c->spd.this.host_addr) || c->spd.this.has_client_wildcard
-               || c->spd.this.has_port_wildcard || c->spd.this.has_id_wildcards
-               || c->spd.this.allow_any)
-               {
-                       struct end t = c->spd.this;
-
-                       c->spd.this = c->spd.that;
-                       c->spd.that = t;
-               }
-
-               c->spd.next = NULL;
-               c->spd.reqid = wm->reqid ?: gen_reqid();
-
-               c->spd.mark_in.value = wm->mark_in.value;
-               c->spd.mark_in.mask = wm->mark_in.mask;
-               c->spd.mark_out.value = wm->mark_out.value;
-               c->spd.mark_out.mask = wm->mark_out.mask;
-
-               /* set internal fields */
-               c->instance_serial = 0;
-               c->ac_next = connections;
-               connections = c;
-               c->interface = NULL;
-               c->spd.routing = RT_UNROUTED;
-               c->newest_isakmp_sa = SOS_NOBODY;
-               c->newest_ipsec_sa = SOS_NOBODY;
-               c->spd.eroute_owner = SOS_NOBODY;
-
-               if (c->policy & POLICY_GROUP)
-               {
-                       c->kind = CK_GROUP;
-                       add_group(c);
-               }
-               else if ((isanyaddr(&c->spd.that.host_addr) && !NEVER_NEGOTIATE(c->policy))
-               || c->spd.that.has_client_wildcard || c->spd.that.has_port_wildcard
-               || c->spd.that.has_id_wildcards || c->spd.that.allow_any)
-               {
-                       /* Opportunistic or Road Warrior or wildcard client subnet
-                        * or wildcard ID */
-                       c->kind = CK_TEMPLATE;
-               }
-               else
-               {
-                       c->kind = CK_PERMANENT;
-               }
-               set_policy_prio(c);     /* must be after kind is set */
-
-#ifdef DEBUG
-               c->extra_debugging = wm->debugging;
-#endif
-
-               c->gw_info = NULL;
-
-               passert(!(wm->left.virt && wm->right.virt));
-               if (wm->left.virt || wm->right.virt)
-               {
-                       passert(isanyaddr(&c->spd.that.host_addr));
-                       c->spd.that.virt = create_virtual(c,
-                               wm->left.virt ? wm->left.virt : wm->right.virt);
-                       if (c->spd.that.virt)
-                               c->spd.that.has_client = TRUE;
-               }
-
-               (void)orient(c);
-
-               /* if rightsourceip defines a subnet then create an in-memory pool */
-               if (whack_attr->add_pool(whack_attr, c->name,
-                                                       c->spd.this.is_left ? &wm->right : &wm->left))
-               {
-                       c->spd.that.pool = clone_str(c->name);
-                       c->spd.that.modecfg = TRUE;
-                       c->spd.that.has_client = FALSE;
-                       /* reset the host_srcip so that it gets assigned in modecfg */
-                       DESTROY_IF(c->spd.that.host_srcip);
-                       c->spd.that.host_srcip = host_create_any(AF_INET);
-               }
-
-               if (c->ikev1)
-               {
-                       connect_to_host_pair(c);
-               }
-
-               /* log all about this connection */
-               plog("added connection description \"%s\"", c->name);
-               DBG(DBG_CONTROL,
-                       char topo[BUF_LEN];
-
-                       (void) format_connection(topo, sizeof(topo), c, &c->spd);
-
-                       DBG_log("%s", topo);
-
-                       /* Make sure that address families can be correctly inferred
-                        * from printed ends.
-                        */
-                       passert(c->addr_family == addrtypeof(&c->spd.this.host_addr)
-                               && c->addr_family == addrtypeof(&c->spd.this.host_nexthop)
-                               && (c->spd.this.has_client? c->tunnel_addr_family : c->addr_family)
-                                 == subnettypeof(&c->spd.this.client)
-
-                               && c->addr_family == addrtypeof(&c->spd.that.host_addr)
-                               && c->addr_family == addrtypeof(&c->spd.that.host_nexthop)
-                               && (c->spd.that.has_client? c->tunnel_addr_family : c->addr_family)
-                                 == subnettypeof(&c->spd.that.client));
-
-                       DBG_log("ike_life: %lus; ipsec_life: %lus; rekey_margin: %lus;"
-                               " rekey_fuzz: %lu%%; keyingtries: %lu; policy: %s"
-                               , (unsigned long) c->sa_ike_life_seconds
-                               , (unsigned long) c->sa_ipsec_life_seconds
-                               , (unsigned long) c->sa_rekey_margin
-                               , (unsigned long) c->sa_rekey_fuzz
-                               , (unsigned long) c->sa_keying_tries
-                               , prettypolicy(c->policy));
-               );
-       }
-}
-
-/* Derive a template connection from a group connection and target.
- * Similar to instantiate().  Happens at whack --listen.
- * Returns name of new connection.  May be NULL.
- * Caller is responsible for freeing.
- */
-char *add_group_instance(connection_t *group, const ip_subnet *target)
-{
-       char namebuf[100], targetbuf[SUBNETTOT_BUF];
-       connection_t *t;
-       char *name = NULL;
-
-       passert(group->kind == CK_GROUP);
-       passert(oriented(*group));
-
-       /* manufacture a unique name for this template */
-       subnettot(target, 0, targetbuf, sizeof(targetbuf));
-       snprintf(namebuf, sizeof(namebuf), "%s#%s", group->name, targetbuf);
-
-       if (con_by_name(namebuf, FALSE) != NULL)
-       {
-               loglog(RC_DUPNAME, "group name + target yields duplicate name \"%s\""
-                       , namebuf);
-       }
-       else
-       {
-               t = clone_thing(*group);
-               t->name = namebuf;
-               unshare_connection_strings(t);
-               name = clone_str(t->name);
-               t->spd.that.client = *target;
-               t->policy &= ~(POLICY_GROUP | POLICY_GROUTED);
-               t->kind = isanyaddr(&t->spd.that.host_addr) && !NEVER_NEGOTIATE(t->policy)
-                       ? CK_TEMPLATE : CK_INSTANCE;
-
-               /* reset log file info */
-               t->log_file_name = NULL;
-               t->log_file = NULL;
-               t->log_file_err = FALSE;
-
-               t->spd.reqid = gen_reqid();
-
-               if (t->spd.that.virt)
-               {
-                       DBG_log("virtual_ip not supported in group instance");
-                       t->spd.that.virt = NULL;
-               }
-
-               /* add to connections list */
-               t->ac_next = connections;
-               connections = t;
-
-               /* same host_pair as parent: stick after parent on list */
-               group->hp_next = t;
-
-               /* route if group is routed */
-               if (group->policy & POLICY_GROUTED)
-               {
-                       if (!trap_connection(t))
-                               whack_log(RC_ROUTE, "could not route");
-               }
-       }
-       return name;
-}
-
-/* an old target has disappeared for a group: delete instance */
-void remove_group_instance(const connection_t *group USED_BY_DEBUG,
-                                                  const char *name)
-{
-       passert(group->kind == CK_GROUP);
-       passert(oriented(*group));
-
-       delete_connections_by_name(name, FALSE);
-}
-
-/* Common part of instantiating a Road Warrior or Opportunistic connection.
- * his_id can be used to carry over an ID discovered in Phase 1.
- * It must not disagree with the one in c, but if that is unspecified,
- * the new connection will use his_id.
- * If his_id is NULL, and c.that.id is uninstantiated (ID_ANY), the
- * new connection will continue to have an uninstantiated that.id.
- * Note: instantiation does not affect port numbers.
- *
- * Note that instantiate can only deal with a single SPD/eroute.
- */
-static connection_t *instantiate(connection_t *c, const ip_address *him,
-                                                                u_int16_t his_port, identification_t *his_id)
-{
-       connection_t *d;
-
-       passert(c->kind == CK_TEMPLATE);
-       passert(c->spd.next == NULL);
-
-       c->instance_serial++;
-       d = clone_thing(*c);
-       d->spd.that.allow_any = FALSE;
-
-       if (his_id)
-       {
-               d->spd.that.id = his_id;
-               d->spd.that.has_id_wildcards = FALSE;
-       }
-       unshare_connection_strings(d);
-       if (d->spd.this.groups)
-       {
-               d->spd.this.groups = d->spd.this.groups->get_ref(d->spd.this.groups);
-       }
-       if (d->spd.that.groups)
-       {
-               d->spd.that.groups = d->spd.that.groups->get_ref(d->spd.that.groups);
-       }
-       d->kind = CK_INSTANCE;
-
-       passert(oriented(*d));
-       d->spd.that.host_addr = *him;
-       setportof(htons(c->spd.that.port), &d->spd.that.host_addr);
-
-       if (his_port) d->spd.that.host_port = his_port;
-
-       default_end(&d->spd.that, &d->spd.this.host_addr);
-
-       /* We cannot guess what our next_hop should be, but if it was
-        * explicitly specified as 0.0.0.0, we set it to be him.
-        * (whack will not allow nexthop to be elided in RW case.)
-        */
-       default_end(&d->spd.this, &d->spd.that.host_addr);
-       d->spd.next = NULL;
-       d->spd.reqid = gen_reqid();
-
-       /* set internal fields */
-       d->ac_next = connections;
-       connections = d;
-       d->spd.routing = RT_UNROUTED;
-       d->newest_isakmp_sa = SOS_NOBODY;
-       d->newest_ipsec_sa = SOS_NOBODY;
-       d->spd.eroute_owner = SOS_NOBODY;
-
-       /* reset log file info */
-       d->log_file_name = NULL;
-       d->log_file = NULL;
-       d->log_file_err = FALSE;
-
-       connect_to_host_pair(d);
-
-       if (sameaddr(&d->spd.that.host_addr, &d->spd.this.host_nexthop))
-       {
-               d->spd.this.host_nexthop = *him;
-       }
-       return d;
-}
-
-connection_t *rw_instantiate(connection_t *c, const ip_address *him,
-                                                        u_int16_t his_port, const ip_subnet *his_net,
-                                                        identification_t *his_id)
-{
-       connection_t *d = instantiate(c, him, his_port, his_id);
-
-       if (d && his_net && is_virtual_connection(c))
-       {
-               d->spd.that.client = *his_net;
-               d->spd.that.virt = NULL;
-               if (subnetishost(his_net) && addrinsubnet(him, his_net))
-                       d->spd.that.has_client = FALSE;
-       }
-
-       if (d->policy & POLICY_OPPO)
-       {
-               /* This must be before we know the client addresses.
-                * Fill in one that is impossible.  This prevents anyone else from
-                * trying to use this connection to get to a particular client
-                */
-               d->spd.that.client = *aftoinfo(subnettypeof(&d->spd.that.client))->none;
-       }
-       DBG(DBG_CONTROL
-               , DBG_log("instantiated \"%s\" for %s" , d->name, ip_str(him)));
-       return d;
-}
-
-#ifdef ADNS
-
-connection_t *oppo_instantiate(connection_t *c, const ip_address *him,
-                                                          identification_t *his_id, struct gw_info *gw,
-                                                          const ip_address *our_client USED_BY_DEBUG,
-                                                          const ip_address *peer_client)
-{
-       connection_t *d = instantiate(c, him, 0, his_id);
-
-       passert(d->spd.next == NULL);
-
-       /* fill in our client side */
-       if (d->spd.this.has_client)
-       {
-               /* there was a client in the abstract connection
-                * so we demand that the required client is within that subnet.
-                */
-               passert(addrinsubnet(our_client, &d->spd.this.client));
-               happy(addrtosubnet(our_client, &d->spd.this.client));
-               /* opportunistic connections do not use port selectors */
-               setportof(0, &d->spd.this.client.addr);
-       }
-       else
-       {
-               /* there was no client in the abstract connection
-                * so we demand that the required client be the host
-                */
-               passert(sameaddr(our_client, &d->spd.this.host_addr));
-       }
-
-       /* fill in peer's client side.
-        * If the client is the peer, excise the client from the connection.
-        */
-       passert((d->policy & POLICY_OPPO)
-               && addrinsubnet(peer_client, &d->spd.that.client));
-       happy(addrtosubnet(peer_client, &d->spd.that.client));
-       /* opportunistic connections do not use port selectors */
-       setportof(0, &d->spd.that.client.addr);
-
-       if (sameaddr(peer_client, &d->spd.that.host_addr))
-               d->spd.that.has_client = FALSE;
-
-       passert(d->gw_info == NULL);
-       gw_addref(gw);
-       d->gw_info = gw;
-
-       /* Adjust routing if something is eclipsing c.
-        * It must be a %hold for us (hard to passert this).
-        * If there was another instance eclipsing, we'd be using it.
-        */
-       if (c->spd.routing == RT_ROUTED_ECLIPSED)
-               d->spd.routing = RT_ROUTED_PROSPECTIVE;
-
-       /* Remember if the template is routed:
-        * if so, this instance applies for initiation
-        * even if it is created for responding.
-        */
-       if (routed(c->spd.routing))
-               d->instance_initiation_ok = TRUE;
-
-       DBG(DBG_CONTROL,
-               char topo[BUF_LEN];
-
-               (void) format_connection(topo, sizeof(topo), d, &d->spd);
-               DBG_log("instantiated \"%s\": %s", d->name, topo);
-       );
-       return d;
-}
-
-#endif /* ADNS */
-
-/* priority formatting */
-void fmt_policy_prio(policy_prio_t pp, char buf[POLICY_PRIO_BUF])
-{
-       if (pp == BOTTOM_PRIO)
-       {
-               snprintf(buf, POLICY_PRIO_BUF, "0");
-       }
-       else
-       {
-               snprintf(buf, POLICY_PRIO_BUF, "%lu,%lu"
-                       , pp>>16, (pp & ~(~(policy_prio_t)0 << 16)) >> 8);
-       }
-}
-
-/* Format any information needed to identify an instance of a connection.
- * Fills any needed information into buf which MUST be big enough.
- * Road Warrior: peer's IP address
- * Opportunistic: [" " myclient "==="] " ..." peer ["===" hisclient] '\0'
- */
-static size_t fmt_client(const ip_subnet *client, const ip_address *gw,
-                                                const char *prefix, char buf[ADDRTOT_BUF])
-{
-       if (subnetisaddr(client, gw))
-       {
-               buf[0] = '\0';  /* compact denotation for "self" */
-       }
-       else
-       {
-               char *ap;
-
-               strcpy(buf, prefix);
-               ap = buf + strlen(prefix);
-               if (subnetisnone(client))
-                       strcpy(ap, "?");    /* unknown */
-               else
-                       subnettot(client, 0, ap, SUBNETTOT_BUF);
-       }
-       return strlen(buf);
-}
-
-void fmt_conn_instance(const connection_t *c, char buf[CONN_INST_BUF])
-{
-       char *p = buf;
-
-       *p = '\0';
-
-       if (c->kind == CK_INSTANCE)
-       {
-               if (c->instance_serial != 0)
-               {
-                       snprintf(p, CONN_INST_BUF, "[%lu]", c->instance_serial);
-                       p += strlen(p);
-               }
-
-               if (c->policy & POLICY_OPPO)
-               {
-                       size_t w = fmt_client(&c->spd.this.client, &c->spd.this.host_addr, " ", p);
-
-                       p += w;
-
-                       strcpy(p, w == 0? " ..." : "=== ...");
-                       p += strlen(p);
-
-                       addrtot(&c->spd.that.host_addr, 0, p, ADDRTOT_BUF);
-                       p += strlen(p);
-
-                       (void) fmt_client(&c->spd.that.client, &c->spd.that.host_addr, "===", p);
-               }
-               else
-               {
-                       *p++ = ' ';
-                       addrtot(&c->spd.that.host_addr, 0, p, ADDRTOT_BUF);
-#
-                       if (c->spd.that.host_port != pluto_port)
-                       {
-                               p += strlen(p);
-                               sprintf(p, ":%d", c->spd.that.host_port);
-                       }
-               }
-       }
-}
-
-/* Find an existing connection for a trapped outbound packet.
- * This is attempted before we bother with gateway discovery.
- *   + this connection is routed or instance_of_routed_template
- *     (i.e. approved for on-demand)
- *   + this subnet contains our_client (or we are our_client)
- *   + that subnet contains peer_client (or peer is peer_client)
- *   + don't care about Phase 1 IDs (we don't know)
- * Note: result may still need to be instantiated.
- * The winner has the highest policy priority.
- *
- * If there are several with that priority, we give preference to
- * the first one that is an instance.
- *
- * See also build_outgoing_opportunistic_connection.
- */
-connection_t *find_connection_for_clients(struct spd_route **srp,
-                                                                                 const ip_address *our_client,
-                                                                                 const ip_address *peer_client,
-                                                                                 int transport_proto)
-{
-       connection_t *c = connections, *best = NULL;
-       policy_prio_t best_prio = BOTTOM_PRIO;
-       struct spd_route *sr;
-       struct spd_route *best_sr = NULL;
-       int our_port  = ntohs(portof(our_client));
-       int peer_port = ntohs(portof(peer_client));
-
-       passert(!isanyaddr(our_client) && !isanyaddr(peer_client));
-#ifdef DEBUG
-       if (DBGP(DBG_CONTROL))
-       {
-               char ocb[ADDRTOT_BUF], pcb[ADDRTOT_BUF];
-
-               addrtot(our_client, 0, ocb, sizeof(ocb));
-               addrtot(peer_client, 0, pcb, sizeof(pcb));
-               DBG_log("find_connection: "
-                               "looking for policy for connection: %s:%d/%d -> %s:%d/%d"
-                               , ocb, transport_proto, our_port, pcb, transport_proto, peer_port);
-       }
-#endif /* DEBUG */
-
-       for (c = connections; c != NULL; c = c->ac_next)
-       {
-               if (c->kind == CK_GROUP)
-               {
-                       continue;
-               }
-
-               for (sr = &c->spd; best!=c && sr; sr = sr->next)
-               {
-                       if ((routed(sr->routing) || c->instance_initiation_ok)
-                       && addrinsubnet(our_client, &sr->this.client)
-                       && addrinsubnet(peer_client, &sr->that.client)
-                       && addrinsubnet(peer_client, &sr->that.client)
-                       && (!sr->this.protocol || transport_proto == sr->this.protocol)
-                       && (!sr->this.port || our_port == sr->this.port)
-                       && (!sr->that.port || peer_port == sr->that.port))
-                       {
-                               char cib[CONN_INST_BUF];
-                               char cib2[CONN_INST_BUF];
-
-                               policy_prio_t prio = 8 * (c->prio + (c->kind == CK_INSTANCE))
-                                                                  + 2 * (sr->this.port == our_port)
-                                                                  + 2 * (sr->that.port == peer_port)
-                                                                  +     (sr->this.protocol == transport_proto);
-
-#ifdef DEBUG
-                               if (DBGP(DBG_CONTROL|DBG_CONTROLMORE))
-                               {
-                                       char c_ocb[SUBNETTOT_BUF], c_pcb[SUBNETTOT_BUF];
-
-                                       subnettot(&c->spd.this.client, 0, c_ocb, sizeof(c_ocb));
-                                       subnettot(&c->spd.that.client, 0, c_pcb, sizeof(c_pcb));
-                                       DBG_log("find_connection: conn \"%s\"%s has compatible peers: %s->%s [pri: %ld]"
-                                                       , c->name
-                                                       , (fmt_conn_instance(c, cib), cib)
-                                                       , c_ocb, c_pcb, prio);
-                               }
-#endif /* DEBUG */
-
-                               if (best == NULL)
-                               {
-                                       best = c;
-                                       best_sr = sr;
-                                       best_prio = prio;
-                               }
-
-                               DBG(DBG_CONTROLMORE,
-                                       DBG_log("find_connection: "
-                                                       "comparing best \"%s\"%s [pri:%ld]{%p} (child %s) to \"%s\"%s [pri:%ld]{%p} (child %s)"
-                                                       , best->name
-                                                       , (fmt_conn_instance(best, cib), cib)
-                                                       , best_prio
-                                                       , best
-                                                       , (best->policy_next ? best->policy_next->name : "none")
-                                                       , c->name
-                                                       , (fmt_conn_instance(c, cib2), cib2)
-                                                       , prio
-                                                       , c
-                                                       , (c->policy_next ? c->policy_next->name : "none")));
-
-                               if (prio > best_prio)
-                               {
-                                       best = c;
-                                       best_sr = sr;
-                                       best_prio = prio;
-                               }
-                       }
-               }
-       }
-
-       if (best && NEVER_NEGOTIATE(best->policy))
-       {
-               best = NULL;
-       }
-       if (srp && best)
-       {
-               *srp = best_sr;
-       }
-
-#ifdef DEBUG
-       if (DBGP(DBG_CONTROL))
-       {
-               if (best)
-               {
-                       char cib[CONN_INST_BUF];
-                       DBG_log("find_connection: concluding with \"%s\"%s [pri:%ld]{%p} kind=%s"
-                                       , best->name
-                                       , (fmt_conn_instance(best, cib), cib)
-                                       , best_prio
-                                       , best
-                                       , enum_name(&connection_kind_names, best->kind));
-               } else {
-                       DBG_log("find_connection: concluding with empty");
-               }
-       }
-#endif /* DEBUG */
-
-       return best;
-}
-
-#ifdef ADNS
-
-/* Find and instantiate a connection for an outgoing Opportunistic connection.
- * We've already discovered its gateway.
- * We look for a the connection such that:
- *   + this is one of our interfaces
- *   + this subnet contains our_client (or we are our_client)
- *     (we will specialize the client).  We prefer the smallest such subnet.
- *   + that subnet contains peer_clent (we will specialize the client).
- *     We prefer the smallest such subnet.
- *   + is opportunistic
- *   + that peer is NO_IP
- *   + don't care about Phase 1 IDs (probably should be default)
- * We could look for a connection that already had the desired peer
- * (rather than NO_IP) specified, but it doesn't seem worth the
- * bother.
- *
- * We look for the routed policy applying to the narrowest subnets.
- * We only succeed if we find such a policy AND it is satisfactory.
- *
- * The body of the inner loop is a lot like that in
- * find_connection_for_clients.  In this case, we know the gateways
- * that we need to instantiate an opportunistic connection.
- */
-connection_t *build_outgoing_opportunistic_connection(struct gw_info *gw,
-                                                                                       const ip_address *our_client,
-                                                                                       const ip_address *peer_client)
-{
-       struct iface *p;
-       connection_t *best = NULL;
-       struct spd_route *sr, *bestsr;
-       char ocb[ADDRTOT_BUF], pcb[ADDRTOT_BUF];
-
-       addrtot(our_client, 0, ocb, sizeof(ocb));
-       addrtot(peer_client, 0, pcb, sizeof(pcb));
-
-       /* for each of our addresses... */
-       for (p = interfaces; p != NULL; p = p->next)
-       {
-               /* go through those connections with our address and NO_IP as hosts
-                * We cannot know what port the peer would use, so we assume
-                * that it is pluto_port (makes debugging easier).
-                */
-               connection_t *c = find_host_pair_connections(&p->addr, pluto_port,
-                                                                                (ip_address *)NULL, pluto_port);
-
-               for (; c != NULL; c = c->hp_next)
-               {
-                       DBG(DBG_OPPO,
-                               DBG_log("checking %s", c->name));
-                       if (c->kind == CK_GROUP)
-                       {
-                               continue;
-                       }
-
-                       for (sr = &c->spd; best!=c && sr; sr = sr->next)
-                       {
-                               if (routed(sr->routing)
-                               && addrinsubnet(our_client, &sr->this.client)
-                               && addrinsubnet(peer_client, &sr->that.client))
-                               {
-                                       if (best == NULL)
-                                       {
-                                               best = c;
-                                               break;
-                                       }
-
-                                       DBG(DBG_OPPO,
-                                               DBG_log("comparing best %s to %s"
-                                                               , best->name, c->name));
-
-                                       for (bestsr = &best->spd; best!=c && bestsr; bestsr=bestsr->next)
-                                       {
-                                               if (!subnetinsubnet(&bestsr->this.client, &sr->this.client)
-                                               || (samesubnet(&bestsr->this.client, &sr->this.client)
-                                                        && !subnetinsubnet(&bestsr->that.client
-                                                                                               , &sr->that.client)))
-                                               {
-                                                       best = c;
-                                               }
-                                       }
-                               }
-                       }
-               }
-       }
-
-       if (best == NULL || NEVER_NEGOTIATE(best->policy) ||
-          (best->policy & POLICY_OPPO) == LEMPTY || best->kind != CK_TEMPLATE)
-       {
-               return NULL;
-       }
-       else
-       {
-               chunk_t encoding = gw->gw_id->get_encoding(gw->gw_id);
-               id_type_t type   = gw->gw_id->get_type(gw->gw_id);
-               ip_address ip_addr;
-
-               initaddr(encoding.ptr, encoding.len,
-                               (type == ID_IPV4_ADDR) ? AF_INET : AF_INET6, &ip_addr);
-
-               return oppo_instantiate(best, &ip_addr, NULL, gw, our_client, peer_client);
-       }
-}
-
-#endif /* ADNS */
-
-bool orient(connection_t *c)
-{
-       struct spd_route *sr;
-
-       if (!oriented(*c))
-       {
-               struct iface *p;
-
-               for (sr = &c->spd; sr; sr = sr->next)
-               {
-                       /* Note: this loop does not stop when it finds a match:
-                        * it continues checking to catch any ambiguity.
-                        */
-                       for (p = interfaces; p != NULL; p = p->next)
-                       {
-                               if (p->ike_float)
-                               {
-                                       continue;
-                               }
-
-                               for (;;)
-                               {
-                                       /* check if this interface matches this end */
-                                       if (sameaddr(&sr->this.host_addr, &p->addr)
-                                               && sr->this.host_port == pluto_port)
-                                       {
-                                               if (oriented(*c))
-                                               {
-                                                       if (c->interface == p)
-                                                               loglog(RC_LOG_SERIOUS
-                                                                          , "both sides of \"%s\" are our interface %s!"
-                                                                          , c->name, p->rname);
-                                                       else
-                                                               loglog(RC_LOG_SERIOUS, "two interfaces match \"%s\" (%s, %s)"
-                                                                          , c->name, c->interface->rname, p->rname);
-                                                       c->interface = NULL;        /* withdraw orientation */
-                                                       return FALSE;
-                                               }
-                                               c->interface = p;
-                                       }
-
-                                       /* done with this interface if it doesn't match that end */
-                                       if (!(sameaddr(&sr->that.host_addr, &p->addr)
-                                               && sr->that.host_port == pluto_port))
-                                               break;
-
-                                       /* swap ends and try again.
-                                        * It is a little tricky to see that this loop will stop.
-                                        * Only continue if the far side matches.
-                                        * If both sides match, there is an error-out.
-                                        */
-                                       {
-                                               struct end t = sr->this;
-
-                                               sr->this = sr->that;
-                                               sr->that = t;
-                                       }
-                               }
-                       }
-               }
-       }
-       return oriented(*c);
-}
-
-void initiate_connection(const char *name, int whackfd)
-{
-       connection_t *c = con_by_name(name, TRUE);
-
-       if (c && c->ikev1)
-       {
-               set_cur_connection(c);
-               if (!oriented(*c))
-               {
-                       loglog(RC_ORIENT, "we have no ipsecN interface for either end of this connection");
-               }
-               else if (NEVER_NEGOTIATE(c->policy))
-               {
-                       loglog(RC_INITSHUNT
-                               , "cannot initiate an authby=never connection");
-               }
-               else if (c->kind != CK_PERMANENT && !c->spd.that.allow_any)
-               {
-                       if (isanyaddr(&c->spd.that.host_addr))
-                               loglog(RC_NOPEERIP, "cannot initiate connection without knowing peer IP address");
-                       else
-                               loglog(RC_WILDCARD, "cannot initiate connection with ID wildcards");
-               }
-               else
-               {
-                       /* do we have to prompt for a PIN code? */
-                       if (c->spd.this.sc && !c->spd.this.sc->valid && whackfd != NULL_FD)
-                       {
-                               scx_get_pin(c->spd.this.sc, whackfd);
-                       }
-                       if (c->spd.this.sc && !c->spd.this.sc->valid)
-                       {
-                               loglog(RC_NOVALIDPIN, "cannot initiate connection without valid PIN");
-                       }
-                       else
-                       {
-
-                               if (c->spd.that.allow_any)
-                               {
-                                       c = instantiate(c, &c->spd.that.host_addr,
-                                                                       c->spd.that.host_port, c->spd.that.id);
-                               }
-
-                               /* We will only request an IPsec SA if policy isn't empty
-                                * (ignoring Main Mode items).
-                                * This is a fudge, but not yet important.
-                                * If we are to proceed asynchronously, whackfd will be NULL_FD.
-                                */
-                               c->policy |= POLICY_UP;
-                               ipsecdoi_initiate(whackfd, c, c->policy, 1, SOS_NOBODY);
-                               whackfd = NULL_FD;      /* protect from close */
-                       }
-               }
-               reset_cur_connection();
-       }
-       close_any(whackfd);
-}
-
-/* (Possibly) Opportunistic Initiation:
- * Knowing clients (single IP addresses), try to build an tunnel.
- * This may involve discovering a gateway and instantiating an
- * Opportunistic connection.  Called when a packet is caught by
- * a %trap, or when whack --oppohere --oppothere is used.
- * It may turn out that an existing or non-opporunistic connnection
- * can handle the traffic.
- *
- * Most of the code will be restarted if an ADNS request is made
- * to discover the gateway.  The only difference between the first
- * and second entry is whether gateways_from_dns is NULL or not.
- *      initiate_opportunistic: initial entrypoint
- *      continue_oppo: where we pickup when ADNS result arrives
- *      initiate_opportunistic_body: main body shared by above routines
- *      cannot_oppo: a helper function to log a diagnostic
- * This structure repeats a lot of code when the ADNS result arrives.
- * This seems like a waste, but anything learned the first time through
- * may no longer be true!
- *
- * After the first IKE message is sent, the regular state machinery
- * carries negotiation forward.
- */
-
-enum find_oppo_step {
-       fos_start,
-       fos_myid_ip_txt,
-       fos_myid_hostname_txt,
-       fos_myid_ip_key,
-       fos_myid_hostname_key,
-       fos_our_client,
-       fos_our_txt,
-#ifdef USE_KEYRR
-       fos_our_key,
-#endif /* USE_KEYRR */
-       fos_his_client,
-       fos_done
-};
-
-#ifdef DEBUG
-static const char *const oppo_step_name[] = {
-       "fos_start",
-       "fos_myid_ip_txt",
-       "fos_myid_hostname_txt",
-       "fos_myid_ip_key",
-       "fos_myid_hostname_key",
-       "fos_our_client",
-       "fos_our_txt",
-#ifdef USE_KEYRR
-       "fos_our_key",
-#endif /* USE_KEYRR */
-       "fos_his_client",
-       "fos_done"
-};
-#endif /* DEBUG */
-
-struct find_oppo_bundle {
-       enum find_oppo_step step;
-       err_t want;
-       bool failure_ok;            /* if true, continue_oppo should not die on DNS failure */
-       ip_address our_client;      /* not pointer! */
-       ip_address peer_client;
-       int transport_proto;
-       bool held;
-       policy_prio_t policy_prio;
-       ipsec_spi_t failure_shunt;  /* in host order!  0 for delete. */
-       int whackfd;
-};
-
-struct find_oppo_continuation {
-       struct adns_continuation ac;        /* common prefix */
-       struct find_oppo_bundle b;
-};
-
-static void cannot_oppo(connection_t *c, struct find_oppo_bundle *b, err_t ugh)
-{
-       char pcb[ADDRTOT_BUF];
-       char ocb[ADDRTOT_BUF];
-
-       addrtot(&b->peer_client, 0, pcb, sizeof(pcb));
-       addrtot(&b->our_client, 0, ocb, sizeof(ocb));
-
-       DBG(DBG_DNS | DBG_OPPO, DBG_log("Can't Opportunistically initiate for %s to %s: %s"
-               , ocb, pcb, ugh));
-
-       whack_log(RC_OPPOFAILURE
-               , "Can't Opportunistically initiate for %s to %s: %s"
-               , ocb, pcb, ugh);
-
-       if (c && c->policy_next)
-       {
-               /* there is some policy that comes afterwards */
-               struct spd_route *shunt_spd;
-               connection_t *nc = c->policy_next;
-               struct state *st;
-
-               passert(c->kind == CK_TEMPLATE);
-               passert(c->policy_next->kind == CK_PERMANENT);
-
-               DBG(DBG_OPPO, DBG_log("OE failed for %s to %s, but %s overrides shunt"
-                                                         , ocb, pcb, c->policy_next->name));
-
-               /*
-                * okay, here we need add to the "next" policy, which is ought
-                * to be an instance.
-                * We will add another entry to the spd_route list for the specific
-                * situation that we have.
-                */
-
-               shunt_spd = clone_thing(nc->spd);
-
-               shunt_spd->next = nc->spd.next;
-               nc->spd.next = shunt_spd;
-
-               happy(addrtosubnet(&b->peer_client, &shunt_spd->that.client));
-
-               if (sameaddr(&b->peer_client, &shunt_spd->that.host_addr))
-                       shunt_spd->that.has_client = FALSE;
-
-               /*
-                * override the tunnel destination with the one from the secondaried
-                * policy
-                */
-               shunt_spd->that.host_addr = nc->spd.that.host_addr;
-
-               /* now, lookup the state, and poke it up.
-                */
-
-               st = state_with_serialno(nc->newest_ipsec_sa);
-
-               /* XXX what to do if the IPSEC SA has died? */
-               passert(st != NULL);
-
-               /* link the new connection instance to the state's list of
-                * connections
-                */
-
-               DBG(DBG_OPPO, DBG_log("installing state: %ld for %s to %s"
-                                                         , nc->newest_ipsec_sa
-                                                         , ocb, pcb));
-
-#ifdef DEBUG
-               if (DBGP(DBG_OPPO | DBG_CONTROLMORE))
-               {
-                       char state_buf[LOG_WIDTH];
-                       char state_buf2[LOG_WIDTH];
-                       time_t n = now();
-
-                       fmt_state(FALSE, st, n
-                                         , state_buf, sizeof(state_buf)
-                                         , state_buf2, sizeof(state_buf2));
-                       DBG_log("cannot_oppo, failure SA1: %s", state_buf);
-                       DBG_log("cannot_oppo, failure SA2: %s", state_buf2);
-               }
-#endif /* DEBUG */
-
-               if (!route_and_eroute(c, shunt_spd, st))
-               {
-                       whack_log(RC_OPPOFAILURE
-                                         , "failed to instantiate shunt policy %s for %s to %s"
-                                         , c->name
-                                         , ocb, pcb);
-               }
-               return;
-       }
-}
-
-static void initiate_opportunistic_body(struct find_oppo_bundle *b
-       , struct adns_continuation *ac, err_t ac_ugh);      /* forward */
-
-void initiate_opportunistic(const ip_address *our_client,
-                                                       const ip_address *peer_client, int transport_proto,
-                                                       bool held, int whackfd)
-{
-       struct find_oppo_bundle b;
-
-       b.want = (whackfd == NULL_FD ? "whack" : "acquire");
-       b.failure_ok = FALSE;
-       b.our_client = *our_client;
-       b.peer_client = *peer_client;
-       b.transport_proto = transport_proto;
-       b.held = held;
-       b.policy_prio = BOTTOM_PRIO;
-       b.failure_shunt = 0;
-       b.whackfd = whackfd;
-       b.step = fos_start;
-       initiate_opportunistic_body(&b, NULL, NULL);
-}
-
-#ifdef ADNS
-
-static void continue_oppo(struct adns_continuation *acr, err_t ugh)
-{
-       struct find_oppo_continuation *cr = (void *)acr;    /* inherit, damn you! */
-       connection_t *c;
-       bool was_held = cr->b.held;
-       int whackfd = cr->b.whackfd;
-
-       /* note: cr->id has no resources; cr->sgw_id is ID_ANY:
-        * neither need freeing.
-        */
-       whack_log_fd = whackfd;
-
-#ifdef DEBUG
-       /* if we're going to ignore the error, at least note it in debugging log */
-       if (cr->b.failure_ok && ugh)
-       {
-               DBG(DBG_CONTROL | DBG_DNS,
-                       {
-                               char ocb[ADDRTOT_BUF];
-                               char pcb[ADDRTOT_BUF];
-
-                               addrtot(&cr->b.our_client, 0, ocb, sizeof(ocb));
-                               addrtot(&cr->b.peer_client, 0, pcb, sizeof(pcb));
-                               DBG_log("continuing from failed DNS lookup for %s, %s to %s: %s"
-                                       , cr->b.want, ocb, pcb, ugh);
-                       });
-       }
-#endif
-
-       if (!cr->b.failure_ok && ugh)
-       {
-               c = find_connection_for_clients(NULL, &cr->b.our_client, &cr->b.peer_client
-                       , cr->b.transport_proto);
-               cannot_oppo(c, &cr->b
-                                       , builddiag("%s: %s", cr->b.want, ugh));
-       }
-       else if (was_held && !cr->b.held)
-       {
-               /* was_held indicates we were started due to a %trap firing
-                * (as opposed to a "whack --oppohere --oppothere").
-                * Since the %hold has gone, we can assume that somebody else
-                * has beaten us to the punch.  We can go home.  But lets log it.
-                */
-               char ocb[ADDRTOT_BUF];
-               char pcb[ADDRTOT_BUF];
-
-               addrtot(&cr->b.our_client, 0, ocb, sizeof(ocb));
-               addrtot(&cr->b.peer_client, 0, pcb, sizeof(pcb));
-
-               loglog(RC_COMMENT
-                       , "%%hold otherwise handled during DNS lookup for Opportunistic Initiation for %s to %s"
-                       , ocb, pcb);
-       }
-       else
-       {
-               initiate_opportunistic_body(&cr->b, &cr->ac, ugh);
-               whackfd = NULL_FD;      /* was handed off */
-       }
-
-       whack_log_fd = NULL_FD;
-       close_any(whackfd);
-}
-
-#endif /* ADNS */
-
-#ifdef USE_KEYRR
-static err_t check_key_recs(enum myid_state try_state, const connection_t *c,
-                                                       struct adns_continuation *ac)
-{
-       /* Check if KEY lookup yielded good results.
-        * Looking up based on our ID.  Used if
-        * client is ourself, or if TXT had no public key.
-        * Note: if c is different this time, there is
-        * a chance that we did the wrong query.
-        * If so, treat as a kind of failure.
-        */
-       enum myid_state old_myid_state = myid_state;
-       private_key_t *private;
-       err_t ugh = NULL;
-
-       myid_state = try_state;
-
-       if (old_myid_state != myid_state && old_myid_state == MYID_SPECIFIED)
-       {
-               ugh = "%myid was specified while we were guessing";
-       }
-       else if ((private = get_private_key(c)) == NULL)
-       {
-               ugh = "we don't know our own RSA key";
-       }
-       else if (!same_id(&ac->id, &c->spd.this.id))
-       {
-               ugh = "our ID changed underfoot";
-       }
-       else
-       {
-               /* Similar to code in RSA_check_signature
-                * for checking the other side.
-                */
-               pubkey_list_t *kr;
-
-               ugh = "no KEY RR found for us";
-               for (kr = ac->keys_from_dns; kr != NULL; kr = kr->next)
-               {
-                       ugh = "all our KEY RRs have the wrong public key";
-                       if (kr->key->alg == PUBKEY_ALG_RSA
-                       && private->belongs_to(private, &kr->key->public_key))
-                       {
-                               ugh = NULL;     /* good! */
-                               break;
-                       }
-               }
-       }
-       if (ugh)
-       {
-               myid_state = old_myid_state;
-       }
-       return ugh;
-}
-#endif /* USE_KEYRR */
-
-#ifdef ADNS
-
-static err_t check_txt_recs(enum myid_state try_state, const connection_t *c,
-                                                       struct adns_continuation *ac)
-{
-       /* Check if TXT lookup yielded good results.
-        * Looking up based on our ID.  Used if
-        * client is ourself, or if TXT had no public key.
-        * Note: if c is different this time, there is
-        * a chance that we did the wrong query.
-        * If so, treat as a kind of failure.
-        */
-       enum myid_state old_myid_state = myid_state;
-       private_key_t *private;
-       err_t ugh = NULL;
-
-       myid_state = try_state;
-
-       if (old_myid_state != myid_state
-       && old_myid_state == MYID_SPECIFIED)
-       {
-               ugh = "%myid was specified while we were guessing";
-       }
-       else if ((private = get_private_key(c)) == NULL)
-       {
-               ugh = "we don't know our own RSA key";
-       }
-       else if (!ac->id->equals(ac->id, c->spd.this.id))
-       {
-               ugh = "our ID changed underfoot";
-       }
-       else
-       {
-               /* Similar to code in RSA_check_signature
-                * for checking the other side.
-                */
-               struct gw_info *gwp;
-
-               ugh = "no TXT RR found for us";
-               for (gwp = ac->gateways_from_dns; gwp != NULL; gwp = gwp->next)
-               {
-                       public_key_t *pub_key = gwp->key->public_key;
-
-                       ugh = "all our TXT RRs have the wrong public key";
-                       if (pub_key->get_type(pub_key) == KEY_RSA &&
-                           private->belongs_to(private, pub_key))
-                       {
-                               ugh = NULL;     /* good! */
-                               break;
-                       }
-               }
-       }
-       if (ugh)
-       {
-               myid_state = old_myid_state;
-       }
-       return ugh;
-}
-
-#endif /* ADNS */
-
-
-/* note: gateways_from_dns must be NULL iff this is the first call */
-static void initiate_opportunistic_body(struct find_oppo_bundle *b,
-                                                                               struct adns_continuation *ac,
-                                                                               err_t ac_ugh)
-{
-       connection_t *c;
-       struct spd_route *sr;
-
-       /* What connection shall we use?
-        * First try for one that explicitly handles the clients.
-        */
-       DBG(DBG_CONTROL,
-               {
-                       char ours[ADDRTOT_BUF];
-                       char his[ADDRTOT_BUF];
-                       int ourport;
-                       int hisport;
-
-                       addrtot(&b->our_client, 0, ours, sizeof(ours));
-                       addrtot(&b->peer_client, 0, his, sizeof(his));
-                       ourport = ntohs(portof(&b->our_client));
-                       hisport = ntohs(portof(&b->peer_client));
-                       DBG_log("initiate on demand from %s:%d to %s:%d proto=%d state: %s because: %s"
-                               , ours, ourport, his, hisport, b->transport_proto
-                               , oppo_step_name[b->step], b->want);
-               });
-       if (isanyaddr(&b->our_client) || isanyaddr(&b->peer_client))
-       {
-               cannot_oppo(NULL, b, "impossible IP address");
-       }
-       else if ((c = find_connection_for_clients(&sr
-                                                                                         , &b->our_client
-                                                                                         , &b->peer_client
-                                                                                         , b->transport_proto)) == NULL)
-       {
-               /* No connection explicitly handles the clients and there
-                * are no Opportunistic connections -- whine and give up.
-                * The failure policy cannot be gotten from a connection; we pick %pass.
-                */
-               cannot_oppo(NULL, b, "no routed Opportunistic template covers this pair");
-       }
-       else if (c->kind != CK_TEMPLATE)
-       {
-               /* We've found a connection that can serve.
-                * Do we have to initiate it?
-                * Not if there is currently an IPSEC SA.
-                * But if there is an IPSEC SA, then the kernel would not
-                * have generated the acquire.  So we assume that there isn't one.
-                * This may be redundant if a non-opportunistic
-                * negotiation is already being attempted.
-                */
-
-               /* If we are to proceed asynchronously, b->whackfd will be NULL_FD. */
-
-               if(c->kind == CK_INSTANCE)
-               {
-                       char cib[CONN_INST_BUF];
-                       /* there is already an instance being negotiated, no nothing */
-                       DBG(DBG_CONTROL, DBG_log("found existing instance \"%s\"%s, rekeying it"
-                                                                        , c->name
-                                                                        , (fmt_conn_instance(c, cib), cib)));
-                       /* XXX-mcr - return; */
-               }
-
-               /* otherwise, there is some kind of static conn that can handle
-                * this connection, so we initiate it */
-
-               if (b->held)
-               {
-                       /* what should we do on failure? */
-                       (void) assign_hold(c, sr, b->transport_proto, &b->our_client, &b->peer_client);
-               }
-               ipsecdoi_initiate(b->whackfd, c, c->policy, 1, SOS_NOBODY);
-               b->whackfd = NULL_FD;   /* protect from close */
-       }
-#ifdef ADNS
-       else
-       {
-               /* We are handling an opportunistic situation.
-                * This involves several DNS lookup steps that require suspension.
-                * Note: many facts might change while we're suspended.
-                * Here be dragons.
-                *
-                * The first chunk of code handles the result of the previous
-                * DNS query (if any).  It also selects the kind of the next step.
-                * The second chunk initiates the next DNS query (if any).
-                */
-               enum find_oppo_step next_step = fos_myid_ip_txt;
-               err_t ugh = ac_ugh;
-               char mycredentialstr[BUF_LEN];
-               char cib[CONN_INST_BUF];
-
-               DBG(DBG_CONTROL, DBG_log("creating new instance from \"%s\"%s",
-                                                                c->name, (fmt_conn_instance(c, cib), cib)));
-               snprintf(mycredentialstr, BUF_LEN, "%Y", sr->this.id);
-
-               /* handle any DNS answer; select next step */
-               switch (b->step)
-               {
-               case fos_start:
-                       /* just starting out: select first query step */
-                       next_step = fos_myid_ip_txt;
-                       break;
-
-               case fos_myid_ip_txt:   /* TXT for our default IP address as %myid */
-                       ugh = check_txt_recs(MYID_IP, c, ac);
-                       if (ugh)
-                       {
-                               /* cannot use our IP as OE identitiy for initiation */
-                               DBG(DBG_OPPO,
-                                       DBG_log("can not use our IP (%Y:TXT) as identity: %s",
-                                                       myids[MYID_IP], ugh));
-                               if (!logged_myid_ip_txt_warning)
-                               {
-                                       loglog(RC_LOG_SERIOUS,
-                                                       "can not use our IP (%Y:TXT) as identity: %s",
-                                                       myids[MYID_IP], ugh);
-                                       logged_myid_ip_txt_warning = TRUE;
-                               }
-
-                               next_step = fos_myid_hostname_txt;
-                               ugh = NULL;     /* failure can be recovered from */
-                       }
-                       else
-                       {
-                               /* we can use our IP as OE identity for initiation */
-                               if (!logged_myid_ip_txt_warning)
-                               {
-                                       loglog(RC_LOG_SERIOUS,
-                                                       "using our IP (%Y:TXT) as identity!",
-                                                       myids[MYID_IP]);
-                                       logged_myid_ip_txt_warning = TRUE;
-                               }
-
-                               next_step = fos_our_client;
-                       }
-                       break;
-
-               case fos_myid_hostname_txt:     /* TXT for our hostname as %myid */
-                       ugh = check_txt_recs(MYID_HOSTNAME, c, ac);
-                       if (ugh)
-                       {
-                               /* cannot use our hostname as OE identitiy for initiation */
-                               DBG(DBG_OPPO,
-                                       DBG_log("can not use our hostname (%Y:TXT) as identity: %s",
-                                                       myids[MYID_HOSTNAME], ugh));
-                               if (!logged_myid_fqdn_txt_warning)
-                               {
-                                       loglog(RC_LOG_SERIOUS,
-                                                       "can not use our hostname (%Y:TXT) as identity: %s",
-                                                       myids[MYID_HOSTNAME], ugh);
-                                       logged_myid_fqdn_txt_warning = TRUE;
-                               }
-#ifdef USE_KEYRR
-                               next_step = fos_myid_ip_key;
-                               ugh = NULL;     /* failure can be recovered from */
-#endif
-                       }
-                       else
-                       {
-                               /* we can use our hostname as OE identity for initiation */
-                               if (!logged_myid_fqdn_txt_warning)
-                               {
-                                       loglog(RC_LOG_SERIOUS,
-                                                       "using our hostname (%Y:TXT) as identity!",
-                                                       myids[MYID_HOSTNAME]);
-                                       logged_myid_fqdn_txt_warning = TRUE;
-                               }
-                               next_step = fos_our_client;
-                       }
-                       break;
-
-#ifdef USE_KEYRR
-               case fos_myid_ip_key:   /* KEY for our default IP address as %myid */
-                       ugh = check_key_recs(MYID_IP, c, ac);
-                       if (ugh)
-                       {
-                               /* cannot use our IP as OE identitiy for initiation */
-                               DBG(DBG_OPPO,
-                                       DBG_log("can not use our IP (%Y:KEY) as identity: %s",
-                                                       myids[MYID_IP], ugh));
-                               if (!logged_myid_ip_key_warning)
-                               {
-                                       loglog(RC_LOG_SERIOUS,
-                                                       "can not use our IP (%Y:KEY) as identity: %s",
-                                                       myids[MYID_IP], ugh);
-                                       logged_myid_ip_key_warning = TRUE;
-                               }
-
-                               next_step = fos_myid_hostname_key;
-                               ugh = NULL;     /* failure can be recovered from */
-                       }
-                       else
-                       {
-                               /* we can use our IP as OE identity for initiation */
-                               if (!logged_myid_ip_key_warning)
-                               {
-                                       loglog(RC_LOG_SERIOUS,
-                                                       "using our IP (%Y:KEY) as identity!",
-                                                       myids[MYID_IP]);
-                                       logged_myid_ip_key_warning = TRUE;
-                               }
-                               next_step = fos_our_client;
-                       }
-                       break;
-
-               case fos_myid_hostname_key:     /* KEY for our hostname as %myid */
-                       ugh = check_key_recs(MYID_HOSTNAME, c, ac);
-                       if (ugh)
-                       {
-                               /* cannot use our IP as OE identitiy for initiation */
-                               DBG(DBG_OPPO,
-                                       DBG_log("can not use our hostname (%Y:KEY) as identity: %s",
-                                                       myids[MYID_HOSTNAME], ugh));
-                               if (!logged_myid_fqdn_key_warning)
-                               {
-                                       loglog(RC_LOG_SERIOUS,
-                                                       "can not use our hostname (%Y:KEY) as identity: %s",
-                                                       myids[MYID_HOSTNAME], ugh);
-                                       logged_myid_fqdn_key_warning = TRUE;
-                               }
-                               next_step = fos_myid_hostname_key;
-                               ugh = NULL;     /* failure can be recovered from */
-                       }
-                       else
-                       {
-                               /* we can use our IP as OE identity for initiation */
-                               if (!logged_myid_fqdn_key_warning)
-                               {
-                                       loglog(RC_LOG_SERIOUS,
-                                                       "using our hostname (%Y:KEY) as identity!",
-                                                       myids[MYID_HOSTNAME]);
-                                       logged_myid_fqdn_key_warning = TRUE;
-                               }
-                               next_step = fos_our_client;
-                       }
-                       break;
-#endif
-
-               case fos_our_client:    /* TXT for our client */
-                       {
-                               /* Our client is not us: we must check the TXT records.
-                                * Note: if c is different this time, there is
-                                * a chance that we did the wrong query.
-                                * If so, treat as a kind of failure.
-                                */
-                               private_key_t *private = get_private_key(c);
-
-                               next_step = fos_his_client;     /* normal situation */
-
-                               if (private == NULL)
-                               {
-                                       ugh = "we don't know our own RSA key";
-                               }
-                               else if (sameaddr(&sr->this.host_addr, &b->our_client))
-                               {
-                                       /* this wasn't true when we started -- bail */
-                                       ugh = "our IP address changed underfoot";
-                               }
-                               else if (!ac->sgw_id->equals(ac->sgw_id, sr->this.id))
-                               {
-                                       /* this wasn't true when we started -- bail */
-                                       ugh = "our ID changed underfoot";
-                               }
-                               else
-                               {
-                                       /* Similar to code in quick_inI1_outR1_tail
-                                        * for checking the other side.
-                                        */
-                                       struct gw_info *gwp;
-
-                                       ugh = "no TXT RR for our client delegates us";
-                                       for (gwp = ac->gateways_from_dns; gwp != NULL; gwp = gwp->next)
-                                       {
-                                               ugh = "TXT RR for our client has wrong key";
-                                               /* If there is a key from the TXT record,
-                                                * we count it as a win if we match the key.
-                                                * If there was no key, we have a tentative win:
-                                                * we need to check our KEY record to be sure.
-                                                */
-                                               if (!gwp->gw_key_present)
-                                               {
-                                                       /* Success, but the TXT had no key
-                                                        * so we must check our our own KEY records.
-                                                        */
-                                                       next_step = fos_our_txt;
-                                                       ugh = NULL; /* good! */
-                                                       break;
-                                               }
-                                               if (private->belongs_to(private, gwp->key->public_key))
-                                               {
-                                                       ugh = NULL; /* good! */
-                                                       break;
-                                               }
-                                       }
-                               }
-                       }
-                       break;
-
-               case fos_our_txt:       /* TXT for us */
-                       {
-                               /* Check if TXT lookup yielded good results.
-                                * Looking up based on our ID.  Used if
-                                * client is ourself, or if TXT had no public key.
-                                * Note: if c is different this time, there is
-                                * a chance that we did the wrong query.
-                                * If so, treat as a kind of failure.
-                                */
-                               private_key_t *private = get_private_key(c);
-
-                               next_step = fos_his_client;     /* unless we decide to look for KEY RR */
-
-                               if (private == NULL)
-                               {
-                                       ugh = "we don't know our own RSA key";
-                               }
-                               else if (!ac->id->equals(ac->id, c->spd.this.id))
-                               {
-                                       ugh = "our ID changed underfoot";
-                               }
-                               else
-                               {
-                                       /* Similar to code in RSA_check_signature
-                                        * for checking the other side.
-                                        */
-                                       struct gw_info *gwp;
-
-                                       ugh = "no TXT RR for us";
-                                       for (gwp = ac->gateways_from_dns; gwp != NULL; gwp = gwp->next)
-                                       {
-                                               ugh = "TXT RR for us has wrong key";
-                                               if (gwp->gw_key_present &&
-                                                       private->belongs_to(private, gwp->key->public_key))
-                                               {
-                                                       DBG(DBG_CONTROL,
-                                                               DBG_log("initiate on demand found TXT with right public key at: %s"
-                                                                               , mycredentialstr));
-                                                       ugh = NULL;
-                                                       break;
-                                               }
-                                       }
-#ifdef USE_KEYRR
-                                       if (ugh)
-                                       {
-                                               /* if no TXT with right key, try KEY */
-                                               DBG(DBG_CONTROL,
-                                                       DBG_log("will try for KEY RR since initiate on demand found %s: %s"
-                                                                       , ugh, mycredentialstr));
-                                               next_step = fos_our_key;
-                                               ugh = NULL;
-                                       }
-#endif
-                               }
-                       }
-                       break;
-
-#ifdef USE_KEYRR
-               case fos_our_key:       /* KEY for us */
-                       {
-                               /* Check if KEY lookup yielded good results.
-                                * Looking up based on our ID.  Used if
-                                * client is ourself, or if TXT had no public key.
-                                * Note: if c is different this time, there is
-                                * a chance that we did the wrong query.
-                                * If so, treat as a kind of failure.
-                                */
-                               private_key_t *private = get_private_key(c);
-
-                               next_step = fos_his_client;     /* always */
-
-                               if (private == NULL)
-                               {
-                                       ugh = "we don't know our own RSA key";
-                               }
-                               else if (!same_id(&ac->id, &c->spd.this.id))
-                               {
-                                       ugh = "our ID changed underfoot";
-                               }
-                               else
-                               {
-                                       /* Similar to code in RSA_check_signature
-                                        * for checking the other side.
-                                        */
-                                       pubkey_list_t *kr;
-
-                                       ugh = "no KEY RR found for us (and no good TXT RR)";
-                                       for (kr = ac->keys_from_dns; kr != NULL; kr = kr->next)
-                                       {
-                                               ugh = "all our KEY RRs have the wrong public key (and no good TXT RR)";
-                                               if (kr->key->alg == PUBKEY_ALG_RSA
-                                               && private->belongs_to(private, kr->key->public_key))
-                                               {
-                                                       /* do this only once a day */
-                                                       if (!logged_txt_warning)
-                                                       {
-                                                               loglog(RC_LOG_SERIOUS
-                                                                          , "found KEY RR but not TXT RR for %s. See http://www.freeswan.org/err/txt-change.html."
-                                                                          , mycredentialstr);
-                                                               logged_txt_warning = TRUE;
-                                                       }
-                                                       ugh = NULL; /* good! */
-                                                       break;
-                                               }
-                                       }
-                               }
-                       }
-                       break;
-#endif /* USE_KEYRR */
-
-               case fos_his_client:    /* TXT for his client */
-                       {
-                               /* We've finished last DNS queries: TXT for his client.
-                                * Using the information, try to instantiate a connection
-                                * and start negotiating.
-                                * We now know the peer.  The chosing of "c" ignored this,
-                                * so we will disregard its current value.
-                                * !!! We need to randomize the entry in gw that we choose.
-                                */
-                               next_step = fos_done;   /* no more queries */
-
-                               c = build_outgoing_opportunistic_connection(ac->gateways_from_dns
-                                                                                                                       , &b->our_client
-                                                                                                                       , &b->peer_client);
-
-                               if (c == NULL)
-                               {
-                                       /* We cannot seem to instantiate a suitable connection:
-                                        * complain clearly.
-                                        */
-                                       char ocb[ADDRTOT_BUF], pcb[ADDRTOT_BUF];
-
-                                       addrtot(&b->our_client, 0, ocb, sizeof(ocb));
-                                       addrtot(&b->peer_client, 0, pcb, sizeof(pcb));
-                                       loglog(RC_OPPOFAILURE,
-                                                       "no suitable connection for opportunism "
-                                                       "between %s and %s with %Y as peer",
-                                                        ocb, pcb, ac->gateways_from_dns->gw_id);
-                               }
-                               else
-                               {
-                                       /* If we are to proceed asynchronously, b->whackfd will be NULL_FD. */
-                                       passert(c->kind == CK_INSTANCE);
-                                       passert(c->gw_info != NULL);
-                                       passert(HAS_IPSEC_POLICY(c->policy));
-                                       passert(LHAS(LELEM(RT_UNROUTED) | LELEM(RT_ROUTED_PROSPECTIVE), c->spd.routing));
-                                       if (b->held)
-                                       {
-                                               /* what should we do on failure? */
-                                               (void) assign_hold(c, &c->spd
-                                                                                  , b->transport_proto
-                                                                                  , &b->our_client, &b->peer_client);
-                                       }
-                                       c->gw_info->key->last_tried_time = now();
-                                       ipsecdoi_initiate(b->whackfd, c, c->policy, 1, SOS_NOBODY);
-                                       b->whackfd = NULL_FD;       /* protect from close */
-                               }
-                       }
-                       break;
-
-               default:
-                       bad_case(b->step);
-               }
-
-               /* the second chunk: initiate the next DNS query (if any) */
-               DBG(DBG_CONTROL,
-               {
-                       char ours[ADDRTOT_BUF];
-                       char his[ADDRTOT_BUF];
-
-                       addrtot(&b->our_client, 0, ours, sizeof(ours));
-                       addrtot(&b->peer_client, 0, his, sizeof(his));
-                       DBG_log("initiate on demand from %s to %s new state: %s with ugh: %s"
-                                       , ours, his, oppo_step_name[b->step], ugh ? ugh : "ok");
-               });
-
-               if (ugh)
-               {
-                       b->policy_prio = c->prio;
-                       b->failure_shunt = shunt_policy_spi(c, FALSE);
-                       cannot_oppo(c, b, ugh);
-               }
-               else if (next_step == fos_done)
-               {
-                       /* nothing to do */
-               }
-               else
-               {
-                       /* set up the next query */
-                       struct find_oppo_continuation *cr = malloc_thing(struct find_oppo_continuation);
-                       identification_t *id;
-
-                       b->policy_prio = c->prio;
-                       b->failure_shunt = shunt_policy_spi(c, FALSE);
-                       cr->b = *b; /* copy; start hand off of whackfd */
-                       cr->b.failure_ok = FALSE;
-                       cr->b.step = next_step;
-
-                       for (sr = &c->spd
-                       ; sr!=NULL && !sameaddr(&sr->this.host_addr, &b->our_client)
-                       ; sr = sr->next)
-                               ;
-
-                       if (sr == NULL)
-                               sr = &c->spd;
-
-                       /* If a %hold shunt has replaced the eroute for this template,
-                        * record this fact.
-                        */
-                       if (b->held
-                       && sr->routing == RT_ROUTED_PROSPECTIVE && eclipsable(sr))
-                       {
-                               sr->routing = RT_ROUTED_ECLIPSED;
-                               eclipse_count++;
-                       }
-
-                       /* Switch to issue next query.
-                        * A case may turn out to be unnecessary.  If so, it falls
-                        * through to the next case.
-                        * Figuring out what %myid can stand for must be done before
-                        * our client credentials are looked up: we must know what
-                        * the client credentials may use to identify us.
-                        * On the other hand, our own credentials should be looked
-                        * up after our clients in case our credentials are not
-                        * needed at all.
-                        * XXX this is a wasted effort if we don't have credentials
-                        * BUT they are not needed.
-                        */
-                       switch (next_step)
-                       {
-                       case fos_myid_ip_txt:
-                               if (c->spd.this.id->get_type(c->spd.this.id) == ID_MYID
-                               && myid_state != MYID_SPECIFIED)
-                               {
-                                       cr->b.failure_ok = TRUE;
-                                       cr->b.want = b->want = "TXT record for IP address as %myid";
-                                       ugh = start_adns_query(myids[MYID_IP], myids[MYID_IP],
-                                                                                  T_TXT, continue_oppo, &cr->ac);
-                                       break;
-                               }
-                               cr->b.step = fos_myid_hostname_txt;
-                               /* fall through */
-
-                       case fos_myid_hostname_txt:
-                               if (c->spd.this.id->get_type(c->spd.this.id) == ID_MYID
-                               && myid_state != MYID_SPECIFIED)
-                               {
-#ifdef USE_KEYRR
-                                       cr->b.failure_ok = TRUE;
-#else
-                                       cr->b.failure_ok = FALSE;
-#endif
-                                       cr->b.want = b->want = "TXT record for hostname as %myid";
-                                       ugh = start_adns_query(myids[MYID_HOSTNAME],
-                                                                                  myids[MYID_HOSTNAME],
-                                                                                  T_TXT, continue_oppo, &cr->ac);
-                                       break;
-                               }
-
-#ifdef USE_KEYRR
-                               cr->b.step = fos_myid_ip_key;
-                               /* fall through */
-
-                       case fos_myid_ip_key:
-                               if (c->spd.this.id.kind == ID_MYID
-                               && myid_state != MYID_SPECIFIED)
-                               {
-                                       cr->b.failure_ok = TRUE;
-                                       cr->b.want = b->want = "KEY record for IP address as %myid (no good TXT)";
-                                       ugh = start_adns_query(myids[MYID_IP], NULL, /* security gateway meaningless */
-                                                                                  T_KEY, continue_oppo, &cr->ac);
-                                       break;
-                               }
-                               cr->b.step = fos_myid_hostname_key;
-                               /* fall through */
-
-                       case fos_myid_hostname_key:
-                               if (c->spd.this.id.kind == ID_MYID
-                               && myid_state != MYID_SPECIFIED)
-                               {
-                                       cr->b.failure_ok = FALSE;           /* last attempt! */
-                                       cr->b.want = b->want = "KEY record for hostname as %myid (no good TXT)";
-                                       ugh = start_adns_query(myids[MYID_HOSTNAME], NULL, /* security gateway meaningless */
-                                                                                  T_KEY, continue_oppo, &cr->ac);
-                                       break;
-                               }
-#endif
-                               cr->b.step = fos_our_client;
-                               /* fall through */
-
-                       case fos_our_client:        /* TXT for our client */
-                               if (!sameaddr(&c->spd.this.host_addr, &b->our_client))
-                               {
-                                       /* Check that at least one TXT(reverse(b->our_client)) is workable.
-                                        * Note: {unshare|free}_id_content not needed for id: ephemeral.
-                                        */
-                                       cr->b.want = b->want = "our client's TXT record";
-                                       id = identification_create_from_sockaddr((sockaddr_t*)&b->our_client);
-                                       ugh = start_adns_query(id, c->spd.this.id, /* we are the security gateway */
-                                                                                  T_TXT, continue_oppo, &cr->ac);
-                                       id->destroy(id);
-                                       break;
-                               }
-                               cr->b.step = fos_our_txt;
-                               /* fall through */
-
-                       case fos_our_txt:   /* TXT for us */
-                               cr->b.failure_ok = b->failure_ok = TRUE;
-                               cr->b.want = b->want = "our TXT record";
-                               ugh = start_adns_query(sr->this.id, sr->this.id, /* we are the security gateway */
-                                                                          T_TXT, continue_oppo, &cr->ac);
-                               break;
-
-#ifdef USE_KEYRR
-                       case fos_our_key:   /* KEY for us */
-                               cr->b.want = b->want = "our KEY record";
-                               cr->b.failure_ok = b->failure_ok = FALSE;
-                               ugh = start_adns_query(sr->this.id, NULL,  /* security gateway meaningless */
-                                                                          T_KEY, continue_oppo, &cr->ac);
-                               break;
-#endif /* USE_KEYRR */
-
-                       case fos_his_client:        /* TXT for his client */
-                               /* note: {unshare|free}_id_content not needed for id: ephemeral */
-                               cr->b.want = b->want = "target's TXT record";
-                               cr->b.failure_ok = b->failure_ok = FALSE;
-                               id = identification_create_from_sockaddr((sockaddr_t*)&b->peer_client);
-                               ugh = start_adns_query(id, NULL, /* security gateway unconstrained */
-                                                                          T_TXT, continue_oppo, &cr->ac);
-                               id->destroy(id);
-                               break;
-
-                       default:
-                               bad_case(next_step);
-                       }
-
-                       if (ugh == NULL)
-                               b->whackfd = NULL_FD;   /* complete hand-off */
-                       else
-                               cannot_oppo(c, b, ugh);
-               }
-       }
-#endif /* ADNS */
-       close_any(b->whackfd);
-}
-
-void terminate_connection(const char *nm)
-{
-       /* Loop because more than one may match (master and instances)
-        * But at least one is required (enforced by con_by_name).
-        */
-       connection_t *c = con_by_name(nm, TRUE);
-
-       if (c == NULL || !c->ikev1)
-               return;
-
-       do
-       {
-               connection_t *n = c->ac_next;  /* grab this before c might disappear */
-
-               if (streq(c->name, nm)
-               && c->kind >= CK_PERMANENT
-               && !NEVER_NEGOTIATE(c->policy))
-               {
-                       set_cur_connection(c);
-                       plog("terminating SAs using this connection");
-                       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;
-       } while (c);
-}
-
-/* an ISAKMP SA has been established.
- * Note the serial number, and release any connections with
- * the same peer ID but different peer IP address.
- */
-bool uniqueIDs = FALSE; /* --uniqueids? */
-
-void ISAKMP_SA_established(connection_t *c, so_serial_t serial)
-{
-       c->newest_isakmp_sa = serial;
-
-       /* the connection is now oriented so that we are able to determine
-        * whether we are a mode config server with a virtual IP to send.
-        */
-       if (!c->spd.that.host_srcip->is_anyaddr(c->spd.that.host_srcip) &&
-           !c->spd.that.has_natip)
-       {
-               c->spd.that.modecfg = TRUE;
-       }
-
-       if (uniqueIDs)
-       {
-               /* for all connections: if the same Phase 1 IDs are used
-                * for a different IP address, unorient that connection.
-                */
-               connection_t *d;
-
-               for (d = connections; d != NULL; )
-               {
-                       connection_t *next = d->ac_next;       /* might move underneath us */
-
-                       if (d->kind >= CK_PERMANENT &&
-                               c->spd.this.id->equals(c->spd.this.id, d->spd.this.id) &&
-                               c->spd.that.id->equals(c->spd.that.id, d->spd.that.id) &&
-                               !sameaddr(&c->spd.that.host_addr, &d->spd.that.host_addr))
-                       {
-                               release_connection(d, FALSE);
-                       }
-                       d = next;
-               }
-       }
-}
-
-/* Find the connection to connection c's peer's client with the
- * largest value of .routing.  All other things being equal,
- * preference is given to c.  If none is routed, return NULL.
- *
- * If erop is non-null, set *erop to a connection sharing both
- * our client subnet and peer's client subnet with the largest value
- * of .routing.  If none is erouted, set *erop to NULL.
- *
- * The return value is used to find other connections sharing a route.
- * *erop is used to find other connections sharing an eroute.
- */
-connection_t *route_owner(connection_t *c, struct spd_route **srp,
-                                                 connection_t **erop, struct spd_route **esrp)
-{
-       connection_t *d
-               , *best_ro = c
-               , *best_ero = c;
-       struct spd_route *srd, *src;
-       struct spd_route *best_sr, *best_esr;
-       enum routing_t best_routing, best_erouting;
-
-       passert(oriented(*c));
-       best_sr  = NULL;
-       best_esr = NULL;
-       best_routing = c->spd.routing;
-       best_erouting = best_routing;
-
-       for (d = connections; d != NULL; d = d->ac_next)
-       {
-               for (srd = &d->spd; srd; srd = srd->next)
-               {
-                       if (srd->routing == RT_UNROUTED)
-                               continue;
-
-                       for (src = &c->spd; src; src=src->next)
-                       {
-                               if (!samesubnet(&src->that.client, &srd->that.client))
-                               {
-                                       continue;
-                               }
-                               if (src->that.protocol != srd->that.protocol)
-                               {
-                                       continue;
-                               }
-                               if (src->that.port != srd->that.port)
-                               {
-                                       continue;
-                               }
-                               if (src->mark_out.value != srd->mark_out.value)
-                               {
-                                       continue;
-                               }
-                               passert(oriented(*d));
-                               if (srd->routing > best_routing)
-                               {
-                                       best_ro = d;
-                                       best_sr = srd;
-                                       best_routing = srd->routing;
-                               }
-
-                               if (!samesubnet(&src->this.client, &srd->this.client))
-                               {
-                                       continue;
-                               }
-                               if (src->this.protocol != srd->this.protocol)
-                               {
-                                       continue;
-                               }
-                               if (src->this.port != srd->this.port)
-                               {
-                                       continue;
-                               }
-                               if (src->mark_in.value != srd->mark_in.value)
-                               {
-                                       continue;
-                               }
-                               if (srd->routing > best_erouting)
-                               {
-                                       best_ero = d;
-                                       best_esr = srd;
-                                       best_erouting = srd->routing;
-                               }
-                       }
-               }
-       }
-
-       DBG(DBG_CONTROL,
-               {
-                       char cib[CONN_INST_BUF];
-                       err_t m = builddiag("route owner of \"%s\"%s %s:"
-                               , c->name
-                               , (fmt_conn_instance(c, cib), cib)
-                               , enum_name(&routing_story, c->spd.routing));
-
-                       if (!routed(best_ro->spd.routing))
-                               m = builddiag("%s NULL", m);
-                       else if (best_ro == c)
-                               m = builddiag("%s self", m);
-                       else
-                               m = builddiag("%s \"%s\"%s %s", m
-                                       , best_ro->name
-                                       , (fmt_conn_instance(best_ro, cib), cib)
-                                       , enum_name(&routing_story, best_ro->spd.routing));
-
-                       if (erop)
-                       {
-                               m = builddiag("%s; eroute owner:", m);
-                               if (!erouted(best_ero->spd.routing))
-                                       m = builddiag("%s NULL", m);
-                               else if (best_ero == c)
-                                       m = builddiag("%s self", m);
-                               else
-                                       m = builddiag("%s \"%s\"%s %s", m
-                                               , best_ero->name
-                                               , (fmt_conn_instance(best_ero, cib), cib)
-                                               , enum_name(&routing_story, best_ero->spd.routing));
-                       }
-
-                       DBG_log("%s", m);
-               });
-
-       if (erop)
-       {
-               *erop = erouted(best_erouting)? best_ero : NULL;
-       }
-       if (srp)
-       {
-               *srp = best_sr;
-               if (esrp)
-               {
-                       *esrp = best_esr;
-               }
-       }
-
-       return routed(best_routing)? best_ro : NULL;
-}
-
-/* Find a connection that owns the shunt eroute between subnets.
- * There ought to be only one.
- * This might get to be a bottleneck -- try hashing if it does.
- */
-connection_t *shunt_owner(const ip_subnet *ours, const ip_subnet *his)
-{
-       connection_t *c;
-       struct spd_route *sr;
-
-       for (c = connections; c != NULL; c = c->ac_next)
-       {
-               for (sr = &c->spd; sr; sr = sr->next)
-               {
-                       if (shunt_erouted(sr->routing)
-                       && samesubnet(ours, &sr->this.client)
-                       && samesubnet(his, &sr->that.client))
-                               return c;
-               }
-       }
-       return NULL;
-}
-
-/* Find some connection with this pair of hosts.
- * We don't know enough to chose amongst those available.
- * ??? no longer usefully different from find_host_pair_connections
- */
-connection_t *find_host_connection(const ip_address *me, u_int16_t my_port,
-                                                                  const ip_address *him, u_int16_t his_port,
-                                                                  lset_t policy)
-{
-       connection_t *c = find_host_pair_connections(me, my_port, him, his_port);
-
-       if (policy != LEMPTY)
-       {
-               lset_t auth_requested  = policy & POLICY_ID_AUTH_MASK;
-
-               /* if we have requirements for the policy,
-                * choose the first matching connection.
-                */
-               while (c)
-               {
-                       if (c->policy & auth_requested)
-                       {
-                               break;
-                       }
-                       c = c->hp_next;
-               }
-       }
-       return c;
-}
-
-/* given an up-until-now satisfactory connection, find the best connection
- * now that we just got the Phase 1 Id Payload from the peer.
- *
- * Comments in the code describe the (tricky!) matching criteria.
- * Although this routine could handle the initiator case,
- * it isn't currently called in this case.
- * If it were, it could "upgrade" an Opportunistic Connection
- * to a Road Warrior Connection if a suitable Peer ID were found.
- *
- * In RFC 2409 "The Internet Key Exchange (IKE)",
- * in 5.1 "IKE Phase 1 Authenticated With Signatures", describing Main
- * Mode:
- *
- *         Initiator                          Responder
- *        -----------                        -----------
- *         HDR, SA                     -->
- *                                     <--    HDR, SA
- *         HDR, KE, Ni                 -->
- *                                     <--    HDR, KE, Nr
- *         HDR*, IDii, [ CERT, ] SIG_I -->
- *                                     <--    HDR*, IDir, [ CERT, ] SIG_R
- *
- * In 5.4 "Phase 1 Authenticated With a Pre-Shared Key":
- *
- *               HDR, SA             -->
- *                                   <--    HDR, SA
- *               HDR, KE, Ni         -->
- *                                   <--    HDR, KE, Nr
- *               HDR*, IDii, HASH_I  -->
- *                                   <--    HDR*, IDir, HASH_R
- *
- * refine_host_connection could be called in two case:
- *
- * - the Responder receives the IDii payload:
- *   + [PSK] after using PSK to decode this message
- *   + before sending its IDir payload
- *   + before using its ID in HASH_R computation
- *   + [DSig] before using its private key to sign SIG_R
- *   + before using the Initiator's ID in HASH_I calculation
- *   + [DSig] before using the Initiator's public key to check SIG_I
- *
- * - the Initiator receives the IDir payload:
- *   + [PSK] after using PSK to encode previous message and decode this message
- *   + after sending its IDii payload
- *   + after using its ID in HASH_I computation
- *   + [DSig] after using its private key to sign SIG_I
- *   + before using the Responder's ID to compute HASH_R
- *   + [DSig] before using Responder's public key to check SIG_R
- *
- * refine_host_connection can choose a different connection, as long as
- * nothing already used is changed.
- *
- * In the Initiator case, the particular connection might have been
- * specified by whatever provoked Pluto to initiate.  For example:
- *      whack --initiate connection-name
- * The advantages of switching connections when we're the Initiator seem
- * less important than the disadvantages, so after FreeS/WAN 1.9, we
- * don't do this.
- */
-#define PRIO_NO_MATCH_FOUND     2048
-
-connection_t *refine_host_connection(const struct state *st,
-                                                                        identification_t *peer_id,
-                                                                        identification_t *peer_ca)
-{
-       connection_t *c = st->st_connection;
-       connection_t *d;
-       connection_t *best_found = NULL;
-       u_int16_t auth = st->st_oakley.auth;
-       lset_t auth_policy = POLICY_PSK;
-       const chunk_t *psk = NULL;
-       bool wcpip; /* wildcard Peer IP? */
-       int best_prio = PRIO_NO_MATCH_FOUND;
-       int our_pathlen, peer_pathlen;
-
-       if (c->spd.that.id->equals(c->spd.that.id, peer_id) &&
-               trusted_ca(peer_ca, c->spd.that.ca, &peer_pathlen) &&
-               peer_pathlen == 0 &&
-               match_requested_ca(c->requested_ca, c->spd.this.ca, &our_pathlen) &&
-               our_pathlen == 0)
-       {
-               DBG(DBG_CONTROL,
-                       DBG_log("current connection is a full match"
-                                       " -- no need to look further");
-               )
-               return c;
-       }
-
-       switch (auth)
-       {
-       case OAKLEY_PRESHARED_KEY:
-               auth_policy = POLICY_PSK;
-               psk = get_preshared_secret(c);
-               /* It should be virtually impossible to fail to find PSK:
-                * we just used it to decode the current message!
-                */
-               if (psk == NULL)
-               {
-                       return NULL;        /* cannot determine PSK! */
-               }
-               break;
-       case XAUTHInitPreShared:
-       case XAUTHRespPreShared:
-               auth_policy = POLICY_XAUTH_PSK;
-               psk = get_preshared_secret(c);
-               if (psk == NULL)
-               {
-                       return NULL;        /* cannot determine PSK! */
-               }
-               break;
-       case OAKLEY_RSA_SIG:
-       case OAKLEY_ECDSA_256:
-       case OAKLEY_ECDSA_384:
-       case OAKLEY_ECDSA_521:
-               auth_policy = POLICY_PUBKEY;
-               break;
-       case XAUTHInitRSA:
-       case XAUTHRespRSA:
-               auth_policy = POLICY_XAUTH_RSASIG;
-               break;
-       default:
-               bad_case(auth);
-       }
-
-       /* The current connection won't do: search for one that will.
-        * First search for one with the same pair of hosts.
-        * If that fails, search for a suitable Road Warrior or Opportunistic
-        * connection (i.e. wildcard peer IP).
-        * We need to match:
-        * - peer_id (slightly complicated by instantiation)
-        * - if PSK auth, the key must not change (we used it to decode message)
-        * - policy-as-used must be acceptable to new connection
-        */
-       d = c->host_pair->connections;
-       for (wcpip = FALSE; ; wcpip = TRUE)
-       {
-               for (; d != NULL; d = d->hp_next)
-               {
-                       const char *match_name[] = {"no", "ok"};
-
-                       id_match_t match_level = peer_id->matches(peer_id, d->spd.that.id);
-
-                       bool matching_id = match_level > ID_MATCH_NONE;
-
-                       bool matching_auth = (d->policy & auth_policy) != LEMPTY;
-
-                       bool matching_trust = trusted_ca(peer_ca
-                                                                               , d->spd.that.ca, &peer_pathlen);
-                       bool matching_request = match_requested_ca(c->requested_ca
-                                                                               , d->spd.this.ca, &our_pathlen);
-                       bool match = matching_id && matching_auth && matching_trust;
-
-                       int prio = (ID_MATCH_PERFECT) * !matching_request +
-                                               ID_MATCH_PERFECT - match_level;
-
-                       prio = (X509_MAX_PATH_LEN + 1) * prio + peer_pathlen;
-                       prio = (X509_MAX_PATH_LEN + 1) * prio + our_pathlen;
-
-                       DBG(DBG_CONTROLMORE,
-                               DBG_log("%s: %s match (id: %s, auth: %s, trust: %s, request: %s, prio: %4d)"
-                                       , d->name
-                                       , match ? "full":" no"
-                                       , match_name[matching_id]
-                                       , match_name[matching_auth]
-                                       , match_name[matching_trust]
-                                       , match_name[matching_request]
-                                       , match ? prio:PRIO_NO_MATCH_FOUND)
-                       )
-
-                       /* do we have a match? */
-                       if (!match)
-                       {
-                               continue;
-                       }
-
-                       /* ignore group connections */
-                       if (d->policy & POLICY_GROUP)
-                       {
-                               continue;
-                       }
-
-                       if (c->spd.that.host_port != d->spd.that.host_port
-                       && d->kind == CK_INSTANCE)
-                       {
-                               continue;
-                       }
-
-                       switch (auth)
-                       {
-                       case OAKLEY_PRESHARED_KEY:
-                       case XAUTHInitPreShared:
-                       case XAUTHRespPreShared:
-                               /* secret must match the one we already used */
-                               {
-                                       const chunk_t *dpsk = get_preshared_secret(d);
-
-                                       if (dpsk == NULL)
-                                       {
-                                               continue;       /* no secret */
-                                       }
-                                       if (psk != dpsk)
-                                       {
-                                               if (psk->len != dpsk->len
-                                               || memcmp(psk->ptr, dpsk->ptr, psk->len) != 0)
-                                               {
-                                                       continue;   /* different secret */
-                                               }
-                                       }
-                               }
-                               break;
-
-                       case OAKLEY_RSA_SIG:
-                       case OAKLEY_ECDSA_256:
-                       case OAKLEY_ECDSA_384:
-                       case OAKLEY_ECDSA_521:
-                       case XAUTHInitRSA:
-                       case XAUTHRespRSA:
-                               /*
-                                * We must at least be able to find our private key
-                               .*/
-                               if (d->spd.this.sc == NULL              /* no smartcard */
-                               && get_private_key(d) == NULL)      /* no private key */
-                               {
-                                       continue;
-                               }
-                               break;
-
-                       default:
-                               bad_case(auth);
-                       }
-
-                       /* d has passed all the tests.
-                        * We'll go with it if the Peer ID was an exact match.
-                        */
-                       if (prio == 0)
-                       {
-                               return d;
-                       }
-
-                       /* We'll remember it as best_found in case an exact
-                        * match doesn't come along.
-                        */
-                       if (prio < best_prio)
-                       {
-                               best_found = d;
-                               best_prio = prio;
-                       }
-               }
-               if (wcpip)
-                       return best_found;  /* been around twice already */
-
-               /* Starting second time around.
-                * We're willing to settle for a connection that needs Peer IP
-                * instantiated: Road Warrior or Opportunistic.
-                * Look on list of connections for host pair with wildcard Peer IP
-                */
-               d = find_host_pair_connections(&c->spd.this.host_addr, c->spd.this.host_port
-                       , (ip_address *)NULL, c->spd.that.host_port);
-       }
-}
-
-/**
- * With virtual addressing, we must not allow someone to use an already
- * used (by another id) addr/net.
- */
-static bool is_virtual_net_used(const ip_subnet *peer_net,
-                                                               identification_t *peer_id)
-{
-       connection_t *d;
-
-       for (d = connections; d != NULL; d = d->ac_next)
-       {
-               switch (d->kind)
-               {
-               case CK_PERMANENT:
-               case CK_INSTANCE:
-                       if ((subnetinsubnet(peer_net,&d->spd.that.client) ||
-                                subnetinsubnet(&d->spd.that.client,peer_net))
-                       && !d->spd.that.id->equals(d->spd.that.id, peer_id))
-                       {
-                               char client[SUBNETTOT_BUF];
-
-                               subnettot(peer_net, 0, client, sizeof(client));
-                               plog("Virtual IP %s is already used by '%Y'",
-                                                client, d->spd.that.id);
-                               plog("Your ID is '%Y'", peer_id);
-
-                               return TRUE; /* already used by another one */
-                       }
-                       break;
-               case CK_GOING_AWAY:
-               default:
-               break;
-               }
-       }
-       return FALSE; /* you can safely use it */
-}
-
-/* find_client_connection: given a connection suitable for ISAKMP
- * (i.e. the hosts match), find a one suitable for IPSEC
- * (i.e. with matching clients).
- *
- * If we don't find an exact match (not even our current connection),
- * we try for one that still needs instantiation.  Try Road Warrior
- * abstract connections and the Opportunistic abstract connections.
- * This requires inverse instantiation: abstraction.
- *
- * After failing to find an exact match, we abstract the peer
- * to be NO_IP (the wildcard value).  This enables matches with
- * Road Warrior and Opportunistic abstract connections.
- *
- * After failing that search, we also abstract the Phase 1 peer ID
- * if possible.  If the peer's ID was the peer's IP address, we make
- * it NO_ID; instantiation will make it the peer's IP address again.
- *
- * If searching for a Road Warrior abstract connection fails,
- * and conditions are suitable, we search for the best Opportunistic
- * abstract connection.
- *
- * Note: in the end, both Phase 1 IDs must be preserved, after any
- * instantiation.  They are the IDs that have been authenticated.
- */
-
-#define PATH_WEIGHT     1
-#define WILD_WEIGHT     (X509_MAX_PATH_LEN+1)
-#define PRIO_WEIGHT     (ID_MATCH_PERFECT+1) * WILD_WEIGHT
-
-/* fc_try: a helper function for find_client_connection */
-static connection_t *fc_try(const connection_t *c, struct host_pair *hp,
-                                                       identification_t *peer_id,
-                                                       const ip_subnet *our_net,
-                                                       const ip_subnet *peer_net,
-                                                       const u_int8_t our_protocol,
-                                                       const u_int16_t our_port,
-                                                       const u_int8_t peer_protocol,
-                                                       const u_int16_t peer_port,
-                                                       identification_t *peer_ca,
-                                                       ietf_attributes_t *peer_attributes)
-{
-       connection_t *d;
-       connection_t *best = NULL;
-       policy_prio_t best_prio = BOTTOM_PRIO;
-       id_match_t match_level;
-       int pathlen;
-
-
-       const bool peer_net_is_host = subnetisaddr(peer_net, &c->spd.that.host_addr);
-
-       for (d = hp->connections; d != NULL; d = d->hp_next)
-       {
-               struct spd_route *sr;
-
-               if (d->policy & POLICY_GROUP)
-               {
-                       continue;
-               }
-
-               match_level = c->spd.that.id->matches(c->spd.that.id, d->spd.that.id);
-
-               if (!(c->spd.this.id->equals(c->spd.this.id, d->spd.this.id) &&
-                       (match_level > ID_MATCH_NONE) &&
-                       trusted_ca(peer_ca, d->spd.that.ca, &pathlen) &&
-                       match_group_membership(peer_attributes, d->name, d->spd.that.groups)))
-               {
-                       continue;
-               }
-
-               /* compare protocol and ports */
-               if (d->spd.this.protocol != our_protocol
-               ||  d->spd.this.port != our_port
-               ||  d->spd.that.protocol != peer_protocol
-               || (d->spd.that.port != peer_port && !d->spd.that.has_port_wildcard))
-               {
-                       continue;
-               }
-
-               /* non-Opportunistic case:
-                * our_client must match.
-                *
-                * So must peer_client, but the testing is complicated
-                * by the fact that the peer might be a wildcard
-                * and if so, the default value of that.client
-                * won't match the default peer_net.  The appropriate test:
-                *
-                * If d has a peer client, it must match peer_net.
-                * If d has no peer client, peer_net must just have peer itself.
-                */
-
-               for (sr = &d->spd; best != d && sr != NULL; sr = sr->next)
-               {
-                       policy_prio_t prio;
-#ifdef DEBUG
-                       if (DBGP(DBG_CONTROLMORE))
-                       {
-                               char s1[SUBNETTOT_BUF],d1[SUBNETTOT_BUF];
-                               char s3[SUBNETTOT_BUF],d3[SUBNETTOT_BUF];
-
-                               subnettot(our_net,  0, s1, sizeof(s1));
-                               subnettot(peer_net, 0, d1, sizeof(d1));
-                               subnettot(&sr->this.client,  0, s3, sizeof(s3));
-                               subnettot(&sr->that.client,  0, d3, sizeof(d3));
-                               DBG_log("  fc_try trying "
-                                               "%s:%s:%d/%d -> %s:%d/%d vs %s:%s:%d/%d -> %s:%d/%d"
-                                               , c->name, s1, c->spd.this.protocol, c->spd.this.port
-                                                                , d1, c->spd.that.protocol, c->spd.that.port
-                                               , d->name, s3, sr->this.protocol, sr->this.port
-                                                                , d3, sr->that.protocol, sr->that.port);
-                       }
-#endif /* DEBUG */
-
-                       if (!samesubnet(&sr->this.client, our_net))
-                       {
-                               continue;
-                       }
-                       if (sr->that.has_client)
-                       {
-                               if (sr->that.has_client_wildcard)
-                               {
-                                       if (!subnetinsubnet(peer_net, &sr->that.client))
-                                       {
-                                               continue;
-                                       }
-                               }
-                               else
-                               {
-                                       if (!samesubnet(&sr->that.client, peer_net) && !is_virtual_connection(d))
-                                       {
-                                               continue;
-                                       }
-                                       if (is_virtual_connection(d)
-                                       && (!is_virtual_net_allowed(d, peer_net, &c->spd.that.host_addr)
-                                               || is_virtual_net_used(peer_net, peer_id?peer_id:c->spd.that.id)))
-                                       {
-                                               continue;
-                                       }
-                               }
-                       }
-                       else
-                       {
-                               host_t *vip = c->spd.that.host_srcip;
-
-                               if (!peer_net_is_host && !(sr->that.modecfg && c->spd.that.modecfg &&
-                                               subnetisaddr(peer_net, (ip_address*)vip->get_sockaddr(vip))))
-                               {
-                                       continue;
-                               }
-                       }
-
-                       /* We've run the gauntlet -- success:
-                        * We've got an exact match of subnets.
-                        * The connection is feasible, but we continue looking for the best.
-                        * The highest priority wins, implementing eroute-like rule.
-                        * - a routed connection is preferrred
-                        * - given that, the smallest number of ID wildcards are preferred
-                        * - given that, the shortest CA pathlength is preferred
-                        */
-                       prio = PRIO_WEIGHT * routed(sr->routing)
-                                + WILD_WEIGHT * match_level
-                                + PATH_WEIGHT * (X509_MAX_PATH_LEN - pathlen)
-                                + 1;
-                       if (prio > best_prio)
-                       {
-                               best = d;
-                               best_prio = prio;
-                       }
-               }
-       }
-
-       if (best && NEVER_NEGOTIATE(best->policy))
-       {
-               best = NULL;
-       }
-       DBG(DBG_CONTROLMORE,
-               DBG_log("  fc_try concluding with %s [%ld]"
-                               , (best ? best->name : "none"), best_prio)
-       )
-       return best;
-}
-
-static connection_t *fc_try_oppo(const connection_t *c,
-                                                                struct host_pair *hp,
-                                                                const ip_subnet *our_net,
-                                                                const ip_subnet *peer_net,
-                                                                const u_int8_t our_protocol,
-                                                                const u_int16_t our_port,
-                                                                const u_int8_t peer_protocol,
-                                                                const u_int16_t peer_port,
-                                                                identification_t *peer_ca,
-                                                                ietf_attributes_t *peer_attributes)
-{
-       connection_t *d;
-       connection_t *best = NULL;
-       policy_prio_t best_prio = BOTTOM_PRIO;
-       id_match_t match_level;
-       int pathlen;
-
-       for (d = hp->connections; d != NULL; d = d->hp_next)
-       {
-               struct spd_route *sr;
-               policy_prio_t prio;
-
-               if (d->policy & POLICY_GROUP)
-               {
-                       continue;
-               }
-               match_level = c->spd.that.id->matches(c->spd.that.id, c->spd.that.id);
-
-               if (!(c->spd.this.id->equals(c->spd.this.id, d->spd.this.id) &&
-                       (match_level > ID_MATCH_NONE) &&
-                       trusted_ca(peer_ca, d->spd.that.ca, &pathlen) &&
-                       match_group_membership(peer_attributes, d->name, d->spd.that.groups)))
-               {
-                       continue;
-               }
-
-               /* compare protocol and ports */
-               if (d->spd.this.protocol != our_protocol
-               ||  d->spd.this.port != our_port
-               ||  d->spd.that.protocol != peer_protocol
-               || (d->spd.that.port != peer_port && !d->spd.that.has_port_wildcard))
-               {
-                       continue;
-               }
-
-               /* Opportunistic case:
-                * our_net must be inside d->spd.this.client
-                * and peer_net must be inside d->spd.that.client
-                * Note: this host_pair chain also has shunt
-                * eroute conns (clear, drop), but they won't
-                * be marked as opportunistic.
-                */
-               for (sr = &d->spd; sr != NULL; sr = sr->next)
-               {
-#ifdef DEBUG
-                       if (DBGP(DBG_CONTROLMORE))
-                       {
-                               char s1[SUBNETTOT_BUF],d1[SUBNETTOT_BUF];
-                               char s3[SUBNETTOT_BUF],d3[SUBNETTOT_BUF];
-
-                               subnettot(our_net,  0, s1, sizeof(s1));
-                               subnettot(peer_net, 0, d1, sizeof(d1));
-                               subnettot(&sr->this.client,  0, s3, sizeof(s3));
-                               subnettot(&sr->that.client,  0, d3, sizeof(d3));
-                               DBG_log("  fc_try_oppo trying %s:%s -> %s vs %s:%s -> %s"
-                                               , c->name, s1, d1, d->name, s3, d3);
-                       }
-#endif /* DEBUG */
-
-                       if (!subnetinsubnet(our_net, &sr->this.client)
-                       || !subnetinsubnet(peer_net, &sr->that.client))
-                       {
-                               continue;
-                       }
-
-                       /* The connection is feasible, but we continue looking for the best.
-                        * The highest priority wins, implementing eroute-like rule.
-                        * - our smallest client subnet is preferred (longest mask)
-                        * - given that, his smallest client subnet is preferred
-                        * - given that, a routed connection is preferrred
-                        * - given that, the smallest number of ID wildcards are preferred
-                        * - given that, the shortest CA pathlength is preferred
-                        */
-                       prio = PRIO_WEIGHT * (d->prio + routed(sr->routing))
-                                + WILD_WEIGHT * match_level
-                                + PATH_WEIGHT * (X509_MAX_PATH_LEN - pathlen);
-                       if (prio > best_prio)
-                       {
-                               best = d;
-                               best_prio = prio;
-                       }
-               }
-       }
-
-       /* if the best wasn't opportunistic, we fail: it must be a shunt */
-       if (best && (NEVER_NEGOTIATE(best->policy) ||
-          (best->policy & POLICY_OPPO) == LEMPTY))
-       {
-               best = NULL;
-       }
-
-       DBG(DBG_CONTROLMORE,
-               DBG_log("  fc_try_oppo concluding with %s [%ld]"
-                               , (best ? best->name : "none"), best_prio)
-       )
-       return best;
-
-}
-
-/*
- * get the peer's CA and group attributes
- */
-void get_peer_ca_and_groups(connection_t *c,
-                                                       identification_t **peer_ca,
-                                                       ietf_attributes_t **peer_attributes)
-{
-       struct state *p1st;
-
-       *peer_ca = NULL;
-       *peer_attributes = NULL;
-
-       p1st = find_phase1_state(c, ISAKMP_SA_ESTABLISHED_STATES);
-       if (p1st && p1st->st_peer_pubkey && p1st->st_peer_pubkey->issuer)
-       {
-               certificate_t *cert;
-
-               cert = ac_get_cert(p1st->st_peer_pubkey->issuer,
-                                                  p1st->st_peer_pubkey->serial);
-               if (cert && ac_verify_cert(cert, strict_crl_policy))
-               {
-                       ac_t *ac = (ac_t*)cert;
-
-                       *peer_attributes = ac->get_groups(ac);
-               }
-               else
-               {
-                       DBG(DBG_CONTROL,
-                               DBG_log("no valid attribute cert found")
-                       )
-               }
-               *peer_ca = p1st->st_peer_pubkey->issuer;
-       }
-}
-
-connection_t *find_client_connection(connection_t *c,
-                                                                        const ip_subnet *our_net,
-                                                                        const ip_subnet *peer_net,
-                                                                        const u_int8_t our_protocol,
-                                                                        const u_int16_t our_port,
-                                                                        const u_int8_t peer_protocol,
-                                                                        const u_int16_t peer_port)
-{
-       connection_t *d;
-       struct spd_route *sr;
-       ietf_attributes_t *peer_attributes = NULL;
-       identification_t *peer_ca;
-
-       get_peer_ca_and_groups(c, &peer_ca, &peer_attributes);
-
-#ifdef DEBUG
-       if (DBGP(DBG_CONTROLMORE))
-       {
-               char s1[SUBNETTOT_BUF],d1[SUBNETTOT_BUF];
-
-               subnettot(our_net,  0, s1, sizeof(s1));
-               subnettot(peer_net, 0, d1, sizeof(d1));
-
-               DBG_log("find_client_connection starting with %s"
-                       , (c ? c->name : "(none)"));
-               DBG_log("  looking for %s:%d/%d -> %s:%d/%d"
-                       , s1, our_protocol, our_port
-                       , d1, peer_protocol, peer_port);
-       }
-#endif /* DEBUG */
-
-       /* give priority to current connection
-        * but even greater priority to a routed concrete connection
-        */
-       {
-               connection_t *unrouted = NULL;
-               int srnum = -1;
-
-               for (sr = &c->spd; unrouted == NULL && sr != NULL; sr = sr->next)
-               {
-                       srnum++;
-
-#ifdef DEBUG
-                       if (DBGP(DBG_CONTROLMORE))
-                       {
-                               char s2[SUBNETTOT_BUF],d2[SUBNETTOT_BUF];
-
-                               subnettot(&sr->this.client, 0, s2, sizeof(s2));
-                               subnettot(&sr->that.client, 0, d2, sizeof(d2));
-                               DBG_log("  concrete checking against sr#%d %s -> %s"
-                                               , srnum, s2, d2);
-                       }
-#endif /* DEBUG */
-
-                       if (samesubnet(&sr->this.client, our_net)
-                       && samesubnet(&sr->that.client, peer_net)
-                       && sr->this.protocol == our_protocol
-                       && sr->this.port == our_port
-                       && sr->that.protocol == peer_protocol
-                       && sr->that.port == peer_port
-                       && match_group_membership(peer_attributes, c->name, sr->that.groups))
-                       {
-                               passert(oriented(*c));
-                               if (routed(sr->routing))
-                               {
-                                       DESTROY_IF(peer_attributes);
-                                       return c;
-                               }
-                               unrouted = c;
-                       }
-               }
-
-               /* exact match? */
-               d = fc_try(c, c->host_pair, NULL, our_net, peer_net
-                       , our_protocol, our_port, peer_protocol, peer_port
-                       , peer_ca, peer_attributes);
-
-               DBG(DBG_CONTROLMORE,
-                       DBG_log("  fc_try %s gives %s"
-                                       , c->name
-                                       , (d ? d->name : "none"))
-               )
-
-               if (d == NULL)
-               {
-                       d = unrouted;
-               }
-       }
-
-       if (d == NULL)
-       {
-               /* look for an abstract connection to match */
-               struct spd_route *sr;
-               struct host_pair *hp = NULL;
-
-               for (sr = &c->spd; hp==NULL && sr != NULL; sr = sr->next)
-               {
-                       hp = find_host_pair(&sr->this.host_addr
-                                                               , sr->this.host_port
-                                                               , NULL
-                                                               , sr->that.host_port);
-#ifdef DEBUG
-                       if (DBGP(DBG_CONTROLMORE))
-                       {
-                               char s2[SUBNETTOT_BUF],d2[SUBNETTOT_BUF];
-
-                               subnettot(&sr->this.client, 0, s2, sizeof(s2));
-                               subnettot(&sr->that.client, 0, d2, sizeof(d2));
-
-                               DBG_log("  checking hostpair %s -> %s is %s"
-                                               , s2, d2
-                                               , (hp ? "found" : "not found"));
-                       }
-#endif /* DEBUG */
-               }
-
-               if (hp)
-               {
-                       /* RW match with actual peer_id or abstract peer_id? */
-                       d = fc_try(c, hp, NULL, our_net, peer_net
-                               , our_protocol, our_port, peer_protocol, peer_port
-                               , peer_ca, peer_attributes);
-
-                       if (d == NULL
-                       && subnetishost(our_net)
-                       && subnetishost(peer_net))
-                       {
-                               /* Opportunistic match?
-                                * Always use abstract peer_id.
-                                * Note that later instantiation will result in the same peer_id.
-                                */
-                               d = fc_try_oppo(c, hp, our_net, peer_net
-                                       , our_protocol, our_port, peer_protocol, peer_port
-                                       , peer_ca, peer_attributes);
-                       }
-               }
-       }
-
-       DBG(DBG_CONTROLMORE,
-               DBG_log("  concluding with d = %s"
-                               , (d ? d->name : "none"))
-       )
-       DESTROY_IF(peer_attributes);
-       return d;
-}
-
-int connection_compare(const connection_t *ca, const connection_t *cb)
-{
-       int ret;
-
-       /* DBG_log("comparing %s to %s", ca->name, cb->name);  */
-
-       ret = strcasecmp(ca->name, cb->name);
-       if (ret)
-       {
-               return ret;
-       }
-
-       ret = ca->kind - cb->kind;  /* note: enum connection_kind behaves like int */
-       if (ret)
-       {
-               return ret;
-       }
-
-       /* same name, and same type */
-       switch (ca->kind)
-       {
-       case CK_INSTANCE:
-               return ca->instance_serial < cb->instance_serial ? -1
-                       : ca->instance_serial > cb->instance_serial ? 1
-                       : 0;
-
-       default:
-               return ca->prio < cb->prio ? -1
-                       : ca->prio > cb->prio ? 1
-                       : 0;
-       }
-}
-
-static int connection_compare_qsort(const void *a, const void *b)
-{
-       return connection_compare(*(const connection_t *const *)a
-                                                       , *(const connection_t *const *)b);
-}
-
-void show_connections_status(bool all, const char *name)
-{
-       connection_t *c;
-       int count, i;
-       connection_t **array;
-
-       /* make an array of connections, and sort it */
-       count = 0;
-       for (c = connections; c != NULL; c = c->ac_next)
-       {
-               if (c->ikev1 && (name == NULL || streq(c->name, name)))
-                       count++;
-       }
-       array = malloc(sizeof(connection_t *)*count);
-
-       count=0;
-       for (c = connections; c != NULL; c = c->ac_next)
-       {
-               if (c->ikev1 && (name == NULL || streq(c->name, name)))
-                       array[count++]=c;
-       }
-
-       /* sort it! */
-       qsort(array, count, sizeof(connection_t *), connection_compare_qsort);
-
-       for (i = 0; i < count; i++)
-       {
-               const char *ifn;
-               char instance[1 + 10 + 1];
-               char prio[POLICY_PRIO_BUF];
-
-               c = array[i];
-
-               ifn = oriented(*c)? c->interface->rname : "";
-
-               instance[0] = '\0';
-               if (c->kind == CK_INSTANCE && c->instance_serial != 0)
-                       snprintf(instance, sizeof(instance), "[%lu]", c->instance_serial);
-
-               /* show topology */
-               {
-                       char topo[BUF_LEN];
-                       struct spd_route *sr = &c->spd;
-                       int num=0;
-
-                       while (sr)
-                       {
-                               (void) format_connection(topo, sizeof(topo), c, sr);
-                               whack_log(RC_COMMENT, "\"%s\"%s: %s; %s; eroute owner: #%lu"
-                                                 , c->name, instance, topo
-                                                 , enum_name(&routing_story, sr->routing)
-                                                 , sr->eroute_owner);
-                               sr = sr->next;
-                               num++;
-                       }
-               }
-
-               if (all)
-               {
-                       /* show CAs if defined */
-                       if (c->spd.this.ca && c->spd.that.ca)
-                       {
-                               whack_log(RC_COMMENT, "\"%s\"%s:   CAs: \"%Y\"...\"%Y\"",
-                                                 c->name, instance, c->spd.this.ca, c->spd.that.ca);
-                       }
-                       else if (c->spd.this.ca)
-                       {
-                               whack_log(RC_COMMENT, "\"%s\"%s:   CAs: \"%Y\"...%%any",
-                                                 c->name, instance, c->spd.this.ca);
-
-                       }
-                       else if (c->spd.that.ca)
-                       {
-                               whack_log(RC_COMMENT, "\"%s\"%s:   CAs: %%any...\"%Y\"",
-                                                 c->name, instance, c->spd.that.ca);
-                       }
-
-                       /* show group attributes if defined */
-                       if (c->spd.that.groups)
-                       {
-                               whack_log(RC_COMMENT, "\"%s\"%s:   groups: %s"
-                                       , c->name
-                                       , instance
-                                       , c->spd.that.groups->get_string(c->spd.that.groups));
-                       }
-
-                       whack_log(RC_COMMENT
-                               , "\"%s\"%s:   ike_life: %lus; ipsec_life: %lus;"
-                               " rekey_margin: %lus; rekey_fuzz: %lu%%; keyingtries: %lu"
-                               , c->name
-                               , instance
-                               , (unsigned long) c->sa_ike_life_seconds
-                               , (unsigned long) c->sa_ipsec_life_seconds
-                               , (unsigned long) c->sa_rekey_margin
-                               , (unsigned long) c->sa_rekey_fuzz
-                               , (unsigned long) c->sa_keying_tries);
-
-                       /* show DPD parameters if defined */
-
-                       if (c->dpd_action != DPD_ACTION_NONE)
-                               whack_log(RC_COMMENT
-                                       , "\"%s\"%s:   dpd_action: %N;"
-                                       " dpd_delay: %lus; dpd_timeout: %lus;"
-                                       , c->name
-                                       , instance
-                                       , dpd_action_names, c->dpd_action
-                                       , (unsigned long) c->dpd_delay
-                                       , (unsigned long) c->dpd_timeout);
-
-                       if (c->policy_next)
-                       {
-                               whack_log(RC_COMMENT
-                                       , "\"%s\"%s:   policy_next: %s"
-                                       , c->name, instance, c->policy_next->name);
-                       }
-
-                       /* Note: we display key_from_DNS_on_demand as if policy [lr]KOD */
-                       fmt_policy_prio(c->prio, prio);
-                       whack_log(RC_COMMENT
-                               , "\"%s\"%s:   policy: %s%s%s; prio: %s; interface: %s; "
-                               , c->name
-                               , instance
-                               , prettypolicy(c->policy)
-                               , c->spd.this.key_from_DNS_on_demand? "+lKOD" : ""
-                               , c->spd.that.key_from_DNS_on_demand? "+rKOD" : ""
-                               , prio
-                               , ifn);
-               }
-
-               whack_log(RC_COMMENT
-                       , "\"%s\"%s:   newest ISAKMP SA: #%ld; newest IPsec SA: #%ld; "
-                       , c->name
-                       , instance
-                       , c->newest_isakmp_sa
-                       , c->newest_ipsec_sa);
-
-               if (all)
-               {
-                       ike_alg_show_connection(c, instance);
-                       kernel_alg_show_connection(c, instance);
-               }
-       }
-       if (count > 0)
-               whack_log(RC_COMMENT, BLANK_FORMAT);    /* spacer */
-
-       free(array);
-}
-
-/* struct pending, the structure representing Quick Mode
- * negotiations delayed until a Keying Channel has been negotiated.
- * Essentially, a pending call to quick_outI1.
- */
-
-struct pending {
-       int whack_sock;
-       struct state *isakmp_sa;
-       connection_t *connection;
-       lset_t policy;
-       unsigned long try;
-       so_serial_t replacing;
-
-       struct pending *next;
-};
-
-/* queue a Quick Mode negotiation pending completion of a suitable Main Mode */
-void add_pending(int whack_sock, struct state *isakmp_sa, connection_t *c,
-                                lset_t policy, unsigned long try, so_serial_t replacing)
-{
-       bool already_queued = FALSE;
-       struct pending *p = c->host_pair->pending;
-
-       while (p)
-       {
-               if (streq(c->name, p->connection->name))
-               {
-                       already_queued = TRUE;
-                       break;
-               }
-               p = p->next;
-       }
-       DBG(DBG_CONTROL,
-               DBG_log("Queuing pending Quick Mode with %s \"%s\"%s"
-                               , ip_str(&c->spd.that.host_addr)
-                               , c->name
-                               , already_queued? " already done" : "")
-       )
-       if (already_queued)
-               return;
-
-       p = malloc_thing(struct pending);
-       p->whack_sock = whack_sock;
-       p->isakmp_sa = isakmp_sa;
-       p->connection = c;
-       p->policy = policy;
-       p->try = try;
-       p->replacing = replacing;
-       p->next = c->host_pair->pending;
-       c->host_pair->pending = p;
-}
-
-/* Release all the whacks awaiting the completion of this state.
- * This is accomplished by closing all the whack socket file descriptors.
- * We go to a lot of trouble to tell each whack, but to not tell it twice.
- */
-void release_pending_whacks(struct state *st, err_t story)
-{
-       struct pending *p;
-       struct stat stst;
-
-       if (st->st_whack_sock == NULL_FD || fstat(st->st_whack_sock, &stst) != 0)
-               zero(&stst);    /* resulting st_dev/st_ino ought to be distinct */
-
-       release_whack(st);
-
-       for (p = st->st_connection->host_pair->pending; p != NULL; p = p->next)
-       {
-               if (p->isakmp_sa == st && p->whack_sock != NULL_FD)
-               {
-                       struct stat pst;
-
-                       if (fstat(p->whack_sock, &pst) == 0
-                       && (stst.st_dev != pst.st_dev || stst.st_ino != pst.st_ino))
-                       {
-                               passert(whack_log_fd == NULL_FD);
-                               whack_log_fd = p->whack_sock;
-                               whack_log(RC_COMMENT
-                                       , "%s for ISAKMP SA, but releasing whack for pending IPSEC SA"
-                                       , story);
-                               whack_log_fd = NULL_FD;
-                       }
-                       close(p->whack_sock);
-                       p->whack_sock = NULL_FD;
-               }
-       }
-}
-
-static void delete_pending(struct pending **pp)
-{
-       struct pending *p = *pp;
-
-       *pp = p->next;
-       if (p->connection)
-       {
-               connection_discard(p->connection);
-       }
-       close_any(p->whack_sock);
-       free(p);
-}
-
-void unpend(struct state *st)
-{
-       struct pending **pp
-               , *p;
-
-       for (pp = &st->st_connection->host_pair->pending; (p = *pp) != NULL; )
-       {
-               if (p->isakmp_sa == st)
-               {
-                       DBG(DBG_CONTROL, DBG_log("unqueuing pending Quick Mode with %s \"%s\""
-                               , ip_str(&p->connection->spd.that.host_addr)
-                               , p->connection->name));
-                       (void) quick_outI1(p->whack_sock, st, p->connection, p->policy
-                               , p->try, p->replacing);
-                       p->whack_sock = NULL_FD;    /* ownership transferred */
-                       p->connection = NULL;       /* ownership transferred */
-                       delete_pending(pp);
-               }
-               else
-               {
-                       pp = &p->next;
-               }
-       }
-}
-
-/* a Main Mode negotiation has been replaced; update any pending */
-void update_pending(struct state *os, struct state *ns)
-{
-       struct pending *p;
-
-       for (p = os->st_connection->host_pair->pending; p != NULL; p = p->next)
-       {
-               if (p->isakmp_sa == os)
-                       p->isakmp_sa = ns;
-               if (p->connection->spd.this.host_port != ns->st_connection->spd.this.host_port)
-               {
-                       p->connection->spd.this.host_port = ns->st_connection->spd.this.host_port;
-                       p->connection->spd.that.host_port = ns->st_connection->spd.that.host_port;
-               }
-       }
-}
-
-/* a Main Mode negotiation has failed; discard any pending */
-void flush_pending_by_state(struct state *st)
-{
-       struct host_pair *hp = st->st_connection->host_pair;
-
-       if (hp)
-       {
-               struct pending **pp
-                       , *p;
-
-               for (pp = &hp->pending; (p = *pp) != NULL; )
-               {
-                       if (p->isakmp_sa == st)
-                               delete_pending(pp);
-                       else
-                               pp = &p->next;
-               }
-       }
-}
-
-/* a connection has been deleted; discard any related pending */
-static void flush_pending_by_connection(connection_t *c)
-{
-       if (c->host_pair)
-       {
-               struct pending **pp
-                       , *p;
-
-               for (pp = &c->host_pair->pending; (p = *pp) != NULL; )
-               {
-                       if (p->connection == c)
-                       {
-                               p->connection = NULL;   /* prevent delete_pending from releasing */
-                               delete_pending(pp);
-                       }
-                       else
-                       {
-                               pp = &p->next;
-                       }
-               }
-       }
-}
-
-void show_pending_phase2(const struct host_pair *hp, const struct state *st)
-{
-       const struct pending *p;
-
-       for (p = hp->pending; p != NULL; p = p->next)
-       {
-               if (p->isakmp_sa == st)
-               {
-                       /* connection-name state-number [replacing state-number] */
-                       char cip[CONN_INST_BUF];
-
-                       fmt_conn_instance(p->connection, cip);
-                       whack_log(RC_COMMENT, "#%lu: pending Phase 2 for \"%s\"%s replacing #%lu"
-                               , p->isakmp_sa->st_serialno
-                               , p->connection->name
-                               , cip
-                               , p->replacing);
-               }
-       }
-}
-
-/* Delete a connection if it is an instance and it is no longer in use.
- * We must be careful to avoid circularity:
- * we don't touch it if it is CK_GOING_AWAY.
- */
-void connection_discard(connection_t *c)
-{
-       if (c->kind == CK_INSTANCE)
-       {
-               /* see if it is being used by a pending */
-               struct pending *p;
-
-               for (p = c->host_pair->pending; p != NULL; p = p->next)
-                       if (p->connection == c)
-                               return; /* in use, so we're done */
-
-               if (!states_use_connection(c))
-                       delete_connection(c, FALSE);
-       }
-}
-
-
-/* A template connection's eroute can be eclipsed by
- * either a %hold or an eroute for an instance iff
- * the template is a /32 -> /32.  This requires some special casing.
- */
-
-long eclipse_count = 0;
-
-connection_t *eclipsed(connection_t *c, struct spd_route **esrp)
-{
-       connection_t *ue;
-       struct spd_route *sr1 = &c->spd;
-
-       ue = NULL;
-
-       while (sr1 && ue)
-       {
-               for (ue = connections; ue != NULL; ue = ue->ac_next)
-               {
-                       struct spd_route *srue = &ue->spd;
-
-                       while (srue     && srue->routing == RT_ROUTED_ECLIPSED
-                       && !(samesubnet(&sr1->this.client, &srue->this.client)
-                                && samesubnet(&sr1->that.client, &srue->that.client)))
-                       {
-                               srue = srue->next;
-                       }
-                       if (srue && srue->routing == RT_ROUTED_ECLIPSED)
-                       {
-                               *esrp = srue;
-                               break;
-                       }
-               }
-       }
-       return ue;
-}
-
-/*
- * Local Variables:
- * c-basic-offset:4
- * c-style: pluto
- * End:
- */
diff --git a/src/pluto/connections.h b/src/pluto/connections.h
deleted file mode 100644 (file)
index e3775fc..0000000
+++ /dev/null
@@ -1,366 +0,0 @@
-/* information about connections between hosts and clients
- * Copyright (C) 1998-2001  D. Hugh Redelmeier
- * Copyright (C) 2009-2010  Andreas Steffen - Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef _CONNECTIONS_H
-#define _CONNECTIONS_H
-
-#include <sys/queue.h>
-
-#include <utils/host.h>
-#include <utils/linked_list.h>
-#include <utils/identification.h>
-#include <credentials/ietf_attributes/ietf_attributes.h>
-
-#include "certs.h"
-#include "smartcard.h"
-#include "whack.h"
-
-/* There are two kinds of connections:
- * - ISAKMP connections, between hosts (for IKE communication)
- * - IPsec connections, between clients (for secure IP communication)
- *
- * An ISAKMP connection looks like:
- *   host<--->host
- *
- * An IPsec connection looks like:
- *   client-subnet<-->host<->nexthop<--->nexthop<->host<-->client-subnet
- *
- * For the connection to be relevant to this instance of Pluto,
- * exactly one of the hosts must be a public interface of our machine
- * known to this instance.
- *
- * The client subnet might simply be the host -- this is a
- * representation of "host mode".
- *
- * Each nexthop defaults to the neighbouring host's IP address.
- * The nexthop is a property of the pair of hosts, not each
- * individually.  It is only needed for IPsec because of the
- * way IPsec is mixed into the kernel routing logic.  Furthermore,
- * only this end's nexthop is actually used.  Eventually, nexthop
- * will be unnecessary.
- *
- * Other information represented:
- * - each connection has a name: a chunk of uninterpreted text
- *   that is unique for each connection.
- * - security requirements (currently just the "policy" flags from
- *   the whack command to initiate the connection, but eventually
- *   much more.  Different for ISAKMP and IPsec connections.
- * - rekeying parameters:
- *   + time an SA may live
- *   + time before SA death that a rekeying should be attempted
- *     (only by the initiator)
- *   + number of times to attempt rekeying
- * - With the current KLIPS, we must route packets for a client
- *   subnet through the ipsec interface (ipsec0).  Only one
- *   gateway can get traffic for a specific (client) subnet.
- *   Furthermore, if the routing isn't in place, packets will
- *   be sent in the clear.
- *   "routing" indicates whether the routing has been done for
- *   this connection.  Note that several connections may claim
- *   the same routing, as long as they agree about where the
- *   packets are to be sent.
- * - With the current KLIPS, only one outbound IPsec SA bundle can be
- *   used for a particular client.  This is due to a limitation
- *   of using only routing for selection.  So only one IPsec state (SA)
- *   may "own" the eroute.  "eroute_owner" is the serial number of
- *   this state, SOS_NOBODY if there is none.  "routing" indicates
- *   what kind of erouting has been done for this connection, if any.
- *
- * Details on routing is in constants.h
- *
- * Operations on Connections:
- *
- * - add a new connection (with all details) [whack command]
- * - delete a connection (by name) [whack command]
- * - initiate a connection (by name) [whack command]
- * - find a connection (by IP addresses of hosts)
- *   [response to peer request; finding ISAKMP connection for IPsec connection]
- *
- * Some connections are templates, missing the address of the peer
- * (represented by INADDR_ANY).  These are always arranged so that the
- * missing end is "that" (there can only be one missing end).  These can
- * be instantiated (turned into real connections) by Pluto in one of two
- * different ways: Road Warrior Instantiation or Opportunistic
- * Instantiation.  A template connection is marked for Opportunistic
- * Instantiation by specifying the peer client as 0.0.0.0/32 (or the IPV6
- * equivalent).  Otherwise, it is suitable for Road Warrior Instantiation.
- *
- * Instantiation creates a new temporary connection, with the missing
- * details filled in.  The resulting template lasts only as long as there
- * is a state that uses it.
- */
-
-/* connection policy priority: how important this policy is
- * - used to implement eroute-like precedence (augmented by a small
- *   bonus for a routed connection).
- * - a whole number
- * - larger is more important
- * - three subcomponents.  In order of decreasing significance:
- *   + length of source subnet mask (8 bits)
- *   + length of destination subnet mask (8 bits)
- *   + bias (8 bit)
- * - a bias of 1 is added to allow prio BOTTOM_PRIO to be less than all
- *   normal priorities
- * - other bias values are created on the fly to give mild preference
- *   to certaion conditions (eg. routedness)
- * - priority is inherited -- an instance of a policy has the same priority
- *   as the original policy, even though its subnets might be smaller.
- * - display format: n,m
- */
-typedef unsigned long policy_prio_t;
-#define BOTTOM_PRIO   ((policy_prio_t)0)        /* smaller than any real prio */
-#define set_policy_prio(c) { (c)->prio = \
-               ((policy_prio_t)(c)->spd.this.client.maskbits << 16) \
-               | ((policy_prio_t)(c)->spd.that.client.maskbits << 8) \
-               | (policy_prio_t)1; }
-#define POLICY_PRIO_BUF (3+1+3+1)
-extern void fmt_policy_prio(policy_prio_t pp, char buf[POLICY_PRIO_BUF]);
-
-struct virtual_t;
-
-struct end {
-       identification_t *id;
-       ip_address host_addr, host_nexthop;
-       host_t *host_srcip;
-       ip_subnet client;
-
-       bool is_left;
-       bool key_from_DNS_on_demand;
-       bool has_client;
-       bool has_client_wildcard;
-       bool has_port_wildcard;
-       bool has_id_wildcards;
-       bool has_natip;
-       char *updown;
-       u_int16_t host_port;        /* host order */
-       u_int16_t port;             /* host order */
-       u_int8_t protocol;
-       cert_t *cert;               /* end certificate */
-       identification_t *ca;       /* CA distinguished name */
-       ietf_attributes_t *groups;  /* access control groups */
-       smartcard_t *sc;            /* smartcard reader and key info */
-       struct virtual_t *virt;
-       bool modecfg;               /* this end: request local address from server */
-                                                               /* that end: give local addresses to clients */
-       char *pool;                                     /* name of an associated virtual IP address pool */
-       bool hostaccess;            /* allow access to host via iptables INPUT/OUTPUT */
-                                                               /* rules if client behind host is a subnet */
-       bool allow_any;             /* IP address is subject to change */
-       certpolicy_t sendcert;      /* whether or not to send the certificate */
-};
-
-struct spd_route {
-       struct spd_route *next;
-       struct end this;
-       struct end that;
-       so_serial_t eroute_owner;
-       enum routing_t routing;     /* level of routing in place */
-       uint32_t reqid;
-       mark_t mark_in;
-       mark_t mark_out;
-};
-
-typedef struct connection connection_t;
-
-struct connection {
-       char *name;
-       bool ikev1;
-
-       lset_t policy;
-       time_t sa_ike_life_seconds;
-       time_t sa_ipsec_life_seconds;
-       time_t sa_rekey_margin;
-       unsigned long sa_rekey_fuzz;
-       unsigned long sa_keying_tries;
-
-       identification_t *xauth_identity;     /* XAUTH identity */
-
-       /* RFC 3706 DPD */
-       time_t dpd_delay;
-       time_t dpd_timeout;
-       dpd_action_t dpd_action;
-
-       char              *log_file_name;     /* name of log file */
-       FILE              *log_file;          /* possibly open FILE */
-       TAILQ_ENTRY(connection) log_link;     /* linked list of open conns */
-       bool               log_file_err;      /* only bitch once */
-
-       struct spd_route spd;
-
-       /* internal fields: */
-
-       unsigned long instance_serial;
-       policy_prio_t prio;
-       bool instance_initiation_ok;        /* this is an instance of a policy that mandates initiate */
-       enum connection_kind kind;
-       const struct iface *interface;      /* filled in iff oriented */
-
-       so_serial_t /* state object serial number */
-               newest_isakmp_sa,
-               newest_ipsec_sa;
-
-
-#ifdef DEBUG
-       lset_t extra_debugging;
-#endif
-
-       /* note: if the client is the gateway, the following must be equal */
-       sa_family_t addr_family;            /* between gateways */
-       sa_family_t tunnel_addr_family;     /* between clients */
-
-       connection_t *policy_next;          /* if multiple policies,
-                                                                                  next one to apply */
-       struct gw_info *gw_info;
-       struct alg_info_esp *alg_info_esp;
-       struct alg_info_ike *alg_info_ike;
-       struct host_pair *host_pair;
-       connection_t *hp_next;              /* host pair list link */
-       connection_t *ac_next;              /* all connections list link */
-       linked_list_t *requested_ca;        /* collected certificate requests */
-       linked_list_t *requested;           /* requested attributes with handlers */
-       linked_list_t *attributes;          /* configuration attributes with handlers */
-       bool got_certrequest;
-};
-
-#define oriented(c) ((c).interface != NULL)
-extern bool orient(connection_t *c);
-
-extern bool same_peer_ids(const connection_t *c, const connection_t *d,
-                                                 identification_t *his_id);
-
-/* Format the topology of a connection end, leaving out defaults.
- * Largest left end looks like: client === host : port [ host_id ] --- hop
- * Note: if that==NULL, skip nexthop
- */
-#define END_BUF (SUBNETTOT_BUF + ADDRTOT_BUF + IDTOA_BUF + ADDRTOT_BUF + 10)
-extern size_t format_end(char *buf, size_t buf_len, const struct end *this,
-                                                const struct end *that, bool is_left, lset_t policy);
-
-extern void add_connection(const whack_message_t *wm);
-extern void initiate_connection(const char *name, int whackfd);
-extern void initiate_opportunistic(const ip_address *our_client,
-                                                                  const ip_address *peer_client,
-                                                                  int transport_proto, bool held, int whackfd);
-extern void terminate_connection(const char *nm);
-extern void release_connection(connection_t *c, bool relations);
-extern void delete_connection(connection_t *c, bool relations);
-extern void delete_connections_by_name(const char *name, bool strict);
-extern void delete_every_connection(void);
-extern char *add_group_instance(connection_t *group, const ip_subnet *target);
-extern void remove_group_instance(const connection_t *group, const char *name);
-extern void release_dead_interfaces(void);
-extern void check_orientations(void);
-extern connection_t *route_owner(connection_t *c, struct spd_route **srp,
-                                                                connection_t **erop, struct spd_route **esrp);
-extern connection_t *shunt_owner(const ip_subnet *ours, const ip_subnet *his);
-
-extern bool uniqueIDs;  /* --uniqueids? */
-extern void ISAKMP_SA_established(connection_t *c, so_serial_t serial);
-
-#define id_is_ipaddr(id) ((id)->get_type(id) == ID_IPV4_ADDR || \
-                                                 (id)->get_type(id) == ID_IPV6_ADDR)
-extern bool his_id_was_instantiated(const connection_t *c);
-
-struct state;   /* forward declaration of tag (defined in state.h) */
-
-extern connection_t* con_by_name(const char *nm, bool strict);
-extern connection_t* find_host_connection(const ip_address *me,
-                                                                                 u_int16_t my_port,
-                                                                                 const ip_address *him,
-                                                                                 u_int16_t his_port, lset_t policy);
-extern connection_t* refine_host_connection(const struct state *st,
-                                                                                       identification_t *id,
-                                                                                       identification_t *peer_ca);
-extern connection_t* find_client_connection(connection_t *c,
-                                                                                       const ip_subnet *our_net,
-                                                                                       const ip_subnet *peer_net,
-                                                                                       const u_int8_t our_protocol,
-                                                                                       const u_int16_t out_port,
-                                                                                       const u_int8_t peer_protocol,
-                                                                                       const u_int16_t peer_port);
-extern connection_t* find_connection_by_reqid(uint32_t reqid);
-extern connection_t* find_connection_for_clients(struct spd_route **srp,
-                                                                                                const ip_address *our_client,
-                                                                                                const ip_address *peer_client,
-                                                                                                int transport_proto);
-extern void get_peer_ca_and_groups(connection_t *c,
-                                                                  identification_t **peer_ca,
-                                                                  ietf_attributes_t **peer_attributes);
-
-/* instantiating routines
- * Note: connection_discard() is in state.h because all its work
- * is looking through state objects.
- */
-struct gw_info; /* forward declaration of tag (defined in dnskey.h) */
-struct alg_info;        /* forward declaration of tag (defined in alg_info.h) */
-extern connection_t *rw_instantiate(connection_t *c,
-                                                                       const ip_address *him,
-                                                                       u_int16_t his_port,
-                                                                       const ip_subnet *his_net,
-                                                                       identification_t *his_id);
-
-extern connection_t *oppo_instantiate(connection_t *c,
-                                                                         const ip_address *him,
-                                                                         identification_t *his_id,
-                                                                         struct gw_info *gw,
-                                                                         const ip_address *our_client,
-                                                                         const ip_address *peer_client);
-
-extern connection_t
-  *build_outgoing_opportunistic_connection(struct gw_info *gw,
-                                                                                  const ip_address *our_client,
-                                                                                  const ip_address *peer_client);
-
-#define CONN_INST_BUF  BUF_LEN
-
-extern void fmt_conn_instance(const connection_t *c, char buf[CONN_INST_BUF]);
-
-/* operations on "pending", the structure representing Quick Mode
- * negotiations delayed until a Keying Channel has been negotiated.
- */
-
-struct pending; /* forward declaration (opaque outside connections.c) */
-
-extern void add_pending(int whack_sock, struct state *isakmp_sa,
-                                               connection_t *c, lset_t policy, unsigned long try,
-                                               so_serial_t replacing);
-
-extern void release_pending_whacks(struct state *st, err_t story);
-extern void unpend(struct state *st);
-extern void update_pending(struct state *os, struct state *ns);
-extern void flush_pending_by_state(struct state *st);
-extern void show_pending_phase2(const struct host_pair *hp, const struct state *st);
-
-extern void connection_discard(connection_t *c);
-
-/* A template connection's eroute can be eclipsed by
- * either a %hold or an eroute for an instance iff
- * the template is a /32 -> /32.  This requires some special casing.
- */
-#define eclipsable(sr) (subnetishost(&(sr)->this.client) && subnetishost(&(sr)->that.client))
-extern long eclipse_count;
-extern connection_t *eclipsed(connection_t *c, struct spd_route **);
-
-
-/* print connection status */
-
-extern void show_connections_status(bool all, const char *name);
-extern int  connection_compare(const connection_t *ca
-       , const connection_t *cb);
-extern void update_host_pair(const char *why, connection_t *c
-       , const ip_address *myaddr, u_int16_t myport
-       , const ip_address *hisaddr, u_int16_t hisport);
-
-#endif /* _CONNECTIONS_H */
diff --git a/src/pluto/constants.c b/src/pluto/constants.c
deleted file mode 100644 (file)
index 73ec0bc..0000000
+++ /dev/null
@@ -1,1401 +0,0 @@
-/* tables of names for values defined in constants.h
- * Copyright (C) 1998-2002 D. Hugh Redelmeier.
- * Copyright (C) 2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-/*
- * Note that the array sizes are all specified; this is to enable range
- * checking by code that only includes constants.h.
- */
-
-#include <stddef.h>
-#include <string.h>
-#include <stdio.h>
-#include <netinet/in.h>
-
-#include <freeswan.h>
-
-#include <attributes/attributes.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "packet.h"
-
-/* string naming compile-time options that have interop implications */
-
-const char compile_time_interop_options[] = ""
-#ifdef THREADS
-               " THREADS"
-#endif
-#ifdef SMARTCARD
-               " SMARTCARD"
-#endif
-#ifdef VENDORID
-               " VENDORID"
-#endif
-#ifdef CISCO_QUIRKS
-               " CISCO_QUIRKS"
-#endif
-#ifdef USE_KEYRR
-               " KEYRR"
-#endif
-       ;
-
-/* version */
-
-static const char *const version_name[] = {
-               "ISAKMP Version 1.0",
-};
-
-enum_names version_names =
-       { ISAKMP_MAJOR_VERSION<<ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION,
-               ISAKMP_MAJOR_VERSION<<ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION,
-               version_name, NULL };
-
-/* RFC 3706 Dead Peer Detection */
-
-ENUM(dpd_action_names, DPD_ACTION_NONE, DPD_ACTION_RESTART,
-       "none",
-       "clear",
-       "hold",
-       "restart"
-);
-
-/* Timer events */
-
-ENUM(timer_event_names, EVENT_NULL, EVENT_LOG_DAILY,
-       "EVENT_NULL",
-       "EVENT_REINIT_SECRET",
-       "EVENT_SO_DISCARD",
-       "EVENT_RETRANSMIT",
-       "EVENT_SA_REPLACE",
-       "EVENT_SA_REPLACE_IF_USED",
-       "EVENT_SA_EXPIRE",
-       "EVENT_NAT_T_KEEPALIVE",
-       "EVENT_DPD",
-       "EVENT_DPD_TIMEOUT",
-       "EVENT_LOG_DAILY"
-);
-
-/* Domain of Interpretation */
-
-static const char *const doi_name[] = {
-               "ISAKMP_DOI_ISAKMP",
-               "ISAKMP_DOI_IPSEC",
-};
-
-enum_names doi_names = { ISAKMP_DOI_ISAKMP, ISAKMP_DOI_IPSEC, doi_name, NULL };
-
-/* debugging settings: a set of selections for reporting
- * These would be more naturally situated in log.h,
- * but they are shared with whack.
- * It turns out that "debug-" is clutter in all contexts this is used,
- * so we leave it off.
- */
-#ifdef DEBUG
-const char *const debug_bit_names[] = {
-       "raw",
-       "crypt",
-       "parsing",
-       "emitting",
-       "control",
-       "lifecycle",
-       "kernel",
-       "dns",
-       "natt",
-       "oppo",
-       "controlmore",
-
-       "private",
-
-       "impair-delay-adns-key-answer",
-       "impair-delay-adns-txt-answer",
-       "impair-bust-mi2",
-       "impair-bust-mr2",
-
-       NULL
-};
-#endif
-
-/* State of exchanges */
-
-static const char *const state_name[] = {
-       "STATE_UNDEFINED",
-
-       "STATE_MAIN_R0",
-       "STATE_MAIN_I1",
-       "STATE_MAIN_R1",
-       "STATE_MAIN_I2",
-       "STATE_MAIN_R2",
-       "STATE_MAIN_I3",
-       "STATE_MAIN_R3",
-       "STATE_MAIN_I4",
-
-       "STATE_QUICK_R0",
-       "STATE_QUICK_I1",
-       "STATE_QUICK_R1",
-       "STATE_QUICK_I2",
-       "STATE_QUICK_R2",
-
-       "STATE_INFO",
-       "STATE_INFO_PROTECTED",
-
-       "STATE_XAUTH_I0",
-       "STATE_XAUTH_R1",
-       "STATE_XAUTH_I1",
-       "STATE_XAUTH_R2",
-       "STATE_XAUTH_I2",
-       "STATE_XAUTH_R3",
-
-       "STATE_MODE_CFG_R0",
-       "STATE_MODE_CFG_I1",
-       "STATE_MODE_CFG_R1",
-       "STATE_MODE_CFG_I2",
-
-       "STATE_MODE_CFG_I0",
-       "STATE_MODE_CFG_R3",
-       "STATE_MODE_CFG_I3",
-       "STATE_MODE_CFG_R4",
-
-       "STATE_IKE_ROOF"
-};
-
-enum_names state_names =
-       { STATE_UNDEFINED, STATE_IKE_ROOF-1, state_name, NULL };
-
-/* story for state */
-
-const char *const state_story[] = {
-       "undefined state after error",                   /* STATE_UNDEFINED */
-       "expecting MI1",                         /* STATE_MAIN_R0 */
-       "sent MI1, expecting MR1",               /* STATE_MAIN_I1 */
-       "sent MR1, expecting MI2",               /* STATE_MAIN_R1 */
-       "sent MI2, expecting MR2",               /* STATE_MAIN_I2 */
-       "sent MR2, expecting MI3",               /* STATE_MAIN_R2 */
-       "sent MI3, expecting MR3",               /* STATE_MAIN_I3 */
-       "sent MR3, ISAKMP SA established",       /* STATE_MAIN_R3 */
-       "ISAKMP SA established",                 /* STATE_MAIN_I4 */
-
-       "expecting QI1",                         /* STATE_QUICK_R0 */
-       "sent QI1, expecting QR1",               /* STATE_QUICK_I1 */
-       "sent QR1, inbound IPsec SA installed, expecting QI2",  /* STATE_QUICK_R1 */
-       "sent QI2, IPsec SA established",        /* STATE_QUICK_I2 */
-       "IPsec SA established",                  /* STATE_QUICK_R2 */
-
-       "got Informational Message in clear",    /* STATE_INFO */
-       "got encrypted Informational Message",   /* STATE_INFO_PROTECTED */
-
-       "expecting XAUTH request",               /* STATE_XAUTH_I0 */
-       "sent XAUTH request, expecting reply",   /* STATE_XAUTH_R1 */
-       "sent XAUTH reply, expecting status",    /* STATE_XAUTH_I1 */
-       "sent XAUTH status, expecting ack",      /* STATE_XAUTH_R2 */
-       "sent XAUTH ack, established",           /* STATE_XAUTH_I2 */
-       "received XAUTH ack, established",       /* STATE_XAUTH_R3 */
-
-       "expecting ModeCfg request",             /* STATE_MODE_CFG_R0 */
-       "sent ModeCfg request, expecting reply", /* STATE_MODE_CFG_I1 */
-       "sent ModeCfg reply, established",       /* STATE_MODE_CFG_R1 */
-       "received ModeCfg reply, established",   /* STATE_MODE_CFG_I2 */
-
-       "expecting ModeCfg set",                 /* STATE_MODE_CFG_I0 */
-       "sent ModeCfg set, expecting ack",       /* STATE_MODE_CFG_R3 */
-       "sent ModeCfg ack, established",         /* STATE_MODE_CFG_I3 */
-       "received ModeCfg ack, established",     /* STATE_MODE_CFG_R4 */
-};
-
-/* kind of struct connection */
-
-static const char *const connection_kind_name[] = {
-       "CK_GROUP",         /* policy group: instantiates to template */
-       "CK_TEMPLATE",      /* abstract connection, with wildcard */
-       "CK_PERMANENT",     /* normal connection */
-       "CK_INSTANCE",      /* instance of template, created for a particular attempt */
-       "CK_GOING_AWAY"     /* instance being deleted -- don't delete again */
-};
-
-enum_names connection_kind_names =
-       { CK_GROUP, CK_GOING_AWAY, connection_kind_name, NULL };
-
-/* routing status names */
-
-static const char *const routing_story_strings[] = {
-       "unrouted", /* RT_UNROUTED: unrouted */
-       "unrouted HOLD",    /* RT_UNROUTED_HOLD: unrouted, but HOLD shunt installed */
-       "eroute eclipsed",  /* RT_ROUTED_ECLIPSED: RT_ROUTED_PROSPECTIVE except bare HOLD or instance has eroute */
-       "prospective erouted",      /* RT_ROUTED_PROSPECTIVE: routed, and prospective shunt installed */
-       "erouted HOLD",     /* RT_ROUTED_HOLD: routed, and HOLD shunt installed */
-       "fail erouted",     /* RT_ROUTED_FAILURE: routed, and failure-context shunt eroute installed */
-       "erouted",  /* RT_ROUTED_TUNNEL: routed, and erouted to an IPSEC SA group */
-       "keyed, unrouted",  /* RT_UNROUTED_KEYED: was routed+keyed, but it got turned into an outer policy */
-};
-
-enum_names routing_story =
-       { RT_UNROUTED, RT_ROUTED_TUNNEL, routing_story_strings, NULL};
-
-/* Payload types (RFC 2408 "ISAKMP" section 3.1) */
-
-const char *const payload_name[] = {
-       "ISAKMP_NEXT_NONE",
-       "ISAKMP_NEXT_SA",
-       "ISAKMP_NEXT_P",
-       "ISAKMP_NEXT_T",
-       "ISAKMP_NEXT_KE",
-       "ISAKMP_NEXT_ID",
-       "ISAKMP_NEXT_CERT",
-       "ISAKMP_NEXT_CR",
-       "ISAKMP_NEXT_HASH",
-       "ISAKMP_NEXT_SIG",
-       "ISAKMP_NEXT_NONCE",
-       "ISAKMP_NEXT_N",
-       "ISAKMP_NEXT_D",
-       "ISAKMP_NEXT_VID",
-       "ISAKMP_NEXT_MODECFG",
-       "ISAKMP_NEXT_15",
-       "ISAKMP_NEXT_16",
-       "ISAKMP_NEXT_17",
-       "ISAKMP_NEXT_18",
-       "ISAKMP_NEXT_19",
-       "ISAKMP_NEXT_NAT-D",
-       "ISAKMP_NEXT_NAT-OA",
-       NULL
-};
-
-const char *const payload_name_nat_d[] = {
-       "ISAKMP_NEXT_NAT-D",
-       "ISAKMP_NEXT_NAT-OA", NULL
-};
-
-static enum_names payload_names_nat_d =
-       { ISAKMP_NEXT_NATD_DRAFTS, ISAKMP_NEXT_NATOA_DRAFTS, payload_name_nat_d, NULL };
-
-enum_names payload_names =
-       { ISAKMP_NEXT_NONE, ISAKMP_NEXT_NATOA_RFC, payload_name, &payload_names_nat_d };
-
-/* Exchange types (note: two discontinuous ranges) */
-
-static const char *const exchange_name[] = {
-       "ISAKMP_XCHG_NONE",
-       "ISAKMP_XCHG_BASE",
-       "ISAKMP_XCHG_IDPROT",
-       "ISAKMP_XCHG_AO",
-       "ISAKMP_XCHG_AGGR",
-       "ISAKMP_XCHG_INFO",
-       "ISAKMP_XCHG_MODE_CFG",
-};
-
-static const char *const exchange_name2[] = {
-       "ISAKMP_XCHG_QUICK",
-       "ISAKMP_XCHG_NGRP",
-       "ISAKMP_XCHG_ACK_INFO",
-};
-
-static enum_names exchange_desc2 =
-       { ISAKMP_XCHG_QUICK, ISAKMP_XCHG_ACK_INFO, exchange_name2, NULL };
-
-enum_names exchange_names =
-       { ISAKMP_XCHG_NONE, ISAKMP_XCHG_MODE_CFG, exchange_name, &exchange_desc2 };
-
-/* Flag BITS */
-const char *const flag_bit_names[] = {
-       "ISAKMP_FLAG_ENCRYPTION",
-       "ISAKMP_FLAG_COMMIT",
-       NULL
-};
-
-/* Situation BITS definition for IPsec DOI */
-
-const char *const sit_bit_names[] = {
-       "SIT_IDENTITY_ONLY",
-       "SIT_SECRECY",
-       "SIT_INTEGRITY",
-       NULL
-};
-
-/* Protocol IDs (RFC 2407 "IPsec DOI" section 4.4.1) */
-
-static const char *const protocol_name[] = {
-       "PROTO_ISAKMP",
-       "PROTO_IPSEC_AH",
-       "PROTO_IPSEC_ESP",
-       "PROTO_IPCOMP",
-};
-
-enum_names protocol_names =
-       { PROTO_ISAKMP, PROTO_IPCOMP, protocol_name, NULL };
-
-/* IPsec ISAKMP transform values */
-
-static const char *const isakmp_transform_name[] = {
-       "KEY_IKE",
-};
-
-enum_names isakmp_transformid_names =
-       { KEY_IKE, KEY_IKE, isakmp_transform_name, NULL };
-
-/* IPsec AH transform values */
-
-static const char *const ah_transform_name[] = {
-       "HMAC_MD5",
-       "HMAC_SHA1",
-       "DES_MAC",
-       "HMAC_SHA2_256",
-       "HMAC_SHA2_384",
-       "HMAC_SHA2_512",
-       "HMAC_RIPEMD",
-       "AES_XCBC_96",
-       "SIG_RSA",
-       "AES_128_GMAC",
-       "AES_192_GMAC",
-       "AES_256_GMAC"
-};
-
-static const char *const ah_transform_name_high[] = {
-       "HMAC_SHA2_256_96"
-};
-
-enum_names ah_transform_names_high =
-       { AH_SHA2_256_96, AH_SHA2_256_96, ah_transform_name_high, NULL };
-
-enum_names ah_transform_names =
-       { AH_MD5, AH_AES_256_GMAC, ah_transform_name, &ah_transform_names_high };
-
-/* IPsec ESP transform values */
-
-static const char *const esp_transform_name[] = {
-       "DES_IV64",
-       "DES_CBC",
-       "3DES_CBC",
-       "RC5_CBC",
-       "IDEA_CBC",
-       "CAST_CBC",
-       "BLOWFISH_CBC",
-       "3IDEA",
-       "DES_IV32",
-       "RC4",
-       "NULL",
-       "AES_CBC",
-       "AES_CTR",
-       "AES_CCM_8",
-       "AES_CCM_12",
-       "AES_CCM_16",
-       "UNASSIGNED_17",
-       "AES_GCM_8",
-       "AES_GCM_12",
-       "AES_GCM_16",
-       "SEED_CBC",
-       "CAMELLIA_CBC",
-       "AES_GMAC"
-};
-
-static const char *const esp_transform_name_high[] = {
-       "SERPENT_CBC",
-       "TWOFISH_CBC"
-};
-
-enum_names esp_transform_names_high =
-       { ESP_SERPENT, ESP_TWOFISH, esp_transform_name_high, NULL };
-
-enum_names esp_transform_names =
-       { ESP_DES_IV64, ESP_AES_GMAC, esp_transform_name, &esp_transform_names_high };
-
-/* IPCOMP transform values */
-
-static const char *const ipcomp_transform_name[] = {
-       "IPCOMP_OUI",
-       "IPCOMP_DEFLATE",
-       "IPCOMP_LZS",
-       "IPCOMP_LZJH",
-};
-
-enum_names ipcomp_transformid_names =
-       { IPCOMP_OUI, IPCOMP_LZJH, ipcomp_transform_name, NULL };
-
-/* Identification type values */
-
-static const char *const ident_name[] = {
-       "ID_IPV4_ADDR",
-       "ID_FQDN",
-       "ID_USER_FQDN",
-       "ID_IPV4_ADDR_SUBNET",
-       "ID_IPV6_ADDR",
-       "ID_IPV6_ADDR_SUBNET",
-       "ID_IPV4_ADDR_RANGE",
-       "ID_IPV6_ADDR_RANGE",
-       "ID_DER_ASN1_DN",
-       "ID_DER_ASN1_GN",
-       "ID_KEY_ID",
-};
-
-enum_names ident_names =
-       { ID_IPV4_ADDR, ID_KEY_ID, ident_name, NULL };
-
-/* Certificate type values */
-
-static const char *const cert_type_name[] = {
-       "CERT_NONE",
-       "CERT_PKCS7_WRAPPED_X509",
-       "CERT_PGP",
-       "CERT_DNS_SIGNED_KEY",
-       "CERT_X509_SIGNATURE",
-       "CERT_X509_KEY_EXCHANGE",
-       "CERT_KERBEROS_TOKENS",
-       "CERT_CRL",
-       "CERT_ARL",
-       "CERT_SPKI",
-       "CERT_X509_ATTRIBUTE",
-};
-
-enum_names cert_type_names =
-       { CERT_NONE, CERT_X509_ATTRIBUTE, cert_type_name, NULL };
-
-/* Certificate policy names */
-
-ENUM(cert_policy_names, CERT_ALWAYS_SEND, CERT_NEVER_SEND,
-       "ALWAYS_SEND",
-       "SEND_IF_ASKED",
-       "NEVER_SEND",
-);
-
-/* Goal BITs for establishing an SA
- * Note: we drop the POLICY_ prefix so that logs are more concise.
- */
-
-const char *const sa_policy_bit_names[] = {
-       "PSK",
-       "PUBKEY",
-       "ENCRYPT",
-       "AUTHENTICATE",
-       "COMPRESS",
-       "TUNNEL",
-       "PFS",
-       "DISABLEARRIVALCHECK",
-       "SHUNT0",
-       "SHUNT1",
-       "FAILSHUNT0",
-       "FAILSHUNT1",
-       "DONTREKEY",
-       "OPPORTUNISTIC",
-       "GROUP",
-       "GROUTED",
-       "UP",
-       "MODECFGPUSH",
-       "XAUTHPSK",
-       "XAUTHRSASIG",
-       "XAUTHSERVER",
-       "DONTREAUTH",
-       "BEET",
-       "MOBIKE",
-       "PROXY",
-       NULL
-};
-
-const char *const policy_shunt_names[4] = {
-       "TRAP",
-       "PASS",
-       "DROP",
-       "REJECT",
-};
-
-const char *const policy_fail_names[4] = {
-       "NONE",
-       "PASS",
-       "DROP",
-       "REJECT",
-};
-
-/* Oakley transform attributes
- * oakley_attr_bit_names does double duty: it is used for enum names
- * and bit names.
- */
-
-const char *const oakley_attr_bit_names[] = {
-       "OAKLEY_ENCRYPTION_ALGORITHM",
-       "OAKLEY_HASH_ALGORITHM",
-       "OAKLEY_AUTHENTICATION_METHOD",
-       "OAKLEY_GROUP_DESCRIPTION",
-       "OAKLEY_GROUP_TYPE",
-       "OAKLEY_GROUP_PRIME",
-       "OAKLEY_GROUP_GENERATOR_ONE",
-       "OAKLEY_GROUP_GENERATOR_TWO",
-       "OAKLEY_GROUP_CURVE_A",
-       "OAKLEY_GROUP_CURVE_B",
-       "OAKLEY_LIFE_TYPE",
-       "OAKLEY_LIFE_DURATION",
-       "OAKLEY_PRF",
-       "OAKLEY_KEY_LENGTH",
-       "OAKLEY_FIELD_SIZE",
-       "OAKLEY_GROUP_ORDER",
-       "OAKLEY_BLOCK_SIZE",
-       NULL
-};
-
-static const char *const oakley_var_attr_name[] = {
-       "OAKLEY_GROUP_PRIME (variable length)",
-       "OAKLEY_GROUP_GENERATOR_ONE (variable length)",
-       "OAKLEY_GROUP_GENERATOR_TWO (variable length)",
-       "OAKLEY_GROUP_CURVE_A (variable length)",
-       "OAKLEY_GROUP_CURVE_B (variable length)",
-       NULL,
-       "OAKLEY_LIFE_DURATION (variable length)",
-       NULL,
-       NULL,
-       NULL,
-       "OAKLEY_GROUP_ORDER (variable length)",
-};
-
-static enum_names oakley_attr_desc_tv = {
-       OAKLEY_ENCRYPTION_ALGORITHM + ISAKMP_ATTR_AF_TV,
-       OAKLEY_GROUP_ORDER + ISAKMP_ATTR_AF_TV, oakley_attr_bit_names, NULL };
-
-enum_names oakley_attr_names = {
-       OAKLEY_GROUP_PRIME, OAKLEY_GROUP_ORDER,
-       oakley_var_attr_name, &oakley_attr_desc_tv };
-
-/* for each Oakley attribute, which enum_names describes its values? */
-enum_names *oakley_attr_val_descs[] = {
-       NULL,                   /* (none) */
-       &oakley_enc_names,      /* OAKLEY_ENCRYPTION_ALGORITHM */
-       &oakley_hash_names,     /* OAKLEY_HASH_ALGORITHM */
-       &oakley_auth_names,     /* OAKLEY_AUTHENTICATION_METHOD */
-       &oakley_group_names,    /* OAKLEY_GROUP_DESCRIPTION */
-       &oakley_group_type_names,/* OAKLEY_GROUP_TYPE */
-       NULL,                   /* OAKLEY_GROUP_PRIME */
-       NULL,                   /* OAKLEY_GROUP_GENERATOR_ONE */
-       NULL,                   /* OAKLEY_GROUP_GENERATOR_TWO */
-       NULL,                   /* OAKLEY_GROUP_CURVE_A */
-       NULL,                   /* OAKLEY_GROUP_CURVE_B */
-       &oakley_lifetime_names, /* OAKLEY_LIFE_TYPE */
-       NULL,                   /* OAKLEY_LIFE_DURATION */
-       &oakley_prf_names,      /* OAKLEY_PRF */
-       NULL,                   /* OAKLEY_KEY_LENGTH */
-       NULL,                   /* OAKLEY_FIELD_SIZE */
-       NULL,                   /* OAKLEY_GROUP_ORDER */
-};
-
-/* IPsec DOI attributes (RFC 2407 "IPsec DOI" section 4.5) */
-
-static const char *const ipsec_attr_name[] = {
-       "SA_LIFE_TYPE",
-       "SA_LIFE_DURATION",
-       "GROUP_DESCRIPTION",
-       "ENCAPSULATION_MODE",
-       "AUTH_ALGORITHM",
-       "KEY_LENGTH",
-       "KEY_ROUNDS",
-       "COMPRESS_DICT_SIZE",
-       "COMPRESS_PRIVATE_ALG",
-};
-
-static const char *const ipsec_var_attr_name[] = {
-       "SA_LIFE_DURATION (variable length)",
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       "COMPRESS_PRIVATE_ALG (variable length)",
-};
-
-static enum_names ipsec_attr_desc_tv = {
-       SA_LIFE_TYPE + ISAKMP_ATTR_AF_TV,
-       COMPRESS_PRIVATE_ALG + ISAKMP_ATTR_AF_TV,
-       ipsec_attr_name, NULL };
-
-enum_names ipsec_attr_names = {
-       SA_LIFE_DURATION, COMPRESS_PRIVATE_ALG,
-       ipsec_var_attr_name, &ipsec_attr_desc_tv };
-
-/* for each IPsec attribute, which enum_names describes its values? */
-enum_names *ipsec_attr_val_descs[] = {
-       NULL,                   /* (none) */
-       &sa_lifetime_names,     /* SA_LIFE_TYPE */
-       NULL,                   /* SA_LIFE_DURATION */
-       &oakley_group_names,    /* GROUP_DESCRIPTION */
-       &enc_mode_names,                /* ENCAPSULATION_MODE */
-       &auth_alg_names,                /* AUTH_ALGORITHM */
-       NULL,                   /* KEY_LENGTH */
-       NULL,                   /* KEY_ROUNDS */
-       NULL,                   /* COMPRESS_DICT_SIZE */
-       NULL,                   /* COMPRESS_PRIVATE_ALG */
-};
-
-/* SA Lifetime Type attribute */
-
-static const char *const sa_lifetime_name[] = {
-       "SA_LIFE_TYPE_SECONDS",
-       "SA_LIFE_TYPE_KBYTES",
-};
-
-enum_names sa_lifetime_names =
-       { SA_LIFE_TYPE_SECONDS, SA_LIFE_TYPE_KBYTES, sa_lifetime_name, NULL };
-
-/* Encapsulation Mode attribute */
-
-static const char *const enc_mode_name[] = {
-       "ENCAPSULATION_MODE_TUNNEL",
-       "ENCAPSULATION_MODE_TRANSPORT",
-       "ENCAPSULATION_MODE_UDP_TUNNEL",
-       "ENCAPSULATION_MODE_UDP_TRANSPORT",
-};
-
-static const char *const enc_udp_mode_name[] = {
-               "ENCAPSULATION_MODE_UDP_TUNNEL",
-               "ENCAPSULATION_MODE_UDP_TRANSPORT",
-       };
-
-static enum_names enc_udp_mode_names =
-       { ENCAPSULATION_MODE_UDP_TUNNEL_DRAFTS, ENCAPSULATION_MODE_UDP_TRANSPORT_DRAFTS, enc_udp_mode_name, NULL };
-
-enum_names enc_mode_names =
-       { ENCAPSULATION_MODE_TUNNEL, ENCAPSULATION_MODE_UDP_TRANSPORT_RFC, enc_mode_name, &enc_udp_mode_names };
-
-/* Auth Algorithm attribute */
-
-static const char *const auth_alg_name[] = {
-    "AUTH_NONE",
-       "HMAC_MD5",
-       "HMAC_SHA1",
-       "DES_MAC",
-       "KPDK",
-       "HMAC_SHA2_256",
-       "HMAC_SHA2_384",
-       "HMAC_SHA2_512",
-       "HMAC_RIPEMD",
-       "AES_XCBC_96",
-       "SIG_RSA"
-};
-
-static const char *const extended_auth_alg_name[] = {
-       "NULL",
-       "HMAC_SHA2_256_96"
-};
-
-enum_names extended_auth_alg_names =
-       { AUTH_ALGORITHM_NULL, AUTH_ALGORITHM_HMAC_SHA2_256_96,
-               extended_auth_alg_name, NULL };
-
-enum_names auth_alg_names =
-       { AUTH_ALGORITHM_NONE, AUTH_ALGORITHM_SIG_RSA,
-               auth_alg_name, &extended_auth_alg_names };
-
-/* From draft-beaulieu-ike-xauth */
-static const char *const xauth_type_name[] = {
-       "Generic",
-       "RADIUS-CHAP",
-       "OTP",
-       "S/KEY",
-};
-
-enum_names xauth_type_names =
-       { XAUTH_TYPE_GENERIC, XAUTH_TYPE_SKEY, xauth_type_name, NULL};
-
-/* From draft-beaulieu-ike-xauth */
-static const char *const xauth_attr_tv_name[] = {
-       "XAUTH_TYPE",
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       "XAUTH_STATUS",
-};
-
-enum_names xauth_attr_tv_names = {
-       XAUTH_TYPE   + ISAKMP_ATTR_AF_TV,
-       XAUTH_STATUS + ISAKMP_ATTR_AF_TV, xauth_attr_tv_name, NULL };
-
-static const char *const unity_attr_name[] = {
-       "UNITY_BANNER",
-       "UNITY_SAVE_PASSWD",
-       "UNITY_DEF_DOMAIN",
-       "UNITY_SPLITDNS_NAME",
-       "UNITY_SPLIT_INCLUDE",
-       "UNITY_NATT_PORT",
-       "UNITY_LOCAL_LAN",
-       "UNITY_PFS",
-       "UNITY_FW_TYPE",
-       "UNITY_BACKUP_SERVERS",
-       "UNITY_DDNS_HOSTNAME",
-};
-
-enum_names unity_attr_names =
-       { UNITY_BANNER , UNITY_DDNS_HOSTNAME, unity_attr_name , &xauth_attr_tv_names };
-
-static const char *const microsoft_attr_name[] = {
-       "INTERNAL_IP4_SERVER",
-       "INTERNAL_IP6_SERVER",
-};
-
-enum_names microsoft_attr_names =
-       { INTERNAL_IP4_SERVER, INTERNAL_IP6_SERVER, microsoft_attr_name , &unity_attr_names };
-
-static const char *const xauth_attr_name[] = {
-       "XAUTH_USER_NAME",
-       "XAUTH_USER_PASSWORD",
-       "XAUTH_PASSCODE",
-       "XAUTH_MESSAGE",
-       "XAUTH_CHALLENGE",
-       "XAUTH_DOMAIN",
-       "XAUTH_STATUS (wrong TLV syntax, should be TV)",
-       "XAUTH_NEXT_PIN",
-       "XAUTH_ANSWER",
-};
-
-enum_names xauth_attr_names =
-       { XAUTH_USER_NAME , XAUTH_ANSWER, xauth_attr_name , &microsoft_attr_names };
-
-static const char *const modecfg_attr_name[] = {
-       "INTERNAL_IP4_ADDRESS",
-       "INTERNAL_IP4_NETMASK",
-       "INTERNAL_IP4_DNS",
-       "INTERNAL_IP4_NBNS",
-       "INTERNAL_ADDRESS_EXPIRY",
-       "INTERNAL_IP4_DHCP",
-       "APPLICATION_VERSION",
-       "INTERNAL_IP6_ADDRESS",
-       "INTERNAL_IP6_NETMASK",
-       "INTERNAL_IP6_DNS",
-       "INTERNAL_IP6_NBNS",
-       "INTERNAL_IP6_DHCP",
-       "INTERNAL_IP4_SUBNET",
-       "SUPPORTED_ATTRIBUTES",
-       "INTERNAL_IP6_SUBNET",
-};
-
-enum_names modecfg_attr_names =
-       { INTERNAL_IP4_ADDRESS, INTERNAL_IP6_SUBNET, modecfg_attr_name , &xauth_attr_names };
-
-/* Oakley Lifetime Type attribute */
-
-static const char *const oakley_lifetime_name[] = {
-       "OAKLEY_LIFE_SECONDS",
-       "OAKLEY_LIFE_KILOBYTES",
-};
-
-enum_names oakley_lifetime_names =
-       { OAKLEY_LIFE_SECONDS, OAKLEY_LIFE_KILOBYTES, oakley_lifetime_name, NULL };
-
-/* Oakley PRF attribute (none defined) */
-
-enum_names oakley_prf_names =
-       { 1, 0, NULL, NULL };
-
-/* Oakley Encryption Algorithm attribute */
-
-static const char *const oakley_enc_name[] = {
-       "DES_CBC",
-       "IDEA_CBC",
-       "BLOWFISH_CBC",
-       "RC5_R16_B64_CBC",
-       "3DES_CBC",
-       "CAST_CBC",
-       "AES_CBC",
-       "CAMELLIA_CBC"
-};
-
-#ifdef NO_EXTRA_IKE
-enum_names oakley_enc_names =
-       { OAKLEY_DES_CBC, OAKLEY_CAMELLIA_CBC, oakley_enc_name, NULL };
-#else
-static const char *const oakley_enc_name_draft_aes_cbc_02[] = {
-       "MARS_CBC"       /*      65001   */,
-       "RC6_CBC"        /*      65002   */,
-       "ID_65003"       /*      65003   */,
-       "SERPENT_CBC"    /*      65004   */,
-       "TWOFISH_CBC"    /*      65005   */,
-};
-
-static const char *const oakley_enc_name_ssh[] = {
-       "TWOFISH_CBC_SSH",
-};
-
-enum_names oakley_enc_names_ssh =
-       { OAKLEY_TWOFISH_CBC_SSH, OAKLEY_TWOFISH_CBC_SSH, oakley_enc_name_ssh
-               , NULL };
-
-enum_names oakley_enc_names_draft_aes_cbc_02 =
-       { OAKLEY_MARS_CBC, OAKLEY_TWOFISH_CBC, oakley_enc_name_draft_aes_cbc_02
-               , &oakley_enc_names_ssh };
-
-enum_names oakley_enc_names =
-       { OAKLEY_DES_CBC, OAKLEY_CAMELLIA_CBC, oakley_enc_name
-               , &oakley_enc_names_draft_aes_cbc_02 };
-#endif
-
-/* Oakley Hash Algorithm attribute */
-
-static const char *const oakley_hash_name[] = {
-       "HMAC_MD5",
-       "HMAC_SHA1",
-       "HMAC_TIGER",
-       "HMAC_SHA2_256",
-       "HMAC_SHA2_384",
-       "HMAC_SHA2_512",
-};
-
-enum_names oakley_hash_names =
-       { OAKLEY_MD5, OAKLEY_SHA2_512, oakley_hash_name, NULL };
-
-/* Oakley Authentication Method attribute */
-
-static const char *const oakley_auth_name1[] = {
-       "pre-shared key",
-       "DSS signature",
-       "RSA signature",
-       "RSA encryption",
-       "RSA encryption revised",
-       "ElGamal encryption",
-       "ELGamal encryption revised",
-       "ECDSA signature",
-       "ECDSA-256 signature",
-       "ECDSA-384 signature",
-       "ECDSA-521-signature",
-};
-
-static const char *const oakley_auth_name2[] = {
-       "HybridInitRSA",
-       "HybridRespRSA",
-       "HybridInitDSS",
-       "HybridRespDSS",
-};
-
-static const char *const oakley_auth_name3[] = {
-       "XAUTHInitPreShared",
-       "XAUTHRespPreShared",
-       "XAUTHInitDSS",
-       "XAUTHRespDSS",
-       "XAUTHInitRSA",
-       "XAUTHRespRSA",
-       "XAUTHInitRSAEncryption",
-       "XAUTHRespRSAEncryption",
-       "XAUTHInitRSARevisedEncryption",
-       "XAUTHRespRSARevisedEncryption",
-};
-
-static enum_names oakley_auth_names1 =
-       { OAKLEY_PRESHARED_KEY, OAKLEY_ECDSA_521
-               , oakley_auth_name1, NULL };
-
-static enum_names oakley_auth_names2 =
-       { HybridInitRSA, HybridRespDSS
-               , oakley_auth_name2, &oakley_auth_names1 };
-
-enum_names oakley_auth_names =
-       { XAUTHInitPreShared, XAUTHRespRSARevisedEncryption
-               , oakley_auth_name3, &oakley_auth_names2 };
-
-/* Oakley Group Description attribute */
-
-static const char *const oakley_group_name[] = {
-       "MODP_768",
-       "MODP_1024",
-       "GP_155",
-       "GP_185",
-       "MODP_1536",
-};
-
-static const char *const oakley_group_name_rfc3526[] = {
-       "MODP_2048",
-       "MODP_3072",
-       "MODP_4096",
-       "MODP_6144",
-       "MODP_8192"
-};
-
-static const char *const oakley_group_name_rfc4753[] = {
-       "ECP_256",
-       "ECP_384",
-       "ECP_521"
-};
-
-static const char *const oakley_group_name_rfc5114[] = {
-       "MODP_1024_160",
-       "MODP_2048_224",
-       "MODP_2048_256",
-       "ECP_192",
-       "ECP_224"
-};
-
-enum_names oakley_group_names_rfc5114 =
-       { MODP_1024_160, ECP_224_BIT,
-                       oakley_group_name_rfc5114, NULL };
-
-enum_names oakley_group_names_rfc4753 =
-       { ECP_256_BIT, ECP_521_BIT,
-                       oakley_group_name_rfc4753, &oakley_group_names_rfc5114 };
-
-enum_names oakley_group_names_rfc3526 =
-       { MODP_2048_BIT, MODP_8192_BIT,
-                       oakley_group_name_rfc3526, &oakley_group_names_rfc4753 };
-
-enum_names oakley_group_names =
-       { MODP_768_BIT, MODP_1536_BIT,
-                       oakley_group_name, &oakley_group_names_rfc3526 };
-
-/* Oakley Group Type attribute */
-
-static const char *const oakley_group_type_name[] = {
-       "OAKLEY_GROUP_TYPE_MODP",
-       "OAKLEY_GROUP_TYPE_ECP",
-       "OAKLEY_GROUP_TYPE_EC2N",
-};
-
-enum_names oakley_group_type_names =
-       { OAKLEY_GROUP_TYPE_MODP, OAKLEY_GROUP_TYPE_EC2N, oakley_group_type_name, NULL };
-
-/* Notify messages -- error types */
-
-static const char *const notification_name[] = {
-       "INVALID_PAYLOAD_TYPE",
-       "DOI_NOT_SUPPORTED",
-       "SITUATION_NOT_SUPPORTED",
-       "INVALID_COOKIE",
-       "INVALID_MAJOR_VERSION",
-       "INVALID_MINOR_VERSION",
-       "INVALID_EXCHANGE_TYPE",
-       "INVALID_FLAGS",
-       "INVALID_MESSAGE_ID",
-       "INVALID_PROTOCOL_ID",
-       "INVALID_SPI",
-       "INVALID_TRANSFORM_ID",
-       "ATTRIBUTES_NOT_SUPPORTED",
-       "NO_PROPOSAL_CHOSEN",
-       "BAD_PROPOSAL_SYNTAX",
-       "PAYLOAD_MALFORMED",
-       "INVALID_KEY_INFORMATION",
-       "INVALID_ID_INFORMATION",
-       "INVALID_CERT_ENCODING",
-       "INVALID_CERTIFICATE",
-       "CERT_TYPE_UNSUPPORTED",
-       "INVALID_CERT_AUTHORITY",
-       "INVALID_HASH_INFORMATION",
-       "AUTHENTICATION_FAILED",
-       "INVALID_SIGNATURE",
-       "ADDRESS_NOTIFICATION",
-       "NOTIFY_SA_LIFETIME",
-       "CERTIFICATE_UNAVAILABLE",
-       "UNSUPPORTED_EXCHANGE_TYPE",
-       "UNEQUAL_PAYLOAD_LENGTHS",
-};
-
-static const char *const notification_status_name[] = {
-       "CONNECTED",
-};
-
-static const char *const ipsec_notification_name[] = {
-       "IPSEC_RESPONDER_LIFETIME",
-       "IPSEC_REPLAY_STATUS",
-       "IPSEC_INITIAL_CONTACT",
-};
-
-static const char *const notification_dpd_name[] = {
-       "R_U_THERE",
-       "R_U_THERE_ACK",
-};
-
-static const char *const notification_juniper_name[] = {
-       "NS_NHTB_INFORM",
-};
-
-enum_names notification_juniper_names =
-       { NS_NHTB_INFORM, NS_NHTB_INFORM,
-               notification_juniper_name, NULL };
-
-enum_names notification_dpd_names =
-       { R_U_THERE, R_U_THERE_ACK,
-               notification_dpd_name, &notification_juniper_names };
-
-enum_names ipsec_notification_names =
-       { IPSEC_RESPONDER_LIFETIME, IPSEC_INITIAL_CONTACT,
-               ipsec_notification_name, &notification_dpd_names };
-
-enum_names notification_status_names =
-       { ISAKMP_CONNECTED, ISAKMP_CONNECTED,
-               notification_status_name, &ipsec_notification_names };
-
-enum_names notification_names =
-       { ISAKMP_INVALID_PAYLOAD_TYPE, ISAKMP_UNEQUAL_PAYLOAD_LENGTHS,
-               notification_name, &notification_status_names };
-
-/* MODECFG
- * From draft-dukes-ike-mode-cfg
- */
-const char *const attr_msg_type_name[] = {
-       "ISAKMP_CFG_RESERVED",
-       "ISAKMP_CFG_REQUEST",
-       "ISAKMP_CFG_REPLY",
-       "ISAKMP_CFG_SET",
-       "ISAKMP_CFG_ACK",
-       NULL
-};
-
-enum_names attr_msg_type_names =
-       { 0 , ISAKMP_CFG_ACK, attr_msg_type_name , NULL };
-
-/* socket address family info */
-
-static const char *const af_inet_name[] = {
-       "AF_INET",
-};
-
-static const char *const af_inet6_name[] = {
-       "AF_INET6",
-};
-
-static enum_names af_names6 = { AF_INET6, AF_INET6, af_inet6_name, NULL };
-
-enum_names af_names = { AF_INET, AF_INET, af_inet_name, &af_names6 };
-
-static ip_address ipv4_any, ipv6_any;
-static ip_subnet ipv4_wildcard, ipv6_wildcard;
-static ip_subnet ipv4_all, ipv6_all;
-
-const struct af_info af_inet4_info = {
-       AF_INET,
-       "AF_INET",
-       sizeof(struct in_addr),
-       sizeof(struct sockaddr_in),
-       32,
-       ID_IPV4_ADDR, ID_IPV4_ADDR_SUBNET, ID_IPV4_ADDR_RANGE,
-       &ipv4_any, &ipv4_wildcard, &ipv4_all,
-};
-
-const struct af_info af_inet6_info = {
-       AF_INET6,
-       "AF_INET6",
-       sizeof(struct in6_addr),
-       sizeof(struct sockaddr_in6),
-       128,
-       ID_IPV6_ADDR, ID_IPV6_ADDR_SUBNET, ID_IPV6_ADDR_RANGE,
-       &ipv6_any, &ipv6_wildcard, &ipv6_all,
-};
-
-const struct af_info *
-aftoinfo(int af)
-{
-       switch (af)
-       {
-               case AF_INET:
-                       return &af_inet4_info;
-               case AF_INET6:
-                       return &af_inet6_info;
-               default:
-                       return NULL;
-       }
-}
-
-bool subnetisnone(const ip_subnet *sn)
-{
-       ip_address base;
-
-       networkof(sn, &base);
-       return isanyaddr(&base) && subnetishost(sn);
-}
-
-#ifdef ADNS
-
-/* BIND enumerated types */
-
-#include <arpa/nameser.h>
-
-static const char *const rr_type_name[] = {
-       "T_A",  /* 1 host address */
-       "T_NS", /* 2 authoritative server */
-       "T_MD", /* 3 mail destination */
-       "T_MF", /* 4 mail forwarder */
-       "T_CNAME",      /* 5 canonical name */
-       "T_SOA",        /* 6 start of authority zone */
-       "T_MB", /* 7 mailbox domain name */
-       "T_MG", /* 8 mail group member */
-       "T_MR", /* 9 mail rename name */
-       "T_NULL",       /* 10 null resource record */
-       "T_WKS",        /* 11 well known service */
-       "T_PTR",        /* 12 domain name pointer */
-       "T_HINFO",      /* 13 host information */
-       "T_MINFO",      /* 14 mailbox information */
-       "T_MX", /* 15 mail routing information */
-       "T_TXT",        /* 16 text strings */
-       "T_RP", /* 17 responsible person */
-       "T_AFSDB",      /* 18 AFS cell database */
-       "T_X25",        /* 19 X_25 calling address */
-       "T_ISDN",       /* 20 ISDN calling address */
-       "T_RT", /* 21 router */
-       "T_NSAP",       /* 22 NSAP address */
-       "T_NSAP_PTR",   /* 23 reverse NSAP lookup (deprecated) */
-       "T_SIG",        /* 24 security signature */
-       "T_KEY",        /* 25 security key */
-       "T_PX", /* 26 X.400 mail mapping */
-       "T_GPOS",       /* 27 geographical position (withdrawn) */
-       "T_AAAA",       /* 28 IP6 Address */
-       "T_LOC",        /* 29 Location Information */
-       "T_NXT",        /* 30 Next Valid Name in Zone */
-       "T_EID",        /* 31 Endpoint identifier */
-       "T_NIMLOC",     /* 32 Nimrod locator */
-       "T_SRV",        /* 33 Server selection */
-       "T_ATMA",       /* 34 ATM Address */
-       "T_NAPTR",      /* 35 Naming Authority PoinTeR */
-       NULL
-};
-
-enum_names rr_type_names = { T_A, T_NAPTR, rr_type_name, NULL };
-
-/* Query type values which do not appear in resource records */
-static const char *const rr_qtype_name[] = {
-       "T_IXFR",       /* 251 incremental zone transfer */
-       "T_AXFR",       /* 252 transfer zone of authority */
-       "T_MAILB",      /* 253 transfer mailbox records */
-       "T_MAILA",      /* 254 transfer mail agent records */
-       "T_ANY",        /* 255 wildcard match */
-       NULL
-};
-
-enum_names rr_qtype_names = { T_IXFR, T_ANY, rr_qtype_name, &rr_type_names };
-
-static const char *const rr_class_name[] = {
-       "C_IN", /* 1 the arpa internet */
-       NULL
-};
-
-enum_names rr_class_names = { C_IN, C_IN, rr_class_name, NULL };
-
-#endif /* ADNS */
-
-/*
- * NAT-Traversal defines for nat_traveral type from nat_traversal.h
- *
- */
-const char *const natt_type_bitnames[] = {
-       "draft-ietf-ipsec-nat-t-ike-00/01",    /* 0 */
-       "draft-ietf-ipsec-nat-t-ike-02/03",
-       "RFC 3947",
-       "3",                                   /* 3 */
-       "4",   "5",   "6",   "7",
-       "8",   "9",   "10",  "11",
-       "12",  "13",  "14",  "15",
-       "16",  "17",  "18",  "19",
-       "20",  "21",  "22",  "23",
-       "24",  "25",  "26",  "27",
-       "28",  "29",
-       "nat is behind me",
-       "nat is behind peer"
-};
-
-/* look up enum names in an enum_names */
-
-const char* enum_name(enum_names *ed, unsigned long val)
-{
-       enum_names  *p;
-
-       for (p = ed; p != NULL; p = p->en_next_range)
-       {
-               if (p->en_first <= val && val <= p->en_last)
-                       return p->en_names[val - p->en_first];
-       }
-       return NULL;
-}
-
-/* find or construct a string to describe an enum value
- * Result may be in STATIC buffer!
- */
-const char *
-enum_show(enum_names *ed, unsigned long val)
-{
-       const char *p = enum_name(ed, val);
-
-       if (p == NULL)
-       {
-               static char buf[12];    /* only one!  I hope that it is big enough */
-
-               snprintf(buf, sizeof(buf), "%lu??", val);
-               p = buf;
-       }
-       return p;
-}
-
-
-static char bitnamesbuf[200];   /* only one!  I hope that it is big enough! */
-
-int
-enum_search(enum_names *ed, const char *str)
-{
-       enum_names  *p;
-       const char *ptr;
-       unsigned en;
-
-       for (p = ed; p != NULL; p = p->en_next_range)
-       {
-               for (en = p->en_first; en <= p->en_last ;en++)
-               {
-                       ptr = p->en_names[en - p->en_first];
-                       if (ptr == 0)
-                       {
-                               continue;
-                       }
-                       if (streq(ptr, str))
-                       {
-                               return en;
-                       }
-               }
-       }
-       return -1;
-}
-
-/* construct a string to name the bits on in a set
- * Result may be in STATIC buffer!
- * Note: prettypolicy depends on internal details.
- */
-const char* bitnamesof(const char *const table[], lset_t val)
-{
-       char *p = bitnamesbuf;
-       lset_t bit;
-       const char *const *tp;
-
-       if (val == 0)
-               return "none";
-
-       for (tp = table, bit = 01; val != 0; bit <<= 1)
-       {
-               if (val & bit)
-               {
-                       const char *n = *tp;
-                       size_t nl;
-
-                       if (n == NULL || *n == '\0')
-                       {
-                               /* no name for this bit, so use hex */
-                               static char flagbuf[sizeof("0x80000000")];
-
-                               snprintf(flagbuf, sizeof(flagbuf), "0x%llx", bit);
-                               n = flagbuf;
-                       }
-
-                       nl = strlen(n);
-
-                       if (p != bitnamesbuf && p < bitnamesbuf+sizeof(bitnamesbuf) - 1)
-                               *p++ = '+';
-
-                       if (bitnamesbuf+sizeof(bitnamesbuf) - p > (ptrdiff_t)nl)
-                       {
-                               strcpy(p, n);
-                               p += nl;
-                       }
-                       val -= bit;
-               }
-               if (*tp != NULL)
-                       tp++;   /* move on, but not past end */
-       }
-       *p = '\0';
-       return bitnamesbuf;
-}
-
-/* print a policy: like bitnamesof, but it also does the non-bitfields.
- * Suppress the shunt and fail fields if 0.
- */
-const char* prettypolicy(lset_t policy)
-{
-       const char *bn = bitnamesof(sa_policy_bit_names
-               , policy & ~(POLICY_SHUNT_MASK | POLICY_FAIL_MASK));
-       size_t len;
-       lset_t shunt = (policy & POLICY_SHUNT_MASK) >> POLICY_SHUNT_SHIFT;
-       lset_t fail = (policy & POLICY_FAIL_MASK) >> POLICY_FAIL_SHIFT;
-
-       if (bn != bitnamesbuf)
-               bitnamesbuf[0] = '\0';
-       len = strlen(bitnamesbuf);
-       if (shunt != 0)
-       {
-               snprintf(bitnamesbuf + len, sizeof(bitnamesbuf) - len, "+%s"
-                       , policy_shunt_names[shunt]);
-               len += strlen(bitnamesbuf + len);
-       }
-       if (fail != 0)
-       {
-               snprintf(bitnamesbuf + len, sizeof(bitnamesbuf) - len, "+failure%s"
-                       , policy_fail_names[fail]);
-               len += strlen(bitnamesbuf + len);
-       }
-       if (NEVER_NEGOTIATE(policy))
-       {
-               snprintf(bitnamesbuf + len, sizeof(bitnamesbuf) - len, "+NEVER_NEGOTIATE");
-               len += strlen(bitnamesbuf + len);
-       }
-       return bitnamesbuf;
-}
-
-/* test a set by seeing if all bits have names */
-
-bool testset(const char *const table[], lset_t val)
-{
-       lset_t bit;
-       const char *const *tp;
-
-       for (tp = table, bit = 01; val != 0; bit <<= 1, tp++)
-       {
-               const char *n = *tp;
-
-               if (n == NULL || ((val & bit) && *n == '\0'))
-                       return FALSE;
-               val &= ~bit;
-       }
-       return TRUE;
-}
-
-
-const char sparse_end[] = "end of sparse names";
-
-/* look up enum names in a sparse_names */
-const char *sparse_name(sparse_names sd, unsigned long val)
-{
-       const struct sparse_name *p;
-
-       for (p = sd; p->name != sparse_end; p++)
-               if (p->val == val)
-                       return p->name;
-       return NULL;
-}
-
-/* find or construct a string to describe an sparse value
- * Result may be in STATIC buffer!
- */
-const char* sparse_val_show(sparse_names sd, unsigned long val)
-{
-       const char *p = sparse_name(sd, val);
-
-       if (p == NULL)
-       {
-               static char buf[12];    /* only one!  I hope that it is big enough */
-
-               snprintf(buf, sizeof(buf), "%lu??", val);
-               p = buf;
-       }
-       return p;
-}
-
-void init_constants(void)
-{
-       happy(anyaddr(AF_INET, &ipv4_any));
-       happy(anyaddr(AF_INET6, &ipv6_any));
-
-       happy(addrtosubnet(&ipv4_any, &ipv4_wildcard));
-       happy(addrtosubnet(&ipv6_any, &ipv6_wildcard));
-
-       happy(initsubnet(&ipv4_any, 0, '0', &ipv4_all));
-       happy(initsubnet(&ipv6_any, 0, '0', &ipv6_all));
-}
-
-u_char secret_of_the_day[HASH_SIZE_SHA1];
-
-
diff --git a/src/pluto/constants.h b/src/pluto/constants.h
deleted file mode 100644 (file)
index c931f17..0000000
+++ /dev/null
@@ -1,1099 +0,0 @@
-/* manifest constants
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2002  D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef _CONSTANTS_H
-#define _CONSTANTS_H
-
-#include <freeswan.h>
-
-#include <kernel/kernel_ipsec.h>
-
-#include <utils.h>
-#include <utils/identification.h>
-#include <crypto/hashers/hasher.h>
-
-extern const char compile_time_interop_options[];
-
-extern void init_constants(void);
-
-/*
- * NOTE:For debugging purposes, constants.c has tables to map numbers back to names.
- * Any changes here should be reflected there.
- */
-
-/* Many routines return only success or failure, but wish to describe
- * the failure in a message.  We use the convention that they return
- * a NULL on success and a pointer to constant string on failure.
- * The fact that the string is a constant is limiting, but it
- * avoids storage management issues: the recipient is allowed to assume
- * that the string will live "long enough" (usually forever).
- * <freeswan.h> defines err_t for this return type.
- */
-
-#define NULL_FD (-1)    /* NULL file descriptor */
-#define dup_any(fd) ((fd) == NULL_FD? NULL_FD : dup(fd))
-#define close_any(fd) { if ((fd) != NULL_FD) { close(fd); (fd) = NULL_FD; } }
-
-/* set type with room for at least 64 elements for ALG opts (was 32 in stock FS) */
-
-typedef unsigned long long lset_t;
-#define LEMPTY 0ULL
-#define LELEM(opt) (1ULL << (opt))
-#define LRANGE(lwb, upb) LRANGES(LELEM(lwb), LELEM(upb))
-#define LRANGES(first, last) (last - first + last)
-#define LHAS(set, elem)  ((LELEM(elem) & (set)) != LEMPTY)
-#define LIN(subset, set)  (((subset) & (set)) == (subset))
-#define LDISJOINT(a, b)  (((a) & (b)) == LEMPTY)
-
-/* Control and lock pathnames */
-#ifndef IPSEC_PIDDIR
-# define IPSEC_PIDDIR "/var/run"
-#endif
-#ifndef DEFAULT_CTLBASE
-# define DEFAULT_CTLBASE IPSEC_PIDDIR "/pluto"
-#endif
-
-#define CTL_SUFFIX ".ctl"       /* for UNIX domain socket pathname */
-#define LOCK_SUFFIX ".pid"      /* for pluto's lock */
-#define INFO_SUFFIX ".info"     /* for UNIX domain socket for apps */
-
-/* Routines to check and display values.
- *
- * An enum_names describes an enumeration.
- * enum_name() returns the name of an enum value, or NULL if invalid.
- * enum_show() is like enum_name, except it formats a numeric representation
- *    for any invalid value (in a static area!)
- *
- * bitnames() formats a display of a set of named bits (in a static area)
- */
-
-struct enum_names {
-       unsigned long en_first;  /* first value in range */
-       unsigned long en_last;   /* last value in range (inclusive) */
-       const char *const *en_names;
-       const struct enum_names *en_next_range;     /* descriptor of next range */
-};
-
-typedef const struct enum_names enum_names;
-
-extern const char *enum_name(enum_names *ed, unsigned long val);
-extern const char *enum_show(enum_names *ed, unsigned long val);
-extern int enum_search(enum_names *ed, const char *string);
-
-extern bool testset(const char *const table[], lset_t val);
-extern const char *bitnamesof(const char *const table[], lset_t val);
-
-/* sparse_names is much like enum_names, except values are
- * not known to be contiguous or ordered.
- * The array of names is ended with one with the name sparse_end
- * (this avoids having to reserve a value to signify the end).
- * Often appropriate for enums defined by others.
- */
-struct sparse_name {
-       unsigned long val;
-       const char *const name;
-};
-typedef const struct sparse_name sparse_names[];
-
-extern const char *sparse_name(sparse_names sd, unsigned long val);
-extern const char *sparse_val_show(sparse_names sd, unsigned long val);
-extern const char sparse_end[];
-
-#define FULL_INET_ADDRESS_SIZE    6
-
-/* limits on nonce sizes.  See RFC2409 "The internet key exchange (IKE)" 5 */
-#define MINIMUM_NONCE_SIZE      8       /* bytes */
-#define DEFAULT_NONCE_SIZE      16      /* bytes */
-#define MAXIMUM_NONCE_SIZE      256     /* bytes */
-
-#define COOKIE_SIZE 8
-#define MAX_ISAKMP_SPI_SIZE 16
-
-#define DES_CBC_BLOCK_SIZE      (64 / BITS_PER_BYTE)
-
-/* Maximum is required for SHA2_512 */
-#define MAX_DIGEST_LEN          HASH_SIZE_SHA512
-
-/* RFC 2404 "HMAC-SHA-1-96" section 3 */
-#define HMAC_SHA1_KEY_LEN       HASH_SIZE_SHA1
-
-/* RFC 2403 "HMAC-MD5-96" section 3 */
-#define HMAC_MD5_KEY_LEN        HASH_SIZE_MD5
-
-#define IKE_UDP_PORT    500
-
-/* IPsec AH transform values
- * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.3
- * and in http://www.iana.org/assignments/isakmp-registry
- */
-enum ipsec_authentication_algo {
-       AH_NONE         = 0,
-       AH_MD5          = 2,
-       AH_SHA          = 3,
-       AH_DES          = 4,
-       AH_SHA2_256     = 5,
-       AH_SHA2_384     = 6,
-       AH_SHA2_512     = 7,
-       AH_RIPEMD       = 8,
-       AH_AES_XCBC_MAC = 9,
-       AH_RSA          = 10,
-       AH_AES_128_GMAC = 11,
-       AH_AES_192_GMAC = 12,
-       AH_AES_256_GMAC = 13,
-       AH_SHA2_256_96  = 252
-};
-
-extern enum_names ah_transform_names;
-
-/* IPsec ESP transform values
- * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.4
- * and from http://www.iana.org/assignments/isakmp-registry
- */
-
-enum ipsec_cipher_algo {
-       ESP_NONE          = 0,
-       ESP_DES_IV64      = 1,
-       ESP_DES           = 2,
-       ESP_3DES          = 3,
-       ESP_RC5           = 4,
-       ESP_IDEA          = 5,
-       ESP_CAST          = 6,
-       ESP_BLOWFISH      = 7,
-       ESP_3IDEA         = 8,
-       ESP_DES_IV32      = 9,
-       ESP_RC4           = 10,
-       ESP_NULL          = 11,
-       ESP_AES           = 12,
-       ESP_AES_CTR       = 13,
-       ESP_AES_CCM_8     = 14,
-       ESP_AES_CCM_12    = 15,
-       ESP_AES_CCM_16    = 16,
-       ESP_UNASSIGNED_17 = 17,
-       ESP_AES_GCM_8     = 18,
-       ESP_AES_GCM_12    = 19,
-       ESP_AES_GCM_16    = 20,
-       ESP_SEED_CBC      = 21,
-       ESP_CAMELLIA      = 22,
-       ESP_AES_GMAC      = 23,
-       ESP_SERPENT       = 252,
-       ESP_TWOFISH       = 253
-};
-
-extern enum_names esp_transform_names;
-
-/* IPCOMP transform values
- * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.5
- * now defined in kernel/kernel_ipsec.h
- */
-
-extern enum_names ipcomp_transformid_names;
-
-/* Certificate type values
- * RFC 2408 ISAKMP, chapter 3.9
- */
-enum ipsec_cert_type {
-       CERT_NONE=                0,
-       CERT_PKCS7_WRAPPED_X509=  1,
-       CERT_PGP=                 2,
-       CERT_DNS_SIGNED_KEY=      3,
-       CERT_X509_SIGNATURE=      4,
-       CERT_X509_KEY_EXCHANGE=   5,
-       CERT_KERBEROS_TOKENS=     6,
-       CERT_CRL=                 7,
-       CERT_ARL=                 8,
-       CERT_SPKI=                9,
-       CERT_X509_ATTRIBUTE=      10,
-       CERT_RAW_RSA_KEY=         11
-};
-
-/* RFC 2560 OCSP - certificate status */
-
-typedef enum {
-       CERT_GOOD =         0,
-       CERT_REVOKED =      1,
-       CERT_UNKNOWN =      2,
-       CERT_UNDEFINED =    3
-} cert_status_t;
-
-/* RFC 3706 Dead Peer Detection */
-
-extern enum_name_t *dpd_action_names;
-
-typedef enum {
-       DPD_ACTION_NONE =    0,
-       DPD_ACTION_CLEAR =   1,
-       DPD_ACTION_HOLD  =   2,
-       DPD_ACTION_RESTART = 3,
-       DPD_ACTION_UNKNOWN = 4
-} dpd_action_t;
-
-/* Timer events */
-
-extern enum_name_t *timer_event_names;
-
-enum event_type {
-       EVENT_NULL, /* non-event */
-       EVENT_REINIT_SECRET,        /* Refresh cookie secret */
-       EVENT_SO_DISCARD,           /* discard unfinished state object */
-       EVENT_RETRANSMIT,           /* Retransmit packet */
-       EVENT_SA_REPLACE,           /* SA replacement event */
-       EVENT_SA_REPLACE_IF_USED,   /* SA replacement event */
-       EVENT_SA_EXPIRE,            /* SA expiration event */
-       EVENT_NAT_T_KEEPALIVE,      /* NAT Traversal Keepalive */
-       EVENT_DPD,                  /* dead peer detection */
-       EVENT_DPD_TIMEOUT,          /* dead peer detection timeout */
-       EVENT_LOG_DAILY             /* reset certain log events/stats */
-};
-
-#define EVENT_REINIT_SECRET_DELAY               3600 /* 1 hour */
-#define EVENT_RETRANSMIT_DELAY_0                10   /* 10 seconds */
-
-/* Misc. stuff */
-
-#define MAXIMUM_RETRANSMISSIONS              2
-#define MAXIMUM_RETRANSMISSIONS_INITIAL      20
-
-#define MAX_INPUT_UDP_SIZE             65536
-#define MAX_OUTPUT_UDP_SIZE            65536
-
-/* Version numbers */
-
-#define ISAKMP_MAJOR_VERSION   0x1
-#define ISAKMP_MINOR_VERSION   0x0
-
-extern enum_names version_names;
-
-/* Domain of Interpretation */
-
-extern enum_names doi_names;
-
-#define ISAKMP_DOI_ISAKMP          0
-#define ISAKMP_DOI_IPSEC           1
-
-/* IPsec DOI things */
-
-#define IPSEC_DOI_SITUATION_LENGTH 4
-#define IPSEC_DOI_LDI_LENGTH       4
-#define IPSEC_DOI_SPI_SIZE         4
-
-/* SPI value 0 is invalid and values 1-255 are reserved to IANA.
- * ESP: RFC 2402 2.4; AH: RFC 2406 2.1
- * IPComp RFC 2393 substitutes a CPI in the place of an SPI.
- * see also draft-shacham-ippcp-rfc2393bis-05.txt.
- * We (FreeS/WAN) reserve 0x100 to 0xFFF for manual keying, so
- * Pluto won't generate these values.
- */
-#define IPSEC_DOI_SPI_MIN          0x100
-#define IPSEC_DOI_SPI_OUR_MIN      0x1000
-
-/* debugging settings: a set of selections for reporting
- * These would be more naturally situated in log.h,
- * but they are shared with whack.
- * IMPAIR_* actually change behaviour, usually badly,
- * to aid in testing.  Naturally, these are not included in ALL.
- *
- * NOTE: changes here must be done in concert with changes to DBGOPT_*
- * in whack.c.  A change to WHACK_MAGIC in whack.h will be required too.
- */
-#ifdef DEBUG
-extern const char *const debug_bit_names[];
-#endif
-
-#define DBG_RAW         LELEM(0)        /* raw packet I/O */
-#define DBG_CRYPT       LELEM(1)        /* encryption/decryption of messages */
-#define DBG_PARSING     LELEM(2)        /* show decoding of messages */
-#define DBG_EMITTING    LELEM(3)        /* show encoding of messages */
-#define DBG_CONTROL     LELEM(4)        /* control flow within Pluto */
-#define DBG_LIFECYCLE   LELEM(5)        /* SA lifecycle */
-#define DBG_KERNEL      LELEM(6)        /* messages to kernel */
-#define DBG_DNS         LELEM(7)        /* DNS activity */
-#define DBG_NATT        LELEM(8)        /* NAT-T */
-#define DBG_OPPO        LELEM(9)        /* opportunism */
-#define DBG_CONTROLMORE LELEM(10)       /* more detailed debugging */
-
-#define DBG_PRIVATE     LELEM(11)       /* private information: DANGER! */
-
-#define IMPAIR0 12      /* first bit for IMPAIR_* */
-
-#define IMPAIR_DELAY_ADNS_KEY_ANSWER    LELEM(IMPAIR0+0)        /* sleep before answering */
-#define IMPAIR_DELAY_ADNS_TXT_ANSWER    LELEM(IMPAIR0+1)        /* sleep before answering */
-#define IMPAIR_BUST_MI2 LELEM(IMPAIR0+2)        /* make MI2 really large */
-#define IMPAIR_BUST_MR2 LELEM(IMPAIR0+3)        /* make MI2 really large */
-
-#define DBG_NONE        0       /* no options on, including impairments */
-#define DBG_ALL         LRANGES(DBG_RAW, DBG_CONTROLMORE)  /* all logging options on EXCEPT DBG_PRIVATE */
-
-/* State of exchanges
- *
- * The name of the state describes the last message sent, not the
- * message currently being input or output (except during retry).
- * In effect, the state represents the last completed action.
- *
- * Messages are named [MQ][IR]n where
- * - M stands for Main Mode (Phase 1);
- *   Q stands for Quick Mode (Phase 2)
- * - I stands for Initiator;
- *   R stands for Responder
- * - n, a digit, stands for the number of the message
- *
- * It would be more convenient if each state accepted a message
- * and produced one.  This is the case for states at the start
- * or end of an exchange.  To fix this, we pretend that there are
- * MR0 and QR0 messages before the MI1 and QR1 messages.  Similarly,
- * we pretend that there are MR4 and QR2 messages.
- *
- * STATE_MAIN_R0 and STATE_QUICK_R0 are intermediate states (not
- * retained between messages) representing the state that accepts the
- * first message of an exchange has been read but not processed.
- *
- * state_microcode state_microcode_table in demux.c describes
- * other important details.
- */
-
-extern enum_names state_names;
-extern const char *const state_story[];
-
-enum state_kind {
-       STATE_UNDEFINED,    /* 0 -- most likely accident */
-
-       /* IKE states */
-
-       STATE_MAIN_R0,
-       STATE_MAIN_I1,
-       STATE_MAIN_R1,
-       STATE_MAIN_I2,
-       STATE_MAIN_R2,
-       STATE_MAIN_I3,
-       STATE_MAIN_R3,
-       STATE_MAIN_I4,
-
-       STATE_QUICK_R0,
-       STATE_QUICK_I1,
-       STATE_QUICK_R1,
-       STATE_QUICK_I2,
-       STATE_QUICK_R2,
-
-       STATE_INFO,
-       STATE_INFO_PROTECTED,
-
-       /* XAUTH states */
-
-       STATE_XAUTH_I0,              /* initiator state (client) */
-       STATE_XAUTH_R1,              /* responder state (server) */
-       STATE_XAUTH_I1,
-       STATE_XAUTH_R2,
-       STATE_XAUTH_I2,
-       STATE_XAUTH_R3,
-
-       /* Mode Config pull states */
-
-       STATE_MODE_CFG_R0,           /* responder state (server) */
-       STATE_MODE_CFG_I1,           /* initiator state (client) */
-       STATE_MODE_CFG_R1,
-       STATE_MODE_CFG_I2,
-
-       /* Mode Config push states */
-
-       STATE_MODE_CFG_I0,           /* initiator state (client) */
-       STATE_MODE_CFG_R3,           /* responder state (server) */
-       STATE_MODE_CFG_I3,
-       STATE_MODE_CFG_R4,
-
-       STATE_IKE_ROOF
-};
-
-#define STATE_IKE_FLOOR STATE_MAIN_R0
-
-#define PHASE1_INITIATOR_STATES  (LELEM(STATE_MAIN_I1) | LELEM(STATE_MAIN_I2) \
-       | LELEM(STATE_MAIN_I3) | LELEM(STATE_MAIN_I4))
-#define ISAKMP_SA_ESTABLISHED_STATES ( \
-         LELEM(STATE_MAIN_R3)     | LELEM(STATE_MAIN_I4)     \
-       | LELEM(STATE_XAUTH_R1)    | LELEM(STATE_XAUTH_R2) | LELEM(STATE_XAUTH_R3) \
-       | LELEM(STATE_XAUTH_I1)    | LELEM(STATE_XAUTH_I2)    \
-       | LELEM(STATE_MODE_CFG_I1) | LELEM(STATE_MODE_CFG_R1) | LELEM(STATE_MODE_CFG_I2) \
-       | LELEM(STATE_MODE_CFG_R3) | LELEM(STATE_MODE_CFG_I3) | LELEM(STATE_MODE_CFG_R4))
-
-#define IS_PHASE1(s) ((STATE_MAIN_R0 <= (s) && (s) <= STATE_MAIN_I4) \
-                                  || (STATE_XAUTH_I0 <= (s) && (s) <= STATE_XAUTH_R3) \
-                                  || (STATE_MODE_CFG_R0 <= (s) && (s) <= STATE_MODE_CFG_R4))
-
-#define IS_QUICK(s) (STATE_QUICK_R0 <= (s) && (s) <= STATE_QUICK_R2)
-#define IS_ISAKMP_ENCRYPTED(s) (STATE_MAIN_I2 <= (s))
-
-#define IS_ISAKMP_SA_ESTABLISHED(s) (        \
-                                  (s) == STATE_MAIN_R3      \
-                               || (s) == STATE_MAIN_I4      \
-                               || (s) == STATE_XAUTH_I2     \
-                               || (s) == STATE_XAUTH_R3     \
-                               || (s) == STATE_MODE_CFG_R1  \
-                               || (s) == STATE_MODE_CFG_I2  \
-                               || (s) == STATE_MODE_CFG_I3  \
-                               || (s) == STATE_MODE_CFG_R4)
-
-#define IS_IPSEC_SA_ESTABLISHED(s) ((s) == STATE_QUICK_I2 || (s) == STATE_QUICK_R2)
-#define IS_ONLY_INBOUND_IPSEC_SA_ESTABLISHED(s) ((s) == STATE_QUICK_R1)
-
-/* kind of struct connection
- * Ordered (mostly) by concreteness.  Order is exploited.
- */
-
-extern enum_names connection_kind_names;
-
-enum connection_kind {
-       CK_GROUP,           /* policy group: instantiates to template */
-       CK_TEMPLATE,        /* abstract connection, with wildcard */
-       CK_PERMANENT,       /* normal connection */
-       CK_INSTANCE,        /* instance of template, created for a particular attempt */
-       CK_GOING_AWAY       /* instance being deleted -- don't delete again */
-};
-
-
-/* routing status.
- * Note: routing ignores source address, but erouting does not!
- * Note: a connection can only be routed if it is NEVER_NEGOTIATE
- * or HAS_IPSEC_POLICY.
- */
-
-extern enum_names routing_story;
-
-/* note that this is assumed to be ordered! */
-enum routing_t {
-       RT_UNROUTED,        /* unrouted */
-       RT_UNROUTED_HOLD,   /* unrouted, but HOLD shunt installed */
-       RT_ROUTED_ECLIPSED, /* RT_ROUTED_PROSPECTIVE except bare HOLD or instance has eroute */
-       RT_ROUTED_PROSPECTIVE,      /* routed, and prospective shunt installed */
-       RT_ROUTED_HOLD,     /* routed, and HOLD shunt installed */
-       RT_ROUTED_FAILURE,  /* routed, and failure-context shunt installed */
-       RT_ROUTED_TUNNEL,   /* routed, and erouted to an IPSEC SA group */
-       RT_UNROUTED_KEYED   /* keyed, but not routed, on purpose */
-};
-
-#define routed(rs) ((rs) > RT_UNROUTED_HOLD)
-#define erouted(rs) ((rs) != RT_UNROUTED)
-#define shunt_erouted(rs) (erouted(rs) && (rs) != RT_ROUTED_TUNNEL)
-
-/* Payload types
- * RFC2408 Internet Security Association and Key Management Protocol (ISAKMP)
- * section 3.1
- *
- * RESERVED 14-127
- * Private USE 128-255
- */
-
-extern enum_names payload_names;
-extern const char *const payload_name[];
-
-#define ISAKMP_NEXT_NONE       0        /* No other payload following */
-#define ISAKMP_NEXT_SA         1        /* Security Association */
-#define ISAKMP_NEXT_P          2        /* Proposal */
-#define ISAKMP_NEXT_T          3        /* Transform */
-#define ISAKMP_NEXT_KE         4        /* Key Exchange */
-#define ISAKMP_NEXT_ID         5        /* Identification */
-#define ISAKMP_NEXT_CERT       6        /* Certificate */
-#define ISAKMP_NEXT_CR         7        /* Certificate Request */
-#define ISAKMP_NEXT_HASH       8        /* Hash */
-#define ISAKMP_NEXT_SIG        9        /* Signature */
-#define ISAKMP_NEXT_NONCE      10       /* Nonce */
-#define ISAKMP_NEXT_N          11       /* Notification */
-#define ISAKMP_NEXT_D          12       /* Delete */
-#define ISAKMP_NEXT_VID        13       /* Vendor ID */
-#define ISAKMP_NEXT_ATTR       14       /* Mode config Attribute */
-
-#define ISAKMP_NEXT_NATD_RFC   20       /* NAT-Traversal: NAT-D (rfc) */
-#define ISAKMP_NEXT_NATOA_RFC  21       /* NAT-Traversal: NAT-OA (rfc) */
-#define ISAKMP_NEXT_ROOF       22       /* roof on payload types */
-
-#define ISAKMP_NEXT_NATD_DRAFTS   130   /* NAT-Traversal: NAT-D (drafts) */
-#define ISAKMP_NEXT_NATOA_DRAFTS  131   /* NAT-Traversal: NAT-OA (drafts) */
-
-/* These values are to be used within the Type field of an Attribute (14)
- * ISAKMP payload.
- */
-#define ISAKMP_CFG_REQUEST         1
-#define ISAKMP_CFG_REPLY           2
-#define ISAKMP_CFG_SET             3
-#define ISAKMP_CFG_ACK             4
-
-extern enum_names attr_msg_type_names;
-
-extern enum_names modecfg_attr_names;
-
-/* XAUTH authentication types */
-#define XAUTH_TYPE_GENERIC 0
-#define XAUTH_TYPE_CHAP    1
-#define XAUTH_TYPE_OTP     2
-#define XAUTH_TYPE_SKEY    3
-
-/* Values for XAUTH_STATUS */
-#define XAUTH_STATUS_FAIL       0
-#define XAUTH_STATUS_OK         1
-
-extern enum_names xauth_type_names;
-
-/* Exchange types
- * RFC2408 "Internet Security Association and Key Management Protocol (ISAKMP)"
- * section 3.1
- *
- * ISAKMP Future Use     6 - 31
- * DOI Specific Use     32 - 239
- * Private Use         240 - 255
- *
- * Note: draft-ietf-ipsec-dhless-enc-mode-00.txt Appendix A
- * defines "DHless RSA Encryption" as 6.
- */
-
-extern enum_names exchange_names;
-
-#define ISAKMP_XCHG_NONE       0
-#define ISAKMP_XCHG_BASE       1
-#define ISAKMP_XCHG_IDPROT     2        /* ID Protection */
-#define ISAKMP_XCHG_AO         3        /* Authentication Only */
-#define ISAKMP_XCHG_AGGR       4        /* Aggressive */
-#define ISAKMP_XCHG_INFO       5        /* Informational */
-#define ISAKMP_XCHG_MODE_CFG   6        /* Mode Config */
-
-/* Extra exchange types, defined by Oakley
- * RFC2409 "The Internet Key Exchange (IKE)", near end of Appendix A
- */
-#define ISAKMP_XCHG_QUICK      32       /* Oakley Quick Mode */
-#define ISAKMP_XCHG_NGRP       33       /* Oakley New Group Mode */
-/* added in draft-ietf-ipsec-ike-01.txt, near end of Appendix A */
-#define ISAKMP_XCHG_ACK_INFO   34       /* Oakley Acknowledged Informational */
-
-/* Flag bits */
-
-extern const char *const flag_bit_names[];
-
-#define ISAKMP_FLAG_ENCRYPTION   0x1
-#define ISAKMP_FLAG_COMMIT       0x2
-
-/* Situation definition for IPsec DOI */
-
-extern const char *const sit_bit_names[];
-
-#define SIT_IDENTITY_ONLY        0x01
-#define SIT_SECRECY              0x02
-#define SIT_INTEGRITY            0x04
-
-/* Protocol IDs
- * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.1
- */
-
-extern enum_names protocol_names;
-
-#define PROTO_ISAKMP             1
-#define PROTO_IPSEC_AH           2
-#define PROTO_IPSEC_ESP          3
-#define PROTO_IPCOMP             4
-
-/* warning: trans_show uses enum_show, so same static buffer is used */
-#define trans_show(p, t) \
-       ((p)==PROTO_IPSEC_AH ? enum_show(&ah_transformid_names, (t)) \
-       : (p)==PROTO_IPSEC_ESP ? enum_show(&esp_transformid_names, (t)) \
-       : (p)==PROTO_IPCOMP ? enum_show(&ipcomp_transformid_names, (t)) \
-       : "??")
-
-#define KEY_IKE               1
-
-extern enum_names isakmp_transformid_names;
-
-/* the following are from RFC 2393/draft-shacham-ippcp-rfc2393bis-05.txt 3.3 */
-typedef u_int16_t cpi_t;
-#define IPCOMP_CPI_SIZE          2
-#define IPCOMP_FIRST_NEGOTIATED  256
-#define IPCOMP_LAST_NEGOTIATED   61439
-
-/* Identification type values
- * RFC 2407 The Internet IP security Domain of Interpretation for ISAKMP 4.6.2.1
- */
-
-extern enum_names ident_names;
-extern enum_names cert_type_names;
-
-extern enum_name_t *cert_policy_names;
-
-typedef enum certpolicy {
-       CERT_ALWAYS_SEND   = 0,
-       CERT_SEND_IF_ASKED = 1,
-       CERT_NEVER_SEND    = 2,
-
-       CERT_YES_SEND      = 3,       /* synonym for CERT_ALWAYS_SEND */
-       CERT_NO_SEND       = 4        /* synonym for CERT_NEVER_SEND  */
-} certpolicy_t;
-
-/* Policies for establishing an SA
- *
- * These are used to specify attributes (eg. encryption) and techniques
- * (eg PFS) for an SA.
- * Note: certain CD_ definitions in whack.c parallel these -- keep them
- * in sync!
- */
-
-extern const char *const sa_policy_bit_names[];
-extern const char *prettypolicy(lset_t policy);
-
-/* ISAKMP auth techniques (none means never negotiate) */
-#define POLICY_PSK           LELEM(0)
-#define POLICY_PUBKEY        LELEM(1)
-
-#define POLICY_ISAKMP_SHIFT     0       /* log2(POLICY_PSK) */
-#define POLICY_ID_AUTH_MASK     (POLICY_PSK | POLICY_PUBKEY | POLICY_XAUTH_PSK | POLICY_XAUTH_RSASIG)
-#define POLICY_ISAKMP_MASK      POLICY_ID_AUTH_MASK     /* all so far */
-
-/* Quick Mode (IPSEC) attributes */
-#define POLICY_ENCRYPT       LELEM(2)   /* must be first of IPSEC policies */
-#define POLICY_AUTHENTICATE  LELEM(3)   /* must be second */
-#define POLICY_COMPRESS      LELEM(4)   /* must be third */
-#define POLICY_TUNNEL        LELEM(5)
-#define POLICY_PFS           LELEM(6)
-#define POLICY_DISABLEARRIVALCHECK  LELEM(7)    /* suppress tunnel egress address checking */
-
-#define POLICY_IPSEC_SHIFT      2       /* log2(POLICY_ENCRYPT) */
-#define POLICY_IPSEC_MASK       LRANGES(POLICY_ENCRYPT, POLICY_DISABLEARRIVALCHECK)
-
-/* shunt attributes: what to do when routed without tunnel (2 bits) */
-#define POLICY_SHUNT_SHIFT      8       /* log2(POLICY_SHUNT_PASS) */
-#define POLICY_SHUNT_MASK       (03ul << POLICY_SHUNT_SHIFT)
-
-#define POLICY_SHUNT_TRAP       (0ul << POLICY_SHUNT_SHIFT) /* default: negotiate */
-#define POLICY_SHUNT_PASS       (1ul << POLICY_SHUNT_SHIFT)
-#define POLICY_SHUNT_DROP       (2ul << POLICY_SHUNT_SHIFT)
-#define POLICY_SHUNT_REJECT     (3ul << POLICY_SHUNT_SHIFT)
-
-/* fail attributes: what to do with failed negotiation (2 bits) */
-
-#define POLICY_FAIL_SHIFT       10      /* log2(POLICY_FAIL_PASS) */
-#define POLICY_FAIL_MASK        (03ul << POLICY_FAIL_SHIFT)
-
-#define POLICY_FAIL_NONE     (0ul << POLICY_FAIL_SHIFT) /* default */
-#define POLICY_FAIL_PASS     (1ul << POLICY_FAIL_SHIFT)
-#define POLICY_FAIL_DROP     (2ul << POLICY_FAIL_SHIFT)
-#define POLICY_FAIL_REJECT   (3ul << POLICY_FAIL_SHIFT)
-
-/* connection policy
- * Other policies could vary per state object.  These live in connection.
- */
-#define POLICY_DONT_REKEY       LELEM(12)       /* don't rekey state either Phase */
-#define POLICY_OPPO             LELEM(13)       /* is this opportunistic? */
-#define POLICY_GROUP            LELEM(14)       /* is this a group template? */
-#define POLICY_GROUTED          LELEM(15)       /* do we want this group routed? */
-#define POLICY_UP               LELEM(16)       /* do we want this up? */
-#define POLICY_MODECFG_PUSH     LELEM(17)       /* is modecfg pushed by server? */
-#define POLICY_XAUTH_PSK        LELEM(18)       /* do we support XAUTH????PreShared? */
-#define POLICY_XAUTH_RSASIG     LELEM(19)       /* do we support XAUTH????RSA? */
-#define POLICY_XAUTH_SERVER     LELEM(20)       /* are we an XAUTH server? */
-#define POLICY_DONT_REAUTH      LELEM(21)       /* don't reauthenticate on rekeying, IKEv2 only */
-#define POLICY_BEET             LELEM(22)       /* bound end2end tunnel, IKEv2 */
-#define POLICY_MOBIKE           LELEM(23)       /* enable MOBIKE for IKEv2  */
-#define POLICY_FORCE_ENCAP      LELEM(24)       /* force UDP encapsulation (IKEv2)  */
-#define POLICY_PROXY            LELEM(25)       /* proxy transport mode (MIPv6) */
-
-/* Any IPsec policy?  If not, a connection description
- * is only for ISAKMP SA, not IPSEC SA.  (A pun, I admit.)
- * Note: a connection can only be routed if it is NEVER_NEGOTIATE
- * or HAS_IPSEC_POLICY.
- */
-#define HAS_IPSEC_POLICY(p) (((p) & POLICY_IPSEC_MASK) != 0)
-
-/* Don't allow negotiation? */
-#define NEVER_NEGOTIATE(p)  (LDISJOINT((p), POLICY_ID_AUTH_MASK))
-
-
-/* Oakley transform attributes
- * draft-ietf-ipsec-ike-01.txt appendix A
- */
-
-extern enum_names oakley_attr_names;
-extern const char *const oakley_attr_bit_names[];
-
-#define OAKLEY_ENCRYPTION_ALGORITHM    1
-#define OAKLEY_HASH_ALGORITHM          2
-#define OAKLEY_AUTHENTICATION_METHOD   3
-#define OAKLEY_GROUP_DESCRIPTION       4
-#define OAKLEY_GROUP_TYPE              5
-#define OAKLEY_GROUP_PRIME             6        /* B/V */
-#define OAKLEY_GROUP_GENERATOR_ONE     7        /* B/V */
-#define OAKLEY_GROUP_GENERATOR_TWO     8        /* B/V */
-#define OAKLEY_GROUP_CURVE_A           9        /* B/V */
-#define OAKLEY_GROUP_CURVE_B          10        /* B/V */
-#define OAKLEY_LIFE_TYPE              11
-#define OAKLEY_LIFE_DURATION          12        /* B/V */
-#define OAKLEY_PRF                    13
-#define OAKLEY_KEY_LENGTH             14
-#define OAKLEY_FIELD_SIZE             15
-#define OAKLEY_GROUP_ORDER            16        /* B/V */
-#define OAKLEY_BLOCK_SIZE             17
-
-/* for each Oakley attribute, which enum_names describes its values? */
-extern enum_names *oakley_attr_val_descs[];
-
-/* IPsec DOI attributes
- * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.5
- */
-
-extern enum_names ipsec_attr_names;
-
-#define SA_LIFE_TYPE             1
-#define SA_LIFE_DURATION         2      /* B/V */
-#define GROUP_DESCRIPTION        3
-#define ENCAPSULATION_MODE       4
-#define AUTH_ALGORITHM           5
-#define KEY_LENGTH               6
-#define KEY_ROUNDS               7
-#define COMPRESS_DICT_SIZE       8
-#define COMPRESS_PRIVATE_ALG     9      /* B/V */
-
-/* for each IPsec attribute, which enum_names describes its values? */
-extern enum_names *ipsec_attr_val_descs[];
-
-/* SA Lifetime Type attribute
- * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.5
- * Default time specified in 4.5
- *
- * There are two defaults for IPSEC SA lifetime, SA_LIFE_DURATION_DEFAULT,
- * and PLUTO_SA_LIFE_DURATION_DEFAULT.
- * SA_LIFE_DURATION_DEFAULT is specified in RFC2407 "The Internet IP
- * Security Domain of Interpretation for ISAKMP" 4.5.  It applies when
- * an ISAKMP negotiation does not explicitly specify a life duration.
- * PLUTO_SA_LIFE_DURATION_DEFAULT is specified in pluto(8).  It applies
- * when a connection description does not specify --ipseclifetime.
- * The value of SA_LIFE_DURATION_MAXIMUM is our local policy.
- */
-
-extern enum_names sa_lifetime_names;
-
-#define SA_LIFE_TYPE_SECONDS   1
-#define SA_LIFE_TYPE_KBYTES    2
-
-#define SA_LIFE_DURATION_DEFAULT          28800 /* eight hours (RFC2407 4.5) */
-#define PLUTO_SA_LIFE_DURATION_DEFAULT     3600 /* one hour    (pluto(8)) */
-#define SA_LIFE_DURATION_MAXIMUM          86400 /* one day */
-
-#define SA_REPLACEMENT_MARGIN_DEFAULT       540 /* (IPSEC & IKE) nine minutes */
-#define SA_REPLACEMENT_FUZZ_DEFAULT         100 /* (IPSEC & IKE) 100% of MARGIN */
-#define SA_REPLACEMENT_RETRIES_DEFAULT        3 /* (IPSEC & IKE) */
-
-#define SA_LIFE_DURATION_K_DEFAULT  0xFFFFFFFFlu
-
-/* Encapsulation Mode attribute */
-
-extern enum_names enc_mode_names;
-
-#define ENCAPSULATION_MODE_UNSPECIFIED 0        /* not legal -- used internally */
-#define ENCAPSULATION_MODE_TUNNEL      1
-#define ENCAPSULATION_MODE_TRANSPORT   2
-
-#define ENCAPSULATION_MODE_UDP_TUNNEL_RFC          3
-#define ENCAPSULATION_MODE_UDP_TRANSPORT_RFC       4
-
-#define ENCAPSULATION_MODE_UDP_TUNNEL_DRAFTS       61443
-#define ENCAPSULATION_MODE_UDP_TRANSPORT_DRAFTS    61444
-
-/* Auth Algorithm attribute */
-
-extern enum_names auth_alg_names, extended_auth_alg_names;
-
-#define AUTH_ALGORITHM_NONE                0  /* our private designation */
-#define AUTH_ALGORITHM_HMAC_MD5            1
-#define AUTH_ALGORITHM_HMAC_SHA1           2
-#define AUTH_ALGORITHM_DES_MAC             3
-#define AUTH_ALGORITHM_KPDK                4
-#define AUTH_ALGORITHM_HMAC_SHA2_256       5
-#define AUTH_ALGORITHM_HMAC_SHA2_384       6
-#define AUTH_ALGORITHM_HMAC_SHA2_512       7
-#define AUTH_ALGORITHM_HMAC_RIPEMD         8
-#define AUTH_ALGORITHM_AES_XCBC_MAC        9
-#define AUTH_ALGORITHM_SIG_RSA            10
-#define AUTH_ALGORITHM_AES_128_GMAC       11
-#define AUTH_ALGORITHM_AES_192_GMAC       12
-#define AUTH_ALGORITHM_AES_256_GMAC       13
-#define AUTH_ALGORITHM_NULL              251
-#define AUTH_ALGORITHM_HMAC_SHA2_256_96  252
-
-/* Oakley Lifetime Type attribute
- * draft-ietf-ipsec-ike-01.txt appendix A
- * As far as I can see, there is not specification for
- * OAKLEY_ISAKMP_SA_LIFETIME_DEFAULT.  This could lead to interop problems!
- * For no particular reason, we chose three hours.
- * The value of OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM is our local policy.
- */
-extern enum_names oakley_lifetime_names;
-
-#define OAKLEY_LIFE_SECONDS   1
-#define OAKLEY_LIFE_KILOBYTES 2
-
-#define OAKLEY_ISAKMP_SA_LIFETIME_DEFAULT 10800   /* three hours */
-#define OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM 86400   /* one day */
-
-/* Oakley PRF attribute (none defined)
- * draft-ietf-ipsec-ike-01.txt appendix A
- */
-extern enum_names oakley_prf_names;
-
-/* HMAC (see rfc2104.txt) */
-
-#define HMAC_IPAD            0x36
-#define HMAC_OPAD            0x5C
-
-/* Oakley Encryption Algorithm attribute
- * draft-ietf-ipsec-ike-01.txt appendix A
- * and from http://www.isi.edu/in-notes/iana/assignments/ipsec-registry
- */
-
-extern enum_names oakley_enc_names;
-
-#define OAKLEY_DES_CBC                  1
-#define OAKLEY_IDEA_CBC                 2
-#define OAKLEY_BLOWFISH_CBC             3
-#define OAKLEY_RC5_R16_B64_CBC          4
-#define OAKLEY_3DES_CBC                 5
-#define OAKLEY_CAST_CBC                 6
-#define OAKLEY_AES_CBC                  7
-#define OAKLEY_CAMELLIA_CBC             8
-
-#define OAKLEY_MARS_CBC                 65001
-#define OAKLEY_RC6_CBC                  65002
-#define OAKLEY_ID_65003                 65003
-#define OAKLEY_SERPENT_CBC              65004
-#define OAKLEY_TWOFISH_CBC              65005
-
-#define OAKLEY_TWOFISH_CBC_SSH          65289
-
-#define OAKLEY_ENCRYPT_MAX              65535   /* pretty useless :) */
-
-/* Oakley Hash Algorithm attribute
- * draft-ietf-ipsec-ike-01.txt appendix A
- * and from http://www.isi.edu/in-notes/iana/assignments/ipsec-registry
- */
-
-extern enum_names oakley_hash_names;
-
-#define OAKLEY_MD5              1
-#define OAKLEY_SHA              2
-#define OAKLEY_TIGER            3
-#define OAKLEY_SHA2_256         4
-#define OAKLEY_SHA2_384         5
-#define OAKLEY_SHA2_512         6
-
-#define OAKLEY_HASH_MAX         7
-
-/* Oakley Authentication Method attribute
- * draft-ietf-ipsec-ike-01.txt appendix A
- * Goofy Hybrid extensions from draft-ietf-ipsec-isakmp-hybrid-auth-05.txt
- * Goofy XAUTH extensions from draft-ietf-ipsec-isakmp-xauth-06.txt
- */
-
-extern enum_names oakley_auth_names;
-
-#define OAKLEY_PRESHARED_KEY       1
-#define OAKLEY_DSS_SIG             2
-#define OAKLEY_RSA_SIG             3
-#define OAKLEY_RSA_ENC             4
-#define OAKLEY_RSA_ENC_REV         5
-#define OAKLEY_ELGAMAL_ENC         6
-#define OAKLEY_ELGAMAL_ENC_REV     7
-#define OAKLEY_ECDSA_SIG           8
-#define OAKLEY_ECDSA_256           9
-#define OAKLEY_ECDSA_384          10
-#define OAKLEY_ECDSA_521          11
-
-#define OAKLEY_AUTH_ROOF          12    /* roof on auth values THAT WE SUPPORT */
-
-#define HybridInitRSA                   64221
-#define HybridRespRSA                   64222
-#define HybridInitDSS                   64223
-#define HybridRespDSS                   64224
-
-#define XAUTHInitPreShared              65001
-#define XAUTHRespPreShared              65002
-#define XAUTHInitDSS                    65003
-#define XAUTHRespDSS                    65004
-#define XAUTHInitRSA                    65005
-#define XAUTHRespRSA                    65006
-#define XAUTHInitRSAEncryption          65007
-#define XAUTHRespRSAEncryption          65008
-#define XAUTHInitRSARevisedEncryption   65009
-#define XAUTHRespRSARevisedEncryption   65010
-
-/* Oakley Group Description attribute
- * draft-ietf-ipsec-ike-01.txt appendix A
- */
-extern enum_names oakley_group_names;
-
-/*      you must also touch: constants.c, crypto.c */
-
-/* Oakley Group Type attribute
- * draft-ietf-ipsec-ike-01.txt appendix A
- */
-extern enum_names oakley_group_type_names;
-
-#define OAKLEY_GROUP_TYPE_MODP     1
-#define OAKLEY_GROUP_TYPE_ECP      2
-#define OAKLEY_GROUP_TYPE_EC2N     3
-
-
-/* Notify messages -- error types
- * See RFC2408 ISAKMP 3.14.1
- */
-
-extern enum_names notification_names;
-extern enum_names ipsec_notification_names;
-
-typedef enum {
-       ISAKMP_NOTHING_WRONG =              0,  /* unofficial! */
-
-       ISAKMP_INVALID_PAYLOAD_TYPE =       1,
-       ISAKMP_DOI_NOT_SUPPORTED =          2,
-       ISAKMP_SITUATION_NOT_SUPPORTED =    3,
-       ISAKMP_INVALID_COOKIE =             4,
-       ISAKMP_INVALID_MAJOR_VERSION =      5,
-       ISAKMP_INVALID_MINOR_VERSION =      6,
-       ISAKMP_INVALID_EXCHANGE_TYPE =      7,
-       ISAKMP_INVALID_FLAGS =              8,
-       ISAKMP_INVALID_MESSAGE_ID =         9,
-       ISAKMP_INVALID_PROTOCOL_ID =       10,
-       ISAKMP_INVALID_SPI =               11,
-       ISAKMP_INVALID_TRANSFORM_ID =      12,
-       ISAKMP_ATTRIBUTES_NOT_SUPPORTED =  13,
-       ISAKMP_NO_PROPOSAL_CHOSEN =        14,
-       ISAKMP_BAD_PROPOSAL_SYNTAX =       15,
-       ISAKMP_PAYLOAD_MALFORMED =         16,
-       ISAKMP_INVALID_KEY_INFORMATION =   17,
-       ISAKMP_INVALID_ID_INFORMATION =    18,
-       ISAKMP_INVALID_CERT_ENCODING =     19,
-       ISAKMP_INVALID_CERTIFICATE =       20,
-       ISAKMP_CERT_TYPE_UNSUPPORTED =     21,
-       ISAKMP_INVALID_CERT_AUTHORITY =    22,
-       ISAKMP_INVALID_HASH_INFORMATION =  23,
-       ISAKMP_AUTHENTICATION_FAILED =     24,
-       ISAKMP_INVALID_SIGNATURE =         25,
-       ISAKMP_ADDRESS_NOTIFICATION =      26,
-       ISAKMP_NOTIFY_SA_LIFETIME =        27,
-       ISAKMP_CERTIFICATE_UNAVAILABLE =   28,
-       ISAKMP_UNSUPPORTED_EXCHANGE_TYPE = 29,
-       ISAKMP_UNEQUAL_PAYLOAD_LENGTHS =   30,
-
-       /* ISAKMP status type */
-       ISAKMP_CONNECTED =              16384,
-
-       /* IPSEC DOI additions; status types (RFC2407 IPSEC DOI 4.6.3)
-        * These must be sent under the protection of an ISAKMP SA.
-        */
-       IPSEC_RESPONDER_LIFETIME =      24576,
-       IPSEC_REPLAY_STATUS =           24577,
-       IPSEC_INITIAL_CONTACT =         24578,
-
-       /* RFC 3706 DPD */
-       R_U_THERE =                     36136,
-       R_U_THERE_ACK =                 36137,
-
-       /* Juniper SRX private use */
-       NS_NHTB_INFORM =                40001
-
-       } notification_t;
-
-
-/* Public key algorithm number
- * Same numbering as used in DNSsec
- * See RFC 2535 DNSsec 3.2 The KEY Algorithm Number Specification.
- * Also found in BIND 8.2.2 include/isc/dst.h as DST algorithm codes.
- */
-
-enum pubkey_alg
-{
-       PUBKEY_ALG_RSA = 1,
-       PUBKEY_ALG_DSA = 3,
-};
-
-/* Limits on size of RSA moduli.
- * The upper bound matches that of DNSsec (see RFC 2537).
- * The lower bound must be more than 11 octets for certain
- * the encoding to work, but it must be much larger for any
- * real security.  For now, we require 512 bits.
- */
-
-#define RSA_MIN_OCTETS_RFC      12
-
-#define RSA_MIN_OCTETS  (512 / BITS_PER_BYTE)
-#define RSA_MIN_OCTETS_UGH      "RSA modulus too small for security: less than 512 bits"
-
-#define RSA_MAX_OCTETS  (8192 / BITS_PER_BYTE)
-#define RSA_MAX_OCTETS_UGH      "RSA modulus too large: more than 8192 bits"
-
-/* Note: RFC 2537 encoding adds a few bytes.  If you use a small
- * modulus like 3, the overhead is only 2 bytes
- */
-#define RSA_MAX_ENCODING_BYTES  (RSA_MAX_OCTETS + 2)
-
-/* socket address family info */
-
-struct af_info
-{
-       int af;
-       const char *name;
-       size_t ia_sz;
-       size_t sa_sz;
-       int mask_cnt;
-       u_int8_t id_addr, id_subnet, id_range;
-       const ip_address *any;
-       const ip_subnet *none;      /* 0.0.0.0/32 or IPv6 equivalent */
-       const ip_subnet *all;       /* 0.0.0.0/0 or IPv6 equivalent */
-};
-
-extern const struct af_info
-       af_inet4_info,
-       af_inet6_info;
-
-extern const struct af_info *aftoinfo(int af);
-
-extern enum_names af_names;
-
-#define subnetisaddr(sn, a) (subnetishost(sn) && addrinsubnet((a), (sn)))
-extern bool subnetisnone(const ip_subnet *sn);
-
-/* BIND enumerated types */
-
-extern enum_names
-       rr_qtype_names,
-       rr_type_names,
-       rr_class_names;
-
-/* How authenticated is info that might have come from DNS?
- * In order of increasing confidence.
- */
-enum dns_auth_level {
-       DAL_UNSIGNED,       /* AD in response, but no signature: no authentication */
-       DAL_NOTSEC, /* no AD in response: authentication impossible */
-       DAL_SIGNED, /* AD and signature in response: authentic */
-       DAL_LOCAL   /* locally provided (pretty good) */
-};
-
-/*
- * define a macro for use in error messages
- */
-
-#ifdef USE_KEYRR
-#define RRNAME "TXT or KEY"
-#else
-#define RRNAME "TXT"
-#endif
-
-/* natt traversal types */
-extern const char *const natt_type_bitnames[];
-
-/* secret value for responder cookies */
-extern u_char secret_of_the_day[HASH_SIZE_SHA1];
-
-#endif /* _CONSTANTS_H */
diff --git a/src/pluto/cookie.c b/src/pluto/cookie.c
deleted file mode 100644 (file)
index 00c863f..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/* cookie generation/verification routines.
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2002  D. Hugh Redelmeier.
- * Copyright (C) 2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-
-#include <freeswan.h>
-
-#include <library.h>
-#include <crypto/rngs/rng.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "cookie.h"
-
-const u_char zero_cookie[COOKIE_SIZE];  /* guaranteed 0 */
-
-/* Generate a cookie.
- * First argument is true if we're to create an Initiator cookie.
- * Length SHOULD be a multiple of sizeof(u_int32_t).
- */
-void get_cookie(bool initiator, u_int8_t *cookie, int length, ip_address *addr)
-{
-       hasher_t *hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
-       u_char buffer[HASH_SIZE_SHA1];
-
-       do {
-               if (initiator)
-               {
-                       rng_t *rng;
-
-                       rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
-                       rng->get_bytes(rng, length, cookie);
-                       rng->destroy(rng);
-               }
-               else  /* Responder cookie */
-               {
-                       chunk_t addr_chunk, secret_chunk, counter_chunk;
-                       size_t addr_len;
-                       static u_int32_t counter = 0;
-                       unsigned char addr_buf[
-                               sizeof(union {struct in_addr A; struct in6_addr B;})];
-
-                       addr_len = addrbytesof(addr, addr_buf, sizeof(addr_buf));
-                       addr_chunk = chunk_create(addr_buf, addr_len);
-                       secret_chunk = chunk_create(secret_of_the_day, HASH_SIZE_SHA1);
-                       counter++;
-                       counter_chunk = chunk_create((void *) &counter, sizeof(counter));
-                       hasher->get_hash(hasher, addr_chunk, NULL);
-                       hasher->get_hash(hasher, secret_chunk, NULL);
-                       hasher->get_hash(hasher, counter_chunk, buffer);
-                       memcpy(cookie, buffer, length);
-               }
-       } while (is_zero_cookie(cookie));   /* probably never loops */
-
-       hasher->destroy(hasher);
-}
diff --git a/src/pluto/cookie.h b/src/pluto/cookie.h
deleted file mode 100644 (file)
index 809d664..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/* cookie generation/verification routines.
- * Copyright (C) 1998-2002  D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <freeswan.h>
-
-extern const u_char zero_cookie[COOKIE_SIZE];   /* guaranteed 0 */
-
-extern void get_cookie(bool initiator, u_int8_t *cookie, int length,
-                                          ip_address *addr);
-
-#define is_zero_cookie(cookie) all_zero((cookie), COOKIE_SIZE)
diff --git a/src/pluto/crl.c b/src/pluto/crl.c
deleted file mode 100644 (file)
index c49b09e..0000000
+++ /dev/null
@@ -1,541 +0,0 @@
-/* Support of X.509 certificate revocation lists (CRLs)
- * Copyright (C) 2000-2009 Andreas Steffen
- *
- * HSR Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <time.h>
-#include <sys/types.h>
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "x509.h"
-#include "crl.h"
-#include "ca.h"
-#include "certs.h"
-#include "keys.h"
-#include "whack.h"
-#include "fetch.h"
-#include "builder.h"
-
-
-/* chained lists of X.509 crls */
-
-static x509crl_t  *x509crls = NULL;
-
-/**
- *  Get the X.509 CRL with a given issuer
- */
-static x509crl_t* get_x509crl(identification_t *issuer, chunk_t keyid)
-{
-       x509crl_t *x509crl = x509crls;
-       x509crl_t *prev_crl = NULL;
-
-       while (x509crl != NULL)
-       {
-               certificate_t *cert_crl = x509crl->crl;
-               crl_t *crl = (crl_t*)cert_crl;
-               identification_t *crl_issuer = cert_crl->get_issuer(cert_crl);
-               chunk_t authKeyID = crl->get_authKeyIdentifier(crl);
-
-               if ((keyid.ptr && authKeyID.ptr)? same_keyid(keyid, authKeyID) :
-                       issuer->equals(issuer, crl_issuer))
-               {
-                       if (x509crl != x509crls)
-                       {
-                               /* bring the CRL up front */
-                               prev_crl->next = x509crl->next;
-                               x509crl->next = x509crls;
-                               x509crls = x509crl;
-                       }
-                       return x509crl;
-               }
-               prev_crl = x509crl;
-               x509crl = x509crl->next;
-       }
-       return NULL;
-}
-
-/**
- *  Free the dynamic memory used to store CRLs
- */
-void free_crl(x509crl_t *crl)
-{
-       DESTROY_IF(crl->crl);
-       crl->distributionPoints->destroy_function(crl->distributionPoints, free);
-       free(crl);
-}
-
-static void free_first_crl(void)
-{
-       x509crl_t *crl = x509crls;
-
-       x509crls = crl->next;
-       free_crl(crl);
-}
-
-void free_crls(void)
-{
-       lock_crl_list("free_crls");
-
-       while (x509crls != NULL)
-       {
-               free_first_crl();
-       }
-
-       unlock_crl_list("free_crls");
-}
-
-/**
- * Insert X.509 CRL into chained list
- */
-bool insert_crl(x509crl_t *x509crl, char *crl_uri, bool cache_crl)
-{
-       certificate_t *cert_crl = x509crl->crl;
-       crl_t *crl = (crl_t*)cert_crl;
-       identification_t *issuer = cert_crl->get_issuer(cert_crl);
-       chunk_t authKeyID = crl->get_authKeyIdentifier(crl);
-       cert_t *issuer_cert;
-       x509crl_t *oldcrl;
-       time_t now, nextUpdate;
-       bool valid_sig;
-
-       /* add distribution point */
-       add_distribution_point(x509crl->distributionPoints, crl_uri);
-
-       lock_authcert_list("insert_crl");
-
-       /* get the issuer cacert */
-       issuer_cert = get_authcert(issuer, authKeyID, X509_CA);
-       if (issuer_cert == NULL)
-       {
-               plog("crl issuer cacert not found");
-               free_crl(x509crl);
-               unlock_authcert_list("insert_crl");
-               return FALSE;
-       }
-       DBG(DBG_CONTROL,
-               DBG_log("crl issuer cacert found")
-       )
-
-       /* check the issuer's signature of the crl */
-       valid_sig = cert_crl->issued_by(cert_crl, issuer_cert->cert);
-       unlock_authcert_list("insert_crl");
-
-       if (!valid_sig)
-       {
-               free_crl(x509crl);
-               return FALSE;
-       }
-       DBG(DBG_CONTROL,
-               DBG_log("crl signature is valid")
-       )
-
-       /* note the current time */
-       time(&now);
-
-       lock_crl_list("insert_crl");
-       oldcrl = get_x509crl(issuer, authKeyID);
-
-       if (oldcrl != NULL)
-       {
-               certificate_t *old_cert_crl = oldcrl->crl;
-
-               if (crl_is_newer((crl_t*)cert_crl, (crl_t*)old_cert_crl))
-               {
-                       /* keep any known CRL distribution points */
-                       add_distribution_points(x509crl->distributionPoints,
-                                                                       oldcrl->distributionPoints);
-
-                       /* now delete the old CRL */
-                       free_first_crl();
-                       DBG(DBG_CONTROL,
-                               DBG_log("thisUpdate is newer - existing crl deleted")
-                       )
-               }
-               else
-               {
-                       unlock_crl_list("insert_crls");
-                       DBG(DBG_CONTROL,
-                               DBG_log("thisUpdate is not newer - existing crl not replaced");
-                       )
-                       free_crl(x509crl);
-                       old_cert_crl->get_validity(old_cert_crl, &now, NULL, &nextUpdate);
-                       return nextUpdate - now > 2*crl_check_interval;
-               }
-       }
-
-       /* insert new CRL */
-       x509crl->next = x509crls;
-       x509crls = x509crl;
-
-       unlock_crl_list("insert_crl");
-
-       /* If crl caching is enabled then the crl is saved locally.
-        * Only http or ldap URIs are cached but not local file URIs.
-        * The CRL's authorityKeyIdentifier is used as a unique filename
-        */
-       if (cache_crl && strncasecmp(crl_uri, "file", 4) != 0)
-       {
-               char buf[BUF_LEN];
-               chunk_t hex, encoding;
-
-               hex = chunk_to_hex(crl->get_authKeyIdentifier(crl), NULL, FALSE);
-               snprintf(buf, sizeof(buf), "%s/%s.crl", CRL_PATH, hex.ptr);
-               free(hex.ptr);
-
-               if (cert_crl->get_encoding(cert_crl, CERT_ASN1_DER, &encoding))
-               {
-                       chunk_write(encoding, buf, "crl", 022, TRUE);
-                       free(encoding.ptr);
-               }
-       }
-
-       /* is the fetched crl valid? */
-       cert_crl->get_validity(cert_crl, &now, NULL, &nextUpdate);
-       return nextUpdate - now > 2*crl_check_interval;
-}
-
-/**
- *  Loads CRLs
- */
-void load_crls(void)
-{
-       struct dirent **filelist;
-       u_char buf[BUF_LEN];
-       u_char *save_dir;
-       int n;
-
-       /* change directory to specified path */
-       save_dir = getcwd(buf, BUF_LEN);
-       if (chdir(CRL_PATH))
-       {
-               plog("Could not change to directory '%s'", CRL_PATH);
-       }
-       else
-       {
-               plog("Changing to directory '%s'", CRL_PATH);
-               n = scandir(CRL_PATH, &filelist, file_select, alphasort);
-
-               if (n < 0)
-                       plog("  scandir() error");
-               else
-               {
-                       while (n--)
-                       {
-                               char *filename = filelist[n]->d_name;
-                               x509crl_t *x509crl;
-
-                               x509crl = lib->creds->create(lib->creds, CRED_CERTIFICATE,
-                                                                                CERT_PLUTO_CRL,
-                                                                                BUILD_FROM_FILE, filename, BUILD_END);
-                               if (x509crl)
-                               {
-                                       char crl_uri[BUF_LEN];
-
-                                       plog("  loaded crl from '%s'", filename);
-                                       snprintf(crl_uri, BUF_LEN, "file://%s/%s", CRL_PATH, filename);
-                                       insert_crl(x509crl, crl_uri, FALSE);
-                               }
-                               free(filelist[n]);
-                       }
-                       free(filelist);
-               }
-       }
-       /* restore directory path */
-       ignore_result(chdir(save_dir));
-}
-
-
-/*  Checks if the current certificate is revoked. It goes through the
- *  list of revoked certificates of the corresponding crl. Either the
- *  status CERT_GOOD or CERT_REVOKED is returned
- */
-static cert_status_t check_revocation(crl_t *crl, chunk_t cert_serial,
-                                                                         time_t *revocationDate,
-                                                                         crl_reason_t *revocationReason)
-{
-       enumerator_t *enumerator;
-       cert_status_t status;
-       chunk_t serial;
-
-       DBG(DBG_CONTROL,
-               DBG_log("serial number: %#B", &cert_serial)
-       )
-       *revocationDate = UNDEFINED_TIME;
-       *revocationReason = CRL_REASON_UNSPECIFIED;
-       status = CERT_GOOD;
-
-       enumerator = crl->create_enumerator(crl);
-       while (enumerator->enumerate(enumerator, &serial,
-                                                                revocationDate, revocationReason))
-       {
-               if (chunk_equals(serial, cert_serial))
-               {
-                       status = CERT_REVOKED;
-                       break;
-               }
-       }
-       enumerator->destroy(enumerator);
-       return status;
-}
-
-/*
- * check if any crls are about to expire
- */
-void check_crls(void)
-{
-       x509crl_t *x509crl;
-       time_t now, nextUpdate, time_left;
-
-       lock_crl_list("check_crls");
-       time(&now);
-       x509crl = x509crls;
-
-       while (x509crl != NULL)
-       {
-               certificate_t *cert_crl = x509crl->crl;
-               crl_t *crl = (crl_t*)cert_crl;
-               identification_t *issuer = cert_crl->get_issuer(cert_crl);
-               chunk_t authKeyID = crl->get_authKeyIdentifier(crl);
-
-               cert_crl->get_validity(cert_crl, &now, NULL, &nextUpdate);
-               time_left = nextUpdate - now;
-
-               DBG(DBG_CONTROL,
-                       DBG_log("issuer: '%Y'", issuer);
-                       if (authKeyID.ptr)
-                       {
-                               DBG_log("authkey: %#B", &authKeyID);
-                       }
-                       DBG_log("%ld seconds left", time_left)
-               )
-               if (time_left < 2*crl_check_interval)
-               {
-                       fetch_req_t *req = build_crl_fetch_request(issuer, authKeyID,
-                                                                                       x509crl->distributionPoints);
-                       add_crl_fetch_request(req);
-               }
-               x509crl = x509crl->next;
-       }
-       unlock_crl_list("check_crls");
-}
-
-/*
- * verify if a cert hasn't been revoked by a crl
- */
-cert_status_t verify_by_crl(cert_t *cert, time_t *until, time_t *revocationDate,
-                                                       crl_reason_t *revocationReason)
-{
-       certificate_t *certificate = cert->cert;
-       x509_t *x509 = (x509_t*)certificate;
-       identification_t *issuer = certificate->get_issuer(certificate);
-       chunk_t authKeyID = x509->get_authKeyIdentifier(x509);
-       x509crl_t *x509crl;
-       ca_info_t *ca;
-       enumerator_t *enumerator;
-       x509_cdp_t *cdp;
-
-       ca = get_ca_info(issuer, authKeyID);
-
-       *revocationDate = UNDEFINED_TIME;
-       *revocationReason = CRL_REASON_UNSPECIFIED;
-
-       lock_crl_list("verify_by_crl");
-       x509crl = get_x509crl(issuer, authKeyID);
-
-       if (x509crl == NULL)
-       {
-               linked_list_t *crluris;
-
-               unlock_crl_list("verify_by_crl");
-               plog("crl not found");
-
-               crluris = linked_list_create();
-               if (ca)
-               {
-                       add_distribution_points(crluris, ca->crluris);
-               }
-
-               enumerator = x509->create_crl_uri_enumerator(x509);
-               while (enumerator->enumerate(enumerator, &cdp))
-               {
-                       add_distribution_point(crluris, cdp->uri);
-               }
-               enumerator->destroy(enumerator);
-
-               if (crluris->get_count(crluris) > 0)
-               {
-                       fetch_req_t *req;
-
-                       req = build_crl_fetch_request(issuer, authKeyID, crluris);
-                       crluris->destroy_function(crluris, free);
-                       add_crl_fetch_request(req);
-                       wake_fetch_thread("verify_by_crl");
-                       return CERT_UNKNOWN;
-               }
-               else
-               {
-                       crluris->destroy(crluris);
-                       return CERT_UNDEFINED;
-               }
-       }
-       else
-       {
-               certificate_t *cert_crl = x509crl->crl;
-               crl_t *crl = (crl_t*)cert_crl;
-               chunk_t authKeyID = crl->get_authKeyIdentifier(crl);
-               cert_t *issuer_cert;
-               bool trusted, valid;
-
-               DBG(DBG_CONTROL,
-                       DBG_log("crl found")
-               )
-
-               if (ca)
-               {
-                       add_distribution_points(x509crl->distributionPoints, ca->crluris);
-               }
-
-               enumerator = x509->create_crl_uri_enumerator(x509);
-               while (enumerator->enumerate(enumerator, &cdp))
-               {
-                       add_distribution_point(x509crl->distributionPoints, cdp->uri);
-               }
-               enumerator->destroy(enumerator);
-
-               lock_authcert_list("verify_by_crl");
-
-               issuer_cert = get_authcert(issuer, authKeyID, X509_CA);
-               trusted = issuer_cert ? cert_crl->issued_by(cert_crl, issuer_cert->cert)
-                                                         : FALSE;
-
-               unlock_authcert_list("verify_by_crl");
-
-               if (trusted)
-               {
-                       cert_status_t status;
-
-                       DBG(DBG_CONTROL,
-                               DBG_log("crl signature is valid")
-                       )
-
-                       /* return the expiration date */
-                       valid = cert_crl->get_validity(cert_crl, NULL, NULL, until);
-
-                       /* has the certificate been revoked? */
-                       status = check_revocation(crl, x509->get_serial(x509), revocationDate
-                                                               , revocationReason);
-
-                       if (valid)
-                       {
-                               unlock_crl_list("verify_by_crl");
-                               DBG(DBG_CONTROL,
-                                       DBG_log("crl is valid: until %T", until, FALSE)
-                               )
-                       }
-                       else
-                       {
-                               fetch_req_t *req;
-
-                               DBG(DBG_CONTROL,
-                                       DBG_log("crl is stale: since %T", until, FALSE)
-                               )
-
-                               /* try to fetch a crl update */
-                               req = build_crl_fetch_request(issuer, authKeyID,
-                                                                                         x509crl->distributionPoints);
-                               unlock_crl_list("verify_by_crl");
-
-                               add_crl_fetch_request(req);
-                               wake_fetch_thread("verify_by_crl");
-                       }
-                       return status;
-               }
-               else
-               {
-                       unlock_crl_list("verify_by_crl");
-                       plog("crl signature is invalid");
-                       return CERT_UNKNOWN;
-               }
-       }
-}
-
-/*
- *  list all X.509 crls in the chained list
- */
-void list_crls(bool utc, bool strict)
-{
-       x509crl_t *x509crl;
-
-       lock_crl_list("list_crls");
-       x509crl = x509crls;
-
-       if (x509crl)
-       {
-               whack_log(RC_COMMENT, " ");
-               whack_log(RC_COMMENT, "List of X.509 CRLs:");
-       }
-
-       while (x509crl)
-       {
-               certificate_t *cert_crl = x509crl->crl;
-               crl_t *crl = (crl_t*)cert_crl;
-               chunk_t serial, authKeyID;
-               time_t thisUpdate, nextUpdate;
-               u_int revoked = 0;
-               enumerator_t *enumerator;
-
-               whack_log(RC_COMMENT, " ");
-               whack_log(RC_COMMENT, "  issuer:   \"%Y\"",
-                               cert_crl->get_issuer(cert_crl));
-               serial = chunk_skip_zero(crl->get_serial(crl));
-               if (serial.ptr)
-               {
-                       whack_log(RC_COMMENT, "  serial:    %#B", &serial);
-               }
-
-               /* count number of revoked certificates in CRL */
-               enumerator = crl->create_enumerator(crl);
-               while (enumerator->enumerate(enumerator, NULL, NULL, NULL))
-               {
-                       revoked++;
-               }
-               enumerator->destroy(enumerator);
-               whack_log(RC_COMMENT, "  revoked:   %d certificates", revoked);
-
-               list_distribution_points(x509crl->distributionPoints);
-
-               cert_crl->get_validity(cert_crl, NULL, &thisUpdate, &nextUpdate);
-               whack_log(RC_COMMENT, "  updates:   this %T", &thisUpdate, utc);
-               whack_log(RC_COMMENT, "             next %T %s", &nextUpdate, utc,
-                               check_expiry(nextUpdate, CRL_WARNING_INTERVAL, strict));
-               authKeyID = crl->get_authKeyIdentifier(crl);
-               if (authKeyID.ptr)
-               {
-                       whack_log(RC_COMMENT, "  authkey:   %#B", &authKeyID);
-               }
-
-               x509crl = x509crl->next;
-       }
-       unlock_crl_list("list_crls");
-}
-
diff --git a/src/pluto/crl.h b/src/pluto/crl.h
deleted file mode 100644 (file)
index 43bafe1..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/* Support of X.509 certificate revocation lists (CRLs)
- * Copyright (C) 2000-2004 Andreas Steffen, Zuercher Hochschule Winterthur
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include "constants.h"
-
-#include <utils/linked_list.h>
-#include <credentials/certificates/certificate.h>
-#include <credentials/certificates/crl.h>
-
-/* storage structure for an X.509 CRL */
-
-typedef struct x509crl x509crl_t;
-
-struct x509crl {
-       certificate_t *crl;
-       x509crl_t     *next;
-       linked_list_t *distributionPoints;
-};
-
-/* apply a strict CRL policy
- * flag set in plutomain.c and used in ipsec_doi.c and rcv_whack.c
- */
-extern bool strict_crl_policy;
-
-/*
- * cache the retrieved CRLs by storing them locally as a file
- */
-extern bool cache_crls;
-
-/*
- * check periodically for expired crls
- */
-extern long crl_check_interval;
-extern void load_crls(void);
-extern void check_crls(void);
-extern bool insert_crl(x509crl_t *crl, char *crl_uri, bool cache_crl);
-extern cert_status_t verify_by_crl(cert_t *cert, time_t *until,
-                                                                  time_t *revocationDate,
-                                                                  crl_reason_t *revocationReason);
-extern void list_crls(bool utc, bool strict);
-extern void free_crls(void);
-extern void free_crl(x509crl_t *crl);
diff --git a/src/pluto/crypto.c b/src/pluto/crypto.c
deleted file mode 100644 (file)
index a4f6782..0000000
+++ /dev/null
@@ -1,698 +0,0 @@
-/* crypto interfaces
- *
- * Copyright (C) 2010 Tobias Brunner
- * Copyright (C) 2007-2009 Andreas Steffen
- * Hochschule fuer Technik Rapperswil
- *
- * Copyright (C) 1998-2001 D. Hugh Redelmeier
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "crypto.h"
-#include "log.h"
-
-static struct encrypt_desc encrypt_desc_3des =
-{
-       algo_type:        IKE_ALG_ENCRYPT,
-       algo_id:          OAKLEY_3DES_CBC,
-       plugin_name:      NULL,
-       algo_next:        NULL,
-
-       enc_blocksize:    DES_BLOCK_SIZE,
-       keydeflen:        DES_BLOCK_SIZE * 3 * BITS_PER_BYTE,
-       keyminlen:        DES_BLOCK_SIZE * 3 * BITS_PER_BYTE,
-       keymaxlen:        DES_BLOCK_SIZE * 3 * BITS_PER_BYTE,
-};
-
-#define  AES_KEY_MIN_LEN       128
-#define  AES_KEY_DEF_LEN       128
-#define  AES_KEY_MAX_LEN       256
-
-static struct encrypt_desc encrypt_desc_aes =
-{
-       algo_type:        IKE_ALG_ENCRYPT,
-       algo_id:          OAKLEY_AES_CBC,
-       plugin_name:      NULL,
-       algo_next:        NULL,
-
-       enc_blocksize:    AES_BLOCK_SIZE,
-       keyminlen:        AES_KEY_MIN_LEN,
-       keydeflen:        AES_KEY_DEF_LEN,
-       keymaxlen:        AES_KEY_MAX_LEN,
-};
-
-#define  CAMELLIA_KEY_MIN_LEN  128
-#define  CAMELLIA_KEY_DEF_LEN  128
-#define  CAMELLIA_KEY_MAX_LEN  256
-
-static struct encrypt_desc encrypt_desc_camellia =
-{
-       algo_type:        IKE_ALG_ENCRYPT,
-       algo_id:          OAKLEY_CAMELLIA_CBC,
-       plugin_name:      NULL,
-       algo_next:        NULL,
-
-       enc_blocksize:    CAMELLIA_BLOCK_SIZE,
-       keyminlen:        CAMELLIA_KEY_MIN_LEN,
-       keydeflen:        CAMELLIA_KEY_DEF_LEN,
-       keymaxlen:        CAMELLIA_KEY_MAX_LEN,
-};
-
-#define  BLOWFISH_KEY_MIN_LEN  128
-#define  BLOWFISH_KEY_MAX_LEN  448
-
-static struct encrypt_desc encrypt_desc_blowfish =
-{
-       algo_type:        IKE_ALG_ENCRYPT,
-       algo_id:          OAKLEY_BLOWFISH_CBC,
-       plugin_name:      NULL,
-       algo_next:        NULL,
-
-       enc_blocksize:    BLOWFISH_BLOCK_SIZE,
-       keyminlen:        BLOWFISH_KEY_MIN_LEN,
-       keydeflen:        BLOWFISH_KEY_MIN_LEN,
-       keymaxlen:        BLOWFISH_KEY_MAX_LEN,
-};
-
-#define  SERPENT_KEY_MIN_LEN   128
-#define  SERPENT_KEY_DEF_LEN   128
-#define  SERPENT_KEY_MAX_LEN   256
-
-static struct encrypt_desc encrypt_desc_serpent =
-{
-       algo_type:        IKE_ALG_ENCRYPT,
-       algo_id:          OAKLEY_SERPENT_CBC,
-       plugin_name:      NULL,
-       algo_next:        NULL,
-
-       enc_blocksize:    SERPENT_BLOCK_SIZE,
-       keyminlen:        SERPENT_KEY_MIN_LEN,
-       keydeflen:        SERPENT_KEY_DEF_LEN,
-       keymaxlen:        SERPENT_KEY_MAX_LEN,
-};
-
-#define  TWOFISH_KEY_MIN_LEN   128
-#define  TWOFISH_KEY_DEF_LEN   128
-#define  TWOFISH_KEY_MAX_LEN   256
-
-static struct encrypt_desc encrypt_desc_twofish =
-{
-       algo_type:        IKE_ALG_ENCRYPT,
-       algo_id:          OAKLEY_TWOFISH_CBC,
-       plugin_name:      NULL,
-       algo_next:        NULL,
-
-       enc_blocksize:    TWOFISH_BLOCK_SIZE,
-       keydeflen:        TWOFISH_KEY_MIN_LEN,
-       keyminlen:        TWOFISH_KEY_DEF_LEN,
-       keymaxlen:        TWOFISH_KEY_MAX_LEN,
-};
-
-static struct encrypt_desc encrypt_desc_twofish_ssh =
-{
-       algo_type:        IKE_ALG_ENCRYPT,
-       algo_id:          OAKLEY_TWOFISH_CBC_SSH,
-       plugin_name:      NULL,
-       algo_next:        NULL,
-
-       enc_blocksize:    TWOFISH_BLOCK_SIZE,
-       keydeflen:        TWOFISH_KEY_MIN_LEN,
-       keyminlen:        TWOFISH_KEY_DEF_LEN,
-       keymaxlen:        TWOFISH_KEY_MAX_LEN,
-};
-
-static struct hash_desc hash_desc_md5 =
-{
-       algo_type:        IKE_ALG_HASH,
-       algo_id:          OAKLEY_MD5,
-       plugin_name:      NULL,
-       algo_next:        NULL,
-       hash_digest_size: HASH_SIZE_MD5,
-};
-
-static struct hash_desc hash_desc_sha1 =
-{
-       algo_type:        IKE_ALG_HASH,
-       algo_id:          OAKLEY_SHA,
-       plugin_name:      NULL,
-       algo_next:        NULL,
-       hash_digest_size: HASH_SIZE_SHA1,
-};
-
-static struct hash_desc hash_desc_sha2_256 = {
-       algo_type:        IKE_ALG_HASH,
-       algo_id:          OAKLEY_SHA2_256,
-       plugin_name:      NULL,
-       algo_next:        NULL,
-       hash_digest_size: HASH_SIZE_SHA256,
-};
-
-static struct hash_desc hash_desc_sha2_384 = {
-       algo_type:        IKE_ALG_HASH,
-       algo_id:          OAKLEY_SHA2_384,
-       plugin_name:      NULL,
-       algo_next:        NULL,
-       hash_digest_size: HASH_SIZE_SHA384,
-};
-
-static struct hash_desc hash_desc_sha2_512 = {
-       algo_type:        IKE_ALG_HASH,
-       algo_id:          OAKLEY_SHA2_512,
-       plugin_name:      NULL,
-       algo_next:        NULL,
-       hash_digest_size: HASH_SIZE_SHA512,
-};
-
-const struct dh_desc unset_group = {
-       algo_type:        IKE_ALG_DH_GROUP,
-       algo_id:          MODP_NONE,
-       plugin_name:      NULL,
-       algo_next:        NULL,
-       ke_size:          0
-};
-
-static struct dh_desc dh_desc_modp_1024 = {
-       algo_type:        IKE_ALG_DH_GROUP,
-       algo_id:          MODP_1024_BIT,
-       plugin_name:      NULL,
-       algo_next:        NULL,
-       ke_size:          1024 / BITS_PER_BYTE
-};
-
-static struct dh_desc dh_desc_modp_1536 = {
-       algo_type:        IKE_ALG_DH_GROUP,
-       algo_id:          MODP_1536_BIT,
-       plugin_name:      NULL,
-       algo_next:        NULL,
-       ke_size:          1536 / BITS_PER_BYTE
-};
-
-static struct dh_desc dh_desc_modp_2048 = {
-       algo_type:        IKE_ALG_DH_GROUP,
-       algo_id:          MODP_2048_BIT,
-       algo_next:        NULL,
-       ke_size:          2048 / BITS_PER_BYTE
-};
-
-static struct dh_desc dh_desc_modp_3072 = {
-       algo_type:        IKE_ALG_DH_GROUP,
-       algo_id:          MODP_3072_BIT,
-       plugin_name:      NULL,
-       algo_next:        NULL,
-       ke_size:          3072 / BITS_PER_BYTE
-};
-
-static struct dh_desc dh_desc_modp_4096 = {
-       algo_type:        IKE_ALG_DH_GROUP,
-       algo_id:          MODP_4096_BIT,
-       plugin_name:      NULL,
-       algo_next:        NULL,
-       ke_size:          4096 / BITS_PER_BYTE
-};
-
-static struct dh_desc dh_desc_modp_6144 = {
-       algo_type:        IKE_ALG_DH_GROUP,
-       algo_id:          MODP_6144_BIT,
-       plugin_name:      NULL,
-       algo_next:        NULL,
-       ke_size:          6144 / BITS_PER_BYTE
-};
-
-static struct dh_desc dh_desc_modp_8192 = {
-       algo_type:        IKE_ALG_DH_GROUP,
-       algo_id:          MODP_8192_BIT,
-       plugin_name:      NULL,
-       algo_next:        NULL,
-       ke_size:          8192 / BITS_PER_BYTE
-};
-
-static struct dh_desc dh_desc_ecp_256 = {
-       algo_type:        IKE_ALG_DH_GROUP,
-       algo_id:          ECP_256_BIT,
-       plugin_name:      NULL,
-       algo_next:        NULL,
-       ke_size:          2*256 / BITS_PER_BYTE
-};
-
-static struct dh_desc dh_desc_ecp_384 = {
-       algo_type:        IKE_ALG_DH_GROUP,
-       algo_id:          ECP_384_BIT,
-       plugin_name:      NULL,
-       algo_next:        NULL,
-       ke_size:          2*384 / BITS_PER_BYTE
-};
-
-static struct dh_desc dh_desc_ecp_521 = {
-       algo_type:        IKE_ALG_DH_GROUP,
-       algo_id:          ECP_521_BIT,
-       plugin_name:      NULL,
-       algo_next:        NULL,
-       ke_size:          2*528 / BITS_PER_BYTE
-};
-
-static struct dh_desc dh_desc_modp_1024_160 = {
-       algo_type:        IKE_ALG_DH_GROUP,
-       algo_id:          MODP_1024_160,
-       plugin_name:      NULL,
-       algo_next:        NULL,
-       ke_size:          1024 / BITS_PER_BYTE
-};
-
-static struct dh_desc dh_desc_modp_2048_224 = {
-       algo_type:        IKE_ALG_DH_GROUP,
-       algo_id:          MODP_2048_224,
-       plugin_name:      NULL,
-       algo_next:        NULL,
-       ke_size:          2048 / BITS_PER_BYTE
-};
-
-static struct dh_desc dh_desc_modp_2048_256 = {
-       algo_type:        IKE_ALG_DH_GROUP,
-       algo_id:          MODP_2048_256,
-       plugin_name:      NULL,
-       algo_next:        NULL,
-       ke_size:          2048 / BITS_PER_BYTE
-};
-
-static struct dh_desc dh_desc_ecp_192 = {
-       algo_type:        IKE_ALG_DH_GROUP,
-       algo_id:          ECP_192_BIT,
-       plugin_name:      NULL,
-       algo_next:        NULL,
-       ke_size:          2*192 / BITS_PER_BYTE
-};
-
-static struct dh_desc dh_desc_ecp_224 = {
-       algo_type:  IKE_ALG_DH_GROUP,
-       algo_id:    ECP_224_BIT,
-       plugin_name:      NULL,
-       algo_next:        NULL,
-       ke_size:          2*224 / BITS_PER_BYTE
-};
-
-bool init_crypto(void)
-{
-       enumerator_t *enumerator;
-       encryption_algorithm_t encryption_alg;
-       hash_algorithm_t hash_alg;
-       diffie_hellman_group_t dh_group;
-       const char *plugin_name;
-       bool no_md5  = TRUE;
-       bool no_sha1 = TRUE;
-
-       enumerator = lib->crypto->create_hasher_enumerator(lib->crypto);
-       while (enumerator->enumerate(enumerator, &hash_alg, &plugin_name))
-       {
-               const struct hash_desc *desc;
-
-               switch (hash_alg)
-               {
-                       case HASH_SHA1:
-                               desc = &hash_desc_sha1;
-                               no_sha1 = FALSE;
-                               break;
-                       case HASH_SHA256:
-                               desc = &hash_desc_sha2_256;
-                               break;
-                       case HASH_SHA384:
-                               desc = &hash_desc_sha2_384;
-                               break;
-                       case HASH_SHA512:
-                               desc = &hash_desc_sha2_512;
-                               break;
-                       case HASH_MD5:
-                               desc = &hash_desc_md5;
-                               no_md5 = FALSE;
-                               break;
-                       default:
-                               continue;
-               }
-               ike_alg_add((struct ike_alg *)desc, plugin_name);
-       }
-       enumerator->destroy(enumerator);
-
-       if (no_sha1 || no_md5)
-       {
-               plog("pluto cannot run without a %s%s%s hasher",
-                        (no_sha1) ? "SHA-1" : "",
-                        (no_sha1 && no_md5) ? " and " : "",
-                        (no_md5) ? "MD5" : "");
-               return FALSE;
-       }
-
-       enumerator = lib->crypto->create_crypter_enumerator(lib->crypto);
-       while (enumerator->enumerate(enumerator, &encryption_alg, &plugin_name))
-       {
-               const struct encrypt_desc *desc;
-
-               switch (encryption_alg)
-               {
-                       case ENCR_3DES:
-                               desc = &encrypt_desc_3des;
-                               break;
-                       case ENCR_BLOWFISH:
-                               desc = &encrypt_desc_blowfish;
-                               break;
-                       case ENCR_AES_CBC:
-                               desc = &encrypt_desc_aes;
-                               break;
-                       case ENCR_CAMELLIA_CBC:
-                               desc = &encrypt_desc_camellia;
-                               break;
-                       case ENCR_TWOFISH_CBC:
-                               desc = &encrypt_desc_twofish;
-                               ike_alg_add((struct ike_alg *)&encrypt_desc_twofish_ssh,
-                                                       plugin_name);
-                               break;
-                       case ENCR_SERPENT_CBC:
-                               desc = &encrypt_desc_serpent;
-                               break;
-                       default:
-                               continue;
-               }
-               ike_alg_add((struct ike_alg *)desc, plugin_name);
-       }
-       enumerator->destroy(enumerator);
-
-       enumerator = lib->crypto->create_dh_enumerator(lib->crypto);
-       while (enumerator->enumerate(enumerator, &dh_group, &plugin_name))
-       {
-               const struct dh_desc *desc;
-
-               switch (dh_group)
-               {
-                       case MODP_1024_BIT:
-                               desc = &dh_desc_modp_1024;
-                               break;
-                       case MODP_1536_BIT:
-                               desc = &dh_desc_modp_1536;
-                               break;
-                       case MODP_2048_BIT:
-                               desc = &dh_desc_modp_2048;
-                               break;
-                       case MODP_3072_BIT:
-                               desc = &dh_desc_modp_3072;
-                               break;
-                       case MODP_4096_BIT:
-                               desc = &dh_desc_modp_4096;
-                               break;
-                       case MODP_6144_BIT:
-                               desc = &dh_desc_modp_6144;
-                               break;
-                       case MODP_8192_BIT:
-                               desc = &dh_desc_modp_8192;
-                               break;
-                       case ECP_256_BIT:
-                               desc = &dh_desc_ecp_256;
-                               break;
-                       case ECP_384_BIT:
-                               desc = &dh_desc_ecp_384;
-                               break;
-                       case ECP_521_BIT:
-                               desc = &dh_desc_ecp_521;
-                               break;
-                       case MODP_1024_160:
-                               desc = &dh_desc_modp_1024_160;
-                               break;
-                       case MODP_2048_224:
-                               desc = &dh_desc_modp_2048_224;
-                               break;
-                       case MODP_2048_256:
-                               desc = &dh_desc_modp_2048_256;
-                               break;
-                       case ECP_192_BIT:
-                               desc = &dh_desc_ecp_192;
-                               break;
-                       case ECP_224_BIT:
-                               desc = &dh_desc_ecp_224;
-                               break;
-                       default:
-                               continue;
-               }
-               ike_alg_add((struct ike_alg *)desc, plugin_name);
-       }
-       enumerator->destroy(enumerator);
-       return TRUE;
-}
-
-void free_crypto(void)
-{
-       /* currently nothing to do */
-}
-
-/**
- * Converts IKEv1 encryption algorithm name to crypter name
- */
-encryption_algorithm_t oakley_to_encryption_algorithm(int alg)
-{
-       switch (alg)
-       {
-               case OAKLEY_DES_CBC:
-                       return ENCR_DES;
-               case OAKLEY_IDEA_CBC:
-                       return ENCR_IDEA;
-               case OAKLEY_BLOWFISH_CBC:
-                       return ENCR_BLOWFISH;
-               case OAKLEY_RC5_R16_B64_CBC:
-                       return ENCR_RC5;
-               case OAKLEY_3DES_CBC:
-                       return ENCR_3DES;
-               case OAKLEY_CAST_CBC:
-                       return ENCR_CAST;
-               case OAKLEY_AES_CBC:
-                       return ENCR_AES_CBC;
-               case OAKLEY_CAMELLIA_CBC:
-                       return ENCR_CAMELLIA_CBC;
-               case OAKLEY_SERPENT_CBC:
-                       return ENCR_SERPENT_CBC;
-               case OAKLEY_TWOFISH_CBC:
-               case OAKLEY_TWOFISH_CBC_SSH:
-                       return ENCR_TWOFISH_CBC;
-               default:
-                       return ENCR_UNDEFINED;
-       }
-}
-
-/**
- * Converts IKEv1 hash algorithm name to hasher name
- */
-hash_algorithm_t oakley_to_hash_algorithm(int alg)
-{
-       switch (alg)
-       {
-               case OAKLEY_MD5:
-                       return HASH_MD5;
-               case OAKLEY_SHA:
-                       return HASH_SHA1;
-               case OAKLEY_SHA2_256:
-                       return HASH_SHA256;
-               case OAKLEY_SHA2_384:
-                       return HASH_SHA384;
-               case OAKLEY_SHA2_512:
-                       return HASH_SHA512;
-               default:
-                       return HASH_UNKNOWN;
-       }
-}
-
-/**
- * Converts IKEv1 hash algorithm name to IKEv2 prf name
- */
-pseudo_random_function_t oakley_to_prf(int alg)
-{
-       switch (alg)
-       {
-               case OAKLEY_MD5:
-                       return PRF_HMAC_MD5;
-               case OAKLEY_SHA:
-                       return PRF_HMAC_SHA1;
-               case OAKLEY_SHA2_256:
-                       return PRF_HMAC_SHA2_256;
-               case OAKLEY_SHA2_384:
-                       return PRF_HMAC_SHA2_384;
-               case OAKLEY_SHA2_512:
-                       return PRF_HMAC_SHA2_512;
-               default:
-                       return PRF_UNDEFINED;
-       }
-}
-
-/**
- * Maps IKEv1 authentication method to IKEv2 signature scheme
- */
-signature_scheme_t oakley_to_signature_scheme(int method)
-{
-       switch (method)
-       {
-               case OAKLEY_RSA_SIG:
-               case XAUTHInitRSA:
-               case XAUTHRespRSA:
-                       return SIGN_RSA_EMSA_PKCS1_NULL;
-               case OAKLEY_ECDSA_256:
-               case OAKLEY_ECDSA_384:
-               case OAKLEY_ECDSA_521:
-                       return SIGN_ECDSA_WITH_NULL;
-               default:
-                       return SIGN_UNKNOWN;
-       }
-}
-
-/**
- * Table to map IKEv2 encryption algorithms to IKEv1 (or IKEv1 ESP) and back
- */
-struct {
-       encryption_algorithm_t alg;
-       int oakley;
-       int esp;
-} encr_map[] = {
-       {ENCR_DES,                OAKLEY_DES_CBC,         ESP_DES       },
-       {ENCR_3DES,               OAKLEY_3DES_CBC,        ESP_3DES      },
-       {ENCR_RC5,                OAKLEY_RC5_R16_B64_CBC, ESP_RC5       },
-       {ENCR_IDEA,               OAKLEY_IDEA_CBC,        ESP_IDEA      },
-       {ENCR_CAST,               OAKLEY_CAST_CBC,        ESP_CAST      },
-       {ENCR_BLOWFISH,           OAKLEY_BLOWFISH_CBC,    ESP_BLOWFISH  },
-       {ENCR_AES_CBC,            OAKLEY_AES_CBC,         ESP_AES       },
-       {ENCR_CAMELLIA_CBC,       OAKLEY_CAMELLIA_CBC,    ESP_CAMELLIA  },
-       {ENCR_SERPENT_CBC,        OAKLEY_SERPENT_CBC,     ESP_SERPENT   },
-       {ENCR_TWOFISH_CBC,        OAKLEY_TWOFISH_CBC,     ESP_TWOFISH   },
-       {ENCR_NULL,               0,                      ESP_NULL      },
-       {ENCR_AES_CTR,            0,                      ESP_AES_CTR   },
-       {ENCR_AES_CCM_ICV8,       0,                      ESP_AES_CCM_8 },
-       {ENCR_AES_CCM_ICV12,      0,                      ESP_AES_CCM_12},
-       {ENCR_AES_CCM_ICV16,      0,                      ESP_AES_CCM_16},
-       {ENCR_AES_GCM_ICV8,       0,                      ESP_AES_GCM_8 },
-       {ENCR_AES_GCM_ICV12,      0,                      ESP_AES_GCM_12},
-       {ENCR_AES_GCM_ICV16,      0,                      ESP_AES_GCM_16},
-       {ENCR_NULL_AUTH_AES_GMAC, 0,                      ESP_AES_GMAC  },
-};
-
-/**
- * Converts IKEv2 encryption to IKEv1 encryption algorithm
- */
-int oakley_from_encryption_algorithm(encryption_algorithm_t alg)
-{
-       int i;
-       for (i = 0; i < countof(encr_map); i++)
-       {
-               if (encr_map[i].alg == alg)
-               {
-                       return encr_map[i].oakley;
-               }
-       }
-       return 0;
-}
-
-/**
- * Converts IKEv2 encryption to IKEv1 ESP encryption algorithm
- */
-int esp_from_encryption_algorithm(encryption_algorithm_t alg)
-{
-       int i;
-       for (i = 0; i < countof(encr_map); i++)
-       {
-               if (encr_map[i].alg == alg)
-               {
-                       return encr_map[i].esp;
-               }
-       }
-       return 0;
-}
-
-/**
- * Converts IKEv1 ESP encryption to IKEv2 algorithm
- */
-encryption_algorithm_t encryption_algorithm_from_esp(int esp)
-{
-       int i;
-       for (i = 0; i < countof(encr_map); i++)
-       {
-               if (encr_map[i].esp == esp)
-               {
-                       return encr_map[i].alg;
-               }
-       }
-       return 0;
-}
-
-/**
- * Table to map IKEv2 integrity algorithms to IKEv1 (or IKEv1 ESP) and back
- */
-struct {
-       integrity_algorithm_t alg;
-       int oakley;
-       int esp;
-} auth_map[] = {
-       {AUTH_HMAC_MD5_96,       OAKLEY_MD5,      AUTH_ALGORITHM_HMAC_MD5        },
-       {AUTH_HMAC_SHA1_96,      OAKLEY_SHA,      AUTH_ALGORITHM_HMAC_SHA1       },
-       {AUTH_HMAC_SHA2_256_96,  0,               AUTH_ALGORITHM_HMAC_SHA2_256_96},
-       {AUTH_HMAC_SHA2_256_128, OAKLEY_SHA2_256, AUTH_ALGORITHM_HMAC_SHA2_256   },
-       {AUTH_HMAC_SHA2_384_192, OAKLEY_SHA2_384, AUTH_ALGORITHM_HMAC_SHA2_384   },
-       {AUTH_HMAC_SHA2_512_256, OAKLEY_SHA2_512, AUTH_ALGORITHM_HMAC_SHA2_512   },
-       {AUTH_AES_XCBC_96,       0,               AUTH_ALGORITHM_AES_XCBC_MAC    },
-       {AUTH_AES_128_GMAC,      0,               AUTH_ALGORITHM_AES_128_GMAC    },
-       {AUTH_AES_192_GMAC,      0,               AUTH_ALGORITHM_AES_192_GMAC    },
-       {AUTH_AES_256_GMAC,      0,               AUTH_ALGORITHM_AES_256_GMAC    },
-};
-
-
-/**
- * Converts IKEv2 integrity to IKEv1 hash algorithm
- */
-int oakley_from_integrity_algorithm(integrity_algorithm_t alg)
-{
-       int i;
-       for (i = 0; i < countof(auth_map); i++)
-       {
-               if (auth_map[i].alg == alg)
-               {
-                       return auth_map[i].oakley;
-               }
-       }
-       return 0;
-}
-
-/**
- * Converts IKEv2 integrity to IKEv1 ESP authentication algorithm
- */
-int esp_from_integrity_algorithm(integrity_algorithm_t alg)
-{
-       int i;
-       for (i = 0; i < countof(auth_map); i++)
-       {
-               if (auth_map[i].alg == alg)
-               {
-                       return auth_map[i].esp;
-               }
-       }
-       return 0;
-}
-
-/**
- * Converts IKEv1 ESP authentication to IKEv2 integrity algorithm
- */
-integrity_algorithm_t integrity_algorithm_from_esp(int esp)
-{
-       int i;
-       for (i = 0; i < countof(auth_map); i++)
-       {
-               if (auth_map[i].esp == esp)
-               {
-                       return auth_map[i].alg;
-               }
-       }
-       return 0;
-}
-
diff --git a/src/pluto/crypto.h b/src/pluto/crypto.h
deleted file mode 100644 (file)
index 16ad127..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/* crypto interfaces
- *
- * Copyright (C) 2010 Tobias Brunner
- * Copyright (C) 2009 Andreas Steffen
- * Hochschule fuer Technik Rapperswil
- *
- * Copyright (C) 1998, 1999  D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <crypto/crypters/crypter.h>
-#include <crypto/signers/signer.h>
-#include <crypto/hashers/hasher.h>
-#include <crypto/prfs/prf.h>
-#include <credentials/keys/public_key.h>
-
-#include "ike_alg.h"
-
-extern bool init_crypto(void);
-extern void free_crypto(void);
-
-extern const struct dh_desc unset_group;      /* magic signifier */
-
-/* unification of cryptographic encoding/decoding algorithms
- * The IV is taken from and returned to st->st_new_iv.
- * This allows the old IV to be retained.
- * Use update_iv to commit to the new IV (for example, once a packet has
- * been validated).
- */
-
-#define MAX_OAKLEY_KEY_LEN0  (3 * DES_CBC_BLOCK_SIZE)
-#define MAX_OAKLEY_KEY_LEN  (256/BITS_PER_BYTE)
-
-struct state;   /* forward declaration, dammit */
-
-#define update_iv(st)   memcpy((st)->st_iv, (st)->st_new_iv \
-       , (st)->st_iv_len = (st)->st_new_iv_len)
-
-#define set_ph1_iv(st, iv) \
-       passert((st)->st_ph1_iv_len <= sizeof((st)->st_ph1_iv)); \
-       memcpy((st)->st_ph1_iv, (iv), (st)->st_ph1_iv_len);
-
-/* unification of cryptographic hashing mechanisms */
-
-extern encryption_algorithm_t oakley_to_encryption_algorithm(int alg);
-extern hash_algorithm_t oakley_to_hash_algorithm(int alg);
-extern pseudo_random_function_t oakley_to_prf(int alg);
-extern signature_scheme_t oakley_to_signature_scheme(int method);
-extern int oakley_from_encryption_algorithm(encryption_algorithm_t alg);
-extern int oakley_from_integrity_algorithm(integrity_algorithm_t alg);
-extern int esp_from_encryption_algorithm(encryption_algorithm_t alg);
-extern int esp_from_integrity_algorithm(integrity_algorithm_t alg);
-extern encryption_algorithm_t encryption_algorithm_from_esp(int esp);
-extern integrity_algorithm_t integrity_algorithm_from_esp(int esp);
-
diff --git a/src/pluto/db_ops.c b/src/pluto/db_ops.c
deleted file mode 100644 (file)
index 547ea5f..0000000
+++ /dev/null
@@ -1,412 +0,0 @@
-/* Dynamic db (proposal, transforms, attributes) handling.
- * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-/*
- * The stratedy is to have (full contained) struct db_prop in db_context
- * pointing to ONE dynamically sizable transform vector (trans0).
- * Each transform stores attrib. in ONE dyn. sizable attribute vector (attrs0)
- * in a "serialized" way (attributes storage is used in linear sequence for
- * subsecuent transforms).
- *
- * Resizing for both trans0 and attrs0 is supported:
- * - For trans0: quite simple, just allocate and copy trans. vector content
- *               also update trans_cur (by offset)
- * - For attrs0: after allocating and copying attrs, I must rewrite each
- *               trans->attrs present in trans0; to achieve this, calculate
- *               attrs pointer offset (new minus old) and iterate over
- *               each transform "adding" this difference.
- *               also update attrs_cur (by offset)
- *
- * db_context structure:
- *      +---------------------+
- *      |  prop               |
- *      |    .protoid         |
- *      |    .trans           | --+
- *      |    .trans_cnt       |   |
- *      +---------------------+ <-+
- *      |  trans0             | ----> { trans#1 | ... | trans#i | ...   }
- *      +---------------------+                       ^
- *      |  trans_cur          | ----------------------' current transf.
- *      +---------------------+
- *      |  attrs0             | ----> { attr#1 | ... | attr#j | ...  }
- *      +---------------------+                      ^
- *      |  attrs_cur          | ---------------------' current attr.
- *      +---------------------+
- *      | max_trans,max_attrs |  max_trans/attrs: number of elem. of each vector
- *      +---------------------+
- *
- * See testing examples at end for interface usage.
- */
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <malloc.h>
-#include <sys/types.h>
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "state.h"
-#include "packet.h"
-#include "spdb.h"
-#include "db_ops.h"
-#include "log.h"
-#include "whack.h"
-
-#include <assert.h>
-
-#ifdef NOT_YET
-/*
- *      Allocator cache:
- *      Because of the single-threaded nature of pluto/spdb.c,
- *      alloc()/free() is exercised many times with very small
- *      lifetime objects.
- *      Just caching last object (currently it will select the
- *      largest) will avoid this allocation mas^Wperturbations
- *
- */
-struct db_ops_alloc_cache {
-               void *ptr;
-               int size;
-};
-#endif
-
-#ifndef NO_DB_OPS_STATS
-/*
- *      stats: do account for allocations
- *      displayed in db_ops_show_status()
- */
-struct db_ops_stats {
-               int st_curr_cnt;        /* current number of allocations */
-               int st_total_cnt;       /* total allocations so far */
-               size_t st_maxsz;        /* max. size requested */
-};
-#define DB_OPS_ZERO { 0, 0, 0};
-#define DB_OPS_STATS_DESC   "{curr_cnt, total_cnt, maxsz}"
-#define DB_OPS_STATS_STR(name)  name "={%d,%d,%d} "
-#define DB_OPS_STATS_F(st) (st).st_curr_cnt, (st).st_total_cnt, (int)(st).st_maxsz
-static struct db_ops_stats db_context_st = DB_OPS_ZERO;
-static struct db_ops_stats db_trans_st = DB_OPS_ZERO;
-static struct db_ops_stats db_attrs_st = DB_OPS_ZERO;
-static __inline__ void *malloc_bytes_st(size_t size, struct db_ops_stats *st)
-{
-               void *ptr = malloc(size);
-               if (ptr)
-               {
-                               st->st_curr_cnt++;
-                               st->st_total_cnt++;
-                               if (size > st->st_maxsz) st->st_maxsz=size;
-               }
-               return ptr;
-}
-#define ALLOC_BYTES_ST(z,st) malloc_bytes_st(z, &st);
-#define PFREE_ST(p,st)         do { st.st_curr_cnt--; free(p);  } while (0);
-
-#else
-
-#define ALLOC_BYTES_ST(z,n) malloc(z);
-#define PFREE_ST(p,n)         free(p);
-
-#endif /* NO_DB_OPS_STATS */
-/*      Initialize db object
- *      max_trans and max_attrs can be 0, will be dynamically expanded
- *      as a result of "add" operations
- */
-int
-db_prop_init(struct db_context *ctx, u_int8_t protoid, int max_trans, int max_attrs)
-{
-               ctx->trans0 = NULL;
-               ctx->attrs0 = NULL;
-
-               if (max_trans > 0) { /* quite silly if not */
-                               ctx->trans0 = ALLOC_BYTES_ST ( sizeof(struct db_trans) * max_trans,
-                                                               db_trans_st);
-                               memset(ctx->trans0, '\0', sizeof(struct db_trans) * max_trans);
-               }
-
-               if (max_attrs > 0) { /* quite silly if not */
-                               ctx->attrs0 = ALLOC_BYTES_ST (sizeof(struct db_attr) * max_attrs,
-                                                               db_attrs_st);
-                               memset(ctx->attrs0, '\0', sizeof(struct db_attr) * max_attrs);
-               }
-
-               ctx->max_trans = max_trans;
-               ctx->max_attrs = max_attrs;
-               ctx->trans_cur = ctx->trans0;
-               ctx->attrs_cur = ctx->attrs0;
-               ctx->prop.protoid = protoid;
-               ctx->prop.trans = ctx->trans0;
-               ctx->prop.trans_cnt = 0;
-               return 0;
-}
-
-/*      Expand storage for transforms by number delta_trans */
-static int
-db_trans_expand(struct db_context *ctx, int delta_trans)
-{
-               int ret = -1;
-               struct db_trans *new_trans, *old_trans;
-               int max_trans = ctx->max_trans + delta_trans;
-               int offset;
-
-               old_trans = ctx->trans0;
-               new_trans = ALLOC_BYTES_ST ( sizeof (struct db_trans) * max_trans,
-                                               db_trans_st);
-               if (!new_trans)
-                               goto out;
-               memcpy(new_trans, old_trans, ctx->max_trans * sizeof(struct db_trans));
-
-               /* update trans0 (obviously) */
-               ctx->trans0 = ctx->prop.trans = new_trans;
-               /* update trans_cur (by offset) */
-               offset = (char *)(new_trans) - (char *)(old_trans);
-
-               {
-                 char *cctx = (char *)(ctx->trans_cur);
-
-                 cctx += offset;
-                 ctx->trans_cur = (struct db_trans *)cctx;
-               }
-               /* update elem count */
-               ctx->max_trans = max_trans;
-               PFREE_ST(old_trans, db_trans_st);
-               ret = 0;
-out:
-               return ret;
-}
-/*
- *      Expand storage for attributes by delta_attrs number AND
- *      rewrite trans->attr pointers
- */
-static int
-db_attrs_expand(struct db_context *ctx, int delta_attrs)
-{
-               int ret = -1;
-               struct db_attr *new_attrs, *old_attrs;
-               struct db_trans *t;
-               int ti;
-               int max_attrs = ctx->max_attrs + delta_attrs;
-               int offset;
-
-               old_attrs = ctx->attrs0;
-               new_attrs = ALLOC_BYTES_ST ( sizeof (struct db_attr) * max_attrs,
-                                               db_attrs_st);
-               if (!new_attrs)
-                               goto out;
-
-               memcpy(new_attrs, old_attrs, ctx->max_attrs * sizeof(struct db_attr));
-
-               /* update attrs0 and attrs_cur (obviously) */
-               offset = (char *)(new_attrs) - (char *)(old_attrs);
-
-               {
-                 char *actx = (char *)(ctx->attrs0);
-
-                 actx += offset;
-                 ctx->attrs0 = (struct db_attr *)actx;
-
-                 actx = (char *)ctx->attrs_cur;
-                 actx += offset;
-                 ctx->attrs_cur = (struct db_attr *)actx;
-               }
-
-               /* for each transform, rewrite attrs pointer by offsetting it */
-               for (t=ctx->prop.trans, ti=0; ti < ctx->prop.trans_cnt; t++, ti++) {
-                               char *actx = (char *)(t->attrs);
-
-                               actx += offset;
-                               t->attrs = (struct db_attr *)actx;
-               }
-               /* update elem count */
-               ctx->max_attrs = max_attrs;
-               PFREE_ST(old_attrs, db_attrs_st);
-               ret = 0;
-out:
-               return ret;
-}
-/*      Allocate a new db object */
-struct db_context *
-db_prop_new(u_int8_t protoid, int max_trans, int max_attrs)
-{
-               struct db_context *ctx;
-               ctx = ALLOC_BYTES_ST ( sizeof (struct db_context), db_context_st);
-               if (!ctx) goto out;
-
-               if (db_prop_init(ctx, protoid, max_trans, max_attrs) < 0) {
-                               PFREE_ST(ctx, db_context_st);
-                               ctx=NULL;
-               }
-out:
-               return ctx;
-}
-/*      Free a db object */
-void
-db_destroy(struct db_context *ctx)
-{
-               if (ctx->trans0) PFREE_ST(ctx->trans0, db_trans_st);
-               if (ctx->attrs0) PFREE_ST(ctx->attrs0, db_attrs_st);
-               PFREE_ST(ctx, db_context_st);
-}
-/*      Start a new transform, expand trans0 is needed */
-int
-db_trans_add(struct db_context *ctx, u_int8_t transid)
-{
-               /*      skip incrementing current trans pointer the 1st time*/
-               if (ctx->trans_cur && ctx->trans_cur->attr_cnt)
-                               ctx->trans_cur++;
-               /*
-                *      Strategy: if more space is needed, expand by
-                *                <current_size>/2 + 1
-                *
-                *      This happens to produce a "reasonable" sequence
-                *      after few allocations, eg.:
-                *      0,1,2,4,8,13,20,31,47
-                */
-               if ((ctx->trans_cur - ctx->trans0) >= ctx->max_trans) {
-                               /* XXX:jjo if fails should shout and flag it */
-                               if (db_trans_expand(ctx, ctx->max_trans/2 + 1)<0)
-                                               return -1;
-               }
-               ctx->trans_cur->transid = transid;
-               ctx->trans_cur->attrs=ctx->attrs_cur;
-               ctx->trans_cur->attr_cnt = 0;
-               ctx->prop.trans_cnt++;
-               return 0;
-}
-/*      Add attr copy to current transform, expanding attrs0 if needed */
-int
-db_attr_add(struct db_context *ctx, const struct db_attr *a)
-{
-               /*
-                *      Strategy: if more space is needed, expand by
-                *                <current_size>/2 + 1
-                */
-               if ((ctx->attrs_cur - ctx->attrs0) >= ctx->max_attrs) {
-                               /* XXX:jjo if fails should shout and flag it */
-                               if (db_attrs_expand(ctx, ctx->max_attrs/2 + 1) < 0)
-                                               return -1;
-               }
-               *ctx->attrs_cur++=*a;
-               ctx->trans_cur->attr_cnt++;
-               return 0;
-}
-/*      Add attr copy (by value) to current transform,
- *      expanding attrs0 if needed, just calls db_attr_add().
- */
-int
-db_attr_add_values(struct db_context *ctx,  u_int16_t type, u_int16_t val)
-{
-               struct db_attr attr;
-               attr.type = type;
-               attr.val = val;
-               return db_attr_add (ctx, &attr);
-}
-#ifndef NO_DB_OPS_STATS
-int
-db_ops_show_status(void)
-{
-               whack_log(RC_COMMENT, "stats " __FILE__ ": "
-                                               DB_OPS_STATS_DESC " :"
-                                               DB_OPS_STATS_STR("context")
-                                               DB_OPS_STATS_STR("trans")
-                                               DB_OPS_STATS_STR("attrs"),
-                                               DB_OPS_STATS_F(db_context_st),
-                                               DB_OPS_STATS_F(db_trans_st),
-                                               DB_OPS_STATS_F(db_attrs_st)
-                                               );
-               return 0;
-}
-#endif /* NO_DB_OPS_STATS */
-/*
- * From below to end just testing stuff ....
- */
-#ifdef TEST
-static void db_prop_print(struct db_prop *p)
-{
-               struct db_trans *t;
-               struct db_attr *a;
-               int ti, ai;
-               enum_names *n, *n_at, *n_av;
-               printf("protoid=\"%s\"\n", enum_name(&protocol_names, p->protoid));
-               for (ti=0, t=p->trans; ti< p->trans_cnt; ti++, t++) {
-                               switch( t->transid) {
-                                               case PROTO_ISAKMP:
-                                                               n=&isakmp_transformid_names;break;
-                                               case PROTO_IPSEC_ESP:
-                                                               n=&esp_transformid_names;break;
-                                               default:
-                                                               continue;
-                               }
-                               printf("  transid=\"%s\"\n",
-                                               enum_name(n, t->transid));
-                               for (ai=0, a=t->attrs; ai < t->attr_cnt; ai++, a++) {
-                                               int i;
-                                               switch( t->transid) {
-                                                               case PROTO_ISAKMP:
-                                                                               n_at=&oakley_attr_names;
-                                                                               i=a->type|ISAKMP_ATTR_AF_TV;
-                                                                               n_av=oakley_attr_val_descs[(i)&ISAKMP_ATTR_RTYPE_MASK];
-                                                                               break;
-                                                               case PROTO_IPSEC_ESP:
-                                                                               n_at=&ipsec_attr_names;
-                                                                               i=a->type|ISAKMP_ATTR_AF_TV;
-                                                                               n_av=ipsec_attr_val_descs[(i)&ISAKMP_ATTR_RTYPE_MASK];
-                                                                               break;
-                                                               default:
-                                                                               continue;
-                                               }
-                                               printf("    type=\"%s\" value=\"%s\"\n",
-                                                               enum_name(n_at, i),
-                                                               enum_name(n_av, a->val));
-                               }
-               }
-
-}
-static void db_print(struct db_context *ctx)
-{
-               printf("trans_cur diff=%d, attrs_cur diff=%d\n",
-                                               ctx->trans_cur - ctx->trans0,
-                                               ctx->attrs_cur - ctx->attrs0);
-               db_prop_print(&ctx->prop);
-}
-
-void
-passert_fail(const char *pred_str, const char *file_str, unsigned long line_no);
-void abort(void);
-void
-passert_fail(const char *pred_str, const char *file_str, unsigned long line_no)
-{
-       fprintf(stderr, "ASSERTION FAILED at %s:%lu: %s", file_str, line_no, pred_str);
-       abort();    /* exiting correctly doesn't always work */
-}
-int main(void) {
-               struct db_context *ctx=db_prop_new(PROTO_ISAKMP, 0, 0);
-               db_trans_add(ctx, KEY_IKE);
-               db_attr_add_values(ctx, OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC);
-               db_attr_add_values(ctx, OAKLEY_HASH_ALGORITHM, OAKLEY_MD5);
-               db_attr_add_values(ctx, OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_SIG);
-               db_attr_add_values(ctx, OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024);
-               db_trans_add(ctx, KEY_IKE);
-               db_attr_add_values(ctx, OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_AES_CBC);
-               db_attr_add_values(ctx, OAKLEY_HASH_ALGORITHM, OAKLEY_MD5);
-               db_attr_add_values(ctx, OAKLEY_AUTHENTICATION_METHOD, OAKLEY_PRESHARED_KEY);
-               db_attr_add_values(ctx, OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536);
-               db_trans_add(ctx, ESP_3DES);
-               db_attr_add_values(ctx, AUTH_ALGORITHM, AUTH_ALGORITHM_HMAC_SHA1);
-               db_print(ctx);
-               db_destroy(ctx);
-               return 0;
-}
-#endif
diff --git a/src/pluto/db_ops.h b/src/pluto/db_ops.h
deleted file mode 100644 (file)
index 464c245..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Dynamic db (proposal, transforms, attributes) handling.
- * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef _DB_OPS_H
-#define _DB_OPS_H
-
-/*
- *      Main db object, (quite proposal "oriented")
- */
-#ifndef NO_DB_CONTEXT
-struct db_context {
-               struct db_prop prop;            /* proposal buffer (not pointer) */
-               struct db_trans *trans0;        /* transf. list, dynamically sized */
-               struct db_trans *trans_cur;     /* current transform ptr */
-               struct db_attr *attrs0;         /* attr. list, dynamically sized */
-               struct db_attr *attrs_cur;      /* current attribute ptr */
-               int max_trans;                  /* size of trans list */
-               int max_attrs;                  /* size of attrs list */
-};
-/*
- *      Allocate a new db object
- */
-struct db_context * db_prop_new(u_int8_t protoid, int max_trans, int max_attrs);
-/*      Initialize object for proposal building  */
-int db_prop_init(struct db_context *ctx, u_int8_t protoid, int max_trans, int max_attrs);
-/*      Free all resourses for this db */
-void db_destroy(struct db_context *ctx);
-
-/*      Start a new transform */
-int db_trans_add(struct db_context *ctx, u_int8_t transid);
-/*      Add a new attribute by copying db_attr content */
-int db_attr_add(struct db_context *db_ctx, const struct db_attr *attr);
-/*      Add a new attribute by value */
-int db_attr_add_values(struct db_context *ctx,  u_int16_t type, u_int16_t val);
-
-/*      Get proposal from db object */
-static __inline__ struct db_prop *db_prop_get(struct db_context *ctx) {
-               return &ctx->prop;
-}
-/*      Show stats (allocation, etc) */
-#endif /* NO_DB_CONTEXT */
-int db_ops_show_status(void);
-#endif /* _DB_OPS_H */
diff --git a/src/pluto/defs.c b/src/pluto/defs.c
deleted file mode 100644 (file)
index 7f3a819..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/* misc. universal things
- * Copyright (C) 1998-2001  D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <dirent.h>
-#include <inttypes.h>
-#include <time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "whack.h"      /* for RC_LOG_SERIOUS */
-
-bool
-all_zero(const unsigned char *m, size_t len)
-{
-       size_t i;
-
-       for (i = 0; i != len; i++)
-               if (m[i] != '\0')
-                       return FALSE;
-       return TRUE;
-}
-
-/*  Note that there may be as many as six IDs that are temporary at
- *  one time before unsharing the two ends of a connection. So we need
- *  at least six temporary buffers for DER_ASN1_DN IDs.
- *  We rotate them. Be careful!
- */
-#define MAX_BUF         10
-
-char*
-temporary_cyclic_buffer(void)
-{
-       static char buf[MAX_BUF][BUF_LEN];  /* MAX_BUF internal buffers */
-       static int counter = 0;                     /* cyclic counter */
-
-       if (++counter == MAX_BUF) counter = 0;      /* next internal buffer */
-       return buf[counter];                        /* assign temporary buffer */
-}
-
-/* concatenates two sub paths into a string with a maximum size of BUF_LEN
- * use for temporary storage only
- */
-char* concatenate_paths(char *a, char *b)
-{
-       char *c;
-
-       if (*b == '/' || *b == '.')
-               return b;
-
-       c = temporary_cyclic_buffer();
-       snprintf(c, BUF_LEN, "%s/%s", a, b);
-       return c;
-}
-
-/* moves a chunk to a memory position, chunk is freed afterwards
- * position pointer is advanced after the insertion point
- */
-void
-mv_chunk(u_char **pos, chunk_t content)
-{
-       if (content.len > 0)
-       {
-               chunkcpy(*pos, content);
-               free(content.ptr);
-       }
-}
-
-/*  checks if the expiration date has been reached and
- *  warns during the warning_interval of the imminent
- *  expiry. strict=TRUE declares a fatal error,
- *  strict=FALSE issues a warning upon expiry.
- */
-const char*
-check_expiry(time_t expiration_date, int warning_interval, bool strict)
-{
-       time_t now, time_left;
-
-       if (expiration_date == UNDEFINED_TIME)
-         return "ok (expires never)";
-
-       /* determine the current time */
-       time(&now);
-
-       time_left = (expiration_date - now);
-       if (time_left < 0)
-               return strict? "fatal (expired)" : "warning (expired)";
-
-       if (time_left > 86400*warning_interval)
-               return "ok";
-       {
-               static char buf[35]; /* temporary storage */
-               const char* unit = "second";
-
-               if (time_left > 172800)
-               {
-                       time_left /= 86400;
-                       unit = "day";
-               }
-               else if (time_left > 7200)
-               {
-                       time_left /= 3600;
-                       unit = "hour";
-               }
-               else if (time_left > 120)
-               {
-                       time_left /= 60;
-                       unit = "minute";
-               }
-               snprintf(buf, 35, "warning (expires in %" PRIu64 " %s%s)",
-                                (u_int64_t)time_left, unit, (time_left == 1) ? "" : "s");
-               return buf;
-       }
-}
-
-
-/*
- *  Filter eliminating the directory entries '.' and '..'
- */
-int
-file_select(const struct dirent *entry)
-{
-       return strcmp(entry->d_name, "." ) &&
-                  strcmp(entry->d_name, "..");
-}
-
-
diff --git a/src/pluto/defs.h b/src/pluto/defs.h
deleted file mode 100644 (file)
index 532652e..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/* misc. universal things
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2001  D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef _DEFS_H
-#define _DEFS_H
-
-#include <string.h>
-#include <sys/types.h>
-
-#include <chunk.h>
-
-#ifdef DEBUG
-# define USED_BY_DEBUG  /* ignore */
-#else
-# define USED_BY_DEBUG  UNUSED
-#endif
-
-/* type of serial number of a state object
- * Needed in connections.h and state.h; here to simplify dependencies.
- */
-typedef unsigned long so_serial_t;
-#define SOS_NOBODY      0       /* null serial number */
-#define SOS_FIRST       1       /* first normal serial number */
-
-/* memory allocation */
-
-#define clone_thing(orig) clalloc((void *)&(orig), sizeof(orig))
-
-#define clone_str(str) \
-       ((str) == NULL? NULL : strdup(str))
-
-#define replace(p, q) \
-       { free(p); (p) = (q); }
-
-#define chunkcpy(dst, chunk) \
-       { memcpy(dst, chunk.ptr, chunk.len); dst += chunk.len;}
-
-extern char* temporary_cyclic_buffer(void);
-extern char* concatenate_paths(char *a, char *b);
-
-/* move a chunk to a memory position and free it after insertion */
-extern void mv_chunk(u_char **pos, chunk_t content);
-
-/* warns a predefined interval before expiry */
-extern const char* check_expiry(time_t expiration_date,
-       int warning_interval, bool strict);
-
-#define MAX_PROMPT_PASS_TRIALS  5
-#define PROMPT_PASS_LEN         64
-
-/* filter eliminating the directory entries '.' and '..' */
-typedef struct dirent dirent_t;
-extern int file_select(const dirent_t *entry);
-
-/* cleanly exit Pluto */
-extern void exit_pluto(int /*status*/) NEVER_RETURNS;
-
-/* zero all bytes */
-#define zero(x) memset((x), '\0', sizeof(*(x)))
-
-/* are all bytes 0? */
-extern bool all_zero(const unsigned char *m, size_t len);
-
-/* pad_up(n, m) is the amount to add to n to make it a multiple of m */
-#define pad_up(n, m) (((m) - 1) - (((n) + (m) - 1) % (m)))
-
-#endif /* _DEFS_H */
diff --git a/src/pluto/demux.c b/src/pluto/demux.c
deleted file mode 100644 (file)
index 612e081..0000000
+++ /dev/null
@@ -1,2527 +0,0 @@
-/* demultiplex incoming IKE messages
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2002  D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-/* Ordering Constraints on Payloads
- *
- * rfc2409: The Internet Key Exchange (IKE)
- *
- * 5 Exchanges:
- *   "The SA payload MUST precede all other payloads in a phase 1 exchange."
- *
- *   "Except where otherwise noted, there are no requirements for ISAKMP
- *    payloads in any message to be in any particular order."
- *
- * 5.3 Phase 1 Authenticated With a Revised Mode of Public Key Encryption:
- *
- *   "If the HASH payload is sent it MUST be the first payload of the
- *    second message exchange and MUST be followed by the encrypted
- *    nonce. If the HASH payload is not sent, the first payload of the
- *    second message exchange MUST be the encrypted nonce."
- *
- *   "Save the requirements on the location of the optional HASH payload
- *    and the mandatory nonce payload there are no further payload
- *    requirements. All payloads-- in whatever order-- following the
- *    encrypted nonce MUST be encrypted with Ke_i or Ke_r depending on the
- *    direction."
- *
- * 5.5 Phase 2 - Quick Mode
- *
- *   "In Quick Mode, a HASH payload MUST immediately follow the ISAKMP
- *    header and a SA payload MUST immediately follow the HASH."
- *   [NOTE: there may be more than one SA payload, so this is not
- *    totally reasonable.  Probably all SAs should be so constrained.]
- *
- *   "If ISAKMP is acting as a client negotiator on behalf of another
- *    party, the identities of the parties MUST be passed as IDci and
- *    then IDcr."
- *
- *   "With the exception of the HASH, SA, and the optional ID payloads,
- *    there are no payload ordering restrictions on Quick Mode."
- */
-
-/* Unfolding of Identity -- a central mystery
- *
- * This concerns Phase 1 identities, those of the IKE hosts.
- * These are the only ones that are authenticated.  Phase 2
- * identities are for IPsec SAs.
- *
- * There are three case of interest:
- *
- * (1) We initiate, based on a whack command specifying a Connection.
- *     We know the identity of the peer from the Connection.
- *
- * (2) (to be implemented) we initiate based on a flow from our client
- *     to some IP address.
- *     We immediately know one of the peer's client IP addresses from
- *     the flow.  We must use this to figure out the peer's IP address
- *     and Id.  To be solved.
- *
- * (3) We respond to an IKE negotiation.
- *     We immediately know the peer's IP address.
- *     We get an ID Payload in Main I2.
- *
- *     Unfortunately, this is too late for a number of things:
- *     - the ISAKMP SA proposals have already been made (Main I1)
- *       AND one accepted (Main R1)
- *     - the SA includes a specification of the type of ID
- *       authentication so this is negotiated without being told the ID.
- *     - with Preshared Key authentication, Main I2 is encrypted
- *       using the key, so it cannot be decoded to reveal the ID
- *       without knowing (or guessing) which key to use.
- *
- *     There are three reasonable choices here for the responder:
- *     + assume that the initiator is making wise offers since it
- *       knows the IDs involved.  We can balk later (but not gracefully)
- *       when we find the actual initiator ID
- *     + attempt to infer identity by IP address.  Again, we can balk
- *       when the true identity is revealed.  Actually, it is enough
- *       to infer properties of the identity (eg. SA properties and
- *       PSK, if needed).
- *     + make all properties universal so discrimination based on
- *       identity isn't required.  For example, always accept the same
- *       kinds of encryption.  Accept Public Key Id authentication
- *       since the Initiator presumably has our public key and thinks
- *       we must have / can find his.  This approach is weakest
- *       for preshared key since the actual key must be known to
- *       decrypt the Initiator's ID Payload.
- *     These choices can be blended.  For example, a class of Identities
- *     can be inferred, sufficient to select a preshared key but not
- *     sufficient to infer a unique identity.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/time.h>   /* only used for belt-and-suspenders select call */
-#include <sys/poll.h>   /* only used for forensic poll call */
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/queue.h>
-
-#if defined(IP_RECVERR) && defined(MSG_ERRQUEUE)
-#  include <asm/types.h>        /* for __u8, __u32 */
-#  include <linux/errqueue.h>
-#  include <sys/uio.h>  /* struct iovec */
-#endif
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "cookie.h"
-#include "connections.h"
-#include "state.h"
-#include "packet.h"
-#include "crypto.h"
-#include "ike_alg.h"
-#include "log.h"
-#include "demux.h"      /* needs packet.h */
-#include "ipsec_doi.h"  /* needs demux.h and state.h */
-#include "timer.h"
-#include "whack.h"      /* requires connections.h */
-#include "server.h"
-#include "nat_traversal.h"
-#include "vendor.h"
-#include "modecfg.h"
-
-/* This file does basic header checking and demux of
- * incoming packets.
- */
-
-/* forward declarations */
-static bool read_packet(struct msg_digest *md);
-static void process_packet(struct msg_digest **mdp);
-
-/* Reply messages are built in this buffer.
- * Only one state transition function can be using it at a time
- * so suspended STFs must save and restore it.
- * It could be an auto variable of complete_state_transition except for the fact
- * that when a suspended STF resumes, its reply message buffer
- * must be at the same location -- there are pointers into it.
- */
-u_int8_t reply_buffer[MAX_OUTPUT_UDP_SIZE];
-
-/* state_microcode is a tuple of information parameterizing certain
- * centralized processing of a packet.  For example, it roughly
- * specifies what payloads are expected in this message.
- * The microcode is selected primarily based on the state.
- * In Phase 1, the payload structure often depends on the
- * authentication technique, so that too plays a part in selecting
- * the state_microcode to use.
- */
-
-struct state_microcode {
-       enum state_kind state, next_state;
-       lset_t flags;
-       lset_t req_payloads;        /* required payloads (allows just one) */
-       lset_t opt_payloads;        /* optional payloads (any mumber) */
-       /* if not ISAKMP_NEXT_NONE, process_packet will emit HDR with this as np */
-       u_int8_t first_out_payload;
-       enum event_type timeout_event;
-       state_transition_fn *processor;
-};
-
-/* State Microcode Flags, in several groups */
-
-/* Oakley Auth values: to which auth values does this entry apply?
- * Most entries will use SMF_ALL_AUTH because they apply to all.
- * Note: SMF_ALL_AUTH matches 0 for those circumstances when no auth
- * has been set.
- */
-#define SMF_ALL_AUTH    LRANGE(0, OAKLEY_AUTH_ROOF-1)
-#define SMF_PSK_AUTH    LELEM(OAKLEY_PRESHARED_KEY)
-#define SMF_DS_AUTH     (LELEM(OAKLEY_DSS_SIG)   | LELEM(OAKLEY_RSA_SIG)   | \
-                                                LELEM(OAKLEY_ECDSA_SIG) | LELEM(OAKLEY_ECDSA_256) | \
-                                                LELEM(OAKLEY_ECDSA_384) | LELEM(OAKLEY_ECDSA_521))
-#define SMF_PKE_AUTH    (LELEM(OAKLEY_RSA_ENC) | LELEM(OAKLEY_ELGAMAL_ENC))
-#define SMF_RPKE_AUTH   (LELEM(OAKLEY_RSA_ENC_REV) | LELEM(OAKLEY_ELGAMAL_ENC_REV))
-
-/* misc flags */
-
-#define SMF_INITIATOR   LELEM(OAKLEY_AUTH_ROOF + 0)
-#define SMF_FIRST_ENCRYPTED_INPUT       LELEM(OAKLEY_AUTH_ROOF + 1)
-#define SMF_INPUT_ENCRYPTED     LELEM(OAKLEY_AUTH_ROOF + 2)
-#define SMF_OUTPUT_ENCRYPTED    LELEM(OAKLEY_AUTH_ROOF + 3)
-#define SMF_RETRANSMIT_ON_DUPLICATE     LELEM(OAKLEY_AUTH_ROOF + 4)
-
-#define SMF_ENCRYPTED (SMF_INPUT_ENCRYPTED | SMF_OUTPUT_ENCRYPTED)
-
-/* this state generates a reply message */
-#define SMF_REPLY   LELEM(OAKLEY_AUTH_ROOF + 5)
-
-/* this state completes P1, so any pending P2 negotiations should start */
-#define SMF_RELEASE_PENDING_P2  LELEM(OAKLEY_AUTH_ROOF + 6)
-
-/* end of flags */
-
-
-static state_transition_fn      /* forward declaration */
-       unexpected,
-       informational;
-
-/* state_microcode_table is a table of all state_microcode tuples.
- * It must be in order of state (the first element).
- * After initialization, ike_microcode_index[s] points to the
- * first entry in state_microcode_table for state s.
- * Remember that each state name in Main or Quick Mode describes
- * what has happened in the past, not what this message is.
- */
-
-static const struct state_microcode
-       *ike_microcode_index[STATE_IKE_ROOF - STATE_IKE_FLOOR];
-
-static const struct state_microcode state_microcode_table[] = {
-#define PT(n) ISAKMP_NEXT_##n
-#define P(n) LELEM(PT(n))
-
-       /***** Phase 1 Main Mode *****/
-
-       /* No state for main_outI1: --> HDR, SA */
-
-       /* STATE_MAIN_R0: I1 --> R1
-        * HDR, SA --> HDR, SA
-        */
-       { STATE_MAIN_R0, STATE_MAIN_R1
-       , SMF_ALL_AUTH | SMF_REPLY
-       , P(SA), P(VID) | P(CR), PT(NONE)
-       , EVENT_RETRANSMIT, main_inI1_outR1},
-
-       /* STATE_MAIN_I1: R1 --> I2
-        * HDR, SA --> auth dependent
-        * SMF_PSK_AUTH, SMF_DS_AUTH: --> HDR, KE, Ni
-        * SMF_PKE_AUTH:
-        *  --> HDR, KE, [ HASH(1), ] <IDi1_b>PubKey_r, <Ni_b>PubKey_r
-        * SMF_RPKE_AUTH:
-        *  --> HDR, [ HASH(1), ] <Ni_b>Pubkey_r, <KE_b>Ke_i, <IDi1_b>Ke_i [,<<Cert-I_b>Ke_i]
-        * Note: since we don't know auth at start, we cannot differentiate
-        * microcode entries based on it.
-        */
-       { STATE_MAIN_I1, STATE_MAIN_I2
-       , SMF_ALL_AUTH | SMF_INITIATOR | SMF_REPLY
-       , P(SA), P(VID) | P(CR), PT(NONE) /* don't know yet */
-       , EVENT_RETRANSMIT, main_inR1_outI2 },
-
-       /* STATE_MAIN_R1: I2 --> R2
-        * SMF_PSK_AUTH, SMF_DS_AUTH: HDR, KE, Ni --> HDR, KE, Nr
-        * SMF_PKE_AUTH: HDR, KE, [ HASH(1), ] <IDi1_b>PubKey_r, <Ni_b>PubKey_r
-        *      --> HDR, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i
-        * SMF_RPKE_AUTH:
-        *      HDR, [ HASH(1), ] <Ni_b>Pubkey_r, <KE_b>Ke_i, <IDi1_b>Ke_i [,<<Cert-I_b>Ke_i]
-        *      --> HDR, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDr1_b>Ke_r
-        */
-       { STATE_MAIN_R1, STATE_MAIN_R2
-       , SMF_PSK_AUTH | SMF_DS_AUTH | SMF_REPLY
-       , P(KE) | P(NONCE), P(VID) | P(CR) | P(NATD_RFC), PT(KE)
-       , EVENT_RETRANSMIT, main_inI2_outR2 },
-
-       { STATE_MAIN_R1, STATE_UNDEFINED
-       , SMF_PKE_AUTH | SMF_REPLY
-       , P(KE) | P(ID) | P(NONCE), P(VID) | P(CR) | P(HASH), PT(KE)
-       , EVENT_RETRANSMIT, unexpected /* ??? not yet implemented */ },
-
-       { STATE_MAIN_R1, STATE_UNDEFINED
-       , SMF_RPKE_AUTH | SMF_REPLY
-       , P(NONCE) | P(KE) | P(ID), P(VID) | P(CR) | P(HASH) | P(CERT), PT(NONCE)
-       , EVENT_RETRANSMIT, unexpected /* ??? not yet implemented */ },
-
-       /* for states from here on, output message must be encrypted */
-
-       /* STATE_MAIN_I2: R2 --> I3
-        * SMF_PSK_AUTH: HDR, KE, Nr --> HDR*, IDi1, HASH_I
-        * SMF_DS_AUTH: HDR, KE, Nr --> HDR*, IDi1, [ CERT, ] SIG_I
-        * SMF_PKE_AUTH: HDR, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i
-        *      --> HDR*, HASH_I
-        * SMF_RPKE_AUTH: HDR, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDr1_b>Ke_r
-        *      --> HDR*, HASH_I
-        */
-       { STATE_MAIN_I2, STATE_MAIN_I3
-       , SMF_PSK_AUTH | SMF_DS_AUTH | SMF_INITIATOR | SMF_OUTPUT_ENCRYPTED | SMF_REPLY
-       , P(KE) | P(NONCE), P(VID) | P(CR) | P(NATD_RFC), PT(ID)
-       , EVENT_RETRANSMIT, main_inR2_outI3 },
-
-       { STATE_MAIN_I2, STATE_UNDEFINED
-       , SMF_PKE_AUTH | SMF_INITIATOR | SMF_OUTPUT_ENCRYPTED | SMF_REPLY
-       , P(KE) | P(ID) | P(NONCE), P(VID) | P(CR), PT(HASH)
-       , EVENT_RETRANSMIT, unexpected /* ??? not yet implemented */ },
-
-       { STATE_MAIN_I2, STATE_UNDEFINED
-       , SMF_ALL_AUTH | SMF_INITIATOR | SMF_OUTPUT_ENCRYPTED | SMF_REPLY
-       , P(NONCE) | P(KE) | P(ID), P(VID) | P(CR), PT(HASH)
-       , EVENT_RETRANSMIT, unexpected /* ??? not yet implemented */ },
-
-       /* for states from here on, input message must be encrypted */
-
-       /* STATE_MAIN_R2: I3 --> R3
-        * SMF_PSK_AUTH: HDR*, IDi1, HASH_I --> HDR*, IDr1, HASH_R
-        * SMF_DS_AUTH: HDR*, IDi1, [ CERT, ] SIG_I --> HDR*, IDr1, [ CERT, ] SIG_R
-        * SMF_PKE_AUTH, SMF_RPKE_AUTH: HDR*, HASH_I --> HDR*, HASH_R
-        */
-       { STATE_MAIN_R2, STATE_MAIN_R3
-       , SMF_PSK_AUTH | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED
-         | SMF_REPLY | SMF_RELEASE_PENDING_P2
-       , P(ID) | P(HASH), P(VID) | P(CR), PT(NONE)
-       , EVENT_SA_REPLACE, main_inI3_outR3 },
-
-       { STATE_MAIN_R2, STATE_MAIN_R3
-       , SMF_DS_AUTH | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED
-         | SMF_REPLY | SMF_RELEASE_PENDING_P2
-       , P(ID) | P(SIG), P(VID) | P(CR) | P(CERT), PT(NONE)
-       , EVENT_SA_REPLACE, main_inI3_outR3 },
-
-       { STATE_MAIN_R2, STATE_UNDEFINED
-       , SMF_PKE_AUTH | SMF_RPKE_AUTH | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED
-         | SMF_REPLY | SMF_RELEASE_PENDING_P2
-       , P(HASH), P(VID) | P(CR), PT(NONE)
-       , EVENT_SA_REPLACE, unexpected /* ??? not yet implemented */ },
-
-       /* STATE_MAIN_I3: R3 --> done
-        * SMF_PSK_AUTH: HDR*, IDr1, HASH_R --> done
-        * SMF_DS_AUTH: HDR*, IDr1, [ CERT, ] SIG_R --> done
-        * SMF_PKE_AUTH, SMF_RPKE_AUTH: HDR*, HASH_R --> done
-        * May initiate quick mode by calling quick_outI1
-        */
-       { STATE_MAIN_I3, STATE_MAIN_I4
-       , SMF_PSK_AUTH | SMF_INITIATOR
-         | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2
-       , P(ID) | P(HASH), P(VID) | P(CR), PT(NONE)
-       , EVENT_SA_REPLACE, main_inR3 },
-
-       { STATE_MAIN_I3, STATE_MAIN_I4
-       , SMF_DS_AUTH | SMF_INITIATOR
-         | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2
-       , P(ID) | P(SIG), P(VID) | P(CR) | P(CERT), PT(NONE)
-       , EVENT_SA_REPLACE, main_inR3 },
-
-       { STATE_MAIN_I3, STATE_UNDEFINED
-       , SMF_PKE_AUTH | SMF_RPKE_AUTH | SMF_INITIATOR
-         | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2
-       , P(HASH), P(VID) | P(CR), PT(NONE)
-       , EVENT_SA_REPLACE, unexpected /* ??? not yet implemented */ },
-
-       /* STATE_MAIN_R3: can only get here due to packet loss */
-       { STATE_MAIN_R3, STATE_UNDEFINED
-       , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_RETRANSMIT_ON_DUPLICATE
-       , LEMPTY, LEMPTY
-       , PT(NONE), EVENT_NULL, unexpected },
-
-       /* STATE_MAIN_I4: can only get here due to packet loss */
-       { STATE_MAIN_I4, STATE_UNDEFINED
-       , SMF_ALL_AUTH | SMF_INITIATOR | SMF_ENCRYPTED
-       , LEMPTY, LEMPTY
-       , PT(NONE), EVENT_NULL, unexpected },
-
-
-       /***** Phase 2 Quick Mode *****/
-
-       /* No state for quick_outI1:
-        * --> HDR*, HASH(1), SA, Nr [, KE ] [, IDci, IDcr ]
-        */
-
-       /* STATE_QUICK_R0:
-        * HDR*, HASH(1), SA, Ni [, KE ] [, IDci, IDcr ] -->
-        * HDR*, HASH(2), SA, Nr [, KE ] [, IDci, IDcr ]
-        * Installs inbound IPsec SAs.
-        * Because it may suspend for asynchronous DNS, first_out_payload
-        * is set to NONE to suppress early emission of HDR*.
-        * ??? it is legal to have multiple SAs, but we don't support it yet.
-        */
-       { STATE_QUICK_R0, STATE_QUICK_R1
-       , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY
-       , P(HASH) | P(SA) | P(NONCE), /* P(SA) | */ P(KE) | P(ID) | P(NATOA_RFC), PT(NONE)
-       , EVENT_RETRANSMIT, quick_inI1_outR1 },
-
-       /* STATE_QUICK_I1:
-        * HDR*, HASH(2), SA, Nr [, KE ] [, IDci, IDcr ] -->
-        * HDR*, HASH(3)
-        * Installs inbound and outbound IPsec SAs, routing, etc.
-        * ??? it is legal to have multiple SAs, but we don't support it yet.
-        */
-       { STATE_QUICK_I1, STATE_QUICK_I2
-       , SMF_ALL_AUTH | SMF_INITIATOR | SMF_ENCRYPTED | SMF_REPLY
-       , P(HASH) | P(SA) | P(NONCE), /* P(SA) | */ P(KE) | P(ID) | P(NATOA_RFC), PT(HASH)
-       , EVENT_SA_REPLACE, quick_inR1_outI2 },
-
-       /* STATE_QUICK_R1: HDR*, HASH(3) --> done
-        * Installs outbound IPsec SAs, routing, etc.
-        */
-       { STATE_QUICK_R1, STATE_QUICK_R2
-       , SMF_ALL_AUTH | SMF_ENCRYPTED
-       , P(HASH), LEMPTY, PT(NONE)
-       , EVENT_SA_REPLACE, quick_inI2 },
-
-       /* STATE_QUICK_I2: can only happen due to lost packet */
-       { STATE_QUICK_I2, STATE_UNDEFINED
-       , SMF_ALL_AUTH | SMF_INITIATOR | SMF_ENCRYPTED | SMF_RETRANSMIT_ON_DUPLICATE
-       , LEMPTY, LEMPTY, PT(NONE)
-       , EVENT_NULL, unexpected },
-
-       /* STATE_QUICK_R2: can only happen due to lost packet */
-       { STATE_QUICK_R2, STATE_UNDEFINED
-       , SMF_ALL_AUTH | SMF_ENCRYPTED
-       , LEMPTY, LEMPTY, PT(NONE)
-       , EVENT_NULL, unexpected },
-
-
-       /***** informational messages *****/
-
-       /* STATE_INFO: */
-       { STATE_INFO, STATE_UNDEFINED
-       , SMF_ALL_AUTH
-       , LEMPTY, LEMPTY, PT(NONE)
-       , EVENT_NULL, informational },
-
-       /* STATE_INFO_PROTECTED: */
-       { STATE_INFO_PROTECTED, STATE_UNDEFINED
-       , SMF_ALL_AUTH | SMF_ENCRYPTED
-       , P(HASH), LEMPTY, PT(NONE)
-       , EVENT_NULL, informational },
-
-       /* XAUTH state transitions */
-       { STATE_XAUTH_I0, STATE_XAUTH_I1
-       , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY
-       , P(ATTR) | P(HASH), P(VID), PT(HASH)
-       , EVENT_RETRANSMIT, xauth_inI0 },
-
-       { STATE_XAUTH_R1, STATE_XAUTH_R2
-       , SMF_ALL_AUTH | SMF_ENCRYPTED
-       , P(ATTR) | P(HASH), P(VID), PT(HASH)
-       , EVENT_RETRANSMIT, xauth_inR1 },
-
-       { STATE_XAUTH_I1, STATE_XAUTH_I2
-       , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY | SMF_RELEASE_PENDING_P2
-       , P(ATTR) | P(HASH), P(VID), PT(HASH)
-       , EVENT_SA_REPLACE, xauth_inI1 },
-
-       { STATE_XAUTH_R2, STATE_XAUTH_R3
-       , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2
-       , P(ATTR) | P(HASH), P(VID), PT(NONE)
-       , EVENT_SA_REPLACE, xauth_inR2 },
-
-       { STATE_XAUTH_I2, STATE_UNDEFINED
-       , SMF_ALL_AUTH | SMF_ENCRYPTED
-       , LEMPTY, LEMPTY, PT(NONE)
-       , EVENT_NULL, unexpected },
-
-       { STATE_XAUTH_R3, STATE_UNDEFINED
-       , SMF_ALL_AUTH | SMF_ENCRYPTED
-       , LEMPTY, LEMPTY, PT(NONE)
-       , EVENT_NULL, unexpected },
-
-       /* ModeCfg pull mode state transitions */
-
-       { STATE_MODE_CFG_R0, STATE_MODE_CFG_R1
-       , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY | SMF_RELEASE_PENDING_P2
-       , P(ATTR) | P(HASH), P(VID), PT(HASH)
-       , EVENT_SA_REPLACE, modecfg_inR0 },
-
-       { STATE_MODE_CFG_I1, STATE_MODE_CFG_I2
-       , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2
-       , P(ATTR) | P(HASH), P(VID), PT(HASH)
-       , EVENT_SA_REPLACE, modecfg_inI1 },
-
-       { STATE_MODE_CFG_R1, STATE_UNDEFINED
-       , SMF_ALL_AUTH | SMF_ENCRYPTED
-       , LEMPTY, LEMPTY, PT(NONE)
-       , EVENT_NULL, unexpected },
-
-       { STATE_MODE_CFG_I2, STATE_UNDEFINED
-       , SMF_ALL_AUTH | SMF_ENCRYPTED
-       , LEMPTY, LEMPTY, PT(NONE)
-       , EVENT_NULL, unexpected },
-
-   /* ModeCfg push mode state transitions */
-
-       { STATE_MODE_CFG_I0, STATE_MODE_CFG_I3
-       , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY | SMF_RELEASE_PENDING_P2
-       , P(ATTR) | P(HASH), P(VID), PT(HASH)
-       , EVENT_SA_REPLACE, modecfg_inI0 },
-
-       { STATE_MODE_CFG_R3, STATE_MODE_CFG_R4
-       , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2
-       , P(ATTR) | P(HASH), P(VID), PT(HASH)
-       , EVENT_SA_REPLACE, modecfg_inR3 },
-
-       { STATE_MODE_CFG_I3, STATE_UNDEFINED
-       , SMF_ALL_AUTH | SMF_ENCRYPTED
-       , LEMPTY, LEMPTY, PT(NONE)
-       , EVENT_NULL, unexpected },
-
-       { STATE_MODE_CFG_R4, STATE_UNDEFINED
-       , SMF_ALL_AUTH | SMF_ENCRYPTED
-       , LEMPTY, LEMPTY, PT(NONE)
-       , EVENT_NULL, unexpected },
-
-#undef P
-#undef PT
-};
-
-void
-init_demux(void)
-{
-       /* fill ike_microcode_index:
-        * make ike_microcode_index[s] point to first entry in
-        * state_microcode_table for state s (backward scan makes this easier).
-        * Check that table is in order -- catch coding errors.
-        * For what it's worth, this routine is idempotent.
-        */
-       const struct state_microcode *t;
-
-       for (t = &state_microcode_table[countof(state_microcode_table) - 1];;)
-       {
-               passert(STATE_IKE_FLOOR <= t->state && t->state < STATE_IKE_ROOF);
-               ike_microcode_index[t->state - STATE_IKE_FLOOR] = t;
-               if (t == state_microcode_table)
-                       break;
-               t--;
-               passert(t[0].state <= t[1].state);
-       }
-}
-
-/* Process any message on the MSG_ERRQUEUE
- *
- * This information is generated because of the IP_RECVERR socket option.
- * The API is sparsely documented, and may be LINUX-only, and only on
- * fairly recent versions at that (hence the conditional compilation).
- *
- * - ip(7) describes IP_RECVERR
- * - recvmsg(2) describes MSG_ERRQUEUE
- * - readv(2) describes iovec
- * - cmsg(3) describes how to process auxiliary messages
- *
- * ??? we should link this message with one we've sent
- * so that the diagnostic can refer to that negotiation.
- *
- * ??? how long can the messge be?
- *
- * ??? poll(2) has a very incomplete description of the POLL* events.
- * We assume that POLLIN, POLLOUT, and POLLERR are all we need to deal with
- * and that POLLERR will be on iff there is a MSG_ERRQUEUE message.
- *
- * We have to code around a couple of surprises:
- *
- * - Select can say that a socket is ready to read from, and
- *   yet a read will hang.  It turns out that a message available on the
- *   MSG_ERRQUEUE will cause select to say something is pending, but
- *   a normal read will hang.  poll(2) can tell when a MSG_ERRQUEUE
- *   message is pending.
- *
- *   This is dealt with by calling check_msg_errqueue after select
- *   has indicated that there is something to read, but before the
- *   read is performed.  check_msg_errqueue will return TRUE if there
- *   is something left to read.
- *
- * - A write to a socket may fail because there is a pending MSG_ERRQUEUE
- *   message, without there being anything wrong with the write.  This
- *   makes for confusing diagnostics.
- *
- *   To avoid this, we call check_msg_errqueue before a write.  True,
- *   there is a race condition (a MSG_ERRQUEUE message might arrive
- *   between the check and the write), but we should eliminate many
- *   of the problematic events.  To narrow the window, the poll(2)
- *   will await until an event happens (in the case or a write,
- *   POLLOUT; this should be benign for POLLIN).
- */
-
-#if defined(IP_RECVERR) && defined(MSG_ERRQUEUE)
-static bool
-check_msg_errqueue(const struct iface *ifp, short interest)
-{
-       struct pollfd pfd;
-
-       pfd.fd = ifp->fd;
-       pfd.events = interest | POLLPRI | POLLOUT;
-
-       while (pfd.revents = 0
-       , poll(&pfd, 1, -1) > 0 && (pfd.revents & POLLERR))
-       {
-               u_int8_t buffer[3000];  /* hope that this is big enough */
-               union
-               {
-                       struct sockaddr sa;
-                       struct sockaddr_in sa_in4;
-                       struct sockaddr_in6 sa_in6;
-               } from;
-
-               int from_len = sizeof(from);
-
-               int packet_len;
-
-               struct msghdr emh;
-               struct iovec eiov;
-               union {
-                       /* force alignment (not documented as necessary) */
-                       struct cmsghdr ecms;
-
-                       /* how much space is enough? */
-                       unsigned char space[256];
-               } ecms_buf;
-
-               struct cmsghdr *cm;
-               char fromstr[sizeof(" for message to  port 65536") + INET6_ADDRSTRLEN];
-               struct state *sender = NULL;
-
-               zero(&from.sa);
-               from_len = sizeof(from);
-
-               emh.msg_name = &from.sa;        /* ??? filled in? */
-               emh.msg_namelen = sizeof(from);
-               emh.msg_iov = &eiov;
-               emh.msg_iovlen = 1;
-               emh.msg_control = &ecms_buf;
-               emh.msg_controllen = sizeof(ecms_buf);
-               emh.msg_flags = 0;
-
-               eiov.iov_base = buffer; /* see readv(2) */
-               eiov.iov_len = sizeof(buffer);
-
-               packet_len = recvmsg(ifp->fd, &emh, MSG_ERRQUEUE);
-
-               if (packet_len == -1)
-               {
-                       log_errno((e, "recvmsg(,, MSG_ERRQUEUE) on %s failed in comm_handle"
-                               , ifp->rname));
-                       break;
-               }
-               else if (packet_len == sizeof(buffer))
-               {
-                       plog("MSG_ERRQUEUE message longer than %lu bytes; truncated"
-                               , (unsigned long) sizeof(buffer));
-               }
-               else
-               {
-                       sender = find_sender((size_t) packet_len, buffer);
-               }
-
-               DBG_cond_dump(DBG_ALL, "rejected packet:\n", buffer, packet_len);
-               DBG_cond_dump(DBG_ALL, "control:\n", emh.msg_control, emh.msg_controllen);
-               /* ??? Andi Kleen <ak@suse.de> and misc documentation
-                * suggests that name will have the original destination
-                * of the packet.  We seem to see msg_namelen == 0.
-                * Andi says that this is a kernel bug and has fixed it.
-                * Perhaps in 2.2.18/2.4.0.
-                */
-               passert(emh.msg_name == &from.sa);
-               DBG_cond_dump(DBG_ALL, "name:\n", emh.msg_name
-                       , emh.msg_namelen);
-
-               fromstr[0] = '\0';      /* usual case :-( */
-               switch (from.sa.sa_family)
-               {
-               char as[INET6_ADDRSTRLEN];
-
-               case AF_INET:
-                       if (emh.msg_namelen == sizeof(struct sockaddr_in))
-                               snprintf(fromstr, sizeof(fromstr)
-                               , " for message to %s port %u"
-                                       , inet_ntop(from.sa.sa_family
-                                       , &from.sa_in4.sin_addr, as, sizeof(as))
-                                       , ntohs(from.sa_in4.sin_port));
-                       break;
-               case AF_INET6:
-                       if (emh.msg_namelen == sizeof(struct sockaddr_in6))
-                               snprintf(fromstr, sizeof(fromstr)
-                                       , " for message to %s port %u"
-                                       , inet_ntop(from.sa.sa_family
-                                       , &from.sa_in6.sin6_addr, as, sizeof(as))
-                                       , ntohs(from.sa_in6.sin6_port));
-                       break;
-               }
-
-               for (cm = CMSG_FIRSTHDR(&emh)
-               ; cm != NULL
-               ; cm = CMSG_NXTHDR(&emh,cm))
-               {
-                       if (cm->cmsg_level == SOL_IP
-                       && cm->cmsg_type == IP_RECVERR)
-                       {
-                               /* ip(7) and recvmsg(2) specify:
-                                * ee_origin is SO_EE_ORIGIN_ICMP for ICMP
-                                *  or SO_EE_ORIGIN_LOCAL for locally generated errors.
-                                * ee_type and ee_code are from the ICMP header.
-                                * ee_info is the discovered MTU for EMSGSIZE errors
-                                * ee_data is not used.
-                                *
-                                * ??? recvmsg(2) says "SOCK_EE_OFFENDER" but
-                                * means "SO_EE_OFFENDER".  The OFFENDER is really
-                                * the router that complained.  As such, the port
-                                * is meaningless.
-                                */
-
-                               /* ??? cmsg(3) claims that CMSG_DATA returns
-                                * void *, but RFC 2292 and /usr/include/bits/socket.h
-                                * say unsigned char *.  The manual is being fixed.
-                                */
-                               struct sock_extended_err *ee = (void *)CMSG_DATA(cm);
-                               const char *offstr = "unspecified";
-                               char offstrspace[INET6_ADDRSTRLEN];
-                               char orname[50];
-
-                               if (cm->cmsg_len > CMSG_LEN(sizeof(struct sock_extended_err)))
-                               {
-                                       const struct sockaddr *offender = SO_EE_OFFENDER(ee);
-
-                                       switch (offender->sa_family)
-                                       {
-                                       case AF_INET:
-                                               offstr = inet_ntop(offender->sa_family
-                                                       , &((const struct sockaddr_in *)offender)->sin_addr
-                                                       , offstrspace, sizeof(offstrspace));
-                                               break;
-                                       case AF_INET6:
-                                               offstr = inet_ntop(offender->sa_family
-                                                       , &((const struct sockaddr_in6 *)offender)->sin6_addr
-                                                       , offstrspace, sizeof(offstrspace));
-                                               break;
-                                       default:
-                                               offstr = "unknown";
-                                               break;
-                                       }
-                               }
-
-                               switch (ee->ee_origin)
-                               {
-                               case SO_EE_ORIGIN_NONE:
-                                       snprintf(orname, sizeof(orname), "none");
-                                       break;
-                               case SO_EE_ORIGIN_LOCAL:
-                                       snprintf(orname, sizeof(orname), "local");
-                                       break;
-                               case SO_EE_ORIGIN_ICMP:
-                                       snprintf(orname, sizeof(orname)
-                                               , "ICMP type %d code %d (not authenticated)"
-                                               , ee->ee_type, ee->ee_code
-                                               );
-                                       break;
-                               case SO_EE_ORIGIN_ICMP6:
-                                       snprintf(orname, sizeof(orname)
-                                               , "ICMP6 type %d code %d (not authenticated)"
-                                               , ee->ee_type, ee->ee_code
-                                               );
-                                       break;
-                               default:
-                                       snprintf(orname, sizeof(orname), "invalid origin %lu"
-                                               , (unsigned long) ee->ee_origin);
-                                       break;
-                               }
-
-                               {
-                                       struct state *old_state = cur_state;
-
-                                       cur_state = sender;
-
-                                       /* note dirty trick to suppress ~ at start of format
-                                        * if we know what state to blame.
-                                        */
-                                       if ((packet_len == 1) && (buffer[0] == 0xff)
-#ifdef DEBUG
-                                               && ((cur_debugging & DBG_NATT) == 0)
-#endif
-                                               ) {
-                                                       /* don't log NAT-T keepalive related errors unless NATT debug is
-                                                        * enabled
-                                                        */
-                                       }
-                                       else
-                                       plog((sender != NULL) + "~"
-                                               "ERROR: asynchronous network error report on %s"
-                                               "%s"
-                                               ", complainant %s"
-                                               ": %s"
-                                               " [errno %lu, origin %s"
-                                               /* ", pad %d, info %ld" */
-                                               /* ", data %ld" */
-                                               "]"
-                                               , ifp->rname
-                                               , fromstr
-                                               , offstr
-                                               , strerror(ee->ee_errno)
-                                               , (unsigned long) ee->ee_errno
-                                               , orname
-                                               /* , ee->ee_pad, (unsigned long)ee->ee_info */
-                                               /* , (unsigned long)ee->ee_data */
-                                               );
-                                       cur_state = old_state;
-                               }
-                       }
-                       else
-                       {
-                               /* .cmsg_len is a kernel_size_t(!), but the value
-                                * certainly ought to fit in an unsigned long.
-                                */
-                               plog("unknown cmsg: level %d, type %d, len %lu"
-                                       , cm->cmsg_level, cm->cmsg_type
-                                       , (unsigned long) cm->cmsg_len);
-                       }
-               }
-       }
-       return (pfd.revents & interest) != 0;
-}
-#endif /* defined(IP_RECVERR) && defined(MSG_ERRQUEUE) */
-
-bool
-send_packet(struct state *st, const char *where)
-{
-       connection_t *c = st->st_connection;
-       int port_buf;
-       bool err;
-       u_int8_t ike_pkt[MAX_OUTPUT_UDP_SIZE];
-       u_int8_t *ptr;
-       unsigned long len;
-
-       if (c->interface->ike_float && st->st_tpacket.len != 1)
-       {
-               if ((unsigned long) st->st_tpacket.len > (MAX_OUTPUT_UDP_SIZE-sizeof(u_int32_t)))
-               {
-                       DBG_log("send_packet(): really too big");
-                       return FALSE;
-               }
-               ptr = ike_pkt;
-               /** Add Non-ESP marker **/
-               memset(ike_pkt, 0, sizeof(u_int32_t));
-               memcpy(ike_pkt + sizeof(u_int32_t), st->st_tpacket.ptr,
-                       (unsigned long)st->st_tpacket.len);
-               len = (unsigned long) st->st_tpacket.len + sizeof(u_int32_t);
-       }
-       else
-       {
-               ptr = st->st_tpacket.ptr;
-               len = (unsigned long) st->st_tpacket.len;
-       }
-
-       DBG(DBG_RAW,
-               {
-                       DBG_log("sending %lu bytes for %s through %s to %s:%u:"
-                               , (unsigned long) st->st_tpacket.len
-                               , where
-                               , c->interface->rname
-                               , ip_str(&c->spd.that.host_addr)
-                               , (unsigned)c->spd.that.host_port);
-                       DBG_dump_chunk(NULL, st->st_tpacket);
-               });
-
-       /* XXX: Not very clean.  We manipulate the port of the ip_address to
-        * have a port in the sockaddr*, but we retain the original port
-        * and restore it afterwards.
-        */
-
-       port_buf = portof(&c->spd.that.host_addr);
-       setportof(htons(c->spd.that.host_port), &c->spd.that.host_addr);
-
-#if defined(IP_RECVERR) && defined(MSG_ERRQUEUE)
-       (void) check_msg_errqueue(c->interface, POLLOUT);
-#endif /* defined(IP_RECVERR) && defined(MSG_ERRQUEUE) */
-
-       err = sendto(c->interface->fd
-               , ptr, len, 0
-               , sockaddrof(&c->spd.that.host_addr)
-               , sockaddrlenof(&c->spd.that.host_addr)) != (ssize_t)len;
-
-       /* restore port */
-       setportof(port_buf, &c->spd.that.host_addr);
-
-       if (err)
-       {
-          /* do not log NAT-T Keep Alive packets */
-               if (streq(where, "NAT-T Keep Alive"))
-                       return FALSE;
-               log_errno((e, "sendto on %s to %s:%u failed in %s"
-                       , c->interface->rname
-                       , ip_str(&c->spd.that.host_addr)
-                       , (unsigned)c->spd.that.host_port
-                       , where));
-               return FALSE;
-       }
-       else
-       {
-               return TRUE;
-       }
-}
-
-static stf_status
-unexpected(struct msg_digest *md)
-{
-       loglog(RC_LOG_SERIOUS, "unexpected message received in state %s"
-               , enum_name(&state_names, md->st->st_state));
-       return STF_IGNORE;
-}
-
-static stf_status
-informational(struct msg_digest *md UNUSED)
-{
-       struct payload_digest *const n_pld = md->chain[ISAKMP_NEXT_N];
-
-       /* If the Notification Payload is not null... */
-       if (n_pld != NULL)
-       {
-               pb_stream *const n_pbs = &n_pld->pbs;
-               struct isakmp_notification *const n = &n_pld->payload.notification;
-               int disp_len;
-               char disp_buf[200];
-
-               /* Switch on Notification Type (enum) */
-               switch (n->isan_type)
-               {
-               case R_U_THERE:
-                       return dpd_inI_outR(md->st, n, n_pbs);
-
-               case R_U_THERE_ACK:
-                       return dpd_inR(md->st, n, n_pbs);
-               default:
-                       if (pbs_left(n_pbs) >= sizeof(disp_buf)-1)
-                               disp_len = sizeof(disp_buf)-1;
-                       else
-                               disp_len = pbs_left(n_pbs);
-                       memcpy(disp_buf, n_pbs->cur, disp_len);
-                       disp_buf[disp_len] = '\0';
-                       break;
-               }
-       }
-       return STF_IGNORE;
-}
-
-/* message digest allocation and deallocation */
-
-static struct msg_digest *md_pool = NULL;
-
-/* free_md_pool is only used to avoid leak reports */
-void
-free_md_pool(void)
-{
-       for (;;)
-       {
-               struct msg_digest *md = md_pool;
-
-               if (md == NULL)
-                       break;
-               md_pool = md->next;
-               free(md);
-       }
-}
-
-static struct msg_digest *
-malloc_md(void)
-{
-       struct msg_digest *md = md_pool;
-
-       /* convenient initializer:
-        * - all pointers NULL
-        * - .note = NOTHING_WRONG
-        * - .encrypted = FALSE
-        */
-       static const struct msg_digest blank_md = {
-               .next = NULL,
-       };
-
-       if (md == NULL)
-       {
-               md = malloc_thing(struct msg_digest);
-               zero(md);
-       }
-       else
-               md_pool = md->next;
-
-       *md = blank_md;
-       md->digest_roof = md->digest;
-
-       /* note: although there may be multiple msg_digests at once
-        * (due to suspended state transitions), there is a single
-        * global reply_buffer.  It will need to be saved and restored.
-        */
-       init_pbs(&md->reply, reply_buffer, sizeof(reply_buffer), "reply packet");
-
-       return md;
-}
-
-void
-release_md(struct msg_digest *md)
-{
-       chunk_free(&md->raw_packet);
-       free(md->packet_pbs.start);
-       md->packet_pbs.start = NULL;
-       md->next = md_pool;
-       md_pool = md;
-}
-
-/* wrapper for read_packet and process_packet
- *
- * The main purpose of this wrapper is to factor out teardown code
- * from the many return points in process_packet.  This amounts to
- * releasing the msg_digest and resetting global variables.
- *
- * When processing of a packet is suspended (STF_SUSPEND),
- * process_packet sets md to NULL to prevent the msg_digest being freed.
- * Someone else must ensure that msg_digest is freed eventually.
- *
- * read_packet is broken out to minimize the lifetime of the
- * enormous input packet buffer, an auto.
- */
-void
-comm_handle(const struct iface *ifp)
-{
-       static struct msg_digest *md;
-
-#if defined(IP_RECVERR) && defined(MSG_ERRQUEUE)
-       /* Even though select(2) says that there is a message,
-        * it might only be a MSG_ERRQUEUE message.  At least
-        * sometimes that leads to a hanging recvfrom.  To avoid
-        * what appears to be a kernel bug, check_msg_errqueue
-        * uses poll(2) and tells us if there is anything for us
-        * to read.
-        *
-        * This is early enough that teardown isn't required:
-        * just return on failure.
-        */
-       if (!check_msg_errqueue(ifp, POLLIN))
-               return; /* no normal message to read */
-#endif /* defined(IP_RECVERR) && defined(MSG_ERRQUEUE) */
-
-       md = malloc_md();
-       md->iface = ifp;
-
-       if (read_packet(md))
-               process_packet(&md);
-
-       if (md != NULL)
-               release_md(md);
-
-       cur_state = NULL;
-       reset_cur_connection();
-       cur_from = NULL;
-}
-
-/* read the message.
- * Since we don't know its size, we read it into
- * an overly large buffer and then copy it to a
- * new, properly sized buffer.
- */
-static bool
-read_packet(struct msg_digest *md)
-{
-       const struct iface *ifp = md->iface;
-       int packet_len;
-       u_int8_t *buffer;
-       u_int8_t *buffer_nat;
-       union
-       {
-               struct sockaddr sa;
-               struct sockaddr_in sa_in4;
-               struct sockaddr_in6 sa_in6;
-       } from;
-       int from_len = sizeof(from);
-       err_t from_ugh = NULL;
-       static const char undisclosed[] = "unknown source";
-
-       happy(anyaddr(addrtypeof(&ifp->addr), &md->sender));
-       zero(&from.sa);
-       ioctl(ifp->fd, FIONREAD, &packet_len);
-       buffer = malloc(packet_len);
-       packet_len = recvfrom(ifp->fd, buffer, packet_len, 0
-               , &from.sa, &from_len);
-
-       /* First: digest the from address.
-        * We presume that nothing here disturbs errno.
-        */
-       if (packet_len == -1
-       && from_len == sizeof(from)
-       && all_zero((const void *)&from.sa, sizeof(from)))
-       {
-               /* "from" is untouched -- not set by recvfrom */
-               from_ugh = undisclosed;
-       }
-       else if (from_len
-       < (int) (offsetof(struct sockaddr, sa_family) + sizeof(from.sa.sa_family)))
-       {
-               from_ugh = "truncated";
-       }
-       else
-       {
-               const struct af_info *afi = aftoinfo(from.sa.sa_family);
-
-               if (afi == NULL)
-               {
-                       from_ugh = "unexpected Address Family";
-               }
-               else if (from_len != (int)afi->sa_sz)
-               {
-                       from_ugh = "wrong length";
-               }
-               else
-               {
-                       switch (from.sa.sa_family)
-                       {
-                       case AF_INET:
-                               from_ugh = initaddr((void *) &from.sa_in4.sin_addr
-                                       , sizeof(from.sa_in4.sin_addr), AF_INET, &md->sender);
-                               md->sender_port = ntohs(from.sa_in4.sin_port);
-                               break;
-                       case AF_INET6:
-                               from_ugh = initaddr((void *) &from.sa_in6.sin6_addr
-                                       , sizeof(from.sa_in6.sin6_addr), AF_INET6, &md->sender);
-                               md->sender_port = ntohs(from.sa_in6.sin6_port);
-                               break;
-                       }
-               }
-       }
-
-       /* now we report any actual I/O error */
-       if (packet_len == -1)
-       {
-               if (from_ugh == undisclosed
-               && errno == ECONNREFUSED)
-               {
-                       /* Tone down scary message for vague event:
-                        * We get "connection refused" in response to some
-                        * datagram we sent, but we cannot tell which one.
-                        */
-                       plog("some IKE message we sent has been rejected with ECONNREFUSED (kernel supplied no details)");
-               }
-               else if (from_ugh != NULL)
-               {
-                       log_errno((e, "recvfrom on %s failed; Pluto cannot decode source sockaddr in rejection: %s"
-                               , ifp->rname, from_ugh));
-               }
-               else
-               {
-                       log_errno((e, "recvfrom on %s from %s:%u failed"
-                               , ifp->rname
-                               , ip_str(&md->sender), (unsigned)md->sender_port));
-               }
-               free(buffer);
-               return FALSE;
-       }
-       else if (from_ugh != NULL)
-       {
-               plog("recvfrom on %s returned malformed source sockaddr: %s"
-                       , ifp->rname, from_ugh);
-               free(buffer);
-               return FALSE;
-       }
-       cur_from = &md->sender;
-       cur_from_port = md->sender_port;
-
-       if (ifp->ike_float == TRUE)
-       {
-               u_int32_t non_esp;
-
-               if (packet_len < (int)sizeof(u_int32_t))
-               {
-                       plog("recvfrom %s:%u too small packet (%d)"
-                               , ip_str(cur_from), (unsigned) cur_from_port, packet_len);
-                       free(buffer);
-                       return FALSE;
-               }
-               memcpy(&non_esp, buffer, sizeof(u_int32_t));
-               if (non_esp != 0)
-               {
-                       plog("recvfrom %s:%u has no Non-ESP marker"
-                               , ip_str(cur_from), (unsigned) cur_from_port);
-                       free(buffer);
-                       return FALSE;
-               }
-               packet_len -= sizeof(u_int32_t);
-               buffer_nat = malloc(packet_len);
-               memcpy(buffer_nat, buffer + sizeof(u_int32_t), packet_len);
-               free(buffer);
-               buffer = buffer_nat;
-       }
-
-       /* Clone actual message contents
-        * and set up md->packet_pbs to describe it.
-        */
-       init_pbs(&md->packet_pbs, buffer, packet_len, "packet");
-
-       DBG(DBG_RAW | DBG_CRYPT | DBG_PARSING | DBG_CONTROL,
-               {
-                       DBG_log(BLANK_FORMAT);
-                       DBG_log("*received %d bytes from %s:%u on %s"
-                               , (int) pbs_room(&md->packet_pbs)
-                               , ip_str(cur_from), (unsigned) cur_from_port
-                               , ifp->rname);
-               });
-
-       DBG(DBG_RAW,
-               DBG_dump("", md->packet_pbs.start, pbs_room(&md->packet_pbs)));
-
-               if ((pbs_room(&md->packet_pbs)==1) && (md->packet_pbs.start[0]==0xff))
-               {
-                       /**
-                        * NAT-T Keep-alive packets should be discarded by kernel ESPinUDP
-                        * layer. But bogus keep-alive packets (sent with a non-esp marker)
-                        * can reach this point. Complain and discard them.
-                        */
-                       DBG(DBG_NATT,
-                               DBG_log("NAT-T keep-alive (bogus ?) should not reach this point. "
-                                               "Ignored. Sender: %s:%u", ip_str(cur_from),
-                                               (unsigned) cur_from_port);
-                       )
-                       return FALSE;
-               }
-
-#define IKEV2_VERSION_OFFSET    17
-#define IKEV2_VERSION           0x20
-
-       /* ignore IKEv2 packets - they will be handled by charon */
-       if (pbs_room(&md->packet_pbs) > IKEV2_VERSION_OFFSET
-       &&  (md->packet_pbs.start[IKEV2_VERSION_OFFSET] & 0xF0) == IKEV2_VERSION)
-       {
-               DBG(DBG_CONTROLMORE,
-                       DBG_log("  ignoring IKEv2 packet")
-               )
-               return FALSE;
-       }
-
-       return TRUE;
-}
-
-/* process an input packet, possibly generating a reply.
- *
- * If all goes well, this routine eventually calls a state-specific
- * transition function.
- */
-static void
-process_packet(struct msg_digest **mdp)
-{
-       struct msg_digest *md = *mdp;
-       const struct state_microcode *smc;
-       bool new_iv_set = FALSE;
-       bool restore_iv = FALSE;
-       u_char new_iv[MAX_DIGEST_LEN];
-       u_int new_iv_len = 0;
-
-       struct state *st = NULL;
-       enum state_kind from_state = STATE_UNDEFINED;       /* state we started in */
-
-#define SEND_NOTIFICATION(t) { \
-       if (st) send_notification_from_state(st, from_state, t); \
-       else send_notification_from_md(md, t); }
-
-       if (!in_struct(&md->hdr, &isakmp_hdr_desc, &md->packet_pbs, &md->message_pbs))
-       {
-               /* Identify specific failures:
-                * - bad ISAKMP major/minor version numbers
-                */
-               if (md->packet_pbs.roof - md->packet_pbs.cur >= (ptrdiff_t)isakmp_hdr_desc.size)
-               {
-                       struct isakmp_hdr *hdr = (struct isakmp_hdr *)md->packet_pbs.cur;
-                       if ((hdr->isa_version >> ISA_MAJ_SHIFT) != ISAKMP_MAJOR_VERSION)
-                       {
-                               SEND_NOTIFICATION(ISAKMP_INVALID_MAJOR_VERSION);
-                               return;
-                       }
-                       else if ((hdr->isa_version & ISA_MIN_MASK) != ISAKMP_MINOR_VERSION)
-                       {
-                               SEND_NOTIFICATION(ISAKMP_INVALID_MINOR_VERSION);
-                               return;
-                       }
-               }
-               SEND_NOTIFICATION(ISAKMP_PAYLOAD_MALFORMED);
-               return;
-       }
-
-       if (md->packet_pbs.roof != md->message_pbs.roof)
-       {
-               plog("size (%u) differs from size specified in ISAKMP HDR (%u)"
-                       , (unsigned) pbs_room(&md->packet_pbs), md->hdr.isa_length);
-#ifdef CISCO_QUIRKS
-               if (pbs_room(&md->packet_pbs) - md->hdr.isa_length == 16)
-                       plog("Cisco VPN client appends 16 surplus NULL bytes");
-               else
-#endif
-               return;
-       }
-
-       switch (md->hdr.isa_xchg)
-       {
-#ifdef NOTYET
-       case ISAKMP_XCHG_NONE:
-       case ISAKMP_XCHG_BASE:
-#endif
-
-       case ISAKMP_XCHG_IDPROT:    /* part of a Main Mode exchange */
-               if (md->hdr.isa_msgid != MAINMODE_MSGID)
-               {
-                       plog("Message ID was 0x%08lx but should be zero in Main Mode",
-                               (unsigned long) md->hdr.isa_msgid);
-                       SEND_NOTIFICATION(ISAKMP_INVALID_MESSAGE_ID);
-                       return;
-               }
-
-               if (is_zero_cookie(md->hdr.isa_icookie))
-               {
-                       plog("Initiator Cookie must not be zero in Main Mode message");
-                       SEND_NOTIFICATION(ISAKMP_INVALID_COOKIE);
-                       return;
-               }
-
-               if (is_zero_cookie(md->hdr.isa_rcookie))
-               {
-                       /* initial message from initiator
-                        * ??? what if this is a duplicate of another message?
-                        */
-                       if (md->hdr.isa_flags & ISAKMP_FLAG_ENCRYPTION)
-                       {
-                               plog("initial Main Mode message is invalid:"
-                                       " its Encrypted Flag is on");
-                               SEND_NOTIFICATION(ISAKMP_INVALID_FLAGS);
-                               return;
-                       }
-
-                       /* don't build a state until the message looks tasty */
-                       from_state = STATE_MAIN_R0;
-               }
-               else
-               {
-                       /* not an initial message */
-
-                       st = find_state(md->hdr.isa_icookie, md->hdr.isa_rcookie
-                               , &md->sender, md->hdr.isa_msgid);
-
-                       if (st == NULL)
-                       {
-                               /* perhaps this is a first message from the responder
-                                * and contains a responder cookie that we've not yet seen.
-                                */
-                               st = find_state(md->hdr.isa_icookie, zero_cookie
-                                       , &md->sender, md->hdr.isa_msgid);
-
-                               if (st == NULL)
-                               {
-                                       plog("Main Mode message is part of an unknown exchange");
-                                       /* XXX Could send notification back */
-                                       return;
-                               }
-                       }
-                       set_cur_state(st);
-                       from_state = st->st_state;
-               }
-               break;
-
-#ifdef NOTYET
-       case ISAKMP_XCHG_AO:
-       case ISAKMP_XCHG_AGGR:
-#endif
-
-       case ISAKMP_XCHG_INFO:      /* an informational exchange */
-               st = find_state(md->hdr.isa_icookie, md->hdr.isa_rcookie
-                       , &md->sender, MAINMODE_MSGID);
-
-               if (st != NULL)
-                       set_cur_state(st);
-
-               if (md->hdr.isa_flags & ISAKMP_FLAG_ENCRYPTION)
-               {
-                       if (st == NULL)
-                       {
-                               plog("Informational Exchange is for an unknown (expired?) SA");
-                               /* XXX Could send notification back */
-                               return;
-                       }
-
-                       if (!IS_ISAKMP_ENCRYPTED(st->st_state))
-                       {
-                               loglog(RC_LOG_SERIOUS, "encrypted Informational Exchange message is invalid"
-                                       " because no key is known");
-                               /* XXX Could send notification back */
-                               return;
-                       }
-
-                       if (md->hdr.isa_msgid == MAINMODE_MSGID)
-                       {
-                               loglog(RC_LOG_SERIOUS, "Informational Exchange message is invalid because"
-                                       " it has a Message ID of 0");
-                               /* XXX Could send notification back */
-                               return;
-                       }
-
-                       if (!reserve_msgid(st, md->hdr.isa_msgid))
-                       {
-                               loglog(RC_LOG_SERIOUS, "Informational Exchange message is invalid because"
-                                       " it has a previously used Message ID (0x%08lx)"
-                                       , (unsigned long)md->hdr.isa_msgid);
-                               /* XXX Could send notification back */
-                               return;
-                       }
-
-                       if (!IS_ISAKMP_SA_ESTABLISHED(st->st_state))
-                       {
-                               memcpy(st->st_ph1_iv, st->st_new_iv, st->st_new_iv_len);
-                               st->st_ph1_iv_len = st->st_new_iv_len;
-
-                               /* backup new_iv */
-                               new_iv_len = st->st_new_iv_len;
-                               passert(new_iv_len <= MAX_DIGEST_LEN)
-                               memcpy(new_iv, st->st_new_iv, new_iv_len);
-                               restore_iv = TRUE;
-                       }
-                       init_phase2_iv(st, &md->hdr.isa_msgid);
-                       new_iv_set = TRUE;
-
-                       from_state = STATE_INFO_PROTECTED;
-               }
-               else
-               {
-                       if (st != NULL && IS_ISAKMP_ENCRYPTED(st->st_state))
-                       {
-                               loglog(RC_LOG_SERIOUS, "Informational Exchange message"
-                                       " must be encrypted");
-                               /* XXX Could send notification back */
-                               return;
-                       }
-                       from_state = STATE_INFO;
-               }
-               break;
-
-       case ISAKMP_XCHG_QUICK:     /* part of a Quick Mode exchange */
-               if (is_zero_cookie(md->hdr.isa_icookie))
-               {
-                       plog("Quick Mode message is invalid because"
-                               " it has an Initiator Cookie of 0");
-                       SEND_NOTIFICATION(ISAKMP_INVALID_COOKIE);
-                       return;
-               }
-
-               if (is_zero_cookie(md->hdr.isa_rcookie))
-               {
-                       plog("Quick Mode message is invalid because"
-                               " it has a Responder Cookie of 0");
-                       SEND_NOTIFICATION(ISAKMP_INVALID_COOKIE);
-                       return;
-               }
-
-               if (md->hdr.isa_msgid == MAINMODE_MSGID)
-               {
-                       plog("Quick Mode message is invalid because"
-                               " it has a Message ID of 0");
-                       SEND_NOTIFICATION(ISAKMP_INVALID_MESSAGE_ID);
-                       return;
-               }
-
-               st = find_state(md->hdr.isa_icookie, md->hdr.isa_rcookie
-                       , &md->sender, md->hdr.isa_msgid);
-
-               if (st == NULL)
-               {
-                       /* No appropriate Quick Mode state.
-                        * See if we have a Main Mode state.
-                        * ??? what if this is a duplicate of another message?
-                        */
-                       st = find_state(md->hdr.isa_icookie, md->hdr.isa_rcookie
-                               , &md->sender, MAINMODE_MSGID);
-
-                       if (st == NULL)
-                       {
-                               plog("Quick Mode message is for a non-existent (expired?)"
-                                       " ISAKMP SA");
-                               /* XXX Could send notification back */
-                               return;
-                       }
-
-                       set_cur_state(st);
-
-                       if (!IS_ISAKMP_SA_ESTABLISHED(st->st_state))
-                       {
-                               loglog(RC_LOG_SERIOUS, "Quick Mode message is unacceptable because"
-                                       " it is for an incomplete ISAKMP SA");
-                               SEND_NOTIFICATION(ISAKMP_PAYLOAD_MALFORMED /* XXX ? */);
-                               return;
-                       }
-
-                       /* only accept this new Quick Mode exchange if it has a unique message ID */
-                       if (!reserve_msgid(st, md->hdr.isa_msgid))
-                       {
-                               loglog(RC_LOG_SERIOUS, "Quick Mode I1 message is unacceptable because"
-                                       " it uses a previously used Message ID 0x%08lx"
-                                       " (perhaps this is a duplicated packet)"
-                                       , (unsigned long) md->hdr.isa_msgid);
-                               SEND_NOTIFICATION(ISAKMP_INVALID_MESSAGE_ID);
-                               return;
-                       }
-
-                       /* Quick Mode Initial IV */
-                       init_phase2_iv(st, &md->hdr.isa_msgid);
-                       new_iv_set = TRUE;
-
-                       from_state = STATE_QUICK_R0;
-               }
-               else
-               {
-                       set_cur_state(st);
-                       from_state = st->st_state;
-               }
-
-               break;
-
-       case ISAKMP_XCHG_MODE_CFG:
-               if (is_zero_cookie(md->hdr.isa_icookie))
-               {
-                       plog("ModeCfg message is invalid because"
-                               " it has an Initiator Cookie of 0");
-                       /* XXX Could send notification back */
-                       return;
-               }
-
-               if (is_zero_cookie(md->hdr.isa_rcookie))
-               {
-                       plog("ModeCfg message is invalid because"
-                               " it has a Responder Cookie of 0");
-                       /* XXX Could send notification back */
-                       return;
-               }
-
-               if (md->hdr.isa_msgid == 0)
-               {
-                       plog("ModeCfg message is invalid because"
-                               " it has a Message ID of 0");
-                       /* XXX Could send notification back */
-                       return;
-               }
-
-               st = find_state(md->hdr.isa_icookie, md->hdr.isa_rcookie
-                                               , &md->sender, md->hdr.isa_msgid);
-
-               if (st == NULL)
-               {
-                       bool has_xauth_policy;
-
-                       /* No appropriate ModeCfg state.
-                        * See if we have a Main Mode state.
-                        * ??? what if this is a duplicate of another message?
-                        */
-                       st = find_state(md->hdr.isa_icookie, md->hdr.isa_rcookie
-                                                       , &md->sender, 0);
-
-                       if (st == NULL)
-                       {
-                               plog("ModeCfg message is for a non-existent (expired?)"
-                                       " ISAKMP SA");
-                               /* XXX Could send notification back */
-                               return;
-                       }
-
-                       set_cur_state(st);
-
-                       /* the XAUTH_STATUS message might have a new msgid */
-                       if (st->st_state == STATE_XAUTH_I1)
-                       {
-                               init_phase2_iv(st, &md->hdr.isa_msgid);
-                               new_iv_set = TRUE;
-                               from_state = st->st_state;
-                               break;
-                       }
-
-                       if (!IS_ISAKMP_SA_ESTABLISHED(st->st_state))
-                       {
-                               loglog(RC_LOG_SERIOUS, "ModeCfg message is unacceptable because"
-                                               " it is for an incomplete ISAKMP SA (state=%s)"
-                                               , enum_name(&state_names, st->st_state));
-                               /* XXX Could send notification back */
-                               return;
-                       }
-                       init_phase2_iv(st, &md->hdr.isa_msgid);
-                       new_iv_set = TRUE;
-
-                       /*
-                        * okay, now we have to figure out if we are receiving a bogus
-                        * new message in an outstanding XAUTH server conversation
-                        * (i.e. a reply to our challenge)
-                        * (this occurs with some broken other implementations).
-                        *
-                        * or if receiving for the first time, an XAUTH challenge.
-                        *
-                        * or if we are getting a MODECFG request.
-                        *
-                        * we distinguish these states because we can not both be an
-                        * XAUTH server and client, and our policy tells us which
-                        * one we are.
-                        *
-                        * to complicate further, it is normal to start a new msgid
-                        * when going from one state to another, or when restarting
-                        * the challenge.
-                        *
-                        */
-
-                       has_xauth_policy = (st->st_connection->policy
-                                                          & (POLICY_XAUTH_RSASIG | POLICY_XAUTH_PSK))
-                                                          != LEMPTY;
-
-                       if (has_xauth_policy && !st->st_xauth.started
-                       && IS_PHASE1(st->st_state))
-                       {
-                               from_state = STATE_XAUTH_I0;
-                       }
-                       else if (st->st_connection->spd.that.modecfg
-                       && IS_PHASE1(st->st_state))
-                       {
-                               from_state = STATE_MODE_CFG_R0;
-                       }
-                       else if (st->st_connection->spd.this.modecfg
-                       && IS_PHASE1(st->st_state))
-                       {
-                               from_state = STATE_MODE_CFG_I0;
-                       }
-                       else
-                       {
-                               /* XXX check if we are being a mode config server here */
-                               plog("received ModeCfg message when in state %s, and we aren't mode config client"
-                                        , enum_name(&state_names, st->st_state));
-                               return;
-                       }
-               }
-               else
-               {
-                       set_cur_state(st);
-                       from_state = st->st_state;
-               }
-               break;
-
-#ifdef NOTYET
-       case ISAKMP_XCHG_NGRP:
-       case ISAKMP_XCHG_ACK_INFO:
-#endif
-
-       default:
-               plog("unsupported exchange type %s in message"
-                       , enum_show(&exchange_names, md->hdr.isa_xchg));
-               SEND_NOTIFICATION(ISAKMP_UNSUPPORTED_EXCHANGE_TYPE);
-               return;
-       }
-
-       /* We have found a from_state, and perhaps a state object.
-        * If we need to build a new state object,
-        * we wait until the packet has been sanity checked.
-        */
-
-       /* We don't support the Commit Flag.  It is such a bad feature.
-        * It isn't protected -- neither encrypted nor authenticated.
-        * A man in the middle turns it on, leading to DoS.
-        * We just ignore it, with a warning.
-        * By placing the check here, we could easily add a policy bit
-        * to a connection to suppress the warning.  This might be useful
-        * because the Commit Flag is expected from some peers.
-        */
-       if (md->hdr.isa_flags & ISAKMP_FLAG_COMMIT)
-       {
-               plog("IKE message has the Commit Flag set but Pluto doesn't implement this feature; ignoring flag");
-       }
-
-       /* Set smc to describe this state's properties.
-        * Look up the appropriate microcode based on state and
-        * possibly Oakley Auth type.
-        */
-       passert(STATE_IKE_FLOOR <= from_state && from_state < STATE_IKE_ROOF);
-       smc = ike_microcode_index[from_state - STATE_IKE_FLOOR];
-
-       if (st != NULL)
-       {
-               u_int16_t auth;
-
-               switch (st->st_oakley.auth)
-               {
-               case XAUTHInitPreShared:
-               case XAUTHRespPreShared:
-                       auth = OAKLEY_PRESHARED_KEY;
-                       break;
-               case XAUTHInitRSA:
-               case XAUTHRespRSA:
-                       auth = OAKLEY_RSA_SIG;
-                       break;
-               default:
-                       auth = st->st_oakley.auth;
-               }
-
-               while (!LHAS(smc->flags, auth))
-               {
-                       smc++;
-                       passert(smc->state == from_state);
-               }
-       }
-
-       /* Ignore a packet if the state has a suspended state transition
-        * Probably a duplicated packet but the original packet is not yet
-        * recorded in st->st_rpacket, so duplicate checking won't catch.
-        * ??? Should the packet be recorded earlier to improve diagnosis?
-        */
-       if (st != NULL && st->st_suspended_md != NULL)
-       {
-               loglog(RC_LOG, "discarding packet received during DNS lookup in %s"
-                       , enum_name(&state_names, st->st_state));
-               return;
-       }
-
-       /* Detect and handle duplicated packets.
-        * This won't work for the initial packet of an exchange
-        * because we won't have a state object to remember it.
-        * If we are in a non-receiving state (terminal), and the preceding
-        * state did transmit, then the duplicate may indicate that that
-        * transmission wasn't received -- retransmit it.
-        * Otherwise, just discard it.
-        * ??? Notification packets are like exchanges -- I hope that
-        * they are idempotent!
-        */
-       if (st != NULL
-       && st->st_rpacket.ptr != NULL
-       && st->st_rpacket.len == pbs_room(&md->packet_pbs)
-       && memeq(st->st_rpacket.ptr, md->packet_pbs.start, st->st_rpacket.len))
-       {
-               if (smc->flags & SMF_RETRANSMIT_ON_DUPLICATE)
-               {
-                       if (st->st_retransmit < MAXIMUM_RETRANSMISSIONS)
-                       {
-                               st->st_retransmit++;
-                               loglog(RC_RETRANSMISSION
-                                       , "retransmitting in response to duplicate packet; already %s"
-                                       , enum_name(&state_names, st->st_state));
-                               send_packet(st, "retransmit in response to duplicate");
-                       }
-                       else
-                       {
-                               loglog(RC_LOG_SERIOUS, "discarding duplicate packet -- exhausted retransmission; already %s"
-                                       , enum_name(&state_names, st->st_state));
-                       }
-               }
-               else
-               {
-                       loglog(RC_LOG_SERIOUS, "discarding duplicate packet; already %s"
-                               , enum_name(&state_names, st->st_state));
-               }
-               return;
-       }
-
-       if (md->hdr.isa_flags & ISAKMP_FLAG_ENCRYPTION)
-       {
-               DBG(DBG_CRYPT, DBG_log("received encrypted packet from %s:%u"
-                       , ip_str(&md->sender), (unsigned)md->sender_port));
-
-               if (st == NULL)
-               {
-                       plog("discarding encrypted message for an unknown ISAKMP SA");
-                       SEND_NOTIFICATION(ISAKMP_PAYLOAD_MALFORMED /* XXX ? */);
-                       return;
-               }
-               if (st->st_skeyid_e.ptr == (u_char *) NULL)
-               {
-                       loglog(RC_LOG_SERIOUS, "discarding encrypted message"
-                               " because we haven't yet negotiated keying materiel");
-                       SEND_NOTIFICATION(ISAKMP_INVALID_FLAGS);
-                       return;
-               }
-
-               /* Mark as encrypted */
-               md->encrypted = TRUE;
-
-               DBG(DBG_CRYPT, DBG_log("decrypting %u bytes using algorithm %s"
-                       , (unsigned) pbs_left(&md->message_pbs)
-                       , enum_show(&oakley_enc_names, st->st_oakley.encrypt)));
-
-               /* do the specified decryption
-                *
-                * IV is from st->st_iv or (if new_iv_set) st->st_new_iv.
-                * The new IV is placed in st->st_new_iv
-                *
-                * See RFC 2409 "IKE" Appendix B
-                *
-                * XXX The IV should only be updated really if the packet
-                * is successfully processed.
-                * We should keep this value, check for a success return
-                * value from the parsing routines and then replace.
-                *
-                * Each post phase 1 exchange generates IVs from
-                * the last phase 1 block, not the last block sent.
-                */
-               {
-                       size_t crypter_block_size, crypter_iv_size;
-                       encryption_algorithm_t enc_alg;
-                       crypter_t *crypter;
-                       chunk_t data, iv;
-                   char *new_iv;
-
-                       enc_alg = oakley_to_encryption_algorithm(st->st_oakley.encrypt);
-                       crypter = lib->crypto->create_crypter(lib->crypto, enc_alg, st->st_enc_key.len);
-                       crypter_block_size = crypter->get_block_size(crypter);
-                       crypter_iv_size = crypter->get_iv_size(crypter);
-
-                       if (pbs_left(&md->message_pbs) % crypter_block_size != 0)
-                       {
-                               loglog(RC_LOG_SERIOUS, "malformed message: not a multiple of encryption blocksize");
-                               SEND_NOTIFICATION(ISAKMP_PAYLOAD_MALFORMED);
-                               return;
-                       }
-
-                       /* XXX Detect weak keys */
-
-                       /* grab a copy of raw packet (for duplicate packet detection) */
-                       md->raw_packet = chunk_create(md->packet_pbs.start, pbs_room(&md->packet_pbs));
-                       md->raw_packet = chunk_clone(md->raw_packet);
-
-                       data = chunk_create(md->message_pbs.cur, pbs_left(&md->message_pbs));
-
-                       /* Decrypt everything after header */
-                       if (!new_iv_set)
-                       {
-                               /* use old IV */
-                               passert(st->st_iv_len <= sizeof(st->st_new_iv));
-                               st->st_new_iv_len = st->st_iv_len;
-                               memcpy(st->st_new_iv, st->st_iv, st->st_new_iv_len);
-                       }
-
-                       /* form iv by truncation */
-                       st->st_new_iv_len = crypter_iv_size;
-                       iv = chunk_create(st->st_new_iv, st->st_new_iv_len);
-                       new_iv = alloca(crypter_iv_size);
-                       memcpy(new_iv, data.ptr + data.len - crypter_iv_size,
-                                  crypter_iv_size);
-
-                       crypter->set_key(crypter, st->st_enc_key);
-                       crypter->decrypt(crypter, data, iv, NULL);
-                       crypter->destroy(crypter);
-
-                       memcpy(st->st_new_iv, new_iv, crypter_iv_size);
-                       if (restore_iv)
-                       {
-                               memcpy(st->st_new_iv, new_iv, new_iv_len);
-                               st->st_new_iv_len = new_iv_len;
-                       }
-               }
-
-               DBG_cond_dump(DBG_CRYPT, "decrypted:\n", md->message_pbs.cur
-                       , md->message_pbs.roof - md->message_pbs.cur);
-
-               DBG_cond_dump(DBG_CRYPT, "next IV:"
-                       , st->st_new_iv, st->st_new_iv_len);
-       }
-       else
-       {
-               /* packet was not encryped -- should it have been? */
-
-               if (smc->flags & SMF_INPUT_ENCRYPTED)
-               {
-                       loglog(RC_LOG_SERIOUS, "packet rejected: should have been encrypted");
-                       SEND_NOTIFICATION(ISAKMP_INVALID_FLAGS);
-                       return;
-               }
-       }
-
-       /* Digest the message.
-        * Padding must be removed to make hashing work.
-        * Padding comes from encryption (so this code must be after decryption).
-        * Padding rules are described before the definition of
-        * struct isakmp_hdr in packet.h.
-        */
-       {
-               struct payload_digest *pd = md->digest;
-               int np = md->hdr.isa_np;
-               lset_t needed = smc->req_payloads;
-               const char *excuse
-                       = LIN(SMF_PSK_AUTH | SMF_FIRST_ENCRYPTED_INPUT, smc->flags)
-                               ? "probable authentication failure (mismatch of preshared secrets?): "
-                               : "";
-
-               while (np != ISAKMP_NEXT_NONE)
-               {
-                       struct_desc *sd = np < ISAKMP_NEXT_ROOF? payload_descs[np] : NULL;
-
-                       if (pd == &md->digest[PAYLIMIT])
-                       {
-                               loglog(RC_LOG_SERIOUS, "more than %d payloads in message; ignored", PAYLIMIT);
-                               SEND_NOTIFICATION(ISAKMP_PAYLOAD_MALFORMED);
-                               return;
-                       }
-
-                       switch (np)
-                       {
-                               case ISAKMP_NEXT_NATD_RFC:
-                               case ISAKMP_NEXT_NATOA_RFC:
-                                       if (!st || !(st->nat_traversal & NAT_T_WITH_RFC_VALUES))
-                                       {
-                                               /*
-                                                * don't accept NAT-D/NAT-OA reloc directly in message, unless
-                                                * we're using NAT-T RFC
-                                                */
-                                               sd = NULL;
-                                       }
-                                       break;
-                       }
-
-                       if (sd == NULL)
-                       {
-                               /* payload type is out of range or requires special handling */
-                               switch (np)
-                               {
-                               case ISAKMP_NEXT_ID:
-                                       sd = IS_PHASE1(from_state)
-                                               ? &isakmp_identification_desc : &isakmp_ipsec_identification_desc;
-                                       break;
-                               case ISAKMP_NEXT_NATD_DRAFTS:
-                                       np = ISAKMP_NEXT_NATD_RFC;  /* NAT-D relocated */
-                                       sd = payload_descs[np];
-                                       break;
-                               case ISAKMP_NEXT_NATOA_DRAFTS:
-                                       np = ISAKMP_NEXT_NATOA_RFC;  /* NAT-OA relocated */
-                                       sd = payload_descs[np];
-                                       break;
-                               default:
-                                       loglog(RC_LOG_SERIOUS, "%smessage ignored because it contains an unknown or"
-                                               " unexpected payload type (%s) at the outermost level"
-                                               , excuse, enum_show(&payload_names, np));
-                                       SEND_NOTIFICATION(ISAKMP_INVALID_PAYLOAD_TYPE);
-                                       return;
-                               }
-                       }
-
-                       {
-                               lset_t s = LELEM(np);
-
-                               if (LDISJOINT(s
-                               , needed | smc->opt_payloads| LELEM(ISAKMP_NEXT_N) | LELEM(ISAKMP_NEXT_D)))
-                               {
-                                       loglog(RC_LOG_SERIOUS, "%smessage ignored because it "
-                                                  "contains an unexpected payload type (%s)"
-                                               , excuse, enum_show(&payload_names, np));
-                                       SEND_NOTIFICATION(ISAKMP_INVALID_PAYLOAD_TYPE);
-                                       return;
-                               }
-                               needed &= ~s;
-                       }
-
-                       if (!in_struct(&pd->payload, sd, &md->message_pbs, &pd->pbs))
-                       {
-                               loglog(RC_LOG_SERIOUS, "%smalformed payload in packet", excuse);
-                               if (md->hdr.isa_xchg != ISAKMP_XCHG_INFO)
-                                       SEND_NOTIFICATION(ISAKMP_PAYLOAD_MALFORMED);
-                               return;
-                       }
-
-                       /* place this payload at the end of the chain for this type */
-                       {
-                               struct payload_digest **p;
-
-                               for (p = &md->chain[np]; *p != NULL; p = &(*p)->next)
-                                       ;
-                               *p = pd;
-                               pd->next = NULL;
-                       }
-
-                       np = pd->payload.generic.isag_np;
-                       pd++;
-
-                       /* since we've digested one payload happily, it is probably
-                        * the case that any decryption worked.  So we will not suggest
-                        * encryption failure as an excuse for subsequent payload
-                        * problems.
-                        */
-                       excuse = "";
-               }
-
-               md->digest_roof = pd;
-
-               DBG(DBG_PARSING,
-                       if (pbs_left(&md->message_pbs) != 0)
-                               DBG_log("removing %d bytes of padding", (int) pbs_left(&md->message_pbs)));
-
-               md->message_pbs.roof = md->message_pbs.cur;
-
-               /* check that all mandatory payloads appeared */
-
-               if (needed != 0)
-               {
-                       loglog(RC_LOG_SERIOUS, "message for %s is missing payloads %s"
-                               , enum_show(&state_names, from_state)
-                               , bitnamesof(payload_name, needed));
-                       SEND_NOTIFICATION(ISAKMP_PAYLOAD_MALFORMED);
-                       return;
-               }
-       }
-
-       /* more sanity checking: enforce most ordering constraints */
-
-       if (IS_PHASE1(from_state))
-       {
-               /* rfc2409: The Internet Key Exchange (IKE), 5 Exchanges:
-                * "The SA payload MUST precede all other payloads in a phase 1 exchange."
-                */
-               if (md->chain[ISAKMP_NEXT_SA] != NULL
-               && md->hdr.isa_np != ISAKMP_NEXT_SA)
-               {
-                       loglog(RC_LOG_SERIOUS, "malformed Phase 1 message: does not start with an SA payload");
-                       SEND_NOTIFICATION(ISAKMP_PAYLOAD_MALFORMED);
-                       return;
-               }
-       }
-       else if (IS_QUICK(from_state))
-       {
-               /* rfc2409: The Internet Key Exchange (IKE), 5.5 Phase 2 - Quick Mode
-                *
-                * "In Quick Mode, a HASH payload MUST immediately follow the ISAKMP
-                *  header and a SA payload MUST immediately follow the HASH."
-                * [NOTE: there may be more than one SA payload, so this is not
-                *  totally reasonable.  Probably all SAs should be so constrained.]
-                *
-                * "If ISAKMP is acting as a client negotiator on behalf of another
-                *  party, the identities of the parties MUST be passed as IDci and
-                *  then IDcr."
-                *
-                * "With the exception of the HASH, SA, and the optional ID payloads,
-                *  there are no payload ordering restrictions on Quick Mode."
-                */
-
-               if (md->hdr.isa_np != ISAKMP_NEXT_HASH)
-               {
-                       loglog(RC_LOG_SERIOUS, "malformed Quick Mode message: does not start with a HASH payload");
-                       SEND_NOTIFICATION(ISAKMP_PAYLOAD_MALFORMED);
-                       return;
-               }
-
-               {
-                       struct payload_digest *p;
-                       int i;
-
-                       for (p = md->chain[ISAKMP_NEXT_SA], i = 1; p != NULL
-                       ; p = p->next, i++)
-                       {
-                               if (p != &md->digest[i])
-                               {
-                                       loglog(RC_LOG_SERIOUS, "malformed Quick Mode message: SA payload is in wrong position");
-                                       SEND_NOTIFICATION(ISAKMP_PAYLOAD_MALFORMED);
-                                       return;
-                               }
-                       }
-               }
-
-               /* rfc2409: The Internet Key Exchange (IKE), 5.5 Phase 2 - Quick Mode:
-                * "If ISAKMP is acting as a client negotiator on behalf of another
-                *  party, the identities of the parties MUST be passed as IDci and
-                *  then IDcr."
-                */
-               {
-                       struct payload_digest *id = md->chain[ISAKMP_NEXT_ID];
-
-                       if (id != NULL)
-                       {
-                               if (id->next == NULL || id->next->next != NULL)
-                               {
-                                       loglog(RC_LOG_SERIOUS, "malformed Quick Mode message:"
-                                               " if any ID payload is present,"
-                                               " there must be exactly two");
-                                       SEND_NOTIFICATION(ISAKMP_PAYLOAD_MALFORMED);
-                                       return;
-                               }
-                               if (id+1 != id->next)
-                               {
-                                       loglog(RC_LOG_SERIOUS, "malformed Quick Mode message:"
-                                               " the ID payloads are not adjacent");
-                                       SEND_NOTIFICATION(ISAKMP_PAYLOAD_MALFORMED);
-                                       return;
-                               }
-                       }
-               }
-       }
-
-       /* Ignore payloads that we don't handle:
-        * Delete, Notification, VendorID
-        */
-       /* XXX Handle deletions */
-       /* XXX Handle Notifications */
-       /* XXX Handle VID payloads */
-       {
-               struct payload_digest *p;
-
-               for (p = md->chain[ISAKMP_NEXT_N]; p != NULL; p = p->next)
-               {
-                       if (p->payload.notification.isan_type != R_U_THERE
-                       &&  p->payload.notification.isan_type != R_U_THERE_ACK)
-                       {
-                               loglog(RC_LOG_SERIOUS, "ignoring informational payload, type %s"
-                                       , enum_show(&notification_names, p->payload.notification.isan_type));
-                       }
-                       DBG_cond_dump(DBG_PARSING, "info:", p->pbs.cur, pbs_left(&p->pbs));
-               }
-
-               for (p = md->chain[ISAKMP_NEXT_D]; p != NULL; p = p->next)
-               {
-                       accept_delete(st, md, p);
-                       DBG_cond_dump(DBG_PARSING, "del:", p->pbs.cur, pbs_left(&p->pbs));
-               }
-
-               for (p = md->chain[ISAKMP_NEXT_VID]; p != NULL; p = p->next)
-               {
-                       handle_vendorid(md, p->pbs.cur, pbs_left(&p->pbs));
-               }
-       }
-       md->from_state = from_state;
-       md->smc = smc;
-       md->st = st;
-
-       /* possibly fill in hdr */
-       if (smc->first_out_payload != ISAKMP_NEXT_NONE)
-               echo_hdr(md, (smc->flags & SMF_OUTPUT_ENCRYPTED) != 0
-                       , smc->first_out_payload);
-
-       complete_state_transition(mdp, smc->processor(md));
-}
-
-/* complete job started by the state-specific state transition function */
-
-void
-complete_state_transition(struct msg_digest **mdp, stf_status result)
-{
-       bool has_xauth_policy;
-       bool is_xauth_server;
-       struct msg_digest *md = *mdp;
-       const struct state_microcode *smc = md->smc;
-       enum state_kind from_state = md->from_state;
-       struct state *st;
-
-       cur_state = st = md->st;    /* might have changed */
-
-       /* If state has DPD support, import it */
-       if (st && md->dpd)
-               st->st_dpd = TRUE;
-
-       switch (result)
-       {
-               case STF_IGNORE:
-                       break;
-
-               case STF_SUSPEND:
-                       /* the stf didn't complete its job: don't relase md */
-                       *mdp = NULL;
-                       break;
-
-               case STF_OK:
-                       /* advance the state */
-                       st->st_state = smc->next_state;
-
-                       /* Delete previous retransmission event.
-                        * New event will be scheduled below.
-                        */
-                       delete_event(st);
-
-                       /* replace previous receive packet with latest */
-
-                       free(st->st_rpacket.ptr);
-
-                       if (md->encrypted)
-                       {
-                               /* if encrypted, duplication already done */
-                               st->st_rpacket = md->raw_packet;
-                               md->raw_packet.ptr = NULL;
-                       }
-                       else
-                       {
-                               st->st_rpacket = chunk_create(md->packet_pbs.start,
-                                                                                         pbs_room(&md->packet_pbs));
-                               st->st_rpacket = chunk_clone(st->st_rpacket);
-                       }
-
-                       /* free previous transmit packet */
-                       chunk_free(&st->st_tpacket);
-
-                       /* if requested, send the new reply packet */
-                       if (smc->flags & SMF_REPLY)
-                       {
-                               close_output_pbs(&md->reply);   /* good form, but actually a no-op */
-
-                               st->st_tpacket = chunk_create(md->reply.start, pbs_offset(&md->reply));
-                               st->st_tpacket = chunk_clone(st->st_tpacket);
-
-                               if (nat_traversal_enabled)
-                                       nat_traversal_change_port_lookup(md, md->st);
-
-                               /* actually send the packet
-                                * Note: this is a great place to implement "impairments"
-                                * for testing purposes.  Suppress or duplicate the
-                                * send_packet call depending on st->st_state.
-                                */
-                               send_packet(st, enum_name(&state_names, from_state));
-                       }
-
-                       /* Schedule for whatever timeout is specified */
-                       {
-                               time_t delay = UNDEFINED_TIME;
-                               enum event_type kind = smc->timeout_event;
-                               bool agreed_time = FALSE;
-                               connection_t *c = st->st_connection;
-
-                               switch (kind)
-                               {
-                               case EVENT_RETRANSMIT:  /* Retransmit packet */
-                                       delay = EVENT_RETRANSMIT_DELAY_0;
-                                       break;
-
-                               case EVENT_SA_REPLACE:  /* SA replacement event */
-                                       if (IS_PHASE1(st->st_state))
-                                       {
-                                               /* Note: we will defer to the "negotiated" (dictated)
-                                                * lifetime if we are POLICY_DONT_REKEY.
-                                                * This allows the other side to dictate
-                                                * a time we would not otherwise accept
-                                                * but it prevents us from having to initiate
-                                                * rekeying.  The negative consequences seem
-                                                * minor.
-                                                */
-                                               delay = c->sa_ike_life_seconds;
-                                               if ((c->policy & POLICY_DONT_REKEY)
-                                               || delay >= st->st_oakley.life_seconds)
-                                               {
-                                                       agreed_time = TRUE;
-                                                       delay = st->st_oakley.life_seconds;
-                                               }
-                                       }
-                                       else
-                                       {
-                                               /* Delay is min of up to four things:
-                                                * each can limit the lifetime.
-                                                */
-                                               delay = c->sa_ipsec_life_seconds;
-                                               if (st->st_ah.present
-                                               && delay >= st->st_ah.attrs.life_seconds)
-                                               {
-                                                       agreed_time = TRUE;
-                                                       delay = st->st_ah.attrs.life_seconds;
-                                               }
-                                               if (st->st_esp.present
-                                               && delay >= st->st_esp.attrs.life_seconds)
-                                               {
-                                                       agreed_time = TRUE;
-                                                       delay = st->st_esp.attrs.life_seconds;
-                                               }
-                                               if (st->st_ipcomp.present
-                                               && delay >= st->st_ipcomp.attrs.life_seconds)
-                                               {
-                                                       agreed_time = TRUE;
-                                                       delay = st->st_ipcomp.attrs.life_seconds;
-                                               }
-                                       }
-
-                                       /* By default, we plan to rekey.
-                                        *
-                                        * If there isn't enough time to rekey, plan to
-                                        * expire.
-                                        *
-                                        * If we are --dontrekey, a lot more rules apply.
-                                        * If we are the Initiator, use REPLACE_IF_USED.
-                                        * If we are the Responder, and the dictated time
-                                        * was unacceptable (too large), plan to REPLACE
-                                        * (the only way to ratchet down the time).
-                                        * If we are the Responder, and the dictated time
-                                        * is acceptable, plan to EXPIRE.
-                                        *
-                                        * Important policy lies buried here.
-                                        * For example, we favour the initiator over the
-                                        * responder by making the initiator start rekeying
-                                        * sooner.  Also, fuzz is only added to the
-                                        * initiator's margin.
-                                        *
-                                        * Note: for ISAKMP SA, we let the negotiated
-                                        * time stand (implemented by earlier logic).
-                                        */
-                                       if (agreed_time
-                                       && (c->policy & POLICY_DONT_REKEY))
-                                       {
-                                               kind = (smc->flags & SMF_INITIATOR)
-                                                       ? EVENT_SA_REPLACE_IF_USED
-                                                       : EVENT_SA_EXPIRE;
-                                       }
-                                       if (kind != EVENT_SA_EXPIRE)
-                                       {
-                                               unsigned long marg = c->sa_rekey_margin;
-
-                                               if (smc->flags & SMF_INITIATOR)
-                                                       marg += marg
-                                                               * c->sa_rekey_fuzz / 100.E0
-                                                               * (rand() / (RAND_MAX + 1.E0));
-                                               else
-                                                       marg /= 2;
-
-                                               if ((unsigned long)delay > marg)
-                                               {
-                                                       delay -= marg;
-                                                       st->st_margin = marg;
-                                               }
-                                               else
-                                               {
-                                                       kind = EVENT_SA_EXPIRE;
-                                               }
-                                       }
-                                       break;
-
-                               case EVENT_NULL:                /* non-event */
-                               case EVENT_REINIT_SECRET:       /* Refresh cookie secret */
-                               default:
-                                       bad_case(kind);
-                               }
-                               event_schedule(kind, delay, st);
-                       }
-
-                       /* tell whack and log of progress */
-                       {
-                               const char *story = state_story[st->st_state];
-                               enum rc_type w = RC_NEW_STATE + st->st_state;
-                               char sadetails[128];
-
-                               sadetails[0]='\0';
-
-                               if (IS_IPSEC_SA_ESTABLISHED(st->st_state))
-                               {
-                                       char *b = sadetails;
-                                       const char *ini = " {";
-                                       const char *fin = "";
-
-                                       /* -1 is to leave space for "fin" */
-
-                                       if (st->st_esp.present)
-                                       {
-                                               snprintf(b, sizeof(sadetails)-(b-sadetails)-1
-                                                                , "%sESP=>0x%08x <0x%08x"
-                                                                , ini
-                                                                , ntohl(st->st_esp.attrs.spi)
-                                                                , ntohl(st->st_esp.our_spi));
-                                               ini = " ";
-                                               fin = "}";
-                                       }
-                                       /* advance b to end of string */
-                                       b = b + strlen(b);
-
-                                       if (st->st_ah.present)
-                                       {
-                                               snprintf(b, sizeof(sadetails)-(b-sadetails)-1
-                                                                , "%sAH=>0x%08x <0x%08x"
-                                                                , ini
-                                                                , ntohl(st->st_ah.attrs.spi)
-                                                                , ntohl(st->st_ah.our_spi));
-                                               ini = " ";
-                                               fin = "}";
-                                       }
-                                       /* advance b to end of string */
-                                       b = b + strlen(b);
-
-                                       if (st->st_ipcomp.present)
-                                       {
-                                               snprintf(b, sizeof(sadetails)-(b-sadetails)-1
-                                                                , "%sIPCOMP=>0x%08x <0x%08x"
-                                                                , ini
-                                                                , ntohl(st->st_ipcomp.attrs.spi)
-                                                                , ntohl(st->st_ipcomp.our_spi));
-                                               ini = " ";
-                                               fin = "}";
-                                       }
-                                       /* advance b to end of string */
-                                       b = b + strlen(b);
-
-                                       if (st->nat_traversal)
-                                       {
-                                               char oa[ADDRTOT_BUF];
-                                               addrtot(&st->nat_oa, 0, oa, sizeof(oa));
-                                               snprintf(b, sizeof(sadetails)-(b-sadetails)-1
-                                                                , "%sNATOA=%s"
-                                                                , ini, oa);
-                                               ini = " ";
-                                               fin = "}";
-                                       }
-
-                                       /* advance b to end of string */
-                                       b = b + strlen(b);
-
-                                       if (st->st_dpd)
-                                       {
-                                               snprintf(b, sizeof(sadetails)-(b-sadetails)-1
-                                                                , "%sDPD"
-                                                                , ini);
-                                               ini = " ";
-                                               fin = "}";
-                                       }
-
-                                       strcat(b, fin);
-                               }
-
-                               if (IS_ISAKMP_SA_ESTABLISHED(st->st_state)
-                               ||  IS_IPSEC_SA_ESTABLISHED(st->st_state))
-                               {
-                                       /* log our success */
-                                       plog("%s%s", story, sadetails);
-                                       w = RC_SUCCESS;
-                               }
-
-                               /* tell whack our progress */
-                               whack_log(w
-                                       , "%s: %s%s"
-                                       , enum_name(&state_names, st->st_state)
-                                       , story, sadetails);
-                       }
-
-                       has_xauth_policy = (st->st_connection->policy
-                                                          & (POLICY_XAUTH_RSASIG | POLICY_XAUTH_PSK))
-                                                          != LEMPTY;
-                       is_xauth_server =  (st->st_connection->policy
-                                                          & POLICY_XAUTH_SERVER)
-                                                          != LEMPTY;
-
-                       /* Should we start XAUTH as a server */
-                       if (has_xauth_policy && is_xauth_server
-                       && IS_ISAKMP_SA_ESTABLISHED(st->st_state)
-                       && !st->st_xauth.started)
-                       {
-                               DBG(DBG_CONTROL,
-                                       DBG_log("starting XAUTH server")
-                               )
-                               xauth_send_request(st);
-                               break;
-                       }
-
-                       /* Wait for XAUTH request from server */
-                       if (has_xauth_policy && !is_xauth_server
-                       && IS_ISAKMP_SA_ESTABLISHED(st->st_state)
-                       && !st->st_xauth.started)
-                       {
-                               DBG(DBG_CONTROL,
-                                       DBG_log("waiting for XAUTH request from server")
-                               )
-                               break;
-                       }
-
-                       /* Should we start ModeConfig as a client? */
-                       if (st->st_connection->spd.this.modecfg
-                       && IS_ISAKMP_SA_ESTABLISHED(st->st_state)
-                       && !(st->st_connection->policy & POLICY_MODECFG_PUSH)
-                       && !st->st_modecfg.started)
-                       {
-                               DBG(DBG_CONTROL,
-                                       DBG_log("starting ModeCfg client in pull mode")
-                               )
-                               modecfg_send_request(st);
-                               break;
-                       }
-
-                       /* Should we start ModeConfig as a server? */
-                       if (st->st_connection->spd.that.modecfg
-                       && IS_ISAKMP_SA_ESTABLISHED(st->st_state)
-                       && !st->st_modecfg.started
-                       && (st->st_connection->policy & POLICY_MODECFG_PUSH))
-                       {
-                               DBG(DBG_CONTROL,
-                                       DBG_log("starting ModeCfg server in push mode")
-                               )
-                               modecfg_send_set(st);
-                               break;
-                       }
-
-                       /* Wait for ModeConfig set from server */
-                       if (st->st_connection->spd.this.modecfg
-                       && IS_ISAKMP_SA_ESTABLISHED(st->st_state)
-                       && !st->st_modecfg.vars_set)
-                       {
-                               DBG(DBG_CONTROL,
-                                       DBG_log("waiting for ModeCfg set from server")
-                               )
-                               break;
-                       }
-
-                       if (smc->flags & SMF_RELEASE_PENDING_P2)
-                       {
-                               /* Initiate any Quick Mode negotiations that
-                                * were waiting to piggyback on this Keying Channel.
-                                *
-                                * ??? there is a potential race condition
-                                * if we are the responder: the initial Phase 2
-                                * message might outrun the final Phase 1 message.
-                                * I think that retransmission will recover.
-                                */
-                               unpend(st);
-                       }
-
-                       if (IS_ISAKMP_SA_ESTABLISHED(st->st_state)
-                       ||  IS_IPSEC_SA_ESTABLISHED(st->st_state))
-                               release_whack(st);
-                       break;
-
-               case STF_INTERNAL_ERROR:
-                       whack_log(RC_INTERNALERR + md->note
-                               , "%s: internal error"
-                               , enum_name(&state_names, st->st_state));
-
-                       DBG(DBG_CONTROL,
-                               DBG_log("state transition function for %s had internal error"
-                                       , enum_name(&state_names, from_state)));
-                       break;
-
-               default:        /* a shortcut to STF_FAIL, setting md->note */
-                       passert(result > STF_FAIL);
-                       md->note = result - STF_FAIL;
-                       result = STF_FAIL;
-                       /* FALL THROUGH ... */
-               case STF_FAIL:
-                       /* As it is, we act as if this message never happened:
-                        * whatever retrying was in place, remains in place.
-                        */
-                       whack_log(RC_NOTIFICATION + md->note
-                               , "%s: %s"
-                               , enum_name(&state_names, (st == NULL)? STATE_MAIN_R0:st->st_state)
-                               , enum_name(&notification_names, md->note));
-
-                       SEND_NOTIFICATION(md->note);
-
-                       DBG(DBG_CONTROL,
-                               DBG_log("state transition function for %s failed: %s"
-                                       , enum_name(&state_names, from_state)
-                                       , enum_name(&notification_names, md->note)));
-                       break;
-       }
-}
diff --git a/src/pluto/demux.h b/src/pluto/demux.h
deleted file mode 100644 (file)
index 6ce53c1..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/* demultiplex incoming IKE messages
- * Copyright (C) 1998-2002  D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef _DEMUX_H
-#define _DEMUX_H
-
-#include "packet.h"
-#include "state.h"
-
-extern void init_demux(void);
-extern bool send_packet(struct state *st, const char *where);
-extern void comm_handle(const struct iface *ifp);
-
-extern u_int8_t reply_buffer[MAX_OUTPUT_UDP_SIZE];
-
-/* State transition function infrastructure
- *
- * com_handle parses a message, decides what state object it applies to,
- * and calls the appropriate state transition function (STF).
- * These declarations define the interface to these functions.
- *
- * Each STF must be able to be restarted up to any failure point:
- * a later message will cause the state to be re-entered.  This
- * explains the use of the replace macro and the care in handling
- * MP_INT members of struct state.
- */
-
-struct payload_digest {
-       pb_stream pbs;
-       union payload payload;
-       struct payload_digest *next;   /* of same kind */
-};
-
-/* message digest
- * Note: raw_packet and packet_pbs are "owners" of space on heap.
- */
-
-struct msg_digest {
-       struct msg_digest *next;    /* for free list */
-       chunk_t raw_packet;         /* if encrypted, received packet before decryption */
-       const struct iface *iface;  /* interface on which message arrived */
-       ip_address sender;  /* where message came from */
-       u_int16_t sender_port;      /* host order */
-       pb_stream packet_pbs;       /* whole packet */
-       pb_stream message_pbs;      /* message to be processed */
-       struct isakmp_hdr hdr;      /* message's header */
-       bool encrypted;             /* was it encrypted? */
-       enum state_kind from_state; /* state we started in */
-       const struct state_microcode *smc;  /* microcode for initial state */
-       struct state *st;           /* current state object */
-       pb_stream reply;            /* room for reply */
-       pb_stream rbody;            /* room for reply body (after header) */
-       notification_t note;        /* reason for failure */
-       bool dpd;                   /* peer supports RFC 3706 DPD */
-       bool openpgp;               /* peer supports OpenPGP certificates */
-       bool ms_nt5;                /* peer is a windows 2000+ host */
-
-#   define PAYLIMIT 40
-       struct payload_digest
-               digest[PAYLIMIT],
-               *digest_roof,
-               *chain[ISAKMP_NEXT_ROOF];
-               unsigned short nat_traversal_vid;
-};
-
-extern void release_md(struct msg_digest *md);
-
-/* status for state-transition-function
- * Note: STF_FAIL + notification_t means fail with that notification
- */
-
-typedef enum {
-       STF_IGNORE, /* don't respond */
-       STF_SUSPEND,    /* unfinished -- don't release resources */
-       STF_OK,     /* success */
-       STF_INTERNAL_ERROR, /* discard everything, we failed */
-       STF_FAIL    /* discard everything, something failed.  notification_t added. */
-} stf_status;
-
-typedef stf_status state_transition_fn(struct msg_digest *md);
-
-extern void complete_state_transition(struct msg_digest **mdp, stf_status result);
-
-extern void free_md_pool(void);
-
-#endif /* _DEMUX_H */
diff --git a/src/pluto/dnskey.c b/src/pluto/dnskey.c
deleted file mode 100644 (file)
index 91b1b6a..0000000
+++ /dev/null
@@ -1,1590 +0,0 @@
-/* Find public key in DNS
- * Copyright (C) 2000-2002  D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/nameser.h>
-#include <resolv.h>
-#include <netdb.h>      /* ??? for h_errno */
-#include <sys/queue.h>
-
-#include <freeswan.h>
-
-#include <utils/identification.h>
-#include <credentials/keys/public_key.h>
-
-#include "constants.h"
-#include "adns.h"       /* needs <resolv.h> */
-#include "defs.h"
-#include "log.h"
-#include "myid.h"
-#include "connections.h"
-#include "keys.h"           /* needs connections.h */
-#include "dnskey.h"
-#include "packet.h"
-#include "timer.h"
-
-/* somebody has to decide */
-#define MAX_TXT_RDATA   ((MAX_KEY_BYTES * 8 / 6) + 40)  /* somewhat arbitrary overkill */
-
-/* ADNS stuff */
-
-int adns_qfd = NULL_FD, /* file descriptor for sending queries to adns (O_NONBLOCK) */
-       adns_afd = NULL_FD; /* file descriptor for receiving answers from adns */
-static pid_t adns_pid = 0;
-const char *pluto_adns_option = NULL;   /* path from --pluto_adns */
-
-int adns_restart_count;
-#define ADNS_RESTART_MAX 20
-
-void
-init_adns(void)
-{
-       const char *adns_path = pluto_adns_option;
-       static const char adns_name[] = "_pluto_adns";
-       const char *helper_bin_dir = getenv("IPSEC_LIBDIR");
-       char adns_path_space[4096]; /* plenty long? */
-       int qfds[2];
-       int afds[2];
-
-       /* find a pathname to the ADNS program */
-       if (adns_path == NULL)
-       {
-               /* pathname was not specified as an option: build it.
-                * First, figure out the directory to be used.
-                */
-               ssize_t n;
-
-               if (helper_bin_dir != NULL)
-               {
-                       n = strlen(helper_bin_dir);
-                       if ((size_t)n <= sizeof(adns_path_space) - sizeof(adns_name))
-                       {
-                               strcpy(adns_path_space, helper_bin_dir);
-                               if (n > 0 && adns_path_space[n -1] != '/')
-                               {
-                                       adns_path_space[n++] = '/';
-                               }
-                       }
-               }
-               else
-               {
-                       /* The program will be in the same directory as Pluto,
-                        * so we use the sympolic link /proc/self/exe to
-                        * tell us of the path prefix.
-                        */
-                       n = readlink("/proc/self/exe", adns_path_space, sizeof(adns_path_space));
-
-                       if (n < 0)
-                       {
-                               exit_log_errno((e
-                                       , "readlink(\"/proc/self/exe\") failed in init_adns()"));
-                       }
-               }
-
-               if ((size_t)n > sizeof(adns_path_space) - sizeof(adns_name))
-               {
-                       exit_log("path to %s is too long", adns_name);
-               }
-
-               while (n > 0 && adns_path_space[n - 1] != '/')
-               {
-                       n--;
-               }
-               strcpy(adns_path_space + n, adns_name);
-               adns_path = adns_path_space;
-       }
-       if (access(adns_path, X_OK) < 0)
-       {
-               exit_log_errno((e, "%s missing or not executable", adns_path));
-       }
-
-       if (pipe(qfds) != 0 || pipe(afds) != 0)
-       {
-               exit_log_errno((e, "pipe(2) failed in init_adns()"));
-       }
-
-       adns_pid = fork();
-       switch (adns_pid)
-       {
-       case -1:
-               exit_log_errno((e, "fork() failed in init_adns()"));
-
-       case 0:
-               /* child */
-               {
-                       /* Make stdin and stdout our pipes.
-                        * Take care to handle case where pipes already use these fds.
-                        */
-                       if (afds[1] == 0)
-                       {
-                               afds[1] = dup(afds[1]); /* avoid being overwritten */
-                       }
-                       if (qfds[0] != 0)
-                       {
-                               dup2(qfds[0], 0);
-                               close(qfds[0]);
-                       }
-                       if (afds[1] != 1)
-                       {
-                               dup2(afds[1], 1);
-                               close(qfds[1]);
-                       }
-                       if (afds[0] > 1)
-                       {
-                               close(afds[0]);
-                       }
-                       if (afds[1] > 1)
-                       {
-                               close(afds[1]);
-                       }
-                       DBG(DBG_DNS, execlp(adns_path, adns_name, "-d", NULL));
-
-                       execlp(adns_path, adns_name, NULL);
-                       exit_log_errno((e, "execlp of %s failed", adns_path));
-               }
-       default:
-               /* parent */
-               close(qfds[0]);
-               adns_qfd = qfds[1];
-               adns_afd = afds[0];
-               close(afds[1]);
-               fcntl(adns_qfd, F_SETFD, FD_CLOEXEC);
-               fcntl(adns_afd, F_SETFD, FD_CLOEXEC);
-               fcntl(adns_qfd, F_SETFL, O_NONBLOCK);
-               break;
-       }
-}
-
-void
-stop_adns(void)
-{
-       close_any(adns_qfd);
-       adns_qfd = NULL_FD;
-       close_any(adns_afd);
-       adns_afd = NULL_FD;
-
-       if (adns_pid != 0)
-       {
-               int status;
-               pid_t p = waitpid(adns_pid, &status, 0);
-
-               if (p == -1)
-               {
-                       log_errno((e, "waitpid for ADNS process failed"));
-               }
-               else if (WIFEXITED(status))
-               {
-                       if (WEXITSTATUS(status) != 0)
-                       {
-                               plog("ADNS process exited with status %d"
-                                       , (int) WEXITSTATUS(status));
-                       }
-               }
-               else if (WIFSIGNALED(status))
-               {
-                       plog("ADNS process terminated by signal %d", (int)WTERMSIG(status));
-               }
-               else
-               {
-                       plog("wait for end of ADNS process returned odd status 0x%x\n"
-                               , status);
-               }
-       }
-}
-
-
-
-/* tricky macro to pass any hot potato */
-#define TRY(x)  { err_t ugh = x; if (ugh != NULL) return ugh; }
-
-
-/* Process TXT X-IPsec-Server record, accumulating relevant ones
- * in cr->gateways_from_dns, a list sorted by "preference".
- *
- * Format of TXT record body: X-IPsec-Server ( nnn ) = iii kkk
- *  nnn is a 16-bit unsigned integer preference
- *  iii is @FQDN or dotted-decimal IPv4 address or colon-hex IPv6 address
- *  kkk is an optional RSA public signing key in base 64.
- *
- * NOTE: we've got to be very wary of anything we find -- bad guys
- * might have prepared it.
- */
-
-#define our_TXT_attr_string "X-IPsec-Server"
-static const char our_TXT_attr[] = our_TXT_attr_string;
-
-identification_t* decode_iii(u_char **pp)
-{
-       identification_t *gw_id;
-       u_char *p = *pp + strspn(*pp, " \t");
-       u_char *e = p + strcspn(p, " \t");
-       u_char under = *e;
-
-       if (p == e)
-       {
-               return NULL;
-       }
-       *e = '\0';
-       gw_id = identification_create_from_string(p);
-       *e = under;
-       *pp = e + strspn(e, " \t");
-
-       return gw_id;
-}
-
-static err_t process_txt_rr_body(u_char *str, bool doit,
-                                                                enum dns_auth_level dns_auth_level,
-                                                                struct adns_continuation *const cr)
-{
-       identification_t *client_id = cr->id;   /* subject of query */
-       u_char *p = str;
-       unsigned long pref = 0;
-       struct gw_info gi;
-
-       p += strspn(p, " \t");      /* ignore leading whitespace */
-
-       /* is this for us? */
-       if (strncasecmp(p, our_TXT_attr, sizeof(our_TXT_attr)-1) != 0)
-       {
-               return NULL;    /* neither interesting nor bad */
-       }
-
-       p += sizeof(our_TXT_attr) - 1;      /* ignore our attribute name */
-       p += strspn(p, " \t");      /* ignore leading whitespace */
-
-       /* decode '(' nnn ')' */
-       if (*p != '(')
-       {
-               return "X-IPsec-Server missing '('";
-       }
-
-       {
-               char *e;
-
-               p++;
-               pref = strtoul(p, &e, 0);
-               if ((u_char *)e == p)
-               {
-                       return "malformed X-IPsec-Server priority";
-               }
-               p = e + strspn(e, " \t");
-
-               if (*p != ')')
-               {
-                       return "X-IPsec-Server priority missing ')'";
-               }
-               p++;
-               p += strspn(p, " \t");
-
-               if (pref > 0xFFFF)
-               {
-                       return "X-IPsec-Server priority larger than 0xFFFF";
-               }
-       }
-
-       /* time for '=' */
-
-       if (*p != '=')
-       {
-               return "X-IPsec-Server priority missing '='";
-       }
-       p++;
-       p += strspn(p, " \t");
-
-       /* Decode iii (Security Gateway ID). */
-       zero(&gi);  /* before first use */
-
-       gi.gw_id = decode_iii(&p);
-       if (gi.gw_id == NULL)
-       {
-               return "TXT " our_TXT_attr_string " badly formed (no gateway specified)";
-       }
-
-       if (!cr->sgw_specified)
-       {
-               /* we don't know the peer's ID (because we are initiating
-                * and we don't know who to initiate with.
-                * So we're looking for gateway specs with an IP address
-                */
-               if (gi.gw_id->get_type(gi.gw_id) != ID_IPV4_ADDR &&
-                       gi.gw_id->get_type(gi.gw_id) != ID_IPV6_ADDR)
-               {
-                       DBG(DBG_DNS,
-                               DBG_log("TXT %s record for '%Y': security gateway '%Y';"
-                                               " ignored because gateway's IP is unspecified",
-                                               our_TXT_attr, client_id, gi.gw_id);
-                               )
-                       return NULL;        /* we cannot use this record, but it isn't wrong */
-               }
-       }
-       else
-       {
-               /* We do know the peer's ID (because we are responding)
-                * So we're looking for gateway specs specifying this known ID.
-                */
-               identification_t *peer_id = cr->sgw_id;
-
-               if (!peer_id->equals(peer_id, gi.gw_id))
-               {
-                       DBG(DBG_DNS,
-                               DBG_log("TXT %s record for '%Y': security gateway '%Y';"
-                                               " ignored -- looking to confirm '%Y' as gateway",
-                                               our_TXT_attr, client_id, gi.gw_id, peer_id);
-                               )
-                       return NULL;        /* we cannot use this record, but it isn't wrong */
-               }
-       }
-
-       if (doit)
-       {
-               /* really accept gateway */
-               struct gw_info **gwip;  /* gateway insertion point */
-
-               gi.client_id = client_id;      /* will need to unshare_id_content */
-
-               /* decode optional kkk: base 64 encoding of key */
-
-               gi.gw_key_present = *p != '\0';
-               if (gi.gw_key_present)
-               {
-                       /* Decode base 64 encoding of key.
-                        * Similar code is in process_lwdnsq_key.
-                        */
-                       u_char buf[RSA_MAX_ENCODING_BYTES];  /* plenty of space for binary form of public key */
-                       size_t sz;
-                       err_t ugh;
-                       chunk_t rfc3110_chunk;
-                       public_key_t *key;
-
-                       ugh = ttodatav(p, 0, 64, buf, sizeof(buf), &sz,
-                                               diag_space, sizeof(diag_space), TTODATAV_SPACECOUNTS);
-                       if (ugh)
-                       {
-                               return builddiag("malformed key data: %s", ugh);
-                       }
-                       if (sz > sizeof(buf))
-                       {
-                               return builddiag("key data larger than %lu bytes",
-                                                                (unsigned long) sizeof(buf));
-                       }
-                       rfc3110_chunk = chunk_create(buf, sz);
-                       key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
-                                                                               BUILD_BLOB_DNSKEY, rfc3110_chunk,
-                                                                               BUILD_END);
-                       if (key == NULL)
-                       {
-                               return builddiag("invalid key data");
-                       }
-
-                       /* now find a key entry to put it in */
-                       gi.key = public_key_from_rsa(key);
-
-                       unreference_key(&cr->last_info);
-                       cr->last_info = reference_key(gi.key);
-               }
-
-               /* we're home free!  Allocate everything and add to gateways list. */
-               gi.refcnt = 1;
-               gi.pref = pref;
-               gi.key->dns_auth_level = dns_auth_level;
-               gi.key->last_tried_time = gi.key->last_worked_time = NO_TIME;
-
-               /* find insertion point */
-               for (gwip = &cr->gateways_from_dns; *gwip != NULL && (*gwip)->pref < pref; gwip = &(*gwip)->next)
-                       ;
-
-               DBG(DBG_DNS,
-                       {
-                               chunk_t keyid;
-                               public_key_t *key = gi.key->public_key;
-
-                               if (gi.gw_key_present &&
-                                       key->get_fingerprint(key, KEYID_PUBKEY_SHA1, &keyid))
-                               {
-                                       DBG_log("gateway for %s is %s with key %#B",
-                                                       client_id, gi.gw_id, &keyid);
-                               }
-                               else
-                               {
-                                       DBG_log("gateway for '%Y' is '%Y'; no key specified",
-                                                       client_id, gi.gw_id);
-                               }
-                       });
-
-               gi.next = *gwip;
-               *gwip = clone_thing(gi);
-               (*gwip)->gw_id = (*gwip)->gw_id->clone((*gwip)->gw_id);
-               (*gwip)->client_id = (*gwip)->client_id->clone((*gwip)->client_id);
-       }
-
-       return NULL;
-}
-
-static const char *
-rr_typename(int type)
-{
-       switch (type)
-       {
-       case T_TXT:
-               return "TXT";
-       case T_KEY:
-               return "KEY";
-       default:
-               return "???";
-       }
-}
-
-
-/* structure of Query Reply (RFC 1035 4.1.1):
- *
- *  +---------------------+
- *  |        Header       |
- *  +---------------------+
- *  |       Question      | the question for the name server
- *  +---------------------+
- *  |        Answer       | RRs answering the question
- *  +---------------------+
- *  |      Authority      | RRs pointing toward an authority
- *  +---------------------+
- *  |      Additional     | RRs holding additional information
- *  +---------------------+
- */
-
-/* Header section format (as modified by RFC 2535 6.1):
- *                                  1  1  1  1  1  1
- *    0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
- *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- *  |                      ID                       |
- *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- *  |QR|   Opcode  |AA|TC|RD|RA| Z|AD|CD|   RCODE   |
- *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- *  |                    QDCOUNT                    |
- *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- *  |                    ANCOUNT                    |
- *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- *  |                    NSCOUNT                    |
- *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- *  |                    ARCOUNT                    |
- *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- */
-struct qr_header {
-       u_int16_t   id;     /* 16-bit identifier to match query */
-
-       u_int16_t   stuff;  /* packed crud: */
-
-#define QRS_QR  0x8000  /* QR: on if this is a response */
-
-#define QRS_OPCODE_SHIFT        11  /* OPCODE field */
-#define QRS_OPCODE_MASK 0xF
-#define QRSO_QUERY      0   /* standard query */
-#define QRSO_IQUERY     1   /* inverse query */
-#define QRSO_STATUS     2   /* server status request query */
-
-#define QRS_AA 0x0400   /* AA: on if Authoritative Answer */
-#define QRS_TC 0x0200   /* TC: on if truncation happened */
-#define QRS_RD 0x0100   /* RD: on if recursion desired */
-#define QRS_RA 0x0080   /* RA: on if recursion available */
-#define QRS_Z  0x0040   /* Z: reserved; must be zero */
-#define QRS_AD 0x0020   /* AD: on if authentic data (RFC 2535) */
-#define QRS_CD 0x0010   /* AD: on if checking disabled (RFC 2535) */
-
-#define QRS_RCODE_SHIFT 0 /* RCODE field: response code */
-#define QRS_RCODE_MASK  0xF
-#define QRSR_OK     0
-
-
-       u_int16_t qdcount;      /* number of entries in question section */
-       u_int16_t ancount;      /* number of resource records in answer section */
-       u_int16_t nscount;      /* number of name server resource records in authority section */
-       u_int16_t arcount;      /* number of resource records in additional records section */
-};
-
-static field_desc qr_header_fields[] = {
-       { ft_nat, 16/BITS_PER_BYTE, "ID", NULL },
-       { ft_nat, 16/BITS_PER_BYTE, "stuff", NULL },
-       { ft_nat, 16/BITS_PER_BYTE, "QD Count", NULL },
-       { ft_nat, 16/BITS_PER_BYTE, "Answer Count", NULL },
-       { ft_nat, 16/BITS_PER_BYTE, "Authority Count", NULL },
-       { ft_nat, 16/BITS_PER_BYTE, "Additional Count", NULL },
-       { ft_end, 0, NULL, NULL }
-};
-
-static struct_desc qr_header_desc = {
-       "Query Response Header",
-       qr_header_fields,
-       sizeof(struct qr_header)
-};
-
-/* Messages for codes in RCODE (see RFC 1035 4.1.1) */
-static const err_t rcode_text[QRS_RCODE_MASK + 1] = {
-       NULL,   /* not an error */
-       "Format error - The name server was unable to interpret the query",
-       "Server failure - The name server was unable to process this query"
-               " due to a problem with the name server",
-       "Name Error - Meaningful only for responses from an authoritative name"
-               " server, this code signifies that the domain name referenced in"
-               " the query does not exist",
-       "Not Implemented - The name server does not support the requested"
-               " kind of query",
-       "Refused - The name server refuses to perform the specified operation"
-               " for policy reasons",
-       /* the rest are reserved for future use */
-       };
-
-/* throw away a possibly compressed domain name */
-
-static err_t
-eat_name(pb_stream *pbs)
-{
-       u_char name_buf[NS_MAXDNAME + 2];
-       u_char *ip = pbs->cur;
-       unsigned oi = 0;
-       unsigned jump_count = 0;
-
-       for (;;)
-       {
-               u_int8_t b;
-
-               if (ip >= pbs->roof)
-                       return "ran out of message while skipping domain name";
-
-               b = *ip++;
-               if (jump_count == 0)
-                       pbs->cur = ip;
-
-               if (b == 0)
-                       break;
-
-               switch (b & 0xC0)
-               {
-                       case 0x00:
-                               /* we grab the next b characters */
-                               if (oi + b > NS_MAXDNAME)
-                                       return "domain name too long";
-
-                               if (pbs->roof - ip <= b)
-                                       return "domain name falls off end of message";
-
-                               if (oi != 0)
-                                       name_buf[oi++] = '.';
-
-                               memcpy(name_buf + oi, ip, b);
-                               oi += b;
-                               ip += b;
-                               if (jump_count == 0)
-                                       pbs->cur = ip;
-                               break;
-
-                       case 0xC0:
-                               {
-                                       unsigned ix;
-
-                                       if (ip >= pbs->roof)
-                                               return "ran out of message in middle of compressed domain name";
-
-                                       ix = ((b & ~0xC0u) << 8) | *ip++;
-                                       if (jump_count == 0)
-                                               pbs->cur = ip;
-
-                                       if (ix >= pbs_room(pbs))
-                                               return "impossible compressed domain name";
-
-                                       /* Avoid infinite loop.
-                                        * There can be no more jumps than there are bytes
-                                        * in the packet.  Not a tight limit, but good enough.
-                                        */
-                                       jump_count++;
-                                       if (jump_count > pbs_room(pbs))
-                                               return "loop in compressed domain name";
-
-                                       ip = pbs->start + ix;
-                               }
-                               break;
-
-                       default:
-                               return "invalid code in label";
-               }
-       }
-
-       name_buf[oi++] = '\0';
-
-       DBG(DBG_DNS, DBG_log("skipping name %s", name_buf));
-
-       return NULL;
-}
-
-static err_t
-eat_name_helpfully(pb_stream *pbs, const char *context)
-{
-       err_t ugh = eat_name(pbs);
-
-       return ugh == NULL? ugh
-               : builddiag("malformed name within DNS record of %s: %s", context, ugh);
-}
-
-/* non-variable part of 4.1.2 Question Section entry:
- *                                 1  1  1  1  1  1
- *   0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- * |                                               |
- * /                     QNAME                     /
- * /                                               /
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- * |                     QTYPE                     |
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- * |                     QCLASS                    |
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- */
-
-struct qs_fixed {
-       u_int16_t qtype;
-       u_int16_t qclass;
-};
-
-static field_desc qs_fixed_fields[] = {
-       { ft_loose_enum, 16/BITS_PER_BYTE, "QTYPE", &rr_qtype_names },
-       { ft_loose_enum, 16/BITS_PER_BYTE, "QCLASS", &rr_class_names },
-       { ft_end, 0, NULL, NULL }
-};
-
-static struct_desc qs_fixed_desc = {
-       "Question Section entry fixed part",
-       qs_fixed_fields,
-       sizeof(struct qs_fixed)
-};
-
-/* 4.1.3. Resource record format:
- *                                 1  1  1  1  1  1
- *   0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- * |                                               |
- * /                                               /
- * /                      NAME                     /
- * |                                               |
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- * |                      TYPE                     |
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- * |                     CLASS                     |
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- * |                      TTL                      |
- * |                                               |
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- * |                   RDLENGTH                    |
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
- * /                     RDATA                     /
- * /                                               /
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- */
-
-struct rr_fixed {
-       u_int16_t type;
-       u_int16_t class;
-       u_int32_t ttl;      /* actually signed */
-       u_int16_t rdlength;
-};
-
-
-static field_desc rr_fixed_fields[] = {
-       { ft_loose_enum, 16/BITS_PER_BYTE, "type", &rr_type_names },
-       { ft_loose_enum, 16/BITS_PER_BYTE, "class", &rr_class_names },
-       { ft_nat, 32/BITS_PER_BYTE, "TTL", NULL },
-       { ft_nat, 16/BITS_PER_BYTE, "RD length", NULL },
-       { ft_end, 0, NULL, NULL }
-};
-
-static struct_desc rr_fixed_desc = {
-       "Resource Record fixed part",
-       rr_fixed_fields,
-       /* note: following is tricky: avoids padding problems */
-       offsetof(struct rr_fixed, rdlength) + sizeof(u_int16_t)
-};
-
-/* RFC 1035 3.3.14: TXT RRs have text in the RDATA field.
- * It is in the form of a sequence of <character-string>s as described in 3.3.
- * unpack_txt_rdata() deals with this peculiar representation.
- */
-
-/* RFC 2535 3.1 KEY RDATA format:
- *
- *                      1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * |             flags             |    protocol   |   algorithm   |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * |                                                               /
- * /                          public key                           /
- * /                                                               /
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
- */
-
-struct key_rdata {
-       u_int16_t flags;
-       u_int8_t protocol;
-       u_int8_t algorithm;
-};
-
-static field_desc key_rdata_fields[] = {
-       { ft_nat, 16/BITS_PER_BYTE, "flags", NULL },
-       { ft_nat, 8/BITS_PER_BYTE, "protocol", NULL },
-       { ft_nat, 8/BITS_PER_BYTE, "algorithm", NULL },
-       { ft_end, 0, NULL, NULL }
-};
-
-static struct_desc key_rdata_desc = {
-       "KEY RR RData fixed part",
-       key_rdata_fields,
-       sizeof(struct key_rdata)
-};
-
-/* RFC 2535 4.1 SIG RDATA format:
- *
- *                      1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * |        type covered           |  algorithm    |     labels    |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * |                         original TTL                          |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * |                      signature expiration                     |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * |                      signature inception                      |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * |            key  tag           |                               |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+         signer's name         +
- * |                                                               /
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-/
- * /                                                               /
- * /                            signature                          /
- * /                                                               /
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-
-struct sig_rdata {
-       u_int16_t type_covered;
-       u_int8_t algorithm;
-       u_int8_t labels;
-       u_int32_t original_ttl;
-       u_int32_t sig_expiration;
-       u_int32_t sig_inception;
-       u_int16_t key_tag;
-};
-
-static field_desc sig_rdata_fields[] = {
-       { ft_nat, 16/BITS_PER_BYTE, "type_covered", NULL},
-       { ft_nat, 8/BITS_PER_BYTE, "algorithm", NULL},
-       { ft_nat, 8/BITS_PER_BYTE, "labels", NULL},
-       { ft_nat, 32/BITS_PER_BYTE, "original ttl", NULL},
-       { ft_nat, 32/BITS_PER_BYTE, "sig expiration", NULL},
-       { ft_nat, 32/BITS_PER_BYTE, "sig inception", NULL},
-       { ft_nat, 16/BITS_PER_BYTE, "key tag", NULL},
-       { ft_end, 0, NULL, NULL }
-};
-
-static struct_desc sig_rdata_desc = {
-       "SIG RR RData fixed part",
-       sig_rdata_fields,
-       sizeof(struct sig_rdata)
-};
-
-/* handle a KEY Resource Record. */
-
-#ifdef USE_KEYRR
-static err_t
-process_key_rr(u_char *ptr, size_t len
-, bool doit     /* should we capture information? */
-, enum dns_auth_level dns_auth_level
-, struct adns_continuation *const cr)
-{
-       pb_stream pbs;
-       struct key_rdata kr;
-
-       if (len < sizeof(struct key_rdata))
-               return "KEY Resource Record's RD Length is too small";
-
-       init_pbs(&pbs, ptr, len, "KEY RR");
-
-       if (!in_struct(&kr, &key_rdata_desc, &pbs, NULL))
-               return "failed to get fixed part of KEY Resource Record RDATA";
-
-       if (kr.protocol == 4        /* IPSEC (RFC 2535 3.1.3) */
-       && kr.algorithm == 1        /* RSA/MD5 (RFC 2535 3.2) */
-       && (kr.flags & 0x8000) == 0 /* use for authentication (3.1.2) */
-       && (kr.flags & 0x2CF0) == 0)        /* must be zero */
-       {
-               /* we have what seems to be a tasty key */
-
-               if (doit)
-               {
-                       chunk_t k = { pbs.cur, pbs_left(&pbs) };
-
-                       TRY(add_public_key(&cr->id, dns_auth_level, PUBKEY_ALG_RSA, &k
-                               , &cr->keys_from_dns));
-               }
-       }
-       return NULL;
-}
-#endif /* USE_KEYRR */
-
-
-/* unpack TXT rr RDATA into C string.
- * A sequence of <character-string>s as described in RFC 1035 3.3.
- * We concatenate them.
- */
-static err_t
-unpack_txt_rdata(u_char *d, size_t dlen, const u_char *s, size_t slen)
-{
-       size_t i = 0
-               , o = 0;
-
-       while (i < slen)
-       {
-               size_t cl = s[i++];
-
-               if (i + cl > slen)
-                       return "TXT rr RDATA representation malformed";
-
-               if (o + cl >= dlen)
-                       return "TXT rr RDATA too large";
-
-               memcpy(d + o, s + i, cl);
-               i += cl;
-               o += cl;
-       }
-       d[o] = '\0';
-       if (strlen(d) != o)
-               return "TXT rr RDATA contains a NUL";
-
-       return NULL;
-}
-
-static err_t
-process_txt_rr(u_char *rdata, size_t rdlen
-, bool doit     /* should we capture information? */
-, enum dns_auth_level dns_auth_level
-, struct adns_continuation *const cr)
-{
-       u_char str[RSA_MAX_ENCODING_BYTES * 8 / 6 + 20];    /* space for unpacked RDATA */
-
-       TRY(unpack_txt_rdata(str, sizeof(str), rdata, rdlen));
-       return process_txt_rr_body(str, doit, dns_auth_level, cr);
-}
-
-static err_t
-process_answer_section(pb_stream *pbs
-, bool doit     /* should we capture information? */
-, enum dns_auth_level *dns_auth_level
-, u_int16_t ancount     /* number of RRs in the answer section */
-, struct adns_continuation *const cr)
-{
-       const int type = cr->query.type;    /* type of RR of interest */
-       unsigned c;
-
-       DBG(DBG_DNS, DBG_log("*Answer Section:"));
-
-       for (c = 0; c != ancount; c++)
-       {
-               struct rr_fixed rrf;
-               size_t tail;
-
-               /* ??? do we need to match the name? */
-
-               TRY(eat_name_helpfully(pbs, "Answer Section"));
-
-               if (!in_struct(&rrf, &rr_fixed_desc, pbs, NULL))
-                       return "failed to get fixed part of Answer Section Resource Record";
-
-               if (rrf.rdlength > pbs_left(pbs))
-                       return "RD Length extends beyond end of message";
-
-               /* ??? should we care about ttl? */
-
-               tail = rrf.rdlength;
-
-               if (rrf.type == type && rrf.class == C_IN)
-               {
-                       err_t ugh = NULL;
-
-                       switch (type)
-                       {
-#ifdef USE_KEYRR
-                       case T_KEY:
-                               ugh = process_key_rr(pbs->cur, tail, doit, *dns_auth_level, cr);
-                               break;
-#endif /* USE_KEYRR */
-                       case T_TXT:
-                               ugh = process_txt_rr(pbs->cur, tail, doit, *dns_auth_level, cr);
-                               break;
-                       case T_SIG:
-                               /* Check if SIG RR authenticates what we are learning.
-                                * The RRset covered by a SIG must have the same owner,
-                                * class, and type.
-                                * For us, the class is always C_IN, so that matches.
-                                * We decode the SIG RR's fixed part to check
-                                * that the type_covered field matches our query type
-                                * (this may be redundant).
-                                * We don't check the owner (apparently this is the
-                                * name on the record) -- we assume that it matches
-                                * or we would not have been given this SIG in the
-                                * Answer Section.
-                                *
-                                * We only look on first pass, and only if we've something
-                                * to learn.  This cuts down on useless decoding.
-                                */
-                               if (!doit && *dns_auth_level == DAL_UNSIGNED)
-                               {
-                                       struct sig_rdata sr;
-
-                                       if (!in_struct(&sr, &sig_rdata_desc, pbs, NULL))
-                                               ugh = "failed to get fixed part of SIG Resource Record RDATA";
-                                       else if (sr.type_covered == type)
-                                               *dns_auth_level = DAL_SIGNED;
-                               }
-                               break;
-                       default:
-                               ugh = builddiag("unexpected RR type %d", type);
-                               break;
-                       }
-                       if (ugh != NULL)
-                               return ugh;
-               }
-               in_raw(NULL, tail, pbs, "RR RDATA");
-       }
-
-       return doit
-               && cr->gateways_from_dns == NULL
-#ifdef USE_KEYRR
-               && cr->keys_from_dns == NULL
-#endif /* USE_KEYRR */
-               ? builddiag("no suitable %s record found in DNS", rr_typename(type))
-               : NULL;
-}
-
-/* process DNS answer -- TXT or KEY query */
-
-static err_t
-process_dns_answer(struct adns_continuation *const cr
-, u_char ans[], int anslen)
-{
-       const int type = cr->query.type;    /* type of record being sought */
-       int r;      /* all-purpose return value holder */
-       u_int16_t c;        /* number of current RR in current answer section */
-       pb_stream pbs;
-       u_int8_t *ans_start;        /* saved position of answer section */
-       struct qr_header qr_header;
-       enum dns_auth_level dns_auth_level;
-
-       init_pbs(&pbs, ans, anslen, "Query Response Message");
-
-       /* decode and check header */
-
-       if (!in_struct(&qr_header, &qr_header_desc, &pbs, NULL))
-               return "malformed header";
-
-       /* ID: nothing to do with us */
-
-       /* stuff -- lots of things */
-       if ((qr_header.stuff & QRS_QR) == 0)
-               return "not a response?!?";
-
-       if (((qr_header.stuff >> QRS_OPCODE_SHIFT) & QRS_OPCODE_MASK) != QRSO_QUERY)
-               return "unexpected opcode";
-
-       /* I don't think we care about AA */
-
-       if (qr_header.stuff & QRS_TC)
-               return "response truncated";
-
-       /* I don't think we care about RD, RA, or CD */
-
-       /* AD means "authentic data" */
-       dns_auth_level = qr_header.stuff & QRS_AD? DAL_UNSIGNED : DAL_NOTSEC;
-
-       if (qr_header.stuff & QRS_Z)
-               return "Z bit is not zero";
-
-       r = (qr_header.stuff >> QRS_RCODE_SHIFT) & QRS_RCODE_MASK;
-       if (r != 0)
-               return r < (int)countof(rcode_text)? rcode_text[r] : "unknown rcode";
-
-       if (qr_header.ancount == 0)
-               return builddiag("no %s RR found by DNS", rr_typename(type));
-
-       /* end of header checking */
-
-       /* Question Section processing */
-
-       /* 4.1.2. Question section format:
-        *                                 1  1  1  1  1  1
-        *   0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
-        * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
-        * |                                               |
-        * /                     QNAME                     /
-        * /                                               /
-        * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
-        * |                     QTYPE                     |
-        * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
-        * |                     QCLASS                    |
-        * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
-        */
-
-       DBG(DBG_DNS, DBG_log("*Question Section:"));
-
-       for (c = 0; c != qr_header.qdcount; c++)
-       {
-               struct qs_fixed qsf;
-
-               TRY(eat_name_helpfully(&pbs, "Question Section"));
-
-               if (!in_struct(&qsf, &qs_fixed_desc, &pbs, NULL))
-                       return "failed to get fixed part of Question Section";
-
-               if (qsf.qtype != type)
-                       return "unexpected QTYPE in Question Section";
-
-               if (qsf.qclass != C_IN)
-                       return "unexpected QCLASS in Question Section";
-       }
-
-       /* rest of sections are made up of Resource Records */
-
-       /* Answer Section processing -- error checking, noting T_SIG */
-
-       ans_start = pbs.cur;        /* remember start of answer section */
-
-       TRY(process_answer_section(&pbs, FALSE, &dns_auth_level
-               , qr_header.ancount, cr));
-
-       /* Authority Section processing (just sanity checking) */
-
-       DBG(DBG_DNS, DBG_log("*Authority Section:"));
-
-       for (c = 0; c != qr_header.nscount; c++)
-       {
-               struct rr_fixed rrf;
-               size_t tail;
-
-               TRY(eat_name_helpfully(&pbs, "Authority Section"));
-
-               if (!in_struct(&rrf, &rr_fixed_desc, &pbs, NULL))
-                       return "failed to get fixed part of Authority Section Resource Record";
-
-               if (rrf.rdlength > pbs_left(&pbs))
-                       return "RD Length extends beyond end of message";
-
-               /* ??? should we care about ttl? */
-
-               tail = rrf.rdlength;
-
-               in_raw(NULL, tail, &pbs, "RR RDATA");
-       }
-
-       /* Additional Section processing (just sanity checking) */
-
-       DBG(DBG_DNS, DBG_log("*Additional Section:"));
-
-       for (c = 0; c != qr_header.arcount; c++)
-       {
-               struct rr_fixed rrf;
-               size_t tail;
-
-               TRY(eat_name_helpfully(&pbs, "Additional Section"));
-
-               if (!in_struct(&rrf, &rr_fixed_desc, &pbs, NULL))
-                       return "failed to get fixed part of Additional Section Resource Record";
-
-               if (rrf.rdlength > pbs_left(&pbs))
-                       return "RD Length extends beyond end of message";
-
-               /* ??? should we care about ttl? */
-
-               tail = rrf.rdlength;
-
-               in_raw(NULL, tail, &pbs, "RR RDATA");
-       }
-
-       /* done all sections */
-
-       /* ??? is padding legal, or can we complain if more left in record? */
-
-       /* process Answer Section again -- accept contents */
-
-       pbs.cur = ans_start;        /* go back to start of answer section */
-
-       return process_answer_section(&pbs, TRUE, &dns_auth_level
-               , qr_header.ancount, cr);
-}
-
-/****************************************************************/
-
-static err_t build_dns_name(u_char name_buf[NS_MAXDNAME + 2],
-                                                       unsigned long serial USED_BY_DEBUG,
-                                                       identification_t *id,
-                                                       const char *typename USED_BY_DEBUG,
-                                                       identification_t *gw USED_BY_DEBUG)
-{
-       /* note: all end in "." to suppress relative searches */
-       id = resolve_myid(id);
-
-       switch (id->get_type(id))
-       {
-               case ID_IPV4_ADDR:
-               {
-                       chunk_t b = id->get_encoding(id);
-
-                       snprintf(name_buf, NS_MAXDNAME + 2, "%d.%d.%d.%d.in-addr.arpa.",
-                                                          b.ptr[3], b.ptr[2], b.ptr[1], b.ptr[0]);
-                       break;
-               }
-               case ID_IPV6_ADDR:
-               {
-                       chunk_t b = id->get_encoding(id);
-                       size_t bl;
-                       u_char *op = name_buf;
-                       static const char suffix[] = "IP6.INT.";
-
-                       for (bl = b.len; bl-- != 0; )
-                       {
-                               if (op + 4 + sizeof(suffix) >= name_buf + NS_MAXDNAME + 1)
-                               {
-                                       return "IPv6 reverse name too long";
-                               }
-                               op += sprintf(op, "%x.%x.", b.ptr[bl] & 0xF, b.ptr[bl] >> 4);
-                       }
-                       strcpy(op, suffix);
-                       break;
-               }
-               case ID_FQDN:
-               {
-                       if (snprintf(name_buf, NS_MAXDNAME + 2, "%Y.", id) > NS_MAXDNAME + 1)
-                       {
-                               return "FQDN too long for domain name";
-                       }
-                       break;
-               }
-               default:
-                       return "can only query DNS for key for ID that is a FQDN, IPV4_ADDR, or IPV6_ADDR";
-       }
-
-       DBG(DBG_CONTROL | DBG_DNS,
-               DBG_log("DNS query %lu for %s for %s (gw: %Y)", serial, typename, name_buf, gw)
-       )
-       return NULL;
-}
-
-void gw_addref(struct gw_info *gw)
-{
-       if (gw != NULL)
-       {
-               DBG(DBG_DNS, DBG_log("gw_addref: %p refcnt: %d++", gw, gw->refcnt))
-               gw->refcnt++;
-       }
-}
-
-void gw_delref(struct gw_info **gwp)
-{
-       struct gw_info *gw = *gwp;
-
-       if (gw != NULL)
-       {
-               DBG(DBG_DNS, DBG_log("gw_delref: %p refcnt: %d--", gw, gw->refcnt));
-
-               passert(gw->refcnt != 0);
-               gw->refcnt--;
-               if (gw->refcnt == 0)
-               {
-                       DESTROY_IF(gw->client_id);
-                       DESTROY_IF(gw->gw_id);
-                       if (gw->gw_key_present)
-                       {
-                               unreference_key(&gw->key);
-                       }
-                       gw_delref(&gw->next);
-                       free(gw);   /* trickery could make this a tail-call */
-               }
-               *gwp = NULL;
-       }
-}
-
-static int adns_in_flight = 0;  /* queries outstanding */
-
-/* Start an asynchronous DNS query.
- *
- * For KEY record, the result will be a list in cr->keys_from_dns.
- * For TXT records, the result will be a list in cr->gateways_from_dns.
- *
- * If sgw_id is null, only consider TXT records that specify an
- * IP address for the gatway: we need this in the initiation case.
- *
- * If sgw_id is non-null, only consider TXT records that specify
- * this id as the security gatway; this is useful to the Responder
- * for confirming claims of gateways.
- *
- * Continuation cr gives information for continuing when the result shows up.
- *
- * Two kinds of errors must be handled: synchronous (immediate)
- * and asynchronous.  Synchronous errors are indicated by the returned
- * value of start_adns_query; in this case, the continuation will
- * have been freed and the continuation routine will not be called.
- * Asynchronous errors are indicated by the ugh parameter passed to the
- * continuation routine.
- *
- * After the continuation routine has completed, handle_adns_answer
- * will free the continuation.  The continuation routine should have
- * freed any axiliary resources.
- *
- * Note: in the synchronous error case, start_adns_query will have
- * freed the continuation; this means that the caller will have to
- * be very careful to release any auxiliary resources that were in
- * the continuation record without using the continuation record.
- *
- * Either there will be an error result passed to the continuation routine,
- * or the results will be in cr->keys_from_dns or cr->gateways_from_dns.
- * The result variables must by left NULL by the continutation routine.
- * The continuation routine is responsible for establishing and
- * disestablishing any logging context (whack_log_fd, cur_*).
- */
-
-static struct adns_continuation *continuations = NULL;  /* newest of queue */
-static struct adns_continuation *next_query = NULL;     /* oldest not sent */
-
-static struct adns_continuation *continuation_for_qtid(unsigned long qtid)
-{
-       struct adns_continuation *cr = NULL;
-
-       if (qtid != 0)
-       {
-               for (cr = continuations; cr != NULL && cr->qtid != qtid; cr = cr->previous)
-                       ;
-       }
-       return cr;
-}
-
-static void release_adns_continuation(struct adns_continuation *cr)
-{
-       passert(cr != next_query);
-       gw_delref(&cr->gateways_from_dns);
-#ifdef USE_KEYRR
-       free_public_keys(&cr->keys_from_dns);
-#endif /* USE_KEYRR */
-       cr->id = cr->id->clone(cr->id);
-       cr->sgw_id = cr->sgw_id->clone(cr->sgw_id);
-
-       /* unlink from doubly-linked list */
-       if (cr->next == NULL)
-       {
-               continuations = cr->previous;
-       }
-       else
-       {
-               cr->next->previous = cr->previous;
-       }
-
-       if (cr->previous != NULL)
-       {
-               cr->previous->next = cr->next;
-       }
-
-       free(cr);
-}
-
-err_t start_adns_query(identification_t *id,     /* domain to query */
-                                          identification_t *sgw_id, /* if non-null, any accepted gw_info must match */
-                                          int type,                 /* T_TXT or T_KEY, selecting rr type of interest */
-                                          cont_fn_t cont_fn,
-                                          struct adns_continuation *cr)
-{
-       static unsigned long qtid = 1;      /* query transaction id; NOTE: static */
-       const char *typename = rr_typename(type);
-
-       if(adns_pid == 0 && adns_restart_count < ADNS_RESTART_MAX)
-       {
-               plog("ADNS helper was not running. Restarting attempt %d",adns_restart_count);
-               init_adns();
-       }
-
-       /* Splice this in at head of doubly-linked list of continuations.
-        * Note: this must be done before any release_adns_continuation().
-        */
-       cr->next = NULL;
-       cr->previous = continuations;
-       if (continuations != NULL)
-       {
-               continuations->next = cr;
-       }
-       continuations = cr;
-
-       cr->qtid = qtid++;
-       cr->type = type;
-       cr->cont_fn = cont_fn;
-       cr->id = id->clone(id);
-       cr->sgw_specified = (sgw_id != NULL);
-       cr->sgw_id = cr->sgw_specified ?
-                                               sgw_id->clone(sgw_id) :
-                                               identification_create_from_string("%any");
-       cr->gateways_from_dns = NULL;
-#ifdef USE_KEYRR
-       cr->keys_from_dns = NULL;
-#endif /* USE_KEYRR */
-
-#ifdef DEBUG
-       cr->debugging = cur_debugging;
-#else
-       cr->debugging = LEMPTY;
-#endif
-
-       zero(&cr->query);
-       {
-               err_t ugh = build_dns_name(cr->query.name_buf, cr->qtid, id,
-                                                                  typename, cr->sgw_id);
-
-               if (ugh)
-               {
-                       release_adns_continuation(cr);
-                       return ugh;
-               }
-       }
-
-       if (next_query == NULL)
-               next_query = cr;
-
-       unsent_ADNS_queries = TRUE;
-
-       return NULL;
-}
-
-/* send remaining ADNS queries (until pipe full or none left)
- *
- * This is a co-routine, so it uses static variables to
- * preserve state across calls.
- */
-bool unsent_ADNS_queries = FALSE;
-
-void
-send_unsent_ADNS_queries(void)
-{
-       static const unsigned char *buf_end = NULL; /* NOTE STATIC */
-       static const unsigned char *buf_cur = NULL; /* NOTE STATIC */
-
-       if (adns_qfd == NULL_FD)
-               return; /* nothing useful to do */
-
-       for (;;)
-       {
-               if (buf_cur != buf_end)
-               {
-                       static int try = 0; /* NOTE STATIC */
-                       size_t n = buf_end - buf_cur;
-                       ssize_t r = write(adns_qfd, buf_cur, n);
-
-                       if (r == -1)
-                       {
-                               switch (errno)
-                               {
-                               case EINTR:
-                                       continue;   /* try again now */
-                               case EAGAIN:
-                                       DBG(DBG_DNS, DBG_log("EAGAIN writing to ADNS"));
-                                       break;      /* try again later */
-                               default:
-                                       try++;
-                                       log_errno((e, "error %d writing DNS query", try));
-                                       break;      /* try again later */
-                               }
-                               unsent_ADNS_queries = TRUE;
-                               break;  /* done! */
-                       }
-                       else
-                       {
-                               passert(r >= 0);
-                               try = 0;
-                               buf_cur += r;
-                       }
-               }
-               else
-               {
-                       if (next_query == NULL)
-                       {
-                               unsent_ADNS_queries = FALSE;
-                               break;  /* done! */
-                       }
-
-                       next_query->query.debugging = next_query->debugging;
-                       next_query->query.serial = next_query->qtid;
-                       next_query->query.len = sizeof(next_query->query);
-                       next_query->query.qmagic = ADNS_Q_MAGIC;
-                       next_query->query.type = next_query->type;
-                       buf_cur = (const void *)&next_query->query;
-                       buf_end = buf_cur + sizeof(next_query->query);
-
-                       next_query = next_query->next;
-                       adns_in_flight++;
-               }
-       }
-}
-
-static void recover_adns_die(void)
-{
-       struct adns_continuation *cr = NULL;
-
-       adns_pid = 0;
-       if(adns_restart_count < ADNS_RESTART_MAX) {
-               adns_restart_count++;
-
-               /* next DNS query will restart it */
-
-               /* we have to walk the list of the outstanding requests,
-                * and redo them!
-                */
-
-               cr = continuations;
-
-               /* find the head of the list */
-               if(continuations != NULL) {
-                       for (; cr->previous != NULL; cr = cr->previous);
-               }
-
-               next_query = cr;
-
-               if(next_query != NULL) {
-                       unsent_ADNS_queries = TRUE;
-               }
-       }
-}
-
-void reset_adns_restart_count(void)
-{
-       adns_restart_count=0;
-}
-
-void handle_adns_answer(void)
-{
-  /* These are retained across calls to handle_adns_answer. */
-       static size_t buflen = 0;   /* bytes in answer buffer */
-       static struct adns_answer buf;
-
-       ssize_t n;
-
-       passert(buflen < sizeof(buf));
-       n = read(adns_afd, (unsigned char *)&buf + buflen, sizeof(buf) - buflen);
-
-       if (n < 0)
-       {
-               if (errno != EINTR)
-               {
-                       log_errno((e, "error reading answer from adns"));
-                       /* ??? how can we recover? */
-               }
-               n = 0;  /* now n reflects amount read */
-       }
-       else if (n == 0)
-       {
-               /* EOF */
-               if (adns_in_flight != 0)
-               {
-                       plog("EOF from ADNS with %d queries outstanding (restarts %d)"
-                                , adns_in_flight, adns_restart_count);
-                       recover_adns_die();
-               }
-               if (buflen != 0)
-               {
-                       plog("EOF from ADNS with %lu bytes of a partial answer outstanding"
-                                "(restarts %d)"
-                                , (unsigned long)buflen
-                                ,  adns_restart_count);
-                       recover_adns_die();
-               }
-               stop_adns();
-               return;
-       }
-       else
-       {
-               passert(adns_in_flight > 0);
-       }
-
-       buflen += n;
-       while (buflen >= offsetof(struct adns_answer, ans) && buflen >= buf.len)
-       {
-               /* we've got a tasty answer -- process it */
-               err_t ugh;
-               struct adns_continuation *cr = continuation_for_qtid(buf.serial);       /* assume it works */
-               const char *typename = rr_typename(cr->query.type);
-               const char *name_buf = cr->query.name_buf;
-
-#ifdef USE_KEYRR
-               passert(cr->keys_from_dns == NULL);
-#endif /* USE_KEYRR */
-               passert(cr->gateways_from_dns == NULL);
-               adns_in_flight--;
-               if (buf.result == -1)
-               {
-                       /* newer resolvers support statp->res_h_errno as well as h_errno.
-                        * That might be better, but older resolvers don't.
-                        * See resolver(3), if you have it.
-                        * The undocumented(!) h_errno values are defined in
-                        * /usr/include/netdb.h.
-                        */
-                       switch (buf.h_errno_val)
-                       {
-                       case NO_DATA:
-                               ugh = builddiag("no %s record for %s", typename, name_buf);
-                               break;
-                       case HOST_NOT_FOUND:
-                               ugh = builddiag("no host %s for %s record", name_buf, typename);
-                               break;
-                       default:
-                               ugh = builddiag("failure querying DNS for %s of %s: %s"
-                                       , typename, name_buf, hstrerror(buf.h_errno_val));
-                               break;
-                       }
-               }
-               else if (buf.result > (int) sizeof(buf.ans))
-               {
-                       ugh = builddiag("(INTERNAL ERROR) answer too long (%ld) for buffer"
-                               , (long)buf.result);
-               }
-               else
-               {
-                       ugh = process_dns_answer(cr, buf.ans, buf.result);
-                       if (ugh != NULL)
-                               ugh = builddiag("failure processing %s record of DNS answer for %s: %s"
-                                       , typename, name_buf, ugh);
-               }
-               DBG(DBG_RAW | DBG_CRYPT | DBG_PARSING | DBG_CONTROL | DBG_DNS,
-                       DBG_log(BLANK_FORMAT);
-                       if (ugh == NULL)
-                               DBG_log("asynch DNS answer %lu for %s of %s"
-                                       , cr->query.serial, typename, name_buf);
-                       else
-                               DBG_log("asynch DNS answer %lu %s", cr->query.serial, ugh);
-                       );
-
-               passert(GLOBALS_ARE_RESET());
-               cr->cont_fn(cr, ugh);
-               reset_globals();
-               release_adns_continuation(cr);
-
-               /* shift out answer that we've consumed */
-               buflen -= buf.len;
-               memmove((unsigned char *)&buf, (unsigned char *)&buf + buf.len, buflen);
-       }
-}
diff --git a/src/pluto/dnskey.h b/src/pluto/dnskey.h
deleted file mode 100644 (file)
index 39a406c..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/* Find public key in DNS
- * Copyright (C) 2000-2002  D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <utils/identification.h>
-
-extern int adns_qfd;   /* file descriptor for sending queries to adns */
-extern int adns_afd;   /* file descriptor for receiving answers from adns */
-extern const char *pluto_adns_option;   /* path from --pluto_adns */
-extern void init_adns(void);
-extern void stop_adns(void);
-extern void handle_adns_answer(void);
-
-extern bool unsent_ADNS_queries;
-extern void send_unsent_ADNS_queries(void);
-
-/* (common prefix of) stuff remembered between async query and answer.
- * Filled in by start_adns_query.
- * Freed by call to release_adns_continuation.
- */
-
-struct adns_continuation;       /* forward declaration (not far!) */
-
-typedef void (*cont_fn_t)(struct adns_continuation *cr, err_t ugh);
-
-struct adns_continuation {
-       unsigned long qtid;    /* query transaction id number */
-       int type;              /* T_TXT or T_KEY, selecting rr type of interest */
-       cont_fn_t cont_fn;     /* function to carry on suspended work */
-       identification_t *id;  /* subject of query */
-       bool sgw_specified;
-       identification_t *sgw_id; /* peer, if constrained */
-       lset_t debugging;      /* only used #ifdef DEBUG, but don't want layout to change */
-       struct gw_info *gateways_from_dns;  /* answer, if looking for our TXT rrs */
-#ifdef USE_KEYRR
-       struct pubkey_list *keys_from_dns;  /* answer, if looking for KEY rrs */
-#endif
-       struct adns_continuation *previous, *next;
-       struct pubkey *last_info;  /* the last structure we accumulated */
-       struct adns_query query;
-};
-
-extern err_t start_adns_query(identification_t *id       /* domain to query */
-       , identification_t *sgw_id   /* if non-null, any accepted gw_info must match */
-       , int type  /* T_TXT or T_KEY, selecting rr type of interest */
-       , cont_fn_t cont_fn /* continuation function */
-       , struct adns_continuation *cr);
-
-
-/* Gateway info gleaned from reverse DNS of client */
-struct gw_info {
-       unsigned refcnt;             /* reference counted! */
-       unsigned pref;               /* preference: lower is better */
-#define NO_TIME ((time_t) -2)    /* time_t value meaning "not_yet" */
-       identification_t* client_id; /* id of client of peer */
-       identification_t* gw_id;     /* id of peer (if id_is_ipaddr, .ip_addr is address) */
-       bool gw_key_present;
-       struct pubkey *key;
-       struct gw_info *next;
-};
-
-extern void gw_addref(struct gw_info *gw);
-extern void gw_delref(struct gw_info **gwp);
-extern void reset_adns_restart_count(void);
-
diff --git a/src/pluto/event_queue.c b/src/pluto/event_queue.c
deleted file mode 100644 (file)
index 602a013..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (C) 2010 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <unistd.h>
-#include <fcntl.h>
-
-#include "event_queue.h"
-
-#include <debug.h>
-#include <threading/mutex.h>
-#include <utils/linked_list.h>
-
-typedef struct private_event_queue_t private_event_queue_t;
-
-/**
- * Private data of event_queue_t class.
- */
-struct private_event_queue_t {
-       /**
-        * Public event_queue_t interface.
-        */
-       event_queue_t public;
-
-       /**
-        * List of queued events (event_t*).
-        */
-       linked_list_t *events;
-
-       /**
-        * Mutex for event list.
-        */
-       mutex_t *mutex;
-
-       /**
-        * Read end of the notification pipe.
-        */
-       int read_fd;
-
-       /**
-        * Write end of the notification pipe.
-        */
-       int write_fd;
-
-};
-
-typedef struct event_t event_t;
-
-struct event_t {
-       /**
-        * Callback function.
-        */
-       void (*callback)(void *data);
-
-       /**
-        * Data to supply to the callback.
-        */
-       void *data;
-
-       /**
-        * Cleanup function.
-        */
-       void (*cleanup)(void *data);
-};
-
-static event_t *event_create(void (*callback)(void *data), void *data,
-                                                        void (*cleanup)(void *data))
-{
-       event_t *this;
-       INIT(this,
-               .callback = callback,
-               .data = data,
-               .cleanup = cleanup,
-       );
-       return this;
-}
-
-static void event_destroy(event_t *this)
-{
-       if (this->cleanup)
-       {
-               this->cleanup(this->data);
-       }
-       free(this);
-}
-
-METHOD(event_queue_t, get_event_fd, int,
-          private_event_queue_t *this)
-{
-       return this->read_fd;
-}
-
-METHOD(event_queue_t, handle, void,
-          private_event_queue_t *this)
-{
-       char buf[10];
-       linked_list_t *events;
-       event_t *event;
-       this->mutex->lock(this->mutex);
-       /* flush pipe */
-       while (read(this->read_fd, &buf, sizeof(buf)) == sizeof(buf));
-       /* replace the list, so we can unlock the mutex while executing the jobs */
-       events = this->events;
-       this->events = linked_list_create();
-       this->mutex->unlock(this->mutex);
-
-       while (events->remove_first(events, (void**)&event) == SUCCESS)
-       {
-               event->callback(event->data);
-               event_destroy(event);
-       }
-       events->destroy(events);
-}
-
-METHOD(event_queue_t, queue, void,
-          private_event_queue_t *this, void (*callback)(void *data), void *data,
-          void (*cleanup)(void *data))
-{
-       event_t *event = event_create(callback, data, cleanup);
-       char c = 0;
-       this->mutex->lock(this->mutex);
-       this->events->insert_last(this->events, event);
-       ignore_result(write(this->write_fd, &c, 1));
-       this->mutex->unlock(this->mutex);
-}
-
-METHOD(event_queue_t, destroy, void,
-          private_event_queue_t *this)
-{
-       this->mutex->lock(this->mutex);
-       this->events->destroy_function(this->events, (void*)event_destroy);
-       this->mutex->unlock(this->mutex);
-       this->mutex->destroy(this->mutex);
-       close(this->read_fd);
-       close(this->write_fd);
-       free(this);
-}
-
-static bool set_nonblock(int socket)
-{
-       int flags = fcntl(socket, F_GETFL);
-       return flags != -1 && fcntl(socket, F_SETFL, flags | O_NONBLOCK) != -1;
-}
-
-static bool set_cloexec(int socket)
-{
-       int flags = fcntl(socket, F_GETFD);
-       return flags != -1 && fcntl(socket, F_SETFD, flags | FD_CLOEXEC) != -1;
-}
-
-/*
- * Described in header.
- */
-event_queue_t *event_queue_create()
-{
-       private_event_queue_t *this;
-       int fd[2];
-
-       INIT(this,
-               .public = {
-                       .get_event_fd = _get_event_fd,
-                       .handle = _handle,
-                       .queue = _queue,
-                       .destroy = _destroy,
-               },
-               .events = linked_list_create(),
-               .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
-       );
-
-       if (pipe(fd) == -1 ||
-               !set_nonblock(fd[0]) || !set_cloexec(fd[0]) ||
-               !set_nonblock(fd[1]) || !set_cloexec(fd[1]))
-       {
-               DBG1(DBG_JOB, "failed to create pipe for job queue");
-               _destroy(this);
-               return NULL;
-       }
-
-       this->read_fd = fd[0];
-       this->write_fd = fd[1];
-
-       return &this->public;
-}
-
diff --git a/src/pluto/event_queue.h b/src/pluto/event_queue.h
deleted file mode 100644 (file)
index 343729e..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2010 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup event_queue event_queue
- * @{ @ingroup pluto
- */
-
-#ifndef EVENT_QUEUE_H_
-#define EVENT_QUEUE_H_
-
-typedef struct event_queue_t event_queue_t;
-
-/**
- * The event queue facility can be used to synchronize thread-pool threads
- * with the pluto main thread.  That is, all queued callbacks are executed
- * asynchronously by the pluto main thread.
- */
-struct event_queue_t {
-
-       /**
-        * Returns the file descriptor used to notify the main thread.
-        *
-        * @return                              fd to use in the main thread
-        */
-       int (*get_event_fd) (event_queue_t *this);
-
-       /**
-        * Handle all queued events.
-        */
-       void (*handle) (event_queue_t *this);
-
-       /**
-        * Add an event to the queue.
-        *
-        * @param callback              callback function to add to the queue
-        * @param data                  data supplied to the callback function
-        * @param cleanup               optional cleanup function
-        */
-       void (*queue) (event_queue_t *this, void (*callback)(void *data),
-                                  void *data, void (*cleanup)(void *data));
-
-       /**
-        * Destroy this instance.
-        */
-       void (*destroy) (event_queue_t *this);
-
-};
-
-/**
- * Create the event queue.
- *
- * @return                                     created object
- */
-event_queue_t *event_queue_create();
-
-#endif /** EVENT_QUEUE_H_ @}*/
diff --git a/src/pluto/fetch.c b/src/pluto/fetch.c
deleted file mode 100644 (file)
index 3dfc138..0000000
+++ /dev/null
@@ -1,766 +0,0 @@
-/* Dynamic fetching of X.509 CRLs
- * Copyright (C) 2002 Stephane Laroche <stephane.laroche@colubris.com>
- * Copyright (C) 2002-2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <stdlib.h>
-#include <errno.h>
-#include <sys/time.h>
-#include <time.h>
-#include <string.h>
-
-#ifdef THREADS
-#include <pthread.h>
-#endif
-
-#include <freeswan.h>
-
-#include <library.h>
-#include <debug.h>
-#include <asn1/asn1.h>
-#include <credentials/certificates/certificate.h>
-#ifdef THREADS
-#include <threading/thread.h>
-#endif
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "x509.h"
-#include "ca.h"
-#include "whack.h"
-#include "ocsp.h"
-#include "crl.h"
-#include "fetch.h"
-#include "builder.h"
-
-fetch_req_t empty_fetch_req = {
-       NULL    , /* next */
-                 0 , /* trials */
-    NULL    , /* issuer */
-  { NULL, 0}, /* authKeyID */
-       NULL      /* distributionPoints */
-};
-
-/* chained list of crl fetch requests */
-static fetch_req_t *crl_fetch_reqs  = NULL;
-
-/* chained list of ocsp fetch requests */
-static ocsp_location_t *ocsp_fetch_reqs = NULL;
-
-#ifdef THREADS
-static thread_t *thread;
-static pthread_mutex_t certs_and_keys_mutex  = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t authcert_list_mutex   = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t crl_list_mutex        = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t ocsp_cache_mutex      = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t ca_info_list_mutex    = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t crl_fetch_list_mutex  = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t ocsp_fetch_list_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t fetch_wake_mutex      = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t  fetch_wake_cond       = PTHREAD_COND_INITIALIZER;
-
-/**
- * lock access to my certs and keys
- */
-void lock_certs_and_keys(const char *who)
-{
-       pthread_mutex_lock(&certs_and_keys_mutex);
-       DBG(DBG_CONTROLMORE,
-               DBG_log("certs and keys locked by '%s'", who)
-       )
-}
-
-/**
- * Unlock access to my certs and keys
- */
-void unlock_certs_and_keys(const char *who)
-{
-       DBG(DBG_CONTROLMORE,
-               DBG_log("certs and keys unlocked by '%s'", who)
-       )
-       pthread_mutex_unlock(&certs_and_keys_mutex);
-}
-
-/**
- * Lock access to the chained authcert list
- */
-void lock_authcert_list(const char *who)
-{
-       pthread_mutex_lock(&authcert_list_mutex);
-       DBG(DBG_CONTROLMORE,
-               DBG_log("authcert list locked by '%s'", who)
-       )
-}
-
-/**
- * Unlock access to the chained authcert list
- */
-void unlock_authcert_list(const char *who)
-{
-       DBG(DBG_CONTROLMORE,
-               DBG_log("authcert list unlocked by '%s'", who)
-       )
-       pthread_mutex_unlock(&authcert_list_mutex);
-}
-
-/**
- * Lock access to the chained crl list
- */
-void lock_crl_list(const char *who)
-{
-       pthread_mutex_lock(&crl_list_mutex);
-       DBG(DBG_CONTROLMORE,
-               DBG_log("crl list locked by '%s'", who)
-       )
-}
-
-/**
- * Unlock access to the chained crl list
- */
-void unlock_crl_list(const char *who)
-{
-       DBG(DBG_CONTROLMORE,
-               DBG_log("crl list unlocked by '%s'", who)
-       )
-       pthread_mutex_unlock(&crl_list_mutex);
-}
-
-/**
- * Lock access to the ocsp cache
- */
-extern void lock_ocsp_cache(const char *who)
-{
-       pthread_mutex_lock(&ocsp_cache_mutex);
-       DBG(DBG_CONTROLMORE,
-               DBG_log("ocsp cache locked by '%s'", who)
-       )
-}
-
-/**
- * Unlock access to the ocsp cache
- */
-extern void unlock_ocsp_cache(const char *who)
-{
-       DBG(DBG_CONTROLMORE,
-               DBG_log("ocsp cache unlocked by '%s'", who)
-       )
-       pthread_mutex_unlock(&ocsp_cache_mutex);
-}
-
-/**
- * Lock access to the ca info list
- */
-extern void lock_ca_info_list(const char *who)
-{
-       pthread_mutex_lock(&ca_info_list_mutex);
-       DBG(DBG_CONTROLMORE,
-               DBG_log("ca info list locked by '%s'", who)
-       )
-}
-
-/**
- * Unlock access to the ca info list
- */
-extern void unlock_ca_info_list(const char *who)
-{
-       DBG(DBG_CONTROLMORE,
-               DBG_log("ca info list unlocked by '%s'", who)
-       )
-       pthread_mutex_unlock(&ca_info_list_mutex);
-}
-
-/**
- * Lock access to the chained crl fetch request list
- */
-static void lock_crl_fetch_list(const char *who)
-{
-       pthread_mutex_lock(&crl_fetch_list_mutex);
-       DBG(DBG_CONTROLMORE,
-               DBG_log("crl fetch request list locked by '%s'", who)
-       )
-}
-
-/**
- * Unlock access to the chained crl fetch request list
- */
-static void unlock_crl_fetch_list(const char *who)
-{
-       DBG(DBG_CONTROLMORE,
-               DBG_log("crl fetch request list unlocked by '%s'", who)
-       )
-       pthread_mutex_unlock(&crl_fetch_list_mutex);
-}
-
-/**
- * Lock access to the chained ocsp fetch request list
- */
-static void lock_ocsp_fetch_list(const char *who)
-{
-       pthread_mutex_lock(&ocsp_fetch_list_mutex);
-       DBG(DBG_CONTROLMORE,
-               DBG_log("ocsp fetch request list locked by '%s'", who)
-       )
-}
-
-/**
- * Unlock access to the chained ocsp fetch request list
- */
-static void unlock_ocsp_fetch_list(const char *who)
-{
-       DBG(DBG_CONTROLMORE,
-               DBG_log("ocsp fetch request list unlocked by '%s'", who)
-       )
-       pthread_mutex_unlock(&ocsp_fetch_list_mutex);
-}
-
-/**
- * Wakes up the sleeping fetch thread
- */
-void wake_fetch_thread(const char *who)
-{
-       if (crl_check_interval > 0)
-       {
-               DBG(DBG_CONTROLMORE,
-                       DBG_log("fetch thread wake call by '%s'", who)
-               )
-               pthread_mutex_lock(&fetch_wake_mutex);
-               pthread_cond_signal(&fetch_wake_cond);
-               pthread_mutex_unlock(&fetch_wake_mutex);
-       }
-}
-#else /* !THREADS */
-#define lock_crl_fetch_list(who)    /* do nothing */
-#define unlock_crl_fetch_list(who)  /* do nothing */
-#define lock_ocsp_fetch_list(who)   /* do nothing */
-#define unlock_ocsp_fetch_list(who) /* do nothing */
-#endif /* !THREADS */
-
-/**
- *  Free the dynamic memory used to store fetch requests
- */
-static void free_fetch_request(fetch_req_t *req)
-{
-       req->distributionPoints->destroy_function(req->distributionPoints, free);
-       DESTROY_IF(req->issuer);
-       free(req->authKeyID.ptr);
-       free(req);
-}
-
-#ifdef THREADS
-/**
- * Fetch an ASN.1 blob coded in PEM or DER format from a URL
- */
-x509crl_t* fetch_crl(char *url)
-{
-       x509crl_t *crl;
-       chunk_t blob;
-
-       DBG1(DBG_LIB, "  fetching crl from '%s' ...", url);
-       if (lib->fetcher->fetch(lib->fetcher, url, &blob, FETCH_END) != SUCCESS)
-       {
-               DBG1(DBG_LIB, "crl fetching failed");
-               return FALSE;
-       }
-       crl = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_PLUTO_CRL,
-                                                        BUILD_BLOB_PEM, blob, BUILD_END);
-       free(blob.ptr);
-       if (!crl)
-       {
-               DBG1(DBG_LIB, "crl fetched successfully but data coded in unknown "
-                        "format");
-       }
-       return crl;
-}
-
-/**
- * Complete a distributionPoint URI with ca information
- */
-static char* complete_uri(char *distPoint, const char *ldaphost)
-{
-       char *symbol = strchr(distPoint, ':');
-
-       if (symbol)
-       {
-               int type_len = symbol - distPoint;
-
-               if (type_len >= 4 && strncasecmp(distPoint, "ldap", 4) == 0)
-               {
-                       char *ptr  = symbol + 1;
-                       int len = strlen(distPoint) - (type_len + 1);
-
-                       if (len > 2 && *ptr++ == '/' && *ptr++ == '/')
-                       {
-                               len -= 2;
-                               symbol = strchr(ptr, '/');
-
-                               if (symbol && symbol - ptr == 0 && ldaphost)
-                               {
-                                       char uri[BUF_LEN];
-
-                                       /* insert the ldaphost into the uri */
-                                       snprintf(uri, BUF_LEN, "%.*s%s%.*s",
-                                                        (int)strlen(distPoint) - len, distPoint, ldaphost,
-                                                        len, symbol);
-                                       return strdup(uri);
-                               }
-                       }
-               }
-       }
-
-       /* default action:  copy distributionPoint without change */
-       return strdup(distPoint);
-}
-
-/**
- * Try to fetch the crls defined by the fetch requests
- */
-static void fetch_crls(bool cache_crls)
-{
-       fetch_req_t *req;
-       fetch_req_t **reqp;
-
-       lock_crl_fetch_list("fetch_crls");
-       req  =  crl_fetch_reqs;
-       reqp = &crl_fetch_reqs;
-
-       while (req != NULL)
-       {
-               enumerator_t *enumerator;
-               char *point;
-               bool valid_crl = FALSE;
-               const char *ldaphost;
-               ca_info_t *ca;
-
-               lock_ca_info_list("fetch_crls");
-
-               ca = get_ca_info(req->issuer, req->authKeyID);
-               ldaphost = (ca == NULL)? NULL : ca->ldaphost;
-
-               enumerator = req->distributionPoints->create_enumerator(req->distributionPoints);
-               while (enumerator->enumerate(enumerator, &point))
-               {
-                       x509crl_t *crl;
-                       char *uri;
-
-                       uri = complete_uri(point, ldaphost);
-                       crl = fetch_crl(uri);
-                       free(uri);
-
-                       if (crl)
-                       {
-                               if (insert_crl(crl, point, cache_crls))
-                               {
-                                       DBG(DBG_CONTROL,
-                                               DBG_log("we have a valid crl")
-                                       )
-                                       valid_crl = TRUE;
-                                       break;
-                               }
-                       }
-               }
-               enumerator->destroy(enumerator);
-               unlock_ca_info_list("fetch_crls");
-
-               if (valid_crl)
-               {
-                       /* delete fetch request */
-                       fetch_req_t *req_free = req;
-
-                       req   = req->next;
-                       *reqp = req;
-                       free_fetch_request(req_free);
-               }
-               else
-               {
-                       /* try again next time */
-                       req->trials++;
-                       reqp = &req->next;
-                       req  =  req->next;
-               }
-       }
-       unlock_crl_fetch_list("fetch_crls");
-}
-
-static void fetch_ocsp_status(ocsp_location_t* location)
-{
-       chunk_t request = build_ocsp_request(location);
-       chunk_t response = chunk_empty;
-
-       DBG1(DBG_LIB, "  requesting ocsp status from '%s' ...", location->uri);
-       if (lib->fetcher->fetch(lib->fetcher, location->uri, &response,
-                                                       FETCH_REQUEST_DATA, request,
-                                                       FETCH_REQUEST_TYPE, "application/ocsp-request",
-                                                       FETCH_END) == SUCCESS)
-       {
-               parse_ocsp(location, response);
-       }
-       else
-       {
-               DBG1(DBG_LIB, "ocsp request to %s failed", location->uri);
-       }
-
-       free(request.ptr);
-       chunk_free(&location->nonce);
-
-       /* increment the trial counter of the unresolved fetch requests */
-       {
-               ocsp_certinfo_t *certinfo = location->certinfo;
-
-               while (certinfo != NULL)
-               {
-                       certinfo->trials++;
-                       certinfo = certinfo->next;
-               }
-       }
-}
-
-/**
- * Try to fetch the necessary ocsp information
- */
-static void fetch_ocsp(void)
-{
-       ocsp_location_t *location;
-
-       lock_ocsp_fetch_list("fetch_ocsp");
-       location = ocsp_fetch_reqs;
-
-       /* fetch the ocps status for all locations */
-       while (location != NULL)
-       {
-               if (location->certinfo != NULL)
-               {
-                       fetch_ocsp_status(location);
-               }
-               location = location->next;
-       }
-
-       unlock_ocsp_fetch_list("fetch_ocsp");
-}
-
-static void* fetch_thread(void *arg)
-{
-       struct timespec wait_interval;
-
-       /* the fetching thread is only cancellable while waiting for new events */
-       thread_cancelability(FALSE);
-
-       DBG(DBG_CONTROL,
-               DBG_log("fetch thread started")
-       )
-
-       pthread_mutex_lock(&fetch_wake_mutex);
-
-       while(1)
-       {
-               int status;
-
-               wait_interval.tv_nsec = 0;
-               wait_interval.tv_sec = time(NULL) + crl_check_interval;
-
-               DBG(DBG_CONTROL,
-                       DBG_log("next regular crl check in %ld seconds", crl_check_interval)
-               )
-
-               thread_cancelability(TRUE);
-               status = pthread_cond_timedwait(&fetch_wake_cond, &fetch_wake_mutex
-                                                                               , &wait_interval);
-               thread_cancelability(FALSE);
-
-               if (status == ETIMEDOUT)
-               {
-                       DBG(DBG_CONTROL,
-                               DBG_log(" ");
-                               DBG_log("*time to check crls and the ocsp cache")
-                       )
-                       check_ocsp();
-                       check_crls();
-               }
-               else
-               {
-                       DBG(DBG_CONTROL,
-                               DBG_log("fetch thread was woken up")
-                       )
-               }
-               fetch_ocsp();
-               fetch_crls(cache_crls);
-       }
-       return NULL;
-}
-#endif /* THREADS*/
-
-/**
- * Initializes curl and starts the fetching thread
- */
-void fetch_initialize(void)
-{
-       if (crl_check_interval > 0)
-       {
-#ifdef THREADS
-               thread = thread_create((thread_main_t)fetch_thread, NULL);
-               if (thread == NULL)
-               {
-                       plog("fetching thread could not be started");
-               }
-#else   /* !THREADS */
-               plog("warning: not compiled with pthread support");
-#endif  /* !THREADS */
-       }
-}
-
-/**
- * Terminates the fetching thread
- */
-void fetch_finalize(void)
-{
-       if (crl_check_interval > 0)
-       {
-#ifdef THREADS
-               if (thread)
-               {
-                       thread->cancel(thread);
-                       thread->join(thread);
-               }
-#endif
-       }
-}
-
-void free_crl_fetch(void)
-{
-   lock_crl_fetch_list("free_crl_fetch");
-
-       while (crl_fetch_reqs != NULL)
-       {
-               fetch_req_t *req = crl_fetch_reqs;
-               crl_fetch_reqs = req->next;
-               free_fetch_request(req);
-       }
-
-       unlock_crl_fetch_list("free_crl_fetch");
-}
-
-/**
- * Free the chained list of ocsp requests
- */
-void free_ocsp_fetch(void)
-{
-       lock_ocsp_fetch_list("free_ocsp_fetch");
-       free_ocsp_locations(&ocsp_fetch_reqs);
-       unlock_ocsp_fetch_list("free_ocsp_fetch");
-}
-
-
-/**
- * Add an additional distribution point
- */
-void add_distribution_point(linked_list_t *points, char *new_point)
-{
-       char *point;
-       bool add = TRUE;
-       enumerator_t *enumerator;
-
-       if (new_point == NULL || *new_point == '\0')
-       {
-               return;
-       }
-
-       enumerator = points->create_enumerator(points);
-       while (enumerator->enumerate(enumerator, &point))
-       {
-               if (streq(point, new_point))
-               {
-                       add = FALSE;
-                       break;
-               }
-       }
-       enumerator->destroy(enumerator);
-
-       if (add)
-       {
-               points->insert_last(points, strdup(new_point));
-       }
-}
-
-/**
- * Add additional distribution points
- */
-void add_distribution_points(linked_list_t *points, linked_list_t *new_points)
-{
-       char *new_point;
-       enumerator_t *enumerator;
-
-       enumerator = new_points->create_enumerator(new_points);
-       while (enumerator->enumerate(enumerator, &new_point))
-       {
-               bool add = TRUE;
-               char *point;
-               enumerator_t *enumerator;
-
-               enumerator = points->create_enumerator(points);
-               while (enumerator->enumerate(enumerator, &point))
-               {
-                       if (streq(point, new_point))
-                       {
-                               add = FALSE;
-                               break;
-                       }
-               }
-               enumerator->destroy(enumerator);
-
-               if (add)
-               {
-                       points->insert_last(points, strdup(new_point));
-               }
-       }
-       enumerator->destroy(enumerator);
-}
-
-fetch_req_t* build_crl_fetch_request(identification_t *issuer,
-                                                                        chunk_t authKeyID,
-                                                                        linked_list_t *distributionPoints)
-{
-       char *point;
-       enumerator_t *enumerator;
-       fetch_req_t *req = malloc_thing(fetch_req_t);
-
-       memset(req, 0, sizeof(fetch_req_t));
-       req->distributionPoints = linked_list_create();
-
-       /* clone fields */
-       req->issuer = issuer->clone(issuer);
-       req->authKeyID = chunk_clone(authKeyID);
-
-       /* copy distribution points */
-       enumerator = distributionPoints->create_enumerator(distributionPoints);
-       while (enumerator->enumerate(enumerator, &point))
-       {
-               req->distributionPoints->insert_last(req->distributionPoints,
-                                                                                        strdup(point));
-       }
-       enumerator->destroy(enumerator);
-
-       return req;
-}
-
-/**
- * Add a crl fetch request to the chained list
- */
-void add_crl_fetch_request(fetch_req_t *req)
-{
-       fetch_req_t *r;
-
-       lock_crl_fetch_list("add_crl_fetch_request");
-       r = crl_fetch_reqs;
-
-       while (r != NULL)
-       {
-               if (req->authKeyID.ptr ? same_keyid(req->authKeyID, r->authKeyID) :
-                       req->issuer->equals(req->issuer, r->issuer))
-               {
-                       /* there is already a fetch request */
-                       DBG(DBG_CONTROL,
-                               DBG_log("crl fetch request already exists")
-                       )
-
-                       /* there might be new distribution points */
-                       add_distribution_points(r->distributionPoints,
-                                                                       req->distributionPoints);
-
-                       unlock_crl_fetch_list("add_crl_fetch_request");
-                       free_fetch_request(req);
-                       return;
-               }
-               r = r->next;
-       }
-
-       /* insert new fetch request at the head of the queue */
-       req->next = crl_fetch_reqs;
-       crl_fetch_reqs = req;
-
-       DBG(DBG_CONTROL,
-               DBG_log("crl fetch request added")
-       )
-       unlock_crl_fetch_list("add_crl_fetch_request");
-}
-
-/**
- * Add an ocsp fetch request to the chained list
- */
-void add_ocsp_fetch_request(ocsp_location_t *location, chunk_t serialNumber)
-{
-       ocsp_certinfo_t certinfo;
-
-       certinfo.serialNumber = serialNumber;
-
-       lock_ocsp_fetch_list("add_ocsp_fetch_request");
-       add_certinfo(location, &certinfo, &ocsp_fetch_reqs, TRUE);
-       unlock_ocsp_fetch_list("add_ocsp_fetch_request");
-}
-
-/**
- * List all distribution points
- */
-void list_distribution_points(linked_list_t *distributionPoints)
-{
-       char *point;
-       bool first_point = TRUE;
-       enumerator_t *enumerator;
-
-       enumerator = distributionPoints->create_enumerator(distributionPoints);
-       while (enumerator->enumerate(enumerator, &point))
-       {
-               whack_log(RC_COMMENT, "  %s '%s'",
-                                (first_point)? "distPts: " : "         ", point);
-               first_point = FALSE;
-       }
-       enumerator->destroy(enumerator);
-}
-
-/**
- *  List all fetch requests in the chained list
- */
-void list_crl_fetch_requests(bool utc)
-{
-       fetch_req_t *req;
-
-       lock_crl_fetch_list("list_crl_fetch_requests");
-       req = crl_fetch_reqs;
-
-       if (req != NULL)
-       {
-               whack_log(RC_COMMENT, " ");
-               whack_log(RC_COMMENT, "List of CRL Fetch Requests:");
-       }
-
-       while (req != NULL)
-       {
-               whack_log(RC_COMMENT, " ");
-               whack_log(RC_COMMENT, "  trials:    %d", req->trials);
-               whack_log(RC_COMMENT, "  issuer:   \"%Y\"", req->issuer);
-               if (req->authKeyID.ptr)
-               {
-                       whack_log(RC_COMMENT, "  authkey:   %#B", &req->authKeyID);
-               }
-               list_distribution_points(req->distributionPoints);
-               req = req->next;
-       }
-       unlock_crl_fetch_list("list_crl_fetch_requests");
-}
-
-void list_ocsp_fetch_requests(bool utc)
-{
-       lock_ocsp_fetch_list("list_ocsp_fetch_requests");
-       list_ocsp_locations(ocsp_fetch_reqs, TRUE, utc, FALSE);
-       unlock_ocsp_fetch_list("list_ocsp_fetch_requests");
-
-}
diff --git a/src/pluto/fetch.h b/src/pluto/fetch.h
deleted file mode 100644 (file)
index 265dc5f..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/* Dynamic fetching of X.509 CRLs
- * Copyright (C) 2002 Stephane Laroche <stephane.laroche@colubris.com>
- * Copyright (C) 2002-2004 Andreas Steffen, Zuercher Hochschule Winterthur
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <utils/linked_list.h>
-#include <utils/identification.h>
-
-#include "x509.h"
-
-#define FETCH_CMD_TIMEOUT       10      /* seconds */
-
-struct ocsp_location;   /* forward declaration of ocsp_location defined in ocsp.h */
-
-typedef enum {
-       FETCH_GET =  1,
-       FETCH_POST = 2
-} fetch_request_t;
-
-typedef struct fetch_req fetch_req_t;
-
-struct fetch_req {
-       fetch_req_t      *next;
-       int               trials;
-       identification_t *issuer;
-       chunk_t           authKeyID;
-       linked_list_t    *distributionPoints;
-};
-
-#ifdef THREADS
-extern void lock_crl_list(const char *who);
-extern void unlock_crl_list(const char *who);
-extern void lock_ocsp_cache(const char *who);
-extern void unlock_ocsp_cache(const char *who);
-extern void lock_ca_info_list(const char *who);
-extern void unlock_ca_info_list(const char *who);
-extern void lock_authcert_list(const char *who);
-extern void unlock_authcert_list(const char *who);
-extern void lock_certs_and_keys(const char *who);
-extern void unlock_certs_and_keys(const char *who);
-extern void wake_fetch_thread(const char *who);
-#else
-#define lock_crl_list(who)          /* do nothing */
-#define unlock_crl_list(who)        /* do nothing */
-#define lock_ocsp_cache(who)        /* do nothing */
-#define unlock_ocsp_cache(who)      /* do nothing */
-#define lock_ca_info_list(who)      /* do nothing */
-#define unlock_ca_info_list(who)    /* do nothing */
-#define lock_authcert_list(who)     /* do nothing */
-#define unlock_authcert_list(who)   /* do nothing */
-#define lock_certs_and_keys(who)    /* do nothing */
-#define unlock_certs_and_keys(who)  /* do nothing */
-#define wake_fetch_thread(who)      /* do nothing */
-#endif
-extern void fetch_initialize(void);
-extern void fetch_finalize(void);
-extern void free_crl_fetch(void);
-extern void free_ocsp_fetch(void);
-extern void add_distribution_point(linked_list_t *points, char* new_point);
-extern void add_distribution_points(linked_list_t *points,
-                                                                       linked_list_t *new_points);
-extern fetch_req_t* build_crl_fetch_request(identification_t *issuer,
-                                                                                       chunk_t authKeyID,
-                                                                                       linked_list_t *distributionPoints);
-extern void add_crl_fetch_request(fetch_req_t *req);
-extern void add_ocsp_fetch_request(struct ocsp_location *location,
-                                                                  chunk_t serialNumber);
-extern void list_distribution_points(linked_list_t *distributionPoints);
-extern void list_crl_fetch_requests(bool utc);
-extern void list_ocsp_fetch_requests(bool utc);
-extern size_t write_buffer(void *ptr, size_t size, size_t nmemb, void *data);
-
diff --git a/src/pluto/foodgroups.c b/src/pluto/foodgroups.c
deleted file mode 100644 (file)
index e4f9a1d..0000000
+++ /dev/null
@@ -1,450 +0,0 @@
-/* Implement policy groups-style control files (aka "foodgroups")
- * Copyright (C) 2002  D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <string.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <sys/queue.h>
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "connections.h"
-#include "foodgroups.h"
-#include "kernel.h"
-#include "lex.h"
-#include "log.h"
-#include "whack.h"
-
-
-/* Food group config files are found in directory fg_path */
-
-#ifndef POLICYGROUPSDIR
-#define POLICYGROUPSDIR IPSEC_CONFDIR "/ipsec.d/policies"
-#endif
-
-const char *policygroups_dir = POLICYGROUPSDIR;
-
-static char *fg_path = NULL;
-static size_t fg_path_space = 0;
-
-
-/* Groups is a list of connections that are policy groups.
- * The list is updated as group connections are added and deleted.
- */
-
-struct fg_groups {
-       struct fg_groups *next;
-       connection_t *connection;
-};
-
-static struct fg_groups *groups = NULL;
-
-
-/* Targets is a list of pairs: subnet and its policy group.
- * This list is bulk-updated on whack --listen and
- * incrementally updated when group connections are deleted.
- *
- * It is ordered by source subnet, and if those are equal, then target subnet.
- * A subnet is compared by comparing the network, and if those are equal,
- * comparing the mask.
- */
-
-struct fg_targets {
-       struct fg_targets *next;
-       struct fg_groups *group;
-       ip_subnet subnet;
-       char *name; /* name of instance of group conn */
-};
-
-static struct fg_targets *targets = NULL;
-
-struct fg_targets *new_targets;
-
-/* ipcmp compares the two ip_address values a and b.
- * It returns -1, 0, or +1 if a is, respectively,
- * less than, equal to, or greater than b.
- */
-static int ipcmp(ip_address *a, ip_address *b)
-{
-       if (addrtypeof(a) != addrtypeof(b))
-       {
-               return addrtypeof(a) < addrtypeof(b)? -1 : 1;
-       }
-       else if (sameaddr(a, b))
-       {
-               return 0;
-       }
-       else
-       {
-               const struct sockaddr *sa = sockaddrof(a)
-                       , *sb = sockaddrof(b);
-
-               passert(addrtypeof(a) == AF_INET);      /* not yet implemented IPv6 version :-( */
-               return (ntohl(((const struct sockaddr_in *)sa)->sin_addr.s_addr)
-                       < ntohl(((const struct sockaddr_in *)sb)->sin_addr.s_addr))
-                       ? -1 : 1;
-       }
-}
-
-/* subnetcmp compares the two ip_subnet values a and b.
- * It returns -1, 0, or +1 if a is, respectively,
- * less than, equal to, or greater than b.
- */
-static int subnetcmp(const ip_subnet *a, const ip_subnet *b)
-{
-       ip_address neta, maska, netb, maskb;
-       int r;
-
-       networkof(a, &neta);
-       maskof(a, &maska);
-       networkof(b, &netb);
-       maskof(b, &maskb);
-       r = ipcmp(&neta, &netb);
-       if (r == 0)
-               r = ipcmp(&maska, &maskb);
-       return r;
-}
-
-static void read_foodgroup(struct fg_groups *g)
-{
-       const char *fgn = g->connection->name;
-       const ip_subnet *lsn = &g->connection->spd.this.client;
-       size_t plen = strlen(policygroups_dir) + 1 + strlen(fgn) + 1;
-       struct file_lex_position flp_space;
-
-       if (plen > fg_path_space)
-       {
-               free(fg_path);
-               fg_path_space = plen + 10;
-               fg_path = malloc(fg_path_space);
-       }
-       snprintf(fg_path, fg_path_space, "%s/%s", policygroups_dir, fgn);
-       if (!lexopen(&flp_space, fg_path, TRUE))
-       {
-               DBG(DBG_CONTROL, DBG_log("no group file \"%s\"", fg_path));
-       }
-       else
-       {
-               plog("loading group \"%s\"", fg_path);
-               for (;;)
-               {
-                       switch (flp->bdry)
-                       {
-                       case B_none:
-                               {
-                                       /* !!! this test is not sufficient for distinguishing address families.
-                                        * We need a notation to specify that a FQDN is to be resolved to IPv6.
-                                        */
-                                       const struct af_info *afi = strchr(tok, ':') == NULL
-                                               ? &af_inet4_info: &af_inet6_info;
-                                       ip_subnet sn;
-                                       err_t ugh;
-
-                                       if (strchr(tok, '/') == NULL)
-                                       {
-                                               /* no /, so treat as /32 or V6 equivalent */
-                                               ip_address t;
-
-                                               ugh = ttoaddr(tok, 0, afi->af, &t);
-                                               if (ugh == NULL)
-                                                       ugh = addrtosubnet(&t, &sn);
-                                       }
-                                       else
-                                       {
-                                               ugh = ttosubnet(tok, 0, afi->af, &sn);
-                                       }
-
-                                       if (ugh != NULL)
-                                       {
-                                               loglog(RC_LOG_SERIOUS, "\"%s\" line %d: %s \"%s\""
-                                                       , flp->filename, flp->lino, ugh, tok);
-                                       }
-                                       else if (afi->af != AF_INET)
-                                       {
-                                               loglog(RC_LOG_SERIOUS
-                                                       , "\"%s\" line %d: unsupported Address Family \"%s\""
-                                                       , flp->filename, flp->lino, tok);
-                                       }
-                                       else
-                                       {
-                                               /* Find where new entry ought to go in new_targets. */
-                                               struct fg_targets **pp;
-                                               int r;
-
-                                               for (pp = &new_targets; ; pp = &(*pp)->next)
-                                               {
-                                                       if (*pp == NULL)
-                                                       {
-                                                               r = -1; /* end of list is infinite */
-                                                               break;
-                                                       }
-                                                       r = subnetcmp(lsn, &(*pp)->group->connection->spd.this.client);
-                                                       if (r == 0)
-                                                               r = subnetcmp(&sn, &(*pp)->subnet);
-                                                       if (r <= 0)
-                                                               break;
-                                               }
-
-                                               if (r == 0)
-                                               {
-                                                       char source[SUBNETTOT_BUF];
-
-                                                       subnettot(lsn, 0, source, sizeof(source));
-                                                       loglog(RC_LOG_SERIOUS
-                                                               , "\"%s\" line %d: subnet \"%s\", source %s, already \"%s\""
-                                                               , flp->filename
-                                                               , flp->lino
-                                                               , tok
-                                                               , source
-                                                               , (*pp)->group->connection->name);
-                                               }
-                                               else
-                                               {
-                                                       struct fg_targets *f = malloc_thing(struct fg_targets);
-
-                                                       f->next = *pp;
-                                                       f->group = g;
-                                                       f->subnet = sn;
-                                                       f->name = NULL;
-                                                       *pp = f;
-                                               }
-                                       }
-                               }
-                               (void)shift();  /* next */
-                               continue;
-
-                       case B_record:
-                               flp->bdry = B_none;     /* eat the Record Boundary */
-                               (void)shift();  /* get real first token */
-                               continue;
-
-                       case B_file:
-                               break;  /* done */
-                       }
-                       break;      /* if we reach here, out of loop */
-               }
-               lexclose();
-       }
-}
-
-static void free_targets(void)
-{
-       while (targets != NULL)
-       {
-               struct fg_targets *t = targets;
-
-               targets = t->next;
-               free(t->name);
-               free(t);
-       }
-}
-
-void load_groups(void)
-{
-       passert(new_targets == NULL);
-
-       /* for each group, add config file targets into new_targets */
-       {
-               struct fg_groups *g;
-
-               for (g = groups; g != NULL; g = g->next)
-                       if (oriented(*g->connection))
-                               read_foodgroup(g);
-       }
-
-       /* dump new_targets */
-       DBG(DBG_CONTROL,
-               {
-                       struct fg_targets *t;
-
-                       for (t = new_targets; t != NULL; t = t->next)
-                       {
-                               char asource[SUBNETTOT_BUF];
-                               char atarget[SUBNETTOT_BUF];
-
-                               subnettot(&t->group->connection->spd.this.client
-                                       , 0, asource, sizeof(asource));
-                               subnettot(&t->subnet, 0, atarget, sizeof(atarget));
-                               DBG_log("%s->%s %s"
-                                       , asource, atarget
-                                       , t->group->connection->name);
-                       }
-               });
-
-       /* determine and deal with differences between targets and new_targets.
-        * structured like a merge.
-        */
-       {
-               struct fg_targets *op = targets
-                       , *np = new_targets;
-
-               while (op != NULL && np != NULL)
-               {
-                       int r = subnetcmp(&op->group->connection->spd.this.client
-                               , &np->group->connection->spd.this.client);
-
-                       if (r == 0)
-                               r = subnetcmp(&op->subnet, &np->subnet);
-
-                       if (r == 0 && op->group == np->group)
-                       {
-                               /* unchanged -- steal name & skip over */
-                               np->name = op->name;
-                               op->name = NULL;
-                               op = op->next;
-                               np = np->next;
-                       }
-                       else
-                       {
-                               /* note: following cases overlap! */
-                               if (r <= 0)
-                               {
-                                       remove_group_instance(op->group->connection, op->name);
-                                       op = op->next;
-                               }
-                               if (r >= 0)
-                               {
-                                       np->name = add_group_instance(np->group->connection, &np->subnet);
-                                       np = np->next;
-                               }
-                       }
-               }
-               for (; op != NULL; op = op->next)
-                       remove_group_instance(op->group->connection, op->name);
-               for (; np != NULL; np = np->next)
-                       np->name = add_group_instance(np->group->connection, &np->subnet);
-
-               /* update: new_targets replaces targets */
-               free_targets();
-               targets = new_targets;
-               new_targets = NULL;
-       }
-}
-
-
-void add_group(connection_t *c)
-{
-       struct fg_groups *g = malloc_thing(struct fg_groups);
-
-       g->next = groups;
-       groups = g;
-
-       g->connection = c;
-}
-
-static struct fg_groups *find_group(const connection_t *c)
-{
-       struct fg_groups *g;
-
-       for (g = groups; g != NULL && g->connection != c; g = g->next)
-               ;
-       return g;
-}
-
-void route_group(connection_t *c)
-{
-       /* it makes no sense to route a connection that is ISAKMP-only */
-       if (!NEVER_NEGOTIATE(c->policy) && !HAS_IPSEC_POLICY(c->policy))
-       {
-               loglog(RC_ROUTE, "cannot route an ISAKMP-only group connection");
-       }
-       else
-       {
-               struct fg_groups *g = find_group(c);
-               struct fg_targets *t;
-
-               passert(g != NULL);
-               g->connection->policy |= POLICY_GROUTED;
-               for (t = targets; t != NULL; t = t->next)
-               {
-                       if (t->group == g)
-                       {
-                               connection_t *ci = con_by_name(t->name, FALSE);
-
-                               if (ci != NULL)
-                               {
-                                       set_cur_connection(ci);
-                                       if (!trap_connection(ci))
-                                               whack_log(RC_ROUTE, "could not route");
-                                       set_cur_connection(c);
-                               }
-                       }
-               }
-       }
-}
-
-void unroute_group(connection_t *c)
-{
-       struct fg_groups *g = find_group(c);
-       struct fg_targets *t;
-
-       passert(g != NULL);
-       g->connection->policy &= ~POLICY_GROUTED;
-       for (t = targets; t != NULL; t = t->next)
-       {
-               if (t->group == g)
-               {
-                       connection_t *ci = con_by_name(t->name, FALSE);
-
-                       if (ci != NULL)
-                       {
-                               set_cur_connection(ci);
-                               unroute_connection(ci);
-                               set_cur_connection(c);
-                       }
-               }
-       }
-}
-
-void delete_group(const connection_t *c)
-{
-       struct fg_groups *g;
-
-       /* find and remove from groups */
-       {
-               struct fg_groups **pp;
-
-               for (pp = &groups; (g = *pp)->connection != c; pp = &(*pp)->next)
-                       ;
-
-               *pp = g->next;
-       }
-
-       /* find and remove from targets */
-       {
-               struct fg_targets **pp;
-
-               for (pp = &targets; *pp != NULL; )
-               {
-                       struct fg_targets *t = *pp;
-
-                       if (t->group == g)
-                       {
-                               *pp = t->next;
-                               remove_group_instance(t->group->connection, t->name);
-                               free(t);
-                               /* pp is ready for next iteration */
-                       }
-                       else
-                       {
-                               pp = &t->next;
-                       }
-               }
-       }
-
-       free(g);
-}
diff --git a/src/pluto/foodgroups.h b/src/pluto/foodgroups.h
deleted file mode 100644 (file)
index b6d3386..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Implement policygroups-style control files (aka "foodgroups")
- * Copyright (C) 2002  D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-struct connection;      /* forward declaration */
-extern void add_group(struct connection *c);
-extern void route_group(struct connection *c);
-extern void unroute_group(struct connection *c);
-extern void delete_group(const struct connection *c);
-
-extern const char *policygroups_dir;
-extern void load_groups(void);
diff --git a/src/pluto/ike_alg.c b/src/pluto/ike_alg.c
deleted file mode 100644 (file)
index 3061630..0000000
+++ /dev/null
@@ -1,452 +0,0 @@
-/* IKE modular algorithm handling interface
- * Copyright (C) JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
- * Copyright (C) 2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <sys/queue.h>
-
-#include <freeswan.h>
-
-#include <library.h>
-#include <debug.h>
-#include <credentials/keys/public_key.h>
-#include <credentials/keys/private_key.h>
-#include <crypto/hashers/hasher.h>
-#include <crypto/crypters/crypter.h>
-#include <crypto/prfs/prf.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "crypto.h"
-#include "state.h"
-#include "packet.h"
-#include "keys.h"
-#include "log.h"
-#include "whack.h"
-#include "spdb.h"
-#include "alg_info.h"
-#include "ike_alg.h"
-#include "db_ops.h"
-#include "connections.h"
-#include "kernel.h"
-
-#define return_on(var, val) do { var=val;goto return_out; } while(0);
-
-/**
- * IKE algorithm list handling - registration and lookup
- */
-
-/* Modular IKE algorithm storage structure */
-
-static struct ike_alg *ike_alg_base[IKE_ALG_MAX+1] = {NULL, NULL};
-
-/**
- * Return ike_algo object by {type, id}
- */
-static struct ike_alg *ike_alg_find(u_int algo_type, u_int algo_id,
-                                                                       u_int keysize __attribute__((unused)))
-{
-       struct ike_alg *e = ike_alg_base[algo_type];
-
-       while (e != NULL && algo_id > e->algo_id)
-       {
-               e = e->algo_next;
-       }
-       return (e != NULL && e->algo_id == algo_id) ? e : NULL;
-}
-
-/**
- * "raw" ike_alg list adding function
- */
-int ike_alg_add(struct ike_alg* a, const char *plugin_name)
-{
-       if (a->algo_type > IKE_ALG_MAX)
-       {
-               plog("ike_alg: Not added, invalid algorithm type");
-               return -EINVAL;
-       }
-
-       if (ike_alg_find(a->algo_type, a->algo_id, 0) != NULL)
-       {
-               plog("ike_alg: Not added, algorithm already exists");
-               return -EEXIST;
-       }
-
-       {
-               struct ike_alg **ep = &ike_alg_base[a->algo_type];
-               struct ike_alg *e = *ep;
-
-               while (e != NULL && a->algo_id > e->algo_id)
-               {
-                       ep = &e->algo_next;
-                       e = *ep;
-               }
-               *ep = a;
-               a->plugin_name = plugin_name;
-               a->algo_next = e;
-               return 0;
-       }
-}
-
-/**
- * Get IKE hash algorithm
- */
-struct hash_desc *ike_alg_get_hasher(u_int alg)
-{
-       return (struct hash_desc *) ike_alg_find(IKE_ALG_HASH, alg, 0);
-}
-
-/**
- * Get IKE encryption algorithm
- */
-struct encrypt_desc *ike_alg_get_crypter(u_int alg)
-{
-       return (struct encrypt_desc *) ike_alg_find(IKE_ALG_ENCRYPT, alg, 0);
-}
-
-/**
- * Get IKE dh group
- */
-struct dh_desc *ike_alg_get_dh_group(u_int alg)
-{
-       return (struct dh_desc *) ike_alg_find(IKE_ALG_DH_GROUP, alg, 0);
-}
-
-/**
- * Get pfsgroup for this connection
- */
-const struct dh_desc *ike_alg_pfsgroup(connection_t *c, lset_t policy)
-{
-       const struct dh_desc *ret = NULL;
-
-       if ((policy & POLICY_PFS) &&
-               c->alg_info_esp && c->alg_info_esp->esp_pfsgroup)
-       {
-               ret = ike_alg_get_dh_group(c->alg_info_esp->esp_pfsgroup);
-       }
-       return ret;
-}
-
-/**
- * Create an OAKLEY proposal based on alg_info and policy
- */
-struct db_context *ike_alg_db_new(connection_t *c, lset_t policy)
-{
-       struct alg_info_ike *ai = c->alg_info_ike;
-       struct db_context *db_ctx = NULL;
-       struct ike_info *ike_info;
-       u_int ealg, halg, modp, eklen = 0;
-       int i;
-
-       bool is_xauth_server = (policy & POLICY_XAUTH_SERVER) != LEMPTY;
-
-       if (!ai)
-       {
-               whack_log(RC_LOG_SERIOUS, "no IKE algorithms "
-                                                                 "for this connection "
-                                                                 "(check ike algorithm string)");
-               goto fail;
-       }
-       policy &= POLICY_ID_AUTH_MASK;
-       db_ctx = db_prop_new(PROTO_ISAKMP, 8, 8 * 5);
-
-       /* for each group */
-       ALG_INFO_IKE_FOREACH(ai, ike_info, i)
-       {
-               ealg = ike_info->ike_ealg;
-               halg = ike_info->ike_halg;
-               modp = ike_info->ike_modp;
-               eklen= ike_info->ike_eklen;
-
-               if (!ike_alg_get_crypter(ealg))
-               {
-                       plog("ike alg: crypter %s not present",
-                                       enum_show(&oakley_enc_names, ealg));
-                       continue;
-               }
-               if (!ike_alg_get_hasher(halg))
-               {
-                       plog("ike alg: hasher %s not present",
-                                       enum_show(&oakley_hash_names, halg));
-                       continue;
-               }
-               if (!ike_alg_get_dh_group(modp))
-               {
-                       plog("ike alg: dh group %s not present",
-                                       enum_show(&oakley_group_names, modp));
-                       continue;
-               }
-
-               if (policy & POLICY_PUBKEY)
-               {
-                       int auth_method = 0, key_size = 0;
-                       key_type_t key_type = KEY_ANY;
-
-                       if (c->spd.this.cert)
-                       {
-                               certificate_t *certificate = c->spd.this.cert->cert;
-                               public_key_t *key = certificate->get_public_key(certificate);
-
-                               if (key == NULL)
-                               {
-                                       plog("ike alg: unable to retrieve my public key");
-                                       continue;
-                               }
-                               key_type = key->get_type(key);
-                               key_size = key->get_keysize(key);
-                               key->destroy(key);
-                       }
-                       else
-                       {
-                               private_key_t *key = get_private_key(c);
-
-                               if (key == NULL)
-                               {
-                                       plog("ike alg: unable to retrieve my private key");
-                                       continue;
-                               }
-                               key_type = key->get_type(key);
-                               key_size = key->get_keysize(key);
-                       }
-                       switch (key_type)
-                       {
-                               case KEY_RSA:
-                                       auth_method = OAKLEY_RSA_SIG;
-                                       break;
-                               case KEY_ECDSA:
-                                       switch (key_size)
-                                       {
-                                               case 256:
-                                                       auth_method = OAKLEY_ECDSA_256;
-                                                       break;
-                                               case 384:
-                                                       auth_method = OAKLEY_ECDSA_384;
-                                                       break;
-                                               case 521:
-                                                       auth_method = OAKLEY_ECDSA_521;
-                                                       break;
-                                               default:
-                                                       continue;
-                                       }
-                                       break;
-                               default:
-                                       continue;
-                       }
-                       db_trans_add(db_ctx, KEY_IKE);
-                       db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg);
-                       db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg);
-                       if (eklen)
-                       {
-                               db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen);
-                       }
-                       db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD, auth_method);
-                       db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp);
-               }
-
-               if (policy & POLICY_PSK)
-               {
-                       db_trans_add(db_ctx, KEY_IKE);
-                       db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg);
-                       db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg);
-                       if (eklen)
-                       {
-                               db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen);
-                       }
-                       db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD, OAKLEY_PRESHARED_KEY);
-                       db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp);
-               }
-
-               if (policy & POLICY_XAUTH_RSASIG)
-               {
-                       db_trans_add(db_ctx, KEY_IKE);
-                       db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg);
-                       db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg);
-                       if (eklen)
-                       {
-                               db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen);
-                       }
-                       db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD
-                               , is_xauth_server ? XAUTHRespRSA : XAUTHInitRSA);
-                       db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp);
-               }
-
-               if (policy & POLICY_XAUTH_PSK)
-               {
-                       db_trans_add(db_ctx, KEY_IKE);
-                       db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg);
-                       db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg);
-                       if (eklen)
-                       {
-                               db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen);
-                       }
-                       db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD
-                               , is_xauth_server ? XAUTHRespPreShared : XAUTHInitPreShared);
-                       db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp);
-               }
-       }
-fail:
-       return db_ctx;
-}
-
-/**
- * Print the name of an algorithm plus the name of the plugin that registered it
- */
-static void print_alg(char *buf, int *len, enum_names *alg_names, int alg_type,
-                                         const char *plugin_name)
-{
-       char alg_name[BUF_LEN];
-       int alg_name_len;
-
-       alg_name_len = sprintf(alg_name, " %s[%s]", enum_name(alg_names, alg_type),
-                                                  plugin_name);
-       if (*len + alg_name_len > CRYPTO_MAX_ALG_LINE)
-       {
-               whack_log(RC_COMMENT, "%s", buf);
-               *len = sprintf(buf, "             ");
-       }
-       sprintf(buf + *len, "%s", alg_name);
-       *len += alg_name_len;
-}
-
-/**
- * Show registered IKE algorithms
- */
-void ike_alg_list(void)
-{
-       rng_quality_t quality;
-       enumerator_t *enumerator;
-       const char *plugin_name;
-       char buf[BUF_LEN];
-       int len;
-       struct ike_alg *a;
-
-       whack_log(RC_COMMENT, " ");
-       whack_log(RC_COMMENT, "List of registered IKEv1 Algorithms:");
-       whack_log(RC_COMMENT, " ");
-
-       len = sprintf(buf, "  encryption:");
-       for (a = ike_alg_base[IKE_ALG_ENCRYPT]; a != NULL; a = a->algo_next)
-       {
-           print_alg(buf, &len, &oakley_enc_names, a->algo_id, a->plugin_name);
-       }
-       whack_log(RC_COMMENT, "%s", buf);
-
-       len = sprintf(buf, "  integrity: ");
-       for (a = ike_alg_base[IKE_ALG_HASH]; a != NULL; a = a->algo_next)
-       {
-           print_alg(buf, &len, &oakley_hash_names, a->algo_id, a->plugin_name);
-       }
-       whack_log(RC_COMMENT, "%s", buf);
-
-       len = sprintf(buf, "  dh-group:  ");
-       for (a = ike_alg_base[IKE_ALG_DH_GROUP]; a != NULL; a = a->algo_next)
-       {
-           print_alg(buf, &len, &oakley_group_names, a->algo_id, a->plugin_name);
-       }
-       whack_log(RC_COMMENT, "%s", buf);
-
-       len = sprintf(buf, "  random-gen:");
-       enumerator = lib->crypto->create_rng_enumerator(lib->crypto);
-       while (enumerator->enumerate(enumerator, &quality, &plugin_name))
-       {
-           len += sprintf(buf + len, " %N[%s]", rng_quality_names, quality,
-                                                                                        plugin_name);
-       }
-       enumerator->destroy(enumerator);
-       whack_log(RC_COMMENT, "%s", buf);
-}
-
-/**
- * Show IKE algorithms for this connection (result from ike= string)
- * and newest SA
- */
-void ike_alg_show_connection(connection_t *c, const char *instance)
-{
-       struct state *st = state_with_serialno(c->newest_isakmp_sa);
-
-       if (st)
-       {
-               if (st->st_oakley.encrypt == OAKLEY_3DES_CBC)
-               {
-                       whack_log(RC_COMMENT,
-                                       "\"%s\"%s:   IKE proposal: %s/%s/%s",
-                                       c->name, instance,
-                                       enum_show(&oakley_enc_names, st->st_oakley.encrypt),
-                                       enum_show(&oakley_hash_names, st->st_oakley.hash),
-                                       enum_show(&oakley_group_names, st->st_oakley.group->algo_id)
-                       );
-               }
-               else
-               {
-                       whack_log(RC_COMMENT,
-                                       "\"%s\"%s:   IKE proposal: %s_%u/%s/%s",
-                                       c->name, instance,
-                                       enum_show(&oakley_enc_names, st->st_oakley.encrypt),
-                                       st->st_oakley.enckeylen,
-                                       enum_show(&oakley_hash_names, st->st_oakley.hash),
-                                       enum_show(&oakley_group_names, st->st_oakley.group->algo_id)
-                       );
-               }
-       }
-}
-
-/**
- * ML: make F_STRICT logic consider enc,hash/auth,modp algorithms
- */
-bool ike_alg_ok_final(u_int ealg, u_int key_len, u_int aalg, u_int group,
-                                         struct alg_info_ike *alg_info_ike)
-{
-       /*
-        * simple test to discard low key_len, will accept it only
-        * if specified in "esp" string
-        */
-       bool ealg_insecure = (key_len < 128);
-
-       if (ealg_insecure
-       || (alg_info_ike && alg_info_ike->alg_info_flags & ALG_INFO_F_STRICT))
-       {
-               int i;
-               struct ike_info *ike_info;
-
-               if (alg_info_ike)
-               {
-                       ALG_INFO_IKE_FOREACH(alg_info_ike, ike_info, i)
-                       {
-                               if (ike_info->ike_ealg == ealg
-                               && (ike_info->ike_eklen == 0 || key_len == 0 || ike_info->ike_eklen == key_len)
-                               && ike_info->ike_halg == aalg
-                               && ike_info->ike_modp == group)
-                               {
-                                       if (ealg_insecure)
-                                               loglog(RC_LOG_SERIOUS, "You should NOT use insecure IKE algorithms (%s)!"
-                                                               , enum_name(&oakley_enc_names, ealg));
-                                       return TRUE;
-                               }
-                       }
-               }
-               plog("Oakley Transform [%s (%d), %s, %s] refused due to %s"
-                               , enum_name(&oakley_enc_names, ealg), key_len
-                               , enum_name(&oakley_hash_names, aalg)
-                               , enum_name(&oakley_group_names, group)
-                               , ealg_insecure ?
-                                       "insecure key_len and enc. alg. not listed in \"ike\" string" : "strict flag"
-               );
-               return FALSE;
-       }
-       return TRUE;
-}
-
diff --git a/src/pluto/ike_alg.h b/src/pluto/ike_alg.h
deleted file mode 100644 (file)
index c3ce8bb..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/* IKE modular algorithm handling interface
- * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef _IKE_ALG_H
-#define _IKE_ALG_H
-
-#include <freeswan.h>
-
-#include "connections.h"
-
-struct ike_alg {
-       u_int16_t algo_type;
-       u_int16_t algo_id;
-       const char *plugin_name;
-       struct ike_alg *algo_next;
-};
-
-struct encrypt_desc {
-       u_int16_t algo_type;
-       u_int16_t algo_id;
-       const char *plugin_name;
-       struct ike_alg *algo_next;
-
-       size_t enc_blocksize;
-       u_int keydeflen;
-       u_int keymaxlen;
-       u_int keyminlen;
-};
-
-struct hash_desc {
-       u_int16_t algo_type;
-       u_int16_t algo_id;
-       const char *plugin_name;
-       struct ike_alg *algo_next;
-
-       size_t hash_digest_size;
-};
-
-struct dh_desc {
-       u_int16_t algo_type;
-       u_int16_t algo_id;
-       const char *plugin_name;
-       struct ike_alg *algo_next;
-
-       size_t ke_size;
-};
-
-#define IKE_ALG_ENCRYPT         0
-#define IKE_ALG_HASH            1
-#define IKE_ALG_DH_GROUP               2
-#define IKE_ALG_MAX             IKE_ALG_DH_GROUP
-
-extern int ike_alg_add(struct ike_alg *a, const char *plugin_name);
-extern struct hash_desc *ike_alg_get_hasher(u_int alg);
-extern struct encrypt_desc *ike_alg_get_crypter(u_int alg);
-extern struct dh_desc *ike_alg_get_dh_group(u_int alg);
-extern const struct dh_desc* ike_alg_pfsgroup(struct connection *c, lset_t policy);
-extern struct db_context * ike_alg_db_new(struct connection *c, lset_t policy);
-extern void ike_alg_list(void);
-extern void ike_alg_show_connection(struct connection *c, const char *instance);
-extern bool ike_alg_ok_final(u_int ealg, u_int key_len, u_int aalg, u_int group
-       , struct alg_info_ike *alg_info_ike);
-extern int ike_alg_init(void);
-
-#endif /* _IKE_ALG_H */
diff --git a/src/pluto/ipsec_doi.c b/src/pluto/ipsec_doi.c
deleted file mode 100644 (file)
index 3e7adcc..0000000
+++ /dev/null
@@ -1,5921 +0,0 @@
-/* IPsec DOI and Oakley resolution routines
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2002  D. Hugh Redelmeier.
- * Copyright (C) 2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <resolv.h>
-#include <arpa/nameser.h>       /* missing from <resolv.h> on old systems */
-#include <sys/queue.h>
-
-#include <freeswan.h>
-
-#include <library.h>
-#include <asn1/asn1.h>
-#include <crypto/hashers/hasher.h>
-#include <crypto/prfs/prf.h>
-#include <crypto/rngs/rng.h>
-#include <credentials/keys/private_key.h>
-#include <credentials/keys/public_key.h>
-#include <utils/identification.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "myid.h"
-#include "state.h"
-#include "x509.h"
-#include "ac.h"
-#include "crl.h"
-#include "ca.h"
-#include "certs.h"
-#include "smartcard.h"
-#include "connections.h"
-#include "keys.h"
-#include "packet.h"
-#include "demux.h"      /* needs packet.h */
-#include "adns.h"       /* needs <resolv.h> */
-#include "dnskey.h"     /* needs keys.h and adns.h */
-#include "kernel.h"
-#include "log.h"
-#include "cookie.h"
-#include "server.h"
-#include "spdb.h"
-#include "timer.h"
-#include "ipsec_doi.h"  /* needs demux.h and state.h */
-#include "whack.h"
-#include "fetch.h"
-#include "pkcs7.h"
-#include "crypto.h"
-#include "vendor.h"
-#include "alg_info.h"
-#include "ike_alg.h"
-#include "kernel_alg.h"
-#include "nat_traversal.h"
-#include "virtual.h"
-
-/*
- * are we sending Pluto's Vendor ID?
- */
-#ifdef VENDORID
-#define SEND_PLUTO_VID  1
-#else /* !VENDORID */
-#define SEND_PLUTO_VID  0
-#endif /* !VENDORID */
-
-/*
- * are we sending an XAUTH VID?
- */
-#ifdef XAUTH_VID
-#define SEND_XAUTH_VID  1
-#else /* !XAUTH_VID */
-#define SEND_XAUTH_VID  0
-#endif /* !XAUTH_VID */
-
-/*
- * are we sending a Cisco Unity VID?
- */
-#ifdef CISCO_QUIRKS
-#define SEND_CISCO_UNITY_VID    1
-#else /* !CISCO_QUIRKS */
-#define SEND_CISCO_UNITY_VID    0
-#endif /* !CISCO_QUIRKS */
-
-/* MAGIC: perform f, a function that returns notification_t
- * and return from the ENCLOSING stf_status returning function if it fails.
- */
-#define RETURN_STF_FAILURE(f) \
-       { int r = (f); if (r != ISAKMP_NOTHING_WRONG) return STF_FAIL + r; }
-
-/* The endpoint(s) for which an SA is getting installed, so keying material
- * can be properly wiped.
- */
-enum endpoint {
-       EP_LOCAL  = 1,
-       EP_REMOTE = 1 << 1,
-};
-
-/* create output HDR as replica of input HDR */
-void echo_hdr(struct msg_digest *md, bool enc, u_int8_t np)
-{
-       struct isakmp_hdr r_hdr = md->hdr;  /* mostly same as incoming header */
-
-       r_hdr.isa_flags &= ~ISAKMP_FLAG_COMMIT;     /* we won't ever turn on this bit */
-       if (enc)
-       {
-               r_hdr.isa_flags |= ISAKMP_FLAG_ENCRYPTION;
-       }
-       /* some day, we may have to set r_hdr.isa_version */
-       r_hdr.isa_np = np;
-       if (!out_struct(&r_hdr, &isakmp_hdr_desc, &md->reply, &md->rbody))
-       {
-               impossible();   /* surely must have room and be well-formed */
-       }
-}
-
-/* Compute DH shared secret from our local secret and the peer's public value.
- * We make the leap that the length should be that of the group
- * (see quoted passage at start of ACCEPT_KE).
- */
-static void compute_dh_shared(struct state *st, const chunk_t g)
-{
-       passert(st->st_dh);
-       st->st_dh->set_other_public_value(st->st_dh, g);
-       st->st_dh->get_shared_secret(st->st_dh, &st->st_shared);
-       DBG_cond_dump_chunk(DBG_CRYPT, "DH shared secret:\n", st->st_shared);
-}
-
-/* if we haven't already done so, compute a local DH secret (st->st_sec) and
- * the corresponding public value (g).  This is emitted as a KE payload.
- */
-static bool build_and_ship_KE(struct state *st, chunk_t *g,
-                                                         const struct dh_desc *group,
-                                                         pb_stream *outs, u_int8_t np)
-{
-       if (st->st_dh == NULL)
-       {
-               st->st_dh = lib->crypto->create_dh(lib->crypto, group->algo_id);
-               if (st->st_dh == NULL)
-               {
-                       plog("Diffie Hellman group %N is not available",
-                                diffie_hellman_group_names, group->algo_id);
-                       return FALSE;
-               }
-       }
-       st->st_dh->get_my_public_value(st->st_dh, g);
-       DBG(DBG_CRYPT,
-               DBG_dump_chunk("Public DH value sent:\n", *g)
-       )
-       return out_generic_chunk(np, &isakmp_keyex_desc, outs, *g, "keyex value");
-}
-
-/* accept_ke
- *
- * Check and accept DH public value (Gi or Gr) from peer's message.
- * According to RFC2409 "The Internet key exchange (IKE)" 5:
- *  The Diffie-Hellman public value passed in a KE payload, in either
- *  a phase 1 or phase 2 exchange, MUST be the length of the negotiated
- *  Diffie-Hellman group enforced, if necessary, by pre-pending the
- *  value with zeros.
- */
-static notification_t accept_KE(chunk_t *dest, const char *val_name,
-                                                               const struct dh_desc *gr,
-                                                               pb_stream *pbs)
-{
-       if (pbs_left(pbs) != gr->ke_size)
-       {
-               loglog(RC_LOG_SERIOUS, "KE has %u byte DH public value; %u required"
-                       , (unsigned) pbs_left(pbs), gr->ke_size);
-               /* XXX Could send notification back */
-               return ISAKMP_INVALID_KEY_INFORMATION;
-       }
-       free(dest->ptr);
-       *dest = chunk_create(pbs->cur, pbs_left(pbs));
-       *dest = chunk_clone(*dest);
-       DBG_cond_dump_chunk(DBG_CRYPT, "DH public value received:\n", *dest);
-       return ISAKMP_NOTHING_WRONG;
-}
-
-/* accept_PFS_KE
- *
- * Check and accept optional Quick Mode KE payload for PFS.
- * Extends ACCEPT_PFS to check whether KE is allowed or required.
- */
-static notification_t accept_PFS_KE(struct msg_digest *md, chunk_t *dest,
-                                                                       const char *val_name, const char *msg_name)
-{
-       struct state *st = md->st;
-       struct payload_digest *const ke_pd = md->chain[ISAKMP_NEXT_KE];
-
-       if (ke_pd == NULL)
-       {
-               if (st->st_pfs_group != NULL)
-               {
-                       loglog(RC_LOG_SERIOUS, "missing KE payload in %s message", msg_name);
-                       return ISAKMP_INVALID_KEY_INFORMATION;
-               }
-       }
-       else
-       {
-               if (st->st_pfs_group == NULL)
-               {
-                       loglog(RC_LOG_SERIOUS, "%s message KE payload requires a GROUP_DESCRIPTION attribute in SA"
-                               , msg_name);
-                       return ISAKMP_INVALID_KEY_INFORMATION;
-               }
-               if (ke_pd->next != NULL)
-               {
-                       loglog(RC_LOG_SERIOUS, "%s message contains several KE payloads; we accept at most one", msg_name);
-                       return ISAKMP_INVALID_KEY_INFORMATION;     /* ??? */
-               }
-               return accept_KE(dest, val_name, st->st_pfs_group, &ke_pd->pbs);
-       }
-       return ISAKMP_NOTHING_WRONG;
-}
-
-static bool build_and_ship_nonce(chunk_t *n, pb_stream *outs, u_int8_t np,
-                                                                const char *name)
-{
-       rng_t *rng;
-
-       free(n->ptr);
-       *n = chunk_create(malloc(DEFAULT_NONCE_SIZE), DEFAULT_NONCE_SIZE);
-       rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
-       rng->get_bytes(rng, DEFAULT_NONCE_SIZE, n->ptr);
-       rng->destroy(rng);
-       return out_generic_chunk(np, &isakmp_nonce_desc, outs, *n, name);
-}
-
-static linked_list_t* collect_rw_ca_candidates(struct msg_digest *md)
-{
-       linked_list_t *list = linked_list_create();
-       connection_t *d;
-
-       d = find_host_connection(&md->iface->addr, pluto_port, (ip_address*)NULL,
-                                                         md->sender_port, LEMPTY);
-
-       for (; d != NULL; d = d->hp_next)
-       {
-               /* must be a road warrior connection */
-               if (d->kind == CK_TEMPLATE && !(d->policy & POLICY_OPPO) &&
-                       d->spd.that.ca)
-               {
-                       enumerator_t *enumerator;
-                       identification_t *ca;
-                       bool new_entry = TRUE;
-
-                       enumerator = list->create_enumerator(list);
-                       while (enumerator->enumerate(enumerator, &ca))
-                       {
-                               if (ca->equals(ca, d->spd.that.ca))
-                               {
-                                       new_entry = FALSE;
-                                       break;
-                               }
-                       }
-                       enumerator->destroy(enumerator);
-
-                       if (new_entry)
-                       {
-                               list->insert_last(list, d->spd.that.ca->clone(d->spd.that.ca));
-                       }
-               }
-       }
-       return list;
-}
-
-static bool build_and_ship_CR(u_int8_t type, chunk_t ca, pb_stream *outs,
-                                                         u_int8_t np)
-{
-       pb_stream cr_pbs;
-       struct isakmp_cr cr_hd;
-       cr_hd.isacr_np = np;
-       cr_hd.isacr_type = type;
-
-       /* build CR header */
-       if (!out_struct(&cr_hd, &isakmp_ipsec_cert_req_desc, outs, &cr_pbs))
-       {
-               return FALSE;
-       }
-       if (ca.ptr != NULL)
-       {
-               /* build CR body containing the distinguished name of the CA */
-               if (!out_chunk(ca, &cr_pbs, "CA"))
-                       return FALSE;
-       }
-       close_output_pbs(&cr_pbs);
-       return TRUE;
-}
-
-/* Send a notification to the peer.  We could decide
- * whether to send the notification, based on the type and the
- * destination, if we care to.
- */
-static void send_notification(struct state *sndst, u_int16_t type,
-                                                         struct state *encst, msgid_t msgid,
-                                                         u_char *icookie, u_char *rcookie,
-                                                         u_char *spi, size_t spisize, u_char protoid)
-{
-       u_char buffer[1024];
-       pb_stream pbs, r_hdr_pbs;
-       u_char *r_hashval    = NULL;  /* where in reply to jam hash value */
-       u_char *r_hash_start = NULL;  /* start of what is to be hashed */
-
-       passert((sndst) && (sndst->st_connection));
-
-       plog("sending %snotification %s to %s:%u"
-               , encst ? "encrypted " : ""
-               , enum_name(&notification_names, type)
-               , ip_str(&sndst->st_connection->spd.that.host_addr)
-               , (unsigned)sndst->st_connection->spd.that.host_port);
-
-       memset(buffer, 0, sizeof(buffer));
-       init_pbs(&pbs, buffer, sizeof(buffer), "ISAKMP notify");
-
-       /* HDR* */
-       {
-               struct isakmp_hdr hdr;
-
-               hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION;
-               hdr.isa_np = encst ? ISAKMP_NEXT_HASH : ISAKMP_NEXT_N;
-               hdr.isa_xchg = ISAKMP_XCHG_INFO;
-               hdr.isa_msgid = msgid;
-               hdr.isa_flags = encst ? ISAKMP_FLAG_ENCRYPTION : 0;
-               if (icookie)
-               {
-                       memcpy(hdr.isa_icookie, icookie, COOKIE_SIZE);
-               }
-               if (rcookie)
-               {
-                       memcpy(hdr.isa_rcookie, rcookie, COOKIE_SIZE);
-               }
-               if (!out_struct(&hdr, &isakmp_hdr_desc, &pbs, &r_hdr_pbs))
-               {
-                       impossible();
-               }
-       }
-
-       /* HASH -- value to be filled later */
-       if (encst)
-       {
-               pb_stream hash_pbs;
-               if (!out_generic(ISAKMP_NEXT_N, &isakmp_hash_desc, &r_hdr_pbs, &hash_pbs))
-               {
-                       impossible();
-               }
-               r_hashval = hash_pbs.cur;  /* remember where to plant value */
-               if (!out_zero(
-               encst->st_oakley.hasher->hash_digest_size, &hash_pbs, "HASH"))
-               {
-                       impossible();
-               }
-               close_output_pbs(&hash_pbs);
-               r_hash_start = r_hdr_pbs.cur; /* hash from after HASH */
-       }
-
-       /* Notification Payload */
-       {
-               pb_stream not_pbs;
-               struct isakmp_notification isan;
-
-               isan.isan_doi = ISAKMP_DOI_IPSEC;
-               isan.isan_np = ISAKMP_NEXT_NONE;
-               isan.isan_type = type;
-               isan.isan_spisize = spisize;
-               isan.isan_protoid = protoid;
-
-               if (!out_struct(&isan, &isakmp_notification_desc, &r_hdr_pbs, &not_pbs)
-                       || !out_raw(spi, spisize, &not_pbs, "spi"))
-               {
-                       impossible();
-               }
-               close_output_pbs(&not_pbs);
-       }
-
-       /* calculate hash value and patch into Hash Payload */
-       if (encst)
-       {
-               chunk_t msgid_chunk = chunk_from_thing(msgid);
-               chunk_t msg_chunk = { r_hash_start, r_hdr_pbs.cur-r_hash_start };
-               pseudo_random_function_t prf_alg;
-               prf_t *prf;
-
-               prf_alg = oakley_to_prf(encst->st_oakley.hash);
-               prf = lib->crypto->create_prf(lib->crypto, prf_alg);
-               prf->set_key(prf, encst->st_skeyid_a);
-               prf->get_bytes(prf, msgid_chunk, NULL);
-               prf->get_bytes(prf, msg_chunk, r_hashval);
-
-               DBG(DBG_CRYPT,
-                       DBG_log("HASH computed:");
-                       DBG_dump("", r_hashval, prf->get_block_size(prf));
-               )
-               prf->destroy(prf);
-       }
-
-       /* Encrypt message (preserve st_iv and st_new_iv) */
-       if (encst)
-       {
-               u_char old_iv[MAX_DIGEST_LEN];
-               u_char new_iv[MAX_DIGEST_LEN];
-
-               u_int old_iv_len = encst->st_iv_len;
-               u_int new_iv_len = encst->st_new_iv_len;
-
-               if (old_iv_len > MAX_DIGEST_LEN || new_iv_len > MAX_DIGEST_LEN)
-               {
-                       impossible();
-               }
-               memcpy(old_iv, encst->st_iv, old_iv_len);
-               memcpy(new_iv, encst->st_new_iv, new_iv_len);
-
-               if (!IS_ISAKMP_SA_ESTABLISHED(encst->st_state))
-               {
-                       memcpy(encst->st_ph1_iv, encst->st_new_iv, encst->st_new_iv_len);
-                       encst->st_ph1_iv_len = encst->st_new_iv_len;
-               }
-               init_phase2_iv(encst, &msgid);
-               if (!encrypt_message(&r_hdr_pbs, encst))
-               {
-                       impossible();
-               }
-
-               /* restore preserved st_iv and st_new_iv */
-               memcpy(encst->st_iv, old_iv, old_iv_len);
-               memcpy(encst->st_new_iv, new_iv, new_iv_len);
-               encst->st_iv_len = old_iv_len;
-               encst->st_new_iv_len = new_iv_len;
-       }
-       else
-       {
-               close_output_pbs(&r_hdr_pbs);
-       }
-
-       /* Send packet (preserve st_tpacket) */
-       {
-               chunk_t saved_tpacket = sndst->st_tpacket;
-
-               sndst->st_tpacket = chunk_create(pbs.start, pbs_offset(&pbs));
-               send_packet(sndst, "ISAKMP notify");
-               sndst->st_tpacket = saved_tpacket;
-       }
-}
-
-void send_notification_from_state(struct state *st, enum state_kind state,
-                                                                 u_int16_t type)
-{
-       struct state *p1st;
-
-       passert(st);
-
-       if (state == STATE_UNDEFINED)
-               state = st->st_state;
-
-       if (IS_QUICK(state))
-       {
-               p1st = find_phase1_state(st->st_connection, ISAKMP_SA_ESTABLISHED_STATES);
-               if ((p1st == NULL) || (!IS_ISAKMP_SA_ESTABLISHED(p1st->st_state)))
-               {
-                       loglog(RC_LOG_SERIOUS,
-                               "no Phase1 state for Quick mode notification");
-                       return;
-               }
-               send_notification(st, type, p1st, generate_msgid(p1st),
-                       st->st_icookie, st->st_rcookie, NULL, 0, PROTO_ISAKMP);
-       }
-       else if (IS_ISAKMP_ENCRYPTED(state) && st->st_enc_key.ptr != NULL)
-       {
-               send_notification(st, type, st, generate_msgid(st),
-                       st->st_icookie, st->st_rcookie, NULL, 0, PROTO_ISAKMP);
-       }
-       else
-       {
-               /* no ISAKMP SA established - don't encrypt notification */
-               send_notification(st, type, NULL, 0,
-                       st->st_icookie, st->st_rcookie, NULL, 0, PROTO_ISAKMP);
-       }
-}
-
-void send_notification_from_md(struct msg_digest *md, u_int16_t type)
-{
-       /**
-        * Create a dummy state to be able to use send_packet in
-        * send_notification
-        *
-        * we need to set:
-        *   st_connection->that.host_addr
-        *   st_connection->that.host_port
-        *   st_connection->interface
-        */
-       struct state st;
-       connection_t cnx;
-
-       passert(md);
-
-       memset(&st, 0, sizeof(st));
-       memset(&cnx, 0, sizeof(cnx));
-       st.st_connection = &cnx;
-       cnx.spd.that.host_addr = md->sender;
-       cnx.spd.that.host_port = md->sender_port;
-       cnx.interface = md->iface;
-
-       send_notification(&st, type, NULL, 0,
-               md->hdr.isa_icookie, md->hdr.isa_rcookie, NULL, 0, PROTO_ISAKMP);
-}
-
-/* Send a Delete Notification to announce deletion of ISAKMP SA or
- * inbound IPSEC SAs.  Does nothing if no such SAs are being deleted.
- * Delete Notifications cannot announce deletion of outbound IPSEC/ISAKMP SAs.
- */
-void send_delete(struct state *st)
-{
-       pb_stream reply_pbs;
-       pb_stream r_hdr_pbs;
-       msgid_t     msgid;
-       u_char buffer[8192];
-       struct state *p1st;
-       ip_said said[EM_MAXRELSPIS];
-       ip_said *ns = said;
-       u_char
-               *r_hashval,     /* where in reply to jam hash value */
-               *r_hash_start;  /* start of what is to be hashed */
-       bool isakmp_sa = FALSE;
-
-       if (IS_IPSEC_SA_ESTABLISHED(st->st_state))
-       {
-               p1st = find_phase1_state(st->st_connection, ISAKMP_SA_ESTABLISHED_STATES);
-               if (p1st == NULL)
-               {
-                       DBG(DBG_CONTROL, DBG_log("no Phase 1 state for Delete"));
-                       return;
-               }
-
-               if (st->st_ah.present)
-               {
-                       ns->spi = st->st_ah.our_spi;
-                       ns->dst = st->st_connection->spd.this.host_addr;
-                       ns->proto = PROTO_IPSEC_AH;
-                       ns++;
-               }
-               if (st->st_esp.present)
-               {
-                       ns->spi = st->st_esp.our_spi;
-                       ns->dst = st->st_connection->spd.this.host_addr;
-                       ns->proto = PROTO_IPSEC_ESP;
-                       ns++;
-               }
-
-               passert(ns != said);    /* there must be some SAs to delete */
-       }
-       else if (IS_ISAKMP_SA_ESTABLISHED(st->st_state))
-       {
-               p1st = st;
-               isakmp_sa = TRUE;
-       }
-       else
-       {
-               return; /* nothing to do */
-       }
-
-       msgid = generate_msgid(p1st);
-
-       zero(buffer);
-       init_pbs(&reply_pbs, buffer, sizeof(buffer), "delete msg");
-
-       /* HDR* */
-       {
-               struct isakmp_hdr hdr;
-
-               hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION;
-               hdr.isa_np = ISAKMP_NEXT_HASH;
-               hdr.isa_xchg = ISAKMP_XCHG_INFO;
-               hdr.isa_msgid = msgid;
-               hdr.isa_flags = ISAKMP_FLAG_ENCRYPTION;
-               memcpy(hdr.isa_icookie, p1st->st_icookie, COOKIE_SIZE);
-               memcpy(hdr.isa_rcookie, p1st->st_rcookie, COOKIE_SIZE);
-               if (!out_struct(&hdr, &isakmp_hdr_desc, &reply_pbs, &r_hdr_pbs))
-                       impossible();
-       }
-
-       /* HASH -- value to be filled later */
-       {
-               pb_stream hash_pbs;
-
-               if (!out_generic(ISAKMP_NEXT_D, &isakmp_hash_desc, &r_hdr_pbs, &hash_pbs))
-               {
-                       impossible();
-               }
-               r_hashval = hash_pbs.cur;       /* remember where to plant value */
-               if (!out_zero(p1st->st_oakley.hasher->hash_digest_size, &hash_pbs, "HASH(1)"))
-               {
-                       impossible();
-               }
-               close_output_pbs(&hash_pbs);
-               r_hash_start = r_hdr_pbs.cur;   /* hash from after HASH(1) */
-       }
-
-       /* Delete Payloads */
-       if (isakmp_sa)
-       {
-               pb_stream del_pbs;
-               struct isakmp_delete isad;
-               u_char isakmp_spi[2*COOKIE_SIZE];
-
-               isad.isad_doi = ISAKMP_DOI_IPSEC;
-               isad.isad_np = ISAKMP_NEXT_NONE;
-               isad.isad_spisize = (2 * COOKIE_SIZE);
-               isad.isad_protoid = PROTO_ISAKMP;
-               isad.isad_nospi = 1;
-
-               memcpy(isakmp_spi, st->st_icookie, COOKIE_SIZE);
-               memcpy(isakmp_spi+COOKIE_SIZE, st->st_rcookie, COOKIE_SIZE);
-
-               if (!out_struct(&isad, &isakmp_delete_desc, &r_hdr_pbs, &del_pbs)
-               || !out_raw(&isakmp_spi, (2*COOKIE_SIZE), &del_pbs, "delete payload"))
-               {
-                       impossible();
-               }
-               close_output_pbs(&del_pbs);
-       }
-       else
-       {
-               while (ns != said)
-               {
-
-                       pb_stream del_pbs;
-                       struct isakmp_delete isad;
-
-                       ns--;
-                       isad.isad_doi = ISAKMP_DOI_IPSEC;
-                       isad.isad_np = ns == said? ISAKMP_NEXT_NONE : ISAKMP_NEXT_D;
-                       isad.isad_spisize = sizeof(ipsec_spi_t);
-                       isad.isad_protoid = ns->proto;
-
-                       isad.isad_nospi = 1;
-                       if (!out_struct(&isad, &isakmp_delete_desc, &r_hdr_pbs, &del_pbs)
-                       || !out_raw(&ns->spi, sizeof(ipsec_spi_t), &del_pbs, "delete payload"))
-                       {
-                               impossible();
-                       }
-                       close_output_pbs(&del_pbs);
-               }
-       }
-
-       /* calculate hash value and patch into Hash Payload */
-       {
-               chunk_t msgid_chunk = chunk_from_thing(msgid);
-               chunk_t msg_chunk = { r_hash_start, r_hdr_pbs.cur-r_hash_start };
-               pseudo_random_function_t prf_alg;
-               prf_t *prf;
-
-               prf_alg = oakley_to_prf(p1st->st_oakley.hash);
-               prf = lib->crypto->create_prf(lib->crypto, prf_alg);
-               prf->set_key(prf, p1st->st_skeyid_a);
-               prf->get_bytes(prf, msgid_chunk, NULL);
-               prf->get_bytes(prf, msg_chunk, r_hashval);
-
-               DBG(DBG_CRYPT,
-                       DBG_log("HASH(1) computed:");
-                       DBG_dump("", r_hashval, prf->get_block_size(prf));
-               )
-
-               prf->destroy(prf);
-       }
-
-       /* Do a dance to avoid needing a new state object.
-        * We use the Phase 1 State.  This is the one with right
-        * IV, for one thing.
-        * The tricky bits are:
-        * - we need to preserve (save/restore) st_iv (but not st_iv_new)
-        * - we need to preserve (save/restore) st_tpacket.
-        */
-       {
-               u_char old_iv[MAX_DIGEST_LEN];
-               chunk_t saved_tpacket = p1st->st_tpacket;
-
-               memcpy(old_iv, p1st->st_iv, p1st->st_iv_len);
-               init_phase2_iv(p1st, &msgid);
-
-               if (!encrypt_message(&r_hdr_pbs, p1st))
-               {
-                       impossible();
-               }
-               p1st->st_tpacket = chunk_create(reply_pbs.start, pbs_offset(&reply_pbs));
-               send_packet(p1st, "delete notify");
-               p1st->st_tpacket = saved_tpacket;
-
-               /* get back old IV for this state */
-               memcpy(p1st->st_iv, old_iv, p1st->st_iv_len);
-       }
-}
-
-void accept_delete(struct state *st, struct msg_digest *md,
-                                  struct payload_digest *p)
-{
-       struct isakmp_delete *d = &(p->payload.delete);
-       identification_t *this_id = NULL, *that_id = NULL;
-       ip_address peer_addr;
-       size_t sizespi;
-       int i;
-
-       if (!md->encrypted)
-       {
-               loglog(RC_LOG_SERIOUS, "ignoring Delete SA payload: not encrypted");
-               return;
-       }
-
-       if (!IS_ISAKMP_SA_ESTABLISHED(st->st_state))
-       {
-               /* can't happen (if msg is encrypt), but just to be sure */
-               loglog(RC_LOG_SERIOUS, "ignoring Delete SA payload: "
-               "ISAKMP SA not established");
-               return;
-       }
-
-       if (d->isad_nospi == 0)
-       {
-               loglog(RC_LOG_SERIOUS, "ignoring Delete SA payload: no SPI");
-               return;
-       }
-
-       switch (d->isad_protoid)
-       {
-       case PROTO_ISAKMP:
-               sizespi = 2 * COOKIE_SIZE;
-               break;
-       case PROTO_IPSEC_AH:
-       case PROTO_IPSEC_ESP:
-               sizespi = sizeof(ipsec_spi_t);
-               break;
-       case PROTO_IPCOMP:
-               /* nothing interesting to delete */
-               return;
-       default:
-               loglog(RC_LOG_SERIOUS
-                       , "ignoring Delete SA payload: unknown Protocol ID (%s)"
-                       , enum_show(&protocol_names, d->isad_protoid));
-               return;
-       }
-
-       if (d->isad_spisize != sizespi)
-       {
-               loglog(RC_LOG_SERIOUS
-                       , "ignoring Delete SA payload: bad SPI size (%d) for %s"
-                       , d->isad_spisize, enum_show(&protocol_names, d->isad_protoid));
-               return;
-       }
-
-       if (pbs_left(&p->pbs) != d->isad_nospi * sizespi)
-       {
-               loglog(RC_LOG_SERIOUS
-                       , "ignoring Delete SA payload: invalid payload size");
-               return;
-       }
-
-       if (d->isad_protoid == PROTO_ISAKMP)
-       {
-               struct end *this = &st->st_connection->spd.this;
-               struct end *that = &st->st_connection->spd.that;
-               this_id = this->id->clone(this->id);
-               that_id = that->id->clone(that->id);
-               peer_addr = st->st_connection->spd.that.host_addr;
-       }
-
-       for (i = 0; i < d->isad_nospi; i++)
-       {
-               u_char *spi = p->pbs.cur + (i * sizespi);
-
-               if (d->isad_protoid == PROTO_ISAKMP)
-               {
-                       /**
-                        * ISAKMP
-                        */
-                       struct state *dst = find_state(spi /*iCookie*/
-                               , spi+COOKIE_SIZE /*rCookie*/
-                               , &peer_addr
-                               , MAINMODE_MSGID);
-
-                       if (dst == NULL)
-                       {
-                               loglog(RC_LOG_SERIOUS, "ignoring Delete SA payload: "
-                                       "ISAKMP SA not found (maybe expired)");
-                       }
-                       else if (! this_id->equals(this_id, dst->st_connection->spd.this.id) ||
-                                        ! that_id->equals(that_id, dst->st_connection->spd.that.id))
-                       {
-                               /* we've not authenticated the relevant identities */
-                               loglog(RC_LOG_SERIOUS, "ignoring Delete SA payload: "
-                                       "ISAKMP SA used to convey Delete has different IDs from ISAKMP SA it deletes");
-                       }
-                       else
-                       {
-                               connection_t *oldc;
-
-                               oldc = cur_connection;
-                               set_cur_connection(dst->st_connection);
-
-                               if (nat_traversal_enabled)
-                               {
-                                       nat_traversal_change_port_lookup(md, dst);
-                               }
-                               loglog(RC_LOG_SERIOUS, "received Delete SA payload: "
-                                       "deleting ISAKMP State #%lu", dst->st_serialno);
-                               delete_state(dst);
-                               set_cur_connection(oldc);
-                       }
-               }
-               else
-               {
-                       /**
-                        * IPSEC (ESP/AH)
-                        */
-                       bool bogus;
-                       struct state *dst = find_phase2_state_to_delete(st
-                               , d->isad_protoid
-                               , *(ipsec_spi_t *)spi   /* network order */
-                               , &bogus);
-
-                       if (dst == NULL)
-                       {
-                               loglog(RC_LOG_SERIOUS
-                                          , "ignoring Delete SA payload: %s SA(0x%08lx) not found (%s)"
-                                          , enum_show(&protocol_names, d->isad_protoid)
-                                          , (unsigned long)ntohl((unsigned long)*(ipsec_spi_t *)spi)
-                                          , bogus ? "our SPI - bogus implementation" : "maybe expired");
-                       }
-                       else
-                       {
-                               connection_t *rc = dst->st_connection;
-                               connection_t *oldc;
-
-                               oldc = cur_connection;
-                               set_cur_connection(rc);
-
-                               if (nat_traversal_enabled)
-                               {
-                                       nat_traversal_change_port_lookup(md, dst);
-                               }
-                               if (rc->newest_ipsec_sa == dst->st_serialno
-                               && (rc->policy & POLICY_UP))
-                               {
-                                       /* Last IPSec SA for a permanent connection that we
-                                        * have initiated.  Replace it in a few seconds.
-                                        *
-                                        * Useful if the other peer is rebooting.
-                                        */
-#define DELETE_SA_DELAY  EVENT_RETRANSMIT_DELAY_0
-                                       if (dst->st_event != NULL
-                                       && dst->st_event->ev_type == EVENT_SA_REPLACE
-                                       && dst->st_event->ev_time <= DELETE_SA_DELAY + now())
-                                       {
-                                               /* Patch from Angus Lees to ignore retransmited
-                                                * Delete SA.
-                                                */
-                                               loglog(RC_LOG_SERIOUS, "received Delete SA payload: "
-                                                       "already replacing IPSEC State #%lu in %d seconds"
-                                                       , dst->st_serialno, (int)(dst->st_event->ev_time - now()));
-                                       }
-                                       else
-                                       {
-                                               loglog(RC_LOG_SERIOUS, "received Delete SA payload: "
-                                                       "replace IPSEC State #%lu in %d seconds"
-                                                       , dst->st_serialno, DELETE_SA_DELAY);
-                                               dst->st_margin = DELETE_SA_DELAY;
-                                               delete_event(dst);
-                                               event_schedule(EVENT_SA_REPLACE, DELETE_SA_DELAY, dst);
-                                       }
-                               }
-                               else
-                               {
-                                       loglog(RC_LOG_SERIOUS, "received Delete SA(0x%08lx) payload: "
-                                                  "deleting IPSEC State #%lu"
-                                                  , (unsigned long)ntohl((unsigned long)*(ipsec_spi_t *)spi)
-                                                  , dst->st_serialno);
-                                       delete_state(dst);
-                               }
-
-                               /* reset connection */
-                               set_cur_connection(oldc);
-                       }
-               }
-       }
-
-       if (d->isad_protoid == PROTO_ISAKMP)
-       {
-               this_id->destroy(this_id);
-               that_id->destroy(that_id);
-       }
-}
-
-/* The whole message must be a multiple of 4 octets.
- * I'm not sure where this is spelled out, but look at
- * rfc2408 3.6 Transform Payload.
- * Note: it talks about 4 BYTE boundaries!
- */
-void close_message(pb_stream *pbs)
-{
-       size_t padding =  pad_up(pbs_offset(pbs), 4);
-
-       if (padding != 0)
-       {
-               (void) out_zero(padding, pbs, "message padding");
-       }
-       close_output_pbs(pbs);
-}
-
-/* Initiate an Oakley Main Mode exchange.
- * --> HDR;SA
- * Note: this is not called from demux.c
- */
-static stf_status
-main_outI1(int whack_sock, connection_t *c, struct state *predecessor
-       , lset_t policy, unsigned long try)
-{
-       struct state *st = new_state();
-       pb_stream reply;    /* not actually a reply, but you know what I mean */
-       pb_stream rbody;
-       int vids_to_send = 0;
-
-       /* set up new state */
-       st->st_connection = c;
-       set_cur_state(st);  /* we must reset before exit */
-       st->st_policy = policy & ~POLICY_IPSEC_MASK;
-       st->st_whack_sock = whack_sock;
-       st->st_try = try;
-       st->st_state = STATE_MAIN_I1;
-
-       /* determine how many Vendor ID payloads we will be sending */
-       if (SEND_PLUTO_VID)
-       {
-               vids_to_send++;
-       }
-       if (SEND_CISCO_UNITY_VID)
-       {
-               vids_to_send++;
-       }
-       if (c->spd.this.cert &&
-               c->spd.this.cert->cert->get_type(c->spd.this.cert->cert) == CERT_GPG)
-       {
-               vids_to_send++;
-       }
-       if (SEND_XAUTH_VID)
-       {
-               vids_to_send++;
-       }
-
-       /* always send DPD Vendor ID */
-       vids_to_send++;
-
-       if (nat_traversal_enabled)
-       {
-               vids_to_send++;
-       }
-
-   get_cookie(TRUE, st->st_icookie, COOKIE_SIZE, &c->spd.that.host_addr);
-
-       insert_state(st);   /* needs cookies, connection, and msgid (0) */
-
-       if (HAS_IPSEC_POLICY(policy))
-       {
-               add_pending(dup_any(whack_sock), st, c, policy, 1
-                       , predecessor == NULL? SOS_NOBODY : predecessor->st_serialno);
-       }
-       if (predecessor == NULL)
-       {
-               plog("initiating Main Mode");
-       }
-       else
-       {
-               plog("initiating Main Mode to replace #%lu", predecessor->st_serialno);
-       }
-
-       /* set up reply */
-       init_pbs(&reply, reply_buffer, sizeof(reply_buffer), "reply packet");
-
-       /* HDR out */
-       {
-               struct isakmp_hdr hdr;
-
-               zero(&hdr);     /* default to 0 */
-               hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION;
-               hdr.isa_np = ISAKMP_NEXT_SA;
-               hdr.isa_xchg = ISAKMP_XCHG_IDPROT;
-               memcpy(hdr.isa_icookie, st->st_icookie, COOKIE_SIZE);
-               /* R-cookie, flags and MessageID are left zero */
-
-               if (!out_struct(&hdr, &isakmp_hdr_desc, &reply, &rbody))
-               {
-                       reset_cur_state();
-                       return STF_INTERNAL_ERROR;
-               }
-       }
-
-       /* SA out */
-       {
-               u_char *sa_start = rbody.cur;
-
-               if (!out_sa(&rbody, &oakley_sadb, st, TRUE
-               , vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE))
-               {
-                       reset_cur_state();
-                       return STF_INTERNAL_ERROR;
-               }
-
-               /* save initiator SA for later HASH */
-               passert(st->st_p1isa.ptr == NULL);      /* no leak!  (MUST be first time) */
-               st->st_p1isa = chunk_create(sa_start, rbody.cur - sa_start);
-               st->st_p1isa = chunk_clone(st->st_p1isa);
-       }
-
-       /* if enabled send Pluto Vendor ID */
-       if (SEND_PLUTO_VID)
-       {
-               if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
-               , &rbody, VID_STRONGSWAN))
-               {
-                       reset_cur_state();
-                       return STF_INTERNAL_ERROR;
-               }
-       }
-
-       /* if enabled send Cisco Unity Vendor ID */
-       if (SEND_CISCO_UNITY_VID)
-       {
-               if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
-               , &rbody, VID_CISCO_UNITY))
-               {
-                       reset_cur_state();
-                       return STF_INTERNAL_ERROR;
-               }
-       }
-       /* if we  have an OpenPGP certificate we assume an
-        * OpenPGP peer and have to send the Vendor ID
-        */
-       if (c->spd.this.cert &&
-               c->spd.this.cert->cert->get_type(c->spd.this.cert->cert) == CERT_GPG)
-       {
-               if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
-               , &rbody, VID_OPENPGP))
-               {
-                       reset_cur_state();
-                       return STF_INTERNAL_ERROR;
-               }
-       }
-
-       /* Announce our ability to do eXtended AUTHentication to the peer */
-       if (SEND_XAUTH_VID)
-       {
-               if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
-               , &rbody, VID_MISC_XAUTH))
-               {
-                       reset_cur_state();
-                       return STF_INTERNAL_ERROR;
-               }
-       }
-
-       /* Announce our ability to do Dead Peer Detection to the peer */
-       {
-               if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
-               , &rbody, VID_MISC_DPD))
-               {
-                       reset_cur_state();
-                       return STF_INTERNAL_ERROR;
-               }
-       }
-
-       if (nat_traversal_enabled)
-       {
-               /* Add supported NAT-Traversal VID */
-               if (!nat_traversal_add_vid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
-               , &rbody))
-               {
-                       reset_cur_state();
-                       return STF_INTERNAL_ERROR;
-               }
-       }
-
-       close_message(&rbody);
-       close_output_pbs(&reply);
-       st->st_tpacket = chunk_create(reply.start, pbs_offset(&reply));
-       st->st_tpacket = chunk_clone(st->st_tpacket);
-
-       /* Transmit */
-
-       send_packet(st, "main_outI1");
-
-       /* Set up a retransmission event, half a minute henceforth */
-       delete_event(st);
-       event_schedule(EVENT_RETRANSMIT, EVENT_RETRANSMIT_DELAY_0, st);
-
-       if (predecessor != NULL)
-       {
-               update_pending(predecessor, st);
-               whack_log(RC_NEW_STATE + STATE_MAIN_I1
-                       , "%s: initiate, replacing #%lu"
-                       , enum_name(&state_names, st->st_state)
-                       , predecessor->st_serialno);
-       }
-       else
-       {
-               whack_log(RC_NEW_STATE + STATE_MAIN_I1
-                       , "%s: initiate", enum_name(&state_names, st->st_state));
-       }
-       reset_cur_state();
-       return STF_OK;
-}
-
-void ipsecdoi_initiate(int whack_sock, connection_t *c, lset_t policy,
-                                          unsigned long try, so_serial_t replacing)
-{
-       /* If there's already an ISAKMP SA established, use that and
-        * go directly to Quick Mode.  We are even willing to use one
-        * that is still being negotiated, but only if we are the Initiator
-        * (thus we can be sure that the IDs are not going to change;
-        * other issues around intent might matter).
-        * Note: there is no way to initiate with a Road Warrior.
-        */
-       struct state *st = find_phase1_state(c
-               , ISAKMP_SA_ESTABLISHED_STATES | PHASE1_INITIATOR_STATES);
-
-       if (st == NULL)
-       {
-               (void) main_outI1(whack_sock, c, NULL, policy, try);
-       }
-       else if (HAS_IPSEC_POLICY(policy))
-       {
-               if (!IS_ISAKMP_SA_ESTABLISHED(st->st_state))
-               {
-                       /* leave our Phase 2 negotiation pending */
-                       add_pending(whack_sock, st, c, policy, try, replacing);
-               }
-               else
-               {
-                       /* ??? we assume that peer_nexthop_sin isn't important:
-                        * we already have it from when we negotiated the ISAKMP SA!
-                        * It isn't clear what to do with the error return.
-                        */
-                       (void) quick_outI1(whack_sock, st, c, policy, try, replacing);
-               }
-       }
-       else
-       {
-               close_any(whack_sock);
-       }
-}
-
-/* Replace SA with a fresh one that is similar
- *
- * Shares some logic with ipsecdoi_initiate, but not the same!
- * - we must not reuse the ISAKMP SA if we are trying to replace it!
- * - if trying to replace IPSEC SA, use ipsecdoi_initiate to build
- *   ISAKMP SA if needed.
- * - duplicate whack fd, if live.
- * Does not delete the old state -- someone else will do that.
- */
-void ipsecdoi_replace(struct state *st, unsigned long try)
-{
-       int whack_sock = dup_any(st->st_whack_sock);
-       lset_t policy = st->st_policy;
-
-       if (IS_PHASE1(st->st_state))
-       {
-               passert(!HAS_IPSEC_POLICY(policy));
-               (void) main_outI1(whack_sock, st->st_connection, st, policy, try);
-       }
-       else
-       {
-               /* Add features of actual old state to policy.  This ensures
-                * that rekeying doesn't downgrade security.  I admit that
-                * this doesn't capture everything.
-                */
-               if (st->st_pfs_group != NULL)
-                       policy |= POLICY_PFS;
-               if (st->st_ah.present)
-               {
-                       policy |= POLICY_AUTHENTICATE;
-                       if (st->st_ah.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)
-                               policy |= POLICY_TUNNEL;
-               }
-               if (st->st_esp.present && st->st_esp.attrs.transid != ESP_NULL)
-               {
-                       policy |= POLICY_ENCRYPT;
-                       if (st->st_esp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)
-                               policy |= POLICY_TUNNEL;
-               }
-               if (st->st_ipcomp.present)
-               {
-                       policy |= POLICY_COMPRESS;
-                       if (st->st_ipcomp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)
-                               policy |= POLICY_TUNNEL;
-               }
-               passert(HAS_IPSEC_POLICY(policy));
-               ipsecdoi_initiate(whack_sock, st->st_connection, policy, try
-                       , st->st_serialno);
-       }
-}
-
-/* SKEYID for preshared keys.
- * See draft-ietf-ipsec-ike-01.txt 4.1
- */
-static bool skeyid_preshared(struct state *st)
-{
-       const chunk_t *pss = get_preshared_secret(st->st_connection);
-
-       if (pss == NULL)
-       {
-               loglog(RC_LOG_SERIOUS, "preshared secret disappeared!");
-               return FALSE;
-       }
-       else
-       {
-               pseudo_random_function_t prf_alg;
-               prf_t *prf;
-
-               prf_alg = oakley_to_prf(st->st_oakley.hash);
-               prf = lib->crypto->create_prf(lib->crypto, prf_alg);
-               if (prf == NULL)
-               {
-                       loglog(RC_LOG_SERIOUS, "%N not available to compute skeyid",
-                                                                       pseudo_random_function_names, prf_alg);
-                       return FALSE;
-               }
-               free(st->st_skeyid.ptr);
-               prf->set_key(prf, *pss);
-               prf->allocate_bytes(prf, st->st_ni, NULL);
-               prf->allocate_bytes(prf, st->st_nr, &st->st_skeyid);
-               prf->destroy(prf);
-               return TRUE;
-       }
-}
-
-static bool skeyid_digisig(struct state *st)
-{
-       chunk_t nir;
-       pseudo_random_function_t prf_alg;
-       prf_t *prf;
-
-       prf_alg = oakley_to_prf(st->st_oakley.hash);
-       prf = lib->crypto->create_prf(lib->crypto, prf_alg);
-       if (prf == NULL)
-       {
-               loglog(RC_LOG_SERIOUS, "%N not available to compute skeyid",
-                                                               pseudo_random_function_names, prf_alg);
-               return FALSE;
-       }
-       free(st->st_skeyid.ptr);
-       nir = chunk_cat("cc", st->st_ni, st->st_nr);
-       prf->set_key(prf, nir);
-       prf->allocate_bytes(prf, st->st_shared, &st->st_skeyid);
-       prf->destroy(prf);
-       free(nir.ptr);
-       return TRUE;
-}
-
-/* Generate the SKEYID_* and new IV
- * See draft-ietf-ipsec-ike-01.txt 4.1
- */
-static bool generate_skeyids_iv(struct state *st)
-{
-       /* Generate the SKEYID */
-       switch (st->st_oakley.auth)
-       {
-               case OAKLEY_PRESHARED_KEY:
-               case XAUTHInitPreShared:
-               case XAUTHRespPreShared:
-                       if (!skeyid_preshared(st))
-                       {
-                               return FALSE;
-                       }
-                       break;
-
-               case OAKLEY_RSA_SIG:
-               case OAKLEY_ECDSA_256:
-               case OAKLEY_ECDSA_384:
-               case OAKLEY_ECDSA_521:
-               case XAUTHInitRSA:
-               case XAUTHRespRSA:
-                       if (!skeyid_digisig(st))
-                       {
-                               return FALSE;
-                       }
-                       break;
-
-               case OAKLEY_DSS_SIG:
-                       /* XXX */
-
-               case OAKLEY_RSA_ENC:
-               case OAKLEY_RSA_ENC_REV:
-               case OAKLEY_ELGAMAL_ENC:
-               case OAKLEY_ELGAMAL_ENC_REV:
-                       /* XXX */
-
-               default:
-                       bad_case(st->st_oakley.auth);
-       }
-
-       /* generate SKEYID_* from SKEYID */
-       {
-               chunk_t seed_skeyid_d = chunk_from_chars(0x00);
-               chunk_t seed_skeyid_a = chunk_from_chars(0x01);
-               chunk_t seed_skeyid_e = chunk_from_chars(0x02);
-               chunk_t icookie = { st->st_icookie, COOKIE_SIZE };
-               chunk_t rcookie = { st->st_rcookie, COOKIE_SIZE };
-               pseudo_random_function_t prf_alg;
-               prf_t *prf;
-
-               prf_alg = oakley_to_prf(st->st_oakley.hash);
-               prf = lib->crypto->create_prf(lib->crypto, prf_alg);
-               prf->set_key(prf, st->st_skeyid);
-
-               /* SKEYID_D */
-               free(st->st_skeyid_d.ptr);
-               prf->allocate_bytes(prf, st->st_shared, NULL);
-               prf->allocate_bytes(prf, icookie, NULL);
-               prf->allocate_bytes(prf, rcookie, NULL);
-               prf->allocate_bytes(prf, seed_skeyid_d, &st->st_skeyid_d);
-
-               /* SKEYID_A */
-               free(st->st_skeyid_a.ptr);
-               prf->allocate_bytes(prf, st->st_skeyid_d, NULL);
-               prf->allocate_bytes(prf, st->st_shared, NULL);
-               prf->allocate_bytes(prf, icookie, NULL);
-               prf->allocate_bytes(prf, rcookie, NULL);
-               prf->allocate_bytes(prf, seed_skeyid_a, &st->st_skeyid_a);
-
-               /* SKEYID_E */
-               free(st->st_skeyid_e.ptr);
-               prf->allocate_bytes(prf, st->st_skeyid_a, NULL);
-               prf->allocate_bytes(prf, st->st_shared, NULL);
-               prf->allocate_bytes(prf, icookie, NULL);
-               prf->allocate_bytes(prf, rcookie, NULL);
-               prf->allocate_bytes(prf, seed_skeyid_e, &st->st_skeyid_e);
-
-               prf->destroy(prf);
-       }
-
-       /* generate IV */
-       {
-               hash_algorithm_t hash_alg;
-               hasher_t *hasher;
-
-               hash_alg = oakley_to_hash_algorithm(st->st_oakley.hash);
-               hasher = lib->crypto->create_hasher(lib->crypto, hash_alg);
-               st->st_new_iv_len = hasher->get_hash_size(hasher);
-               passert(st->st_new_iv_len <= sizeof(st->st_new_iv));
-
-               DBG(DBG_CRYPT,
-                       DBG_dump_chunk("DH_i:", st->st_gi);
-                       DBG_dump_chunk("DH_r:", st->st_gr);
-               );
-
-               hasher->get_hash(hasher, st->st_gi, NULL);
-               hasher->get_hash(hasher, st->st_gr, st->st_new_iv);
-               hasher->destroy(hasher);
-       }
-
-       /* Oakley Keying Material
-        * Derived from Skeyid_e: if it is not big enough, generate more
-        * using the PRF.
-        * See RFC 2409 "IKE" Appendix B
-        */
-       {
-               size_t keysize = st->st_oakley.enckeylen/BITS_PER_BYTE;
-
-               /* free any existing key */
-               free(st->st_enc_key.ptr);
-
-               if (keysize > st->st_skeyid_e.len)
-               {
-                       u_char keytemp[MAX_OAKLEY_KEY_LEN + MAX_DIGEST_LEN];
-                       chunk_t seed = chunk_from_chars(0x00);
-                       size_t prf_block_size, i;
-                       pseudo_random_function_t prf_alg;
-                       prf_t *prf;
-
-                       prf_alg = oakley_to_prf(st->st_oakley.hash);
-                       prf = lib->crypto->create_prf(lib->crypto, prf_alg);
-                       prf->set_key(prf, st->st_skeyid_e);
-                       prf_block_size = prf->get_block_size(prf);
-
-                       for (i = 0;;)
-                       {
-                               prf->get_bytes(prf, seed, &keytemp[i]);
-                               i += prf_block_size;
-                               if (i >= keysize)
-                               {
-                                       break;
-                               }
-                               seed = chunk_create(&keytemp[i-prf_block_size], prf_block_size);
-                       }
-                       prf->destroy(prf);
-                       st->st_enc_key = chunk_create(keytemp, keysize);
-               }
-               else
-               {
-                       st->st_enc_key = chunk_create(st->st_skeyid_e.ptr, keysize);
-               }
-               st->st_enc_key = chunk_clone(st->st_enc_key);
-       }
-
-       DBG(DBG_CRYPT,
-               DBG_dump_chunk("Skeyid:  ", st->st_skeyid);
-               DBG_dump_chunk("Skeyid_d:", st->st_skeyid_d);
-               DBG_dump_chunk("Skeyid_a:", st->st_skeyid_a);
-               DBG_dump_chunk("Skeyid_e:", st->st_skeyid_e);
-               DBG_dump_chunk("enc key:", st->st_enc_key);
-               DBG_dump("IV:", st->st_new_iv, st->st_new_iv_len));
-       return TRUE;
-}
-
-/* Generate HASH_I or HASH_R for ISAKMP Phase I.
- * This will *not* generate other hash payloads (eg. Phase II or Quick Mode,
- * New Group Mode, or ISAKMP Informational Exchanges).
- * If the hashi argument is TRUE, generate HASH_I; if FALSE generate HASH_R.
- * If hashus argument is TRUE, we're generating a hash for our end.
- * See RFC2409 IKE 5.
- */
- static void main_mode_hash(struct state *st, chunk_t *hash, bool hashi,
-                                                        const pb_stream *idpl)
-{
-       chunk_t icookie = { st->st_icookie, COOKIE_SIZE };
-       chunk_t rcookie = { st->st_rcookie, COOKIE_SIZE };
-       chunk_t sa_body = { st->st_p1isa.ptr + sizeof(struct isakmp_generic),
-                                               st->st_p1isa.len - sizeof(struct isakmp_generic) };
-       chunk_t id_body = { idpl->start + sizeof(struct isakmp_generic),
-                                               pbs_offset(idpl) - sizeof(struct isakmp_generic) };
-       pseudo_random_function_t prf_alg;
-       prf_t *prf;
-
-       switch (st->st_oakley.auth)
-       {
-               case OAKLEY_ECDSA_256:
-                       prf_alg = PRF_HMAC_SHA2_256;
-                       break;
-               case OAKLEY_ECDSA_384:
-                       prf_alg = PRF_HMAC_SHA2_384;
-                       break;
-               case OAKLEY_ECDSA_521:
-                       prf_alg = PRF_HMAC_SHA2_512;
-                       break;
-               default:
-                       prf_alg = oakley_to_prf(st->st_oakley.hash);
-       }
-       prf = lib->crypto->create_prf(lib->crypto, prf_alg);
-       prf->set_key(prf, st->st_skeyid);
-
-       if (hashi)
-       {
-               prf->get_bytes(prf, st->st_gi, NULL);
-               prf->get_bytes(prf, st->st_gr, NULL);
-               prf->get_bytes(prf, icookie, NULL);
-               prf->get_bytes(prf, rcookie, NULL);
-       }
-       else
-       {
-               prf->get_bytes(prf, st->st_gr, NULL);
-               prf->get_bytes(prf, st->st_gi, NULL);
-               prf->get_bytes(prf, rcookie, NULL);
-               prf->get_bytes(prf, icookie, NULL);
-       }
-
-       DBG(DBG_CRYPT,
-               DBG_log("hashing %u bytes of SA", sa_body.len)
-       )
-       prf->get_bytes(prf, sa_body, NULL);
-
-       /* Hash identification payload, without generic payload header.
-        * We used to reconstruct ID Payload for this purpose, but now
-        * we use the bytes as they appear on the wire to avoid
-        * "spelling problems".
-        */
-       prf->get_bytes(prf, id_body, hash->ptr);
-       hash->len = prf->get_block_size(prf);
-       prf->destroy(prf);
-}
-
-/* Create a public key signature of a hash.
- * Poorly specified in draft-ietf-ipsec-ike-01.txt 6.1.1.2.
- * Use PKCS#1 version 1.5 encryption of hash (called
- * RSAES-PKCS1-V1_5) in PKCS#2.
- */
-static size_t sign_hash(signature_scheme_t scheme, connection_t *c,
-                                               u_char sig_val[RSA_MAX_OCTETS], chunk_t hash)
-{
-       size_t sz = 0;
-       smartcard_t *sc = c->spd.this.sc;
-
-       if (sc == NULL)             /* no smartcard */
-       {
-               chunk_t sig;
-               private_key_t *private = get_private_key(c);
-
-               if (private == NULL)
-               {
-                       return 0;   /* failure: no key to use */
-               }
-               if (!private->sign(private, scheme, hash, &sig))
-               {
-                       return 0;
-               }
-               memcpy(sig_val, sig.ptr, sig.len);
-               sz = sig.len;
-               free(sig.ptr);
-       }
-       else if (sc->valid) /* if valid pin then sign hash on the smartcard */
-       {
-               lock_certs_and_keys("sign_hash");
-               if (!scx_establish_context(sc) || !scx_login(sc))
-               {
-                       scx_release_context(sc);
-                       unlock_certs_and_keys("sign_hash");
-                       return 0;
-               }
-
-               sz = scx_get_keylength(sc);
-               if (sz == 0)
-               {
-                       plog("failed to get keylength from smartcard");
-                       scx_release_context(sc);
-                       unlock_certs_and_keys("sign_hash");
-                       return 0;
-               }
-
-               DBG(DBG_CONTROL | DBG_CRYPT,
-                       DBG_log("signing hash with private key from smartcard (slot: %d, id: %s)"
-                               , (int)sc->slot, sc->id)
-               )
-               sz = scx_sign_hash(sc, hash.ptr, hash.len, sig_val, sz) ? sz : 0;
-               if (!pkcs11_keep_state)
-               {
-                       scx_release_context(sc);
-               }
-               unlock_certs_and_keys("sign_hash");
-       }
-       return sz;
-}
-
-/* Check signature against all public keys we can find.
- * If we need keys from DNS KEY records, and they haven't been fetched,
- * return STF_SUSPEND to ask for asynch DNS lookup.
- *
- * Note: parameter keys_from_dns contains results of DNS lookup for key
- * or is NULL indicating lookup not yet tried.
- *
- * take_a_crack is a helper function.  Mostly forensic.
- * If only we had coroutines.
- */
-struct tac_state {
-       struct state *st;
-       chunk_t hash;
-       chunk_t sig;
-       int tried_cnt;      /* number of keys tried */
-};
-
-static bool take_a_crack(struct tac_state *s, pubkey_t *kr)
-{
-       public_key_t *pub_key = kr->public_key;
-       chunk_t keyid = chunk_empty;
-       signature_scheme_t scheme;
-
-       s->tried_cnt++;
-       scheme = oakley_to_signature_scheme(s->st->st_oakley.auth);
-       pub_key->get_fingerprint(pub_key, KEYID_PUBKEY_INFO_SHA1, &keyid);
-
-       if (pub_key->verify(pub_key, scheme, s->hash, s->sig))
-       {
-               DBG(DBG_CRYPT | DBG_CONTROL,
-                       DBG_log("%s check passed with keyid %#B",
-                                       enum_show(&oakley_auth_names, s->st->st_oakley.auth), &keyid)
-               )
-               unreference_key(&s->st->st_peer_pubkey);
-               s->st->st_peer_pubkey = reference_key(kr);
-               return TRUE;
-       }
-       else
-       {
-               DBG(DBG_CRYPT,
-                       DBG_log("%s check failed with keyid %#B",
-                                       enum_show(&oakley_auth_names, s->st->st_oakley.auth), &keyid)
-               )
-               return FALSE;
-       }
-}
-
-static stf_status check_signature(key_type_t key_type, identification_t* peer,
-                                                                 struct state *st, chunk_t hash,
-                                                                 const pb_stream *sig_pbs,
-#ifdef USE_KEYRR
-                                                                 const pubkey_list_t *keys_from_dns,
-#endif /* USE_KEYRR */
-                                                                 const struct gw_info *gateways_from_dns)
-{
-       const connection_t *c = st->st_connection;
-       struct tac_state s;
-
-       s.st = st;
-       s.hash = hash;
-       s.sig  = chunk_create(sig_pbs->cur, pbs_left(sig_pbs));
-       s.tried_cnt = 0;
-
-       /* try all gateway records hung off c */
-       if (c->policy & POLICY_OPPO)
-       {
-               struct gw_info *gw;
-
-               for (gw = c->gw_info; gw != NULL; gw = gw->next)
-               {
-                       /* only consider entries that have a key and are for our peer */
-                       if (gw->gw_key_present &&
-                               gw->gw_id->equals(gw->gw_id, c->spd.that.id) &&
-                               take_a_crack(&s, gw->key))
-                       {
-                               return STF_OK;
-                       }
-               }
-       }
-
-       /* try all appropriate Public keys */
-       {
-               pubkey_list_t *p, **pp;
-
-               pp = &pubkeys;
-
-               for (p = pubkeys; p != NULL; p = *pp)
-               {
-                       pubkey_t *key = p->key;
-                       key_type_t type = key->public_key->get_type(key->public_key);
-
-                       if (type == key_type && peer->equals(peer, key->id))
-                       {
-                               time_t now = time(NULL);
-
-                               /* check if found public key has expired */
-                               if (key->until_time != UNDEFINED_TIME && key->until_time < now)
-                               {
-                                       loglog(RC_LOG_SERIOUS,
-                                               "cached public key has expired and has been deleted");
-                                       *pp = free_public_keyentry(p);
-                                       continue; /* continue with next public key */
-                               }
-                               if (take_a_crack(&s, key))
-                               {
-                                       return STF_OK;
-                               }
-                       }
-                       pp = &p->next;
-               }
-   }
-
-       /* if no key was found and that side of connection is
-        * key_from_DNS_on_demand then go search DNS for keys for peer.
-        */
-       if (s.tried_cnt == 0 && c->spd.that.key_from_DNS_on_demand)
-       {
-               if (gateways_from_dns != NULL)
-               {
-                       /* TXT keys */
-                       const struct gw_info *gwp;
-
-                       for (gwp = gateways_from_dns; gwp != NULL; gwp = gwp->next)
-                       {
-                               if (gwp->gw_key_present && take_a_crack(&s, gwp->key))
-                               {
-                                       return STF_OK;
-                               }
-                       }
-               }
-#ifdef USE_KEYRR
-               else if (keys_from_dns != NULL)
-               {
-                       /* KEY keys */
-                       const pubkey_list_t *kr;
-
-                       for (kr = keys_from_dns; kr != NULL; kr = kr->next)
-                       {
-                               if (kr->key->alg == PUBKEY_ALG_RSA && take_a_crack(&s, kr->key))
-                               {
-                                       return STF_OK;
-                               }
-                       }
-               }
-#endif /* USE_KEYRR */
-               else
-               {
-                       /* nothing yet: ask for asynch DNS lookup */
-                       return STF_SUSPEND;
-               }
-       }
-
-       /* no acceptable key was found: diagnose */
-       {
-               if (s.tried_cnt == 0)
-               {
-                       loglog(RC_LOG_SERIOUS, "no public key known for '%Y'", peer);
-               }
-               else if (s.tried_cnt == 1)
-               {
-                       loglog(RC_LOG_SERIOUS, "signature check for '%Y' failed: "
-                                       " wrong key?; tried %d", peer, s.tried_cnt);
-                       DBG(DBG_CONTROL,
-                               DBG_log("public key for '%Y' failed: "
-                                               "decrypted SIG payload into a malformed ECB", peer)
-                       )
-               }
-               else
-               {
-                       loglog(RC_LOG_SERIOUS, "signature check for '%Y' failed: "
-                                         "tried %d keys but none worked.", peer, s.tried_cnt);
-                       DBG(DBG_CONTROL,
-                               DBG_log("all %d public keys for '%Y' failed: "
-                                               "best decrypted SIG payload into a malformed ECB",
-                                               s.tried_cnt, peer)
-                       )
-               }
-               return STF_FAIL + ISAKMP_INVALID_KEY_INFORMATION;
-       }
-}
-
-static notification_t accept_nonce(struct msg_digest *md, chunk_t *dest,
-                                                                  const char *name)
-{
-       pb_stream *nonce_pbs = &md->chain[ISAKMP_NEXT_NONCE]->pbs;
-       size_t len = pbs_left(nonce_pbs);
-
-       if (len < MINIMUM_NONCE_SIZE || MAXIMUM_NONCE_SIZE < len)
-       {
-               loglog(RC_LOG_SERIOUS, "%s length not between %d and %d"
-                       , name , MINIMUM_NONCE_SIZE, MAXIMUM_NONCE_SIZE);
-               return ISAKMP_PAYLOAD_MALFORMED;       /* ??? */
-       }
-       free(dest->ptr);
-       *dest = chunk_create(nonce_pbs->cur, len);
-       *dest = chunk_clone(*dest);
-       return ISAKMP_NOTHING_WRONG;
-}
-
-/* encrypt message, sans fixed part of header
- * IV is fetched from st->st_new_iv and stored into st->st_iv.
- * The theory is that there will be no "backing out", so we commit to IV.
- * We also close the pbs.
- */
-bool encrypt_message(pb_stream *pbs, struct state *st)
-{
-       u_int8_t *enc_start = pbs->start + sizeof(struct isakmp_hdr);
-       size_t enc_len = pbs_offset(pbs) - sizeof(struct isakmp_hdr);
-       chunk_t data, iv;
-    char *new_iv;
-       size_t crypter_block_size, crypter_iv_size;
-       encryption_algorithm_t enc_alg;
-       crypter_t *crypter;
-
-       DBG_cond_dump(DBG_CRYPT | DBG_RAW, "encrypting:\n", enc_start, enc_len);
-       enc_alg = oakley_to_encryption_algorithm(st->st_oakley.encrypt);
-       crypter = lib->crypto->create_crypter(lib->crypto, enc_alg, st->st_enc_key.len);
-       crypter_block_size = crypter->get_block_size(crypter);
-       crypter_iv_size = crypter->get_iv_size(crypter);
-
-       /* Pad up to multiple of encryption blocksize.
-        * See the description associated with the definition of
-        * struct isakmp_hdr in packet.h.
-        */
-       {
-               size_t padding = pad_up(enc_len, crypter_block_size);
-
-               if (padding != 0)
-               {
-                       if (!out_zero(padding, pbs, "encryption padding"))
-                               return FALSE;
-                       enc_len += padding;
-               }
-       }
-
-       DBG(DBG_CRYPT, DBG_log("encrypting using %s", enum_show(&oakley_enc_names, st->st_oakley.encrypt)));
-       data = chunk_create(enc_start, enc_len);
-
-       /* form iv by truncation */
-       st->st_new_iv_len = crypter_iv_size;
-       iv = chunk_create(st->st_new_iv, st->st_new_iv_len);
-
-       crypter->set_key(crypter, st->st_enc_key);
-       crypter->encrypt(crypter, data, iv, NULL);
-       crypter->destroy(crypter);
-
-       new_iv = data.ptr + data.len - crypter_iv_size;
-       memcpy(st->st_new_iv, new_iv, crypter_iv_size);
-       update_iv(st);
-       DBG_cond_dump(DBG_CRYPT, "next IV:", st->st_iv, st->st_iv_len);
-       close_message(pbs);
-       return TRUE;
-}
-
-/* Compute HASH(1), HASH(2) of Quick Mode.
- * HASH(1) is part of Quick I1 message.
- * HASH(2) is part of Quick R1 message.
- * Used by: quick_outI1, quick_inI1_outR1 (twice), quick_inR1_outI2
- * (see RFC 2409 "IKE" 5.5, pg. 18 or draft-ietf-ipsec-ike-01.txt 6.2 pg 25)
- */
-static size_t quick_mode_hash12(u_char *dest, u_char *start, u_char *roof,
-                                                               const struct state *st, const msgid_t *msgid,
-                                                               bool hash2)
-{
-       chunk_t msgid_chunk = chunk_from_thing(*msgid);
-       chunk_t msg_chunk = { start, roof - start };
-       pseudo_random_function_t prf_alg;
-       prf_t *prf;
-       size_t prf_block_size;
-
-       prf_alg = oakley_to_prf(st->st_oakley.hash);
-       prf = lib->crypto->create_prf(lib->crypto, prf_alg);
-       prf->set_key(prf, st->st_skeyid_a);
-       prf->get_bytes(prf, msgid_chunk, NULL);
-       if (hash2)
-       {
-               prf->get_bytes(prf, st->st_ni, NULL); /* include Ni_b in the hash */
-       }
-       prf->get_bytes(prf, msg_chunk, dest);
-       prf_block_size = prf->get_block_size(prf);
-       prf->destroy(prf);
-
-       DBG(DBG_CRYPT,
-               DBG_log("HASH(%d) computed:", hash2 + 1);
-               DBG_dump("", dest, prf_block_size)
-       )
-       return prf_block_size;
-}
-
-/* Compute HASH(3) in Quick Mode (part of Quick I2 message).
- * Used by: quick_inR1_outI2, quick_inI2
- * See RFC2409 "The Internet Key Exchange (IKE)" 5.5.
- * NOTE: this hash (unlike HASH(1) and HASH(2)) ONLY covers the
- * Message ID and Nonces.  This is a mistake.
- */
-static size_t quick_mode_hash3(u_char *dest, struct state *st)
-{
-       chunk_t seed_chunk = chunk_from_chars(0x00);
-       chunk_t msgid_chunk = chunk_from_thing(st->st_msgid);
-       pseudo_random_function_t prf_alg;
-       prf_t *prf;
-       size_t prf_block_size;
-
-       prf_alg = oakley_to_prf(st->st_oakley.hash);
-       prf = lib->crypto->create_prf(lib->crypto, prf_alg);
-       prf->set_key(prf, st->st_skeyid_a);
-       prf->get_bytes(prf, seed_chunk, NULL );
-       prf->get_bytes(prf, msgid_chunk, NULL);
-       prf->get_bytes(prf, st->st_ni, NULL);
-       prf->get_bytes(prf, st->st_nr, dest);
-       prf_block_size = prf->get_block_size(prf);
-       prf->destroy(prf);
-
-       DBG_cond_dump(DBG_CRYPT, "HASH(3) computed:", dest, prf_block_size);
-       return prf_block_size;
-}
-
-/* Compute Phase 2 IV.
- * Uses Phase 1 IV from st_iv; puts result in st_new_iv.
- */
-void init_phase2_iv(struct state *st, const msgid_t *msgid)
-{
-       chunk_t iv_chunk = { st->st_ph1_iv, st->st_ph1_iv_len };
-       chunk_t msgid_chunk = chunk_from_thing(*msgid);
-       hash_algorithm_t hash_alg;
-       hasher_t *hasher;
-
-       hash_alg = oakley_to_hash_algorithm(st->st_oakley.hash);
-       hasher = lib->crypto->create_hasher(lib->crypto, hash_alg);
-
-       DBG_cond_dump(DBG_CRYPT, "last Phase 1 IV:",
-                                 st->st_ph1_iv, st->st_ph1_iv_len);
-
-       st->st_new_iv_len = hasher->get_hash_size(hasher);
-       passert(st->st_new_iv_len <= sizeof(st->st_new_iv));
-
-       hasher->get_hash(hasher, iv_chunk, NULL);
-       hasher->get_hash(hasher, msgid_chunk, st->st_new_iv);
-       hasher->destroy(hasher);
-
-       DBG_cond_dump(DBG_CRYPT, "computed Phase 2 IV:",
-                                 st->st_new_iv, st->st_new_iv_len);
-}
-
-/* Initiate quick mode.
- * --> HDR*, HASH(1), SA, Nr [, KE ] [, IDci, IDcr ]
- * (see RFC 2409 "IKE" 5.5)
- * Note: this is not called from demux.c
- */
-
-static bool emit_subnet_id(ip_subnet *net, u_int8_t np, u_int8_t protoid,
-                                                  u_int16_t port, pb_stream *outs)
-{
-       struct isakmp_ipsec_id id;
-       pb_stream id_pbs;
-       ip_address ta;
-       const unsigned char *tbp;
-       size_t tal;
-
-       id.isaiid_np = np;
-       id.isaiid_idtype = subnetishost(net)
-                                          ? aftoinfo(subnettypeof(net))->id_addr
-                                          : aftoinfo(subnettypeof(net))->id_subnet;
-       id.isaiid_protoid = protoid;
-       id.isaiid_port = port;
-
-       if (!out_struct(&id, &isakmp_ipsec_identification_desc, outs, &id_pbs))
-       {
-               return FALSE;
-       }
-       networkof(net, &ta);
-       tal = addrbytesptr(&ta, &tbp);
-       if (!out_raw(tbp, tal, &id_pbs, "client network"))
-       {
-               return FALSE;
-       }
-       if (!subnetishost(net))
-       {
-               maskof(net, &ta);
-               tal = addrbytesptr(&ta, &tbp);
-               if (!out_raw(tbp, tal, &id_pbs, "client mask"))
-               {
-                       return FALSE;
-               }
-       }
-       close_output_pbs(&id_pbs);
-       return TRUE;
-}
-
-stf_status quick_outI1(int whack_sock, struct state *isakmp_sa,
-                                          connection_t *c, lset_t policy, unsigned long try,
-                                          so_serial_t replacing)
-{
-       struct state *st = duplicate_state(isakmp_sa);
-       pb_stream reply;    /* not really a reply */
-       pb_stream rbody;
-       u_char      /* set by START_HASH_PAYLOAD: */
-               *r_hashval,     /* where in reply to jam hash value */
-               *r_hash_start;  /* start of what is to be hashed */
-       bool has_client = c->spd.this.has_client || c->spd.that.has_client ||
-                                         c->spd.this.protocol || c->spd.that.protocol ||
-                                         c->spd.this.port || c->spd.that.port;
-       bool send_natoa = FALSE;
-       u_int8_t np = ISAKMP_NEXT_NONE;
-       connection_t *ph1_c = isakmp_sa->st_connection;
-
-       if (c->spd.this.modecfg && !c->spd.this.has_client &&
-               c->spd.this.host_srcip->is_anyaddr(c->spd.this.host_srcip))
-       {
-               host_t * ph1_srcip = ph1_c->spd.this.host_srcip;
-
-               if (ph1_c->spd.this.modecfg && !ph1_srcip->is_anyaddr(ph1_srcip))
-               {
-                       c->spd.this.host_srcip->destroy(c->spd.this.host_srcip);
-                       c->spd.this.host_srcip = ph1_srcip->clone(ph1_srcip);
-                       c->spd.this.client = ph1_c->spd.this.client;
-                       c->spd.this.has_client = TRUE;
-                       plog("inheriting virtual IP source address %H from ModeCfg", ph1_srcip);
-               }
-       }
-
-       if (ph1_c->policy & (POLICY_XAUTH_RSASIG | POLICY_XAUTH_PSK) &&
-               ph1_c->xauth_identity && !c->xauth_identity)
-       {
-               DBG(DBG_CONTROL,
-                       DBG_log("inheriting XAUTH identity %Y", ph1_c->xauth_identity)
-               )
-               c->xauth_identity = ph1_c->xauth_identity->clone(ph1_c->xauth_identity);
-       }
-
-       st->st_whack_sock = whack_sock;
-       st->st_connection = c;
-       set_cur_state(st);  /* we must reset before exit */
-       st->st_policy = policy;
-       st->st_try = try;
-
-       st->st_myuserprotoid = c->spd.this.protocol;
-       st->st_peeruserprotoid = c->spd.that.protocol;
-       st->st_myuserport = c->spd.this.port;
-       st->st_peeruserport = c->spd.that.port;
-
-       st->st_msgid = generate_msgid(isakmp_sa);
-       st->st_state = STATE_QUICK_I1;
-
-       insert_state(st);   /* needs cookies, connection, and msgid */
-
-       if (replacing == SOS_NOBODY)
-       {
-               plog("initiating Quick Mode %s {using isakmp#%lu}",
-                        prettypolicy(policy), isakmp_sa->st_serialno);
-       }
-       else
-       {
-               plog("initiating Quick Mode %s to replace #%lu {using isakmp#%lu}",
-                        prettypolicy(policy), replacing, isakmp_sa->st_serialno);
-       }
-       if (isakmp_sa->nat_traversal & NAT_T_DETECTED)
-       {
-               /* Duplicate nat_traversal status in new state */
-               st->nat_traversal = isakmp_sa->nat_traversal;
-
-               if (isakmp_sa->nat_traversal & LELEM(NAT_TRAVERSAL_NAT_BHND_ME))
-               {
-                       has_client = TRUE;
-               }
-          nat_traversal_change_port_lookup(NULL, st);
-       }
-       else
-       {
-               st->nat_traversal = 0;
-       }
-
-       /* are we going to send a NAT-OA payload? */
-       if ((st->nat_traversal & NAT_T_WITH_NATOA)
-       && !(st->st_policy & POLICY_TUNNEL)
-       && (st->nat_traversal & LELEM(NAT_TRAVERSAL_NAT_BHND_ME)))
-       {
-               send_natoa = TRUE;
-               np = (st->nat_traversal & NAT_T_WITH_RFC_VALUES) ?
-                                 ISAKMP_NEXT_NATOA_RFC : ISAKMP_NEXT_NATOA_DRAFTS;
-       }
-
-       /* set up reply */
-       init_pbs(&reply, reply_buffer, sizeof(reply_buffer), "reply packet");
-
-       /* HDR* out */
-       {
-               struct isakmp_hdr hdr;
-
-               hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION;
-               hdr.isa_np = ISAKMP_NEXT_HASH;
-               hdr.isa_xchg = ISAKMP_XCHG_QUICK;
-               hdr.isa_msgid = st->st_msgid;
-               hdr.isa_flags = ISAKMP_FLAG_ENCRYPTION;
-               memcpy(hdr.isa_icookie, st->st_icookie, COOKIE_SIZE);
-               memcpy(hdr.isa_rcookie, st->st_rcookie, COOKIE_SIZE);
-               if (!out_struct(&hdr, &isakmp_hdr_desc, &reply, &rbody))
-               {
-                       reset_cur_state();
-                       return STF_INTERNAL_ERROR;
-               }
-       }
-
-       /* HASH(1) -- create and note space to be filled later */
-       START_HASH_PAYLOAD(rbody, ISAKMP_NEXT_SA);
-
-       /* SA out */
-
-       /*
-        * See if pfs_group has been specified for this conn,
-        * if not, fallback to old use-same-as-P1 behaviour
-        */
-#ifndef NO_IKE_ALG
-       if (st->st_connection)
-       {
-                       st->st_pfs_group = ike_alg_pfsgroup(st->st_connection, policy);
-       }
-       if (!st->st_pfs_group)
-#endif
-       /* If PFS specified, use the same group as during Phase 1:
-        * since no negotiation is possible, we pick one that is
-        * very likely supported.
-        */
-                       st->st_pfs_group = policy & POLICY_PFS? isakmp_sa->st_oakley.group : NULL;
-
-       /* Emit SA payload based on a subset of the policy bits.
-        * POLICY_COMPRESS is considered iff we can do IPcomp.
-        */
-       {
-               lset_t pm = POLICY_ENCRYPT | POLICY_AUTHENTICATE;
-
-               if (can_do_IPcomp)
-               {
-                       pm |= POLICY_COMPRESS;
-               }
-               if (!out_sa(&rbody,
-                       &ipsec_sadb[(st->st_policy & pm) >> POLICY_IPSEC_SHIFT],
-                       st, FALSE, ISAKMP_NEXT_NONCE))
-               {
-                       reset_cur_state();
-                       return STF_INTERNAL_ERROR;
-               }
-       }
-
-       /* Ni out */
-       if (!build_and_ship_nonce(&st->st_ni, &rbody
-       , policy & POLICY_PFS? ISAKMP_NEXT_KE : has_client? ISAKMP_NEXT_ID : np
-       , "Ni"))
-       {
-               reset_cur_state();
-               return STF_INTERNAL_ERROR;
-       }
-
-       /* [ KE ] out (for PFS) */
-
-       if (st->st_pfs_group != NULL)
-       {
-               if (!build_and_ship_KE(st, &st->st_gi, st->st_pfs_group
-               , &rbody, has_client? ISAKMP_NEXT_ID : np))
-               {
-                       reset_cur_state();
-                       return STF_INTERNAL_ERROR;
-               }
-       }
-
-       /* [ IDci, IDcr ] out */
-       if (has_client)
-       {
-               /* IDci (we are initiator), then IDcr (peer is responder) */
-               if (!emit_subnet_id(&c->spd.this.client
-                 , ISAKMP_NEXT_ID, st->st_myuserprotoid, st->st_myuserport, &rbody)
-               || !emit_subnet_id(&c->spd.that.client
-                 , np, st->st_peeruserprotoid, st->st_peeruserport, &rbody))
-               {
-                       reset_cur_state();
-                       return STF_INTERNAL_ERROR;
-               }
-       }
-
-       /* Send NAT-OA if our address is NATed */
-       if (send_natoa)
-       {
-               if (!nat_traversal_add_natoa(ISAKMP_NEXT_NONE, &rbody, st))
-               {
-                       reset_cur_state();
-                       return STF_INTERNAL_ERROR;
-               }
-       }
-
-       /* finish computing  HASH(1), inserting it in output */
-       (void) quick_mode_hash12(r_hashval, r_hash_start, rbody.cur
-               , st, &st->st_msgid, FALSE);
-
-       /* encrypt message, except for fixed part of header */
-
-       init_phase2_iv(isakmp_sa, &st->st_msgid);
-       st->st_new_iv_len = isakmp_sa->st_new_iv_len;
-       memcpy(st->st_new_iv, isakmp_sa->st_new_iv, st->st_new_iv_len);
-
-       if (!encrypt_message(&rbody, st))
-       {
-               reset_cur_state();
-               return STF_INTERNAL_ERROR;
-       }
-
-       /* save packet, now that we know its size */
-       st->st_tpacket = chunk_create(reply.start, pbs_offset(&reply));
-       st->st_tpacket = chunk_clone(st->st_tpacket);
-
-       /* send the packet */
-
-       send_packet(st, "quick_outI1");
-
-       delete_event(st);
-       event_schedule(EVENT_RETRANSMIT, EVENT_RETRANSMIT_DELAY_0, st);
-
-       if (replacing == SOS_NOBODY)
-       {
-               whack_log(RC_NEW_STATE + STATE_QUICK_I1
-                       , "%s: initiate"
-                       , enum_name(&state_names, st->st_state));
-       }
-       else
-       {
-               whack_log(RC_NEW_STATE + STATE_QUICK_I1
-                       , "%s: initiate to replace #%lu"
-                       , enum_name(&state_names, st->st_state)
-                       , replacing);
-       }
-       reset_cur_state();
-       return STF_OK;
-}
-
-
-/*
- * Decode the CERT payload of Phase 1.
- */
-static void decode_cert(struct msg_digest *md)
-{
-       struct payload_digest *p;
-
-       for (p = md->chain[ISAKMP_NEXT_CERT]; p != NULL; p = p->next)
-       {
-               struct isakmp_cert *const cert = &p->payload.cert;
-               chunk_t blob;
-               time_t valid_until;
-               blob.ptr = p->pbs.cur;
-               blob.len = pbs_left(&p->pbs);
-               if (cert->isacert_type == CERT_X509_SIGNATURE)
-               {
-                       cert_t x509cert = cert_empty;
-
-                       x509cert.cert = lib->creds->create(lib->creds,
-                                                                                          CRED_CERTIFICATE, CERT_X509,
-                                                                                          BUILD_BLOB_ASN1_DER, blob,
-                                                                                          BUILD_END);
-                       if (x509cert.cert)
-                       {
-                               if (verify_x509cert(&x509cert, strict_crl_policy, &valid_until))
-                               {
-                                       DBG(DBG_PARSING,
-                                               DBG_log("Public key validated")
-                                       )
-                                       add_public_key_from_cert(&x509cert, valid_until, DAL_SIGNED);
-                               }
-                               else
-                               {
-                                       plog("X.509 certificate rejected");
-                               }
-                               x509cert.cert->destroy(x509cert.cert);
-                       }
-                       else
-                       {
-                               plog("Syntax error in X.509 certificate");
-                       }
-               }
-               else if (cert->isacert_type == CERT_PKCS7_WRAPPED_X509)
-               {
-                       linked_list_t *certs = linked_list_create();
-
-                       if (pkcs7_parse_signedData(blob, NULL, certs, NULL, NULL))
-                       {
-                               store_x509certs(certs, strict_crl_policy);
-                       }
-                       else
-                       {
-                               plog("Syntax error in PKCS#7 wrapped X.509 certificates");
-                       }
-                       certs->destroy_offset(certs, offsetof(certificate_t, destroy));
-               }
-               else
-               {
-                       loglog(RC_LOG_SERIOUS, "ignoring %s certificate payload",
-                                  enum_show(&cert_type_names, cert->isacert_type));
-                       DBG_cond_dump_chunk(DBG_PARSING, "CERT:\n", blob);
-               }
-       }
-}
-
-/*
- * Decode the CR payload of Phase 1.
- */
-static void decode_cr(struct msg_digest *md, connection_t *c)
-{
-       struct payload_digest *p;
-
-       for (p = md->chain[ISAKMP_NEXT_CR]; p != NULL; p = p->next)
-       {
-               struct isakmp_cr *const cr = &p->payload.cr;
-               chunk_t ca_name;
-
-               ca_name.len = pbs_left(&p->pbs);
-               ca_name.ptr = (ca_name.len > 0)? p->pbs.cur : NULL;
-
-               DBG_cond_dump_chunk(DBG_PARSING, "CR", ca_name);
-
-               if (cr->isacr_type == CERT_X509_SIGNATURE)
-               {
-                       if (ca_name.len > 0)
-                       {
-                               identification_t *ca;
-
-                               if (!is_asn1(ca_name))
-                               {
-                                       continue;
-                               }
-                               if (c->requested_ca == NULL)
-                               {
-                                       c->requested_ca = linked_list_create();
-                               }
-                               ca = identification_create_from_encoding(ID_DER_ASN1_DN, ca_name);
-                               c->requested_ca->insert_last(c->requested_ca, ca);
-                               DBG(DBG_PARSING | DBG_CONTROL,
-                                       DBG_log("requested CA: \"%Y\"", ca)
-                               )
-                       }
-                       else
-                       {
-                               DBG(DBG_PARSING | DBG_CONTROL,
-                                       DBG_log("requested CA: %%any")
-                               )
-                       }
-                       c->got_certrequest = TRUE;
-               }
-               else
-               {
-                       loglog(RC_LOG_SERIOUS, "ignoring %s certificate request payload",
-                                  enum_show(&cert_type_names, cr->isacr_type));
-               }
-       }
-}
-
-/* Decode the ID payload of Phase 1 (main_inI3_outR3 and main_inR3)
- * Note: we may change connections as a result.
- * We must be called before SIG or HASH are decoded since we
- * may change the peer's public key or ID.
- */
-static bool decode_peer_id(struct msg_digest *md, identification_t **peer)
-{
-       struct state *const st = md->st;
-       struct payload_digest *const id_pld = md->chain[ISAKMP_NEXT_ID];
-       const pb_stream *const id_pbs = &id_pld->pbs;
-       struct isakmp_id *const id = &id_pld->payload.id;
-       chunk_t id_payload;
-
-       /* I think that RFC2407 (IPSEC DOI) 4.6.2 is confused.
-        * It talks about the protocol ID and Port fields of the ID
-        * Payload, but they don't exist as such in Phase 1.
-        * We use more appropriate names.
-        * isaid_doi_specific_a is in place of Protocol ID.
-        * isaid_doi_specific_b is in place of Port.
-        * Besides, there is no good reason for allowing these to be
-        * other than 0 in Phase 1.
-        */
-       if ((st->nat_traversal & NAT_T_WITH_PORT_FLOATING)
-       &&   id->isaid_doi_specific_a == IPPROTO_UDP
-       &&  (id->isaid_doi_specific_b == 0 || id->isaid_doi_specific_b == NAT_T_IKE_FLOAT_PORT))
-       {
-               DBG_log("protocol/port in Phase 1 ID Payload is %d/%d. "
-                               "accepted with port_floating NAT-T",
-                               id->isaid_doi_specific_a, id->isaid_doi_specific_b);
-       }
-       else if (!(id->isaid_doi_specific_a == 0 && id->isaid_doi_specific_b == 0)
-                &&  !(id->isaid_doi_specific_a == IPPROTO_UDP && id->isaid_doi_specific_b == IKE_UDP_PORT))
-       {
-               loglog(RC_LOG_SERIOUS, "protocol/port in Phase 1 ID Payload must be 0/0 or %d/%d"
-                       " but are %d/%d"
-                       , IPPROTO_UDP, IKE_UDP_PORT
-                       , id->isaid_doi_specific_a, id->isaid_doi_specific_b);
-               return FALSE;
-       }
-
-       id_payload = chunk_create(id_pbs->cur, pbs_left(id_pbs));
-
-       switch (id->isaid_idtype)
-       {
-               case ID_IPV4_ADDR:
-                       if (id_payload.len != 4)
-                       {
-                               loglog(RC_LOG_SERIOUS, "improper %s Phase 1 ID payload",
-                                                               enum_show(&ident_names, id->isaid_idtype));
-                               return FALSE;
-                       }
-                       break;
-               case ID_IPV6_ADDR:
-                       if (id_payload.len != 16)
-                       {
-                               loglog(RC_LOG_SERIOUS, "improper %s Phase 1 ID payload",
-                                                               enum_show(&ident_names, id->isaid_idtype));
-                               return FALSE;
-                       }
-                       break;
-               case ID_USER_FQDN:
-               case ID_FQDN:
-                       if (memchr(id_payload.ptr, '\0', id_payload.len) != NULL)
-                       {
-                               loglog(RC_LOG_SERIOUS, "%s Phase 1 ID payload contains "
-                                                                          "a NUL character",
-                                                               enum_show(&ident_names, id->isaid_idtype));
-                               return FALSE;
-                       }
-                       break;
-               case ID_KEY_ID:
-               case ID_DER_ASN1_DN:
-                       break;
-               default:
-                       /* XXX Could send notification back */
-                       loglog(RC_LOG_SERIOUS, "unacceptable identity type (%s) "
-                                                                  "in Phase 1 ID payload",
-                                                               enum_show(&ident_names, id->isaid_idtype));
-                       return FALSE;
-       }
-       *peer = identification_create_from_encoding(id->isaid_idtype, id_payload);
-
-       plog("Peer ID is %s: '%Y'",     enum_show(&ident_names, id->isaid_idtype),
-                                                               *peer);
-
-       /* check for certificates */
-       decode_cert(md);
-       return TRUE;
-}
-
-/* Now that we've decoded the ID payload, let's see if we
- * need to switch connections.
- * We must not switch horses if we initiated:
- * - if the initiation was explicit, we'd be ignoring user's intent
- * - if opportunistic, we'll lose our HOLD info
- */
-static bool switch_connection(struct msg_digest *md, identification_t *peer,
-                                                         bool initiator)
-{
-       struct state *const st = md->st;
-       connection_t *c = st->st_connection;
-       identification_t *peer_ca;
-
-       peer_ca = st->st_peer_pubkey ? st->st_peer_pubkey->issuer : NULL;
-       if (peer_ca)
-       {
-               DBG(DBG_CONTROL,
-                       DBG_log("peer CA:      \"%Y\"", peer_ca)
-               )
-       }
-       else
-       {
-               DBG(DBG_CONTROL,
-                       DBG_log("peer CA:      %%none")
-               )
-       }
-
-       if (initiator)
-       {
-               int pathlen;
-
-               if (!peer->equals(peer, c->spd.that.id))
-               {
-                       loglog(RC_LOG_SERIOUS,
-                                       "we require peer to have ID '%Y', but peer declares '%Y'",
-                                       c->spd.that.id, peer);
-                       return FALSE;
-               }
-
-               if (c->spd.that.ca)
-               {
-                       DBG(DBG_CONTROL,
-                               DBG_log("required CA:  \"%s\"", c->spd.that.ca);
-                       )
-               }
-               else
-               {
-                       DBG(DBG_CONTROL,
-                               DBG_log("required CA:  %%none");
-                       )
-               }
-
-               if (!trusted_ca(peer_ca, c->spd.that.ca, &pathlen))
-               {
-                       loglog(RC_LOG_SERIOUS
-                               , "we don't accept the peer's CA");
-                       return FALSE;
-               }
-       }
-       else
-       {
-               connection_t *r;
-
-               /* check for certificate requests */
-               decode_cr(md, c);
-
-               r = refine_host_connection(st, peer, peer_ca);
-
-               /* delete the collected certificate requests */
-               if (c->requested_ca)
-               {
-                       c->requested_ca->destroy_offset(c->requested_ca,
-                                                                        offsetof(identification_t, destroy));
-                       c->requested_ca = NULL;
-               }
-
-               if (r == NULL)
-               {
-                       loglog(RC_LOG_SERIOUS, "no suitable connection for peer '%Y'", peer);
-                       return FALSE;
-               }
-
-               if (r->spd.this.ca)
-               {
-                       DBG(DBG_CONTROL,
-                               DBG_log("offered CA:   \"%Y\"", r->spd.this.ca)
-                       )
-               }
-               else
-               {
-                       DBG(DBG_CONTROL,
-                               DBG_log("offered CA:   %%none")
-                       )
-               }
-
-               if (r != c)
-               {
-                       /* apparently, r is an improvement on c -- replace */
-
-                       DBG(DBG_CONTROL
-                               , DBG_log("switched from \"%s\" to \"%s\"", c->name, r->name));
-                       if (r->kind == CK_TEMPLATE)
-                       {
-                               /* instantiate it, filling in peer's ID */
-                               r = rw_instantiate(r, &c->spd.that.host_addr
-                                               , c->spd.that.host_port, NULL, peer);
-                       }
-
-                       /* copy certificate request info */
-                       r->got_certrequest = c->got_certrequest;
-
-                       st->st_connection = r;      /* kill reference to c */
-                       set_cur_connection(r);
-                       connection_discard(c);
-               }
-               else if (c->spd.that.has_id_wildcards)
-               {
-                       c->spd.that.id->destroy(c->spd.that.id);
-                       c->spd.that.id = peer->clone(peer);
-                       c->spd.that.has_id_wildcards = FALSE;
-               }
-       }
-       return TRUE;
-}
-
-/* Decode the variable part of an ID packet (during Quick Mode).
- * This is designed for packets that identify clients, not peers.
- * Rejects 0.0.0.0/32 or IPv6 equivalent because
- * (1) it is wrong and (2) we use this value for inband signalling.
- */
-static bool decode_net_id(struct isakmp_ipsec_id *id, pb_stream *id_pbs,
-                                                 ip_subnet *net, const char *which)
-{
-       const struct af_info *afi = NULL;
-
-       /* Note: the following may be a pointer into static memory
-        * that may be recycled, but only if the type is not known.
-        * That case is disposed of very early -- in the first switch.
-        */
-       const char *idtypename = enum_show(&ident_names, id->isaiid_idtype);
-
-       switch (id->isaiid_idtype)
-       {
-               case ID_IPV4_ADDR:
-               case ID_IPV4_ADDR_SUBNET:
-               case ID_IPV4_ADDR_RANGE:
-                       afi = &af_inet4_info;
-                       break;
-               case ID_IPV6_ADDR:
-               case ID_IPV6_ADDR_SUBNET:
-               case ID_IPV6_ADDR_RANGE:
-                       afi = &af_inet6_info;
-                       break;
-               case ID_FQDN:
-                       return TRUE;
-               default:
-                       /* XXX support more */
-                       loglog(RC_LOG_SERIOUS, "unsupported ID type %s"
-                               , idtypename);
-                       /* XXX Could send notification back */
-                       return FALSE;
-       }
-
-       switch (id->isaiid_idtype)
-       {
-               case ID_IPV4_ADDR:
-               case ID_IPV6_ADDR:
-               {
-                       ip_address temp_address;
-                       err_t ugh;
-
-                       ugh = initaddr(id_pbs->cur, pbs_left(id_pbs), afi->af, &temp_address);
-
-                       if (ugh != NULL)
-                       {
-                               loglog(RC_LOG_SERIOUS, "%s ID payload %s has wrong length in Quick I1 (%s)"
-                                       , which, idtypename, ugh);
-                               /* XXX Could send notification back */
-                               return FALSE;
-                       }
-                       if (isanyaddr(&temp_address))
-                       {
-                               loglog(RC_LOG_SERIOUS, "%s ID payload %s is invalid (%s) in Quick I1"
-                                       , which, idtypename, ip_str(&temp_address));
-                               /* XXX Could send notification back */
-                               return FALSE;
-                       }
-                       happy(addrtosubnet(&temp_address, net));
-                       DBG(DBG_PARSING | DBG_CONTROL
-                               , DBG_log("%s is %s", which, ip_str(&temp_address)));
-                       break;
-               }
-
-               case ID_IPV4_ADDR_SUBNET:
-               case ID_IPV6_ADDR_SUBNET:
-               {
-                       ip_address temp_address, temp_mask;
-                       err_t ugh;
-
-                       if (pbs_left(id_pbs) != 2 * afi->ia_sz)
-                       {
-                               loglog(RC_LOG_SERIOUS, "%s ID payload %s wrong length in Quick I1"
-                                       , which, idtypename);
-                               /* XXX Could send notification back */
-                               return FALSE;
-                       }
-                       ugh = initaddr(id_pbs->cur
-                               , afi->ia_sz, afi->af, &temp_address);
-                       if (ugh == NULL)
-                       {
-                               ugh = initaddr(id_pbs->cur + afi->ia_sz
-                                       , afi->ia_sz, afi->af, &temp_mask);
-                       }
-                       if (ugh == NULL)
-                       {
-                               ugh = initsubnet(&temp_address, masktocount(&temp_mask)
-                                       , '0', net);
-                       }
-                       if (ugh == NULL && subnetisnone(net))
-                       {
-                               ugh = "contains only anyaddr";
-                       }
-                       if (ugh != NULL)
-                       {
-                               loglog(RC_LOG_SERIOUS, "%s ID payload %s bad subnet in Quick I1 (%s)"
-                                       , which, idtypename, ugh);
-                               /* XXX Could send notification back */
-                               return FALSE;
-                       }
-                       DBG(DBG_PARSING | DBG_CONTROL,
-                               {
-                                       char temp_buff[SUBNETTOT_BUF];
-
-                                       subnettot(net, 0, temp_buff, sizeof(temp_buff));
-                                       DBG_log("%s is subnet %s", which, temp_buff);
-                               });
-                       break;
-               }
-
-               case ID_IPV4_ADDR_RANGE:
-               case ID_IPV6_ADDR_RANGE:
-               {
-                       ip_address temp_address_from, temp_address_to;
-                       err_t ugh;
-
-                       if (pbs_left(id_pbs) != 2 * afi->ia_sz)
-                       {
-                               loglog(RC_LOG_SERIOUS, "%s ID payload %s wrong length in Quick I1"
-                                       , which, idtypename);
-                               /* XXX Could send notification back */
-                               return FALSE;
-                       }
-                       ugh = initaddr(id_pbs->cur, afi->ia_sz, afi->af, &temp_address_from);
-                       if (ugh == NULL)
-                       {
-                               ugh = initaddr(id_pbs->cur + afi->ia_sz
-                                       , afi->ia_sz, afi->af, &temp_address_to);
-                       }
-                       if (ugh != NULL)
-                       {
-                               loglog(RC_LOG_SERIOUS, "%s ID payload %s malformed (%s) in Quick I1"
-                                       , which, idtypename, ugh);
-                               /* XXX Could send notification back */
-                               return FALSE;
-                       }
-
-                       ugh = rangetosubnet(&temp_address_from, &temp_address_to, net);
-                       if (ugh == NULL && subnetisnone(net))
-                       {
-                               ugh = "contains only anyaddr";
-                       }
-                       if (ugh != NULL)
-                       {
-                               char temp_buff1[ADDRTOT_BUF], temp_buff2[ADDRTOT_BUF];
-
-                               addrtot(&temp_address_from, 0, temp_buff1, sizeof(temp_buff1));
-                               addrtot(&temp_address_to, 0, temp_buff2, sizeof(temp_buff2));
-                               loglog(RC_LOG_SERIOUS, "%s ID payload in Quick I1, %s"
-                                       " %s - %s unacceptable: %s"
-                                       , which, idtypename, temp_buff1, temp_buff2, ugh);
-                               return FALSE;
-                       }
-                       DBG(DBG_PARSING | DBG_CONTROL,
-                               {
-                                       char temp_buff[SUBNETTOT_BUF];
-
-                                       subnettot(net, 0, temp_buff, sizeof(temp_buff));
-                                       DBG_log("%s is subnet %s (received as range)"
-                                               , which, temp_buff);
-                               });
-                       break;
-               }
-       }
-
-       /* set the port selector */
-       setportof(htons(id->isaiid_port), &net->addr);
-
-       DBG(DBG_PARSING | DBG_CONTROL,
-               DBG_log("%s protocol/port is %d/%d", which, id->isaiid_protoid, id->isaiid_port)
-       )
-
-       return TRUE;
-}
-
-/* like decode, but checks that what is received matches what was sent */
-static bool check_net_id(struct isakmp_ipsec_id *id, pb_stream *id_pbs,
-                                                u_int8_t *protoid, u_int16_t *port, ip_subnet *net,
-                                                const char *which)
-{
-       ip_subnet net_temp;
-
-       if (!decode_net_id(id, id_pbs, &net_temp, which))
-       {
-               return FALSE;
-       }
-       if (!samesubnet(net, &net_temp)
-       || *protoid != id->isaiid_protoid || *port != id->isaiid_port)
-       {
-               loglog(RC_LOG_SERIOUS, "%s ID returned doesn't match my proposal", which);
-               return FALSE;
-       }
-       return TRUE;
-}
-
-/*
- * look for the existence of a non-expiring preloaded public key
- */
-static bool has_preloaded_public_key(struct state *st)
-{
-       connection_t *c = st->st_connection;
-
-       /* do not consider rw connections since
-        * the peer's identity must be known
-        */
-       if (c->kind == CK_PERMANENT)
-       {
-               pubkey_list_t *p;
-
-               /* look for a matching RSA public key */
-               for (p = pubkeys; p != NULL; p = p->next)
-               {
-                       pubkey_t *key = p->key;
-                       key_type_t type = key->public_key->get_type(key->public_key);
-
-                       if (type == KEY_RSA &&
-                               c->spd.that.id->equals(c->spd.that.id, key->id) &&
-                               key->until_time == UNDEFINED_TIME)
-                       {
-                               /* found a preloaded public key */
-                               return TRUE;
-                       }
-               }
-       }
-       return FALSE;
-}
-
-/* Compute keying material for an SA
- */
-static void compute_keymat_internal(struct state *st, u_int8_t protoid,
-                                                                       ipsec_spi_t spi, size_t needed_len,
-                                                                       u_char **keymat_out)
-{
-       size_t i = 0, prf_block_size, needed_space;
-       chunk_t protoid_chunk = chunk_from_thing(protoid);
-       chunk_t spi_chunk = chunk_from_thing(spi);
-       pseudo_random_function_t prf_alg = oakley_to_prf(st->st_oakley.hash);
-       prf_t *prf = lib->crypto->create_prf(lib->crypto, prf_alg);
-
-       prf->set_key(prf, st->st_skeyid_d);
-       prf_block_size = prf->get_block_size(prf);
-
-       /* Although only needed_len bytes are desired, we must round up to a
-        * multiple of prf_block_size so that the buffer isn't overrun */
-       needed_space = needed_len + pad_up(needed_len, prf_block_size);
-       replace(*keymat_out, malloc(needed_space));
-
-       for (;;)
-       {
-               char *keymat_i = (*keymat_out) + i;
-               chunk_t keymat = { keymat_i,  prf_block_size };
-
-               if (st->st_shared.ptr != NULL)
-               {       /* PFS: include the g^xy */
-                       prf->get_bytes(prf, st->st_shared, NULL);
-               }
-               prf->get_bytes(prf, protoid_chunk, NULL);
-               prf->get_bytes(prf, spi_chunk, NULL);
-               prf->get_bytes(prf, st->st_ni, NULL);
-               prf->get_bytes(prf, st->st_nr, keymat_i);
-
-               i += prf_block_size;
-               if (i >= needed_space)
-               {
-                       break;
-               }
-
-               /* more keying material needed: prepare to go around again */
-               prf->get_bytes(prf, keymat, NULL);
-       }
-       prf->destroy(prf);
-}
-
-/*
- * Produce the new key material of Quick Mode.
- * RFC 2409 "IKE" section 5.5
- * specifies how this is to be done.
- */
-static void compute_proto_keymat(struct state *st, u_int8_t protoid,
-                                                                struct ipsec_proto_info *pi, enum endpoint ep)
-{
-       size_t needed_len = 0; /* bytes of keying material needed */
-
-       /* Add up the requirements for keying material
-        * (It probably doesn't matter if we produce too much!)
-        */
-       switch (protoid)
-       {
-               case PROTO_IPSEC_ESP:
-               {
-                       needed_len = kernel_alg_esp_enc_keylen(pi->attrs.transid);
-
-                       if (needed_len && pi->attrs.key_len)
-                       {
-                               needed_len = pi->attrs.key_len / BITS_PER_BYTE;
-                       }
-
-                       switch (pi->attrs.transid)
-                       {
-                               case ESP_NULL:
-                                       needed_len = 0;
-                                       break;
-                               case ESP_AES_CCM_8:
-                               case ESP_AES_CCM_12:
-                               case ESP_AES_CCM_16:
-                                       needed_len += 3;
-                                       break;
-                               case ESP_AES_GCM_8:
-                               case ESP_AES_GCM_12:
-                               case ESP_AES_GCM_16:
-                               case ESP_AES_CTR:
-                               case ESP_AES_GMAC:
-                                       needed_len += 4;
-                                       break;
-                               default:
-                                       if (needed_len == 0)
-                                       {
-                                               bad_case(pi->attrs.transid);
-                                       }
-                       }
-
-                       if (kernel_alg_esp_auth_ok(pi->attrs.auth, NULL))
-                       {
-                               needed_len += kernel_alg_esp_auth_keylen(pi->attrs.auth);
-                       }
-                       else
-                       {
-                               switch (pi->attrs.auth)
-                               {
-                                       case AUTH_ALGORITHM_NONE:
-                                               break;
-                                       case AUTH_ALGORITHM_HMAC_MD5:
-                                               needed_len += HMAC_MD5_KEY_LEN;
-                                               break;
-                                       case AUTH_ALGORITHM_HMAC_SHA1:
-                                               needed_len += HMAC_SHA1_KEY_LEN;
-                                               break;
-                                       case AUTH_ALGORITHM_DES_MAC:
-                                       default:
-                                               bad_case(pi->attrs.auth);
-                               }
-                       }
-                       break;
-               }
-               case PROTO_IPSEC_AH:
-               {
-                       switch (pi->attrs.transid)
-                       {
-                               case AH_MD5:
-                                       needed_len = HMAC_MD5_KEY_LEN;
-                                       break;
-                               case AH_SHA:
-                                       needed_len = HMAC_SHA1_KEY_LEN;
-                                       break;
-                               default:
-                                       bad_case(pi->attrs.transid);
-                       }
-                       break;
-               }
-               default:
-                       bad_case(protoid);
-       }
-
-       pi->keymat_len = needed_len;
-
-       if (ep & EP_LOCAL)
-       {
-               compute_keymat_internal(st, protoid, pi->our_spi, needed_len,
-                                                               &pi->our_keymat);
-               DBG(DBG_CRYPT,
-                       DBG_dump("KEYMAT computed:\n", pi->our_keymat,
-                                        pi->keymat_len));
-       }
-       if (ep & EP_REMOTE)
-       {
-               compute_keymat_internal(st, protoid, pi->attrs.spi, needed_len,
-                                                               &pi->peer_keymat);
-               DBG(DBG_CRYPT,
-                       DBG_dump("Peer KEYMAT computed:\n", pi->peer_keymat,
-                                        pi->keymat_len));
-       }
-}
-
-static void compute_keymats(struct state *st, enum endpoint ep)
-{
-       if (st->st_ah.present)
-       {
-               compute_proto_keymat(st, PROTO_IPSEC_AH, &st->st_ah, ep);
-       }
-       if (st->st_esp.present)
-       {
-               compute_proto_keymat(st, PROTO_IPSEC_ESP, &st->st_esp, ep);
-       }
-}
-
-static void wipe_proto_keymat(struct ipsec_proto_info *pi, enum endpoint ep)
-{
-       if (ep & EP_LOCAL)
-       {
-               memwipe(pi->our_keymat, pi->keymat_len);
-       }
-       if (ep & EP_REMOTE)
-       {
-               memwipe(pi->peer_keymat, pi->keymat_len);
-       }
-}
-
-static void wipe_keymats(struct state *st, enum endpoint ep)
-{
-       if (st->st_ah.present)
-       {
-               wipe_proto_keymat(&st->st_ah, ep);
-       }
-       if (st->st_esp.present)
-       {
-               wipe_proto_keymat(&st->st_esp, ep);
-       }
-}
-
-static bool uses_pubkey_auth(int auth)
-{
-       switch (auth)
-       {
-               case OAKLEY_RSA_SIG:
-               case OAKLEY_ECDSA_SIG:
-               case OAKLEY_ECDSA_256:
-               case OAKLEY_ECDSA_384:
-               case OAKLEY_ECDSA_521:
-               case XAUTHInitRSA:
-               case XAUTHRespRSA:
-                       return TRUE;
-               default:
-                       return FALSE;
-       }
-}
-
-/* build an ID payload
- * Note: no memory is allocated for the body of the payload (tl->ptr).
- * We assume it will end up being a pointer into a sufficiently
- * stable datastructure.  It only needs to last a short time.
- */
-static void build_id_payload(struct isakmp_ipsec_id *hd, chunk_t *tl, struct end *end)
-{
-       identification_t *id = resolve_myid(end->id);
-
-       zero(hd);
-       hd->isaiid_idtype = id->get_type(id);
-
-       switch (id->get_type(id))
-       {
-               case ID_ANY:
-                       hd->isaiid_idtype = aftoinfo(addrtypeof(&end->host_addr))->id_addr;
-                       tl->len = addrbytesptr(&end->host_addr,
-                                               (const unsigned char **)&tl->ptr); /* sets tl->ptr too */
-                       break;
-               case ID_IPV4_ADDR:
-               case ID_IPV6_ADDR:
-               case ID_FQDN:
-               case ID_USER_FQDN:
-               case ID_DER_ASN1_DN:
-               case ID_KEY_ID:
-                       *tl = id->get_encoding(id);
-                       break;
-               default:
-                       bad_case(id->get_type(id));
-       }
-}
-
-/* State Transition Functions.
- *
- * The definition of state_microcode_table in demux.c is a good
- * overview of these routines.
- *
- * - Called from process_packet; result handled by complete_state_transition
- * - struct state_microcode member "processor" points to these
- * - these routine definitionss are in state order
- * - these routines must be restartable from any point of error return:
- *   beware of memory allocated before any error.
- * - output HDR is usually emitted by process_packet (if state_microcode
- *   member first_out_payload isn't ISAKMP_NEXT_NONE).
- *
- * The transition functions' functions include:
- * - process and judge payloads
- * - update st_iv (result of decryption is in st_new_iv)
- * - build reply packet
- */
-
-/* Handle a Main Mode Oakley first packet (responder side).
- * HDR;SA --> HDR;SA
- */
-stf_status main_inI1_outR1(struct msg_digest *md)
-{
-       struct payload_digest *const sa_pd = md->chain[ISAKMP_NEXT_SA];
-       struct state *st;
-       connection_t *c;
-       struct isakmp_proposal proposal;
-       pb_stream proposal_pbs;
-       pb_stream r_sa_pbs;
-       u_int32_t ipsecdoisit;
-       lset_t policy = LEMPTY;
-       int vids_to_send = 0;
-
-       /* We preparse the peer's proposal in order to determine
-        * the requested authentication policy (RSA or PSK)
-        */
-       RETURN_STF_FAILURE(preparse_isakmp_sa_body(&sa_pd->payload.sa
-               , &sa_pd->pbs, &ipsecdoisit, &proposal_pbs, &proposal));
-
-       backup_pbs(&proposal_pbs);
-       RETURN_STF_FAILURE(parse_isakmp_policy(&proposal_pbs
-                                        , proposal.isap_notrans, &policy));
-       restore_pbs(&proposal_pbs);
-
-       /* We are only considering candidate connections that match
-        * the requested authentication policy (RSA or PSK)
-        */
-       c = find_host_connection(&md->iface->addr, pluto_port
-                                                  , &md->sender, md->sender_port, policy);
-
-       if (c == NULL && md->iface->ike_float)
-       {
-               c = find_host_connection(&md->iface->addr, NAT_T_IKE_FLOAT_PORT
-                               , &md->sender, md->sender_port, policy);
-       }
-
-       if (c == NULL)
-       {
-               /* See if a wildcarded connection can be found.
-                * We cannot pick the right connection, so we're making a guess.
-                * All Road Warrior connections are fair game:
-                * we pick the first we come across (if any).
-                * If we don't find any, we pick the first opportunistic
-                * with the smallest subnet that includes the peer.
-                * There is, of course, no necessary relationship between
-                * an Initiator's address and that of its client,
-                * but Food Groups kind of assumes one.
-                */
-               {
-                       connection_t *d;
-
-                       d = find_host_connection(&md->iface->addr
-                               , pluto_port, (ip_address*)NULL, md->sender_port, policy);
-
-                       for (; d != NULL; d = d->hp_next)
-                       {
-                               if (d->kind == CK_GROUP)
-                               {
-                                       /* ignore */
-                               }
-                               else
-                               {
-                                       if (d->kind == CK_TEMPLATE && !(d->policy & POLICY_OPPO))
-                                       {
-                                               /* must be Road Warrior: we have a winner */
-                                               c = d;
-                                               break;
-                                       }
-
-                                       /* Opportunistic or Shunt: pick tightest match */
-                                       if (addrinsubnet(&md->sender, &d->spd.that.client)
-                                       && (c == NULL || !subnetinsubnet(&c->spd.that.client, &d->spd.that.client)))
-                                               c = d;
-                               }
-                       }
-               }
-
-               if (c == NULL)
-               {
-                       loglog(RC_LOG_SERIOUS, "initial Main Mode message received on %s:%u"
-                               " but no connection has been authorized%s%s"
-                               , ip_str(&md->iface->addr), ntohs(portof(&md->iface->addr))
-                               , (policy != LEMPTY) ? " with policy=" : ""
-                               , (policy != LEMPTY) ? bitnamesof(sa_policy_bit_names, policy) : "");
-                       /* XXX notification is in order! */
-                       return STF_IGNORE;
-               }
-               else if (c->kind != CK_TEMPLATE)
-               {
-                       loglog(RC_LOG_SERIOUS, "initial Main Mode message received on %s:%u"
-                               " but \"%s\" forbids connection"
-                               , ip_str(&md->iface->addr), pluto_port, c->name);
-                       /* XXX notification is in order! */
-                       return STF_IGNORE;
-               }
-               else
-               {
-                       /* Create a temporary connection that is a copy of this one.
-                        * His ID isn't declared yet.
-                        */
-                       c = rw_instantiate(c, &md->sender, md->sender_port, NULL, NULL);
-               }
-       }
-       else if (c->kind == CK_TEMPLATE)
-       {
-               /* Create an instance
-                * This is a rare case: wildcard peer ID but static peer IP address
-                */
-                c = rw_instantiate(c, &md->sender, md->sender_port, NULL, c->spd.that.id);
-       }
-
-       /* Set up state */
-       md->st = st = new_state();
-       st->st_connection = c;
-       set_cur_state(st);  /* (caller will reset cur_state) */
-       st->st_try = 0;     /* not our job to try again from start */
-       st->st_policy = c->policy & ~POLICY_IPSEC_MASK;     /* only as accurate as connection */
-
-       memcpy(st->st_icookie, md->hdr.isa_icookie, COOKIE_SIZE);
-       get_cookie(FALSE, st->st_rcookie, COOKIE_SIZE, &md->sender);
-
-       insert_state(st);   /* needs cookies, connection, and msgid (0) */
-
-       st->st_doi = ISAKMP_DOI_IPSEC;
-       st->st_situation = SIT_IDENTITY_ONLY; /* We only support this */
-
-       if ((c->kind == CK_INSTANCE) && (c->spd.that.host_port != pluto_port))
-       {
-          plog("responding to Main Mode from unknown peer %s:%u"
-                       , ip_str(&c->spd.that.host_addr), c->spd.that.host_port);
-       }
-       else if (c->kind == CK_INSTANCE)
-       {
-               plog("responding to Main Mode from unknown peer %s"
-                       , ip_str(&c->spd.that.host_addr));
-       }
-       else
-       {
-               plog("responding to Main Mode");
-       }
-
-       /* parse_isakmp_sa also spits out a winning SA into our reply,
-        * so we have to build our md->reply and emit HDR before calling it.
-        */
-
-       /* determine how many Vendor ID payloads we will be sending */
-       if (SEND_PLUTO_VID)
-       {
-               vids_to_send++;
-       }
-       if (SEND_CISCO_UNITY_VID)
-       {
-               vids_to_send++;
-       }
-       if (md->openpgp)
-       {
-               vids_to_send++;
-       }
-       if (SEND_XAUTH_VID)
-       {
-               vids_to_send++;
-       }
-       /* always send DPD Vendor ID */
-               vids_to_send++;
-       if (md->nat_traversal_vid && nat_traversal_enabled)
-       {
-               vids_to_send++;
-       }
-
-       /* HDR out.
-        * We can't leave this to comm_handle() because we must
-        * fill in the cookie.
-        */
-       {
-               struct isakmp_hdr r_hdr = md->hdr;
-
-               r_hdr.isa_flags &= ~ISAKMP_FLAG_COMMIT; /* we won't ever turn on this bit */
-               memcpy(r_hdr.isa_rcookie, st->st_rcookie, COOKIE_SIZE);
-               r_hdr.isa_np = ISAKMP_NEXT_SA;
-               if (!out_struct(&r_hdr, &isakmp_hdr_desc, &md->reply, &md->rbody))
-                       return STF_INTERNAL_ERROR;
-       }
-
-       /* start of SA out */
-       {
-               struct isakmp_sa r_sa = sa_pd->payload.sa;
-
-               r_sa.isasa_np = vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE;
-
-               if (!out_struct(&r_sa, &isakmp_sa_desc, &md->rbody, &r_sa_pbs))
-                       return STF_INTERNAL_ERROR;
-       }
-
-       /* SA body in and out */
-       RETURN_STF_FAILURE(parse_isakmp_sa_body(ipsecdoisit, &proposal_pbs
-               ,&proposal, &r_sa_pbs, st, FALSE));
-
-       /* if enabled send Pluto Vendor ID */
-       if (SEND_PLUTO_VID)
-       {
-               if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
-               , &md->rbody, VID_STRONGSWAN))
-               {
-                       return STF_INTERNAL_ERROR;
-               }
-       }
-
-       /* if enabled send Cisco Unity Vendor ID */
-       if (SEND_CISCO_UNITY_VID)
-       {
-               if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
-               , &md->rbody, VID_CISCO_UNITY))
-               {
-                       return STF_INTERNAL_ERROR;
-               }
-       }
-
-       /*
-        * if the peer sent an OpenPGP Vendor ID we offer the same capability
-        */
-       if (md->openpgp)
-       {
-               if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
-               , &md->rbody, VID_OPENPGP))
-               {
-                       return STF_INTERNAL_ERROR;
-               }
-       }
-
-       /* Announce our ability to do eXtended AUTHentication to the peer */
-       if (SEND_XAUTH_VID)
-       {
-               if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
-               , &md->rbody, VID_MISC_XAUTH))
-               {
-                       return STF_INTERNAL_ERROR;
-               }
-       }
-
-       /* Announce our ability to do Dead Peer Detection to the peer */
-       if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
-       , &md->rbody, VID_MISC_DPD))
-       {
-               return STF_INTERNAL_ERROR;
-       }
-
-       if (md->nat_traversal_vid && nat_traversal_enabled)
-       {
-               /* reply if NAT-Traversal draft is supported */
-               st->nat_traversal = nat_traversal_vid_to_method(md->nat_traversal_vid);
-
-               if (st->nat_traversal
-               && !out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
-               , &md->rbody, md->nat_traversal_vid))
-               {
-                       return STF_INTERNAL_ERROR;
-               }
-       }
-
-       close_message(&md->rbody);
-
-       /* save initiator SA for HASH */
-       free(st->st_p1isa.ptr);
-       st->st_p1isa = chunk_create(sa_pd->pbs.start, pbs_room(&sa_pd->pbs));
-       st->st_p1isa = chunk_clone(st->st_p1isa);
-
-       return STF_OK;
-}
-
-/* STATE_MAIN_I1: HDR, SA --> auth dependent
- * PSK_AUTH, DS_AUTH: --> HDR, KE, Ni
- *
- * The following are not yet implemented:
- * PKE_AUTH: --> HDR, KE, [ HASH(1), ] <IDi1_b>PubKey_r, <Ni_b>PubKey_r
- * RPKE_AUTH: --> HDR, [ HASH(1), ] <Ni_b>Pubkey_r, <KE_b>Ke_i,
- *                <IDi1_b>Ke_i [,<<Cert-I_b>Ke_i]
- *
- * We must verify that the proposal received matches one we sent.
- */
-stf_status main_inR1_outI2(struct msg_digest *md)
-{
-       struct state *const st = md->st;
-
-       u_int8_t np = ISAKMP_NEXT_NONE;
-
-       /* verify echoed SA */
-       {
-               u_int32_t ipsecdoisit;
-               pb_stream proposal_pbs;
-               struct isakmp_proposal proposal;
-               struct payload_digest *const sapd = md->chain[ISAKMP_NEXT_SA];
-
-               RETURN_STF_FAILURE(preparse_isakmp_sa_body(&sapd->payload.sa
-                       ,&sapd->pbs, &ipsecdoisit, &proposal_pbs, &proposal));
-               if (proposal.isap_notrans != 1)
-               {
-                       loglog(RC_LOG_SERIOUS, "a single Transform is required in a selecting Oakley Proposal; found %u"
-                       , (unsigned)proposal.isap_notrans);
-                       RETURN_STF_FAILURE(ISAKMP_BAD_PROPOSAL_SYNTAX);
-               }
-               RETURN_STF_FAILURE(parse_isakmp_sa_body(ipsecdoisit
-                       , &proposal_pbs, &proposal, NULL, st, TRUE));
-       }
-
-       if (nat_traversal_enabled && md->nat_traversal_vid)
-       {
-               st->nat_traversal = nat_traversal_vid_to_method(md->nat_traversal_vid);
-               plog("enabling possible NAT-traversal with method %s"
-                        , bitnamesof(natt_type_bitnames, st->nat_traversal));
-       }
-       if (st->nat_traversal & NAT_T_WITH_NATD)
-       {
-               np = (st->nat_traversal & NAT_T_WITH_RFC_VALUES) ?
-                               ISAKMP_NEXT_NATD_RFC : ISAKMP_NEXT_NATD_DRAFTS;
-       }
-
-       /**************** build output packet HDR;KE;Ni ****************/
-
-       /* HDR out.
-        * We can't leave this to comm_handle() because the isa_np
-        * depends on the type of Auth (eventually).
-        */
-       echo_hdr(md, FALSE, ISAKMP_NEXT_KE);
-
-       /* KE out */
-       if (!build_and_ship_KE(st, &st->st_gi, st->st_oakley.group
-       , &md->rbody, ISAKMP_NEXT_NONCE))
-       {
-               return STF_INTERNAL_ERROR;
-       }
-
-#ifdef DEBUG
-       /* Ni out */
-       if (!build_and_ship_nonce(&st->st_ni, &md->rbody
-       , (cur_debugging & IMPAIR_BUST_MI2)? ISAKMP_NEXT_VID : np, "Ni"))
-       {
-               return STF_INTERNAL_ERROR;
-       }
-       if (cur_debugging & IMPAIR_BUST_MI2)
-       {
-               /* generate a pointless large VID payload to push message over MTU */
-               pb_stream vid_pbs;
-
-               if (!out_generic(np, &isakmp_vendor_id_desc, &md->rbody, &vid_pbs))
-               {
-                       return STF_INTERNAL_ERROR;
-               }
-               if (!out_zero(1500 /*MTU?*/, &vid_pbs, "Filler VID"))
-               {
-                       return STF_INTERNAL_ERROR;
-               }
-               close_output_pbs(&vid_pbs);
-       }
-#else
-       /* Ni out */
-       if (!build_and_ship_nonce(&st->st_ni, &md->rbody, np, "Ni"))
-       {
-               return STF_INTERNAL_ERROR;
-       }
-#endif
-
-       if (st->nat_traversal & NAT_T_WITH_NATD)
-       {
-               if (!nat_traversal_add_natd(ISAKMP_NEXT_NONE, &md->rbody, md))
-               {
-                       return STF_INTERNAL_ERROR;
-               }
-       }
-
-       /* finish message */
-       close_message(&md->rbody);
-
-       /* Reinsert the state, using the responder cookie we just received */
-       unhash_state(st);
-       memcpy(st->st_rcookie, md->hdr.isa_rcookie, COOKIE_SIZE);
-       insert_state(st);   /* needs cookies, connection, and msgid (0) */
-
-       return STF_OK;
-}
-
-/* STATE_MAIN_R1:
- * PSK_AUTH, DS_AUTH: HDR, KE, Ni --> HDR, KE, Nr
- *
- * The following are not yet implemented:
- * PKE_AUTH: HDR, KE, [ HASH(1), ] <IDi1_b>PubKey_r, <Ni_b>PubKey_r
- *          --> HDR, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i
- * RPKE_AUTH:
- *          HDR, [ HASH(1), ] <Ni_b>Pubkey_r, <KE_b>Ke_i, <IDi1_b>Ke_i [,<<Cert-I_b>Ke_i]
- *          --> HDR, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDr1_b>Ke_r
- */
-stf_status main_inI2_outR2(struct msg_digest *md)
-{
-       struct state *const st = md->st;
-       pb_stream *keyex_pbs = &md->chain[ISAKMP_NEXT_KE]->pbs;
-
-       /* send CR if auth is RSA or ECDSA and no preloaded public key exists*/
-       bool pubkey_auth = uses_pubkey_auth(st->st_oakley.auth);
-       bool send_cr = !no_cr_send && pubkey_auth && !has_preloaded_public_key(st);
-
-       u_int8_t np = ISAKMP_NEXT_NONE;
-
-       /* KE in */
-       RETURN_STF_FAILURE(accept_KE(&st->st_gi, "Gi", st->st_oakley.group, keyex_pbs));
-
-       /* Ni in */
-       RETURN_STF_FAILURE(accept_nonce(md, &st->st_ni, "Ni"));
-
-       if (st->nat_traversal & NAT_T_WITH_NATD)
-       {
-          nat_traversal_natd_lookup(md);
-
-          np = (st->nat_traversal & NAT_T_WITH_RFC_VALUES) ?
-                               ISAKMP_NEXT_NATD_RFC : ISAKMP_NEXT_NATD_DRAFTS;
-       }
-       if (st->nat_traversal)
-       {
-          nat_traversal_show_result(st->nat_traversal, md->sender_port);
-       }
-       if (st->nat_traversal & NAT_T_WITH_KA)
-       {
-          nat_traversal_new_ka_event();
-       }
-
-       /* decode certificate requests */
-       st->st_connection->got_certrequest = FALSE;
-       decode_cr(md, st->st_connection);
-
-       /**************** build output packet HDR;KE;Nr ****************/
-
-       /* HDR out done */
-
-       /* KE out */
-       if (!build_and_ship_KE(st, &st->st_gr, st->st_oakley.group
-       , &md->rbody, ISAKMP_NEXT_NONCE))
-       {
-               return STF_INTERNAL_ERROR;
-       }
-
-#ifdef DEBUG
-       /* Nr out */
-       if (!build_and_ship_nonce(&st->st_nr, &md->rbody,
-          (cur_debugging & IMPAIR_BUST_MR2)? ISAKMP_NEXT_VID
-               : (send_cr? ISAKMP_NEXT_CR : np), "Nr"))
-       {
-               return STF_INTERNAL_ERROR;
-       }
-       if (cur_debugging & IMPAIR_BUST_MR2)
-       {
-               /* generate a pointless large VID payload to push message over MTU */
-               pb_stream vid_pbs;
-
-               if (!out_generic((send_cr)? ISAKMP_NEXT_CR : np,
-                       &isakmp_vendor_id_desc, &md->rbody, &vid_pbs))
-               {
-                       return STF_INTERNAL_ERROR;
-               }
-               if (!out_zero(1500 /*MTU?*/, &vid_pbs, "Filler VID"))
-               {
-                       return STF_INTERNAL_ERROR;
-               }
-               close_output_pbs(&vid_pbs);
-       }
-#else
-       /* Nr out */
-       if (!build_and_ship_nonce(&st->st_nr, &md->rbody,
-               (send_cr)? ISAKMP_NEXT_CR : np, "Nr"))
-               return STF_INTERNAL_ERROR;
-#endif
-
-       /* CR out */
-       if (send_cr)
-       {
-               if (st->st_connection->kind == CK_PERMANENT)
-               {
-                       identification_t *ca = st->st_connection->spd.that.ca;
-                       chunk_t cr = (ca) ? ca->get_encoding(ca) : chunk_empty;
-
-                       if (!build_and_ship_CR(CERT_X509_SIGNATURE, cr, &md->rbody, np))
-                       {
-                               return STF_INTERNAL_ERROR;
-                       }
-               }
-               else
-               {
-                       linked_list_t *list = collect_rw_ca_candidates(md);
-                       int count = list->get_count(list);
-                       bool error = FALSE;
-
-                       if (count)
-                       {
-                               enumerator_t *enumerator;
-                               identification_t *ca;
-
-                               enumerator = list->create_enumerator(list);
-                               while (enumerator->enumerate(enumerator, &ca))
-                               {
-                                       if (!build_and_ship_CR(CERT_X509_SIGNATURE,
-                                                                                  ca->get_encoding(ca), &md->rbody,
-                                                                                  --count ? ISAKMP_NEXT_CR : np))
-                                       {
-                                               error = TRUE;
-                                               break;
-                                       }
-                               }
-                               enumerator->destroy(enumerator);
-                       }
-                       else
-                       {
-                               if (!build_and_ship_CR(CERT_X509_SIGNATURE, chunk_empty,
-                                                                          &md->rbody, np))
-                               {
-                                       error = TRUE;
-                               }
-                       }
-                       list->destroy_offset(list, offsetof(identification_t, destroy));
-                       if (error)
-                       {
-                               return STF_INTERNAL_ERROR;
-                       }
-               }
-       }
-
-       if (st->nat_traversal & NAT_T_WITH_NATD)
-       {
-          if (!nat_traversal_add_natd(ISAKMP_NEXT_NONE, &md->rbody, md))
-               {
-                  return STF_INTERNAL_ERROR;
-               }
-       }
-
-       /* finish message */
-       close_message(&md->rbody);
-
-       /* next message will be encrypted, but not this one.
-        * We could defer this calculation.
-        */
-       compute_dh_shared(st, st->st_gi);
-       if (!generate_skeyids_iv(st))
-       {
-               return STF_FAIL + ISAKMP_AUTHENTICATION_FAILED;
-       }
-       update_iv(st);
-
-       return STF_OK;
-}
-
-/* STATE_MAIN_I2:
- * SMF_PSK_AUTH: HDR, KE, Nr --> HDR*, IDi1, HASH_I
- * SMF_DS_AUTH: HDR, KE, Nr --> HDR*, IDi1, [ CERT, ] SIG_I
- *
- * The following are not yet implemented.
- * SMF_PKE_AUTH: HDR, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i
- *          --> HDR*, HASH_I
- * SMF_RPKE_AUTH: HDR, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDr1_b>Ke_r
- *          --> HDR*, HASH_I
- */
-stf_status main_inR2_outI3(struct msg_digest *md)
-{
-       struct state *const st = md->st;
-       pb_stream *const keyex_pbs = &md->chain[ISAKMP_NEXT_KE]->pbs;
-       pb_stream id_pbs;   /* ID Payload; also used for hash calculation */
-
-       connection_t *c = st->st_connection;
-       certpolicy_t cert_policy = c->spd.this.sendcert;
-       cert_t *mycert = c->spd.this.cert;
-       bool requested, send_cert, send_cr;
-       bool pubkey_auth = uses_pubkey_auth(st->st_oakley.auth);
-
-       int auth_payload = pubkey_auth ? ISAKMP_NEXT_SIG : ISAKMP_NEXT_HASH;
-
-       /* KE in */
-       RETURN_STF_FAILURE(accept_KE(&st->st_gr, "Gr", st->st_oakley.group, keyex_pbs));
-
-       /* Nr in */
-       RETURN_STF_FAILURE(accept_nonce(md, &st->st_nr, "Nr"));
-
-       /* decode certificate requests */
-       c->got_certrequest = FALSE;
-       decode_cr(md, c);
-
-       /* free collected certificate requests since as initiator
-        * we don't heed them anyway
-        */
-       if (c->requested_ca)
-       {
-               c->requested_ca->destroy_offset(c->requested_ca,
-                                                                offsetof(identification_t, destroy));
-               c->requested_ca = NULL;
-       }
-
-       /* send certificate if auth is RSA, we have one and we want
-        * or are requested to send it
-        */
-       requested = cert_policy == CERT_SEND_IF_ASKED && c->got_certrequest;
-       send_cert = pubkey_auth && mycert &&
-                               mycert->cert->get_type(mycert->cert) == CERT_X509 &&
-                               (cert_policy == CERT_ALWAYS_SEND || requested);
-
-       /* send certificate request if we don't have a preloaded RSA public key */
-       send_cr = !no_cr_send && send_cert && !has_preloaded_public_key(st);
-
-       /* done parsing; initialize crypto  */
-       compute_dh_shared(st, st->st_gr);
-       if (!generate_skeyids_iv(st))
-       {
-               return STF_FAIL + ISAKMP_AUTHENTICATION_FAILED;
-       }
-       if (st->nat_traversal & NAT_T_WITH_NATD)
-       {
-               nat_traversal_natd_lookup(md);
-       }
-       if (st->nat_traversal)
-       {
-               nat_traversal_show_result(st->nat_traversal, md->sender_port);
-       }
-       if (st->nat_traversal & NAT_T_WITH_KA)
-       {
-               nat_traversal_new_ka_event();
-       }
-
-       /*************** build output packet HDR*;IDii;HASH/SIG_I ***************/
-       /* ??? NOTE: this is almost the same as main_inI3_outR3's code */
-
-       /* HDR* out done */
-
-       /* IDii out */
-       {
-               struct isakmp_ipsec_id id_hd;
-               chunk_t id_b;
-
-               build_id_payload(&id_hd, &id_b, &c->spd.this);
-               id_hd.isaiid_np = (send_cert)? ISAKMP_NEXT_CERT : auth_payload;
-               if (!out_struct(&id_hd, &isakmp_ipsec_identification_desc, &md->rbody, &id_pbs)
-               || !out_chunk(id_b, &id_pbs, "my identity"))
-               {
-                       return STF_INTERNAL_ERROR;
-               }
-               close_output_pbs(&id_pbs);
-       }
-
-       /* CERT out */
-       if (pubkey_auth)
-       {
-               DBG(DBG_CONTROL,
-                       DBG_log("our certificate policy is %N", cert_policy_names, cert_policy)
-               )
-               if (mycert && mycert->cert->get_type(mycert->cert) == CERT_X509)
-               {
-                       const char *request_text = "";
-
-                       if (cert_policy == CERT_SEND_IF_ASKED)
-                       {
-                               request_text = (send_cert)? "upon request":"without request";
-                       }
-                       plog("we have a cert %s sending it %s"
-                               , send_cert? "and are":"but are not", request_text);
-               }
-               else
-               {
-                       plog("we don't have a cert");
-               }
-       }
-       if (send_cert)
-       {
-               bool success = FALSE;
-               chunk_t cert_encoding;
-               pb_stream cert_pbs;
-
-               struct isakmp_cert cert_hd;
-               cert_hd.isacert_np = (send_cr)? ISAKMP_NEXT_CR : ISAKMP_NEXT_SIG;
-               cert_hd.isacert_type = CERT_X509_SIGNATURE;
-
-               if (!out_struct(&cert_hd, &isakmp_ipsec_certificate_desc, &md->rbody, &cert_pbs))
-               {
-                       return STF_INTERNAL_ERROR;
-               }
-               if (mycert->cert->get_encoding(mycert->cert, CERT_ASN1_DER,
-                                                                          &cert_encoding))
-               {
-                       success = out_chunk(cert_encoding, &cert_pbs, "CERT");
-                       free(cert_encoding.ptr);
-               }
-               if (!success)
-               {
-                       return STF_INTERNAL_ERROR;
-               }
-               close_output_pbs(&cert_pbs);
-       }
-
-       /* CR out */
-       if (send_cr)
-       {
-               identification_t *ca = st->st_connection->spd.that.ca;
-               chunk_t cr = (ca) ? ca->get_encoding(ca) : chunk_empty;
-
-               if (!build_and_ship_CR(CERT_X509_SIGNATURE, cr, &md->rbody, ISAKMP_NEXT_SIG))
-               {
-                       return STF_INTERNAL_ERROR;
-               }
-       }
-
-   /* HASH_I or SIG_I out */
-       {
-               chunk_t hash = chunk_alloca(MAX_DIGEST_LEN);
-
-               main_mode_hash(st, &hash, TRUE, &id_pbs);
-
-               if (auth_payload == ISAKMP_NEXT_HASH)
-               {
-                       /* HASH_I out */
-                       if (!out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_hash_desc, &md->rbody,
-                                                                hash.ptr, hash.len, "HASH_I"))
-                       {
-                               return STF_INTERNAL_ERROR;
-                       }
-               }
-               else
-               {
-                       /* SIG_I out */
-                       u_char sig_val[RSA_MAX_OCTETS];
-                       signature_scheme_t scheme;
-                       size_t sig_len;
-
-                       scheme = oakley_to_signature_scheme(st->st_oakley.auth);
-
-                       sig_len = sign_hash(scheme, c, sig_val, hash);
-                       if (sig_len == 0)
-                       {
-                               loglog(RC_LOG_SERIOUS, "unable to locate my private key for signature");
-                               return STF_FAIL + ISAKMP_AUTHENTICATION_FAILED;
-                       }
-
-                       if (!out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_signature_desc
-                       , &md->rbody, sig_val, sig_len, "SIG_I"))
-                       {
-                               return STF_INTERNAL_ERROR;
-                       }
-               }
-       }
-
-       /* encrypt message, except for fixed part of header */
-
-       /* st_new_iv was computed by generate_skeyids_iv */
-       if (!encrypt_message(&md->rbody, st))
-       {
-               return STF_INTERNAL_ERROR;      /* ??? we may be partly committed */
-       }
-       return STF_OK;
-}
-
-/* Shared logic for asynchronous lookup of DNS KEY records.
- * Used for STATE_MAIN_R2 and STATE_MAIN_I3.
- */
-
-enum key_oppo_step {
-       kos_null,
-       kos_his_txt
-#ifdef USE_KEYRR
-       , kos_his_key
-#endif
-};
-
-struct key_continuation {
-       struct adns_continuation ac;        /* common prefix */
-       struct msg_digest *md;
-       enum   key_oppo_step step;
-       bool                 failure_ok;
-       err_t                last_ugh;
-};
-
-typedef stf_status (key_tail_fn)(struct msg_digest *md
-                                                                 , struct key_continuation *kc);
-
-static void report_key_dns_failure(identification_t *id, err_t ugh)
-{
-       loglog(RC_LOG_SERIOUS, "no RSA public key known for '%Y'"
-               "; DNS search for KEY failed (%s)", id, ugh);
-}
-
-
-/* Processs the Main Mode ID Payload and the Authenticator
- * (Hash or Signature Payload).
- * If a DNS query is still needed to get the other host's public key,
- * the query is initiated and STF_SUSPEND is returned.
- * Note: parameter kc is a continuation containing the results from
- * the previous DNS query, or NULL indicating no query has been issued.
- */
-static stf_status
-main_id_and_auth(struct msg_digest *md
-                                , bool initiator       /* are we the Initiator? */
-                                , cont_fn_t cont_fn    /* continuation function */
-                                , const struct key_continuation *kc    /* current state, can be NULL */
-)
-{
-       chunk_t hash = chunk_alloca(MAX_DIGEST_LEN);
-       struct state *st = md->st;
-       identification_t *peer;
-       stf_status r = STF_OK;
-
-       /* ID Payload in */
-       if (!decode_peer_id(md, &peer))
-       {
-               return STF_FAIL + ISAKMP_INVALID_ID_INFORMATION;
-       }
-
-       /* Hash the ID Payload.
-        * main_mode_hash requires idpl->cur to be at end of payload
-        * so we temporarily set if so.
-        */
-       {
-               pb_stream *idpl = &md->chain[ISAKMP_NEXT_ID]->pbs;
-               u_int8_t *old_cur = idpl->cur;
-
-               idpl->cur = idpl->roof;
-               main_mode_hash(st, &hash, !initiator, idpl);
-               idpl->cur = old_cur;
-       }
-
-       switch (st->st_oakley.auth)
-       {
-       case OAKLEY_PRESHARED_KEY:
-       case XAUTHInitPreShared:
-       case XAUTHRespPreShared:
-               {
-                       pb_stream *const hash_pbs = &md->chain[ISAKMP_NEXT_HASH]->pbs;
-
-                       if (pbs_left(hash_pbs) != hash.len
-                       || memcmp(hash_pbs->cur, hash.ptr, hash.len) != 0)
-                       {
-                               DBG_cond_dump(DBG_CRYPT, "received HASH:"
-                                       , hash_pbs->cur, pbs_left(hash_pbs));
-                               loglog(RC_LOG_SERIOUS, "received Hash Payload does not match computed value");
-                               /* XXX Could send notification back */
-                               r = STF_FAIL + ISAKMP_INVALID_HASH_INFORMATION;
-                       }
-               }
-               break;
-
-       case OAKLEY_RSA_SIG:
-       case XAUTHInitRSA:
-       case XAUTHRespRSA:
-               r = check_signature(KEY_RSA, peer, st, hash,
-                                                       &md->chain[ISAKMP_NEXT_SIG]->pbs,
-#ifdef USE_KEYRR
-                                                       kc == NULL ? NULL : kc->ac.keys_from_dns,
-#endif /* USE_KEYRR */
-                                                       kc == NULL ? NULL : kc->ac.gateways_from_dns
-                       );
-
-               if (r == STF_SUSPEND)
-               {
-                       err_t ugh = NULL;
-#ifdef ADNS
-                       /* initiate/resume asynchronous DNS lookup for key */
-                       struct key_continuation *nkc = malloc_thing(struct key_continuation);
-                       enum key_oppo_step step_done = kc == NULL? kos_null : kc->step;
-
-                       /* Record that state is used by a suspended md */
-                       passert(st->st_suspended_md == NULL);
-                       st->st_suspended_md = md;
-
-                       nkc->failure_ok = FALSE;
-                       nkc->md = md;
-
-                       switch (step_done)
-                       {
-                       case kos_null:
-                               /* first try: look for the TXT records */
-                               nkc->step = kos_his_txt;
-#ifdef USE_KEYRR
-                               nkc->failure_ok = TRUE;
-#endif
-                               ugh = start_adns_query(peer, peer, T_TXT, cont_fn, &nkc->ac);
-                               break;
-
-#ifdef USE_KEYRR
-                       case kos_his_txt:
-                               /* second try: look for the KEY records */
-                               nkc->step = kos_his_key;
-                               ugh = start_adns_query(peer, NULL, T_KEY, cont_fn, &nkc->ac);
-                               break;
-#endif /* USE_KEYRR */
-
-                       default:
-                               bad_case(step_done);
-                       }
-#else /* ADNS */
-                       ugh = "adns not supported";
-#endif /* ADNS */
-                       if (ugh != NULL)
-                       {
-                               report_key_dns_failure(peer, ugh);
-                               st->st_suspended_md = NULL;
-                               r = STF_FAIL + ISAKMP_INVALID_KEY_INFORMATION;
-                       }
-               }
-               break;
-
-       case OAKLEY_ECDSA_256:
-       case OAKLEY_ECDSA_384:
-       case OAKLEY_ECDSA_521:
-               r = check_signature(KEY_ECDSA, peer, st, hash,
-                                                       &md->chain[ISAKMP_NEXT_SIG]->pbs,
-#ifdef USE_KEYRR
-                                                       NULL,
-#endif /* USE_KEYRR */
-                                                       NULL);
-               break;
-
-       default:
-               bad_case(st->st_oakley.auth);
-       }
-       if (r != STF_OK)
-       {
-               peer->destroy(peer);
-               return r;
-       }
-       DBG(DBG_CRYPT, DBG_log("authentication succeeded"));
-
-       /*
-        * With the peer ID known, let's see if we need to switch connections.
-        */
-       if (!switch_connection(md, peer, initiator))
-       {
-               r = STF_FAIL + ISAKMP_INVALID_ID_INFORMATION;
-       }
-       peer->destroy(peer);
-       return r;
-}
-
-/* This continuation is called as part of either
- * the main_inI3_outR3 state or main_inR3 state.
- *
- * The "tail" function is the corresponding tail
- * function main_inI3_outR3_tail | main_inR3_tail,
- * either directly when the state is started, or via
- * adns continuation.
- *
- * Basically, we go around in a circle:
- *   main_in?3* -> key_continue
- *                ^            \
- *               /              V
- *             adns            main_in?3*_tail
- *              ^               |
- *               \              V
- *                main_id_and_auth
- *
- * until such time as main_id_and_auth is able
- * to find authentication, or we run out of things
- * to try.
- */
-static void key_continue(struct adns_continuation *cr, err_t ugh,
-                                                key_tail_fn *tail)
-{
-       struct key_continuation *kc = (void *)cr;
-       struct state *st = kc->md->st;
-
-       passert(cur_state == NULL);
-
-       /* if st == NULL, our state has been deleted -- just clean up */
-       if (st != NULL)
-       {
-               stf_status r;
-
-               passert(st->st_suspended_md == kc->md);
-               st->st_suspended_md = NULL;     /* no longer connected or suspended */
-               cur_state = st;
-
-               if (!kc->failure_ok && ugh != NULL)
-               {
-                       report_key_dns_failure(st->st_connection->spd.that.id, ugh);
-                       r = STF_FAIL + ISAKMP_INVALID_KEY_INFORMATION;
-               }
-               else
-               {
-
-#ifdef USE_KEYRR
-                       passert(kc->step == kos_his_txt || kc->step == kos_his_key);
-#else
-                       passert(kc->step == kos_his_txt);
-#endif
-                       kc->last_ugh = ugh; /* record previous error in case we need it */
-                       r = (*tail)(kc->md, kc);
-               }
-               complete_state_transition(&kc->md, r);
-       }
-       if (kc->md != NULL)
-       {
-               release_md(kc->md);
-       }
-       cur_state = NULL;
-}
-
-/* STATE_MAIN_R2:
- * PSK_AUTH: HDR*, IDi1, HASH_I --> HDR*, IDr1, HASH_R
- * DS_AUTH: HDR*, IDi1, [ CERT, ] SIG_I --> HDR*, IDr1, [ CERT, ] SIG_R
- * PKE_AUTH, RPKE_AUTH: HDR*, HASH_I --> HDR*, HASH_R
- *
- * Broken into parts to allow asynchronous DNS lookup.
- *
- * - main_inI3_outR3 to start
- * - main_inI3_outR3_tail to finish or suspend for DNS lookup
- * - main_inI3_outR3_continue to start main_inI3_outR3_tail again
- */
-static key_tail_fn main_inI3_outR3_tail;        /* forward */
-
-stf_status main_inI3_outR3(struct msg_digest *md)
-{
-       return main_inI3_outR3_tail(md, NULL);
-}
-
-static void main_inI3_outR3_continue(struct adns_continuation *cr, err_t ugh)
-{
-       key_continue(cr, ugh, main_inI3_outR3_tail);
-}
-
-static stf_status
-main_inI3_outR3_tail(struct msg_digest *md
-, struct key_continuation *kc)
-{
-       struct state *const st = md->st;
-       u_int8_t auth_payload;
-       pb_stream r_id_pbs; /* ID Payload; also used for hash calculation */
-       certpolicy_t cert_policy;
-       cert_t *mycert;
-       bool pubkey_auth, send_cert, requested;
-
-       /* ID and HASH_I or SIG_I in
-        * Note: this may switch the connection being used!
-        */
-       {
-               stf_status r = main_id_and_auth(md, FALSE
-                                                                               , main_inI3_outR3_continue
-                                                                               , kc);
-
-               if (r != STF_OK)
-               {
-                       return r;
-               }
-       }
-
-       /* send certificate if pubkey authentication is used, we have one
-        * and we want or are requested to send it
-        */
-       cert_policy = st->st_connection->spd.this.sendcert;
-       mycert = st->st_connection->spd.this.cert;
-       requested = cert_policy == CERT_SEND_IF_ASKED
-                               && st->st_connection->got_certrequest;
-       pubkey_auth = uses_pubkey_auth(st->st_oakley.auth);
-       send_cert = pubkey_auth && mycert &&
-                               mycert->cert->get_type(mycert->cert) == CERT_X509 &&
-                               (cert_policy == CERT_ALWAYS_SEND || requested);
-
-       /*************** build output packet HDR*;IDir;HASH/SIG_R ***************/
-       /* proccess_packet() would automatically generate the HDR*
-        * payload if smc->first_out_payload is not ISAKMP_NEXT_NONE.
-        * We don't do this because we wish there to be no partially
-        * built output packet if we need to suspend for asynch DNS.
-        */
-       /* ??? NOTE: this is almost the same as main_inR2_outI3's code */
-
-       /* HDR* out
-        * If auth were PKE_AUTH or RPKE_AUTH, ISAKMP_NEXT_HASH would
-        * be first payload.
-        */
-       echo_hdr(md, TRUE, ISAKMP_NEXT_ID);
-
-       auth_payload = pubkey_auth ? ISAKMP_NEXT_SIG : ISAKMP_NEXT_HASH;
-
-       /* IDir out */
-       {
-               /* id_hd should be struct isakmp_id, but struct isakmp_ipsec_id
-                * allows build_id_payload() to work for both phases.
-                */
-               struct isakmp_ipsec_id id_hd;
-               chunk_t id_b;
-
-               build_id_payload(&id_hd, &id_b, &st->st_connection->spd.this);
-               id_hd.isaiid_np = (send_cert)? ISAKMP_NEXT_CERT : auth_payload;
-               if (!out_struct(&id_hd, &isakmp_ipsec_identification_desc, &md->rbody, &r_id_pbs)
-               || !out_chunk(id_b, &r_id_pbs, "my identity"))
-               {
-                       return STF_INTERNAL_ERROR;
-               }
-               close_output_pbs(&r_id_pbs);
-       }
-
-       /* CERT out */
-       if (pubkey_auth)
-       {
-               DBG(DBG_CONTROL,
-                       DBG_log("our certificate policy is %N", cert_policy_names, cert_policy)
-               )
-               if (mycert && mycert->cert->get_type(mycert->cert) == CERT_X509)
-               {
-                       const char *request_text = "";
-
-                       if (cert_policy == CERT_SEND_IF_ASKED)
-                       {
-                               request_text = (send_cert)? "upon request":"without request";
-                       }
-                       plog("we have a cert %s sending it %s"
-                               , send_cert? "and are":"but are not", request_text);
-               }
-               else
-               {
-                       plog("we don't have a cert");
-               }
-       }
-       if (send_cert)
-       {
-               bool success = FALSE;
-               chunk_t cert_encoding;
-               pb_stream cert_pbs;
-               struct isakmp_cert cert_hd;
-
-               cert_hd.isacert_np = ISAKMP_NEXT_SIG;
-               cert_hd.isacert_type = CERT_X509_SIGNATURE;
-
-               if (!out_struct(&cert_hd, &isakmp_ipsec_certificate_desc, &md->rbody, &cert_pbs))
-               {
-                       return STF_INTERNAL_ERROR;
-               }
-               if (mycert->cert->get_encoding(mycert->cert, CERT_ASN1_DER,
-                                                                          &cert_encoding))
-               {
-                       success = out_chunk(cert_encoding, &cert_pbs, "CERT");
-                       free(cert_encoding.ptr);
-               }
-               if (!success)
-               {
-                       return STF_INTERNAL_ERROR;
-               }
-               close_output_pbs(&cert_pbs);
-       }
-
-       /* HASH_R or SIG_R out */
-       {
-               chunk_t hash = chunk_alloca(MAX_DIGEST_LEN);
-
-               main_mode_hash(st, &hash, FALSE, &r_id_pbs);
-
-               if (auth_payload == ISAKMP_NEXT_HASH)
-               {
-                       /* HASH_R out */
-                       if (!out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_hash_desc, &md->rbody,
-                                                                hash.ptr, hash.len, "HASH_R"))
-                       {
-                               return STF_INTERNAL_ERROR;
-                       }
-               }
-               else
-               {
-                       /* SIG_R out */
-                       u_char sig_val[RSA_MAX_OCTETS];
-                       signature_scheme_t scheme;
-                       size_t sig_len;
-
-                       scheme = oakley_to_signature_scheme(st->st_oakley.auth);
-
-                       sig_len = sign_hash(scheme, st->st_connection, sig_val, hash);
-                       if (sig_len == 0)
-                       {
-                               loglog(RC_LOG_SERIOUS, "unable to locate my private key for signature");
-                               return STF_FAIL + ISAKMP_AUTHENTICATION_FAILED;
-                       }
-
-                       if (!out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_signature_desc
-                       , &md->rbody, sig_val, sig_len, "SIG_R"))
-                       {
-                               return STF_INTERNAL_ERROR;
-                       }
-               }
-       }
-
-       /* encrypt message, sans fixed part of header */
-
-       if (!encrypt_message(&md->rbody, st))
-       {
-               return STF_INTERNAL_ERROR;      /* ??? we may be partly committed */
-       }
-
-       /* Last block of Phase 1 (R3), kept for Phase 2 IV generation */
-       DBG_cond_dump(DBG_CRYPT, "last encrypted block of Phase 1:"
-               , st->st_new_iv, st->st_new_iv_len);
-
-       ISAKMP_SA_established(st->st_connection, st->st_serialno);
-
-       /* Save Phase 1 IV */
-       st->st_ph1_iv_len = st->st_new_iv_len;
-       set_ph1_iv(st, st->st_new_iv);
-
-       return STF_OK;
-}
-
-/* STATE_MAIN_I3:
- * Handle HDR*;IDir;HASH/SIG_R from responder.
- *
- * Broken into parts to allow asynchronous DNS for KEY records.
- *
- * - main_inR3 to start
- * - main_inR3_tail to finish or suspend for DNS lookup
- * - main_inR3_continue to start main_inR3_tail again
- */
-
-static key_tail_fn main_inR3_tail;      /* forward */
-
-stf_status main_inR3(struct msg_digest *md)
-{
-       return main_inR3_tail(md, NULL);
-}
-
-static void main_inR3_continue(struct adns_continuation *cr, err_t ugh)
-{
-       key_continue(cr, ugh, main_inR3_tail);
-}
-
-static stf_status main_inR3_tail(struct msg_digest *md,
-                                                                struct key_continuation *kc)
-{
-       struct state *const st = md->st;
-
-       /* ID and HASH_R or SIG_R in
-        * Note: this may switch the connection being used!
-        */
-       {
-               stf_status r = main_id_and_auth(md, TRUE, main_inR3_continue, kc);
-
-               if (r != STF_OK)
-               {
-                       return r;
-               }
-       }
-
-       /**************** done input ****************/
-
-       ISAKMP_SA_established(st->st_connection, st->st_serialno);
-
-       /* Save Phase 1 IV */
-       st->st_ph1_iv_len = st->st_new_iv_len;
-       set_ph1_iv(st, st->st_new_iv);
-
-
-       update_iv(st);      /* finalize our Phase 1 IV */
-
-       return STF_OK;
-}
-
-/* Handle first message of Phase 2 -- Quick Mode.
- * HDR*, HASH(1), SA, Ni [, KE ] [, IDci, IDcr ] -->
- * HDR*, HASH(2), SA, Nr [, KE ] [, IDci, IDcr ]
- * (see RFC 2409 "IKE" 5.5)
- * Installs inbound IPsec SAs.
- * Although this seems early, we know enough to do so, and
- * this way we know that it is soon enough to catch all
- * packets that other side could send using this IPsec SA.
- *
- * Broken into parts to allow asynchronous DNS for TXT records:
- *
- * - quick_inI1_outR1 starts the ball rolling.
- *   It checks and parses enough to learn the Phase 2 IDs
- *
- * - quick_inI1_outR1_tail does the rest of the job
- *   unless DNS must be consulted.  In that case,
- *   it starts a DNS query, salts away what is needed
- *   to continue, and suspends.  Calls
- *   + quick_inI1_outR1_start_query
- *   + quick_inI1_outR1_process_answer
- *
- * - quick_inI1_outR1_continue will restart quick_inI1_outR1_tail
- *   when DNS comes back with an answer.
- *
- * A big chunk of quick_inI1_outR1_tail is executed twice.
- * This is necessary because the set of connections
- * might change while we are awaiting DNS.
- * When first called, gateways_from_dns == NULL.  If DNS is
- * consulted asynchronously, gateways_from_dns != NULL the second time.
- * Remember that our state object might disappear too!
- *
- *
- * If the connection is opportunistic, we must verify delegation.
- *
- * 1. Check that we are authorized to be SG for
- *    our client.  We look for the TXT record that
- *    delegates us.  We also check that the public
- *    key (if present) matches the private key we used.
- *    Eventually, we should probably require DNSsec
- *    authentication for our side.
- *
- * 2. If our client TXT record did not include a
- *    public key, check the KEY record indicated
- *    by the identity in the TXT record.
- *
- * 3. If the peer's client is the peer itself, we
- *    consider it authenticated.  Otherwise, we check
- *    the TXT record for the client to see that
- *    the identity of the SG matches the peer and
- *    that some public key (if present in the TXT)
- *    matches.  We need not check the public key if
- *    it isn't in the TXT record.
- *
- * Since p isn't yet instantiated, we need to look
- * in c for description of peer.
- *
- * We cannot afford to block waiting for a DNS query.
- * The code here is structured as two halves:
- * - process the result of just completed
- *   DNS query (if any)
- * - if another query is needed, initiate the next
- *   DNS query and suspend
- */
-
-enum verify_oppo_step {
-       vos_fail,
-       vos_start,
-       vos_our_client,
-       vos_our_txt,
-#ifdef USE_KEYRR
-       vos_our_key,
-#endif /* USE_KEYRR */
-       vos_his_client,
-       vos_done
-};
-
-static const char *const verify_step_name[] = {
-  "vos_fail",
-  "vos_start",
-  "vos_our_client",
-  "vos_our_txt",
-#ifdef USE_KEYRR
-  "vos_our_key",
-#endif /* USE_KEYRR */
-  "vos_his_client",
-  "vos_done"
-};
-
-/* hold anything we can handle of a Phase 2 ID */
-struct p2id {
-       ip_subnet net;
-       u_int8_t proto;
-       u_int16_t port;
-};
-
-struct verify_oppo_bundle {
-       enum verify_oppo_step step;
-       bool failure_ok;      /* if true, quick_inI1_outR1_continue will try
-                                                  * other things on DNS failure */
-       struct msg_digest *md;
-       struct p2id my, his;
-       unsigned int new_iv_len;    /* p1st's might change */
-       u_char new_iv[MAX_DIGEST_LEN];
-       /* int whackfd; */  /* not needed because we are Responder */
-};
-
-struct verify_oppo_continuation {
-       struct adns_continuation ac;        /* common prefix */
-       struct verify_oppo_bundle b;
-};
-
-static stf_status quick_inI1_outR1_tail(struct verify_oppo_bundle *b
-       , struct adns_continuation *ac);
-
-stf_status quick_inI1_outR1(struct msg_digest *md)
-{
-       const struct state *const p1st = md->st;
-       connection_t *c = p1st->st_connection;
-       struct payload_digest *const id_pd = md->chain[ISAKMP_NEXT_ID];
-       struct verify_oppo_bundle b;
-
-       /* HASH(1) in */
-       CHECK_QUICK_HASH(md
-               , quick_mode_hash12(hash_val, hash_pbs->roof, md->message_pbs.roof
-                       , p1st, &md->hdr.isa_msgid, FALSE)
-               , "HASH(1)", "Quick I1");
-
-       /* [ IDci, IDcr ] in
-        * We do this now (probably out of physical order) because
-        * we wish to select the correct connection before we consult
-        * it for policy.
-        */
-
-       if (id_pd != NULL)
-       {
-               /* ??? we are assuming IPSEC_DOI */
-
-               /* IDci (initiator is peer) */
-
-               if (!decode_net_id(&id_pd->payload.ipsec_id, &id_pd->pbs
-               , &b.his.net, "peer client"))
-               {
-                       return STF_FAIL + ISAKMP_INVALID_ID_INFORMATION;
-               }
-
-               /* Hack for MS 818043 NAT-T Update */
-
-               if (id_pd->payload.ipsec_id.isaiid_idtype == ID_FQDN)
-               {
-                       happy(addrtosubnet(&c->spd.that.host_addr, &b.his.net));
-               }
-
-               /* End Hack for MS 818043 NAT-T Update */
-
-               b.his.proto = id_pd->payload.ipsec_id.isaiid_protoid;
-               b.his.port = id_pd->payload.ipsec_id.isaiid_port;
-               b.his.net.addr.u.v4.sin_port = htons(b.his.port);
-
-               /* IDcr (we are responder) */
-
-               if (!decode_net_id(&id_pd->next->payload.ipsec_id, &id_pd->next->pbs
-               , &b.my.net, "our client"))
-               {
-                       return STF_FAIL + ISAKMP_INVALID_ID_INFORMATION;
-               }
-               b.my.proto = id_pd->next->payload.ipsec_id.isaiid_protoid;
-               b.my.port = id_pd->next->payload.ipsec_id.isaiid_port;
-               b.my.net.addr.u.v4.sin_port = htons(b.my.port);
-       }
-       else
-       {
-               /* implicit IDci and IDcr: peer and self */
-               if (!sameaddrtype(&c->spd.this.host_addr, &c->spd.that.host_addr))
-               {
-                       return STF_FAIL;
-               }
-               happy(addrtosubnet(&c->spd.this.host_addr, &b.my.net));
-               happy(addrtosubnet(&c->spd.that.host_addr, &b.his.net));
-               b.his.proto = b.my.proto = 0;
-               b.his.port = b.my.port = 0;
-       }
-       b.step = vos_start;
-       b.md = md;
-       b.new_iv_len = p1st->st_new_iv_len;
-       memcpy(b.new_iv, p1st->st_new_iv, p1st->st_new_iv_len);
-       return quick_inI1_outR1_tail(&b, NULL);
-}
-
-#ifdef ADNS
-
-static void
-report_verify_failure(struct verify_oppo_bundle *b, err_t ugh)
-{
-       struct state *st = b->md->st;
-       char fgwb[ADDRTOT_BUF]
-               , cb[ADDRTOT_BUF];
-       ip_address client;
-       err_t which = NULL;
-
-       switch (b->step)
-       {
-       case vos_our_client:
-       case vos_our_txt:
-#ifdef USE_KEYRR
-       case vos_our_key:
-#endif /* USE_KEYRR */
-               which = "our";
-               networkof(&b->my.net, &client);
-               break;
-
-       case vos_his_client:
-               which = "his";
-               networkof(&b->his.net, &client);
-               break;
-
-       case vos_start:
-       case vos_done:
-       case vos_fail:
-       default:
-               bad_case(b->step);
-       }
-
-       addrtot(&st->st_connection->spd.that.host_addr, 0, fgwb, sizeof(fgwb));
-       addrtot(&client, 0, cb, sizeof(cb));
-       loglog(RC_OPPOFAILURE
-               , "gateway %s wants connection with %s as %s client, but DNS fails to confirm delegation: %s"
-               , fgwb, cb, which, ugh);
-}
-
-static void quick_inI1_outR1_continue(struct adns_continuation *cr, err_t ugh)
-{
-       stf_status r;
-       struct verify_oppo_continuation *vc = (void *)cr;
-       struct verify_oppo_bundle *b = &vc->b;
-       struct state *st = b->md->st;
-
-       passert(cur_state == NULL);
-       /* if st == NULL, our state has been deleted -- just clean up */
-       if (st != NULL)
-       {
-               passert(st->st_suspended_md == b->md);
-               st->st_suspended_md = NULL;     /* no longer connected or suspended */
-               cur_state = st;
-               if (!b->failure_ok && ugh != NULL)
-               {
-                       report_verify_failure(b, ugh);
-                       r = STF_FAIL + ISAKMP_INVALID_ID_INFORMATION;
-               }
-               else
-               {
-                       r = quick_inI1_outR1_tail(b, cr);
-               }
-               complete_state_transition(&b->md, r);
-       }
-       if (b->md != NULL)
-       {
-               release_md(b->md);
-       }
-       cur_state = NULL;
-}
-
-static stf_status quick_inI1_outR1_start_query(struct verify_oppo_bundle *b,
-                                                                                          enum verify_oppo_step next_step)
-{
-       struct msg_digest *md = b->md;
-       struct state *p1st = md->st;
-       connection_t *c = p1st->st_connection;
-       struct verify_oppo_continuation *vc = malloc_thing(struct verify_oppo_continuation);
-       identification_t *id;           /* subject of query */
-       identification_t *our_id;       /* needed for myid playing */
-       identification_t *our_id_space; /* ephemeral: no need for unshare_id_content */
-       ip_address client;
-       err_t ugh = NULL;
-
-       /* Record that state is used by a suspended md */
-       b->step = next_step;    /* not just vc->b.step */
-       vc->b = *b;
-       passert(p1st->st_suspended_md == NULL);
-       p1st->st_suspended_md = b->md;
-
-       DBG(DBG_CONTROL,
-               {
-                       char ours[SUBNETTOT_BUF];
-                       char his[SUBNETTOT_BUF];
-
-                       subnettot(&c->spd.this.client, 0, ours, sizeof(ours));
-                       subnettot(&c->spd.that.client, 0, his, sizeof(his));
-
-                       DBG_log("responding with DNS query - from %s to %s new state: %s"
-                                       , ours, his, verify_step_name[b->step]);
-               });
-
-       /* Resolve %myid in a cheesy way.
-        * We have to do the resolution because start_adns_query
-        * et al have insufficient information to do so.
-        * If %myid is already known, we'll use that value
-        * (XXX this may be a mistake: it could be stale).
-        * If %myid is unknown, we should check to see if
-        * there are credentials for the IP address or the FQDN.
-        * Instead, we'll just assume the IP address since we are
-        * acting as the responder and only the IP address would
-        * have gotten it to us.
-        * We don't even try to do this for the other side:
-        * %myid makes no sense for the other side (but it is syntactically
-        * legal).
-        */
-       our_id = resolve_myid(c->spd.this.id);
-       if (our_id->get_type(our_id) == ID_ANY)
-       {
-               our_id_space = identification_create_from_sockaddr((sockaddr_t*)&c->spd.this.host_addr);
-               our_id = our_id_space;
-       }
-
-       switch (next_step)
-       {
-       case vos_our_client:
-               networkof(&b->my.net, &client);
-               id = identification_create_from_sockaddr((sockaddr_t*)&client);
-               vc->b.failure_ok = b->failure_ok = FALSE;
-               ugh = start_adns_query(id
-                       , our_id
-                       , T_TXT
-                       , quick_inI1_outR1_continue
-                       , &vc->ac);
-               break;
-
-       case vos_our_txt:
-               vc->b.failure_ok = b->failure_ok = TRUE;
-               ugh = start_adns_query(our_id
-                       , our_id    /* self as SG */
-                       , T_TXT
-                       , quick_inI1_outR1_continue
-                       , &vc->ac);
-               break;
-
-#ifdef USE_KEYRR
-       case vos_our_key:
-               vc->b.failure_ok = b->failure_ok = FALSE;
-               ugh = start_adns_query(our_id
-                       , NULL
-                       , T_KEY
-                       , quick_inI1_outR1_continue
-                       , &vc->ac);
-               break;
-#endif
-
-       case vos_his_client:
-               networkof(&b->his.net, &client);
-               id = identification_create_from_sockaddr((sockaddr_t*)&client);
-               vc->b.failure_ok = b->failure_ok = FALSE;
-               ugh = start_adns_query(id
-                       , c->spd.that.id
-                       , T_TXT
-                       , quick_inI1_outR1_continue
-                       , &vc->ac);
-               break;
-
-       default:
-               bad_case(next_step);
-       }
-
-       if (ugh != NULL)
-       {
-               /* note: we'd like to use vc->b but vc has been freed
-                * so we have to use b.  This is why we plunked next_state
-                * into b, not just vc->b.
-                */
-               report_verify_failure(b, ugh);
-               p1st->st_suspended_md = NULL;
-               return STF_FAIL + ISAKMP_INVALID_ID_INFORMATION;
-       }
-       else
-       {
-               return STF_SUSPEND;
-       }
-}
-
-static enum verify_oppo_step quick_inI1_outR1_process_answer(
-                                                                               struct verify_oppo_bundle *b,
-                                                                               struct adns_continuation *ac,
-                                                                               struct state *p1st)
-{
-       connection_t *c = p1st->st_connection;
-       enum verify_oppo_step next_step = vos_our_client;
-       err_t ugh = NULL;
-
-       DBG(DBG_CONTROL,
-               {
-                       char ours[SUBNETTOT_BUF];
-                       char his[SUBNETTOT_BUF];
-
-                       subnettot(&c->spd.this.client, 0, ours, sizeof(ours));
-                       subnettot(&c->spd.that.client, 0, his, sizeof(his));
-                       DBG_log("responding on demand from %s to %s state: %s"
-                                       , ours, his, verify_step_name[b->step]);
-               });
-
-       /* process just completed DNS query (if any) */
-       switch (b->step)
-       {
-       case vos_start:
-               /* no query to digest */
-               next_step = vos_our_client;
-               break;
-
-       case vos_our_client:
-               next_step = vos_his_client;
-               {
-                       private_key_t *private = get_private_key(c);
-                       struct gw_info *gwp;
-
-                       if (private == NULL)
-                       {
-                               ugh = "we don't know our own key";
-                               break;
-                       }
-                       ugh = "our client does not delegate us as its Security Gateway";
-                       for (gwp = ac->gateways_from_dns; gwp != NULL; gwp = gwp->next)
-                       {
-                               ugh = "our client delegates us as its Security Gateway but with the wrong public key";
-                               /* If there is no key in the TXT record,
-                                * we count it as a win, but we will have
-                                * to separately fetch and check the KEY record.
-                                * If there is a key from the TXT record,
-                                * we count it as a win if we match the key.
-                                */
-                               if (!gwp->gw_key_present)
-                               {
-                                       next_step = vos_our_txt;
-                                       ugh = NULL; /* good! */
-                                       break;
-                               }
-                               else if (private->belongs_to(private, gwp->key->public_key))
-                               {
-                                       ugh = NULL; /* good! */
-                                       break;
-                               }
-                       }
-               }
-               break;
-
-       case vos_our_txt:
-               next_step = vos_his_client;
-               {
-                       private_key_t *private = get_private_key(c);
-
-                       if (private == NULL)
-                       {
-                               ugh = "we don't know our own key";
-                               break;
-                       }
-                       {
-                               struct gw_info *gwp;
-
-                               for (gwp = ac->gateways_from_dns; gwp != NULL; gwp = gwp->next)
-                               {
-#ifdef USE_KEYRR
-                                       /* not an error yet, because we have to check KEY RR as well */
-                                       ugh = NULL;
-#else
-                                       ugh = "our client delegation depends on our " RRNAME " record, but it has the wrong public key";
-#endif
-                                       if (gwp->gw_key_present
-                                       && private->belongs_to(private, gwp->key->public_key))
-                                       {
-                                               ugh = NULL;     /* good! */
-                                               break;
-                                       }
-#ifdef USE_KEYRR
-                                       next_step = vos_our_key;
-#endif
-                               }
-                       }
-               }
-               break;
-
-#ifdef USE_KEYRR
-       case vos_our_key:
-               next_step = vos_his_client;
-               {
-                       private_key_t *private = get_private_key(c);
-
-                       if (private == NULL)
-                       {
-                               ugh = "we don't know our own key";
-                               break;
-                       }
-                       {
-                               pubkey_list_t *kp;
-
-                               ugh = "our client delegation depends on our missing " RRNAME " record";
-                               for (kp = ac->keys_from_dns; kp != NULL; kp = kp->next)
-                               {
-                                       ugh = "our client delegation depends on our " RRNAME " record, but it has the wrong public key";
-                                       if (private->belongs_to(private, kp->key->public_key))
-                                       {
-                                               /* do this only once a day */
-                                               if (!logged_txt_warning)
-                                               {
-                                                       loglog(RC_LOG_SERIOUS, "found KEY RR but not TXT RR. See http://www.freeswan.org/err/txt-change.html.");
-                                                       logged_txt_warning = TRUE;
-                                               }
-                                               ugh = NULL;     /* good! */
-                                               break;
-                                       }
-                               }
-                       }
-               }
-               break;
-#endif /* USE_KEYRR */
-
-       case vos_his_client:
-               next_step = vos_done;
-               {
-                       public_key_t *pub_key;
-                       struct gw_info *gwp;
-
-                       /* check that the public key that authenticated
-                        * the ISAKMP SA (p1st) will do for this gateway.
-                        */
-                       pub_key = p1st->st_peer_pubkey->public_key;
-
-                       ugh = "peer's client does not delegate to peer";
-                       for (gwp = ac->gateways_from_dns; gwp != NULL; gwp = gwp->next)
-                       {
-                               ugh = "peer and its client disagree about public key";
-                               /* If there is a key from the TXT record,
-                                * we count it as a win if we match the key.
-                                * If there was no key, we claim a match since
-                                * it implies fetching a KEY from the same
-                                * place we must have gotten it.
-                                */
-                               if (!gwp->gw_key_present ||
-                                       pub_key->equals(pub_key, gwp->key->public_key))
-                               {
-                                       ugh = NULL; /* good! */
-                                       break;
-                               }
-                       }
-               }
-               break;
-
-       default:
-               bad_case(b->step);
-       }
-
-       if (ugh != NULL)
-       {
-               report_verify_failure(b, ugh);
-               next_step = vos_fail;
-       }
-       return next_step;
-}
-
-#endif /* ADNS */
-
-static stf_status quick_inI1_outR1_tail(struct verify_oppo_bundle *b,
-                                                                               struct adns_continuation *ac)
-{
-       struct msg_digest *md = b->md;
-       struct state *const p1st = md->st;
-       connection_t *c = p1st->st_connection;
-       struct payload_digest *const id_pd = md->chain[ISAKMP_NEXT_ID];
-       ip_subnet *our_net = &b->my.net
-               , *his_net = &b->his.net;
-
-       u_char      /* set by START_HASH_PAYLOAD: */
-               *r_hashval,     /* where in reply to jam hash value */
-               *r_hash_start;  /* from where to start hashing */
-
-       /* Now that we have identities of client subnets, we must look for
-        * a suitable connection (our current one only matches for hosts).
-        */
-       {
-               connection_t *p = find_client_connection(c
-                       , our_net, his_net, b->my.proto, b->my.port, b->his.proto, b->his.port);
-
-               if (p == NULL)
-               {
-                       /* This message occurs in very puzzling circumstances
-                        * so we must add as much information and beauty as we can.
-                        */
-                       struct end
-                               me = c->spd.this,
-                               he = c->spd.that;
-                       char buf[2*SUBNETTOT_BUF + 2*ADDRTOT_BUF + 2*BUF_LEN + 2*ADDRTOT_BUF + 12]; /* + 12 for separating */
-                       size_t l;
-
-                       me.client = *our_net;
-                       me.has_client = !subnetisaddr(our_net, &me.host_addr);
-                       me.protocol = b->my.proto;
-                       me.port = b->my.port;
-
-                       he.client = *his_net;
-                       he.has_client = !subnetisaddr(his_net, &he.host_addr);
-                       he.protocol = b->his.proto;
-                       he.port = b->his.port;
-
-                       l = format_end(buf, sizeof(buf), &me, NULL, TRUE, LEMPTY);
-                       l += snprintf(buf + l, sizeof(buf) - l, "...");
-                       (void)format_end(buf + l, sizeof(buf) - l, &he, NULL, FALSE, LEMPTY);
-                       plog("cannot respond to IPsec SA request"
-                               " because no connection is known for %s"
-                               , buf);
-                       return STF_FAIL + ISAKMP_INVALID_ID_INFORMATION;
-               }
-               else if (p != c)
-               {
-                       /* We've got a better connection: it can support the
-                        * specified clients.  But it may need instantiation.
-                        */
-                       if (p->kind == CK_TEMPLATE)
-                       {
-                               /* Yup, it needs instantiation.  How much?
-                                * Is it a Road Warrior connection (simple)
-                                * or is it an Opportunistic connection (needing gw validation)?
-                                */
-                               if (p->policy & POLICY_OPPO)
-                               {
-#ifdef ADNS
-                                       /* Opportunistic case: delegation must be verified.
-                                        * Here be dragons.
-                                        */
-                                       enum verify_oppo_step next_step;
-                                       ip_address our_client, his_client;
-
-                                       passert(subnetishost(our_net) && subnetishost(his_net));
-                                       networkof(our_net, &our_client);
-                                       networkof(his_net, &his_client);
-
-                                       next_step = quick_inI1_outR1_process_answer(b, ac, p1st);
-                                       if (next_step == vos_fail)
-                                       {
-                                               return STF_FAIL + ISAKMP_INVALID_ID_INFORMATION;
-                                       }
-
-                                       /* short circuit: if peer's client is self,
-                                        * accept that we've verified delegation in Phase 1
-                                        */
-                                       if (next_step == vos_his_client
-                                       && sameaddr(&c->spd.that.host_addr, &his_client))
-                                       {
-                                               next_step = vos_done;
-                                       }
-
-                                       /* the second chunk: initiate the next DNS query (if any) */
-                                       DBG(DBG_CONTROL,
-                                               {
-                                                       char ours[SUBNETTOT_BUF];
-                                                       char his[SUBNETTOT_BUF];
-
-                                                       subnettot(&c->spd.this.client, 0, ours, sizeof(ours));
-                                                       subnettot(&c->spd.that.client, 0, his, sizeof(his));
-
-                                                       DBG_log("responding on demand from %s to %s new state: %s"
-                                                                       , ours, his, verify_step_name[next_step]);
-                                               });
-
-                                       /* start next DNS query and suspend (if necessary) */
-                                       if (next_step != vos_done)
-                                       {
-                                               return quick_inI1_outR1_start_query(b, next_step);
-                                       }
-
-                                       /* Instantiate inbound Opportunistic connection,
-                                        * carrying over authenticated peer ID
-                                        * and filling in a few more details.
-                                        * We used to include gateways_from_dns, but that
-                                        * seems pointless at this stage of negotiation.
-                                        * We should record DNS sec use, if any -- belongs in
-                                        * state during perhaps.
-                                        */
-                                       p = oppo_instantiate(p, &c->spd.that.host_addr, c->spd.that.id
-                                               , NULL, &our_client, &his_client);
-#else /* ADNS */
-                                       plog("opportunistic connections not supported because"
-                                                " adns is not available");
-                                       return STF_INTERNAL_ERROR;
-#endif /* ADNS */
-                               }
-                               else
-                               {
-                                       /* Plain Road Warrior:
-                                        * instantiate, carrying over authenticated peer ID
-                                        */
-                                       host_t *vip = c->spd.that.host_srcip;
-
-                                       p = rw_instantiate(p, &c->spd.that.host_addr, md->sender_port
-                                                               , his_net, c->spd.that.id);
-
-                                       /* inherit any virtual IP assigned by a Mode Config exchange */
-                                       if (p->spd.that.modecfg && c->spd.that.modecfg &&
-                                               subnetisaddr(his_net, (ip_address*)vip->get_sockaddr(vip)))
-                                       {
-                                               DBG(DBG_CONTROL,
-                                                       DBG_log("inheriting virtual IP source address %H from ModeCfg", vip)
-                                               )
-                                               p->spd.that.host_srcip->destroy(p->spd.that.host_srcip);
-                                               p->spd.that.host_srcip = vip->clone(vip);
-                                               p->spd.that.client = c->spd.that.client;
-                                               p->spd.that.has_client = TRUE;
-                                       }
-
-                                       if (c->policy & (POLICY_XAUTH_RSASIG | POLICY_XAUTH_PSK) &&
-                                               c->xauth_identity && !p->xauth_identity)
-                                       {
-                                               DBG(DBG_CONTROL,
-                                                       DBG_log("inheriting XAUTH identity %Y", c->xauth_identity)
-                                               )
-                                               p->xauth_identity = c->xauth_identity->clone(c->xauth_identity);
-                                       }
-                               }
-                       }
-#ifdef DEBUG
-                       /* temporarily bump up cur_debugging to get "using..." message
-                        * printed if we'd want it with new connection.
-                        */
-                       {
-                               lset_t old_cur_debugging = cur_debugging;
-
-                               cur_debugging |= p->extra_debugging;
-                               DBG(DBG_CONTROL, DBG_log("using connection \"%s\"", p->name));
-                               cur_debugging = old_cur_debugging;
-                       }
-#endif
-                       c = p;
-               }
-               /* fill in the client's true ip address/subnet */
-               if (p->spd.that.has_client_wildcard)
-               {
-                       p->spd.that.client = *his_net;
-                       p->spd.that.has_client_wildcard = FALSE;
-               }
-               else if (is_virtual_connection(c))
-               {
-                       c->spd.that.client = *his_net;
-                       c->spd.that.virt = NULL;
-                       if (subnetishost(his_net) && addrinsubnet(&c->spd.that.host_addr, his_net))
-                       {
-                               c->spd.that.has_client = FALSE;
-                       }
-               }
-
-               /* fill in the client's true port */
-               if (p->spd.that.has_port_wildcard)
-               {
-                       int port = htons(b->his.port);
-
-                       setportof(port, &p->spd.that.host_addr);
-                       setportof(port, &p->spd.that.client.addr);
-
-                       p->spd.that.port = b->his.port;
-                       p->spd.that.has_port_wildcard = FALSE;
-               }
-       }
-
-       /* now that we are sure of our connection, create our new state */
-       {
-               enum endpoint ep = EP_LOCAL;
-               struct state *const st = duplicate_state(p1st);
-
-               /* first: fill in missing bits of our new state object
-                * note: we don't copy over st_peer_pubkey, the public key
-                * that authenticated the ISAKMP SA.  We only need it in this
-                * routine, so we can "reach back" to p1st to get it.
-                */
-
-               if (st->st_connection != c)
-               {
-                       connection_t *t = st->st_connection;
-
-                       st->st_connection = c;
-                       set_cur_connection(c);
-                       connection_discard(t);
-               }
-
-               st->st_try = 0; /* not our job to try again from start */
-
-               st->st_msgid = md->hdr.isa_msgid;
-
-               st->st_new_iv_len = b->new_iv_len;
-               memcpy(st->st_new_iv, b->new_iv, b->new_iv_len);
-
-               set_cur_state(st);      /* (caller will reset) */
-               md->st = st;    /* feed back new state */
-
-               st->st_peeruserprotoid = b->his.proto;
-               st->st_peeruserport = b->his.port;
-               st->st_myuserprotoid = b->my.proto;
-               st->st_myuserport = b->my.port;
-
-               insert_state(st);       /* needs cookies, connection, and msgid */
-
-               /* copy the connection's
-                * IPSEC policy into our state.  The ISAKMP policy is water under
-                * the bridge, I think.  It will reflect the ISAKMP SA that we
-                * are using.
-                */
-               st->st_policy = (p1st->st_policy & POLICY_ISAKMP_MASK)
-                       | (c->policy & ~POLICY_ISAKMP_MASK);
-
-               if (p1st->nat_traversal & NAT_T_DETECTED)
-               {
-                       st->nat_traversal = p1st->nat_traversal;
-                       nat_traversal_change_port_lookup(md, md->st);
-               }
-               else
-               {
-                       st->nat_traversal = 0;
-               }
-               if ((st->nat_traversal & NAT_T_DETECTED)
-               &&  (st->nat_traversal & NAT_T_WITH_NATOA))
-               {
-                       nat_traversal_natoa_lookup(md);
-               }
-
-               /* Start the output packet.
-                *
-                * proccess_packet() would automatically generate the HDR*
-                * payload if smc->first_out_payload is not ISAKMP_NEXT_NONE.
-                * We don't do this because we wish there to be no partially
-                * built output packet if we need to suspend for asynch DNS.
-                *
-                * We build the reply packet as we parse the message since
-                * the parse_ipsec_sa_body emits the reply SA
-                */
-
-               /* HDR* out */
-               echo_hdr(md, TRUE, ISAKMP_NEXT_HASH);
-
-               /* HASH(2) out -- first pass */
-               START_HASH_PAYLOAD(md->rbody, ISAKMP_NEXT_SA);
-
-               /* process SA (in and out) */
-               {
-                       struct payload_digest *const sapd = md->chain[ISAKMP_NEXT_SA];
-                       pb_stream r_sa_pbs;
-                       struct isakmp_sa sa = sapd->payload.sa;
-
-                       /* sa header is unchanged -- except for np */
-                       sa.isasa_np = ISAKMP_NEXT_NONCE;
-                       if (!out_struct(&sa, &isakmp_sa_desc, &md->rbody, &r_sa_pbs))
-                       {
-                               return STF_INTERNAL_ERROR;
-                       }
-
-                       /* parse and accept body */
-                       st->st_pfs_group = &unset_group;
-                       RETURN_STF_FAILURE(parse_ipsec_sa_body(&sapd->pbs
-                                       , &sapd->payload.sa, &r_sa_pbs, FALSE, st));
-               }
-
-               passert(st->st_pfs_group != &unset_group);
-
-               if ((st->st_policy & POLICY_PFS) && st->st_pfs_group == NULL)
-               {
-                       loglog(RC_LOG_SERIOUS, "we require PFS but Quick I1 SA specifies no GROUP_DESCRIPTION");
-                       return STF_FAIL + ISAKMP_NO_PROPOSAL_CHOSEN;
-               }
-
-               /* Ni in */
-               RETURN_STF_FAILURE(accept_nonce(md, &st->st_ni, "Ni"));
-
-               /* [ KE ] in (for PFS) */
-               RETURN_STF_FAILURE(accept_PFS_KE(md, &st->st_gi, "Gi", "Quick Mode I1"));
-
-               plog("responding to Quick Mode");
-
-               /**** finish reply packet: Nr [, KE ] [, IDci, IDcr ] ****/
-
-               /* Nr out */
-               if (!build_and_ship_nonce(&st->st_nr, &md->rbody
-               , st->st_pfs_group != NULL? ISAKMP_NEXT_KE : id_pd != NULL? ISAKMP_NEXT_ID : ISAKMP_NEXT_NONE
-               , "Nr"))
-                {
-                       return STF_INTERNAL_ERROR;
-               }
-
-               /* [ KE ] out (for PFS) */
-
-               if (st->st_pfs_group != NULL)
-               {
-                       if (!build_and_ship_KE(st, &st->st_gr, st->st_pfs_group
-                       , &md->rbody, id_pd != NULL? ISAKMP_NEXT_ID : ISAKMP_NEXT_NONE))
-                       {
-                               return STF_INTERNAL_ERROR;
-                       }
-
-                       /* MPZ-Operations might be done after sending the packet... */
-                       compute_dh_shared(st, st->st_gi);
-               }
-
-               /* [ IDci, IDcr ] out */
-               if  (id_pd != NULL)
-               {
-                       struct isakmp_ipsec_id *p = (void *)md->rbody.cur;  /* UGH! */
-
-                       if (!out_raw(id_pd->pbs.start, pbs_room(&id_pd->pbs), &md->rbody, "IDci"))
-                       {
-                               return STF_INTERNAL_ERROR;
-                       }
-                       p->isaiid_np = ISAKMP_NEXT_ID;
-
-                       p = (void *)md->rbody.cur;  /* UGH! */
-
-                       if (!out_raw(id_pd->next->pbs.start, pbs_room(&id_pd->next->pbs), &md->rbody, "IDcr"))
-                       {
-                               return STF_INTERNAL_ERROR;
-                       }
-                       p->isaiid_np = ISAKMP_NEXT_NONE;
-               }
-
-               if ((st->nat_traversal & NAT_T_WITH_NATOA)
-               && (st->nat_traversal & LELEM(NAT_TRAVERSAL_NAT_BHND_ME))
-               && (st->st_esp.attrs.encapsulation == ENCAPSULATION_MODE_TRANSPORT))
-               {
-                       /** Send NAT-OA if our address is NATed and if we use Transport Mode */
-                       if (!nat_traversal_add_natoa(ISAKMP_NEXT_NONE, &md->rbody, md->st))
-                       {
-                               return STF_INTERNAL_ERROR;
-                       }
-               }
-               if ((st->nat_traversal & NAT_T_DETECTED)
-               && (st->st_esp.attrs.encapsulation == ENCAPSULATION_MODE_TRANSPORT)
-               && (c->spd.that.has_client))
-               {
-                       /** Remove client **/
-                       addrtosubnet(&c->spd.that.host_addr, &c->spd.that.client);
-                       c->spd.that.has_client = FALSE;
-               }
-
-               /* Compute reply HASH(2) and insert in output */
-               (void)quick_mode_hash12(r_hashval, r_hash_start, md->rbody.cur
-                       , st, &st->st_msgid, TRUE);
-
-               /* Derive new keying material */
-               compute_keymats(st, ep);
-
-               /* Tell the kernel to establish the new inbound SA
-                * (unless the commit bit is set -- which we don't support).
-                * We do this before any state updating so that
-                * failure won't look like success.
-                */
-               if (!install_inbound_ipsec_sa(st))
-               {
-                       wipe_keymats(st, ep);
-                       return STF_INTERNAL_ERROR;  /* ??? we may be partly committed */
-               }
-               wipe_keymats(st, ep);
-
-               /* encrypt message, except for fixed part of header */
-
-               if (!encrypt_message(&md->rbody, st))
-               {
-                       return STF_INTERNAL_ERROR;  /* ??? we may be partly committed */
-               }
-
-               return STF_OK;
-       }
-}
-
-/*
- * Initialize RFC 3706 Dead Peer Detection
- */
-static void dpd_init(struct state *st)
-{
-       struct state *p1st = find_state(st->st_icookie, st->st_rcookie
-                                                               , &st->st_connection->spd.that.host_addr, 0);
-
-       if (p1st == NULL)
-       {
-               loglog(RC_LOG_SERIOUS, "could not find phase 1 state for DPD");
-       }
-       else if (p1st->st_dpd)
-       {
-               plog("Dead Peer Detection (RFC 3706) enabled");
-               /* randomize the first DPD event */
-
-               event_schedule(EVENT_DPD
-                       , (0.5 + rand()/(RAND_MAX + 1.E0)) * st->st_connection->dpd_delay
-                       , st);
-       }
-}
-
-/* Handle (the single) message from Responder in Quick Mode.
- * HDR*, HASH(2), SA, Nr [, KE ] [, IDci, IDcr ] -->
- * HDR*, HASH(3)
- * (see RFC 2409 "IKE" 5.5)
- * Installs inbound and outbound IPsec SAs, routing, etc.
- */
-stf_status quick_inR1_outI2(struct msg_digest *md)
-{
-       enum endpoint ep = EP_LOCAL | EP_REMOTE;
-       struct state *const st = md->st;
-       const connection_t *c = st->st_connection;
-
-       /* HASH(2) in */
-       CHECK_QUICK_HASH(md
-               , quick_mode_hash12(hash_val, hash_pbs->roof, md->message_pbs.roof
-                       , st, &st->st_msgid, TRUE)
-               , "HASH(2)", "Quick R1");
-
-       /* SA in */
-       {
-               struct payload_digest *const sa_pd = md->chain[ISAKMP_NEXT_SA];
-
-               RETURN_STF_FAILURE(parse_ipsec_sa_body(&sa_pd->pbs
-                       , &sa_pd->payload.sa, NULL, TRUE, st));
-       }
-
-       /* Nr in */
-       RETURN_STF_FAILURE(accept_nonce(md, &st->st_nr, "Nr"));
-
-       /* [ KE ] in (for PFS) */
-       RETURN_STF_FAILURE(accept_PFS_KE(md, &st->st_gr, "Gr", "Quick Mode R1"));
-
-       if (st->st_pfs_group != NULL)
-       {
-               compute_dh_shared(st, st->st_gr);
-       }
-
-       /* [ IDci, IDcr ] in; these must match what we sent */
-
-       {
-               struct payload_digest *const id_pd = md->chain[ISAKMP_NEXT_ID];
-
-               if (id_pd != NULL)
-               {
-                       /* ??? we are assuming IPSEC_DOI */
-
-                       /* IDci (we are initiator) */
-
-                       if (!check_net_id(&id_pd->payload.ipsec_id, &id_pd->pbs
-                       , &st->st_myuserprotoid, &st->st_myuserport
-                       , &st->st_connection->spd.this.client
-                       , "our client"))
-                       {
-                               return STF_FAIL + ISAKMP_INVALID_ID_INFORMATION;
-                       }
-
-                       /* IDcr (responder is peer) */
-
-                       if (!check_net_id(&id_pd->next->payload.ipsec_id, &id_pd->next->pbs
-                       , &st->st_peeruserprotoid, &st->st_peeruserport
-                       , &st->st_connection->spd.that.client
-                       , "peer client"))
-                       {
-                               return STF_FAIL + ISAKMP_INVALID_ID_INFORMATION;
-                       }
-               }
-               else
-               {
-                       /* no IDci, IDcr: we must check that the defaults match our proposal */
-                       if (!subnetisaddr(&c->spd.this.client, &c->spd.this.host_addr)
-                       || !subnetisaddr(&c->spd.that.client, &c->spd.that.host_addr))
-                       {
-                               loglog(RC_LOG_SERIOUS, "IDci, IDcr payloads missing in message"
-                                       " but default does not match proposal");
-                               return STF_FAIL + ISAKMP_INVALID_ID_INFORMATION;
-                       }
-               }
-       }
-
-       /* check the peer's group attributes */
-       {
-               identification_t *peer_ca = NULL;
-               ietf_attributes_t *peer_attributes = NULL;
-               bool match;
-
-               get_peer_ca_and_groups(st->st_connection, &peer_ca, &peer_attributes);
-               match = match_group_membership(peer_attributes,
-                                                                          st->st_connection->name,
-                                                                          st->st_connection->spd.that.groups);
-               DESTROY_IF(peer_attributes);
-
-               if (!match)
-               {
-                       ietf_attributes_t *groups = st->st_connection->spd.that.groups;
-
-                       loglog(RC_LOG_SERIOUS,
-                                  "peer with attributes '%s' is not a member of the groups '%s'",
-                                       peer_attributes->get_string(peer_attributes),
-                                       groups->get_string(groups));
-                       return STF_FAIL + ISAKMP_INVALID_ID_INFORMATION;
-               }
-       }
-
-       if ((st->nat_traversal & NAT_T_DETECTED)
-       &&  (st->nat_traversal & NAT_T_WITH_NATOA))
-       {
-               nat_traversal_natoa_lookup(md);
-       }
-
-       /* ??? We used to copy the accepted proposal into the state, but it was
-        * never used.  From sa_pd->pbs.start, length pbs_room(&sa_pd->pbs).
-        */
-
-       /**************** build reply packet HDR*, HASH(3) ****************/
-
-       /* HDR* out done */
-
-       /* HASH(3) out -- since this is the only content, no passes needed */
-       {
-               u_char  /* set by START_HASH_PAYLOAD: */
-                       *r_hashval, /* where in reply to jam hash value */
-                       *r_hash_start;      /* start of what is to be hashed */
-
-               START_HASH_PAYLOAD(md->rbody, ISAKMP_NEXT_NONE);
-               (void)quick_mode_hash3(r_hashval, st);
-       }
-
-       /* Derive new keying material */
-       compute_keymats(st, ep);
-
-       /* Tell the kernel to establish the inbound, outbound, and routing part
-        * of the new SA (unless the commit bit is set -- which we don't support).
-        * We do this before any state updating so that
-        * failure won't look like success.
-        */
-       if (!install_ipsec_sa(st, TRUE))
-       {
-               wipe_keymats(st, ep);
-               return STF_INTERNAL_ERROR;
-       }
-       wipe_keymats(st, ep);
-
-       /* encrypt message, except for fixed part of header */
-
-       if (!encrypt_message(&md->rbody, st))
-       {
-               return STF_INTERNAL_ERROR;      /* ??? we may be partly committed */
-       }
-       DBG(DBG_CONTROLMORE,
-               DBG_log("inR1_outI2: instance %s[%ld], setting newest_ipsec_sa to #%ld (was #%ld) (spd.eroute=#%ld)"
-                                                          , st->st_connection->name
-                                                          , st->st_connection->instance_serial
-                                                          , st->st_serialno
-                                                          , st->st_connection->newest_ipsec_sa
-                                                          , st->st_connection->spd.eroute_owner)
-       )
-       st->st_connection->newest_ipsec_sa = st->st_serialno;
-
-       /* note (presumed) success */
-       if (c->gw_info != NULL)
-       {
-               c->gw_info->key->last_worked_time = now();
-       }
-
-       /* If we want DPD on this connection then initialize it */
-       if (st->st_connection->dpd_action != DPD_ACTION_NONE)
-       {
-               dpd_init(st);
-       }
-       return STF_OK;
-}
-
-/* Handle last message of Quick Mode.
- * HDR*, HASH(3) -> done
- * (see RFC 2409 "IKE" 5.5)
- * Installs outbound IPsec SAs, routing, etc.
- */
-stf_status quick_inI2(struct msg_digest *md)
-{
-       enum endpoint ep = EP_REMOTE;
-       struct state *const st = md->st;
-
-       /* HASH(3) in */
-       CHECK_QUICK_HASH(md, quick_mode_hash3(hash_val, st)
-               , "HASH(3)", "Quick I2");
-
-       /* Derive keying material */
-       compute_keymats(st, ep);
-
-       /* Tell the kernel to establish the outbound and routing part of the new SA
-        * (the previous state established inbound)
-        * (unless the commit bit is set -- which we don't support).
-        * We do this before any state updating so that
-        * failure won't look like success.
-        */
-       if (!install_ipsec_sa(st, FALSE))
-       {
-               wipe_keymats(st, ep);
-               return STF_INTERNAL_ERROR;
-       }
-       wipe_keymats(st, ep);
-
-       DBG(DBG_CONTROLMORE,
-               DBG_log("inI2: instance %s[%ld], setting newest_ipsec_sa to #%ld (was #%ld) (spd.eroute=#%ld)"
-                                                          , st->st_connection->name
-                                                          , st->st_connection->instance_serial
-                                                          , st->st_serialno
-                                                          , st->st_connection->newest_ipsec_sa
-                                                          , st->st_connection->spd.eroute_owner)
-       )
-       st->st_connection->newest_ipsec_sa = st->st_serialno;
-
-       update_iv(st);      /* not actually used, but tidy */
-
-       /* note (presumed) success */
-       {
-               struct gw_info *gw = st->st_connection->gw_info;
-
-               if (gw != NULL)
-               {
-                       gw->key->last_worked_time = now();
-               }
-       }
-
-       /* If we want DPD on this connection then initialize it */
-       if (st->st_connection->dpd_action != DPD_ACTION_NONE)
-       {
-               dpd_init(st);
-       }
-       return STF_OK;
-}
-
-static stf_status send_isakmp_notification(struct state *st, u_int16_t type,
-                                                                                  const void *data, size_t len)
-{
-       msgid_t msgid;
-       pb_stream reply;
-       pb_stream rbody;
-       u_char
-               *r_hashval,     /* where in reply to jam hash value */
-               *r_hash_start;  /* start of what is to be hashed */
-
-       msgid = generate_msgid(st);
-
-       init_pbs(&reply, reply_buffer, sizeof(reply_buffer), "ISAKMP notify");
-
-       /* HDR* */
-       {
-               struct isakmp_hdr hdr;
-
-               hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION;
-               hdr.isa_np = ISAKMP_NEXT_HASH;
-               hdr.isa_xchg = ISAKMP_XCHG_INFO;
-               hdr.isa_msgid = msgid;
-               hdr.isa_flags = ISAKMP_FLAG_ENCRYPTION;
-               memcpy(hdr.isa_icookie, st->st_icookie, COOKIE_SIZE);
-               memcpy(hdr.isa_rcookie, st->st_rcookie, COOKIE_SIZE);
-               if (!out_struct(&hdr, &isakmp_hdr_desc, &reply, &rbody))
-               {
-                       impossible();
-               }
-       }
-       /* HASH -- create and note space to be filled later */
-       START_HASH_PAYLOAD(rbody, ISAKMP_NEXT_N);
-
-       /* NOTIFY */
-       {
-               pb_stream notify_pbs;
-               struct isakmp_notification isan;
-
-               isan.isan_np = ISAKMP_NEXT_NONE;
-               isan.isan_doi = ISAKMP_DOI_IPSEC;
-               isan.isan_protoid = PROTO_ISAKMP;
-               isan.isan_spisize = COOKIE_SIZE * 2;
-               isan.isan_type = type;
-               if (!out_struct(&isan, &isakmp_notification_desc, &rbody, &notify_pbs))
-               {
-                       return STF_INTERNAL_ERROR;
-               }
-               if (!out_raw(st->st_icookie, COOKIE_SIZE, &notify_pbs, "notify icookie"))
-               {
-                       return STF_INTERNAL_ERROR;
-               }
-               if (!out_raw(st->st_rcookie, COOKIE_SIZE, &notify_pbs, "notify rcookie"))
-               {
-                       return STF_INTERNAL_ERROR;
-               }
-               if (data != NULL && len > 0)
-               {
-                       if (!out_raw(data, len, &notify_pbs, "notify data"))
-                       {
-                               return STF_INTERNAL_ERROR;
-                       }
-               }
-               close_output_pbs(&notify_pbs);
-       }
-
-       {
-               /* finish computing HASH */
-               chunk_t msgid_chunk = chunk_from_thing(msgid);
-               chunk_t msg_chunk = { r_hash_start, rbody.cur-r_hash_start };
-               pseudo_random_function_t prf_alg;
-               prf_t *prf;
-
-               prf_alg = oakley_to_prf(st->st_oakley.hash);
-               prf = lib->crypto->create_prf(lib->crypto, prf_alg);
-               prf->set_key(prf, st->st_skeyid_a);
-               prf->get_bytes(prf, msgid_chunk, NULL);
-               prf->get_bytes(prf, msg_chunk, r_hashval);
-
-               DBG(DBG_CRYPT,
-                       DBG_log("HASH computed:");
-                       DBG_dump("", r_hashval, prf->get_block_size(prf));
-               )
-               prf->destroy(prf);
-       }
-
-       /* Encrypt message (preserve st_iv and st_new_iv) */
-       {
-               u_char old_iv[MAX_DIGEST_LEN];
-               u_char new_iv[MAX_DIGEST_LEN];
-
-               u_int old_iv_len = st->st_iv_len;
-               u_int new_iv_len = st->st_new_iv_len;
-
-               if (old_iv_len > MAX_DIGEST_LEN || new_iv_len > MAX_DIGEST_LEN)
-                       return STF_INTERNAL_ERROR;
-
-               memcpy(old_iv, st->st_iv, old_iv_len);
-               memcpy(new_iv, st->st_new_iv, new_iv_len);
-
-               init_phase2_iv(st, &msgid);
-               if (!encrypt_message(&rbody, st))
-               {
-                       return STF_INTERNAL_ERROR;
-               }
-
-               /* restore preserved st_iv and st_new_iv */
-               memcpy(st->st_iv, old_iv, old_iv_len);
-               memcpy(st->st_new_iv, new_iv, new_iv_len);
-               st->st_iv_len = old_iv_len;
-               st->st_new_iv_len = new_iv_len;
-       }
-
-       /* Send packet (preserve st_tpacket) */
-       {
-               chunk_t saved_tpacket = st->st_tpacket;
-
-               st->st_tpacket = chunk_create(reply.start, pbs_offset(&reply));
-               send_packet(st, "ISAKMP notify");
-               st->st_tpacket = saved_tpacket;
-       }
-
-       return STF_IGNORE;
-}
-
-/*
- * DPD Out Initiator
- */
-void dpd_outI(struct state *p2st)
-{
-       struct state *st;
-       u_int32_t seqno;
-       time_t tm;
-       time_t idle_time;
-       time_t delay = p2st->st_connection->dpd_delay;
-       time_t timeout = p2st->st_connection->dpd_timeout;
-
-       /* find the newest related Phase 1 state */
-       st = find_phase1_state(p2st->st_connection, ISAKMP_SA_ESTABLISHED_STATES);
-
-       if (st == NULL)
-       {
-               loglog(RC_LOG_SERIOUS, "DPD: Could not find newest phase 1 state");
-               return;
-       }
-
-       /* If no DPD, then get out of here */
-       if (!st->st_dpd)
-       {
-               return;
-       }
-
-       /* schedule the next periodic DPD event */
-       event_schedule(EVENT_DPD, delay, p2st);
-
-       /* Current time */
-       tm = now();
-
-       /* Make sure we really need to invoke DPD */
-       if (!was_eroute_idle(p2st, delay, &idle_time))
-       {
-               DBG(DBG_CONTROL,
-                       DBG_log("recent eroute activity %u seconds ago, "
-                                       "no need to send DPD notification"
-                                 , (int)idle_time)
-               )
-               st->st_last_dpd = tm;
-               delete_dpd_event(st);
-               return;
-       }
-
-       /* If an R_U_THERE has been sent or received recently, or if a
-        * companion Phase 2 SA has shown eroute activity,
-        * then we don't need to invoke DPD.
-        */
-       if (tm < st->st_last_dpd + delay)
-       {
-               DBG(DBG_CONTROL,
-                       DBG_log("recent DPD activity %u seconds ago, "
-                                       "no need to send DPD notification"
-                                 , (int)(tm - st->st_last_dpd))
-               )
-               return;
-       }
-
-       if (!IS_ISAKMP_SA_ESTABLISHED(st->st_state))
-               return;
-
-       if (!st->st_dpd_seqno)
-       {
-               rng_t *rng;
-
-               /* Get a non-zero random value that has room to grow */
-               rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
-               rng->get_bytes(rng, sizeof(st->st_dpd_seqno), (u_char *)&st->st_dpd_seqno);
-               rng->destroy(rng);
-               st->st_dpd_seqno &= 0x7fff;
-               st->st_dpd_seqno++;
-       }
-       seqno = htonl(st->st_dpd_seqno);
-
-       if (send_isakmp_notification(st, R_U_THERE, &seqno, sizeof(seqno)) != STF_IGNORE)
-       {
-               loglog(RC_LOG_SERIOUS, "DPD: Could not send R_U_THERE");
-               return;
-       }
-       DBG(DBG_CONTROL,
-               DBG_log("sent DPD notification R_U_THERE with seqno = %u", st->st_dpd_seqno)
-       )
-       st->st_dpd_expectseqno = st->st_dpd_seqno++;
-       st->st_last_dpd = tm;
-       /* Only schedule a new timeout if there isn't one currently,
-        * or if it would be sooner than the current timeout. */
-       if (st->st_dpd_event == NULL
-       || st->st_dpd_event->ev_time > tm + timeout)
-       {
-               delete_dpd_event(st);
-               event_schedule(EVENT_DPD_TIMEOUT, timeout, st);
-       }
-}
-
-/*
- * DPD in Initiator, out Responder
- */
-stf_status
-dpd_inI_outR(struct state *st, struct isakmp_notification *const n, pb_stream *pbs)
-{
-   time_t tm = now();
-       u_int32_t seqno;
-
-       if (st == NULL || !IS_ISAKMP_SA_ESTABLISHED(st->st_state))
-       {
-               loglog(RC_LOG_SERIOUS, "DPD: Received R_U_THERE for unestablished ISAKMP SA");
-               return STF_IGNORE;
-       }
-       if (n->isan_spisize != COOKIE_SIZE * 2 || pbs_left(pbs) < COOKIE_SIZE * 2)
-       {
-               loglog(RC_LOG_SERIOUS, "DPD: R_U_THERE has invalid SPI length (%d)", n->isan_spisize);
-               return STF_FAIL + ISAKMP_PAYLOAD_MALFORMED;
-       }
-
-       if (memcmp(pbs->cur, st->st_icookie, COOKIE_SIZE) != 0)
-       {
-#ifdef APPLY_CRISCO
-               /* Ignore it, cisco sends odd icookies */
-#else
-               loglog(RC_LOG_SERIOUS, "DPD: R_U_THERE has invalid icookie (broken Cisco?)");
-               return STF_FAIL + ISAKMP_INVALID_COOKIE;
-#endif
-       }
-       pbs->cur += COOKIE_SIZE;
-
-       if (memcmp(pbs->cur, st->st_rcookie, COOKIE_SIZE) != 0)
-       {
-               loglog(RC_LOG_SERIOUS, "DPD: R_U_THERE has invalid rcookie (broken Cisco?)");
-               return STF_FAIL + ISAKMP_INVALID_COOKIE;
-       }
-       pbs->cur += COOKIE_SIZE;
-
-       if (pbs_left(pbs) != sizeof(seqno))
-       {
-               loglog(RC_LOG_SERIOUS, "DPD: R_U_THERE has invalid data length (%d)"
-                       , (int) pbs_left(pbs));
-               return STF_FAIL + ISAKMP_PAYLOAD_MALFORMED;
-       }
-
-       seqno = ntohl(*(u_int32_t *)pbs->cur);
-       DBG(DBG_CONTROL,
-               DBG_log("received DPD notification R_U_THERE with seqno = %u", seqno)
-       )
-
-       if (st->st_dpd_peerseqno && seqno <= st->st_dpd_peerseqno) {
-               loglog(RC_LOG_SERIOUS, "DPD: Received old or duplicate R_U_THERE");
-               return STF_IGNORE;
-       }
-
-       st->st_dpd_peerseqno = seqno;
-       delete_dpd_event(st);
-
-       if (send_isakmp_notification(st, R_U_THERE_ACK, pbs->cur, pbs_left(pbs)) != STF_IGNORE)
-       {
-               loglog(RC_LOG_SERIOUS, "DPD Info: could not send R_U_THERE_ACK");
-               return STF_IGNORE;
-       }
-       DBG(DBG_CONTROL,
-               DBG_log("sent DPD notification R_U_THERE_ACK with seqno = %u", seqno)
-       )
-
-       st->st_last_dpd = tm;
-       return STF_IGNORE;
-}
-
-/*
- * DPD out Responder
- */
-stf_status dpd_inR(struct state *st, struct isakmp_notification *const n,
-                                  pb_stream *pbs)
-{
-       u_int32_t seqno;
-
-       if (st == NULL || !IS_ISAKMP_SA_ESTABLISHED(st->st_state))
-       {
-               loglog(RC_LOG_SERIOUS
-                       , "DPD: Received R_U_THERE_ACK for unestablished ISAKMP SA");
-               return STF_FAIL;
-       }
-
-   if (n->isan_spisize != COOKIE_SIZE * 2 || pbs_left(pbs) < COOKIE_SIZE * 2)
-       {
-               loglog(RC_LOG_SERIOUS
-                       , "DPD: R_U_THERE_ACK has invalid SPI length (%d)"
-                       , n->isan_spisize);
-               return STF_FAIL + ISAKMP_PAYLOAD_MALFORMED;
-       }
-
-       if (memcmp(pbs->cur, st->st_icookie, COOKIE_SIZE) != 0)
-       {
-#ifdef APPLY_CRISCO
-               /* Ignore it, cisco sends odd icookies */
-#else
-               loglog(RC_LOG_SERIOUS, "DPD: R_U_THERE_ACK has invalid icookie");
-               return STF_FAIL + ISAKMP_INVALID_COOKIE;
-#endif
-       }
-       pbs->cur += COOKIE_SIZE;
-
-       if (memcmp(pbs->cur, st->st_rcookie, COOKIE_SIZE) != 0)
-       {
-#ifdef APPLY_CRISCO
-               /* Ignore it, cisco sends odd icookies */
-#else
-               loglog(RC_LOG_SERIOUS, "DPD: R_U_THERE_ACK has invalid rcookie");
-               return STF_FAIL + ISAKMP_INVALID_COOKIE;
-#endif
-       }
-       pbs->cur += COOKIE_SIZE;
-
-       if (pbs_left(pbs) != sizeof(seqno))
-       {
-               loglog(RC_LOG_SERIOUS
-                       , " DPD: R_U_THERE_ACK has invalid data length (%d)"
-                       , (int) pbs_left(pbs));
-               return STF_FAIL + ISAKMP_PAYLOAD_MALFORMED;
-       }
-
-       seqno = ntohl(*(u_int32_t *)pbs->cur);
-       DBG(DBG_CONTROL,
-               DBG_log("received DPD notification R_U_THERE_ACK with seqno = %u"
-               , seqno)
-       )
-
-       if (!st->st_dpd_expectseqno && seqno != st->st_dpd_expectseqno)
-       {
-               loglog(RC_LOG_SERIOUS
-                       , "DPD: R_U_THERE_ACK has unexpected sequence number %u (expected %u)"
-                       , seqno, st->st_dpd_expectseqno);
-               return STF_FAIL + ISAKMP_PAYLOAD_MALFORMED;
-       }
-
-       st->st_dpd_expectseqno = 0;
-       delete_dpd_event(st);
-       return STF_IGNORE;
-}
-
-/*
- * DPD Timeout Function
- *
- * This function is called when a timeout DPD_EVENT occurs.  We set clear/trap
- * both the SA and the eroutes, depending on what the connection definition
- * tells us (either 'hold' or 'clear')
- */
-void
-dpd_timeout(struct state *st)
-{
-       struct state *newest_phase1_st;
-       connection_t *c = st->st_connection;
-       int action = st->st_connection->dpd_action;
-       char cname[BUF_LEN];
-
-       passert(action == DPD_ACTION_HOLD
-                || action == DPD_ACTION_CLEAR
-                || DPD_ACTION_RESTART);
-
-       /* is there a newer phase1_state? */
-       newest_phase1_st = find_phase1_state(c, ISAKMP_SA_ESTABLISHED_STATES);
-       if (newest_phase1_st != NULL && newest_phase1_st != st)
-       {
-               plog("DPD: Phase1 state #%ld has been superseded by #%ld"
-                        " - timeout ignored"
-                        , st->st_serialno, newest_phase1_st->st_serialno);
-               return;
-       }
-
-       loglog(RC_LOG_SERIOUS, "DPD: No response from peer - declaring peer dead");
-
-       /* delete the state, which is probably in phase 2 */
-       set_cur_connection(c);
-       plog("DPD: Terminating all SAs using this connection");
-       delete_states_by_connection(c, TRUE);
-       reset_cur_connection();
-
-       switch (action)
-       {
-       case DPD_ACTION_HOLD:
-               /* dpdaction=hold - Wipe the SA's but %trap the eroute so we don't
-                * leak traffic.  Also, being in %trap means new packets will
-                * force an initiation of the conn again.
-                */
-               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 \"%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 \"%s\"", c->name);
-               unroute_connection(c);
-
-               /* caching the connection name before deletion */
-               strncpy(cname, c->name, BUF_LEN);
-               cname[BUF_LEN-1] = '\0';
-
-               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/ipsec_doi.h b/src/pluto/ipsec_doi.h
deleted file mode 100644 (file)
index c11edaa..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/* IPsec DOI and Oakley resolution routines
- * Copyright (C) 1998-2002  D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef _IPSEC_DOI_H
-#define _IPSEC_DOI_H
-
-#include "defs.h"
-
-extern void echo_hdr(struct msg_digest *md, bool enc, u_int8_t np);
-
-extern void ipsecdoi_initiate(int whack_sock, struct connection *c
-       , lset_t policy, unsigned long try, so_serial_t replacing);
-
-extern void ipsecdoi_replace(struct state *st, unsigned long try);
-
-extern void init_phase2_iv(struct state *st, const msgid_t *msgid);
-
-extern stf_status quick_outI1(int whack_sock
-       , struct state *isakmp_sa
-       , struct connection *c
-       , lset_t policy
-       , unsigned long try
-       , so_serial_t replacing);
-
-extern state_transition_fn
-       main_inI1_outR1,
-       main_inR1_outI2,
-       main_inI2_outR2,
-       main_inR2_outI3,
-       main_inI3_outR3,
-       main_inR3,
-       quick_inI1_outR1,
-       quick_inR1_outI2,
-       quick_inI2;
-
-extern void send_delete(struct state *st);
-extern void accept_delete(struct state *st, struct msg_digest *md
-       , struct payload_digest *p);
-extern void close_message(pb_stream *pbs);
-extern bool encrypt_message(pb_stream *pbs, struct state *st);
-
-
-extern void send_notification_from_state(struct state *st,
-       enum state_kind state, u_int16_t type);
-extern void send_notification_from_md(struct msg_digest *md, u_int16_t type);
-
-extern const char *init_pluto_vendorid(void);
-
-extern void dpd_outI(struct state *st);
-extern stf_status dpd_inI_outR(struct state *st
-                       , struct isakmp_notification *const n, pb_stream *n_pbs);
-extern stf_status dpd_inR(struct state *st
-                       , struct isakmp_notification *const n, pb_stream *n_pbs);
-extern void dpd_timeout(struct state *st);
-
-/* START_HASH_PAYLOAD
- *
- * Emit a to-be-filled-in hash payload, noting the field start (r_hashval)
- * and the start of the part of the message to be hashed (r_hash_start).
- * This macro is magic.
- * - it can cause the caller to return
- * - it references variables local to the caller (r_hashval, r_hash_start, st)
- */
-#define START_HASH_PAYLOAD(rbody, np) { \
-       pb_stream hash_pbs; \
-       if (!out_generic(np, &isakmp_hash_desc, &(rbody), &hash_pbs)) \
-               return STF_INTERNAL_ERROR; \
-       r_hashval = hash_pbs.cur;   /* remember where to plant value */ \
-       if (!out_zero(st->st_oakley.hasher->hash_digest_size, &hash_pbs, "HASH")) \
-               return STF_INTERNAL_ERROR; \
-       close_output_pbs(&hash_pbs); \
-       r_hash_start = (rbody).cur; /* hash from after HASH payload */ \
-}
-
-/* CHECK_QUICK_HASH
- *
- * This macro is magic -- it cannot be expressed as a function.
- * - it causes the caller to return!
- * - it declares local variables and expects the "do_hash" argument
- *   expression to reference them (hash_val, hash_pbs)
- */
-#define CHECK_QUICK_HASH(md, do_hash, hash_name, msg_name) { \
-               pb_stream *const hash_pbs = &md->chain[ISAKMP_NEXT_HASH]->pbs; \
-               u_char hash_val[MAX_DIGEST_LEN]; \
-               size_t hash_len = do_hash; \
-               if (pbs_left(hash_pbs) != hash_len \
-               || memcmp(hash_pbs->cur, hash_val, hash_len) != 0) \
-               { \
-                       DBG_cond_dump(DBG_CRYPT, "received " hash_name ":", hash_pbs->cur, pbs_left(hash_pbs)); \
-                       loglog(RC_LOG_SERIOUS, "received " hash_name " does not match computed value in " msg_name); \
-                       /* XXX Could send notification back */ \
-                       return STF_FAIL + ISAKMP_INVALID_HASH_INFORMATION; \
-               } \
-       }
-
-#endif /* _IPSEC_DOI_H */
-
diff --git a/src/pluto/kameipsec.h b/src/pluto/kameipsec.h
deleted file mode 100644 (file)
index 5e9d8ce..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef __IPSEC_H
-#define __IPSEC_H 1
-
-/* The definitions, required to talk to KAME racoon IKE. */
-
-#define IPSEC_PORT_ANY          0
-#define IPSEC_ULPROTO_ANY       255
-#define IPSEC_PROTO_ANY         255
-
-enum {
-               IPSEC_MODE_ANY          = 0,    /* We do not support this for SA */
-               IPSEC_MODE_TRANSPORT    = 1,
-               IPSEC_MODE_TUNNEL       = 2
-};
-
-enum {
-               IPSEC_DIR_ANY           = 0,
-               IPSEC_DIR_INBOUND       = 1,
-               IPSEC_DIR_OUTBOUND      = 2,
-               IPSEC_DIR_FWD           = 3,    /* It is our own */
-               IPSEC_DIR_MAX           = 4,
-               IPSEC_DIR_INVALID       = 5
-};
-
-enum {
-               IPSEC_POLICY_DISCARD    = 0,
-               IPSEC_POLICY_NONE       = 1,
-               IPSEC_POLICY_IPSEC      = 2,
-               IPSEC_POLICY_ENTRUST    = 3,
-               IPSEC_POLICY_BYPASS     = 4
-};
-
-enum {
-               IPSEC_LEVEL_DEFAULT     = 0,
-               IPSEC_LEVEL_USE         = 1,
-               IPSEC_LEVEL_REQUIRE     = 2,
-               IPSEC_LEVEL_UNIQUE      = 3
-};
-
-#define IPSEC_MANUAL_REQID_MAX  0x3fff
-
-#define IPSEC_REPLAYWSIZE  32
-
-#define IP_IPSEC_POLICY 16
-#define IPV6_IPSEC_POLICY 34
-
-#endif  /* __IPSEC_H */
diff --git a/src/pluto/kernel.c b/src/pluto/kernel.c
deleted file mode 100644 (file)
index e4729ef..0000000
+++ /dev/null
@@ -1,2114 +0,0 @@
-/* routines that interface with the kernel's IPsec mechanism
- *
- * Copyright (C) 2010 Tobias Brunner
- * Copyright (C) 2009 Andreas Steffen
- * Hochschule fuer Technik Rapperswil
- *
- * Copyright (C) 1998-2002  D. Hugh Redelmeier
- * Copyright (C) 1997 Angelos D. Keromytis
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <stddef.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/queue.h>
-#include <sys/wait.h>
-
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include <freeswan.h>
-
-#include <library.h>
-#include <hydra.h>
-#include <crypto/rngs/rng.h>
-#include <kernel/kernel_listener.h>
-
-#include <signal.h>
-#include <sys/time.h>   /* for select(2) */
-#include <sys/types.h>  /* for select(2) */
-#include <pfkeyv2.h>
-#include <pfkey.h>
-#include "kameipsec.h"
-
-#include "constants.h"
-#include "defs.h"
-#include "connections.h"
-#include "state.h"
-#include "timer.h"
-#include "kernel.h"
-#include "kernel_pfkey.h"
-#include "log.h"
-#include "ca.h"
-#include "server.h"
-#include "whack.h"      /* for RC_LOG_SERIOUS */
-#include "keys.h"
-#include "crypto.h"
-#include "nat_traversal.h"
-#include "alg_info.h"
-#include "kernel_alg.h"
-#include "pluto.h"
-
-
-bool can_do_IPcomp = TRUE;  /* can system actually perform IPCOMP? */
-
-/* test if the routes required for two different connections agree
- * It is assumed that the destination subnets agree; we are only
- * testing that the interfaces and nexthops match.
- */
-#define routes_agree(c, d) ((c)->interface == (d)->interface \
-               && sameaddr(&(c)->spd.this.host_nexthop, &(d)->spd.this.host_nexthop))
-
-/* forward declaration */
-static bool shunt_eroute(connection_t *c, struct spd_route *sr,
-                                                enum routing_t rt_kind, unsigned int op,
-                                                const char *opname);
-
-static void set_text_said(char *text_said, const ip_address *dst,
-                                                 ipsec_spi_t spi, int proto);
-
-/**
- * Default IPsec SA config (e.g. to install trap policies).
- */
-static ipsec_sa_cfg_t null_ipsec_sa = {
-       .mode = MODE_TRANSPORT,
-       .esp = {
-               .use = TRUE,
-       },
-};
-
-/**
- * Helper function that converts an ip_subnet to a traffic_selector_t.
- */
-static traffic_selector_t *traffic_selector_from_subnet(const ip_subnet *client,
-                                                                                                               const u_int8_t proto)
-{
-       traffic_selector_t *ts;
-       host_t *net;
-       net = host_create_from_sockaddr((sockaddr_t*)&client->addr);
-       ts = traffic_selector_create_from_subnet(net, client->maskbits, proto,
-                                                                                        net->get_port(net));
-       return ts;
-}
-
-/**
- * Helper function that converts a traffic_selector_t to an ip_subnet.
- */
-static ip_subnet subnet_from_traffic_selector(traffic_selector_t *ts)
-{
-       ip_subnet subnet;
-       host_t *net;
-       u_int8_t mask;
-       ts->to_subnet(ts, &net, &mask);
-       subnet.addr = *(ip_address*)net->get_sockaddr(net);
-       subnet.maskbits = mask;
-       net->destroy(net);
-       return subnet;
-}
-
-
-void record_and_initiate_opportunistic(const ip_subnet *ours,
-                                                                          const ip_subnet *his,
-                                                                          int transport_proto, const char *why)
-{
-       ip_address src, dst;
-       passert(samesubnettype(ours, his));
-
-       /* actually initiate opportunism */
-       networkof(ours, &src);
-       networkof(his, &dst);
-       initiate_opportunistic(&src, &dst, transport_proto, TRUE, NULL_FD);
-}
-
-/* Generate Unique SPI numbers.
- *
- * The returned SPI is in network byte order.
- */
-ipsec_spi_t get_ipsec_spi(ipsec_spi_t avoid, int proto, struct spd_route *sr,
-                                                 bool tunnel)
-{
-       host_t *host_src, *host_dst;
-       u_int32_t spi;
-
-       host_src = host_create_from_sockaddr((sockaddr_t*)&sr->that.host_addr);
-       host_dst = host_create_from_sockaddr((sockaddr_t*)&sr->this.host_addr);
-
-       if (hydra->kernel_interface->get_spi(hydra->kernel_interface, host_src,
-                                                               host_dst, proto, sr->reqid, &spi) != SUCCESS)
-       {
-               spi = 0;
-       }
-
-       host_src->destroy(host_src);
-       host_dst->destroy(host_dst);
-
-       return spi;
-}
-
-/* Generate Unique CPI numbers.
- * The result is returned as an SPI (4 bytes) in network order!
- * The real bits are in the nework-low-order 2 bytes.
- */
-ipsec_spi_t get_my_cpi(struct spd_route *sr, bool tunnel)
-{
-       host_t *host_src, *host_dst;
-       u_int16_t cpi;
-
-       host_src = host_create_from_sockaddr((sockaddr_t*)&sr->that.host_addr);
-       host_dst = host_create_from_sockaddr((sockaddr_t*)&sr->this.host_addr);
-
-       if (hydra->kernel_interface->get_cpi(hydra->kernel_interface, host_src,
-                                                                                host_dst, sr->reqid, &cpi) != SUCCESS)
-
-       {
-               cpi = 0;
-       }
-
-       host_src->destroy(host_src);
-       host_dst->destroy(host_dst);
-
-       return htonl((u_int32_t)ntohs(cpi));
-}
-
-/* Replace the shell metacharacters ', \, ", `, and $ in a character string
- * by escape sequences consisting of their octal values
- */
-static void escape_metachar(const char *src, char *dst, size_t dstlen)
-{
-       while (*src != '\0' && dstlen > 4)
-       {
-               switch (*src)
-               {
-               case '\'':
-               case '\\':
-               case '"':
-               case '`':
-               case '$':
-                       sprintf(dst,"\\%s%o", (*src < 64)?"0":"", *src);
-                       dst += 4;
-                       dstlen -= 4;
-                       break;
-               default:
-                       *dst++ = *src;
-                       dstlen--;
-               }
-               src++;
-       }
-       *dst = '\0';
-}
-
-/* invoke the updown script to do the routing and firewall commands required
- *
- * The user-specified updown script is run.  Parameters are fed to it in
- * the form of environment variables.  All such environment variables
- * have names starting with "PLUTO_".
- *
- * The operation to be performed is specified by PLUTO_VERB.  This
- * verb has a suffix "-host" if the client on this end is just the
- * host; otherwise the suffix is "-client".  If the address family
- * of the host is IPv6, an extra suffix of "-v6" is added.
- *
- * "prepare-host" and "prepare-client" are used to delete a route
- * that may exist (due to forces outside of Pluto).  It is used to
- * prepare for pluto creating a route.
- *
- * "route-host" and "route-client" are used to install a route.
- * Since routing is based only on destination, the PLUTO_MY_CLIENT_*
- * values are probably of no use (using them may signify a bug).
- *
- * "unroute-host" and "unroute-client" are used to delete a route.
- * Since routing is based only on destination, the PLUTO_MY_CLIENT_*
- * values are probably of no use (using them may signify a bug).
- *
- * "up-host" and "up-client" are run when an eroute is added (not replaced).
- * They are useful for adjusting a firewall: usually for adding a rule
- * to let processed packets flow between clients.  Note that only
- * one eroute may exist for a pair of client subnets but inbound
- * IPsec SAs may persist without an eroute.
- *
- * "down-host" and "down-client" are run when an eroute is deleted.
- * They are useful for adjusting a firewall.
- */
-
-#ifndef DEFAULT_UPDOWN
-# define DEFAULT_UPDOWN "ipsec _updown"
-#endif
-
-static bool do_command(connection_t *c, struct spd_route *sr, struct state *st,
-                                          const char *verb)
-{
-       char cmd[1536];     /* arbitrary limit on shell command length */
-       const char *verb_suffix;
-
-       /* figure out which verb suffix applies */
-       {
-               const char *hs, *cs;
-
-               switch (addrtypeof(&sr->this.host_addr))
-               {
-                       case AF_INET:
-                               hs = "-host";
-                               cs = "-client";
-                               break;
-                       case AF_INET6:
-                               hs = "-host-v6";
-                               cs = "-client-v6";
-                               break;
-                       default:
-                               loglog(RC_LOG_SERIOUS, "unknown address family");
-                               return FALSE;
-               }
-               verb_suffix = subnetisaddr(&sr->this.client, &sr->this.host_addr)
-                       ? hs : cs;
-       }
-
-       /* form the command string */
-       {
-               char
-                       nexthop_str[sizeof("PLUTO_NEXT_HOP='' ") +ADDRTOT_BUF] = "",
-                       srcip_str[sizeof("PLUTO_MY_SOURCEIP='' ")+ADDRTOT_BUF] = "",
-                       me_str[ADDRTOT_BUF],
-                       myid_str[BUF_LEN],
-                       myclient_str[SUBNETTOT_BUF],
-                       myclientnet_str[ADDRTOT_BUF],
-                       myclientmask_str[ADDRTOT_BUF],
-                       peer_str[ADDRTOT_BUF],
-                       peerid_str[BUF_LEN],
-                       peerclient_str[SUBNETTOT_BUF],
-                       peerclientnet_str[ADDRTOT_BUF],
-                       peerclientmask_str[ADDRTOT_BUF],
-                       peerca_str[BUF_LEN],
-                       mark_in[BUF_LEN] = "",
-                       mark_out[BUF_LEN] = "",
-                       udp_encap[BUF_LEN] = "",
-                       xauth_id_str[BUF_LEN] = "",
-                       secure_myid_str[BUF_LEN] = "",
-                       secure_peerid_str[BUF_LEN] = "",
-                       secure_peerca_str[BUF_LEN] = "",
-                       secure_xauth_id_str[BUF_LEN] = "";
-               ip_address ta;
-               pubkey_list_t *p;
-
-               if (addrbytesptr(&sr->this.host_nexthop, NULL)
-               && !isanyaddr(&sr->this.host_nexthop))
-               {
-                       char *n;
-
-                       strcpy(nexthop_str, "PLUTO_NEXT_HOP='");
-                       n = nexthop_str + strlen(nexthop_str);
-
-                       addrtot(&sr->this.host_nexthop, 0
-                                       ,n , sizeof(nexthop_str)-strlen(nexthop_str));
-                       strncat(nexthop_str, "' ", sizeof(nexthop_str));
-               }
-
-               if (!sr->this.host_srcip->is_anyaddr(sr->this.host_srcip))
-               {
-                       char *n;
-
-                       strcpy(srcip_str, "PLUTO_MY_SOURCEIP='");
-                       n = srcip_str + strlen(srcip_str);
-                       snprintf(n, sizeof(srcip_str)-strlen(srcip_str), "%H",
-                                               sr->this.host_srcip);
-                       strncat(srcip_str, "' ", sizeof(srcip_str));
-               }
-
-               if (sr->mark_in.value)
-               {
-                       snprintf(mark_in, sizeof(mark_in), "PLUTO_MARK_IN='%u/0x%08x' ",
-                                        sr->mark_in.value, sr->mark_in.mask);
-               }
-
-               if (sr->mark_out.value)
-               {
-                       snprintf(mark_out, sizeof(mark_out), "PLUTO_MARK_OUT='%u/0x%08x' ",
-                                        sr->mark_out.value, sr->mark_out.mask);
-               }
-
-               if (st && (st->nat_traversal & NAT_T_DETECTED))
-               {
-                       snprintf(udp_encap, sizeof(udp_encap), "PLUTO_UDP_ENC='%u' ",
-                                        sr->that.host_port);
-               }
-
-               addrtot(&sr->this.host_addr, 0, me_str, sizeof(me_str));
-               snprintf(myid_str, sizeof(myid_str), "%Y", sr->this.id);
-               escape_metachar(myid_str, secure_myid_str, sizeof(secure_myid_str));
-               subnettot(&sr->this.client, 0, myclient_str, sizeof(myclientnet_str));
-               networkof(&sr->this.client, &ta);
-               addrtot(&ta, 0, myclientnet_str, sizeof(myclientnet_str));
-               maskof(&sr->this.client, &ta);
-               addrtot(&ta, 0, myclientmask_str, sizeof(myclientmask_str));
-
-               if (c->xauth_identity &&
-                       c->xauth_identity->get_type(c->xauth_identity) != ID_ANY)
-               {
-                       snprintf(xauth_id_str, sizeof(xauth_id_str), "%Y", c->xauth_identity);
-                       escape_metachar(xauth_id_str, secure_xauth_id_str,
-                                        sizeof(secure_xauth_id_str));
-                       snprintf(xauth_id_str, sizeof(xauth_id_str), "PLUTO_XAUTH_ID='%s' ",
-                                        secure_xauth_id_str);
-               }
-
-               addrtot(&sr->that.host_addr, 0, peer_str, sizeof(peer_str));
-               snprintf(peerid_str, sizeof(peerid_str), "%Y", sr->that.id);
-               escape_metachar(peerid_str, secure_peerid_str, sizeof(secure_peerid_str));
-               subnettot(&sr->that.client, 0, peerclient_str, sizeof(peerclientnet_str));
-               networkof(&sr->that.client, &ta);
-               addrtot(&ta, 0, peerclientnet_str, sizeof(peerclientnet_str));
-               maskof(&sr->that.client, &ta);
-               addrtot(&ta, 0, peerclientmask_str, sizeof(peerclientmask_str));
-
-               for (p = pubkeys; p != NULL; p = p->next)
-               {
-                       pubkey_t *key = p->key;
-                       key_type_t type = key->public_key->get_type(key->public_key);
-                       int pathlen;
-
-                       if (type == KEY_RSA &&
-                               sr->that.id->equals(sr->that.id, key->id) &&
-                               trusted_ca(key->issuer, sr->that.ca, &pathlen))
-                       {
-                               if (key->issuer)
-                               {
-                                       snprintf(peerca_str, BUF_LEN, "%Y", key->issuer);
-                                       escape_metachar(peerca_str, secure_peerca_str, BUF_LEN);
-                               }
-                               else
-                               {
-                                       secure_peerca_str[0] = '\0';
-                               }
-                               break;
-                       }
-               }
-
-               if (-1 == snprintf(cmd, sizeof(cmd)
-                       , "2>&1 "   /* capture stderr along with stdout */
-                       "PLUTO_VERSION='1.1' "      /* change VERSION when interface spec changes */
-                       "PLUTO_VERB='%s%s' "
-                       "PLUTO_CONNECTION='%s' "
-                       "%s"        /* optional PLUTO_NEXT_HOP */
-                       "PLUTO_INTERFACE='%s' "
-                       "%s"        /* optional PLUTO_HOST_ACCESS */
-                       "PLUTO_REQID='%u' "
-                       "PLUTO_ME='%s' "
-                       "PLUTO_MY_ID='%s' "
-                       "PLUTO_MY_CLIENT='%s' "
-                       "PLUTO_MY_CLIENT_NET='%s' "
-                       "PLUTO_MY_CLIENT_MASK='%s' "
-                       "PLUTO_MY_PORT='%u' "
-                       "PLUTO_MY_PROTOCOL='%u' "
-                       "PLUTO_PEER='%s' "
-                       "PLUTO_PEER_ID='%s' "
-                       "PLUTO_PEER_CLIENT='%s' "
-                       "PLUTO_PEER_CLIENT_NET='%s' "
-                       "PLUTO_PEER_CLIENT_MASK='%s' "
-                       "PLUTO_PEER_PORT='%u' "
-                       "PLUTO_PEER_PROTOCOL='%u' "
-                       "PLUTO_PEER_CA='%s' "
-                       "%s"        /* optional PLUTO_MY_SRCIP */
-                       "%s"        /* optional PLUTO_XAUTH_ID */
-                       "%s"        /* optional PLUTO_MARK_IN */
-                       "%s"        /* optional PLUTO_MARK_OUT */
-                       "%s"        /* optional PLUTO_UDP_ENC */
-                       "%s"        /* actual script */
-                       , verb, verb_suffix
-                       , c->name
-                       , nexthop_str
-                       , c->interface->vname
-                       , sr->this.hostaccess? "PLUTO_HOST_ACCESS='1' " : ""
-                       , sr->reqid
-                       , me_str
-                       , secure_myid_str
-                       , myclient_str
-                       , myclientnet_str
-                       , myclientmask_str
-                       , sr->this.port
-                       , sr->this.protocol
-                       , peer_str
-                       , secure_peerid_str
-                       , peerclient_str
-                       , peerclientnet_str
-                       , peerclientmask_str
-                       , sr->that.port
-                       , sr->that.protocol
-                       , secure_peerca_str
-                       , srcip_str
-                       , xauth_id_str
-                       , mark_in
-                       , mark_out
-                       , udp_encap
-                       , sr->this.updown == NULL? DEFAULT_UPDOWN : sr->this.updown))
-               {
-                       loglog(RC_LOG_SERIOUS, "%s%s command too long!", verb, verb_suffix);
-                       return FALSE;
-               }
-       }
-
-       DBG(DBG_CONTROL, DBG_log("executing %s%s: %s"
-               , verb, verb_suffix, cmd));
-
-       /* invoke the script, catching stderr and stdout
-        * It may be of concern that some file descriptors will
-        * be inherited.  For the ones under our control, we
-        * have done fcntl(fd, F_SETFD, FD_CLOEXEC) to prevent this.
-        * Any used by library routines (perhaps the resolver or syslog)
-        * will remain.
-        */
-       FILE *f = popen(cmd, "r");
-
-       if (f == NULL)
-       {
-               loglog(RC_LOG_SERIOUS, "unable to popen %s%s command", verb, verb_suffix);
-               return FALSE;
-       }
-
-       /* log any output */
-       for (;;)
-       {
-               /* if response doesn't fit in this buffer, it will be folded */
-               char resp[256];
-
-               if (fgets(resp, sizeof(resp), f) == NULL)
-               {
-                       if (ferror(f))
-                       {
-                               log_errno((e, "fgets failed on output of %s%s command"
-                                       , verb, verb_suffix));
-                               return FALSE;
-                       }
-                       else
-                       {
-                               passert(feof(f));
-                               break;
-                       }
-               }
-               else
-               {
-                       char *e = resp + strlen(resp);
-
-                       if (e > resp && e[-1] == '\n')
-                               e[-1] = '\0';       /* trim trailing '\n' */
-                       plog("%s%s output: %s", verb, verb_suffix, resp);
-               }
-       }
-
-       /* report on and react to return code */
-       {
-               int r = pclose(f);
-
-               if (r == -1)
-               {
-                       log_errno((e, "pclose failed for %s%s command"
-                               , verb, verb_suffix));
-                       return FALSE;
-               }
-               else if (WIFEXITED(r))
-               {
-                       if (WEXITSTATUS(r) != 0)
-                       {
-                               loglog(RC_LOG_SERIOUS, "%s%s command exited with status %d"
-                                       , verb, verb_suffix, WEXITSTATUS(r));
-                               return FALSE;
-                       }
-               }
-               else if (WIFSIGNALED(r))
-               {
-                       loglog(RC_LOG_SERIOUS, "%s%s command exited with signal %d"
-                               , verb, verb_suffix, WTERMSIG(r));
-                       return FALSE;
-               }
-               else
-               {
-                       loglog(RC_LOG_SERIOUS, "%s%s command exited with unknown status %d"
-                               , verb, verb_suffix, r);
-                       return FALSE;
-               }
-       }
-       return TRUE;
-}
-
-/* Check that we can route (and eroute).  Diagnose if we cannot. */
-
-enum routability {
-       route_impossible = 0,
-       route_easy = 1,
-       route_nearconflict = 2,
-       route_farconflict = 3
-};
-
-static enum routability could_route(connection_t *c)
-{
-       struct spd_route *esr, *rosr;
-       connection_t *ero      /* who, if anyone, owns our eroute? */
-               , *ro = route_owner(c, &rosr, &ero, &esr); /* who owns our route? */
-
-       /* it makes no sense to route a connection that is ISAKMP-only */
-       if (!NEVER_NEGOTIATE(c->policy) && !HAS_IPSEC_POLICY(c->policy))
-       {
-               loglog(RC_ROUTE, "cannot route an ISAKMP-only connection");
-               return route_impossible;
-       }
-
-       /* if this is a Road Warrior template, we cannot route.
-        * Opportunistic template is OK.
-        */
-       if (c->kind == CK_TEMPLATE && !(c->policy & POLICY_OPPO))
-       {
-               loglog(RC_ROUTE, "cannot route Road Warrior template");
-               return route_impossible;
-       }
-
-       /* if we don't know nexthop, we cannot route */
-       if (isanyaddr(&c->spd.this.host_nexthop))
-       {
-               loglog(RC_ROUTE, "cannot route connection without knowing our nexthop");
-               return route_impossible;
-       }
-
-       /* if routing would affect IKE messages, reject */
-       if (c->spd.this.host_port != NAT_T_IKE_FLOAT_PORT
-        && c->spd.this.host_port != IKE_UDP_PORT
-        && addrinsubnet(&c->spd.that.host_addr, &c->spd.that.client))
-       {
-               loglog(RC_LOG_SERIOUS, "cannot install route: peer is within its client");
-               return route_impossible;
-       }
-
-       /* If there is already a route for peer's client subnet
-        * and it disagrees about interface or nexthop, we cannot steal it.
-        * Note: if this connection is already routed (perhaps for another
-        * state object), the route will agree.
-        * This is as it should be -- it will arise during rekeying.
-        */
-       if (ro != NULL && !routes_agree(ro, c))
-       {
-               loglog(RC_LOG_SERIOUS, "cannot route -- route already in use for \"%s\""
-                       , ro->name);
-               return route_impossible;  /* another connection already
-                                                                        using the eroute */
-       }
-
-       /* if there is an eroute for another connection, there is a problem */
-       if (ero != NULL && ero != c)
-       {
-               connection_t *ero2, *ero_top;
-               connection_t *inside, *outside;
-
-               /*
-                * note, wavesec (PERMANENT) goes *outside* and
-                * OE goes *inside* (TEMPLATE)
-                */
-               inside = NULL;
-               outside= NULL;
-               if (ero->kind == CK_PERMANENT
-                  && c->kind == CK_TEMPLATE)
-               {
-                       outside = ero;
-                       inside = c;
-               }
-               else if (c->kind == CK_PERMANENT
-                               && ero->kind == CK_TEMPLATE)
-               {
-                       outside = c;
-                       inside = ero;
-               }
-
-               /* okay, check again, with correct order */
-               if (outside && outside->kind == CK_PERMANENT
-                       && inside && inside->kind == CK_TEMPLATE)
-               {
-                       char inst[CONN_INST_BUF];
-
-                       /* this is a co-terminal attempt of the "near" kind. */
-                       /* when chaining, we chain from inside to outside */
-
-                       /* XXX permit multiple deep connections? */
-                       passert(inside->policy_next == NULL);
-
-                       inside->policy_next = outside;
-
-                       /* since we are going to steal the eroute from the secondary
-                        * policy, we need to make sure that it no longer thinks that
-                        * it owns the eroute.
-                        */
-                       outside->spd.eroute_owner = SOS_NOBODY;
-                       outside->spd.routing = RT_UNROUTED_KEYED;
-
-                       /* set the priority of the new eroute owner to be higher
-                        * than that of the current eroute owner
-                        */
-                       inside->prio = outside->prio + 1;
-
-                       fmt_conn_instance(inside, inst);
-
-                       loglog(RC_LOG_SERIOUS
-                                  , "conflict on eroute (%s), switching eroute to %s and linking %s"
-                                  , inst, inside->name, outside->name);
-
-                       return route_nearconflict;
-               }
-
-               /* look along the chain of policies for one with the same name */
-               ero_top = ero;
-
-               for (ero2 = ero; ero2 != NULL; ero2 = ero->policy_next)
-               {
-                       if (ero2->kind == CK_TEMPLATE
-                       && streq(ero2->name, c->name))
-                               break;
-               }
-
-               /* If we fell of the end of the list, then we found no TEMPLATE
-                * so there must be a conflict that we can't resolve.
-                * As the names are not equal, then we aren't replacing/rekeying.
-                */
-               if (ero2 == NULL)
-               {
-                       char inst[CONN_INST_BUF];
-
-                       fmt_conn_instance(ero, inst);
-
-                       loglog(RC_LOG_SERIOUS
-                               , "cannot install eroute -- it is in use for \"%s\"%s #%lu"
-                               , ero->name, inst, esr->eroute_owner);
-                       return route_impossible;
-               }
-       }
-       return route_easy;
-}
-
-bool trap_connection(connection_t *c)
-{
-       switch (could_route(c))
-       {
-       case route_impossible:
-               return FALSE;
-
-       case route_nearconflict:
-       case route_easy:
-               /* RT_ROUTED_TUNNEL is treated specially: we don't override
-                * because we don't want to lose track of the IPSEC_SAs etc.
-                */
-               if (c->spd.routing < RT_ROUTED_TUNNEL)
-               {
-                       return route_and_eroute(c, &c->spd, NULL);
-               }
-               return TRUE;
-
-       case route_farconflict:
-               return FALSE;
-       }
-
-       return FALSE;
-}
-
-/**
- * Delete any eroute for a connection and unroute it if route isn't shared
- */
-void unroute_connection(connection_t *c)
-{
-       struct spd_route *sr;
-       enum routing_t cr;
-
-       for (sr = &c->spd; sr; sr = sr->next)
-       {
-               cr = sr->routing;
-
-               if (erouted(cr))
-               {
-                       /* cannot handle a live one */
-                       passert(sr->routing != RT_ROUTED_TUNNEL);
-                       shunt_eroute(c, sr, RT_UNROUTED, ERO_DELETE, "delete");
-               }
-
-               sr->routing = RT_UNROUTED;  /* do now so route_owner won't find us */
-
-               /* only unroute if no other connection shares it */
-               if (routed(cr) && route_owner(c, NULL, NULL, NULL) == NULL)
-               {
-                       (void) do_command(c, sr, NULL, "unroute");
-               }
-       }
-}
-
-
-static void set_text_said(char *text_said, const ip_address *dst,
-                                                 ipsec_spi_t spi, int proto)
-{
-       ip_said said;
-
-       initsaid(dst, spi, proto, &said);
-       satot(&said, 0, text_said, SATOT_BUF);
-}
-
-
-/**
- * Setup an IPsec route entry.
- * op is one of the ERO_* operators.
- */
-static bool raw_eroute(const ip_address *this_host,
-                                          const ip_subnet *this_client,
-                                          const ip_address *that_host,
-                                          const ip_subnet *that_client,
-                                          mark_t mark,
-                                          ipsec_spi_t spi,
-                                          unsigned int proto,
-                                          unsigned int satype,
-                                          unsigned int transport_proto,
-                                          ipsec_sa_cfg_t *sa,
-                                          unsigned int op,
-                                          const char *opname USED_BY_DEBUG)
-{
-       traffic_selector_t *ts_src, *ts_dst;
-       host_t *host_src, *host_dst;
-       policy_type_t type = POLICY_IPSEC;
-       policy_dir_t dir = POLICY_OUT;
-       policy_priority_t priority = POLICY_PRIORITY_DEFAULT;
-       char text_said[SATOT_BUF];
-       bool ok = TRUE,
-                deleting = (op & ERO_MASK) == ERO_DELETE,
-                replacing = op & (SADB_X_SAFLAGS_REPLACEFLOW << ERO_FLAG_SHIFT);
-
-       set_text_said(text_said, that_host, spi, proto);
-
-       DBG(DBG_CONTROL | DBG_KERNEL,
-               {
-                       int sport = ntohs(portof(&this_client->addr));
-                       int dport = ntohs(portof(&that_client->addr));
-                       char mybuf[SUBNETTOT_BUF];
-                       char peerbuf[SUBNETTOT_BUF];
-
-                       subnettot(this_client, 0, mybuf, sizeof(mybuf));
-                       subnettot(that_client, 0, peerbuf, sizeof(peerbuf));
-                       DBG_log("%s eroute %s:%d -> %s:%d => %s:%d"
-                               , opname, mybuf, sport, peerbuf, dport
-                               , text_said, transport_proto);
-               });
-
-       if (satype == SADB_X_SATYPE_INT)
-       {
-               switch (ntohl(spi))
-               {
-                       case SPI_PASS:
-                               type = POLICY_PASS;
-                               break;
-                       case SPI_DROP:
-                       case SPI_REJECT:
-                               type = POLICY_DROP;
-                               break;
-                       case SPI_TRAP:
-                       case SPI_TRAPSUBNET:
-                       case SPI_HOLD:
-                               if (op & (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT))
-                               {
-                                       return TRUE;
-                               }
-                               priority = POLICY_PRIORITY_ROUTED;
-                               break;
-               }
-       }
-
-       if (op & (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT))
-       {
-               dir = POLICY_IN;
-       }
-
-       host_src = host_create_from_sockaddr((sockaddr_t*)this_host);
-       host_dst = host_create_from_sockaddr((sockaddr_t*)that_host);
-       ts_src = traffic_selector_from_subnet(this_client, transport_proto);
-       ts_dst = traffic_selector_from_subnet(that_client, transport_proto);
-
-       if (deleting || replacing)
-       {
-               hydra->kernel_interface->del_policy(hydra->kernel_interface,
-                                               ts_src, ts_dst, dir, sa->reqid, mark, priority);
-       }
-
-       if (!deleting)
-       {
-               ok = hydra->kernel_interface->add_policy(hydra->kernel_interface,
-                                               host_src, host_dst, ts_src, ts_dst, dir, type, sa,
-                                               mark, priority) == SUCCESS;
-       }
-
-       if (dir == POLICY_IN)
-       {       /* handle forward policy */
-               dir = POLICY_FWD;
-               if (deleting || replacing)
-               {
-                       hydra->kernel_interface->del_policy(hydra->kernel_interface,
-                                               ts_src, ts_dst, dir, sa->reqid, mark, priority);
-               }
-
-               if (!deleting && ok &&
-                       (sa->mode == MODE_TUNNEL || satype == SADB_X_SATYPE_INT))
-               {
-                       ok = hydra->kernel_interface->add_policy(hydra->kernel_interface,
-                                               host_src, host_dst, ts_src, ts_dst, dir, type, sa,
-                                               mark, priority) == SUCCESS;
-               }
-       }
-
-       host_src->destroy(host_src);
-       host_dst->destroy(host_dst);
-       ts_src->destroy(ts_src);
-       ts_dst->destroy(ts_dst);
-
-       return ok;
-}
-
-static bool eroute_connection(struct spd_route *sr, ipsec_spi_t spi,
-                                                         unsigned int proto, unsigned int satype,
-                                                         ipsec_sa_cfg_t *sa, unsigned int op,
-                                                         const char *opname)
-{
-       const ip_address *peer = &sr->that.host_addr;
-       char buf2[256];
-       bool ok;
-
-       snprintf(buf2, sizeof(buf2)
-                        , "eroute_connection %s", opname);
-
-       if (proto == SA_INT)
-       {
-               peer = aftoinfo(addrtypeof(peer))->any;
-       }
-       ok = raw_eroute(peer, &sr->that.client,
-                                       &sr->this.host_addr, &sr->this.client, sr->mark_in,
-                                       spi, proto, satype, sr->this.protocol,
-                                       sa, op | (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT), buf2);
-       return raw_eroute(&sr->this.host_addr, &sr->this.client, peer,
-                                         &sr->that.client, sr->mark_out, spi, proto, satype,
-                                         sr->this.protocol, sa, op, buf2) && ok;
-}
-
-/* assign a bare hold to a connection */
-
-bool assign_hold(connection_t *c USED_BY_DEBUG, struct spd_route *sr,
-                                int transport_proto,
-                                const ip_address *src,
-                                const ip_address *dst)
-{
-       /* either the automatically installed %hold eroute is broad enough
-        * or we try to add a broader one and delete the automatic one.
-        * Beware: this %hold might be already handled, but still squeak
-        * through because of a race.
-        */
-       enum routing_t ro = sr->routing     /* routing, old */
-               , rn = ro;                      /* routing, new */
-
-       passert(LHAS(LELEM(CK_PERMANENT) | LELEM(CK_INSTANCE), c->kind));
-       /* figure out what routing should become */
-       switch (ro)
-       {
-       case RT_UNROUTED:
-               rn = RT_UNROUTED_HOLD;
-               break;
-       case RT_ROUTED_PROSPECTIVE:
-               rn = RT_ROUTED_HOLD;
-               break;
-       default:
-               /* no change: this %hold is old news and should just be deleted */
-               break;
-       }
-
-       /* We need a broad %hold
-        * First we ensure that there is a broad %hold.
-        * There may already be one (race condition): no need to create one.
-        * There may already be a %trap: replace it.
-        * There may not be any broad eroute: add %hold.
-        */
-       if (rn != ro)
-       {
-               if (erouted(ro)
-               ? !eroute_connection(sr, htonl(SPI_HOLD), SA_INT, SADB_X_SATYPE_INT,
-                                                        &null_ipsec_sa, ERO_REPLACE,
-                                                        "replace %trap with broad %hold")
-               : !eroute_connection(sr, htonl(SPI_HOLD), SA_INT, SADB_X_SATYPE_INT,
-                                                        &null_ipsec_sa, ERO_ADD, "add broad %hold"))
-               {
-                       return FALSE;
-               }
-       }
-       sr->routing = rn;
-       return TRUE;
-}
-
-/* install or remove eroute for SA Group */
-static bool sag_eroute(struct state *st, struct spd_route *sr,
-                                          unsigned op, const char *opname)
-{
-       u_int inner_proto, inner_satype;
-       ipsec_spi_t inner_spi = 0;
-       ipsec_sa_cfg_t sa = {
-               .mode = MODE_TRANSPORT,
-       };
-       bool tunnel = FALSE;
-
-       if (st->st_ah.present)
-       {
-               inner_spi = st->st_ah.attrs.spi;
-               inner_proto = SA_AH;
-               inner_satype = SADB_SATYPE_AH;
-               sa.ah.use = TRUE;
-               sa.ah.spi = inner_spi;
-               tunnel |= st->st_ah.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL;
-       }
-
-       if (st->st_esp.present)
-       {
-               inner_spi = st->st_esp.attrs.spi;
-               inner_proto = SA_ESP;
-               inner_satype = SADB_SATYPE_ESP;
-               sa.esp.use = TRUE;
-               sa.esp.spi = inner_spi;
-               tunnel |= st->st_esp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL;
-       }
-
-       if (st->st_ipcomp.present)
-       {
-               inner_spi = st->st_ipcomp.attrs.spi;
-               inner_proto = SA_COMP;
-               inner_satype = SADB_X_SATYPE_COMP;
-               sa.ipcomp.transform = st->st_ipcomp.attrs.transid;
-               sa.ipcomp.cpi = htons(ntohl(inner_spi));
-               tunnel |= st->st_ipcomp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL;
-       }
-
-       if (!sa.ah.use && !sa.esp.use && !sa.ipcomp.transform)
-       {
-               impossible();   /* no transform at all! */
-       }
-
-       if (tunnel)
-       {
-               inner_spi = st->st_tunnel_out_spi;
-               inner_proto = SA_IPIP;
-               inner_satype = SADB_X_SATYPE_IPIP;
-               sa.mode = MODE_TUNNEL;
-       }
-
-       sa.reqid = sr->reqid;
-
-       return eroute_connection(sr, inner_spi, inner_proto, inner_satype,
-                                                        &sa, op, opname);
-}
-
-/* compute a (host-order!) SPI to implement the policy in connection c */
-ipsec_spi_t
-shunt_policy_spi(connection_t *c, bool prospective)
-{
-       /* note: these are in host order :-( */
-       static const ipsec_spi_t shunt_spi[] =
-       {
-               SPI_TRAP,       /* --initiateontraffic */
-               SPI_PASS,       /* --pass */
-               SPI_DROP,       /* --drop */
-               SPI_REJECT,     /* --reject */
-       };
-
-       static const ipsec_spi_t fail_spi[] =
-       {
-               0,      /* --none*/
-               SPI_PASS,       /* --failpass */
-               SPI_DROP,       /* --faildrop */
-               SPI_REJECT,     /* --failreject */
-       };
-
-       return prospective
-               ? shunt_spi[(c->policy & POLICY_SHUNT_MASK) >> POLICY_SHUNT_SHIFT]
-               : fail_spi[(c->policy & POLICY_FAIL_MASK) >> POLICY_FAIL_SHIFT];
-}
-
-/* Add/replace/delete a shunt eroute.
- * Such an eroute determines the fate of packets without the use
- * of any SAs.  These are defaults, in effect.
- * If a negotiation has not been attempted, use %trap.
- * If negotiation has failed, the choice between %trap/%pass/%drop/%reject
- * is specified in the policy of connection c.
- */
-static bool shunt_eroute(connection_t *c, struct spd_route *sr,
-                                                enum routing_t rt_kind,
-                                                unsigned int op, const char *opname)
-{
-       /* We are constructing a special SAID for the eroute.
-        * The destination doesn't seem to matter, but the family does.
-        * The protocol is SA_INT -- mark this as shunt.
-        * The satype has no meaning, but is required for PF_KEY header!
-        * The SPI signifies the kind of shunt.
-        */
-       ipsec_spi_t spi = shunt_policy_spi(c, rt_kind == RT_ROUTED_PROSPECTIVE);
-
-       if (spi == 0)
-       {
-               /* we're supposed to end up with no eroute: rejig op and opname */
-               switch (op)
-               {
-               case ERO_REPLACE:
-                       /* replace with nothing == delete */
-                       op = ERO_DELETE;
-                       opname = "delete";
-                       break;
-               case ERO_ADD:
-                       /* add nothing == do nothing */
-                       return TRUE;
-               case ERO_DELETE:
-                       /* delete remains delete */
-                       break;
-               default:
-                       bad_case(op);
-               }
-       }
-       if (sr->routing == RT_ROUTED_ECLIPSED && c->kind == CK_TEMPLATE)
-       {
-               /* We think that we have an eroute, but we don't.
-                * Adjust the request and account for eclipses.
-                */
-               passert(eclipsable(sr));
-               switch (op)
-               {
-               case ERO_REPLACE:
-                       /* really an add */
-                       op = ERO_ADD;
-                       opname = "replace eclipsed";
-                       eclipse_count--;
-                       break;
-               case ERO_DELETE:
-                       /* delete unnecessary: we don't actually have an eroute */
-                       eclipse_count--;
-                       return TRUE;
-               case ERO_ADD:
-               default:
-                       bad_case(op);
-               }
-       }
-       else if (eclipse_count > 0 && op == ERO_DELETE && eclipsable(sr))
-       {
-               /* maybe we are uneclipsing something */
-               struct spd_route *esr;
-               connection_t *ue = eclipsed(c, &esr);
-
-               if (ue != NULL)
-               {
-                       esr->routing = RT_ROUTED_PROSPECTIVE;
-                       return shunt_eroute(ue, esr
-                                                               , RT_ROUTED_PROSPECTIVE, ERO_REPLACE, "restoring eclipsed");
-               }
-       }
-
-       return eroute_connection(sr, htonl(spi), SA_INT, SADB_X_SATYPE_INT,
-                                                        &null_ipsec_sa, op, opname);
-}
-
-static bool setup_half_ipsec_sa(struct state *st, bool inbound)
-{
-       host_t *host_src, *host_dst;
-       connection_t *c = st->st_connection;
-       struct end *src, *dst;
-       ipsec_mode_t mode = MODE_TRANSPORT;
-       ipsec_sa_cfg_t sa = { .mode = 0 };
-       lifetime_cfg_t lt_none = { .time = { .rekey = 0 } };
-       mark_t mark;
-       bool ok = TRUE;
-       /* SPIs, saved for undoing, if necessary */
-       struct kernel_sa said[EM_MAXRELSPIS], *said_next = said;
-       if (inbound)
-       {
-               src = &c->spd.that;
-               dst = &c->spd.this;
-               mark = c->spd.mark_in;
-       }
-       else
-       {
-               src = &c->spd.this;
-               dst = &c->spd.that;
-               mark = c->spd.mark_out;
-       }
-
-       host_src = host_create_from_sockaddr((sockaddr_t*)&src->host_addr);
-       host_dst = host_create_from_sockaddr((sockaddr_t*)&dst->host_addr);
-
-       if (st->st_ah.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL
-               || st->st_esp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL
-               || st->st_ipcomp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)
-       {
-               mode = MODE_TUNNEL;
-       }
-
-       sa.mode = mode;
-       sa.reqid = c->spd.reqid;
-
-       memset(said, 0, sizeof(said));
-
-       /* set up IPCOMP SA, if any */
-
-       if (st->st_ipcomp.present)
-       {
-               ipsec_spi_t ipcomp_spi = inbound ? st->st_ipcomp.our_spi
-                                                                                : st->st_ipcomp.attrs.spi;
-
-               switch (st->st_ipcomp.attrs.transid)
-               {
-                       case IPCOMP_DEFLATE:
-                               break;
-
-                       default:
-                               loglog(RC_LOG_SERIOUS, "IPCOMP transform %s not implemented",
-                                          enum_name(&ipcomp_transformid_names,
-                                                                st->st_ipcomp.attrs.transid));
-                               goto fail;
-               }
-
-               sa.ipcomp.cpi = htons(ntohl(ipcomp_spi));
-               sa.ipcomp.transform = st->st_ipcomp.attrs.transid;
-
-               said_next->spi = ipcomp_spi;
-               said_next->proto = IPPROTO_COMP;
-
-               if (hydra->kernel_interface->add_sa(hydra->kernel_interface, host_src,
-                                               host_dst, ipcomp_spi, said_next->proto, c->spd.reqid,
-                                               mark, 0, &lt_none, ENCR_UNDEFINED, chunk_empty,
-                                               AUTH_UNDEFINED, chunk_empty, mode,
-                                               st->st_ipcomp.attrs.transid, 0 /* cpi */, FALSE, FALSE,
-                                               inbound, NULL, NULL) != SUCCESS)
-               {
-                       goto fail;
-               }
-               said_next++;
-               mode = MODE_TRANSPORT;
-       }
-
-       /* set up ESP SA, if any */
-
-       if (st->st_esp.present)
-       {
-               ipsec_spi_t esp_spi = inbound ? st->st_esp.our_spi
-                                                                         : st->st_esp.attrs.spi;
-               u_char *esp_dst_keymat = inbound ? st->st_esp.our_keymat
-                                                                                : st->st_esp.peer_keymat;
-               bool encap = st->nat_traversal & NAT_T_DETECTED;
-               encryption_algorithm_t enc_alg;
-               integrity_algorithm_t auth_alg;
-               const struct esp_info *ei;
-               chunk_t enc_key, auth_key;
-               u_int16_t key_len;
-
-               if ((ei = kernel_alg_esp_info(st->st_esp.attrs.transid,
-                                                                         st->st_esp.attrs.auth)) == NULL)
-               {
-                       loglog(RC_LOG_SERIOUS, "ESP transform %s / auth %s"
-                                  " not implemented yet",
-                                  enum_name(&esp_transform_names, st->st_esp.attrs.transid),
-                                  enum_name(&auth_alg_names, st->st_esp.attrs.auth));
-                       goto fail;
-               }
-
-               key_len = st->st_esp.attrs.key_len / 8;
-               if (key_len)
-               {
-                       /* XXX: must change to check valid _range_ key_len */
-                       if (key_len > ei->enckeylen)
-                       {
-                               loglog(RC_LOG_SERIOUS, "ESP transform %s: key_len=%d > %d",
-                                       enum_name(&esp_transform_names, st->st_esp.attrs.transid),
-                                       (int)key_len, (int)ei->enckeylen);
-                               goto fail;
-                       }
-               }
-               else
-               {
-                       key_len = ei->enckeylen;
-               }
-
-               switch (ei->transid)
-               {
-                       case ESP_3DES:
-                               /* 168 bits in kernel, need 192 bits for keymat_len */
-                               if (key_len == 21)
-                               {
-                                       key_len = 24;
-                               }
-                               break;
-                       case ESP_DES:
-                               /* 56 bits in kernel, need 64 bits for keymat_len */
-                               if (key_len == 7)
-                               {
-                                       key_len = 8;
-                               }
-                               break;
-                       case ESP_AES_CCM_8:
-                       case ESP_AES_CCM_12:
-                       case ESP_AES_CCM_16:
-                               key_len += 3;
-                               break;
-                       case ESP_AES_GCM_8:
-                       case ESP_AES_GCM_12:
-                       case ESP_AES_GCM_16:
-                       case ESP_AES_CTR:
-                       case ESP_AES_GMAC:
-                               key_len += 4;
-                               break;
-                       default:
-                               break;
-               }
-
-               if (encap)
-               {
-                       host_src->set_port(host_src, src->host_port);
-                       host_dst->set_port(host_dst, dst->host_port);
-                       // st->nat_oa is currently unused
-               }
-
-               /* divide up keying material */
-               enc_alg = encryption_algorithm_from_esp(st->st_esp.attrs.transid);
-               enc_key.ptr = esp_dst_keymat;
-               enc_key.len = key_len;
-               auth_alg = integrity_algorithm_from_esp(st->st_esp.attrs.auth);
-               auth_alg = auth_alg ? : AUTH_UNDEFINED;
-               auth_key.ptr = esp_dst_keymat + key_len;
-               auth_key.len = ei->authkeylen;
-
-               sa.esp.use = TRUE;
-               sa.esp.spi = esp_spi;
-
-               said_next->spi = esp_spi;
-               said_next->proto = IPPROTO_ESP;
-
-               if (hydra->kernel_interface->add_sa(hydra->kernel_interface, host_src,
-                                               host_dst, esp_spi, said_next->proto, c->spd.reqid,
-                                               mark, 0, &lt_none, enc_alg, enc_key,
-                                               auth_alg, auth_key, mode, IPCOMP_NONE, 0 /* cpi */,
-                                               encap, FALSE, inbound, NULL, NULL) != SUCCESS)
-               {
-                       goto fail;
-               }
-               said_next++;
-               mode = MODE_TRANSPORT;
-       }
-
-       /* set up AH SA, if any */
-
-       if (st->st_ah.present)
-       {
-               ipsec_spi_t ah_spi = inbound ? st->st_ah.our_spi
-                                                                        : st->st_ah.attrs.spi;
-               u_char *ah_dst_keymat = inbound ? st->st_ah.our_keymat
-                                                                               : st->st_ah.peer_keymat;
-               integrity_algorithm_t auth_alg;
-               chunk_t auth_key;
-
-               auth_alg = integrity_algorithm_from_esp(st->st_ah.attrs.auth);
-               auth_key.ptr = ah_dst_keymat;
-               auth_key.len = st->st_ah.keymat_len;
-
-               sa.ah.use = TRUE;
-               sa.ah.spi = ah_spi;
-
-               said_next->spi = ah_spi;
-               said_next->proto = IPPROTO_AH;
-
-               if (hydra->kernel_interface->add_sa(hydra->kernel_interface, host_src,
-                                               host_dst, ah_spi, said_next->proto, c->spd.reqid,
-                                               mark, 0, &lt_none, ENCR_UNDEFINED, chunk_empty,
-                                               auth_alg, auth_key, mode, IPCOMP_NONE, 0 /* cpi */,
-                                               FALSE, FALSE, inbound, NULL, NULL) != SUCCESS)
-               {
-                       goto fail;
-               }
-               said_next++;
-               mode = MODE_TRANSPORT;
-       }
-
-       goto cleanup;
-
-fail:
-       /* undo the done SPIs */
-       while (said_next-- != said)
-       {
-               hydra->kernel_interface->del_sa(hydra->kernel_interface, host_src,
-                                                                               host_dst, said_next->spi,
-                                                                               said_next->proto, 0 /* cpi */,
-                                                                               mark);
-       }
-       ok = FALSE;
-
-cleanup:
-       host_src->destroy(host_src);
-       host_dst->destroy(host_dst);
-       return ok;
-}
-
-static bool teardown_half_ipsec_sa(struct state *st, bool inbound)
-{
-       connection_t *c = st->st_connection;
-       const struct end *src, *dst;
-       host_t *host_src, *host_dst;
-       ipsec_spi_t spi;
-       mark_t mark;
-       bool result = TRUE;
-
-       if (inbound)
-       {
-               src = &c->spd.that;
-               dst = &c->spd.this;
-               mark = c->spd.mark_in;
-       }
-       else
-       {
-               src = &c->spd.this;
-               dst = &c->spd.that;
-               mark = c->spd.mark_out;
-       }
-
-       host_src = host_create_from_sockaddr((sockaddr_t*)&src->host_addr);
-       host_dst = host_create_from_sockaddr((sockaddr_t*)&dst->host_addr);
-
-       if (st->st_ah.present)
-       {
-               spi = inbound ? st->st_ah.our_spi : st->st_ah.attrs.spi;
-               result &= hydra->kernel_interface->del_sa(hydra->kernel_interface,
-                                                               host_src, host_dst, spi, IPPROTO_AH,
-                                                               0 /* cpi */, mark) == SUCCESS;
-       }
-
-       if (st->st_esp.present)
-       {
-               spi = inbound ? st->st_esp.our_spi : st->st_esp.attrs.spi;
-               result &= hydra->kernel_interface->del_sa(hydra->kernel_interface,
-                                                               host_src, host_dst, spi, IPPROTO_ESP,
-                                                               0 /* cpi */, mark) == SUCCESS;
-       }
-
-       if (st->st_ipcomp.present)
-       {
-               spi = inbound ? st->st_ipcomp.our_spi : st->st_ipcomp.attrs.spi;
-               result &= hydra->kernel_interface->del_sa(hydra->kernel_interface,
-                                                               host_src, host_dst, spi, IPPROTO_COMP,
-                                                               0 /* cpi */, mark) == SUCCESS;
-       }
-
-       host_src->destroy(host_src);
-       host_dst->destroy(host_dst);
-
-       return result;
-}
-
-/*
- * get information about a given sa
- */
-bool get_sa_info(struct state *st, bool inbound, u_int *bytes, time_t *use_time)
-{
-       connection_t *c = st->st_connection;
-       traffic_selector_t *ts_src = NULL, *ts_dst = NULL;
-       host_t *host_src = NULL, *host_dst = NULL;
-       const struct end *src, *dst;
-       ipsec_spi_t spi;
-       mark_t mark;
-       u_int64_t bytes_kernel = 0;
-       bool result = FALSE;
-
-       *use_time = UNDEFINED_TIME;
-
-       if (!st->st_esp.present)
-       {
-               goto failed;
-       }
-
-       if (inbound)
-       {
-               src = &c->spd.that;
-               dst = &c->spd.this;
-               mark = c->spd.mark_in;
-               spi = st->st_esp.our_spi;
-       }
-       else
-       {
-               src = &c->spd.this;
-               dst = &c->spd.that;
-               mark = c->spd.mark_out;
-               spi = st->st_esp.attrs.spi;
-       }
-
-       host_src = host_create_from_sockaddr((sockaddr_t*)&src->host_addr);
-       host_dst = host_create_from_sockaddr((sockaddr_t*)&dst->host_addr);
-
-       switch(hydra->kernel_interface->query_sa(hydra->kernel_interface, host_src,
-                                                                                        host_dst, spi, IPPROTO_ESP,
-                                                                                        mark, &bytes_kernel))
-       {
-               case FAILED:
-                       goto failed;
-               case SUCCESS:
-                       *bytes = bytes_kernel;
-                       break;
-               case NOT_SUPPORTED:
-               default:
-                       break;
-       }
-
-       if (st->st_serialno == c->spd.eroute_owner)
-       {
-               u_int32_t time_kernel;
-
-               ts_src = traffic_selector_from_subnet(&src->client, src->protocol);
-               ts_dst = traffic_selector_from_subnet(&dst->client, dst->protocol);
-
-               if (hydra->kernel_interface->query_policy(hydra->kernel_interface,
-                                                       ts_src, ts_dst, inbound ? POLICY_IN : POLICY_OUT,
-                                                       mark, &time_kernel) != SUCCESS)
-               {
-                       goto failed;
-               }
-               *use_time = time_kernel;
-
-               if (inbound &&
-                       st->st_esp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)
-               {
-                       if (hydra->kernel_interface->query_policy(hydra->kernel_interface,
-                                                       ts_src, ts_dst, POLICY_FWD, mark,
-                                                       &time_kernel) != SUCCESS)
-                       {
-                               goto failed;
-                       }
-                       *use_time = max(*use_time, time_kernel);
-               }
-       }
-
-       result = TRUE;
-
-failed:
-       DESTROY_IF(host_src);
-       DESTROY_IF(host_dst);
-       DESTROY_IF(ts_src);
-       DESTROY_IF(ts_dst);
-       return result;
-}
-
-/**
- * Handler for kernel events (called by thread-pool thread)
- */
-kernel_listener_t *kernel_handler;
-
-/**
- * Data for acquire events
- */
-typedef struct {
-       /** Subnets */
-       ip_subnet src, dst;
-       /** Transport protocol */
-       int proto;
-} acquire_data_t;
-
-/**
- * Callback for acquire events (called by main thread)
- */
-void handle_acquire(acquire_data_t *this)
-{
-       record_and_initiate_opportunistic(&this->src, &this->dst, this->proto,
-                                                                         "%acquire");
-}
-
-METHOD(kernel_listener_t, acquire, bool,
-          kernel_listener_t *this, u_int32_t reqid,
-          traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
-{
-       if (src_ts && dst_ts)
-       {
-               acquire_data_t *data;
-               DBG(DBG_CONTROL,
-                       DBG_log("creating acquire event for policy %R === %R "
-                                       "with reqid {%u}", src_ts, dst_ts, reqid));
-               INIT(data,
-                       .src = subnet_from_traffic_selector(src_ts),
-                       .dst = subnet_from_traffic_selector(dst_ts),
-                       .proto = src_ts->get_protocol(src_ts),
-               );
-               pluto->events->queue(pluto->events, (void*)handle_acquire, data, free);
-       }
-       else
-       {
-               DBG(DBG_CONTROL,
-                       DBG_log("ignoring acquire without traffic selectors for policy "
-                                       "with reqid {%u}", reqid));
-       }
-       DESTROY_IF(src_ts);
-       DESTROY_IF(dst_ts);
-       return TRUE;
-}
-
-/**
- * Data for mapping events
- */
-typedef struct {
-       /** reqid, spi of affected SA */
-       u_int32_t reqid, spi;
-       /** new endpont */
-       ip_address new_end;
-} mapping_data_t;
-
-/**
- * Callback for mapping events (called by main thread)
- */
-void handle_mapping(mapping_data_t *this)
-{
-       process_nat_t_new_mapping(this->reqid, this->spi, &this->new_end);
-}
-
-
-METHOD(kernel_listener_t, mapping, bool,
-          kernel_listener_t *this, u_int32_t reqid, u_int32_t spi, host_t *remote)
-{
-       mapping_data_t *data;
-       DBG(DBG_CONTROL,
-               DBG_log("creating mapping event for SA with SPI %.8x and reqid {%u}",
-                               spi, reqid));
-       INIT(data,
-               .reqid = reqid,
-               .spi = spi,
-               .new_end = *(ip_address*)remote->get_sockaddr(remote),
-       );
-       pluto->events->queue(pluto->events, (void*)handle_mapping, data, free);
-       return TRUE;
-}
-
-void init_kernel(void)
-{
-       /* register SA types that we can negotiate */
-       can_do_IPcomp = FALSE;  /* until we get a response from the kernel */
-       pfkey_register();
-
-       INIT(kernel_handler,
-               .acquire = _acquire,
-               .mapping = _mapping,
-       );
-       hydra->kernel_interface->add_listener(hydra->kernel_interface,
-                                                                                 kernel_handler);
-}
-
-void kernel_finalize()
-{
-       hydra->kernel_interface->remove_listener(hydra->kernel_interface,
-                                                                                        kernel_handler);
-       free(kernel_handler);
-}
-
-/* Note: install_inbound_ipsec_sa is only used by the Responder.
- * The Responder will subsequently use install_ipsec_sa for the outbound.
- * The Initiator uses install_ipsec_sa to install both at once.
- */
-bool install_inbound_ipsec_sa(struct state *st)
-{
-       connection_t *const c = st->st_connection;
-
-       /* If our peer has a fixed-address client, check if we already
-        * have a route for that client that conflicts.  We will take this
-        * as proof that that route and the connections using it are
-        * obsolete and should be eliminated.  Interestingly, this is
-        * the only case in which we can tell that a connection is obsolete.
-        */
-       passert(c->kind == CK_PERMANENT || c->kind == CK_INSTANCE);
-       if (c->spd.that.has_client)
-       {
-               for (;;)
-               {
-                       struct spd_route *esr;
-                       connection_t *o = route_owner(c, &esr, NULL, NULL);
-
-                       if (o == NULL)
-                       {
-                               break;  /* nobody has a route */
-                       }
-
-                       /* note: we ignore the client addresses at this end */
-                       if (sameaddr(&o->spd.that.host_addr, &c->spd.that.host_addr) &&
-                               o->interface == c->interface)
-                       {
-                               break;  /* existing route is compatible */
-                       }
-
-                       if (o->kind == CK_TEMPLATE && streq(o->name, c->name))
-                       {
-                               break;  /* ??? is this good enough?? */
-                       }
-
-                       loglog(RC_LOG_SERIOUS, "route to peer's client conflicts with \"%s\" %s; releasing old connection to free the route"
-                               , o->name, ip_str(&o->spd.that.host_addr));
-                       release_connection(o, FALSE);
-               }
-       }
-
-       DBG(DBG_CONTROL, DBG_log("install_inbound_ipsec_sa() checking if we can route"));
-       /* check that we will be able to route and eroute */
-       switch (could_route(c))
-       {
-               case route_easy:
-               case route_nearconflict:
-                       break;
-               default:
-                       return FALSE;
-       }
-
-       /* (attempt to) actually set up the SAs */
-       return setup_half_ipsec_sa(st, TRUE);
-}
-
-/* Install a route and then a prospective shunt eroute or an SA group eroute.
- * Assumption: could_route gave a go-ahead.
- * Any SA Group must have already been created.
- * On failure, steps will be unwound.
- */
-bool route_and_eroute(connection_t *c, struct spd_route *sr, struct state *st)
-{
-       struct spd_route *esr;
-       struct spd_route *rosr;
-       connection_t *ero      /* who, if anyone, owns our eroute? */
-               , *ro = route_owner(c, &rosr, &ero, &esr);
-       bool eroute_installed = FALSE
-               , firewall_notified = FALSE
-               , route_installed = FALSE;
-
-       connection_t *ero_top;
-
-       DBG(DBG_CONTROLMORE,
-               DBG_log("route_and_eroute with c: %s (next: %s) ero:%s esr:{%p} ro:%s rosr:{%p} and state: %lu"
-                               , c->name
-                               , (c->policy_next ? c->policy_next->name : "none")
-                               , ero ? ero->name : "null"
-                               , esr
-                               , ro ? ro->name : "null"
-                               , rosr
-                               , st ? st->st_serialno : 0));
-
-       /* look along the chain of policies for one with the same name */
-       ero_top = ero;
-
-#if 0
-       /* XXX - mcr this made sense before, and likely will make sense
-        * again, so I'l leaving this to remind me what is up */
-       if (ero!= NULL && ero->routing == RT_UNROUTED_KEYED)
-               ero = NULL;
-
-       for (ero2 = ero; ero2 != NULL; ero2 = ero->policy_next)
-               if ((ero2->kind == CK_TEMPLATE || ero2->kind==CK_SECONDARY)
-               && streq(ero2->name, c->name))
-                       break;
-#endif
-
-       /* install the eroute */
-
-       if (ero != NULL)
-       {
-               /* We're replacing an eroute */
-
-               /* if no state provided, then install a shunt for later */
-               if (st == NULL)
-               {
-                       eroute_installed = shunt_eroute(c, sr, RT_ROUTED_PROSPECTIVE
-                                                                                       , ERO_REPLACE, "replace");
-               }
-               else
-               {
-                       eroute_installed = sag_eroute(st, sr, ERO_REPLACE, "replace");
-               }
-#if 0
-               /* XXX - MCR. I previously felt that this was a bogus check */
-               if (ero != NULL && ero != c && esr != sr)
-               {
-                       /* By elimination, we must be eclipsing ero.  Check. */
-                       passert(ero->kind == CK_TEMPLATE && streq(ero->name, c->name));
-                       passert(LHAS(LELEM(RT_ROUTED_PROSPECTIVE) | LELEM(RT_ROUTED_ECLIPSED)
-                               , esr->routing));
-                       passert(samesubnet(&esr->this.client, &sr->this.client)
-                               && samesubnet(&esr->that.client, &sr->that.client));
-               }
-#endif
-       }
-       else
-       {
-               /* we're adding an eroute */
-
-               /* if no state provided, then install a shunt for later */
-               if (st == NULL)
-               {
-                       eroute_installed = shunt_eroute(c, sr, RT_ROUTED_PROSPECTIVE
-                                                                                       , ERO_ADD, "add");
-               }
-               else
-               {
-                       eroute_installed = sag_eroute(st, sr, ERO_ADD, "add");
-               }
-       }
-
-       /* notify the firewall of a new tunnel */
-
-       if (eroute_installed)
-       {
-               /* do we have to notify the firewall?  Yes, if we are installing
-                * a tunnel eroute and the firewall wasn't notified
-                * for a previous tunnel with the same clients.  Any Previous
-                * tunnel would have to be for our connection, so the actual
-                * test is simple.
-                */
-               firewall_notified = st == NULL  /* not a tunnel eroute */
-                       || sr->eroute_owner != SOS_NOBODY   /* already notified */
-                       || do_command(c, sr, st, "up"); /* go ahead and notify */
-       }
-
-       /* install the route */
-
-       DBG(DBG_CONTROL,
-               DBG_log("route_and_eroute: firewall_notified: %s"
-                               , firewall_notified ? "true" : "false"));
-       if (!firewall_notified)
-       {
-               /* we're in trouble -- don't do routing */
-       }
-       else if (ro == NULL)
-       {
-               /* a new route: no deletion required, but preparation is */
-               (void) do_command(c, sr, st, "prepare");    /* just in case; ignore failure */
-               route_installed = do_command(c, sr, st, "route");
-       }
-       else if (routed(sr->routing) || routes_agree(ro, c))
-       {
-               route_installed = TRUE; /* nothing to be done */
-       }
-       else
-       {
-               /* Some other connection must own the route
-                * and the route must disagree.  But since could_route
-                * must have allowed our stealing it, we'll do so.
-                *
-                * A feature of LINUX allows us to install the new route
-                * before deleting the old if the nexthops differ.
-                * This reduces the "window of vulnerability" when packets
-                * might flow in the clear.
-                */
-               if (sameaddr(&sr->this.host_nexthop, &esr->this.host_nexthop))
-               {
-                       (void) do_command(ro, sr, st, "unroute");
-                       route_installed = do_command(c, sr, st, "route");
-               }
-               else
-               {
-                       route_installed = do_command(c, sr, st, "route");
-                       (void) do_command(ro, sr, st, "unroute");
-               }
-
-               /* record unrouting */
-               if (route_installed)
-               {
-                       do {
-                               passert(!erouted(rosr->routing));
-                               rosr->routing = RT_UNROUTED;
-
-                               /* no need to keep old value */
-                               ro = route_owner(c, &rosr, NULL, NULL);
-                       } while (ro != NULL);
-               }
-       }
-
-       /* all done -- clean up */
-       if (route_installed)
-       {
-               /* Success! */
-
-               if (ero != NULL && ero != c)
-               {
-                       /* check if ero is an ancestor of c. */
-                       connection_t *ero2;
-
-                       for (ero2 = c; ero2 != NULL && ero2 != c; ero2 = ero2->policy_next)
-                               ;
-
-                       if (ero2 == NULL)
-                       {
-                               /* By elimination, we must be eclipsing ero.  Checked above. */
-                               if (ero->spd.routing != RT_ROUTED_ECLIPSED)
-                               {
-                                       ero->spd.routing = RT_ROUTED_ECLIPSED;
-                                       eclipse_count++;
-                               }
-                       }
-               }
-
-               if (st == NULL)
-               {
-                       passert(sr->eroute_owner == SOS_NOBODY);
-                       sr->routing = RT_ROUTED_PROSPECTIVE;
-               }
-               else
-               {
-                       char cib[CONN_INST_BUF];
-                       sr->routing = RT_ROUTED_TUNNEL;
-
-                       DBG(DBG_CONTROL,
-                               DBG_log("route_and_eroute: instance \"%s\"%s, setting eroute_owner {spd=%p,sr=%p} to #%ld (was #%ld) (newest_ipsec_sa=#%ld)"
-                                               , st->st_connection->name
-                                               , (fmt_conn_instance(st->st_connection, cib), cib)
-                                               , &st->st_connection->spd, sr
-                                               , st->st_serialno
-                                               , sr->eroute_owner
-                                               , st->st_connection->newest_ipsec_sa));
-                       sr->eroute_owner = st->st_serialno;
-               }
-
-               return TRUE;
-       }
-       else
-       {
-               /* Failure!  Unwind our work. */
-               if (firewall_notified && sr->eroute_owner == SOS_NOBODY)
-                       (void) do_command(c, sr, st, "down");
-
-               if (eroute_installed)
-               {
-                       /* Restore original eroute, if we can.
-                        * Since there is nothing much to be done if the restoration
-                        * fails, ignore success or failure.
-                        */
-                       if (ero != NULL)
-                       {
-                               /* restore ero's former glory */
-                               if (esr->eroute_owner == SOS_NOBODY)
-                               {
-                                       /* note: normal or eclipse case */
-                                       (void) shunt_eroute(ero, esr
-                                                                               , esr->routing, ERO_REPLACE, "restore");
-                               }
-                               else
-                               {
-                                       /* Try to find state that owned eroute.
-                                        * Don't do anything if it cannot be found.
-                                        * This case isn't likely since we don't run
-                                        * the updown script when replacing a SA group
-                                        * with its successor (for the same conn).
-                                        */
-                                       struct state *ost = state_with_serialno(esr->eroute_owner);
-
-                                       if (ost != NULL)
-                                               (void) sag_eroute(ost, esr, ERO_REPLACE, "restore");
-                               }
-                       }
-                       else
-                       {
-                               /* there was no previous eroute: delete whatever we installed */
-                               if (st == NULL)
-                               {
-                                       (void) shunt_eroute(c, sr, sr->routing, ERO_DELETE, "delete");
-                               }
-                               else
-                               {
-                                       (void) sag_eroute(st, sr, ERO_DELETE, "delete");
-                               }
-                       }
-               }
-
-               return FALSE;
-       }
-}
-
-bool install_ipsec_sa(struct state *st, bool inbound_also)
-{
-       struct spd_route *sr;
-
-       DBG(DBG_CONTROL, DBG_log("install_ipsec_sa() for #%ld: %s"
-                                                        , st->st_serialno
-                                                        , inbound_also?
-                                                        "inbound and outbound" : "outbound only"));
-
-       switch (could_route(st->st_connection))
-       {
-               case route_easy:
-               case route_nearconflict:
-                       break;
-               default:
-                       return FALSE;
-       }
-
-       /* (attempt to) actually set up the SA group */
-       if ((inbound_also && !setup_half_ipsec_sa(st, TRUE)) ||
-               !setup_half_ipsec_sa(st, FALSE))
-       {
-               return FALSE;
-       }
-
-       for (sr = &st->st_connection->spd; sr != NULL; sr = sr->next)
-       {
-               DBG(DBG_CONTROL, DBG_log("sr for #%ld: %s"
-                                                                , st->st_serialno
-                                                                , enum_name(&routing_story, sr->routing)));
-
-               /*
-                * if the eroute owner is not us, then make it us.
-                * See test co-terminal-02, pluto-rekey-01, pluto-unit-02/oppo-twice
-                */
-               pexpect(sr->eroute_owner == SOS_NOBODY
-                               || sr->routing >= RT_ROUTED_TUNNEL);
-
-               if (sr->eroute_owner != st->st_serialno
-                       && sr->routing != RT_UNROUTED_KEYED)
-               {
-                       if (!route_and_eroute(st->st_connection, sr, st))
-                       {
-                               delete_ipsec_sa(st, FALSE);
-                               /* XXX go and unroute any SRs that were successfully
-                                * routed already.
-                                */
-                               return FALSE;
-                       }
-               }
-       }
-
-       return TRUE;
-}
-
-/* delete an IPSEC SA.
- * we may not succeed, but we bull ahead anyway because
- * we cannot do anything better by recognizing failure
- */
-void delete_ipsec_sa(struct state *st, bool inbound_only)
-{
-       if (!inbound_only)
-       {
-               /* If the state is the eroute owner, we must adjust
-                * the routing for the connection.
-                */
-               connection_t *c = st->st_connection;
-               struct spd_route *sr;
-
-               passert(st->st_connection);
-
-               for (sr = &c->spd; sr; sr = sr->next)
-               {
-                       if (sr->eroute_owner == st->st_serialno
-                       && sr->routing == RT_ROUTED_TUNNEL)
-                       {
-                               sr->eroute_owner = SOS_NOBODY;
-
-                               /* Routing should become RT_ROUTED_FAILURE,
-                                * but if POLICY_FAIL_NONE, then we just go
-                                * right back to RT_ROUTED_PROSPECTIVE as if no
-                                * failure happened.
-                                */
-                               sr->routing = (c->policy & POLICY_FAIL_MASK) == POLICY_FAIL_NONE
-                                       ? RT_ROUTED_PROSPECTIVE : RT_ROUTED_FAILURE;
-
-                               (void) do_command(c, sr, st, "down");
-                               if ((c->policy & POLICY_DONT_REKEY)     && c->kind == CK_INSTANCE)
-                               {
-                                       /* in this special case, even if the connection
-                                        * is still alive (due to an ISAKMP SA),
-                                        * we get rid of routing.
-                                        * Even though there is still an eroute, the c->routing
-                                        * setting will convince unroute_connection to delete it.
-                                        * unroute_connection would be upset if c->routing == RT_ROUTED_TUNNEL
-                                        */
-                                       unroute_connection(c);
-                               }
-                               else
-                               {
-                                       (void) shunt_eroute(c, sr, sr->routing, ERO_REPLACE, "replace with shunt");
-                               }
-                       }
-               }
-               (void) teardown_half_ipsec_sa(st, FALSE);
-       }
-       (void) teardown_half_ipsec_sa(st, TRUE);
-}
-
-static bool update_nat_t_ipsec_esp_sa (struct state *st, bool inbound)
-{
-       connection_t *c = st->st_connection;
-       host_t *host_src, *host_dst, *new_src, *new_dst;
-       ipsec_spi_t spi = inbound ? st->st_esp.our_spi : st->st_esp.attrs.spi;
-       struct end *src = inbound ? &c->spd.that : &c->spd.this,
-                          *dst = inbound ? &c->spd.this : &c->spd.that;
-       mark_t mark = inbound ? c->spd.mark_in : c->spd.mark_out;
-       bool result;
-
-       host_src = host_create_from_sockaddr((sockaddr_t*)&src->host_addr);
-       host_dst = host_create_from_sockaddr((sockaddr_t*)&dst->host_addr);
-
-       new_src = host_src->clone(host_src);
-       new_dst = host_dst->clone(host_dst);
-       new_src->set_port(new_src, src->host_port);
-       new_dst->set_port(new_dst, dst->host_port);
-
-       result = hydra->kernel_interface->update_sa(hydra->kernel_interface,
-                                       spi, IPPROTO_ESP, 0 /* cpi */, host_src, host_dst,
-                                       new_src, new_dst, TRUE /* encap */, TRUE /* new_encap */,
-                                       mark) == SUCCESS;
-
-       host_src->destroy(host_src);
-       host_dst->destroy(host_dst);
-       new_src->destroy(new_src);
-       new_dst->destroy(new_dst);
-
-       return result;
-}
-
-bool update_ipsec_sa (struct state *st)
-{
-       if (IS_IPSEC_SA_ESTABLISHED(st->st_state))
-       {
-               if (st->st_esp.present && (
-                  (!update_nat_t_ipsec_esp_sa (st, TRUE)) ||
-                  (!update_nat_t_ipsec_esp_sa (st, FALSE))))
-               {
-                       return FALSE;
-               }
-       }
-       else if (IS_ONLY_INBOUND_IPSEC_SA_ESTABLISHED(st->st_state))
-       {
-               if (st->st_esp.present && !update_nat_t_ipsec_esp_sa (st, FALSE))
-               {
-                       return FALSE;
-               }
-       }
-       else
-       {
-               DBG_log("assert failed at %s:%d st_state=%d", __FILE__, __LINE__, st->st_state);
-               return FALSE;
-       }
-       return TRUE;
-}
-
-/* Check if there was traffic on given SA during the last idle_max
- * seconds. If TRUE, the SA was idle and DPD exchange should be performed.
- * If FALSE, DPD is not necessary. We also return TRUE for errors, as they
- * could mean that the SA is broken and needs to be replace anyway.
- */
-bool was_eroute_idle(struct state *st, time_t idle_max, time_t *idle_time)
-{
-       time_t use_time;
-       u_int bytes;
-       int ret = TRUE;
-
-       passert(st != NULL);
-
-       if (get_sa_info(st, TRUE, &bytes, &use_time) && use_time != UNDEFINED_TIME)
-       {
-               *idle_time = time_monotonic(NULL) - use_time;
-               ret = *idle_time >= idle_max;
-       }
-
-       return ret;
-}
diff --git a/src/pluto/kernel.h b/src/pluto/kernel.h
deleted file mode 100644 (file)
index 1fa11c5..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/* declarations of routines that interface with the kernel's IPsec mechanism
- * Copyright (C) 1998-2001  D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include "connections.h"
-
-extern bool can_do_IPcomp;  /* can system actually perform IPCOMP? */
-
-/* Declare eroute things early enough for uses.
- *
- * Flags are encoded above the low-order byte of verbs.
- * "real" eroutes are only outbound.  Inbound eroutes don't exist,
- * but an addflow with an INBOUND flag allows IPIP tunnels to be
- * limited to appropriate source and destination addresses.
- */
-
-#define ERO_MASK        0xFF
-#define ERO_FLAG_SHIFT  8
-
-#define ERO_DELETE      SADB_X_DELFLOW
-#define ERO_ADD SADB_X_ADDFLOW
-#define ERO_REPLACE     (SADB_X_ADDFLOW | (SADB_X_SAFLAGS_REPLACEFLOW << ERO_FLAG_SHIFT))
-
-struct pfkey_proto_info {
-               int proto;
-               int encapsulation;
-               unsigned reqid;
-};
-struct sadb_msg;
-
-struct kernel_sa {
-               const ip_address *src;
-               const ip_address *dst;
-
-               const ip_subnet *src_client;
-               const ip_subnet *dst_client;
-
-               ipsec_spi_t spi;
-               unsigned proto;
-               unsigned satype;
-               unsigned transport_proto;
-               unsigned replay_window;
-               unsigned reqid;
-
-               unsigned authalg;
-               unsigned authkeylen;
-               char *authkey;
-
-               unsigned encalg;
-               unsigned enckeylen;
-               char *enckey;
-
-               unsigned compalg;
-
-               int encapsulation;
-
-               u_int16_t natt_sport, natt_dport;
-               u_int8_t transid, natt_type;
-               ip_address *natt_oa;
-
-               const char *text_said;
-};
-
-/* A netlink header defines EM_MAXRELSPIS, the max number of SAs in a group.
- * Is there a PF_KEY equivalent?
- */
-#ifndef EM_MAXRELSPIS
-# define EM_MAXRELSPIS 4        /* AH ESP IPCOMP IPIP */
-#endif
-
-extern void record_and_initiate_opportunistic(const ip_subnet *
-                                                                                         , const ip_subnet *
-                                                                                         , int transport_proto
-                                                                                         , const char *why);
-
-extern void init_kernel(void);
-extern void kernel_finalize(void);
-
-extern bool trap_connection(struct connection *c);
-extern void unroute_connection(struct connection *c);
-
-extern bool assign_hold(struct connection *c
-                                               , struct spd_route *sr
-                                               , int transport_proto
-                                               , const ip_address *src, const ip_address *dst);
-
-extern ipsec_spi_t shunt_policy_spi(struct connection *c, bool prospective);
-
-
-struct state;   /* forward declaration of tag */
-extern ipsec_spi_t get_ipsec_spi(ipsec_spi_t avoid
-                                                                , int proto
-                                                                , struct spd_route *sr
-                                                                , bool tunnel_mode);
-extern ipsec_spi_t get_my_cpi(struct spd_route *sr, bool tunnel_mode);
-
-extern bool install_inbound_ipsec_sa(struct state *st);
-extern bool install_ipsec_sa(struct state *st, bool inbound_also);
-extern void delete_ipsec_sa(struct state *st, bool inbound_only);
-extern bool route_and_eroute(struct connection *c
-                                                        , struct spd_route *sr
-                                                        , struct state *st);
-extern bool was_eroute_idle(struct state *st, time_t idle_max
-       , time_t *idle_time);
-extern bool get_sa_info(struct state *st, bool inbound, u_int *bytes
-       , time_t *use_time);
-
-extern bool update_ipsec_sa(struct state *st);
diff --git a/src/pluto/kernel_alg.c b/src/pluto/kernel_alg.c
deleted file mode 100644 (file)
index b4b18fd..0000000
+++ /dev/null
@@ -1,663 +0,0 @@
-/* Kernel runtime algorithm handling interface
- * Copyright (C) JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
- * Copyright (C) 2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <unistd.h>
-#include <sys/queue.h>
-
-#include <pfkeyv2.h>
-#include <pfkey.h>
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "connections.h"
-#include "state.h"
-#include "packet.h"
-#include "spdb.h"
-#include "kernel.h"
-#include "kernel_alg.h"
-#include "alg_info.h"
-#include "log.h"
-#include "whack.h"
-#include "db_ops.h"
-
-/* ALG storage */
-static struct sadb_alg esp_aalg[SADB_AALG_MAX+1];
-static struct sadb_alg esp_ealg[SADB_EALG_MAX+1];
-static int esp_ealg_num = 0;
-static int esp_aalg_num = 0;
-
-#define ESP_EALG_PRESENT(algo) (((algo)<=SADB_EALG_MAX)&&(esp_ealg[(algo)].sadb_alg_id==(algo)))
-#define ESP_EALG_FOR_EACH_UPDOWN(algo) \
-               for (algo=SADB_EALG_MAX; algo >0 ; algo--) \
-                               if (ESP_EALG_PRESENT(algo))
-#define ESP_AALG_PRESENT(algo) ((algo<=SADB_AALG_MAX)&&(esp_aalg[(algo)].sadb_alg_id==(algo)))
-#define ESP_AALG_FOR_EACH_UPDOWN(algo) \
-               for (algo=SADB_AALG_MAX; algo >0 ; algo--) \
-                               if (ESP_AALG_PRESENT(algo))
-
-static struct sadb_alg* sadb_alg_ptr (int satype, int exttype, int alg_id,
-                                                                         int rw)
-{
-       struct sadb_alg *alg_p = NULL;
-
-       switch (exttype)
-       {
-       case SADB_EXT_SUPPORTED_AUTH:
-               if (alg_id > SADB_AALG_MAX)
-                       return NULL;
-               break;
-       case SADB_EXT_SUPPORTED_ENCRYPT:
-               if (alg_id > SADB_EALG_MAX)
-                       return NULL;
-               break;
-       default:
-               return NULL;
-       }
-
-       switch (satype)
-       {
-       case SADB_SATYPE_ESP:
-               alg_p = (exttype == SADB_EXT_SUPPORTED_ENCRYPT)?
-                                       &esp_ealg[alg_id] : &esp_aalg[alg_id];
-               /* get for write: increment elem count */
-               if (rw)
-               {
-                       (exttype == SADB_EXT_SUPPORTED_ENCRYPT)?
-                               esp_ealg_num++ : esp_aalg_num++;
-               }
-               break;
-       case SADB_SATYPE_AH:
-       default:
-               return NULL;
-       }
-
-       return alg_p;
-}
-
-const struct sadb_alg* kernel_alg_sadb_alg_get(int satype, int exttype,
-                                                                                          int alg_id)
-{
-       return sadb_alg_ptr(satype, exttype, alg_id, 0);
-}
-
-/*
- *      Forget previous registration
- */
-static void kernel_alg_init(void)
-{
-       DBG(DBG_KERNEL,
-               DBG_log("alg_init(): memset(%p, 0, %d) memset(%p, 0, %d)",
-                               &esp_aalg,  (int)sizeof (esp_aalg),
-                               &esp_ealg,  (int)sizeof (esp_ealg))
-       )
-       memset (&esp_aalg, 0, sizeof (esp_aalg));
-       memset (&esp_ealg, 0, sizeof (esp_ealg));
-       esp_ealg_num=esp_aalg_num = 0;
-}
-
-static int kernel_alg_add(int satype, int exttype,
-                                                 const struct sadb_alg *sadb_alg)
-{
-       struct sadb_alg *alg_p = NULL;
-       int alg_id = sadb_alg->sadb_alg_id;
-
-       DBG(DBG_KERNEL,
-               DBG_log("kernel_alg_add(): satype=%d, exttype=%d, alg_id=%d",
-                               satype, exttype, sadb_alg->sadb_alg_id)
-       )
-       if (!(alg_p = sadb_alg_ptr(satype, exttype, alg_id, 1)))
-               return -1;
-
-       /* This logic "mimics" KLIPS: first algo implementation will be used */
-       if (alg_p->sadb_alg_id)
-       {
-               DBG(DBG_KERNEL,
-                       DBG_log("kernel_alg_add(): discarding already setup "
-                                       "satype=%d, exttype=%d, alg_id=%d",
-                                       satype, exttype, sadb_alg->sadb_alg_id)
-               )
-               return 0;
-       }
-       *alg_p = *sadb_alg;
-       return 1;
-}
-
-bool kernel_alg_esp_enc_ok(u_int alg_id, u_int key_len,
-                                       struct alg_info_esp *alg_info __attribute__((unused)))
-{
-       struct sadb_alg *alg_p = NULL;
-
-       /*
-        * test #1: encrypt algo must be present
-        */
-       int ret = ESP_EALG_PRESENT(alg_id);
-       if (!ret) goto out;
-
-       alg_p = &esp_ealg[alg_id];
-
-       /*
-        * test #2: if key_len specified, it must be in range
-        */
-       if (key_len
-       && (key_len < alg_p->sadb_alg_minbits || key_len > alg_p->sadb_alg_maxbits))
-       {
-               plog("kernel_alg_db_add() key_len not in range: alg_id=%d, "
-                        "key_len=%d, alg_minbits=%d, alg_maxbits=%d"
-                        , alg_id, key_len
-                        , alg_p->sadb_alg_minbits
-                        , alg_p->sadb_alg_maxbits);
-               ret = FALSE;
-       }
-
-out:
-       if (ret)
-       {
-               DBG(DBG_KERNEL,
-                       DBG_log("kernel_alg_esp_enc_ok(%d,%d): "
-                                       "alg_id=%d, "
-                                       "alg_ivlen=%d, alg_minbits=%d, alg_maxbits=%d, "
-                                       "res=%d, ret=%d"
-                                       , alg_id, key_len
-                                       , alg_p->sadb_alg_id
-                                       , alg_p->sadb_alg_ivlen
-                                       , alg_p->sadb_alg_minbits
-                                       , alg_p->sadb_alg_maxbits
-                                       , alg_p->sadb_alg_reserved
-                                       , ret);
-               )
-       }
-       else
-       {
-               DBG(DBG_KERNEL,
-                       DBG_log("kernel_alg_esp_enc_ok(%d,%d): NO", alg_id, key_len);
-               )
-       }
-       return ret;
-}
-
-/*
- * ML: make F_STRICT logic consider enc,auth algorithms
- */
-bool kernel_alg_esp_ok_final(u_int ealg, u_int key_len, u_int aalg,
-                                                        struct alg_info_esp *alg_info)
-{
-       int ealg_insecure;
-
-       /*
-        * key_len passed comes from esp_attrs read from peer
-        * For many older algorithms (eg 3DES) this key_len is fixed
-        * and get passed as 0.
-        * ... then get default key_len
-        */
-       if (key_len == 0)
-               key_len = kernel_alg_esp_enc_keylen(ealg) * BITS_PER_BYTE;
-
-       /*
-        * simple test to toss low key_len, will accept it only
-        * if specified in "esp" string
-        */
-       ealg_insecure = (key_len < 128) ;
-
-       if (ealg_insecure
-       || (alg_info && alg_info->alg_info_flags & ALG_INFO_F_STRICT))
-       {
-               int i;
-               struct esp_info *esp_info;
-
-               if (alg_info)
-               {
-                       ALG_INFO_ESP_FOREACH(alg_info, esp_info, i)
-                       {
-                               if (esp_info->esp_ealg_id == ealg
-                               && (esp_info->esp_ealg_keylen == 0 || key_len == 0
-                                       || esp_info->esp_ealg_keylen == key_len)
-                               &&  esp_info->esp_aalg_id == aalg)
-                               {
-                                       if (ealg_insecure)
-                                       {
-                                               loglog(RC_LOG_SERIOUS
-                                                       , "You should NOT use insecure ESP algorithms [%s (%d)]!"
-                                                       , enum_name(&esp_transform_names, ealg), key_len);
-                                       }
-                                       return TRUE;
-                               }
-                       }
-               }
-               plog("IPSec Transform [%s (%d), %s] refused due to %s",
-                               enum_name(&esp_transform_names, ealg), key_len,
-                               enum_name(&auth_alg_names, aalg),
-                               ealg_insecure ? "insecure key_len and enc. alg. not listed in \"esp\" string" : "strict flag");
-               return FALSE;
-       }
-       return TRUE;
-}
-
-/**
- * Load kernel_alg arrays pluto's SADB_REGISTER user by pluto/kernel.c
- */
-void kernel_alg_register_pfkey(const struct sadb_msg *msg_buf, int buflen)
-{
-       /* Trick: one 'type-mangle-able' pointer to ease offset/assign */
-       union {
-               const struct sadb_msg *msg;
-               const struct sadb_supported *supported;
-               const struct sadb_ext *ext;
-               const struct sadb_alg *alg;
-               const char *ch;
-       } sadb;
-
-       int satype;
-       int msglen;
-       int i = 0;
-
-       /* Initialize alg arrays */
-       kernel_alg_init();
-       satype = msg_buf->sadb_msg_satype;
-       sadb.msg = msg_buf;
-       msglen = sadb.msg->sadb_msg_len*IPSEC_PFKEYv2_ALIGN;
-       msglen -= sizeof(struct sadb_msg);
-       buflen -= sizeof(struct sadb_msg);
-       passert(buflen > 0);
-
-       sadb.msg++;
-
-       while (msglen)
-       {
-               int supp_exttype = sadb.supported->sadb_supported_exttype;
-               int supp_len = sadb.supported->sadb_supported_len*IPSEC_PFKEYv2_ALIGN;
-
-               DBG(DBG_KERNEL,
-                       DBG_log("kernel_alg_register_pfkey(): SADB_SATYPE_%s: "
-                                       "sadb_msg_len=%d sadb_supported_len=%d"
-                                       , satype==SADB_SATYPE_ESP? "ESP" : "AH"
-                                       , msg_buf->sadb_msg_len, supp_len)
-               )
-               sadb.supported++;
-               msglen -= supp_len;
-               buflen -= supp_len;
-               passert(buflen >= 0);
-
-               for (supp_len -= sizeof(struct sadb_supported);
-                        supp_len;
-                        supp_len -= sizeof(struct sadb_alg), sadb.alg++,i++)
-               {
-                       kernel_alg_add(satype, supp_exttype, sadb.alg);
-
-                       DBG(DBG_KERNEL,
-                               DBG_log("kernel_alg_register_pfkey(): SADB_SATYPE_%s: "
-                                               "alg[%d], exttype=%d, satype=%d, alg_id=%d, "
-                                               "alg_ivlen=%d, alg_minbits=%d, alg_maxbits=%d, "
-                                               "res=%d"
-                                               , satype == SADB_SATYPE_ESP? "ESP" : "AH"
-                                               , i
-                                               , supp_exttype
-                                               , satype
-                                               , sadb.alg->sadb_alg_id
-                                               , sadb.alg->sadb_alg_ivlen
-                                               , sadb.alg->sadb_alg_minbits
-                                               , sadb.alg->sadb_alg_maxbits
-                                               , sadb.alg->sadb_alg_reserved)
-                       )
-                       /* if AES_CBC is registered then also register AES_CCM and AES_GCM */
-                       if (satype == SADB_SATYPE_ESP &&
-                               supp_exttype == SADB_EXT_SUPPORTED_ENCRYPT &&
-                               sadb.alg->sadb_alg_id == SADB_X_EALG_AESCBC)
-                       {
-                               struct sadb_alg alg = *sadb.alg;
-                               int alg_id;
-
-                               for (alg_id = SADB_X_EALG_AES_CCM_ICV8;
-                                        alg_id <= SADB_X_EALG_AES_GCM_ICV16; alg_id++)
-                               {
-                                       if (alg_id != ESP_UNASSIGNED_17)
-                                       {
-                                               alg.sadb_alg_id = alg_id;
-                                               kernel_alg_add(satype, supp_exttype, &alg);
-                                       }
-                               }
-
-                               /* also register AES_GMAC */
-                               alg.sadb_alg_id = SADB_X_EALG_NULL_AES_GMAC;
-                               kernel_alg_add(satype, supp_exttype, &alg);
-                       }
-                       /* if SHA2_256 is registered then also register SHA2_256_96 */
-                       if (satype == SADB_SATYPE_ESP &&
-                               supp_exttype == SADB_EXT_SUPPORTED_AUTH &&
-                               sadb.alg->sadb_alg_id == SADB_X_AALG_SHA2_256HMAC)
-                       {
-                               struct sadb_alg alg = *sadb.alg;
-
-                               alg.sadb_alg_id = SADB_X_AALG_SHA2_256_96HMAC;
-                               kernel_alg_add(satype, supp_exttype, &alg);
-                       }
-               }
-       }
-}
-
-u_int kernel_alg_esp_enc_keylen(u_int alg_id)
-{
-       u_int keylen = 0;
-
-       if (!ESP_EALG_PRESENT(alg_id))
-       {
-               goto none;
-       }
-       keylen = esp_ealg[alg_id].sadb_alg_maxbits/BITS_PER_BYTE;
-
-       switch (alg_id)
-       {
-               /*
-                * this is veryUgly[TM]
-                * Peer should have sent KEY_LENGTH attribute for ESP_AES
-                * but if not do force it to 128 instead of using sadb_alg_maxbits
-                * from kernel.
-                */
-               case ESP_AES:
-                       keylen = 128/BITS_PER_BYTE;
-                       break;
-       }
-
-none:
-       DBG(DBG_KERNEL,
-               DBG_log("kernel_alg_esp_enc_keylen(): alg_id=%d, keylen=%d",
-                               alg_id, keylen)
-       )
-       return keylen;
-}
-
-struct sadb_alg* kernel_alg_esp_sadb_alg(u_int alg_id)
-{
-       struct sadb_alg *sadb_alg = (ESP_EALG_PRESENT(alg_id))
-                               ? &esp_ealg[alg_id] : NULL;
-
-       DBG(DBG_KERNEL,
-               DBG_log("kernel_alg_esp_sadb_alg(): alg_id=%d, sadb_alg=%p"
-                               , alg_id, sadb_alg)
-       )
-       return sadb_alg;
-}
-
-/**
- * Print the name of a kernel algorithm
- */
-static void print_alg(char *buf, int *len, enum_names *alg_names, int alg_type)
-{
-       char alg_name[BUF_LEN];
-       int alg_name_len;
-
-       alg_name_len = sprintf(alg_name, " %s", enum_name(alg_names, alg_type));
-       if (*len + alg_name_len > CRYPTO_MAX_ALG_LINE)
-       {
-               whack_log(RC_COMMENT, "%s", buf);
-               *len = sprintf(buf, "             ");
-       }
-       sprintf(buf + *len, "%s", alg_name);
-       *len += alg_name_len;
-}
-
-void kernel_alg_list(void)
-{
-       char buf[BUF_LEN];
-       int len;
-       u_int sadb_id;
-
-       whack_log(RC_COMMENT, " ");
-       whack_log(RC_COMMENT, "List of registered ESP Algorithms:");
-       whack_log(RC_COMMENT, " ");
-
-       len = sprintf(buf, "  encryption:");
-       for (sadb_id = 1; sadb_id <= SADB_EALG_MAX; sadb_id++)
-       {
-               if (ESP_EALG_PRESENT(sadb_id))
-               {
-                       print_alg(buf, &len, &esp_transform_names, sadb_id);
-               }
-       }
-       whack_log(RC_COMMENT, "%s", buf);
-
-       len = sprintf(buf, "  integrity: ");
-       for (sadb_id = 1; sadb_id <= SADB_AALG_MAX; sadb_id++)
-       {
-               if (ESP_AALG_PRESENT(sadb_id))
-               {
-                       u_int aaid = alg_info_esp_sadb2aa(sadb_id);
-
-                       print_alg(buf, &len, &auth_alg_names, aaid);
-               }
-       }
-       whack_log(RC_COMMENT, "%s", buf);
-}
-
-void kernel_alg_show_connection(connection_t *c, const char *instance)
-{
-       struct state *st = state_with_serialno(c->newest_ipsec_sa);
-
-       if (st && st->st_esp.present)
-       {
-               const char *aalg_name, *pfsgroup_name;
-
-               aalg_name = (c->policy & POLICY_AUTHENTICATE) ?
-                                       enum_show(&ah_transform_names, st->st_ah.attrs.transid):
-                                       enum_show(&auth_alg_names, st->st_esp.attrs.auth);
-
-               pfsgroup_name = (c->policy & POLICY_PFS) ?
-                                               (c->alg_info_esp && c->alg_info_esp->esp_pfsgroup) ?
-                                                       enum_show(&oakley_group_names,
-                                                                                 c->alg_info_esp->esp_pfsgroup) :
-                                                       "<Phase1>" : "<N/A>";
-
-               if (st->st_esp.attrs.key_len)
-               {
-                       whack_log(RC_COMMENT, "\"%s\"%s:   ESP%s proposal: %s_%u/%s/%s",
-                               c->name, instance,
-                               (st->st_ah.present) ? "/AH" : "",
-                               enum_show(&esp_transform_names, st->st_esp.attrs.transid),
-                               st->st_esp.attrs.key_len, aalg_name, pfsgroup_name);
-               }
-               else
-               {
-                       whack_log(RC_COMMENT, "\"%s\"%s:   ESP%s proposal: %s/%s/%s",
-                               c->name, instance,
-                               (st->st_ah.present) ? "/AH" : "",
-                               enum_show(&esp_transform_names, st->st_esp.attrs.transid),
-                               aalg_name, pfsgroup_name);
-               }
-       }
-}
-
-bool kernel_alg_esp_auth_ok(u_int auth,
-                                                       struct alg_info_esp *alg_info __attribute__((unused)))
-{
-       return ESP_AALG_PRESENT(alg_info_esp_aa2sadb(auth));
-}
-
-u_int kernel_alg_esp_auth_keylen(u_int auth)
-{
-       u_int sadb_aalg = alg_info_esp_aa2sadb(auth);
-
-       u_int a_keylen = (sadb_aalg)
-                                  ? esp_aalg[sadb_aalg].sadb_alg_maxbits/BITS_PER_BYTE
-                                  : 0;
-
-       DBG(DBG_CONTROL | DBG_CRYPT | DBG_PARSING,
-               DBG_log("kernel_alg_esp_auth_keylen(auth=%d, sadb_aalg=%d): "
-                               "a_keylen=%d", auth, sadb_aalg, a_keylen)
-       )
-       return a_keylen;
-}
-
-struct esp_info* kernel_alg_esp_info(int transid, int auth)
-{
-       int sadb_aalg, sadb_ealg;
-       static struct esp_info ei_buf;
-
-       sadb_ealg = transid;
-       sadb_aalg = alg_info_esp_aa2sadb(auth);
-
-       if (!ESP_EALG_PRESENT(sadb_ealg))
-               goto none;
-       if (!ESP_AALG_PRESENT(sadb_aalg))
-               goto none;
-
-       memset(&ei_buf, 0, sizeof (ei_buf));
-       ei_buf.transid = transid;
-       ei_buf.auth = auth;
-
-       /* don't return "default" keylen because this value is used from
-        * setup_half_ipsec_sa() to "validate" keylen
-        * In effect,  enckeylen will be used as "max" value
-        */
-       ei_buf.enckeylen = esp_ealg[sadb_ealg].sadb_alg_maxbits/BITS_PER_BYTE;
-       ei_buf.authkeylen = esp_aalg[sadb_aalg].sadb_alg_maxbits/BITS_PER_BYTE;
-       ei_buf.encryptalg = sadb_ealg;
-       ei_buf.authalg = sadb_aalg;
-
-       DBG(DBG_PARSING,
-               DBG_log("kernel_alg_esp_info():"
-                               "transid=%d, auth=%d, ei=%p, "
-                               "enckeylen=%d, authkeylen=%d, encryptalg=%d, authalg=%d",
-                               transid, auth, &ei_buf,
-                               (int)ei_buf.enckeylen, (int)ei_buf.authkeylen,
-                               ei_buf.encryptalg, ei_buf.authalg)
-       )
-       return &ei_buf;
-
-none:
-       DBG(DBG_PARSING,
-               DBG_log("kernel_alg_esp_info():"
-                               "transid=%d, auth=%d, ei=NULL",
-                               transid, auth)
-       )
-       return NULL;
-}
-
-static void kernel_alg_policy_algorithms(struct esp_info *esp_info)
-{
-       u_int ealg_id = esp_info->esp_ealg_id;
-
-       switch(ealg_id)
-       {
-       case 0:
-       case ESP_DES:
-       case ESP_3DES:
-       case ESP_NULL:
-       case ESP_CAST:
-                       break;
-       default:
-               if (!esp_info->esp_ealg_keylen)
-               {
-                       /* algos that need  KEY_LENGTH
-                        *
-                        * Note: this is a very dirty hack ;-)
-                        * Idea: Add a key_length_needed attribute to
-                        * esp_ealg ??
-                        */
-                       esp_info->esp_ealg_keylen = esp_ealg[ealg_id].sadb_alg_maxbits;
-               }
-       }
-}
-
-static bool kernel_alg_db_add(struct db_context *db_ctx,
-                                                         struct esp_info *esp_info, lset_t policy)
-{
-       u_int ealg_id, aalg_id;
-
-       ealg_id = esp_info->esp_ealg_id;
-
-       if (!ESP_EALG_PRESENT(ealg_id))
-       {
-               DBG_log("kernel_alg_db_add() kernel enc ealg_id=%d not present", ealg_id);
-               return FALSE;
-       }
-
-       if (!(policy & POLICY_AUTHENTICATE) &&    /* skip ESP auth attrs for AH */
-               esp_info->esp_aalg_id != AUTH_ALGORITHM_NONE)
-       {
-               aalg_id = alg_info_esp_aa2sadb(esp_info->esp_aalg_id);
-
-               if (!ESP_AALG_PRESENT(aalg_id))
-               {
-                       DBG_log("kernel_alg_db_add() kernel auth aalg_id=%d not present",
-                                       aalg_id);
-                       return FALSE;
-               }
-       }
-
-       /* do algo policy */
-       kernel_alg_policy_algorithms(esp_info);
-
-       /*  open new transformation */
-       db_trans_add(db_ctx, ealg_id);
-
-       /* add ESP auth attr if not AH or AEAD */
-       if (!(policy & POLICY_AUTHENTICATE) &&
-               esp_info->esp_aalg_id != AUTH_ALGORITHM_NONE)
-       {
-               db_attr_add_values(db_ctx, AUTH_ALGORITHM, esp_info->esp_aalg_id);
-       }
-
-       /* add keylength if specified in esp= string */
-       if (esp_info->esp_ealg_keylen)
-       {
-               db_attr_add_values(db_ctx, KEY_LENGTH, esp_info->esp_ealg_keylen);
-       }
-
-       return TRUE;
-}
-
-/*
- *      Create proposal with runtime kernel algos, merging
- *      with passed proposal if not NULL
- *
- *      for now this function does free() previous returned
- *      malloced pointer (this quirk allows easier spdb.c change)
- */
-struct db_context* kernel_alg_db_new(struct alg_info_esp *alg_info,
-                                                                        lset_t policy)
-{
-       const struct esp_info *esp_info;
-       struct esp_info tmp_esp_info;
-       struct db_context *ctx_new = NULL;
-       u_int trans_cnt = esp_ealg_num * esp_aalg_num;
-
-       if (!(policy & POLICY_ENCRYPT))     /* not possible, I think  */
-       {
-               return NULL;
-       }
-
-       /* pass aprox. number of transforms and attributes */
-       ctx_new = db_prop_new(PROTO_IPSEC_ESP, trans_cnt, trans_cnt * 2);
-
-       if (alg_info)
-       {
-               int i;
-
-               ALG_INFO_ESP_FOREACH(alg_info, esp_info, i)
-               {
-                       tmp_esp_info = *esp_info;
-                       kernel_alg_db_add(ctx_new, &tmp_esp_info, policy);
-               }
-       }
-       return ctx_new;
-}
-
diff --git a/src/pluto/kernel_alg.h b/src/pluto/kernel_alg.h
deleted file mode 100644 (file)
index 4c757db..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Kernel runtime algorithm handling interface definitions
- * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef _KERNEL_ALG_H
-#define _KERNEL_ALG_H
-
-#include "alg_info.h"
-#include "spdb.h"
-
-/* status info */
-extern void kernel_alg_show_status(void);
-void kernel_alg_show_connection(struct connection *c, const char *instance);
-
-/* Registration messages from pluto */
-extern void kernel_alg_register_pfkey(const struct sadb_msg *msg, int buflen);
-
-/* ESP interface */
-extern struct sadb_alg *kernel_alg_esp_sadb_alg(u_int alg_id);
-extern u_int kernel_alg_esp_ivlen(u_int alg_id);
-extern bool kernel_alg_esp_enc_ok(u_int alg_id, u_int key_len, struct alg_info_esp *nfo);
-extern bool kernel_alg_esp_ok_final(u_int ealg, u_int key_len, u_int aalg, struct alg_info_esp *alg_info);
-extern u_int kernel_alg_esp_enc_keylen(u_int alg_id);
-extern bool kernel_alg_esp_auth_ok(u_int auth, struct alg_info_esp *nfo);
-extern u_int kernel_alg_esp_auth_keylen(u_int auth);
-extern void kernel_alg_list(void);
-
-/* get sadb_alg for passed args */
-extern const struct sadb_alg * kernel_alg_sadb_alg_get(int satype, int exttype, int alg_id);
-
-extern struct db_context * kernel_alg_db_new(struct alg_info_esp *ai, lset_t policy);
-struct esp_info * kernel_alg_esp_info(int esp_id, int auth_id);
-#endif /* _KERNEL_ALG_H */
diff --git a/src/pluto/kernel_pfkey.c b/src/pluto/kernel_pfkey.c
deleted file mode 100644 (file)
index 77fff2f..0000000
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * Copyright (C) 2010 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
- * Copyright (C) 2003 Herbert Xu.
- * Copyright (C) 1998-2002  D. Hugh Redelmeier.
- * Copyright (C) 1997 Angelos D. Keromytis.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <errno.h>
-#include <unistd.h>
-
-#include <sys/select.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-
-#include <freeswan.h>
-#include <pfkeyv2.h>
-#include <pfkey.h>
-
-#include "constants.h"
-#include "kernel.h"
-#include "kernel_pfkey.h"
-#include "log.h"
-#include "whack.h"      /* for RC_LOG_SERIOUS */
-#include "kernel_alg.h"
-
-
-static int pfkeyfd = NULL_FD;
-
-typedef u_int32_t pfkey_seq_t;
-static pfkey_seq_t pfkey_seq = 0; /* sequence number for our PF_KEY messages */
-
-static pid_t pid;
-
-#define NE(x) { x, #x } /* Name Entry -- shorthand for sparse_names */
-
-static sparse_names pfkey_type_names = {
-               NE(SADB_RESERVED),
-               NE(SADB_GETSPI),
-               NE(SADB_UPDATE),
-               NE(SADB_ADD),
-               NE(SADB_DELETE),
-               NE(SADB_GET),
-               NE(SADB_ACQUIRE),
-               NE(SADB_REGISTER),
-               NE(SADB_EXPIRE),
-               NE(SADB_FLUSH),
-               NE(SADB_DUMP),
-               NE(SADB_X_PROMISC),
-               NE(SADB_X_PCHANGE),
-               NE(SADB_X_GRPSA),
-               NE(SADB_X_ADDFLOW),
-               NE(SADB_X_DELFLOW),
-               NE(SADB_X_DEBUG),
-               NE(SADB_X_NAT_T_NEW_MAPPING),
-               NE(SADB_MAX),
-               { 0, sparse_end }
-};
-
-#undef NE
-
-typedef union {
-               unsigned char bytes[PFKEYv2_MAX_MSGSIZE];
-               struct sadb_msg msg;
-       } pfkey_buf;
-
-static bool
-pfkey_input_ready(void)
-{
-       int ndes;
-       fd_set readfds;
-       struct timeval tm = { .tv_sec = 0 }; /* don't wait, polling */
-
-       FD_ZERO(&readfds);  /* we only care about pfkeyfd */
-       FD_SET(pfkeyfd, &readfds);
-
-       do {
-               ndes = select(pfkeyfd + 1, &readfds, NULL, NULL, &tm);
-       } while (ndes == -1 && errno == EINTR);
-
-       if (ndes < 0)
-       {
-               log_errno((e, "select() failed in pfkey_get()"));
-               return FALSE;
-       }
-       else if (ndes == 0)
-       {
-               return FALSE;   /* nothing to read */
-       }
-       passert(ndes == 1 && FD_ISSET(pfkeyfd, &readfds));
-       return TRUE;
-}
-
-/* get a PF_KEY message from kernel.
- * Returns TRUE if message found, FALSE if no message pending,
- * and aborts or keeps trying when an error is encountered.
- * The only validation of the message is that the message length
- * received matches that in the message header, and that the message
- * is for this process.
- */
-static bool
-pfkey_get(pfkey_buf *buf)
-{
-       for (;;)
-       {
-               /* len must be less than PFKEYv2_MAX_MSGSIZE,
-                * so it should fit in an int.  We use this fact when printing it.
-                */
-               ssize_t len;
-
-               if (!pfkey_input_ready())
-               {
-                       return FALSE;
-               }
-
-               len = read(pfkeyfd, buf->bytes, sizeof(buf->bytes));
-
-               if (len < 0)
-               {
-                       if (errno == EAGAIN)
-                       {
-                               return FALSE;
-                       }
-                       log_errno((e, "read() failed in pfkey_get()"));
-                       return FALSE;
-               }
-               else if ((size_t)len < sizeof(buf->msg))
-               {
-                       plog("pfkey_get read truncated PF_KEY message: %d bytes; ignoring",
-                                (int)len);
-               }
-               else if ((size_t)len != buf->msg.sadb_msg_len * IPSEC_PFKEYv2_ALIGN)
-               {
-                       plog("pfkey_get read PF_KEY message with length %d that doesn't"
-                                " equal sadb_msg_len %u * %u; ignoring message", (int)len,
-                                (unsigned)buf->msg.sadb_msg_len, (unsigned)IPSEC_PFKEYv2_ALIGN);
-               }
-               else if (buf->msg.sadb_msg_pid != (unsigned)pid)
-               {
-                       /* not for us: ignore */
-                       DBG(DBG_KERNEL,
-                               DBG_log("pfkey_get: ignoring PF_KEY %s message %u for process"
-                                               " %u", sparse_val_show(pfkey_type_names,
-                                                                                          buf->msg.sadb_msg_type),
-                                               buf->msg.sadb_msg_seq, buf->msg.sadb_msg_pid));
-               }
-               else
-               {
-                       DBG(DBG_KERNEL,
-                               DBG_log("pfkey_get: %s message %u",
-                                               sparse_val_show(pfkey_type_names,
-                                                                               buf->msg.sadb_msg_type),
-                                               buf->msg.sadb_msg_seq));
-                       return TRUE;
-               }
-       }
-}
-
-/* get a response to a specific message */
-static bool
-pfkey_get_response(pfkey_buf *buf, pfkey_seq_t seq)
-{
-       while (pfkey_get(buf))
-       {
-               if (buf->msg.sadb_msg_seq == seq)
-               {
-                       return TRUE;
-               }
-       }
-       return FALSE;
-}
-
-static bool
-pfkey_build(int error, const char *description, const char *text_said,
-                       struct sadb_ext *extensions[SADB_EXT_MAX + 1])
-{
-       if (error != 0)
-       {
-               loglog(RC_LOG_SERIOUS, "building of %s %s failed, code %d", description,
-                                                          text_said, error);
-               pfkey_extensions_free(extensions);
-               return FALSE;
-       }
-       return TRUE;
-}
-
-/* pfkey_extensions_init + pfkey_build + pfkey_msg_hdr_build */
-static bool
-pfkey_msg_start(u_int8_t msg_type, u_int8_t satype, const char *description,
-                               const char *text_said,
-                               struct sadb_ext *extensions[SADB_EXT_MAX + 1])
-{
-       pfkey_extensions_init(extensions);
-       return pfkey_build(pfkey_msg_hdr_build(&extensions[0], msg_type, satype, 0,
-                                                                                  ++pfkey_seq, pid),
-                                          description, text_said, extensions);
-}
-
-/* Finish (building, sending, accepting response for) PF_KEY message.
- * If response isn't NULL, the response from the kernel will be
- * placed there (and its errno field will not be examined).
- * Returns TRUE iff all appears well.
- */
-static bool
-finish_pfkey_msg(struct sadb_ext *extensions[SADB_EXT_MAX + 1],
-                                const char *description, const char *text_said,
-                                pfkey_buf *response)
-{
-       struct sadb_msg *pfkey_msg;
-       bool success = TRUE;
-       int error;
-
-       error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_IN);
-
-       if (error != 0)
-       {
-               loglog(RC_LOG_SERIOUS, "pfkey_msg_build of %s %s failed, code %d",
-                                                          description, text_said, error);
-               success = FALSE;
-       }
-       else
-       {
-               size_t len = pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN;
-
-               DBG(DBG_KERNEL,
-                       DBG_log("finish_pfkey_msg: %s message %u for %s %s",
-                                       sparse_val_show(pfkey_type_names, pfkey_msg->sadb_msg_type),
-                                       pfkey_msg->sadb_msg_seq, description, text_said);
-                       DBG_dump(NULL, (void *) pfkey_msg, len));
-
-               ssize_t r = write(pfkeyfd, pfkey_msg, len);
-
-               if (r != (ssize_t)len)
-               {
-                       if (r < 0)
-                       {
-                               log_errno((e, "pfkey write() of %s message %u for %s %s"
-                                                 " failed", sparse_val_show(pfkey_type_names,
-                                                       pfkey_msg->sadb_msg_type), pfkey_msg->sadb_msg_seq,
-                                                 description, text_said));
-                       }
-                       else
-                       {
-                               loglog(RC_LOG_SERIOUS, "ERROR: pfkey write() of %s message"
-                                          " %u for %s %s truncated: %ld instead of %ld",
-                                          sparse_val_show(pfkey_type_names,
-                                                       pfkey_msg->sadb_msg_type), pfkey_msg->sadb_msg_seq,
-                                               description, text_said, (long)r, (long)len);
-                       }
-                       success = FALSE;
-
-                       /* if we were compiled with debugging, but we haven't already
-                        * dumped the command, do so.
-                        */
-#ifdef DEBUG
-                       if ((cur_debugging & DBG_KERNEL) == 0)
-                               DBG_dump(NULL, (void *) pfkey_msg, len);
-#endif
-               }
-               else
-               {
-                       /* Check response from kernel.
-                        * It ought to be an echo, perhaps with additional info.
-                        * If the caller wants it, response will point to space.
-                        */
-                       pfkey_buf b;
-                       pfkey_buf *bp = response != NULL? response : &b;
-
-                       if (!pfkey_get_response(bp,
-                                               ((struct sadb_msg *)extensions[0])->sadb_msg_seq))
-                       {
-                               loglog(RC_LOG_SERIOUS, "ERROR: no response to our PF_KEY %s"
-                                          " message for %s %s", sparse_val_show(pfkey_type_names,
-                                                       pfkey_msg->sadb_msg_type), description, text_said);
-                               success = FALSE;
-                       }
-                       else if (pfkey_msg->sadb_msg_type != bp->msg.sadb_msg_type)
-                       {
-                               loglog(RC_LOG_SERIOUS, "ERROR: response to our PF_KEY %s"
-                                          " message for %s %s was of wrong type (%s)",
-                                          sparse_name(pfkey_type_names, pfkey_msg->sadb_msg_type),
-                                          description, text_said, sparse_val_show(pfkey_type_names,
-                                                       bp->msg.sadb_msg_type));
-                               success = FALSE;
-                       }
-                       else if (response == NULL && bp->msg.sadb_msg_errno != 0)
-                       {
-                               /* Kernel is signalling a problem */
-                               loglog(RC_LOG_SERIOUS, "ERROR: PF_KEY %s response for %s %s"
-                                          " included errno %u: %s",
-                                          sparse_val_show(pfkey_type_names,
-                                                       pfkey_msg->sadb_msg_type), description, text_said,
-                                          (unsigned) bp->msg.sadb_msg_errno,
-                                          strerror(bp->msg.sadb_msg_errno));
-                               success = FALSE;
-                       }
-               }
-       }
-       pfkey_extensions_free(extensions);
-       pfkey_msg_free(&pfkey_msg);
-       return success;
-}
-
-/* Process a SADB_REGISTER message from the kernel.
- * This will be a response to one of ours, but it may be asynchronous
- * (if kernel modules are loaded and unloaded).
- * Some sanity checking has already been performed.
- */
-static void
-pfkey_register_response(const struct sadb_msg *msg)
-{
-       /* Find out what the kernel can support.
-        */
-       switch (msg->sadb_msg_satype)
-       {
-       case SADB_SATYPE_ESP:
-#ifndef NO_KERNEL_ALG
-               kernel_alg_register_pfkey(msg, sizeof (pfkey_buf));
-#endif
-               break;
-       case SADB_X_SATYPE_IPCOMP:
-               /* ??? There ought to be an extension to list the
-                * supported algorithms, but RFC 2367 doesn't
-                * list one for IPcomp.
-                */
-               can_do_IPcomp = TRUE;
-               break;
-       default:
-               break;
-       }
-}
-
-/**  register SA types that can be negotiated */
-static void
-pfkey_register_proto(unsigned satype, const char *satypename)
-{
-       struct sadb_ext *extensions[SADB_EXT_MAX + 1];
-       pfkey_buf pfb;
-
-       if (!(pfkey_msg_start(SADB_REGISTER, satype, satypename, NULL, extensions)
-                 && finish_pfkey_msg(extensions, satypename, "", &pfb)))
-       {
-               /* ??? should this be loglog */
-               plog("no kernel support for %s", satypename);
-       }
-       else
-       {
-               pfkey_register_response(&pfb.msg);
-               DBG(DBG_KERNEL,
-                       DBG_log("%s registered with kernel.", satypename));
-       }
-}
-
-void
-pfkey_register(void)
-{
-       pid = getpid();
-
-       pfkeyfd = socket(PF_KEY, SOCK_RAW, PF_KEY_V2);
-       if (pfkeyfd == -1)
-       {
-               exit_log_errno((e, "socket() in init_pfkeyfd()"));
-       }
-
-       pfkey_register_proto(SADB_SATYPE_AH, "AH");
-       pfkey_register_proto(SADB_SATYPE_ESP, "ESP");
-       pfkey_register_proto(SADB_X_SATYPE_IPCOMP, "IPCOMP");
-
-       close(pfkeyfd);
-}
diff --git a/src/pluto/kernel_pfkey.h b/src/pluto/kernel_pfkey.h
deleted file mode 100644 (file)
index b50ad6c..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2010 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-/**
- * Register our capabilities via PF_KEY, also learn the kernel's capabilities,
- * i.e. the supported algorithms.
- */
-void pfkey_register();
diff --git a/src/pluto/keys.c b/src/pluto/keys.c
deleted file mode 100644 (file)
index 5fcbdfa..0000000
+++ /dev/null
@@ -1,1474 +0,0 @@
-/* mechanisms for preshared keys (public, private, and preshared secrets)
- * Copyright (C) 1998-2001  D. Hugh Redelmeier.
- * Copyright (C) 2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <errno.h>
-#include <time.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <resolv.h>
-#include <arpa/nameser.h>       /* missing from <resolv.h> on old systems */
-#include <sys/queue.h>
-
-#ifdef HAVE_GLOB_H
-#include <glob.h>
-#ifndef GLOB_ABORTED
-# define GLOB_ABORTED    GLOB_ABEND     /* fix for old versions */
-#endif
-#endif
-
-#include <freeswan.h>
-
-#include <library.h>
-#include <asn1/asn1.h>
-#include <credentials/certificates/pgp_certificate.h>
-#include <credentials/sets/mem_cred.h>
-#include <credentials/sets/callback_cred.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "x509.h"
-#include "certs.h"
-#include "smartcard.h"
-#include "connections.h"
-#include "state.h"
-#include "lex.h"
-#include "keys.h"
-#include "adns.h"       /* needs <resolv.h> */
-#include "dnskey.h"     /* needs keys.h and adns.h */
-#include "log.h"
-#include "whack.h"      /* for RC_LOG_SERIOUS */
-#include "timer.h"
-#include "fetch.h"
-
-const char *shared_secrets_file = SHARED_SECRETS_FILE;
-
-
-typedef enum secret_kind_t secret_kind_t;
-
-enum secret_kind_t {
-       SECRET_PSK,
-       SECRET_PUBKEY,
-       SECRET_XAUTH,
-       SECRET_PIN
-};
-
-typedef struct secret_t secret_t;
-
-struct secret_t {
-       linked_list_t *ids;
-       secret_kind_t kind;
-       union {
-               chunk_t        preshared_secret;
-               private_key_t *private_key;
-               smartcard_t   *smartcard;
-       } u;
-       secret_t *next;
-};
-
-/*
- * free a public key struct
- */
-static void free_public_key(pubkey_t *pk)
-{
-       DESTROY_IF(pk->id);
-       DESTROY_IF(pk->public_key);
-       DESTROY_IF(pk->issuer);
-       free(pk->serial.ptr);
-       free(pk);
-}
-
-secret_t *secrets = NULL;
-
-/**
- * Find the secret associated with the combination of me and the peer.
- */
-const secret_t* match_secret(identification_t *my_id, identification_t *his_id,
-                                                        secret_kind_t kind)
-{
-       enum {      /* bits */
-               match_default = 0x01,
-               match_him     = 0x02,
-               match_me      = 0x04
-       };
-
-       unsigned int best_match = 0;
-       secret_t *s, *best = NULL;
-
-       for (s = secrets; s != NULL; s = s->next)
-       {
-               unsigned int match = 0;
-
-               if (s->kind != kind)
-               {
-                       continue;
-               }
-
-               if (s->ids->get_count(s->ids) == 0)
-               {
-                       /* a default (signified by lack of ids):
-                        * accept if no more specific match found
-                        */
-                       match = match_default;
-               }
-               else
-               {
-                       /* check if both ends match ids */
-                       enumerator_t *enumerator;
-                       identification_t *id;
-
-                       enumerator = s->ids->create_enumerator(s->ids);
-                       while (enumerator->enumerate(enumerator, &id))
-                       {
-                               if (my_id->equals(my_id, id))
-                               {
-                                       match |= match_me;
-                               }
-                               if (his_id->equals(his_id, id))
-                               {
-                                       match |= match_him;
-                               }
-                       }
-                       enumerator->destroy(enumerator);
-
-                       /* If our end matched the only id in the list,
-                        * default to matching any peer.
-                        * A more specific match will trump this.
-                        */
-                       if (match == match_me && s->ids->get_count(s->ids) == 1)
-                       {
-                               match |= match_default;
-                       }
-               }
-
-               switch (match)
-               {
-                       case match_me:
-                               /* if this is an asymmetric (eg. public key) system,
-                                * allow this-side-only match to count, even if
-                                * there are other ids in the list.
-                                */
-                               if (kind != SECRET_PUBKEY)
-                               {
-                                       break;
-                               }
-                               /* FALLTHROUGH */
-                       case match_default:              /* default all */
-                       case match_me | match_default:   /* default peer */
-                       case match_me | match_him:       /* explicit */
-                               if (match == best_match)
-                               {
-                                       /* two good matches are equally good: do they agree? */
-                                       bool same = FALSE;
-
-                                       switch (kind)
-                                       {
-                                       case SECRET_PSK:
-                                       case SECRET_XAUTH:
-                                               same = chunk_equals(s->u.preshared_secret,
-                                                                                       best->u.preshared_secret);
-                                               break;
-                                       case SECRET_PUBKEY:
-                                               same = s->u.private_key->equals(s->u.private_key,
-                                                                                                               best->u.private_key);
-                                               break;
-                                       default:
-                                               bad_case(kind);
-                                       }
-                                       if (!same)
-                                       {
-                                               loglog(RC_LOG_SERIOUS, "multiple ipsec.secrets entries with "
-                                                       "distinct secrets match endpoints: first secret used");
-                                               best = s;       /* list is backwards: take latest in list */
-                                       }
-                               }
-                               else if (match > best_match)
-                               {
-                                       /* this is the best match so far */
-                                       best_match = match;
-                                       best = s;
-                               }
-               }
-       }
-       return best;
-}
-
-/**
- * Retrieves an XAUTH secret primarily based on the user ID and
- * secondarily based on the server ID
- */
-bool get_xauth_secret(identification_t *user, identification_t *server,
-                                         chunk_t *secret)
-{
-       const secret_t *s;
-
-       s = match_secret(user, server, SECRET_XAUTH);
-       if (s)
-       {
-               *secret = chunk_clone(s->u.preshared_secret);
-               return TRUE;
-       }
-       else
-       {
-               *secret = chunk_empty;
-               return FALSE;
-       }
-}
-
-/**
- * We match the ID (if none, the IP address). Failure is indicated by a NULL.
- */
-static const secret_t* get_secret(const connection_t *c, secret_kind_t kind)
-{
-       identification_t *my_id, *his_id;
-       const secret_t *best;
-
-       my_id  = c->spd.this.id;
-
-       if (his_id_was_instantiated(c))
-       {
-               /* roadwarrior: replace him with 0.0.0.0 */
-               his_id = identification_create_from_string("%any");
-       }
-       else if (kind == SECRET_PSK && (c->policy & (POLICY_PSK | POLICY_XAUTH_PSK)) &&
-               ((c->kind == CK_TEMPLATE &&
-                c->spd.that.id->get_type(c->spd.that.id) == ID_ANY) ||
-               (c->kind == CK_INSTANCE && id_is_ipaddr(c->spd.that.id))))
-       {
-               /* roadwarrior: replace him with 0.0.0.0 */
-               his_id = identification_create_from_string("%any");
-       }
-       else
-       {
-               his_id = c->spd.that.id->clone(c->spd.that.id);
-       }
-
-       best = match_secret(my_id, his_id, kind);
-
-       his_id->destroy(his_id);
-       return best;
-}
-
-/* find the appropriate preshared key (see get_secret).
- * Failure is indicated by a NULL pointer.
- * Note: the result is not to be freed by the caller.
- */
-const chunk_t* get_preshared_secret(const connection_t *c)
-{
-       const secret_t *s = get_secret(c, SECRET_PSK);
-
-       DBG(DBG_PRIVATE,
-               if (s == NULL)
-                       DBG_log("no Preshared Key Found");
-               else
-                       DBG_dump_chunk("Preshared Key", s->u.preshared_secret);
-       )
-       return s == NULL? NULL : &s->u.preshared_secret;
-}
-
-/* check the existence of a private key matching a public key contained
- * in an X.509 or OpenPGP certificate
- */
-bool has_private_key(cert_t *cert)
-{
-       secret_t *s;
-       bool has_key = FALSE;
-       public_key_t *pub_key = cert->cert->get_public_key(cert->cert);
-
-       for (s = secrets; s != NULL; s = s->next)
-       {
-               if (s->kind == SECRET_PUBKEY &&
-                       s->u.private_key->belongs_to(s->u.private_key, pub_key))
-               {
-                       has_key = TRUE;
-                       break;
-               }
-       }
-       pub_key->destroy(pub_key);
-       return has_key;
-}
-
-/*
- * get the matching private key belonging to a given X.509 certificate
- */
-private_key_t* get_x509_private_key(const cert_t *cert)
-{
-       public_key_t *public_key = cert->cert->get_public_key(cert->cert);
-       private_key_t *private_key = NULL;
-       secret_t *s;
-
-       for (s = secrets; s != NULL; s = s->next)
-       {
-
-               if (s->kind == SECRET_PUBKEY &&
-                       s->u.private_key->belongs_to(s->u.private_key, public_key))
-               {
-                       private_key = s->u.private_key;
-                       break;
-               }
-       }
-       public_key->destroy(public_key);
-       return private_key;
-}
-
-/* find the appropriate private key (see get_secret).
- * Failure is indicated by a NULL pointer.
- */
-private_key_t* get_private_key(const connection_t *c)
-{
-       const secret_t *s, *best = NULL;
-
-       /* is a certificate assigned to this connection? */
-       if (c->spd.this.cert)
-       {
-               certificate_t *certificate;
-               public_key_t *pub_key;
-
-               certificate = c->spd.this.cert->cert;
-               pub_key = certificate->get_public_key(certificate);
-
-               for (s = secrets; s != NULL; s = s->next)
-               {
-                       if (s->kind == SECRET_PUBKEY &&
-                               s->u.private_key->belongs_to(s->u.private_key, pub_key))
-                       {
-                               best = s;
-                               break; /* found the private key - no sense in searching further */
-                       }
-               }
-               pub_key->destroy(pub_key);
-       }
-       else
-       {
-               best = get_secret(c, SECRET_PUBKEY);
-       }
-       return best ? best->u.private_key : NULL;
-}
-
-/* digest a secrets file
- *
- * The file is a sequence of records.  A record is a maximal sequence of
- * tokens such that the first, and only the first, is in the first column
- * of a line.
- *
- * Tokens are generally separated by whitespace and are key words, ids,
- * strings, or data suitable for ttodata(3).  As a nod to convention,
- * a trailing ":" on what would otherwise be a token is taken as a
- * separate token.  If preceded by whitespace, a "#" is taken as starting
- * a comment: it and the rest of the line are ignored.
- *
- * One kind of record is an include directive.  It starts with "include".
- * The filename is the only other token in the record.
- * If the filename does not start with /, it is taken to
- * be relative to the directory containing the current file.
- *
- * The other kind of record describes a key.  It starts with a
- * sequence of ids and ends with key information.  Each id
- * is an IP address, a Fully Qualified Domain Name (which will immediately
- * be resolved), or @FQDN which will be left as a name.
- *
- * The key part can be in several forms.
- *
- * The old form of the key is still supported: a simple
- * quoted strings (with no escapes) is taken as a preshred key.
- *
- * The new form starts the key part with a ":".
- *
- * For Preshared Key, use the "PSK" keyword, and follow it by a string
- * or a data token suitable for ttodata(3).
- *
- * For RSA Private Key, use the "RSA" keyword, followed by a
- * brace-enclosed list of key field keywords and data values.
- * The data values are large integers to be decoded by ttodata(3).
- * The fields are a subset of those used by BIND 8.2 and have the
- * same names.
- */
-
-/* parse PSK from file */
-static err_t process_psk_secret(chunk_t *psk)
-{
-       err_t ugh = NULL;
-
-       if (*tok == '"' || *tok == '\'')
-       {
-               chunk_t secret = { tok + 1, flp->cur - tok  -2 };
-
-               *psk = chunk_clone(secret);
-               (void) shift();
-       }
-       else
-       {
-               char buf[BUF_LEN];      /* limit on size of binary representation of key */
-               size_t sz;
-
-               ugh = ttodatav(tok, flp->cur - tok, 0, buf, sizeof(buf), &sz
-                       , diag_space, sizeof(diag_space), TTODATAV_SPACECOUNTS);
-               if (ugh != NULL)
-               {
-                       /* ttodata didn't like PSK data */
-                       ugh = builddiag("PSK data malformed (%s): %s", ugh, tok);
-               }
-               else
-               {
-                       chunk_t secret = { buf, sz };
-                       *psk = chunk_clone(secret);
-                       (void) shift();
-               }
-       }
-       return ugh;
-}
-
-typedef enum rsa_private_key_part_t rsa_private_key_part_t;
-
-enum rsa_private_key_part_t {
-       RSA_PART_MODULUS          = 0,
-       RSA_PART_PUBLIC_EXPONENT  = 1,
-       RSA_PART_PRIVATE_EXPONENT = 2,
-       RSA_PART_PRIME1           = 3,
-       RSA_PART_PRIME2           = 4,
-       RSA_PART_EXPONENT1        = 5,
-       RSA_PART_EXPONENT2        = 6,
-       RSA_PART_COEFFICIENT      = 7
-};
-
-const char *rsa_private_key_part_names[] = {
-       "Modulus",
-       "PublicExponent",
-       "PrivateExponent",
-       "Prime1",
-       "Prime2",
-       "Exponent1",
-       "Exponent2",
-       "Coefficient"
-};
-
-/**
- * Parse fields of an RSA private key in BIND 8.2's representation
- * consistiong of a braced list of keyword and value pairs in required order.
- */
-static err_t process_rsa_secret(private_key_t **key)
-{
-       chunk_t rsa_chunk[countof(rsa_private_key_part_names)];
-       u_char buf[RSA_MAX_ENCODING_BYTES];   /* limit on size of binary representation of key */
-       rsa_private_key_part_t part, p;
-       size_t sz;
-       err_t ugh;
-
-       for (part = RSA_PART_MODULUS; part <= RSA_PART_COEFFICIENT; part++)
-       {
-               const char *keyword = rsa_private_key_part_names[part];
-
-               if (!shift())
-               {
-                       ugh = "premature end of RSA key";
-                       goto end;
-               }
-               if (!tokeqword(keyword))
-               {
-                       ugh = builddiag("%s keyword not found where expected in RSA key"
-                               , keyword);
-                       goto end;
-               }
-               if (!(shift() && (!tokeq(":") || shift())))   /* ignore optional ":" */
-               {
-                       ugh = "premature end of RSA key";
-                       goto end;
-               }
-               ugh = ttodatav(tok, flp->cur - tok, 0, buf, sizeof(buf), &sz,
-                                          diag_space, sizeof(diag_space), TTODATAV_SPACECOUNTS);
-               if (ugh)
-               {
-                       ugh = builddiag("RSA data malformed (%s): %s", ugh, tok);
-                       goto end;
-               }
-               rsa_chunk[part] = chunk_create(buf, sz);
-               rsa_chunk[part] = chunk_clone(rsa_chunk[part]);
-       }
-
-       /* We require an (indented) '}' and the end of the record.
-        * We break down the test so that the diagnostic will be more helpful.
-        * Some people don't seem to wish to indent the brace!
-        */
-       if (!shift() || !tokeq("}"))
-       {
-               ugh = "malformed end of RSA private key -- indented '}' required";
-               goto end;
-       }
-       if (shift())
-       {
-               ugh = "malformed end of RSA private key -- unexpected token after '}'";
-               goto end;
-       }
-
-       *key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
-                                       BUILD_RSA_MODULUS,  rsa_chunk[RSA_PART_MODULUS],
-                                       BUILD_RSA_PUB_EXP,  rsa_chunk[RSA_PART_PUBLIC_EXPONENT],
-                                       BUILD_RSA_PRIV_EXP, rsa_chunk[RSA_PART_PRIVATE_EXPONENT],
-                                       BUILD_RSA_PRIME1,   rsa_chunk[RSA_PART_PRIME1],
-                                       BUILD_RSA_PRIME2,   rsa_chunk[RSA_PART_PRIME2],
-                                       BUILD_RSA_EXP1,     rsa_chunk[RSA_PART_EXPONENT1],
-                                       BUILD_RSA_EXP2,     rsa_chunk[RSA_PART_EXPONENT2],
-                                       BUILD_RSA_COEFF,    rsa_chunk[RSA_PART_COEFFICIENT],
-                                       BUILD_END);
-
-       if (*key == NULL)
-       {
-               ugh = "parsing of RSA private key failed";
-       }
-
-end:
-       /* clean up and return */
-       for (p = RSA_PART_MODULUS ; p < part; p++)
-       {
-               chunk_clear(&rsa_chunk[p]);
-       }
-       return ugh;
-}
-
-/* struct used to prompt for a secret passphrase
- * from a console with file descriptor fd
- */
-typedef struct {
-       char secret[PROMPT_PASS_LEN+1];
-       bool prompt;
-       int fd;
-       int try;
-} prompt_pass_t;
-
-/**
- * Passphrase callback to read from whack fd
- */
-static shared_key_t* whack_pass_cb(prompt_pass_t *pass, shared_key_type_t type,
-                                                               identification_t *me, identification_t *other,
-                                                               id_match_t *match_me, id_match_t *match_other)
-{
-       int n;
-
-       if (type != SHARED_ANY && type != SHARED_PRIVATE_KEY_PASS)
-       {
-               return NULL;
-       }
-
-       if (pass->try > MAX_PROMPT_PASS_TRIALS)
-       {
-               whack_log(RC_LOG_SERIOUS, "invalid passphrase, too many trials");
-               return NULL;
-       }
-       if (pass->try == 1)
-       {
-               whack_log(RC_ENTERSECRET, "need passphrase for 'private key'");
-       }
-       else
-       {
-               whack_log(RC_ENTERSECRET, "invalid passphrase, please try again");
-       }
-       pass->try++;
-
-       n = read(pass->fd, pass->secret, PROMPT_PASS_LEN);
-       if (n == -1)
-       {
-               whack_log(RC_LOG_SERIOUS, "read(whackfd) failed");
-               return NULL;
-       }
-       pass->secret[n-1] = '\0';
-
-       if (strlen(pass->secret) == 0)
-       {
-               whack_log(RC_LOG_SERIOUS, "no passphrase entered, aborted");
-               return NULL;
-       }
-       if (match_me)
-       {
-               *match_me = ID_MATCH_PERFECT;
-       }
-       if (match_other)
-       {
-               *match_other = ID_MATCH_NONE;
-       }
-       return shared_key_create(SHARED_PRIVATE_KEY_PASS,
-                               chunk_clone(chunk_create(pass->secret, strlen(pass->secret))));
-}
-
-/**
- *  Loads a PKCS#1 or PGP private key file
- */
-static private_key_t* load_private_key(char* filename, prompt_pass_t *pass,
-                                                                          key_type_t type)
-{
-       private_key_t *key = NULL;
-       char *path;
-
-       path = concatenate_paths(PRIVATE_KEY_PATH, filename);
-       if (pass && pass->prompt && pass->fd != NULL_FD)
-       {       /* use passphrase callback */
-               callback_cred_t *cb;
-
-               cb = callback_cred_create_shared((void*)whack_pass_cb, pass);
-               lib->credmgr->add_local_set(lib->credmgr, &cb->set, FALSE);
-
-               key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
-                                                                BUILD_FROM_FILE, path, BUILD_END);
-               lib->credmgr->remove_local_set(lib->credmgr, &cb->set);
-               cb->destroy(cb);
-               if (key)
-               {
-                       whack_log(RC_SUCCESS, "valid passphrase");
-               }
-       }
-       else if (pass)
-       {       /* use a given passphrase */
-               mem_cred_t *mem;
-               shared_key_t *shared;
-
-               mem = mem_cred_create();
-               lib->credmgr->add_local_set(lib->credmgr, &mem->set, FALSE);
-               shared = shared_key_create(SHARED_PRIVATE_KEY_PASS,
-                               chunk_clone(chunk_create(pass->secret, strlen(pass->secret))));
-               mem->add_shared(mem, shared, NULL);
-               key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
-                                                                BUILD_FROM_FILE, path, BUILD_END);
-               lib->credmgr->remove_local_set(lib->credmgr, &mem->set);
-               mem->destroy(mem);
-       }
-       else
-       {       /* no passphrase */
-               key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
-                                                                BUILD_FROM_FILE, path, BUILD_END);
-
-       }
-       if (key)
-       {
-               plog("  loaded private key from '%s'", filename);
-       }
-       else
-       {
-               plog("  syntax error in private key file");
-       }
-       return key;
-}
-
-/**
- * process a key file protected with optional passphrase which can either be
- * read from ipsec.secrets or prompted for by using whack
- */
-static err_t process_keyfile(private_key_t **key, key_type_t type, int whackfd)
-{
-       char filename[BUF_LEN];
-       prompt_pass_t pass;
-
-       memset(filename,'\0', BUF_LEN);
-       memset(pass.secret,'\0', sizeof(pass.secret));
-       pass.prompt = FALSE;
-       pass.fd = whackfd;
-       pass.try = 1;
-
-       /* we expect the filename of a PKCS#1 private key file */
-
-       if (*tok == '"' || *tok == '\'')  /* quoted filename */
-               memcpy(filename, tok+1, flp->cur - tok - 2);
-       else
-               memcpy(filename, tok, flp->cur - tok);
-
-       if (shift())
-       {
-               /* we expect an appended passphrase or passphrase prompt*/
-               if (tokeqword("%prompt"))
-               {
-                       if (pass.fd == NULL_FD)
-                       {
-                               return "Private key file -- enter passphrase using 'ipsec secrets'";
-                       }
-                       pass.prompt = TRUE;
-               }
-               else
-               {
-                       char *passphrase = tok;
-                       size_t len = flp->cur - passphrase;
-
-                       if (*tok == '"' || *tok == '\'')  /* quoted passphrase */
-                       {
-                               passphrase++;
-                               len -= 2;
-                       }
-                       if (len > PROMPT_PASS_LEN)
-                       {
-                               return "Private key file -- passphrase exceeds 64 characters";
-                       }
-                       memcpy(pass.secret, passphrase, len);
-               }
-               if (shift())
-               {
-                       return "Private key file -- unexpected token after passphrase";
-               }
-       }
-       *key = load_private_key(filename, &pass, type);
-
-       return *key ? NULL : "Private key file -- could not be loaded";
-}
-
-/**
- * Process pin read from ipsec.secrets or prompted for it using whack
- */
-static err_t process_pin(secret_t *s, int whackfd)
-{
-       smartcard_t *sc;
-       const char *pin_status = "no pin";
-
-       s->kind = SECRET_PIN;
-
-       /* looking for the smartcard keyword */
-       if (!shift() || strncmp(tok, SCX_TOKEN, strlen(SCX_TOKEN)) != 0)
-                return "PIN keyword must be followed by %smartcard<reader>:<id>";
-
-       sc = scx_add(scx_parse_number_slot_id(tok + strlen(SCX_TOKEN)));
-       s->u.smartcard = sc;
-       scx_share(sc);
-       if (sc->pin.ptr != NULL)
-       {
-               scx_release_context(sc);
-               scx_free_pin(&sc->pin);
-       }
-       sc->valid = FALSE;
-
-       if (!shift())
-               return "PIN statement must be terminated either by <pin code>, %pinpad or %prompt";
-
-       if (tokeqword("%prompt"))
-       {
-               shift();
-               /* if whackfd exists, whack will be used to prompt for a pin */
-               if (whackfd != NULL_FD)
-                       pin_status = scx_get_pin(sc, whackfd) ? "valid pin" : "invalid pin";
-               else
-                       pin_status = "pin entry via prompt";
-       }
-       else if (tokeqword("%pinpad"))
-       {
-               chunk_t empty_pin = { "", 0 };
-
-               shift();
-
-               /* pin will be entered via pin pad during verification */
-               sc->pin = chunk_clone(empty_pin);
-               sc->pinpad = TRUE;
-               sc->valid = TRUE;
-               pin_status = "pin entry via pad";
-               if (pkcs11_keep_state)
-               {
-                       scx_verify_pin(sc);
-               }
-       }
-       else
-       {
-               /* we read the pin directly from ipsec.secrets */
-               err_t ugh = process_psk_secret(&sc->pin);
-               if (ugh != NULL)
-               return ugh;
-               /* verify the pin */
-               pin_status = scx_verify_pin(sc) ? "valid PIN" : "invalid PIN";
-       }
-#ifdef SMARTCARD
-       {
-               char buf[BUF_LEN];
-
-               if (sc->any_slot)
-                       snprintf(buf, BUF_LEN, "any slot");
-               else
-                       snprintf(buf, BUF_LEN, "slot: %lu", sc->slot);
-
-               plog("  %s for #%d (%s, id: %s)"
-                       , pin_status, sc->number, scx_print_slot(sc, ""), sc->id);
-       }
-#else
-       plog("  warning: SMARTCARD support is deactivated in pluto/Makefile!");
-#endif
-       return NULL;
-}
-
-static void log_psk(char *label, secret_t *s)
-{
-       int n = 0;
-       char buf[BUF_LEN];
-       enumerator_t *enumerator;
-       identification_t *id;
-
-       if (s->ids->get_count(s->ids) == 0)
-       {
-               n = snprintf(buf, BUF_LEN, "%%any");
-       }
-       else
-       {
-               enumerator = s->ids->create_enumerator(s->ids);
-               while(enumerator->enumerate(enumerator, &id))
-               {
-                       n += snprintf(buf + n, BUF_LEN - n, "%Y ", id);
-                       if (n >= BUF_LEN)
-                       {
-                               n = BUF_LEN - 1;
-                               break;
-                       }
-               }
-               enumerator->destroy(enumerator);
-       }
-       plog("  loaded %s secret for %.*s", label, n, buf);
-}
-
-static void process_secret(secret_t *s, int whackfd)
-{
-       err_t ugh = NULL;
-
-       s->kind = SECRET_PSK;  /* default */
-       if (tokeqword("psk"))
-       {
-               log_psk("PSK", s);
-
-               /* preshared key: quoted string or ttodata format */
-               ugh = !shift()? "unexpected end of record in PSK"
-                       : process_psk_secret(&s->u.preshared_secret);
-       }
-       else if (tokeqword("xauth"))
-       {
-               s->kind = SECRET_XAUTH;
-               log_psk("XAUTH", s);
-
-               /* xauth secret: quoted string or ttodata format */
-               ugh = !shift()? "unexpected end of record in XAUTH"
-                       : process_psk_secret(&s->u.preshared_secret);
-       }
-       else if (tokeqword("rsa"))
-       {
-               /* RSA key: the fun begins.
-                * A braced list of keyword and value pairs.
-                */
-               s->kind = SECRET_PUBKEY;
-               if (!shift())
-               {
-                       ugh = "bad RSA key syntax";
-               }
-               else if (tokeq("{"))
-               {
-                       ugh = process_rsa_secret(&s->u.private_key);
-               }
-               else
-               {
-                  ugh = process_keyfile(&s->u.private_key, KEY_RSA, whackfd);
-               }
-       }
-       else if (tokeqword("ecdsa"))
-       {
-               s->kind = SECRET_PUBKEY;
-               if (!shift())
-               {
-                       ugh = "bad ECDSA key syntax";
-               }
-               else
-               {
-                  ugh = process_keyfile(&s->u.private_key, KEY_ECDSA, whackfd);
-               }
-       }
-       else if (tokeqword("pin"))
-       {
-               ugh = process_pin(s, whackfd);
-       }
-       else
-       {
-               ugh = builddiag("unrecognized key format: %s", tok);
-       }
-
-       if (ugh != NULL)
-       {
-               loglog(RC_LOG_SERIOUS, "\"%s\" line %d: %s"
-                       , flp->filename, flp->lino, ugh);
-               s->ids->destroy_offset(s->ids, offsetof(identification_t, destroy));
-               free(s);
-       }
-       else if (flushline("expected record boundary in key"))
-       {
-               /* gauntlet has been run: install new secret */
-               lock_certs_and_keys("process_secret");
-               s->next = secrets;
-               secrets = s;
-               unlock_certs_and_keys("process_secrets");
-       }
-}
-
-static void process_secrets_file(const char *file_pat, int whackfd);    /* forward declaration */
-
-static void process_secret_records(int whackfd)
-{
-       /* read records from ipsec.secrets and load them into our table */
-       for (;;)
-       {
-               (void)flushline(NULL);  /* silently ditch leftovers, if any */
-               if (flp->bdry == B_file)
-               {
-                       break;
-               }
-               flp->bdry = B_none;     /* eat the Record Boundary */
-               (void)shift();  /* get real first token */
-
-               if (tokeqword("include"))
-               {
-                       /* an include directive */
-                       char fn[MAX_TOK_LEN];       /* space for filename (I hope) */
-                       char *p = fn;
-                       char *end_prefix = strrchr(flp->filename, '/');
-
-                       if (!shift())
-                       {
-                               loglog(RC_LOG_SERIOUS, "\"%s\" line %d: unexpected end of include directive"
-                                       , flp->filename, flp->lino);
-                               continue;   /* abandon this record */
-                       }
-
-                       /* if path is relative and including file's pathname has
-                        * a non-empty dirname, prefix this path with that dirname.
-                        */
-                       if (tok[0] != '/' && end_prefix != NULL)
-                       {
-                               size_t pl = end_prefix - flp->filename + 1;
-
-                               /* "clamp" length to prevent problems now;
-                                * will be rediscovered and reported later.
-                                */
-                               if (pl > sizeof(fn))
-                               {
-                                       pl = sizeof(fn);
-                               }
-                               memcpy(fn, flp->filename, pl);
-                               p += pl;
-                       }
-                       if (flp->cur - tok >= &fn[sizeof(fn)] - p)
-                       {
-                               loglog(RC_LOG_SERIOUS, "\"%s\" line %d: include pathname too long"
-                                       , flp->filename, flp->lino);
-                               continue;   /* abandon this record */
-                       }
-                       strcpy(p, tok);
-                       (void) shift();     /* move to Record Boundary, we hope */
-                       if (flushline("ignoring malformed INCLUDE -- expected Record Boundary after filename"))
-                       {
-                               process_secrets_file(fn, whackfd);
-                               tok = NULL;     /* correct, but probably redundant */
-                       }
-               }
-               else
-               {
-                       /* expecting a list of indices and then the key info */
-                       secret_t *s = malloc_thing(secret_t);
-
-                       zero(s);
-                       s->ids = linked_list_create();
-                       s->kind = SECRET_PSK;  /* default */
-                       s->u.preshared_secret = chunk_empty;
-                       s->next = NULL;
-
-                       for (;;)
-                       {
-                               if (tokeq(":"))
-                               {
-                                       /* found key part */
-                                       shift();    /* discard explicit separator */
-                                       process_secret(s, whackfd);
-                                       break;
-                               }
-                               else
-                               {
-                                       identification_t *id;
-
-                                       id = identification_create_from_string(tok);
-                                       s->ids->insert_last(s->ids, id);
-
-                                       if (!shift())
-                                       {
-                                               /* unexpected Record Boundary or EOF */
-                                               loglog(RC_LOG_SERIOUS, "\"%s\" line %d: unexpected end"
-                                                          " of id list", flp->filename, flp->lino);
-                                               s->ids->destroy_offset(s->ids,
-                                                                               offsetof(identification_t, destroy));
-                                               free(s);
-                                               break;
-                                       }
-                               }
-                       }
-               }
-       }
-}
-
-static int globugh(const char *epath, int eerrno)
-{
-       log_errno_routine(eerrno, "problem with secrets file \"%s\"", epath);
-       return 1;   /* stop glob */
-}
-
-static void process_secrets_file(const char *file_pat, int whackfd)
-{
-       struct file_lex_position pos;
-       char **fnp;
-
-       pos.depth = flp == NULL? 0 : flp->depth + 1;
-
-       if (pos.depth > 10)
-       {
-               loglog(RC_LOG_SERIOUS, "preshared secrets file \"%s\" nested too deeply", file_pat);
-               return;
-       }
-
-#ifdef HAVE_GLOB_H
-       /* do globbing */
-       {
-               glob_t globbuf;
-               int r = glob(file_pat, GLOB_ERR, globugh, &globbuf);
-
-               if (r != 0)
-               {
-                       switch (r)
-                       {
-                       case GLOB_NOSPACE:
-                               loglog(RC_LOG_SERIOUS, "out of space processing secrets filename \"%s\"", file_pat);
-                               break;
-                       case GLOB_ABORTED:
-                               break;  /* already logged */
-                       case GLOB_NOMATCH:
-                               loglog(RC_LOG_SERIOUS, "no secrets filename matched \"%s\"", file_pat);
-                               break;
-                       default:
-                               loglog(RC_LOG_SERIOUS, "unknown glob error %d", r);
-                               break;
-                       }
-                       globfree(&globbuf);
-                       return;
-               }
-
-               /* for each file... */
-               for (fnp = globbuf.gl_pathv; *fnp != NULL; fnp++)
-               {
-                       if (lexopen(&pos, *fnp, FALSE))
-                       {
-                               plog("loading secrets from \"%s\"", *fnp);
-                               flushline("file starts with indentation (continuation notation)");
-                               process_secret_records(whackfd);
-                               lexclose();
-                       }
-               }
-
-               globfree(&globbuf);
-       }
-#else /* HAVE_GLOB_H */
-       /* if glob(3) is not available, try to load pattern directly */
-       if (lexopen(&pos, file_pat, FALSE))
-       {
-               plog("loading secrets from \"%s\"", file_pat);
-               flushline("file starts with indentation (continuation notation)");
-               process_secret_records(whackfd);
-               lexclose();
-       }
-#endif /* HAVE_GLOB_H */
-}
-
-void free_preshared_secrets(void)
-{
-       lock_certs_and_keys("free_preshared_secrets");
-
-       if (secrets != NULL)
-       {
-               secret_t *s, *ns;
-
-               plog("forgetting secrets");
-
-               for (s = secrets; s != NULL; s = ns)
-               {
-                       ns = s->next;
-                       s->ids->destroy_offset(s->ids, offsetof(identification_t, destroy));
-
-                       switch (s->kind)
-                       {
-                               case SECRET_PSK:
-                               case SECRET_XAUTH:
-                                       free(s->u.preshared_secret.ptr);
-                                       break;
-                               case SECRET_PUBKEY:
-                                       DESTROY_IF(s->u.private_key);
-                                       break;
-                               case SECRET_PIN:
-                                       scx_release(s->u.smartcard);
-                                       break;
-                               default:
-                                       bad_case(s->kind);
-                       }
-                       free(s);
-               }
-               secrets = NULL;
-       }
-
-       unlock_certs_and_keys("free_preshard_secrets");
-}
-
-void load_preshared_secrets(int whackfd)
-{
-       free_preshared_secrets();
-       (void) process_secrets_file(shared_secrets_file, whackfd);
-}
-
-/* public key machinery
- * Note: caller must set dns_auth_level.
- */
-
-pubkey_t* public_key_from_rsa(public_key_t *key)
-{
-       pubkey_t *p = malloc_thing(pubkey_t);
-
-       zero(p);
-       p->id = identification_create_from_string("%any");  /* don't know, doesn't matter */
-       p->issuer = NULL;
-       p->serial = chunk_empty;
-       p->public_key = key;
-
-       /* note that we return a 1 reference count upon creation:
-        * invariant: recount > 0.
-        */
-       p->refcnt = 1;
-       return p;
-}
-
-/* Free a public key record.
- * As a convenience, this returns a pointer to next.
- */
-pubkey_list_t* free_public_keyentry(pubkey_list_t *p)
-{
-       pubkey_list_t *nxt = p->next;
-
-       if (p->key != NULL)
-       {
-               unreference_key(&p->key);
-       }
-       free(p);
-       return nxt;
-}
-
-void free_public_keys(pubkey_list_t **keys)
-{
-       while (*keys != NULL)
-       {
-               *keys = free_public_keyentry(*keys);
-       }
-}
-
-/* root of chained public key list */
-
-pubkey_list_t *pubkeys = NULL;  /* keys from ipsec.conf */
-
-void free_remembered_public_keys(void)
-{
-       free_public_keys(&pubkeys);
-}
-
-/**
- * Transfer public keys from *keys list to front of pubkeys list
- */
-void transfer_to_public_keys(struct gw_info *gateways_from_dns
-#ifdef USE_KEYRR
-, pubkey_list_t **keys
-#endif /* USE_KEYRR */
-)
-{
-       {
-               struct gw_info *gwp;
-
-               for (gwp = gateways_from_dns; gwp != NULL; gwp = gwp->next)
-               {
-                       pubkey_list_t *pl = malloc_thing(pubkey_list_t);
-
-                       pl->key = gwp->key; /* note: this is a transfer */
-                       gwp->key = NULL;    /* really, it is! */
-                       pl->next = pubkeys;
-                       pubkeys = pl;
-               }
-       }
-
-#ifdef USE_KEYRR
-       {
-               pubkey_list_t **pp = keys;
-
-               while (*pp != NULL)
-               {
-                       pp = &(*pp)->next;
-               }
-               *pp = pubkeys;
-               pubkeys = *keys;
-               *keys = NULL;
-       }
-#endif /* USE_KEYRR */
-}
-
-
-static void install_public_key(pubkey_t *pk, pubkey_list_t **head)
-{
-       pubkey_list_t *p = malloc_thing(pubkey_list_t);
-
-       /* install new key at front */
-       p->key = reference_key(pk);
-       p->next = *head;
-       *head = p;
-}
-
-void delete_public_keys(identification_t *id, key_type_t type,
-                                               identification_t *issuer, chunk_t serial)
-{
-       pubkey_list_t **pp, *p;
-       pubkey_t *pk;
-       key_type_t pk_type;
-
-       for (pp = &pubkeys; (p = *pp) != NULL; )
-       {
-               pk = p->key;
-               pk_type = pk->public_key->get_type(pk->public_key);
-
-               if (id->equals(id, pk->id) && pk_type == type
-               && (issuer == NULL || pk->issuer == NULL
-                       || issuer->equals(issuer, pk->issuer))
-               && (serial.ptr == NULL || chunk_equals(serial, pk->serial)))
-               {
-                       *pp = free_public_keyentry(p);
-               }
-               else
-               {
-                       pp = &p->next;
-               }
-       }
-}
-
-pubkey_t* reference_key(pubkey_t *pk)
-{
-       DBG(DBG_CONTROLMORE,
-               DBG_log("  ref key: %p %p cnt %d '%Y'",
-                                pk, pk->public_key, pk->refcnt, pk->id)
-       )
-       pk->refcnt++;
-       return pk;
-}
-
-void unreference_key(pubkey_t **pkp)
-{
-       pubkey_t *pk = *pkp;
-
-       if (pk == NULL)
-       {
-               return;
-       }
-
-       DBG(DBG_CONTROLMORE,
-               DBG_log("unref key: %p %p cnt %d '%Y'",
-                                pk, pk->public_key, pk->refcnt, pk->id)
-       )
-
-       /* cancel out the pointer */
-       *pkp = NULL;
-
-       passert(pk->refcnt != 0);
-       pk->refcnt--;
-       if (pk->refcnt == 0)
-       {
-               free_public_key(pk);
-       }
-}
-
-bool add_public_key(identification_t *id, enum dns_auth_level dns_auth_level,
-                                       enum pubkey_alg alg, chunk_t rfc3110_key,
-                                       pubkey_list_t **head)
-{
-       public_key_t *key = NULL;
-       pubkey_t *pk;
-
-   /* first: algorithm-specific decoding of key chunk */
-       switch (alg)
-       {
-               case PUBKEY_ALG_RSA:
-                       key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
-                                                                               BUILD_BLOB_DNSKEY, rfc3110_key,
-                                                                               BUILD_END);
-                       if (key == NULL)
-                       {
-                               return FALSE;
-                       }
-                       break;
-               default:
-                       bad_case(alg);
-       }
-
-       pk = malloc_thing(pubkey_t);
-       zero(pk);
-       pk->public_key = key;
-       pk->id = id->clone(id);
-       pk->dns_auth_level = dns_auth_level;
-       pk->until_time = UNDEFINED_TIME;
-       pk->issuer = NULL;
-       pk->serial = chunk_empty;
-       install_public_key(pk, head);
-       return TRUE;
-}
-
-/**
- * Extract id and public key a certificate and insert it into a pubkeyrec
- */
-void add_public_key_from_cert(cert_t *cert , time_t until,
-                                                         enum dns_auth_level dns_auth_level)
-{
-       certificate_t *certificate = cert->cert;
-       identification_t *subject = certificate->get_subject(certificate);
-       identification_t *issuer = NULL;
-       identification_t *id;
-       chunk_t serialNumber = chunk_empty;
-       pubkey_t *pk;
-       key_type_t pk_type;
-
-       /* ID type: ID_DER_ASN1_DN  (X.509 subject field) */
-       pk = malloc_thing(pubkey_t);
-       zero(pk);
-       pk->public_key = certificate->get_public_key(certificate);
-       pk_type = pk->public_key->get_type(pk->public_key);
-       pk->id = subject->clone(subject);
-       pk->dns_auth_level = dns_auth_level;
-       pk->until_time = until;
-       if (certificate->get_type(certificate) == CERT_X509)
-       {
-               x509_t *x509 = (x509_t*)certificate;
-
-               issuer = certificate->get_issuer(certificate);
-               serialNumber = x509->get_serial(x509);
-               pk->issuer = issuer->clone(issuer);
-               pk->serial = chunk_clone(serialNumber);
-       }
-       delete_public_keys(pk->id, pk_type, pk->issuer, pk->serial);
-       install_public_key(pk, &pubkeys);
-
-       if (certificate->get_type(certificate) == CERT_X509)
-       {
-               x509_t *x509 = (x509_t*)certificate;
-               enumerator_t *enumerator;
-
-               /* insert all subjectAltNames from X.509 certificates */
-               enumerator = x509->create_subjectAltName_enumerator(x509);
-               while (enumerator->enumerate(enumerator, &id))
-               {
-                       if (id->get_type(id) != ID_ANY)
-                       {
-                               pk = malloc_thing(pubkey_t);
-                               zero(pk);
-                               pk->id = id->clone(id);
-                               pk->public_key = certificate->get_public_key(certificate);
-                               pk->dns_auth_level = dns_auth_level;
-                               pk->until_time = until;
-                               pk->issuer = issuer->clone(issuer);
-                               pk->serial = chunk_clone(serialNumber);
-                               delete_public_keys(pk->id, pk_type, pk->issuer, pk->serial);
-                               install_public_key(pk, &pubkeys);
-                       }
-               }
-               enumerator->destroy(enumerator);
-       }
-       else
-       {
-               pgp_certificate_t *pgp_cert = (pgp_certificate_t*)certificate;
-               chunk_t fingerprint = pgp_cert->get_fingerprint(pgp_cert);
-
-               /* add v3 or v4 PGP fingerprint */
-               pk = malloc_thing(pubkey_t);
-               zero(pk);
-               pk->id = identification_create_from_encoding(ID_KEY_ID, fingerprint);
-               pk->public_key = certificate->get_public_key(certificate);
-               pk->dns_auth_level = dns_auth_level;
-               pk->until_time = until;
-               delete_public_keys(pk->id, pk_type, pk->issuer, pk->serial);
-               install_public_key(pk, &pubkeys);
-       }
-}
-
-/*  when a X.509 certificate gets revoked, all instances of
- *  the corresponding public key must be removed
- */
-void remove_x509_public_key(const cert_t *cert)
-{
-       public_key_t *revoked_key = cert->cert->get_public_key(cert->cert);
-       pubkey_list_t *p, **pp;
-
-       p  = pubkeys;
-       pp = &pubkeys;
-
-       while(p != NULL)
-       {
-               if (revoked_key->equals(revoked_key, p->key->public_key))
-               {
-                       /* remove p from list and free memory */
-                       *pp = free_public_keyentry(p);
-                       loglog(RC_LOG_SERIOUS, "invalid public key deleted");
-               }
-               else
-               {
-                       pp = &p->next;
-               }
-               p =*pp;
-       }
-       revoked_key->destroy(revoked_key);
-}
-
-/*
- *  list all public keys in the chained list
- */
-void list_public_keys(bool utc)
-{
-       pubkey_list_t *p = pubkeys;
-       chunk_t serial;
-
-       if (p != NULL)
-       {
-               whack_log(RC_COMMENT, " ");
-               whack_log(RC_COMMENT, "List of Public Keys:");
-       }
-
-       while (p != NULL)
-       {
-               pubkey_t *key = p->key;
-               public_key_t *public = key->public_key;
-               chunk_t keyid;
-
-               whack_log(RC_COMMENT, " ");
-               whack_log(RC_COMMENT, "  identity: '%Y'", key->id);
-               whack_log(RC_COMMENT, "  pubkey:    %N %4d bits, until %T %s",
-                       key_type_names, public->get_type(public),
-                       public->get_keysize(public),
-                       &key->until_time, utc,
-                       check_expiry(key->until_time, PUBKEY_WARNING_INTERVAL, TRUE));
-               if (public->get_fingerprint(public, KEYID_PUBKEY_INFO_SHA1, &keyid))
-               {
-                       whack_log(RC_COMMENT,"  keyid:     %#B", &keyid);
-               }
-               if (key->issuer)
-               {
-                       whack_log(RC_COMMENT,"  issuer:   \"%Y\"", key->issuer);
-               }
-               if (key->serial.len)
-               {
-                       serial = chunk_skip_zero(key->serial);
-                       whack_log(RC_COMMENT,"  serial:    %#B", &serial);
-               }
-               p = p->next;
-       }
-}
diff --git a/src/pluto/keys.h b/src/pluto/keys.h
deleted file mode 100644 (file)
index 73cc213..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/* mechanisms for preshared keys (public, private, and preshared secrets)
- * Copyright (C) 1998-2002  D. Hugh Redelmeier.
- * Copyright (C) 2009 Andreas Steffen, Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef _KEYS_H
-#define _KEYS_H
-
-#include <utils/identification.h>
-#include <credentials/keys/private_key.h>
-#include <credentials/keys/public_key.h>
-
-#include "certs.h"
-#include "connections.h"
-
-#ifndef SHARED_SECRETS_FILE
-# define SHARED_SECRETS_FILE  IPSEC_CONFDIR "/ipsec.secrets"
-#endif
-
-const char *shared_secrets_file;
-
-extern void load_preshared_secrets(int whackfd);
-extern void free_preshared_secrets(void);
-
-extern void xauth_defaults(void);
-
-extern bool get_xauth_secret(identification_t *user, identification_t *server,
-                                                        chunk_t *secret);
-extern const chunk_t *get_preshared_secret(const connection_t *c);
-extern private_key_t *get_private_key(const connection_t *c);
-extern private_key_t *get_x509_private_key(const cert_t *cert);
-
-/* public key machinery  */
-
-typedef struct pubkey pubkey_t;
-
-struct pubkey {
-       identification_t *id;
-       unsigned refcnt;    /* reference counted! */
-       enum dns_auth_level dns_auth_level;
-       char *dns_sig;
-       time_t last_tried_time, last_worked_time, until_time;
-       identification_t *issuer;
-       chunk_t serial;
-       public_key_t *public_key;
-};
-
-typedef struct pubkey_list pubkey_list_t;
-
-struct pubkey_list {
-       pubkey_t *key;
-       pubkey_list_t *next;
-};
-
-extern pubkey_list_t *pubkeys;  /* keys from ipsec.conf or from certs */
-
-extern pubkey_t *public_key_from_rsa(public_key_t *key);
-extern pubkey_list_t *free_public_keyentry(pubkey_list_t *p);
-extern void free_public_keys(pubkey_list_t **keys);
-extern void free_remembered_public_keys(void);
-extern void delete_public_keys(identification_t *id, key_type_t type,
-                                                          identification_t *issuer, chunk_t serial);
-extern pubkey_t *reference_key(pubkey_t *pk);
-extern void unreference_key(pubkey_t **pkp);
-extern bool add_public_key(identification_t *id,
-                                                  enum dns_auth_level dns_auth_level,
-                                                  enum pubkey_alg alg,
-                                                  chunk_t rfc3110_key,
-                                                  pubkey_list_t **head);
-extern bool has_private_key(cert_t *cert);
-extern void add_public_key_from_cert(cert_t *cert, time_t until,
-                                                                        enum dns_auth_level dns_auth_level);
-extern void remove_x509_public_key(const cert_t *cert);
-extern void list_public_keys(bool utc);
-
-struct gw_info; /* forward declaration of tag (defined in dnskey.h) */
-extern void transfer_to_public_keys(struct gw_info *gateways_from_dns
-#ifdef USE_KEYRR
-       , pubkey_list_t **keys
-#endif /* USE_KEYRR */
-       );
-
-#endif /* _KEYS_H */
diff --git a/src/pluto/lex.c b/src/pluto/lex.c
deleted file mode 100644 (file)
index d5ebdab..0000000
+++ /dev/null
@@ -1,211 +0,0 @@
-/* lexer (lexical analyzer) for control files
- * Copyright (C) 1998-2001  D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "whack.h"      /* for RC_LOG_SERIOUS */
-#include "lex.h"
-
-struct file_lex_position *flp = NULL;
-
-/* Open a file for lexical processing.
- * new_flp and name must point into storage with will live
- * at least until the file is closed.
- */
-bool
-lexopen(struct file_lex_position *new_flp, const char *name, bool optional)
-{
-       FILE *f = fopen(name, "r");
-
-       if (f == NULL)
-       {
-               if (!optional || errno != ENOENT)
-                       log_errno((e, "could not open \"%s\"", name));
-               return FALSE;
-       }
-       else
-       {
-               new_flp->previous = flp;
-               flp = new_flp;
-               flp->filename = name;
-               flp->fp = f;
-               flp->lino = 0;
-               flp->bdry = B_none;
-
-               flp->cur = flp->buffer; /* nothing loaded yet */
-               flp->under = *flp->cur = '\0';
-
-               (void) shift(); /* prime tok */
-               return TRUE;
-       }
-}
-
-void
-lexclose(void)
-{
-       fclose(flp->fp);
-       flp = flp->previous;
-}
-
-/* Token decoding: shift() loads the next token into tok.
- * Iff a token starts at the left margin, it is considered
- * to be the first in a record.  We create a special condition,
- * Record Boundary (analogous to EOF), just before such a token.
- * We are unwilling to shift through a record boundary:
- * it must be overridden first.
- * Returns FALSE iff Record Boundary or EOF (i.e. no token);
- * tok will then be NULL.
- */
-
-char *tok;
-#define tokeq(s) (streq(tok, (s)))
-#define tokeqword(s) (strcasecmp(tok, (s)) == 0)
-
-bool
-shift(void)
-{
-       char *p = flp->cur;
-       char *sor = NULL;   /* start of record for any new lines */
-
-       passert(flp->bdry == B_none);
-
-       *p = flp->under;
-       flp->under = '\0';
-
-       for (;;)
-       {
-               switch (*p)
-               {
-               case '\0':      /* end of line */
-               case '#':       /* comment to end of line: treat as end of line */
-                       /* get the next line */
-                       if (fgets(flp->buffer, sizeof(flp->buffer)-1, flp->fp) == NULL)
-                       {
-                               flp->bdry = B_file;
-                               tok = flp->cur = NULL;
-                               return FALSE;
-                       }
-                       else
-                       {
-                               /* strip trailing whitespace, including \n */
-
-                               for (p = flp->buffer+strlen(flp->buffer)-1
-                               ; p>flp->buffer && isspace(p[-1]); p--)
-                                       ;
-                               *p = '\0';
-
-                               flp->lino++;
-                               sor = p = flp->buffer;
-                       }
-                       break;      /* try again for a token */
-
-               case ' ':       /* whitespace */
-               case '\t':
-                       p++;
-                       break;      /* try again for a token */
-
-               case '"':       /* quoted token */
-               case '\'':
-                       if (p != sor)
-                       {
-                               /* we have a quoted token: note and advance to its end */
-                               tok = p;
-                               p = strchr(p+1, *p);
-                               if (p == NULL)
-                               {
-                                       loglog(RC_LOG_SERIOUS, "\"%s\" line %d: unterminated string"
-                                               , flp->filename, flp->lino);
-                                       p = tok + strlen(tok);
-                               }
-                               else
-                               {
-                                       p++;        /* include delimiter in token */
-                               }
-
-                               /* remember token delimiter and replace with '\0' */
-                               flp->under = *p;
-                               *p = '\0';
-                               flp->cur = p;
-                               return TRUE;
-                       }
-                       /* FALL THROUGH */
-               default:
-                       if (p != sor)
-                       {
-                               /* we seem to have a token: note and advance to its end */
-                               tok = p;
-
-                               if (p[0] == '0' && p[1] == 't')
-                               {
-                                       /* 0t... token goes to end of line */
-                                       p += strlen(p);
-                               }
-                               else
-                               {
-                                       /* "ordinary" token: up to whitespace or end of line */
-                                       do {
-                                               p++;
-                                       } while (*p != '\0' && !isspace(*p))
-                                               ;
-
-                                       /* fudge to separate ':' from a preceding adjacent token */
-                                       if (p-1 > tok && p[-1] == ':')
-                                               p--;
-                               }
-
-                               /* remember token delimiter and replace with '\0' */
-                               flp->under = *p;
-                               *p = '\0';
-                               flp->cur = p;
-                               return TRUE;
-                       }
-
-                       /* we have a start-of-record: return it, deferring "real" token */
-                       flp->bdry = B_record;
-                       tok = NULL;
-                       flp->under = *p;
-                       flp->cur = p;
-                       return FALSE;
-               }
-       }
-}
-
-/* ensures we are at a Record (or File) boundary, optionally warning if not */
-
-bool
-flushline(const char *m)
-{
-       if (flp->bdry != B_none)
-       {
-               return TRUE;
-       }
-       else
-       {
-               if (m != NULL)
-                       loglog(RC_LOG_SERIOUS, "\"%s\" line %d: %s", flp->filename, flp->lino, m);
-               do {} while (shift());
-               return FALSE;
-       }
-}
diff --git a/src/pluto/lex.h b/src/pluto/lex.h
deleted file mode 100644 (file)
index aa0be78..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/* lexer (lexical analyzer) for control files
- * Copyright (C) 1998-2001  D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#define MAX_TOK_LEN 2048    /* includes terminal '\0' */
-struct file_lex_position
-{
-       int depth;  /* how deeply we are nested */
-       const char *filename;
-       FILE *fp;
-       enum { B_none, B_record, B_file } bdry;     /* current boundary */
-       int lino;   /* line number in file */
-       char buffer[MAX_TOK_LEN + 1];    /* note: one extra char for our use (jamming '"') */
-       char *cur;  /* cursor */
-       char under; /* except in shift(): character originally at *cur */
-       struct file_lex_position *previous;
-};
-
-extern struct file_lex_position *flp;
-
-extern bool lexopen(struct file_lex_position *new_flp, const char *name, bool optional);
-extern void lexclose(void);
-
-
-/* Token decoding: shift() loads the next token into tok.
- * Iff a token starts at the left margin, it is considered
- * to be the first in a record.  We create a special condition,
- * Record Boundary (analogous to EOF), just before such a token.
- * We are unwilling to shift through a record boundary:
- * it must be overridden first.
- * Returns FALSE iff Record Boundary or EOF (i.e. no token);
- * tok will then be NULL.
- */
-
-extern char *tok;
-#define tokeq(s) (streq(tok, (s)))
-#define tokeqword(s) (strcasecmp(tok, (s)) == 0)
-
-extern bool shift(void);
-extern bool flushline(const char *m);
diff --git a/src/pluto/log.c b/src/pluto/log.c
deleted file mode 100644 (file)
index f6fa226..0000000
+++ /dev/null
@@ -1,946 +0,0 @@
-/* error logging functions
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
- * Copyright (C) 2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <stdarg.h>
-#include <syslog.h>
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-#include <signal.h>     /* used only if MSG_NOSIGNAL not defined */
-#include <sys/queue.h>
-#include <libgen.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#ifdef ANDROID
-#include <android/log.h>
-#endif
-
-#include <freeswan.h>
-#include <library.h>
-#include <debug.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "server.h"
-#include "state.h"
-#include "connections.h"
-#include "myid.h"
-#include "kernel.h"
-#include "whack.h"
-#include "whack_attribute.h"
-#include "timer.h"
-
-/* close one per-peer log */
-static void perpeer_logclose(connection_t *c);     /* forward */
-
-
-bool
-       log_to_stderr = TRUE,       /* should log go to stderr? */
-       log_to_syslog = TRUE,       /* should log go to syslog? */
-       log_to_perpeer= FALSE;      /* should log go to per-IP file? */
-
-bool
-       logged_txt_warning = FALSE;  /* should we complain about finding KEY? */
-
-/* should we complain when we find no local id */
-bool
-       logged_myid_fqdn_txt_warning = FALSE,
-       logged_myid_ip_txt_warning   = FALSE,
-       logged_myid_fqdn_key_warning = FALSE,
-       logged_myid_ip_key_warning   = FALSE;
-
-/* may include trailing / */
-const char *base_perpeer_logdir = PERPEERLOGDIR;
-static int perpeer_count = 0;
-
-/* from sys/queue.h */
-static TAILQ_HEAD(perpeer, connection) perpeer_list;
-
-
-/* Context for logging.
- *
- * Global variables: must be carefully adjusted at transaction boundaries!
- * If the context provides a whack file descriptor, messages
- * should be copied to it -- see whack_log()
- */
-int whack_log_fd = NULL_FD;     /* only set during whack_handle() */
-struct state *cur_state = NULL; /* current state, for diagnostics */
-connection_t *cur_connection = NULL;       /* current connection, for diagnostics */
-const ip_address *cur_from = NULL;      /* source of current current message */
-u_int16_t cur_from_port;        /* host order */
-
-/**
- * pluto dbg function for libstrongswan
- */
-static void pluto_dbg(debug_t group, level_t level, char *fmt, ...)
-{
-       int priority = LOG_INFO;
-       int debug_level;
-       char buffer[8192];
-       char *current = buffer, *next;
-       va_list args;
-
-       if (cur_debugging & DBG_PRIVATE)
-       {
-               debug_level = 4;
-       }
-       else if (cur_debugging & DBG_RAW)
-       {
-               debug_level = 3;
-       }
-       else if (cur_debugging & DBG_PARSING)
-       {
-               debug_level = 2;
-       }
-       else
-       {
-               debug_level = 1;
-       }
-
-       if (level <= debug_level)
-       {
-               va_start(args, fmt);
-
-               if (log_to_stderr)
-               {
-                       if (level > 1)
-                       {
-                               fprintf(stderr, "| ");
-                       }
-                       vfprintf(stderr, fmt, args);
-                       fprintf(stderr, "\n");
-               }
-               if (log_to_syslog
-#ifdef ANDROID
-                       || TRUE
-#endif
-                       )
-               {
-                       /* write in memory buffer first */
-                       vsnprintf(buffer, sizeof(buffer), fmt, args);
-
-                       /* do a syslog with every line */
-                       while (current)
-                       {
-                               next = strchr(current, '\n');
-                               if (next)
-                               {
-                                       *(next++) = '\0';
-                               }
-                               syslog(priority, "%s%s\n", (level > 1)? "| ":"", current);
-#ifdef ANDROID
-                               __android_log_print(level > 1 ? ANDROID_LOG_DEBUG
-                                                                                         : ANDROID_LOG_INFO, "pluto",
-                                                                       "%s%s\n", level > 1 ? "| " : "", current);
-#endif
-                               current = next;
-                       }
-               }
-               va_end(args);
-       }
-}
-
-void
-init_log(const char *program)
-{
-       /* enable pluto debugging hook for libstrongswan */
-       dbg = pluto_dbg;
-
-       if (log_to_stderr)
-       {
-               setbuf(stderr, NULL);
-       }
-       if (log_to_syslog)
-       {
-               openlog(program, LOG_CONS | LOG_NDELAY | LOG_PID, LOG_AUTHPRIV);
-       }
-       TAILQ_INIT(&perpeer_list);
-}
-
-void
-close_peerlog(void)
-{
-       /* exit if the queue has not been initialized */
-       if (perpeer_list.tqh_first == NULL)
-         return;
-
-       /* end of queue is given by pointer to "HEAD" */
-       while (TAILQ_LAST(&perpeer_list, perpeer) != (void *)&perpeer_list)
-          perpeer_logclose(TAILQ_LAST(&perpeer_list, perpeer));
-}
-
-void
-close_log(void)
-{
-       if (log_to_syslog)
-               closelog();
-
-       close_peerlog();
-}
-
-/* Sanitize character string in situ: turns dangerous characters into \OOO.
- * With a bit of work, we could use simpler reps for \\, \r, etc.,
- * but this is only to protect against something that shouldn't be used.
- * Truncate resulting string to what fits in buffer.
- */
-static size_t
-sanitize(char *buf, size_t size)
-{
-#   define UGLY_WIDTH   4       /* width for ugly character: \OOO */
-       size_t len;
-       size_t added = 0;
-       char *p;
-
-       passert(size >= UGLY_WIDTH);        /* need room to swing cat */
-
-       /* find right side of string to be sanitized and count
-        * number of columns to be added.  Stop on end of string
-        * or lack of room for more result.
-        */
-       for (p = buf; *p != '\0' && &p[added] < &buf[size - UGLY_WIDTH]; )
-       {
-               unsigned char c = *p++;
-
-               if (c == '\\' || !isprint(c))
-                       added += UGLY_WIDTH - 1;
-       }
-
-       /* at this point, p points after last original character to be
-        * included.  added is how many characters are added to sanitize.
-        * so p[added] will point after last sanitized character.
-        */
-
-       p[added] = '\0';
-       len = &p[added] - buf;
-
-       /* scan backwards, copying characters to their new home
-        * and inserting the expansions for ugly characters.
-        * It is finished when no more shifting is required.
-        * This is a predecrement loop.
-        */
-       while (added != 0)
-       {
-               char fmtd[UGLY_WIDTH + 1];
-               unsigned char c;
-
-               while ((c = *--p) != '\\' && isprint(c))
-                       p[added] = c;
-               added -= UGLY_WIDTH - 1;
-               snprintf(fmtd, sizeof(fmtd), "\\%03o", c);
-               memcpy(p + added, fmtd, UGLY_WIDTH);
-       }
-       return len;
-#   undef UGLY_WIDTH
-}
-
-/* format a string for the log, with suitable prefixes.
- * A format starting with ~ indicates that this is a reprocessing
- * of the message, so prefixing and quoting is suppressed.
- */
-static void
-fmt_log(char *buf, size_t buf_len, const char *fmt, va_list ap)
-{
-       bool reproc = *fmt == '~';
-       size_t ps;
-       connection_t *c = cur_state != NULL ? cur_state->st_connection
-               : cur_connection;
-
-       buf[0] = '\0';
-       if (reproc)
-               fmt++;  /* ~ at start of format suppresses this prefix */
-       else if (c != NULL)
-       {
-               /* start with name of connection */
-               char *const be = buf + buf_len;
-               char *bp = buf;
-
-               snprintf(bp, be - bp, "\"%s\"", c->name);
-               bp += strlen(bp);
-
-               /* if it fits, put in any connection instance information */
-               if (be - bp > CONN_INST_BUF)
-               {
-                       fmt_conn_instance(c, bp);
-                       bp += strlen(bp);
-               }
-
-               if (cur_state != NULL)
-               {
-                       /* state number */
-                       snprintf(bp, be - bp, " #%lu", cur_state->st_serialno);
-                       bp += strlen(bp);
-               }
-               snprintf(bp, be - bp, ": ");
-       }
-       else if (cur_from != NULL)
-       {
-               /* peer's IP address */
-               /* Note: must not use ip_str() because our caller might! */
-               char ab[ADDRTOT_BUF];
-
-               (void) addrtot(cur_from, 0, ab, sizeof(ab));
-               snprintf(buf, buf_len, "packet from %s:%u: "
-                       , ab, (unsigned)cur_from_port);
-       }
-
-       ps = strlen(buf);
-       vsnprintf(buf + ps, buf_len - ps, fmt, ap);
-       if (!reproc)
-               (void)sanitize(buf, buf_len);
-}
-
-static void
-perpeer_logclose(connection_t *c)
-{
-       /* only free/close things if we had used them! */
-       if (c->log_file != NULL)
-       {
-               passert(perpeer_count > 0);
-
-               TAILQ_REMOVE(&perpeer_list, c, log_link);
-               perpeer_count--;
-               fclose(c->log_file);
-               c->log_file=NULL;
-       }
-}
-
-void
-perpeer_logfree(connection_t *c)
-{
-       perpeer_logclose(c);
-       if (c->log_file_name != NULL)
-       {
-               free(c->log_file_name);
-               c->log_file_name = NULL;
-               c->log_file_err = FALSE;
-       }
-}
-
-/* open the per-peer log */
-static void
-open_peerlog(connection_t *c)
-{
-       syslog(LOG_INFO, "opening log file for conn %s", c->name);
-
-       if (c->log_file_name == NULL)
-       {
-               char peername[ADDRTOT_BUF], dname[ADDRTOT_BUF];
-               int  peernamelen, lf_len;
-
-               addrtot(&c->spd.that.host_addr, 'Q', peername, sizeof(peername));
-               peernamelen = strlen(peername);
-
-               /* copy IP address, turning : and . into / */
-               {
-                       char ch, *p, *q;
-
-                       p = peername;
-                       q = dname;
-                       do {
-                               ch = *p++;
-                               if (ch == '.' || ch == ':')
-                                       ch = '/';
-                               *q++ = ch;
-                       } while (ch != '\0');
-               }
-
-               lf_len = peernamelen * 2
-                       + strlen(base_perpeer_logdir)
-                       + sizeof("//.log")
-                       + 1;
-               c->log_file_name = malloc(lf_len);
-
-               fprintf(stderr, "base dir |%s| dname |%s| peername |%s|"
-                               , base_perpeer_logdir, dname, peername);
-               snprintf(c->log_file_name, lf_len, "%s/%s/%s.log"
-                                , base_perpeer_logdir, dname, peername);
-
-               syslog(LOG_DEBUG, "conn %s logfile is %s", c->name, c->log_file_name);
-       }
-
-       /* now open the file, creating directories if necessary */
-
-       {  /* create the directory */
-               char *dname;
-               int   bpl_len = strlen(base_perpeer_logdir);
-               char *slashloc;
-
-               dname = clone_str(c->log_file_name);
-               dname = dirname(dname);
-
-               if (access(dname, W_OK) != 0)
-               {
-                       if (errno != ENOENT)
-                       {
-                               if (c->log_file_err)
-                               {
-                                       syslog(LOG_CRIT, "can not write to %s: %s"
-                                                  , dname, strerror(errno));
-                                       c->log_file_err = TRUE;
-                                       free(dname);
-                                       return;
-                               }
-                       }
-
-                       /* directory does not exist, walk path creating dirs */
-                       /* start at base_perpeer_logdir */
-                       slashloc = dname + bpl_len;
-                       slashloc++;    /* since, by construction there is a slash
-                                                         right there */
-
-                       while (*slashloc != '\0')
-                       {
-                               char saveslash;
-
-                               /* look for next slash */
-                               while (*slashloc != '\0' && *slashloc != '/') slashloc++;
-
-                               saveslash = *slashloc;
-
-                               *slashloc = '\0';
-
-                               if (mkdir(dname, 0750) != 0 && errno != EEXIST)
-                               {
-                                       syslog(LOG_CRIT, "can not create dir %s: %s"
-                                                  , dname, strerror(errno));
-                                       c->log_file_err = TRUE;
-                                       free(dname);
-                                       return;
-                               }
-                               syslog(LOG_DEBUG, "created new directory %s", dname);
-                               *slashloc = saveslash;
-                               slashloc++;
-                       }
-               }
-               free(dname);
-       }
-
-       c->log_file = fopen(c->log_file_name, "a");
-       if (c->log_file == NULL)
-       {
-               if (c->log_file_err)
-               {
-                       syslog(LOG_CRIT, "logging system can not open %s: %s"
-                                  , c->log_file_name, strerror(errno));
-                       c->log_file_err = TRUE;
-               }
-               return;
-       }
-
-       /* look for a connection to close! */
-       while (perpeer_count >= MAX_PEERLOG_COUNT)
-       {
-               /* can not be NULL because perpeer_count > 0 */
-               passert(TAILQ_LAST(&perpeer_list, perpeer) != (void *)&perpeer_list);
-
-               perpeer_logclose(TAILQ_LAST(&perpeer_list, perpeer));
-       }
-
-       /* insert this into the list */
-       TAILQ_INSERT_HEAD(&perpeer_list, c, log_link);
-       passert(c->log_file != NULL);
-       perpeer_count++;
-}
-
-/* log a line to cur_connection's log */
-static void
-peerlog(const char *prefix, const char *m)
-{
-       if (cur_connection == NULL)
-       {
-               /* we can not log it in this case. Oh well. */
-               return;
-       }
-
-       if (cur_connection->log_file == NULL)
-       {
-               open_peerlog(cur_connection);
-       }
-
-       /* despite our attempts above, we may not be able to open the file. */
-       if (cur_connection->log_file != NULL)
-       {
-               char datebuf[32];
-               time_t n;
-               struct tm *t;
-
-               time(&n);
-               t = localtime(&n);
-
-               strftime(datebuf, sizeof(datebuf), "%Y-%m-%d %T", t);
-               fprintf(cur_connection->log_file, "%s %s%s\n", datebuf, prefix, m);
-
-               /* now move it to the front of the list */
-               TAILQ_REMOVE(&perpeer_list, cur_connection, log_link);
-               TAILQ_INSERT_HEAD(&perpeer_list, cur_connection, log_link);
-       }
-}
-
-void
-plog(const char *message, ...)
-{
-       va_list args;
-       char m[LOG_WIDTH];  /* longer messages will be truncated */
-
-       va_start(args, message);
-       fmt_log(m, sizeof(m), message, args);
-       va_end(args);
-
-       if (log_to_stderr)
-               fprintf(stderr, "%s\n", m);
-       if (log_to_syslog)
-               syslog(LOG_WARNING, "%s", m);
-       if (log_to_perpeer)
-               peerlog("", m);
-#ifdef ANDROID
-       __android_log_print(ANDROID_LOG_WARN, "pluto", "%s\n", m);
-#endif
-
-       whack_log(RC_LOG, "~%s", m);
-}
-
-void
-loglog(int mess_no, const char *message, ...)
-{
-       va_list args;
-       char m[LOG_WIDTH];  /* longer messages will be truncated */
-
-       va_start(args, message);
-       fmt_log(m, sizeof(m), message, args);
-       va_end(args);
-
-       if (log_to_stderr)
-               fprintf(stderr, "%s\n", m);
-       if (log_to_syslog)
-               syslog(LOG_WARNING, "%s", m);
-       if (log_to_perpeer)
-               peerlog("", m);
-#ifdef ANDROID
-       __android_log_print(ANDROID_LOG_WARN, "pluto", "%s\n", m);
-#endif
-
-       whack_log(mess_no, "~%s", m);
-}
-
-void
-log_errno_routine(int e, const char *message, ...)
-{
-       va_list args;
-       char m[LOG_WIDTH];  /* longer messages will be truncated */
-
-       va_start(args, message);
-       fmt_log(m, sizeof(m), message, args);
-       va_end(args);
-
-       if (log_to_stderr)
-               fprintf(stderr, "ERROR: %s. Errno %d: %s\n", m, e, strerror(e));
-       if (log_to_syslog)
-               syslog(LOG_ERR, "ERROR: %s. Errno %d: %s", m, e, strerror(e));
-       if (log_to_perpeer)
-               peerlog(strerror(e), m);
-#ifdef ANDROID
-       __android_log_print(ANDROID_LOG_ERROR, "pluto", "ERROR: %s. Errno %d: %s\n",
-                                               m, e, strerror(e));
-#endif
-
-       whack_log(RC_LOG_SERIOUS
-               , "~ERROR: %s. Errno %d: %s", m, e, strerror(e));
-}
-
-void
-exit_log(const char *message, ...)
-{
-       va_list args;
-       char m[LOG_WIDTH];  /* longer messages will be truncated */
-
-       va_start(args, message);
-       fmt_log(m, sizeof(m), message, args);
-       va_end(args);
-
-       if (log_to_stderr)
-               fprintf(stderr, "FATAL ERROR: %s\n", m);
-       if (log_to_syslog)
-               syslog(LOG_ERR, "FATAL ERROR: %s", m);
-       if (log_to_perpeer)
-               peerlog("FATAL ERROR: ", m);
-#ifdef ANDROID
-       __android_log_print(ANDROID_LOG_ERROR, "pluto", "FATAL ERROR: %s\n", m);
-#endif
-
-       whack_log(RC_LOG_SERIOUS, "~FATAL ERROR: %s", m);
-
-       exit_pluto(1);
-}
-
-void
-exit_log_errno_routine(int e, const char *message, ...)
-{
-       va_list args;
-       char m[LOG_WIDTH];  /* longer messages will be truncated */
-
-       va_start(args, message);
-       fmt_log(m, sizeof(m), message, args);
-       va_end(args);
-
-       if (log_to_stderr)
-               fprintf(stderr, "FATAL ERROR: %s. Errno %d: %s\n", m, e, strerror(e));
-       if (log_to_syslog)
-               syslog(LOG_ERR, "FATAL ERROR: %s. Errno %d: %s", m, e, strerror(e));
-       if (log_to_perpeer)
-               peerlog(strerror(e), m);
-#ifdef ANDROID
-       __android_log_print(ANDROID_LOG_ERROR, "pluto", "FATAL ERROR: %s. "
-                                               "Errno %d: %s\n", m, e, strerror(e));
-#endif
-
-       whack_log(RC_LOG_SERIOUS
-               , "~FATAL ERROR: %s. Errno %d: %s", m, e, strerror(e));
-
-       exit_pluto(1);
-}
-
-/* emit message to whack.
- * form is "ddd statename text" where
- * - ddd is a decimal status code (RC_*) as described in whack.h
- * - text is a human-readable annotation
- */
-#ifdef DEBUG
-static volatile sig_atomic_t dying_breath = FALSE;
-#endif
-
-void
-whack_log(int mess_no, const char *message, ...)
-{
-       int wfd = whack_log_fd != NULL_FD ? whack_log_fd
-               : cur_state != NULL ? cur_state->st_whack_sock
-               : NULL_FD;
-
-       if (wfd != NULL_FD
-#ifdef DEBUG
-       || dying_breath
-#endif
-       )
-       {
-               va_list args;
-               char m[LOG_WIDTH];      /* longer messages will be truncated */
-               int prelen = snprintf(m, sizeof(m), "%03d ", mess_no);
-
-               passert(prelen >= 0);
-
-               va_start(args, message);
-               fmt_log(m+prelen, sizeof(m)-prelen, message, args);
-               va_end(args);
-
-#if DEBUG
-               if (dying_breath)
-               {
-                       /* status output copied to log */
-                       if (log_to_stderr)
-                               fprintf(stderr, "%s\n", m + prelen);
-                       if (log_to_syslog)
-                               syslog(LOG_WARNING, "%s", m + prelen);
-                       if (log_to_perpeer)
-                               peerlog("", m);
-#ifdef ANDROID
-                       __android_log_print(ANDROID_LOG_WARN, "pluto", "%s\n", m + prelen);
-#endif
-               }
-#endif
-
-               if (wfd != NULL_FD)
-               {
-                       /* write to whack socket, but suppress possible SIGPIPE */
-                       size_t len = strlen(m);
-#ifdef MSG_NOSIGNAL     /* depends on version of glibc??? */
-                       m[len] = '\n';      /* don't need NUL, do need NL */
-                       (void) send(wfd, m, len + 1, MSG_NOSIGNAL);
-#else /* !MSG_NOSIGNAL */
-                       int r;
-                       struct sigaction act
-                               , oldact;
-
-                       m[len] = '\n';      /* don't need NUL, do need NL */
-                       act.sa_handler = SIG_IGN;
-                       sigemptyset(&act.sa_mask);
-                       act.sa_flags = 0;   /* no nothing */
-                       r = sigaction(SIGPIPE, &act, &oldact);
-                       passert(r == 0);
-
-                       (void) write(wfd, m, len + 1);
-
-                       r = sigaction(SIGPIPE, &oldact, NULL);
-                       passert(r == 0);
-#endif /* !MSG_NOSIGNAL */
-               }
-       }
-}
-
-/* Build up a diagnostic in a static buffer.
- * Although this would be a generally useful function, it is very
- * hard to come up with a discipline that prevents different uses
- * from interfering.  It is intended that by limiting it to building
- * diagnostics, we will avoid this problem.
- * Juggling is performed to allow an argument to be a previous
- * result: the new string may safely depend on the old one.  This
- * restriction is not checked in any way: violators will produce
- * confusing results (without crashing!).
- */
-char diag_space[sizeof(diag_space)];
-
-err_t
-builddiag(const char *fmt, ...)
-{
-       static char diag_space[LOG_WIDTH];  /* longer messages will be truncated */
-       char t[sizeof(diag_space)]; /* build result here first */
-       va_list args;
-
-       va_start(args, fmt);
-       t[0] = '\0';        /* in case nothing terminates string */
-       vsnprintf(t, sizeof(t), fmt, args);
-       va_end(args);
-       strcpy(diag_space, t);
-       return diag_space;
-}
-
-/* Debugging message support */
-
-#ifdef DEBUG
-
-void
-switch_fail(int n, const char *file_str, unsigned long line_no)
-{
-       char buf[30];
-
-       snprintf(buf, sizeof(buf), "case %d unexpected", n);
-       passert_fail(buf, file_str, line_no);
-}
-
-void
-passert_fail(const char *pred_str, const char *file_str, unsigned long line_no)
-{
-       /* we will get a possibly unplanned prefix.  Hope it works */
-       loglog(RC_LOG_SERIOUS, "ASSERTION FAILED at %s:%lu: %s", file_str, line_no, pred_str);
-       if (!dying_breath)
-       {
-               dying_breath = TRUE;
-               show_status(TRUE, NULL);
-       }
-       abort();    /* exiting correctly doesn't always work */
-}
-
-void
-pexpect_log(const char *pred_str, const char *file_str, unsigned long line_no)
-{
-       /* we will get a possibly unplanned prefix.  Hope it works */
-       loglog(RC_LOG_SERIOUS, "EXPECTATION FAILED at %s:%lu: %s", file_str, line_no, pred_str);
-}
-
-lset_t
-       base_debugging = DBG_NONE,  /* default to reporting nothing */
-       cur_debugging =  DBG_NONE;
-
-void
-extra_debugging(const connection_t *c)
-{
-       if(c == NULL)
-       {
-               reset_debugging();
-               return;
-       }
-
-       if (c!= NULL && c->extra_debugging != 0)
-       {
-               plog("enabling for connection: %s"
-                       , bitnamesof(debug_bit_names, c->extra_debugging & ~cur_debugging));
-               cur_debugging |= c->extra_debugging;
-       }
-}
-
-/* log a debugging message (prefixed by "| ") */
-
-void
-DBG_log(const char *message, ...)
-{
-       va_list args;
-       char m[LOG_WIDTH];  /* longer messages will be truncated */
-
-       va_start(args, message);
-       vsnprintf(m, sizeof(m), message, args);
-       va_end(args);
-
-       (void)sanitize(m, sizeof(m));
-
-       if (log_to_stderr)
-               fprintf(stderr, "| %s\n", m);
-       if (log_to_syslog)
-               syslog(LOG_DEBUG, "| %s", m);
-       if (log_to_perpeer)
-               peerlog("| ", m);
-#ifdef ANDROID
-       __android_log_print(ANDROID_LOG_DEBUG, "pluto", "| %s\n", m);
-#endif
-}
-
-/* dump raw bytes in hex to stderr (for lack of any better destination) */
-
-void
-DBG_dump(const char *label, const void *p, size_t len)
-{
-#   define DUMP_LABEL_WIDTH 20  /* arbitrary modest boundary */
-#   define DUMP_WIDTH   (4 * (1 + 4 * 3) + 1)
-       char buf[DUMP_LABEL_WIDTH + DUMP_WIDTH];
-       char *bp;
-       const unsigned char *cp = p;
-
-       bp = buf;
-
-       if (label != NULL && label[0] != '\0')
-       {
-               /* Handle the label.  Care must be taken to avoid buffer overrun. */
-               size_t llen = strlen(label);
-
-               if (llen + 1 > sizeof(buf))
-               {
-                       DBG_log("%s", label);
-               }
-               else
-               {
-                       strcpy(buf, label);
-                       if (buf[llen-1] == '\n')
-                       {
-                               buf[llen-1] = '\0';     /* get rid of newline */
-                               DBG_log("%s", buf);
-                       }
-                       else if (llen < DUMP_LABEL_WIDTH)
-                       {
-                               bp = buf + llen;
-                       }
-                       else
-                       {
-                               DBG_log("%s", buf);
-                       }
-               }
-       }
-
-       do {
-               int i, j;
-
-               for (i = 0; len!=0 && i!=4; i++)
-               {
-                       *bp++ = ' ';
-                       for (j = 0; len!=0 && j!=4; len--, j++)
-                       {
-                               static const char hexdig[] = "0123456789abcdef";
-
-                               *bp++ = ' ';
-                               *bp++ = hexdig[(*cp >> 4) & 0xF];
-                               *bp++ = hexdig[*cp & 0xF];
-                               cp++;
-                       }
-               }
-               *bp = '\0';
-               DBG_log("%s", buf);
-               bp = buf;
-       } while (len != 0);
-#   undef DUMP_LABEL_WIDTH
-#   undef DUMP_WIDTH
-}
-
-#endif /* DEBUG */
-
-static void show_loaded_plugins()
-{
-       whack_log(RC_COMMENT, "loaded plugins: %s",
-                         lib->plugins->loaded_plugins(lib->plugins));
-}
-
-void show_status(bool all, const char *name)
-{
-       if (all)
-       {
-               whack_log(RC_COMMENT, "Status of IKEv1 pluto daemon (strongSwan "VERSION"):");
-               show_ifaces_status();
-               show_myid_status();
-               show_loaded_plugins();
-               show_debug_status();
-               show_pools(name);
-               whack_log(RC_COMMENT, BLANK_FORMAT);    /* spacer */
-       }
-       show_connections_status(all, name);
-       show_states_status(all, name);
-}
-
-/* ip_str: a simple to use variant of addrtot.
- * It stores its result in a static buffer.
- * This means that newer calls overwrite the storage of older calls.
- * Note: this is not used in any of the logging functions, so their
- * callers may use it.
- */
-const char *
-ip_str(const ip_address *src)
-{
-       static char buf[ADDRTOT_BUF];
-
-       addrtot(src, 0, buf, sizeof(buf));
-       return buf;
-}
-
-/*
- * a routine that attempts to schedule itself daily.
- *
- */
-
-void
-daily_log_reset(void)
-{
-       /* now perform actions */
-       logged_txt_warning = FALSE;
-
-       logged_myid_fqdn_txt_warning = FALSE;
-       logged_myid_ip_txt_warning   = FALSE;
-       logged_myid_fqdn_key_warning = FALSE;
-       logged_myid_ip_key_warning   = FALSE;
-}
-
-void
-daily_log_event(void)
-{
-       struct tm lt;
-       time_t t, interval;
-
-       /* attempt to schedule oneself to midnight, local time
-        * do this by getting seconds in the day, and delaying
-        * by 86400 - 3600*hours - 60*minutes - seconds.
-        */
-       time(&t);
-       localtime_r(&t, &lt);
-       interval = 3600 * (24 - lt.tm_hour) - 60 * lt.tm_min - lt.tm_sec;
-
-       event_schedule(EVENT_LOG_DAILY, interval, NULL);
-       daily_log_reset();
-}
-
-/*
- * Local Variables:
- * c-basic-offset:4
- * c-style: pluto
- * End:
- */
diff --git a/src/pluto/log.h b/src/pluto/log.h
deleted file mode 100644 (file)
index 52c01bb..0000000
+++ /dev/null
@@ -1,234 +0,0 @@
-/* logging definitions
- * Copyright (C) 1998-2001  D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <freeswan.h>
-
-#define LOG_WIDTH   1024    /* roof of number of chars in log line */
-
-#ifndef PERPEERLOGDIR
-#define PERPEERLOGDIR "/var/log/pluto/peer"
-#endif
-
-/* our versions of assert: log result */
-
-#ifdef DEBUG
-
-extern void passert_fail(const char *pred_str
-       , const char *file_str, unsigned long line_no) NEVER_RETURNS;
-
-extern void pexpect_log(const char *pred_str
-                                               , const char *file_str, unsigned long line_no);
-
-# define impossible() passert_fail("impossible", __FILE__, __LINE__)
-
-extern void switch_fail(int n
-       , const char *file_str, unsigned long line_no) NEVER_RETURNS;
-
-# define bad_case(n) switch_fail((int) n, __FILE__, __LINE__)
-
-# define passert(pred) { \
-               if (!(pred)) \
-                       passert_fail(#pred, __FILE__, __LINE__); \
-       }
-
-# define pexpect(pred) { \
-               if (!(pred)) \
-                       pexpect_log(#pred, __FILE__, __LINE__); \
-       }
-
-/* assert that an err_t is NULL; evaluate exactly once */
-# define happy(x) { \
-               err_t ugh = x; \
-               if (ugh != NULL) \
-                       passert_fail(ugh, __FILE__, __LINE__); \
-       }
-
-#else /*!DEBUG*/
-
-# define impossible() abort()
-# define bad_case(n) abort()
-# define passert(pred)  { }     /* do nothing */
-# define happy(x)  { (void) x; }        /* evaluate non-judgementally */
-
-#endif /*!DEBUG*/
-
-
-extern bool
-       log_to_stderr,      /* should log go to stderr? */
-       log_to_syslog,      /* should log go to syslog? */
-       log_to_perpeer;     /* should log go to per-IP file? */
-
-extern const char *base_perpeer_logdir;
-
-/* maximum number of files to keep open for per-peer log files */
-#define MAX_PEERLOG_COUNT 16
-
-/* Context for logging.
- *
- * Global variables: must be carefully adjusted at transaction boundaries!
- * All are to be left in RESET condition and will be checked.
- * There are several pairs of routines to set and reset them.
- * If the context provides a whack file descriptor, messages
- * should be copied to it -- see whack_log()
- */
-extern int whack_log_fd;        /* only set during whack_handle() */
-extern struct state *cur_state; /* current state, for diagnostics */
-extern struct connection *cur_connection;       /* current connection, for diagnostics */
-extern const ip_address *cur_from;      /* source of current current message */
-extern u_int16_t cur_from_port; /* host order */
-
-#ifdef DEBUG
-
-  extern lset_t cur_debugging;  /* current debugging level */
-
-  extern void extra_debugging(const struct connection *c);
-
-# define reset_debugging() { cur_debugging = base_debugging; }
-
-# define GLOBALS_ARE_RESET() (whack_log_fd == NULL_FD \
-       && cur_state == NULL \
-       && cur_connection == NULL \
-       && cur_from == NULL \
-       && cur_debugging == base_debugging)
-
-#else /*!DEBUG*/
-
-# define extra_debugging(c)  { }
-
-# define reset_debugging() { }
-
-# define GLOBALS_ARE_RESET() (whack_log_fd == NULL_FD \
-       && cur_state == NULL \
-       && cur_connection == NULL \
-       && cur_from == NULL)
-
-#endif /*!DEBUG*/
-
-#define reset_globals() { \
-       whack_log_fd = NULL_FD; \
-       cur_state = NULL; \
-       cur_from = NULL; \
-       reset_cur_connection(); \
-       }
-
-
-#define set_cur_connection(c) { \
-       cur_connection = (c); \
-       extra_debugging(c); \
-       }
-
-#define reset_cur_connection() { \
-       cur_connection = NULL; \
-       reset_debugging(); \
-       }
-
-
-#define set_cur_state(s) { \
-       cur_state = (s); \
-       extra_debugging((s)->st_connection); \
-       }
-
-#define reset_cur_state() { \
-       cur_state = NULL; \
-       reset_debugging(); \
-       }
-
-extern void init_log(const char *program);
-extern void close_log(void);
-extern void plog(const char *message, ...) PRINTF_LIKE(1);
-extern void exit_log(const char *message, ...) PRINTF_LIKE(1) NEVER_RETURNS;
-
-/* close of all per-peer logging */
-extern void close_peerlog(void);
-
-/* free all per-peer log resources */
-extern void perpeer_logfree(struct connection *c);
-
-
-
-/* the following routines do a dance to capture errno before it is changed
- * A call must doubly parenthesize the argument list (no varargs macros).
- * The first argument must be "e", the local variable that captures errno.
- */
-#define log_errno(a) { int e = errno; log_errno_routine a; }
-extern void log_errno_routine(int e, const char *message, ...) PRINTF_LIKE(2);
-#define exit_log_errno(a) { int e = errno; exit_log_errno_routine a; }
-extern void exit_log_errno_routine(int e, const char *message, ...) PRINTF_LIKE(2) NEVER_RETURNS NEVER_RETURNS;
-
-extern void whack_log(int mess_no, const char *message, ...) PRINTF_LIKE(2);
-
-/* Log to both main log and whack log
- * Much like log, actually, except for specifying mess_no.
- */
-extern void loglog(int mess_no, const char *message, ...) PRINTF_LIKE(2);
-
-/* show status, usually on whack log */
-extern void show_status(bool all, const char *name);
-
-/* Build up a diagnostic in a static buffer.
- * Although this would be a generally useful function, it is very
- * hard to come up with a discipline that prevents different uses
- * from interfering.  It is intended that by limiting it to building
- * diagnostics, we will avoid this problem.
- * Juggling is performed to allow an argument to be a previous
- * result: the new string may safely depend on the old one.  This
- * restriction is not checked in any way: violators will produce
- * confusing results (without crashing!).
- */
-extern char diag_space[LOG_WIDTH];      /* output buffer, but can be occupied at call */
-extern err_t builddiag(const char *fmt, ...) PRINTF_LIKE(1);
-
-#ifdef DEBUG
-
-extern lset_t base_debugging;   /* bits selecting what to report */
-
-#define DBGP(cond)         (cur_debugging & (cond))
-#define DBG(cond, action)   { if (DBGP(cond)) { action ; } }
-
-extern void DBG_log(const char *message, ...) PRINTF_LIKE(1);
-extern void DBG_dump(const char *label, const void *p, size_t len);
-#define DBG_dump_chunk(label, ch) DBG_dump(label, (ch).ptr, (ch).len)
-
-#else /*!DEBUG*/
-
-#define DBG(cond, action)       { }     /* do nothing */
-
-#endif /*!DEBUG*/
-
-#define DBG_cond_dump(cond, label, p, len) DBG(cond, DBG_dump(label, p, len))
-#define DBG_cond_dump_chunk(cond, label, ch) DBG(cond, DBG_dump_chunk(label, ch))
-
-
-/* ip_str: a simple to use variant of addrtot.
- * It stores its result in a static buffer.
- * This means that newer calls overwrite the storage of older calls.
- * Note: this is not used in any of the logging functions, so their
- * callers may use it.
- */
-extern const char *ip_str(const ip_address *src);
-
-/*
- * call this routine to reset daily items.
- */
-extern void daily_log_reset(void);
-extern void daily_log_event(void);
-
-/*
- * some events are to be logged only occasionally.
- */
-extern bool logged_txt_warning;
-extern bool logged_myid_ip_txt_warning;
-extern bool logged_myid_ip_key_warning;
-extern bool logged_myid_fqdn_txt_warning;
-extern bool logged_myid_fqdn_key_warning;
diff --git a/src/pluto/modecfg.c b/src/pluto/modecfg.c
deleted file mode 100644 (file)
index 8298ea6..0000000
+++ /dev/null
@@ -1,1263 +0,0 @@
-/* Mode config related functions
- * Copyright (C) 2001-2002 Colubris Networks
- * Copyright (C) 2003 Sean Mathews - Nu Tech Software Solutions, inc.
- * Copyright (C) 2003-2004 Xelerance Corporation
- * Copyright (C) 2006-2010 Andreas Steffen - Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- *
- * This code originally written by Colubris Networks, Inc.
- * Extraction of patch and porting to 1.99 codebases by Xelerance Corporation
- * Porting to 2.x by Sean Mathews
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <freeswan.h>
-
-#include <library.h>
-#include <hydra.h>
-#include <utils/linked_list.h>
-#include <crypto/prfs/prf.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "state.h"
-#include "demux.h"
-#include "timer.h"
-#include "ipsec_doi.h"
-#include "log.h"
-#include "crypto.h"
-#include "modecfg.h"
-#include "whack.h"
-#include "pluto.h"
-
-#define MAX_XAUTH_TRIES         3
-
-#define DEFAULT_UNITY_BANNER   "Welcome to strongSwan - the Linux VPN Solution!\n"
-
-/**
- * Creates a modecfg_attribute_t object
- */
-static modecfg_attribute_t *modecfg_attribute_create(configuration_attribute_type_t type,
-                                                                                                        chunk_t value)
-{
-       modecfg_attribute_t *this;
-
-       this = malloc_thing(modecfg_attribute_t);
-       this->type = ((u_int16_t)type) & 0x7FFF;
-       this->is_tv = FALSE;
-       this->value = chunk_clone(value);
-       this->handler = NULL;
-
-       return this;
-}
-
-/**
- * Creates a modecfg_attribute_t object coded in TV format
- */
-static modecfg_attribute_t *modecfg_attribute_create_tv(configuration_attribute_type_t type,
-                                                                                                                        size_t value)
-{
-       modecfg_attribute_t *this;
-
-       this = modecfg_attribute_create(type, chunk_empty);
-       this->value.len = value;
-       this->is_tv = TRUE;
-
-       return this;
-}
-
-/**
- * Destroys a modecfg_attribute_t object
- */
-void modecfg_attribute_destroy(modecfg_attribute_t *this)
-{
-       free(this->value.ptr);
-       free(this);
-}
-
-/**
- * Get attributes to be sent to client
- */
-static void get_attributes(connection_t *c, linked_list_t *ca_list)
-{
-       configuration_attribute_type_t type;
-       identification_t *client_id;
-       modecfg_attribute_t *ca;
-       enumerator_t *enumerator;
-       chunk_t value;
-       host_t *vip = NULL, *requested_vip = NULL;
-       bool want_unity_banner = FALSE;
-       int family;
-
-#ifdef CISCO_QUIRKS
-       /* always send banner in ModeCfg push mode */
-       if (ca_list->get_count(ca_list) == 0)
-       {
-               want_unity_banner = TRUE;
-       }
-#endif
-
-       /* scan list of requested attributes in ModeCfg pull mode */
-       while (ca_list->remove_last(ca_list, (void **)&ca) == SUCCESS)
-       {
-               switch (ca->type)
-               {
-                       case INTERNAL_IP4_ADDRESS:
-                       case INTERNAL_IP6_ADDRESS:
-                       {
-                               int family;
-
-                               family = (ca->type == INTERNAL_IP4_ADDRESS) ? AF_INET : AF_INET6;
-                               DESTROY_IF(requested_vip);
-                               requested_vip = (ca->value.len) ?
-                                                               host_create_from_chunk(family, ca->value, 0) :
-                                                               host_create_any(family);
-                               plog("peer requested virtual IP %H", requested_vip);
-                               break;
-                       }
-#ifdef CISCO_QUIRKS
-                       case UNITY_BANNER:
-                               want_unity_banner = TRUE;
-                               break;
-#endif
-                       default:
-                               break;
-               }
-               modecfg_attribute_destroy(ca);
-       }
-
-       if (requested_vip == NULL)
-       {
-               requested_vip = host_create_any(AF_INET);
-       }
-
-       client_id = (c->xauth_identity) ? c->xauth_identity : c->spd.that.id;
-
-       /* if no virtual IP has been assigned yet - acquire one */
-       if (c->spd.that.host_srcip->is_anyaddr(c->spd.that.host_srcip))
-       {
-               if (c->spd.that.pool)
-               {
-                       vip = hydra->attributes->acquire_address(hydra->attributes,
-                                                               c->spd.that.pool, client_id, requested_vip);
-                       if (vip)
-                       {
-                               c->spd.that.host_srcip->destroy(c->spd.that.host_srcip);
-                               c->spd.that.host_srcip = vip;
-                       }
-               }
-               else
-               {
-                       plog("no virtual IP found");
-               }
-       }
-
-       requested_vip->destroy(requested_vip);
-
-       /* if we have a virtual IP address - send it */
-       if (!c->spd.that.host_srcip->is_anyaddr(c->spd.that.host_srcip))
-       {
-               vip = c->spd.that.host_srcip;
-               plog("assigning virtual IP %H to peer", vip);
-               family = vip->get_family(vip);
-               ca = modecfg_attribute_create((family == AF_INET) ?
-                                                                          INTERNAL_IP4_ADDRESS :
-                                                                          INTERNAL_IP6_ADDRESS,
-                                                                          vip->get_address(vip));
-               ca_list->insert_last(ca_list, ca);
-
-               /* set the remote client subnet to virtual IP */
-               c->spd.that.client.addr     = *(ip_address*)vip->get_sockaddr(vip);
-               c->spd.that.client.maskbits = (family == AF_INET) ? 32 : 128;
-               c->spd.that.has_client      = TRUE;
-       }
-
-       /* assign attributes from registered providers */
-       enumerator = hydra->attributes->create_responder_enumerator(hydra->attributes,
-                                                                                       c->spd.that.pool, client_id, vip);
-       while (enumerator->enumerate(enumerator, &type, &value))
-       {
-               ca = modecfg_attribute_create(type, value);
-               ca_list->insert_last(ca_list, ca);
-               if (type == UNITY_BANNER)
-               {
-                       want_unity_banner = FALSE;
-               }
-       }
-       enumerator->destroy(enumerator);
-
-       if (want_unity_banner)
-       {
-               ca = modecfg_attribute_create(UNITY_BANNER,
-                                                                         chunk_create(DEFAULT_UNITY_BANNER,
-                                                                         strlen(DEFAULT_UNITY_BANNER)));
-               ca_list->insert_last(ca_list, ca);
-       }
-}
-
-/**
- * Set srcip and client subnet to internal IP address
- */
-static bool set_attributes(connection_t *c, linked_list_t *ca_list)
-{
-       host_t *vip, *srcip;
-       modecfg_attribute_t *ca, *ca_handler;
-       enumerator_t *enumerator;
-       bool vip_set = FALSE;
-
-       enumerator = ca_list->create_enumerator(ca_list);
-       while (enumerator->enumerate(enumerator, &ca))
-       {
-               int family = AF_INET6;
-               attribute_handler_t *handler = NULL;
-               enumerator_t *e;
-
-               switch (ca->type)
-               {
-                       case INTERNAL_IP4_ADDRESS:
-                               family = AF_INET;
-                               /* fall */
-                       case INTERNAL_IP6_ADDRESS:
-                               if (ca->value.len == 0)
-                               {
-                                       vip = host_create_any(family);
-                               }
-                               else
-                               {
-                                       /* skip prefix byte in IPv6 payload*/
-                                       if (family == AF_INET6)
-                                       {
-                                               ca->value.len = 16;
-                                       }
-                                       vip = host_create_from_chunk(family, ca->value, 0);
-                               }
-                               if (vip)
-                               {
-                                       srcip = c->spd.this.host_srcip;
-
-                                       if (srcip->is_anyaddr(srcip) || srcip->equals(srcip, vip))
-                                       {
-                                               plog("setting virtual IP source address to %H", vip);
-                                       }
-                                       else
-                                       {
-                                               plog("replacing virtual IP source address %H by %H",
-                                                         srcip, vip);
-                                       }
-                                       srcip->destroy(srcip);
-                                       c->spd.this.host_srcip = vip;
-
-                                       /* setting client subnet to vip/32 */
-                                       addrtosubnet((ip_address*)vip->get_sockaddr(vip),
-                                                                &c->spd.this.client);
-                                       setportof(0, &c->spd.this.client.addr);
-                                       c->spd.this.has_client = TRUE;
-
-                                       vip_set = TRUE;
-                               }
-                               continue;
-                       case APPLICATION_VERSION:
-#ifdef CISCO_QUIRKS
-                       case UNITY_BANNER:
-#endif
-                               if (ca->value.len > 0)
-                               {
-                                       DBG(DBG_PARSING | DBG_CONTROLMORE,
-                                               DBG_log("   '%.*s'", ca->value.len, ca->value.ptr)
-                                       )
-                               }
-                               break;
-                       default:
-                               break;
-               }
-
-               /* find the first handler which requested this attribute */
-               e = c->requested->create_enumerator(c->requested);
-               while (e->enumerate(e, &ca_handler))
-               {
-                       if (ca_handler->type == ca->type)
-                       {
-                               handler = ca_handler->handler;
-                               break;
-                       }
-               }
-               e->destroy(e);
-
-               /* and pass it to the handle function */
-               handler = hydra->attributes->handle(hydra->attributes,
-                                                        c->spd.that.id, handler, ca->type, ca->value);
-               if (handler)
-               {
-                       ca_handler = modecfg_attribute_create(ca->type, ca->value);
-                       ca_handler->handler = handler;
-
-                       if (c->attributes == NULL)
-                       {
-                               c->attributes = linked_list_create();
-                       }
-                       c->attributes->insert_last(c->attributes, ca_handler);
-               }
-       }
-       enumerator->destroy(enumerator);
-       c->requested->destroy_function(c->requested, (void*)modecfg_attribute_destroy);
-       c->requested = NULL;
-       return vip_set;
-}
-
-/**
- * Register configuration attribute handlers
- */
-static void register_attribute_handlers(connection_t *c)
-{
-       configuration_attribute_type_t type;
-       modecfg_attribute_t *ca;
-       chunk_t value;
-       attribute_handler_t *handler;
-       enumerator_t *enumerator;
-
-       /* add configuration attributes requested by handlers */
-       if (c->requested == NULL)
-       {
-               c->requested = linked_list_create();
-       }
-       enumerator = hydra->attributes->create_initiator_enumerator(
-                                                       hydra->attributes,c->spd.that.id, c->spd.this.host_srcip);
-       while (enumerator->enumerate(enumerator, &handler, &type, &value))
-       {
-               ca = modecfg_attribute_create(type, value);
-               ca->handler = handler;
-               c->requested->insert_last(c->requested, ca);
-       }
-       enumerator->destroy(enumerator);
-}
-
-/**
- * Compute HASH of Mode Config.
- */
-static size_t modecfg_hash(u_char *dest, u_char *start, u_char *roof,
-                                                  const struct state *st)
-{
-       chunk_t msgid_chunk = chunk_from_thing(st->st_msgid);
-       chunk_t msg_chunk = { start, roof - start };
-       size_t prf_block_size;
-       pseudo_random_function_t prf_alg;
-       prf_t *prf;
-
-       prf_alg = oakley_to_prf(st->st_oakley.hash);
-       prf = lib->crypto->create_prf(lib->crypto, prf_alg);
-       prf->set_key(prf, st->st_skeyid_a);
-       prf->get_bytes(prf, msgid_chunk, NULL);
-       prf->get_bytes(prf, msg_chunk, dest);
-       prf_block_size = prf->get_block_size(prf);
-       prf->destroy(prf);
-
-       DBG(DBG_CRYPT,
-               DBG_log("ModeCfg HASH computed:");
-               DBG_dump("", dest, prf_block_size)
-       )
-       return prf_block_size;
-}
-
-
-/**
- * Generate an IKE message containing ModeCfg information (eg: IP, DNS, WINS)
- */
-static stf_status modecfg_build_msg(struct state *st, pb_stream *rbody,
-                                                                       u_int16_t msg_type,     linked_list_t *ca_list,
-                                                                       u_int16_t ap_id)
-{
-       u_char *r_hash_start, *r_hashval;
-       struct isakmp_mode_attr attrh;
-       struct isakmp_attribute attr;
-       pb_stream strattr,attrval;
-       enumerator_t *enumerator;
-       modecfg_attribute_t *ca;
-
-       START_HASH_PAYLOAD(*rbody, ISAKMP_NEXT_ATTR);
-
-       attrh.isama_np         = ISAKMP_NEXT_NONE;
-       attrh.isama_type       = msg_type;
-       attrh.isama_identifier = ap_id;
-
-       if (!out_struct(&attrh, &isakmp_attr_desc, rbody, &strattr))
-       {
-               return STF_INTERNAL_ERROR;
-       }
-
-       enumerator = ca_list->create_enumerator(ca_list);
-       while (enumerator->enumerate(enumerator, &ca))
-       {
-               DBG(DBG_CONTROLMORE,
-                       DBG_log("building %N attribute", configuration_attribute_type_names, ca->type)
-               )
-               if (ca->is_tv)
-               {
-                       attr.isaat_af_type = ca->type | ISAKMP_ATTR_AF_TV;
-                       attr.isaat_lv = ca->value.len;
-                       out_struct(&attr, &isakmp_modecfg_attribute_desc, &strattr, &attrval);
-               }
-               else
-               {
-                       char buf[BUF_LEN];
-
-                       attr.isaat_af_type = ca->type | ISAKMP_ATTR_AF_TLV;
-                       out_struct(&attr, &isakmp_modecfg_attribute_desc, &strattr, &attrval);
-                       snprintf(buf, BUF_LEN, "%N", configuration_attribute_type_names, ca->type);
-                       out_raw(ca->value.ptr, ca->value.len, &attrval, buf);
-               }
-               close_output_pbs(&attrval);
-       }
-       enumerator->destroy(enumerator);
-       close_output_pbs(&strattr);
-
-       modecfg_hash(r_hashval, r_hash_start, rbody->cur, st);
-       close_message(rbody);
-       encrypt_message(rbody, st);
-       return STF_OK;
-}
-
-/**
- * Send ModeCfg message
- */
-static stf_status modecfg_send_msg(struct state *st, int isama_type,
-                                                                  linked_list_t *ca_list)
-{
-       pb_stream msg;
-       pb_stream rbody;
-       char buf[BUF_LEN];
-
-       /* set up attr */
-       init_pbs(&msg, buf, sizeof(buf), "ModeCfg msg buffer");
-
-       /* this is the beginning of a new exchange */
-       st->st_msgid = generate_msgid(st);
-       init_phase2_iv(st, &st->st_msgid);
-
-       /* HDR out */
-       {
-               struct isakmp_hdr hdr;
-
-               zero(&hdr);     /* default to 0 */
-               hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION;
-               hdr.isa_np = ISAKMP_NEXT_HASH;
-               hdr.isa_xchg = ISAKMP_XCHG_MODE_CFG;
-               hdr.isa_flags = ISAKMP_FLAG_ENCRYPTION;
-               memcpy(hdr.isa_icookie, st->st_icookie, COOKIE_SIZE);
-               memcpy(hdr.isa_rcookie, st->st_rcookie, COOKIE_SIZE);
-               hdr.isa_msgid = st->st_msgid;
-
-               if (!out_struct(&hdr, &isakmp_hdr_desc, &msg, &rbody))
-               {
-                       return STF_INTERNAL_ERROR;
-               }
-       }
-
-       /* ATTR out with isama_id of 0 */
-       modecfg_build_msg(st, &rbody, isama_type, ca_list, 0);
-
-       free(st->st_tpacket.ptr);
-       st->st_tpacket = chunk_create(msg.start, pbs_offset(&msg));
-       st->st_tpacket = chunk_clone(st->st_tpacket);
-
-       /* Transmit */
-       send_packet(st, "ModeCfg msg");
-
-       if (st->st_event->ev_type != EVENT_RETRANSMIT)
-       {
-               delete_event(st);
-               event_schedule(EVENT_RETRANSMIT, EVENT_RETRANSMIT_DELAY_0, st);
-       }
-       return STF_OK;
-}
-
-/**
- * Parse a ModeCfg attribute payload
- */
-static stf_status modecfg_parse_attributes(pb_stream *attrs, linked_list_t *ca_list)
-{
-       struct isakmp_attribute attr;
-       pb_stream strattr;
-       u_int16_t attr_type;
-       u_int16_t attr_len;
-       chunk_t attr_chunk;
-       modecfg_attribute_t *ca;
-
-       while (pbs_left(attrs) >= sizeof(struct isakmp_attribute))
-       {
-               if (!in_struct(&attr, &isakmp_modecfg_attribute_desc, attrs, &strattr))
-               {
-                       return STF_FAIL;
-               }
-               attr_type = attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK;
-               attr_len  = attr.isaat_lv;
-               DBG(DBG_CONTROLMORE,
-                       DBG_log("processing %N attribute",
-                                       configuration_attribute_type_names, attr_type)
-               )
-
-               switch (attr_type)
-               {
-                       case INTERNAL_IP4_ADDRESS:
-                       case INTERNAL_IP4_NETMASK:
-                       case INTERNAL_IP4_DNS:
-                       case INTERNAL_IP4_NBNS:
-                       case INTERNAL_ADDRESS_EXPIRY:
-                       case INTERNAL_IP4_DHCP:
-                               if (attr_len != 4 && attr_len != 0)
-                               {
-                                       goto error;
-                               }
-                               break;
-                       case INTERNAL_IP4_SUBNET:
-                               if (attr_len != 8 && attr_len != 0)
-                               {
-                                       goto error;
-                               }
-                               break;
-                       case INTERNAL_IP6_NETMASK:
-                       case INTERNAL_IP6_DNS:
-                       case INTERNAL_IP6_NBNS:
-                       case INTERNAL_IP6_DHCP:
-                               if (attr_len != 16 && attr_len != 0)
-                               {
-                                       goto error;
-                               }
-                               break;
-                       case INTERNAL_IP6_ADDRESS:
-                               if (attr_len != 17 && attr_len != 16 && attr_len != 0)
-                               {
-                                       goto error;
-                               }
-                               break;
-                       case INTERNAL_IP6_SUBNET:
-                               if (attr_len != 17 && attr_len != 0)
-                               {
-                                       goto error;
-                               }
-                               break;
-                       case SUPPORTED_ATTRIBUTES:
-                               if (attr_len % 2)
-                               {
-                                       goto error;
-                               }
-                               break;
-                       case APPLICATION_VERSION:
-                               break;
-                       /* XAUTH attributes */
-                       case XAUTH_TYPE:
-                       case XAUTH_STATUS:
-                       case XAUTH_USER_NAME:
-                       case XAUTH_USER_PASSWORD:
-                       case XAUTH_PASSCODE:
-                       case XAUTH_MESSAGE:
-                       case XAUTH_CHALLENGE:
-                       case XAUTH_DOMAIN:
-                       case XAUTH_NEXT_PIN:
-                       case XAUTH_ANSWER:
-                               break;
-                       /* Microsoft attributes */
-                       case INTERNAL_IP4_SERVER:
-                       case INTERNAL_IP6_SERVER:
-                               break;
-                       /* Cisco Unity attributes */
-                       case UNITY_BANNER:
-                       case UNITY_SAVE_PASSWD:
-                       case UNITY_DEF_DOMAIN:
-                       case UNITY_SPLITDNS_NAME:
-                       case UNITY_SPLIT_INCLUDE:
-                       case UNITY_NATT_PORT:
-                       case UNITY_LOCAL_LAN:
-                       case UNITY_PFS:
-                       case UNITY_FW_TYPE:
-                       case UNITY_BACKUP_SERVERS:
-                       case UNITY_DDNS_HOSTNAME:
-                               break;
-                       default:
-                               plog("unknown attribute type (%u)", attr_type);
-                               continue;
-               }
-
-               /* add attribute */
-               if (attr.isaat_af_type & ISAKMP_ATTR_AF_TV)
-               {
-                       ca = modecfg_attribute_create_tv(attr_type, attr_len);
-               }
-               else
-               {
-                       attr_chunk = chunk_create(strattr.cur, attr_len);
-                       ca = modecfg_attribute_create(attr_type, attr_chunk);
-               }
-               ca_list->insert_last(ca_list, ca);
-       }
-       return STF_OK;
-
-error:
-       plog("%N attribute has invalid size of %u octets",
-                configuration_attribute_type_names, attr_type, attr_len);
-       return STF_FAIL;
-}
-
-/**
- * Parse a ModeCfg message
- */
-static stf_status modecfg_parse_msg(struct msg_digest *md, int isama_type,
-                                                                       u_int16_t *isama_id, linked_list_t *ca_list)
-{
-       modecfg_attribute_t *ca;
-       struct state *const st = md->st;
-       struct payload_digest *p;
-       stf_status stat;
-
-       st->st_msgid = md->hdr.isa_msgid;
-
-       CHECK_QUICK_HASH(md, modecfg_hash(hash_val, hash_pbs->roof,
-                                        md->message_pbs.roof, st), "MODECFG-HASH", "ISAKMP_CFG_MSG");
-
-       /* process the ModeCfg payloads received */
-       for (p = md->chain[ISAKMP_NEXT_ATTR]; p != NULL; p = p->next)
-       {
-               if (p->payload.attribute.isama_type == isama_type)
-               {
-                       *isama_id = p->payload.attribute.isama_identifier;
-
-                       stat = modecfg_parse_attributes(&p->pbs, ca_list);
-                       if (stat == STF_OK)
-                       {
-                               /* return with a valid set of attributes */
-                               return STF_OK;
-                       }
-               }
-               else
-               {
-                       plog("expected %s, got %s instead (ignored)"
-                               , enum_name(&attr_msg_type_names, isama_type)
-                               , enum_name(&attr_msg_type_names, p->payload.attribute.isama_type));
-
-                       stat = modecfg_parse_attributes(&p->pbs, ca_list);
-               }
-
-               /* abort if a parsing error occurred */
-               if (stat != STF_OK)
-               {
-                       ca_list->destroy_function(ca_list, (void*)modecfg_attribute_destroy);
-                       return stat;
-               }
-
-               /* discard the parsed attributes and look for another payload */
-               while (ca_list->remove_last(ca_list, (void **)&ca) == SUCCESS) {}
-       }
-       return STF_IGNORE;
-}
-
-/**
- * Used in ModeCfg pull mode on the client (initiator)
- *   called in demux.c
- *   client -> CFG_REQUEST
- *   STF_OK transitions to STATE_MODE_CFG_I1
- */
-stf_status modecfg_send_request(struct state *st)
-{
-       connection_t *c = st->st_connection;
-       stf_status stat;
-       modecfg_attribute_t *ca;
-       enumerator_t *enumerator;
-       int family;
-       chunk_t value;
-       host_t *vip;
-       linked_list_t *ca_list = linked_list_create();
-
-       vip = c->spd.this.host_srcip;
-       value = vip->is_anyaddr(vip) ? chunk_empty : vip->get_address(vip);
-       family = vip->get_family(vip);
-       ca = modecfg_attribute_create((family == AF_INET) ?
-                                                                  INTERNAL_IP4_ADDRESS : INTERNAL_IP6_ADDRESS,
-                                                                  value);
-       ca_list->insert_last(ca_list, ca);
-
-       register_attribute_handlers(c);
-       enumerator = c->requested->create_enumerator(c->requested);
-       while (enumerator->enumerate(enumerator, &ca))
-       {
-               ca = modecfg_attribute_create(ca->type, chunk_empty);
-               ca_list->insert_last(ca_list, ca);
-       }
-       enumerator->destroy(enumerator);
-
-       plog("sending ModeCfg request");
-
-       st->st_state = STATE_MODE_CFG_I1;
-       stat = modecfg_send_msg(st, ISAKMP_CFG_REQUEST, ca_list);
-       ca_list->destroy_function(ca_list, (void *)modecfg_attribute_destroy);
-       if (stat == STF_OK)
-       {
-               st->st_modecfg.started = TRUE;
-       }
-       return stat;
-}
-
-/**
- * Used in ModeCfg pull mode on the server (responder)
- *   called in demux.c from STATE_MODE_CFG_R0
- *   server <- CFG_REQUEST
- *   server -> CFG_REPLY
- *   STF_OK transitions to  STATE_MODE_CFG_R0
- */
-stf_status modecfg_inR0(struct msg_digest *md)
-{
-       struct state *const st = md->st;
-       u_int16_t isama_id;
-       stf_status stat, stat_build;
-       linked_list_t *ca_list = linked_list_create();
-
-       plog("parsing ModeCfg request");
-
-       stat = modecfg_parse_msg(md, ISAKMP_CFG_REQUEST, &isama_id, ca_list);
-       if (stat != STF_OK)
-       {
-               return stat;
-       }
-
-       /* build the CFG_REPLY */
-       get_attributes(st->st_connection, ca_list);
-
-       plog("sending ModeCfg reply");
-
-       stat_build = modecfg_build_msg(st, &md->rbody, ISAKMP_CFG_REPLY,
-                                                                  ca_list, isama_id);
-       ca_list->destroy_function(ca_list, (void *)modecfg_attribute_destroy);
-
-       if (stat_build != STF_OK)
-       {
-               return stat_build;
-       }
-       st->st_msgid = 0;
-       return STF_OK;
-}
-
-/**
- * Used in ModeCfg pull mode on the client (initiator)
- *   called in demux.c from STATE_MODE_CFG_I1
- *   client <- CFG_REPLY
- *   STF_OK transitions to  STATE_MODE_CFG_I2
- */
-stf_status modecfg_inI1(struct msg_digest *md)
-{
-       struct state *const st = md->st;
-       u_int16_t isama_id;
-       stf_status stat;
-       linked_list_t *ca_list = linked_list_create();
-
-       plog("parsing ModeCfg reply");
-
-       stat = modecfg_parse_msg(md, ISAKMP_CFG_REPLY, &isama_id, ca_list);
-       if (stat != STF_OK)
-       {
-               return stat;
-       }
-       st->st_modecfg.vars_set = set_attributes(st->st_connection, ca_list);
-       st->st_msgid = 0;
-       ca_list->destroy_function(ca_list, (void *)modecfg_attribute_destroy);
-       return STF_OK;
-}
-
-/**
- * Used in ModeCfg push mode on the server (responder)
- *   called in demux.c
- *   server -> CFG_SET
- *   STF_OK transitions to STATE_MODE_CFG_R3
- */
-stf_status modecfg_send_set(struct state *st)
-{
-       stf_status stat;
-       linked_list_t *ca_list = linked_list_create();
-
-
-       plog("sending ModeCfg set");
-
-       get_attributes(st->st_connection, ca_list);
-       st->st_state = STATE_MODE_CFG_R3;
-       stat = modecfg_send_msg(st, ISAKMP_CFG_SET, ca_list);
-       ca_list->destroy_function(ca_list, (void *)modecfg_attribute_destroy);
-       if (stat == STF_OK)
-       {
-               st->st_modecfg.started = TRUE;
-       }
-       return stat;
-}
-
-/**
- * Used in ModeCfg push mode on the client (initiator)
- *   called in demux.c from STATE_MODE_CFG_I0
- *   client <- CFG_SET
- *   client -> CFG_ACK
- *   STF_OK transitions to  STATE_MODE_CFG_I3
- */
-stf_status modecfg_inI0(struct msg_digest *md)
-{
-       struct state *const st = md->st;
-       u_int16_t isama_id;
-       stf_status stat, stat_build;
-       modecfg_attribute_t *ca;
-       linked_list_t *ca_list, *ca_ack_list;
-
-       plog("parsing ModeCfg set");
-
-       ca_list = linked_list_create();
-       stat = modecfg_parse_msg(md, ISAKMP_CFG_SET, &isama_id, ca_list);
-       if (stat != STF_OK)
-       {
-               return stat;
-       }
-       register_attribute_handlers(st->st_connection);
-       st->st_modecfg.vars_set = set_attributes(st->st_connection, ca_list);
-
-       /* prepare ModeCfg ack which sends zero length attributes */
-       ca_ack_list = linked_list_create();
-       while (ca_list->remove_last(ca_list, (void **)&ca) == SUCCESS)
-       {
-               switch (ca->type)
-               {
-                       case INTERNAL_IP4_ADDRESS:
-                       case INTERNAL_IP4_DNS:
-                       case INTERNAL_IP4_NBNS:
-                       case APPLICATION_VERSION:
-                       case INTERNAL_IP6_ADDRESS:
-                       case INTERNAL_IP6_DNS:
-                       case INTERNAL_IP6_NBNS:
-#ifdef CISCO_QUIRKS
-                       case UNITY_BANNER:
-#endif
-                               /* supported attributes */
-                               ca->value.len = 0;
-                               ca_ack_list->insert_last(ca_ack_list, ca);
-                               break;
-                       default:
-                               /* unsupportd attributes */
-                               modecfg_attribute_destroy(ca);
-               }
-       }
-       ca_list->destroy(ca_list);
-
-       plog("sending ModeCfg ack");
-
-       stat_build = modecfg_build_msg(st, &md->rbody, ISAKMP_CFG_ACK,
-                                                                  ca_ack_list, isama_id);
-       ca_ack_list->destroy_function(ca_ack_list, (void *)modecfg_attribute_destroy);
-       if (stat_build != STF_OK)
-       {
-               return stat_build;
-       }
-       st->st_msgid = 0;
-       return STF_OK;
-}
-
-/**
- * Used in ModeCfg push mode on the server (responder)
- *   called in demux.c from STATE_MODE_CFG_R3
- *   server <- CFG_ACK
- *   STF_OK transitions to  STATE_MODE_CFG_R4
- */
-stf_status modecfg_inR3(struct msg_digest *md)
-{
-       struct state *const st = md->st;
-       u_int16_t isama_id;
-       stf_status stat;
-       linked_list_t *ca_list = linked_list_create();
-
-       plog("parsing ModeCfg ack");
-
-       stat = modecfg_parse_msg(md, ISAKMP_CFG_ACK, &isama_id, ca_list);
-       ca_list->destroy_function(ca_list, (void *)modecfg_attribute_destroy);
-       if (stat != STF_OK)
-       {
-               return stat;
-       }
-       st->st_msgid = 0;
-       return STF_OK;
-}
-
-/**
- * Used on the XAUTH server (responder)
- *   called in demux.c
- *   server -> CFG_REQUEST
- *   STF_OK transitions to STATE_XAUTH_R1
- */
-stf_status xauth_send_request(struct state *st)
-{
-       stf_status stat;
-       modecfg_attribute_t *ca;
-       linked_list_t *ca_list = linked_list_create();
-
-       ca = modecfg_attribute_create(XAUTH_USER_NAME, chunk_empty);
-       ca_list->insert_last(ca_list, ca);
-       ca = modecfg_attribute_create(XAUTH_USER_PASSWORD, chunk_empty);
-       ca_list->insert_last(ca_list, ca);
-
-       plog("sending XAUTH request");
-       st->st_state = STATE_XAUTH_R1;
-       stat = modecfg_send_msg(st, ISAKMP_CFG_REQUEST, ca_list);
-       ca_list->destroy_function(ca_list, (void *)modecfg_attribute_destroy);
-       if (stat == STF_OK)
-       {
-               st->st_xauth.started = TRUE;
-       }
-       return stat;
-}
-
-/**
- * Used on the XAUTH client (initiator)
- *   called in demux.c from STATE_XAUTH_I0
- *   client <- CFG_REQUEST
- *   client -> CFG_REPLY
- *   STF_OK transitions to  STATE_XAUTH_I1
- */
-stf_status xauth_inI0(struct msg_digest *md)
-{
-       struct state *const st = md->st;
-       connection_t *c = st->st_connection;
-       u_int16_t isama_id;
-       stf_status stat, stat_build;
-       modecfg_attribute_t *ca;
-       bool xauth_user_name_present = FALSE;
-       bool xauth_user_password_present = FALSE;
-       bool xauth_type_present = FALSE;
-       chunk_t xauth_user_name, xauth_user_password;
-       identification_t *user_id;
-       linked_list_t *ca_list = linked_list_create();
-
-       plog("parsing XAUTH request");
-
-       stat = modecfg_parse_msg(md, ISAKMP_CFG_REQUEST, &isama_id, ca_list);
-       if (stat != STF_OK)
-       {
-               return stat;
-       }
-
-       while (ca_list->remove_last(ca_list, (void **)&ca) == SUCCESS)
-       {
-               switch (ca->type)
-               {
-                       case XAUTH_TYPE:
-                               if (ca->value.len != XAUTH_TYPE_GENERIC)
-                               {
-                                       plog("xauth type %s is not supported",
-                                                 enum_name(&xauth_type_names, ca->value.len));
-                                       stat = STF_FAIL;
-                               }
-                               else
-                               {
-                                       xauth_type_present = TRUE;
-                               }
-                               break;
-                       case XAUTH_USER_NAME:
-                               xauth_user_name_present = TRUE;
-                               break;
-                       case XAUTH_USER_PASSWORD:
-                               xauth_user_password_present = TRUE;
-                               break;
-                       case XAUTH_MESSAGE:
-                               if (ca->value.len)
-                               {
-                                       DBG(DBG_PARSING | DBG_CONTROLMORE,
-                                               DBG_log("   '%.*s'", ca->value.len, ca->value.ptr)
-                                       )
-                               }
-                               break;
-                       default:
-                               break;
-               }
-               modecfg_attribute_destroy(ca);
-       }
-
-       if (!xauth_user_name_present)
-       {
-               plog("user name attribute is missing in XAUTH request");
-               stat = STF_FAIL;
-       }
-       if (!xauth_user_password_present)
-       {
-               plog("user password attribute is missing in XAUTH request");
-               stat = STF_FAIL;
-       }
-
-       /* prepare XAUTH reply */
-       if (stat == STF_OK)
-       {
-               /* get user credentials using a plugin function */
-               if (!pluto->xauth->get_secret(pluto->xauth, c, &xauth_user_password))
-               {
-                       plog("xauth user credentials not found");
-                       stat = STF_FAIL;
-               }
-       }
-       if (stat == STF_OK)
-       {
-               /* insert xauth type if present */
-               if (xauth_type_present)
-               {
-                       ca = modecfg_attribute_create_tv(XAUTH_TYPE, XAUTH_TYPE_GENERIC);
-                       ca_list->insert_last(ca_list, ca);
-               }
-
-               /* insert xauth user name */
-               user_id = (c->xauth_identity) ? c->xauth_identity : c->spd.this.id;
-               xauth_user_name = user_id->get_encoding(user_id);
-               DBG(DBG_CONTROL,
-                       DBG_log("my xauth user name is '%.*s'", xauth_user_name.len,
-                                                                                                       xauth_user_name.ptr)
-               )
-               ca = modecfg_attribute_create(XAUTH_USER_NAME, xauth_user_name);
-               ca_list->insert_last(ca_list, ca);
-
-               /* insert xauth user password */
-               DBG(DBG_PRIVATE,
-                       DBG_log("my xauth user password is '%.*s'",     xauth_user_password.len,
-                                                                                                               xauth_user_password.ptr)
-               )
-               ca = modecfg_attribute_create(XAUTH_USER_PASSWORD, xauth_user_password);
-               ca_list->insert_last(ca_list, ca);
-               chunk_clear(&xauth_user_password);
-       }
-       else
-       {
-               ca = modecfg_attribute_create_tv(XAUTH_STATUS, XAUTH_STATUS_FAIL);
-               ca_list->insert_last(ca_list, ca);
-       }
-
-       plog("sending XAUTH reply");
-       stat_build = modecfg_build_msg(st, &md->rbody, ISAKMP_CFG_REPLY,
-                                                                  ca_list, isama_id);
-       ca_list->destroy_function(ca_list, (void *)modecfg_attribute_destroy);
-       if (stat_build != STF_OK)
-       {
-               return stat_build;
-       }
-       if (stat == STF_OK)
-       {
-               st->st_xauth.started = TRUE;
-               st->st_msgid = 0;
-               return STF_OK;
-       }
-       else
-       {
-               /* send XAUTH reply msg and then delete ISAKMP SA */
-               free(st->st_tpacket.ptr);
-               st->st_tpacket = chunk_create(md->reply.start, pbs_offset(&md->reply));
-               st->st_tpacket = chunk_clone(st->st_tpacket);
-               send_packet(st, "XAUTH reply msg");
-               delete_state(st);
-               return STF_IGNORE;
-       }
-}
-
-/**
- *  Used on the XAUTH server (responder)
- *    called in demux.c from STATE_XAUTH_R1
-      server <- CFG_REPLY
-      server -> CFG_SET
-      STF_OK transitions to  STATE_XAUTH_R2
- */
-stf_status xauth_inR1(struct msg_digest *md)
-{
-       struct state *const st = md->st;
-       connection_t *c = st->st_connection;
-       u_int16_t isama_id;
-       stf_status stat, stat_build;
-       chunk_t xauth_user_name, xauth_user_password;
-       int xauth_status = XAUTH_STATUS_OK;
-       modecfg_attribute_t *ca;
-       linked_list_t *ca_list = linked_list_create();
-
-       plog("parsing XAUTH reply");
-
-       stat = modecfg_parse_msg(md, ISAKMP_CFG_REPLY, &isama_id, ca_list);
-       if (stat != STF_OK)
-       {
-               return stat;
-       }
-
-       /* initialize xauth_secret */
-       xauth_user_name = chunk_empty;
-       xauth_user_password = chunk_empty;
-
-       while (ca_list->remove_last(ca_list, (void **)&ca) == SUCCESS)
-       {
-               switch (ca->type)
-               {
-                       case XAUTH_STATUS:
-                               xauth_status = ca->value.len;
-                               break;
-                       case XAUTH_USER_NAME:
-                               xauth_user_name = chunk_clone(ca->value);
-                               break;
-                       case XAUTH_USER_PASSWORD:
-                               xauth_user_password = chunk_clone(ca->value);
-                               break;
-                       default:
-                               break;
-               }
-               modecfg_attribute_destroy(ca);
-       }
-       /* did the client return an XAUTH FAIL status? */
-       if (xauth_status == XAUTH_STATUS_FAIL)
-       {
-               plog("received FAIL status in XAUTH reply");
-
-               /* client is not able to do XAUTH, delete ISAKMP SA */
-               free(xauth_user_name.ptr);
-               free(xauth_user_password.ptr);
-               delete_state(st);
-               ca_list->destroy(ca_list);
-               return STF_IGNORE;
-       }
-
-       /* check XAUTH reply */
-       if (xauth_user_name.ptr == NULL)
-       {
-               plog("user name attribute is missing in XAUTH reply");
-               st->st_xauth.status = FALSE;
-       }
-       else if (xauth_user_password.ptr == NULL)
-       {
-               plog("user password attribute is missing in XAUTH reply");
-               st->st_xauth.status = FALSE;
-       }
-       else
-       {
-               DBG(DBG_CONTROL,
-                       DBG_log("peer xauth user name is '%.*s'", xauth_user_name.len,
-                                                                                                         xauth_user_name.ptr)
-               )
-               DESTROY_IF(c->xauth_identity);
-               c->xauth_identity = identification_create_from_data(xauth_user_name);
-
-               DBG(DBG_PRIVATE,
-                       DBG_log("peer xauth user password is '%.*s'", xauth_user_password.len,
-                                                                                                                 xauth_user_password.ptr)
-               )
-               /* verify the user credentials using a plugin function */
-               st->st_xauth.status = pluto->xauth->verify_secret(pluto->xauth, c,
-                                                                                                                 xauth_user_password);
-               plog("extended authentication %s", st->st_xauth.status? "was successful":"failed");
-       }
-       chunk_clear(&xauth_user_name);
-       chunk_clear(&xauth_user_password);
-
-       plog("sending XAUTH status");
-       xauth_status = (st->st_xauth.status) ? XAUTH_STATUS_OK : XAUTH_STATUS_FAIL;
-       ca = modecfg_attribute_create_tv(XAUTH_STATUS, xauth_status);
-       ca_list->insert_last(ca_list, ca);
-       stat_build = modecfg_send_msg(st, ISAKMP_CFG_SET, ca_list);
-       ca_list->destroy_function(ca_list, (void *)modecfg_attribute_destroy);
-       if (stat_build != STF_OK)
-       {
-               return stat_build;
-       }
-       return STF_OK;
-}
-
-/**
- * Used on the XAUTH client (initiator)
- *   called in demux.c from STATE_XAUTH_I1
- *   client <- CFG_SET
- *   client -> CFG_ACK
- *   STF_OK transitions to  STATE_XAUTH_I2
- */
-stf_status xauth_inI1(struct msg_digest *md)
-{
-       struct state *const st = md->st;
-       u_int16_t isama_id;
-       stf_status stat, stat_build;
-       modecfg_attribute_t *ca;
-       linked_list_t *ca_list = linked_list_create();
-
-       plog("parsing XAUTH status");
-       stat = modecfg_parse_msg(md, ISAKMP_CFG_SET, &isama_id, ca_list);
-       if (stat != STF_OK)
-       {
-               /* notification payload - not exactly the right choice, but okay */
-               md->note = ISAKMP_ATTRIBUTES_NOT_SUPPORTED;
-               return stat;
-       }
-
-       st->st_xauth.status = FALSE;
-       while (ca_list->remove_last(ca_list, (void **)&ca) == SUCCESS)
-       {
-               if (ca->type == XAUTH_STATUS)
-               {
-                       st->st_xauth.status = (ca->value.len == XAUTH_STATUS_OK);
-               }
-               modecfg_attribute_destroy(ca);
-       }
-       plog("extended authentication %s", st->st_xauth.status? "was successful":"failed");
-
-       plog("sending XAUTH ack");
-       stat_build = modecfg_build_msg(st, &md->rbody, ISAKMP_CFG_ACK, ca_list, isama_id);
-       ca_list->destroy(ca_list);
-
-       if (stat_build != STF_OK)
-       {
-               return stat_build;
-       }
-       if (st->st_xauth.status)
-       {
-               st->st_msgid = 0;
-               return STF_OK;
-       }
-       else
-       {
-               /* send XAUTH ack msg and then delete ISAKMP SA */
-               free(st->st_tpacket.ptr);
-               st->st_tpacket = chunk_create(md->reply.start, pbs_offset(&md->reply));
-               st->st_tpacket = chunk_clone(st->st_tpacket);
-               send_packet(st, "XAUTH ack msg");
-               delete_state(st);
-               return STF_IGNORE;
-       }
-}
-
-/**
- * Used on the XAUTH server (responder)
- *   called in demux.c from STATE_XAUTH_R2
- *   server <- CFG_ACK
- *   STF_OK transitions to  STATE_XAUTH_R3
- */
-stf_status xauth_inR2(struct msg_digest *md)
-{
-       struct state *const st = md->st;
-       u_int16_t isama_id;
-       stf_status stat;
-       linked_list_t *ca_list = linked_list_create();
-
-       plog("parsing XAUTH ack");
-
-       stat = modecfg_parse_msg(md, ISAKMP_CFG_ACK, &isama_id, ca_list);
-       if (stat != STF_OK)
-       {
-               return stat;
-       }
-       ca_list->destroy_function(ca_list, (void *)modecfg_attribute_destroy);
-       st->st_msgid = 0;
-       if (st->st_xauth.status)
-       {
-               return STF_OK;
-       }
-       else
-       {
-               delete_state(st);
-               return STF_IGNORE;
-       }
-
-}
diff --git a/src/pluto/modecfg.h b/src/pluto/modecfg.h
deleted file mode 100644 (file)
index 7adf186..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/* Mode Config related functions
- * Copyright (C) 2001-2002 Colubris Networks
- * Copyright (C) 2003-2004 Xelerance Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef _MODECFG_H
-#define _MODECFG_H
-
-#include <chunk.h>
-#include <attributes/attribute_handler.h>
-
-#include "state.h"
-#include "demux.h"
-
-typedef struct modecfg_attribute_t modecfg_attribute_t;
-
-/**
- * Defines a modecfg_attribute_t object.
- */
-struct modecfg_attribute_t {
-       /**
-        * Type of the attribute.
-        */
-       u_int16_t type;
-
-       /**
-        * Attribute is coded as TV
-        */
-       bool is_tv;
-
-       /**
-        * Attribute value as chunk.
-        */
-       chunk_t value;
-
-       /**
-        * Attribute handler.
-        */
-       attribute_handler_t *handler;
-};
-
-/* Destroys a modecfg_attribute_t object */
-extern void modecfg_attribute_destroy(modecfg_attribute_t *this);
-
-/* ModeConfig pull mode start function */
-extern stf_status modecfg_send_request(struct state *st);
-
-/* ModeConfig pull mode state transition functions */
-extern stf_status modecfg_inR0(struct msg_digest *md);
-extern stf_status modecfg_inI1(struct msg_digest *md);
-
-/* ModeConfig push mode start function */
-extern stf_status modecfg_send_set(struct state *st);
-
-/* ModeConfig push mode state transition functions */
-extern stf_status modecfg_inI0(struct msg_digest *md);
-extern stf_status modecfg_inR3(struct msg_digest *md);
-
-/* XAUTH start function */
-extern stf_status xauth_send_request(struct state *st);
-
-/* XAUTH state transition funcgtions */
-extern stf_status xauth_inI0(struct msg_digest *md);
-extern stf_status xauth_inR1(struct msg_digest *md);
-extern stf_status xauth_inI1(struct msg_digest *md);
-extern stf_status xauth_inR2(struct msg_digest *md);
-
-#endif /* _MODECFG_H */
diff --git a/src/pluto/myid.c b/src/pluto/myid.c
deleted file mode 100644 (file)
index c90d14e..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/* identity representation, as in IKE ID Payloads (RFC 2407 DOI 4.6.2.1)
- * Copyright (C) 1999-2001  D. Hugh Redelmeier
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <errno.h>
-#include <unistd.h>
-
-#ifndef HOST_NAME_MAX        /* POSIX 1003.1-2001 says <unistd.h> defines this */
-# define HOST_NAME_MAX  255 /* upper bound, according to SUSv2 */
-#endif
-
-#include <utils/identification.h>
-
-#include <freeswan.h>
-
-#include "myid.h"
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "connections.h"
-#include "packet.h"
-#include "whack.h"
-
-enum myid_state myid_state = MYID_UNKNOWN;
-
-identification_t *myids[MYID_SPECIFIED+1];    /* %myid */
-
-/**
- * Fills in myid from environment variable IPSECmyid or defaultrouteaddr
- */
-void init_myid(void)
-{
-       myid_state = MYID_UNKNOWN;
-       {
-               enum myid_state s;
-
-               for (s = MYID_UNKNOWN; s <= MYID_SPECIFIED; s++)
-               {
-                       myids[s] = identification_create_from_string("%any");
-               }
-       }
-       set_myid(MYID_SPECIFIED, getenv("IPSECmyid"));
-       set_myid(MYID_IP, getenv("defaultrouteaddr"));
-       set_myFQDN();
-}
-
-/**
- *  Free myid module
- */
-void free_myid(void)
-{
-       enum myid_state s;
-
-       for (s = MYID_UNKNOWN; s <= MYID_SPECIFIED; s++)
-       {
-               DESTROY_IF(myids[s]);
-       }
-}
-
-void set_myid(enum myid_state s, char *idstr)
-{
-       if (idstr)
-       {
-               myids[s]->destroy(myids[s]);
-               myids[s] = identification_create_from_string(idstr);
-               if (s == MYID_SPECIFIED)
-               {
-                               myid_state = MYID_SPECIFIED;
-               }
-       }
-}
-
-void set_myFQDN(void)
-{
-       char FQDN[HOST_NAME_MAX + 1];
-       int r = gethostname(FQDN, sizeof(FQDN));
-       size_t len;
-
-       if (r != 0)
-       {
-               log_errno((e, "gethostname() failed in set_myFQDN"));
-       }
-       else
-       {
-               FQDN[sizeof(FQDN) - 1] = '\0';  /* insurance */
-               len = strlen(FQDN);
-
-               if (len > 0 && FQDN[len-1] == '.')
-               {
-                       /* nuke trailing . */
-                       FQDN[len-1] = '\0';
-               }
-               if (!strcaseeq(FQDN, "localhost.localdomain"))
-               {
-                       myids[MYID_HOSTNAME]->destroy(myids[MYID_HOSTNAME]);
-                       myids[MYID_HOSTNAME] = identification_create_from_string(FQDN);
-               }
-       }
-}
-
-void show_myid_status(void)
-{
-       whack_log(RC_COMMENT, "%%myid = '%Y'", myids[myid_state]);
-}
-
-/*
- * Local Variables:
- * c-basic-offset:4
- * c-style: pluto
- * End:
- */
diff --git a/src/pluto/myid.h b/src/pluto/myid.h
deleted file mode 100644 (file)
index 012a349..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/* identity representation, as in IKE ID Payloads (RFC 2407 DOI 4.6.2.1)
- * Copyright (C) 1999-2001  D. Hugh Redelmeier
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef _MYID_H
-#define _MYID_H
-
-#include <utils/identification.h>
-
-extern void init_myid(void);
-extern void free_myid(void);
-
-enum myid_state {
-       MYID_UNKNOWN,       /* not yet figured out */
-       MYID_HOSTNAME,      /* our current hostname */
-       MYID_IP,            /* our default IP address */
-       MYID_SPECIFIED      /* as specified by ipsec.conf */
-};
-
-extern enum myid_state myid_state;
-extern identification_t* myids[MYID_SPECIFIED+1];  /* %myid */
-extern void set_myid(enum myid_state s, char *);
-extern void show_myid_status(void);
-extern void set_myFQDN(void);
-
-#define resolve_myid(id) ((id)->get_type(id) == ID_MYID? myids[myid_state] : (id))
-
-#endif /* _MYID_H */
diff --git a/src/pluto/nat_traversal.c b/src/pluto/nat_traversal.c
deleted file mode 100644 (file)
index 28be768..0000000
+++ /dev/null
@@ -1,845 +0,0 @@
-/*
- * Copyright (C) 2010 Tobias Brunner
- * Copyright (C) 2009 Andreas Steffen
- * Hochschule fuer Technik Rapperswil
- * Copyright (C) 2002-2005 Mathieu Lafon
- * Arkoon Network Security
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <stdarg.h>
-#include <syslog.h>
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-#include <signal.h>     /* used only if MSG_NOSIGNAL not defined */
-#include <sys/queue.h>
-
-#include <library.h>
-#include <crypto/hashers/hasher.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "server.h"
-#include "state.h"
-#include "connections.h"
-#include "packet.h"
-#include "demux.h"
-#include "kernel.h"
-#include "whack.h"
-#include "timer.h"
-#include "cookie.h"
-#include "crypto.h"
-#include "vendor.h"
-#include "ike_alg.h"
-#include "nat_traversal.h"
-
-/* #define FORCE_NAT_TRAVERSAL */
-#define NAT_D_DEBUG
-#define NAT_T_SUPPORT_LAST_DRAFTS
-
-#ifndef SOL_UDP
-#define SOL_UDP 17
-#endif
-
-#ifndef UDP_ESPINUDP
-#define UDP_ESPINUDP    100
-#endif
-
-#define DEFAULT_KEEP_ALIVE_PERIOD  20
-
-#ifdef _IKE_ALG_H
-/* Alg patch: hash_digest_len -> hash_digest_size */
-#define hash_digest_len hash_digest_size
-#endif
-
-bool nat_traversal_enabled = FALSE;
-bool nat_traversal_support_non_ike = FALSE;
-bool nat_traversal_support_port_floating = FALSE;
-
-static unsigned int _kap = 0;
-static unsigned int _ka_evt = 0;
-static bool _force_ka = 0;
-
-static const char *natt_version = "0.6c";
-
-void init_nat_traversal (bool activate, unsigned int keep_alive_period,
-               bool fka, bool spf)
-{
-       nat_traversal_enabled = activate;
-       nat_traversal_support_non_ike = activate;
-#ifdef NAT_T_SUPPORT_LAST_DRAFTS
-       nat_traversal_support_port_floating = activate ? spf : FALSE;
-#endif
-       _force_ka = fka;
-       _kap = keep_alive_period ? keep_alive_period : DEFAULT_KEEP_ALIVE_PERIOD;
-       plog("  including NAT-Traversal patch (Version %s)%s%s%s"
-                , natt_version, activate ? "" : " [disabled]"
-                , activate & fka ? " [Force KeepAlive]" : ""
-                , activate & !spf ? " [Port Floating disabled]" : "");
-}
-
-static void disable_nat_traversal (int type)
-{
-       if (type == ESPINUDP_WITH_NON_IKE)
-               nat_traversal_support_non_ike = FALSE;
-       else
-               nat_traversal_support_port_floating = FALSE;
-
-       if (!nat_traversal_support_non_ike &&
-               !nat_traversal_support_port_floating)
-                       nat_traversal_enabled = FALSE;
-}
-
-static void _natd_hash(const struct hash_desc *oakley_hasher, char *hash,
-               u_int8_t *icookie, u_int8_t *rcookie,
-               const ip_address *ip, u_int16_t port)
-{
-       if (is_zero_cookie(icookie))
-       {
-               DBG_log("_natd_hash: Warning, icookie is zero !!");
-       }
-       if (is_zero_cookie(rcookie))
-       {
-               DBG_log("_natd_hash: Warning, rcookie is zero !!");
-       }
-
-       /**
-        * draft-ietf-ipsec-nat-t-ike-01.txt
-        *
-        *   HASH = HASH(CKY-I | CKY-R | IP | Port)
-        *
-        * All values in network order
-        */
-       {
-               chunk_t icookie_chunk = { icookie, COOKIE_SIZE };
-               chunk_t rcookie_chunk = { rcookie, COOKIE_SIZE };
-               chunk_t port_chunk = chunk_from_thing(port);
-               chunk_t addr_chunk;
-               hash_algorithm_t hash_alg;
-               hasher_t *hasher;
-               size_t hash_size;
-
-               hash_alg = oakley_to_hash_algorithm(oakley_hasher->algo_id);
-               hasher = lib->crypto->create_hasher(lib->crypto, hash_alg);
-               hasher->get_hash(hasher, icookie_chunk, NULL);
-               hasher->get_hash(hasher, rcookie_chunk, NULL);
-               switch (addrtypeof(ip))
-               {
-                       case AF_INET:
-                               addr_chunk = chunk_from_thing(ip->u.v4.sin_addr.s_addr);
-                               break;
-                       case AF_INET6:
-                               addr_chunk = chunk_from_thing(ip->u.v6.sin6_addr.s6_addr);
-                               break;
-                       default:
-                               addr_chunk = chunk_empty; /* should never occur */
-               }
-               hasher->get_hash(hasher, addr_chunk, NULL);
-               hasher->get_hash(hasher, port_chunk, hash);
-               hash_size = hasher->get_hash_size(hasher);
-               hasher->destroy(hasher);
-#ifdef NAT_D_DEBUG
-               DBG(DBG_NATT,
-                       DBG_dump_chunk("_natd_hash: icookie=", icookie_chunk);
-                       DBG_dump_chunk("_natd_hash: rcookie=", rcookie_chunk);
-                       DBG_dump_chunk("_natd_hash: ip=", addr_chunk);
-                       DBG_log("_natd_hash: port=%d", port);
-                       DBG_dump("_natd_hash: hash=", hash, hash_size);
-               )
-#endif
-       }
-}
-
-/* Add NAT-Traversal VIDs (supported ones)
- * used when we are Initiator
- */
-bool nat_traversal_add_vid(u_int8_t np, pb_stream *outs)
-{
-       bool r = TRUE;
-
-       if (nat_traversal_support_port_floating)
-       {
-               u_int8_t last_np = nat_traversal_support_non_ike ?
-                                                               ISAKMP_NEXT_VID : np;
-
-               if (r)
-                       r = out_vendorid(ISAKMP_NEXT_VID, outs, VID_NATT_RFC);
-               if (r)
-                       r = out_vendorid(ISAKMP_NEXT_VID, outs, VID_NATT_IETF_03);
-               if (r)
-                       r = out_vendorid(ISAKMP_NEXT_VID, outs, VID_NATT_IETF_02);
-               if (r)
-                       r = out_vendorid(last_np, outs, VID_NATT_IETF_02_N);
-       }
-       if (nat_traversal_support_non_ike)
-       {
-               if (r)
-                       r = out_vendorid(np, outs, VID_NATT_IETF_00);
-       }
-       return r;
-}
-
-u_int32_t nat_traversal_vid_to_method(unsigned short nat_t_vid)
-{
-       switch (nat_t_vid)
-       {
-       case VID_NATT_IETF_00:
-               return LELEM(NAT_TRAVERSAL_IETF_00_01);
-       case VID_NATT_IETF_02:
-       case VID_NATT_IETF_02_N:
-       case VID_NATT_IETF_03:
-               return LELEM(NAT_TRAVERSAL_IETF_02_03);
-       case VID_NATT_RFC:
-               return LELEM(NAT_TRAVERSAL_RFC);
-       }
-       return 0;
-}
-
-void nat_traversal_natd_lookup(struct msg_digest *md)
-{
-       char hash[MAX_DIGEST_LEN];
-       struct payload_digest *p;
-       struct state *st = md->st;
-       int i;
-
-       if (!st || !md->iface || !st->st_oakley.hasher)
-       {
-               loglog(RC_LOG_SERIOUS, "NAT-Traversal: assert failed %s:%d"
-                               , __FILE__, __LINE__);
-               return;
-       }
-
-       /** Count NAT-D **/
-       for (p = md->chain[ISAKMP_NEXT_NATD_RFC], i=0; p != NULL; p = p->next, i++);
-
-       /*
-        * We need at least 2 NAT-D (1 for us, many for peer)
-        */
-       if (i < 2)
-       {
-               loglog(RC_LOG_SERIOUS,
-                       "NAT-Traversal: Only %d NAT-D - Aborting NAT-Traversal negotiation", i);
-               st->nat_traversal = 0;
-               return;
-       }
-
-       /*
-        * First one with my IP & port
-        */
-       p = md->chain[ISAKMP_NEXT_NATD_RFC];
-       _natd_hash(st->st_oakley.hasher, hash, st->st_icookie, st->st_rcookie,
-               &(md->iface->addr), ntohs(st->st_connection->spd.this.host_port));
-
-       if (!(pbs_left(&p->pbs) == st->st_oakley.hasher->hash_digest_len &&
-                 memeq(p->pbs.cur, hash, st->st_oakley.hasher->hash_digest_len)))
-       {
-#ifdef NAT_D_DEBUG
-               DBG(DBG_NATT,
-                       DBG_log("NAT_TRAVERSAL_NAT_BHND_ME");
-                       DBG_dump("expected NAT-D:", hash
-                                               , st->st_oakley.hasher->hash_digest_len);
-                       DBG_dump("received NAT-D:", p->pbs.cur, pbs_left(&p->pbs));
-               )
-#endif
-               st->nat_traversal |= LELEM(NAT_TRAVERSAL_NAT_BHND_ME);
-       }
-
-       /*
-        * The others with sender IP & port
-        */
-       _natd_hash(st->st_oakley.hasher, hash, st->st_icookie, st->st_rcookie,
-                               &(md->sender), ntohs(md->sender_port));
-       for (p = p->next, i=0 ; p != NULL; p = p->next)
-       {
-               if (pbs_left(&p->pbs) == st->st_oakley.hasher->hash_digest_len &&
-                       memeq(p->pbs.cur, hash, st->st_oakley.hasher->hash_digest_len))
-               {
-                       i++;
-               }
-       }
-       if (!i)
-       {
-#ifdef NAT_D_DEBUG
-               DBG(DBG_NATT,
-                       DBG_log("NAT_TRAVERSAL_NAT_BHND_PEER");
-                       DBG_dump("expected NAT-D:", hash
-                                               , st->st_oakley.hasher->hash_digest_len);
-                       p = md->chain[ISAKMP_NEXT_NATD_RFC];
-                       for (p = p->next, i=0 ; p != NULL; p = p->next)
-                       {
-                               DBG_dump("received NAT-D:", p->pbs.cur, pbs_left(&p->pbs));
-                       }
-               )
-#endif
-               st->nat_traversal |= LELEM(NAT_TRAVERSAL_NAT_BHND_PEER);
-       }
-#ifdef FORCE_NAT_TRAVERSAL
-       st->nat_traversal |= LELEM(NAT_TRAVERSAL_NAT_BHND_PEER);
-       st->nat_traversal |= LELEM(NAT_TRAVERSAL_NAT_BHND_ME);
-#endif
-}
-
-bool nat_traversal_add_natd(u_int8_t np, pb_stream *outs,
-               struct msg_digest *md)
-{
-       char hash[MAX_DIGEST_LEN];
-       struct state *st = md->st;
-
-       if (!st || !st->st_oakley.hasher)
-       {
-               loglog(RC_LOG_SERIOUS, "NAT-Traversal: assert failed %s:%d"
-                                               , __FILE__, __LINE__);
-               return FALSE;
-       }
-
-       DBG(DBG_EMITTING,
-               DBG_log("sending NATD payloads")
-       )
-
-       /*
-        * First one with sender IP & port
-        */
-       _natd_hash(st->st_oakley.hasher, hash, st->st_icookie,
-               is_zero_cookie(st->st_rcookie) ? md->hdr.isa_rcookie : st->st_rcookie,
-               &(md->sender),
-#ifdef FORCE_NAT_TRAVERSAL
-               0
-#else
-               ntohs(md->sender_port)
-#endif
-       );
-       if (!out_generic_raw((st->nat_traversal & NAT_T_WITH_RFC_VALUES
-               ? ISAKMP_NEXT_NATD_RFC : ISAKMP_NEXT_NATD_DRAFTS), &isakmp_nat_d, outs,
-               hash, st->st_oakley.hasher->hash_digest_len, "NAT-D"))
-       {
-               return FALSE;
-       }
-
-       /*
-        * Second one with my IP & port
-        */
-       _natd_hash(st->st_oakley.hasher, hash, st->st_icookie,
-               is_zero_cookie(st->st_rcookie) ? md->hdr.isa_rcookie : st->st_rcookie,
-               &(md->iface->addr),
-#ifdef FORCE_NAT_TRAVERSAL
-               0
-#else
-               ntohs(st->st_connection->spd.this.host_port)
-#endif
-       );
-       return (out_generic_raw(np, &isakmp_nat_d, outs,
-               hash, st->st_oakley.hasher->hash_digest_len, "NAT-D"));
-}
-
-/*
- * nat_traversal_natoa_lookup()
- *
- * Look for NAT-OA in message
- */
-void nat_traversal_natoa_lookup(struct msg_digest *md)
-{
-       struct payload_digest *p;
-       struct state *st = md->st;
-       int i;
-       ip_address ip;
-
-       if (!st || !md->iface)
-       {
-               loglog(RC_LOG_SERIOUS, "NAT-Traversal: assert failed %s:%d"
-                               , __FILE__, __LINE__);
-               return;
-       }
-
-       /* Initialize NAT-OA */
-       anyaddr(AF_INET, &st->nat_oa);
-
-       /* Count NAT-OA **/
-       for (p = md->chain[ISAKMP_NEXT_NATOA_RFC], i=0; p != NULL; p = p->next, i++);
-
-       DBG(DBG_NATT,
-               DBG_log("NAT-Traversal: received %d NAT-OA.", i)
-       )
-
-       if (i == 0)
-               return;
-
-       if (!(st->nat_traversal & LELEM(NAT_TRAVERSAL_NAT_BHND_PEER)))
-       {
-               loglog(RC_LOG_SERIOUS, "NAT-Traversal: received %d NAT-OA. "
-                                               "ignored because peer is not NATed", i);
-               return;
-       }
-
-       if (i > 1)
-       {
-               loglog(RC_LOG_SERIOUS, "NAT-Traversal: received %d NAT-OA. "
-                               "using first, ignoring others", i);
-       }
-
-       /* Take first */
-       p = md->chain[ISAKMP_NEXT_NATOA_RFC];
-
-       DBG(DBG_PARSING,
-               DBG_dump("NAT-OA:", p->pbs.start, pbs_room(&p->pbs));
-       );
-
-       switch (p->payload.nat_oa.isanoa_idtype)
-       {
-       case ID_IPV4_ADDR:
-               if (pbs_left(&p->pbs) == sizeof(struct in_addr))
-               {
-                       initaddr(p->pbs.cur, pbs_left(&p->pbs), AF_INET, &ip);
-               }
-               else
-               {
-                       loglog(RC_LOG_SERIOUS, "NAT-Traversal: received IPv4 NAT-OA "
-                                               "with invalid IP size (%d)", (int)pbs_left(&p->pbs));
-                       return;
-               }
-               break;
-       case ID_IPV6_ADDR:
-               if (pbs_left(&p->pbs) == sizeof(struct in6_addr))
-               {
-                       initaddr(p->pbs.cur, pbs_left(&p->pbs), AF_INET6, &ip);
-               }
-               else
-               {
-                       loglog(RC_LOG_SERIOUS, "NAT-Traversal: received IPv6 NAT-OA "
-                                               "with invalid IP size (%d)", (int)pbs_left(&p->pbs));
-                       return;
-               }
-               break;
-       default:
-               loglog(RC_LOG_SERIOUS, "NAT-Traversal: "
-                                               "invalid ID Type (%d) in NAT-OA - ignored",
-                                               p->payload.nat_oa.isanoa_idtype);
-                       return;
-       }
-
-       DBG(DBG_NATT,
-               {
-                       char ip_t[ADDRTOT_BUF];
-                       addrtot(&ip, 0, ip_t, sizeof(ip_t));
-
-                       DBG_log("received NAT-OA: %s", ip_t);
-               }
-       )
-
-       if (isanyaddr(&ip))
-               loglog(RC_LOG_SERIOUS, "NAT-Traversal: received %%any NAT-OA...");
-       else
-               st->nat_oa = ip;
-}
-
-bool nat_traversal_add_natoa(u_int8_t np, pb_stream *outs,
-               struct state *st)
-{
-       struct isakmp_nat_oa natoa;
-       pb_stream pbs;
-       unsigned char ip_val[sizeof(struct in6_addr)];
-       size_t ip_len = 0;
-       ip_address *ip;
-
-       if ((!st) || (!st->st_connection))
-       {
-               loglog(RC_LOG_SERIOUS, "NAT-Traversal: assert failed %s:%d"
-                                               , __FILE__, __LINE__);
-               return FALSE;
-       }
-       ip = &(st->st_connection->spd.this.host_addr);
-
-       memset(&natoa, 0, sizeof(natoa));
-       natoa.isanoa_np = np;
-
-       switch (addrtypeof(ip))
-       {
-       case AF_INET:
-               ip_len = sizeof(ip->u.v4.sin_addr.s_addr);
-               memcpy(ip_val, &ip->u.v4.sin_addr.s_addr, ip_len);
-               natoa.isanoa_idtype = ID_IPV4_ADDR;
-               break;
-       case AF_INET6:
-               ip_len = sizeof(ip->u.v6.sin6_addr.s6_addr);
-               memcpy(ip_val, &ip->u.v6.sin6_addr.s6_addr, ip_len);
-               natoa.isanoa_idtype = ID_IPV6_ADDR;
-               break;
-       default:
-               loglog(RC_LOG_SERIOUS, "NAT-Traversal: "
-                                               "invalid addrtypeof()=%d", addrtypeof(ip));
-               return FALSE;
-       }
-
-       if (!out_struct(&natoa, &isakmp_nat_oa, outs, &pbs))
-               return FALSE;
-
-       if (!out_raw(ip_val, ip_len, &pbs, "NAT-OA"))
-               return FALSE;
-
-       DBG(DBG_NATT,
-               DBG_dump("NAT-OA (S):", ip_val, ip_len)
-       )
-
-       close_output_pbs(&pbs);
-       return TRUE;
-}
-
-void nat_traversal_show_result (u_int32_t nt, u_int16_t sport)
-{
-       const char *mth = NULL, *rslt = NULL;
-
-       switch (nt & NAT_TRAVERSAL_METHOD)
-       {
-       case LELEM(NAT_TRAVERSAL_IETF_00_01):
-               mth = natt_type_bitnames[0];
-               break;
-       case LELEM(NAT_TRAVERSAL_IETF_02_03):
-               mth = natt_type_bitnames[1];
-               break;
-       case LELEM(NAT_TRAVERSAL_RFC):
-               mth = natt_type_bitnames[2];
-               break;
-       }
-
-       switch (nt & NAT_T_DETECTED)
-       {
-       case 0:
-               rslt = "no NAT detected";
-               break;
-       case LELEM(NAT_TRAVERSAL_NAT_BHND_ME):
-               rslt = "i am NATed";
-               break;
-       case LELEM(NAT_TRAVERSAL_NAT_BHND_PEER):
-               rslt = "peer is NATed";
-               break;
-       case LELEM(NAT_TRAVERSAL_NAT_BHND_ME) | LELEM(NAT_TRAVERSAL_NAT_BHND_PEER):
-               rslt = "both are NATed";
-               break;
-       }
-
-       loglog(RC_LOG_SERIOUS,
-               "NAT-Traversal: Result using %s: %s",
-               mth ? mth : "unknown method",
-               rslt ? rslt : "unknown result"
-       );
-
-       if ((nt & LELEM(NAT_TRAVERSAL_NAT_BHND_PEER))
-       &&  (sport == IKE_UDP_PORT)
-       &&  ((nt & NAT_T_WITH_PORT_FLOATING)==0))
-       {
-               loglog(RC_LOG_SERIOUS,
-                               "Warning: peer is NATed but source port is still udp/%d. "
-                               "Ipsec-passthrough NAT device suspected -- NAT-T may not work.",
-                               IKE_UDP_PORT
-               );
-       }
-}
-
-int nat_traversal_espinudp_socket (int sk, u_int32_t type)
-{
-       int r = setsockopt(sk, SOL_UDP, UDP_ESPINUDP, &type, sizeof(type));
-
-       if (r < 0 && errno == ENOPROTOOPT)
-       {
-               loglog(RC_LOG_SERIOUS,
-                               "NAT-Traversal: ESPINUDP(%d) not supported by kernel -- "
-                               "NAT-T disabled", type);
-               disable_nat_traversal(type);
-       }
-       return r;
-}
-
-void nat_traversal_new_ka_event (void)
-{
-       if (_ka_evt)
-               return;  /* event already scheduled */
-
-       event_schedule(EVENT_NAT_T_KEEPALIVE, _kap, NULL);
-       _ka_evt = 1;
-}
-
-static void nat_traversal_send_ka (struct state *st)
-{
-       static unsigned char ka_payload = 0xff;
-       chunk_t sav;
-
-       DBG(DBG_NATT,
-               DBG_log("ka_event: send NAT-KA to %s:%d",
-                               ip_str(&st->st_connection->spd.that.host_addr),
-                               st->st_connection->spd.that.host_port);
-       )
-
-       /* save state chunk */
-       sav = st->st_tpacket;
-
-       /* send keep alive */
-       st->st_tpacket = chunk_create(&ka_payload, 1);
-       send_packet(st, "NAT-T Keep Alive");
-
-       /* restore state chunk */
-       st->st_tpacket = sav;
-}
-
-/**
- * Find ISAKMP States with NAT-T and send keep-alive
- */
-static void nat_traversal_ka_event_state (struct state *st, void *data)
-{
-       unsigned int *_kap_st = (unsigned int *)data;
-       const connection_t *c = st->st_connection;
-
-       if (!c)
-               return;
-
-       if ((st->st_state == STATE_MAIN_R3 || st->st_state == STATE_MAIN_I4)
-       &&  (st->nat_traversal & NAT_T_DETECTED)
-       &&  ((st->nat_traversal & LELEM(NAT_TRAVERSAL_NAT_BHND_ME)) || _force_ka))
-       {
-               /*
-                * - ISAKMP established
-                * - NAT-Traversal detected
-                * - NAT-KeepAlive needed (we are NATed)
-                */
-               if (c->newest_isakmp_sa != st->st_serialno)
-               {
-                       /*
-                        * if newest is also valid, ignore this one, we will only use
-                        * newest.
-                        */
-                       struct state *st_newest;
-
-                       st_newest = state_with_serialno(c->newest_isakmp_sa);
-                       if (st_newest
-                       && (st_newest->st_state == STATE_MAIN_R3 || st_newest->st_state == STATE_MAIN_I4)
-                       && (st_newest->nat_traversal & NAT_T_DETECTED)
-                       && ((st_newest->nat_traversal & LELEM(NAT_TRAVERSAL_NAT_BHND_ME)) || _force_ka))
-                       {
-                               return;
-                       }
-               }
-               set_cur_state(st);
-               nat_traversal_send_ka(st);
-               reset_cur_state();
-               (*_kap_st)++;
-       }
-}
-
-void nat_traversal_ka_event (void)
-{
-       unsigned int _kap_st = 0;
-
-       _ka_evt = 0;  /* ready to be reschedule */
-
-       for_each_state((void *)nat_traversal_ka_event_state, &_kap_st);
-
-       /* if there are still states who needs Keep-Alive, schedule new event */
-       if (_kap_st)
-               nat_traversal_new_ka_event();
-}
-
-struct _new_mapp_nfo {
-               ip_address addr;
-               u_int16_t sport, dport;
-};
-
-static void nat_traversal_find_new_mapp_state (struct state *st, void *data)
-{
-       connection_t *c = st->st_connection;
-       struct _new_mapp_nfo *nfo = (struct _new_mapp_nfo *)data;
-
-       if (c != NULL
-       && sameaddr(&c->spd.that.host_addr, &(nfo->addr))
-       &&  c->spd.that.host_port == nfo->sport)
-       {
-
-               /* change host port */
-               c->spd.that.host_port = nfo->dport;
-
-               if (IS_IPSEC_SA_ESTABLISHED(st->st_state)
-               ||  IS_ONLY_INBOUND_IPSEC_SA_ESTABLISHED(st->st_state))
-               {
-                       if (!update_ipsec_sa(st))
-                       {
-                               /*
-                                * If ipsec update failed, restore old port or we'll
-                                * not be able to update anymore.
-                                */
-                               c->spd.that.host_port = nfo->sport;
-                       }
-               }
-       }
-}
-
-static int nat_traversal_new_mapping(const ip_address *src, u_int16_t sport,
-               const ip_address *dst, u_int16_t dport)
-{
-       char srca[ADDRTOT_BUF], dsta[ADDRTOT_BUF];
-       struct _new_mapp_nfo nfo;
-
-       addrtot(src, 0, srca, ADDRTOT_BUF);
-       addrtot(dst, 0, dsta, ADDRTOT_BUF);
-
-       if (!sameaddr(src, dst))
-       {
-               loglog(RC_LOG_SERIOUS, "nat_traversal_new_mapping: "
-                               "address change currently not supported [%s:%d,%s:%d]",
-                               srca, sport, dsta, dport);
-               return -1;
-       }
-
-       if (sport == dport)
-       {
-               /* no change */
-               return 0;
-       }
-
-       DBG_log("NAT-T: new mapping %s:%d/%d)", srca, sport, dport);
-
-       nfo.addr = *src;
-       nfo.sport = sport;
-       nfo.dport = dport;
-
-       for_each_state((void *)nat_traversal_find_new_mapp_state, &nfo);
-
-       return 0;
-}
-
-void nat_traversal_change_port_lookup(struct msg_digest *md, struct state *st)
-{
-       connection_t *c = st ? st->st_connection : NULL;
-       struct iface *i = NULL;
-
-       if ((st == NULL) || (c == NULL))
-               return;
-
-       if (md)
-       {
-               /*
-                * If source port has changed, update (including other states and
-                * established kernel SA)
-                */
-               if (c->spd.that.host_port != md->sender_port)
-               {
-                       nat_traversal_new_mapping(&c->spd.that.host_addr, c->spd.that.host_port,
-                                               &c->spd.that.host_addr, md->sender_port);
-               }
-
-               /*
-                * If interface type has changed, update local port (500/4500)
-                */
-               if ((c->spd.this.host_port == NAT_T_IKE_FLOAT_PORT && !md->iface->ike_float)
-               ||  (c->spd.this.host_port != NAT_T_IKE_FLOAT_PORT &&  md->iface->ike_float))
-               {
-                       c->spd.this.host_port = (md->iface->ike_float)
-                               ? NAT_T_IKE_FLOAT_PORT : pluto_port;
-
-                       DBG(DBG_NATT,
-                               DBG_log("NAT-T: updating local port to %d", c->spd.this.host_port);
-                       );
-               }
-       }
-
-       /*
-        * If we're initiator and NAT-T (with port floating) is detected, we
-        * need to change port (MAIN_I3 or QUICK_I1)
-        */
-       if ((st->st_state == STATE_MAIN_I3 || st->st_state == STATE_QUICK_I1)
-       &&  (st->nat_traversal & NAT_T_WITH_PORT_FLOATING)
-       &&  (st->nat_traversal & NAT_T_DETECTED)
-       &&  (c->spd.this.host_port != NAT_T_IKE_FLOAT_PORT))
-       {
-               DBG(DBG_NATT,
-                       DBG_log("NAT-T: floating to port %d", NAT_T_IKE_FLOAT_PORT);
-               )
-               c->spd.this.host_port = NAT_T_IKE_FLOAT_PORT;
-               c->spd.that.host_port = NAT_T_IKE_FLOAT_PORT;
-               /*
-                * Also update pending connections or they will be deleted if uniqueids
-                * option is set.
-                */
-               update_pending(st, st);
-       }
-
-       /*
-        * Find valid interface according to local port (500/4500)
-        */
-       if ((c->spd.this.host_port == NAT_T_IKE_FLOAT_PORT && !c->interface->ike_float)
-       ||  (c->spd.this.host_port != NAT_T_IKE_FLOAT_PORT &&  c->interface->ike_float))
-       {
-               for (i = interfaces; i !=  NULL; i = i->next)
-               {
-                       if (sameaddr(&c->interface->addr, &i->addr)
-                       && i->ike_float != c->interface->ike_float)
-                       {
-                               DBG(DBG_NATT,
-                                       DBG_log("NAT-T: using interface %s:%d", i->rname,
-                                               i->ike_float ? NAT_T_IKE_FLOAT_PORT : pluto_port);
-                               )
-                               c->interface = i;
-                               break;
-                       }
-               }
-       }
-}
-
-struct _new_kernel_mapp_nfo {
-               u_int32_t reqid;
-               u_int32_t spi;
-               ip_address *addr;
-};
-
-static void nat_t_new_kernel_mapp (struct state *st, void *data)
-{
-       connection_t *c = st->st_connection;
-       struct _new_kernel_mapp_nfo *nfo = (struct _new_kernel_mapp_nfo *)data;
-
-       if (c != NULL && st->st_esp.present
-               &&  nfo->spi == st->st_esp.our_spi
-               &&  nfo->reqid == c->spd.reqid)
-       {
-               u_int16_t port = ntohs(portof(nfo->addr));
-
-               DBG(DBG_NATT, {
-                       char text_said[SATOT_BUF];
-                       char olda[ADDRTOT_BUF];
-                       char newa[ADDRTOT_BUF];
-                       ip_said said;
-
-                       initsaid(&c->spd.that.host_addr, nfo->spi, SA_ESP, &said);
-                       satot(&said, 0, text_said, SATOT_BUF);
-                       addrtot(&c->spd.that.host_addr, 0, olda, ADDRTOT_BUF);
-                       addrtot(nfo->addr, 0, newa, ADDRTOT_BUF);
-
-                       DBG_log("new kernel mapping %s %s:%d %s:%d",
-                                       text_said, olda, c->spd.that.host_port, newa, port);
-               })
-
-               nat_traversal_new_mapping(&c->spd.that.host_addr, c->spd.that.host_port,
-                                                                 nfo->addr, port);
-       }
-}
-
-void process_nat_t_new_mapping(u_int32_t reqid, u_int32_t spi,
-                                                          ip_address *new_end)
-{
-       struct _new_kernel_mapp_nfo nfo = {
-               .reqid = reqid,
-               .spi = spi,
-               .addr = new_end,
-       };
-       for_each_state((void *)nat_t_new_kernel_mapp, &nfo);
-}
-
diff --git a/src/pluto/nat_traversal.h b/src/pluto/nat_traversal.h
deleted file mode 100644 (file)
index 80bdaf7..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2010 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
- * Copyright (C) 2002-2003 Mathieu Lafon
- * Arkoon Network Security
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef _NAT_TRAVERSAL_H
-#define _NAT_TRAVERSAL_H
-
-#include "packet.h"
-
-#define NAT_TRAVERSAL_IETF_00_01     1
-#define NAT_TRAVERSAL_IETF_02_03     2
-#define NAT_TRAVERSAL_RFC            3
-
-#define NAT_TRAVERSAL_NAT_BHND_ME    30
-#define NAT_TRAVERSAL_NAT_BHND_PEER  31
-
-#define NAT_TRAVERSAL_METHOD  (0xffffffff - LELEM(30) - LELEM(31))
-
-/**
- * NAT-Traversal methods which need NAT-D
- */
-#define NAT_T_WITH_NATD \
-               ( LELEM(NAT_TRAVERSAL_IETF_00_01) | LELEM(NAT_TRAVERSAL_IETF_02_03) | \
-               LELEM(NAT_TRAVERSAL_RFC) )
-/**
- * NAT-Traversal methods which need NAT-OA
- */
-#define NAT_T_WITH_NATOA \
-               ( LELEM(NAT_TRAVERSAL_IETF_00_01) | LELEM(NAT_TRAVERSAL_IETF_02_03) | \
-               LELEM(NAT_TRAVERSAL_RFC) )
-/**
- * NAT-Traversal methods which use NAT-KeepAlive
- */
-#define NAT_T_WITH_KA \
-               ( LELEM(NAT_TRAVERSAL_IETF_00_01) | LELEM(NAT_TRAVERSAL_IETF_02_03) | \
-               LELEM(NAT_TRAVERSAL_RFC) )
-/**
- * NAT-Traversal methods which use floating port
- */
-#define NAT_T_WITH_PORT_FLOATING \
-               ( LELEM(NAT_TRAVERSAL_IETF_02_03) | LELEM(NAT_TRAVERSAL_RFC) )
-
-/**
- * NAT-Traversal methods which use officials values (RFC)
- */
-#define NAT_T_WITH_RFC_VALUES \
-               ( LELEM(NAT_TRAVERSAL_RFC) )
-
-/**
- * NAT-Traversal detected
- */
-#define NAT_T_DETECTED \
-               ( LELEM(NAT_TRAVERSAL_NAT_BHND_ME) | LELEM(NAT_TRAVERSAL_NAT_BHND_PEER) )
-
-/**
- * NAT-T Port Floating
- */
-#define NAT_T_IKE_FLOAT_PORT     4500
-
-void init_nat_traversal (bool activate, unsigned int keep_alive_period,
-               bool fka, bool spf);
-
-extern bool nat_traversal_enabled;
-extern bool nat_traversal_support_non_ike;
-extern bool nat_traversal_support_port_floating;
-
-/**
- * NAT-D
- */
-void nat_traversal_natd_lookup(struct msg_digest *md);
-#ifndef PB_STREAM_UNDEFINED
-bool nat_traversal_add_natd(u_int8_t np, pb_stream *outs,
-               struct msg_digest *md);
-#endif
-
-/**
- * NAT-OA
- */
-void nat_traversal_natoa_lookup(struct msg_digest *md);
-#ifndef PB_STREAM_UNDEFINED
-bool nat_traversal_add_natoa(u_int8_t np, pb_stream *outs,
-               struct state *st);
-#endif
-
-/**
- * NAT-keep_alive
- */
-void nat_traversal_new_ka_event (void);
-void nat_traversal_ka_event (void);
-
-void nat_traversal_show_result (u_int32_t nt, u_int16_t sport);
-
-int nat_traversal_espinudp_socket (int sk, u_int32_t type);
-
-/**
- * Vendor ID
- */
-#ifndef PB_STREAM_UNDEFINED
-bool nat_traversal_add_vid(u_int8_t np, pb_stream *outs);
-#endif
-u_int32_t nat_traversal_vid_to_method(unsigned short nat_t_vid);
-
-void nat_traversal_change_port_lookup(struct msg_digest *md, struct state *st);
-
-/**
- * New NAT mapping
- */
-void process_nat_t_new_mapping(u_int32_t reqid, u_int32_t spi,
-                                                          ip_address *new_end);
-
-/**
- * IKE port floating
- */
-bool
-nat_traversal_port_float(struct state *st, struct msg_digest *md, bool in);
-
-/**
- * Encapsulation mode macro (see demux.c)
- */
-#define NAT_T_ENCAPSULATION_MODE(st,nat_t_policy) ( \
-               ((st)->nat_traversal & NAT_T_DETECTED) \
-                               ? ( ((nat_t_policy) & POLICY_TUNNEL) \
-                                               ? ( ((st)->nat_traversal & NAT_T_WITH_RFC_VALUES) \
-                                                               ? (ENCAPSULATION_MODE_UDP_TUNNEL_RFC) \
-                                                               : (ENCAPSULATION_MODE_UDP_TUNNEL_DRAFTS) \
-                                                 ) \
-                                               : ( ((st)->nat_traversal & NAT_T_WITH_RFC_VALUES) \
-                                                               ? (ENCAPSULATION_MODE_UDP_TRANSPORT_RFC) \
-                                                               : (ENCAPSULATION_MODE_UDP_TRANSPORT_DRAFTS) \
-                                                 ) \
-                                 ) \
-                               : ( ((st)->st_policy & POLICY_TUNNEL) \
-                                               ? (ENCAPSULATION_MODE_TUNNEL) \
-                                               : (ENCAPSULATION_MODE_TRANSPORT) \
-                                 ) \
-               )
-
-#endif /* _NAT_TRAVERSAL_H */
-
diff --git a/src/pluto/ocsp.c b/src/pluto/ocsp.c
deleted file mode 100644 (file)
index c299e3d..0000000
+++ /dev/null
@@ -1,1558 +0,0 @@
-/* Support of the Online Certificate Status Protocol (OCSP)
- * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
- * Copyright (C) 2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include <freeswan.h>
-
-#include <library.h>
-#include <asn1/asn1.h>
-#include <asn1/asn1_parser.h>
-#include <asn1/oid.h>
-#include <crypto/rngs/rng.h>
-#include <crypto/hashers/hasher.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "x509.h"
-#include "crl.h"
-#include "ca.h"
-#include "certs.h"
-#include "smartcard.h"
-#include "whack.h"
-#include "keys.h"
-#include "fetch.h"
-#include "ocsp.h"
-
-#define NONCE_LENGTH            16
-
-static const char *const cert_status_names[] = {
-       "good",
-       "revoked",
-       "unknown",
-       "undefined"
-};
-
-
-static const char *const response_status_names[] = {
-       "successful",
-       "malformed request",
-       "internal error",
-       "try later",
-       "status #4",
-       "signature required",
-       "unauthorized"
-};
-
-/* response container */
-typedef struct response response_t;
-
-struct response {
-       chunk_t          tbs;
-       identification_t *responder_id_name;
-       chunk_t           responder_id_key;
-       time_t            produced_at;
-       chunk_t           responses;
-       chunk_t           nonce;
-       int               algorithm;
-       chunk_t           signature;
-};
-
-const response_t empty_response = {
-       { NULL, 0 }   ,     /* tbs */
-         NULL        ,     /* responder_id_name */
-       { NULL, 0 }   ,     /* responder_id_key */
-       UNDEFINED_TIME,     /* produced_at */
-       { NULL, 0 }   ,     /* single_response */
-       { NULL, 0 }   ,     /* nonce */
-       OID_UNKNOWN   ,     /* signature_algorithm */
-       { NULL, 0 }         /* signature */
-};
-
-/* single response container */
-typedef struct single_response single_response_t;
-
-struct single_response {
-       single_response_t *next;
-       int               hash_algorithm;
-       chunk_t           issuer_name_hash;
-       chunk_t           issuer_key_hash;
-       chunk_t           serialNumber;
-       cert_status_t     status;
-       time_t            revocationTime;
-       crl_reason_t      revocationReason;
-       time_t            thisUpdate;
-       time_t            nextUpdate;
-};
-
-const single_response_t empty_single_response = {
-         NULL                , /* *next */
-       OID_UNKNOWN           , /* hash_algorithm */
-       { NULL, 0 }           , /* issuer_name_hash */
-       { NULL, 0 }           , /* issuer_key_hash */
-       { NULL, 0 }           , /* serial_number */
-       CERT_UNDEFINED        , /* status */
-       UNDEFINED_TIME        , /* revocationTime */
-       CRL_REASON_UNSPECIFIED, /* revocationReason */
-       UNDEFINED_TIME        , /* this_update */
-       UNDEFINED_TIME          /* next_update */
-};
-
-
-/* list of single requests */
-typedef struct request_list request_list_t;
-struct request_list {
-       chunk_t request;
-       request_list_t *next;
-};
-
-/* some OCSP specific prefabricated ASN.1 constants */
-static const chunk_t ASN1_nonce_oid = chunk_from_chars(
-       0x06, 0x09, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x02
-);
-static const chunk_t ASN1_response_oid = chunk_from_chars(
-       0x06, 0x09, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x04
-);
-static const chunk_t ASN1_response_content = chunk_from_chars(
-       0x04, 0x0D,
-                 0x30, 0x0B,
-                               0x06, 0x09, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01
-);
-
-/* default OCSP uri */
-static chunk_t ocsp_default_uri;
-
-/* ocsp cache: pointer to first element */
-static ocsp_location_t *ocsp_cache = NULL;
-
-/* static temporary storage for ocsp requestor information */
-static cert_t *ocsp_requestor_cert = NULL;
-
-static smartcard_t *ocsp_requestor_sc = NULL;
-
-static private_key_t *ocsp_requestor_key = NULL;
-
-/**
- * ASN.1 definition of ocspResponse
- */
-static const asn1Object_t ocspResponseObjects[] = {
-       { 0, "OCSPResponse",                    ASN1_SEQUENCE,          ASN1_NONE }, /* 0 */
-       { 1,   "responseStatus",                ASN1_ENUMERATED,        ASN1_BODY }, /* 1 */
-       { 1,   "responseBytesContext",  ASN1_CONTEXT_C_0,       ASN1_OPT  }, /* 2 */
-       { 2,     "responseBytes",               ASN1_SEQUENCE,          ASN1_NONE }, /* 3 */
-       { 3,       "responseType",              ASN1_OID,                       ASN1_BODY }, /* 4 */
-       { 3,       "response",                  ASN1_OCTET_STRING,      ASN1_BODY }, /* 5 */
-       { 1,   "end opt",                               ASN1_EOC,                       ASN1_END  }, /* 6 */
-       { 0, "exit",                                    ASN1_EOC,                       ASN1_EXIT }
-};
-#define OCSP_RESPONSE_STATUS   1
-#define OCSP_RESPONSE_TYPE             4
-#define OCSP_RESPONSE                  5
-
-/**
- * ASN.1 definition of basicResponse
- */
-static const asn1Object_t basicResponseObjects[] = {
-       { 0, "BasicOCSPResponse",                               ASN1_SEQUENCE,                  ASN1_NONE }, /*  0 */
-       { 1,   "tbsResponseData",                               ASN1_SEQUENCE,                  ASN1_OBJ  }, /*  1 */
-       { 2,     "versionContext",                              ASN1_CONTEXT_C_0,               ASN1_NONE |
-                                                                                                                                       ASN1_DEF  }, /*  2 */
-       { 3,       "version",                                   ASN1_INTEGER,                   ASN1_BODY }, /*  3 */
-       { 2,     "responderIdContext",                  ASN1_CONTEXT_C_1,               ASN1_OPT  }, /*  4 */
-       { 3,       "responderIdByName",                 ASN1_SEQUENCE,                  ASN1_OBJ  }, /*  5 */
-       { 2,     "end choice",                                  ASN1_EOC,                               ASN1_END  }, /*  6 */
-       { 2,     "responderIdContext",                  ASN1_CONTEXT_C_2,               ASN1_OPT  }, /*  7 */
-       { 3,       "responderIdByKey",                  ASN1_OCTET_STRING,              ASN1_BODY }, /*  8 */
-       { 2,     "end choice",                                  ASN1_EOC,                               ASN1_END  }, /*  9 */
-       { 2,     "producedAt",                                  ASN1_GENERALIZEDTIME,   ASN1_BODY }, /* 10 */
-       { 2,     "responses",                                   ASN1_SEQUENCE,                  ASN1_OBJ  }, /* 11 */
-       { 2,     "responseExtensionsContext",   ASN1_CONTEXT_C_1,               ASN1_OPT  }, /* 12 */
-       { 3,       "responseExtensions",                ASN1_SEQUENCE,                  ASN1_LOOP }, /* 13 */
-       { 4,         "extension",                               ASN1_SEQUENCE,                  ASN1_NONE }, /* 14 */
-       { 5,           "extnID",                                ASN1_OID,                               ASN1_BODY }, /* 15 */
-       { 5,           "critical",                              ASN1_BOOLEAN,                   ASN1_BODY |
-                                                                                                                                       ASN1_DEF  }, /* 16 */
-       { 5,           "extnValue",                             ASN1_OCTET_STRING,              ASN1_BODY }, /* 17 */
-       { 3,       "end loop",                                  ASN1_EOC,                               ASN1_END  }, /* 18 */
-       { 2,     "end opt",                                             ASN1_EOC,                               ASN1_END  }, /* 19 */
-       { 1,   "signatureAlgorithm",                    ASN1_EOC,                               ASN1_RAW  }, /* 20 */
-       { 1,   "signature",                                             ASN1_BIT_STRING,                ASN1_BODY }, /* 21 */
-       { 1,   "certsContext",                                  ASN1_CONTEXT_C_0,               ASN1_OPT  }, /* 22 */
-       { 2,     "certs",                                               ASN1_SEQUENCE,                  ASN1_LOOP }, /* 23 */
-       { 3,       "certificate",                               ASN1_SEQUENCE,                  ASN1_RAW  }, /* 24 */
-       { 2,     "end loop",                                    ASN1_EOC,                               ASN1_END  }, /* 25 */
-       { 1,   "end opt",                                               ASN1_EOC,                               ASN1_END  }, /* 26 */
-       { 0, "exit",                                                    ASN1_EOC,                               ASN1_EXIT }
-};
-#define BASIC_RESPONSE_TBS_DATA                 1
-#define BASIC_RESPONSE_VERSION          3
-#define BASIC_RESPONSE_ID_BY_NAME       5
-#define BASIC_RESPONSE_ID_BY_KEY        8
-#define BASIC_RESPONSE_PRODUCED_AT     10
-#define BASIC_RESPONSE_RESPONSES       11
-#define BASIC_RESPONSE_EXT_ID          15
-#define BASIC_RESPONSE_CRITICAL                16
-#define BASIC_RESPONSE_EXT_VALUE       17
-#define BASIC_RESPONSE_ALGORITHM       20
-#define BASIC_RESPONSE_SIGNATURE       21
-#define BASIC_RESPONSE_CERTIFICATE     24
-
-/**
- * ASN.1 definition of responses
- */
-static const asn1Object_t responsesObjects[] = {
-       { 0, "responses",                       ASN1_SEQUENCE,  ASN1_LOOP }, /* 0 */
-       { 1,   "singleResponse",        ASN1_EOC,               ASN1_RAW  }, /* 1 */
-       { 0, "end loop",                        ASN1_EOC,               ASN1_END  }, /* 2 */
-       { 0, "exit",                            ASN1_EOC,               ASN1_EXIT }
-};
-#define RESPONSES_SINGLE_RESPONSE      1
-
-/**
- * ASN.1 definition of singleResponse
- */
-static const asn1Object_t singleResponseObjects[] = {
-       { 0, "singleResponse",                          ASN1_SEQUENCE,                  ASN1_BODY }, /*  0 */
-       { 1,   "certID",                                        ASN1_SEQUENCE,                  ASN1_NONE }, /*  1 */
-       { 2,     "algorithm",                           ASN1_EOC,                               ASN1_RAW  }, /*  2 */
-       { 2,     "issuerNameHash",                      ASN1_OCTET_STRING,              ASN1_BODY }, /*  3 */
-       { 2,     "issuerKeyHash",                       ASN1_OCTET_STRING,              ASN1_BODY }, /*  4 */
-       { 2,     "serialNumber",                        ASN1_INTEGER,                   ASN1_BODY }, /*  5 */
-       { 1,   "certStatusGood",                        ASN1_CONTEXT_S_0,               ASN1_OPT  }, /*  6 */
-       { 1,   "end opt",                                       ASN1_EOC,                               ASN1_END  }, /*  7 */
-       { 1,   "certStatusRevoked",                     ASN1_CONTEXT_C_1,               ASN1_OPT  }, /*  8 */
-       { 2,     "revocationTime",                      ASN1_GENERALIZEDTIME,   ASN1_BODY }, /*  9 */
-       { 2,     "revocationReason",            ASN1_CONTEXT_C_0,               ASN1_OPT  }, /* 10 */
-       { 3,       "crlReason",                         ASN1_ENUMERATED,                ASN1_BODY }, /* 11 */
-       { 2,     "end opt",                                     ASN1_EOC,                               ASN1_END  }, /* 12 */
-       { 1,   "end opt",                                       ASN1_EOC,                               ASN1_END  }, /* 13 */
-       { 1,   "certStatusUnknown",                     ASN1_CONTEXT_S_2,               ASN1_OPT  }, /* 14 */
-       { 1,   "end opt",                                       ASN1_EOC,                               ASN1_END  }, /* 15 */
-       { 1,   "thisUpdate",                            ASN1_GENERALIZEDTIME,   ASN1_BODY }, /* 16 */
-       { 1,   "nextUpdateContext",                     ASN1_CONTEXT_C_0,               ASN1_OPT  }, /* 17 */
-       { 2,     "nextUpdate",                          ASN1_GENERALIZEDTIME,   ASN1_BODY }, /* 18 */
-       { 1,   "end opt",                                       ASN1_EOC,                               ASN1_END  }, /* 19 */
-       { 1,   "singleExtensionsContext",       ASN1_CONTEXT_C_1,               ASN1_OPT  }, /* 20 */
-       { 2,     "singleExtensions",            ASN1_SEQUENCE,                  ASN1_LOOP }, /* 21 */
-       { 3,       "extension",                         ASN1_SEQUENCE,                  ASN1_NONE }, /* 22 */
-       { 4,         "extnID",                          ASN1_OID,                               ASN1_BODY }, /* 23 */
-       { 4,         "critical",                        ASN1_BOOLEAN,                   ASN1_BODY |
-                                                                                                                               ASN1_DEF  }, /* 24 */
-       { 4,         "extnValue",                       ASN1_OCTET_STRING,              ASN1_BODY }, /* 25 */
-       { 2,     "end loop",                            ASN1_EOC,                               ASN1_END  }, /* 26 */
-       { 1,   "end opt",                                       ASN1_EOC,                               ASN1_END  }, /* 27 */
-       { 0, "exit",                                            ASN1_EOC,                               ASN1_EXIT }
-};
-#define SINGLE_RESPONSE_ALGORITHM                                       2
-#define SINGLE_RESPONSE_ISSUER_NAME_HASH                        3
-#define SINGLE_RESPONSE_ISSUER_KEY_HASH                                 4
-#define SINGLE_RESPONSE_SERIAL_NUMBER                           5
-#define SINGLE_RESPONSE_CERT_STATUS_GOOD                        6
-#define SINGLE_RESPONSE_CERT_STATUS_REVOKED                     8
-#define SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME     9
-#define SINGLE_RESPONSE_CERT_STATUS_CRL_REASON         11
-#define SINGLE_RESPONSE_CERT_STATUS_UNKNOWN                    14
-#define SINGLE_RESPONSE_THIS_UPDATE                                    16
-#define SINGLE_RESPONSE_NEXT_UPDATE                                    18
-#define SINGLE_RESPONSE_EXT_ID                                         23
-#define SINGLE_RESPONSE_CRITICAL                                       24
-#define SINGLE_RESPONSE_EXT_VALUE                                      25
-
-/*
- * Build an ocsp location from certificate information
- * without unsharing its contents
- */
-static bool build_ocsp_location(const cert_t *cert, ocsp_location_t *location)
-{
-       certificate_t *certificate = cert->cert;
-       identification_t *issuer = certificate->get_issuer(certificate);
-       x509_t *x509 = (x509_t*)certificate;
-       chunk_t issuer_dn = issuer->get_encoding(issuer);
-       chunk_t authKeyID = x509->get_authKeyIdentifier(x509);
-       hasher_t *hasher;
-       static u_char digest[HASH_SIZE_SHA1];  /* temporary storage */
-
-       enumerator_t *enumerator = x509->create_ocsp_uri_enumerator(x509);
-
-       location->uri = NULL;
-       while (enumerator->enumerate(enumerator, &location->uri))
-       {
-               break;
-       }
-       enumerator->destroy(enumerator);
-
-       if (location->uri == NULL)
-       {
-               ca_info_t *ca = get_ca_info(issuer, authKeyID);
-               if (ca && ca->ocspuri)
-               {
-                       location->uri = ca->ocspuri;
-               }
-               else
-               {   /* abort if no ocsp location uri is defined */
-                       return FALSE;
-               }
-       }
-
-       /* compute authNameID from as SHA-1 hash of issuer DN */
-       location->authNameID = chunk_create(digest, HASH_SIZE_SHA1);
-       hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
-       if (hasher == NULL)
-       {
-               return FALSE;
-       }
-       hasher->get_hash(hasher, issuer_dn, digest);
-       hasher->destroy(hasher);
-
-       location->next = NULL;
-       location->issuer = issuer;
-       location->authKeyID = authKeyID;
-
-       if (authKeyID.ptr == NULL)
-       {
-               cert_t *authcert = get_authcert(issuer, authKeyID, X509_CA);
-
-               if (authcert)
-               {
-                       x509_t *x509 = (x509_t*)authcert->cert;
-
-                       location->authKeyID = x509->get_subjectKeyIdentifier(x509);
-               }
-       }
-
-       location->nonce = chunk_empty;
-       location->certinfo = NULL;
-
-       return TRUE;
-}
-
-/**
- * Compare two ocsp locations for equality
- */
-static bool same_ocsp_location(const ocsp_location_t *a, const ocsp_location_t *b)
-{
-       return ((a->authKeyID.ptr)
-                               ? same_keyid(a->authKeyID, b->authKeyID)
-                               : a->issuer->equals(a->issuer, b->issuer))
-                       && streq(a->uri, b->uri);
-}
-
-/**
- * Find an existing ocsp location in a chained list
- */
-ocsp_location_t* get_ocsp_location(const ocsp_location_t * loc, ocsp_location_t *chain)
-{
-
-       while (chain)
-       {
-               if (same_ocsp_location(loc, chain))
-                       return chain;
-               chain = chain->next;
-       }
-       return NULL;
-}
-
-/**
- * Retrieves the status of a cert from the ocsp cache
- * returns CERT_UNDEFINED if no status is found
- */
-static cert_status_t get_ocsp_status(const ocsp_location_t *loc,
-                                                                        chunk_t serialNumber,
-                                                                        time_t *nextUpdate, time_t *revocationTime,
-                                                                        crl_reason_t *revocationReason)
-{
-       ocsp_certinfo_t *certinfo, **certinfop;
-       int cmp = -1;
-
-       /* find location */
-       ocsp_location_t *location = get_ocsp_location(loc, ocsp_cache);
-
-       if (location == NULL)
-               return CERT_UNDEFINED;
-
-       /* traverse list of certinfos in increasing order */
-       certinfop = &location->certinfo;
-       certinfo = *certinfop;
-
-       while (certinfo)
-       {
-               cmp = chunk_compare(serialNumber, certinfo->serialNumber);
-               if (cmp <= 0)
-                       break;
-               certinfop = &certinfo->next;
-               certinfo = *certinfop;
-       }
-
-       if (cmp == 0)
-       {
-               *nextUpdate = certinfo->nextUpdate;
-               *revocationTime = certinfo->revocationTime;
-               *revocationReason = certinfo->revocationReason;
-               return certinfo->status;
-       }
-
-       return CERT_UNDEFINED;
-}
-
-/**
- * Verify the ocsp status of a certificate
- */
-cert_status_t verify_by_ocsp(const cert_t *cert, time_t *until,
-                                                        time_t *revocationDate,
-                                                        crl_reason_t *revocationReason)
-{
-       x509_t *x509 = (x509_t*)cert->cert;
-       chunk_t serialNumber = x509->get_serial(x509);
-       cert_status_t status;
-       ocsp_location_t location;
-       time_t nextUpdate = UNDEFINED_TIME;
-
-       *revocationDate = UNDEFINED_TIME;
-       *revocationReason = CRL_REASON_UNSPECIFIED;
-
-       /* is an ocsp location defined? */
-       if (!build_ocsp_location(cert, &location))
-       {
-               return CERT_UNDEFINED;
-       }
-
-       lock_ocsp_cache("verify_by_ocsp");
-       status = get_ocsp_status(&location, serialNumber, &nextUpdate
-               , revocationDate, revocationReason);
-       unlock_ocsp_cache("verify_by_ocsp");
-
-       if (status == CERT_UNDEFINED || nextUpdate < time(NULL))
-       {
-               plog("ocsp status is stale or not in cache");
-               add_ocsp_fetch_request(&location, serialNumber);
-
-               /* inititate fetching of ocsp status */
-               wake_fetch_thread("verify_by_ocsp");
-       }
-       *until = nextUpdate;
-       return status;
-}
-
-/**
- * Check if an ocsp status is about to expire
- */
-void check_ocsp(void)
-{
-       ocsp_location_t *location;
-
-       lock_ocsp_cache("check_ocsp");
-       location = ocsp_cache;
-
-       while (location)
-       {
-               char buf[BUF_LEN];
-               bool first = TRUE;
-               ocsp_certinfo_t *certinfo = location->certinfo;
-
-               while (certinfo)
-               {
-                       if (!certinfo->once)
-                       {
-                               time_t time_left = certinfo->nextUpdate - time(NULL);
-
-                               DBG(DBG_CONTROL,
-                                       if (first)
-                                       {
-                                               DBG_log("issuer: \"%Y\"", location->issuer);
-                                               if (location->authKeyID.ptr)
-                                               {
-                                                       datatot(location->authKeyID.ptr, location->authKeyID.len
-                                                               , ':', buf, BUF_LEN);
-                                                       DBG_log("authkey: %s", buf);
-                                               }
-                                               first = FALSE;
-                                       }
-                                       datatot(certinfo->serialNumber.ptr, certinfo->serialNumber.len
-                                               , ':', buf, BUF_LEN);
-                                       DBG_log("serial: %s, %ld seconds left", buf, time_left)
-                               )
-
-                               if (time_left < 2*crl_check_interval)
-                                       add_ocsp_fetch_request(location, certinfo->serialNumber);
-                       }
-                       certinfo = certinfo->next;
-               }
-               location = location->next;
-       }
-       unlock_ocsp_cache("check_ocsp");
-}
-
-/**
- *  frees the allocated memory of a certinfo struct
- */
-static void free_certinfo(ocsp_certinfo_t *certinfo)
-{
-       free(certinfo->serialNumber.ptr);
-       free(certinfo);
-}
-
-/**
- * frees all certinfos in a chained list
- */
-static void free_certinfos(ocsp_certinfo_t *chain)
-{
-       ocsp_certinfo_t *certinfo;
-
-       while (chain)
-       {
-               certinfo = chain;
-               chain = chain->next;
-               free_certinfo(certinfo);
-       }
-}
-
-/**
- * Frees the memory allocated to an ocsp location including all certinfos
- */
-static void free_ocsp_location(ocsp_location_t* location)
-{
-       DESTROY_IF(location->issuer);
-       free(location->authNameID.ptr);
-       free(location->authKeyID.ptr);
-       free(location->uri);
-       free_certinfos(location->certinfo);
-       free(location);
-}
-
-/*
- * Free a chained list of ocsp locations
- */
-void free_ocsp_locations(ocsp_location_t **chain)
-{
-       while (*chain)
-       {
-               ocsp_location_t *location = *chain;
-               *chain = location->next;
-               free_ocsp_location(location);
-       }
-}
-
-/**
- * Free the ocsp cache
- */
-void free_ocsp_cache(void)
-{
-       lock_ocsp_cache("free_ocsp_cache");
-       free_ocsp_locations(&ocsp_cache);
-       unlock_ocsp_cache("free_ocsp_cache");
-}
-
-/**
- * Frees the ocsp cache and global variables
- */
-void free_ocsp(void)
-{
-       free(ocsp_default_uri.ptr);
-       free_ocsp_cache();
-}
-
-/**
- * List a chained list of ocsp_locations
- */
-void list_ocsp_locations(ocsp_location_t *location, bool requests,
-                                                bool utc, bool strict)
-{
-       bool first = TRUE;
-
-       while (location)
-       {
-               ocsp_certinfo_t *certinfo = location->certinfo;
-
-               if (certinfo)
-               {
-                       if (first)
-                       {
-                               whack_log(RC_COMMENT, " ");
-                               whack_log(RC_COMMENT, "List of OCSP %s:", requests ?
-                                       "Fetch Requests" : "Responses");
-                               first = FALSE;
-                       }
-                       whack_log(RC_COMMENT, " ");
-                       if (location->issuer)
-                       {
-                               whack_log(RC_COMMENT, "  issuer:   \"%Y\"", location->issuer);
-                       }
-                       whack_log(RC_COMMENT, "  uri:      '%s'", location->uri);
-                       if (location->authNameID.ptr)
-                       {
-                               whack_log(RC_COMMENT, "  authname:  %#B", &location->authNameID);
-                       }
-                       if (location->authKeyID.ptr)
-                       {
-                               whack_log(RC_COMMENT, "  authkey:   %#B", &location->authKeyID);
-                       }
-                       while (certinfo)
-                       {
-                               chunk_t serial = chunk_skip_zero(certinfo->serialNumber);
-
-                               if (requests)
-                               {
-                                       whack_log(RC_COMMENT, "  serial:    %#B, %d trials",
-                                                &serial, certinfo->trials);
-                               }
-                               else if (certinfo->once)
-                               {
-                                       whack_log(RC_COMMENT, "  serial:    %#B, %s, once%s",
-                                               &serial, cert_status_names[certinfo->status],
-                                               (certinfo->nextUpdate < time(NULL))? " (expired)": "");
-                               }
-                               else
-                               {
-                                       whack_log(RC_COMMENT, "  serial:    %#B, %s, until %T %s",
-                                               &serial, cert_status_names[certinfo->status],
-                                               &certinfo->nextUpdate, utc,
-                                               check_expiry(certinfo->nextUpdate, OCSP_WARNING_INTERVAL, strict));
-                               }
-                               certinfo = certinfo->next;
-                       }
-               }
-               location = location->next;
-       }
-}
-
-/**
- * List the ocsp cache
- */
-void list_ocsp_cache(bool utc, bool strict)
-{
-       lock_ocsp_cache("list_ocsp_cache");
-       list_ocsp_locations(ocsp_cache, FALSE, utc, strict);
-       unlock_ocsp_cache("list_ocsp_cache");
-}
-
-static bool get_ocsp_requestor_cert(ocsp_location_t *location)
-{
-       cert_t *cert = NULL;
-
-       /* initialize temporary static storage */
-       ocsp_requestor_cert = NULL;
-       ocsp_requestor_sc   = NULL;
-       ocsp_requestor_key  = NULL;
-
-       for (;;)
-       {
-               certificate_t *certificate;
-
-               /* looking for a certificate from the same issuer */
-               cert = get_x509cert(location->issuer, location->authKeyID, cert);
-               if (cert == NULL)
-               {
-                       break;
-               }
-               certificate = cert->cert;
-               DBG(DBG_CONTROL,
-                       DBG_log("candidate: '%Y'", certificate->get_subject(certificate));
-               )
-
-               if (cert->smartcard)
-               {
-                       /* look for a matching private key on a smartcard */
-                       smartcard_t *sc = scx_get(cert);
-
-                       if (sc)
-                       {
-                               DBG(DBG_CONTROL,
-                                       DBG_log("matching smartcard found")
-                               )
-                               if (sc->valid)
-                               {
-                                       ocsp_requestor_cert = cert;
-                                       ocsp_requestor_sc = sc;
-                                       return TRUE;
-                               }
-                               plog("unable to sign ocsp request without PIN");
-                       }
-               }
-               else
-               {
-                       /* look for a matching private key in the chained list */
-                       private_key_t *private = get_x509_private_key(cert);
-
-                       if (private)
-                       {
-                               DBG(DBG_CONTROL,
-                                       DBG_log("matching private key found")
-                               )
-                               ocsp_requestor_cert = cert;
-                               ocsp_requestor_key = private;
-                               return TRUE;
-                       }
-               }
-       }
-       return FALSE;
-}
-
-static chunk_t sc_build_sha1_signature(chunk_t tbs, smartcard_t *sc)
-{
-       hasher_t *hasher;
-       u_char *pos;
-       chunk_t digest;
-       chunk_t digest_info, sigdata;
-       size_t siglen = 0;
-
-       if (!scx_establish_context(sc) || !scx_login(sc))
-       {
-               scx_release_context(sc);
-               return chunk_empty;
-       }
-
-       siglen = scx_get_keylength(sc);
-
-       if (siglen == 0)
-       {
-               plog("failed to get keylength from smartcard");
-               scx_release_context(sc);
-               return chunk_empty;
-       }
-
-       DBG(DBG_CONTROL | DBG_CRYPT,
-               DBG_log("signing hash with RSA key from smartcard (slot: %d, id: %s)"
-                       , (int)sc->slot, sc->id)
-       )
-
-       hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
-       if (hasher == NULL)
-       {
-               return chunk_empty;
-       }
-       hasher->allocate_hash(hasher, tbs, &digest);
-       hasher->destroy(hasher);
-
-       /* according to PKCS#1 v2.1 digest must be packaged into
-        * an ASN.1 structure for encryption
-        */
-       digest_info = asn1_wrap(ASN1_SEQUENCE, "mm"
-               , asn1_algorithmIdentifier(OID_SHA1)
-               , asn1_wrap(ASN1_OCTET_STRING, "m", digest));
-
-       pos = asn1_build_object(&sigdata, ASN1_BIT_STRING, 1 + siglen);
-       *pos++ = 0x00;
-       scx_sign_hash(sc, digest_info.ptr, digest_info.len, pos, siglen);
-       free(digest_info.ptr);
-
-       if (!pkcs11_keep_state)
-       {
-               scx_release_context(sc);
-       }
-       return sigdata;
-}
-
-/**
- * build signature into ocsp request gets built only if a request cert
- * with a corresponding private key is found
- */
-static chunk_t build_signature(chunk_t tbsRequest)
-{
-       chunk_t sigdata, cert, certs = chunk_empty;
-
-       if (ocsp_requestor_sc)
-       {
-               /* RSA signature is done on smartcard */
-               sigdata = sc_build_sha1_signature(tbsRequest, ocsp_requestor_sc);
-       }
-       else
-       {
-               /* RSA signature is done in software */
-               sigdata = x509_build_signature(tbsRequest, OID_SHA1, ocsp_requestor_key,
-                                                                          TRUE);
-       }
-       if (sigdata.ptr == NULL)
-       {
-               return chunk_empty;
-       }
-
-       /* include our certificate */
-       if (ocsp_requestor_cert->cert->get_encoding(ocsp_requestor_cert->cert,
-                                                                                               CERT_ASN1_DER, &cert))
-       {
-               certs = asn1_wrap(ASN1_CONTEXT_C_0, "m",
-                                       asn1_wrap(ASN1_SEQUENCE, "m", cert));
-       }
-       /* build signature comprising algorithm, signature and cert */
-       return asn1_wrap(ASN1_CONTEXT_C_0, "m"
-                               , asn1_wrap(ASN1_SEQUENCE, "mmm"
-                                       , asn1_algorithmIdentifier(OID_SHA1_WITH_RSA)
-                                       , sigdata
-                                       , certs
-                                 )
-                  );
-}
-
-/**
- * Build request (into requestList)
- * no singleRequestExtensions used
- */
-static chunk_t build_request(ocsp_location_t *location, ocsp_certinfo_t *certinfo)
-{
-       chunk_t reqCert = asn1_wrap(ASN1_SEQUENCE, "mmmm"
-                               , asn1_algorithmIdentifier(OID_SHA1)
-                               , asn1_simple_object(ASN1_OCTET_STRING, location->authNameID)
-                               , asn1_simple_object(ASN1_OCTET_STRING, location->authKeyID)
-                               , asn1_simple_object(ASN1_INTEGER, certinfo->serialNumber));
-
-       return asn1_wrap(ASN1_SEQUENCE, "m", reqCert);
-}
-
-/**
- * build requestList (into TBSRequest)
- */
-static chunk_t build_request_list(ocsp_location_t *location)
-{
-       chunk_t requestList;
-       request_list_t *reqs = NULL;
-       ocsp_certinfo_t *certinfo = location->certinfo;
-       u_char *pos;
-
-       size_t datalen = 0;
-
-       /* build content */
-       while (certinfo)
-       {
-               /* build request for every certificate in list
-                * and store them in a chained list
-                */
-               request_list_t *req = malloc_thing(request_list_t);
-
-               req->request = build_request(location, certinfo);
-               req->next = reqs;
-               reqs = req;
-
-               datalen += req->request.len;
-               certinfo = certinfo->next;
-       }
-
-       pos = asn1_build_object(&requestList, ASN1_SEQUENCE, datalen);
-
-       /* copy all in chained list, free list afterwards */
-       while (reqs)
-       {
-               request_list_t *req = reqs;
-
-               mv_chunk(&pos, req->request);
-               reqs = reqs->next;
-               free(req);
-       }
-
-       return requestList;
-}
-
-/**
- * Build requestorName (into TBSRequest)
- */
-static chunk_t build_requestor_name(void)
-{
-       certificate_t *certificate = ocsp_requestor_cert->cert;
-       identification_t *subject = certificate->get_subject(certificate);
-
-       return asn1_wrap(ASN1_CONTEXT_C_1, "m"
-                               , asn1_simple_object(ASN1_CONTEXT_C_4
-                                       , subject->get_encoding(subject)));
-}
-
-/**
- * build nonce extension (into requestExtensions)
- */
-static chunk_t build_nonce_extension(ocsp_location_t *location)
-{
-       rng_t *rng;
-
-       /* generate a random nonce */
-       location->nonce.ptr = malloc(NONCE_LENGTH),
-       location->nonce.len = NONCE_LENGTH;
-       rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
-       rng->get_bytes(rng, location->nonce.len, location->nonce.ptr);
-       rng->destroy(rng);
-
-       return asn1_wrap(ASN1_SEQUENCE, "cm"
-                               , ASN1_nonce_oid
-                               , asn1_simple_object(ASN1_OCTET_STRING, location->nonce));
-}
-
-/**
- * Build requestExtensions (into TBSRequest)
- */
-static chunk_t build_request_ext(ocsp_location_t *location)
-{
-       return asn1_wrap(ASN1_CONTEXT_C_2, "m"
-                               , asn1_wrap(ASN1_SEQUENCE, "mm"
-                                       , build_nonce_extension(location)
-                                       , asn1_wrap(ASN1_SEQUENCE, "cc"
-                                               , ASN1_response_oid
-                                               , ASN1_response_content
-                                         )
-                                 )
-                       );
-}
-
-/**
- * Build TBSRequest (into OCSPRequest)
- */
-static chunk_t build_tbs_request(ocsp_location_t *location, bool has_requestor_cert)
-{
-       /* version is skipped since the default is ok */
-       return asn1_wrap(ASN1_SEQUENCE, "mmm"
-                               , (has_requestor_cert)
-                                               ? build_requestor_name()
-                                               : chunk_empty
-                               , build_request_list(location)
-                               , build_request_ext(location));
-}
-
-/**
- * Assembles an ocsp request to given location
- * and sets nonce field in location to the sent nonce
- */
-chunk_t build_ocsp_request(ocsp_location_t *location)
-{
-       bool has_requestor_cert;
-       chunk_t tbsRequest, signature;
-
-       DBG(DBG_CONTROL,
-               DBG_log("assembling ocsp request");
-               DBG_log("issuer: \"%Y\"", location->issuer);
-               if (location->authKeyID.ptr)
-               {
-                       DBG_log("authkey: %#B", &location->authKeyID);
-               }
-       )
-       lock_certs_and_keys("build_ocsp_request");
-
-       /* looks for requestor cert and matching private key */
-       has_requestor_cert = get_ocsp_requestor_cert(location);
-
-       /* build content */
-       tbsRequest = build_tbs_request(location, has_requestor_cert);
-
-       /* sign tbsReuqest */
-       signature = (has_requestor_cert)? build_signature(tbsRequest)
-                                                                       : chunk_empty;
-
-       unlock_certs_and_keys("build_ocsp_request");
-
-       return asn1_wrap(ASN1_SEQUENCE, "mm"
-                               , tbsRequest
-                               , signature);
-}
-
-/**
- * Check if the OCSP response has a valid signature
- */
-static bool valid_ocsp_response(response_t *res)
-{
-       int pathlen, pathlen_constraint;
-       cert_t *authcert;
-
-       lock_authcert_list("valid_ocsp_response");
-
-       authcert = get_authcert(res->responder_id_name, res->responder_id_key,
-                                                       X509_OCSP_SIGNER | X509_CA);
-       if (authcert == NULL)
-       {
-               plog("no matching ocsp signer cert found");
-               unlock_authcert_list("valid_ocsp_response");
-               return FALSE;
-       }
-       DBG(DBG_CONTROL,
-               DBG_log("ocsp signer cert found")
-       )
-
-       if (!x509_check_signature(res->tbs, res->signature, res->algorithm,
-                                                         authcert->cert))
-       {
-               plog("signature of ocsp response is invalid");
-               unlock_authcert_list("valid_ocsp_response");
-               return FALSE;
-       }
-       DBG(DBG_CONTROL,
-               DBG_log("signature of ocsp response is valid")
-       )
-
-
-       for (pathlen = -1; pathlen <= X509_MAX_PATH_LEN; pathlen++)
-       {
-               cert_t *cert = authcert;
-               certificate_t *certificate = cert->cert;
-               x509_t *x509 = (x509_t*)certificate;
-               identification_t *subject = certificate->get_subject(certificate);
-               identification_t *issuer  = certificate->get_issuer(certificate);
-               chunk_t authKeyID = x509->get_authKeyIdentifier(x509);
-               time_t not_before, not_after;
-
-               DBG(DBG_CONTROL,
-                       DBG_log("subject: '%Y'", subject);
-                       DBG_log("issuer:  '%Y'", issuer);
-                       if (authKeyID.ptr)
-                       {
-                               DBG_log("authkey:  %#B", &authKeyID);
-                       }
-               )
-
-               if (!certificate->get_validity(certificate, NULL, &not_before, &not_after))
-               {
-                       plog("certificate is invalid (valid from %T to %T)",
-                                &not_before, FALSE, &not_after, FALSE);
-
-                       unlock_authcert_list("valid_ocsp_response");
-                       return FALSE;
-               }
-               DBG(DBG_CONTROL,
-                       DBG_log("certificate is valid")
-               )
-
-               authcert = get_authcert(issuer, authKeyID, X509_CA);
-               if (authcert == NULL)
-               {
-                       plog("issuer cacert not found");
-                       unlock_authcert_list("valid_ocsp_response");
-                       return FALSE;
-               }
-               DBG(DBG_CONTROL,
-                       DBG_log("issuer cacert found")
-               )
-
-               if (!certificate->issued_by(certificate, authcert->cert))
-               {
-                       plog("certificate signature is invalid");
-                       unlock_authcert_list("valid_ocsp_response");
-                       return FALSE;
-               }
-               DBG(DBG_CONTROL,
-                       DBG_log("certificate signature is valid")
-               )
-
-               /* check path length constraint */
-               pathlen_constraint = x509->get_constraint(x509, X509_PATH_LEN);
-               if (pathlen_constraint != X509_NO_CONSTRAINT &&
-                       pathlen > pathlen_constraint)
-               {
-                       plog("path length of %d violates constraint of %d",
-                                pathlen, pathlen_constraint);
-                       return FALSE;
-               }
-
-               /* check if cert is self-signed */
-               if (x509->get_flags(x509) & X509_SELF_SIGNED)
-               {
-                       DBG(DBG_CONTROL,
-                               DBG_log("reached self-signed root ca with a path length of %d",
-                                               pathlen)
-                       )
-                       unlock_authcert_list("valid_ocsp_response");
-                       return TRUE;
-               }
-       }
-       plog("maximum path length of %d exceeded", X509_MAX_PATH_LEN);
-       unlock_authcert_list("valid_ocsp_response");
-       return FALSE;
-}
-
-/**
- * Parse a basic OCSP response
- */
-static bool parse_basic_ocsp_response(chunk_t blob, int level0, response_t *res)
-{
-       asn1_parser_t *parser;
-       chunk_t object;
-       u_int version;
-       int objectID;
-       int extn_oid = OID_UNKNOWN;
-       bool success = FALSE;
-       bool critical;
-
-       parser = asn1_parser_create(basicResponseObjects, blob);
-       parser->set_top_level(parser, level0);
-
-       while (parser->iterate(parser, &objectID, &object))
-       {
-               switch (objectID)
-               {
-               case BASIC_RESPONSE_TBS_DATA:
-                       res->tbs = object;
-                       break;
-               case BASIC_RESPONSE_VERSION:
-                       version = (object.len)? (1 + (u_int)*object.ptr) : 1;
-                       if (version != OCSP_BASIC_RESPONSE_VERSION)
-                       {
-                               plog("wrong ocsp basic response version (version= %i)",  version);
-                               goto end;
-                       }
-                       break;
-               case BASIC_RESPONSE_ID_BY_NAME:
-                       res->responder_id_name = identification_create_from_encoding(
-                                                                               ID_DER_ASN1_DN, object);
-                       DBG(DBG_PARSING,
-                               DBG_log("  '%Y'", res->responder_id_name)
-                       )
-                       break;
-               case BASIC_RESPONSE_ID_BY_KEY:
-                       res->responder_id_key = object;
-                       break;
-               case BASIC_RESPONSE_PRODUCED_AT:
-                       res->produced_at = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
-                       break;
-               case BASIC_RESPONSE_RESPONSES:
-                       res->responses = object;
-                       break;
-               case BASIC_RESPONSE_EXT_ID:
-                       extn_oid = asn1_known_oid(object);
-                       break;
-               case BASIC_RESPONSE_CRITICAL:
-                       critical = object.len && *object.ptr;
-                       DBG(DBG_PARSING,
-                               DBG_log("  %s",(critical)?"TRUE":"FALSE");
-                       )
-                       break;
-               case BASIC_RESPONSE_EXT_VALUE:
-                       if (extn_oid == OID_NONCE)
-                               res->nonce = object;
-                       break;
-               case BASIC_RESPONSE_ALGORITHM:
-                       res->algorithm = asn1_parse_algorithmIdentifier(object,
-                                                               parser->get_level(parser)+1, NULL);
-                       break;
-               case BASIC_RESPONSE_SIGNATURE:
-                       res->signature = object;
-                       break;
-               case BASIC_RESPONSE_CERTIFICATE:
-                       {
-                               cert_t *cert = malloc_thing(cert_t);
-                               x509_t *x509;
-
-                               *cert = cert_empty;
-                               cert->cert = lib->creds->create(lib->creds,
-                                                                                 CRED_CERTIFICATE, CERT_X509,
-                                                                                 BUILD_BLOB_ASN1_DER, object,
-                                                                                 BUILD_END);
-                               if (cert->cert == NULL)
-                               {
-                                       DBG(DBG_CONTROL | DBG_PARSING,
-                                               DBG_log("parsing of embedded ocsp certificate failed")
-                                       )
-                                       cert_free(cert);
-                                       break;
-                               }
-                               x509 = (x509_t*)cert->cert;
-
-                               if ((x509->get_flags(x509) & X509_OCSP_SIGNER) &&
-                                       trust_authcert_candidate(cert, NULL))
-                               {
-                                       add_authcert(cert, X509_OCSP_SIGNER);
-                               }
-                               else
-                               {
-                                       DBG(DBG_CONTROL | DBG_PARSING,
-                                               DBG_log("embedded ocsp certificate rejected")
-                                       )
-                                       cert_free(cert);
-                               }
-                       }
-                       break;
-               }
-       }
-       success = parser->success(parser);
-
-end:
-       parser->destroy(parser);
-       return success;
-
-}
-
-
-/**
- * Parse an ocsp response and return the result as a response_t struct
- */
-static response_status parse_ocsp_response(chunk_t blob, response_t * res)
-{
-       asn1_parser_t *parser;
-       chunk_t object;
-       int objectID;
-       int ocspResponseType = OID_UNKNOWN;
-       bool success = FALSE;
-       response_status rStatus = STATUS_INTERNALERROR;
-
-       parser = asn1_parser_create(ocspResponseObjects, blob);
-
-       while (parser->iterate(parser, &objectID, &object))
-       {
-               switch (objectID) {
-               case OCSP_RESPONSE_STATUS:
-                       rStatus = (response_status) *object.ptr;
-
-                       switch (rStatus)
-                       {
-                       case STATUS_SUCCESSFUL:
-                               break;
-                       case STATUS_MALFORMEDREQUEST:
-                       case STATUS_INTERNALERROR:
-                       case STATUS_TRYLATER:
-                       case STATUS_SIGREQUIRED:
-                       case STATUS_UNAUTHORIZED:
-                               plog("ocsp response: server said '%s'"
-                                       , response_status_names[rStatus]);
-                               goto end;
-                       default:
-                               goto end;
-                       }
-                       break;
-               case OCSP_RESPONSE_TYPE:
-                       ocspResponseType = asn1_known_oid(object);
-                       break;
-               case OCSP_RESPONSE:
-                       {
-                               switch (ocspResponseType) {
-                               case OID_BASIC:
-                                       success = parse_basic_ocsp_response(object,
-                                                                       parser->get_level(parser)+1, res);
-                                       break;
-                               default:
-                                       DBG(DBG_CONTROL,
-                                               DBG_log("ocsp response is not of type BASIC");
-                                               DBG_dump_chunk("ocsp response OID: ", object);
-                                       )
-                                       goto end;
-                               }
-                       }
-                       break;
-               }
-       }
-       success &= parser->success(parser);
-
-end:
-       parser->destroy(parser);
-       return rStatus;
-}
-
-/**
- * Parse a basic OCSP response
- */
-static bool parse_ocsp_single_response(chunk_t blob, int level0,
-                                                                          single_response_t *sres)
-{
-       asn1_parser_t *parser;
-       chunk_t object;
-       u_int extn_oid;
-       int objectID;
-       bool critical;
-       bool success = FALSE;
-
-       parser = asn1_parser_create(singleResponseObjects, blob);
-       parser->set_top_level(parser, level0);
-
-       while (parser->iterate(parser, &objectID, &object))
-       {
-               switch (objectID)
-               {
-               case SINGLE_RESPONSE_ALGORITHM:
-                       sres->hash_algorithm = asn1_parse_algorithmIdentifier(object,
-                                                                               parser->get_level(parser)+1, NULL);
-                       break;
-               case SINGLE_RESPONSE_ISSUER_NAME_HASH:
-                       sres->issuer_name_hash = object;
-                       break;
-               case SINGLE_RESPONSE_ISSUER_KEY_HASH:
-                       sres->issuer_key_hash = object;
-                       break;
-               case SINGLE_RESPONSE_SERIAL_NUMBER:
-                       sres->serialNumber = object;
-                       break;
-               case SINGLE_RESPONSE_CERT_STATUS_GOOD:
-                       sres->status = CERT_GOOD;
-                       break;
-               case SINGLE_RESPONSE_CERT_STATUS_REVOKED:
-                       sres->status = CERT_REVOKED;
-                       break;
-               case SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME:
-                       sres->revocationTime = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
-                       break;
-               case SINGLE_RESPONSE_CERT_STATUS_CRL_REASON:
-                       sres->revocationReason = (object.len == 1)
-                               ? *object.ptr : CRL_REASON_UNSPECIFIED;
-                       break;
-               case SINGLE_RESPONSE_CERT_STATUS_UNKNOWN:
-                       sres->status = CERT_UNKNOWN;
-                       break;
-               case SINGLE_RESPONSE_THIS_UPDATE:
-                       sres->thisUpdate = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
-                       break;
-               case SINGLE_RESPONSE_NEXT_UPDATE:
-                       sres->nextUpdate = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
-                       break;
-               case SINGLE_RESPONSE_EXT_ID:
-                       extn_oid = asn1_known_oid(object);
-                       break;
-               case SINGLE_RESPONSE_CRITICAL:
-                       critical = object.len && *object.ptr;
-                       DBG(DBG_PARSING,
-                               DBG_log("  %s",(critical)?"TRUE":"FALSE");
-                       )
-               case SINGLE_RESPONSE_EXT_VALUE:
-                       break;
-               }
-       }
-       success = parser->success(parser);
-       parser->destroy(parser);
-       return success;
-}
-
-/**
- * Add an ocsp location to a chained list
- */
-ocsp_location_t* add_ocsp_location(const ocsp_location_t *loc,
-                                                                  ocsp_location_t **chain)
-{
-       ocsp_location_t *location = malloc_thing(ocsp_location_t);
-
-       /* unshare location fields */
-       location->issuer = loc->issuer->clone(loc->issuer);
-       location->authNameID = chunk_clone(loc->authNameID);
-       location->authKeyID = chunk_clone(loc->authKeyID);
-       location->uri = strdup(loc->uri);
-       location->certinfo = NULL;
-
-       /* insert new ocsp location in front of chain */
-       location->next = *chain;
-       *chain = location;
-
-       DBG(DBG_CONTROL,
-               DBG_log("new ocsp location added")
-       )
-
-       return location;
-}
-
-/**
- * add a certinfo struct to a chained list
- */
-void add_certinfo(ocsp_location_t *loc, ocsp_certinfo_t *info,
-                                 ocsp_location_t **chain, bool request)
-{
-       ocsp_location_t *location;
-       ocsp_certinfo_t *certinfo, **certinfop;
-       char buf[BUF_LEN];
-       time_t now;
-       int cmp = -1;
-
-       location = get_ocsp_location(loc, *chain);
-       if (location == NULL)
-       {
-               location = add_ocsp_location(loc, chain);
-       }
-
-       /* traverse list of certinfos in increasing order */
-       certinfop = &location->certinfo;
-       certinfo = *certinfop;
-
-       while (certinfo)
-       {
-               cmp = chunk_compare(info->serialNumber, certinfo->serialNumber);
-               if (cmp <= 0)
-                       break;
-               certinfop = &certinfo->next;
-               certinfo = *certinfop;
-       }
-
-       if (cmp != 0)
-       {
-               /* add a new certinfo entry */
-               ocsp_certinfo_t *cnew = malloc_thing(ocsp_certinfo_t);
-
-               cnew->serialNumber = chunk_clone(info->serialNumber);
-               cnew->next = certinfo;
-               cnew->trials = 0;
-               *certinfop = cnew;
-               certinfo = cnew;
-       }
-
-       DBG(DBG_CONTROL,
-               datatot(info->serialNumber.ptr, info->serialNumber.len, ':'
-                       , buf, BUF_LEN);
-               DBG_log("ocsp %s for serial %s %s"
-                       , request?"fetch request":"certinfo"
-                       , buf
-                       , (cmp == 0)? (request?"already exists":"updated"):"added")
-       )
-
-       time(&now);
-
-       if (request)
-       {
-               certinfo->status = CERT_UNDEFINED;
-
-               if (cmp != 0)
-               {
-                       certinfo->thisUpdate = now;
-               }
-               certinfo->nextUpdate = UNDEFINED_TIME;
-       }
-       else
-       {
-               certinfo->status = info->status;
-               certinfo->revocationTime = info->revocationTime;
-               certinfo->revocationReason = info->revocationReason;
-
-               certinfo->thisUpdate = (info->thisUpdate != UNDEFINED_TIME)?
-                       info->thisUpdate : now;
-
-               certinfo->once = (info->nextUpdate == UNDEFINED_TIME);
-
-               certinfo->nextUpdate = (certinfo->once)?
-                       (now + OCSP_DEFAULT_VALID_TIME) : info->nextUpdate;
-       }
-}
-
-/**
- * Process received ocsp single response and add it to ocsp cache
- */
-static void process_single_response(ocsp_location_t *location,
-                                                                       single_response_t *sres)
-{
-       ocsp_certinfo_t *certinfo, **certinfop;
-       int cmp = -1;
-
-       if (sres->hash_algorithm != OID_SHA1)
-       {
-               plog("only SHA-1 hash supported in OCSP single response");
-               return;
-       }
-       if (!(chunk_equals(sres->issuer_name_hash, location->authNameID)
-       &&   chunk_equals(sres->issuer_key_hash, location->authKeyID)))
-       {
-               plog("ocsp single response has wrong issuer");
-               return;
-       }
-
-       /* traverse list of certinfos in increasing order */
-       certinfop = &location->certinfo;
-       certinfo = *certinfop;
-
-       while (certinfo)
-       {
-               cmp = chunk_compare(sres->serialNumber, certinfo->serialNumber);
-               if (cmp <= 0)
-                       break;
-               certinfop = &certinfo->next;
-               certinfo = *certinfop;
-       }
-
-       if (cmp != 0)
-       {
-               plog("received unrequested cert status from ocsp server");
-               return;
-       }
-
-       /* unlink cert from ocsp fetch request list */
-       *certinfop = certinfo->next;
-
-       /* update certinfo using the single response information */
-       certinfo->thisUpdate = sres->thisUpdate;
-       certinfo->nextUpdate = sres->nextUpdate;
-       certinfo->status = sres->status;
-       certinfo->revocationTime = sres->revocationTime;
-       certinfo->revocationReason = sres->revocationReason;
-
-       /* add or update certinfo in ocsp cache */
-       lock_ocsp_cache("process_single_response");
-       add_certinfo(location, certinfo, &ocsp_cache, FALSE);
-       unlock_ocsp_cache("process_single_response");
-
-       /* free certinfo unlinked from ocsp fetch request list */
-       free_certinfo(certinfo);
-}
-
-/**
- *  Destroy a response_t object
- */
-static void free_response(response_t *res)
-{
-       DESTROY_IF(res->responder_id_name);
-}
-
-/**
- *  Parse and verify ocsp response and update the ocsp cache
- */
-void parse_ocsp(ocsp_location_t *location, chunk_t blob)
-{
-       response_t res = empty_response;
-
-       /* parse the ocsp response without looking at the single responses yet */
-       response_status status = parse_ocsp_response(blob, &res);
-
-       if (status != STATUS_SUCCESSFUL)
-       {
-               plog("error in ocsp response");
-               goto free;
-       }
-       /* check if there was a nonce in the request */
-       if (location->nonce.ptr && res.nonce.ptr == NULL)
-       {
-               plog("ocsp response contains no nonce, replay attack possible");
-       }
-       /* check if the nonce is identical */
-       if (res.nonce.ptr && !chunk_equals(res.nonce, location->nonce))
-       {
-               plog("invalid nonce in ocsp response");
-               goto free;
-       }
-       /* check if the response is signed by a trusted key */
-       if (!valid_ocsp_response(&res))
-       {
-               plog("invalid ocsp response");
-               goto free;
-       }
-       DBG(DBG_CONTROL,
-               DBG_log("valid ocsp response")
-       )
-
-       /* now parse the single responses one at a time */
-       {
-               asn1_parser_t *parser;
-               chunk_t object;
-               int objectID;
-
-               parser = asn1_parser_create(responsesObjects, res.responses);
-
-               while (parser->iterate(parser, &objectID, &object))
-               {
-                       if (objectID == RESPONSES_SINGLE_RESPONSE)
-                       {
-                               single_response_t sres = empty_single_response;
-
-                               if (!parse_ocsp_single_response(object,
-                                                                               parser->get_level(parser)+1, &sres))
-                               {
-                                       goto end;
-                               }
-                               process_single_response(location, &sres);
-                       }
-               }
-end:
-               parser->destroy(parser);
-       }
-
-free:
-       free_response(&res);
-}
diff --git a/src/pluto/ocsp.h b/src/pluto/ocsp.h
deleted file mode 100644 (file)
index 977cca3..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/* Support of the Online Certificate Status Protocol (OCSP) Support
- * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
- * Zuercher Hochschule Winterthur
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include "constants.h"
-
-#include <credentials/certificates/crl.h>
-
-/* constants */
-
-#define OCSP_BASIC_RESPONSE_VERSION     1
-#define OCSP_DEFAULT_VALID_TIME         120  /* validity of one-time response in seconds */
-#define OCSP_WARNING_INTERVAL           2    /* days */
-
-/* OCSP response status */
-
-typedef enum {
-       STATUS_SUCCESSFUL =         0,
-       STATUS_MALFORMEDREQUEST =   1,
-       STATUS_INTERNALERROR =      2,
-       STATUS_TRYLATER =           3,
-       STATUS_SIGREQUIRED =        5,
-       STATUS_UNAUTHORIZED=        6
-} response_status;
-
-/* OCSP access structures */
-
-typedef struct ocsp_certinfo ocsp_certinfo_t;
-
-struct ocsp_certinfo {
-       ocsp_certinfo_t  *next;
-       int              trials;
-       chunk_t          serialNumber;
-       cert_status_t    status;
-       bool             once;
-       crl_reason_t     revocationReason;
-       time_t           revocationTime;
-       time_t           thisUpdate;
-       time_t           nextUpdate;
-};
-
-typedef struct ocsp_location ocsp_location_t;
-
-struct ocsp_location {
-       ocsp_location_t  *next;
-       identification_t *issuer;
-       chunk_t           authNameID;
-       chunk_t           authKeyID;
-       chunk_t           nonce;
-       char             *uri;
-       ocsp_certinfo_t  *certinfo;
-};
-
-extern ocsp_location_t* get_ocsp_location(const ocsp_location_t *loc
-       , ocsp_location_t *chain);
-extern ocsp_location_t* add_ocsp_location(const ocsp_location_t *loc
-       , ocsp_location_t **chain);
-extern void add_certinfo(ocsp_location_t *loc, ocsp_certinfo_t *info
-       , ocsp_location_t **chain, bool request);
-extern void check_ocsp(void);
-extern cert_status_t verify_by_ocsp(const cert_t *cert, time_t *until
-       , time_t *revocationTime, crl_reason_t *revocationReason);
-extern bool ocsp_set_request_cert(char* path);
-extern void ocsp_set_default_uri(char* uri);
-extern void ocsp_cache_add_cert(const cert_t* cert);
-extern chunk_t build_ocsp_request(ocsp_location_t* location);
-extern void parse_ocsp(ocsp_location_t* location, chunk_t blob);
-extern void list_ocsp_locations(ocsp_location_t *location, bool requests
-       , bool utc, bool strict);
-extern void list_ocsp_cache(bool utc, bool strict);
-extern void free_ocsp_locations(ocsp_location_t **chain);
-extern void free_ocsp_cache(void);
-extern void free_ocsp(void);
-extern void ocsp_purge_cache(void);
diff --git a/src/pluto/packet.c b/src/pluto/packet.c
deleted file mode 100644 (file)
index 35fc4af..0000000
+++ /dev/null
@@ -1,1242 +0,0 @@
-/* parsing packets: formats and tools
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2001  D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <netinet/in.h>
-#include <string.h>
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "packet.h"
-#include "whack.h"      /* for RC_LOG_SERIOUS */
-
-/* ISAKMP Header: for all messages
- * layout from RFC 2408 "ISAKMP" section 3.1
- *                      1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !                          Initiator                            !
- * !                            Cookie                             !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !                          Responder                            !
- * !                            Cookie                             !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !  Next Payload ! MjVer ! MnVer ! Exchange Type !     Flags     !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !                          Message ID                           !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !                            Length                             !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-
-static field_desc isa_fields[] = {
-       { ft_raw, COOKIE_SIZE, "initiator cookie", NULL },
-       { ft_raw, COOKIE_SIZE, "responder cookie", NULL },
-       { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
-       { ft_enum, 8/BITS_PER_BYTE, "ISAKMP version", &version_names },
-       { ft_enum, 8/BITS_PER_BYTE, "exchange type", &exchange_names },
-       { ft_set, 8/BITS_PER_BYTE, "flags", flag_bit_names },
-       { ft_raw, 32/BITS_PER_BYTE, "message ID", NULL },
-       { ft_len, 32/BITS_PER_BYTE, "length", NULL },
-       { ft_end, 0, NULL, NULL }
-};
-
-struct_desc isakmp_hdr_desc = { "ISAKMP Message", isa_fields, sizeof(struct isakmp_hdr) };
-
-/* Generic portion of all ISAKMP payloads.
- * layout from RFC 2408 "ISAKMP" section 3.2
- * This describes the first 32-bit chunk of all payloads.
- * The previous next payload depends on the actual payload type.
- *                      1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload  !   RESERVED    !         Payload Length        !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-
-static field_desc isag_fields[] = {
-       { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
-       { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
-       { ft_len, 16/BITS_PER_BYTE, "length", NULL },
-       { ft_end, 0, NULL, NULL }
-};
-
-struct_desc isakmp_generic_desc = { "ISAKMP Generic Payload", isag_fields, sizeof(struct isakmp_generic) };
-
-
-/* ISAKMP Data Attribute (generic representation within payloads)
- * layout from RFC 2408 "ISAKMP" section 3.3
- * This is not a payload type.
- * In TLV format, this is followed by a value field.
- *                      1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !A!       Attribute Type        !    AF=0  Attribute Length     !
- * !F!                             !    AF=1  Attribute Value      !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * .                   AF=0  Attribute Value                       .
- * .                   AF=1  Not Transmitted                       .
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-
-/* Oakley Attributes */
-static field_desc isaat_fields_oakley[] = {
-       { ft_af_enum, 16/BITS_PER_BYTE, "af+type", &oakley_attr_names },
-       { ft_lv, 16/BITS_PER_BYTE, "length/value", NULL },
-       { ft_end, 0, NULL, NULL }
-};
-
-struct_desc isakmp_oakley_attribute_desc = {
-       "ISAKMP Oakley attribute",
-       isaat_fields_oakley, sizeof(struct isakmp_attribute) };
-
-/* IPsec DOI Attributes */
-static field_desc isaat_fields_ipsec[] = {
-       { ft_af_enum, 16/BITS_PER_BYTE, "af+type", &ipsec_attr_names },
-       { ft_lv, 16/BITS_PER_BYTE, "length/value", NULL },
-       { ft_end, 0, NULL, NULL }
-};
-
-struct_desc isakmp_ipsec_attribute_desc = {
-       "ISAKMP IPsec DOI attribute",
-       isaat_fields_ipsec, sizeof(struct isakmp_attribute) };
-
-/* Mode Config Attributes */
-static field_desc isaat_fields_modecfg[] = {
-       { ft_af_loose_enum, 16/BITS_PER_BYTE, "ModeCfg attr type", &modecfg_attr_names },
-       { ft_lv, 16/BITS_PER_BYTE, "length/value", NULL },
-       { ft_end, 0, NULL, NULL }
-};
-
-struct_desc isakmp_modecfg_attribute_desc = {
-       "ISAKMP ModeCfg attribute",
-       isaat_fields_modecfg, sizeof(struct isakmp_attribute) };
-
-/* ISAKMP Security Association Payload
- * layout from RFC 2408 "ISAKMP" section 3.4
- * A variable length Situation follows.
- * Previous next payload: ISAKMP_NEXT_SA
- *                      1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload  !   RESERVED    !         Payload Length        !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !              Domain of Interpretation  (DOI)                  !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !                                                               !
- * ~                           Situation                           ~
- * !                                                               !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-static field_desc isasa_fields[] = {
-       { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
-       { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
-       { ft_len, 16/BITS_PER_BYTE, "length", NULL },
-       { ft_enum, 32/BITS_PER_BYTE, "DOI", &doi_names },
-       { ft_end, 0, NULL, NULL }
-};
-
-struct_desc isakmp_sa_desc = { "ISAKMP Security Association Payload", isasa_fields, sizeof(struct isakmp_sa) };
-
-static field_desc ipsec_sit_field[] = {
-       { ft_set, 32/BITS_PER_BYTE, "IPsec DOI SIT", &sit_bit_names },
-       { ft_end, 0, NULL, NULL }
-};
-
-struct_desc ipsec_sit_desc = { "IPsec DOI SIT", ipsec_sit_field, sizeof(u_int32_t) };
-
-/* ISAKMP Proposal Payload
- * layout from RFC 2408 "ISAKMP" section 3.5
- * A variable length SPI follows.
- * Previous next payload: ISAKMP_NEXT_P
- *                      1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload  !   RESERVED    !         Payload Length        !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !  Proposal #   !  Protocol-Id  !    SPI Size   !# of Transforms!
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !                        SPI (variable)                         !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-static field_desc isap_fields[] = {
-       { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
-       { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
-       { ft_len, 16/BITS_PER_BYTE, "length", NULL },
-       { ft_nat, 8/BITS_PER_BYTE, "proposal number", NULL },
-       { ft_enum, 8/BITS_PER_BYTE, "protocol ID", &protocol_names },
-       { ft_nat, 8/BITS_PER_BYTE, "SPI size", NULL },
-       { ft_nat, 8/BITS_PER_BYTE, "number of transforms", NULL },
-       { ft_end, 0, NULL, NULL }
-};
-
-struct_desc isakmp_proposal_desc = { "ISAKMP Proposal Payload", isap_fields, sizeof(struct isakmp_proposal) };
-
-/* ISAKMP Transform Payload
- * layout from RFC 2408 "ISAKMP" section 3.6
- * Variable length SA Attributes follow.
- * Previous next payload: ISAKMP_NEXT_T
- *                      1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload  !   RESERVED    !         Payload Length        !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !  Transform #  !  Transform-Id !           RESERVED2           !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !                                                               !
- * ~                        SA Attributes                          ~
- * !                                                               !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-
-/* PROTO_ISAKMP */
-static field_desc isat_fields_isakmp[] = {
-       { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
-       { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
-       { ft_len, 16/BITS_PER_BYTE, "length", NULL },
-       { ft_nat, 8/BITS_PER_BYTE, "transform number", NULL },
-       { ft_enum, 8/BITS_PER_BYTE, "transform ID", &isakmp_transformid_names },
-       { ft_mbz, 16/BITS_PER_BYTE, NULL, NULL },
-       { ft_end, 0, NULL, NULL }
-};
-
-struct_desc isakmp_isakmp_transform_desc = {
-       "ISAKMP Transform Payload (ISAKMP)",
-       isat_fields_isakmp, sizeof(struct isakmp_transform) };
-
-/* PROTO_IPSEC_AH */
-static field_desc isat_fields_ah[] = {
-       { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
-       { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
-       { ft_len, 16/BITS_PER_BYTE, "length", NULL },
-       { ft_nat, 8/BITS_PER_BYTE, "transform number", NULL },
-       { ft_enum, 8/BITS_PER_BYTE, "transform ID", &ah_transform_names },
-       { ft_mbz, 16/BITS_PER_BYTE, NULL, NULL },
-       { ft_end, 0, NULL, NULL }
-};
-
-struct_desc isakmp_ah_transform_desc = {
-       "ISAKMP Transform Payload (AH)",
-       isat_fields_ah, sizeof(struct isakmp_transform) };
-
-/* PROTO_IPSEC_ESP */
-static field_desc isat_fields_esp[] = {
-       { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
-       { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
-       { ft_len, 16/BITS_PER_BYTE, "length", NULL },
-       { ft_nat, 8/BITS_PER_BYTE, "transform number", NULL },
-       { ft_enum, 8/BITS_PER_BYTE, "transform ID", &esp_transform_names },
-       { ft_mbz, 16/BITS_PER_BYTE, NULL, NULL },
-       { ft_end, 0, NULL, NULL }
-};
-
-struct_desc isakmp_esp_transform_desc = {
-       "ISAKMP Transform Payload (ESP)",
-       isat_fields_esp, sizeof(struct isakmp_transform) };
-
-/* PROTO_IPCOMP */
-static field_desc isat_fields_ipcomp[] = {
-       { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
-       { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
-       { ft_len, 16/BITS_PER_BYTE, "length", NULL },
-       { ft_nat, 8/BITS_PER_BYTE, "transform number", NULL },
-       { ft_enum, 8/BITS_PER_BYTE, "transform ID", &ipcomp_transformid_names },
-       { ft_mbz, 16/BITS_PER_BYTE, NULL, NULL },
-       { ft_end, 0, NULL, NULL }
-};
-
-struct_desc isakmp_ipcomp_transform_desc = {
-       "ISAKMP Transform Payload (COMP)",
-       isat_fields_ipcomp, sizeof(struct isakmp_transform) };
-
-
-/* ISAKMP Key Exchange Payload: no fixed fields beyond the generic ones.
- * layout from RFC 2408 "ISAKMP" section 3.7
- * Variable Key Exchange Data follow the generic fields.
- * Previous next payload: ISAKMP_NEXT_KE
- *                      1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload  !   RESERVED    !         Payload Length        !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !                                                               !
- * ~                       Key Exchange Data                       ~
- * !                                                               !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-struct_desc isakmp_keyex_desc = { "ISAKMP Key Exchange Payload", isag_fields, sizeof(struct isakmp_generic) };
-
-/* ISAKMP Identification Payload
- * layout from RFC 2408 "ISAKMP" section 3.8
- * See "struct identity" declared later.
- * Variable length Identification Data follow.
- * Previous next payload: ISAKMP_NEXT_ID
- *                      1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload  !   RESERVED    !         Payload Length        !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !   ID Type     !             DOI Specific ID Data              !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !                                                               !
- * ~                   Identification Data                         ~
- * !                                                               !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-static field_desc isaid_fields[] = {
-       { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
-       { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
-       { ft_len, 16/BITS_PER_BYTE, "length", NULL },
-       { ft_enum, 8/BITS_PER_BYTE, "ID type", &ident_names },      /* ??? depends on DOI? */
-       { ft_nat, 8/BITS_PER_BYTE, "DOI specific A", NULL },        /* ??? depends on DOI? */
-       { ft_nat, 16/BITS_PER_BYTE, "DOI specific B", NULL },       /* ??? depends on DOI? */
-       { ft_end, 0, NULL, NULL }
-};
-
-struct_desc isakmp_identification_desc = { "ISAKMP Identification Payload", isaid_fields, sizeof(struct isakmp_id) };
-
-/* IPSEC Identification Payload Content
- * layout from RFC 2407 "IPsec DOI" section 4.6.2
- * See struct isakmp_id declared earlier.
- * Note: Hashing skips the ISAKMP generic payload header
- * Variable length Identification Data follow.
- *                      1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !  Next Payload !   RESERVED    !        Payload Length         !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !   ID Type     !  Protocol ID  !             Port              !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ~                     Identification Data                       ~
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-static field_desc isaiid_fields[] = {
-       { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
-       { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
-       { ft_len, 16/BITS_PER_BYTE, "length", NULL },
-       { ft_enum, 8/BITS_PER_BYTE, "ID type", &ident_names },
-       { ft_nat, 8/BITS_PER_BYTE, "Protocol ID", NULL },   /* ??? UDP/TCP or 0? */
-       { ft_nat, 16/BITS_PER_BYTE, "port", NULL },
-       { ft_end, 0, NULL, NULL }
-};
-
-struct_desc isakmp_ipsec_identification_desc = { "ISAKMP Identification Payload (IPsec DOI)", isaiid_fields, sizeof(struct isakmp_ipsec_id) };
-
-/* ISAKMP Certificate Payload: oddball fixed field beyond the generic ones.
- * layout from RFC 2408 "ISAKMP" section 3.9
- * Variable length Certificate Data follow the generic fields.
- * Previous next payload: ISAKMP_NEXT_CERT.
- *                      1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload  !   RESERVED    !         Payload Length        !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Cert Encoding !                                               !
- * +-+-+-+-+-+-+-+-+                                               !
- * ~                       Certificate Data                        ~
- * !                                                               !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-static field_desc isacert_fields[] = {
-       { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
-       { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
-       { ft_len, 16/BITS_PER_BYTE, "length", NULL },
-       { ft_enum, 8/BITS_PER_BYTE, "cert encoding", &cert_type_names },
-       { ft_end, 0, NULL, NULL }
-};
-
-/* Note: the size field of isakmp_ipsec_certificate_desc cannot be
- * sizeof(struct isakmp_cert) because that will rounded up for padding.
- */
- struct_desc isakmp_ipsec_certificate_desc = { "ISAKMP Certificate Payload", isacert_fields, ISAKMP_CERT_SIZE };
-
-/* ISAKMP Certificate Request Payload: oddball field beyond the generic ones.
- * layout from RFC 2408 "ISAKMP" section 3.10
- * Variable length Certificate Types and Certificate Authorities follow.
- * Previous next payload: ISAKMP_NEXT_CR.
- *                      1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload  !   RESERVED    !         Payload Length        !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !  Cert. Type   !                                               !
- * +-+-+-+-+-+-+-+-+                                               !
- * ~                    Certificate Authority                      ~
- * !                                                               !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-static field_desc isacr_fields[] = {
-       { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
-       { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
-       { ft_len, 16/BITS_PER_BYTE, "length", NULL },
-       { ft_enum, 8/BITS_PER_BYTE, "cert type", &cert_type_names },
-       { ft_end, 0, NULL, NULL }
-};
-
-/* Note: the size field of isakmp_ipsec_cert_req_desc cannot be
- * sizeof(struct isakmp_cr) because that will rounded up for padding.
- */
-struct_desc isakmp_ipsec_cert_req_desc = { "ISAKMP Certificate RequestPayload", isacr_fields, ISAKMP_CR_SIZE };
-
-/* ISAKMP Hash Payload: no fixed fields beyond the generic ones.
- * layout from RFC 2408 "ISAKMP" section 3.11
- * Variable length Hash Data follow.
- * Previous next payload: ISAKMP_NEXT_HASH.
- *                      1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload  !   RESERVED    !         Payload Length        !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !                                                               !
- * ~                           Hash Data                           ~
- * !                                                               !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-struct_desc isakmp_hash_desc = { "ISAKMP Hash Payload", isag_fields, sizeof(struct isakmp_generic) };
-
-/* ISAKMP Signature Payload: no fixed fields beyond the generic ones.
- * layout from RFC 2408 "ISAKMP" section 3.12
- * Variable length Signature Data follow.
- * Previous next payload: ISAKMP_NEXT_SIG.
- *                      1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload  !   RESERVED    !         Payload Length        !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !                                                               !
- * ~                         Signature Data                        ~
- * !                                                               !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-struct_desc isakmp_signature_desc = { "ISAKMP Signature Payload", isag_fields, sizeof(struct isakmp_generic) };
-
-/* ISAKMP Nonce Payload: no fixed fields beyond the generic ones.
- * layout from RFC 2408 "ISAKMP" section 3.13
- * Variable length Nonce Data follow.
- * Previous next payload: ISAKMP_NEXT_NONCE.
- *                      1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload  !   RESERVED    !         Payload Length        !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !                                                               !
- * ~                            Nonce Data                         ~
- * !                                                               !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-struct_desc isakmp_nonce_desc = { "ISAKMP Nonce Payload", isag_fields, sizeof(struct isakmp_generic) };
-
-/* ISAKMP Notification Payload
- * layout from RFC 2408 "ISAKMP" section 3.14
- * This is followed by a variable length SPI
- * and then possibly by variable length Notification Data.
- * Previous next payload: ISAKMP_NEXT_N
- *                      1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload  !   RESERVED    !         Payload Length        !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !              Domain of Interpretation  (DOI)                  !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !  Protocol-ID  !   SPI Size    !      Notify Message Type      !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !                                                               !
- * ~                Security Parameter Index (SPI)                 ~
- * !                                                               !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !                                                               !
- * ~                       Notification Data                       ~
- * !                                                               !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-static field_desc isan_fields[] = {
-       { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
-       { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
-       { ft_len, 16/BITS_PER_BYTE, "length", NULL },
-       { ft_enum, 32/BITS_PER_BYTE, "DOI", &doi_names },
-       { ft_nat, 8/BITS_PER_BYTE, "protocol ID", NULL },   /* ??? really enum: ISAKMP, IPSEC, ESP, ... */
-       { ft_nat, 8/BITS_PER_BYTE, "SPI size", NULL },
-       { ft_enum, 16/BITS_PER_BYTE, "Notify Message Type", &notification_names },
-       { ft_end, 0, NULL, NULL }
-};
-
-struct_desc isakmp_notification_desc = { "ISAKMP Notification Payload", isan_fields, sizeof(struct isakmp_notification) };
-
-/* ISAKMP Delete Payload
- * layout from RFC 2408 "ISAKMP" section 3.15
- * This is followed by a variable length SPI.
- * Previous next payload: ISAKMP_NEXT_D
- *                      1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload  !   RESERVED    !         Payload Length        !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !              Domain of Interpretation  (DOI)                  !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !  Protocol-Id  !   SPI Size    !           # of SPIs           !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !                                                               !
- * ~               Security Parameter Index(es) (SPI)              ~
- * !                                                               !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-static field_desc isad_fields[] = {
-       { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
-       { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
-       { ft_len, 16/BITS_PER_BYTE, "length", NULL },
-       { ft_enum, 32/BITS_PER_BYTE, "DOI", &doi_names },
-       { ft_nat, 8/BITS_PER_BYTE, "protocol ID", NULL },   /* ??? really enum: ISAKMP, IPSEC */
-       { ft_nat, 8/BITS_PER_BYTE, "SPI size", NULL },
-       { ft_nat, 16/BITS_PER_BYTE, "number of SPIs", NULL },
-       { ft_end, 0, NULL, NULL }
-};
-
-struct_desc isakmp_delete_desc = { "ISAKMP Delete Payload", isad_fields, sizeof(struct isakmp_delete) };
-
-/* ISAKMP Vendor ID Payload
- * layout from RFC 2408 "ISAKMP" section 3.15
- * This is followed by a variable length VID.
- * Previous next payload: ISAKMP_NEXT_VID
- *                      1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload  !   RESERVED    !         Payload Length        !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !                                                               !
- * ~                        Vendor ID (VID)                        ~
- * !                                                               !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-struct_desc isakmp_vendor_id_desc = { "ISAKMP Vendor ID Payload", isag_fields, sizeof(struct isakmp_generic) };
-
-/* MODECFG */
-/*
- * From draft-dukes-ike-mode-cfg
-3.2. Attribute Payload
-                                                  1                   2                   3
-          0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-        ! Next Payload  !   RESERVED    !         Payload Length        !
-        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-        !     Type      !   RESERVED    !           Identifier          !
-        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-        !                                                               !
-        ~                           Attributes                          ~
-        !                                                               !
-        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-*/
-static field_desc isaattr_fields[] = {
-       { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
-       { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
-       { ft_len, 16/BITS_PER_BYTE, "length", NULL },
-       { ft_enum, 8/BITS_PER_BYTE, "Attr Msg Type", &attr_msg_type_names },
-       { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
-       { ft_nat, 16/BITS_PER_BYTE, "Identifier", NULL },
-       { ft_end, 0, NULL, NULL }
-};
-
-struct_desc isakmp_attr_desc = { "ISAKMP Mode Attribute", isaattr_fields, sizeof(struct isakmp_mode_attr) };
-
-/* ISAKMP NAT-Traversal NAT-D
- * layout from draft-ietf-ipsec-nat-t-ike-01.txt section 3.2
- *
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload  !   RESERVED    !         Payload Length        !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !                 HASH of the address and port                  !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-struct_desc isakmp_nat_d = { "ISAKMP NAT-D Payload", isag_fields, sizeof(struct isakmp_generic) };
-
-/* ISAKMP NAT-Traversal NAT-OA
- * layout from draft-ietf-ipsec-nat-t-ike-01.txt section 4.2
- *
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload  !   RESERVED    !         Payload Length        !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !   ID Type     !   RESERVED    !            RESERVED           !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !         IPv4 (4 octets) or IPv6 address (16 octets)           !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-static field_desc isanat_oa_fields[] = {
-       { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
-       { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
-       { ft_len, 16/BITS_PER_BYTE, "length", NULL },
-       { ft_enum, 8/BITS_PER_BYTE, "ID type", &ident_names },
-       { ft_mbz, 24/BITS_PER_BYTE, NULL, NULL },
-       { ft_end, 0, NULL, NULL }
-};
-
-struct_desc isakmp_nat_oa = { "ISAKMP NAT-OA Payload", isanat_oa_fields, sizeof(struct isakmp_nat_oa) };
-
-/* descriptor for each payload type
- *
- * There is a slight problem in that some payloads differ, depending
- * on the mode.  Since this is table only used for top-level payloads,
- * Proposal and Transform payloads need not be handled.
- * That leaves only Identification payloads as a problem.
- * We make all these entries NULL
- */
-struct_desc *const payload_descs[ISAKMP_NEXT_ROOF] = {
-       NULL,                               /* 0 ISAKMP_NEXT_NONE (No other payload following) */
-       &isakmp_sa_desc,                    /* 1 ISAKMP_NEXT_SA (Security Association) */
-       NULL,                               /* 2 ISAKMP_NEXT_P (Proposal) */
-       NULL,                               /* 3 ISAKMP_NEXT_T (Transform) */
-       &isakmp_keyex_desc,                 /* 4 ISAKMP_NEXT_KE (Key Exchange) */
-       NULL,                               /* 5 ISAKMP_NEXT_ID (Identification) */
-       &isakmp_ipsec_certificate_desc,     /* 6 ISAKMP_NEXT_CERT (Certificate) */
-       &isakmp_ipsec_cert_req_desc,        /* 7 ISAKMP_NEXT_CR (Certificate Request) */
-       &isakmp_hash_desc,                  /* 8 ISAKMP_NEXT_HASH (Hash) */
-       &isakmp_signature_desc,             /* 9 ISAKMP_NEXT_SIG (Signature) */
-       &isakmp_nonce_desc,                 /* 10 ISAKMP_NEXT_NONCE (Nonce) */
-       &isakmp_notification_desc,          /* 11 ISAKMP_NEXT_N (Notification) */
-       &isakmp_delete_desc,                /* 12 ISAKMP_NEXT_D (Delete) */
-       &isakmp_vendor_id_desc,             /* 13 ISAKMP_NEXT_VID (Vendor ID) */
-       &isakmp_attr_desc,                  /* 14 ISAKMP_NEXT_ATTR (Mode Config) */
-       NULL,                               /* 15 */
-       NULL,                               /* 16 */
-       NULL,                               /* 17 */
-       NULL,                               /* 18 */
-       NULL,                               /* 19 */
-       &isakmp_nat_d,                      /* 20=130 ISAKMP_NEXT_NATD (NAT-D) */
-       &isakmp_nat_oa,                     /* 20=131 ISAKMP_NEXT_NATOA (NAT-OA) */
-};
-
-void
-init_pbs(pb_stream *pbs, u_int8_t *start, size_t len, const char *name)
-{
-       pbs->container = NULL;
-       pbs->desc = NULL;
-       pbs->name = name;
-       pbs->start = pbs->cur = start;
-       pbs->roof = start + len;
-       pbs->lenfld = NULL;
-       pbs->lenfld_desc = NULL;
-}
-
-#ifdef DEBUG
-
-/* print a host struct
- *
- * This code assumes that the network and host structure
- * members have the same alignment and size!  This requires
- * that all padding be explicit.
- */
-void
-DBG_print_struct(const char *label, const void *struct_ptr
-, struct_desc *sd, bool len_meaningful)
-{
-       bool immediate = FALSE;
-       const u_int8_t *inp = struct_ptr;
-       field_desc *fp;
-
-       DBG_log("%s%s:", label, sd->name);
-
-       for (fp = sd->fields; fp->field_type != ft_end; fp++)
-       {
-               int i = fp->size;
-               u_int32_t n = 0;
-
-               switch (fp->field_type)
-               {
-               case ft_mbz:    /* must be zero */
-                       inp += i;
-                       break;
-               case ft_nat:            /* natural number (may be 0) */
-               case ft_len:            /* length of this struct and any following crud */
-               case ft_lv:             /* length/value field of attribute */
-               case ft_enum:           /* value from an enumeration */
-               case ft_loose_enum:     /* value from an enumeration with only some names known */
-               case ft_af_enum:        /* Attribute Format + value from an enumeration */
-               case ft_af_loose_enum:  /* Attribute Format + value from an enumeration */
-               case ft_set:            /* bits representing set */
-                       switch (i)
-                       {
-                       case 8/BITS_PER_BYTE:
-                               n = *(const u_int8_t *)inp;
-                               break;
-                       case 16/BITS_PER_BYTE:
-                               n = *(const u_int16_t *)inp;
-                               break;
-                       case 32/BITS_PER_BYTE:
-                               n = *(const u_int32_t *)inp;
-                               break;
-                       default:
-                               bad_case(i);
-                       }
-                       switch (fp->field_type)
-                       {
-                       case ft_len:        /* length of this struct and any following crud */
-                       case ft_lv:         /* length/value field of attribute */
-                               if (!immediate && !len_meaningful)
-                                       break;
-                               /* FALL THROUGH */
-                       case ft_nat:        /* natural number (may be 0) */
-                               DBG_log("   %s: %lu", fp->name, (unsigned long)n);
-                               break;
-                       case ft_af_enum:       /* Attribute Format + value from an enumeration */
-                       case ft_af_loose_enum: /* Attribute Format + value from an enumeration */
-                               if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV)
-                                       immediate = TRUE;
-                               /* FALL THROUGH */
-                       case ft_enum:       /* value from an enumeration */
-                       case ft_loose_enum: /* value from an enumeration with only some names known */
-                               DBG_log("   %s: %s", fp->name, enum_show(fp->desc, n));
-                               break;
-                       case ft_set:        /* bits representing set */
-                               DBG_log("   %s: %s", fp->name, bitnamesof(fp->desc, n));
-                               break;
-                       default:
-                               bad_case(fp->field_type);
-                       }
-                       inp += i;
-                       break;
-
-               case ft_raw:    /* bytes to be left in network-order */
-                       {
-                               char m[50];     /* arbitrary limit on name width in log */
-
-                               snprintf(m, sizeof(m), "   %s:", fp->name);
-                               DBG_dump(m, inp, i);
-                               inp += i;
-                       }
-                       break;
-               default:
-                       bad_case(fp->field_type);
-               }
-       }
-}
-
-static void
-DBG_prefix_print_struct(const pb_stream *pbs
-, const char *label, const void *struct_ptr
-, struct_desc *sd, bool len_meaningful)
-{
-       /* print out a title, with a prefix of asterisks to show
-        * the nesting level.
-        */
-       char space[40];     /* arbitrary limit on label+flock-of-* */
-       size_t len = strlen(label);
-
-       if (sizeof(space) <= len)
-       {
-               DBG_print_struct(label, struct_ptr, sd, len_meaningful);
-       }
-       else
-       {
-               const pb_stream *p = pbs;
-               char *pre = &space[sizeof(space) - (len + 1)];
-
-               strcpy(pre, label);
-
-               /* put at least one * out */
-               for (;;)
-               {
-                       if (pre <= space)
-                               break;
-                       *--pre = '*';
-                       if (p == NULL)
-                               break;
-                       p = p->container;
-               }
-               DBG_print_struct(pre, struct_ptr, sd, len_meaningful);
-       }
-}
-
-#endif
-
-/* "parse" a network struct into a host struct.
- *
- * This code assumes that the network and host structure
- * members have the same alignment and size!  This requires
- * that all padding be explicit.
- *
- * If obj_pbs is supplied, a new pb_stream is created for the
- * variable part of the structure (this depends on their
- * being one length field in the structure).  The cursor of this
- * new PBS is set to after the parsed part of the struct.
- *
- * This routine returns TRUE iff it succeeds.
- */
-
-bool
-in_struct(void *struct_ptr, struct_desc *sd
-, pb_stream *ins, pb_stream *obj_pbs)
-{
-       err_t ugh = NULL;
-       u_int8_t *cur = ins->cur;
-
-       if (ins->roof - cur < (ptrdiff_t)sd->size)
-       {
-               ugh = builddiag("not enough room in input packet for %s", sd->name);
-       }
-       else
-       {
-               u_int8_t *roof = cur + sd->size;    /* may be changed by a length field */
-               u_int8_t *outp = struct_ptr;
-               bool immediate = FALSE;
-               field_desc *fp;
-
-               for (fp = sd->fields; ugh == NULL; fp++)
-               {
-                       size_t i = fp->size;
-
-                       passert(ins->roof - cur >= (ptrdiff_t)i);
-                       passert(cur - ins->cur <= (ptrdiff_t)(sd->size - i));
-                       passert(outp - (cur - ins->cur) == struct_ptr);
-
-#if 0
-                       DBG(DBG_PARSING, DBG_log("%d %s"
-                               , (int) (cur - ins->cur), fp->name == NULL? "" : fp->name));
-#endif
-                       switch (fp->field_type)
-                       {
-                       case ft_mbz:        /* must be zero */
-                               for (; i != 0; i--)
-                               {
-                                       if (*cur++ != 0)
-                                       {
-                                               ugh = builddiag("byte %d of %s must be zero, but is not"
-                                                       , (int) (cur - ins->cur), sd->name);
-                                               break;
-                                       }
-                                       *outp++ = '\0';     /* probably redundant */
-                               }
-                               break;
-
-                       case ft_nat:           /* natural number (may be 0) */
-                       case ft_len:           /* length of this struct and any following crud */
-                       case ft_lv:            /* length/value field of attribute */
-                       case ft_enum:          /* value from an enumeration */
-                       case ft_loose_enum:    /* value from an enumeration with only some names known */
-                       case ft_af_enum:       /* Attribute Format + value from an enumeration */
-                       case ft_af_loose_enum: /* Attribute Format + value from an enumeration */
-                       case ft_set:           /* bits representing set */
-                       {
-                               u_int32_t n = 0;
-
-                               for (; i != 0; i--)
-                                       n = (n << BITS_PER_BYTE) | *cur++;
-
-                               switch (fp->field_type)
-                               {
-                               case ft_len:    /* length of this struct and any following crud */
-                               case ft_lv:     /* length/value field of attribute */
-                               {
-                                       u_int32_t len = fp->field_type == ft_len? n
-                                               : immediate? sd->size : n + sd->size;
-
-                                       if (len < sd->size)
-                                       {
-                                               ugh = builddiag("%s of %s is smaller than minimum"
-                                                       , fp->name, sd->name);
-                                       }
-                                       else if (pbs_left(ins) < len)
-                                       {
-                                               ugh = builddiag("%s of %s is larger than can fit"
-                                                       , fp->name, sd->name);
-                                       }
-                                       else
-                                       {
-                                               roof = ins->cur + len;
-                                       }
-                                       break;
-                               }
-                               case ft_af_loose_enum:  /* Attribute Format + value from an enumeration */
-                                       if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV)
-                                               immediate = TRUE;
-                                       break;
-                               case ft_af_enum:        /* Attribute Format + value from an enumeration */
-                                       if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV)
-                                               immediate = TRUE;
-                                       /* FALL THROUGH */
-                               case ft_enum:   /* value from an enumeration */
-                                       if (enum_name(fp->desc, n) == NULL)
-                                       {
-                                               ugh = builddiag("%s of %s has an unknown value: %lu"
-                                                       , fp->name, sd->name, (unsigned long)n);
-                                       }
-                                       /* FALL THROUGH */
-                               case ft_loose_enum:     /* value from an enumeration with only some names known */
-                                       break;
-                               case ft_set:    /* bits representing set */
-                                       if (!testset(fp->desc, n))
-                                       {
-                                               ugh = builddiag("bitset %s of %s has unknown member(s): %s"
-                                                       , fp->name, sd->name, bitnamesof(fp->desc, n));
-                                       }
-                                       break;
-                               default:
-                                               break;
-                               }
-                               i = fp->size;
-                               switch (i)
-                               {
-                               case 8/BITS_PER_BYTE:
-                                       *(u_int8_t *)outp = n;
-                                       break;
-                               case 16/BITS_PER_BYTE:
-                                       *(u_int16_t *)outp = n;
-                                       break;
-                               case 32/BITS_PER_BYTE:
-                                       *(u_int32_t *)outp = n;
-                                       break;
-                               default:
-                                       bad_case(i);
-                               }
-                               outp += i;
-                               break;
-                       }
-
-                       case ft_raw:        /* bytes to be left in network-order */
-                               for (; i != 0; i--)
-                               {
-                                       *outp++ = *cur++;
-                               }
-                               break;
-
-                       case ft_end:        /* end of field list */
-                               passert(cur == ins->cur + sd->size);
-                               if (obj_pbs != NULL)
-                               {
-                                       init_pbs(obj_pbs, ins->cur, roof - ins->cur, sd->name);
-                                       obj_pbs->container = ins;
-                                       obj_pbs->desc = sd;
-                                       obj_pbs->cur = cur;
-                               }
-                               ins->cur = roof;
-                               DBG(DBG_PARSING
-                                       , DBG_prefix_print_struct(ins, "parse ", struct_ptr, sd, TRUE));
-                               return TRUE;
-
-                       default:
-                               bad_case(fp->field_type);
-                       }
-               }
-       }
-
-       /* some failure got us here: report it */
-       loglog(RC_LOG_SERIOUS, ugh);
-       return FALSE;
-}
-
-bool
-in_raw(void *bytes, size_t len, pb_stream *ins, const char *name)
-{
-       if (pbs_left(ins) < len)
-       {
-               loglog(RC_LOG_SERIOUS, "not enough bytes left to get %s from %s", name, ins->name);
-               return FALSE;
-       }
-       else
-       {
-               if (bytes == NULL)
-               {
-                       DBG(DBG_PARSING
-                               , DBG_log("skipping %u raw bytes of %s (%s)"
-                                       , (unsigned) len, ins->name, name);
-                                 DBG_dump(name, ins->cur, len));
-               }
-               else
-               {
-                       memcpy(bytes, ins->cur, len);
-                       DBG(DBG_PARSING
-                               , DBG_log("parsing %u raw bytes of %s into %s"
-                                       , (unsigned) len, ins->name, name);
-                                 DBG_dump(name, bytes, len));
-               }
-               ins->cur += len;
-               return TRUE;
-       }
-}
-
-/* "emit" a host struct into a network packet.
- *
- * This code assumes that the network and host structure
- * members have the same alignment and size!  This requires
- * that all padding be explicit.
- *
- * If obj_pbs is non-NULL, its pbs describes a new output stream set up
- * to contain the object.  The cursor will be left at the variable part.
- * This new stream must subsequently be finalized by close_output_pbs().
- *
- * The value of any field of type ft_len is computed, not taken
- * from the input struct.  The length is actually filled in when
- * the object's output stream is finalized.  If obj_pbs is NULL,
- * finalization is done by out_struct before it returns.
- *
- * This routine returns TRUE iff it succeeds.
- */
-
-bool
-out_struct(const void *struct_ptr, struct_desc *sd
-, pb_stream *outs, pb_stream *obj_pbs)
-{
-       err_t ugh = NULL;
-       const u_int8_t *inp = struct_ptr;
-       u_int8_t *cur = outs->cur;
-
-       DBG(DBG_EMITTING
-               , DBG_prefix_print_struct(outs, "emit ", struct_ptr, sd, obj_pbs==NULL));
-
-       if (outs->roof - cur < (ptrdiff_t)sd->size)
-       {
-               ugh = builddiag("not enough room left in output packet to place %s"
-                       , sd->name);
-       }
-       else
-       {
-               bool immediate = FALSE;
-               pb_stream obj;
-               field_desc *fp;
-
-               obj.lenfld = NULL;  /* until a length field is discovered */
-               obj.lenfld_desc = NULL;
-
-               for (fp = sd->fields; ugh == NULL; fp++)
-               {
-                       size_t i = fp->size;
-
-                       passert(outs->roof - cur >= (ptrdiff_t)i);
-                       passert(cur - outs->cur <= (ptrdiff_t)(sd->size - i));
-                       passert(inp - (cur - outs->cur) == struct_ptr);
-
-#if 0
-                       DBG(DBG_EMITTING, DBG_log("%d %s"
-                               , (int) (cur - outs->cur), fp->name == NULL? "" : fp->name);
-#endif
-                       switch (fp->field_type)
-                       {
-                       case ft_mbz:        /* must be zero */
-                               inp += i;
-                               for (; i != 0; i--)
-                                       *cur++ = '\0';
-                               break;
-                       case ft_nat:           /* natural number (may be 0) */
-                       case ft_len:           /* length of this struct and any following crud */
-                       case ft_lv:            /* length/value field of attribute */
-                       case ft_enum:          /* value from an enumeration */
-                       case ft_loose_enum:    /* value from an enumeration with only some names known */
-                       case ft_af_enum:       /* Attribute Format + value from an enumeration */
-                       case ft_af_loose_enum: /* Attribute Format + value from an enumeration */
-                       case ft_set:           /* bits representing set */
-                       {
-                               u_int32_t n = 0;
-
-                               switch (i)
-                               {
-                               case 8/BITS_PER_BYTE:
-                                       n = *(const u_int8_t *)inp;
-                                       break;
-                               case 16/BITS_PER_BYTE:
-                                       n = *(const u_int16_t *)inp;
-                                       break;
-                               case 32/BITS_PER_BYTE:
-                                       n = *(const u_int32_t *)inp;
-                                       break;
-                               default:
-                                       bad_case(i);
-                               }
-
-                               switch (fp->field_type)
-                               {
-                               case ft_len:    /* length of this struct and any following crud */
-                               case ft_lv:     /* length/value field of attribute */
-                                       if (immediate)
-                                               break;  /* not a length */
-                                       /* We can't check the length because it will likely
-                                        * be filled in after variable part is supplied.
-                                        * We do record where this is so that it can be
-                                        * filled in by a subsequent close_output_pbs().
-                                        */
-                                       passert(obj.lenfld == NULL);        /* only one ft_len allowed */
-                                       obj.lenfld = cur;
-                                       obj.lenfld_desc = fp;
-                                       break;
-                               case ft_af_loose_enum: /* Attribute Format + value from an enumeration */
-                                       if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV)
-                                               immediate = TRUE;
-                                       break;
-                               case ft_af_enum:        /* Attribute Format + value from an enumeration */
-                                       if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV)
-                                               immediate = TRUE;
-                                       /* FALL THROUGH */
-                               case ft_enum:   /* value from an enumeration */
-                                       if (enum_name(fp->desc, n) == NULL)
-                                       {
-                                               ugh = builddiag("%s of %s has an unknown value: %lu"
-                                                       , fp->name, sd->name, (unsigned long)n);
-                                       }
-                                       /* FALL THROUGH */
-                               case ft_loose_enum:     /* value from an enumeration with only some names known */
-                                       break;
-                               case ft_set:    /* bits representing set */
-                                       if (!testset(fp->desc, n))
-                                       {
-                                               ugh = builddiag("bitset %s of %s has unknown member(s): %s"
-                                                       , fp->name, sd->name, bitnamesof(fp->desc, n));
-                                       }
-                                       break;
-                               default:
-                                       break;
-                               }
-
-                               while (i-- != 0)
-                               {
-                                       cur[i] = (u_int8_t)n;
-                                       n >>= BITS_PER_BYTE;
-                               }
-                               inp += fp->size;
-                               cur += fp->size;
-                               break;
-                       }
-                       case ft_raw:        /* bytes to be left in network-order */
-                               for (; i != 0; i--)
-                                       *cur++ = *inp++;
-                               break;
-                       case ft_end:        /* end of field list */
-                               passert(cur == outs->cur + sd->size);
-
-                               obj.container = outs;
-                               obj.desc = sd;
-                               obj.name = sd->name;
-                               obj.start = outs->cur;
-                               obj.cur = cur;
-                               obj.roof = outs->roof;  /* limit of possible */
-                               /* obj.lenfld and obj.lenfld_desc already set */
-
-                               if (obj_pbs == NULL)
-                               {
-                                       close_output_pbs(&obj); /* fill in length field, if any */
-                               }
-                               else
-                               {
-                                       /* We set outs->cur to outs->roof so that
-                                        * any attempt to output something into outs
-                                        * before obj is closed will trigger an error.
-                                        */
-                                       outs->cur = outs->roof;
-
-                                       *obj_pbs = obj;
-                               }
-                               return TRUE;
-
-                       default:
-                               bad_case(fp->field_type);
-                       }
-               }
-       }
-
-       /* some failure got us here: report it */
-       loglog(RC_LOG_SERIOUS, ugh);        /* ??? serious, but errno not relevant */
-       return FALSE;
-}
-
-bool
-out_generic(u_int8_t np, struct_desc *sd
-, pb_stream *outs, pb_stream *obj_pbs)
-{
-       struct isakmp_generic gen;
-
-       passert(sd->fields == isakmp_generic_desc.fields);
-       gen.isag_np = np;
-       return out_struct(&gen, sd, outs, obj_pbs);
-}
-
-bool
-out_generic_raw(u_int8_t np, struct_desc *sd
-, pb_stream *outs, const void *bytes, size_t len, const char *name)
-{
-       pb_stream pbs;
-
-       if (!out_generic(np, sd, outs, &pbs)
-       || !out_raw(bytes, len, &pbs, name))
-               return FALSE;
-       close_output_pbs(&pbs);
-       return TRUE;
-}
-
-bool
-out_raw(const void *bytes, size_t len, pb_stream *outs, const char *name)
-{
-       if (pbs_left(outs) < len)
-       {
-               loglog(RC_LOG_SERIOUS, "not enough room left to place %lu bytes of %s in %s"
-                       , (unsigned long) len, name, outs->name);
-               return FALSE;
-       }
-       else
-       {
-               DBG(DBG_EMITTING
-                       , DBG_log("emitting %u raw bytes of %s into %s"
-                               , (unsigned) len, name, outs->name);
-                         DBG_dump(name, bytes, len));
-               memcpy(outs->cur, bytes, len);
-               outs->cur += len;
-               return TRUE;
-       }
-}
-
-bool
-out_zero(size_t len, pb_stream *outs, const char *name)
-{
-       if (pbs_left(outs) < len)
-       {
-               loglog(RC_LOG_SERIOUS, "not enough room left to place %s in %s", name, outs->name);
-               return FALSE;
-       }
-       else
-       {
-               DBG(DBG_EMITTING, DBG_log("emitting %u zero bytes of %s into %s"
-                       , (unsigned) len, name, outs->name));
-               memset(outs->cur, 0x00, len);
-               outs->cur += len;
-               return TRUE;
-       }
-}
-
-/* Record current length.
- * Note: currently, this may be repeated any number of times;
- * the last one wins.
- */
-void
-close_output_pbs(pb_stream *pbs)
-{
-       if (pbs->lenfld != NULL)
-       {
-               u_int32_t len = pbs_offset(pbs);
-               int i = pbs->lenfld_desc->size;
-
-               if (pbs->lenfld_desc->field_type == ft_lv)
-                       len -= sizeof(struct isakmp_attribute);
-               DBG(DBG_EMITTING, DBG_log("emitting length of %s: %lu"
-                       , pbs->name, (unsigned long) len));
-               while (i-- != 0)
-               {
-                       pbs->lenfld[i] = (u_int8_t)len;
-                       len >>= BITS_PER_BYTE;
-               }
-       }
-       if (pbs->container != NULL)
-               pbs->container->cur = pbs->cur; /* pass space utilization up */
-}
diff --git a/src/pluto/packet.h b/src/pluto/packet.h
deleted file mode 100644 (file)
index 1510b81..0000000
+++ /dev/null
@@ -1,653 +0,0 @@
-/* parsing packets: formats and tools
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2001  D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef _PACKET_H
-#define _PACKET_H
-
-/* a struct_desc describes a structure for the struct I/O routines.
- * This requires arrays of field_desc values to describe struct fields.
- */
-
-typedef const struct struct_desc {
-       const char *name;
-       const struct field_desc *fields;
-       size_t size;
-} struct_desc;
-
-/* Note: if an ft_af_enum field has the ISAKMP_ATTR_AF_TV bit set,
- * the subsequent ft_lv field will be interpreted as an immediate value.
- * This matches how attributes are encoded.
- * See RFC 2408 "ISAKMP" 3.3
- */
-
-enum field_type {
-       ft_mbz,           /* must be zero */
-       ft_nat,           /* natural number (may be 0) */
-       ft_len,           /* length of this struct and any following crud */
-       ft_lv,            /* length/value field of attribute */
-       ft_enum,          /* value from an enumeration */
-       ft_loose_enum,    /* value from an enumeration with only some names known */
-       ft_af_loose_enum, /* Attribute Format + enumeration, some names known */
-       ft_af_enum,       /* Attribute Format + value from an enumeration */
-       ft_set,           /* bits representing set */
-       ft_raw,           /* bytes to be left in network-order */
-       ft_end,           /* end of field list */
-};
-
-typedef const struct field_desc {
-       enum field_type field_type;
-       int size;   /* size, in bytes, of field */
-       const char *name;
-       const void *desc;   /* enum_names for enum or char *[] for bits */
-} field_desc;
-
-/* The formatting of input and output of packets is done
- * through packet_byte_stream objects.
- * These describe a stream of bytes in memory.
- * Several routines are provided to manipulate these objects
- * Actual packet transfer is done elsewhere.
- */
-typedef struct packet_byte_stream {
-       struct packet_byte_stream *container;   /* PBS of which we are part */
-       struct_desc *desc;
-       const char *name;   /* what does this PBS represent? */
-       u_int8_t
-               *start,
-               *cur,   /* current position in stream */
-               *roof;  /* byte after last in PBS (actually just a limit on output) */
-       /* For an output PBS, the length field will be filled in later so
-        * we need to record its particulars.  Note: it may not be aligned.
-        */
-       u_int8_t *lenfld;
-       field_desc *lenfld_desc;
-} pb_stream;
-
-/* For an input PBS, pbs_offset is amount of stream processed.
- * For an output PBS, pbs_offset is current size of stream.
- * For an input PBS, pbs_room is size of stream.
- * For an output PBS, pbs_room is maximum size allowed.
- */
-#define pbs_offset(pbs) ((size_t)((pbs)->cur - (pbs)->start))
-#define pbs_room(pbs) ((size_t)((pbs)->roof - (pbs)->start))
-#define pbs_left(pbs) ((size_t)((pbs)->roof - (pbs)->cur))
-
-extern void init_pbs(pb_stream *pbs, u_int8_t *start, size_t len, const char *name);
-
-extern bool in_struct(void *struct_ptr, struct_desc *sd,
-       pb_stream *ins, pb_stream *obj_pbs);
-extern bool in_raw(void *bytes, size_t len, pb_stream *ins, const char *name);
-
-extern bool out_struct(const void *struct_ptr, struct_desc *sd,
-       pb_stream *outs, pb_stream *obj_pbs);
-extern bool out_generic(u_int8_t np, struct_desc *sd,
-       pb_stream *outs, pb_stream *obj_pbs);
-extern bool out_generic_raw(u_int8_t np, struct_desc *sd,
-       pb_stream *outs, const void *bytes, size_t len, const char *name);
-#define out_generic_chunk(np, sd, outs, ch, name) \
-               out_generic_raw(np, sd, outs, (ch).ptr, (ch).len, name)
-extern bool out_zero(size_t len, pb_stream *outs, const char *name);
-extern bool out_raw(const void *bytes, size_t len, pb_stream *outs, const char *name);
-#define out_chunk(ch, outs, name) out_raw((ch).ptr, (ch).len, (outs), (name))
-extern void close_output_pbs(pb_stream *pbs);
-
-#ifdef DEBUG
-extern void DBG_print_struct(const char *label, const void *struct_ptr,
-       struct_desc *sd, bool len_meaningful);
-#endif
-
-/* ISAKMP Header: for all messages
- * layout from RFC 2408 "ISAKMP" section 3.1
- *                      1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !                          Initiator                            !
- * !                            Cookie                             !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !                          Responder                            !
- * !                            Cookie                             !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !  Next Payload ! MjVer ! MnVer ! Exchange Type !     Flags     !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !                          Message ID                           !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !                            Length                             !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * Although the drafts are a little unclear, there are a few
- * places that specify that messages should be padded with 0x00
- * octets (bytes) to make the length a multiple of something.
- *
- * RFC 2408 "ISAKMP" 3.6 specifies that all messages will be
- * padded to be a multiple of 4 octets in length.
- * ??? This looks vestigial, and we ignore this requirement.
- *
- * RFC 2409 "IKE" Appedix B specifies:
- *     Each message should be padded up to the nearest block size
- *     using bytes containing 0x00.
- * ??? This does not appear to be limited to encrypted messages,
- * but it surely must be: the block size is meant to be the encryption
- * block size, and that is meaningless for a non-encrypted message.
- *
- * RFC 2409 "IKE" 5.3 specifies:
- *     Encrypted payloads are padded up to the nearest block size.
- *     All padding bytes, except for the last one, contain 0x00. The
- *     last byte of the padding contains the number of the padding
- *     bytes used, excluding the last one. Note that this means there
- *     will always be padding.
- * ??? This is nuts since payloads are not padded, messages are.
- * It also contradicts Appendix B.  So we ignore it.
- *
- * Summary: we pad encrypted output messages with 0x00 to bring them
- * up to a multiple of the encryption block size.  On input, we require
- * that any encrypted portion of a message be a multiple of the encryption
- * block size.   After any decryption, we ignore padding (any bytes after
- * the first payload that specifies a next payload of none; we don't
- * require them to be zero).
- */
-
-struct isakmp_hdr
-{
-       u_int8_t    isa_icookie[COOKIE_SIZE];
-       u_int8_t    isa_rcookie[COOKIE_SIZE];
-       u_int8_t    isa_np;                 /* Next payload */
-       u_int8_t    isa_version;    /* high-order 4 bits: Major; low order 4: Minor */
-#define ISA_MAJ_SHIFT   4
-#define ISA_MIN_MASK    (~((~0u) << ISA_MAJ_SHIFT))
-       u_int8_t    isa_xchg;               /* Exchange type */
-       u_int8_t    isa_flags;
-       u_int32_t   isa_msgid;              /* Message ID (RAW) */
-       u_int32_t   isa_length;             /* Length of message */
-};
-
-extern struct_desc isakmp_hdr_desc;
-
-/* Generic portion of all ISAKMP payloads.
- * layout from RFC 2408 "ISAKMP" section 3.2
- * This describes the first 32-bit chunk of all payloads.
- * The previous next payload depends on the actual payload type.
- *                      1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload  !   RESERVED    !         Payload Length        !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-struct isakmp_generic
-{
-       u_int8_t    isag_np;
-       u_int8_t    isag_reserved;
-       u_int16_t   isag_length;
-};
-
-extern struct_desc isakmp_generic_desc;
-
-/* ISAKMP Data Attribute (generic representation within payloads)
- * layout from RFC 2408 "ISAKMP" section 3.3
- * This is not a payload type.
- * In TLV format, this is followed by a value field.
- *                      1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !A!       Attribute Type        !    AF=0  Attribute Length     !
- * !F!                             !    AF=1  Attribute Value      !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * .                   AF=0  Attribute Value                       .
- * .                   AF=1  Not Transmitted                       .
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-struct isakmp_attribute
-{
-       /* The high order bit of isaat_af_type is the Attribute Format
-        * If it is off, the format is TLV: lv is the length of the following
-        * attribute value.
-        * If it is on, the format is TV: lv is the value of the attribute.
-        * ISAKMP_ATTR_AF_MASK is the mask in host form.
-        *
-        * The low order 15 bits of isaat_af_type is the Attribute Type.
-        * ISAKMP_ATTR_RTYPE_MASK is the mask in host form.
-        */
-       u_int16_t isaat_af_type;   /* high order bit: AF; lower 15: rtype */
-       u_int16_t isaat_lv;                 /* Length or value */
-};
-
-#define ISAKMP_ATTR_AF_MASK 0x8000
-#define ISAKMP_ATTR_AF_TV ISAKMP_ATTR_AF_MASK /* value in lv */
-#define ISAKMP_ATTR_AF_TLV 0 /* length in lv; value follows */
-
-#define ISAKMP_ATTR_RTYPE_MASK 0x7FFF
-
-extern struct_desc
-       isakmp_oakley_attribute_desc,
-       isakmp_ipsec_attribute_desc;
-
-/* ISAKMP Security Association Payload
- * layout from RFC 2408 "ISAKMP" section 3.4
- * A variable length Situation follows.
- * Previous next payload: ISAKMP_NEXT_SA
- *                      1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload  !   RESERVED    !         Payload Length        !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !              Domain of Interpretation  (DOI)                  !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !                                                               !
- * ~                           Situation                           ~
- * !                                                               !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-struct isakmp_sa
-{
-       u_int8_t  isasa_np;                 /* Next payload */
-       u_int8_t  isasa_reserved;
-       u_int16_t isasa_length;             /* Payload length */
-       u_int32_t isasa_doi;                /* DOI */
-};
-
-extern struct_desc isakmp_sa_desc;
-
-extern struct_desc ipsec_sit_desc;
-
-/* ISAKMP Proposal Payload
- * layout from RFC 2408 "ISAKMP" section 3.5
- * A variable length SPI follows.
- * Previous next payload: ISAKMP_NEXT_P
- *                      1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload  !   RESERVED    !         Payload Length        !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !  Proposal #   !  Protocol-Id  !    SPI Size   !# of Transforms!
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !                        SPI (variable)                         !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-struct isakmp_proposal
-{
-       u_int8_t    isap_np;
-       u_int8_t    isap_reserved;
-       u_int16_t   isap_length;
-       u_int8_t    isap_proposal;
-       u_int8_t    isap_protoid;
-       u_int8_t    isap_spisize;
-       u_int8_t    isap_notrans;           /* Number of transforms */
-};
-
-extern struct_desc isakmp_proposal_desc;
-
-/* ISAKMP Transform Payload
- * layout from RFC 2408 "ISAKMP" section 3.6
- * Variable length SA Attributes follow.
- * Previous next payload: ISAKMP_NEXT_T
- *                      1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload  !   RESERVED    !         Payload Length        !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !  Transform #  !  Transform-Id !           RESERVED2           !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !                                                               !
- * ~                        SA Attributes                          ~
- * !                                                               !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-struct isakmp_transform
-{
-       u_int8_t    isat_np;
-       u_int8_t    isat_reserved;
-       u_int16_t   isat_length;
-       u_int8_t    isat_transnum;          /* Number of the transform */
-       u_int8_t    isat_transid;
-       u_int16_t   isat_reserved2;
-};
-
-extern struct_desc
-       isakmp_isakmp_transform_desc,
-       isakmp_ah_transform_desc,
-       isakmp_esp_transform_desc,
-       isakmp_ipcomp_transform_desc;
-
-/* ISAKMP Key Exchange Payload: no fixed fields beyond the generic ones.
- * layout from RFC 2408 "ISAKMP" section 3.7
- * Variable Key Exchange Data follow the generic fields.
- * Previous next payload: ISAKMP_NEXT_KE
- *                      1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload  !   RESERVED    !         Payload Length        !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !                                                               !
- * ~                       Key Exchange Data                       ~
- * !                                                               !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-extern struct_desc isakmp_keyex_desc;
-
-/* ISAKMP Identification Payload
- * layout from RFC 2408 "ISAKMP" section 3.8
- * See "struct identity" declared later.
- * Variable length Identification Data follow.
- * Previous next payload: ISAKMP_NEXT_ID
- *                      1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload  !   RESERVED    !         Payload Length        !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !   ID Type     !             DOI Specific ID Data              !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !                                                               !
- * ~                   Identification Data                         ~
- * !                                                               !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-struct isakmp_id
-{
-       u_int8_t    isaid_np;
-       u_int8_t    isaid_reserved;
-       u_int16_t   isaid_length;
-       u_int8_t    isaid_idtype;
-       u_int8_t    isaid_doi_specific_a;
-       u_int16_t   isaid_doi_specific_b;
-};
-
-extern struct_desc isakmp_identification_desc;
-
-/* IPSEC Identification Payload Content
- * layout from RFC 2407 "IPsec DOI" section 4.6.2
- * See struct isakmp_id declared earlier.
- * Note: Hashing skips the ISAKMP generic payload header
- * Variable length Identification Data follow.
- *                      1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !  Next Payload !   RESERVED    !        Payload Length         !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !   ID Type     !  Protocol ID  !             Port              !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ~                     Identification Data                       ~
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-struct isakmp_ipsec_id
-{
-       u_int8_t    isaiid_np;
-       u_int8_t    isaiid_reserved;
-       u_int16_t   isaiid_length;
-       u_int8_t    isaiid_idtype;
-       u_int8_t    isaiid_protoid;
-       u_int16_t   isaiid_port;
-};
-
-extern struct_desc isakmp_ipsec_identification_desc;
-
-/* ISAKMP Certificate Payload: no fixed fields beyond the generic ones.
- * layout from RFC 2408 "ISAKMP" section 3.9
- * Variable length Certificate Data follow the generic fields.
- * Previous next payload: ISAKMP_NEXT_CERT.
- *                      1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload  !   RESERVED    !         Payload Length        !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Cert Encoding !                                               !
- * +-+-+-+-+-+-+-+-+                                               !
- * ~                       Certificate Data                        ~
- * !                                                               !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-struct isakmp_cert
-{
-       u_int8_t    isacert_np;
-       u_int8_t    isacert_reserved;
-       u_int16_t   isacert_length;
-       u_int8_t    isacert_type;
-};
-
-/* NOTE: this packet type has a fixed portion that is not a
- * multiple of 4 octets.  This means that sizeof(struct isakmp_cert)
- * yields the wrong value for the length.
- */
-#define ISAKMP_CERT_SIZE                5
-
-extern struct_desc isakmp_ipsec_certificate_desc;
-
-/* ISAKMP Certificate Request Payload: no fixed fields beyond the generic ones.
- * layout from RFC 2408 "ISAKMP" section 3.10
- * Variable length Certificate Types and Certificate Authorities follow.
- * Previous next payload: ISAKMP_NEXT_CR.
- *                      1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload  !   RESERVED    !         Payload Length        !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !  Cert. Type   !                                               !
- * +-+-+-+-+-+-+-+-+                                               !
- * ~                    Certificate Authority                      ~
- * !                                                               !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-struct isakmp_cr
-{
-       u_int8_t    isacr_np;
-       u_int8_t    isacr_reserved;
-       u_int16_t   isacr_length;
-       u_int8_t    isacr_type;
-};
-
-/* NOTE: this packet type has a fixed portion that is not a
- * multiple of 4 octets.  This means that sizeof(struct isakmp_cr)
- * yields the wrong value for the length.
- */
-#define ISAKMP_CR_SIZE          5
-
-extern struct_desc isakmp_ipsec_cert_req_desc;
-
-/* ISAKMP Hash Payload: no fixed fields beyond the generic ones.
- * layout from RFC 2408 "ISAKMP" section 3.11
- * Variable length Hash Data follow.
- * Previous next payload: ISAKMP_NEXT_HASH.
- *                      1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload  !   RESERVED    !         Payload Length        !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !                                                               !
- * ~                           Hash Data                           ~
- * !                                                               !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-extern struct_desc isakmp_hash_desc;
-
-/* ISAKMP Signature Payload: no fixed fields beyond the generic ones.
- * layout from RFC 2408 "ISAKMP" section 3.12
- * Variable length Signature Data follow.
- * Previous next payload: ISAKMP_NEXT_SIG.
- *                      1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload  !   RESERVED    !         Payload Length        !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !                                                               !
- * ~                         Signature Data                        ~
- * !                                                               !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-extern struct_desc isakmp_signature_desc;
-
-/* ISAKMP Nonce Payload: no fixed fields beyond the generic ones.
- * layout from RFC 2408 "ISAKMP" section 3.13
- * Variable length Nonce Data follow.
- * Previous next payload: ISAKMP_NEXT_NONCE.
- *                      1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload  !   RESERVED    !         Payload Length        !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !                                                               !
- * ~                            Nonce Data                         ~
- * !                                                               !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-extern struct_desc isakmp_nonce_desc;
-
-/* ISAKMP Notification Payload
- * layout from RFC 2408 "ISAKMP" section 3.14
- * This is followed by a variable length SPI
- * and then possibly by variable length Notification Data.
- * Previous next payload: ISAKMP_NEXT_N
- *                      1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload  !   RESERVED    !         Payload Length        !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !              Domain of Interpretation  (DOI)                  !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !  Protocol-ID  !   SPI Size    !      Notify Message Type      !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !                                                               !
- * ~                Security Parameter Index (SPI)                 ~
- * !                                                               !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !                                                               !
- * ~                       Notification Data                       ~
- * !                                                               !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-struct isakmp_notification
-{
-       u_int8_t    isan_np;
-       u_int8_t    isan_reserved;
-       u_int16_t   isan_length;
-       u_int32_t   isan_doi;
-       u_int8_t    isan_protoid;
-       u_int8_t    isan_spisize;
-       u_int16_t   isan_type;
-};
-
-extern struct_desc isakmp_notification_desc;
-
-/* ISAKMP Delete Payload
- * layout from RFC 2408 "ISAKMP" section 3.15
- * This is followed by a variable length SPI.
- * Previous next payload: ISAKMP_NEXT_D
- *                      1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload  !   RESERVED    !         Payload Length        !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !              Domain of Interpretation  (DOI)                  !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !  Protocol-Id  !   SPI Size    !           # of SPIs           !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !                                                               !
- * ~               Security Parameter Index(es) (SPI)              ~
- * !                                                               !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-struct isakmp_delete
-{
-       u_int8_t    isad_np;
-       u_int8_t    isad_reserved;
-       u_int16_t   isad_length;
-       u_int32_t   isad_doi;
-       u_int8_t    isad_protoid;
-       u_int8_t    isad_spisize;
-       u_int16_t   isad_nospi;
-};
-
-extern struct_desc isakmp_delete_desc;
-
-/* From draft-dukes-ike-mode-cfg
-3.2. Attribute Payload
-                                                  1                   2                   3
-          0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-        ! Next Payload  !   RESERVED    !         Payload Length        !
-        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-        !     Type      !   RESERVED    !           Identifier          !
-        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-        !                                                               !
-        !                                                               !
-        ~                           Attributes                          ~
-        !                                                               !
-        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-*/
-struct isakmp_mode_attr
-{
-       u_int8_t    isama_np;
-       u_int8_t    isama_reserved;
-       u_int16_t   isama_length;
-       u_int8_t    isama_type;
-       u_int8_t    isama_reserved2;
-       u_int16_t   isama_identifier;
-};
-
-extern struct_desc isakmp_attr_desc;
-extern struct_desc isakmp_modecfg_attribute_desc;
-
-/* ISAKMP Vendor ID Payload
- * layout from RFC 2408 "ISAKMP" section 3.15
- * This is followed by a variable length VID.
- * Previous next payload: ISAKMP_NEXT_VID
- *                      1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload  !   RESERVED    !         Payload Length        !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !                                                               !
- * ~                        Vendor ID (VID)                        ~
- * !                                                               !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-extern struct_desc isakmp_vendor_id_desc;
-
-struct isakmp_nat_oa
-{
-       u_int8_t    isanoa_np;
-       u_int8_t    isanoa_reserved_1;
-       u_int16_t   isanoa_length;
-       u_int8_t    isanoa_idtype;
-       u_int8_t    isanoa_reserved_2;
-       u_int16_t   isanoa_reserved_3;
-};
-
-extern struct_desc isakmp_nat_d;
-extern struct_desc isakmp_nat_oa;
-
-/* union of all payloads */
-
-union payload {
-       struct isakmp_generic generic;
-       struct isakmp_sa sa;
-       struct isakmp_proposal proposal;
-       struct isakmp_transform transform;
-       struct isakmp_id id;    /* Main Mode */
-       struct isakmp_cert cert;
-       struct isakmp_cr cr;
-       struct isakmp_ipsec_id ipsec_id;    /* Quick Mode */
-       struct isakmp_notification notification;
-       struct isakmp_delete delete;
-       struct isakmp_nat_oa nat_oa;
-       struct isakmp_mode_attr attribute;
-};
-
-/* descriptor for each payload type
- *
- * There is a slight problem in that some payloads differ, depending
- * on the mode.  Since this is table only used for top-level payloads,
- * Proposal and Transform payloads need not be handled.
- * That leaves only Identification payloads as a problem.
- * We make all these entries NULL
- */
-extern struct_desc *const payload_descs[ISAKMP_NEXT_ROOF];
-
-#endif /* _PACKET_H */
diff --git a/src/pluto/pkcs7.c b/src/pluto/pkcs7.c
deleted file mode 100644 (file)
index 10b2a4d..0000000
+++ /dev/null
@@ -1,755 +0,0 @@
-/* Support of PKCS#7 data structures
- * Copyright (C) 2005 Jan Hutter, Martin Willi
- * Copyright (C) 2002-2009 Andreas Steffen
- *
- * HSR Hochschule fuer Technik Rapperswil, Switzerland
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#include <library.h>
-#include <debug.h>
-#include <asn1/asn1.h>
-#include <asn1/asn1_parser.h>
-#include <asn1/oid.h>
-#include <crypto/rngs/rng.h>
-#include <crypto/crypters/crypter.h>
-#include <credentials/certificates/x509.h>
-
-#include "pkcs7.h"
-
-const contentInfo_t empty_contentInfo = {
-       OID_UNKNOWN , /* type */
-       { NULL, 0 }   /* content */
-};
-
-/**
- * ASN.1 definition of the PKCS#7 ContentInfo type
- */
-static const asn1Object_t contentInfoObjects[] = {
-       { 0, "contentInfo",                     ASN1_SEQUENCE,     ASN1_NONE          }, /*  0 */
-       { 1,   "contentType",                   ASN1_OID,          ASN1_BODY          }, /*  1 */
-       { 1,   "content",                       ASN1_CONTEXT_C_0,  ASN1_OPT|ASN1_BODY }, /*  2 */
-       { 1,   "end opt",                       ASN1_EOC,          ASN1_END           }, /*  3 */
-       { 0, "exit",                            ASN1_EOC,          ASN1_EXIT          }
-};
-#define PKCS7_INFO_TYPE         1
-#define PKCS7_INFO_CONTENT      2
-
-/**
- * ASN.1 definition of the PKCS#7 signedData type
- */
-static const asn1Object_t signedDataObjects[] = {
-       { 0, "signedData",                      ASN1_SEQUENCE,     ASN1_NONE          }, /*  0 */
-       { 1,   "version",                       ASN1_INTEGER,      ASN1_BODY          }, /*  1 */
-       { 1,   "digestAlgorithms",              ASN1_SET,          ASN1_LOOP          }, /*  2 */
-       { 2,     "algorithm",                   ASN1_EOC,          ASN1_RAW           }, /*  3 */
-       { 1,   "end loop",                      ASN1_EOC,          ASN1_END           }, /*  4 */
-       { 1,   "contentInfo",                   ASN1_EOC,          ASN1_RAW           }, /*  5 */
-       { 1,   "certificates",                  ASN1_CONTEXT_C_0,  ASN1_OPT|ASN1_LOOP }, /*  6 */
-       { 2,      "certificate",                ASN1_SEQUENCE,     ASN1_OBJ           }, /*  7 */
-       { 1,   "end opt or loop",               ASN1_EOC,          ASN1_END           }, /*  8 */
-       { 1,   "crls",                          ASN1_CONTEXT_C_1,  ASN1_OPT|ASN1_LOOP }, /*  9 */
-       { 2,      "crl",                        ASN1_SEQUENCE,     ASN1_OBJ           }, /* 10 */
-       { 1,   "end opt or loop",               ASN1_EOC,          ASN1_END           }, /* 11 */
-       { 1,   "signerInfos",                   ASN1_SET,          ASN1_LOOP          }, /* 12 */
-       { 2,     "signerInfo",                  ASN1_SEQUENCE,     ASN1_NONE          }, /* 13 */
-       { 3,       "version",                   ASN1_INTEGER,      ASN1_BODY          }, /* 14 */
-       { 3,       "issuerAndSerialNumber",     ASN1_SEQUENCE,     ASN1_BODY          }, /* 15 */
-       { 4,         "issuer",                  ASN1_SEQUENCE,     ASN1_OBJ           }, /* 16 */
-       { 4,         "serial",                  ASN1_INTEGER,      ASN1_BODY          }, /* 17 */
-       { 3,       "digestAlgorithm",           ASN1_EOC,          ASN1_RAW           }, /* 18 */
-       { 3,       "authenticatedAttributes",   ASN1_CONTEXT_C_0,  ASN1_OPT|ASN1_OBJ  }, /* 19 */
-       { 3,       "end opt",                   ASN1_EOC,          ASN1_END           }, /* 20 */
-       { 3,       "digestEncryptionAlgorithm", ASN1_EOC,          ASN1_RAW           }, /* 21 */
-       { 3,       "encryptedDigest",           ASN1_OCTET_STRING, ASN1_BODY          }, /* 22 */
-       { 3,       "unauthenticatedAttributes", ASN1_CONTEXT_C_1,  ASN1_OPT           }, /* 23 */
-       { 3,       "end opt",                   ASN1_EOC,          ASN1_END           }, /* 24 */
-       { 1,   "end loop",                      ASN1_EOC,          ASN1_END           }, /* 25 */
-       { 0, "exit",                            ASN1_EOC,          ASN1_EXIT          }
-};
-#define PKCS7_SIGNED_VERSION             1
-#define PKCS7_DIGEST_ALG                 3
-#define PKCS7_SIGNED_CONTENT_INFO        5
-#define PKCS7_SIGNED_CERT                7
-#define PKCS7_SIGNER_INFO               13
-#define PKCS7_SIGNER_INFO_VERSION       14
-#define PKCS7_SIGNED_ISSUER             16
-#define PKCS7_SIGNED_SERIAL_NUMBER      17
-#define PKCS7_DIGEST_ALGORITHM          18
-#define PKCS7_AUTH_ATTRIBUTES           19
-#define PKCS7_DIGEST_ENC_ALGORITHM      21
-#define PKCS7_ENCRYPTED_DIGEST          22
-
-/**
- * ASN.1 definition of the PKCS#7 envelopedData type
- */
-static const asn1Object_t envelopedDataObjects[] = {
-       { 0, "envelopedData",                  ASN1_SEQUENCE,     ASN1_NONE }, /*  0 */
-       { 1,   "version",                      ASN1_INTEGER,      ASN1_BODY }, /*  1 */
-       { 1,   "recipientInfos",               ASN1_SET,          ASN1_LOOP }, /*  2 */
-       { 2,     "recipientInfo",              ASN1_SEQUENCE,     ASN1_BODY }, /*  3 */
-       { 3,       "version",                  ASN1_INTEGER,      ASN1_BODY }, /*  4 */
-       { 3,       "issuerAndSerialNumber",    ASN1_SEQUENCE,     ASN1_BODY }, /*  5 */
-       { 4,         "issuer",                 ASN1_SEQUENCE,     ASN1_OBJ  }, /*  6 */
-       { 4,         "serial",                 ASN1_INTEGER,      ASN1_BODY }, /*  7 */
-       { 3,       "encryptionAlgorithm",      ASN1_EOC,          ASN1_RAW  }, /*  8 */
-       { 3,       "encryptedKey",             ASN1_OCTET_STRING, ASN1_BODY }, /*  9 */
-       { 1,   "end loop",                     ASN1_EOC,          ASN1_END  }, /* 10 */
-       { 1,   "encryptedContentInfo",         ASN1_SEQUENCE,     ASN1_OBJ  }, /* 11 */
-       { 2,     "contentType",                ASN1_OID,          ASN1_BODY }, /* 12 */
-       { 2,     "contentEncryptionAlgorithm", ASN1_EOC,          ASN1_RAW  }, /* 13 */
-       { 2,     "encryptedContent",           ASN1_CONTEXT_S_0,  ASN1_BODY }, /* 14 */
-       { 0, "exit",                           ASN1_EOC,          ASN1_EXIT }
-};
-#define PKCS7_ENVELOPED_VERSION          1
-#define PKCS7_RECIPIENT_INFO_VERSION     4
-#define PKCS7_ISSUER                     6
-#define PKCS7_SERIAL_NUMBER              7
-#define PKCS7_ENCRYPTION_ALG             8
-#define PKCS7_ENCRYPTED_KEY              9
-#define PKCS7_CONTENT_TYPE              12
-#define PKCS7_CONTENT_ENC_ALGORITHM     13
-#define PKCS7_ENCRYPTED_CONTENT         14
-#define PKCS7_ENVELOPED_ROOF            15
-
-/**
- * Parse PKCS#7 ContentInfo object
- */
-bool pkcs7_parse_contentInfo(chunk_t blob, u_int level0, contentInfo_t *cInfo)
-{
-       asn1_parser_t *parser;
-       chunk_t object;
-       int objectID;
-       bool success = FALSE;
-
-       parser = asn1_parser_create(contentInfoObjects, blob);
-       parser->set_top_level(parser, level0);
-
-       while (parser->iterate(parser, &objectID, &object))
-       {
-               if (objectID == PKCS7_INFO_TYPE)
-               {
-                       cInfo->type = asn1_known_oid(object);
-                       if (cInfo->type < OID_PKCS7_DATA
-                       ||  cInfo->type > OID_PKCS7_ENCRYPTED_DATA)
-                       {
-                               DBG1(DBG_LIB, "unknown pkcs7 content type");
-                               goto end;
-                       }
-               }
-               else if (objectID == PKCS7_INFO_CONTENT)
-               {
-                       cInfo->content = object;
-               }
-       }
-       success = parser->success(parser);
-
-end:
-       parser->destroy(parser);
-       return success;
-}
-
-/**
- * Parse a PKCS#7 signedData object
- */
-bool pkcs7_parse_signedData(chunk_t blob, contentInfo_t *data,
-                                                       linked_list_t *certs,
-                                                       chunk_t *attributes, certificate_t *cacert)
-{
-       asn1_parser_t *parser;
-       chunk_t object;
-       int digest_alg = OID_UNKNOWN;
-       int enc_alg    = OID_UNKNOWN;
-       int signerInfos = 0;
-       int version;
-       int objectID;
-       bool success = FALSE;
-
-       contentInfo_t cInfo = empty_contentInfo;
-       chunk_t encrypted_digest = chunk_empty;
-
-       if (!pkcs7_parse_contentInfo(blob, 0, &cInfo))
-       {
-               return FALSE;
-       }
-       if (cInfo.type != OID_PKCS7_SIGNED_DATA)
-       {
-               DBG1(DBG_LIB, "pkcs7 content type is not signedData");
-               return FALSE;
-       }
-
-       parser = asn1_parser_create(signedDataObjects, cInfo.content);
-       parser->set_top_level(parser, 2);
-
-       while (parser->iterate(parser, &objectID, &object))
-       {
-               u_int level = parser->get_level(parser);
-
-               switch (objectID)
-               {
-               case PKCS7_SIGNED_VERSION:
-                       version = object.len ? (int)*object.ptr : 0;
-                       DBG2(DBG_LIB, "  v%d", version);
-                       break;
-               case PKCS7_DIGEST_ALG:
-                       digest_alg = asn1_parse_algorithmIdentifier(object, level, NULL);
-                       break;
-               case PKCS7_SIGNED_CONTENT_INFO:
-                       if (data != NULL)
-                       {
-                               pkcs7_parse_contentInfo(object, level, data);
-                       }
-                       break;
-               case PKCS7_SIGNED_CERT:
-                       {
-                               certificate_t *cert;
-
-                               DBG2(DBG_LIB, "  parsing pkcs7-wrapped certificate");
-                               cert = lib->creds->create(lib->creds,
-                                                                                 CRED_CERTIFICATE, CERT_X509,
-                                                                                 BUILD_BLOB_ASN1_DER, object,
-                                                                                 BUILD_END);
-                               if (cert)
-                               {
-                                       certs->insert_last(certs, cert);
-                               }
-                       }
-                       break;
-               case PKCS7_SIGNER_INFO:
-                       signerInfos++;
-                       DBG2(DBG_LIB, "  signer #%d", signerInfos);
-                       break;
-               case PKCS7_SIGNER_INFO_VERSION:
-                       version = object.len ? (int)*object.ptr : 0;
-                       DBG2(DBG_LIB, "  v%d", version);
-                       break;
-               case PKCS7_SIGNED_ISSUER:
-                       {
-                               identification_t *issuer = identification_create_from_encoding(
-                                                                                                       ID_DER_ASN1_DN, object);
-                               DBG2(DBG_LIB, "  \"%Y\"", issuer);
-                               issuer->destroy(issuer);
-                               break;
-                       }
-               case PKCS7_AUTH_ATTRIBUTES:
-                       if (attributes != NULL)
-                       {
-                               *attributes = object;
-                               *attributes->ptr = ASN1_SET;
-                       }
-                       break;
-               case PKCS7_DIGEST_ALGORITHM:
-                       digest_alg = asn1_parse_algorithmIdentifier(object, level, NULL);
-                       break;
-               case PKCS7_DIGEST_ENC_ALGORITHM:
-                       enc_alg = asn1_parse_algorithmIdentifier(object, level, NULL);
-                       break;
-               case PKCS7_ENCRYPTED_DIGEST:
-                       encrypted_digest = object;
-               }
-       }
-       success = parser->success(parser);
-       parser->destroy(parser);
-       if (!success)
-       {
-               return FALSE;
-       }
-
-       /* check the signature only if a cacert is available */
-       if (cacert != NULL)
-       {
-               public_key_t *key;
-               signature_scheme_t scheme;
-
-               scheme = signature_scheme_from_oid(digest_alg);
-               if (scheme == SIGN_UNKNOWN)
-               {
-                       DBG1(DBG_LIB, "unsupported signature scheme");
-                       return FALSE;
-               }
-               if (signerInfos == 0)
-               {
-                       DBG1(DBG_LIB, "no signerInfo object found");
-                       return FALSE;
-               }
-               else if (signerInfos > 1)
-               {
-                       DBG1(DBG_LIB, "more than one signerInfo object found");
-                       return FALSE;
-               }
-               if (attributes->ptr == NULL)
-               {
-                       DBG1(DBG_LIB, "no authenticatedAttributes object found");
-                       return FALSE;
-               }
-               if (enc_alg != OID_RSA_ENCRYPTION)
-               {
-                       DBG1(DBG_LIB, "only RSA digest encryption supported");
-                       return FALSE;
-               }
-
-               /* verify the signature */
-               key = cacert->get_public_key(cacert);
-               if (key == NULL)
-               {
-                       DBG1(DBG_LIB, "no public key found in CA certificate");
-                       return FALSE;
-               }
-               if (key->verify(key, scheme, *attributes, encrypted_digest))
-               {
-                       DBG2(DBG_LIB, "signature is valid");
-               }
-               else
-               {
-                       DBG1(DBG_LIB, "invalid signature");
-                       success = FALSE;
-               }
-               key->destroy(key);
-       }
-       return success;
-}
-
-/**
- * Parse a PKCS#7 envelopedData object
- */
-bool pkcs7_parse_envelopedData(chunk_t blob, chunk_t *data,
-                                                          chunk_t serialNumber,
-                                                          private_key_t *key)
-{
-       asn1_parser_t *parser;
-       chunk_t object;
-       chunk_t iv                = chunk_empty;
-       chunk_t symmetric_key     = chunk_empty;
-       chunk_t encrypted_content = chunk_empty;
-
-       crypter_t *crypter = NULL;
-
-       int enc_alg         = OID_UNKNOWN;
-       int content_enc_alg = OID_UNKNOWN;
-       int version;
-       int objectID;
-       bool success = FALSE;
-
-       contentInfo_t cInfo = empty_contentInfo;
-       *data = chunk_empty;
-
-       if (!pkcs7_parse_contentInfo(blob, 0, &cInfo))
-       {
-               goto failed;
-       }
-       if (cInfo.type != OID_PKCS7_ENVELOPED_DATA)
-       {
-               DBG1(DBG_LIB, "pkcs7 content type is not envelopedData");
-               goto failed;
-       }
-
-       parser = asn1_parser_create(envelopedDataObjects, cInfo.content);
-       parser->set_top_level(parser, 2);
-
-       while (parser->iterate(parser, &objectID, &object))
-       {
-               u_int level = parser->get_level(parser);
-
-               switch (objectID)
-               {
-               case PKCS7_ENVELOPED_VERSION:
-                       version = object.len ? (int)*object.ptr : 0;
-                       DBG2(DBG_LIB, "  v%d", version);
-                       if (version != 0)
-                       {
-                               DBG1(DBG_LIB, "envelopedData version is not 0");
-                               goto end;
-                       }
-                       break;
-               case PKCS7_RECIPIENT_INFO_VERSION:
-                       version = object.len ? (int)*object.ptr : 0;
-                       DBG2(DBG_LIB, "  v%d", version);
-                       if (version != 0)
-                       {
-                               DBG1(DBG_LIB, "recipient info version is not 0");
-                               goto end;
-                       }
-                       break;
-               case PKCS7_ISSUER:
-                       {
-                               identification_t *issuer = identification_create_from_encoding(
-                                                                                                       ID_DER_ASN1_DN, object);
-                               DBG2(DBG_LIB, "  \"%Y\"", issuer);
-                               issuer->destroy(issuer);
-                               break;
-                       }
-               case PKCS7_SERIAL_NUMBER:
-                       if (!chunk_equals(serialNumber, object))
-                       {
-                               DBG1(DBG_LIB, "serial numbers do not match");
-                               goto end;
-                       }
-                       break;
-               case PKCS7_ENCRYPTION_ALG:
-                       enc_alg = asn1_parse_algorithmIdentifier(object, level, NULL);
-                       if (enc_alg != OID_RSA_ENCRYPTION)
-                       {
-                               DBG1(DBG_LIB, "only rsa encryption supported");
-                               goto end;
-                       }
-                       break;
-               case PKCS7_ENCRYPTED_KEY:
-                       if (!key->decrypt(key, ENCRYPT_RSA_PKCS1, object, &symmetric_key))
-                       {
-                               DBG1(DBG_LIB, "symmetric key could not be decrypted with rsa");
-                               goto end;
-                       }
-                       DBG4(DBG_LIB, "symmetric key %B", &symmetric_key);
-                       break;
-               case PKCS7_CONTENT_TYPE:
-                       if (asn1_known_oid(object) != OID_PKCS7_DATA)
-                       {
-                                DBG1(DBG_LIB, "encrypted content not of type pkcs7 data");
-                                goto end;
-                       }
-                       break;
-               case PKCS7_CONTENT_ENC_ALGORITHM:
-                       content_enc_alg = asn1_parse_algorithmIdentifier(object, level, &iv);
-
-                       if (content_enc_alg == OID_UNKNOWN)
-                       {
-                               DBG1(DBG_LIB, "unknown content encryption algorithm");
-                               goto end;
-                       }
-                       if (!asn1_parse_simple_object(&iv, ASN1_OCTET_STRING, level+1, "IV"))
-                       {
-                               DBG1(DBG_LIB, "IV could not be parsed");
-                               goto end;
-                       }
-                       break;
-               case PKCS7_ENCRYPTED_CONTENT:
-                       encrypted_content = object;
-                       break;
-               }
-       }
-       success = parser->success(parser);
-
-end:
-       parser->destroy(parser);
-       if (!success)
-       {
-               goto failed;
-       }
-       success = FALSE;
-
-       /* decrypt the content */
-       {
-               encryption_algorithm_t alg;
-               size_t key_size;
-               crypter_t *crypter;
-
-               alg = encryption_algorithm_from_oid(content_enc_alg, &key_size);
-               if (alg == ENCR_UNDEFINED)
-               {
-                       DBG1(DBG_LIB, "unsupported content encryption algorithm");
-                       goto failed;
-               }
-               crypter = lib->crypto->create_crypter(lib->crypto, alg, key_size);
-               if (crypter == NULL)
-               {
-                       DBG1(DBG_LIB, "crypter %N not available", encryption_algorithm_names, alg);
-                       goto failed;
-               }
-               if (symmetric_key.len != crypter->get_key_size(crypter))
-               {
-                       DBG1(DBG_LIB, "symmetric key length %d is wrong", symmetric_key.len);
-                       goto failed;
-               }
-               if (iv.len != crypter->get_iv_size(crypter))
-               {
-                       DBG1(DBG_LIB, "IV length %d is wrong", iv.len);
-                       goto failed;
-               }
-               crypter->set_key(crypter, symmetric_key);
-               crypter->decrypt(crypter, encrypted_content, iv, data);
-               DBG4(DBG_LIB, "decrypted content with padding: %B", data);
-       }
-
-       /* remove the padding */
-       {
-               u_char *pos = data->ptr + data->len - 1;
-               u_char pattern = *pos;
-               size_t padding = pattern;
-
-               if (padding > data->len)
-               {
-                       DBG1(DBG_LIB, "padding greater than data length");
-                       goto failed;
-               }
-               data->len -= padding;
-
-               while (padding-- > 0)
-               {
-                       if (*pos-- != pattern)
-                       {
-                               DBG1(DBG_LIB, "wrong padding pattern");
-                               goto failed;
-                       }
-               }
-       }
-       success = TRUE;
-
-failed:
-       DESTROY_IF(crypter);
-       chunk_clear(&symmetric_key);
-       if (!success)
-       {
-               free(data->ptr);
-       }
-       return success;
-}
-
-/**
- * @brief Builds a contentType attribute
- *
- * @return ASN.1 encoded contentType attribute
- */
-chunk_t pkcs7_contentType_attribute(void)
-{
-       return asn1_wrap(ASN1_SEQUENCE, "mm",
-                                               asn1_build_known_oid(OID_PKCS9_CONTENT_TYPE),
-                                               asn1_wrap(ASN1_SET, "m",
-                                                       asn1_build_known_oid(OID_PKCS7_DATA)));
-}
-
-/**
- * @brief Builds a messageDigest attribute
- *
- *
- * @param[in] blob content to create digest of
- * @param[in] digest_alg digest algorithm to be used
- * @return ASN.1 encoded messageDigest attribute
- *
- */
-chunk_t pkcs7_messageDigest_attribute(chunk_t content, int digest_alg)
-{
-       chunk_t digest;
-       hash_algorithm_t hash_alg;
-       hasher_t *hasher;
-
-       hash_alg = hasher_algorithm_from_oid(digest_alg);
-       hasher = lib->crypto->create_hasher(lib->crypto, hash_alg);
-       hasher->allocate_hash(hasher, content, &digest);
-       hasher->destroy(hasher);
-
-       return asn1_wrap(ASN1_SEQUENCE, "mm",
-                               asn1_build_known_oid(OID_PKCS9_MESSAGE_DIGEST),
-                               asn1_wrap(ASN1_SET, "m",
-                                       asn1_wrap(ASN1_OCTET_STRING, "m", digest)));
-}
-
-/**
- * build a DER-encoded contentInfo object
- */
-static chunk_t pkcs7_build_contentInfo(contentInfo_t *cInfo)
-{
-       return (cInfo->content.ptr) ?
-                               asn1_wrap(ASN1_SEQUENCE, "mm",
-                                       asn1_build_known_oid(cInfo->type),
-                                       asn1_simple_object(ASN1_CONTEXT_C_0, cInfo->content)) :
-                               asn1_build_known_oid(cInfo->type);
-}
-
-/**
- * build issuerAndSerialNumber object
- */
-chunk_t pkcs7_build_issuerAndSerialNumber(certificate_t *cert)
-{
-       identification_t *issuer = cert->get_issuer(cert);
-       x509_t *x509 = (x509_t*)cert;
-
-       return asn1_wrap(ASN1_SEQUENCE, "cm",
-                                        issuer->get_encoding(issuer),
-                                        asn1_integer("c", x509->get_serial(x509)));
-}
-
-/**
- * create a signed pkcs7 contentInfo object
- */
-chunk_t pkcs7_build_signedData(chunk_t data, chunk_t attributes,
-                                                          certificate_t *cert, int digest_alg,
-                                                          private_key_t *key)
-{
-       contentInfo_t pkcs7Data, signedData;
-       chunk_t authenticatedAttributes = chunk_empty;
-       chunk_t encryptedDigest = chunk_empty;
-       chunk_t signerInfo, cInfo, signature, encoding = chunk_empty;;
-       signature_scheme_t scheme = signature_scheme_from_oid(digest_alg);
-
-       if (attributes.ptr)
-       {
-               if (key->sign(key, scheme, attributes, &signature))
-               {
-                       encryptedDigest = asn1_wrap(ASN1_OCTET_STRING, "m", signature);
-                       authenticatedAttributes = chunk_clone(attributes);
-                       *authenticatedAttributes.ptr = ASN1_CONTEXT_C_0;
-               }
-       }
-       else if (data.ptr)
-       {
-               if (key->sign(key, scheme, data, &signature))
-               {
-                       encryptedDigest = asn1_wrap(ASN1_OCTET_STRING, "m", signature);
-               }
-       }
-       signerInfo = asn1_wrap(ASN1_SEQUENCE, "cmmmmm"
-                               , ASN1_INTEGER_1
-                               , pkcs7_build_issuerAndSerialNumber(cert)
-                               , asn1_algorithmIdentifier(digest_alg)
-                               , authenticatedAttributes
-                               , asn1_algorithmIdentifier(OID_RSA_ENCRYPTION)
-                               , encryptedDigest);
-
-       pkcs7Data.type    = OID_PKCS7_DATA;
-       pkcs7Data.content = (data.ptr == NULL)? chunk_empty
-                               : asn1_simple_object(ASN1_OCTET_STRING, data);
-
-       cert->get_encoding(cert, CERT_ASN1_DER, &encoding);
-       signedData.type = OID_PKCS7_SIGNED_DATA;
-       signedData.content = asn1_wrap(ASN1_SEQUENCE, "cmmmm"
-                               , ASN1_INTEGER_1
-                               , asn1_wrap(ASN1_SET, "m", asn1_algorithmIdentifier(digest_alg))
-                               , pkcs7_build_contentInfo(&pkcs7Data)
-                               , asn1_wrap(ASN1_CONTEXT_C_0, "m", encoding)
-                               , asn1_wrap(ASN1_SET, "m", signerInfo));
-
-       cInfo = pkcs7_build_contentInfo(&signedData);
-       DBG3(DBG_LIB, "signedData %B", &cInfo);
-
-       free(pkcs7Data.content.ptr);
-       free(signedData.content.ptr);
-       return cInfo;
-}
-
-/**
- * create a symmetrically encrypted pkcs7 contentInfo object
- */
-chunk_t pkcs7_build_envelopedData(chunk_t data, certificate_t *cert, int enc_alg)
-{
-       encryption_algorithm_t alg;
-       size_t alg_key_size;
-       chunk_t symmetricKey, protectedKey, iv, in, out;
-       crypter_t *crypter;
-
-       alg = encryption_algorithm_from_oid(enc_alg, &alg_key_size);
-       crypter = lib->crypto->create_crypter(lib->crypto, alg,
-                                                                                 alg_key_size/BITS_PER_BYTE);
-       if (crypter == NULL)
-       {
-               DBG1(DBG_LIB, "crypter for %N not available", encryption_algorithm_names, alg);
-               return chunk_empty;
-       }
-
-       /* generate a true random symmetric encryption key and a pseudo-random iv */
-       {
-               rng_t *rng;
-
-               rng = lib->crypto->create_rng(lib->crypto, RNG_TRUE);
-               rng->allocate_bytes(rng, crypter->get_key_size(crypter), &symmetricKey);
-               DBG4(DBG_LIB, "symmetric encryption key %B", &symmetricKey);
-               rng->destroy(rng);
-
-               rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
-               rng->allocate_bytes(rng, crypter->get_iv_size(crypter), &iv);
-               DBG4(DBG_LIB, "initialization vector: %B", &iv);
-               rng->destroy(rng);
-       }
-
-       /* pad the data to a multiple of the block size */
-       {
-               size_t block_size = crypter->get_block_size(crypter);
-               size_t padding = block_size - data.len % block_size;
-
-               in.len = data.len + padding;
-               in.ptr = malloc(in.len);
-
-               DBG2(DBG_LIB, "padding %u bytes of data to multiple block size of %u bytes",
-                        data.len, in.len);
-
-               /* copy data */
-               memcpy(in.ptr, data.ptr, data.len);
-               /* append padding */
-               memset(in.ptr + data.len, padding, padding);
-       }
-       DBG3(DBG_LIB, "padded unencrypted data %B", &in);
-
-       /* symmetric encryption of data object */
-       crypter->set_key(crypter, symmetricKey);
-       crypter->encrypt(crypter, in, iv, &out);
-       crypter->destroy(crypter);
-       chunk_clear(&in);
-    DBG3(DBG_LIB, "encrypted data %B", &out);
-
-       /* protect symmetric key by public key encryption */
-       {
-               public_key_t *key = cert->get_public_key(cert);
-
-               if (key == NULL)
-               {
-                       DBG1(DBG_LIB, "public key not found in encryption certificate");
-                       chunk_clear(&symmetricKey);
-                       chunk_free(&iv);
-                       chunk_free(&out);
-                       return chunk_empty;
-               }
-               key->encrypt(key, ENCRYPT_RSA_PKCS1, symmetricKey, &protectedKey);
-               key->destroy(key);
-       }
-
-       /* build pkcs7 enveloped data object */
-       {
-
-               chunk_t contentEncryptionAlgorithm = asn1_wrap(ASN1_SEQUENCE, "mm"
-                                       , asn1_build_known_oid(enc_alg)
-                                       , asn1_simple_object(ASN1_OCTET_STRING, iv));
-
-               chunk_t encryptedContentInfo = asn1_wrap(ASN1_SEQUENCE, "mmm"
-                                       , asn1_build_known_oid(OID_PKCS7_DATA)
-                                       , contentEncryptionAlgorithm
-                                       , asn1_wrap(ASN1_CONTEXT_S_0, "m", out));
-
-               chunk_t encryptedKey = asn1_wrap(ASN1_OCTET_STRING, "m"
-                                       , protectedKey);
-
-               chunk_t recipientInfo = asn1_wrap(ASN1_SEQUENCE, "cmmm"
-                                       , ASN1_INTEGER_0
-                                       , pkcs7_build_issuerAndSerialNumber(cert)
-                                       , asn1_algorithmIdentifier(OID_RSA_ENCRYPTION)
-                                       , encryptedKey);
-
-               chunk_t cInfo;
-               contentInfo_t envelopedData;
-
-               envelopedData.type = OID_PKCS7_ENVELOPED_DATA;
-               envelopedData.content = asn1_wrap(ASN1_SEQUENCE, "cmm"
-                                       , ASN1_INTEGER_0
-                                       , asn1_wrap(ASN1_SET, "m", recipientInfo)
-                                       , encryptedContentInfo);
-
-               cInfo = pkcs7_build_contentInfo(&envelopedData);
-               DBG3(DBG_LIB, "envelopedData %B", &cInfo);
-
-               chunk_free(&envelopedData.content);
-               chunk_free(&iv);
-               chunk_clear(&symmetricKey);
-               return cInfo;
-       }
-}
diff --git a/src/pluto/pkcs7.h b/src/pluto/pkcs7.h
deleted file mode 100644 (file)
index 1743ea9..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/* Support of PKCS#7 data structures
- * Copyright (C) 2005 Jan Hutter, Martin Willi
- * Copyright (C) 2002-2009 Andreas Steffen
- *
- * Hochschule fuer Technik Rapperswil, Switzerland
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef _PKCS7_H
-#define _PKCS7_H
-
-#include <utils/linked_list.h>
-#include <crypto/crypters/crypter.h>
-#include <credentials/keys/private_key.h>
-#include <credentials/certificates/certificate.h>
-
-/* Access structure for a PKCS#7 ContentInfo object */
-
-typedef struct contentInfo contentInfo_t;
-
-struct contentInfo {
-       int     type;
-       chunk_t content;
-};
-
-extern const contentInfo_t empty_contentInfo;
-
-extern bool pkcs7_parse_contentInfo(chunk_t blob, u_int level0,
-                                                                       contentInfo_t *cInfo);
-extern bool pkcs7_parse_signedData(chunk_t blob, contentInfo_t *data,
-                                                                  linked_list_t *cert, chunk_t *attributes,
-                                                                  certificate_t *cacert);
-extern bool pkcs7_parse_envelopedData(chunk_t blob, chunk_t *data,
-                                                                         chunk_t serialNumber, private_key_t *key);
-extern chunk_t pkcs7_contentType_attribute(void);
-extern chunk_t pkcs7_messageDigest_attribute(chunk_t content, int digest_alg);
-extern chunk_t pkcs7_build_issuerAndSerialNumber(certificate_t *cert);
-extern chunk_t pkcs7_build_signedData(chunk_t data, chunk_t attributes,
-                                                                         certificate_t *cert, int digest_alg,
-                                                                         private_key_t *key);
-extern chunk_t pkcs7_build_envelopedData(chunk_t data, certificate_t *cert,
-                                                                                int enc_alg);
-
-#endif /* _PKCS7_H */
diff --git a/src/pluto/plugin_list.c b/src/pluto/plugin_list.c
deleted file mode 100644 (file)
index ae060ac..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2011 Martin Willi, revosec AG
- * Copyright (C) 2011 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <whack.h>
-#include <log.h>
-
-#include <library.h>
-#include <utils/linked_list.h>
-
-/**
- * List loaded plugin information
- */
-void plugin_list(void)
-{
-       plugin_feature_t *features, *fp;
-       enumerator_t *enumerator;
-       linked_list_t *list;
-       plugin_t *plugin;
-       int count, i;
-       bool loaded;
-       char *str;
-
-       whack_log(RC_COMMENT, " ");
-       whack_log(RC_COMMENT, "List of loaded Plugins:");
-       whack_log(RC_COMMENT, " ");
-
-       enumerator = lib->plugins->create_plugin_enumerator(lib->plugins);
-       while (enumerator->enumerate(enumerator, &plugin, &list))
-       {
-               whack_log(RC_COMMENT, "%s:", plugin->get_name(plugin));
-               if (plugin->get_features)
-               {
-                       count = plugin->get_features(plugin, &features);
-                       for (i = 0; i < count; i++)
-                       {
-                               str = plugin_feature_get_string(&features[i]);
-                               switch (features[i].kind)
-                               {
-                                       case FEATURE_PROVIDE:
-                                               fp = &features[i];
-                                               loaded = list->find_first(list, NULL,
-                                                                                                 (void**)&fp) == SUCCESS;
-                                               whack_log(RC_COMMENT, "    %s%s",
-                                                                 str, loaded ? "" : " (not loaded)");
-                                               break;
-                                       case FEATURE_DEPENDS:
-                                               whack_log(RC_COMMENT, "        %s", str);
-                                               break;
-                                       case FEATURE_SDEPEND:
-                                               whack_log(RC_COMMENT, "        %s (soft)", str);
-                                               break;
-                                       default:
-                                               break;
-                               }
-                               free(str);
-                       }
-               }
-       }
-       enumerator->destroy(enumerator);
-}
diff --git a/src/pluto/plugin_list.h b/src/pluto/plugin_list.h
deleted file mode 100644 (file)
index 62e4a16..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* Generates a list of all loaded plugins and their dependencies
- * Copyright (C) 2011 Andreas Steffen
- * HSR Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef _PLUGIN_LIST_H
-#define _PLUGIN_LIST_H
-
-extern void plugin_list(void);
-
-#endif /* _PLUGIN_LIST_H */
diff --git a/src/pluto/plugins/xauth/Makefile.am b/src/pluto/plugins/xauth/Makefile.am
deleted file mode 100644 (file)
index 354325b..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-
-INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
-                  -I$(top_srcdir)/src/libfreeswan -I$(top_srcdir)/src/whack \
-                  -I$(top_srcdir)/src/pluto
-
-AM_CFLAGS = -rdynamic
-
-plugin_LTLIBRARIES = libstrongswan-xauth.la
-
-libstrongswan_xauth_la_SOURCES = \
-       xauth_plugin.h xauth_plugin.c \
-       xauth_default_provider.c xauth_default_provider.h \
-       xauth_default_verifier.c xauth_default_verifier.h
-
-libstrongswan_xauth_la_LDFLAGS = -module -avoid-version
diff --git a/src/pluto/plugins/xauth/xauth_default_provider.c b/src/pluto/plugins/xauth/xauth_default_provider.c
deleted file mode 100644 (file)
index 77c5fac..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2010 Andreas Steffen
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <keys.h>
-
-#include "xauth_default_provider.h"
-
-typedef struct private_xauth_default_provider_t private_xauth_default_provider_t;
-
-/**
- * private data of xauth_default_provider
- */
-struct private_xauth_default_provider_t {
-
-       /**
-        * public functions
-        */
-       xauth_provider_t public;
-};
-
-METHOD(xauth_provider_t, get_secret, bool,
-       private_xauth_default_provider_t *this, connection_t *c, chunk_t *secret)
-{
-       identification_t *user, *server;
-
-       server = c->spd.that.id;
-       user = (c->xauth_identity) ? c->xauth_identity : c->spd.this.id;
-
-       return get_xauth_secret(user, server, secret);
-}
-
-METHOD(xauth_provider_t, destroy, void,
-       private_xauth_default_provider_t *this)
-{
-       free(this);
-}
-
-/*
- * Described in header.
- */
-xauth_provider_t *xauth_default_provider_create()
-{
-       private_xauth_default_provider_t *this;
-
-       INIT(this,
-               .public = {
-                       .get_secret = _get_secret,
-                       .destroy = _destroy,
-                }
-       );
-
-       return &this->public;
-}
-
diff --git a/src/pluto/plugins/xauth/xauth_default_provider.h b/src/pluto/plugins/xauth/xauth_default_provider.h
deleted file mode 100644 (file)
index ff1a91d..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2010 Andreas Steffen
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup xauth_default_provider xauth_default_provider
- * @{ @ingroup xauth
- */
-
-#ifndef XAUTH_DEFAULT_PROVIDER_H_
-#define XAUTH_DEFAULT_PROVIDER_H_
-
-#include <xauth/xauth_provider.h>
-
-
-/**
- * Create an xauth_default_provider instance.
- */
-xauth_provider_t *xauth_default_provider_create();
-
-#endif /** XAUTH_DEFAULT_PROVIDER_H_ @}*/
-
diff --git a/src/pluto/plugins/xauth/xauth_default_verifier.c b/src/pluto/plugins/xauth/xauth_default_verifier.c
deleted file mode 100644 (file)
index ca2e36a..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2010 Andreas Steffen
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <keys.h>
-
-#include "xauth_default_verifier.h"
-
-typedef struct private_xauth_default_verifier_t private_xauth_default_verifier_t;
-
-/**
- * private data of xauth_default_verifier
- */
-struct private_xauth_default_verifier_t {
-
-       /**
-        * public functions
-        */
-       xauth_verifier_t public;
-};
-
-METHOD(xauth_verifier_t, verify_secret, bool,
-       private_xauth_default_verifier_t *this, connection_t *c, chunk_t secret)
-{
-       identification_t *user, *server;
-       chunk_t xauth_secret;
-       bool success = FALSE;
-
-       server = c->spd.this.id;
-       user = (c->xauth_identity) ? c->xauth_identity : c->spd.that.id;
-
-       if (get_xauth_secret(user, server, &xauth_secret))
-       {
-               success = chunk_equals(secret, xauth_secret);
-
-               if (!success && secret.len && secret.ptr[secret.len - 1] == 0)
-               {       /* fix for null-terminated passwords (e.g. from Android 4) */
-                       secret.len--;
-                       success = chunk_equals(secret, xauth_secret);
-               }
-
-               chunk_clear(&xauth_secret);
-       }
-       return success;
-}
-
-METHOD(xauth_verifier_t, destroy, void,
-       private_xauth_default_verifier_t *this)
-{
-       free(this);
-}
-
-
-/*
- * Described in header.
- */
-xauth_verifier_t *xauth_default_verifier_create()
-{
-       private_xauth_default_verifier_t *this;
-
-       INIT(this,
-               .public = {
-                       .verify_secret = _verify_secret,
-                       .destroy = _destroy,
-                }
-       );
-
-       return &this->public;
-}
-
diff --git a/src/pluto/plugins/xauth/xauth_default_verifier.h b/src/pluto/plugins/xauth/xauth_default_verifier.h
deleted file mode 100644 (file)
index e5814d7..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2010 Andreas Steffen
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup xauth_default_verifier xauth_default_verifier
- * @{ @ingroup xauth
- */
-
-#ifndef XAUTH_DEFAULT_VERIFIER_H_
-#define XAUTH_DEFAULT_VERIFIER_H_
-
-#include <xauth/xauth_verifier.h>
-
-
-/**
- * Create an xauth_default_verifier instance.
- */
-xauth_verifier_t *xauth_default_verifier_create();
-
-#endif /** XAUTH_DEFAULT_VERIFIER_H_ @}*/
-
diff --git a/src/pluto/plugins/xauth/xauth_plugin.c b/src/pluto/plugins/xauth/xauth_plugin.c
deleted file mode 100644 (file)
index bfc4820..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2010 Andreas Steffen
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <pluto.h>
-
-#include "xauth_plugin.h"
-#include "xauth_default_provider.h"
-#include "xauth_default_verifier.h"
-
-METHOD(plugin_t, get_name, char*,
-       xauth_plugin_t *this)
-{
-       return "xauth";
-}
-
-METHOD(plugin_t, destroy, void,
-       xauth_plugin_t *this)
-{
-       free(this);
-}
-
-/*
- * see header file
- */
-plugin_t *xauth_plugin_create()
-{
-       xauth_plugin_t *this;
-
-       INIT(this,
-               .plugin = {
-                       .get_name = _get_name,
-                       .reload = (void*)return_false,
-                       .destroy = _destroy,
-               },
-       );
-
-       pluto->xauth->add_provider(pluto->xauth, xauth_default_provider_create());
-       pluto->xauth->add_verifier(pluto->xauth, xauth_default_verifier_create());
-
-       return &this->plugin;
-}
-
diff --git a/src/pluto/plugins/xauth/xauth_plugin.h b/src/pluto/plugins/xauth/xauth_plugin.h
deleted file mode 100644 (file)
index 4f14828..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2010 Andreas Steffen
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup xauth xauth
- * @ingroup pplugins
- *
- * @defgroup xauth_plugin xauth_plugin
- * @{ @ingroup xauth
- */
-
-#ifndef XAUTH_PLUGIN_H_
-#define XAUTH_PLUGIN_H_
-
-#include <plugins/plugin.h>
-
-typedef struct xauth_plugin_t xauth_plugin_t;
-
-/**
- * XAUTH plugin
- */
-struct xauth_plugin_t {
-
-       /**
-        * implements plugin interface
-        */
-       plugin_t plugin;
-};
-
-#endif /** XAUTH_PLUGIN_H_ @}*/
diff --git a/src/pluto/pluto.8 b/src/pluto/pluto.8
deleted file mode 100644 (file)
index ed6f780..0000000
+++ /dev/null
@@ -1,1594 +0,0 @@
-.TH IPSEC_PLUTO 8 "28 March 1999"
-.SH NAME
-pluto \- IPsec IKE keying daemon and control interface
-.PP
-whack \- control interface for IKE keying daemon
-.SH SYNOPSIS
-.na
-.nh
-.HP
-.ft B
-ipsec pluto
-[\-\-help]
-[\-\-version]
-[\-\-optionsfrom\ \c
-\fIfilename\fP]
-[\-\-nofork]
-[\-\-stderrlog]
-[\-\-uniqueids]
-[\fB\-\-interface\fP \fIinterfacename\fP]
-[\-\-ikeport\ \c
-\fIportnumber\fP]
-[\-\-ctlbase\ \c
-\fIpath\fP]
-[\-\-secretsfile\ \c
-\fIsecrets\(hyfile\fP]
-[\-\-adns \fIpathname\fP]
-[\-\-lwdnsq \fIpathname\fP]
-[\-\-perpeerlog]
-[\-\-perpeerlogbase\ \c
-\fIdirname\fP]
-[\-\-debug\(hynone]
-[\-\-debug\(hyall]
-[\-\-debug\(hyraw]
-[\-\-debug\(hycrypt]
-[\-\-debug\(hyparsing]
-[\-\-debug\(hyemitting]
-[\-\-debug\(hycontrol]
-[\-\-debug\(hylifecycle]
-[\-\-debug\(hykernel]
-[\-\-debug\(hydns]
-[\-\-debug\(hyoppo]
-[\-\-debug\(hyprivate]
-.HP
-.ft B
-ipsec whack
-[\-\-help]
-[\-\-version]
-.HP
-.ft B
-ipsec whack
-\-\-name\ \c
-\fIconnection-name\fP
-.br
-[\-\-id\ \c
-\fIid\fP] \c
-[\-\-host\ \c
-\fIip\(hyaddress\fP]
-[\-\-ikeport\ \c
-\fIport\(hynumber\fP]
-[\-\-nexthop\ \c
-\fIip\(hyaddress\fP]
-[\-\-client\ \c
-\fIsubnet\fP]
-[\-\-dnskeyondemand]
-[\-\-updown\ \c
-\fIupdown\fP]
-.br
-\-\-to
-.br
-[\-\-id\ \c
-\fIid\fP]
-[\-\-host\ \c
-\fIip\(hyaddress\fP]
-[\-\-ikeport\ \c
-\fIport\(hynumber\fP]
-[\-\-nexthop\ \c
-\fIip\(hyaddress\fP]
-[\-\-client\ \c
-\fIsubnet\fP]
-[\-\-dnskeyondemand]
-[\-\-updown\ \c
-\fIupdown\fP]
-.br
-[\-\-psk]
-[\-\-rsasig]
-[\-\-encrypt]
-[\-\-authenticate]
-[\-\-compress]
-[\-\-tunnel]
-[\-\-pfs]
-[\-\-disablearrivalcheck]
-[\-\-ipv4]
-[\-\-ipv6]
-[\-\-tunnelipv4]
-[\-\-tunnelipv6]
-[\-\-ikelifetime\ \c
-\fIseconds\fP]
-[\-\-ipseclifetime\ \c
-\fIseconds\fP]
-[\-\-rekeymargin\ \c
-\fIseconds\fP]
-[\-\-rekeyfuzz\ \c
-\fIpercentage\fP]
-[\-\-keyingtries\ \c
-\fIcount\fP]
-[\-\-dontrekey]
-[\-\-delete]
-[\-\-ctlbase\ \c
-\fIpath\fP]
-[\-\-optionsfrom\ \c
-\fIfilename\fP]
-[\-\-label\ \c
-\fIstring\fP]
-.HP
-.ft B
-ipsec whack
-\-\-keyid\ \c
-\fIid\fP
-[\-\-addkey]
-[\-\-pubkeyrsa\ \c
-\fIkey\fP]
-[\-\-ctlbase\ \c
-\fIpath\fP]
-[\-\-optionsfrom\ \c
-\fIfilename\fP]
-[\-\-label\ \c
-\fIstring\fP]
-.HP
-.ft B
-ipsec whack
-\-\-myid\ \c
-\fIid\fP
-.HP
-.ft B
-ipsec whack
-\-\-listen|\-\-unlisten
-[\-\-ctlbase\ \c
-\fIpath\fP]
-[\-\-optionsfrom\ \c
-\fIfilename\fP]
-[\-\-label\ \c
-\fIstring\fP]
-.HP
-.ft B
-ipsec whack
-\-\-route|\-\-unroute
-\-\-name\ \c
-\fIconnection-name\fP
-[\-\-ctlbase\ \c
-\fIpath\fP]
-[\-\-optionsfrom\ \c
-\fIfilename\fP]
-[\-\-label\ \c
-\fIstring\fP]
-.HP
-.ft B
-ipsec whack
-\-\-initiate|\-\-terminate
-\-\-name\ \c
-\fIconnection-name\fP
-[\-\-asynchronous]
-[\-\-ctlbase\ \c
-\fIpath\fP]
-[\-\-optionsfrom\ \c
-\fIfilename\fP]
-[\-\-label\ \c
-\fIstring\fP]
-.HP
-.ft B
-ipsec whack
-[\-\-tunnelipv4]
-[\-\-tunnelipv6]
-\-\-oppohere \fIip\(hyaddress\fP
-\-\-oppothere \fIip\(hyaddress\fP
-.HP
-.ft B
-ipsec whack
-\-\-delete
-\-\-name\ \c
-\fIconnection-name\fP
-[\-\-ctlbase\ \c
-\fIpath\fP]
-[\-\-optionsfrom\ \c
-\fIfilename\fP]
-[\-\-label\ \c
-\fIstring\fP]
-.HP
-.ft B
-ipsec whack
-\-\-deletestate\ \c
-\fIstate-number\fP
-[\-\-ctlbase\ \c
-\fIpath\fP]
-[\-\-optionsfrom\ \c
-\fIfilename\fP]
-[\-\-label\ \c
-\fIstring\fP]
-.HP
-.ft B
-ipsec whack
-[\-\-name\ \c
-\fIconnection-name\fP]
-[\-\-debug\(hynone]
-[\-\-debug\(hyall]
-[\-\-debug\(hyraw]
-[\-\-debug\(hycrypt]
-[\-\-debug\(hyparsing]
-[\-\-debug\(hyemitting]
-[\-\-debug\(hycontrol]
-[\-\-debug\(hylifecycle]
-[\-\-debug\(hykernel]
-[\-\-debug\(hydns]
-[\-\-debug\(hyoppo]
-[\-\-debug\(hyprivate]
-[\-\-ctlbase\ \c
-\fIpath\fP]
-[\-\-optionsfrom\ \c
-\fIfilename\fP]
-[\-\-label\ \c
-\fIstring\fP]
-.HP
-.ft B
-ipsec whack
-\-\-status
-[\-\-ctlbase\ \c
-\fIpath\fP]
-[\-\-optionsfrom\ \c
-\fIfilename\fP]
-[\-\-label\ \c
-\fIstring\fP]
-.HP
-.ft B
-ipsec whack
-\-\-shutdown
-[\-\-ctlbase\ \c
-\fIpath\fP]
-[\-\-optionsfrom\ \c
-\fIfilename\fP]
-[\-\-label\ \c
-\fIstring\fP]
-.ft R
-.hy
-.ad
-.SH DESCRIPTION
-.BR pluto
-is an IKE (``IPsec Key Exchange'') daemon.
-.BR whack
-is an auxiliary program to allow requests to be made to a running
-.BR pluto .
-.LP
-.BR pluto
-is used to automatically build shared ``security associations'' on a
-system that has IPsec, the secure IP protocol.
-In other words,
-.BR pluto
-can eliminate much of the work of manual keying.
-The actual
-secure transmission of packets is the responsibility of the Linux kernel.
-\fIipsec_auto\fP(8) provides a more convenient interface to
-\fBpluto\fP and \fBwhack\fP.
-.SS IKE's Job
-.LP
-A \fISecurity Association\fP (\fISA\fP) is an agreement between two network nodes on
-how to process certain traffic between them.  This processing involves
-encapsulation, authentication, encryption, or compression.
-.LP
-IKE can be deployed on a network node to negotiate Security
-Associations for that node.  These IKE implementations can only
-negotiate with other IKE implementations, so IKE must be on each node
-that is to be an endpoint of an IKE-negotiated Security Association.
-No other nodes need to be running IKE.
-.LP
-An IKE instance (i.e. an IKE implementation on a particular network
-node) communicates with another IKE instance using UDP IP packets, so
-there must be a route between the nodes in each direction.
-.LP
-The negotiation of Security Associations requires a number of choices
-that involve tradeoffs between security, convenience, trust, and
-efficiency.  These are policy issues and are normally specified to the
-IKE instance by the system administrator.
-.LP
-IKE deals with two kinds of Security Associations.  The first part of
-a negotiation between IKE instances is to build an ISAKMP SA.  An
-ISAKMP SA is used to protect communication between the two IKEs.
-IPsec SAs can then be built by the IKEs \- these are used to carry
-protected IP traffic between the systems.
-.LP
-The negotiation of the ISAKMP SA is known as Phase 1.  In theory,
-Phase 1 can be accomplished by a couple of different exchange types,
-but we only implement one called Main Mode (we don't implement
-Aggressive Mode).
-.LP
-Any negotiation under the protection of an ISAKMP SA, including the
-negotiation of IPsec SAs, is part of Phase 2.  The exchange type
-that we use to negotiate an IPsec SA is called Quick Mode.
-.LP
-IKE instances must be able to authenticate each other as part of their
-negotiation of an ISAKMP SA.  This can be done by several mechanisms
-described in the draft standards.
-.LP
-IKE negotiation can be initiated by any instance with any other.  If
-both can find an agreeable set of characteristics for a Security
-Association, and both recognize each others authenticity, they can set
-up a Security Association.  The standards do not specify what causes
-an IKE instance to initiate a negotiation.
-.LP
-In summary, an IKE instance is prepared to automate the management of
-Security Associations in an IPsec environment, but a number of issues
-are considered policy and are left in the system administrator's hands.
-.SS Pluto
-.LP
-\fBpluto\fP is an implementation of IKE.  It runs as a daemon on a network
-node.  Currently, this network node must be a Linux 2.6 system running the
-native \fBNETKEY\fP IPsec stack.
-.LP
-\fBpluto\fP only implements a subset of IKE.  This is enough for it to
-interoperate with other instances of \fBpluto\fP, and many other IKE
-implementations.  We are working on implementing more of IKE.
-.LP
-The policy for acceptable characteristics for Security Associations is
-mostly hardwired into the code of \fBpluto\fP (spdb.c).  Eventually
-this will be moved into a security policy database with reasonable
-expressive power and more convenience.
-.LP
-\fBpluto\fP uses shared secrets or RSA signatures to authenticate
-peers with whom it is negotiating.
-.LP
-\fBpluto\fP initiates negotiation of a Security Association when it is
-manually prodded: the program \fBwhack\fP is run to trigger this.
-It will also initiate a negotiation when the Linux kernel traps an outbound
-packet for Opportunistic Encryption.
-.LP
-\fBpluto\fP implements ISAKMP SAs itself.  After it has negotiated the
-characteristics of an IPsec SA, it directs the Linux kernel to implement it.
-It also invokes a script to adjust any firewall and issue \fIroute\fP(8)
-commands.
-.LP
-When \fBpluto\fP shuts down, it closes all Security Associations.
-.SS Before Running Pluto
-.LP
-\fBpluto\fP runs as a daemon with userid root.  Before running it, a few
-things must be set up.
-.LP
-\fBpluto\fP requires a Linux 2.6 kernel with the modules for the native IPsec
-stack enabled.
-.LP
-\fBpluto\fP supports multiple public networks (that is, networks
-that are considered insecure and thus need to have their traffic
-encrypted or authenticated).  It discovers the
-public interfaces to use by looking at all interfaces that are
-configured (the \fB\-\-interface\fP option can be used to limit
-the interfaces considered).
-It does this only when \fBwhack\fP tells it to \-\-listen,
-so the interfaces must be configured by then.
-\fIifconfig\fP(8) with the \fB\-a\fP flag will show
-the name and status of each network interface.
-.LP
-\fBpluto\fP requires a database of preshared secrets and RSA private keys.
-This is described in the
-.IR ipsec.secrets (5).
-\fBpluto\fP is told of RSA public keys via \fBwhack\fP commands.
-If the connection is Opportunistic, and no RSA public key is known,
-\fBpluto\fP will attempt to fetch RSA keys using the Domain Name System.
-.SS ipsec.secrets file
-.LP
-A \fBpluto\fP daemon and another IKE daemon (for example, another instance
-of \fBpluto\fP) must convince each other that they are who they are supposed
-to be before any negotiation can succeed.  This authentication is
-accomplished by using either secrets that have been shared beforehand
-(manually) or by using RSA signatures.  There are other techniques,
-but they have not been implemented in \fBpluto\fP.
-.LP
-The file \fI/etc/ipsec.secrets\fP is used to keep preshared secret keys
-and RSA private keys for
-authentication with other IKE daemons.  For debugging, there is an
-argument to the \fBpluto\fP command to use a different file.
-This file is described in
-.IR ipsec.secrets (5).
-.SS Running Pluto
-.LP
-To fire up the daemon, just type \fBpluto\fP (be sure to be running as
-the superuser).
-The default IKE port number is 500, the UDP port assigned by IANA for IKE Daemons.
-\fBpluto\fP must be run by the superuser to be able to use the UDP 500 port.
-.LP
-\fBpluto\fP attempts to create a lockfile with the name
-\fI/var/run/pluto.pid\fP.  If the lockfile cannot be created,
-\fBpluto\fP exits \- this prevents multiple \fBpluto\fPs from
-competing  Any ``leftover'' lockfile must be removed before
-\fBpluto\fP will run.  \fBpluto\fP writes its pid into this file so
-that scripts can find it.  This lock will not function properly if it
-is on an NFS volume (but sharing locks on multiple machines doesn't
-make sense anyway).
-.LP
-\fBpluto\fP then forks and the parent exits.  This is the conventional
-``daemon fork''.  It can make debugging awkward, so there is an option
-to suppress this fork.
-.LP
-All logging, including diagnostics, is sent to
-.IR syslog (3)
-with facility=authpriv;
-it decides where to put these messages (possibly in /var/log/secure).
-Since this too can make debugging awkward, there is an option to
-steer logging to stderr.
-.LP
-If the \fB\-\-perpeerlog\fP option is given, then pluto will open
-a log file per connection. By default, this is in /var/log/pluto/peer,
-in a subdirectory formed by turning all dot (.) [IPv4} or colon (:)
-[IPv6] into slashes (/).
-.LP
-The base directory can be changed with the \fB\-\-perpeerlogbase\fP.
-.LP
-Once \fBpluto\fP is started, it waits for requests from \fBwhack\fP.
-.SS Pluto's Internal State
-.LP
-To understand how to use \fBpluto\fP, it is helpful to understand a little
-about its internal state.  Furthermore, the terminology is needed to decipher
-some of the diagnostic messages.
-.LP
-The \fI(potential) connection\fP database describes attributes of a
-connection.  These include the IP addresses of the hosts and client
-subnets and the security characteristics desired.  \fBpluto\fP
-requires this information (simply called a connection) before it can
-respond to a request to build an SA.  Each connection is given a name
-when it is created, and all references are made using this name.
-.LP
-During the IKE exchange to build an SA, the information about the
-negotiation is represented in a \fIstate object\fP.  Each state object
-reflects how far the negotiation has reached.  Once the negotiation is
-complete and the SA established, the state object remains to represent
-the SA.  When the SA is terminated, the state object is discarded.
-Each State object is given a serial number and this is used to refer
-to the state objects in logged messages.
-.LP
-Each state object corresponds to a connection and can be thought of
-as an instantiation of that connection.
-At any particular time, there may be any number of state objects
-corresponding to a particular connection.
-Often there is one representing an ISAKMP SA and another representing
-an IPsec SA.
-.LP
-Each connection may be routed, and must be while it has an IPsec SA.
-The connection specifies the characteristics of the route: the
-interface on this machine, the ``gateway'' (the nexthop),
-and the peer's client subnet.  Two
-connections may not be simultaneously routed if they are for the same
-peer's client subnet but use different interfaces or gateways
-(\fBpluto\fP's logic does not reflect any advanced routing capabilities).
-.LP
-Each eroute is associated with the state object for an IPsec SA
-because it has the particular characteristics of the SA.
-Two eroutes conflict if they specify the identical local
-and remote clients (unlike for routes, the local clients are
-taken into account).
-.LP
-When \fBpluto\fP needs to install a route for a connection,
-it must make sure that no conflicting route is in use.  If another
-connection has a conflicting route, that route will be taken down, as long
-as there is no IPsec SA instantiating that connection.
-If there is such an IPsec SA, the attempt to install a route will fail.
-.LP
-There is an exception.  If \fBpluto\fP, as Responder, needs to install
-a route to a fixed client subnet for a connection, and there is
-already a conflicting route, then the SAs using the route are deleted
-to make room for the new SAs.  The rationale is that the new
-connection is probably more current.  The need for this usually is a
-product of Road Warrior connections (these are explained later; they
-cannot be used to initiate).
-.LP
-When \fBpluto\fP needs to install an eroute for an IPsec SA (for a
-state object), first the state object's connection must be routed (if
-this cannot be done, the eroute and SA will not be installed).
-If a conflicting eroute is already in place for another connection,
-the eroute and SA will not be installed (but note that the routing
-exception mentioned above may have already deleted potentially conflicting SAs).
-If another IPsec
-SA for the same connection already has an eroute, all its outgoing traffic
-is taken over by the new eroute.  The incoming traffic will still be
-processed.  This characteristic is exploited during rekeying.
-.LP
-Some of these routing characteristics are specific to \fBKLIPS\fP, the FreeS/WAN
-implementation of IPsec and are not relevant when running pluto on the native
-Linux 2.6 IPsec stack.
-.SS Using Whack
-.LP
-\fBwhack\fP is used to command a running \fBpluto\fP.
-\fBwhack\fP uses a UNIX domain socket to speak to \fBpluto\fP
-(by default, \fI/var/pluto.ctl\fP).
-.LP
-\fBwhack\fP has an intricate argument syntax.
-This syntax allows many different functions to be specified.
-The help form shows the usage or version information.
-The connection form gives \fBpluto\fP a description of a potential connection.
-The public key form informs \fBpluto\fP of the RSA public key for a potential peer.
-The delete form deletes a connection description and all SAs corresponding
-to it.
-The listen form tells \fBpluto\fP to start or stop listening on the public interfaces
-for IKE requests from peers.
-The route form tells \fBpluto\fP to set up routing for a connection;
-the unroute form undoes this.
-The initiate form tells \fBpluto\fP to negotiate an SA corresponding to a connection.
-The terminate form tells \fBpluto\fP to remove all SAs corresponding to a connection,
-including those being negotiated.
-The status form displays the \fBpluto\fP's internal state.
-The debug form tells \fBpluto\fP to change the selection of debugging output
-``on the fly''.  The shutdown form tells
-\fBpluto\fP to shut down, deleting all SAs.
-.LP
-Most options are specific to one of the forms, and will be described
-with that form.  There are three options that apply to all forms.
-.TP
-\fB\-\-ctlbase\fP\ \fIpath\fP
-\fIpath\fP.ctl is used as the UNIX domain socket for talking
-to \fBpluto\fP.
-This option facilitates debugging.
-.TP
-\fB\-\-optionsfrom\fP\ \fIfilename\fP
-adds the contents of the file to the argument list.
-.TP
-\fB\-\-label\fP\ \fIstring\fP
-adds the string to all error messages generated by \fBwhack\fP.
-.LP
-The help form of \fBwhack\fP is self-explanatory.
-.TP
-\fB\-\-help\fP
-display the usage message.
-.TP
-\fB\-\-version\fP
-display the version of \fBwhack\fP.
-.LP
-The connection form describes a potential connection to \fBpluto\fP.
-\fBpluto\fP needs to know what connections can and should be negotiated.
-When \fBpluto\fP is the initiator, it needs to know what to propose.
-When \fBpluto\fP is the responder, it needs to know enough to decide whether
-is is willing to set up the proposed connection.
-.LP
-The description of a potential connection can specify a large number
-of details.  Each connection has a unique name.  This name will appear
-in a updown shell command, so it should not contain punctuation
-that would make the command ill-formed.
-.TP
-\fB\-\-name\fP\ \fIconnection-name\fP
-.LP
-The topology of
-a connection is symmetric, so to save space here is half a picture:
-
-\ \ \ client_subnet<\-\->host:ikeport<\-\->nexthop<\-\-\-
-
-A similar trick is used in the flags.  The same flag names are used for
-both ends.  Those before the \fB\-\-to\fP flag describe the left side
-and those afterwards describe the right side.  When \fBpluto\fP attempts
-to use the connection, it decides whether it is the left side or the right
-side of the connection, based on the IP numbers of its interfaces.
-.TP
-\fB\-\-id\fP\ \fIid\fP
-the identity of the end.  Currently, this can be an IP address (specified
-as dotted quad or as a Fully Qualified Domain Name, which will be resolved
-immediately) or as a Fully Qualified Domain Name itself (prefixed by ``@''
-to signify that it should not be resolved), or as user@FQDN, or as the
-magic value \fB%myid\fP.
-\fBPluto\fP only authenticates the identity, and does not use it for
-addressing, so, for example, an IP address need not be the one to which
-packets are to be sent.  If the option is absent, the
-identity defaults to the IP address specified by \fB\-\-host\fP.
-\fB%myid\fP allows the identity to be separately specified (by the \fBpluto\fP or \fBwhack\fP option \fB\-\-myid\fP
-or by the \fBipsec.conf\fP(5) \fBconfig setup\fP parameter \fPmyid\fP).
-Otherwise, \fBpluto\fP tries to guess what \fB%myid\fP should stand for:
-the IP address of \fB%defaultroute\fP, if it is supported by a suitable TXT record in the reverse domain for that IP address,
-or the system's hostname, if it is supported by a suitable TXT record in its forward domain.
-.\" The identity is transmitted in the IKE protocol, and is what is authenticated.
-.TP
-\fB\-\-host\fP\ \fIip\(hyaddress\fP
-.TP
-\fB\-\-host\fP\ \fB%any\fP
-.TP
-\fB\-\-host\fP\ \fB%opportunistic\fP
-the IP address of the end (generally the public interface).
-If \fBpluto\fP is to act as a responder
-for IKE negotiations initiated from unknown IP addresses (the
-``Road Warrior'' case), the
-IP address should be specified as \fB%any\fP (currently,
-the obsolete notation \fB0.0.0.0\fP is also accepted for this).
-If \fBpluto\fP is to opportunistically initiate the connection,
-use \fB%opportunistic\fP
-.TP
-\fB\-\-ikeport\fP\ \fIport\(hynumber\fP
-the UDP port that IKE listens to on that host.  The default is 500.
-(\fBpluto\fP on this machine uses the port specified by its own command
-line argument, so this only affects where \fBpluto\fP sends messages.)
-.TP
-\fB\-\-nexthop\fP\ \fIip\(hyaddress\fP
-where to route packets for the peer's client (presumably for the peer too,
-but it will not be used for this).
-When \fBpluto\fP installs an IPsec SA, it issues a route command.
-It uses the nexthop as the gateway.
-The default is the peer's IP address (this can be explicitly written as
-\fB%direct\fP; the obsolete notation \fB0.0.0.0\fP is accepted).
-This option is necessary if \fBpluto\fP's host's interface used for sending
-packets to the peer is neither point-to-point nor directly connected to the
-peer.
-.TP
-\fB\-\-client\fP\ \fIsubnet\fP
-the subnet for which the IPsec traffic will be destined.  If not specified,
-the host will be the client.
-The subnet can be specified in any of the forms supported by \fIipsec_atosubnet\fP(3).
-The general form is \fIaddress\fP/\fImask\fP.  The \fIaddress\fP can be either
-a domain name or four decimal numbers (specifying octets) separated by dots.
-The most convenient form of the \fImask\fP is a decimal integer, specifying
-the number of leading one bits in the mask.  So, for example, 10.0.0.0/8
-would specify the class A network ``Net 10''.
-.TP
-\fB\-\-dnskeyondemand]\fP
-specifies that when an RSA public key is needed to authenticate this
-host, and it isn't already known, fetch it from DNS.
-.TP
-\fB\-\-updown\fP\ \fIupdown\fP
-specifies an external shell command to be run whenever \fBpluto\fP
-brings up or down a connection.
-The script is used to build a shell command, so it may contain positional
-parameters, but ought not to have punctuation that would cause the
-resulting command to be ill-formed.
-The default is \fIipsec _updown\fP.
-.TP
-\fB\-\-to\fP
-separates the specification of the left and right ends of the connection.
-.LP
-The potential connection description also specifies characteristics of
-rekeying and security.
-.TP
-\fB\-\-psk\fP
-Propose and allow preshared secret authentication for IKE peers.  This authentication
-requires that each side use the same secret.  May be combined with \fB\-\-rsasig\fP;
-at least one must be specified.
-.TP
-\fB\-\-rsasig\fP
-Propose and allow RSA signatures for authentication of IKE peers.  This authentication
-requires that each side have have a private key of its own and know the
-public key of its peer.  May be combined with \fB\-\-psk\fP;
-at least one must be specified.
-.TP
-\fB\-\-encrypt\fP
-All proposed or accepted IPsec SAs will include non-null ESP.
-The actual choices of transforms are wired into \fBpluto\fP.
-.TP
-\fB\-\-authenticate\fP
-All proposed IPsec SAs will include AH.
-All accepted IPsec SAs will include AH or ESP with authentication.
-The actual choices of transforms are wired into \fBpluto\fP.
-Note that this has nothing to do with IKE authentication.
-.TP
-\fB\-\-compress\fP
-All proposed IPsec SAs will include IPCOMP (compression).
-This will be ignored if the kernel is not configured with IPCOMP support.
-.TP
-\fB\-\-tunnel\fP
-the IPsec SA should use tunneling.  Implicit if the SA is for clients.
-Must only be used with \fB\-\-authenticate\fP or \fB\-\-encrypt\fP.
-.TP
-\fB\-\-ipv4\fP
-The host addresses will be interpreted as IPv4 addresses.  This is the
-default.  Note that for a connection, all host addresses must be of
-the same Address Family (IPv4 and IPv6 use different Address Families).
-.TP
-\fB\-\-ipv6\fP
-The host addresses (including nexthop) will be interpreted as IPv6 addresses.
-Note that for a connection, all host addresses must be of
-the same Address Family (IPv4 and IPv6 use different Address Families).
-.TP
-\fB\-\-tunnelipv4\fP
-The client addresses will be interpreted as IPv4 addresses.  The default is
-to match what the host will be.  This does not imply \fB\-\-tunnel\fP so the
-flag can be safely used when no tunnel is actually specified.
-Note that for a connection, all tunnel addresses must be of the same
-Address Family.
-.TP
-\fB\-\-tunnelipv6\fP
-The client addresses will be interpreted as IPv6 addresses.  The default is
-to match what the host will be.  This does not imply \fB\-\-tunnel\fP so the
-flag can be safely used when no tunnel is actually specified.
-Note that for a connection, all tunnel addresses must be of the same
-Address Family.
-.TP
-\fB\-\-pfs\fP
-There should be Perfect Forward Secrecy \- new keying material will
-be generated for each IPsec SA rather than being derived from the ISAKMP
-SA keying material.
-Since the group to be used cannot be negotiated (a dubious feature of the
-standard), \fBpluto\fP will propose the same group that was used during Phase 1.
-We don't implement a stronger form of PFS which would require that the
-ISAKMP SA be deleted after the IPSEC SA is negotiated.
-.TP
-\fB\-\-disablearrivalcheck\fP
-If the connection is a tunnel, allow packets arriving through the tunnel
-to have any source and destination addresses.
-.LP
-If none of the \fB\-\-encrypt\fP, \fB\-\-authenticate\fP, \fB\-\-compress\fP,
-or \fB\-\-pfs\fP flags is given, the initiating the connection will
-only build an ISAKMP SA.  For such a connection, client subnets have
-no meaning and must not be specified.
-.LP
-More work is needed to allow for flexible policies.  Currently
-policy is hardwired in the source file spdb.c.  The ISAKMP SAs may use
-Oakley groups MODP1024 and MODP1536; 3DES encryption; SHA1-96
-and MD5-96 authentication.  The IPsec SAs may use 3DES and
-MD5-96 or SHA1-96 for ESP, or just MD5-96 or SHA1-96 for AH.
-IPCOMP Compression is always Deflate.
-.TP
-\fB\-\-ikelifetime\fP\ \fIseconds\fP
-how long \fBpluto\fP will propose that an ISAKMP SA be allowed to live.
-The default is 10800 (three hours) and the maximum is 86400 (one day).
-This option will not affect what is accepted.
-\fBpluto\fP will reject proposals that exceed the maximum.
-.TP
-\fB\-\-ipseclifetime\fP\ \fIseconds\fP
-how long \fBpluto\fP will propose that an IPsec SA be allowed to live.
-The default is 3600 (one hour) and the maximum is 86400 (one day).
-This option will not affect what is accepted.
-\fBpluto\fP will reject proposals that exceed the maximum.
-.TP
-\fB\-\-rekeymargin\fP\ \fIseconds\fP
-how long before an SA's expiration should \fBpluto\fP try to negotiate
-a replacement SA.  This will only happen if \fBpluto\fP was the initiator.
-The default is 540 (nine minutes).
-.TP
-\fB\-\-rekeyfuzz\fP\ \fIpercentage\fP
-maximum size of random component to add to rekeymargin, expressed as
-a percentage of rekeymargin.  \fBpluto\fP will select a delay uniformly
-distributed within this range.  By default, the percentage will be 100.
-If greater determinism is desired, specify 0.  It may be appropriate
-for the percentage to be much larger than 100.
-.TP
-\fB\-\-keyingtries\fP\ \fIcount\fP
-how many times \fBpluto\fP should try to negotiate an SA,
-either for the first time or for rekeying.
-A value of 0 is interpreted as a very large number: never give up.
-The default is three.
-.TP
-\fB\-\-dontrekey\fP
-A misnomer.
-Only rekey a connection if we were the Initiator and there was recent
-traffic on the existing connection.
-This applies to Phase 1 and Phase 2.
-This is currently the only automatic way for a connection to terminate.
-It may be useful with Road Warrior or Opportunistic connections.
-.br
-Since SA lifetime negotiation is take-it-or-leave it, a Responder
-normally uses the shorter of the negotiated or the configured lifetime.
-This only works because if the lifetime is shorter than negotiated,
-the Responder will rekey in time so that everything works.
-This interacts badly with \fB\-\-dontrekey\fP.  In this case,
-the Responder will end up rekeying to rectify a shortfall in an IPsec SA
-lifetime; for an ISAKMP SA, the Responder will accept the negotiated
-lifetime.
-.TP
-\fB\-\-delete\fP
-when used in the connection form, it causes any previous connection
-with this name to be deleted before this one is added.  Unlike a
-normal delete, no diagnostic is produced if there was no previous
-connection to delete.  Any routing in place for the connection is undone.
-.LP
-The delete form deletes a named connection description and any
-SAs established or negotiations initiated using this connection.
-Any routing in place for the connection is undone.
-.TP
-\fB\-\-delete\fP
-.TP
-\fB\-\-name\fP\ \fIconnection-name\fP
-.LP
-The deletestate form deletes the state object with the specified serial number.
-This is useful for selectively deleting instances of connections.
-.TP
-\fB\-\-deletestate\fP\ \fIstate-number\fP
-.LP
-The route form of the \fBwhack\fP command tells \fBpluto\fP to set up
-routing for a connection.
-Although like a traditional route, it uses an ipsec device as a
-virtual interface.
-Once routing is set up, no packets will be
-sent ``in the clear'' to the peer's client specified in the connection.
-A TRAP shunt eroute will be installed; if outbound traffic is caught,
-Pluto will initiate the connection.
-An explicit \fBwhack\fP route is not always needed: if it hasn't been
-done when an IPsec SA is being installed, one will be automatically attempted.
-.LP
-When a routing is attempted for a connection, there must not already
-be a routing for a different connection with the same subnet but different
-interface or destination, or if
-there is, it must not be being used by an IPsec SA.  Otherwise the
-attempt will fail.
-.TP
-\fB\-\-route\fP
-.TP
-\fB\-\-name\fP\ \fIconnection-name\fP
-.LP
-The unroute form of the \fBwhack\fP command tells \fBpluto\fP to undo
-a routing.  \fBpluto\fP will refuse if an IPsec SA is using the connection.
-If another connection is sharing the same routing, it will be left in place.
-Without a routing, packets will be sent without encryption or authentication.
-.TP
-\fB\-\-unroute\fP
-.TP
-\fB\-\-name\fP\ \fIconnection-name\fP
-.LP
-The initiate form tells \fBpluto\fP to initiate a negotiation with another
-\fBpluto\fP (or other IKE daemon) according to the named connection.
-Initiation requires a route that \fB\-\-route\fP would provide;
-if none is in place at the time an IPsec SA is being installed,
-\fBpluto\fP attempts to set one up.
-.TP
-\fB\-\-initiate\fP
-.TP
-\fB\-\-name\fP\ \fIconnection-name\fP
-.TP
-\fB\-\-asynchronous
-.LP
-The initiate form of the \fBwhack\fP command will relay back from
-\fBpluto\fP status information via the UNIX domain socket (unless
-\-\-asynchronous is specified).  The status information is meant to
-look a bit like that from \fBFTP\fP.  Currently \fBwhack\fP simply
-copies this to stderr.  When the request is finished (eg. the SAs are
-established or \fBpluto\fP gives up), \fBpluto\fP closes the channel,
-causing \fBwhack\fP to terminate.
-.LP
-The opportunistic initiate form is mainly used for debugging.
-.TP
-\fB\-\-tunnelipv4\fP
-.TP
-\fB\-\-tunnelipv6\fP
-.TP
-\fB\-\-oppohere\fP\ \fIip-address\fP
-.TP
-\fB\-\-oppothere\fP\ \fIip-address\fP
-.LP
-This will cause \fBpluto\fP to attempt to opportunistically initiate a
-connection from here to the there, even if a previous attempt
-had been made.
-The whack log will show the progress of this attempt.
-.LP
-The terminate form tells \fBpluto\fP to delete any SAs that use the specified
-connection and to stop any negotiations in process.
-It does not prevent new negotiations from starting (the delete form
-has this effect).
-.TP
-\fB\-\-terminate\fP
-.TP
-\fB\-\-name\fP\ \fIconnection-name\fP
-.LP
-The public key for informs \fBpluto\fP of the RSA public key for a potential peer.
-Private keys must be kept secret, so they are kept in
-.IR ipsec.secrets (5).
-.TP
-\fB\-\-keyid\ \fP\fIid\fP
-specififies the identity of the peer for which a public key should be used.
-Its form is identical to the identity in the connection.
-If no public key is specified, \fBpluto\fP attempts to find KEY records
-from DNS for the id (if a FQDN) or through reverse lookup (if an IP address).
-Note that there several interesting ways in which this is not secure.
-.TP
-\fB\-\-addkey\fP
-specifies that the new key is added to the collection; otherwise the
-new key replaces any old ones.
-.TP
-\fB\-\-pubkeyrsa\ \fP\fIkey\fP
-specifies the value of the RSA public key.  It is a sequence of bytes
-as described in RFC 2537 ``RSA/MD5 KEYs and SIGs in the Domain Name System (DNS)''.
-It is denoted in a way suitable for \fIipsec_ttodata\fP(3).
-For example, a base 64 numeral starts with 0s.
-.LP
-The listen form tells \fBpluto\fP to start listening for IKE requests
-on its public interfaces.  To avoid race conditions, it is normal to
-load the appropriate connections into \fBpluto\fP before allowing it
-to listen.  If \fBpluto\fP isn't listening, it is pointless to
-initiate negotiations, so it will refuse requests to do so.  Whenever
-the listen form is used, \fBpluto\fP looks for public interfaces and
-will notice when new ones have been added and when old ones have been
-removed.  This is also the trigger for \fBpluto\fP to read the
-\fIipsec.secrets\fP file.  So listen may useful more than once.
-.TP
-\fB\-\-listen\fP
-start listening for IKE traffic on public interfaces.
-.TP
-\fB\-\-unlisten\fP
-stop listening for IKE traffic on public interfaces.
-.LP
-The status form will display information about the internal state of
-\fBpluto\fP: information about each potential connection, about
-each state object, and about each shunt that \fBpluto\fP is managing
-without an associated connection.
-.TP
-\fB\-\-status\fP
-.LP
-The shutdown form is the proper way to shut down \fBpluto\fP.
-It will tear down the SAs on this machine that \fBpluto\fP has negotiated.
-It does not inform its peers, so the SAs on their machines remain.
-.TP
-\fB\-\-shutdown\fP
-.SS Examples
-.LP
-It would be normal to start \fBpluto\fP in one of the system initialization
-scripts.  It needs to be run by the superuser.  Generally, no arguments are needed.
-To run in manually, the superuser can simply type
-
-\ \ \ ipsec pluto
-
-The command will immediately return, but a \fBpluto\fP process will be left
-running, waiting for requests from \fBwhack\fP or a peer.
-.LP
-Using \fBwhack\fP, several potential connections would be described:
-.HP
-.na
-\ \ \ ipsec whack \-\-name\ silly
-\-\-host\ 127.0.0.1 \-\-to \-\-host\ 127.0.0.2
-\-\-ikelifetime\ 900 \-\-ipseclifetime\ 800 \-\-keyingtries\ 3
-.ad
-.LP
-Since this silly connection description specifies neither encryption,
-authentication, nor tunneling, it could only be used to establish
-an ISAKMP SA.
-.HP
-.na
-\ \ \ ipsec whack \-\-name\ secret \-\-host\ 10.0.0.1 \-\-client\ 10.0.1.0/24
-\-\-to \-\-host\ 10.0.0.2 \-\-client\ 10.0.2.0/24
-\-\-encrypt
-.ad
-.LP
-This is something that must be done on both sides.  If the other
-side is \fBpluto\fP, the same \fBwhack\fP command could be used on it
-(the command syntax is designed to not distinguish which end is ours).
-.LP
-Now that the connections are specified, \fBpluto\fP is ready to handle
-requests and replies via the public interfaces.  We must tell it to discover
-those interfaces and start accepting messages from peers:
-
-\ \ \ ipsec whack \-\-listen
-.LP
-If we don't immediately wish to bring up a secure connection between
-the two clients, we might wish to prevent insecure traffic.
-The routing form asks \fBpluto\fP to cause the packets sent from
-our client to the peer's client to be routed through the ipsec0
-device; if there is no SA, they will be discarded:
-
-\ \ \ ipsec whack \-\-route secret
-.LP
-Finally, we are ready to get \fBpluto\fP to initiate negotiation
-for an IPsec SA (and implicitly, an ISAKMP SA):
-
-\ \ \ ipsec whack \-\-initiate\ \-\-name\ secret
-
-A small log of interesting events will appear on standard output
-(other logging is sent to syslog).
-.LP
-\fBwhack\fP can also be used to terminate \fBpluto\fP cleanly, tearing down
-all SAs that it has negotiated.
-
-\ \ \ ipsec whack \-\-shutdown
-
-Notification of any IPSEC SA deletion, but not ISAKMP SA deletion
-is sent to the peer.  Unfortunately, such Notification is not reliable.
-Furthermore, \fBpluto\fP itself ignores Notifications.
-.SS The updown command
-.LP
-Whenever \fBpluto\fP brings a connection up or down, it invokes
-the updown command.  This command is specified using the \fB\-\-updown\fP
-option.  This allows for customized control over routing and firewall manipulation.
-.LP
-The updown is invoked for five different operations.  Each of
-these operations can be for our client subnet or for our host itself.
-.TP
-\fBprepare-host\fP or \fBprepare-client\fP
-is run before bringing up a new connection if no other connection
-with the same clients is up.  Generally, this is useful for deleting a
-route that might have been set up before \fBpluto\fP was run or
-perhaps by some agent not known to \fBpluto\fP.
-.TP
-\fBroute-host\fP or \fBroute-client\fP
-is run when bringing up a connection for a new peer client subnet
-(even if \fBprepare-host\fP or \fBprepare-client\fP was run).  The
-command should install a suitable route.  Routing decisions are based
-only on the destination (peer's client) subnet address, unlike eroutes
-which discriminate based on source too.
-.TP
-\fBunroute-host\fP or \fBunroute-client\fP
-is run when bringing down the last connection for a particular peer
-client subnet.  It should undo what the \fBroute-host\fP or \fBroute-client\fP
-did.
-.TP
-\fBup-host\fP or \fBup-client\fP
-is run when bringing up a tunnel eroute with a pair of client subnets
-that does not already have a tunnel eroute.
-This command should install firewall rules as appropriate.
-It is generally a good idea to allow IKE messages (UDP port 500)
-travel between the hosts.
-.TP
-\fBdown-host\fP or \fBdown-client\fP
-is run when bringing down the eroute for a pair of client subnets.
-This command should delete firewall rules as appropriate.  Note that
-there may remain some inbound IPsec SAs with these client subnets.
-.LP
-The script is passed a large number of environment variables to specify
-what needs to be done.
-.TP
-\fBPLUTO_VERSION\fP
-indicates what version of this interface is being used.  This document
-describes version 1.1.  This is upwardly compatible with version 1.0.
-.TP
-\fBPLUTO_VERB\fP
-specifies the name of the operation to be performed
-(\fBprepare-host\fP,r \fBprepare-client\fP,
-\fBup-host\fP, \fBup-client\fP,
-\fBdown-host\fP, or \fBdown-client\fP).  If the address family for
-security gateway to security gateway communications is IPv6, then
-a suffix of \-v6 is added to the verb.
-.TP
-\fBPLUTO_CONNECTION\fP
-is the name of the connection for which we are routing.
-.TP
-\fBPLUTO_NEXT_HOP\fP
-is the next hop to which packets bound for the peer must be sent.
-.TP
-\fBPLUTO_INTERFACE\fP
-is the name of the ipsec interface to be used.
-.TP
-\fBPLUTO_ME\fP
-is the IP address of our host.
-.TP
-\fBPLUTO_MY_CLIENT\fP
-is the IP address / count of our client subnet.
-If the client is just the host, this will be the host's own IP address / max
-(where max is 32 for IPv4 and 128 for IPv6).
-.TP
-\fBPLUTO_MY_CLIENT_NET\fP
-is the IP address of our client net.
-If the client is just the host, this will be the host's own IP address.
-.TP
-\fBPLUTO_MY_CLIENT_MASK\fP
-is the mask for our client net.
-If the client is just the host, this will be 255.255.255.255.
-.TP
-\fBPLUTO_PEER\fP
-is the IP address of our peer.
-.TP
-\fBPLUTO_PEER_CLIENT\fP
-is the IP address / count of the peer's client subnet.
-If the client is just the peer, this will be the peer's own IP address / max
-(where max is 32 for IPv4 and 128 for IPv6).
-.TP
-\fBPLUTO_PEER_CLIENT_NET\fP
-is the IP address of the peer's client net.
-If the client is just the peer, this will be the peer's own IP address.
-.TP
-\fBPLUTO_PEER_CLIENT_MASK\fP
-is the mask for the peer's client net.
-If the client is just the peer, this will be 255.255.255.255.
-.LP
-All output sent by the script to stderr or stdout is logged.  The
-script should return an exit status of 0 if and only if it succeeds.
-.LP
-\fBPluto\fP waits for the script to finish and will not do any other
-processing while it is waiting.
-The script may assume that \fBpluto\fP will not change anything
-while the script runs.
-The script should avoid doing anything that takes much time and it
-should not issue any command that requires processing by \fBpluto\fP.
-Either of these activities could be performed by a background
-subprocess of the script.
-.SS Rekeying
-.LP
-When an SA that was initiated by \fBpluto\fP has only a bit of
-lifetime left,
-\fBpluto\fP will initiate the creation of a new SA.  This applies to
-ISAKMP and IPsec SAs.
-The rekeying will be initiated when the SA's remaining lifetime is
-less than the rekeymargin plus a random percentage, between 0 and
-rekeyfuzz, of the rekeymargin.
-.LP
-Similarly, when an SA that was initiated by the peer has only a bit of
-lifetime left, \fBpluto\fP will try to initiate the creation of a
-replacement.
-To give preference to the initiator, this rekeying will only be initiated
-when the SA's remaining lifetime is half of rekeymargin.
-If rekeying is done by the responder, the roles will be reversed: the
-responder for the old SA will be the initiator for the replacement.
-The former initiator might also initiate rekeying, so there may
-be redundant SAs created.
-To avoid these complications, make sure that rekeymargin is generous.
-.LP
-One risk of having the former responder initiate is that perhaps
-none of its proposals is acceptable to the former initiator
-(they have not been used in a successful negotiation).
-To reduce the chances of this happening, and to prevent loss of security,
-the policy settings are taken from the old SA (this is the case even if
-the former initiator is initiating).
-These may be stricter than those of the connection.
-.LP
-\fBpluto\fP will not rekey an SA if that SA is not the most recent of its
-type (IPsec or ISAKMP) for its potential connection.
-This avoids creating redundant SAs.
-.LP
-The random component in the rekeying time (rekeyfuzz) is intended to
-make certain pathological patterns of rekeying unstable.  If both
-sides decide to rekey at the same time, twice as many SAs as necessary
-are created.  This could become a stable pattern without the
-randomness.
-.LP
-Another more important case occurs when a security gateway has SAs
-with many other security gateways.  Each of these connections might
-need to be rekeyed at the same time.  This would cause a high peek
-requirement for resources (network bandwidth, CPU time, entropy for
-random numbers).  The rekeyfuzz can be used to stagger the rekeying
-times.
-.LP
-Once a new set of SAs has been negotiated, \fBpluto\fP will never send
-traffic on a superseded one.  Traffic will be accepted on an old SA
-until it expires.
-.SS Selecting a Connection When Responding: Road Warrior Support
-.LP
-When \fBpluto\fP receives an initial Main Mode message, it needs to
-decide which connection this message is for.  It picks based solely on
-the source and destination IP addresses of the message.  There might
-be several connections with suitable IP addresses, in which case one
-of them is arbitrarily chosen.  (The ISAKMP SA proposal contained in
-the message could be taken into account, but it is not.)
-.LP
-The ISAKMP SA is negotiated before the parties pass further
-identifying information, so all ISAKMP SA characteristics specified in
-the connection description should be the same for every connection
-with the same two host IP addresses.  At the moment, the only
-characteristic that might differ is authentication method.
-.LP
-Up to this point,
-all configuring has presumed that the IP addresses
-are known to all parties ahead of time.  This will not work
-when either end is mobile (or assigned a dynamic IP address for other
-reasons).  We call this situation ``Road Warrior''.  It is fairly tricky
-and has some important limitations, most of which are features of
-the IKE protocol.
-.LP
-Only the initiator may be mobile:
-the initiator may have an IP number unknown to the responder.  When
-the responder doesn't recognize the IP address on the first Main Mode
-packet, it looks for a connection with itself as one end and \fB%any\fP
-as the other.
-If it cannot find one, it refuses to negotiate.  If it
-does find one, it creates a temporary connection that is a duplicate
-except with the \fB%any\fP replaced by the source IP address from the
-packet; if there was no identity specified for the peer, the new IP
-address will be used.
-.LP
-When \fBpluto\fP is using one of these temporary connections and
-needs to find the preshared secret or RSA private key in \fIipsec.secrets\fP,
-and and the connection specified no identity for the peer, \fB%any\fP
-is used as its identity.  After all, the real IP address was apparently
-unknown to the configuration, so it is unreasonable to require that
-it be used in this table.
-.LP
-Part way into the Phase 1 (Main Mode) negotiation using one of these
-temporary connection descriptions, \fBpluto\fP will be receive an
-Identity Payload.  At this point, \fBpluto\fP checks for a more
-appropriate connection, one with an identity for the peer that matches
-the payload but which would use the same keys so-far used for
-authentication.  If it finds one, it will switch to using this better
-connection (or a temporary derived from this, if it has \fB%any\fP
-for the peer's IP address).  It may even turn out that no connection
-matches the newly discovered identity, including the current connection;
-if so, \fBpluto\fP terminates negotiation.
-.LP
-Unfortunately, if preshared secret authentication is being used, the
-Identity Payload is encrypted using this secret, so the secret must be
-selected by the responder without knowing this payload.  This
-limits there to being at most one preshared secret for all Road Warrior
-systems connecting to a host.  RSA Signature authentications does not
-require that the responder know how to select the initiator's public key
-until after the initiator's Identity Payload is decoded (using the
-responder's private key, so that must be preselected).
-.LP
-When \fBpluto\fP is responding to a Quick Mode negotiation via one of these
-temporary connection descriptions, it may well find that the subnets
-specified by the initiator don't match those in the temporary
-connection description.  If so, it will look for a connection with
-matching subnets, its own host address, a peer address of \fB%any\fP
-and matching identities.
-If it finds one, a new temporary connection is derived from this one
-and used for the Quick Mode negotiation of IPsec SAs.  If it does not
-find one, \fBpluto\fP terminates negotiation.
-.LP
-Be sure to specify an appropriate nexthop for the responder
-to send a message to the initiator: \fBpluto\fP has no way of guessing
-it (if forwarding isn't required, use an explicit \fB%direct\fP as the nexthop
-and the IP address of the initiator will be filled in; the obsolete
-notation \fB0.0.0.0\fP is still accepted).
-.LP
-\fBpluto\fP has no special provision for the initiator side.  The current
-(possibly dynamic) IP address and nexthop must be used in defining
-connections.  These must be
-properly configured each time the initiator's IP address changes.
-\fBpluto\fP has no mechanism to do this automatically.
-.LP
-Although we call this Road Warrior Support, it could also be used to
-support encrypted connections with anonymous initiators.  The
-responder's organization could announce the preshared secret that would be used
-with unrecognized initiators and let anyone connect.  Of course the initiator's
-identity would not be authenticated.
-.LP
-If any Road Warrior connections are supported, \fBpluto\fP cannot
-reject an exchange initiated by an unknown host until it has
-determined that the secret is not shared or the signature is invalid.
-This must await the
-third Main Mode message from the initiator.  If no Road Warrior
-connection is supported, the first message from an unknown source
-would be rejected.  This has implications for ease of debugging
-configurations and for denial of service attacks.
-.LP
-Although a Road Warrior connection must be initiated by the mobile
-side, the other side can and will rekey using the temporary connection
-it has created.  If the Road Warrior wishes to be able to disconnect,
-it is probably wise to set \fB\-\-keyingtries\fP to 1 in the
-connection on the non-mobile side to prevent it trying to rekey the
-connection.  Unfortunately, there is no mechanism to unroute the
-connection automatically.
-.SS Debugging
-.LP
-\fBpluto\fP accepts several optional arguments, useful mostly for debugging.
-Except for \fB\-\-interface\fP, each should appear at most once.
-.TP
-\fB\-\-interface\fP \fIinterfacename\fP
-specifies that the named real public network interface should be considered.
-The interface name specified should not be \fBipsec\fP\fIN\fP.
-If the option doesn't appear, all interfaces are considered.
-To specify several interfaces, use the option once for each.
-One use of this option is to specify which interface should be used
-when two or more share the same IP address.
-.TP
-\fB\-\-ikeport\fP \fIport-number\fP
-changes the UDP port that \fBpluto\fP will use
-(default, specified by IANA: 500)
-.TP
-\fB\-\-ctlbase\fP \fIpath\fP
-basename for control files.
-\fIpath\fP.ctl is the socket through which \fBwhack\fP communicates with
-\fBpluto\fP.
-\fIpath\fP.pid is the lockfile to prevent multiple \fBpluto\fP instances.
-The default is \fI/var/run/pluto\fP).
-.TP
-\fB\-\-secretsfile\fP \fIfile\fP
-specifies the file for authentication secrets
-(default: \fI/etc/ipsec.secrets\fP).
-This name is subject to ``globbing'' as in \fIsh\fP(1),
-so every file with a matching name is processed.
-Quoting is generally needed to prevent the shell from doing the globbing.
-.TP
-\fB\-\-adns\fP \fIpathname\fP
-.TP
-\fB\-\-lwdnsq\fP \fIpathname\fP
-specifies where to find \fBpluto\fP's helper program for asynchronous DNS lookup.
-\fBpluto\fP can be built to use one of two helper programs: \fB_pluto_adns\fP
-or \fBlwdnsq\fP.  You must use the program for which it was built.
-By default, \fBpluto\fP will look for the program in
-\fB$IPSEC_DIR\fP (if that environment variable is defined) or, failing that,
-in the same directory as \fBpluto\fP.
-.TP
-\fB\-\-nofork\fP
-disable ``daemon fork'' (default is to fork).  In addition, after the
-lock file and control socket are created, print the line ``Pluto
-initialized'' to standard out.
-.TP
-\fB\-\-uniqueids\fP
-if this option has been selected, whenever a new ISAKMP SA is
-established, any connection with the same Peer ID but a different
-Peer IP address is unoriented (causing all its SAs to be deleted).
-This helps clean up dangling SAs when a connection is lost and
-then regained at another IP address.
-.TP
-\fB\-\-stderrlog\fP
-log goes to standard out {default is to use \fIsyslogd\fP(8))
-.LP
-\fBpluto\fP is willing to produce a prodigious amount of debugging
-information.  To do so, it must be compiled with \-DDEBUG.  There are
-several classes of debugging output, and \fBpluto\fP may be directed to
-produce a selection of them.  All lines of
-debugging output are prefixed with ``|\ '' to distinguish them from error
-messages.
-.LP
-When \fBpluto\fP is invoked, it may be given arguments to specify
-which classes to output.  The current options are:
-.TP
-\fB\-\-debug-raw\fP
-show the raw bytes of messages
-.TP
-\fB\-\-debug-crypt\fP
-show the encryption and decryption of messages
-.TP
-\fB\-\-debug-parsing\fP
-show the structure of input messages
-.TP
-\fB\-\-debug-emitting\fP
-show the structure of output messages
-.TP
-\fB\-\-debug-control\fP
-show \fBpluto\fP's decision making
-.TP
-\fB\-\-debug-lifecycle\fP
-[this option is temporary] log more detail of lifecycle of SAs
-.TP
-\fB\-\-debug-kernel\fP
-show \fBpluto\fP's interaction with the kernel
-.TP
-\fB\-\-debug-dns\fP
-show \fBpluto\fP's interaction with \fBDNS\fP for KEY and TXT records
-.TP
-\fB\-\-debug-oppo\fP
-show why \fBpluto\fP didn't find a suitable DNS TXT record to authorize opportunistic initiation
-.TP
-\fB\-\-debug-all\fP
-all of the above
-.TP
-\fB\-\-debug-private\fP
-allow debugging output with private keys.
-.TP
-\fB\-\-debug-none\fP
-none of the above
-.LP
-The debug form of the
-\fBwhack\fP command will change the selection in a running
-\fBpluto\fP.
-If a connection name is specified, the flags are added whenever
-\fBpluto\fP has identified that it is dealing with that connection.
-Unfortunately, this is often part way into the operation being observed.
-.LP
-For example, to start a \fBpluto\fP with a display of the structure of input
-and output:
-.IP
-pluto \-\-debug-emitting \-\-debug-parsing
-.LP
-To later change this \fBpluto\fP to only display raw bytes:
-.IP
-whack \-\-debug-raw
-.LP
-For testing, SSH's IKE test page is quite useful:
-.IP
-\fIhttp://isakmp-test.ssh.fi/\fP
-.LP
-Hint: ISAKMP SAs are often kept alive by IKEs even after the IPsec SA
-is established.  This allows future IPsec SA's to be negotiated
-directly.  If one of the IKEs is restarted, the other may try to use
-the ISAKMP SA but the new IKE won't know about it.  This can lead to
-much confusion.  \fBpluto\fP is not yet smart enough to get out of such a
-mess.
-.SS Pluto's Behaviour When Things Go Wrong
-.LP
-When \fBpluto\fP doesn't understand or accept a message, it just
-ignores the message.  It is not yet capable of communicating the
-problem to the other IKE daemon (in the future it might use
-Notifications to accomplish this in many cases).  It does log a diagnostic.
-.LP
-When \fBpluto\fP gets no response from a message, it resends the same
-message (a message will be sent at most three times).  This is
-appropriate: UDP is unreliable.
-.LP
-When pluto gets a message that it has already seen, there are many
-cases when it notices and discards it.  This too is appropriate for UDP.
-.LP
-Combine these three rules, and you can explain many apparently
-mysterious behaviours.  In a \fBpluto\fP log, retrying isn't usually the
-interesting event.  The critical thing is either earlier (\fBpluto\fP
-got a message which it didn't like and so ignored, so it was still
-awaiting an acceptable message and got impatient) or on the other
-system (\fBpluto\fP didn't send a reply because it wasn't happy with
-the previous message).
-.SS Notes
-.LP
-Each IPsec SA is assigned an SPI, a 32-bit number used to refer to the SA.
-The IKE protocol lets the destination of the SA choose the SPI.
-The range 0 to 0xFF is reserved for IANA.
-\fBPluto\fP also avoids choosing an SPI in the range 0x100 to 0xFFF,
-leaving these SPIs free for manual keying.
-Remember that the peer, if not \fBpluto\fP, may well chose
-SPIs in this range.
-.SS Policies
-.LP
-This catalogue of policies may be of use when trying to configure
-\fBPluto\fP and another IKE implementation to interoperate.
-.LP
-In Phase 1, only Main Mode is supported.  We are not sure that
-Aggressive Mode is secure.  For one thing, it does not support
-identity protection.  It may allow more severe Denial Of Service
-attacks.
-.LP
-No Informational Exchanges are supported.  These are optional and
-since their delivery is not assured, they must not matter.
-It is the case that some IKE implementations won't interoperate
-without Informational Exchanges, but we feel they are broken.
-.LP
-No Informational Payloads are supported.  These are optional, but
-useful.  It is of concern that these payloads are not authenticated in
-Phase 1, nor in those Phase 2 messages authenticated with HASH(3).
-.IP \(bu \w'\(bu\ 'u
-Diffie Hellman Groups MODP 1024 and MODP 1536 (2 and 5)
-are supported.
-Group MODP768 (1) is not supported because it is too weak.
-.IP \(bu
-Host authetication can be done by RSA Signatures or Pre-Shared
-Secrets.
-.IP \(bu
-3DES CBC (Cypher Block Chaining mode) is the only encryption
-supported, both for ISAKMP SAs and IPSEC SAs.
-.IP \(bu
-MD5 and SHA1 hashing are supported for packet authentication in both
-kinds of SAs.
-.IP \(bu
-The ESP, AH, or AH plus ESP are supported.  If, and only if, AH and
-ESP are combined, the ESP need not have its own authentication
-component.  The selection is controlled by the \-\-encrypt and
-\-\-authenticate flags.
-.IP \(bu
-Each of these may be combined with IPCOMP Deflate compression,
-but only if the potential connection specifies compression and only
-if the kernel is configured with IPCOMP support.
-.IP \(bu
-The IPSEC SAs may be tunnel or transport mode, where appropriate.
-The \-\-tunnel flag controls this when \fBpluto\fP is initiating.
-.IP \(bu
-When responding to an ISAKMP SA proposal, the maximum acceptable
-lifetime is eight hours.  The default is one hour.  There is no
-minimum.  The \-\-ikelifetime flag controls this when \fBpluto\fP
-is initiating.
-.IP \(bu
-When responding to an IPSEC SA proposal, the maximum acceptable
-lifetime is one day.  The default is eight hours.  There is no
-minimum.  The \-\-ipseclifetime flag controls this when \fBpluto\fP
-is initiating.
-.IP \(bu
-PFS is acceptable, and will be proposed if the \-\-pfs flag was
-specified.  The DH group proposed will be the same as negotiated for
-Phase 1.
-.SH SIGNALS
-.LP
-\fBPluto\fP responds to \fBSIGHUP\fP by issuing a suggestion that ``\fBwhack\fP
-\-\-listen'' might have been intended.
-.LP
-\fBPluto\fP exits when it receives \fBSIGTERM\fP.
-.SH EXIT STATUS
-.LP
-\fBpluto\fP normally forks a daemon process, so the exit status is
-normally a very preliminary result.
-.TP
-0
-means that all is OK so far.
-.TP
-1
-means that something was wrong.
-.TP
-10
-means that the lock file already exists.
-.LP
-If \fBwhack\fP detects a problem, it will return an exit status of 1.
-If it received progress messages from \fBpluto\fP, it returns as status
-the value of the numeric prefix from the last such message
-that was not a message sent to syslog or a comment
-(but the prefix for success is treated as 0).
-Otherwise, the exit status is 0.
-.SH FILES
-\fI/var/run/pluto.pid\fP
-.br
-\fI/var/run/pluto.ctl\fP
-.br
-\fI/etc/ipsec.secrets\fP
-.br
-\fI$IPSEC_LIBDIR/_pluto_adns\fP
-.br
-\fI$IPSEC_EXECDIR/lwdnsq\fP
-.br
-\fI/dev/urandom\fP
-.SH ENVIRONMENT
-\fIIPSEC_LIBDIR\fP
-.br
-\fIIPSEC_EXECDIR\fP
-.br
-\fIIPSECmyid\fP
-.SH SEE ALSO
-.LP
-The rest of the FreeS/WAN distribution, in particular \fIipsec\fP(8).
-.LP
-\fIipsec_auto\fP(8) is designed to make using \fBpluto\fP more pleasant.
-Use it!
-.LP
-.IR ipsec.secrets (5)
-describes the format of the secrets file.
-.LP
-\fIipsec_atoaddr\fP(3), part of the FreeS/WAN distribution, describes the
-forms that IP addresses may take.
-\fIipsec_atosubnet\fP(3), part of the FreeS/WAN distribution, describes the
-forms that subnet specifications.
-.LP
-For more information on IPsec, the mailing list, and the relevant
-documents, see:
-.IP
-.nh
-\fIhttp://www.ietf.cnri.reston.va.us/html.charters/ipsec-charter.html\fP
-.hy
-.LP
-At the time of writing, the most relevant IETF RFCs are:
-.IP
-RFC2409 The Internet Key Exchange (IKE)
-.IP
-RFC2408 Internet Security Association and Key Management Protocol (ISAKMP)
-.IP
-RFC2407 The Internet IP Security Domain of Interpretation for ISAKMP
-.LP
-The FreeS/WAN web site <htp://www.freeswan.org>
-and the mailing lists described there.
-.SH HISTORY
-This code is released under the GPL terms.
-See the accompanying file COPYING-2.0 for more details.
-The GPL does NOT apply to those pieces of code written by others
-which are included in this distribution, except as noted by the
-individual authors.
-.LP
-This software was originally written
-for the FreeS/WAN project
-<http://www.freeswan.org>
-by Angelos D. Keromytis
-(angelos@dsl.cis.upenn.edu), in May/June 1997, in Athens, Greece.
-Thanks go to John Ioannidis for his help.
-.LP
-It is currently (2000)
-being developed and maintained by D. Hugh Redelmeier
-(hugh@mimosa.com), in Canada.  The regulations of Greece and Canada
-allow us to make the code freely redistributable.
-.LP
-Kai Martius (admin@imib.med.tu-dresden.de) contributed the initial
-version of the code supporting PFS.
-.LP
-Richard Guy Briggs <rgb@conscoop.ottawa.on.ca> and Peter Onion
-<ponion@srd.bt.co.uk> added the PFKEY2 support.
-.LP
-We gratefully acknowledge that we use parts of Eric Young's \fIlibdes\fP
-package; see \fI../libdes/COPYRIGHT\fP.
-.SH BUGS
-.BR pluto
-is a work-in-progress.  It currently has many limitations.
-For example, it ignores notification messages that it receives, and
-it generates only Delete Notifications and those only for IPSEC SAs.
-.LP
-\fBpluto\fP does not support the Commit Flag.
-The Commit Flag is a bad feature of the IKE protocol.
-It isn't protected -- neither encrypted nor authenticated.
-A man in the middle could turn it on, leading to DoS.
-We just ignore it, with a warning.
-This should let us interoperate with
-implementations that insist on it, with minor damage.
-.LP
-\fBpluto\fP does not check that the SA returned by the Responder
-is actually one that was proposed.  It only checks that the SA is
-acceptable.  The difference is not large, but can show up in attributes
-such as SA lifetime.
-.LP
-There is no good way for a connection to be automatically terminated.
-This is a problem for Road Warrior and Opportunistic connections.
-The \fB\-\-dontrekey\fP option does prevent the SAs from
-being rekeyed on expiry.
-Additionally, if a Road Warrior connection has a client subnet with a fixed IP
-address, a negotiation with that subnet will cause any other
-connection instantiations with that same subnet to be unoriented
-(deleted, in effect).
-See also the \-\-uniqueids option for an extension of this.
-.LP
-When \fBpluto\fP sends a message to a peer that has disappeared,
-\fBpluto\fP receives incomplete information from the kernel, so it
-logs the unsatisfactory message ``some IKE message we sent has been
-rejected with ECONNREFUSED (kernel supplied no details)''.  John
-Denker suggests that this command is useful for tracking down the
-source of these problems:
-.br
-       tcpdump \-i eth0 icmp[0] != 8 and icmp[0] != 0
-.br
-Substitute your public interface for eth0 if it is different.
-.LP
-The word ``authenticate'' is used for two different features.  We must
-authenticate each IKE peer to the other.  This is an important task of
-Phase 1.  Each packet must be authenticated, both in IKE and in IPsec,
-and the method for IPsec is negotiated as an AH SA or part of an ESP SA.
-Unfortunately, the protocol has no mechanism for authenticating the Phase 2
-identities.
-.LP
-Bugs should be reported to the <users@lists.freeswan.org> mailing list.
-Caution: we cannot accept
-actual code from US residents, or even US citizens living outside the
-US, because that would bring FreeS/WAN under US export law.  Some
-other countries cause similar problems.  In general, we would prefer
-that you send detailed problem reports rather than code:  we want
-FreeS/WAN to be unquestionably freely exportable, which means being
-very careful about where the code comes from, and for a small bug fix,
-that is often more time-consuming than just reinventing the fix
-ourselves.
diff --git a/src/pluto/pluto.c b/src/pluto/pluto.c
deleted file mode 100644 (file)
index 66fdb30..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2010 Andreas Steffen
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include "pluto.h"
-
-#include <debug.h>
-
-typedef struct private_pluto_t private_pluto_t;
-
-/**
- * Private additions to pluto_t.
- */
-struct private_pluto_t {
-
-       /**
-        * Public members of pluto_t.
-        */
-       pluto_t public;
-};
-
-/**
- * Single instance of pluto_t.
- */
-pluto_t *pluto;
-
-/**
- * Described in header.
- */
-void pluto_deinit()
-{
-       private_pluto_t *this = (private_pluto_t*)pluto;
-       this->public.events->destroy(this->public.events);
-       this->public.xauth->destroy(this->public.xauth);
-       free(this);
-       pluto = NULL;
-}
-
-/**
- * Described in header.
- */
-bool pluto_init(char *file)
-{
-       private_pluto_t *this;
-
-       INIT(this,
-               .public = {
-                       .events = event_queue_create(),
-                       .xauth = xauth_manager_create(),
-               },
-       );
-       pluto = &this->public;
-
-       if (lib->integrity &&
-               !lib->integrity->check_file(lib->integrity, "pluto", file))
-       {
-               DBG1(DBG_LIB, "integrity check of pluto failed");
-               return FALSE;
-       }
-       return TRUE;
-}
-
diff --git a/src/pluto/pluto.h b/src/pluto/pluto.h
deleted file mode 100644 (file)
index 2440093..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2010 Andreas Steffen
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup pluto pluto
- *
- * @defgroup xauth xauth
- * @ingroup pluto
- *
- * @defgroup pplugins plugins
- * @ingroup pluto
- *
- * @addtogroup pluto
- * @{
- */
-
-#ifndef PLUTO_H_
-#define PLUTO_H_
-
-typedef struct pluto_t pluto_t;
-
-#include <event_queue.h>
-#include <xauth/xauth_manager.h>
-
-#include <library.h>
-
-/**
- * Pluto daemon support object.
- */
-struct pluto_t {
-
-       /**
-        * event queue (callbacks, executed by the pluto main thread)
-        */
-       event_queue_t *events;
-
-       /**
-        * manager for payload attributes
-        */
-       xauth_manager_t *xauth;
-
-};
-
-/**
- * The single instance of pluto_t.
- *
- * Set between calls to pluto_init() and pluto_deinit() calls.
- */
-extern pluto_t *pluto;
-
-/**
- * Initialize pluto.
- *
- * @return                             FALSE if integrity check failed
- */
-bool pluto_init(char *file);
-
-/**
- * Deinitialize pluto.
- */
-void pluto_deinit(void);
-
-#endif /** PLUTO_H_ @}*/
-
diff --git a/src/pluto/plutomain.c b/src/pluto/plutomain.c
deleted file mode 100644 (file)
index dbc857c..0000000
+++ /dev/null
@@ -1,852 +0,0 @@
-/* Pluto main program
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
- * Copyright (C) 2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <fcntl.h>
-#include <getopt.h>
-#include <resolv.h>
-#include <arpa/nameser.h>       /* missing from <resolv.h> on old systems */
-#include <sys/queue.h>
-#include <sys/prctl.h>
-#include <signal.h>
-#include <pwd.h>
-#include <grp.h>
-
-#ifdef CAPABILITIES
-#ifdef HAVE_SYS_CAPABILITY_H
-#include <sys/capability.h>
-#endif /* HAVE_SYS_CAPABILITY_H */
-#endif /* CAPABILITIES */
-
-#include <freeswan.h>
-
-#include <hydra.h>
-#include <library.h>
-#include <debug.h>
-#include <utils/enumerator.h>
-#include <utils/optionsfrom.h>
-
-#include <pfkeyv2.h>
-#include <pfkey.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "myid.h"
-#include "ca.h"
-#include "certs.h"
-#include "ac.h"
-#include "connections.h"
-#include "foodgroups.h"
-#include "packet.h"
-#include "demux.h"      /* needs packet.h */
-#include "server.h"
-#include "kernel.h"
-#include "log.h"
-#include "keys.h"
-#include "adns.h"       /* needs <resolv.h> */
-#include "dnskey.h"     /* needs keys.h and adns.h */
-#include "state.h"
-#include "ipsec_doi.h"  /* needs demux.h and state.h */
-#include "ocsp.h"
-#include "crl.h"
-#include "fetch.h"
-#include "crypto.h"
-#include "nat_traversal.h"
-#include "virtual.h"
-#include "timer.h"
-#include "vendor.h"
-#include "builder.h"
-#include "whack_attribute.h"
-#include "pluto.h"
-
-#ifdef ANDROID
-#include <private/android_filesystem_config.h> /* for AID_VPN */
-#endif
-
-/**
- * Number of threads in the thread pool, if not specified in config.
- */
-#define DEFAULT_THREADS 4
-
-/**
- * PID file, in which pluto stores its process id
- */
-static char pluto_lock[sizeof(ctl_addr.sun_path)] = DEFAULT_CTLBASE LOCK_SUFFIX;
-
-/**
- * TRUE if the lock has been checked.  This helps to avoid any unintended
- * deletion of the lock or control socket.
- */
-static bool pluto_lock_checked = FALSE;
-
-/**
- * Global reference to PID file (required to truncate, if undeletable)
- */
-static FILE *pidfile = NULL;
-
-
-static void usage(const char *mess)
-{
-       if (mess != NULL && *mess != '\0')
-               fprintf(stderr, "%s\n", mess);
-       fprintf(stderr
-               , "Usage: pluto"
-                       " [--help]"
-                       " [--version]"
-                       " [--optionsfrom <filename>]"
-                       " \\\n\t"
-                       "[--nofork]"
-                       " [--stderrlog]"
-                       " [--nocrsend]"
-                       " \\\n\t"
-                       "[--strictcrlpolicy]"
-                       " [--crlcheckinterval <interval>]"
-                       " [--cachecrls]"
-                       " [--uniqueids]"
-                       " \\\n\t"
-                       "[--interface <ifname>]"
-                       " [--ikeport <port-number>]"
-                       " \\\n\t"
-                       "[--ctlbase <path>]"
-                       " \\\n\t"
-                       "[--perpeerlogbase <path>] [--perpeerlog]"
-                       " \\\n\t"
-                       "[--secretsfile <secrets-file>]"
-                       " [--policygroupsdir <policygroups-dir>]"
-                       " \\\n\t"
-                       "[--adns <pathname>]"
-                       "[--pkcs11module <path>]"
-                       "[--pkcs11keepstate]"
-                       "[--pkcs11initargs <string>]"
-#ifdef DEBUG
-                       " \\\n\t"
-                       "[--debug-none]"
-                       " [--debug-all]"
-                       " \\\n\t"
-                       "[--debug-raw]"
-                       " [--debug-crypt]"
-                       " [--debug-parsing]"
-                       " [--debug-emitting]"
-                       " \\\n\t"
-                       "[--debug-control]"
-                       " [--debug-lifecycle]"
-                       " [--debug-kernel]"
-                       " [--debug-dns]"
-                       " \\\n\t"
-                       "[--debug-oppo]"
-                       " [--debug-controlmore]"
-                       " [--debug-private]"
-                       " [--debug-natt]"
-#endif
-                   " \\\n\t"
-                       "[--nat_traversal] [--keep_alive <delay_sec>]"
-                       " \\\n\t"
-                       "[--force_keepalive] [--disable_port_floating]"
-                   " \\\n\t"
-                   "[--virtual_private <network_list>]"
-                       "\n"
-                   "strongSwan "VERSION"\n");
-       exit_pluto(mess == NULL? 0 : 1);
-}
-
-static bool check_lock()
-{
-       struct stat stb;
-       FILE *fpid;
-
-       if (stat(pluto_lock, &stb) == 0)
-       {
-               fpid = fopen(pluto_lock, "r");
-               if (fpid)
-               {
-                       char buf[64];
-                       pid_t pid = 0;
-
-                       memset(buf, 0, sizeof(buf));
-                       if (fread(buf, 1, sizeof(buf), fpid))
-                       {
-                               buf[sizeof(buf) - 1] = '\0';
-                               pid = atoi(buf);
-                       }
-                       fclose(fpid);
-                       if (pid && kill(pid, 0) == 0)
-                       {       /* such a process is running */
-                               return TRUE;
-                       }
-               }
-               fprintf(stderr, "pluto: removing lock file \"%s\", process not "
-                               "running\n", pluto_lock);
-               unlink(pluto_lock);
-       }
-       pluto_lock_checked = TRUE;
-       return FALSE;
-}
-
-static void fill_lock(void)
-{
-       pidfile = fopen(pluto_lock, "w");
-       if (pidfile)
-       {
-               fprintf(pidfile, "%u\n", (u_int)getpid());
-               fflush(pidfile);
-       }
-       /* keep pidfile open so we can truncate it, if we cannot delete it */
-}
-
-static void delete_lock(void)
-{
-       /* because unlinking the PID file may fail, we truncate it to ensure the
-        * daemon can be properly restarted.  one probable cause for this is the
-        * combination of not running as root and the effective user lacking
-        * permissions on the parent dir(s) of the PID file */
-       if (pluto_lock_checked)
-       {
-               if (pidfile)
-               {
-                       ignore_result(ftruncate(fileno(pidfile), 0));
-                       fclose(pidfile);
-               }
-               unlink(pluto_lock);
-               /* delete this here to avoid that exit_pluto calls delete the socket */
-               delete_ctl_socket();
-       }
-}
-
-
-/* by default pluto sends certificate requests to its peers */
-bool no_cr_send = FALSE;
-
-/* by default the CRL policy is lenient */
-bool strict_crl_policy = FALSE;
-
-/* by default CRLs are cached locally as files */
-bool cache_crls = FALSE;
-
-/* by default pluto does not check crls dynamically */
-long crl_check_interval = 0;
-
-/* path to the PKCS#11 module */
-char *pkcs11_module_path = NULL;
-
-/* by default pluto logs out after every smartcard use */
-bool pkcs11_keep_state = FALSE;
-
-/* by default pluto does not allow pkcs11 proxy access via whack */
-bool pkcs11_proxy = FALSE;
-
-/* argument string to pass to PKCS#11 module.
- * Not used for compliant modules, just for NSS softoken
- */
-static const char *pkcs11_init_args = NULL;
-
-/* options read by optionsfrom */
-options_t *options;
-
-int main(int argc, char **argv)
-{
-       bool fork_desired = TRUE;
-       bool log_to_stderr_desired = FALSE;
-       bool nat_traversal = FALSE;
-       bool nat_t_spf = TRUE;  /* support port floating */
-       unsigned int keep_alive = 0;
-       bool force_keepalive = FALSE;
-       char *virtual_private = NULL;
-#ifdef CAPABILITIES
-       int keep[] = {
-                       CAP_NET_ADMIN,
-                       CAP_NET_BIND_SERVICE,
-#ifdef ANDROID
-                       CAP_NET_RAW,
-#endif
-       };
-#endif /* CAPABILITIES */
-
-       /* initialize library and optionsfrom */
-       if (!library_init(NULL))
-       {
-               library_deinit();
-               exit(SS_RC_LIBSTRONGSWAN_INTEGRITY);
-       }
-       if (!libhydra_init("pluto"))
-       {
-               libhydra_deinit();
-               library_deinit();
-               exit(SS_RC_INITIALIZATION_FAILED);
-       }
-       if (!pluto_init(argv[0]))
-       {
-               pluto_deinit();
-               libhydra_deinit();
-               library_deinit();
-               exit(SS_RC_DAEMON_INTEGRITY);
-       }
-       options = options_create();
-
-       /* handle arguments */
-       for (;;)
-       {
-#       define DBG_OFFSET 256
-               static const struct option long_opts[] = {
-                       /* name, has_arg, flag, val */
-                       { "help", no_argument, NULL, 'h' },
-                       { "version", no_argument, NULL, 'v' },
-                       { "optionsfrom", required_argument, NULL, '+' },
-                       { "nofork", no_argument, NULL, 'd' },
-                       { "stderrlog", no_argument, NULL, 'e' },
-                       { "nocrsend", no_argument, NULL, 'c' },
-                       { "strictcrlpolicy", no_argument, NULL, 'r' },
-                       { "crlcheckinterval", required_argument, NULL, 'x'},
-                       { "cachecrls", no_argument, NULL, 'C' },
-                       { "uniqueids", no_argument, NULL, 'u' },
-                       { "interface", required_argument, NULL, 'i' },
-                       { "ikeport", required_argument, NULL, 'p' },
-                       { "ctlbase", required_argument, NULL, 'b' },
-                       { "secretsfile", required_argument, NULL, 's' },
-                       { "foodgroupsdir", required_argument, NULL, 'f' },
-                       { "perpeerlogbase", required_argument, NULL, 'P' },
-                       { "perpeerlog", no_argument, NULL, 'l' },
-                       { "policygroupsdir", required_argument, NULL, 'f' },
-                       { "adns", required_argument, NULL, 'a' },
-                       { "pkcs11module", required_argument, NULL, 'm' },
-                       { "pkcs11keepstate", no_argument, NULL, 'k' },
-                       { "pkcs11initargs", required_argument, NULL, 'z' },
-                       { "pkcs11proxy", no_argument, NULL, 'y' },
-                       { "nat_traversal", no_argument, NULL, '1' },
-                       { "keep_alive", required_argument, NULL, '2' },
-                       { "force_keepalive", no_argument, NULL, '3' },
-                       { "disable_port_floating", no_argument, NULL, '4' },
-                       { "debug-natt", no_argument, NULL, '5' },
-                       { "virtual_private", required_argument, NULL, '6' },
-#ifdef DEBUG
-                       { "debug-none", no_argument, NULL, 'N' },
-                       { "debug-all", no_argument, NULL, 'A' },
-                       { "debug-raw", no_argument, NULL, DBG_RAW + DBG_OFFSET },
-                       { "debug-crypt", no_argument, NULL, DBG_CRYPT + DBG_OFFSET },
-                       { "debug-parsing", no_argument, NULL, DBG_PARSING + DBG_OFFSET },
-                       { "debug-emitting", no_argument, NULL, DBG_EMITTING + DBG_OFFSET },
-                       { "debug-control", no_argument, NULL, DBG_CONTROL + DBG_OFFSET },
-                       { "debug-lifecycle", no_argument, NULL, DBG_LIFECYCLE + DBG_OFFSET },
-                       { "debug-klips", no_argument, NULL, DBG_KERNEL + DBG_OFFSET },
-                       { "debug-kernel", no_argument, NULL, DBG_KERNEL + DBG_OFFSET },
-                       { "debug-dns", no_argument, NULL, DBG_DNS + DBG_OFFSET },
-                       { "debug-oppo", no_argument, NULL, DBG_OPPO + DBG_OFFSET },
-                       { "debug-controlmore", no_argument, NULL, DBG_CONTROLMORE + DBG_OFFSET },
-                       { "debug-private", no_argument, NULL, DBG_PRIVATE + DBG_OFFSET },
-
-                       { "impair-delay-adns-key-answer", no_argument, NULL, IMPAIR_DELAY_ADNS_KEY_ANSWER + DBG_OFFSET },
-                       { "impair-delay-adns-txt-answer", no_argument, NULL, IMPAIR_DELAY_ADNS_TXT_ANSWER + DBG_OFFSET },
-                       { "impair-bust-mi2", no_argument, NULL, IMPAIR_BUST_MI2 + DBG_OFFSET },
-                       { "impair-bust-mr2", no_argument, NULL, IMPAIR_BUST_MR2 + DBG_OFFSET },
-#endif
-                       { 0,0,0,0 }
-                       };
-               /* Note: we don't like the way short options get parsed
-                * by getopt_long, so we simply pass an empty string as
-                * the list.  It could be "hvdenp:l:s:" "NARXPECK".
-                */
-               int c = getopt_long(argc, argv, "", long_opts, NULL);
-
-               /* Note: "breaking" from case terminates loop */
-               switch (c)
-               {
-               case EOF:       /* end of flags */
-                       break;
-
-               case 0: /* long option already handled */
-                       continue;
-
-               case ':':       /* diagnostic already printed by getopt_long */
-               case '?':       /* diagnostic already printed by getopt_long */
-                       usage("");
-                       break;   /* not actually reached */
-
-               case 'h':       /* --help */
-                       usage(NULL);
-                       break;      /* not actually reached */
-
-               case 'v':       /* --version */
-                       {
-                               const char **sp = ipsec_copyright_notice();
-
-                               printf("strongSwan "VERSION"%s\n", compile_time_interop_options);
-                               for (; *sp != NULL; sp++)
-                                       puts(*sp);
-                       }
-                       exit_pluto(0);
-                       break;      /* not actually reached */
-
-               case '+':       /* --optionsfrom <filename> */
-                       if (!options->from(options, optarg, &argc, &argv, optind))
-                       {
-                               exit_pluto(1);
-                       }
-                       continue;
-
-               case 'd':       /* --nofork*/
-                       fork_desired = FALSE;
-                       continue;
-
-               case 'e':       /* --stderrlog */
-                       log_to_stderr_desired = TRUE;
-                       continue;
-
-               case 'c':       /* --nocrsend */
-                       no_cr_send = TRUE;
-                       continue;
-
-               case 'r':       /* --strictcrlpolicy */
-                       strict_crl_policy = TRUE;
-                       continue;
-
-               case 'x':       /* --crlcheckinterval <time>*/
-                       if (optarg == NULL || !isdigit(optarg[0]))
-                               usage("missing interval time");
-
-                       {
-                               char *endptr;
-                               long interval = strtol(optarg, &endptr, 0);
-
-                               if (*endptr != '\0' || endptr == optarg
-                               || interval <= 0)
-                                       usage("<interval-time> must be a positive number");
-                               crl_check_interval = interval;
-                       }
-                       continue;
-
-               case 'C':       /* --cachecrls */
-                       cache_crls = TRUE;
-                       continue;
-
-               case 'u':       /* --uniqueids */
-                       uniqueIDs = TRUE;
-                       continue;
-
-               case 'i':       /* --interface <ifname> */
-                       if (!use_interface(optarg))
-                               usage("too many --interface specifications");
-                       continue;
-
-               case 'p':       /* --port <portnumber> */
-                       if (optarg == NULL || !isdigit(optarg[0]))
-                               usage("missing port number");
-
-                       {
-                               char *endptr;
-                               long port = strtol(optarg, &endptr, 0);
-
-                               if (*endptr != '\0' || endptr == optarg
-                               || port <= 0 || port > 0x10000)
-                                       usage("<port-number> must be a number between 1 and 65535");
-                               pluto_port = port;
-                       }
-                       continue;
-
-               case 'b':       /* --ctlbase <path> */
-                       if (snprintf(ctl_addr.sun_path, sizeof(ctl_addr.sun_path)
-                       , "%s%s", optarg, CTL_SUFFIX) == -1)
-                               usage("<path>" CTL_SUFFIX " too long for sun_path");
-                       if (snprintf(info_addr.sun_path, sizeof(info_addr.sun_path)
-                       , "%s%s", optarg, INFO_SUFFIX) == -1)
-                               usage("<path>" INFO_SUFFIX " too long for sun_path");
-                       if (snprintf(pluto_lock, sizeof(pluto_lock)
-                       , "%s%s", optarg, LOCK_SUFFIX) == -1)
-                               usage("<path>" LOCK_SUFFIX " must fit");
-                       continue;
-
-               case 's':       /* --secretsfile <secrets-file> */
-                       shared_secrets_file = optarg;
-                       continue;
-
-               case 'f':       /* --policygroupsdir <policygroups-dir> */
-                       policygroups_dir = optarg;
-                       continue;
-#ifdef ADNS
-               case 'a':       /* --adns <pathname> */
-                       pluto_adns_option = optarg;
-                       continue;
-#endif
-               case 'm':       /* --pkcs11module <pathname> */
-                       pkcs11_module_path = optarg;
-                       continue;
-
-               case 'k':       /* --pkcs11keepstate */
-                       pkcs11_keep_state = TRUE;
-                       continue;
-
-               case 'y':       /* --pkcs11proxy */
-                       pkcs11_proxy = TRUE;
-                       continue;
-
-               case 'z':       /* --pkcs11initargs */
-                       pkcs11_init_args = optarg;
-                       continue;
-
-#ifdef DEBUG
-               case 'N':       /* --debug-none */
-                       base_debugging = DBG_NONE;
-                       continue;
-
-               case 'A':       /* --debug-all */
-                       base_debugging = DBG_ALL;
-                       continue;
-#endif
-
-               case 'P':       /* --perpeerlogbase */
-                       base_perpeer_logdir = optarg;
-                       continue;
-
-               case 'l':
-                       log_to_perpeer = TRUE;
-                       continue;
-
-               case '1':       /* --nat_traversal */
-                       nat_traversal = TRUE;
-                       continue;
-               case '2':       /* --keep_alive */
-                       keep_alive = atoi(optarg);
-                       continue;
-               case '3':       /* --force_keepalive */
-                       force_keepalive = TRUE;
-                       continue;
-               case '4':       /* --disable_port_floating */
-                       nat_t_spf = FALSE;
-                       continue;
-               case '5':       /* --debug-nat_t */
-                       base_debugging |= DBG_NATT;
-                       continue;
-               case '6':       /* --virtual_private */
-                       virtual_private = optarg;
-                       continue;
-
-               default:
-#ifdef DEBUG
-                       if (c >= DBG_OFFSET)
-                       {
-                               base_debugging |= c - DBG_OFFSET;
-                               continue;
-                       }
-#       undef DBG_OFFSET
-#endif
-                       bad_case(c);
-               }
-               break;
-       }
-       if (optind != argc)
-               usage("unexpected argument");
-       reset_debugging();
-
-       if (check_lock())
-       {
-               fprintf(stderr, "pluto: lock file \"%s\" already exists\n", pluto_lock);
-               exit_pluto(10);
-       }
-
-       /* select between logging methods */
-
-       if (log_to_stderr_desired)
-       {
-               log_to_syslog = FALSE;
-       }
-       else
-       {
-               log_to_stderr = FALSE;
-       }
-
-       /* set the logging function of pfkey debugging */
-#ifdef DEBUG
-       pfkey_debug_func = DBG_log;
-#else
-       pfkey_debug_func = NULL;
-#endif
-
-       /* create control socket.
-        * We must create it before the parent process returns so that
-        * there will be no race condition in using it.  The easiest
-        * place to do this is before the daemon fork.
-        */
-       {
-               err_t ugh = init_ctl_socket();
-
-               if (ugh != NULL)
-               {
-                       fprintf(stderr, "pluto: %s", ugh);
-                       exit_pluto(1);
-               }
-       }
-
-       /* If not suppressed, do daemon fork */
-
-       if (fork_desired)
-       {
-               {
-                       pid_t pid = fork();
-
-                       if (pid < 0)
-                       {
-                               int e = errno;
-
-                               fprintf(stderr, "pluto: fork failed (%d %s)\n",
-                                       errno, strerror(e));
-                               exit_pluto(1);
-                       }
-
-                       if (pid != 0)
-                       {
-                               /* parent: die
-                                * must not use exit_pluto: lock would be removed!
-                                */
-                               exit(0);
-                       }
-                       /* child: fill PID into lock file */
-                       fill_lock();
-               }
-
-               if (setsid() < 0)
-               {
-                       int e = errno;
-
-                       fprintf(stderr, "setsid() failed in main(). Errno %d: %s\n",
-                               errno, strerror(e));
-                       exit_pluto(1);
-               }
-       }
-       else
-       {
-               /* no daemon fork: we have to fill in lock file */
-               fill_lock();
-               fprintf(stdout, "Pluto initialized\n");
-               fflush(stdout);
-       }
-
-       /* Redirect stdin, stdout and stderr to /dev/null
-        */
-       {
-               int fd;
-               if ((fd = open("/dev/null", O_RDWR)) == -1)
-                       abort();
-               if (dup2(fd, 0) != 0)
-                       abort();
-               if (dup2(fd, 1) != 1)
-                       abort();
-               if (!log_to_stderr && dup2(fd, 2) != 2)
-                       abort();
-               close(fd);
-       }
-
-       /* for uncritical pseudo random numbers */
-       srand(time(NULL) + getpid());
-
-       init_constants();
-       init_log("pluto");
-
-       /* Note: some scripts may look for this exact message -- don't change
-        * ipsec barf was one, but it no longer does.
-        */
-       plog("Starting IKEv1 pluto daemon (strongSwan "VERSION")%s",
-                compile_time_interop_options);
-
-       if (lib->integrity)
-       {
-               plog("integrity tests enabled:");
-               plog("lib    'libstrongswan': passed file and segment integrity tests");
-               plog("lib    'libhydra': passed file and segment integrity tests");
-               plog("daemon 'pluto': passed file integrity test");
-       }
-
-       /* load plugins, further infrastructure may need it */
-       if (!lib->plugins->load(lib->plugins, NULL,
-                       lib->settings->get_str(lib->settings, "pluto.load", PLUGINS)))
-       {
-               exit(SS_RC_INITIALIZATION_FAILED);
-       }
-       DBG1(DBG_DMN, "loaded plugins: %s",
-                lib->plugins->loaded_plugins(lib->plugins));
-
-       init_builder();
-       if (!init_secret() || !init_crypto())
-       {
-               plog("initialization failed - aborting pluto");
-               exit_pluto(SS_RC_INITIALIZATION_FAILED);
-       }
-       init_nat_traversal(nat_traversal, keep_alive, force_keepalive, nat_t_spf);
-       init_virtual_ip(virtual_private);
-       scx_init(pkcs11_module_path, pkcs11_init_args);
-       init_states();
-       init_demux();
-       init_kernel();
-#ifdef ADNS
-       init_adns();
-#endif
-       init_myid();
-       fetch_initialize();
-       ac_initialize();
-       whack_attribute_initialize();
-
-       /* drop unneeded capabilities and change UID/GID */
-       prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
-
-#ifdef IPSEC_GROUP
-       {
-               struct group group, *grp;
-               char buf[1024];
-
-               if (getgrnam_r(IPSEC_GROUP, &group, buf, sizeof(buf), &grp) != 0 ||
-                       grp == NULL || setgid(grp->gr_gid) != 0)
-               {
-                       plog("unable to change daemon group");
-                       abort();
-               }
-       }
-#endif
-#ifdef IPSEC_USER
-       {
-               struct passwd passwd, *pwp;
-               char buf[1024];
-
-               if (getpwnam_r(IPSEC_USER, &passwd, buf, sizeof(buf), &pwp) != 0 ||
-                       pwp == NULL || setuid(pwp->pw_uid) != 0)
-               {
-                       plog("unable to change daemon user");
-                       abort();
-               }
-       }
-#endif
-#ifdef ANDROID
-       if (setuid(AID_VPN) != 0)
-       {
-               plog("unable to change daemon user");
-               abort();
-       }
-#endif
-
-#ifdef CAPABILITIES_LIBCAP
-       {
-               cap_t caps;
-               caps = cap_init();
-               cap_set_flag(caps, CAP_EFFECTIVE, countof(keep), keep, CAP_SET);
-               cap_set_flag(caps, CAP_INHERITABLE, countof(keep), keep, CAP_SET);
-               cap_set_flag(caps, CAP_PERMITTED, countof(keep), keep, CAP_SET);
-               if (cap_set_proc(caps) != 0)
-               {
-                       plog("unable to drop daemon capabilities");
-                       abort();
-               }
-               cap_free(caps);
-       }
-#endif /* CAPABILITIES_LIBCAP */
-#ifdef CAPABILITIES_NATIVE
-       {
-               struct __user_cap_data_struct caps = { .effective = 0 };
-               struct __user_cap_header_struct header = {
-                       .version = _LINUX_CAPABILITY_VERSION,
-               };
-               int i;
-               for (i = 0; i < countof(keep); i++)
-               {
-                       caps.effective |= 1 << keep[i];
-                       caps.permitted |= 1 << keep[i];
-                       caps.inheritable |= 1 << keep[i];
-               }
-               if (capset(&header, &caps) != 0)
-               {
-                       plog("unable to drop daemon capabilities");
-                       abort();
-               }
-       }
-#endif /* CAPABILITIES_NATIVE */
-
-       /* loading X.509 CA certificates */
-       load_authcerts("ca", CA_CERT_PATH, X509_CA);
-       /* loading X.509 AA certificates */
-       load_authcerts("aa", AA_CERT_PATH, X509_AA);
-       /* loading X.509 OCSP certificates */
-       load_authcerts("ocsp", OCSP_CERT_PATH, X509_OCSP_SIGNER);
-       /* loading X.509 CRLs */
-       load_crls();
-       /* loading attribute certificates (experimental) */
-       ac_load_certs();
-
-       lib->processor->set_threads(lib->processor,
-                       lib->settings->get_int(lib->settings, "pluto.threads",
-                                                                  DEFAULT_THREADS));
-
-       daily_log_event();
-       call_server();
-       return -1;  /* Shouldn't ever reach this */
-}
-
-/* leave pluto, with status.
- * Once child is launched, parent must not exit this way because
- * the lock would be released.
- *
- *  0 OK
- *  1 general discomfort
- * 10 lock file exists
- */
-void exit_pluto(int status)
-{
-       lib->processor->set_threads(lib->processor, 0);
-       reset_globals();    /* needed because we may be called in odd state */
-       free_preshared_secrets();
-       free_remembered_public_keys();
-       delete_every_connection();
-       whack_attribute_finalize(); /* free in-memory pools */
-       kernel_finalize();
-       fetch_finalize();           /* stop fetching thread */
-       free_crl_fetch();           /* free chain of crl fetch requests */
-       free_ocsp_fetch();          /* free chain of ocsp fetch requests */
-       free_authcerts();           /* free chain of X.509 authority certificates */
-       free_crls();                /* free chain of X.509 CRLs */
-       free_ca_infos();            /* free chain of X.509 CA information records */
-       free_ocsp();                /* free ocsp cache */
-       free_ifaces();
-       ac_finalize();              /* free X.509 attribute certificates */
-       scx_finalize();             /* finalize and unload PKCS #11 module */
-#ifdef ADNS
-       stop_adns();
-#endif
-       free_md_pool();
-       free_crypto();
-       free_myid();                /* free myids */
-       free_events();              /* free remaining events */
-       free_vendorid();            /* free all vendor id records */
-       free_builder();
-       delete_lock();
-       options->destroy(options);
-       pluto_deinit();
-       lib->credmgr->flush_cache(lib->credmgr, CERT_ANY);
-       lib->plugins->unload(lib->plugins);
-       libhydra_deinit();
-       library_deinit();
-       close_log();
-       exit(status);
-}
-
-/*
- * Local Variables:
- * c-basic-offset:4
- * c-style: pluto
- * End:
- */
diff --git a/src/pluto/rcv_whack.c b/src/pluto/rcv_whack.c
deleted file mode 100644 (file)
index 0a7b33a..0000000
+++ /dev/null
@@ -1,728 +0,0 @@
-/* whack communicating routines
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2001  D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <stdio.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <resolv.h>
-#include <arpa/nameser.h>       /* missing from <resolv.h> on old systems */
-#include <sys/queue.h>
-#include <fcntl.h>
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "ca.h"
-#include "certs.h"
-#include "ac.h"
-#include "smartcard.h"
-#include "connections.h"
-#include "foodgroups.h"
-#include "whack.h"      /* needs connections.h */
-#include "packet.h"
-#include "demux.h"      /* needs packet.h */
-#include "state.h"
-#include "ipsec_doi.h"  /* needs demux.h and state.h */
-#include "kernel.h"
-#include "rcv_whack.h"
-#include "log.h"
-#include "keys.h"
-#include "adns.h"       /* needs <resolv.h> */
-#include "dnskey.h"     /* needs keys.h and adns.h */
-#include "server.h"
-#include "fetch.h"
-#include "ocsp.h"
-#include "crl.h"
-#include "myid.h"
-#include "kernel_alg.h"
-#include "ike_alg.h"
-#include "plugin_list.h"
-#include "whack_attribute.h"
-
-/* helper variables and function to decode strings from whack message */
-
-static char *next_str
-       , *str_roof;
-
-static bool unpack_str(char **p)
-{
-       char *end = memchr(next_str, '\0', str_roof - next_str);
-
-       if (end == NULL)
-       {
-               return FALSE;   /* fishy: no end found */
-       }
-       else
-       {
-               *p = next_str == end? NULL : next_str;
-               next_str = end + 1;
-               return TRUE;
-       }
-}
-
-/* bits loading keys from asynchronous DNS */
-
-enum key_add_attempt {
-       ka_TXT,
-#ifdef USE_KEYRR
-       ka_KEY,
-#endif
-       ka_roof     /* largest value + 1 */
-};
-
-struct key_add_common {
-       int refCount;
-       char *diag[ka_roof];
-       int whack_fd;
-       bool success;
-};
-
-struct key_add_continuation {
-       struct adns_continuation ac;        /* common prefix */
-       struct key_add_common *common;      /* common data */
-       enum key_add_attempt lookingfor;
-};
-
-static void key_add_ugh(identification_t *keyid, err_t ugh)
-{
-       loglog(RC_NOKEY, "failure to fetch key for %'Y' from DNS: %s", keyid, ugh);
-}
-
-/* last one out: turn out the lights */
-static void key_add_merge(struct key_add_common *oc, identification_t *keyid)
-{
-       if (oc->refCount == 0)
-       {
-               enum key_add_attempt kaa;
-
-               /* if no success, print all diagnostics */
-               if (!oc->success)
-               {
-                       for (kaa = ka_TXT; kaa != ka_roof; kaa++)
-                       {
-                               key_add_ugh(keyid, oc->diag[kaa]);
-                       }
-               }
-               for (kaa = ka_TXT; kaa != ka_roof; kaa++)
-               {
-                       free(oc->diag[kaa]);
-               }
-               close(oc->whack_fd);
-               free(oc);
-       }
-}
-
-#ifdef ADNS
-
-static void key_add_continue(struct adns_continuation *ac, err_t ugh)
-{
-       struct key_add_continuation *kc = (void *) ac;
-       struct key_add_common *oc = kc->common;
-
-       passert(whack_log_fd == NULL_FD);
-       whack_log_fd = oc->whack_fd;
-
-       if (ugh != NULL)
-       {
-               oc->diag[kc->lookingfor] = clone_str(ugh);
-       }
-       else
-       {
-               oc->success = TRUE;
-               transfer_to_public_keys(kc->ac.gateways_from_dns
-#ifdef USE_KEYRR
-                       , &kc->ac.keys_from_dns
-#endif /* USE_KEYRR */
-                       );
-       }
-
-       oc->refCount--;
-       key_add_merge(oc, ac->id);
-       whack_log_fd = NULL_FD;
-}
-
-#endif /* ADNS */
-
-static void key_add_request(const whack_message_t *msg)
-{
-       identification_t *key_id;
-
-       key_id = identification_create_from_string(msg->keyid);
-
-       if (!msg->whack_addkey)
-       {
-               delete_public_keys(key_id, msg->pubkey_alg, NULL, chunk_empty);
-       }
-       if (msg->keyval.len == 0)
-       {
-               struct key_add_common *oc = malloc_thing(struct key_add_common);
-               enum key_add_attempt kaa;
-               err_t ugh;
-
-               /* initialize state shared by queries */
-               oc->refCount = 0;
-               oc->whack_fd = dup_any(whack_log_fd);
-               oc->success = FALSE;
-
-               for (kaa = ka_TXT; kaa != ka_roof; kaa++)
-               {
-                       struct key_add_continuation *kc;
-
-                       oc->diag[kaa] = NULL;
-                       oc->refCount++;
-                       kc = malloc_thing(struct key_add_continuation);
-                       kc->common = oc;
-                       kc->lookingfor = kaa;
-                       ugh = NULL;
-
-                       switch (kaa)
-                       {
-#ifdef ADNS
-                               case ka_TXT:
-                                       ugh = start_adns_query(key_id
-                                                       , key_id        /* same */
-                                                       , T_TXT
-                                                       , key_add_continue
-                                                       , &kc->ac);
-                                       break;
-#endif /* ADNS */
-#ifdef USE_KEYRR
-                               case ka_KEY:
-                                       ugh = start_adns_query(key_id
-                                                       , NULL
-                                                       , T_KEY
-                                                       , key_add_continue
-                                                       , &kc->ac);
-                                       break;
-#endif /* USE_KEYRR */
-                               default:
-                                       bad_case(kaa);      /* suppress gcc warning */
-                       }
-                       if (ugh)
-                       {
-                               oc->diag[kaa] = clone_str(ugh);
-                               oc->refCount--;
-                       }
-               }
-
-               /* Done launching queries. Handle total failure case. */
-               key_add_merge(oc, key_id);
-       }
-       else
-       {
-               if (!add_public_key(key_id, DAL_LOCAL, msg->pubkey_alg, msg->keyval,
-                       &pubkeys))
-               {
-                       loglog(RC_LOG_SERIOUS, "failed to add public key");
-               }
-       }
-       key_id->destroy(key_id);
-}
-
-/* Handle a kernel request. Supposedly, there's a message in
- * the kernelsock socket.
- */
-void whack_handle(int whackctlfd)
-{
-       whack_message_t msg;
-       struct sockaddr_un whackaddr;
-       int whackaddrlen = sizeof(whackaddr);
-       int whackfd = accept(whackctlfd, (struct sockaddr *)&whackaddr, &whackaddrlen);
-       /* Note: actual value in n should fit in int.  To print, cast to int. */
-       ssize_t n;
-
-       if (whackfd < 0)
-       {
-               log_errno((e, "accept() failed in whack_handle()"));
-               return;
-       }
-       if (fcntl(whackfd, F_SETFD, FD_CLOEXEC) < 0)
-       {
-               log_errno((e, "failed to set CLOEXEC in whack_handle()"));
-               close(whackfd);
-               return;
-       }
-
-       n = read(whackfd, &msg, sizeof(msg));
-
-       if (n == -1)
-       {
-               log_errno((e, "read() failed in whack_handle()"));
-               close(whackfd);
-               return;
-       }
-
-       whack_log_fd = whackfd;
-
-       /* sanity check message */
-       {
-               err_t ugh = NULL;
-
-               next_str = msg.string;
-               str_roof = (char *)&msg + n;
-
-               if ((size_t)n < offsetof(whack_message_t, whack_shutdown) + sizeof(msg.whack_shutdown))
-               {
-                       ugh = builddiag("ignoring runt message from whack: got %d bytes", (int)n);
-               }
-               else if (msg.magic != WHACK_MAGIC)
-               {
-                       if (msg.magic == WHACK_BASIC_MAGIC)
-                       {
-                               /* Only shutdown command.  Simpler inter-version compatibility. */
-                               if (msg.whack_shutdown)
-                               {
-                                       plog("shutting down");
-                                       exit_pluto(0);      /* delete lock and leave, with 0 status */
-                               }
-                               ugh = "";       /* bail early, but without complaint */
-                       }
-                       else
-                       {
-                               ugh = builddiag("ignoring message from whack with bad magic %d; should be %d; probably wrong version"
-                                       , msg.magic, WHACK_MAGIC);
-                       }
-               }
-               else if (next_str > str_roof)
-               {
-                       ugh = builddiag("ignoring truncated message from whack: got %d bytes; expected %u"
-                               , (int) n, (unsigned) sizeof(msg));
-               }
-               else if (!unpack_str(&msg.name)         /* string  1 */
-               || !unpack_str(&msg.left.id)            /* string  2 */
-               || !unpack_str(&msg.left.cert)          /* string  3 */
-               || !unpack_str(&msg.left.ca)            /* string  4 */
-               || !unpack_str(&msg.left.groups)        /* string  5 */
-               || !unpack_str(&msg.left.updown)        /* string  6 */
-               || !unpack_str(&msg.left.sourceip)      /* string  7 */
-               || !unpack_str(&msg.left.virt)          /* string  8 */
-               || !unpack_str(&msg.right.id)           /* string  9 */
-               || !unpack_str(&msg.right.cert)         /* string 10 */
-               || !unpack_str(&msg.right.ca)           /* string 11 */
-               || !unpack_str(&msg.right.groups)       /* string 12 */
-               || !unpack_str(&msg.right.updown)       /* string 13 */
-               || !unpack_str(&msg.right.sourceip)     /* string 14 */
-               || !unpack_str(&msg.right.virt)         /* string 15 */
-               || !unpack_str(&msg.keyid)              /* string 16 */
-               || !unpack_str(&msg.myid)               /* string 17 */
-               || !unpack_str(&msg.cacert)             /* string 18 */
-               || !unpack_str(&msg.ldaphost)           /* string 19 */
-               || !unpack_str(&msg.ldapbase)           /* string 20 */
-               || !unpack_str(&msg.crluri)             /* string 21 */
-               || !unpack_str(&msg.crluri2)            /* string 22 */
-               || !unpack_str(&msg.ocspuri)            /* string 23 */
-               || !unpack_str(&msg.ike)                /* string 24 */
-               || !unpack_str(&msg.esp)                /* string 25 */
-               || !unpack_str(&msg.sc_data)            /* string 26 */
-               || !unpack_str(&msg.whack_lease_ip)     /* string 27 */
-               || !unpack_str(&msg.whack_lease_id)     /* string 28 */
-               || !unpack_str(&msg.xauth_identity)     /* string 29 */
-               || str_roof - next_str != (ptrdiff_t)msg.keyval.len)    /* check chunk */
-               {
-                       ugh = "message from whack contains bad string";
-               }
-               else
-               {
-                       msg.keyval.ptr = next_str;  /* grab chunk */
-               }
-
-               if (ugh != NULL)
-               {
-                       if (*ugh != '\0')
-                               loglog(RC_BADWHACKMESSAGE, "%s", ugh);
-                       whack_log_fd = NULL_FD;
-                       close(whackfd);
-                       return;
-               }
-       }
-
-       if (msg.whack_options)
-       {
-#ifdef DEBUG
-               if (msg.name == NULL)
-               {
-                       /* we do a two-step so that if either old or new would
-                        * cause the message to print, it will be printed.
-                        */
-                       cur_debugging |= msg.debugging;
-                       DBG(DBG_CONTROL
-                               , DBG_log("base debugging = %s"
-                                       , bitnamesof(debug_bit_names, msg.debugging)));
-                       cur_debugging = base_debugging = msg.debugging;
-               }
-               else if (!msg.whack_connection)
-               {
-                       connection_t *c = con_by_name(msg.name, TRUE);
-
-                       if (c != NULL)
-                       {
-                               c->extra_debugging = msg.debugging;
-                               DBG(DBG_CONTROL
-                                       , DBG_log("\"%s\" extra_debugging = %s"
-                                               , c->name
-                                               , bitnamesof(debug_bit_names, c->extra_debugging)));
-                       }
-               }
-#endif
-       }
-
-       if (msg.whack_myid)
-       {
-               set_myid(MYID_SPECIFIED, msg.myid);
-       }
-
-       /* Deleting combined with adding a connection works as replace.
-        * To make this more useful, in only this combination,
-        * delete will silently ignore the lack of the connection.
-        */
-       if (msg.whack_delete)
-       {
-               if (msg.whack_ca)
-               {
-                       find_ca_info_by_name(msg.name, TRUE);
-               }
-               else
-               {
-                       delete_connections_by_name(msg.name, !msg.whack_connection);
-               }
-       }
-
-       if (msg.whack_deletestate)
-       {
-               struct state *st = state_with_serialno(msg.whack_deletestateno);
-
-               if (st == NULL)
-               {
-                       loglog(RC_UNKNOWN_NAME, "no state #%lu to delete"
-                               , msg.whack_deletestateno);
-               }
-               else
-               {
-                       delete_state(st);
-               }
-       }
-
-       if (msg.whack_crash)
-       {
-               delete_states_by_peer(&msg.whack_crash_peer);
-       }
-
-       if (msg.whack_connection)
-       {
-               add_connection(&msg);
-       }
-
-       if (msg.whack_ca && msg.cacert != NULL)
-       {
-               add_ca_info(&msg);
-       }
-
-       /* process "listen" before any operation that could require it */
-       if (msg.whack_listen)
-       {
-               close_peerlog();    /* close any open per-peer logs */
-               plog("listening for IKE messages");
-               listening = TRUE;
-               daily_log_reset();
-#ifdef ADNS
-               reset_adns_restart_count();
-#endif
-               set_myFQDN();
-               find_ifaces();
-               load_preshared_secrets(NULL_FD);
-               load_groups();
-       }
-       if (msg.whack_unlisten)
-       {
-               plog("no longer listening for IKE messages");
-               listening = FALSE;
-       }
-
-       if (msg.whack_reread & REREAD_SECRETS)
-       {
-               load_preshared_secrets(whackfd);
-       }
-
-       if (msg.whack_reread & REREAD_CACERTS)
-       {
-               load_authcerts("ca", CA_CERT_PATH, X509_CA);
-       }
-
-       if (msg.whack_reread & REREAD_AACERTS)
-       {
-               load_authcerts("aa", AA_CERT_PATH, X509_AA);
-       }
-
-       if (msg.whack_reread & REREAD_OCSPCERTS)
-       {
-               load_authcerts("ocsp", OCSP_CERT_PATH, X509_OCSP_SIGNER);
-       }
-
-       if (msg.whack_reread & REREAD_ACERTS)
-       {
-               ac_load_certs();
-       }
-
-       if (msg.whack_reread & REREAD_CRLS)
-       {
-               load_crls();
-       }
-
-       if (msg.whack_purgeocsp)
-       {
-               free_ocsp_fetch();
-               free_ocsp_cache();
-       }
-
-       if (msg.whack_leases)
-       {
-               list_leases(msg.name, msg.whack_lease_ip, msg.whack_lease_id);
-       }
-
-       if (msg.whack_list & LIST_PUBKEYS)
-       {
-               list_public_keys(msg.whack_utc);
-       }
-
-       if (msg.whack_list & LIST_CERTS)
-       {
-               cert_list(msg.whack_utc);
-       }
-
-       if (msg.whack_list & LIST_CACERTS)
-       {
-               list_authcerts("CA", X509_CA, msg.whack_utc);
-       }
-
-       if (msg.whack_list & LIST_AACERTS)
-       {
-               list_authcerts("AA", X509_AA, msg.whack_utc);
-       }
-
-       if (msg.whack_list & LIST_OCSPCERTS)
-       {
-               list_authcerts("OCSP", X509_OCSP_SIGNER, msg.whack_utc);
-       }
-
-       if (msg.whack_list & LIST_ACERTS)
-       {
-               ac_list_certs(msg.whack_utc);
-       }
-
-       if (msg.whack_list & LIST_CAINFOS)
-       {
-               list_ca_infos(msg.whack_utc);
-       }
-
-       if (msg.whack_list & LIST_CRLS)
-       {
-               list_crls(msg.whack_utc, strict_crl_policy);
-               list_crl_fetch_requests(msg.whack_utc);
-       }
-
-       if (msg.whack_list & LIST_OCSP)
-       {
-               list_ocsp_cache(msg.whack_utc, strict_crl_policy);
-               list_ocsp_fetch_requests(msg.whack_utc);
-       }
-
-       if (msg.whack_list & LIST_CARDS)
-       {
-               scx_list(msg.whack_utc);
-       }
-
-       if (msg.whack_list & LIST_ALGS)
-       {
-               ike_alg_list();
-               kernel_alg_list();
-       }
-
-       if (msg.whack_list & LIST_PLUGINS)
-       {
-               plugin_list();
-       }
-
-       if (msg.whack_key)
-       {
-               /* add a public key */
-               key_add_request(&msg);
-       }
-
-       if (msg.whack_route)
-       {
-               if (!listening)
-               {
-                       whack_log(RC_DEAF, "need --listen before --route");
-               }
-               if (msg.name == NULL)
-               {
-                       whack_log(RC_UNKNOWN_NAME
-                               , "whack --route requires a connection name");
-               }
-               else
-               {
-                       connection_t *c = con_by_name(msg.name, TRUE);
-
-                       if (c != NULL && c->ikev1)
-                       {
-                               set_cur_connection(c);
-                               if (!oriented(*c))
-                               {
-                                       whack_log(RC_ORIENT
-                                               , "we have no ipsecN interface for either end of this connection");
-                               }
-                               else if (c->policy & POLICY_GROUP)
-                               {
-                                       route_group(c);
-                               }
-                               else if (!trap_connection(c))
-                               {
-                                       whack_log(RC_ROUTE, "could not route");
-                               }
-                               reset_cur_connection();
-                       }
-               }
-       }
-
-       if (msg.whack_unroute)
-       {
-               if (msg.name == NULL)
-               {
-                       whack_log(RC_UNKNOWN_NAME
-                               , "whack --unroute requires a connection name");
-               }
-               else
-               {
-                       connection_t *c = con_by_name(msg.name, TRUE);
-
-                       if (c != NULL && c->ikev1)
-                       {
-                               struct spd_route *sr;
-                               int fail = 0;
-
-                               set_cur_connection(c);
-
-                               for (sr = &c->spd; sr != NULL; sr = sr->next)
-                               {
-                                       if (sr->routing >= RT_ROUTED_TUNNEL)
-                                       {
-                                               fail++;
-                                       }
-                               }
-                               if (fail > 0)
-                               {
-                                       whack_log(RC_RTBUSY, "cannot unroute: route busy");
-                               }
-                               else if (c->policy & POLICY_GROUP)
-                               {
-                                       unroute_group(c);
-                               }
-                               else
-                               {
-                                       unroute_connection(c);
-                               }
-                               reset_cur_connection();
-                       }
-               }
-       }
-
-       if (msg.whack_initiate)
-       {
-               if (!listening)
-               {
-                       whack_log(RC_DEAF, "need --listen before --initiate");
-               }
-               else if (msg.name == NULL)
-               {
-                       whack_log(RC_UNKNOWN_NAME
-                               , "whack --initiate requires a connection name");
-               }
-               else
-               {
-                       initiate_connection(msg.name
-                               , msg.whack_async? NULL_FD : dup_any(whackfd));
-               }
-       }
-
-       if (msg.whack_oppo_initiate)
-       {
-               if (!listening)
-               {
-                       whack_log(RC_DEAF, "need --listen before opportunistic initiation");
-               }
-               else
-               {
-                       initiate_opportunistic(&msg.oppo_my_client, &msg.oppo_peer_client, 0
-                               , FALSE
-                               , msg.whack_async? NULL_FD : dup_any(whackfd));
-               }
-       }
-
-       if (msg.whack_terminate)
-       {
-               if (msg.name == NULL)
-               {
-                       whack_log(RC_UNKNOWN_NAME
-                               , "whack --terminate requires a connection name");
-               }
-               else
-               {
-                       terminate_connection(msg.name);
-               }
-       }
-
-       if (msg.whack_status)
-       {
-               show_status(msg.whack_statusall, msg.name);
-       }
-
-       if (msg.whack_shutdown)
-       {
-               plog("shutting down");
-               exit_pluto(0);  /* delete lock and leave, with 0 status */
-       }
-
-       if (msg.whack_sc_op != SC_OP_NONE)
-       {
-               if (pkcs11_proxy)
-               {
-                       scx_op_via_whack(msg.sc_data, msg.inbase, msg.outbase
-                                                  , msg.whack_sc_op, msg.keyid, whackfd);
-               }
-               else
-               {
-                  plog("pkcs11 access to smartcard not allowed (set pkcs11proxy=yes)");
-               }
-       }
-
-       whack_log_fd = NULL_FD;
-       close(whackfd);
-}
-
-/*
- * Local Variables:
- * c-basic-offset:4
- * c-style: pluto
- * End:
- */
diff --git a/src/pluto/rcv_whack.h b/src/pluto/rcv_whack.h
deleted file mode 100644 (file)
index 66edaaf..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/* whack communicating routines
- * Copyright (C) 1998, 1999  D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-extern void whack_handle(int kernelfd);
diff --git a/src/pluto/routing.txt b/src/pluto/routing.txt
deleted file mode 100644 (file)
index 2609bf8..0000000
+++ /dev/null
@@ -1,329 +0,0 @@
-Routing and Erouting in Pluto
-=============================
-
-This is meant as internal documentation for Pluto.  As such, it
-presumes some understanding of Pluto's code.
-
-It also describes KLIPS 1 erouting, including details not otherwise
-documented.  KLIPS 1 documentation would be better included in KLIPS.
-
-Routing and erouting are complicated enough that the Pluto code needs
-a guide.  This document is meant to be that guide.
-
-
-Mechanisms available to Pluto
------------------------------
-
-All outbound packets that are to be processed by KLIPS 1 must be
-routed to an ipsecN network interface.  Pluto only uses normal routing
-(as opposed to "Advanced Routing"), so the selection of packets is
-made solely on the basis of the destination address.  (Since the
-actual routing commands are in the updown script, they could be
-changed by the administrator, but Pluto needs to understand what is
-going on, and it currently assumes normal routing is used.)
-
-When an outbound packet hits an ipsecN interface, KLIPS figures out
-how to process it by finding an eroute that applies to the source and
-destination addresses.  Eroutes are global: they are not specific to a
-particular ipsecN interface (routing needs to get the packets to any
-ipsecN interface; erouting takes it from there, ignoring issues of
-source IP address and nexthop (because nobody knows!)).  If multiple
-eroutes apply to the packet, among the ones with the most specific
-source subnet, the one with the most specific destination subset is
-chosen (RGB thinks).  If no eroute is discovered, KLIPS acts as if it
-was covered by a DROP eroute (this is the default behaviour; it can be
-changed).  At most one eroute can exist for a particular pair of
-client subnets.
-
-There are fundamentally two kinds of eroutes: "shunt" eroutes and ones
-that specify that a packet is to be processed by a group of IPSEC SAs.
-Shunt eroutes specify what is to be done with the packet.  Remember
-that these only apply to outbound packets.
-
-- TRAP: notify Pluto of the packet (presumably to attempt to negotiate
-  an appropriate group of IPSEC SAs).  At the same time, KLIPS
-  installs a HOLD shunt (see below) for the specific source and
-  destination addresses from the packet and retains the packet
-  for later reprocessing (KLIPS does not yet implement retention).
-  Beware: if the TRAP's subnets both contained a single IP address
-  then installing the HOLD would actually delete the TRAP.
-
-- PASS: let the packet through in the clear
-
-- DROP: discard the packet
-
-- REJECT: discard the packet and notify the sender
-
-- HOLD: (automatically created by KLIPS when a TRAP fires) block
-  the packet, but retain it.  If there is already a retained
-  packet, drop the old one and retain the new.  When the HOLD
-  shunt is deleted or replaced, the retained packet is reinjected --
-  there might now be a tunnel.  Note that KLIPS doesn't yet
-  implement the retention part, so HOLD is really like a DROP.
-
-One consequence of there being only one eroute for a pair of clients
-is that KLIPS will only use one SA group for output for this pair,
-even though there could be several SA groups that are authorised and
-live.  Pluto chooses to make this the youngest such group.
-
-
-
-KLIPS lets through in the clear outbound UDP/500 packets that would
-otherwise be processed if they originate on this host and meet certain
-other conditions.  The actual test is
-       source == me
-       && (no_eroute || dest == eroute.dest || isanyaddr(eroute.dest))
-       && port == UDP/500
-The idea is that IKE packets between us and a peer should not be
-sent through an IPSEC tunnel negotiated between us.  Furthermore,
-our shunt eroutes should not apply to our IKE packets (shunt eroutes
-will generally have an eroute.dest of 0.0.0.0 or its IPv6 equivalent).
-
-Inbound behaviour is controlled in a quite different way.  KLIPS
-processes only those inbound packets of ESP or AH protocol, with a
-destination address for this machine's ipsecN interfaces. The
-processing is as dictated by the SAs involved.  Unfortunately, the
-decapsulated packet's source and destination address are not checked
-(part of "inbound policy checking").
-
-To prevent clear packets being accepted, firewall rules must be put in
-place.  This has nothing to do with KLIPS, but is nonetheless in
-important part of security.  It isn't clear what firewalling makes
-sense when Opportunism is allowed.
-
-
-For routing and firewalling, Pluto invokes the updown script.  Pluto
-installs eroutes via extended PF_KEY messages.
-
-
-Current Pluto Behaviour
------------------------
-
-Data Structures:
-
-Routes and most eroutes are associated with connections (struct
-connection, a potential connection description).  The enum routing_t
-field "routing" in struct connection records the state of routing and
-erouting for that connection.  The values are:
-    RT_UNROUTED,       /* unrouted */
-    RT_UNROUTED_HOLD,  /* unrouted, but HOLD shunt installed */
-    RT_ROUTED_PROSPECTIVE,     /* routed, and TRAP shunt installed */
-    RT_ROUTED_HOLD,    /* routed, and HOLD shunt installed */
-    RT_ROUTED_FAILURE, /* routed, and failure-context shunt installed */
-    RT_ROUTED_TUNNEL   /* routed, and erouted to an IPSEC SA group */
-Notice that the routing and erouting are not independent: erouting
-(except for HOLD) implies that the connection is routed.
-
-Several struct connections may have the same destination subnet.  If
-they agree on what the route should be, they can share it -- any of
-them may have routing >= RT_ROUTED_PROSPECTIVE.  If they disagree,
-they cannot simultaneously be routed.
-
-invariant: for all struct connections c, d:
-    (c.that.client == d.that.client
-           && c.routing >= RT_ROUTED_PROSPECTIVE
-           && d.routing >= RT_ROUTED_PROSPECTIVE)
-    => c.interface == d.interface && c.this.nexthop == d.this.nexthop
-
-There are two kinds of eroutes: shunt eroutes and ones for an IPSEC SA
-Group.  Most eroutes are associated with and are represeented in a
-connection.  The exception is that some HOLD and PASS shunts do not
-correspond to connections; those are represented in the bare_shunt
-table.
-
-An eroute for an IPSEC SA Group is associated with the state object
-for that Group.  The existence of such an eroute is also represented
-by the "so_serial_t eroute_owner" field in the struct connection.  The
-value is the serial number of the state object for the Group.  The
-special value SOS_NOBODY means that there is no owner associated with
-this connection for the eroute and hence no normal eroute.  At most
-one eroute owner may exist for a particular (source subnet,
-destination subnet) pair.  A Pluto-managed eroute cannot be associated
-with an RT_UNROUTED connection.
-
-invariant: for all struct connection c:
-    c.routing == RT_EROUTED_TUNNEL || c.eroute_owner == SOS_NOBODY
-
-invariant: for all struct connections c, d:
-    c.this.client == d.this.client && c.that.client == d.that.client
-        && &c != &d
-    => c.routing == RT_UNROUTED || d.routing == RT_UNROUTED
-
-If no normal eroute is set for a particular (source subnet,
-destination subnet) pair for which a connection is routed, then a
-shunt eroute would have been installed.  This specifies what should
-happen to packets snared by the route.
-
-When Pluto is notified by KLIPS of a packet that has been TRAPped,
-there is no connection with which to associate the HOLD.  It is
-temporarily held in the "bare_shunt table".  If Opportunism is
-attempted but DNS doesn't provide Security Gateway information, Pluto
-will replace the HOLD with a PASS shunt.  Since this PASS isn't
-associated with a connection, it too will reside in the bare_shunt
-table.  If the HOLD can be associated with a connection, it will be
-removed from the bare_shunt table and represented in the connection.
-
-There are two contexts for which shunt eroutes are installed by Pluto
-for a particular connection.  The first context is with the prospect
-of dealing with packets before any negotiation has been attempted.  I
-call this context "prospective".  Currently is a TRAP shunt, used to
-catch packets for initiate opportunistic negotiation.  In the future,
-it might also be used to implement preordained PASS, DROP, or REJECT
-rules.
-
-The second context is after a failed negotiation.  I call this context
-"failure".  At this point a different kind of shunt eroute is
-appropriate.  Depending on policy, it could be PASS, DROP, or REJECT,
-but it is unlikely to be TRAP.  The shunt eroute should have a
-lifetime (this isn't yet implemented).  When the lifetime expires, the
-failure shunt eroute should be replaced by the prospective shunt
-eroute.
-
-The kind and duration of a failure shunt eroute should perhaps depend
-on the nature of the failure, at least as imperfectly detected by
-Pluto.  We haven't looked at this.  In particular, the mapping from
-observations to robust respose isn't obvious.
-
-The shunt eroute policies should be a function of the potential
-connection.  The failure shunt eroute can be specified for a
-particular connection with the flags --pass and --drop in a connection
-definition.  There are four combinations, and each has a distinct
-meaning.  The failure shunt eroute is incompletely implemented and
-cannot be represented in /etc/ipsec.conf.
-
-There is as yet no control over the prospective shunt eroute: it is
-always TRAP as far as Pluto is concerned.  This is probably
-reasonable: any other fate suggests that no negotiation will be done,
-and so a connection definition is inappropriate.  These should be
-implemented as manual conns.  There remains the issue of whether Pluto
-should be aware of them -- currently it is not.
-
-
-Routines:
-
-[in kernel.c]
-
-bool do_command(struct connection *c, const char *verb)
-    Run the updown script to perform such tasks as installing a route
-    and adjust the firewall.
-
-bool could_route(struct connection *c)
-    Check to see whether we could route and eroute the connection.
-    <- shunt_eroute_connection (to check if --route can be performed)
-    <- install_inbound_ipsec_sa (to see if it will be possible
-       to (later) install route and eroute the corresponding outbound SA)
-    <- install_ipsec_sa (to see if the outbound SA can be routed and erouted)
-
-bool trap_connection(struct connection *c)
-    Install a TRAP shunt eroute for this connection.  This implements
-    "whack --route", the way an admin can specify that packets for a
-    connection should be caught without first bringing it up.
-
-void unroute_connection(struct connection *c)
-    Delete any eroute for a connection and unroute it if route isn't shared.
-    <- release_connection
-    <- whack_handle (for "whack --unroute)
-
-bool eroute_connection(struct connection *c
-, ipsec_spi_t spi, unsigned int proto, unsigned int satype
-, unsigned int op, const char *opname UNUSED)
-    Issue PF_KEY commands to KLIPS to add, replace, or delete an eroute.
-    The verb is specified by op and described (for logging) by opname.
-    <- assign_hold
-    <- sag_eroute
-    <- shunt_eroute
-
-bool assign_hold(struct connection *c
-, const ip_address *src, const ip_address *dst)
-    Take a HOLD from the bare_shunt table and assign it to a connection.
-    If the HOLD is broadened (i.e. the connection's source or destination
-    subnets contain more than one IP address), this will involve replacing
-    the HOLD with a different one.
-
-bool sag_eroute(struct state *st, unsigned op, const char *opname)
-    SA Group eroute manipulation.  The SA Group concerned is
-    identified with a state object.
-    <- route_and_eroute several times
-
-bool shunt_eroute(struct connection *c, unsigned int op, const char *opname)
-    shunt eroute manipulation.  Shunt eroutes are associated with
-    connections.
-    <- unroute_connection
-    <- route_and_eroute
-    <- delete_ipsec_sa
-
-bool route_and_eroute(struct connection *c, struct state *st)
-    Install a route and then a prospective shunt eroute or an SA group
-    eroute.  The code assumes that could_route had previously
-    given the go-ahead.  Any SA group to be erouted must already
-    exist.
-    <- shunt_eroute_connection
-    <- install_ipsec_sa
-
-void scan_proc_shunts(void)
-    Every SHUNT_SCAN_INTERVAL scan /proc/net/ipsec_eroute.
-    Delete any PASS eroute in the bare_shunt table that hasn't been used
-    within the last SHUNT_PATIENCE seconds.
-    For any HOLD for which Pluto hasn't received an ACQUIRE (possibly
-    lost due to congestion), act as if an ACQUIRE were received.
-
-[in connection.c]
-
-struct connection *route_owner(struct connection *c, struct connection **erop)
-    Find the connection to connection c's peer's client with the
-    largest value of .routing.  All other things being equal,
-    preference is given to c.  Return NULL if no connection is routed
-    at all.  If erop is non-null, sets it to a connection sharing both
-    our client subnet and peer's client subnet with the largest value
-    of .routing.
-    The return value is used to find other connections sharing
-    a route.  The value of *erop is used to find other connections
-    sharing an eroute.
-    <- could_route (to find any conflicting routes or eroutes)
-    <- unroute_connection (to find out if our route is still in use
-       after this connection is finished with it)
-    <- install_inbound_ipsec_sa (to find other IPSEC SAs for the
-       same peer clients; when we find them WE KILL THEM; a
-       kludge to deal with road warriors reconnecting)
-    <- route_and_eroute (to find all the connections from which the
-       route or eroute is being stolen)
-
-Uses:
-
-- setting up route & shunt eroute to TRAP packets for opportunism
-  (whack --route).  Perhaps also manually designating DROP, REJECT, or
-  PASS for certain packets.
-
-  whack_handle() responds to --route; calls route_connection()
-
-
-- removing same (whack --unroute)
-
-  whack_handle() responds to --unroute; calls unroute_connection()
-
-- installing route & normal eroute for a newly negotiated group of
-  outbound IPSEC SAs
-
-  + perhaps an (additional) route is not needed: if the negotiation
-    was initiated by a TRAPped outgoing packet, then there must
-    already have been a route that got the packet to ipsecN.  Mind
-    you, it could have been the wrong N!
-
-  install_ipsec_sa()
-
-- updating a normal eroute when a new group of IPSEC SAs replaces
-  an old one due to rekeying.
-
-  install_ipsec_sa()
-
-- replacing an old eroute when a negotiation fails.  But this is
-  tricky.  If this was a rekeying, we should just leave the old
-  normal eroute be -- it might still work.  Otherwise, this was
-  an initial negotiation: we should replace the shunt eroute
-  with one appropriate for the failure context.
-
-- when a group of IPSEC SAs dies or is killed, and it had the eroute,
-  its normal eroute should be replaced by a shunt eroute.  If there
-  was an attempt to replace the group, the replacement is in the
-  failure context; otherwise the replacement is in the prospective
-  context.
diff --git a/src/pluto/rsaref/pkcs11.h b/src/pluto/rsaref/pkcs11.h
deleted file mode 100644 (file)
index 3283bdc..0000000
+++ /dev/null
@@ -1,299 +0,0 @@
-/* pkcs11.h include file for PKCS #11. */
-/* $Revision: 1.2 $ */
-
-/* License to copy and use this software is granted provided that it is
- * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
- * (Cryptoki)" in all material mentioning or referencing this software.
-
- * License is also granted to make and use derivative works provided that
- * such works are identified as "derived from the RSA Security Inc. PKCS #11
- * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
- * referencing the derived work.
-
- * RSA Security Inc. makes no representations concerning either the
- * merchantability of this software or the suitability of this software for
- * any particular purpose. It is provided "as is" without express or implied
- * warranty of any kind.
- */
-
-#ifndef _PKCS11_H_
-#define _PKCS11_H_ 1
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Before including this file (pkcs11.h) (or pkcs11t.h by
- * itself), 6 platform-specific macros must be defined.  These
- * macros are described below, and typical definitions for them
- * are also given.  Be advised that these definitions can depend
- * on both the platform and the compiler used (and possibly also
- * on whether a Cryptoki library is linked statically or
- * dynamically).
- *
- * In addition to defining these 6 macros, the packing convention
- * for Cryptoki structures should be set.  The Cryptoki
- * convention on packing is that structures should be 1-byte
- * aligned.
- *
- * If you're using Microsoft Developer Studio 5.0 to produce
- * Win32 stuff, this might be done by using the following
- * preprocessor directive before including pkcs11.h or pkcs11t.h:
- *
- * #pragma pack(push, cryptoki, 1)
- *
- * and using the following preprocessor directive after including
- * pkcs11.h or pkcs11t.h:
- *
- * #pragma pack(pop, cryptoki)
- *
- * If you're using an earlier version of Microsoft Developer
- * Studio to produce Win16 stuff, this might be done by using
- * the following preprocessor directive before including
- * pkcs11.h or pkcs11t.h:
- *
- * #pragma pack(1)
- *
- * In a UNIX environment, you're on your own for this.  You might
- * not need to do (or be able to do!) anything.
- *
- *
- * Now for the macros:
- *
- *
- * 1. CK_PTR: The indirection string for making a pointer to an
- * object.  It can be used like this:
- *
- * typedef CK_BYTE CK_PTR CK_BYTE_PTR;
- *
- * If you're using Microsoft Developer Studio 5.0 to produce
- * Win32 stuff, it might be defined by:
- *
- * #define CK_PTR *
- *
- * If you're using an earlier version of Microsoft Developer
- * Studio to produce Win16 stuff, it might be defined by:
- *
- * #define CK_PTR far *
- *
- * In a typical UNIX environment, it might be defined by:
- *
- * #define CK_PTR *
- *
- *
- * 2. CK_DEFINE_FUNCTION(returnType, name): A macro which makes
- * an exportable Cryptoki library function definition out of a
- * return type and a function name.  It should be used in the
- * following fashion to define the exposed Cryptoki functions in
- * a Cryptoki library:
- *
- * CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(
- *   CK_VOID_PTR pReserved
- * )
- * {
- *   ...
- * }
- *
- * If you're using Microsoft Developer Studio 5.0 to define a
- * function in a Win32 Cryptoki .dll, it might be defined by:
- *
- * #define CK_DEFINE_FUNCTION(returnType, name) \
- *   returnType __declspec(dllexport) name
- *
- * If you're using an earlier version of Microsoft Developer
- * Studio to define a function in a Win16 Cryptoki .dll, it
- * might be defined by:
- *
- * #define CK_DEFINE_FUNCTION(returnType, name) \
- *   returnType __export _far _pascal name
- *
- * In a UNIX environment, it might be defined by:
- *
- * #define CK_DEFINE_FUNCTION(returnType, name) \
- *   returnType name
- *
- *
- * 3. CK_DECLARE_FUNCTION(returnType, name): A macro which makes
- * an importable Cryptoki library function declaration out of a
- * return type and a function name.  It should be used in the
- * following fashion:
- *
- * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)(
- *   CK_VOID_PTR pReserved
- * );
- *
- * If you're using Microsoft Developer Studio 5.0 to declare a
- * function in a Win32 Cryptoki .dll, it might be defined by:
- *
- * #define CK_DECLARE_FUNCTION(returnType, name) \
- *   returnType __declspec(dllimport) name
- *
- * If you're using an earlier version of Microsoft Developer
- * Studio to declare a function in a Win16 Cryptoki .dll, it
- * might be defined by:
- *
- * #define CK_DECLARE_FUNCTION(returnType, name) \
- *   returnType __export _far _pascal name
- *
- * In a UNIX environment, it might be defined by:
- *
- * #define CK_DECLARE_FUNCTION(returnType, name) \
- *   returnType name
- *
- *
- * 4. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro
- * which makes a Cryptoki API function pointer declaration or
- * function pointer type declaration out of a return type and a
- * function name.  It should be used in the following fashion:
- *
- * // Define funcPtr to be a pointer to a Cryptoki API function
- * // taking arguments args and returning CK_RV.
- * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args);
- *
- * or
- *
- * // Define funcPtrType to be the type of a pointer to a
- * // Cryptoki API function taking arguments args and returning
- * // CK_RV, and then define funcPtr to be a variable of type
- * // funcPtrType.
- * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args);
- * funcPtrType funcPtr;
- *
- * If you're using Microsoft Developer Studio 5.0 to access
- * functions in a Win32 Cryptoki .dll, in might be defined by:
- *
- * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
- *   returnType __declspec(dllimport) (* name)
- *
- * If you're using an earlier version of Microsoft Developer
- * Studio to access functions in a Win16 Cryptoki .dll, it might
- * be defined by:
- *
- * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
- *   returnType __export _far _pascal (* name)
- *
- * In a UNIX environment, it might be defined by:
- *
- * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
- *   returnType (* name)
- *
- *
- * 5. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes
- * a function pointer type for an application callback out of
- * a return type for the callback and a name for the callback.
- * It should be used in the following fashion:
- *
- * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args);
- *
- * to declare a function pointer, myCallback, to a callback
- * which takes arguments args and returns a CK_RV.  It can also
- * be used like this:
- *
- * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args);
- * myCallbackType myCallback;
- *
- * If you're using Microsoft Developer Studio 5.0 to do Win32
- * Cryptoki development, it might be defined by:
- *
- * #define CK_CALLBACK_FUNCTION(returnType, name) \
- *   returnType (* name)
- *
- * If you're using an earlier version of Microsoft Developer
- * Studio to do Win16 development, it might be defined by:
- *
- * #define CK_CALLBACK_FUNCTION(returnType, name) \
- *   returnType _far _pascal (* name)
- *
- * In a UNIX environment, it might be defined by:
- *
- * #define CK_CALLBACK_FUNCTION(returnType, name) \
- *   returnType (* name)
- *
- *
- * 6. NULL_PTR: This macro is the value of a NULL pointer.
- *
- * In any ANSI/ISO C environment (and in many others as well),
- * this should best be defined by
- *
- * #ifndef NULL_PTR
- * #define NULL_PTR 0
- * #endif
- */
-
-
-/* All the various Cryptoki types and #define'd values are in the
- * file pkcs11t.h. */
-#include "pkcs11t.h"
-
-#define __PASTE(x,y)      x##y
-
-
-/* ==============================================================
- * Define the "extern" form of all the entry points.
- * ==============================================================
- */
-
-#define CK_NEED_ARG_LIST  1
-#define CK_PKCS11_FUNCTION_INFO(name) \
-  extern CK_DECLARE_FUNCTION(CK_RV, name)
-
-/* pkcs11f.h has all the information about the Cryptoki
- * function prototypes. */
-#include "pkcs11f.h"
-
-#undef CK_NEED_ARG_LIST
-#undef CK_PKCS11_FUNCTION_INFO
-
-
-/* ==============================================================
- * Define the typedef form of all the entry points.  That is, for
- * each Cryptoki function C_XXX, define a type CK_C_XXX which is
- * a pointer to that kind of function.
- * ==============================================================
- */
-
-#define CK_NEED_ARG_LIST  1
-#define CK_PKCS11_FUNCTION_INFO(name) \
-  typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name))
-
-/* pkcs11f.h has all the information about the Cryptoki
- * function prototypes. */
-#include "pkcs11f.h"
-
-#undef CK_NEED_ARG_LIST
-#undef CK_PKCS11_FUNCTION_INFO
-
-
-/* ==============================================================
- * Define structed vector of entry points.  A CK_FUNCTION_LIST
- * contains a CK_VERSION indicating a library's Cryptoki version
- * and then a whole slew of function pointers to the routines in
- * the library.  This type was declared, but not defined, in
- * pkcs11t.h.
- * ==============================================================
- */
-
-#define CK_PKCS11_FUNCTION_INFO(name) \
-  __PASTE(CK_,name) name;
-
-struct CK_FUNCTION_LIST {
-
-  CK_VERSION    version;  /* Cryptoki version */
-
-/* Pile all the function pointers into the CK_FUNCTION_LIST. */
-/* pkcs11f.h has all the information about the Cryptoki
- * function prototypes. */
-#include "pkcs11f.h"
-
-};
-
-#undef CK_PKCS11_FUNCTION_INFO
-
-
-#undef __PASTE
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/src/pluto/rsaref/pkcs11f.h b/src/pluto/rsaref/pkcs11f.h
deleted file mode 100644 (file)
index 54b884a..0000000
+++ /dev/null
@@ -1,912 +0,0 @@
-/* pkcs11f.h include file for PKCS #11. */
-/* $Revision: 1.2 $ */
-
-/* License to copy and use this software is granted provided that it is
- * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
- * (Cryptoki)" in all material mentioning or referencing this software.
-
- * License is also granted to make and use derivative works provided that
- * such works are identified as "derived from the RSA Security Inc. PKCS #11
- * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
- * referencing the derived work.
-
- * RSA Security Inc. makes no representations concerning either the
- * merchantability of this software or the suitability of this software for
- * any particular purpose. It is provided "as is" without express or implied
- * warranty of any kind.
- */
-
-/* This header file contains pretty much everything about all the */
-/* Cryptoki function prototypes.  Because this information is */
-/* used for more than just declaring function prototypes, the */
-/* order of the functions appearing herein is important, and */
-/* should not be altered. */
-
-/* General-purpose */
-
-/* C_Initialize initializes the Cryptoki library. */
-CK_PKCS11_FUNCTION_INFO(C_Initialize)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_VOID_PTR   pInitArgs  /* if this is not NULL_PTR, it gets
-                            * cast to CK_C_INITIALIZE_ARGS_PTR
-                            * and dereferenced */
-);
-#endif
-
-
-/* C_Finalize indicates that an application is done with the
- * Cryptoki library. */
-CK_PKCS11_FUNCTION_INFO(C_Finalize)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_VOID_PTR   pReserved  /* reserved.  Should be NULL_PTR */
-);
-#endif
-
-
-/* C_GetInfo returns general information about Cryptoki. */
-CK_PKCS11_FUNCTION_INFO(C_GetInfo)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_INFO_PTR   pInfo  /* location that receives information */
-);
-#endif
-
-
-/* C_GetFunctionList returns the function list. */
-CK_PKCS11_FUNCTION_INFO(C_GetFunctionList)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_FUNCTION_LIST_PTR_PTR ppFunctionList  /* receives pointer to
-                                            * function list */
-);
-#endif
-
-
-
-/* Slot and token management */
-
-/* C_GetSlotList obtains a list of slots in the system. */
-CK_PKCS11_FUNCTION_INFO(C_GetSlotList)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_BBOOL       tokenPresent,  /* only slots with tokens? */
-  CK_SLOT_ID_PTR pSlotList,     /* receives array of slot IDs */
-  CK_ULONG_PTR   pulCount       /* receives number of slots */
-);
-#endif
-
-
-/* C_GetSlotInfo obtains information about a particular slot in
- * the system. */
-CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SLOT_ID       slotID,  /* the ID of the slot */
-  CK_SLOT_INFO_PTR pInfo    /* receives the slot information */
-);
-#endif
-
-
-/* C_GetTokenInfo obtains information about a particular token
- * in the system. */
-CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SLOT_ID        slotID,  /* ID of the token's slot */
-  CK_TOKEN_INFO_PTR pInfo    /* receives the token information */
-);
-#endif
-
-
-/* C_GetMechanismList obtains a list of mechanism types
- * supported by a token. */
-CK_PKCS11_FUNCTION_INFO(C_GetMechanismList)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SLOT_ID            slotID,          /* ID of token's slot */
-  CK_MECHANISM_TYPE_PTR pMechanismList,  /* gets mech. array */
-  CK_ULONG_PTR          pulCount         /* gets # of mechs. */
-);
-#endif
-
-
-/* C_GetMechanismInfo obtains information about a particular
- * mechanism possibly supported by a token. */
-CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SLOT_ID            slotID,  /* ID of the token's slot */
-  CK_MECHANISM_TYPE     type,    /* type of mechanism */
-  CK_MECHANISM_INFO_PTR pInfo    /* receives mechanism info */
-);
-#endif
-
-
-/* C_InitToken initializes a token. */
-CK_PKCS11_FUNCTION_INFO(C_InitToken)
-#ifdef CK_NEED_ARG_LIST
-/* pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10 */
-(
-  CK_SLOT_ID      slotID,    /* ID of the token's slot */
-  CK_UTF8CHAR_PTR pPin,      /* the SO's initial PIN */
-  CK_ULONG        ulPinLen,  /* length in bytes of the PIN */
-  CK_UTF8CHAR_PTR pLabel     /* 32-byte token label (blank padded) */
-);
-#endif
-
-
-/* C_InitPIN initializes the normal user's PIN. */
-CK_PKCS11_FUNCTION_INFO(C_InitPIN)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,  /* the session's handle */
-  CK_UTF8CHAR_PTR   pPin,      /* the normal user's PIN */
-  CK_ULONG          ulPinLen   /* length in bytes of the PIN */
-);
-#endif
-
-
-/* C_SetPIN modifies the PIN of the user who is logged in. */
-CK_PKCS11_FUNCTION_INFO(C_SetPIN)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,  /* the session's handle */
-  CK_UTF8CHAR_PTR   pOldPin,   /* the old PIN */
-  CK_ULONG          ulOldLen,  /* length of the old PIN */
-  CK_UTF8CHAR_PTR   pNewPin,   /* the new PIN */
-  CK_ULONG          ulNewLen   /* length of the new PIN */
-);
-#endif
-
-
-
-/* Session management */
-
-/* C_OpenSession opens a session between an application and a
- * token. */
-CK_PKCS11_FUNCTION_INFO(C_OpenSession)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SLOT_ID            slotID,        /* the slot's ID */
-  CK_FLAGS              flags,         /* from CK_SESSION_INFO */
-  CK_VOID_PTR           pApplication,  /* passed to callback */
-  CK_NOTIFY             Notify,        /* callback function */
-  CK_SESSION_HANDLE_PTR phSession      /* gets session handle */
-);
-#endif
-
-
-/* C_CloseSession closes a session between an application and a
- * token. */
-CK_PKCS11_FUNCTION_INFO(C_CloseSession)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession  /* the session's handle */
-);
-#endif
-
-
-/* C_CloseAllSessions closes all sessions with a token. */
-CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SLOT_ID     slotID  /* the token's slot */
-);
-#endif
-
-
-/* C_GetSessionInfo obtains information about the session. */
-CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE   hSession,  /* the session's handle */
-  CK_SESSION_INFO_PTR pInfo      /* receives session info */
-);
-#endif
-
-
-/* C_GetOperationState obtains the state of the cryptographic operation
- * in a session. */
-CK_PKCS11_FUNCTION_INFO(C_GetOperationState)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,             /* session's handle */
-  CK_BYTE_PTR       pOperationState,      /* gets state */
-  CK_ULONG_PTR      pulOperationStateLen  /* gets state length */
-);
-#endif
-
-
-/* C_SetOperationState restores the state of the cryptographic
- * operation in a session. */
-CK_PKCS11_FUNCTION_INFO(C_SetOperationState)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,            /* session's handle */
-  CK_BYTE_PTR      pOperationState,      /* holds state */
-  CK_ULONG         ulOperationStateLen,  /* holds state length */
-  CK_OBJECT_HANDLE hEncryptionKey,       /* en/decryption key */
-  CK_OBJECT_HANDLE hAuthenticationKey    /* sign/verify key */
-);
-#endif
-
-
-/* C_Login logs a user into a token. */
-CK_PKCS11_FUNCTION_INFO(C_Login)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,  /* the session's handle */
-  CK_USER_TYPE      userType,  /* the user type */
-  CK_UTF8CHAR_PTR   pPin,      /* the user's PIN */
-  CK_ULONG          ulPinLen   /* the length of the PIN */
-);
-#endif
-
-
-/* C_Logout logs a user out from a token. */
-CK_PKCS11_FUNCTION_INFO(C_Logout)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession  /* the session's handle */
-);
-#endif
-
-
-
-/* Object management */
-
-/* C_CreateObject creates a new object. */
-CK_PKCS11_FUNCTION_INFO(C_CreateObject)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,    /* the session's handle */
-  CK_ATTRIBUTE_PTR  pTemplate,   /* the object's template */
-  CK_ULONG          ulCount,     /* attributes in template */
-  CK_OBJECT_HANDLE_PTR phObject  /* gets new object's handle. */
-);
-#endif
-
-
-/* C_CopyObject copies an object, creating a new object for the
- * copy. */
-CK_PKCS11_FUNCTION_INFO(C_CopyObject)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE    hSession,    /* the session's handle */
-  CK_OBJECT_HANDLE     hObject,     /* the object's handle */
-  CK_ATTRIBUTE_PTR     pTemplate,   /* template for new object */
-  CK_ULONG             ulCount,     /* attributes in template */
-  CK_OBJECT_HANDLE_PTR phNewObject  /* receives handle of copy */
-);
-#endif
-
-
-/* C_DestroyObject destroys an object. */
-CK_PKCS11_FUNCTION_INFO(C_DestroyObject)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,  /* the session's handle */
-  CK_OBJECT_HANDLE  hObject    /* the object's handle */
-);
-#endif
-
-
-/* C_GetObjectSize gets the size of an object in bytes. */
-CK_PKCS11_FUNCTION_INFO(C_GetObjectSize)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,  /* the session's handle */
-  CK_OBJECT_HANDLE  hObject,   /* the object's handle */
-  CK_ULONG_PTR      pulSize    /* receives size of object */
-);
-#endif
-
-
-/* C_GetAttributeValue obtains the value of one or more object
- * attributes. */
-CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,   /* the session's handle */
-  CK_OBJECT_HANDLE  hObject,    /* the object's handle */
-  CK_ATTRIBUTE_PTR  pTemplate,  /* specifies attrs; gets vals */
-  CK_ULONG          ulCount     /* attributes in template */
-);
-#endif
-
-
-/* C_SetAttributeValue modifies the value of one or more object
- * attributes */
-CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,   /* the session's handle */
-  CK_OBJECT_HANDLE  hObject,    /* the object's handle */
-  CK_ATTRIBUTE_PTR  pTemplate,  /* specifies attrs and values */
-  CK_ULONG          ulCount     /* attributes in template */
-);
-#endif
-
-
-/* C_FindObjectsInit initializes a search for token and session
- * objects that match a template. */
-CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,   /* the session's handle */
-  CK_ATTRIBUTE_PTR  pTemplate,  /* attribute values to match */
-  CK_ULONG          ulCount     /* attrs in search template */
-);
-#endif
-
-
-/* C_FindObjects continues a search for token and session
- * objects that match a template, obtaining additional object
- * handles. */
-CK_PKCS11_FUNCTION_INFO(C_FindObjects)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE    hSession,          /* session's handle */
- CK_OBJECT_HANDLE_PTR phObject,          /* gets obj. handles */
- CK_ULONG             ulMaxObjectCount,  /* max handles to get */
- CK_ULONG_PTR         pulObjectCount     /* actual # returned */
-);
-#endif
-
-
-/* C_FindObjectsFinal finishes a search for token and session
- * objects. */
-CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession  /* the session's handle */
-);
-#endif
-
-
-
-/* Encryption and decryption */
-
-/* C_EncryptInit initializes an encryption operation. */
-CK_PKCS11_FUNCTION_INFO(C_EncryptInit)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,    /* the session's handle */
-  CK_MECHANISM_PTR  pMechanism,  /* the encryption mechanism */
-  CK_OBJECT_HANDLE  hKey         /* handle of encryption key */
-);
-#endif
-
-
-/* C_Encrypt encrypts single-part data. */
-CK_PKCS11_FUNCTION_INFO(C_Encrypt)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,            /* session's handle */
-  CK_BYTE_PTR       pData,               /* the plaintext data */
-  CK_ULONG          ulDataLen,           /* bytes of plaintext */
-  CK_BYTE_PTR       pEncryptedData,      /* gets ciphertext */
-  CK_ULONG_PTR      pulEncryptedDataLen  /* gets c-text size */
-);
-#endif
-
-
-/* C_EncryptUpdate continues a multiple-part encryption
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,           /* session's handle */
-  CK_BYTE_PTR       pPart,              /* the plaintext data */
-  CK_ULONG          ulPartLen,          /* plaintext data len */
-  CK_BYTE_PTR       pEncryptedPart,     /* gets ciphertext */
-  CK_ULONG_PTR      pulEncryptedPartLen /* gets c-text size */
-);
-#endif
-
-
-/* C_EncryptFinal finishes a multiple-part encryption
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_EncryptFinal)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,                /* session handle */
-  CK_BYTE_PTR       pLastEncryptedPart,      /* last c-text */
-  CK_ULONG_PTR      pulLastEncryptedPartLen  /* gets last size */
-);
-#endif
-
-
-/* C_DecryptInit initializes a decryption operation. */
-CK_PKCS11_FUNCTION_INFO(C_DecryptInit)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,    /* the session's handle */
-  CK_MECHANISM_PTR  pMechanism,  /* the decryption mechanism */
-  CK_OBJECT_HANDLE  hKey         /* handle of decryption key */
-);
-#endif
-
-
-/* C_Decrypt decrypts encrypted data in a single part. */
-CK_PKCS11_FUNCTION_INFO(C_Decrypt)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,           /* session's handle */
-  CK_BYTE_PTR       pEncryptedData,     /* ciphertext */
-  CK_ULONG          ulEncryptedDataLen, /* ciphertext length */
-  CK_BYTE_PTR       pData,              /* gets plaintext */
-  CK_ULONG_PTR      pulDataLen          /* gets p-text size */
-);
-#endif
-
-
-/* C_DecryptUpdate continues a multiple-part decryption
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,            /* session's handle */
-  CK_BYTE_PTR       pEncryptedPart,      /* encrypted data */
-  CK_ULONG          ulEncryptedPartLen,  /* input length */
-  CK_BYTE_PTR       pPart,               /* gets plaintext */
-  CK_ULONG_PTR      pulPartLen           /* p-text size */
-);
-#endif
-
-
-/* C_DecryptFinal finishes a multiple-part decryption
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_DecryptFinal)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,       /* the session's handle */
-  CK_BYTE_PTR       pLastPart,      /* gets plaintext */
-  CK_ULONG_PTR      pulLastPartLen  /* p-text size */
-);
-#endif
-
-
-
-/* Message digesting */
-
-/* C_DigestInit initializes a message-digesting operation. */
-CK_PKCS11_FUNCTION_INFO(C_DigestInit)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,   /* the session's handle */
-  CK_MECHANISM_PTR  pMechanism  /* the digesting mechanism */
-);
-#endif
-
-
-/* C_Digest digests data in a single part. */
-CK_PKCS11_FUNCTION_INFO(C_Digest)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,     /* the session's handle */
-  CK_BYTE_PTR       pData,        /* data to be digested */
-  CK_ULONG          ulDataLen,    /* bytes of data to digest */
-  CK_BYTE_PTR       pDigest,      /* gets the message digest */
-  CK_ULONG_PTR      pulDigestLen  /* gets digest length */
-);
-#endif
-
-
-/* C_DigestUpdate continues a multiple-part message-digesting
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_DigestUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,  /* the session's handle */
-  CK_BYTE_PTR       pPart,     /* data to be digested */
-  CK_ULONG          ulPartLen  /* bytes of data to be digested */
-);
-#endif
-
-
-/* C_DigestKey continues a multi-part message-digesting
- * operation, by digesting the value of a secret key as part of
- * the data already digested. */
-CK_PKCS11_FUNCTION_INFO(C_DigestKey)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,  /* the session's handle */
-  CK_OBJECT_HANDLE  hKey       /* secret key to digest */
-);
-#endif
-
-
-/* C_DigestFinal finishes a multiple-part message-digesting
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_DigestFinal)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,     /* the session's handle */
-  CK_BYTE_PTR       pDigest,      /* gets the message digest */
-  CK_ULONG_PTR      pulDigestLen  /* gets byte count of digest */
-);
-#endif
-
-
-
-/* Signing and MACing */
-
-/* C_SignInit initializes a signature (private key encryption)
- * operation, where the signature is (will be) an appendix to
- * the data, and plaintext cannot be recovered from the
- *signature. */
-CK_PKCS11_FUNCTION_INFO(C_SignInit)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,    /* the session's handle */
-  CK_MECHANISM_PTR  pMechanism,  /* the signature mechanism */
-  CK_OBJECT_HANDLE  hKey         /* handle of signature key */
-);
-#endif
-
-
-/* C_Sign signs (encrypts with private key) data in a single
- * part, where the signature is (will be) an appendix to the
- * data, and plaintext cannot be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_Sign)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,        /* the session's handle */
-  CK_BYTE_PTR       pData,           /* the data to sign */
-  CK_ULONG          ulDataLen,       /* count of bytes to sign */
-  CK_BYTE_PTR       pSignature,      /* gets the signature */
-  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
-);
-#endif
-
-
-/* C_SignUpdate continues a multiple-part signature operation,
- * where the signature is (will be) an appendix to the data,
- * and plaintext cannot be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_SignUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,  /* the session's handle */
-  CK_BYTE_PTR       pPart,     /* the data to sign */
-  CK_ULONG          ulPartLen  /* count of bytes to sign */
-);
-#endif
-
-
-/* C_SignFinal finishes a multiple-part signature operation,
- * returning the signature. */
-CK_PKCS11_FUNCTION_INFO(C_SignFinal)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,        /* the session's handle */
-  CK_BYTE_PTR       pSignature,      /* gets the signature */
-  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
-);
-#endif
-
-
-/* C_SignRecoverInit initializes a signature operation, where
- * the data can be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,   /* the session's handle */
-  CK_MECHANISM_PTR  pMechanism, /* the signature mechanism */
-  CK_OBJECT_HANDLE  hKey        /* handle of the signature key */
-);
-#endif
-
-
-/* C_SignRecover signs data in a single operation, where the
- * data can be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_SignRecover)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,        /* the session's handle */
-  CK_BYTE_PTR       pData,           /* the data to sign */
-  CK_ULONG          ulDataLen,       /* count of bytes to sign */
-  CK_BYTE_PTR       pSignature,      /* gets the signature */
-  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
-);
-#endif
-
-
-
-/* Verifying signatures and MACs */
-
-/* C_VerifyInit initializes a verification operation, where the
- * signature is an appendix to the data, and plaintext cannot
- *  cannot be recovered from the signature (e.g. DSA). */
-CK_PKCS11_FUNCTION_INFO(C_VerifyInit)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,    /* the session's handle */
-  CK_MECHANISM_PTR  pMechanism,  /* the verification mechanism */
-  CK_OBJECT_HANDLE  hKey         /* verification key */
-);
-#endif
-
-
-/* C_Verify verifies a signature in a single-part operation,
- * where the signature is an appendix to the data, and plaintext
- * cannot be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_Verify)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,       /* the session's handle */
-  CK_BYTE_PTR       pData,          /* signed data */
-  CK_ULONG          ulDataLen,      /* length of signed data */
-  CK_BYTE_PTR       pSignature,     /* signature */
-  CK_ULONG          ulSignatureLen  /* signature length*/
-);
-#endif
-
-
-/* C_VerifyUpdate continues a multiple-part verification
- * operation, where the signature is an appendix to the data,
- * and plaintext cannot be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,  /* the session's handle */
-  CK_BYTE_PTR       pPart,     /* signed data */
-  CK_ULONG          ulPartLen  /* length of signed data */
-);
-#endif
-
-
-/* C_VerifyFinal finishes a multiple-part verification
- * operation, checking the signature. */
-CK_PKCS11_FUNCTION_INFO(C_VerifyFinal)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,       /* the session's handle */
-  CK_BYTE_PTR       pSignature,     /* signature to verify */
-  CK_ULONG          ulSignatureLen  /* signature length */
-);
-#endif
-
-
-/* C_VerifyRecoverInit initializes a signature verification
- * operation, where the data is recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,    /* the session's handle */
-  CK_MECHANISM_PTR  pMechanism,  /* the verification mechanism */
-  CK_OBJECT_HANDLE  hKey         /* verification key */
-);
-#endif
-
-
-/* C_VerifyRecover verifies a signature in a single-part
- * operation, where the data is recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_VerifyRecover)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,        /* the session's handle */
-  CK_BYTE_PTR       pSignature,      /* signature to verify */
-  CK_ULONG          ulSignatureLen,  /* signature length */
-  CK_BYTE_PTR       pData,           /* gets signed data */
-  CK_ULONG_PTR      pulDataLen       /* gets signed data len */
-);
-#endif
-
-
-
-/* Dual-function cryptographic operations */
-
-/* C_DigestEncryptUpdate continues a multiple-part digesting
- * and encryption operation. */
-CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,            /* session's handle */
-  CK_BYTE_PTR       pPart,               /* the plaintext data */
-  CK_ULONG          ulPartLen,           /* plaintext length */
-  CK_BYTE_PTR       pEncryptedPart,      /* gets ciphertext */
-  CK_ULONG_PTR      pulEncryptedPartLen  /* gets c-text length */
-);
-#endif
-
-
-/* C_DecryptDigestUpdate continues a multiple-part decryption and
- * digesting operation. */
-CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,            /* session's handle */
-  CK_BYTE_PTR       pEncryptedPart,      /* ciphertext */
-  CK_ULONG          ulEncryptedPartLen,  /* ciphertext length */
-  CK_BYTE_PTR       pPart,               /* gets plaintext */
-  CK_ULONG_PTR      pulPartLen           /* gets plaintext len */
-);
-#endif
-
-
-/* C_SignEncryptUpdate continues a multiple-part signing and
- * encryption operation. */
-CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,            /* session's handle */
-  CK_BYTE_PTR       pPart,               /* the plaintext data */
-  CK_ULONG          ulPartLen,           /* plaintext length */
-  CK_BYTE_PTR       pEncryptedPart,      /* gets ciphertext */
-  CK_ULONG_PTR      pulEncryptedPartLen  /* gets c-text length */
-);
-#endif
-
-
-/* C_DecryptVerifyUpdate continues a multiple-part decryption and
- * verify operation. */
-CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,            /* session's handle */
-  CK_BYTE_PTR       pEncryptedPart,      /* ciphertext */
-  CK_ULONG          ulEncryptedPartLen,  /* ciphertext length */
-  CK_BYTE_PTR       pPart,               /* gets plaintext */
-  CK_ULONG_PTR      pulPartLen           /* gets p-text length */
-);
-#endif
-
-
-
-/* Key management */
-
-/* C_GenerateKey generates a secret key, creating a new key
- * object. */
-CK_PKCS11_FUNCTION_INFO(C_GenerateKey)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE    hSession,    /* the session's handle */
-  CK_MECHANISM_PTR     pMechanism,  /* key generation mech. */
-  CK_ATTRIBUTE_PTR     pTemplate,   /* template for new key */
-  CK_ULONG             ulCount,     /* # of attrs in template */
-  CK_OBJECT_HANDLE_PTR phKey        /* gets handle of new key */
-);
-#endif
-
-
-/* C_GenerateKeyPair generates a public-key/private-key pair,
- * creating new key objects. */
-CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE    hSession,                    /* session
-                                                     * handle */
-  CK_MECHANISM_PTR     pMechanism,                  /* key-gen
-                                                     * mech. */
-  CK_ATTRIBUTE_PTR     pPublicKeyTemplate,          /* template
-                                                     * for pub.
-                                                     * key */
-  CK_ULONG             ulPublicKeyAttributeCount,   /* # pub.
-                                                     * attrs. */
-  CK_ATTRIBUTE_PTR     pPrivateKeyTemplate,         /* template
-                                                     * for priv.
-                                                     * key */
-  CK_ULONG             ulPrivateKeyAttributeCount,  /* # priv.
-                                                     * attrs. */
-  CK_OBJECT_HANDLE_PTR phPublicKey,                 /* gets pub.
-                                                     * key
-                                                     * handle */
-  CK_OBJECT_HANDLE_PTR phPrivateKey                 /* gets
-                                                     * priv. key
-                                                     * handle */
-);
-#endif
-
-
-/* C_WrapKey wraps (i.e., encrypts) a key. */
-CK_PKCS11_FUNCTION_INFO(C_WrapKey)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,        /* the session's handle */
-  CK_MECHANISM_PTR  pMechanism,      /* the wrapping mechanism */
-  CK_OBJECT_HANDLE  hWrappingKey,    /* wrapping key */
-  CK_OBJECT_HANDLE  hKey,            /* key to be wrapped */
-  CK_BYTE_PTR       pWrappedKey,     /* gets wrapped key */
-  CK_ULONG_PTR      pulWrappedKeyLen /* gets wrapped key size */
-);
-#endif
-
-
-/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
- * key object. */
-CK_PKCS11_FUNCTION_INFO(C_UnwrapKey)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE    hSession,          /* session's handle */
-  CK_MECHANISM_PTR     pMechanism,        /* unwrapping mech. */
-  CK_OBJECT_HANDLE     hUnwrappingKey,    /* unwrapping key */
-  CK_BYTE_PTR          pWrappedKey,       /* the wrapped key */
-  CK_ULONG             ulWrappedKeyLen,   /* wrapped key len */
-  CK_ATTRIBUTE_PTR     pTemplate,         /* new key template */
-  CK_ULONG             ulAttributeCount,  /* template length */
-  CK_OBJECT_HANDLE_PTR phKey              /* gets new handle */
-);
-#endif
-
-
-/* C_DeriveKey derives a key from a base key, creating a new key
- * object. */
-CK_PKCS11_FUNCTION_INFO(C_DeriveKey)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE    hSession,          /* session's handle */
-  CK_MECHANISM_PTR     pMechanism,        /* key deriv. mech. */
-  CK_OBJECT_HANDLE     hBaseKey,          /* base key */
-  CK_ATTRIBUTE_PTR     pTemplate,         /* new key template */
-  CK_ULONG             ulAttributeCount,  /* template length */
-  CK_OBJECT_HANDLE_PTR phKey              /* gets new handle */
-);
-#endif
-
-
-
-/* Random number generation */
-
-/* C_SeedRandom mixes additional seed material into the token's
- * random number generator. */
-CK_PKCS11_FUNCTION_INFO(C_SeedRandom)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,  /* the session's handle */
-  CK_BYTE_PTR       pSeed,     /* the seed material */
-  CK_ULONG          ulSeedLen  /* length of seed material */
-);
-#endif
-
-
-/* C_GenerateRandom generates random data. */
-CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,    /* the session's handle */
-  CK_BYTE_PTR       RandomData,  /* receives the random data */
-  CK_ULONG          ulRandomLen  /* # of bytes to generate */
-);
-#endif
-
-
-
-/* Parallel function management */
-
-/* C_GetFunctionStatus is a legacy function; it obtains an
- * updated status of a function running in parallel with an
- * application. */
-CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession  /* the session's handle */
-);
-#endif
-
-
-/* C_CancelFunction is a legacy function; it cancels a function
- * running in parallel. */
-CK_PKCS11_FUNCTION_INFO(C_CancelFunction)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession  /* the session's handle */
-);
-#endif
-
-
-
-/* Functions added in for Cryptoki Version 2.01 or later */
-
-/* C_WaitForSlotEvent waits for a slot event (token insertion,
- * removal, etc.) to occur. */
-CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_FLAGS flags,        /* blocking/nonblocking flag */
-  CK_SLOT_ID_PTR pSlot,  /* location that receives the slot ID */
-  CK_VOID_PTR pRserved   /* reserved.  Should be NULL_PTR */
-);
-#endif
diff --git a/src/pluto/rsaref/pkcs11t.h b/src/pluto/rsaref/pkcs11t.h
deleted file mode 100644 (file)
index 3da20b2..0000000
+++ /dev/null
@@ -1,1685 +0,0 @@
-/* pkcs11t.h include file for PKCS #11. */
-/* $Revision: 1.2 $ */
-
-/* License to copy and use this software is granted provided that it is
- * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
- * (Cryptoki)" in all material mentioning or referencing this software.
-
- * License is also granted to make and use derivative works provided that
- * such works are identified as "derived from the RSA Security Inc. PKCS #11
- * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
- * referencing the derived work.
-
- * RSA Security Inc. makes no representations concerning either the
- * merchantability of this software or the suitability of this software for
- * any particular purpose. It is provided "as is" without express or implied
- * warranty of any kind.
- */
-
-/* See top of pkcs11.h for information about the macros that
- * must be defined and the structure-packing conventions that
- * must be set before including this file. */
-
-#ifndef _PKCS11T_H_
-#define _PKCS11T_H_ 1
-
-#define CK_TRUE 1
-#define CK_FALSE 0
-
-#ifndef CK_DISABLE_TRUE_FALSE
-#ifndef FALSE
-#define FALSE CK_FALSE
-#endif
-
-#ifndef TRUE
-#define TRUE CK_TRUE
-#endif
-#endif
-
-/* an unsigned 8-bit value */
-typedef unsigned char     CK_BYTE;
-
-/* an unsigned 8-bit character */
-typedef CK_BYTE           CK_CHAR;
-
-/* an 8-bit UTF-8 character */
-typedef CK_BYTE           CK_UTF8CHAR;
-
-/* a BYTE-sized Boolean flag */
-typedef CK_BYTE           CK_BBOOL;
-
-/* an unsigned value, at least 32 bits long */
-typedef unsigned long int CK_ULONG;
-
-/* a signed value, the same size as a CK_ULONG */
-/* CK_LONG is new for v2.0 */
-typedef long int          CK_LONG;
-
-/* at least 32 bits; each bit is a Boolean flag */
-typedef CK_ULONG          CK_FLAGS;
-
-
-/* some special values for certain CK_ULONG variables */
-#define CK_UNAVAILABLE_INFORMATION (~0UL)
-#define CK_EFFECTIVELY_INFINITE    0
-
-
-typedef CK_BYTE     CK_PTR   CK_BYTE_PTR;
-typedef CK_CHAR     CK_PTR   CK_CHAR_PTR;
-typedef CK_UTF8CHAR CK_PTR   CK_UTF8CHAR_PTR;
-typedef CK_ULONG    CK_PTR   CK_ULONG_PTR;
-typedef void        CK_PTR   CK_VOID_PTR;
-
-/* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */
-typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR;
-
-
-/* The following value is always invalid if used as a session */
-/* handle or object handle */
-#define CK_INVALID_HANDLE 0
-
-
-typedef struct CK_VERSION {
-  CK_BYTE       major;  /* integer portion of version number */
-  CK_BYTE       minor;  /* 1/100ths portion of version number */
-} CK_VERSION;
-
-typedef CK_VERSION CK_PTR CK_VERSION_PTR;
-
-
-typedef struct CK_INFO {
-  /* manufacturerID and libraryDecription have been changed from
-   * CK_CHAR to CK_UTF8CHAR for v2.10 */
-  CK_VERSION    cryptokiVersion;     /* Cryptoki interface ver */
-  CK_UTF8CHAR   manufacturerID[32];  /* blank padded */
-  CK_FLAGS      flags;               /* must be zero */
-
-  /* libraryDescription and libraryVersion are new for v2.0 */
-  CK_UTF8CHAR   libraryDescription[32];  /* blank padded */
-  CK_VERSION    libraryVersion;          /* version of library */
-} CK_INFO;
-
-typedef CK_INFO CK_PTR    CK_INFO_PTR;
-
-
-/* CK_NOTIFICATION enumerates the types of notifications that
- * Cryptoki provides to an application */
-/* CK_NOTIFICATION has been changed from an enum to a CK_ULONG
- * for v2.0 */
-typedef CK_ULONG CK_NOTIFICATION;
-#define CKN_SURRENDER       0
-
-
-typedef CK_ULONG          CK_SLOT_ID;
-
-typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR;
-
-
-/* CK_SLOT_INFO provides information about a slot */
-typedef struct CK_SLOT_INFO {
-  /* slotDescription and manufacturerID have been changed from
-   * CK_CHAR to CK_UTF8CHAR for v2.10 */
-  CK_UTF8CHAR   slotDescription[64];  /* blank padded */
-  CK_UTF8CHAR   manufacturerID[32];   /* blank padded */
-  CK_FLAGS      flags;
-
-  /* hardwareVersion and firmwareVersion are new for v2.0 */
-  CK_VERSION    hardwareVersion;  /* version of hardware */
-  CK_VERSION    firmwareVersion;  /* version of firmware */
-} CK_SLOT_INFO;
-
-/* flags: bit flags that provide capabilities of the slot
- *      Bit Flag              Mask        Meaning
- */
-#define CKF_TOKEN_PRESENT     0x00000001  /* a token is there */
-#define CKF_REMOVABLE_DEVICE  0x00000002  /* removable devices*/
-#define CKF_HW_SLOT           0x00000004  /* hardware slot */
-
-typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR;
-
-
-/* CK_TOKEN_INFO provides information about a token */
-typedef struct CK_TOKEN_INFO {
-  /* label, manufacturerID, and model have been changed from
-   * CK_CHAR to CK_UTF8CHAR for v2.10 */
-  CK_UTF8CHAR   label[32];           /* blank padded */
-  CK_UTF8CHAR   manufacturerID[32];  /* blank padded */
-  CK_UTF8CHAR   model[16];           /* blank padded */
-  CK_CHAR       serialNumber[16];    /* blank padded */
-  CK_FLAGS      flags;               /* see below */
-
-  /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount,
-   * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been
-   * changed from CK_USHORT to CK_ULONG for v2.0 */
-  CK_ULONG      ulMaxSessionCount;     /* max open sessions */
-  CK_ULONG      ulSessionCount;        /* sess. now open */
-  CK_ULONG      ulMaxRwSessionCount;   /* max R/W sessions */
-  CK_ULONG      ulRwSessionCount;      /* R/W sess. now open */
-  CK_ULONG      ulMaxPinLen;           /* in bytes */
-  CK_ULONG      ulMinPinLen;           /* in bytes */
-  CK_ULONG      ulTotalPublicMemory;   /* in bytes */
-  CK_ULONG      ulFreePublicMemory;    /* in bytes */
-  CK_ULONG      ulTotalPrivateMemory;  /* in bytes */
-  CK_ULONG      ulFreePrivateMemory;   /* in bytes */
-
-  /* hardwareVersion, firmwareVersion, and time are new for
-   * v2.0 */
-  CK_VERSION    hardwareVersion;       /* version of hardware */
-  CK_VERSION    firmwareVersion;       /* version of firmware */
-  CK_CHAR       utcTime[16];           /* time */
-} CK_TOKEN_INFO;
-
-/* The flags parameter is defined as follows:
- *      Bit Flag                    Mask        Meaning
- */
-#define CKF_RNG                     0x00000001  /* has random #
-                                                 * generator */
-#define CKF_WRITE_PROTECTED         0x00000002  /* token is
-                                                 * write-
-                                                 * protected */
-#define CKF_LOGIN_REQUIRED          0x00000004  /* user must
-                                                 * login */
-#define CKF_USER_PIN_INITIALIZED    0x00000008  /* normal user's
-                                                 * PIN is set */
-
-/* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0.  If it is set,
- * that means that *every* time the state of cryptographic
- * operations of a session is successfully saved, all keys
- * needed to continue those operations are stored in the state */
-#define CKF_RESTORE_KEY_NOT_NEEDED  0x00000020
-
-/* CKF_CLOCK_ON_TOKEN is new for v2.0.  If it is set, that means
- * that the token has some sort of clock.  The time on that
- * clock is returned in the token info structure */
-#define CKF_CLOCK_ON_TOKEN          0x00000040
-
-/* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0.  If it is
- * set, that means that there is some way for the user to login
- * without sending a PIN through the Cryptoki library itself */
-#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100
-
-/* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0.  If it is true,
- * that means that a single session with the token can perform
- * dual simultaneous cryptographic operations (digest and
- * encrypt; decrypt and digest; sign and encrypt; and decrypt
- * and sign) */
-#define CKF_DUAL_CRYPTO_OPERATIONS  0x00000200
-
-/* CKF_TOKEN_INITIALIZED if new for v2.10. If it is true, the
- * token has been initialized using C_InitializeToken or an
- * equivalent mechanism outside the scope of PKCS #11.
- * Calling C_InitializeToken when this flag is set will cause
- * the token to be reinitialized. */
-#define CKF_TOKEN_INITIALIZED       0x00000400
-
-/* CKF_SECONDARY_AUTHENTICATION if new for v2.10. If it is
- * true, the token supports secondary authentication for
- * private key objects. This flag is deprecated in v2.11 and
-   onwards. */
-#define CKF_SECONDARY_AUTHENTICATION  0x00000800
-
-/* CKF_USER_PIN_COUNT_LOW if new for v2.10. If it is true, an
- * incorrect user login PIN has been entered at least once
- * since the last successful authentication. */
-#define CKF_USER_PIN_COUNT_LOW       0x00010000
-
-/* CKF_USER_PIN_FINAL_TRY if new for v2.10. If it is true,
- * supplying an incorrect user PIN will it to become locked. */
-#define CKF_USER_PIN_FINAL_TRY       0x00020000
-
-/* CKF_USER_PIN_LOCKED if new for v2.10. If it is true, the
- * user PIN has been locked. User login to the token is not
- * possible. */
-#define CKF_USER_PIN_LOCKED          0x00040000
-
-/* CKF_USER_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
- * the user PIN value is the default value set by token
- * initialization or manufacturing, or the PIN has been
- * expired by the card. */
-#define CKF_USER_PIN_TO_BE_CHANGED   0x00080000
-
-/* CKF_SO_PIN_COUNT_LOW if new for v2.10. If it is true, an
- * incorrect SO login PIN has been entered at least once since
- * the last successful authentication. */
-#define CKF_SO_PIN_COUNT_LOW         0x00100000
-
-/* CKF_SO_PIN_FINAL_TRY if new for v2.10. If it is true,
- * supplying an incorrect SO PIN will it to become locked. */
-#define CKF_SO_PIN_FINAL_TRY         0x00200000
-
-/* CKF_SO_PIN_LOCKED if new for v2.10. If it is true, the SO
- * PIN has been locked. SO login to the token is not possible.
- */
-#define CKF_SO_PIN_LOCKED            0x00400000
-
-/* CKF_SO_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
- * the SO PIN value is the default value set by token
- * initialization or manufacturing, or the PIN has been
- * expired by the card. */
-#define CKF_SO_PIN_TO_BE_CHANGED     0x00800000
-
-typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR;
-
-
-/* CK_SESSION_HANDLE is a Cryptoki-assigned value that
- * identifies a session */
-typedef CK_ULONG          CK_SESSION_HANDLE;
-
-typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR;
-
-
-/* CK_USER_TYPE enumerates the types of Cryptoki users */
-/* CK_USER_TYPE has been changed from an enum to a CK_ULONG for
- * v2.0 */
-typedef CK_ULONG          CK_USER_TYPE;
-/* Security Officer */
-#define CKU_SO    0
-/* Normal user */
-#define CKU_USER  1
-/* Context specific (added in v2.20) */
-#define CKU_CONTEXT_SPECIFIC   2
-
-/* CK_STATE enumerates the session states */
-/* CK_STATE has been changed from an enum to a CK_ULONG for
- * v2.0 */
-typedef CK_ULONG          CK_STATE;
-#define CKS_RO_PUBLIC_SESSION  0
-#define CKS_RO_USER_FUNCTIONS  1
-#define CKS_RW_PUBLIC_SESSION  2
-#define CKS_RW_USER_FUNCTIONS  3
-#define CKS_RW_SO_FUNCTIONS    4
-
-
-/* CK_SESSION_INFO provides information about a session */
-typedef struct CK_SESSION_INFO {
-  CK_SLOT_ID    slotID;
-  CK_STATE      state;
-  CK_FLAGS      flags;          /* see below */
-
-  /* ulDeviceError was changed from CK_USHORT to CK_ULONG for
-   * v2.0 */
-  CK_ULONG      ulDeviceError;  /* device-dependent error code */
-} CK_SESSION_INFO;
-
-/* The flags are defined in the following table:
- *      Bit Flag                Mask        Meaning
- */
-#define CKF_RW_SESSION          0x00000002  /* session is r/w */
-#define CKF_SERIAL_SESSION      0x00000004  /* no parallel */
-
-typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR;
-
-
-/* CK_OBJECT_HANDLE is a token-specific identifier for an
- * object  */
-typedef CK_ULONG          CK_OBJECT_HANDLE;
-
-typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR;
-
-
-/* CK_OBJECT_CLASS is a value that identifies the classes (or
- * types) of objects that Cryptoki recognizes.  It is defined
- * as follows: */
-/* CK_OBJECT_CLASS was changed from CK_USHORT to CK_ULONG for
- * v2.0 */
-typedef CK_ULONG          CK_OBJECT_CLASS;
-
-/* The following classes of objects are defined: */
-/* CKO_HW_FEATURE is new for v2.10 */
-/* CKO_DOMAIN_PARAMETERS is new for v2.11 */
-/* CKO_MECHANISM is new for v2.20 */
-#define CKO_DATA              0x00000000
-#define CKO_CERTIFICATE       0x00000001
-#define CKO_PUBLIC_KEY        0x00000002
-#define CKO_PRIVATE_KEY       0x00000003
-#define CKO_SECRET_KEY        0x00000004
-#define CKO_HW_FEATURE        0x00000005
-#define CKO_DOMAIN_PARAMETERS 0x00000006
-#define CKO_MECHANISM         0x00000007
-#define CKO_VENDOR_DEFINED    0x80000000
-
-typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR;
-
-/* CK_HW_FEATURE_TYPE is new for v2.10. CK_HW_FEATURE_TYPE is a
- * value that identifies the hardware feature type of an object
- * with CK_OBJECT_CLASS equal to CKO_HW_FEATURE. */
-typedef CK_ULONG          CK_HW_FEATURE_TYPE;
-
-/* The following hardware feature types are defined */
-/* CKH_USER_INTERFACE is new for v2.20 */
-#define CKH_MONOTONIC_COUNTER  0x00000001
-#define CKH_CLOCK           0x00000002
-#define CKH_USER_INTERFACE  0x00000003
-#define CKH_VENDOR_DEFINED  0x80000000
-
-/* CK_KEY_TYPE is a value that identifies a key type */
-/* CK_KEY_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */
-typedef CK_ULONG          CK_KEY_TYPE;
-
-/* the following key types are defined: */
-#define CKK_RSA             0x00000000
-#define CKK_DSA             0x00000001
-#define CKK_DH              0x00000002
-
-/* CKK_ECDSA and CKK_KEA are new for v2.0 */
-/* CKK_ECDSA is deprecated in v2.11, CKK_EC is preferred. */
-#define CKK_ECDSA           0x00000003
-#define CKK_EC              0x00000003
-#define CKK_X9_42_DH        0x00000004
-#define CKK_KEA             0x00000005
-
-#define CKK_GENERIC_SECRET  0x00000010
-#define CKK_RC2             0x00000011
-#define CKK_RC4             0x00000012
-#define CKK_DES             0x00000013
-#define CKK_DES2            0x00000014
-#define CKK_DES3            0x00000015
-
-/* all these key types are new for v2.0 */
-#define CKK_CAST            0x00000016
-#define CKK_CAST3           0x00000017
-/* CKK_CAST5 is deprecated in v2.11, CKK_CAST128 is preferred. */
-#define CKK_CAST5           0x00000018
-#define CKK_CAST128         0x00000018
-#define CKK_RC5             0x00000019
-#define CKK_IDEA            0x0000001A
-#define CKK_SKIPJACK        0x0000001B
-#define CKK_BATON           0x0000001C
-#define CKK_JUNIPER         0x0000001D
-#define CKK_CDMF            0x0000001E
-#define CKK_AES             0x0000001F
-
-/* BlowFish and TwoFish are new for v2.20 */
-#define CKK_BLOWFISH        0x00000020
-#define CKK_TWOFISH         0x00000021
-
-#define CKK_VENDOR_DEFINED  0x80000000
-
-
-/* CK_CERTIFICATE_TYPE is a value that identifies a certificate
- * type */
-/* CK_CERTIFICATE_TYPE was changed from CK_USHORT to CK_ULONG
- * for v2.0 */
-typedef CK_ULONG          CK_CERTIFICATE_TYPE;
-
-/* The following certificate types are defined: */
-/* CKC_X_509_ATTR_CERT is new for v2.10 */
-/* CKC_WTLS is new for v2.20 */
-#define CKC_X_509           0x00000000
-#define CKC_X_509_ATTR_CERT 0x00000001
-#define CKC_WTLS            0x00000002
-#define CKC_VENDOR_DEFINED  0x80000000
-
-
-/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute
- * type */
-/* CK_ATTRIBUTE_TYPE was changed from CK_USHORT to CK_ULONG for
- * v2.0 */
-typedef CK_ULONG          CK_ATTRIBUTE_TYPE;
-
-/* The CKF_ARRAY_ATTRIBUTE flag identifies an attribute which
-   consists of an array of values. */
-#define CKF_ARRAY_ATTRIBUTE    0x40000000
-
-/* The following attribute types are defined: */
-#define CKA_CLASS              0x00000000
-#define CKA_TOKEN              0x00000001
-#define CKA_PRIVATE            0x00000002
-#define CKA_LABEL              0x00000003
-#define CKA_APPLICATION        0x00000010
-#define CKA_VALUE              0x00000011
-
-/* CKA_OBJECT_ID is new for v2.10 */
-#define CKA_OBJECT_ID          0x00000012
-
-#define CKA_CERTIFICATE_TYPE   0x00000080
-#define CKA_ISSUER             0x00000081
-#define CKA_SERIAL_NUMBER      0x00000082
-
-/* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new
- * for v2.10 */
-#define CKA_AC_ISSUER          0x00000083
-#define CKA_OWNER              0x00000084
-#define CKA_ATTR_TYPES         0x00000085
-
-/* CKA_TRUSTED is new for v2.11 */
-#define CKA_TRUSTED            0x00000086
-
-/* CKA_CERTIFICATE_CATEGORY ...
- * CKA_CHECK_VALUE are new for v2.20 */
-#define CKA_CERTIFICATE_CATEGORY        0x00000087
-#define CKA_JAVA_MIDP_SECURITY_DOMAIN   0x00000088
-#define CKA_URL                         0x00000089
-#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY  0x0000008A
-#define CKA_HASH_OF_ISSUER_PUBLIC_KEY   0x0000008B
-#define CKA_CHECK_VALUE                 0x00000090
-
-#define CKA_KEY_TYPE           0x00000100
-#define CKA_SUBJECT            0x00000101
-#define CKA_ID                 0x00000102
-#define CKA_SENSITIVE          0x00000103
-#define CKA_ENCRYPT            0x00000104
-#define CKA_DECRYPT            0x00000105
-#define CKA_WRAP               0x00000106
-#define CKA_UNWRAP             0x00000107
-#define CKA_SIGN               0x00000108
-#define CKA_SIGN_RECOVER       0x00000109
-#define CKA_VERIFY             0x0000010A
-#define CKA_VERIFY_RECOVER     0x0000010B
-#define CKA_DERIVE             0x0000010C
-#define CKA_START_DATE         0x00000110
-#define CKA_END_DATE           0x00000111
-#define CKA_MODULUS            0x00000120
-#define CKA_MODULUS_BITS       0x00000121
-#define CKA_PUBLIC_EXPONENT    0x00000122
-#define CKA_PRIVATE_EXPONENT   0x00000123
-#define CKA_PRIME_1            0x00000124
-#define CKA_PRIME_2            0x00000125
-#define CKA_EXPONENT_1         0x00000126
-#define CKA_EXPONENT_2         0x00000127
-#define CKA_COEFFICIENT        0x00000128
-#define CKA_PRIME              0x00000130
-#define CKA_SUBPRIME           0x00000131
-#define CKA_BASE               0x00000132
-
-/* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */
-#define CKA_PRIME_BITS         0x00000133
-#define CKA_SUBPRIME_BITS      0x00000134
-#define CKA_SUB_PRIME_BITS     CKA_SUBPRIME_BITS
-/* (To retain backwards-compatibility) */
-
-#define CKA_VALUE_BITS         0x00000160
-#define CKA_VALUE_LEN          0x00000161
-
-/* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE,
- * CKA_ALWAYS_SENSITIVE, CKA_MODIFIABLE, CKA_ECDSA_PARAMS,
- * and CKA_EC_POINT are new for v2.0 */
-#define CKA_EXTRACTABLE        0x00000162
-#define CKA_LOCAL              0x00000163
-#define CKA_NEVER_EXTRACTABLE  0x00000164
-#define CKA_ALWAYS_SENSITIVE   0x00000165
-
-/* CKA_KEY_GEN_MECHANISM is new for v2.11 */
-#define CKA_KEY_GEN_MECHANISM  0x00000166
-
-#define CKA_MODIFIABLE         0x00000170
-
-/* CKA_ECDSA_PARAMS is deprecated in v2.11,
- * CKA_EC_PARAMS is preferred. */
-#define CKA_ECDSA_PARAMS       0x00000180
-#define CKA_EC_PARAMS          0x00000180
-
-#define CKA_EC_POINT           0x00000181
-
-/* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
- * are new for v2.10. Deprecated in v2.11 and onwards. */
-#define CKA_SECONDARY_AUTH     0x00000200
-#define CKA_AUTH_PIN_FLAGS     0x00000201
-
-/* CKA_ALWAYS_AUTHENTICATE ...
- * CKA_UNWRAP_TEMPLATE are new for v2.20 */
-#define CKA_ALWAYS_AUTHENTICATE  0x00000202
-
-#define CKA_WRAP_WITH_TRUSTED    0x00000210
-#define CKA_WRAP_TEMPLATE        (CKF_ARRAY_ATTRIBUTE|0x00000211)
-#define CKA_UNWRAP_TEMPLATE      (CKF_ARRAY_ATTRIBUTE|0x00000212)
-
-/* CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, and CKA_HAS_RESET
- * are new for v2.10 */
-#define CKA_HW_FEATURE_TYPE    0x00000300
-#define CKA_RESET_ON_INIT      0x00000301
-#define CKA_HAS_RESET          0x00000302
-
-/* The following attributes are new for v2.20 */
-#define CKA_PIXEL_X                     0x00000400
-#define CKA_PIXEL_Y                     0x00000401
-#define CKA_RESOLUTION                  0x00000402
-#define CKA_CHAR_ROWS                   0x00000403
-#define CKA_CHAR_COLUMNS                0x00000404
-#define CKA_COLOR                       0x00000405
-#define CKA_BITS_PER_PIXEL              0x00000406
-#define CKA_CHAR_SETS                   0x00000480
-#define CKA_ENCODING_METHODS            0x00000481
-#define CKA_MIME_TYPES                  0x00000482
-#define CKA_MECHANISM_TYPE              0x00000500
-#define CKA_REQUIRED_CMS_ATTRIBUTES     0x00000501
-#define CKA_DEFAULT_CMS_ATTRIBUTES      0x00000502
-#define CKA_SUPPORTED_CMS_ATTRIBUTES    0x00000503
-#define CKA_ALLOWED_MECHANISMS          (CKF_ARRAY_ATTRIBUTE|0x00000600)
-
-#define CKA_VENDOR_DEFINED     0x80000000
-
-
-/* CK_ATTRIBUTE is a structure that includes the type, length
- * and value of an attribute */
-typedef struct CK_ATTRIBUTE {
-  CK_ATTRIBUTE_TYPE type;
-  CK_VOID_PTR       pValue;
-
-  /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */
-  CK_ULONG          ulValueLen;  /* in bytes */
-} CK_ATTRIBUTE;
-
-typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR;
-
-
-/* CK_DATE is a structure that defines a date */
-typedef struct CK_DATE{
-  CK_CHAR       year[4];   /* the year ("1900" - "9999") */
-  CK_CHAR       month[2];  /* the month ("01" - "12") */
-  CK_CHAR       day[2];    /* the day   ("01" - "31") */
-} CK_DATE;
-
-
-/* CK_MECHANISM_TYPE is a value that identifies a mechanism
- * type */
-/* CK_MECHANISM_TYPE was changed from CK_USHORT to CK_ULONG for
- * v2.0 */
-typedef CK_ULONG          CK_MECHANISM_TYPE;
-
-/* the following mechanism types are defined: */
-#define CKM_RSA_PKCS_KEY_PAIR_GEN      0x00000000
-#define CKM_RSA_PKCS                   0x00000001
-#define CKM_RSA_9796                   0x00000002
-#define CKM_RSA_X_509                  0x00000003
-
-/* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS
- * are new for v2.0.  They are mechanisms which hash and sign */
-#define CKM_MD2_RSA_PKCS               0x00000004
-#define CKM_MD5_RSA_PKCS               0x00000005
-#define CKM_SHA1_RSA_PKCS              0x00000006
-
-/* CKM_RIPEMD128_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS, and
- * CKM_RSA_PKCS_OAEP are new for v2.10 */
-#define CKM_RIPEMD128_RSA_PKCS         0x00000007
-#define CKM_RIPEMD160_RSA_PKCS         0x00000008
-#define CKM_RSA_PKCS_OAEP              0x00000009
-
-/* CKM_RSA_X9_31_KEY_PAIR_GEN, CKM_RSA_X9_31, CKM_SHA1_RSA_X9_31,
- * CKM_RSA_PKCS_PSS, and CKM_SHA1_RSA_PKCS_PSS are new for v2.11 */
-#define CKM_RSA_X9_31_KEY_PAIR_GEN     0x0000000A
-#define CKM_RSA_X9_31                  0x0000000B
-#define CKM_SHA1_RSA_X9_31             0x0000000C
-#define CKM_RSA_PKCS_PSS               0x0000000D
-#define CKM_SHA1_RSA_PKCS_PSS          0x0000000E
-
-#define CKM_DSA_KEY_PAIR_GEN           0x00000010
-#define CKM_DSA                        0x00000011
-#define CKM_DSA_SHA1                   0x00000012
-#define CKM_DH_PKCS_KEY_PAIR_GEN       0x00000020
-#define CKM_DH_PKCS_DERIVE             0x00000021
-
-/* CKM_X9_42_DH_KEY_PAIR_GEN, CKM_X9_42_DH_DERIVE,
- * CKM_X9_42_DH_HYBRID_DERIVE, and CKM_X9_42_MQV_DERIVE are new for
- * v2.11 */
-#define CKM_X9_42_DH_KEY_PAIR_GEN      0x00000030
-#define CKM_X9_42_DH_DERIVE            0x00000031
-#define CKM_X9_42_DH_HYBRID_DERIVE     0x00000032
-#define CKM_X9_42_MQV_DERIVE           0x00000033
-
-/* CKM_SHA256/384/512 are new for v2.20 */
-#define CKM_SHA256_RSA_PKCS            0x00000040
-#define CKM_SHA384_RSA_PKCS            0x00000041
-#define CKM_SHA512_RSA_PKCS            0x00000042
-#define CKM_SHA256_RSA_PKCS_PSS        0x00000043
-#define CKM_SHA384_RSA_PKCS_PSS        0x00000044
-#define CKM_SHA512_RSA_PKCS_PSS        0x00000045
-
-#define CKM_RC2_KEY_GEN                0x00000100
-#define CKM_RC2_ECB                    0x00000101
-#define CKM_RC2_CBC                    0x00000102
-#define CKM_RC2_MAC                    0x00000103
-
-/* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */
-#define CKM_RC2_MAC_GENERAL            0x00000104
-#define CKM_RC2_CBC_PAD                0x00000105
-
-#define CKM_RC4_KEY_GEN                0x00000110
-#define CKM_RC4                        0x00000111
-#define CKM_DES_KEY_GEN                0x00000120
-#define CKM_DES_ECB                    0x00000121
-#define CKM_DES_CBC                    0x00000122
-#define CKM_DES_MAC                    0x00000123
-
-/* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */
-#define CKM_DES_MAC_GENERAL            0x00000124
-#define CKM_DES_CBC_PAD                0x00000125
-
-#define CKM_DES2_KEY_GEN               0x00000130
-#define CKM_DES3_KEY_GEN               0x00000131
-#define CKM_DES3_ECB                   0x00000132
-#define CKM_DES3_CBC                   0x00000133
-#define CKM_DES3_MAC                   0x00000134
-
-/* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN,
- * CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC,
- * CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0 */
-#define CKM_DES3_MAC_GENERAL           0x00000135
-#define CKM_DES3_CBC_PAD               0x00000136
-#define CKM_CDMF_KEY_GEN               0x00000140
-#define CKM_CDMF_ECB                   0x00000141
-#define CKM_CDMF_CBC                   0x00000142
-#define CKM_CDMF_MAC                   0x00000143
-#define CKM_CDMF_MAC_GENERAL           0x00000144
-#define CKM_CDMF_CBC_PAD               0x00000145
-
-/* the following four DES mechanisms are new for v2.20 */
-#define CKM_DES_OFB64                  0x00000150
-#define CKM_DES_OFB8                   0x00000151
-#define CKM_DES_CFB64                  0x00000152
-#define CKM_DES_CFB8                   0x00000153
-
-#define CKM_MD2                        0x00000200
-
-/* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */
-#define CKM_MD2_HMAC                   0x00000201
-#define CKM_MD2_HMAC_GENERAL           0x00000202
-
-#define CKM_MD5                        0x00000210
-
-/* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */
-#define CKM_MD5_HMAC                   0x00000211
-#define CKM_MD5_HMAC_GENERAL           0x00000212
-
-#define CKM_SHA_1                      0x00000220
-
-/* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */
-#define CKM_SHA_1_HMAC                 0x00000221
-#define CKM_SHA_1_HMAC_GENERAL         0x00000222
-
-/* CKM_RIPEMD128, CKM_RIPEMD128_HMAC,
- * CKM_RIPEMD128_HMAC_GENERAL, CKM_RIPEMD160, CKM_RIPEMD160_HMAC,
- * and CKM_RIPEMD160_HMAC_GENERAL are new for v2.10 */
-#define CKM_RIPEMD128                  0x00000230
-#define CKM_RIPEMD128_HMAC             0x00000231
-#define CKM_RIPEMD128_HMAC_GENERAL     0x00000232
-#define CKM_RIPEMD160                  0x00000240
-#define CKM_RIPEMD160_HMAC             0x00000241
-#define CKM_RIPEMD160_HMAC_GENERAL     0x00000242
-
-/* CKM_SHA256/384/512 are new for v2.20 */
-#define CKM_SHA256                     0x00000250
-#define CKM_SHA256_HMAC                0x00000251
-#define CKM_SHA256_HMAC_GENERAL        0x00000252
-#define CKM_SHA384                     0x00000260
-#define CKM_SHA384_HMAC                0x00000261
-#define CKM_SHA384_HMAC_GENERAL        0x00000262
-#define CKM_SHA512                     0x00000270
-#define CKM_SHA512_HMAC                0x00000271
-#define CKM_SHA512_HMAC_GENERAL        0x00000272
-
-/* All of the following mechanisms are new for v2.0 */
-/* Note that CAST128 and CAST5 are the same algorithm */
-#define CKM_CAST_KEY_GEN               0x00000300
-#define CKM_CAST_ECB                   0x00000301
-#define CKM_CAST_CBC                   0x00000302
-#define CKM_CAST_MAC                   0x00000303
-#define CKM_CAST_MAC_GENERAL           0x00000304
-#define CKM_CAST_CBC_PAD               0x00000305
-#define CKM_CAST3_KEY_GEN              0x00000310
-#define CKM_CAST3_ECB                  0x00000311
-#define CKM_CAST3_CBC                  0x00000312
-#define CKM_CAST3_MAC                  0x00000313
-#define CKM_CAST3_MAC_GENERAL          0x00000314
-#define CKM_CAST3_CBC_PAD              0x00000315
-#define CKM_CAST5_KEY_GEN              0x00000320
-#define CKM_CAST128_KEY_GEN            0x00000320
-#define CKM_CAST5_ECB                  0x00000321
-#define CKM_CAST128_ECB                0x00000321
-#define CKM_CAST5_CBC                  0x00000322
-#define CKM_CAST128_CBC                0x00000322
-#define CKM_CAST5_MAC                  0x00000323
-#define CKM_CAST128_MAC                0x00000323
-#define CKM_CAST5_MAC_GENERAL          0x00000324
-#define CKM_CAST128_MAC_GENERAL        0x00000324
-#define CKM_CAST5_CBC_PAD              0x00000325
-#define CKM_CAST128_CBC_PAD            0x00000325
-#define CKM_RC5_KEY_GEN                0x00000330
-#define CKM_RC5_ECB                    0x00000331
-#define CKM_RC5_CBC                    0x00000332
-#define CKM_RC5_MAC                    0x00000333
-#define CKM_RC5_MAC_GENERAL            0x00000334
-#define CKM_RC5_CBC_PAD                0x00000335
-#define CKM_IDEA_KEY_GEN               0x00000340
-#define CKM_IDEA_ECB                   0x00000341
-#define CKM_IDEA_CBC                   0x00000342
-#define CKM_IDEA_MAC                   0x00000343
-#define CKM_IDEA_MAC_GENERAL           0x00000344
-#define CKM_IDEA_CBC_PAD               0x00000345
-#define CKM_GENERIC_SECRET_KEY_GEN     0x00000350
-#define CKM_CONCATENATE_BASE_AND_KEY   0x00000360
-#define CKM_CONCATENATE_BASE_AND_DATA  0x00000362
-#define CKM_CONCATENATE_DATA_AND_BASE  0x00000363
-#define CKM_XOR_BASE_AND_DATA          0x00000364
-#define CKM_EXTRACT_KEY_FROM_KEY       0x00000365
-#define CKM_SSL3_PRE_MASTER_KEY_GEN    0x00000370
-#define CKM_SSL3_MASTER_KEY_DERIVE     0x00000371
-#define CKM_SSL3_KEY_AND_MAC_DERIVE    0x00000372
-
-/* CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_PRE_MASTER_KEY_GEN,
- * CKM_TLS_MASTER_KEY_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE, and
- * CKM_TLS_MASTER_KEY_DERIVE_DH are new for v2.11 */
-#define CKM_SSL3_MASTER_KEY_DERIVE_DH  0x00000373
-#define CKM_TLS_PRE_MASTER_KEY_GEN     0x00000374
-#define CKM_TLS_MASTER_KEY_DERIVE      0x00000375
-#define CKM_TLS_KEY_AND_MAC_DERIVE     0x00000376
-#define CKM_TLS_MASTER_KEY_DERIVE_DH   0x00000377
-
-/* CKM_TLS_PRF is new for v2.20 */
-#define CKM_TLS_PRF                    0x00000378
-
-#define CKM_SSL3_MD5_MAC               0x00000380
-#define CKM_SSL3_SHA1_MAC              0x00000381
-#define CKM_MD5_KEY_DERIVATION         0x00000390
-#define CKM_MD2_KEY_DERIVATION         0x00000391
-#define CKM_SHA1_KEY_DERIVATION        0x00000392
-
-/* CKM_SHA256/384/512 are new for v2.20 */
-#define CKM_SHA256_KEY_DERIVATION      0x00000393
-#define CKM_SHA384_KEY_DERIVATION      0x00000394
-#define CKM_SHA512_KEY_DERIVATION      0x00000395
-
-#define CKM_PBE_MD2_DES_CBC            0x000003A0
-#define CKM_PBE_MD5_DES_CBC            0x000003A1
-#define CKM_PBE_MD5_CAST_CBC           0x000003A2
-#define CKM_PBE_MD5_CAST3_CBC          0x000003A3
-#define CKM_PBE_MD5_CAST5_CBC          0x000003A4
-#define CKM_PBE_MD5_CAST128_CBC        0x000003A4
-#define CKM_PBE_SHA1_CAST5_CBC         0x000003A5
-#define CKM_PBE_SHA1_CAST128_CBC       0x000003A5
-#define CKM_PBE_SHA1_RC4_128           0x000003A6
-#define CKM_PBE_SHA1_RC4_40            0x000003A7
-#define CKM_PBE_SHA1_DES3_EDE_CBC      0x000003A8
-#define CKM_PBE_SHA1_DES2_EDE_CBC      0x000003A9
-#define CKM_PBE_SHA1_RC2_128_CBC       0x000003AA
-#define CKM_PBE_SHA1_RC2_40_CBC        0x000003AB
-
-/* CKM_PKCS5_PBKD2 is new for v2.10 */
-#define CKM_PKCS5_PBKD2                0x000003B0
-
-#define CKM_PBA_SHA1_WITH_SHA1_HMAC    0x000003C0
-
-/* WTLS mechanisms are new for v2.20 */
-#define CKM_WTLS_PRE_MASTER_KEY_GEN         0x000003D0
-#define CKM_WTLS_MASTER_KEY_DERIVE          0x000003D1
-#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC   0x000003D2
-#define CKM_WTLS_PRF                        0x000003D3
-#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE  0x000003D4
-#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE  0x000003D5
-
-#define CKM_KEY_WRAP_LYNKS             0x00000400
-#define CKM_KEY_WRAP_SET_OAEP          0x00000401
-
-/* CKM_CMS_SIG is new for v2.20 */
-#define CKM_CMS_SIG                    0x00000500
-
-/* Fortezza mechanisms */
-#define CKM_SKIPJACK_KEY_GEN           0x00001000
-#define CKM_SKIPJACK_ECB64             0x00001001
-#define CKM_SKIPJACK_CBC64             0x00001002
-#define CKM_SKIPJACK_OFB64             0x00001003
-#define CKM_SKIPJACK_CFB64             0x00001004
-#define CKM_SKIPJACK_CFB32             0x00001005
-#define CKM_SKIPJACK_CFB16             0x00001006
-#define CKM_SKIPJACK_CFB8              0x00001007
-#define CKM_SKIPJACK_WRAP              0x00001008
-#define CKM_SKIPJACK_PRIVATE_WRAP      0x00001009
-#define CKM_SKIPJACK_RELAYX            0x0000100a
-#define CKM_KEA_KEY_PAIR_GEN           0x00001010
-#define CKM_KEA_KEY_DERIVE             0x00001011
-#define CKM_FORTEZZA_TIMESTAMP         0x00001020
-#define CKM_BATON_KEY_GEN              0x00001030
-#define CKM_BATON_ECB128               0x00001031
-#define CKM_BATON_ECB96                0x00001032
-#define CKM_BATON_CBC128               0x00001033
-#define CKM_BATON_COUNTER              0x00001034
-#define CKM_BATON_SHUFFLE              0x00001035
-#define CKM_BATON_WRAP                 0x00001036
-
-/* CKM_ECDSA_KEY_PAIR_GEN is deprecated in v2.11,
- * CKM_EC_KEY_PAIR_GEN is preferred */
-#define CKM_ECDSA_KEY_PAIR_GEN         0x00001040
-#define CKM_EC_KEY_PAIR_GEN            0x00001040
-
-#define CKM_ECDSA                      0x00001041
-#define CKM_ECDSA_SHA1                 0x00001042
-
-/* CKM_ECDH1_DERIVE, CKM_ECDH1_COFACTOR_DERIVE, and CKM_ECMQV_DERIVE
- * are new for v2.11 */
-#define CKM_ECDH1_DERIVE               0x00001050
-#define CKM_ECDH1_COFACTOR_DERIVE      0x00001051
-#define CKM_ECMQV_DERIVE               0x00001052
-
-#define CKM_JUNIPER_KEY_GEN            0x00001060
-#define CKM_JUNIPER_ECB128             0x00001061
-#define CKM_JUNIPER_CBC128             0x00001062
-#define CKM_JUNIPER_COUNTER            0x00001063
-#define CKM_JUNIPER_SHUFFLE            0x00001064
-#define CKM_JUNIPER_WRAP               0x00001065
-#define CKM_FASTHASH                   0x00001070
-
-/* CKM_AES_KEY_GEN, CKM_AES_ECB, CKM_AES_CBC, CKM_AES_MAC,
- * CKM_AES_MAC_GENERAL, CKM_AES_CBC_PAD, CKM_DSA_PARAMETER_GEN,
- * CKM_DH_PKCS_PARAMETER_GEN, and CKM_X9_42_DH_PARAMETER_GEN are
- * new for v2.11 */
-#define CKM_AES_KEY_GEN                0x00001080
-#define CKM_AES_ECB                    0x00001081
-#define CKM_AES_CBC                    0x00001082
-#define CKM_AES_MAC                    0x00001083
-#define CKM_AES_MAC_GENERAL            0x00001084
-#define CKM_AES_CBC_PAD                0x00001085
-
-/* BlowFish and TwoFish are new for v2.20 */
-#define CKM_BLOWFISH_KEY_GEN           0x00001090
-#define CKM_BLOWFISH_CBC               0x00001091
-#define CKM_TWOFISH_KEY_GEN            0x00001092
-#define CKM_TWOFISH_CBC                0x00001093
-
-
-/* CKM_xxx_ENCRYPT_DATA mechanisms are new for v2.20 */
-#define CKM_DES_ECB_ENCRYPT_DATA       0x00001100
-#define CKM_DES_CBC_ENCRYPT_DATA       0x00001101
-#define CKM_DES3_ECB_ENCRYPT_DATA      0x00001102
-#define CKM_DES3_CBC_ENCRYPT_DATA      0x00001103
-#define CKM_AES_ECB_ENCRYPT_DATA       0x00001104
-#define CKM_AES_CBC_ENCRYPT_DATA       0x00001105
-
-#define CKM_DSA_PARAMETER_GEN          0x00002000
-#define CKM_DH_PKCS_PARAMETER_GEN      0x00002001
-#define CKM_X9_42_DH_PARAMETER_GEN     0x00002002
-
-#define CKM_VENDOR_DEFINED             0x80000000
-
-typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR;
-
-
-/* CK_MECHANISM is a structure that specifies a particular
- * mechanism  */
-typedef struct CK_MECHANISM {
-  CK_MECHANISM_TYPE mechanism;
-  CK_VOID_PTR       pParameter;
-
-  /* ulParameterLen was changed from CK_USHORT to CK_ULONG for
-   * v2.0 */
-  CK_ULONG          ulParameterLen;  /* in bytes */
-} CK_MECHANISM;
-
-typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR;
-
-
-/* CK_MECHANISM_INFO provides information about a particular
- * mechanism */
-typedef struct CK_MECHANISM_INFO {
-    CK_ULONG    ulMinKeySize;
-    CK_ULONG    ulMaxKeySize;
-    CK_FLAGS    flags;
-} CK_MECHANISM_INFO;
-
-/* The flags are defined as follows:
- *      Bit Flag               Mask        Meaning */
-#define CKF_HW                 0x00000001  /* performed by HW */
-
-/* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN,
- * CKG_SIGN_RECOVER, CKF_VERIFY, CKF_VERIFY_RECOVER,
- * CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP,
- * and CKF_DERIVE are new for v2.0.  They specify whether or not
- * a mechanism can be used for a particular task */
-#define CKF_ENCRYPT            0x00000100
-#define CKF_DECRYPT            0x00000200
-#define CKF_DIGEST             0x00000400
-#define CKF_SIGN               0x00000800
-#define CKF_SIGN_RECOVER       0x00001000
-#define CKF_VERIFY             0x00002000
-#define CKF_VERIFY_RECOVER     0x00004000
-#define CKF_GENERATE           0x00008000
-#define CKF_GENERATE_KEY_PAIR  0x00010000
-#define CKF_WRAP               0x00020000
-#define CKF_UNWRAP             0x00040000
-#define CKF_DERIVE             0x00080000
-
-/* CKF_EC_F_P, CKF_EC_F_2M, CKF_EC_ECPARAMETERS, CKF_EC_NAMEDCURVE,
- * CKF_EC_UNCOMPRESS, and CKF_EC_COMPRESS are new for v2.11. They
- * describe a token's EC capabilities not available in mechanism
- * information. */
-#define CKF_EC_F_P             0x00100000
-#define CKF_EC_F_2M            0x00200000
-#define CKF_EC_ECPARAMETERS    0x00400000
-#define CKF_EC_NAMEDCURVE      0x00800000
-#define CKF_EC_UNCOMPRESS      0x01000000
-#define CKF_EC_COMPRESS        0x02000000
-
-#define CKF_EXTENSION          0x80000000 /* FALSE for this version */
-
-typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR;
-
-
-/* CK_RV is a value that identifies the return value of a
- * Cryptoki function */
-/* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */
-typedef CK_ULONG          CK_RV;
-
-#define CKR_OK                                0x00000000
-#define CKR_CANCEL                            0x00000001
-#define CKR_HOST_MEMORY                       0x00000002
-#define CKR_SLOT_ID_INVALID                   0x00000003
-
-/* CKR_FLAGS_INVALID was removed for v2.0 */
-
-/* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */
-#define CKR_GENERAL_ERROR                     0x00000005
-#define CKR_FUNCTION_FAILED                   0x00000006
-
-/* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS,
- * and CKR_CANT_LOCK are new for v2.01 */
-#define CKR_ARGUMENTS_BAD                     0x00000007
-#define CKR_NO_EVENT                          0x00000008
-#define CKR_NEED_TO_CREATE_THREADS            0x00000009
-#define CKR_CANT_LOCK                         0x0000000A
-
-#define CKR_ATTRIBUTE_READ_ONLY               0x00000010
-#define CKR_ATTRIBUTE_SENSITIVE               0x00000011
-#define CKR_ATTRIBUTE_TYPE_INVALID            0x00000012
-#define CKR_ATTRIBUTE_VALUE_INVALID           0x00000013
-#define CKR_DATA_INVALID                      0x00000020
-#define CKR_DATA_LEN_RANGE                    0x00000021
-#define CKR_DEVICE_ERROR                      0x00000030
-#define CKR_DEVICE_MEMORY                     0x00000031
-#define CKR_DEVICE_REMOVED                    0x00000032
-#define CKR_ENCRYPTED_DATA_INVALID            0x00000040
-#define CKR_ENCRYPTED_DATA_LEN_RANGE          0x00000041
-#define CKR_FUNCTION_CANCELED                 0x00000050
-#define CKR_FUNCTION_NOT_PARALLEL             0x00000051
-
-/* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */
-#define CKR_FUNCTION_NOT_SUPPORTED            0x00000054
-
-#define CKR_KEY_HANDLE_INVALID                0x00000060
-
-/* CKR_KEY_SENSITIVE was removed for v2.0 */
-
-#define CKR_KEY_SIZE_RANGE                    0x00000062
-#define CKR_KEY_TYPE_INCONSISTENT             0x00000063
-
-/* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED,
- * CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED,
- * CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are new for
- * v2.0 */
-#define CKR_KEY_NOT_NEEDED                    0x00000064
-#define CKR_KEY_CHANGED                       0x00000065
-#define CKR_KEY_NEEDED                        0x00000066
-#define CKR_KEY_INDIGESTIBLE                  0x00000067
-#define CKR_KEY_FUNCTION_NOT_PERMITTED        0x00000068
-#define CKR_KEY_NOT_WRAPPABLE                 0x00000069
-#define CKR_KEY_UNEXTRACTABLE                 0x0000006A
-
-#define CKR_MECHANISM_INVALID                 0x00000070
-#define CKR_MECHANISM_PARAM_INVALID           0x00000071
-
-/* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID
- * were removed for v2.0 */
-#define CKR_OBJECT_HANDLE_INVALID             0x00000082
-#define CKR_OPERATION_ACTIVE                  0x00000090
-#define CKR_OPERATION_NOT_INITIALIZED         0x00000091
-#define CKR_PIN_INCORRECT                     0x000000A0
-#define CKR_PIN_INVALID                       0x000000A1
-#define CKR_PIN_LEN_RANGE                     0x000000A2
-
-/* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */
-#define CKR_PIN_EXPIRED                       0x000000A3
-#define CKR_PIN_LOCKED                        0x000000A4
-
-#define CKR_SESSION_CLOSED                    0x000000B0
-#define CKR_SESSION_COUNT                     0x000000B1
-#define CKR_SESSION_HANDLE_INVALID            0x000000B3
-#define CKR_SESSION_PARALLEL_NOT_SUPPORTED    0x000000B4
-#define CKR_SESSION_READ_ONLY                 0x000000B5
-#define CKR_SESSION_EXISTS                    0x000000B6
-
-/* CKR_SESSION_READ_ONLY_EXISTS and
- * CKR_SESSION_READ_WRITE_SO_EXISTS are new for v2.0 */
-#define CKR_SESSION_READ_ONLY_EXISTS          0x000000B7
-#define CKR_SESSION_READ_WRITE_SO_EXISTS      0x000000B8
-
-#define CKR_SIGNATURE_INVALID                 0x000000C0
-#define CKR_SIGNATURE_LEN_RANGE               0x000000C1
-#define CKR_TEMPLATE_INCOMPLETE               0x000000D0
-#define CKR_TEMPLATE_INCONSISTENT             0x000000D1
-#define CKR_TOKEN_NOT_PRESENT                 0x000000E0
-#define CKR_TOKEN_NOT_RECOGNIZED              0x000000E1
-#define CKR_TOKEN_WRITE_PROTECTED             0x000000E2
-#define CKR_UNWRAPPING_KEY_HANDLE_INVALID     0x000000F0
-#define CKR_UNWRAPPING_KEY_SIZE_RANGE         0x000000F1
-#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT  0x000000F2
-#define CKR_USER_ALREADY_LOGGED_IN            0x00000100
-#define CKR_USER_NOT_LOGGED_IN                0x00000101
-#define CKR_USER_PIN_NOT_INITIALIZED          0x00000102
-#define CKR_USER_TYPE_INVALID                 0x00000103
-
-/* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES
- * are new to v2.01 */
-#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN    0x00000104
-#define CKR_USER_TOO_MANY_TYPES               0x00000105
-
-#define CKR_WRAPPED_KEY_INVALID               0x00000110
-#define CKR_WRAPPED_KEY_LEN_RANGE             0x00000112
-#define CKR_WRAPPING_KEY_HANDLE_INVALID       0x00000113
-#define CKR_WRAPPING_KEY_SIZE_RANGE           0x00000114
-#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT    0x00000115
-#define CKR_RANDOM_SEED_NOT_SUPPORTED         0x00000120
-
-/* These are new to v2.0 */
-#define CKR_RANDOM_NO_RNG                     0x00000121
-
-/* These are new to v2.11 */
-#define CKR_DOMAIN_PARAMS_INVALID             0x00000130
-
-/* These are new to v2.0 */
-#define CKR_BUFFER_TOO_SMALL                  0x00000150
-#define CKR_SAVED_STATE_INVALID               0x00000160
-#define CKR_INFORMATION_SENSITIVE             0x00000170
-#define CKR_STATE_UNSAVEABLE                  0x00000180
-
-/* These are new to v2.01 */
-#define CKR_CRYPTOKI_NOT_INITIALIZED          0x00000190
-#define CKR_CRYPTOKI_ALREADY_INITIALIZED      0x00000191
-#define CKR_MUTEX_BAD                         0x000001A0
-#define CKR_MUTEX_NOT_LOCKED                  0x000001A1
-
-/* This is new to v2.20 */
-#define CKR_FUNCTION_REJECTED                 0x00000200
-
-#define CKR_VENDOR_DEFINED                    0x80000000
-
-
-/* CK_NOTIFY is an application callback that processes events */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)(
-  CK_SESSION_HANDLE hSession,     /* the session's handle */
-  CK_NOTIFICATION   event,
-  CK_VOID_PTR       pApplication  /* passed to C_OpenSession */
-);
-
-
-/* CK_FUNCTION_LIST is a structure holding a Cryptoki spec
- * version and pointers of appropriate types to all the
- * Cryptoki functions */
-/* CK_FUNCTION_LIST is new for v2.0 */
-typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST;
-
-typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR;
-
-typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR;
-
-
-/* CK_CREATEMUTEX is an application callback for creating a
- * mutex object */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)(
-  CK_VOID_PTR_PTR ppMutex  /* location to receive ptr to mutex */
-);
-
-
-/* CK_DESTROYMUTEX is an application callback for destroying a
- * mutex object */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)(
-  CK_VOID_PTR pMutex  /* pointer to mutex */
-);
-
-
-/* CK_LOCKMUTEX is an application callback for locking a mutex */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)(
-  CK_VOID_PTR pMutex  /* pointer to mutex */
-);
-
-
-/* CK_UNLOCKMUTEX is an application callback for unlocking a
- * mutex */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)(
-  CK_VOID_PTR pMutex  /* pointer to mutex */
-);
-
-
-/* CK_C_INITIALIZE_ARGS provides the optional arguments to
- * C_Initialize */
-typedef struct CK_C_INITIALIZE_ARGS {
-  CK_CREATEMUTEX CreateMutex;
-  CK_DESTROYMUTEX DestroyMutex;
-  CK_LOCKMUTEX LockMutex;
-  CK_UNLOCKMUTEX UnlockMutex;
-  CK_FLAGS flags;
-  CK_VOID_PTR pReserved;
-} CK_C_INITIALIZE_ARGS;
-
-/* flags: bit flags that provide capabilities of the slot
- *      Bit Flag                           Mask       Meaning
- */
-#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001
-#define CKF_OS_LOCKING_OK                  0x00000002
-
-typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR;
-
-
-/* additional flags for parameters to functions */
-
-/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
-#define CKF_DONT_BLOCK     1
-
-/* CK_RSA_PKCS_OAEP_MGF_TYPE is new for v2.10.
- * CK_RSA_PKCS_OAEP_MGF_TYPE  is used to indicate the Message
- * Generation Function (MGF) applied to a message block when
- * formatting a message block for the PKCS #1 OAEP encryption
- * scheme. */
-typedef CK_ULONG CK_RSA_PKCS_MGF_TYPE;
-
-typedef CK_RSA_PKCS_MGF_TYPE CK_PTR CK_RSA_PKCS_MGF_TYPE_PTR;
-
-/* The following MGFs are defined */
-/* CKG_MGF1_SHA256, CKG_MGF1_SHA384, and CKG_MGF1_SHA512
- * are new for v2.20 */
-#define CKG_MGF1_SHA1         0x00000001
-#define CKG_MGF1_SHA256       0x00000002
-#define CKG_MGF1_SHA384       0x00000003
-#define CKG_MGF1_SHA512       0x00000004
-
-/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is new for v2.10.
- * CK_RSA_PKCS_OAEP_SOURCE_TYPE  is used to indicate the source
- * of the encoding parameter when formatting a message block
- * for the PKCS #1 OAEP encryption scheme. */
-typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE;
-
-typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR;
-
-/* The following encoding parameter sources are defined */
-#define CKZ_DATA_SPECIFIED    0x00000001
-
-/* CK_RSA_PKCS_OAEP_PARAMS is new for v2.10.
- * CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the
- * CKM_RSA_PKCS_OAEP mechanism. */
-typedef struct CK_RSA_PKCS_OAEP_PARAMS {
-        CK_MECHANISM_TYPE hashAlg;
-        CK_RSA_PKCS_MGF_TYPE mgf;
-        CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
-        CK_VOID_PTR pSourceData;
-        CK_ULONG ulSourceDataLen;
-} CK_RSA_PKCS_OAEP_PARAMS;
-
-typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR;
-
-/* CK_RSA_PKCS_PSS_PARAMS is new for v2.11.
- * CK_RSA_PKCS_PSS_PARAMS provides the parameters to the
- * CKM_RSA_PKCS_PSS mechanism(s). */
-typedef struct CK_RSA_PKCS_PSS_PARAMS {
-        CK_MECHANISM_TYPE    hashAlg;
-        CK_RSA_PKCS_MGF_TYPE mgf;
-        CK_ULONG             sLen;
-} CK_RSA_PKCS_PSS_PARAMS;
-
-typedef CK_RSA_PKCS_PSS_PARAMS CK_PTR CK_RSA_PKCS_PSS_PARAMS_PTR;
-
-/* CK_EC_KDF_TYPE is new for v2.11. */
-typedef CK_ULONG CK_EC_KDF_TYPE;
-
-/* The following EC Key Derivation Functions are defined */
-#define CKD_NULL                 0x00000001
-#define CKD_SHA1_KDF             0x00000002
-
-/* CK_ECDH1_DERIVE_PARAMS is new for v2.11.
- * CK_ECDH1_DERIVE_PARAMS provides the parameters to the
- * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms,
- * where each party contributes one key pair.
- */
-typedef struct CK_ECDH1_DERIVE_PARAMS {
-  CK_EC_KDF_TYPE kdf;
-  CK_ULONG ulSharedDataLen;
-  CK_BYTE_PTR pSharedData;
-  CK_ULONG ulPublicDataLen;
-  CK_BYTE_PTR pPublicData;
-} CK_ECDH1_DERIVE_PARAMS;
-
-typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR;
-
-
-/* CK_ECDH2_DERIVE_PARAMS is new for v2.11.
- * CK_ECDH2_DERIVE_PARAMS provides the parameters to the
- * CKM_ECMQV_DERIVE mechanism, where each party contributes two key pairs. */
-typedef struct CK_ECDH2_DERIVE_PARAMS {
-  CK_EC_KDF_TYPE kdf;
-  CK_ULONG ulSharedDataLen;
-  CK_BYTE_PTR pSharedData;
-  CK_ULONG ulPublicDataLen;
-  CK_BYTE_PTR pPublicData;
-  CK_ULONG ulPrivateDataLen;
-  CK_OBJECT_HANDLE hPrivateData;
-  CK_ULONG ulPublicDataLen2;
-  CK_BYTE_PTR pPublicData2;
-} CK_ECDH2_DERIVE_PARAMS;
-
-typedef CK_ECDH2_DERIVE_PARAMS CK_PTR CK_ECDH2_DERIVE_PARAMS_PTR;
-
-typedef struct CK_ECMQV_DERIVE_PARAMS {
-  CK_EC_KDF_TYPE kdf;
-  CK_ULONG ulSharedDataLen;
-  CK_BYTE_PTR pSharedData;
-  CK_ULONG ulPublicDataLen;
-  CK_BYTE_PTR pPublicData;
-  CK_ULONG ulPrivateDataLen;
-  CK_OBJECT_HANDLE hPrivateData;
-  CK_ULONG ulPublicDataLen2;
-  CK_BYTE_PTR pPublicData2;
-  CK_OBJECT_HANDLE publicKey;
-} CK_ECMQV_DERIVE_PARAMS;
-
-typedef CK_ECMQV_DERIVE_PARAMS CK_PTR CK_ECMQV_DERIVE_PARAMS_PTR;
-
-/* Typedefs and defines for the CKM_X9_42_DH_KEY_PAIR_GEN and the
- * CKM_X9_42_DH_PARAMETER_GEN mechanisms (new for PKCS #11 v2.11) */
-typedef CK_ULONG CK_X9_42_DH_KDF_TYPE;
-typedef CK_X9_42_DH_KDF_TYPE CK_PTR CK_X9_42_DH_KDF_TYPE_PTR;
-
-/* The following X9.42 DH key derivation functions are defined
-   (besides CKD_NULL already defined : */
-#define CKD_SHA1_KDF_ASN1        0x00000003
-#define CKD_SHA1_KDF_CONCATENATE 0x00000004
-
-/* CK_X9_42_DH1_DERIVE_PARAMS is new for v2.11.
- * CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the
- * CKM_X9_42_DH_DERIVE key derivation mechanism, where each party
- * contributes one key pair */
-typedef struct CK_X9_42_DH1_DERIVE_PARAMS {
-  CK_X9_42_DH_KDF_TYPE kdf;
-  CK_ULONG ulOtherInfoLen;
-  CK_BYTE_PTR pOtherInfo;
-  CK_ULONG ulPublicDataLen;
-  CK_BYTE_PTR pPublicData;
-} CK_X9_42_DH1_DERIVE_PARAMS;
-
-typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR;
-
-/* CK_X9_42_DH2_DERIVE_PARAMS is new for v2.11.
- * CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the
- * CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE key derivation
- * mechanisms, where each party contributes two key pairs */
-typedef struct CK_X9_42_DH2_DERIVE_PARAMS {
-  CK_X9_42_DH_KDF_TYPE kdf;
-  CK_ULONG ulOtherInfoLen;
-  CK_BYTE_PTR pOtherInfo;
-  CK_ULONG ulPublicDataLen;
-  CK_BYTE_PTR pPublicData;
-  CK_ULONG ulPrivateDataLen;
-  CK_OBJECT_HANDLE hPrivateData;
-  CK_ULONG ulPublicDataLen2;
-  CK_BYTE_PTR pPublicData2;
-} CK_X9_42_DH2_DERIVE_PARAMS;
-
-typedef CK_X9_42_DH2_DERIVE_PARAMS CK_PTR CK_X9_42_DH2_DERIVE_PARAMS_PTR;
-
-typedef struct CK_X9_42_MQV_DERIVE_PARAMS {
-  CK_X9_42_DH_KDF_TYPE kdf;
-  CK_ULONG ulOtherInfoLen;
-  CK_BYTE_PTR pOtherInfo;
-  CK_ULONG ulPublicDataLen;
-  CK_BYTE_PTR pPublicData;
-  CK_ULONG ulPrivateDataLen;
-  CK_OBJECT_HANDLE hPrivateData;
-  CK_ULONG ulPublicDataLen2;
-  CK_BYTE_PTR pPublicData2;
-  CK_OBJECT_HANDLE publicKey;
-} CK_X9_42_MQV_DERIVE_PARAMS;
-
-typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR;
-
-/* CK_KEA_DERIVE_PARAMS provides the parameters to the
- * CKM_KEA_DERIVE mechanism */
-/* CK_KEA_DERIVE_PARAMS is new for v2.0 */
-typedef struct CK_KEA_DERIVE_PARAMS {
-  CK_BBOOL      isSender;
-  CK_ULONG      ulRandomLen;
-  CK_BYTE_PTR   pRandomA;
-  CK_BYTE_PTR   pRandomB;
-  CK_ULONG      ulPublicDataLen;
-  CK_BYTE_PTR   pPublicData;
-} CK_KEA_DERIVE_PARAMS;
-
-typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR;
-
-
-/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and
- * CKM_RC2_MAC mechanisms.  An instance of CK_RC2_PARAMS just
- * holds the effective keysize */
-typedef CK_ULONG          CK_RC2_PARAMS;
-
-typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR;
-
-
-/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC
- * mechanism */
-typedef struct CK_RC2_CBC_PARAMS {
-  /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for
-   * v2.0 */
-  CK_ULONG      ulEffectiveBits;  /* effective bits (1-1024) */
-
-  CK_BYTE       iv[8];            /* IV for CBC mode */
-} CK_RC2_CBC_PARAMS;
-
-typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR;
-
-
-/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the
- * CKM_RC2_MAC_GENERAL mechanism */
-/* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */
-typedef struct CK_RC2_MAC_GENERAL_PARAMS {
-  CK_ULONG      ulEffectiveBits;  /* effective bits (1-1024) */
-  CK_ULONG      ulMacLength;      /* Length of MAC in bytes */
-} CK_RC2_MAC_GENERAL_PARAMS;
-
-typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \
-  CK_RC2_MAC_GENERAL_PARAMS_PTR;
-
-
-/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and
- * CKM_RC5_MAC mechanisms */
-/* CK_RC5_PARAMS is new for v2.0 */
-typedef struct CK_RC5_PARAMS {
-  CK_ULONG      ulWordsize;  /* wordsize in bits */
-  CK_ULONG      ulRounds;    /* number of rounds */
-} CK_RC5_PARAMS;
-
-typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR;
-
-
-/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC
- * mechanism */
-/* CK_RC5_CBC_PARAMS is new for v2.0 */
-typedef struct CK_RC5_CBC_PARAMS {
-  CK_ULONG      ulWordsize;  /* wordsize in bits */
-  CK_ULONG      ulRounds;    /* number of rounds */
-  CK_BYTE_PTR   pIv;         /* pointer to IV */
-  CK_ULONG      ulIvLen;     /* length of IV in bytes */
-} CK_RC5_CBC_PARAMS;
-
-typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR;
-
-
-/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the
- * CKM_RC5_MAC_GENERAL mechanism */
-/* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */
-typedef struct CK_RC5_MAC_GENERAL_PARAMS {
-  CK_ULONG      ulWordsize;   /* wordsize in bits */
-  CK_ULONG      ulRounds;     /* number of rounds */
-  CK_ULONG      ulMacLength;  /* Length of MAC in bytes */
-} CK_RC5_MAC_GENERAL_PARAMS;
-
-typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \
-  CK_RC5_MAC_GENERAL_PARAMS_PTR;
-
-
-/* CK_MAC_GENERAL_PARAMS provides the parameters to most block
- * ciphers' MAC_GENERAL mechanisms.  Its value is the length of
- * the MAC */
-/* CK_MAC_GENERAL_PARAMS is new for v2.0 */
-typedef CK_ULONG          CK_MAC_GENERAL_PARAMS;
-
-typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR;
-
-/* CK_DES/AES_ECB/CBC_ENCRYPT_DATA_PARAMS are new for v2.20 */
-typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS {
-  CK_BYTE      iv[8];
-  CK_BYTE_PTR  pData;
-  CK_ULONG     length;
-} CK_DES_CBC_ENCRYPT_DATA_PARAMS;
-
-typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR;
-
-typedef struct CK_AES_CBC_ENCRYPT_DATA_PARAMS {
-  CK_BYTE      iv[16];
-  CK_BYTE_PTR  pData;
-  CK_ULONG     length;
-} CK_AES_CBC_ENCRYPT_DATA_PARAMS;
-
-typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR;
-
-/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the
- * CKM_SKIPJACK_PRIVATE_WRAP mechanism */
-/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */
-typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS {
-  CK_ULONG      ulPasswordLen;
-  CK_BYTE_PTR   pPassword;
-  CK_ULONG      ulPublicDataLen;
-  CK_BYTE_PTR   pPublicData;
-  CK_ULONG      ulPAndGLen;
-  CK_ULONG      ulQLen;
-  CK_ULONG      ulRandomLen;
-  CK_BYTE_PTR   pRandomA;
-  CK_BYTE_PTR   pPrimeP;
-  CK_BYTE_PTR   pBaseG;
-  CK_BYTE_PTR   pSubprimeQ;
-} CK_SKIPJACK_PRIVATE_WRAP_PARAMS;
-
-typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \
-  CK_SKIPJACK_PRIVATE_WRAP_PTR;
-
-
-/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the
- * CKM_SKIPJACK_RELAYX mechanism */
-/* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */
-typedef struct CK_SKIPJACK_RELAYX_PARAMS {
-  CK_ULONG      ulOldWrappedXLen;
-  CK_BYTE_PTR   pOldWrappedX;
-  CK_ULONG      ulOldPasswordLen;
-  CK_BYTE_PTR   pOldPassword;
-  CK_ULONG      ulOldPublicDataLen;
-  CK_BYTE_PTR   pOldPublicData;
-  CK_ULONG      ulOldRandomLen;
-  CK_BYTE_PTR   pOldRandomA;
-  CK_ULONG      ulNewPasswordLen;
-  CK_BYTE_PTR   pNewPassword;
-  CK_ULONG      ulNewPublicDataLen;
-  CK_BYTE_PTR   pNewPublicData;
-  CK_ULONG      ulNewRandomLen;
-  CK_BYTE_PTR   pNewRandomA;
-} CK_SKIPJACK_RELAYX_PARAMS;
-
-typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \
-  CK_SKIPJACK_RELAYX_PARAMS_PTR;
-
-
-typedef struct CK_PBE_PARAMS {
-  CK_BYTE_PTR      pInitVector;
-  CK_UTF8CHAR_PTR  pPassword;
-  CK_ULONG         ulPasswordLen;
-  CK_BYTE_PTR      pSalt;
-  CK_ULONG         ulSaltLen;
-  CK_ULONG         ulIteration;
-} CK_PBE_PARAMS;
-
-typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR;
-
-
-/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the
- * CKM_KEY_WRAP_SET_OAEP mechanism */
-/* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */
-typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS {
-  CK_BYTE       bBC;     /* block contents byte */
-  CK_BYTE_PTR   pX;      /* extra data */
-  CK_ULONG      ulXLen;  /* length of extra data in bytes */
-} CK_KEY_WRAP_SET_OAEP_PARAMS;
-
-typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR \
-  CK_KEY_WRAP_SET_OAEP_PARAMS_PTR;
-
-
-typedef struct CK_SSL3_RANDOM_DATA {
-  CK_BYTE_PTR  pClientRandom;
-  CK_ULONG     ulClientRandomLen;
-  CK_BYTE_PTR  pServerRandom;
-  CK_ULONG     ulServerRandomLen;
-} CK_SSL3_RANDOM_DATA;
-
-
-typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
-  CK_SSL3_RANDOM_DATA RandomInfo;
-  CK_VERSION_PTR pVersion;
-} CK_SSL3_MASTER_KEY_DERIVE_PARAMS;
-
-typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \
-  CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR;
-
-
-typedef struct CK_SSL3_KEY_MAT_OUT {
-  CK_OBJECT_HANDLE hClientMacSecret;
-  CK_OBJECT_HANDLE hServerMacSecret;
-  CK_OBJECT_HANDLE hClientKey;
-  CK_OBJECT_HANDLE hServerKey;
-  CK_BYTE_PTR      pIVClient;
-  CK_BYTE_PTR      pIVServer;
-} CK_SSL3_KEY_MAT_OUT;
-
-typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR;
-
-
-typedef struct CK_SSL3_KEY_MAT_PARAMS {
-  CK_ULONG                ulMacSizeInBits;
-  CK_ULONG                ulKeySizeInBits;
-  CK_ULONG                ulIVSizeInBits;
-  CK_BBOOL                bIsExport;
-  CK_SSL3_RANDOM_DATA     RandomInfo;
-  CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
-} CK_SSL3_KEY_MAT_PARAMS;
-
-typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR;
-
-/* CK_TLS_PRF_PARAMS is new for version 2.20 */
-typedef struct CK_TLS_PRF_PARAMS {
-  CK_BYTE_PTR  pSeed;
-  CK_ULONG     ulSeedLen;
-  CK_BYTE_PTR  pLabel;
-  CK_ULONG     ulLabelLen;
-  CK_BYTE_PTR  pOutput;
-  CK_ULONG_PTR pulOutputLen;
-} CK_TLS_PRF_PARAMS;
-
-typedef CK_TLS_PRF_PARAMS CK_PTR CK_TLS_PRF_PARAMS_PTR;
-
-/* WTLS is new for version 2.20 */
-typedef struct CK_WTLS_RANDOM_DATA {
-  CK_BYTE_PTR pClientRandom;
-  CK_ULONG    ulClientRandomLen;
-  CK_BYTE_PTR pServerRandom;
-  CK_ULONG    ulServerRandomLen;
-} CK_WTLS_RANDOM_DATA;
-
-typedef CK_WTLS_RANDOM_DATA CK_PTR CK_WTLS_RANDOM_DATA_PTR;
-
-typedef struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS {
-  CK_MECHANISM_TYPE   DigestMechanism;
-  CK_WTLS_RANDOM_DATA RandomInfo;
-  CK_BYTE_PTR         pVersion;
-} CK_WTLS_MASTER_KEY_DERIVE_PARAMS;
-
-typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR \
-  CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR;
-
-typedef struct CK_WTLS_PRF_PARAMS {
-  CK_MECHANISM_TYPE DigestMechanism;
-  CK_BYTE_PTR       pSeed;
-  CK_ULONG          ulSeedLen;
-  CK_BYTE_PTR       pLabel;
-  CK_ULONG          ulLabelLen;
-  CK_BYTE_PTR       pOutput;
-  CK_ULONG_PTR      pulOutputLen;
-} CK_WTLS_PRF_PARAMS;
-
-typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTLS_PRF_PARAMS_PTR;
-
-typedef struct CK_WTLS_KEY_MAT_OUT {
-  CK_OBJECT_HANDLE hMacSecret;
-  CK_OBJECT_HANDLE hKey;
-  CK_BYTE_PTR      pIV;
-} CK_WTLS_KEY_MAT_OUT;
-
-typedef CK_WTLS_KEY_MAT_OUT CK_PTR CK_WTLS_KEY_MAT_OUT_PTR;
-
-typedef struct CK_WTLS_KEY_MAT_PARAMS {
-  CK_MECHANISM_TYPE       DigestMechanism;
-  CK_ULONG                ulMacSizeInBits;
-  CK_ULONG                ulKeySizeInBits;
-  CK_ULONG                ulIVSizeInBits;
-  CK_ULONG                ulSequenceNumber;
-  CK_BBOOL                bIsExport;
-  CK_WTLS_RANDOM_DATA     RandomInfo;
-  CK_WTLS_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
-} CK_WTLS_KEY_MAT_PARAMS;
-
-typedef CK_WTLS_KEY_MAT_PARAMS CK_PTR CK_WTLS_KEY_MAT_PARAMS_PTR;
-
-/* CMS is new for version 2.20 */
-typedef struct CK_CMS_SIG_PARAMS {
-  CK_OBJECT_HANDLE      certificateHandle;
-  CK_MECHANISM_PTR      pSigningMechanism;
-  CK_MECHANISM_PTR      pDigestMechanism;
-  CK_UTF8CHAR_PTR       pContentType;
-  CK_BYTE_PTR           pRequestedAttributes;
-  CK_ULONG              ulRequestedAttributesLen;
-  CK_BYTE_PTR           pRequiredAttributes;
-  CK_ULONG              ulRequiredAttributesLen;
-} CK_CMS_SIG_PARAMS;
-
-typedef CK_CMS_SIG_PARAMS CK_PTR CK_CMS_SIG_PARAMS_PTR;
-
-typedef struct CK_KEY_DERIVATION_STRING_DATA {
-  CK_BYTE_PTR pData;
-  CK_ULONG    ulLen;
-} CK_KEY_DERIVATION_STRING_DATA;
-
-typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \
-  CK_KEY_DERIVATION_STRING_DATA_PTR;
-
-
-/* The CK_EXTRACT_PARAMS is used for the
- * CKM_EXTRACT_KEY_FROM_KEY mechanism.  It specifies which bit
- * of the base key should be used as the first bit of the
- * derived key */
-/* CK_EXTRACT_PARAMS is new for v2.0 */
-typedef CK_ULONG CK_EXTRACT_PARAMS;
-
-typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
-
-/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is new for v2.10.
- * CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to
- * indicate the Pseudo-Random Function (PRF) used to generate
- * key bits using PKCS #5 PBKDF2. */
-typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE;
-
-typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR;
-
-/* The following PRFs are defined in PKCS #5 v2.0. */
-#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001
-
-
-/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is new for v2.10.
- * CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the
- * source of the salt value when deriving a key using PKCS #5
- * PBKDF2. */
-typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE;
-
-typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR;
-
-/* The following salt value sources are defined in PKCS #5 v2.0. */
-#define CKZ_SALT_SPECIFIED        0x00000001
-
-/* CK_PKCS5_PBKD2_PARAMS is new for v2.10.
- * CK_PKCS5_PBKD2_PARAMS is a structure that provides the
- * parameters to the CKM_PKCS5_PBKD2 mechanism. */
-typedef struct CK_PKCS5_PBKD2_PARAMS {
-        CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE           saltSource;
-        CK_VOID_PTR                                pSaltSourceData;
-        CK_ULONG                                   ulSaltSourceDataLen;
-        CK_ULONG                                   iterations;
-        CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
-        CK_VOID_PTR                                pPrfData;
-        CK_ULONG                                   ulPrfDataLen;
-        CK_UTF8CHAR_PTR                            pPassword;
-        CK_ULONG_PTR                               ulPasswordLen;
-} CK_PKCS5_PBKD2_PARAMS;
-
-typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
-
-#endif
diff --git a/src/pluto/rsaref/unix.h b/src/pluto/rsaref/unix.h
deleted file mode 100644 (file)
index 2e7eb66..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-#ifndef UNIX_H
-#define UNIX_H
-
-#define CK_PTR *
-
-#define CK_DEFINE_FUNCTION(returnType, name) \
-   returnType name
-
-#define CK_DECLARE_FUNCTION(returnType, name) \
-   returnType name
-
-#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
-   returnType (* name)
-
-#define CK_CALLBACK_FUNCTION(returnType, name) \
-   returnType (* name)
-
-#ifndef NULL_PTR
-#define NULL_PTR 0
-#endif
-
-#endif
diff --git a/src/pluto/server.c b/src/pluto/server.c
deleted file mode 100644 (file)
index 167b1d4..0000000
+++ /dev/null
@@ -1,910 +0,0 @@
-/* get-next-event loop
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2002  D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-#include <errno.h>
-#include <signal.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#ifdef SOLARIS
-# include <sys/sockio.h>        /* for Solaris 2.6: defines SIOCGIFCONF */
-#endif
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/time.h>
-#include <netdb.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <net/if.h>
-#include <sys/ioctl.h>
-#include <resolv.h>
-#include <arpa/nameser.h>       /* missing from <resolv.h> on old systems */
-#include <sys/queue.h>
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "state.h"
-#include "connections.h"
-#include "kernel.h"
-#include "log.h"
-#include "server.h"
-#include "timer.h"
-#include "packet.h"
-#include "demux.h"  /* needs packet.h */
-#include "rcv_whack.h"
-#include "keys.h"
-#include "adns.h"       /* needs <resolv.h> */
-#include "dnskey.h"     /* needs keys.h and adns.h */
-#include "whack.h"      /* for RC_LOG_SERIOUS */
-#include "pluto.h"
-
-#include <pfkeyv2.h>
-#include <pfkey.h>
-#include "kameipsec.h"
-#include "nat_traversal.h"
-
-/*
- *  Server main loop and socket initialization routines.
- */
-
-static const int on = TRUE;     /* by-reference parameter; constant, we hope */
-
-/* control (whack) socket */
-int ctl_fd = NULL_FD;   /* file descriptor of control (whack) socket */
-struct sockaddr_un ctl_addr = { AF_UNIX, DEFAULT_CTLBASE CTL_SUFFIX };
-
-/* info (showpolicy) socket */
-int policy_fd = NULL_FD;
-struct sockaddr_un info_addr= { AF_UNIX, DEFAULT_CTLBASE INFO_SUFFIX };
-
-/* Initialize the control socket.
- * Note: this is called very early, so little infrastructure is available.
- * It is important that the socket is created before the original
- * Pluto process returns.
- */
-err_t
-init_ctl_socket(void)
-{
-       err_t failed = NULL;
-
-       delete_ctl_socket();        /* preventative medicine */
-       ctl_fd = socket(AF_UNIX, SOCK_STREAM, 0);
-       if (ctl_fd == -1)
-               failed = "create";
-       else if (fcntl(ctl_fd, F_SETFD, FD_CLOEXEC) == -1)
-               failed = "fcntl FD+CLOEXEC";
-       else if (setsockopt(ctl_fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof(on)) < 0)
-               failed = "setsockopt";
-       else
-       {
-               /* to keep control socket secure, use umask */
-               mode_t ou = umask(~S_IRWXU);
-
-               if (bind(ctl_fd, (struct sockaddr *)&ctl_addr
-               , offsetof(struct sockaddr_un, sun_path) + strlen(ctl_addr.sun_path)) < 0)
-                       failed = "bind";
-               umask(ou);
-       }
-
-       /* 5 is a haphazardly chosen limit for the backlog.
-        * Rumour has it that this is the max on BSD systems.
-        */
-       if (failed == NULL && listen(ctl_fd, 5) < 0)
-               failed = "listen() on";
-
-       return failed == NULL? NULL : builddiag("could not %s control socket: %d %s"
-                       , failed, errno, strerror(errno));
-}
-
-void
-delete_ctl_socket(void)
-{
-       /* Is noting failure useful?  Not when used as preventative medicine. */
-       unlink(ctl_addr.sun_path);
-}
-
-bool listening = FALSE; /* should we pay attention to IKE messages? */
-
-struct iface *interfaces = NULL;        /* public interfaces */
-
-/* Initialize the interface sockets. */
-
-static void
-mark_ifaces_dead(void)
-{
-       struct iface *p;
-
-       for (p = interfaces; p != NULL; p = p->next)
-               p->change = IFN_DELETE;
-}
-
-static void
-free_dead_ifaces(void)
-{
-       struct iface *p;
-       bool some_dead = FALSE
-               , some_new = FALSE;
-
-       for (p = interfaces; p != NULL; p = p->next)
-       {
-               if (p->change == IFN_DELETE)
-               {
-                       plog("shutting down interface %s/%s %s"
-                               , p->vname, p->rname, ip_str(&p->addr));
-                       some_dead = TRUE;
-               }
-               else if (p->change == IFN_ADD)
-               {
-                       some_new = TRUE;
-               }
-       }
-
-       if (some_dead)
-       {
-               struct iface **pp;
-
-               release_dead_interfaces();
-               for (pp = &interfaces; (p = *pp) != NULL; )
-               {
-                       if (p->change == IFN_DELETE)
-                       {
-                               *pp = p->next;  /* advance *pp */
-                               free(p->vname);
-                               free(p->rname);
-                               close(p->fd);
-                               free(p);
-                       }
-                       else
-                       {
-                               pp = &p->next;  /* advance pp */
-                       }
-               }
-       }
-
-       /* this must be done after the release_dead_interfaces
-        * in case some to the newly unoriented connections can
-        * become oriented here.
-        */
-       if (some_dead || some_new)
-               check_orientations();
-}
-
-void
-free_ifaces(void)
-{
-       mark_ifaces_dead();
-       free_dead_ifaces();
-}
-
-struct raw_iface {
-       ip_address addr;
-       char name[IFNAMSIZ + 20];   /* what would be a safe size? */
-       struct raw_iface *next;
-};
-
-/* Called to handle --interface <ifname>
- * Semantics: if specified, only these (real) interfaces are considered.
- */
-static const char *pluto_ifn[10];
-static int pluto_ifn_roof = 0;
-
-bool
-use_interface(const char *rifn)
-{
-       if (pluto_ifn_roof >= (int)countof(pluto_ifn))
-       {
-               return FALSE;
-       }
-       else
-       {
-               pluto_ifn[pluto_ifn_roof++] = rifn;
-               return TRUE;
-       }
-}
-
-static struct raw_iface *
-find_raw_ifaces4(void)
-{
-       int j;      /* index into buf */
-       struct ifconf ifconf;
-       struct ifreq buf[300];      /* for list of interfaces -- arbitrary limit */
-       struct raw_iface *rifaces = NULL;
-       int master_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);    /* Get a UDP socket */
-
-       /* get list of interfaces with assigned IPv4 addresses from system */
-
-       if (master_sock == -1)
-               exit_log_errno((e, "socket() failed in find_raw_ifaces4()"));
-
-       if (setsockopt(master_sock, SOL_SOCKET, SO_REUSEADDR
-       , (const void *)&on, sizeof(on)) < 0)
-               exit_log_errno((e, "setsockopt() in find_raw_ifaces4()"));
-
-       /* bind the socket */
-       {
-               ip_address any;
-
-               happy(anyaddr(AF_INET, &any));
-               setportof(htons(pluto_port), &any);
-               if (bind(master_sock, sockaddrof(&any), sockaddrlenof(&any)) < 0)
-                       exit_log_errno((e, "bind() failed in find_raw_ifaces4()"));
-       }
-
-       /* Get local interfaces.  See netdevice(7). */
-       ifconf.ifc_len = sizeof(buf);
-       ifconf.ifc_buf = (void *) buf;
-       zero(buf);
-
-       if (ioctl(master_sock, SIOCGIFCONF, &ifconf) == -1)
-               exit_log_errno((e, "ioctl(SIOCGIFCONF) in find_raw_ifaces4()"));
-
-       /* Add an entry to rifaces for each interesting interface. */
-       for (j = 0; (j+1) * sizeof(*buf) <= (size_t)ifconf.ifc_len; j++)
-       {
-               struct raw_iface ri;
-               const struct sockaddr_in *rs = (struct sockaddr_in *) &buf[j].ifr_addr;
-               struct ifreq auxinfo;
-
-               /* ignore all but AF_INET interfaces */
-               if (rs->sin_family != AF_INET)
-                       continue;   /* not interesting */
-
-               /* build a NUL-terminated copy of the rname field */
-               memcpy(ri.name, buf[j].ifr_name, IFNAMSIZ);
-               ri.name[IFNAMSIZ] = '\0';
-
-               /* ignore if our interface names were specified, and this isn't one */
-               if (pluto_ifn_roof != 0)
-               {
-                       int i;
-
-                       for (i = 0; i != pluto_ifn_roof; i++)
-                               if (streq(ri.name, pluto_ifn[i]))
-                                       break;
-                       if (i == pluto_ifn_roof)
-                               continue;       /* not found -- skip */
-               }
-
-               /* Find out stuff about this interface.  See netdevice(7). */
-               zero(&auxinfo); /* paranoia */
-               memcpy(auxinfo.ifr_name, buf[j].ifr_name, IFNAMSIZ);
-               if (ioctl(master_sock, SIOCGIFFLAGS, &auxinfo) == -1)
-                       exit_log_errno((e
-                               , "ioctl(SIOCGIFFLAGS) for %s in find_raw_ifaces4()"
-                               , ri.name));
-               if (!(auxinfo.ifr_flags & IFF_UP))
-                       continue;   /* ignore an interface that isn't UP */
-
-               /* ignore unconfigured interfaces */
-               if (rs->sin_addr.s_addr == 0)
-                       continue;
-
-               happy(initaddr((const void *)&rs->sin_addr, sizeof(struct in_addr)
-                       , AF_INET, &ri.addr));
-
-               DBG(DBG_CONTROL, DBG_log("found %s with address %s"
-                       , ri.name, ip_str(&ri.addr)));
-               ri.next = rifaces;
-               rifaces = clone_thing(ri);
-       }
-
-       close(master_sock);
-
-       return rifaces;
-}
-
-static struct raw_iface *
-find_raw_ifaces6(void)
-{
-
-       /* Get list of interfaces with IPv6 addresses from system from /proc/net/if_inet6).
-        *
-        * Documentation of format?
-        * RTFS: linux-2.2.16/net/ipv6/addrconf.c:iface_proc_info()
-        *       linux-2.4.9-13/net/ipv6/addrconf.c:iface_proc_info()
-        *
-        * Sample from Gerhard's laptop:
-        *  00000000000000000000000000000001 01 80 10 80       lo
-        *  30490009000000000000000000010002 02 40 00 80   ipsec0
-        *  30490009000000000000000000010002 07 40 00 80     eth0
-        *  fe80000000000000025004fffefd5484 02 0a 20 80   ipsec0
-        *  fe80000000000000025004fffefd5484 07 0a 20 80     eth0
-        *
-        * Each line contains:
-        * - IPv6 address: 16 bytes, in hex, no punctuation
-        * - ifindex: 1 byte, in hex
-        * - prefix_len: 1 byte, in hex
-        * - scope (e.g. global, link local): 1 byte, in hex
-        * - flags: 1 byte, in hex
-        * - device name: string, followed by '\n'
-        */
-       struct raw_iface *rifaces = NULL;
-       static const char proc_name[] = "/proc/net/if_inet6";
-       FILE *proc_sock = fopen(proc_name, "r");
-
-       if (proc_sock == NULL)
-       {
-               DBG(DBG_CONTROL, DBG_log("could not open %s", proc_name));
-       }
-       else
-       {
-               for (;;)
-               {
-                       struct raw_iface ri;
-                       unsigned short xb[8];       /* IPv6 address as 8 16-bit chunks */
-                       char sb[8*5];       /* IPv6 address as string-with-colons */
-                       unsigned int if_idx;        /* proc field, not used */
-                       unsigned int plen;  /* proc field, not used */
-                       unsigned int scope; /* proc field, used to exclude link-local */
-                       unsigned int dad_status;    /* proc field, not used */
-                       /* ??? I hate and distrust scanf -- DHR */
-                       int r = fscanf(proc_sock
-                               , "%4hx%4hx%4hx%4hx%4hx%4hx%4hx%4hx"
-                                 " %02x %02x %02x %02x %20s\n"
-                               , xb+0, xb+1, xb+2, xb+3, xb+4, xb+5, xb+6, xb+7
-                               , &if_idx, &plen, &scope, &dad_status, ri.name);
-
-                       /* ??? we should diagnose any problems */
-                       if (r != 13)
-                               break;
-
-                       /* ignore addresses with link local scope.
-                        * From linux-2.4.9-13/include/net/ipv6.h:
-                        * IPV6_ADDR_LINKLOCAL      0x0020U
-                        * IPV6_ADDR_SCOPE_MASK     0x00f0U
-                        */
-                       if ((scope & 0x00f0U) == 0x0020U)
-                               continue;
-
-                       snprintf(sb, sizeof(sb)
-                               , "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x"
-                               , xb[0], xb[1], xb[2], xb[3], xb[4], xb[5], xb[6], xb[7]);
-
-                       happy(ttoaddr(sb, 0, AF_INET6, &ri.addr));
-
-                       if (!isunspecaddr(&ri.addr))
-                       {
-                               DBG(DBG_CONTROL
-                                       , DBG_log("found %s with address %s"
-                                               , ri.name, sb));
-                               ri.next = rifaces;
-                               rifaces = clone_thing(ri);
-                       }
-               }
-               fclose(proc_sock);
-       }
-
-       return rifaces;
-}
-
-static int
-create_socket(struct raw_iface *ifp, const char *v_name, int port)
-{
-       int fd = socket(addrtypeof(&ifp->addr), SOCK_DGRAM, IPPROTO_UDP);
-       int fcntl_flags;
-
-       if (fd < 0)
-       {
-               log_errno((e, "socket() in process_raw_ifaces()"));
-               return -1;
-       }
-
-       /* Set socket Nonblocking */
-       if ((fcntl_flags=fcntl(fd, F_GETFL)) >= 0) {
-               if (!(fcntl_flags & O_NONBLOCK)) {
-                       fcntl_flags |= O_NONBLOCK;
-                       fcntl(fd, F_SETFL, fcntl_flags);
-               }
-       }
-
-       if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
-       {
-               log_errno((e, "fcntl(,, FD_CLOEXEC) in process_raw_ifaces()"));
-               close(fd);
-               return -1;
-       }
-
-       if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR
-       , (const void *)&on, sizeof(on)) < 0)
-       {
-               log_errno((e, "setsockopt SO_REUSEADDR in process_raw_ifaces()"));
-               close(fd);
-               return -1;
-       }
-
-       /* To improve error reporting.  See ip(7). */
-#if defined(IP_RECVERR) && defined(MSG_ERRQUEUE)
-       if (setsockopt(fd, SOL_IP, IP_RECVERR
-       , (const void *)&on, sizeof(on)) < 0)
-       {
-               log_errno((e, "setsockopt IP_RECVERR in process_raw_ifaces()"));
-               close(fd);
-               return -1;
-       }
-#endif
-
-       /* With IPv6, there is no fragmentation after
-        * it leaves our interface.  PMTU discovery
-        * is mandatory but doesn't work well with IKE (why?).
-        * So we must set the IPV6_USE_MIN_MTU option.
-        * See draft-ietf-ipngwg-rfc2292bis-01.txt 11.1
-        */
-#ifdef IPV6_USE_MIN_MTU /* YUCK: not always defined */
-       if (addrtypeof(&ifp->addr) == AF_INET6
-       && setsockopt(fd, SOL_SOCKET, IPV6_USE_MIN_MTU
-         , (const void *)&on, sizeof(on)) < 0)
-       {
-               log_errno((e, "setsockopt IPV6_USE_MIN_MTU in process_raw_ifaces()"));
-               close(fd);
-               return -1;
-       }
-#endif
-
-       {
-               struct sadb_x_policy policy;
-               int level, opt;
-
-               policy.sadb_x_policy_len = sizeof(policy) / IPSEC_PFKEYv2_ALIGN;
-               policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
-               policy.sadb_x_policy_type = IPSEC_POLICY_BYPASS;
-               policy.sadb_x_policy_dir = IPSEC_DIR_INBOUND;
-               policy.sadb_x_policy_reserved = 0;
-               policy.sadb_x_policy_id = 0;
-               policy.sadb_x_policy_reserved2 = 0;
-
-               if (addrtypeof(&ifp->addr) == AF_INET6)
-               {
-                       level = IPPROTO_IPV6;
-                       opt = IPV6_IPSEC_POLICY;
-               }
-               else
-               {
-                       level = IPPROTO_IP;
-                       opt = IP_IPSEC_POLICY;
-               }
-
-               if (setsockopt(fd, level, opt
-                 , &policy, sizeof(policy)) < 0)
-               {
-                       log_errno((e, "setsockopt IPSEC_POLICY in process_raw_ifaces()"));
-                       close(fd);
-                       return -1;
-               }
-
-               policy.sadb_x_policy_dir = IPSEC_DIR_OUTBOUND;
-
-               if (setsockopt(fd, level, opt
-                 , &policy, sizeof(policy)) < 0)
-               {
-                       log_errno((e, "setsockopt IPSEC_POLICY in process_raw_ifaces()"));
-                       close(fd);
-                       return -1;
-               }
-       }
-
-       setportof(htons(port), &ifp->addr);
-       if (bind(fd, sockaddrof(&ifp->addr), sockaddrlenof(&ifp->addr)) < 0)
-       {
-               log_errno((e, "bind() for %s/%s %s:%u in process_raw_ifaces()"
-                       , ifp->name, v_name
-                       , ip_str(&ifp->addr), (unsigned) port));
-               close(fd);
-               return -1;
-       }
-       setportof(htons(pluto_port), &ifp->addr);
-       return fd;
-}
-
-static void
-process_raw_ifaces(struct raw_iface *rifaces)
-{
-       struct raw_iface *ifp;
-
-       /* For each real interface...
-        */
-       for (ifp = rifaces; ifp != NULL; ifp = ifp->next)
-       {
-               struct raw_iface *v = NULL;
-               bool after = FALSE; /* has vfp passed ifp on the list? */
-               bool bad = FALSE;
-               struct raw_iface *vfp;
-
-               for (vfp = rifaces; vfp != NULL; vfp = vfp->next)
-               {
-                       if (vfp == ifp)
-                       {
-                               after = TRUE;
-                       }
-                       else if (sameaddr(&ifp->addr, &vfp->addr))
-                       {
-                               /* ugh: a second interface with the same IP address
-                                * "after" allows us to avoid double reporting.
-                                */
-                               if (after)
-                               {
-                                       bad = TRUE;
-                                       break;
-                               }
-                               continue;
-                       }
-               }
-
-               if (bad)
-                       continue;
-
-               v = ifp;
-
-               /* We've got all we need; see if this is a new thing:
-                * search old interfaces list.
-                */
-               {
-                       struct iface **p = &interfaces;
-
-                       for (;;)
-                       {
-                               struct iface *q = *p;
-
-                               /* search is over if at end of list */
-                               if (q == NULL)
-                               {
-                                       /* matches nothing -- create a new entry */
-                                       int fd = create_socket(ifp, v->name, pluto_port);
-
-                                       if (fd < 0)
-                                               break;
-
-                                       if (nat_traversal_support_non_ike
-                                       && addrtypeof(&ifp->addr) == AF_INET)
-                                       {
-                                               nat_traversal_espinudp_socket(fd, ESPINUDP_WITH_NON_IKE);
-                                       }
-
-                                       q = malloc_thing(struct iface);
-                                       zero(q);
-                                       q->rname = clone_str(ifp->name);
-                                       q->vname = clone_str(v->name);
-                                       q->addr = ifp->addr;
-                                       q->fd = fd;
-                                       q->next = interfaces;
-                                       q->change = IFN_ADD;
-                                       interfaces = q;
-                                       plog("adding interface %s/%s %s:%d"
-                                               , q->vname, q->rname, ip_str(&q->addr), pluto_port);
-
-                                       if (nat_traversal_support_port_floating
-                                       && addrtypeof(&ifp->addr) == AF_INET)
-                                       {
-                                               fd = create_socket(ifp, v->name, NAT_T_IKE_FLOAT_PORT);
-                                               if (fd < 0)
-                                                       break;
-                                               nat_traversal_espinudp_socket(fd,
-                                                       ESPINUDP_WITH_NON_ESP);
-                                               q = malloc_thing(struct iface);
-                                               zero(q);
-                                               q->rname = clone_str(ifp->name);
-                                               q->vname = clone_str(v->name);
-                                               q->addr = ifp->addr;
-                                               setportof(htons(NAT_T_IKE_FLOAT_PORT), &q->addr);
-                                               q->fd = fd;
-                                               q->next = interfaces;
-                                               q->change = IFN_ADD;
-                                               q->ike_float = TRUE;
-                                               interfaces = q;
-                                               plog("adding interface %s/%s %s:%d",
-                                               q->vname, q->rname, ip_str(&q->addr), NAT_T_IKE_FLOAT_PORT);
-                                       }
-                                       break;
-                               }
-
-                               /* search over if matching old entry found */
-                               if (streq(q->rname, ifp->name)
-                               && streq(q->vname, v->name)
-                               && sameaddr(&q->addr, &ifp->addr))
-                               {
-                                       /* matches -- rejuvinate old entry */
-                                       q->change = IFN_KEEP;
-
-                                       /* look for other interfaces to keep (due to NAT-T) */
-                                       for (q = q->next ; q ; q = q->next)
-                                       {
-                                               if (streq(q->rname, ifp->name)
-                                               && streq(q->vname, v->name)
-                                               && sameaddr(&q->addr, &ifp->addr))
-                                               {
-                                                       q->change = IFN_KEEP;
-                                               }
-                                       }
-                                       break;
-                               }
-
-                               /* try again */
-                               p = &q->next;
-                       } /* for (;;) */
-               }
-       }
-
-       /* delete the raw interfaces list */
-       while (rifaces != NULL)
-       {
-               struct raw_iface *t = rifaces;
-
-               rifaces = t->next;
-               free(t);
-       }
-}
-
-void
-find_ifaces(void)
-{
-       mark_ifaces_dead();
-       process_raw_ifaces(find_raw_ifaces4());
-       process_raw_ifaces(find_raw_ifaces6());
-
-       free_dead_ifaces();     /* ditch remaining old entries */
-
-       if (interfaces == NULL)
-               loglog(RC_LOG_SERIOUS, "no public interfaces found");
-}
-
-void
-show_ifaces_status(void)
-{
-       struct iface *p;
-
-       for (p = interfaces; p != NULL; p = p->next)
-               whack_log(RC_COMMENT, "interface %s/%s %s:%d"
-                       , p->vname, p->rname, ip_str(&p->addr), ntohs(portof(&p->addr)));
-}
-
-void
-show_debug_status(void)
-{
-#ifdef DEBUG
-       whack_log(RC_COMMENT, "debug options: %s"
-               , bitnamesof(debug_bit_names, cur_debugging));
-#endif
-}
-
-static volatile sig_atomic_t sighupflag = FALSE;
-
-static void
-huphandler(int sig UNUSED)
-{
-       sighupflag = TRUE;
-}
-
-static volatile sig_atomic_t sigtermflag = FALSE;
-
-static void
-termhandler(int sig UNUSED)
-{
-       sigtermflag = TRUE;
-}
-
-/* call_server listens for incoming ISAKMP packets and Whack messages,
- * and handles timer events.
- */
-void
-call_server(void)
-{
-       struct iface *ifp;
-
-       /* catch SIGHUP and SIGTERM */
-       {
-               int r;
-               struct sigaction act;
-
-               act.sa_handler = &huphandler;
-               sigemptyset(&act.sa_mask);
-               act.sa_flags = 0;       /* no SA_ONESHOT, no SA_RESTART, no nothing */
-               r = sigaction(SIGHUP, &act, NULL);
-               passert(r == 0);
-
-               act.sa_handler = &termhandler;
-               r = sigaction(SIGTERM, &act, NULL);
-               r = sigaction(SIGINT, &act, NULL);
-               passert(r == 0);
-       }
-
-       for (;;)
-       {
-               fd_set readfds;
-               fd_set writefds;
-               int ndes, events_fd;
-
-               /* wait for next interesting thing */
-
-               for (;;)
-               {
-                       long next_time = next_event();   /* time to any pending timer event */
-                       int maxfd = ctl_fd;
-
-                       if (sigtermflag)
-                               exit_pluto(0);
-
-                       if (sighupflag)
-                       {
-                               /* Ignorant folks think poking any daemon with SIGHUP
-                                * is polite.  We catch it and tell them otherwise.
-                                * There is one use: unsticking a hung recvfrom.
-                                * This sticking happens sometimes -- kernel bug?
-                                */
-                               sighupflag = FALSE;
-                               plog("Pluto ignores SIGHUP -- perhaps you want \"whack --listen\"");
-                       }
-
-                       FD_ZERO(&readfds);
-                       FD_ZERO(&writefds);
-                       FD_SET(ctl_fd, &readfds);
-
-#ifdef ADNS
-                       /* the only write file-descriptor of interest */
-                       if (adns_qfd != NULL_FD && unsent_ADNS_queries)
-                       {
-                               if (maxfd < adns_qfd)
-                                       maxfd = adns_qfd;
-                               FD_SET(adns_qfd, &writefds);
-                       }
-
-                       if (adns_afd != NULL_FD)
-                       {
-                               if (maxfd < adns_afd)
-                                       maxfd = adns_afd;
-                               FD_SET(adns_afd, &readfds);
-                       }
-#endif /* ADNS */
-
-                       events_fd = pluto->events->get_event_fd(pluto->events);
-                       if (maxfd < events_fd)
-                               maxfd = events_fd;
-                       FD_SET(events_fd, &readfds);
-
-                       if (listening)
-                       {
-                               for (ifp = interfaces; ifp != NULL; ifp = ifp->next)
-                               {
-                                       if (maxfd < ifp->fd)
-                                               maxfd = ifp->fd;
-                                       passert(!FD_ISSET(ifp->fd, &readfds));
-                                       FD_SET(ifp->fd, &readfds);
-                               }
-                       }
-
-                       if (next_time == -1)
-                       {
-                               /* select without timer */
-
-                               ndes = select(maxfd + 1, &readfds, &writefds, NULL, NULL);
-                       }
-                       else if (next_time == 0)
-                       {
-                               /* timer without select: there is a timer event pending,
-                                * and it should fire now so don't bother to do the select.
-                                */
-                               ndes = 0;       /* signify timer expiration */
-                       }
-                       else
-                       {
-                               /* select with timer */
-
-                               struct timeval tm;
-
-                               tm.tv_sec = next_time;
-                               tm.tv_usec = 0;
-                               ndes = select(maxfd + 1, &readfds, &writefds, NULL, &tm);
-                       }
-
-                       if (ndes != -1)
-                               break;  /* success */
-
-                       if (errno != EINTR)
-                               exit_log_errno((e, "select() failed in call_server()"));
-
-                       /* retry if terminated by signal */
-               }
-
-               /* figure out what is interesting */
-
-               if (ndes == 0)
-               {
-                       /* timer event */
-
-                       DBG(DBG_CONTROL,
-                               DBG_log(BLANK_FORMAT);
-                               DBG_log("*time to handle event"));
-
-                       handle_timer_event();
-                       passert(GLOBALS_ARE_RESET());
-               }
-               else
-               {
-                       /* at least one file descriptor is ready */
-
-#ifdef ADNS
-                       if (adns_qfd != NULL_FD && FD_ISSET(adns_qfd, &writefds))
-                       {
-                               passert(ndes > 0);
-                               send_unsent_ADNS_queries();
-                               passert(GLOBALS_ARE_RESET());
-                               ndes--;
-                       }
-
-                       if (adns_afd != NULL_FD && FD_ISSET(adns_afd, &readfds))
-                       {
-                               passert(ndes > 0);
-                               DBG(DBG_CONTROL,
-                                       DBG_log(BLANK_FORMAT);
-                                       DBG_log("*received adns message"));
-                               handle_adns_answer();
-                               passert(GLOBALS_ARE_RESET());
-                               ndes--;
-                       }
-#endif /* ADNS*/
-
-                       if (FD_ISSET(events_fd, &readfds))
-                       {
-                               passert(ndes > 0);
-                               DBG(DBG_CONTROL,
-                                       DBG_log(BLANK_FORMAT);
-                                       DBG_log("*handling asynchronous events"));
-                               pluto->events->handle(pluto->events);
-                               passert(GLOBALS_ARE_RESET());
-                               ndes--;
-                       }
-
-                       for (ifp = interfaces; ifp != NULL; ifp = ifp->next)
-                       {
-                               if (FD_ISSET(ifp->fd, &readfds))
-                               {
-                                       /* comm_handle will print DBG_CONTROL intro,
-                                        * with more info than we have here.
-                                        */
-
-                                       passert(ndes > 0);
-                                       comm_handle(ifp);
-                                       passert(GLOBALS_ARE_RESET());
-                                       ndes--;
-                               }
-                       }
-
-                       if (FD_ISSET(ctl_fd, &readfds))
-                       {
-                               passert(ndes > 0);
-                               DBG(DBG_CONTROL,
-                                       DBG_log(BLANK_FORMAT);
-                                       DBG_log("*received whack message"));
-                               whack_handle(ctl_fd);
-                               passert(GLOBALS_ARE_RESET());
-                               ndes--;
-                       }
-
-                       passert(ndes == 0);
-               }
-       }
-}
-
-/*
- * Local Variables:
- * c-basic-offset: 4
- * End Variables:
- */
diff --git a/src/pluto/server.h b/src/pluto/server.h
deleted file mode 100644 (file)
index b8123f6..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/* get-next-event loop
- * Copyright (C) 1998-2001  D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-extern int ctl_fd;      /* file descriptor of control (whack) socket */
-extern struct sockaddr_un ctl_addr;     /* address of control (whack) socket */
-
-extern int info_fd;     /* file descriptor of control (info) socket */
-extern struct sockaddr_un info_addr;    /* address of control (info) socket */
-
-extern err_t init_ctl_socket(void);
-extern void delete_ctl_socket(void);
-
-extern bool listening;  /* should we pay attention to IKE messages? */
-
-
-/* interface: a terminal point for IKE traffic, IPsec transport mode
- * and IPsec tunnels.
- * Essentially:
- * - an IP device (eg. eth1), and
- * - its partner, an ipsec device (eg. ipsec0), and
- * - their shared IP address (eg. 10.7.3.2)
- * Note: the port for IKE is always implicitly UDP/pluto_port.
- */
-struct iface {
-       char *vname;        /* virtual (ipsec) device name */
-       char *rname;        /* real device name */
-       ip_address addr;    /* interface IP address */
-       int fd;     /* file descriptor of socket for IKE UDP messages */
-       struct iface *next;
-       bool ike_float;
-       enum { IFN_ADD, IFN_KEEP, IFN_DELETE } change;
-};
-
-extern struct iface *interfaces;        /* public interfaces */
-
-extern bool use_interface(const char *rifn);
-extern void find_ifaces(void);
-extern void show_ifaces_status(void);
-extern void free_ifaces(void);
-extern void show_debug_status(void);
-extern void call_server(void);
-
-/* in rcv_info.c */
-extern err_t init_info_socket(void);
-extern void delete_info_socket(void);
diff --git a/src/pluto/smartcard.c b/src/pluto/smartcard.c
deleted file mode 100644 (file)
index 85e246a..0000000
+++ /dev/null
@@ -1,1940 +0,0 @@
-/* Support of smartcards and cryptotokens
- * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
- * Copyright (C) 2004 David Buechi, Michael Meier
- * Zuercher Hochschule Winterthur, Switzerland
- *
- * Copyright (C) 2005 Michael Joosten
- *
- * Copyright (C) 2005 Andreas Steffen
- * Hochschule fuer Technik Rapperswil, Switzerland
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <time.h>
-#include <dlfcn.h>
-
-#include <freeswan.h>
-
-#include <asn1/asn1.h>
-#include <credentials/keys/public_key.h>
-#include <credentials/certificates/x509.h>
-
-#include "constants.h"
-
-#ifdef SMARTCARD
-#include "rsaref/unix.h"
-#include "rsaref/pkcs11.h"
-#endif
-
-#include "defs.h"
-#include "log.h"
-#include "x509.h"
-#include "ca.h"
-#include "certs.h"
-#include "keys.h"
-#include "smartcard.h"
-#include "whack.h"
-#include "fetch.h"
-
-#define DEFAULT_BASE    16
-
-/* chained list of smartcard records */
-static smartcard_t *smartcards   = NULL;
-
-/* number of generated sc objects */
-static int sc_number = 0;
-
-const smartcard_t empty_sc = {
-         NULL         , /* next */
-                       0      , /* last_load */
-         NULL         , /* last_cert */
-                       0      , /* count */
-                       0      , /* number */
-         999999       , /* slot */
-         NULL         , /* id */
-         NULL         , /* label */
-       { NULL, 0 }    , /* pin */
-         FALSE        , /* pinpad */
-         FALSE        , /* valid */
-         FALSE        , /* session_opened */
-         FALSE        , /* logged_in */
-         TRUE         , /* any_slot */
-                       0L     , /* session */
-};
-
-#ifdef SMARTCARD        /* compile with smartcard support */
-
-#define SCX_MAGIC       0xd00bed00
-
-struct scx_pkcs11_module {
-               u_int _magic;
-               void *handle;
-};
-
-typedef struct scx_pkcs11_module scx_pkcs11_module_t;
-
-/* PKCS #11 cryptoki context */
-static bool scx_initialized = FALSE;
-static scx_pkcs11_module_t *pkcs11_module = NULL_PTR;
-static CK_FUNCTION_LIST_PTR pkcs11_functions = NULL_PTR;
-
-/* crytoki v2.11 - return values of PKCS #11 functions*/
-
-static const char *const pkcs11_return_name[] = {
-               "CKR_OK",
-               "CKR_CANCEL",
-               "CKR_HOST_MEMORY",
-               "CKR_SLOT_ID_INVALID",
-               "CKR_FLAGS_INVALID",
-               "CKR_GENERAL_ERROR",
-               "CKR_FUNCTION_FAILED",
-               "CKR_ARGUMENTS_BAD",
-               "CKR_NO_EVENT",
-               "CKR_NEED_TO_CREATE_THREADS",
-               "CKR_CANT_LOCK"
-       };
-
-static const char *const pkcs11_return_name_10[] = {
-               "CKR_ATTRIBUTE_READ_ONLY",
-               "CKR_ATTRIBUTE_SENSITIVE",
-               "CKR_ATTRIBUTE_TYPE_INVALID",
-               "CKR_ATTRIBUTE_VALUE_INVALID"
-       };
-
-static const char *const pkcs11_return_name_20[] = {
-               "CKR_DATA_INVALID",
-               "CKR_DATA_LEN_RANGE"
-       };
-
-static const char *const pkcs11_return_name_30[] = {
-               "CKR_DEVICE_ERROR",
-               "CKR_DEVICE_MEMORY",
-               "CKR_DEVICE_REMOVED"
-       };
-
-static const char *const pkcs11_return_name_40[] = {
-               "CKR_ENCRYPTED_DATA_INVALID",
-               "CKR_ENCRYPTED_DATA_LEN_RANGE"
-       };
-
-static const char *const pkcs11_return_name_50[] = {
-               "CKR_FUNCTION_CANCELED",
-               "CKR_FUNCTION_NOT_PARALLEL",
-               "CKR_0x52_UNDEFINED",
-               "CKR_0x53_UNDEFINED",
-               "CKR_FUNCTION_NOT_SUPPORTED"
-       };
-
-static const char *const pkcs11_return_name_60[] = {
-               "CKR_KEY_HANDLE_INVALID",
-               "CKR_KEY_SENSITIVE",
-               "CKR_KEY_SIZE_RANGE",
-               "CKR_KEY_TYPE_INCONSISTENT",
-               "CKR_KEY_NOT_NEEDED",
-               "CKR_KEY_CHANGED",
-               "CKR_KEY_NEEDED",
-               "CKR_KEY_INDIGESTIBLE",
-               "CKR_KEY_FUNCTION_NOT_PERMITTED",
-               "CKR_KEY_NOT_WRAPPABLE",
-               "CKR_KEY_UNEXTRACTABLE"
-        };
-
-static const char *const pkcs11_return_name_70[] = {
-               "CKR_MECHANISM_INVALID",
-               "CKR_MECHANISM_PARAM_INVALID"
-        };
-
-static const char *const pkcs11_return_name_80[] = {
-               "CKR_OBJECT_HANDLE_INVALID"
-        };
-
-static const char *const pkcs11_return_name_90[] = {
-               "CKR_OPERATION_ACTIVE",
-               "CKR_OPERATION_NOT_INITIALIZED"
-        };
-
-static const char *const pkcs11_return_name_A0[] = {
-               "CKR_PIN_INCORRECT",
-               "CKR_PIN_INVALID",
-               "CKR_PIN_LEN_RANGE",
-               "CKR_PIN_EXPIRED",
-               "CKR_PIN_LOCKED"
-        };
-
-static const char *const pkcs11_return_name_B0[] = {
-               "CKR_SESSION_CLOSED",
-               "CKR_SESSION_COUNT",
-               "CKR_0xB2_UNDEFINED",
-               "CKR_SESSION_HANDLE_INVALID",
-               "CKR_SESSION_PARALLEL_NOT_SUPPORTED",
-               "CKR_SESSION_READ_ONLY",
-               "CKR_SESSION_EXISTS",
-               "CKR_SESSION_READ_ONLY_EXISTS",
-               "CKR_SESSION_READ_WRITE_SO_EXISTS"
-        };
-
-static const char *const pkcs11_return_name_C0[] = {
-               "CKR_SIGNATURE_INVALID",
-               "CKR_SIGNATURE_LEN_RANGE"
-        };
-
-static const char *const pkcs11_return_name_D0[] = {
-               "CKR_TEMPLATE_INCOMPLETE",
-               "CKR_TEMPLATE_INCONSISTENT"
-        };
-
-static const char *const pkcs11_return_name_E0[] = {
-               "CKR_TOKEN_NOT_PRESENT",
-               "CKR_TOKEN_NOT_RECOGNIZED",
-               "CKR_TOKEN_WRITE_PROTECTED"
-        };
-
-static const char *const pkcs11_return_name_F0[] = {
-               "CKR_UNWRAPPING_KEY_HANDLE_INVALID",
-               "CKR_UNWRAPPING_KEY_SIZE_RANGE",
-               "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT"
-        };
-
-static const char *const pkcs11_return_name_100[] = {
-               "CKR_USER_ALREADY_LOGGED_IN",
-               "CKR_USER_NOT_LOGGED_IN",
-               "CKR_USER_PIN_NOT_INITIALIZED",
-               "CKR_USER_TYPE_INVALID",
-               "CKR_USER_ANOTHER_ALREADY_LOGGED_IN",
-               "CKR_USER_TOO_MANY_TYPES"
-        };
-
-static const char *const pkcs11_return_name_110[] = {
-               "CKR_WRAPPED_KEY_INVALID",
-               "CKR_0x111_UNDEFINED",
-               "CKR_WRAPPED_KEY_LEN_RANGE",
-               "CKR_WRAPPING_KEY_HANDLE_INVALID",
-               "CKR_WRAPPING_KEY_SIZE_RANGE",
-               "CKR_WRAPPING_KEY_TYPE_INCONSISTENT"
-        };
-
-static const char *const pkcs11_return_name_120[] = {
-               "CKR_RANDOM_SEED_NOT_SUPPORTED",
-               "CKR_RANDOM_NO_RNG"
-        };
-
-static const char *const pkcs11_return_name_130[] = {
-               "CKR_DOMAIN_PARAMS_INVALID"
-        };
-
-static const char *const pkcs11_return_name_150[] = {
-               "CKR_BUFFER_TOO_SMALL"
-        };
-
-static const char *const pkcs11_return_name_160[] = {
-               "CKR_SAVED_STATE_INVALID"
-        };
-
-static const char *const pkcs11_return_name_170[] = {
-               "CKR_INFORMATION_SENSITIVE"
-        };
-
-static const char *const pkcs11_return_name_180[] = {
-               "CKR_STATE_UNSAVEABLE"
-        };
-
-static const char *const pkcs11_return_name_190[] = {
-               "CKR_CRYPTOKI_NOT_INITIALIZED",
-               "CKR_CRYPTOKI_ALREADY_INITIALIZED"
-        };
-
-static const char *const pkcs11_return_name_1A0[] = {
-               "CKR_MUTEX_BAD",
-               "CKR_MUTEX_NOT_LOCKED"
-        };
-
-static const char *const pkcs11_return_name_200[] = {
-               "CKR_FUNCTION_REJECTED"
-        };
-
-static const char *const pkcs11_return_name_vendor[] = {
-               "CKR_VENDOR_DEFINED"
-        };
-
-static enum_names pkcs11_return_names_vendor =
-       { CKR_VENDOR_DEFINED, CKR_VENDOR_DEFINED
-               , pkcs11_return_name_vendor, NULL };
-
-static enum_names pkcs11_return_names_200 =
-       { CKR_FUNCTION_REJECTED, CKR_FUNCTION_REJECTED
-               , pkcs11_return_name_200, &pkcs11_return_names_vendor };
-
-static enum_names pkcs11_return_names_1A0 =
-       { CKR_MUTEX_BAD, CKR_MUTEX_NOT_LOCKED
-               , pkcs11_return_name_1A0, &pkcs11_return_names_200 };
-
-static enum_names pkcs11_return_names_190 =
-       { CKR_CRYPTOKI_NOT_INITIALIZED, CKR_CRYPTOKI_ALREADY_INITIALIZED
-               , pkcs11_return_name_190, &pkcs11_return_names_1A0 };
-
-static enum_names pkcs11_return_names_180 =
-       { CKR_STATE_UNSAVEABLE, CKR_STATE_UNSAVEABLE
-               , pkcs11_return_name_180, &pkcs11_return_names_190 };
-
-static enum_names pkcs11_return_names_170 =
-       { CKR_INFORMATION_SENSITIVE, CKR_INFORMATION_SENSITIVE
-               , pkcs11_return_name_170, &pkcs11_return_names_180 };
-
-static enum_names pkcs11_return_names_160 =
-       { CKR_SAVED_STATE_INVALID, CKR_SAVED_STATE_INVALID
-               , pkcs11_return_name_160, &pkcs11_return_names_170 };
-
-static enum_names pkcs11_return_names_150 =
-       { CKR_BUFFER_TOO_SMALL, CKR_BUFFER_TOO_SMALL
-               , pkcs11_return_name_150, &pkcs11_return_names_160 };
-
-static enum_names pkcs11_return_names_130 =
-       { CKR_DOMAIN_PARAMS_INVALID, CKR_DOMAIN_PARAMS_INVALID
-               , pkcs11_return_name_130, &pkcs11_return_names_150 };
-
-static enum_names pkcs11_return_names_120 =
-       { CKR_RANDOM_SEED_NOT_SUPPORTED, CKR_RANDOM_NO_RNG
-               , pkcs11_return_name_120, &pkcs11_return_names_130 };
-
-static enum_names pkcs11_return_names_110 =
-       { CKR_WRAPPED_KEY_INVALID, CKR_WRAPPING_KEY_TYPE_INCONSISTENT
-               , pkcs11_return_name_110, &pkcs11_return_names_120 };
-
-static enum_names pkcs11_return_names_100 =
-       { CKR_USER_ALREADY_LOGGED_IN, CKR_USER_TOO_MANY_TYPES
-               , pkcs11_return_name_100, &pkcs11_return_names_110 };
-
-static enum_names pkcs11_return_names_F0 =
-       { CKR_UNWRAPPING_KEY_HANDLE_INVALID, CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT
-               , pkcs11_return_name_F0, &pkcs11_return_names_100 };
-
-static enum_names pkcs11_return_names_E0 =
-       { CKR_TOKEN_NOT_PRESENT, CKR_TOKEN_WRITE_PROTECTED
-               , pkcs11_return_name_E0, &pkcs11_return_names_F0 };
-
-static enum_names pkcs11_return_names_D0 =
-       { CKR_TEMPLATE_INCOMPLETE, CKR_TEMPLATE_INCONSISTENT
-               , pkcs11_return_name_D0,&pkcs11_return_names_E0 };
-
-static enum_names pkcs11_return_names_C0 =
-       { CKR_SIGNATURE_INVALID, CKR_SIGNATURE_LEN_RANGE
-               , pkcs11_return_name_C0, &pkcs11_return_names_D0 };
-
-static enum_names pkcs11_return_names_B0 =
-       { CKR_SESSION_CLOSED, CKR_SESSION_READ_WRITE_SO_EXISTS
-               , pkcs11_return_name_B0, &pkcs11_return_names_C0 };
-
-static enum_names pkcs11_return_names_A0 =
-       { CKR_PIN_INCORRECT, CKR_PIN_LOCKED
-               , pkcs11_return_name_A0, &pkcs11_return_names_B0 };
-
-static enum_names pkcs11_return_names_90 =
-       { CKR_OPERATION_ACTIVE, CKR_OPERATION_NOT_INITIALIZED
-               , pkcs11_return_name_90, &pkcs11_return_names_A0 };
-
-static enum_names pkcs11_return_names_80 =
-       { CKR_OBJECT_HANDLE_INVALID, CKR_OBJECT_HANDLE_INVALID
-               , pkcs11_return_name_80, &pkcs11_return_names_90 };
-
-static enum_names pkcs11_return_names_70 =
-       { CKR_MECHANISM_INVALID, CKR_MECHANISM_PARAM_INVALID
-               , pkcs11_return_name_70, &pkcs11_return_names_80 };
-
-static enum_names pkcs11_return_names_60 =
-       { CKR_KEY_HANDLE_INVALID, CKR_KEY_UNEXTRACTABLE
-               , pkcs11_return_name_60, &pkcs11_return_names_70 };
-
-static enum_names pkcs11_return_names_50 =
-       { CKR_FUNCTION_CANCELED, CKR_FUNCTION_NOT_SUPPORTED
-               , pkcs11_return_name_50, &pkcs11_return_names_60 };
-
-static enum_names pkcs11_return_names_40 =
-       { CKR_ENCRYPTED_DATA_INVALID, CKR_ENCRYPTED_DATA_LEN_RANGE
-               , pkcs11_return_name_40, &pkcs11_return_names_50 };
-
-static enum_names pkcs11_return_names_30 =
-       { CKR_DEVICE_ERROR, CKR_DEVICE_REMOVED
-               , pkcs11_return_name_30, &pkcs11_return_names_40 };
-
-static enum_names pkcs11_return_names_20 =
-       { CKR_DATA_INVALID, CKR_DATA_LEN_RANGE
-               , pkcs11_return_name_20, &pkcs11_return_names_30 };
-
-static enum_names pkcs11_return_names_10 =
-       { CKR_ATTRIBUTE_READ_ONLY, CKR_ATTRIBUTE_VALUE_INVALID
-               , pkcs11_return_name_10, &pkcs11_return_names_20};
-
-static enum_names pkcs11_return_names =
-       { CKR_OK, CKR_CANT_LOCK
-               , pkcs11_return_name, &pkcs11_return_names_10};
-
-/*
- * Unload a PKCS#11 module.
- * The calling application is responsible for cleaning up
- * and calling C_Finalize()
- */
-static CK_RV scx_unload_pkcs11_module(scx_pkcs11_module_t *mod)
-{
-       if (!mod || mod->_magic != SCX_MAGIC)
-               return CKR_ARGUMENTS_BAD;
-
-       if (dlclose(mod->handle) < 0)
-               return CKR_FUNCTION_FAILED;
-
-       memset(mod, 0, sizeof(*mod));
-       free(mod);
-       return CKR_OK;
-}
-
-static scx_pkcs11_module_t* scx_load_pkcs11_module(const char *name,
-                                                                CK_FUNCTION_LIST_PTR_PTR funcs)
-{
-       CK_RV (*c_get_function_list)(CK_FUNCTION_LIST_PTR_PTR);
-       scx_pkcs11_module_t *mod;
-       void *handle;
-       int rv;
-
-       if (name == NULL || *name == '\0')
-               return NULL;
-
-       /* Try to load PKCS#11 library module*/
-       handle = dlopen(name, RTLD_NOW);
-       if (handle == NULL)
-               return NULL;
-
-       mod = malloc_thing(scx_pkcs11_module_t);
-       mod->_magic = SCX_MAGIC;
-       mod->handle = handle;
-
-   /* Get the list of function pointers */
-       c_get_function_list = (CK_RV (*)(CK_FUNCTION_LIST_PTR_PTR))
-                       dlsym(mod->handle, "C_GetFunctionList");
-       if (!c_get_function_list)
-               goto failed;
-
-       rv = c_get_function_list(funcs);
-       if (rv == CKR_OK)
-               return mod;
-
-failed: scx_unload_pkcs11_module(mod);
-               return NULL;
-}
-
-/*
- * retrieve a certificate object
- */
-static cert_t* scx_find_cert_object(CK_SESSION_HANDLE session,
-                                                                       CK_OBJECT_HANDLE object, smartcard_t *sc)
-{
-       size_t hex_len, label_len;
-       u_char *hex_id = NULL;
-       cert_t *cert;
-       chunk_t blob;
-
-       CK_ATTRIBUTE attr[] = {
-               { CKA_ID,    NULL_PTR, 0L },
-               { CKA_LABEL, NULL_PTR, 0L },
-               { CKA_VALUE, NULL_PTR, 0L }
-       };
-
-       /* get the length of the attributes first */
-       CK_RV rv = pkcs11_functions->C_GetAttributeValue(session, object, attr, 3);
-       if (rv != CKR_OK)
-       {
-               plog("couldn't read the attribute sizes: %s"
-                       , enum_show(&pkcs11_return_names, rv));
-               return NULL;
-       }
-
-       free(sc->label);
-
-       hex_id    = malloc(attr[0].ulValueLen);
-       hex_len   = attr[0].ulValueLen;
-       sc->label = malloc(attr[1].ulValueLen + 1);
-       label_len = attr[1].ulValueLen;
-       blob.ptr  = malloc(attr[2].ulValueLen);
-       blob.len  = attr[2].ulValueLen;
-
-       attr[0].pValue = hex_id;
-       attr[1].pValue = sc->label;
-       attr[2].pValue = blob.ptr;
-
-       /* now get the attributes */
-       rv = pkcs11_functions->C_GetAttributeValue(session, object, attr, 3);
-       if (rv != CKR_OK)
-       {
-               plog("couldn't read the attributes: %s"
-                       , enum_show(&pkcs11_return_names, rv));
-               free(hex_id);
-               free(sc->label);
-               free(blob.ptr);
-               return NULL;
-       }
-
-       free(sc->id);
-
-       /* convert id from hex to ASCII */
-       sc->id = malloc(2*hex_len + 1);
-       datatot(hex_id, hex_len, 16, sc->id, 2*hex_len + 1);
-       free(hex_id);
-
-       /* safeguard in case the label is not null terminated */
-       sc->label[label_len] = '\0';
-
-       /* parse the retrieved cert */
-
-       /* initialize the return argument */
-       cert = malloc_thing(cert_t);
-       *cert = cert_empty;
-       cert->smartcard = TRUE;
-       cert->cert = lib->creds->create(lib->creds,
-                                                                       CRED_CERTIFICATE, CERT_X509,
-                                                                       BUILD_BLOB_ASN1_DER, blob,
-                                                                       BUILD_END);
-       if (cert->cert)
-       {
-               return cert;
-       }
-
-       plog("failed to load cert from smartcard, error in X.509 certificate");
-       cert_free(cert);
-       return NULL;
-}
-
-
-/*
- * search a given slot for PKCS#11 certificate objects
- */
-static void scx_find_cert_objects(CK_SLOT_ID slot, CK_SESSION_HANDLE session)
-{
-       CK_RV rv;
-       CK_OBJECT_CLASS class = CKO_CERTIFICATE;
-       CK_ATTRIBUTE attr[] = {{ CKA_CLASS, &class, sizeof(class) }};
-
-       rv = pkcs11_functions->C_FindObjectsInit(session, attr, 1);
-       if (rv != CKR_OK)
-       {
-               plog("error in C_FindObjectsInit: %s"
-                       , enum_show(&pkcs11_return_names, rv));
-               return;
-       }
-
-       for (;;)
-       {
-               CK_OBJECT_HANDLE object;
-               CK_ULONG obj_count = 0;
-               time_t valid_until;
-               smartcard_t *sc;
-               cert_t *cert;
-               certificate_t *certificate;
-               x509_t *x509;
-
-               rv = pkcs11_functions->C_FindObjects(session, &object, 1, &obj_count);
-               if (rv != CKR_OK)
-               {
-                       plog("error in C_FindObjects: %s"
-                               , enum_show(&pkcs11_return_names, rv));
-                       break;
-               }
-
-               /* no objects left */
-               if (obj_count == 0)
-                       break;
-
-               /* create and initialize a new smartcard object */
-               sc  = malloc_thing(smartcard_t);
-               *sc = empty_sc;
-               sc->any_slot = FALSE;
-               sc->slot  = slot;
-               cert = scx_find_cert_object(session, object, sc);
-               if (!cert)
-               {
-                       scx_free(sc);
-                       continue;
-               }
-               DBG(DBG_CONTROL,
-                       DBG_log("found cert in %s with id: %s, label: '%s'"
-                               , scx_print_slot(sc, ""), sc->id, sc->label)
-               )
-
-               /* check validity of certificate */
-               certificate = cert->cert;
-               if (!certificate->get_validity(certificate, NULL, NULL, &valid_until))
-               {
-                       cert_free(cert);
-                       scx_free(sc);
-                       continue;
-               }
-               DBG(DBG_CONTROL,
-                       DBG_log("  certificate is valid")
-               )
-
-               sc = scx_add(sc);
-
-               /* put end entity and ca certificates into different chains */
-               x509 = (x509_t*)certificate;
-               if (x509->get_flags(x509) & X509_CA)
-               {
-                       sc->last_cert = add_authcert(cert, X509_CA);
-               }
-               else
-               {
-                       add_public_key_from_cert(cert, valid_until, DAL_LOCAL);
-                       sc->last_cert = cert_add(cert);
-               }
-
-               cert_share(sc->last_cert);
-               time(&sc->last_load);
-       }
-
-       rv = pkcs11_functions->C_FindObjectsFinal(session);
-       if (rv != CKR_OK)
-       {
-               plog("error in C_FindObjectsFinal: %s"
-                               , enum_show(&pkcs11_return_names, rv));
-       }
-}
-
-/*
- * search all slots for PKCS#11 certificate objects
- */
-static void scx_find_all_cert_objects(void)
-{
-       CK_RV rv;
-       CK_SLOT_ID_PTR slots = NULL_PTR;
-       CK_ULONG slot_count = 0;
-       CK_ULONG i;
-
-       if (!scx_initialized)
-       {
-               plog("pkcs11 module not initialized");
-               return;
-       }
-
-       /* read size, always returns CKR_OK ! */
-       rv = pkcs11_functions->C_GetSlotList(FALSE, NULL_PTR, &slot_count);
-
-       /* allocate memory for the slots */
-       slots = (CK_SLOT_ID *)malloc(slot_count * sizeof(CK_SLOT_ID));
-
-       rv = pkcs11_functions->C_GetSlotList(FALSE, slots, &slot_count);
-       if (rv != CKR_OK)
-       {
-               plog("error in C_GetSlotList: %s", enum_show(&pkcs11_return_names, rv));
-               free(slots);
-               return;
-       }
-
-       /* look in every slot for certificate objects */
-       for (i = 0; i < slot_count; i++)
-       {
-               CK_SLOT_ID slot = slots[i];
-               CK_SLOT_INFO info;
-               CK_SESSION_HANDLE session;
-
-               rv = pkcs11_functions->C_GetSlotInfo(slot, &info);
-
-               if (rv != CKR_OK)
-               {
-                       plog("error in C_GetSlotInfo: %s"
-                               , enum_show(&pkcs11_return_names, rv));
-                       continue;
-               }
-
-               if (!(info.flags & CKF_TOKEN_PRESENT))
-               {
-                       plog("no token present in slot %lu", slot);
-                       continue;
-               }
-
-               rv = pkcs11_functions->C_OpenSession(slot
-                               , CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &session);
-               if (rv != CKR_OK)
-               {
-                       plog("failed to open a session on slot %lu: %s"
-                               , slot, enum_show(&pkcs11_return_names, rv));
-                       continue;
-               }
-               DBG(DBG_CONTROLMORE,
-                       DBG_log("pkcs11 session #%ld for searching slot %lu", session, slot)
-               )
-               scx_find_cert_objects(slot, session);
-
-               rv = pkcs11_functions->C_CloseSession(session);
-               if (rv != CKR_OK)
-               {
-                       plog("error in C_CloseSession: %s"
-                               , enum_show(&pkcs11_return_names, rv));
-               }
-       }
-       free(slots);
-}
-#endif
-
-/*
- * load and initialize PKCS#11 cryptoki module
- *
- * init_args should be unused when we have a PKCS#11 compliant module,
- * but NSS softoken breaks that API.
- */
-void scx_init(const char* module, const char *init_args)
-{
-#ifdef SMARTCARD
-       CK_C_INITIALIZE_ARGS args = { .pReserved = (char *)init_args, };
-       CK_RV rv;
-
-       if (scx_initialized)
-       {
-               plog("weird - pkcs11 module seems already to be initialized");
-               return;
-       }
-
-       if (module == NULL)
-#ifdef PKCS11_DEFAULT_LIB
-               module = PKCS11_DEFAULT_LIB;
-#else
-       {
-               plog("no pkcs11 module defined");
-               return;
-       }
-#endif
-
-       DBG(DBG_CONTROL | DBG_CRYPT,
-               DBG_log("pkcs11 module '%s' loading...", module)
-       )
-       pkcs11_module = scx_load_pkcs11_module(module, &pkcs11_functions);
-       if (pkcs11_module == NULL)
-       {
-                plog("failed to load pkcs11 module '%s'", module);
-                return;
-       }
-
-       DBG(DBG_CONTROL | DBG_CRYPT,
-               DBG_log("pkcs11 module initializing...")
-       )
-       rv = pkcs11_functions->C_Initialize(init_args ? &args : NULL);
-       if (rv != CKR_OK)
-       {
-               plog("failed to initialize pkcs11 module: %s"
-                       , enum_show(&pkcs11_return_names, rv));
-               return;
-       }
-
-       scx_initialized = TRUE;
-       DBG(DBG_CONTROL | DBG_CRYPT,
-               DBG_log("pkcs11 module loaded and initialized")
-       )
-
-       scx_find_all_cert_objects();
-#endif
-}
-
-/*
- * finalize and unload PKCS#11 cryptoki module
- */
-void scx_finalize(void)
-{
-#ifdef SMARTCARD
-       while (smartcards != NULL)
-       {
-               scx_release(smartcards);
-       }
-
-       if (pkcs11_functions != NULL_PTR)
-       {
-               pkcs11_functions->C_Finalize(NULL_PTR);
-               pkcs11_functions = NULL_PTR;
-       }
-
-       if (pkcs11_module != NULL)
-       {
-               scx_unload_pkcs11_module(pkcs11_module);
-               pkcs11_module = NULL;
-       }
-
-       scx_initialized = FALSE;
-       DBG(DBG_CONTROL | DBG_CRYPT,
-               DBG_log("pkcs11 module finalized and unloaded")
-       )
-#endif
-}
-
-/*
- * does a filename contain the token %smartcard?
- */
-bool scx_on_smartcard(const char *filename)
-{
-       return strneq(filename, SCX_TOKEN, strlen(SCX_TOKEN));
-}
-
-#ifdef SMARTCARD
-/*
- * find a specific object on the smartcard
- */
-static bool scx_pkcs11_find_object(CK_SESSION_HANDLE session,
-                                                                  CK_OBJECT_HANDLE_PTR object,
-                                                                  CK_OBJECT_CLASS class, const char* id)
-{
-       size_t len;
-       char buf[BUF_LEN];
-       CK_RV rv;
-       CK_ULONG obj_count = 0;
-       CK_ULONG attr_count = 1;
-
-       CK_ATTRIBUTE attr[] = {
-               { CKA_CLASS, &class, sizeof(class) },
-               { CKA_ID, &buf, 0L }
-       };
-
-       if (id != NULL)
-       {
-               ttodata(id, strlen(id), 16, buf, BUF_LEN, &len);
-               attr[1].ulValueLen = len;
-               attr_count = 2;
-       }
-
-       /* get info for certificate with id */
-       rv = pkcs11_functions->C_FindObjectsInit(session, attr, attr_count);
-       if (rv != CKR_OK)
-       {
-               plog("error in C_FindObjectsInit: %s"
-                               , enum_show(&pkcs11_return_names, rv));
-               return FALSE;
-       }
-
-       rv = pkcs11_functions->C_FindObjects(session, object, 1,  &obj_count);
-       if (rv != CKR_OK)
-       {
-               plog("error in C_FindObjects: %s"
-                               , enum_show(&pkcs11_return_names, rv));
-               return FALSE;
-       }
-
-       rv = pkcs11_functions->C_FindObjectsFinal(session);
-       if (rv != CKR_OK)
-       {
-               plog("error in C_FindObjectsFinal: %s"
-                               , enum_show(&pkcs11_return_names, rv));
-               return FALSE;
-       }
-
-       return (obj_count != 0);
-}
-
-/*
- * check if a given certificate object id is found in a slot
- */
-static bool scx_find_cert_id_in_slot(smartcard_t *sc, CK_SLOT_ID slot)
-{
-       CK_SESSION_HANDLE session;
-       CK_OBJECT_HANDLE object;
-       CK_SLOT_INFO info;
-
-       CK_RV rv = pkcs11_functions->C_GetSlotInfo(slot, &info);
-
-       if (rv != CKR_OK)
-       {
-               plog("error in C_GetSlotInfo: %s"
-                       , enum_show(&pkcs11_return_names, rv));
-                return FALSE;
-       }
-
-       if (!(info.flags & CKF_TOKEN_PRESENT))
-       {
-               plog("no token present in slot %lu", slot);
-               return FALSE;
-       }
-
-       rv = pkcs11_functions->C_OpenSession(slot
-                               , CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &session);
-       if (rv != CKR_OK)
-       {
-               plog("failed to open a session on slot %lu: %s"
-                       , slot, enum_show(&pkcs11_return_names, rv));
-               return FALSE;
-       }
-       DBG(DBG_CONTROLMORE,
-               DBG_log("pkcs11 session #%ld for searching slot %lu", session, slot)
-       )
-
-       /* check if there is a certificate on the card in the specified slot */
-       if (scx_pkcs11_find_object(session, &object, CKO_CERTIFICATE, sc->id))
-       {
-               sc->slot = slot;
-               sc->any_slot = FALSE;
-               sc->session = session;
-               sc->session_opened = TRUE;
-               return TRUE;
-       }
-
-       rv = pkcs11_functions->C_CloseSession(session);
-       if (rv != CKR_OK)
-       {
-               plog("error in C_CloseSession: %s"
-                               , enum_show(&pkcs11_return_names, rv));
-       }
-       return FALSE;
-}
-#endif
-
-/*
- * Connect to the smart card in the reader and select the correct slot
- */
-bool scx_establish_context(smartcard_t *sc)
-{
-#ifdef SMARTCARD
-       bool id_found = FALSE;
-
-       if (!scx_initialized)
-       {
-               plog("pkcs11 module not initialized");
-               return FALSE;
-       }
-
-       if (sc->session_opened)
-       {
-               DBG(DBG_CONTROL | DBG_CRYPT,
-                       DBG_log("pkcs11 session #%ld already open", sc->session)
-               )
-               return TRUE;
-       }
-
-       if (!sc->any_slot)
-               id_found = scx_find_cert_id_in_slot(sc, sc->slot);
-
-       if (!id_found)
-       {
-               CK_RV rv;
-               CK_SLOT_ID slot;
-               CK_SLOT_ID_PTR slots = NULL_PTR;
-               CK_ULONG slot_count = 0;
-               CK_ULONG i;
-
-               /* read size, always returns CKR_OK ! */
-               rv = pkcs11_functions->C_GetSlotList(FALSE, NULL_PTR, &slot_count);
-
-               /* allocate memory for the slots */
-               slots = (CK_SLOT_ID *)malloc(slot_count * sizeof(CK_SLOT_ID));
-
-               rv = pkcs11_functions->C_GetSlotList(FALSE, slots, &slot_count);
-               if (rv != CKR_OK)
-               {
-                       plog("error in C_GetSlotList: %s"
-                               , enum_show(&pkcs11_return_names, rv));
-                       free(slots);
-                       return FALSE;
-               }
-
-               /* look in every slot for a certificate with a given object ID */
-               for (i = 0; i < slot_count; i++)
-               {
-                       slot = slots[i];
-                       id_found = scx_find_cert_id_in_slot(sc, slot);
-                       if (id_found)
-                               break;
-               }
-               free(slots);
-       }
-
-       if (id_found)
-       {
-               DBG(DBG_CONTROL | DBG_CRYPT,
-                       DBG_log("found token with id %s in slot %lu", sc->id, sc->slot);
-                       DBG_log("pkcs11 session #%ld opened", sc->session)
-               )
-       }
-       else
-       {
-               plog("  no certificate with id %s found on smartcard", sc->id);
-       }
-       return id_found;
-#else
-       plog("warning: SMARTCARD support is deactivated in pluto/Makefile!");
-       return FALSE;
-#endif
-}
-
-/*
- * log in to a session
- */
-bool scx_login(smartcard_t *sc)
-{
-#ifdef SMARTCARD
-       CK_RV rv;
-
-       if (sc->logged_in)
-       {
-               DBG(DBG_CONTROL | DBG_CRYPT,
-                       DBG_log("pkcs11 session #%ld login already done", sc->session)
-               )
-               return TRUE;
-       }
-
-       if (sc->pin.ptr == NULL)
-       {
-               plog("unable to log in without PIN!");
-               return FALSE;
-       }
-
-       if (!sc->session_opened)
-       {
-               plog("session not opened");
-               return FALSE;
-       }
-
-       rv = pkcs11_functions->C_Login(sc->session, CKU_USER
-                                                               , (CK_UTF8CHAR *) sc->pin.ptr, sc->pin.len);
-       if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN)
-       {
-               plog("unable to login: %s"
-                       , enum_show(&pkcs11_return_names, rv));
-               return FALSE;
-       }
-       DBG(DBG_CONTROL | DBG_CRYPT,
-               DBG_log("pkcs11 session #%ld login successful", sc->session)
-       )
-       sc->logged_in = TRUE;
-       return TRUE;
-#else
-   return FALSE;
-#endif
-}
-
-#ifdef SMARTCARD
-/*
- * logout from a session
- */
-static void scx_logout(smartcard_t *sc)
-{
-       CK_RV rv;
-
-       rv = pkcs11_functions->C_Logout(sc->session);
-       if (rv != CKR_OK)
-               plog("error in C_Logout: %s"
-                       , enum_show(&pkcs11_return_names, rv));
-       else
-               DBG(DBG_CONTROL | DBG_CRYPT,
-                       DBG_log("pkcs11 session #%ld logout", sc->session)
-               )
-       sc->logged_in = FALSE;
-}
-#endif
-
-
-/*
- * Release context and disconnect from card
- */
-void scx_release_context(smartcard_t *sc)
-{
-#ifdef SMARTCARD
-       CK_RV rv;
-
-       if (!scx_initialized)
-               return;
-
-       if (sc->session_opened)
-       {
-               if (sc->logged_in)
-                       scx_logout(sc);
-
-               sc->session_opened = FALSE;
-
-               rv = pkcs11_functions->C_CloseSession(sc->session);
-               if (rv != CKR_OK)
-                       plog("error in C_CloseSession: %s"
-                               , enum_show(&pkcs11_return_names, rv));
-               else
-                       DBG(DBG_CONTROL | DBG_CRYPT,
-                               DBG_log("pkcs11 session #%ld closed", sc->session)
-                       )
-       }
-#endif
-}
-
-/*
- * Load host certificate from smartcard
- */
-cert_t* scx_load_cert(const char *filename, smartcard_t **scp, bool *cached)
-{
-#ifdef SMARTCARD        /* compile with smartcard support */
-       const char *number_slot_id = filename + strlen(SCX_TOKEN);
-       CK_OBJECT_HANDLE object;
-       smartcard_t *sc;
-       cert_t *cert = NULL;
-
-       /* return the smartcard object */
-       *scp = sc = scx_add(scx_parse_number_slot_id(number_slot_id));
-
-       /* is there a cached smartcard certificate? */
-       *cached = sc->last_cert &&
-                         (time(NULL) - sc->last_load) < SCX_CERT_CACHE_INTERVAL;
-
-       if (*cached)
-       {
-               plog("  using cached cert from smartcard #%d (%s, id: %s, label: '%s')"
-                               , sc->number
-                               , scx_print_slot(sc, "")
-                               , sc->id
-                               , sc->label);
-               return sc->last_cert;
-       }
-
-       if (!scx_establish_context(sc))
-       {
-               scx_release_context(sc);
-               return NULL;
-       }
-
-       /* find the certificate object */
-       if (!scx_pkcs11_find_object(sc->session, &object, CKO_CERTIFICATE, sc->id))
-       {
-               scx_release_context(sc);
-               return NULL;
-       }
-
-       /* retrieve the certificate object */
-       cert = scx_find_cert_object(sc->session, object, sc);
-       if (cert == NULL)
-       {
-               scx_release_context(sc);
-               return NULL;
-       }
-
-       if (!pkcs11_keep_state)
-       {
-               scx_release_context(sc);
-       }
-       plog("  loaded cert from smartcard #%d (%s, id: %s, label: '%s')"
-               , sc->number
-               , scx_print_slot(sc, "")
-               , sc->id
-               , sc->label);
-
-       return cert;
-#else
-       plog("  warning: SMARTCARD support is deactivated in pluto/Makefile!");
-       return NULL;
-#endif
-}
-
-/*
- * parse slot number and key id
- * the following syntax is allowed
- *               number   slot   id
- * %smartcard      1       -     -
- * %smartcard#2    2       -     -
- * %smartcard0     -       0     -
- * %smartcard:45   -       -     45
- * %smartcard0:45  -       0     45
- */
-smartcard_t* scx_parse_number_slot_id(const char *number_slot_id)
-{
-       int len = strlen(number_slot_id);
-       smartcard_t *sc = malloc_thing(smartcard_t);
-
-       /* assign default values */
-       *sc = empty_sc;
-
-       if (len == 0)                       /* default: use certificate #1 */
-       {
-               sc->number = 1;
-       }
-       else if (*number_slot_id == '#')    /* #number scheme */
-       {
-               err_t ugh;
-               unsigned long ul;
-
-               ugh = atoul(number_slot_id+1, len-1 , 10, &ul);
-               if (ugh == NULL)
-                       sc->number = (int)ul;
-               else
-                       plog("error parsing smartcard number: %s", ugh);
-       }
-       else                                /* slot:id scheme */
-       {
-               int slot_len = len;
-               char *p = strchr(number_slot_id, ':');
-
-               if (p != NULL)
-               {
-                       int id_len = len - (p + 1 - number_slot_id);
-                       slot_len -= (1 + id_len);
-
-                       if (id_len > 0)             /* we have an id */
-                               sc->id = p + 1;
-               }
-               if (slot_len > 0)               /* we have a slot */
-               {
-                       err_t ugh = NULL;
-                       unsigned long ul;
-
-                       ugh = atoul(number_slot_id, slot_len, 10, &ul);
-                       if (ugh == NULL)
-                       {
-                               sc->slot = ul;
-                               sc->any_slot = FALSE;
-                       }
-                       else
-                               plog("error parsing smartcard slot number: %s", ugh);
-               }
-       }
-       /* unshare the id string */
-       sc->id = clone_str(sc->id);
-       return sc;
-}
-
-/*
- * Verify pin on card
- */
-bool scx_verify_pin(smartcard_t *sc)
-{
-#ifdef SMARTCARD
-       CK_RV rv;
-
-       if (!sc->pinpad)
-               sc->valid = FALSE;
-
-       if (sc->pin.ptr == NULL)
-       {
-               plog("unable to verify without PIN");
-               return FALSE;
-       }
-
-       /* establish context */
-       if (!scx_establish_context(sc))
-       {
-               scx_release_context(sc);
-               return FALSE;
-       }
-
-       rv = pkcs11_functions->C_Login(sc->session, CKU_USER,
-                                                         (CK_UTF8CHAR *) sc->pin.ptr, sc->pin.len);
-       if (rv == CKR_OK || rv == CKR_USER_ALREADY_LOGGED_IN)
-       {
-               sc->valid = TRUE;
-               sc->logged_in = TRUE;
-               DBG(DBG_CONTROL | DBG_CRYPT,
-                       DBG_log((rv == CKR_OK)
-                               ? "PIN code correct"
-                               : "already logged in, no PIN entry required");
-                       DBG_log("pkcs11 session #%ld login successful", sc->session)
-               )
-       }
-       else
-       {
-               DBG(DBG_CONTROL | DBG_CRYPT,
-                       DBG_log("PIN code incorrect")
-               )
-       }
-       if (!pkcs11_keep_state)
-               scx_release_context(sc);
-#else
-       sc->valid = FALSE;
-#endif
-       return sc->valid;
-}
-
-/*
- * Sign hash on smartcard
- */
-bool scx_sign_hash(smartcard_t *sc, const u_char *in, size_t inlen, u_char *out,
-                                  size_t outlen)
-{
-#ifdef SMARTCARD
-       CK_RV rv;
-       CK_OBJECT_HANDLE object;
-       CK_ULONG siglen = (CK_ULONG)outlen;
-       CK_BBOOL sign_flag, decrypt_flag;
-       CK_ATTRIBUTE attr[] = {
-               { CKA_SIGN,    &sign_flag,    sizeof(sign_flag) },
-               { CKA_DECRYPT, &decrypt_flag, sizeof(decrypt_flag) }
-       };
-
-       if (!sc->logged_in)
-               return FALSE;
-
-       if (!scx_pkcs11_find_object(sc->session, &object, CKO_PRIVATE_KEY, sc->id))
-       {
-               plog("unable to find private key with id '%s'", sc->id);
-               return FALSE;
-       }
-
-       rv = pkcs11_functions->C_GetAttributeValue(sc->session, object, attr, 2);
-       if (rv != CKR_OK)
-       {
-               plog("couldn't read the private key attributes: %s"
-                       , enum_show(&pkcs11_return_names, rv));
-               return FALSE;
-       }
-       DBG(DBG_CONTROL,
-               DBG_log("RSA key flags: sign = %s, decrypt = %s"
-                       , (sign_flag)?    "true":"false"
-                       , (decrypt_flag)? "true":"false")
-       )
-
-       if (sign_flag)
-       {
-               CK_MECHANISM mech  = { CKM_RSA_PKCS, NULL_PTR, 0 };
-
-               rv = pkcs11_functions->C_SignInit(sc->session, &mech, object);
-               if (rv != CKR_OK)
-               {
-                       plog("error in C_SignInit: %s"
-                               , enum_show(&pkcs11_return_names, rv));
-                       return FALSE;
-               }
-
-               rv = pkcs11_functions->C_Sign(sc->session, (CK_BYTE_PTR)in, inlen
-                               , out, &siglen);
-               if (rv != CKR_OK)
-               {
-                       plog("error in C_Sign: %s"
-                               , enum_show(&pkcs11_return_names, rv));
-                       return FALSE;
-               }
-       }
-       else if (decrypt_flag)
-       {
-               CK_MECHANISM mech = { CKM_RSA_X_509, NULL_PTR, 0 };
-               size_t padlen;
-               u_char *p = out ;
-
-               /* PKCS#1 v1.5 8.1 encryption-block formatting */
-               *p++ = 0x00;
-               *p++ = 0x01;    /* BT (block type) 01 */
-               padlen = outlen - 3 - inlen;
-               memset(p, 0xFF, padlen);
-               p += padlen;
-               *p++ = 0x00;
-               memcpy(p, in, inlen);
-
-               rv = pkcs11_functions->C_DecryptInit(sc->session, &mech, object);
-               if (rv != CKR_OK)
-               {
-                       plog("error in C_DecryptInit: %s"
-                               , enum_show(&pkcs11_return_names, rv));
-                       return FALSE;
-               }
-
-               rv = pkcs11_functions->C_Decrypt(sc->session, out, outlen
-                               , out, &siglen);
-               if (rv != CKR_OK)
-               {
-                       plog("error in C_Decrypt: %s"
-                               , enum_show(&pkcs11_return_names, rv));
-                       return FALSE;
-               }
-       }
-       else
-       {
-               plog("private key has neither sign nor decrypt flag set");
-               return FALSE;
-       }
-
-       if (siglen > (CK_ULONG)outlen)
-       {
-               plog("signature length (%lu) larger than allocated buffer (%d)"
-                       , siglen, (int)outlen);
-               return FALSE;
-       }
-       return TRUE;
-#else
-       return FALSE;
-#endif
-}
-
-/*
- * encrypt data block with an RSA public key
- */
-bool scx_encrypt(smartcard_t *sc, const u_char *in, size_t inlen, u_char *out,
-                                size_t *outlen)
-{
-#ifdef SMARTCARD
-       CK_RV rv;
-       CK_OBJECT_HANDLE object;
-       CK_ULONG len = (CK_ULONG)(*outlen);
-       CK_BBOOL encrypt_flag;
-       CK_ATTRIBUTE attr[] = {
-               { CKA_MODULUS,         NULL_PTR, 0L },
-               { CKA_PUBLIC_EXPONENT, NULL_PTR, 0L },
-               { CKA_ENCRYPT,         &encrypt_flag, sizeof(encrypt_flag) }
-       };
-       CK_MECHANISM mech = { CKM_RSA_PKCS, NULL_PTR, 0 };
-
-       if (!scx_establish_context(sc))
-       {
-               scx_release_context(sc);
-                       return FALSE;
-       }
-
-       if (!scx_pkcs11_find_object(sc->session, &object, CKO_PUBLIC_KEY, sc->id))
-       {
-               plog("unable to find public key with id '%s'", sc->id);
-               return FALSE;
-       }
-
-       rv = pkcs11_functions->C_GetAttributeValue(sc->session, object, attr, 3);
-       if (rv != CKR_OK)
-       {
-               plog("couldn't read the public key attributes: %s"
-                       , enum_show(&pkcs11_return_names, rv));
-               scx_release_context(sc);
-               return FALSE;
-       }
-
-       if (!encrypt_flag)
-       {
-               plog("public key cannot be used for encryption");
-               scx_release_context(sc);
-               return FALSE;
-       }
-
-       /* there must be enough space left for the PKCS#1 v1.5 padding */
-       if (inlen > attr[0].ulValueLen - 11)
-       {
-               plog("smartcard input data length (%d) exceeds maximum of %lu bytes"
-                               , (int)inlen, attr[0].ulValueLen - 11);
-               if (!pkcs11_keep_state)
-                       scx_release_context(sc);
-               return FALSE;
-       }
-
-       rv = pkcs11_functions->C_EncryptInit(sc->session, &mech, object);
-
-       if (rv != CKR_OK)
-       {
-               if (rv == CKR_FUNCTION_NOT_SUPPORTED)
-               {
-                       public_key_t *key;
-                       chunk_t rsa_modulus, rsa_exponent, rsa_key, cipher_text;
-                       chunk_t plain_text = {(u_char*)in, inlen};
-
-                       DBG(DBG_CONTROL,
-                               DBG_log("doing RSA encryption in software")
-                       )
-                       attr[0].pValue = malloc(attr[0].ulValueLen);
-                       attr[1].pValue = malloc(attr[1].ulValueLen);
-
-                       rv = pkcs11_functions->C_GetAttributeValue(sc->session, object, attr, 2);
-                       if (rv != CKR_OK)
-                       {
-                               plog("couldn't read modulus and public exponent: %s"
-                                       , enum_show(&pkcs11_return_names, rv));
-                               free(attr[0].pValue);
-                               free(attr[1].pValue);
-                               scx_release_context(sc);
-                               return FALSE;
-                       }
-                       rsa_modulus  = chunk_create((u_char*) attr[0].pValue,
-                                                                           (size_t)  attr[0].ulValueLen);
-                       rsa_exponent = chunk_create((u_char*) attr[1].pValue,
-                                                                           (size_t)  attr[1].ulValueLen);
-                       rsa_key = asn1_wrap(ASN1_SEQUENCE, "mm",
-                                                               asn1_integer("m", rsa_modulus),
-                                                               asn1_integer("m", rsa_exponent));
-                       key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
-                                                               BUILD_BLOB_ASN1_DER, rsa_key, BUILD_END);
-                       free(rsa_key.ptr);
-                       if (key == NULL)
-                       {
-                               return FALSE;
-                       }
-                       key->encrypt(key, ENCRYPT_RSA_PKCS1, plain_text, &cipher_text);
-                       key->destroy(key);
-
-                       if (cipher_text.ptr == NULL)
-                       {
-                               plog("smartcard input data length is too large");
-                               if (!pkcs11_keep_state)
-                               {
-                                       scx_release_context(sc);
-                               }
-                               return FALSE;
-                       }
-
-                       memcpy(out, cipher_text.ptr, cipher_text.len);
-                       *outlen = cipher_text.len;
-                       free(cipher_text.ptr);
-
-                       if (!pkcs11_keep_state)
-                       {
-                               scx_release_context(sc);
-                       }
-                       return TRUE;
-               }
-               else
-               {
-                       plog("error in C_EncryptInit: %s"
-                               , enum_show(&pkcs11_return_names, rv));
-                       scx_release_context(sc);
-                       return FALSE;
-               }
-       }
-
-       DBG(DBG_CONTROL,
-               DBG_log("doing RSA encryption on smartcard")
-       )
-       rv = pkcs11_functions->C_Encrypt(sc->session, (u_char*)in, inlen
-                               , out, &len);
-       if (rv != CKR_OK)
-       {
-               plog("error in C_Encrypt: %s"
-                       , enum_show(&pkcs11_return_names, rv));
-               scx_release_context(sc);
-               return FALSE;
-       }
-       if (!pkcs11_keep_state)
-               scx_release_context(sc);
-
-       *outlen = (size_t)len;
-       return TRUE;
-#else
-       return FALSE;
-#endif
-}
-/*
- * decrypt a data block with an RSA private key
- */
-bool scx_decrypt(smartcard_t *sc, const u_char *in, size_t inlen, u_char *out,
-                                size_t *outlen)
-{
-#ifdef SMARTCARD
-       CK_RV rv;
-       CK_OBJECT_HANDLE object;
-       CK_ULONG len = (CK_ULONG)(*outlen);
-       CK_BBOOL decrypt_flag;
-       CK_ATTRIBUTE attr[] = {
-               { CKA_DECRYPT, &decrypt_flag, sizeof(decrypt_flag) }
-       };
-       CK_MECHANISM mech = { CKM_RSA_PKCS, NULL_PTR, 0 };
-
-       if (!scx_establish_context(sc) || !scx_login(sc))
-       {
-               scx_release_context(sc);
-                       return FALSE;
-       }
-
-       if (!scx_pkcs11_find_object(sc->session, &object, CKO_PRIVATE_KEY, sc->id))
-       {
-               plog("unable to find private key with id '%s'", sc->id);
-               return FALSE;
-       }
-
-       rv = pkcs11_functions->C_GetAttributeValue(sc->session, object, attr, 1);
-       if (rv != CKR_OK)
-       {
-               plog("couldn't read the private key attributes: %s"
-                       , enum_show(&pkcs11_return_names, rv));
-               return FALSE;
-       }
-
-       if (!decrypt_flag)
-       {
-               plog("private key cannot be used for decryption");
-               scx_release_context(sc);
-               return FALSE;
-       }
-
-       DBG(DBG_CONTROL,
-               DBG_log("doing RSA decryption on smartcard")
-       )
-       rv = pkcs11_functions->C_DecryptInit(sc->session, &mech, object);
-       if (rv != CKR_OK)
-       {
-               plog("error in C_DecryptInit: %s"
-                       , enum_show(&pkcs11_return_names, rv));
-               scx_release_context(sc);
-               return FALSE;
-       }
-
-       rv = pkcs11_functions->C_Decrypt(sc->session, (u_char*)in, inlen
-                               , out, &len);
-       if (rv != CKR_OK)
-       {
-               plog("error in C_Decrypt: %s"
-                       , enum_show(&pkcs11_return_names, rv));
-               scx_release_context(sc);
-               return FALSE;
-       }
-       if (!pkcs11_keep_state)
-               scx_release_context(sc);
-
-       *outlen = (size_t)len;
-       return TRUE;
-#else
-       return FALSE;
-#endif
-}
-
-/* receive an encrypted data block via whack,
- * decrypt it using a private RSA key and
- * return the decrypted data block via whack
- */
-bool scx_op_via_whack(const char* msg, int inbase, int outbase, sc_op_t op,
-                                         const char* keyid, int whackfd)
-{
-       char inbuf[RSA_MAX_OCTETS];
-       char outbuf[2*RSA_MAX_OCTETS + 1];
-       size_t outlen = sizeof(inbuf);
-       size_t inlen;
-       smartcard_t *sc,*sc_new;
-
-       const char *number_slot_id = "";
-
-       err_t ugh = ttodata(msg, 0, inbase, inbuf, sizeof(inbuf), &inlen);
-
-       /* no prefix - use default base */
-       if (ugh != NULL  && inbase == 0)
-          ugh = ttodata(msg, 0, DEFAULT_BASE, inbuf, sizeof(inbuf), &inlen);
-
-       if (ugh != NULL)
-       {
-               plog("format error in smartcard input data: %s", ugh);
-               return FALSE;
-       }
-
-       if (keyid != NULL)
-       {
-               number_slot_id = (strneq(keyid, SCX_TOKEN, strlen(SCX_TOKEN)))
-                                                ? keyid + strlen(SCX_TOKEN) : keyid;
-       }
-
-       sc_new = scx_parse_number_slot_id(number_slot_id);
-       sc = scx_add(sc_new);
-       if (sc == sc_new)
-               scx_share(sc);
-
-       DBG((op == SC_OP_ENCRYPT)? DBG_PRIVATE:DBG_RAW,
-               DBG_dump("smartcard input data:\n", inbuf, inlen)
-       )
-
-       if (op == SC_OP_DECRYPT)
-       {
-               if (!sc->valid && whackfd != NULL_FD)
-                       scx_get_pin(sc, whackfd);
-
-               if (!sc->valid)
-               {
-                       loglog(RC_NOVALIDPIN, "cannot decrypt without valid PIN");
-                       return FALSE;
-               }
-       }
-
-       DBG(DBG_CONTROL | DBG_CRYPT,
-               DBG_log("using RSA key from smartcard (slot: %d, id: %s)"
-                       , (int)sc->slot, sc->id)
-       )
-
-       switch (op)
-       {
-       case SC_OP_ENCRYPT:
-               if (!scx_encrypt(sc, inbuf, inlen, inbuf, &outlen))
-                       return FALSE;
-               break;
-       case SC_OP_DECRYPT:
-               if (!scx_decrypt(sc, inbuf, inlen, inbuf, &outlen))
-                       return FALSE;
-               break;
-       default:
-               break;
-       }
-
-       DBG((op == SC_OP_DECRYPT)? DBG_PRIVATE:DBG_RAW,
-               DBG_dump("smartcard output data:\n", inbuf, outlen)
-       )
-
-       if (outbase == 0)  /* use default base */
-               outbase = DEFAULT_BASE;
-
-       if (outbase == 256) /* ascii plain text */
-               whack_log(RC_COMMENT, "%.*s", (int)outlen, inbuf);
-       else
-       {
-               outlen = datatot(inbuf, outlen, outbase, outbuf, sizeof(outbuf));
-               if (outlen == 0)
-               {
-                       plog("error in output format conversion");
-                       return FALSE;
-               }
-               whack_log(RC_COMMENT, "%s", outbuf);
-       }
-       return TRUE;
-}
-
- /*
- * get length of RSA key in bytes
- */
-size_t scx_get_keylength(smartcard_t *sc)
-{
-#ifdef SMARTCARD
-       CK_RV rv;
-       CK_OBJECT_HANDLE object;
-       CK_ATTRIBUTE attr[] = {{ CKA_MODULUS, NULL_PTR, 0}};
-
-       if (!sc->logged_in)
-               return FALSE;
-
-       if (!scx_pkcs11_find_object(sc->session, &object, CKO_PRIVATE_KEY, sc->id))
-       {
-               plog("unable to find private key with id '%s'", sc->id);
-               return FALSE;
-       }
-
-       /* get the length of the private key */
-       rv = pkcs11_functions->C_GetAttributeValue(sc->session, object
-                               , (CK_ATTRIBUTE_PTR)&attr, 1);
-       if (rv != CKR_OK)
-       {
-               plog("failed to get key length: %s"
-                       , enum_show(&pkcs11_return_names, rv));
-               return FALSE;
-       }
-
-       return attr[0].ulValueLen;  /*Return key length in bytes */
-#else
-       return 0;
-#endif
-}
-
-/*
- * prompt for pin and verify it
- */
-bool scx_get_pin(smartcard_t *sc, int whackfd)
-{
-#ifdef SMARTCARD
-       char pin[BUF_LEN];
-       int i, n;
-
-       whack_log(RC_ENTERSECRET, "need PIN for #%d (%s, id: %s, label: '%s')"
-               , sc->number, scx_print_slot(sc, ""), sc->id, sc->label);
-
-       for (i = 0; i < SCX_MAX_PIN_TRIALS; i++)
-       {
-               if (i > 0)
-                       whack_log(RC_ENTERSECRET, "invalid PIN, please try again");
-
-               n = read(whackfd, pin, BUF_LEN);
-
-               if (n == -1)
-               {
-                       whack_log(RC_LOG_SERIOUS, "read(whackfd) failed");
-                       return FALSE;
-               }
-
-               if (strlen(pin) == 0)
-               {
-                       whack_log(RC_LOG_SERIOUS, "no PIN entered, aborted");
-                       return FALSE;
-               }
-
-               sc->pin.ptr = pin;
-               sc->pin.len = strlen(pin);
-
-               /* verify the pin */
-               if (scx_verify_pin(sc))
-               {
-                       sc->pin = chunk_create(pin, strlen(pin));
-                       sc->pin = chunk_clone(sc->pin);
-                       break;
-               }
-
-               /* wrong pin - we try another round */
-               sc->pin = chunk_empty;
-       }
-
-       if (sc->valid)
-               whack_log(RC_SUCCESS, "valid PIN");
-       else
-               whack_log(RC_LOG_SERIOUS, "invalid PIN, too many trials");
-#else
-       sc->valid = FALSE;
-       whack_log(RC_LOG_SERIOUS, "SMARTCARD support is deactivated in pluto/Makefile!");
-#endif
-       return sc->valid;
-}
-
-
-/*
- * free the pin code
- */
-void scx_free_pin(chunk_t *pin)
-{
-       if (pin->ptr != NULL)
-       {
-               /* clear pin field in memory */
-               memset(pin->ptr, '\0', pin->len);
-               free(pin->ptr);
-               *pin = chunk_empty;
-       }
-}
-
-/*
- * frees a smartcard record
- */
-void scx_free(smartcard_t *sc)
-{
-       if (sc != NULL)
-       {
-               scx_release_context(sc);
-               cert_release(sc->last_cert);
-               free(sc->id);
-               free(sc->label);
-               scx_free_pin(&sc->pin);
-               free(sc);
-       }
-}
-
-/*  release of a smartcard record decreases the count by one
- "  the record is freed when the counter reaches zero
- */
-void scx_release(smartcard_t *sc)
-{
-       if (sc != NULL && --sc->count == 0)
-       {
-               smartcard_t **pp = &smartcards;
-               while (*pp != sc)
-                       pp = &(*pp)->next;
-               *pp = sc->next;
-               scx_free(sc);
-       }
-}
-
-/*
- *  compare two smartcard records by comparing their slots and ids
- */
-static bool scx_same(smartcard_t *a, smartcard_t *b)
-{
-       if  (a->number && b->number)
-       {
-               /* same number */
-               return a->number == b->number;
-       }
-       else
-       {
-               /* same id and/or same slot */
-               return (!a->id || (b->id && streq(a->id, b->id)))
-                       && (a->any_slot || b->any_slot || a->slot == b->slot);
-       }
-}
-
-/*  for each link pointing to the smartcard record
- "  increase the count by one
- */
-void scx_share(smartcard_t *sc)
-{
-       if (sc != NULL)
-               sc->count++;
-}
-
-/*
- *  adds a smartcard record to the chained list
- */
-smartcard_t* scx_add(smartcard_t *smartcard)
-{
-       smartcard_t *sc = smartcards;
-       smartcard_t **psc = &smartcards;
-
-       while (sc != NULL)
-       {
-               if (scx_same(smartcard, sc)) /* already in chain, free smartcard record */
-               {
-                       scx_free(smartcard);
-                       return sc;
-               }
-               psc = &sc->next;
-               sc = sc->next;
-       }
-
-       /* insert new smartcard record at the end of the chain */
-       *psc = smartcard;
-       smartcard->number = ++sc_number;
-       smartcard->count = 1;
-       DBG(DBG_CONTROL | DBG_PARSING,
-               DBG_log("  smartcard #%d added", sc_number)
-       )
-       return smartcard;
-}
-
-/*
- * get the smartcard that belongs to an X.509 certificate
- */
-smartcard_t* scx_get(cert_t *cert)
-{
-       smartcard_t *sc = smartcards;
-
-       while (sc != NULL)
-       {
-               if (sc->last_cert == cert)
-               {
-                       return sc;
-               }
-               sc = sc->next;
-       }
-       return NULL;
-}
-
-/*
- * prints either the slot number or 'any slot'
- */
-char *scx_print_slot(smartcard_t *sc, const char *whitespace)
-{
-       char *buf = temporary_cyclic_buffer();
-
-       if (sc->any_slot)
-               snprintf(buf, BUF_LEN, "any slot");
-       else
-               snprintf(buf, BUF_LEN, "slot: %s%lu", whitespace, sc->slot);
-       return buf;
-}
-
-/*
- *  list all smartcard info records in a chained list
- */
-void scx_list(bool utc)
-{
-       smartcard_t *sc = smartcards;
-
-       if (sc != NULL)
-       {
-               whack_log(RC_COMMENT, " ");
-               whack_log(RC_COMMENT, "List of Smartcard Objects:");
-       }
-
-       while (sc != NULL)
-       {
-               whack_log(RC_COMMENT, " ");
-               whack_log(RC_COMMENT, "  %s, session %s, logged %s, has %s"
-                       , scx_print_slot(sc, "    ")
-                       , sc->session_opened? "opened" : "closed"
-                       , sc->logged_in? "in" : "out"
-                       , sc->pinpad? "pin pad"
-                               : ((sc->pin.ptr == NULL)? "no pin"
-                                       : sc->valid? "valid pin" : "invalid pin"));
-               if (sc->id != NULL)
-                       whack_log(RC_COMMENT, "  id:       %s", sc->id);
-               if (sc->label != NULL)
-                       whack_log(RC_COMMENT, "  label:   '%s'", sc->label);
-               if (sc->last_cert)
-               {
-                       certificate_t *certificate = sc->last_cert->cert;
-
-                       whack_log(RC_COMMENT, "  subject: '%Y'",
-                                         certificate->get_subject(certificate));
-               }
-               sc = sc->next;
-       }
-}
diff --git a/src/pluto/smartcard.h b/src/pluto/smartcard.h
deleted file mode 100644 (file)
index 7a22297..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/* Support of smartcards and cryptotokens
- * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
- * Copyright (C) 2004 David Buechi, Michael Meier
- * Zuercher Hochschule Winterthur
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef _SMARTCARD_H
-#define _SMARTCARD_H
-
-#include "certs.h"
-
-#define SCX_TOKEN                 "%smartcard"
-#define SCX_CERT_CACHE_INTERVAL   60 /* seconds */
-#define SCX_MAX_PIN_TRIALS        3
-
-/* smartcard operations, update copy in whack.h */
-
-#ifndef SC_OP_T
-#define SC_OP_T
-typedef enum {
-       SC_OP_NONE =    0,
-       SC_OP_ENCRYPT = 1,
-       SC_OP_DECRYPT = 2,
-       SC_OP_SIGN =    3,
-} sc_op_t;
-#endif /* SC_OP_T */
-
-/* smartcard record */
-
-typedef struct smartcard smartcard_t;
-
-struct smartcard {
-       smartcard_t  *next;
-       time_t        last_load;
-       cert_t        *last_cert;
-       int           count;
-       int           number;
-       unsigned long slot;
-       char          *id;
-       char         *label;
-       chunk_t       pin;
-       bool          pinpad;
-       bool          valid;
-       bool          session_opened;
-       bool          logged_in;
-       bool          any_slot;
-       long          session;
-};
-
-extern const smartcard_t empty_sc;
-
-/*  keep a PKCS#11 login during the lifetime of pluto
- *  flag set in plutomain.c and used in ipsec_doi.c and ocsp.c
- */
-extern bool pkcs11_keep_state;
-
-/* allow other applications access to pluto's PKCS#11 interface
- * via whack. Could be used e.g. for disk encryption
- */
-extern bool pkcs11_proxy;
-
-extern smartcard_t* scx_parse_number_slot_id(const char *number_slot_id);
-extern void scx_init(const char *module, const char *init_args);
-extern void scx_finalize(void);
-extern bool scx_establish_context(smartcard_t *sc);
-extern bool scx_login(smartcard_t *sc);
-extern bool scx_on_smartcard(const char *filename);
-extern cert_t* scx_load_cert(const char *filename, smartcard_t **scp, bool *cached);
-extern bool scx_verify_pin(smartcard_t *sc);
-extern void scx_share(smartcard_t *sc);
-extern bool scx_sign_hash(smartcard_t *sc, const u_char *in, size_t inlen
-       , u_char *out, size_t outlen);
-extern bool scx_encrypt(smartcard_t *sc, const u_char *in, size_t inlen
-       , u_char *out, size_t *outlen);
-extern bool scx_decrypt(smartcard_t *sc, const u_char *in, size_t inlen
-       , u_char *out, size_t *outlen);
-extern bool scx_op_via_whack(const char* msg, int inbase, int outbase
-       , sc_op_t op, const char *keyid, int whackfd);
-extern bool scx_get_pin(smartcard_t *sc, int whackfd);
-extern size_t scx_get_keylength(smartcard_t *sc);
-extern smartcard_t* scx_add(smartcard_t *sc);
-extern smartcard_t* scx_get(cert_t *cert);
-extern void scx_release(smartcard_t *sc);
-extern void scx_release_context(smartcard_t *sc);
-extern void scx_free_pin(chunk_t *pin);
-extern void scx_free(smartcard_t *sc);
-extern void scx_list(bool utc);
-extern char *scx_print_slot(smartcard_t *sc, const char *whitespace);
-
-#endif /* _SMARTCARD_H */
diff --git a/src/pluto/spdb.c b/src/pluto/spdb.c
deleted file mode 100644 (file)
index 06fe7d7..0000000
+++ /dev/null
@@ -1,2315 +0,0 @@
-/* Security Policy Data Base (such as it is)
- * Copyright (C) 1998-2001  D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/queue.h>
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "connections.h"
-#include "state.h"
-#include "packet.h"
-#include "keys.h"
-#include "kernel.h"
-#include "log.h"
-#include "spdb.h"
-#include "whack.h"
-#include "crypto.h"
-#include "alg_info.h"
-#include "kernel_alg.h"
-#include "ike_alg.h"
-#include "db_ops.h"
-#include "nat_traversal.h"
-
-#define AD(x) x, countof(x)     /* Array Description */
-#define AD_NULL NULL, 0
-
-/**************** Oakely (main mode) SA database ****************/
-
-/* array of proposals to be conjoined (can only be one for Oakley) */
-
-static struct db_prop oakley_pc[] =
-       { { PROTO_ISAKMP, AD_NULL } };
-
-/* array of proposal conjuncts (can only be one) */
-
-static struct db_prop_conj oakley_props[] = { { AD(oakley_pc) } };
-
-/* the sadb entry */
-struct db_sa oakley_sadb = { AD(oakley_props) };
-
-/**************** IPsec (quick mode) SA database ****************/
-
-/* arrays of attributes for transforms */
-
-static struct db_attr espsha1_attr[] = {
-       { AUTH_ALGORITHM, AUTH_ALGORITHM_HMAC_SHA1 },
-       };
-
-static struct db_attr ah_HMAC_SHA1_attr[] = {
-       { AUTH_ALGORITHM, AUTH_ALGORITHM_HMAC_SHA1 },
-       };
-
-/* arrays of transforms, each in in preference order */
-
-static struct db_trans espa_trans[] = {
-       { ESP_3DES, AD(espsha1_attr) },
-       };
-
-static struct db_trans esp_trans[] = {
-       { ESP_3DES, AD_NULL },
-       };
-
-#ifdef SUPPORT_ESP_NULL
-static struct db_trans espnull_trans[] = {
-       { ESP_NULL, AD(espsha1_attr) },
-       };
-#endif /* SUPPORT_ESP_NULL */
-
-static struct db_trans ah_trans[] = {
-       { AH_SHA, AD(ah_HMAC_SHA1_attr) },
-       };
-
-static struct db_trans ipcomp_trans[] = {
-       { IPCOMP_DEFLATE, AD_NULL },
-       };
-
-/* arrays of proposals to be conjoined */
-
-static struct db_prop ah_pc[] = {
-       { PROTO_IPSEC_AH, AD(ah_trans) },
-       };
-
-#ifdef SUPPORT_ESP_NULL
-static struct db_prop espnull_pc[] = {
-       { PROTO_IPSEC_ESP, AD(espnull_trans) },
-       };
-#endif /* SUPPORT_ESP_NULL */
-
-static struct db_prop esp_pc[] = {
-       { PROTO_IPSEC_ESP, AD(espa_trans) },
-       };
-
-static struct db_prop ah_esp_pc[] = {
-       { PROTO_IPSEC_AH, AD(ah_trans) },
-       { PROTO_IPSEC_ESP, AD(esp_trans) },
-       };
-
-static struct db_prop compress_pc[] = {
-       { PROTO_IPCOMP, AD(ipcomp_trans) },
-       };
-
-static struct db_prop ah_compress_pc[] = {
-       { PROTO_IPSEC_AH, AD(ah_trans) },
-       { PROTO_IPCOMP, AD(ipcomp_trans) },
-       };
-
-#ifdef SUPPORT_ESP_NULL
-static struct db_prop espnull_compress_pc[] = {
-       { PROTO_IPSEC_ESP, AD(espnull_trans) },
-       { PROTO_IPCOMP, AD(ipcomp_trans) },
-       };
-#endif /* SUPPORT_ESP_NULL */
-
-static struct db_prop esp_compress_pc[] = {
-       { PROTO_IPSEC_ESP, AD(espa_trans) },
-       { PROTO_IPCOMP, AD(ipcomp_trans) },
-       };
-
-static struct db_prop ah_esp_compress_pc[] = {
-       { PROTO_IPSEC_AH, AD(ah_trans) },
-       { PROTO_IPSEC_ESP, AD(esp_trans) },
-       { PROTO_IPCOMP, AD(ipcomp_trans) },
-       };
-
-/* arrays of proposal alternatives (each element is a conjunction) */
-
-static struct db_prop_conj ah_props[] = {
-       { AD(ah_pc) },
-#ifdef SUPPORT_ESP_NULL
-       { AD(espnull_pc) }
-#endif
-       };
-
-static struct db_prop_conj esp_props[] =
-       { { AD(esp_pc) } };
-
-static struct db_prop_conj ah_esp_props[] =
-       { { AD(ah_esp_pc) } };
-
-static struct db_prop_conj compress_props[] = {
-       { AD(compress_pc) },
-       };
-
-static struct db_prop_conj ah_compress_props[] = {
-       { AD(ah_compress_pc) },
-#ifdef SUPPORT_ESP_NULL
-       { AD(espnull_compress_pc) }
-#endif
-       };
-
-static struct db_prop_conj esp_compress_props[] =
-       { { AD(esp_compress_pc) } };
-
-static struct db_prop_conj ah_esp_compress_props[] =
-       { { AD(ah_esp_compress_pc) } };
-
-/* The IPsec sadb is subscripted by a bitset (subset of policy)
- * with members from { POLICY_ENCRYPT, POLICY_AUTHENTICATE, POLICY_COMPRESS }
- * shifted right by POLICY_IPSEC_SHIFT.
- */
-struct db_sa ipsec_sadb[1 << 3] = {
-       { AD_NULL },        /* none */
-       { AD(esp_props) },  /* POLICY_ENCRYPT */
-       { AD(ah_props) },   /* POLICY_AUTHENTICATE */
-       { AD(ah_esp_props) },       /* POLICY_ENCRYPT+POLICY_AUTHENTICATE */
-       { AD(compress_props) },     /* POLICY_COMPRESS */
-       { AD(esp_compress_props) }, /* POLICY_ENCRYPT+POLICY_COMPRESS */
-       { AD(ah_compress_props) },  /* POLICY_AUTHENTICATE+POLICY_COMPRESS */
-       { AD(ah_esp_compress_props) },      /* POLICY_ENCRYPT+POLICY_AUTHENTICATE+POLICY_COMPRESS */
-       };
-
-#undef AD
-#undef AD_NULL
-
-/* output an attribute (within an SA) */
-static bool
-out_attr(int type
-, unsigned long val
-, struct_desc *attr_desc
-, enum_names **attr_val_descs USED_BY_DEBUG
-, pb_stream *pbs)
-{
-       struct isakmp_attribute attr;
-
-       if (val >> 16 == 0)
-       {
-               /* short value: use TV form */
-               attr.isaat_af_type = type | ISAKMP_ATTR_AF_TV;
-               attr.isaat_lv = val;
-               if (!out_struct(&attr, attr_desc, pbs, NULL))
-                       return FALSE;
-       }
-       else
-       {
-               /* This is a real fudge!  Since we rarely use long attributes
-                * and since this is the only place where we can cause an
-                * ISAKMP message length to be other than a multiple of 4 octets,
-                * we force the length of the value to be a multiple of 4 octets.
-                * Furthermore, we only handle values up to 4 octets in length.
-                * Voila: a fixed format!
-                */
-               pb_stream val_pbs;
-               u_int32_t nval = htonl(val);
-
-               attr.isaat_af_type = type | ISAKMP_ATTR_AF_TLV;
-               if (!out_struct(&attr, attr_desc, pbs, &val_pbs)
-               || !out_raw(&nval, sizeof(nval), &val_pbs, "long attribute value"))
-                       return FALSE;
-               close_output_pbs(&val_pbs);
-       }
-       DBG(DBG_EMITTING,
-               enum_names *d = attr_val_descs[type];
-
-               if (d != NULL)
-                       DBG_log("    [%lu is %s]"
-                               , val, enum_show(d, val)));
-       return TRUE;
-}
-#define return_on(var, val) do { var=val;goto return_out; } while(0)
-/* Output an SA, as described by a db_sa.
- * This has the side-effect of allocating SPIs for us.
- */
-bool
-out_sa(pb_stream *outs
-, struct db_sa *sadb
-, struct state *st
-, bool oakley_mode
-, u_int8_t np)
-{
-       pb_stream sa_pbs;
-       int pcn;
-       bool ret = FALSE;
-       bool ah_spi_generated = FALSE
-               , esp_spi_generated = FALSE
-               , ipcomp_cpi_generated = FALSE;
-#if !defined NO_KERNEL_ALG || !defined NO_IKE_ALG
-       struct db_context *db_ctx = NULL;
-#endif
-
-       /* SA header out */
-       {
-               struct isakmp_sa sa;
-
-               sa.isasa_np = np;
-               st->st_doi = sa.isasa_doi = ISAKMP_DOI_IPSEC;   /* all we know */
-               if (!out_struct(&sa, &isakmp_sa_desc, outs, &sa_pbs))
-                       return_on(ret, FALSE);
-       }
-
-       /* within SA: situation out */
-       st->st_situation = SIT_IDENTITY_ONLY;
-       if (!out_struct(&st->st_situation, &ipsec_sit_desc, &sa_pbs, NULL))
-               return_on(ret, FALSE);
-
-       /* within SA: Proposal Payloads
-        *
-        * Multiple Proposals with the same number are simultaneous
-        * (conjuncts) and must deal with different protocols (AH or ESP).
-        * Proposals with different numbers are alternatives (disjuncts),
-        * in preference order.
-        * Proposal numbers must be monotonic.
-        * See RFC 2408 "ISAKMP" 4.2
-        */
-
-       for (pcn = 0; pcn != sadb->prop_conj_cnt; pcn++)
-       {
-               struct db_prop_conj *pc = &sadb->prop_conjs[pcn];
-               int pn;
-
-               for (pn = 0; pn != pc->prop_cnt; pn++)
-               {
-                       struct db_prop *p = &pc->props[pn];
-                       pb_stream proposal_pbs;
-                       struct isakmp_proposal proposal;
-                       struct_desc *trans_desc = NULL;
-                       struct_desc *attr_desc = NULL;
-                       enum_names **attr_val_descs = NULL;
-                       int tn;
-                       bool tunnel_mode;
-
-                       tunnel_mode = (pn == pc->prop_cnt-1)
-                               && (st->st_policy & POLICY_TUNNEL);
-
-                       /* Proposal header */
-                       proposal.isap_np = pcn == sadb->prop_conj_cnt-1 && pn == pc->prop_cnt-1
-                               ? ISAKMP_NEXT_NONE : ISAKMP_NEXT_P;
-                       proposal.isap_proposal = pcn;
-                       proposal.isap_protoid = p->protoid;
-                       proposal.isap_spisize = oakley_mode ? 0
-                               : p->protoid == PROTO_IPCOMP ? IPCOMP_CPI_SIZE
-                               : IPSEC_DOI_SPI_SIZE;
-
-                       /* In quick mode ONLY, create proposal for runtime kernel algos.
-                        *  Replace ESP proposals with runtime created one
-                        */
-                       if (!oakley_mode && p->protoid == PROTO_IPSEC_ESP)
-                       {
-                               DBG(DBG_CONTROL | DBG_CRYPT,
-                                       if (st->st_connection->alg_info_esp)
-                                       {
-                                               static char buf[BUF_LEN]="";
-
-                                               alg_info_snprint(buf, sizeof (buf),
-                                                               (struct alg_info *)st->st_connection->alg_info_esp);
-                                               DBG_log("esp proposal: %s", buf);
-                                       }
-                               )
-                               db_ctx = kernel_alg_db_new(st->st_connection->alg_info_esp, st->st_policy);
-                               p = db_prop_get(db_ctx);
-
-                               if (!p || p->trans_cnt == 0)
-                               {
-                                       loglog(RC_LOG_SERIOUS,
-                                               "empty IPSEC SA proposal to send "
-                                               "(no kernel algorithms for esp selection)");
-                                       return_on(ret, FALSE);
-                               }
-                       }
-
-                       if (oakley_mode && p->protoid == PROTO_ISAKMP)
-                       {
-                               DBG(DBG_CONTROL | DBG_CRYPT,
-                                       if (st->st_connection->alg_info_ike)
-                                       {
-                                               static char buf[BUF_LEN]="";
-
-                                               alg_info_snprint(buf, sizeof (buf),
-                                                               (struct alg_info *)st->st_connection->alg_info_ike);
-                                               DBG_log("ike proposal: %s", buf);
-                                       }
-                               )
-                               db_ctx = ike_alg_db_new(st->st_connection, st->st_policy);
-                               p = db_prop_get(db_ctx);
-
-                               if (!p || p->trans_cnt == 0)
-                               {
-                                       loglog(RC_LOG_SERIOUS,
-                                               "empty ISAKMP SA proposal to send "
-                                               "(no algorithms for ike selection?)");
-                                       return_on(ret, FALSE);
-                               }
-                       }
-
-                       proposal.isap_notrans = p->trans_cnt;
-                       if (!out_struct(&proposal, &isakmp_proposal_desc, &sa_pbs, &proposal_pbs))
-                               return_on(ret, FALSE);
-
-                       /* Per-protocols stuff:
-                        * Set trans_desc.
-                        * Set attr_desc.
-                        * Set attr_val_descs.
-                        * If not oakley_mode, emit SPI.
-                        * We allocate SPIs on demand.
-                        * All ESPs in an SA will share a single SPI.
-                        * All AHs in an SAwill share a single SPI.
-                        * AHs' SPI will be distinct from ESPs'.
-                        * This latter is needed because KLIPS doesn't
-                        * use the protocol when looking up a (dest, protocol, spi).
-                        * ??? If multiple ESPs are composed, how should their SPIs
-                        * be allocated?
-                        */
-                       {
-                               ipsec_spi_t *spi_ptr = NULL;
-                               int proto = 0;
-                               bool *spi_generated = NULL;
-
-                               switch (p->protoid)
-                               {
-                               case PROTO_ISAKMP:
-                                       passert(oakley_mode);
-                                       trans_desc = &isakmp_isakmp_transform_desc;
-                                       attr_desc = &isakmp_oakley_attribute_desc;
-                                       attr_val_descs = oakley_attr_val_descs;
-                                       /* no SPI needed */
-                                       break;
-                               case PROTO_IPSEC_AH:
-                                       passert(!oakley_mode);
-                                       trans_desc = &isakmp_ah_transform_desc;
-                                       attr_desc = &isakmp_ipsec_attribute_desc;
-                                       attr_val_descs = ipsec_attr_val_descs;
-                                       spi_ptr = &st->st_ah.our_spi;
-                                       spi_generated = &ah_spi_generated;
-                                       proto = IPPROTO_AH;
-                                       break;
-                               case PROTO_IPSEC_ESP:
-                                       passert(!oakley_mode);
-                                       trans_desc = &isakmp_esp_transform_desc;
-                                       attr_desc = &isakmp_ipsec_attribute_desc;
-                                       attr_val_descs = ipsec_attr_val_descs;
-                                       spi_ptr = &st->st_esp.our_spi;
-                                       spi_generated = &esp_spi_generated;
-                                       proto = IPPROTO_ESP;
-                                       break;
-                               case PROTO_IPCOMP:
-                                       passert(!oakley_mode);
-                                       trans_desc = &isakmp_ipcomp_transform_desc;
-                                       attr_desc = &isakmp_ipsec_attribute_desc;
-                                       attr_val_descs = ipsec_attr_val_descs;
-
-                                       /* a CPI isn't quite the same as an SPI
-                                        * so we use specialized code to emit it.
-                                        */
-                                       if (!ipcomp_cpi_generated)
-                                       {
-                                               st->st_ipcomp.our_spi = get_my_cpi(
-                                                       &st->st_connection->spd, tunnel_mode);
-                                               if (st->st_ipcomp.our_spi == 0)
-                                                       return_on(ret, FALSE);      /* problem generating CPI */
-
-                                               ipcomp_cpi_generated = TRUE;
-                                       }
-                                       /* CPI is stored in network low order end of an
-                                        * ipsec_spi_t.  So we start a couple of bytes in.
-                                        */
-                                       if (!out_raw((u_char *)&st->st_ipcomp.our_spi
-                                        + IPSEC_DOI_SPI_SIZE - IPCOMP_CPI_SIZE
-                                       , IPCOMP_CPI_SIZE
-                                       , &proposal_pbs, "CPI"))
-                                               return_on(ret, FALSE);
-                                       break;
-                               default:
-                                       bad_case(p->protoid);
-                               }
-                               if (spi_ptr != NULL)
-                               {
-                                       if (!*spi_generated)
-                                       {
-                                               *spi_ptr = get_ipsec_spi(0
-                                                       , proto
-                                                       , &st->st_connection->spd
-                                                       , tunnel_mode);
-                                               if (*spi_ptr == 0)
-                                                       return_on(ret, FALSE);
-                                               *spi_generated = TRUE;
-                                       }
-                                       if (!out_raw((u_char *)spi_ptr, IPSEC_DOI_SPI_SIZE
-                                       , &proposal_pbs, "SPI"))
-                                               return_on(ret, FALSE);
-                               }
-                       }
-
-                       /* within proposal: Transform Payloads */
-                       for (tn = 0; tn != p->trans_cnt; tn++)
-                       {
-                               struct db_trans *t = &p->trans[tn];
-                               pb_stream trans_pbs;
-                               struct isakmp_transform trans;
-                               int an;
-
-                               trans.isat_np = (tn == p->trans_cnt - 1)
-                                       ? ISAKMP_NEXT_NONE : ISAKMP_NEXT_T;
-                               trans.isat_transnum = tn;
-                               trans.isat_transid = t->transid;
-                               if (!out_struct(&trans, trans_desc, &proposal_pbs, &trans_pbs))
-                                       return_on(ret, FALSE);
-
-                               /* Within transform: Attributes. */
-
-                               /* For Phase 2 / Quick Mode, GROUP_DESCRIPTION is
-                                * automatically generated because it must be the same
-                                * in every transform.  Except IPCOMP.
-                                */
-                               if (p->protoid != PROTO_IPCOMP && st->st_pfs_group != NULL)
-                               {
-                                       passert(!oakley_mode);
-                                       passert(st->st_pfs_group != &unset_group);
-                                       out_attr(GROUP_DESCRIPTION, st->st_pfs_group->algo_id
-                                               , attr_desc, attr_val_descs
-                                               , &trans_pbs);
-                               }
-
-                               /* automatically generate duration
-                                * and, for Phase 2 / Quick Mode, encapsulation.
-                                */
-                               if (oakley_mode)
-                               {
-                                       out_attr(OAKLEY_LIFE_TYPE, OAKLEY_LIFE_SECONDS
-                                               , attr_desc, attr_val_descs
-                                               , &trans_pbs);
-                                       out_attr(OAKLEY_LIFE_DURATION
-                                               , st->st_connection->sa_ike_life_seconds
-                                               , attr_desc, attr_val_descs
-                                               , &trans_pbs);
-                               }
-                               else
-                               {
-                                       /* RFC 2407 (IPSEC DOI) 4.5 specifies that
-                                        * the default is "unspecified (host-dependent)".
-                                        * This makes little sense, so we always specify it.
-                                        *
-                                        * Unlike other IPSEC transforms, IPCOMP defaults
-                                        * to Transport Mode, so we can exploit the default
-                                        * (draft-shacham-ippcp-rfc2393bis-05.txt 4.1).
-                                        */
-                                       if (p->protoid != PROTO_IPCOMP
-                                       || st->st_policy & POLICY_TUNNEL)
-                                       {
-#ifndef I_KNOW_TRANSPORT_MODE_HAS_SECURITY_CONCERN_BUT_I_WANT_IT
-                                               if ((st->nat_traversal & NAT_T_DETECTED)
-                                               && !(st->st_policy & POLICY_TUNNEL))
-                                               {
-                                                       /* Inform user that we will not respect policy and only
-                                                        * propose Tunnel Mode
-                                                        */
-                                                       loglog(RC_LOG_SERIOUS, "NAT-Traversal: "
-                                                               "Transport Mode not allowed due to security concerns -- "
-                                                               "using Tunnel mode");
-                                               }
-#endif
-                                               out_attr(ENCAPSULATION_MODE
-#ifdef I_KNOW_TRANSPORT_MODE_HAS_SECURITY_CONCERN_BUT_I_WANT_IT
-                                                       , NAT_T_ENCAPSULATION_MODE(st, st->st_policy)
-#else
-                                                               /* If NAT-T is detected, use UDP_TUNNEL as long as Transport
-                                                                * Mode has security concerns.
-                                                                *
-                                                                * User has been informed of that
-                                                                */
-                                                       , NAT_T_ENCAPSULATION_MODE(st, POLICY_TUNNEL)
-#endif
-                                                       , attr_desc, attr_val_descs
-                                                       , &trans_pbs);
-                                       }
-                                       out_attr(SA_LIFE_TYPE, SA_LIFE_TYPE_SECONDS
-                                               , attr_desc, attr_val_descs
-                                               , &trans_pbs);
-                                       out_attr(SA_LIFE_DURATION
-                                               , st->st_connection->sa_ipsec_life_seconds
-                                               , attr_desc, attr_val_descs
-                                               , &trans_pbs);
-                               }
-
-                               /* spit out attributes from table */
-                               for (an = 0; an != t->attr_cnt; an++)
-                               {
-                                       struct db_attr *a = &t->attrs[an];
-
-                                       out_attr(a->type, a->val
-                                               , attr_desc, attr_val_descs
-                                               , &trans_pbs);
-                               }
-
-                               close_output_pbs(&trans_pbs);
-                       }
-                       close_output_pbs(&proposal_pbs);
-               }
-               /* end of a conjunction of proposals */
-       }
-       close_output_pbs(&sa_pbs);
-       ret = TRUE;
-
-return_out:
-
-#if !defined NO_KERNEL_ALG || !defined NO_IKE_ALG
-       if (db_ctx)
-                       db_destroy(db_ctx);
-#endif
-       return ret;
-}
-
-/* Handle long form of duration attribute.
- * The code is can only handle values that can fit in unsigned long.
- * "Clamping" is probably an acceptable way to impose this limitation.
- */
-static u_int32_t decode_long_duration(pb_stream *pbs)
-{
-       u_int32_t val = 0;
-
-       /* ignore leading zeros */
-       while (pbs_left(pbs) != 0 && *pbs->cur == '\0')
-               pbs->cur++;
-
-       if (pbs_left(pbs) > sizeof(val))
-       {
-               /* "clamp" too large value to max representable value */
-               val = UINT32_MAX;
-               DBG(DBG_PARSING, DBG_log("   too large duration clamped to: %lu"
-                       , (unsigned long)val));
-       }
-       else
-       {
-               /* decode number */
-               while (pbs_left(pbs) != 0)
-                       val = (val << BITS_PER_BYTE) | *pbs->cur++;
-               DBG(DBG_PARSING, DBG_log("   long duration: %lu", (unsigned long)val));
-       }
-       return val;
-}
-
-/* Preparse the body of an ISAKMP SA Payload and
- * return body of ISAKMP Proposal Payload
- *
- * Only IPsec DOI is accepted (what is the ISAKMP DOI?).
- * Error response is rudimentary.
- */
-notification_t
-preparse_isakmp_sa_body(const struct isakmp_sa *sa
-                                         , pb_stream *sa_pbs
-                                         , u_int32_t *ipsecdoisit
-                                         , pb_stream *proposal_pbs
-                                         , struct isakmp_proposal *proposal)
-{
-       /* DOI */
-       if (sa->isasa_doi != ISAKMP_DOI_IPSEC)
-       {
-               loglog(RC_LOG_SERIOUS, "Unknown/unsupported DOI %s", enum_show(&doi_names, sa->isasa_doi));
-               /* XXX Could send notification back */
-               return ISAKMP_DOI_NOT_SUPPORTED;
-       }
-
-       /* Situation */
-       if (!in_struct(ipsecdoisit, &ipsec_sit_desc, sa_pbs, NULL))
-       {
-               return ISAKMP_SITUATION_NOT_SUPPORTED;
-       }
-       if (*ipsecdoisit != SIT_IDENTITY_ONLY)
-       {
-               loglog(RC_LOG_SERIOUS, "unsupported IPsec DOI situation (%s)"
-                       , bitnamesof(sit_bit_names, *ipsecdoisit));
-               /* XXX Could send notification back */
-               return ISAKMP_SITUATION_NOT_SUPPORTED;
-       }
-
-       /* The rules for ISAKMP SAs are scattered.
-        * RFC 2409 "IKE" section 5 says that there
-        * can only be one SA, and it can have only one proposal in it.
-        * There may well be multiple transforms.
-        */
-       if (!in_struct(proposal, &isakmp_proposal_desc, sa_pbs, proposal_pbs))
-       {
-               return ISAKMP_PAYLOAD_MALFORMED;
-       }
-       if (proposal->isap_np != ISAKMP_NEXT_NONE)
-       {
-               loglog(RC_LOG_SERIOUS, "Proposal Payload must be alone in Oakley SA; found %s following Proposal"
-                       , enum_show(&payload_names, proposal->isap_np));
-               return ISAKMP_PAYLOAD_MALFORMED;
-       }
-
-       if (proposal->isap_protoid != PROTO_ISAKMP)
-       {
-               loglog(RC_LOG_SERIOUS, "unexpected Protocol ID (%s) found in Oakley Proposal"
-                       , enum_show(&protocol_names, proposal->isap_protoid));
-               return ISAKMP_INVALID_PROTOCOL_ID;
-       }
-
-       /* Just what should we accept for the SPI field?
-        * The RFC is sort of contradictory.  We will ignore the SPI
-        * as long as it is of the proper size.
-        *
-        * From RFC2408 2.4 Identifying Security Associations:
-        *   During phase 1 negotiations, the initiator and responder cookies
-        *   determine the ISAKMP SA. Therefore, the SPI field in the Proposal
-        *   payload is redundant and MAY be set to 0 or it MAY contain the
-        *   transmitting entity's cookie.
-        *
-        * From RFC2408 3.5 Proposal Payload:
-        *    o  SPI Size (1 octet) - Length in octets of the SPI as defined by
-        *       the Protocol-Id.  In the case of ISAKMP, the Initiator and
-        *       Responder cookie pair from the ISAKMP Header is the ISAKMP SPI,
-        *       therefore, the SPI Size is irrelevant and MAY be from zero (0) to
-        *       sixteen (16).  If the SPI Size is non-zero, the content of the
-        *       SPI field MUST be ignored.  If the SPI Size is not a multiple of
-        *       4 octets it will have some impact on the SPI field and the
-        *       alignment of all payloads in the message.  The Domain of
-        *       Interpretation (DOI) will dictate the SPI Size for other
-        *       protocols.
-        */
-       if (proposal->isap_spisize == 0)
-       {
-               /* empty (0) SPI -- fine */
-       }
-       else if (proposal->isap_spisize <= MAX_ISAKMP_SPI_SIZE)
-       {
-               u_char junk_spi[MAX_ISAKMP_SPI_SIZE];
-
-               if (!in_raw(junk_spi, proposal->isap_spisize, proposal_pbs, "Oakley SPI"))
-                       return ISAKMP_PAYLOAD_MALFORMED;
-       }
-       else
-       {
-               loglog(RC_LOG_SERIOUS, "invalid SPI size (%u) in Oakley Proposal"
-                       , (unsigned)proposal->isap_spisize);
-               return ISAKMP_INVALID_SPI;
-       }
-       return ISAKMP_NOTHING_WRONG;
-}
-
-static struct {
-       u_int8_t *start;
-       u_int8_t *cur;
-       u_int8_t *roof;
-} backup;
-
-/**
- * Backup the pointer into a pb_stream
- */
-void backup_pbs(pb_stream *pbs)
-{
-       backup.start = pbs->start;
-       backup.cur   = pbs->cur;
-       backup.roof  = pbs->roof;
-}
-
-/**
- * Restore the pointer into a pb_stream
- */
-void restore_pbs(pb_stream *pbs)
-{
-       pbs->start = backup.start;
-       pbs->cur   = backup.cur;
-       pbs->roof  = backup.roof;
-}
-
-/**
- * Parse an ISAKMP Proposal Payload for RSA and PSK authentication policies
- */
-notification_t parse_isakmp_policy(pb_stream *proposal_pbs, u_int notrans,
-                                                                  lset_t *policy)
-{
-       int last_transnum = -1;
-
-       *policy = LEMPTY;
-
-       while (notrans--)
-       {
-               pb_stream trans_pbs;
-               u_char *attr_start;
-               size_t attr_len;
-               struct isakmp_transform trans;
-
-               if (!in_struct(&trans, &isakmp_isakmp_transform_desc, proposal_pbs, &trans_pbs))
-               {
-                       return ISAKMP_BAD_PROPOSAL_SYNTAX;
-               }
-               if (trans.isat_transnum <= last_transnum)
-               {
-                       /* picky, picky, picky */
-                       loglog(RC_LOG_SERIOUS, "Transform Numbers are not monotonically increasing"
-                               " in Oakley Proposal");
-                       return ISAKMP_BAD_PROPOSAL_SYNTAX;
-               }
-               last_transnum = trans.isat_transnum;
-
-               if (trans.isat_transid != KEY_IKE)
-               {
-                       loglog(RC_LOG_SERIOUS, "expected KEY_IKE but found %s in Oakley Transform"
-                               , enum_show(&isakmp_transformid_names, trans.isat_transid));
-                       return ISAKMP_INVALID_TRANSFORM_ID;
-               }
-
-               attr_start = trans_pbs.cur;
-               attr_len = pbs_left(&trans_pbs);
-
-               /* preprocess authentication attributes only */
-               while (pbs_left(&trans_pbs) != 0)
-               {
-                       struct isakmp_attribute a;
-                       pb_stream attr_pbs;
-
-                       if (!in_struct(&a, &isakmp_oakley_attribute_desc, &trans_pbs, &attr_pbs))
-                       {
-                               return ISAKMP_BAD_PROPOSAL_SYNTAX;
-                       }
-                       passert((a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK) < 32);
-
-                       switch (a.isaat_af_type)
-                       {
-                       case OAKLEY_AUTHENTICATION_METHOD | ISAKMP_ATTR_AF_TV:
-                               switch (a.isaat_lv)
-                               {
-                               case OAKLEY_PRESHARED_KEY:
-                                       *policy |= POLICY_PSK;
-                                       break;
-                               case OAKLEY_RSA_SIG:
-                               case OAKLEY_ECDSA_256:
-                               case OAKLEY_ECDSA_384:
-                               case OAKLEY_ECDSA_521:
-                                       *policy |= POLICY_PUBKEY;
-                                       break;
-                               case XAUTHInitPreShared:
-                                       *policy |= POLICY_XAUTH_SERVER;
-                                       /* fall through */
-                               case XAUTHRespPreShared:
-                                       *policy |= POLICY_XAUTH_PSK;
-                                       break;
-                               case XAUTHInitRSA:
-                                       *policy |= POLICY_XAUTH_SERVER;
-                                       /* fall through */
-                               case XAUTHRespRSA:
-                                       *policy |= POLICY_XAUTH_RSASIG;
-                                       break;
-                               default:
-                                       break;
-                               }
-                               break;
-                       default:
-                               break;
-                       }
-               }
-       }
-       DBG(DBG_CONTROL|DBG_PARSING,
-               DBG_log("preparse_isakmp_policy: peer requests %s authentication"
-                               , prettypolicy(*policy))
-       )
-       return ISAKMP_NOTHING_WRONG;
-}
-
-/**
- * Check that we can find a preshared secret
- */
-static err_t find_preshared_key(struct state* st)
-{
-       err_t ugh = NULL;
-       connection_t *c = st->st_connection;
-
-       if (get_preshared_secret(c) == NULL)
-       {
-               char his_id[BUF_LEN];
-
-               if (his_id_was_instantiated(c))
-               {
-                       strcpy(his_id, "%any");
-               }
-               else
-               {
-                       snprintf(his_id, sizeof(his_id), "%Y", c->spd.that.id);
-               }
-               ugh = builddiag("Can't authenticate: no preshared key found "
-                                               "for '%Y' and '%s'", c->spd.this.id, his_id);
-       }
-       return ugh;
-}
-
-/* Parse the body of an ISAKMP SA Payload (i.e. Phase 1 / Main Mode).
- * Various shortcuts are taken.  In particular, the policy, such as
- * it is, is hardwired.
- *
- * If r_sa is non-NULL, the body of an SA representing the selected
- * proposal is emitted.
- *
- * This routine is used by main_inI1_outR1() and main_inR1_outI2().
- */
-notification_t parse_isakmp_sa_body(u_int32_t ipsecdoisit,
-                                                                       pb_stream *proposal_pbs,
-                                                                       struct isakmp_proposal *proposal,
-                                                                       pb_stream *r_sa_pbs,
-                                                                       struct state *st,
-                                                                       bool initiator)
-{
-       connection_t *c = st->st_connection;
-       unsigned no_trans_left;
-
-       /* for each transform payload... */
-       no_trans_left = proposal->isap_notrans;
-
-       for (;;)
-       {
-               pb_stream trans_pbs;
-               u_char *attr_start;
-               size_t attr_len;
-               struct isakmp_transform trans;
-               lset_t seen_attrs = 0;
-               lset_t seen_durations = 0;
-               u_int16_t life_type = 0;
-               struct oakley_trans_attrs ta = { .encrypter = NULL };
-               err_t ugh = NULL;       /* set to diagnostic when problem detected */
-
-               /* initialize only optional field in ta */
-               ta.life_seconds = OAKLEY_ISAKMP_SA_LIFETIME_DEFAULT;    /* When this SA expires (seconds) */
-
-               if (no_trans_left == 0)
-               {
-                       loglog(RC_LOG_SERIOUS, "number of Transform Payloads disagrees with Oakley Proposal Payload");
-                       return ISAKMP_BAD_PROPOSAL_SYNTAX;
-               }
-
-               in_struct(&trans, &isakmp_isakmp_transform_desc, proposal_pbs, &trans_pbs);
-               attr_start = trans_pbs.cur;
-               attr_len = pbs_left(&trans_pbs);
-
-               /* process all the attributes that make up the transform */
-
-               while (pbs_left(&trans_pbs) != 0)
-               {
-                       struct isakmp_attribute a;
-                       pb_stream attr_pbs;
-                       u_int32_t val;      /* room for larger values */
-
-                       if (!in_struct(&a, &isakmp_oakley_attribute_desc, &trans_pbs, &attr_pbs))
-                               return ISAKMP_BAD_PROPOSAL_SYNTAX;
-
-                       passert((a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK) < 32);
-
-                       if (LHAS(seen_attrs, a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK))
-                       {
-                               loglog(RC_LOG_SERIOUS, "repeated %s attribute in Oakley Transform %u"
-                                       , enum_show(&oakley_attr_names, a.isaat_af_type)
-                                       , trans.isat_transnum);
-                               return ISAKMP_BAD_PROPOSAL_SYNTAX;
-                       }
-
-                       seen_attrs |= LELEM(a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK);
-
-                       val = a.isaat_lv;
-
-                       DBG(DBG_PARSING,
-                       {
-                               enum_names *vdesc = oakley_attr_val_descs
-                                       [a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK];
-
-                               if (vdesc != NULL)
-                               {
-                                       const char *nm = enum_name(vdesc, val);
-
-                                       if (nm != NULL)
-                                               DBG_log("   [%u is %s]", (unsigned)val, nm);
-                               }
-                       });
-
-                       switch (a.isaat_af_type)
-                       {
-                       case OAKLEY_ENCRYPTION_ALGORITHM | ISAKMP_ATTR_AF_TV:
-                               if (ike_alg_get_crypter(val))
-                               {
-                                       ta.encrypt = val;
-                                       ta.encrypter = ike_alg_get_crypter(val);
-                                       ta.enckeylen = ta.encrypter->keydeflen;
-                               }
-                               else
-                               {
-                                       ugh = builddiag("%s is not supported"
-                                                       , enum_show(&oakley_enc_names, val));
-                               }
-                               break;
-
-                       case OAKLEY_HASH_ALGORITHM | ISAKMP_ATTR_AF_TV:
-                               if (ike_alg_get_hasher(val))
-                               {
-                                       ta.hash = val;
-                                       ta.hasher = ike_alg_get_hasher(val);
-                               }
-                               else
-                               {
-                                       ugh = builddiag("%s is not supported"
-                                                       , enum_show(&oakley_hash_names, val));
-                               }
-                               break;
-
-                       case OAKLEY_AUTHENTICATION_METHOD | ISAKMP_ATTR_AF_TV:
-                               {
-                                       /* check that authentication method is acceptable */
-                                       lset_t iap = st->st_policy & POLICY_ID_AUTH_MASK;
-
-                                       /* is the initiator the XAUTH client? */
-                                       bool xauth_init = ( initiator && (st->st_policy & POLICY_XAUTH_SERVER) == LEMPTY)
-                                                                  || (!initiator && (st->st_policy & POLICY_XAUTH_SERVER) != LEMPTY);
-
-                                       switch (val)
-                                       {
-                                       case OAKLEY_PRESHARED_KEY:
-                                               if ((iap & POLICY_PSK) == LEMPTY)
-                                               {
-                                                       ugh = "policy does not allow pre-shared key authentication";
-                                               }
-                                               else
-                                               {
-                                                       ugh = find_preshared_key(st);
-                                                       ta.auth = OAKLEY_PRESHARED_KEY;
-                                               }
-                                               break;
-                                       case XAUTHInitPreShared:
-                                               if ((iap & POLICY_XAUTH_PSK) == LEMPTY || !xauth_init)
-                                               {
-                                                       ugh = "policy does not allow XAUTHInitPreShared authentication";
-                                               }
-                                               else
-                                               {
-                                                       ugh = find_preshared_key(st);
-                                                       ta.auth = XAUTHInitPreShared;
-                                               }
-                                               break;
-                                       case XAUTHRespPreShared:
-                                               if ((iap & POLICY_XAUTH_PSK) == LEMPTY || xauth_init)
-                                               {
-                                                       ugh = "policy does not allow XAUTHRespPreShared authentication";
-                                               }
-                                               else
-                                               {
-                                                       ugh = find_preshared_key(st);
-                                                       ta.auth = XAUTHRespPreShared;
-                                               }
-                                               break;
-                                       case OAKLEY_RSA_SIG:
-                                       case OAKLEY_ECDSA_256:
-                                       case OAKLEY_ECDSA_384:
-                                       case OAKLEY_ECDSA_521:
-                                               if ((iap & POLICY_PUBKEY) == LEMPTY)
-                                               {
-                                                       ugh = "policy does not allow public key authentication";
-                                               }
-                                               else
-                                               {
-                                                       ta.auth = val;
-                                               }
-                                               break;
-                                       case XAUTHInitRSA:
-                                               if ((iap & POLICY_XAUTH_RSASIG) == LEMPTY || !xauth_init)
-                                               {
-                                                       ugh = "policy does not allow XAUTHInitRSA authentication";
-                                               }
-                                               else
-                                               {
-                                                       ta.auth = XAUTHInitRSA;
-                                               }
-                                               break;
-                                       case XAUTHRespRSA:
-                                               if ((iap & POLICY_XAUTH_RSASIG) == LEMPTY || xauth_init)
-                                               {
-                                                       ugh = "policy does not allow XAUTHRespRSA authentication";
-                                               }
-                                               else
-                                               {
-                                                       ta.auth = XAUTHRespRSA;
-                                               }
-                                               break;
-                                       default:
-                                               ugh = builddiag("Pluto does not support %s authentication"
-                                                       , enum_show(&oakley_auth_names, val));
-                                               break;
-                                       }
-                               }
-                               break;
-
-                       case OAKLEY_GROUP_DESCRIPTION | ISAKMP_ATTR_AF_TV:
-                               ta.group = ike_alg_get_dh_group(val);
-                               if (ta.group == NULL)
-                               {
-                                       ugh = builddiag("%s is not supported"
-                                                       , enum_show(&oakley_group_names, val));
-                               }
-                               break;
-
-                       case OAKLEY_LIFE_TYPE | ISAKMP_ATTR_AF_TV:
-                               switch (val)
-                               {
-                               case OAKLEY_LIFE_SECONDS:
-                               case OAKLEY_LIFE_KILOBYTES:
-                                       if (LHAS(seen_durations, val))
-                                       {
-                                               loglog(RC_LOG_SERIOUS
-                                                               , "attribute OAKLEY_LIFE_TYPE value %s repeated"
-                                                               , enum_show(&oakley_lifetime_names, val));
-                                               return ISAKMP_BAD_PROPOSAL_SYNTAX;
-                                       }
-                                       seen_durations |= LELEM(val);
-                                       life_type = val;
-                                       break;
-                               default:
-                                       ugh = builddiag("unknown value %s"
-                                                       , enum_show(&oakley_lifetime_names, val));
-                                       break;
-                               }
-                               break;
-
-                       case OAKLEY_LIFE_DURATION | ISAKMP_ATTR_AF_TLV:
-                               val = decode_long_duration(&attr_pbs);
-                               /* fall through */
-                       case OAKLEY_LIFE_DURATION | ISAKMP_ATTR_AF_TV:
-                               if (!LHAS(seen_attrs, OAKLEY_LIFE_TYPE))
-                               {
-                                       ugh = "OAKLEY_LIFE_DURATION attribute not preceded by OAKLEY_LIFE_TYPE attribute";
-                                       break;
-                               }
-                               seen_attrs &= ~(LELEM(OAKLEY_LIFE_DURATION) | LELEM(OAKLEY_LIFE_TYPE));
-
-                               switch (life_type)
-                               {
-                               case OAKLEY_LIFE_SECONDS:
-                                       if (val > OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM)
-                                       {
-#ifdef CISCO_QUIRKS
-                                               plog("peer requested %lu seconds"
-                                                                               " which exceeds our limit %d seconds"
-                                                                               , (long) val
-                                                                               , OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM);
-                                               plog("lifetime reduced to %d seconds "
-                                                                               "(todo: IPSEC_RESPONDER_LIFETIME notification)"
-                                                                               , OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM);
-                                               val = OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM;
-#else
-                                               ugh = builddiag("peer requested %lu seconds"
-                                                                               " which exceeds our limit %d seconds"
-                                                                               , (long) val
-                                                                               , OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM);
-#endif
-                                       }
-                                       ta.life_seconds = val;
-                                       break;
-                               case OAKLEY_LIFE_KILOBYTES:
-                                       ta.life_kilobytes = val;
-                                       break;
-                               default:
-                                       bad_case(life_type);
-                               }
-                               break;
-
-                       case OAKLEY_KEY_LENGTH | ISAKMP_ATTR_AF_TV:
-                               if ((seen_attrs & LELEM(OAKLEY_ENCRYPTION_ALGORITHM)) == 0)
-                               {
-                                       ugh = "OAKLEY_KEY_LENGTH attribute not preceded by "
-                                                 "OAKLEY_ENCRYPTION_ALGORITHM attribute";
-                                       break;
-                               }
-                               if (ta.encrypter == NULL)
-                               {
-                                       ugh = "NULL encrypter with seen OAKLEY_ENCRYPTION_ALGORITHM";
-                                       break;
-                               }
-                               /*
-                                * check if this keylen is compatible with specified algorithm
-                                */
-                               if (val
-                               && (val < ta.encrypter->keyminlen || val > ta.encrypter->keymaxlen))
-                               {
-                                       ugh = "peer proposed key length not valid for "
-                                                 "encryption algorithm specified";
-                               }
-                               ta.enckeylen = val;
-                               break;
-#if 0 /* not yet supported */
-                       case OAKLEY_GROUP_TYPE | ISAKMP_ATTR_AF_TV:
-                       case OAKLEY_PRF | ISAKMP_ATTR_AF_TV:
-                       case OAKLEY_FIELD_SIZE | ISAKMP_ATTR_AF_TV:
-
-                       case OAKLEY_GROUP_PRIME | ISAKMP_ATTR_AF_TV:
-                       case OAKLEY_GROUP_PRIME | ISAKMP_ATTR_AF_TLV:
-                       case OAKLEY_GROUP_GENERATOR_ONE | ISAKMP_ATTR_AF_TV:
-                       case OAKLEY_GROUP_GENERATOR_ONE | ISAKMP_ATTR_AF_TLV:
-                       case OAKLEY_GROUP_GENERATOR_TWO | ISAKMP_ATTR_AF_TV:
-                       case OAKLEY_GROUP_GENERATOR_TWO | ISAKMP_ATTR_AF_TLV:
-                       case OAKLEY_GROUP_CURVE_A | ISAKMP_ATTR_AF_TV:
-                       case OAKLEY_GROUP_CURVE_A | ISAKMP_ATTR_AF_TLV:
-                       case OAKLEY_GROUP_CURVE_B | ISAKMP_ATTR_AF_TV:
-                       case OAKLEY_GROUP_CURVE_B | ISAKMP_ATTR_AF_TLV:
-                       case OAKLEY_GROUP_ORDER | ISAKMP_ATTR_AF_TV:
-                       case OAKLEY_GROUP_ORDER | ISAKMP_ATTR_AF_TLV:
-#endif
-                       default:
-                               /* fix compiler warning */
-                               memset(&ta, 0, sizeof(ta));
-                               ugh = "unsupported OAKLEY attribute";
-                               break;
-                       }
-
-                       if (ugh != NULL)
-                       {
-                               loglog(RC_LOG_SERIOUS, "%s.  Attribute %s"
-                                       , ugh, enum_show(&oakley_attr_names, a.isaat_af_type));
-                               break;
-                       }
-               }
-
-               /*
-                * ML: at last check for allowed transforms in alg_info_ike
-                *     (ALG_INFO_F_STRICT flag)
-                */
-               if (ugh == NULL)
-               {
-                       if (!ike_alg_ok_final(ta.encrypt, ta.enckeylen, ta.hash,
-                               ta.group ? ta.group->algo_id : -1, c->alg_info_ike))
-                       {
-                               ugh = "OAKLEY proposal refused";
-                       }
-               }
-
-               if (ugh == NULL)
-               {
-                       /* a little more checking is in order */
-                       {
-                               lset_t missing
-                                       = ~seen_attrs
-                                       & (LELEM(OAKLEY_ENCRYPTION_ALGORITHM)
-                                         | LELEM(OAKLEY_HASH_ALGORITHM)
-                                         | LELEM(OAKLEY_AUTHENTICATION_METHOD)
-                                         | LELEM(OAKLEY_GROUP_DESCRIPTION));
-
-                               if (missing)
-                               {
-                                       loglog(RC_LOG_SERIOUS, "missing mandatory attribute(s) %s in Oakley Transform %u"
-                                               , bitnamesof(oakley_attr_bit_names, missing)
-                                               , trans.isat_transnum);
-                                       return ISAKMP_BAD_PROPOSAL_SYNTAX;
-                               }
-                       }
-                       /* We must have liked this transform.
-                        * Lets finish early and leave.
-                        */
-
-                       DBG(DBG_PARSING | DBG_CRYPT
-                               , DBG_log("Oakley Transform %u accepted", trans.isat_transnum));
-
-                       if (r_sa_pbs != NULL)
-                       {
-                               struct isakmp_proposal r_proposal = *proposal;
-                               pb_stream r_proposal_pbs;
-                               struct isakmp_transform r_trans = trans;
-                               pb_stream r_trans_pbs;
-
-                               /* Situation */
-                               if (!out_struct(&ipsecdoisit, &ipsec_sit_desc, r_sa_pbs, NULL))
-                                       impossible();
-
-                               /* Proposal */
-#ifdef EMIT_ISAKMP_SPI
-                               r_proposal.isap_spisize = COOKIE_SIZE;
-#else
-                               r_proposal.isap_spisize = 0;
-#endif
-                               r_proposal.isap_notrans = 1;
-                               if (!out_struct(&r_proposal, &isakmp_proposal_desc, r_sa_pbs, &r_proposal_pbs))
-                                       impossible();
-
-                               /* SPI */
-#ifdef EMIT_ISAKMP_SPI
-                               if (!out_raw(my_cookie, COOKIE_SIZE, &r_proposal_pbs, "SPI"))
-                                       impossible();
-                               r_proposal.isap_spisize = COOKIE_SIZE;
-#else
-                               /* none (0) */
-#endif
-
-                               /* Transform */
-                               r_trans.isat_np = ISAKMP_NEXT_NONE;
-                               if (!out_struct(&r_trans, &isakmp_isakmp_transform_desc, &r_proposal_pbs, &r_trans_pbs))
-                                       impossible();
-
-                               if (!out_raw(attr_start, attr_len, &r_trans_pbs, "attributes"))
-                                       impossible();
-                               close_output_pbs(&r_trans_pbs);
-                               close_output_pbs(&r_proposal_pbs);
-                               close_output_pbs(r_sa_pbs);
-                       }
-
-                       /* copy over the results */
-                       st->st_oakley = ta;
-                       return ISAKMP_NOTHING_WRONG;
-               }
-
-               /* on to next transform */
-               no_trans_left--;
-
-               if (trans.isat_np == ISAKMP_NEXT_NONE)
-               {
-                       if (no_trans_left != 0)
-                       {
-                               loglog(RC_LOG_SERIOUS, "number of Transform Payloads disagrees with Oakley Proposal Payload");
-                               return ISAKMP_BAD_PROPOSAL_SYNTAX;
-                       }
-                       break;
-               }
-               if (trans.isat_np != ISAKMP_NEXT_T)
-               {
-                       loglog(RC_LOG_SERIOUS, "unexpected %s payload in Oakley Proposal"
-                               , enum_show(&payload_names, proposal->isap_np));
-                       return ISAKMP_BAD_PROPOSAL_SYNTAX;
-               }
-       }
-       loglog(RC_LOG_SERIOUS, "no acceptable Oakley Transform");
-       return ISAKMP_NO_PROPOSAL_CHOSEN;
-}
-
-/* Parse the body of an IPsec SA Payload (i.e. Phase 2 / Quick Mode).
- *
- * The main routine is parse_ipsec_sa_body; other functions defined
- * between here and there are just helpers.
- *
- * Various shortcuts are taken.  In particular, the policy, such as
- * it is, is hardwired.
- *
- * If r_sa is non-NULL, the body of an SA representing the selected
- * proposal is emitted into it.
- *
- * If "selection" is true, the SA is supposed to represent the
- * single transform that the peer has accepted.
- * ??? We only check that it is acceptable, not that it is one that we offered!
- *
- * Only IPsec DOI is accepted (what is the ISAKMP DOI?).
- * Error response is rudimentary.
- *
- * Since all ISAKMP groups in all SA Payloads must match, st->st_pfs_group
- * holds this across multiple payloads.
- * &unset_group signifies not yet "set"; NULL signifies NONE.
- *
- * This routine is used by quick_inI1_outR1() and quick_inR1_outI2().
- */
-
-static const struct ipsec_trans_attrs null_ipsec_trans_attrs = {
-       0,                                  /* transid (NULL, for now) */
-       0,                                  /* spi */
-       SA_LIFE_DURATION_DEFAULT,           /* life_seconds */
-       SA_LIFE_DURATION_K_DEFAULT,         /* life_kilobytes */
-       ENCAPSULATION_MODE_UNSPECIFIED,     /* encapsulation */
-       AUTH_ALGORITHM_NONE,                /* auth */
-       0,                                  /* key_len */
-       0,                                  /* key_rounds */
-};
-
-static bool parse_ipsec_transform(struct isakmp_transform *trans,
-                                                                 struct ipsec_trans_attrs *attrs,
-                                                                 pb_stream *prop_pbs,
-                                                                 pb_stream *trans_pbs,
-                                                                 struct_desc *trans_desc,
-                                                                 int previous_transnum, /* or -1 if none */
-                                                                 bool selection, bool is_last, bool is_ipcomp,
-                                                                 struct state *st)  /* current state object */
-{
-       lset_t seen_attrs = 0;
-       lset_t seen_durations = 0;
-       u_int16_t life_type = 0;
-       const struct dh_desc *pfs_group = NULL;
-
-       if (!in_struct(trans, trans_desc, prop_pbs, trans_pbs))
-       {
-               return FALSE;
-       }
-       if (trans->isat_transnum <= previous_transnum)
-       {
-               loglog(RC_LOG_SERIOUS, "Transform Numbers in Proposal are not monotonically increasing");
-               return FALSE;
-       }
-
-       switch (trans->isat_np)
-       {
-               case ISAKMP_NEXT_T:
-                       if (is_last)
-                       {
-                               loglog(RC_LOG_SERIOUS, "Proposal Payload has more Transforms than specified");
-                               return FALSE;
-                       }
-                       break;
-               case ISAKMP_NEXT_NONE:
-                       if (!is_last)
-                       {
-                               loglog(RC_LOG_SERIOUS, "Proposal Payload has fewer Transforms than specified");
-                               return FALSE;
-                       }
-                       break;
-               default:
-                       loglog(RC_LOG_SERIOUS, "expecting Transform Payload, but found %s in Proposal"
-                               , enum_show(&payload_names, trans->isat_np));
-                       return FALSE;
-       }
-
-       *attrs = null_ipsec_trans_attrs;
-       attrs->transid = trans->isat_transid;
-
-       while (pbs_left(trans_pbs) != 0)
-       {
-               struct isakmp_attribute a;
-               pb_stream attr_pbs;
-               enum_names *vdesc;
-               u_int32_t val;  /* room for larger value */
-               bool ipcomp_inappropriate = is_ipcomp;  /* will get reset if OK */
-
-               if (!in_struct(&a, &isakmp_ipsec_attribute_desc, trans_pbs, &attr_pbs))
-                       return FALSE;
-
-               passert((a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK) < 32);
-
-               if (LHAS(seen_attrs, a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK))
-               {
-                       loglog(RC_LOG_SERIOUS, "repeated %s attribute in IPsec Transform %u"
-                               , enum_show(&ipsec_attr_names, a.isaat_af_type)
-                               , trans->isat_transnum);
-                       return FALSE;
-               }
-
-               seen_attrs |= LELEM(a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK);
-
-               val = a.isaat_lv;
-
-               vdesc  = ipsec_attr_val_descs[a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK];
-               if (vdesc != NULL)
-               {
-                       if (enum_name(vdesc, val) == NULL)
-                       {
-                               loglog(RC_LOG_SERIOUS, "invalid value %u for attribute %s in IPsec Transform"
-                                       , (unsigned)val, enum_show(&ipsec_attr_names, a.isaat_af_type));
-                               return FALSE;
-                       }
-                       DBG(DBG_PARSING
-                               , if ((a.isaat_af_type & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV)
-                                       DBG_log("   [%u is %s]"
-                                               , (unsigned)val, enum_show(vdesc, val)));
-               }
-
-               switch (a.isaat_af_type)
-               {
-                       case SA_LIFE_TYPE | ISAKMP_ATTR_AF_TV:
-                               ipcomp_inappropriate = FALSE;
-                               if (LHAS(seen_durations, val))
-                               {
-                                       loglog(RC_LOG_SERIOUS, "attribute SA_LIFE_TYPE value %s repeated in message"
-                                               , enum_show(&sa_lifetime_names, val));
-                                       return FALSE;
-                               }
-                               seen_durations |= LELEM(val);
-                               life_type = val;
-                               break;
-                       case SA_LIFE_DURATION | ISAKMP_ATTR_AF_TLV:
-                               val = decode_long_duration(&attr_pbs);
-                               /* fall through */
-                       case SA_LIFE_DURATION | ISAKMP_ATTR_AF_TV:
-                               ipcomp_inappropriate = FALSE;
-                               if (!LHAS(seen_attrs, SA_LIFE_DURATION))
-                               {
-                                       loglog(RC_LOG_SERIOUS, "SA_LIFE_DURATION IPsec attribute not preceded by SA_LIFE_TYPE attribute");
-                                       return FALSE;
-                               }
-                               seen_attrs &= ~(LELEM(SA_LIFE_DURATION) | LELEM(SA_LIFE_TYPE));
-
-                               switch (life_type)
-                               {
-                                       case SA_LIFE_TYPE_SECONDS:
-                                               /* silently limit duration to our maximum */
-                                               attrs->life_seconds = val <= SA_LIFE_DURATION_MAXIMUM
-                                                       ? val : SA_LIFE_DURATION_MAXIMUM;
-                                               break;
-                                       case SA_LIFE_TYPE_KBYTES:
-                                               attrs->life_kilobytes = val;
-                                               break;
-                                       default:
-                                               bad_case(life_type);
-                               }
-                               break;
-                       case GROUP_DESCRIPTION | ISAKMP_ATTR_AF_TV:
-                               if (is_ipcomp)
-                               {
-                                       /* Accept reluctantly.  Should not happen, according to
-                                        * draft-shacham-ippcp-rfc2393bis-05.txt 4.1.
-                                        */
-                                       ipcomp_inappropriate = FALSE;
-                                       loglog(RC_COMMENT
-                                               , "IPCA (IPcomp SA) contains GROUP_DESCRIPTION."
-                                               "  Ignoring inapproprate attribute.");
-                               }
-                               pfs_group = ike_alg_get_dh_group(val);
-                               if (pfs_group == NULL)
-                               {
-                                       loglog(RC_LOG_SERIOUS, "only OAKLEY_GROUP_MODP1024 and OAKLEY_GROUP_MODP1536 supported for PFS");
-                                       return FALSE;
-                               }
-                               break;
-                       case ENCAPSULATION_MODE | ISAKMP_ATTR_AF_TV:
-                               ipcomp_inappropriate = FALSE;
-                               switch (val)
-                               {
-                               case ENCAPSULATION_MODE_TUNNEL:
-                               case ENCAPSULATION_MODE_TRANSPORT:
-                                       if (st->nat_traversal & NAT_T_DETECTED)
-                                       {
-                                               loglog(RC_LOG_SERIOUS
-                                                       , "%s must only be used if NAT-Traversal is not detected"
-                                                       , enum_name(&enc_mode_names, val));
-                                               /*
-                                                * Accept it anyway because SSH-Sentinel does not
-                                                * use UDP_TUNNEL or UDP_TRANSPORT for the diagnostic.
-                                                *
-                                                * remove when SSH-Sentinel is fixed
-                                                */
-#ifdef I_DONT_CARE_OF_SSH_SENTINEL
-                                               return FALSE;
-#endif
-                                       }
-                                       attrs->encapsulation = val;
-                                       break;
-                               case ENCAPSULATION_MODE_UDP_TRANSPORT_DRAFTS:
-#ifndef I_KNOW_TRANSPORT_MODE_HAS_SECURITY_CONCERN_BUT_I_WANT_IT
-                                       loglog(RC_LOG_SERIOUS
-                                               , "NAT-Traversal: Transport mode disabled due to security concerns");
-                                       return FALSE;
-#endif
-                               case ENCAPSULATION_MODE_UDP_TUNNEL_DRAFTS:
-                                       if (st->nat_traversal & NAT_T_WITH_RFC_VALUES)
-                                       {
-                                               loglog(RC_LOG_SERIOUS
-                                                       , "%s must only be used with old IETF drafts"
-                                                       , enum_name(&enc_mode_names, val));
-                                               return FALSE;
-                                       }
-                                       else if (st->nat_traversal & NAT_T_DETECTED)
-                                       {
-                                               attrs->encapsulation = val
-                                                               - ENCAPSULATION_MODE_UDP_TUNNEL_DRAFTS
-                                                               + ENCAPSULATION_MODE_TUNNEL;
-                                       }
-                                       else
-                                       {
-                                               loglog(RC_LOG_SERIOUS
-                                                       , "%s must only be used if NAT-Traversal is detected"
-                                                       , enum_name(&enc_mode_names, val));
-                                               return FALSE;
-                                       }
-                                       break;
-                                       case ENCAPSULATION_MODE_UDP_TRANSPORT_RFC:
-#ifndef I_KNOW_TRANSPORT_MODE_HAS_SECURITY_CONCERN_BUT_I_WANT_IT
-                                               loglog(RC_LOG_SERIOUS
-                                                       , "NAT-Traversal: Transport mode disabled due "
-                                                         "to security concerns");
-                                               return FALSE;
-#endif
-                                       case ENCAPSULATION_MODE_UDP_TUNNEL_RFC:
-                                               if ((st->nat_traversal & NAT_T_DETECTED)
-                                               && (st->nat_traversal & NAT_T_WITH_RFC_VALUES))
-                                               {
-                                                       attrs->encapsulation = val
-                                                                               - ENCAPSULATION_MODE_UDP_TUNNEL_RFC
-                                                                               + ENCAPSULATION_MODE_TUNNEL;
-                                               }
-                                               else if (st->nat_traversal & NAT_T_DETECTED)
-                                               {
-                                                       loglog(RC_LOG_SERIOUS
-                                                               , "%s must only be used with NAT-T RFC"
-                                                               , enum_name(&enc_mode_names, val));
-                                                       return FALSE;
-                                               }
-                                               else
-                                               {
-                                                       loglog(RC_LOG_SERIOUS
-                                                               , "%s must only be used if NAT-Traversal is detected"
-                                                               , enum_name(&enc_mode_names, val));
-                                                       return FALSE;
-                                               }
-                                               break;
-                                       default:
-                                               loglog(RC_LOG_SERIOUS
-                                                       , "unknown ENCAPSULATION_MODE %d in IPSec SA", val);
-                                               return FALSE;
-                               }
-                               break;
-                       case AUTH_ALGORITHM | ISAKMP_ATTR_AF_TV:
-                               attrs->auth = val;
-                               break;
-                       case KEY_LENGTH | ISAKMP_ATTR_AF_TV:
-                               attrs->key_len = val;
-                               break;
-                       case KEY_ROUNDS | ISAKMP_ATTR_AF_TV:
-                               attrs->key_rounds = val;
-                               break;
-#if 0 /* not yet implemented */
-                       case COMPRESS_DICT_SIZE | ISAKMP_ATTR_AF_TV:
-                               break;
-                       case COMPRESS_PRIVATE_ALG | ISAKMP_ATTR_AF_TV:
-                               break;
-
-                       case SA_LIFE_DURATION | ISAKMP_ATTR_AF_TLV:
-                               break;
-                       case COMPRESS_PRIVATE_ALG | ISAKMP_ATTR_AF_TLV:
-                               break;
-#endif
-                       default:
-                               loglog(RC_LOG_SERIOUS, "unsupported IPsec attribute %s"
-                                       , enum_show(&ipsec_attr_names, a.isaat_af_type));
-                               return FALSE;
-               }
-               if (ipcomp_inappropriate)
-               {
-                       loglog(RC_LOG_SERIOUS, "IPsec attribute %s inappropriate for IPCOMP"
-                               , enum_show(&ipsec_attr_names, a.isaat_af_type));
-                       return FALSE;
-               }
-       }
-
-       /* Although an IPCOMP SA (IPCA) ought not to have a pfs_group,
-        * if it does, demand that it be consistent.
-        * See draft-shacham-ippcp-rfc2393bis-05.txt 4.1.
-        */
-       if (!is_ipcomp || pfs_group != NULL)
-       {
-               if (st->st_pfs_group == &unset_group)
-                       st->st_pfs_group = pfs_group;
-
-               if (st->st_pfs_group != pfs_group)
-               {
-                       loglog(RC_LOG_SERIOUS, "GROUP_DESCRIPTION inconsistent with that of %s in IPsec SA"
-                               , selection? "the Proposal" : "a previous Transform");
-                       return FALSE;
-               }
-       }
-
-       if (LHAS(seen_attrs, SA_LIFE_DURATION))
-       {
-               loglog(RC_LOG_SERIOUS, "SA_LIFE_TYPE IPsec attribute not followed by SA_LIFE_DURATION attribute in message");
-               return FALSE;
-       }
-
-       if (!LHAS(seen_attrs, ENCAPSULATION_MODE))
-       {
-               if (is_ipcomp)
-               {
-                       /* draft-shacham-ippcp-rfc2393bis-05.txt 4.1:
-                        * "If the Encapsulation Mode is unspecified,
-                        * the default value of Transport Mode is assumed."
-                        * This contradicts/overrides the DOI (quuoted below).
-                        */
-                       attrs->encapsulation = ENCAPSULATION_MODE_TRANSPORT;
-               }
-               else
-               {
-                       /* ??? Technically, RFC 2407 (IPSEC DOI) 4.5 specifies that
-                        * the default is "unspecified (host-dependent)".
-                        * This makes little sense, so we demand that it be specified.
-                        */
-                       loglog(RC_LOG_SERIOUS, "IPsec Transform must specify ENCAPSULATION_MODE");
-                       return FALSE;
-               }
-       }
-
-       /* ??? should check for key_len and/or key_rounds if required */
-
-       return TRUE;
-}
-
-static void
-echo_proposal(
-       struct isakmp_proposal r_proposal,  /* proposal to emit */
-       struct isakmp_transform r_trans,    /* winning transformation within it */
-       u_int8_t np,                        /* Next Payload for proposal */
-       pb_stream *r_sa_pbs,                /* SA PBS into which to emit */
-       struct ipsec_proto_info *pi,        /* info about this protocol instance */
-       struct_desc *trans_desc,            /* descriptor for this transformation */
-       pb_stream *trans_pbs,               /* PBS for incoming transform */
-       struct spd_route *sr,               /* host details for the association */
-       bool tunnel_mode)                   /* true for inner most tunnel SA */
-{
-       pb_stream r_proposal_pbs;
-       pb_stream r_trans_pbs;
-
-       /* Proposal */
-       r_proposal.isap_np = np;
-       r_proposal.isap_notrans = 1;
-       if (!out_struct(&r_proposal, &isakmp_proposal_desc, r_sa_pbs, &r_proposal_pbs))
-               impossible();
-
-       /* allocate and emit our CPI/SPI */
-       if (r_proposal.isap_protoid == PROTO_IPCOMP)
-       {
-               /* CPI is stored in network low order end of an
-                * ipsec_spi_t.  So we start a couple of bytes in.
-                * Note: we may fail to generate a satisfactory CPI,
-                * but we'll ignore that.
-                */
-               pi->our_spi = get_my_cpi(sr, tunnel_mode);
-               out_raw((u_char *) &pi->our_spi
-                        + IPSEC_DOI_SPI_SIZE - IPCOMP_CPI_SIZE
-                       , IPCOMP_CPI_SIZE
-                       , &r_proposal_pbs, "CPI");
-       }
-       else
-       {
-               pi->our_spi = get_ipsec_spi(pi->attrs.spi
-                       , r_proposal.isap_protoid == PROTO_IPSEC_AH ?
-                               IPPROTO_AH : IPPROTO_ESP
-                       , sr
-                       , tunnel_mode);
-               /* XXX should check for errors */
-               out_raw((u_char *) &pi->our_spi, IPSEC_DOI_SPI_SIZE
-                       , &r_proposal_pbs, "SPI");
-       }
-
-       /* Transform */
-       r_trans.isat_np = ISAKMP_NEXT_NONE;
-       if (!out_struct(&r_trans, trans_desc, &r_proposal_pbs, &r_trans_pbs))
-               impossible();
-
-       /* Transform Attributes: pure echo */
-       trans_pbs->cur = trans_pbs->start + sizeof(struct isakmp_transform);
-       if (!out_raw(trans_pbs->cur, pbs_left(trans_pbs)
-       , &r_trans_pbs, "attributes"))
-               impossible();
-
-       close_output_pbs(&r_trans_pbs);
-       close_output_pbs(&r_proposal_pbs);
-}
-
-notification_t
-parse_ipsec_sa_body(
-       pb_stream *sa_pbs,          /* body of input SA Payload */
-       const struct isakmp_sa *sa, /* header of input SA Payload */
-       pb_stream *r_sa_pbs,        /* if non-NULL, where to emit body of winning SA */
-       bool selection,             /* if this SA is a selection, only one transform may appear */
-       struct state *st)           /* current state object */
-{
-       const connection_t *c = st->st_connection;
-       u_int32_t ipsecdoisit;
-       pb_stream next_proposal_pbs;
-
-       struct isakmp_proposal next_proposal;
-       ipsec_spi_t next_spi;
-
-       bool next_full = TRUE;
-
-       /* DOI */
-       if (sa->isasa_doi != ISAKMP_DOI_IPSEC)
-       {
-               loglog(RC_LOG_SERIOUS, "Unknown or unsupported DOI %s", enum_show(&doi_names, sa->isasa_doi));
-               /* XXX Could send notification back */
-               return ISAKMP_DOI_NOT_SUPPORTED;
-       }
-
-       /* Situation */
-       if (!in_struct(&ipsecdoisit, &ipsec_sit_desc, sa_pbs, NULL))
-               return ISAKMP_SITUATION_NOT_SUPPORTED;
-
-       if (ipsecdoisit != SIT_IDENTITY_ONLY)
-       {
-               loglog(RC_LOG_SERIOUS, "unsupported IPsec DOI situation (%s)"
-                       , bitnamesof(sit_bit_names, ipsecdoisit));
-               /* XXX Could send notification back */
-               return ISAKMP_SITUATION_NOT_SUPPORTED;
-       }
-
-       /* The rules for IPsec SAs are scattered.
-        * RFC 2408 "ISAKMP" section 4.2 gives some info.
-        * There may be multiple proposals.  Those with identical proposal
-        * numbers must be considered as conjuncts.  Those with different
-        * numbers are disjuncts.
-        * Each proposal may have several transforms, each considered
-        * an alternative.
-        * Each transform may have several attributes, all applying.
-        *
-        * To handle the way proposals are combined, we need to do a
-        * look-ahead.
-        */
-
-       if (!in_struct(&next_proposal, &isakmp_proposal_desc, sa_pbs, &next_proposal_pbs))
-               return ISAKMP_BAD_PROPOSAL_SYNTAX;
-
-       /* for each conjunction of proposals... */
-       while (next_full)
-       {
-               int propno = next_proposal.isap_proposal;
-               pb_stream ah_prop_pbs, esp_prop_pbs, ipcomp_prop_pbs;
-               struct isakmp_proposal ah_proposal = {0, 0, 0, 0, 0, 0, 0};
-               struct isakmp_proposal esp_proposal = {0, 0, 0, 0, 0, 0, 0};
-               struct isakmp_proposal ipcomp_proposal = {0, 0, 0, 0, 0, 0, 0};
-               ipsec_spi_t ah_spi = 0;
-               ipsec_spi_t esp_spi = 0;
-               ipsec_spi_t ipcomp_cpi = 0;
-               bool ah_seen = FALSE;
-               bool esp_seen = FALSE;
-               bool ipcomp_seen = FALSE;
-               bool tunnel_mode = FALSE;
-               int inner_proto = 0;
-               u_int16_t well_known_cpi = 0;
-
-               pb_stream ah_trans_pbs, esp_trans_pbs, ipcomp_trans_pbs;
-               struct isakmp_transform ah_trans, esp_trans, ipcomp_trans;
-               struct ipsec_trans_attrs ah_attrs, esp_attrs, ipcomp_attrs;
-
-               /* for each proposal in the conjunction */
-               do {
-
-                       if (next_proposal.isap_protoid == PROTO_IPCOMP)
-                       {
-                               /* IPCOMP CPI */
-                               if (next_proposal.isap_spisize == IPSEC_DOI_SPI_SIZE)
-                               {
-                                       /* This code is to accommodate those peculiar
-                                        * implementations that send a CPI in the bottom of an
-                                        * SPI-sized field.
-                                        * See draft-shacham-ippcp-rfc2393bis-05.txt 4.1
-                                        */
-                                       u_int8_t filler[IPSEC_DOI_SPI_SIZE - IPCOMP_CPI_SIZE];
-
-                                       if (!in_raw(filler, sizeof(filler)
-                                        , &next_proposal_pbs, "CPI filler")
-                                       || !all_zero(filler, sizeof(filler)))
-                                               return ISAKMP_INVALID_SPI;
-                               }
-                               else if (next_proposal.isap_spisize != IPCOMP_CPI_SIZE)
-                               {
-                                       loglog(RC_LOG_SERIOUS, "IPsec Proposal with improper CPI size (%u)"
-                                               , next_proposal.isap_spisize);
-                                       return ISAKMP_INVALID_SPI;
-                               }
-
-                               /* We store CPI in the low order of a network order
-                                * ipsec_spi_t.  So we start a couple of bytes in.
-                                */
-                               zero(&next_spi);
-                               if (!in_raw((u_char *)&next_spi
-                                 + IPSEC_DOI_SPI_SIZE - IPCOMP_CPI_SIZE
-                               , IPCOMP_CPI_SIZE, &next_proposal_pbs, "CPI"))
-                                       return ISAKMP_INVALID_SPI;
-
-                               /* If sanity ruled, CPIs would have to be such that
-                                * the SAID (the triple (CPI, IPCOM, destination IP))
-                                * would be unique, just like for SPIs.  But there is a
-                                * perversion where CPIs can be well-known and consequently
-                                * the triple is not unique.  We hide this fact from
-                                * ourselves by fudging the top 16 bits to make
-                                * the property true internally!
-                                */
-                               switch (ntohl(next_spi))
-                               {
-                               case IPCOMP_DEFLATE:
-                                       well_known_cpi = ntohl(next_spi);
-                                       next_spi = uniquify_his_cpi(next_spi, st);
-                                       if (next_spi == 0)
-                                       {
-                                               loglog(RC_LOG_SERIOUS
-                                                       , "IPsec Proposal contains well-known CPI that I cannot uniquify");
-                                               return ISAKMP_INVALID_SPI;
-                                       }
-                                       break;
-                               default:
-                                       if (ntohl(next_spi) < IPCOMP_FIRST_NEGOTIATED
-                                       || ntohl(next_spi) > IPCOMP_LAST_NEGOTIATED)
-                                       {
-                                               loglog(RC_LOG_SERIOUS, "IPsec Proposal contains CPI from non-negotiated range (0x%lx)"
-                                                       , (unsigned long) ntohl(next_spi));
-                                               return ISAKMP_INVALID_SPI;
-                                       }
-                                       break;
-                               }
-                       }
-                       else
-                       {
-                               /* AH or ESP SPI */
-                               if (next_proposal.isap_spisize != IPSEC_DOI_SPI_SIZE)
-                               {
-                                       loglog(RC_LOG_SERIOUS, "IPsec Proposal with improper SPI size (%u)"
-                                               , next_proposal.isap_spisize);
-                                       return ISAKMP_INVALID_SPI;
-                               }
-
-                               if (!in_raw((u_char *)&next_spi, sizeof(next_spi), &next_proposal_pbs, "SPI"))
-                                       return ISAKMP_INVALID_SPI;
-
-                               /* SPI value 0 is invalid and values 1-255 are reserved to IANA.
-                                * RFC 2402 (ESP) 2.4, RFC 2406 (AH) 2.1
-                                * IPCOMP???
-                                */
-                               if (ntohl(next_spi) < IPSEC_DOI_SPI_MIN)
-                               {
-                                       loglog(RC_LOG_SERIOUS, "IPsec Proposal contains invalid SPI (0x%lx)"
-                                               , (unsigned long) ntohl(next_spi));
-                                       return ISAKMP_INVALID_SPI;
-                               }
-                       }
-
-                       if (next_proposal.isap_notrans == 0)
-                       {
-                               loglog(RC_LOG_SERIOUS, "IPsec Proposal contains no Transforms");
-                               return ISAKMP_BAD_PROPOSAL_SYNTAX;
-                       }
-
-                       switch (next_proposal.isap_protoid)
-                       {
-                       case PROTO_IPSEC_AH:
-                               if (ah_seen)
-                               {
-                                       loglog(RC_LOG_SERIOUS, "IPsec SA contains two simultaneous AH Proposals");
-                                       return ISAKMP_BAD_PROPOSAL_SYNTAX;
-                               }
-                               ah_seen = TRUE;
-                               ah_prop_pbs = next_proposal_pbs;
-                               ah_proposal = next_proposal;
-                               ah_spi = next_spi;
-                               break;
-
-                       case PROTO_IPSEC_ESP:
-                               if (esp_seen)
-                               {
-                                       loglog(RC_LOG_SERIOUS, "IPsec SA contains two simultaneous ESP Proposals");
-                                       return ISAKMP_BAD_PROPOSAL_SYNTAX;
-                               }
-                               esp_seen = TRUE;
-                               esp_prop_pbs = next_proposal_pbs;
-                               esp_proposal = next_proposal;
-                               esp_spi = next_spi;
-                               break;
-
-                       case PROTO_IPCOMP:
-                               if (ipcomp_seen)
-                               {
-                                       loglog(RC_LOG_SERIOUS, "IPsec SA contains two simultaneous IPCOMP Proposals");
-                                       return ISAKMP_BAD_PROPOSAL_SYNTAX;
-                               }
-                               ipcomp_seen = TRUE;
-                               ipcomp_prop_pbs = next_proposal_pbs;
-                               ipcomp_proposal = next_proposal;
-                               ipcomp_cpi = next_spi;
-                               break;
-
-                       default:
-                               loglog(RC_LOG_SERIOUS, "unexpected Protocol ID (%s) in IPsec Proposal"
-                                       , enum_show(&protocol_names, next_proposal.isap_protoid));
-                               return ISAKMP_INVALID_PROTOCOL_ID;
-                       }
-
-                       /* refill next_proposal */
-                       if (next_proposal.isap_np == ISAKMP_NEXT_NONE)
-                       {
-                               next_full = FALSE;
-                               break;
-                       }
-                       else if (next_proposal.isap_np != ISAKMP_NEXT_P)
-                       {
-                               loglog(RC_LOG_SERIOUS, "unexpected in Proposal: %s"
-                                       , enum_show(&payload_names, next_proposal.isap_np));
-                               return ISAKMP_BAD_PROPOSAL_SYNTAX;
-                       }
-
-                       if (!in_struct(&next_proposal, &isakmp_proposal_desc, sa_pbs, &next_proposal_pbs))
-                               return ISAKMP_BAD_PROPOSAL_SYNTAX;
-               } while (next_proposal.isap_proposal == propno);
-
-               /* Now that we have all conjuncts, we should try
-                * the Cartesian product of eachs tranforms!
-                * At the moment, we take short-cuts on account of
-                * our rudimentary hard-wired policy.
-                * For now, we find an acceptable AH (if any)
-                * and then an acceptable ESP.  The only interaction
-                * is that the ESP acceptance can know whether there
-                * was an acceptable AH and hence not require an AUTH.
-                */
-
-               if (ah_seen)
-               {
-                       int previous_transnum = -1;
-                       int tn;
-
-                       for (tn = 0; tn != ah_proposal.isap_notrans; tn++)
-                       {
-                               int ok_transid = 0;
-                               bool ok_auth = FALSE;
-
-                               if (!parse_ipsec_transform(&ah_trans
-                               , &ah_attrs
-                               , &ah_prop_pbs
-                               , &ah_trans_pbs
-                               , &isakmp_ah_transform_desc
-                               , previous_transnum
-                               , selection
-                               , tn == ah_proposal.isap_notrans - 1
-                               , FALSE
-                               , st))
-                                       return ISAKMP_BAD_PROPOSAL_SYNTAX;
-
-                               previous_transnum = ah_trans.isat_transnum;
-
-                               /* we must understand ah_attrs.transid
-                                * COMBINED with ah_attrs.auth.
-                                * See RFC 2407 "IPsec DOI" section 4.4.3
-                                * The following combinations are legal,
-                                * but we don't implement all of them:
-                                * It seems as if each auth algorithm
-                                * only applies to one ah transid.
-                                * AH_MD5, AUTH_ALGORITHM_HMAC_MD5
-                                * AH_MD5, AUTH_ALGORITHM_KPDK (unimplemented)
-                                * AH_SHA, AUTH_ALGORITHM_HMAC_SHA1
-                                * AH_DES, AUTH_ALGORITHM_DES_MAC (unimplemented)
-                                */
-                               switch (ah_attrs.auth)
-                               {
-                                       case AUTH_ALGORITHM_NONE:
-                                               loglog(RC_LOG_SERIOUS, "AUTH_ALGORITHM attribute missing in AH Transform");
-                                               return ISAKMP_BAD_PROPOSAL_SYNTAX;
-
-                                       case AUTH_ALGORITHM_HMAC_MD5:
-                                               ok_auth = TRUE;
-                                               /* fall through */
-                                       case AUTH_ALGORITHM_KPDK:
-                                               ok_transid = AH_MD5;
-                                               break;
-
-                                       case AUTH_ALGORITHM_HMAC_SHA1:
-                                               ok_auth = TRUE;
-                                               ok_transid = AH_SHA;
-                                               break;
-
-                                       case AUTH_ALGORITHM_DES_MAC:
-                                               ok_transid = AH_DES;
-                                               break;
-                               }
-                               if (ah_attrs.transid != ok_transid)
-                               {
-                                       loglog(RC_LOG_SERIOUS, "%s attribute inappropriate in %s Transform"
-                                               , enum_name(&auth_alg_names, ah_attrs.auth)
-                                               , enum_show(&ah_transform_names, ah_attrs.transid));
-                                       return ISAKMP_BAD_PROPOSAL_SYNTAX;
-                               }
-                               if (!ok_auth)
-                               {
-                                       DBG(DBG_CONTROL | DBG_CRYPT
-                                               , DBG_log("%s attribute unsupported"
-                                                       " in %s Transform from %s"
-                                                       , enum_name(&auth_alg_names, ah_attrs.auth)
-                                                       , enum_show(&ah_transform_names, ah_attrs.transid)
-                                                       , ip_str(&c->spd.that.host_addr)));
-                                       continue;   /* try another */
-                               }
-                               break;  /* we seem to be happy */
-                       }
-                       if (tn == ah_proposal.isap_notrans)
-                               continue;       /* we didn't find a nice one */
-                       ah_attrs.spi = ah_spi;
-                       inner_proto = IPPROTO_AH;
-                       if (ah_attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)
-                               tunnel_mode = TRUE;
-               }
-
-               if (esp_seen)
-               {
-                       int previous_transnum = -1;
-                       int tn;
-
-                       for (tn = 0; tn != esp_proposal.isap_notrans; tn++)
-                       {
-                               if (!parse_ipsec_transform(&esp_trans
-                               , &esp_attrs
-                               , &esp_prop_pbs
-                               , &esp_trans_pbs
-                               , &isakmp_esp_transform_desc
-                               , previous_transnum
-                               , selection
-                               , tn == esp_proposal.isap_notrans - 1
-                               , FALSE
-                               , st))
-                                       return ISAKMP_BAD_PROPOSAL_SYNTAX;
-
-                               previous_transnum = esp_trans.isat_transnum;
-
-                               /* set default key length for AES encryption */
-                               if (!esp_attrs.key_len && esp_attrs.transid == ESP_AES)
-                               {
-                                       esp_attrs.key_len = 128; /* bits */
-                               }
-
-                               if (!kernel_alg_esp_enc_ok(esp_attrs.transid, esp_attrs.key_len
-                                       ,c->alg_info_esp))
-                               {
-                                       switch (esp_attrs.transid)
-                                       {
-                                       case ESP_3DES:
-                                               break;
-#ifdef SUPPORT_ESP_NULL /* should be about as secure as AH-only */
-                                       case ESP_NULL:
-                                               if (esp_attrs.auth == AUTH_ALGORITHM_NONE)
-                                               {
-                                                       loglog(RC_LOG_SERIOUS, "ESP_NULL requires auth algorithm");
-                                                       return BAD_PROPOSAL_SYNTAX;
-                                               }
-                                               if (st->st_policy & POLICY_ENCRYPT)
-                                               {
-                                                       DBG(DBG_CONTROL | DBG_CRYPT
-                                                                       , DBG_log("ESP_NULL Transform Proposal from %s"
-                                                                               " does not satisfy POLICY_ENCRYPT"
-                                                                               , ip_str(&c->spd.that.host_addr)));
-                                                       continue;   /* try another */
-                                               }
-                                               break;
-#endif
-                                       default:
-                                               DBG(DBG_CONTROL | DBG_CRYPT
-                                                       , DBG_log("unsupported ESP Transform %s from %s"
-                                                               , enum_show(&esp_transform_names, esp_attrs.transid)
-                                                               , ip_str(&c->spd.that.host_addr)));
-                                               continue;   /* try another */
-                                       }
-                               }
-
-                               if (!kernel_alg_esp_auth_ok(esp_attrs.auth, c->alg_info_esp))
-                               {
-                                       switch (esp_attrs.auth)
-                                       {
-                                       case AUTH_ALGORITHM_NONE:
-                                               if (!ah_seen)
-                                               {
-                                                       DBG(DBG_CONTROL | DBG_CRYPT
-                                                               , DBG_log("ESP from %s must either have AUTH or be combined with AH"
-                                                                       , ip_str(&c->spd.that.host_addr)));
-                                                       continue;   /* try another */
-                                               }
-                                               break;
-                                       case AUTH_ALGORITHM_HMAC_MD5:
-                                       case AUTH_ALGORITHM_HMAC_SHA1:
-                                               break;
-                                       default:
-                                               DBG(DBG_CONTROL | DBG_CRYPT
-                                                       , DBG_log("unsupported ESP auth alg %s from %s"
-                                                               , enum_show(&auth_alg_names, esp_attrs.auth)
-                                                               , ip_str(&c->spd.that.host_addr)));
-                                               continue;   /* try another */
-                                       }
-                               }
-
-                               /* A last check for allowed transforms in alg_info_esp
-                                * (ALG_INFO_F_STRICT flag)
-                                */
-                               if (!kernel_alg_esp_ok_final(esp_attrs.transid, esp_attrs.key_len
-                                       ,esp_attrs.auth, c->alg_info_esp))
-                               {
-                                       continue;
-                               }
-
-                               if (ah_seen && ah_attrs.encapsulation != esp_attrs.encapsulation)
-                               {
-                                       /* ??? This should be an error, but is it? */
-                                       DBG(DBG_CONTROL | DBG_CRYPT
-                                               , DBG_log("AH and ESP transforms disagree about encapsulation; TUNNEL presumed"));
-                               }
-
-                               break;  /* we seem to be happy */
-                       }
-                       if (tn == esp_proposal.isap_notrans)
-                               continue;       /* we didn't find a nice one */
-
-                       esp_attrs.spi = esp_spi;
-                       inner_proto = IPPROTO_ESP;
-                       if (esp_attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)
-                               tunnel_mode = TRUE;
-               }
-               else if (st->st_policy & POLICY_ENCRYPT)
-               {
-                       DBG(DBG_CONTROL | DBG_CRYPT
-                               , DBG_log("policy for \"%s\" requires encryption but ESP not in Proposal from %s"
-                                       , c->name, ip_str(&c->spd.that.host_addr)));
-                       continue;   /* we needed encryption, but didn't find ESP */
-               }
-               else if ((st->st_policy & POLICY_AUTHENTICATE) && !ah_seen)
-               {
-                       DBG(DBG_CONTROL | DBG_CRYPT
-                               , DBG_log("policy for \"%s\" requires authentication"
-                                       " but none in Proposal from %s"
-                                       , c->name, ip_str(&c->spd.that.host_addr)));
-                       continue;   /* we need authentication, but we found neither ESP nor AH */
-               }
-
-               if (ipcomp_seen)
-               {
-                       int previous_transnum = -1;
-                       int tn;
-
-#ifdef NEVER    /* we think IPcomp is working now */
-                       /**** FUDGE TO PREVENT UNREQUESTED IPCOMP:
-                        **** NEEDED BECAUSE OUR IPCOMP IS EXPERIMENTAL (UNSTABLE).
-                        ****/
-                       if (!(st->st_policy & POLICY_COMPRESS))
-                       {
-                               plog("compression proposed by %s, but policy for \"%s\" forbids it"
-                                       , ip_str(&c->spd.that.host_addr), c->name);
-                               continue;       /* unwanted compression proposal */
-                       }
-#endif
-                       if (!can_do_IPcomp)
-                       {
-                               plog("compression proposed by %s, but kernel does not support IPCOMP"
-                                       , ip_str(&c->spd.that.host_addr));
-                               continue;
-                       }
-
-                       if (well_known_cpi != 0 && !ah_seen && !esp_seen)
-                       {
-                               plog("illegal proposal: bare IPCOMP used with well-known CPI");
-                               return ISAKMP_BAD_PROPOSAL_SYNTAX;
-                       }
-
-                       for (tn = 0; tn != ipcomp_proposal.isap_notrans; tn++)
-                       {
-                               if (!parse_ipsec_transform(&ipcomp_trans
-                               , &ipcomp_attrs
-                               , &ipcomp_prop_pbs
-                               , &ipcomp_trans_pbs
-                               , &isakmp_ipcomp_transform_desc
-                               , previous_transnum
-                               , selection
-                               , tn == ipcomp_proposal.isap_notrans - 1
-                               , TRUE
-                               , st))
-                                       return ISAKMP_BAD_PROPOSAL_SYNTAX;
-
-                               previous_transnum = ipcomp_trans.isat_transnum;
-
-                               if (well_known_cpi != 0 && ipcomp_attrs.transid != well_known_cpi)
-                               {
-                                       plog("illegal proposal: IPCOMP well-known CPI disagrees with transform");
-                                       return ISAKMP_BAD_PROPOSAL_SYNTAX;
-                               }
-
-                               switch (ipcomp_attrs.transid)
-                               {
-                                       case IPCOMP_DEFLATE:    /* all we can handle! */
-                                               break;
-
-                                       default:
-                                               DBG(DBG_CONTROL | DBG_CRYPT
-                                                       , DBG_log("unsupported IPCOMP Transform %s from %s"
-                                                               , enum_show(&ipcomp_transformid_names, ipcomp_attrs.transid)
-                                                               , ip_str(&c->spd.that.host_addr)));
-                                               continue;   /* try another */
-                               }
-
-                               if (ah_seen && ah_attrs.encapsulation != ipcomp_attrs.encapsulation)
-                               {
-                                       /* ??? This should be an error, but is it? */
-                                       DBG(DBG_CONTROL | DBG_CRYPT
-                                               , DBG_log("AH and IPCOMP transforms disagree about encapsulation; TUNNEL presumed"));
-                               } else if (esp_seen && esp_attrs.encapsulation != ipcomp_attrs.encapsulation)
-                               {
-                                       /* ??? This should be an error, but is it? */
-                                       DBG(DBG_CONTROL | DBG_CRYPT
-                                               , DBG_log("ESP and IPCOMP transforms disagree about encapsulation; TUNNEL presumed"));
-                               }
-
-                               break;  /* we seem to be happy */
-                       }
-                       if (tn == ipcomp_proposal.isap_notrans)
-                               continue;       /* we didn't find a nice one */
-                       ipcomp_attrs.spi = ipcomp_cpi;
-                       inner_proto = IPPROTO_COMP;
-                       if (ipcomp_attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)
-                               tunnel_mode = TRUE;
-               }
-
-               /* Eureka: we liked what we saw -- accept it. */
-
-               if (r_sa_pbs != NULL)
-               {
-                       /* emit what we've accepted */
-
-                       /* Situation */
-                       if (!out_struct(&ipsecdoisit, &ipsec_sit_desc, r_sa_pbs, NULL))
-                               impossible();
-
-                       /* AH proposal */
-                       if (ah_seen)
-                               echo_proposal(ah_proposal
-                                       , ah_trans
-                                       , esp_seen || ipcomp_seen? ISAKMP_NEXT_P : ISAKMP_NEXT_NONE
-                                       , r_sa_pbs
-                                       , &st->st_ah
-                                       , &isakmp_ah_transform_desc
-                                       , &ah_trans_pbs
-                                       , &st->st_connection->spd
-                                       , tunnel_mode && inner_proto == IPPROTO_AH);
-
-                       /* ESP proposal */
-                       if (esp_seen)
-                               echo_proposal(esp_proposal
-                                       , esp_trans
-                                       , ipcomp_seen? ISAKMP_NEXT_P : ISAKMP_NEXT_NONE
-                                       , r_sa_pbs
-                                       , &st->st_esp
-                                       , &isakmp_esp_transform_desc
-                                       , &esp_trans_pbs
-                                       , &st->st_connection->spd
-                                       , tunnel_mode && inner_proto == IPPROTO_ESP);
-
-                       /* IPCOMP proposal */
-                       if (ipcomp_seen)
-                               echo_proposal(ipcomp_proposal
-                                       , ipcomp_trans
-                                       , ISAKMP_NEXT_NONE
-                                       , r_sa_pbs
-                                       , &st->st_ipcomp
-                                       , &isakmp_ipcomp_transform_desc
-                                       , &ipcomp_trans_pbs
-                                       , &st->st_connection->spd
-                                       , tunnel_mode && inner_proto == IPPROTO_COMP);
-
-                       close_output_pbs(r_sa_pbs);
-               }
-
-               /* save decoded version of winning SA in state */
-
-               st->st_ah.present = ah_seen;
-               if (ah_seen)
-                       st->st_ah.attrs = ah_attrs;
-
-               st->st_esp.present = esp_seen;
-               if (esp_seen)
-                       st->st_esp.attrs = esp_attrs;
-
-               st->st_ipcomp.present = ipcomp_seen;
-               if (ipcomp_seen)
-                       st->st_ipcomp.attrs = ipcomp_attrs;
-
-               return ISAKMP_NOTHING_WRONG;
-       }
-
-       loglog(RC_LOG_SERIOUS, "no acceptable Proposal in IPsec SA");
-       return ISAKMP_NO_PROPOSAL_CHOSEN;
-}
diff --git a/src/pluto/spdb.h b/src/pluto/spdb.h
deleted file mode 100644 (file)
index 8a0bffb..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/* Security Policy Data Base (such as it is)
- * Copyright (C) 1998, 1999  D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef _SPDB_H
-#define _SPDB_H
-
-#include "packet.h"
-
-/* database of SA properties */
-
-/* Attribute type and value pair.
- * Note: only "basic" values are represented so far.
- */
-struct db_attr {
-       u_int16_t type;     /* ISAKMP_ATTR_AF_TV is implied; 0 for end */
-       u_int16_t val;
-};
-
-/* transform */
-struct db_trans {
-       u_int8_t transid;   /* Transform-Id */
-       struct db_attr *attrs;      /* array */
-       int attr_cnt;       /* number of elements */
-};
-
-/* proposal */
-struct db_prop {
-       u_int8_t protoid;   /* Protocol-Id */
-       struct db_trans *trans;     /* array (disjunction) */
-       int trans_cnt;      /* number of elements */
-       /* SPI size and value isn't part of DB */
-};
-
-/* conjunction of proposals */
-struct db_prop_conj {
-       struct db_prop *props;      /* array */
-       int prop_cnt;       /* number of elements */
-};
-
-/* security association */
-struct db_sa {
-       struct db_prop_conj *prop_conjs;    /* array */
-       int prop_conj_cnt;  /* number of elements */
-       /* Hardwired for now;
-        * DOI: ISAKMP_DOI_IPSEC
-        * Situation: SIT_IDENTITY_ONLY
-        */
-};
-
-/* The oakley sadb */
-extern struct db_sa oakley_sadb;
-
-/* The ipsec sadb is subscripted by a bitset with members
- * from POLICY_ENCRYPT, POLICY_AUTHENTICATE, POLICY_COMPRESS
- */
-extern struct db_sa ipsec_sadb[1 << 3];
-
-/* forward declaration */
-struct state;
-
-extern bool out_sa(
-       pb_stream *outs,
-       struct db_sa *sadb,
-       struct state *st,
-       bool oakley_mode,
-       u_int8_t np);
-
-extern notification_t preparse_isakmp_sa_body(
-       const struct isakmp_sa *sa, /* header of input SA Payload */
-       pb_stream *sa_pbs,          /* body of input SA Payload */
-       u_int32_t *ipsecdoisit,     /* IPsec DOI SIT bitset */
-       pb_stream *proposal_pbs,    /* body of proposal Payload */
-       struct isakmp_proposal *proposal);
-
-extern notification_t parse_isakmp_policy(
-       pb_stream *proposal_pbs,    /* body of proposal Payload */
-       u_int notrans,              /* number of transforms */
-       lset_t *policy);            /* RSA, PSK or XAUTH policy */
-
-extern notification_t parse_isakmp_sa_body(
-       u_int32_t ipsecdoisit,      /* IPsec DOI SIT bitset */
-       pb_stream *proposal_pbs,    /* body of proposal Payload */
-       struct isakmp_proposal *proposal,
-       pb_stream *r_sa_pbs,        /* if non-NULL, where to emit winning SA */
-       struct state *st,           /* current state object */
-       bool initiator);            /* is caller initiator? */
-
-extern notification_t parse_ipsec_sa_body(
-       pb_stream *sa_pbs,          /* body of input SA Payload */
-       const struct isakmp_sa *sa, /* header of input SA Payload */
-       pb_stream *r_sa_pbs,        /* if non-NULL, where to emit winning SA */
-       bool selection,             /* if this SA is a selection, only one transform can appear */
-       struct state *st);          /* current state object */
-
-extern void backup_pbs(pb_stream *pbs);
-extern void restore_pbs(pb_stream *pbs);
-
-#endif /* _SPDB_H */
-
diff --git a/src/pluto/state.c b/src/pluto/state.c
deleted file mode 100644 (file)
index f518588..0000000
+++ /dev/null
@@ -1,952 +0,0 @@
-/* routines for state objects
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2001  D. Hugh Redelmeier.
- * Copyright (C) 2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <fcntl.h>
-#include <sys/queue.h>
-
-#include <freeswan.h>
-
-#include <library.h>
-#include <crypto/rngs/rng.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "connections.h"
-#include "state.h"
-#include "kernel.h"
-#include "log.h"
-#include "packet.h"     /* so we can calculate sizeof(struct isakmp_hdr) */
-#include "keys.h"       /* for free_public_key */
-#include "timer.h"
-#include "whack.h"
-#include "demux.h"      /* needs packet.h */
-#include "ipsec_doi.h"  /* needs demux.h and state.h */
-#include "crypto.h"
-
-/*
- * Global variables: had to go somewhere, might as well be this file.
- */
-
-u_int16_t pluto_port = IKE_UDP_PORT;    /* Pluto's port */
-
-/*
- * This file has the functions that handle the
- * state hash table and the Message ID list.
- */
-
-/* Message-IDs
- *
- * A Message ID is contained in each IKE message header.
- * For Phase 1 exchanges (Main and Aggressive), it will be zero.
- * For other exchanges, which must be under the protection of an
- * ISAKMP SA, the Message ID must be unique within that ISAKMP SA.
- * Effectively, this labels the message as belonging to a particular
- * exchange.
- * BTW, we feel this uniqueness allows rekeying to be somewhat simpler
- * than specified by draft-jenkins-ipsec-rekeying-06.txt.
- *
- * A MessageID is a 32 bit unsigned number.  We represent the value
- * internally in network order -- they are just blobs to us.
- * They are unsigned numbers to make hashing and comparing easy.
- *
- * The following mechanism is used to allocate message IDs.  This
- * requires that we keep track of which numbers have already been used
- * so that we don't allocate one in use.
- */
-
-struct msgid_list
-{
-       msgid_t               msgid; /* network order */
-       struct msgid_list     *next;
-};
-
-bool reserve_msgid(struct state *isakmp_sa, msgid_t msgid)
-{
-       struct msgid_list *p;
-
-       passert(msgid != MAINMODE_MSGID);
-       passert(IS_ISAKMP_ENCRYPTED(isakmp_sa->st_state));
-
-       for (p = isakmp_sa->st_used_msgids; p != NULL; p = p->next)
-               if (p->msgid == msgid)
-                       return FALSE;
-
-       p = malloc_thing(struct msgid_list);
-       p->msgid = msgid;
-       p->next = isakmp_sa->st_used_msgids;
-       isakmp_sa->st_used_msgids = p;
-       return TRUE;
-}
-
-msgid_t generate_msgid(struct state *isakmp_sa)
-{
-       int timeout = 100;  /* only try so hard for unique msgid */
-       msgid_t msgid;
-       rng_t *rng;
-
-       passert(IS_ISAKMP_ENCRYPTED(isakmp_sa->st_state));
-       rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
-
-       for (;;)
-       {
-               rng->get_bytes(rng, sizeof(msgid), (void *) &msgid);
-               if (msgid != 0 && reserve_msgid(isakmp_sa, msgid))
-               {
-                       break;
-               }
-               if (--timeout == 0)
-               {
-                       plog("gave up looking for unique msgid; using 0x%08lx"
-                               , (unsigned long) msgid);
-                       break;
-               }
-       }
-       rng->destroy(rng);
-       return msgid;
-}
-
-
-/* state table functions */
-
-#define STATE_TABLE_SIZE 32
-
-static struct state *statetable[STATE_TABLE_SIZE];
-
-static struct state **state_hash(const u_char *icookie, const u_char *rcookie,
-                                                                const ip_address *peer)
-{
-       u_int i = 0, j;
-       const unsigned char *byte_ptr;
-       size_t length = addrbytesptr(peer, &byte_ptr);
-
-       DBG(DBG_RAW | DBG_CONTROL,
-               DBG_dump("ICOOKIE:", icookie, COOKIE_SIZE);
-               DBG_dump("RCOOKIE:", rcookie, COOKIE_SIZE);
-               DBG_dump("peer:", byte_ptr, length));
-
-       /* XXX the following hash is pretty pathetic */
-
-       for (j = 0; j < COOKIE_SIZE; j++)
-               i = i * 407 + icookie[j] + rcookie[j];
-
-       for (j = 0; j < length; j++)
-               i = i * 613 + byte_ptr[j];
-
-       i = i % STATE_TABLE_SIZE;
-
-       DBG(DBG_CONTROL, DBG_log("state hash entry %d", i));
-
-       return &statetable[i];
-}
-
-/* Get a state object.
- * Caller must schedule an event for this object so that it doesn't leak.
- * Caller must insert_state().
- */
-struct state *new_state(void)
-{
-       /* initialized all to zero & NULL */
-       static const struct state blank_state = {
-               .st_serialno = 0,
-       };
-       static so_serial_t next_so = SOS_FIRST;
-       struct state *st;
-
-       st = clone_thing(blank_state);
-       st->st_serialno = next_so++;
-       passert(next_so > SOS_FIRST);       /* overflow can't happen! */
-       st->st_whack_sock = NULL_FD;
-       DBG(DBG_CONTROL, DBG_log("creating state object #%lu at %p",
-               st->st_serialno, (void *) st));
-       return st;
-}
-
-/*
- * Initialize the state table (and mask*).
- */
-void init_states(void)
-{
-       int i;
-
-       for (i = 0; i < STATE_TABLE_SIZE; i++)
-               statetable[i] = (struct state *) NULL;
-}
-
-/* Find the state object with this serial number.
- * This allows state object references that don't turn into dangerous
- * dangling pointers: reference a state by its serial number.
- * Returns NULL if there is no such state.
- * If this turns out to be a significant CPU hog, it could be
- * improved to use a hash table rather than sequential seartch.
- */
-struct state *state_with_serialno(so_serial_t sn)
-{
-       if (sn >= SOS_FIRST)
-       {
-               struct state *st;
-               int i;
-
-               for (i = 0; i < STATE_TABLE_SIZE; i++)
-                       for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
-                               if (st->st_serialno == sn)
-                                       return st;
-       }
-       return NULL;
-}
-
-/* Insert a state object in the hash table. The object is inserted
- * at the beginning of list.
- * Needs cookies, connection, and msgid.
- */
-void insert_state(struct state *st)
-{
-       struct state **p = state_hash(st->st_icookie, st->st_rcookie
-               , &st->st_connection->spd.that.host_addr);
-
-       passert(st->st_hashchain_prev == NULL && st->st_hashchain_next == NULL);
-
-       if (*p != NULL)
-       {
-               passert((*p)->st_hashchain_prev == NULL);
-               (*p)->st_hashchain_prev = st;
-       }
-       st->st_hashchain_next = *p;
-       *p = st;
-
-       /* Ensure that somebody is in charge of killing this state:
-        * if no event is scheduled for it, schedule one to discard the state.
-        * If nothing goes wrong, this event will be replaced by
-        * a more appropriate one.
-        */
-       if (st->st_event == NULL)
-               event_schedule(EVENT_SO_DISCARD, 0, st);
-}
-
-/* unlink a state object from the hash table, but don't free it
- */
-void unhash_state(struct state *st)
-{
-       /* unlink from forward chain */
-       struct state **p = st->st_hashchain_prev == NULL
-               ? state_hash(st->st_icookie, st->st_rcookie
-                                        , &st->st_connection->spd.that.host_addr)
-               : &st->st_hashchain_prev->st_hashchain_next;
-
-       /* unlink from forward chain */
-       passert(*p == st);
-       *p = st->st_hashchain_next;
-
-       /* unlink from backward chain */
-       if (st->st_hashchain_next != NULL)
-       {
-               passert(st->st_hashchain_next->st_hashchain_prev == st);
-               st->st_hashchain_next->st_hashchain_prev = st->st_hashchain_prev;
-       }
-
-       st->st_hashchain_next = st->st_hashchain_prev = NULL;
-}
-
-/* Free the Whack socket file descriptor.
- * This has the side effect of telling Whack that we're done.
- */
-void release_whack(struct state *st)
-{
-       close_any(st->st_whack_sock);
-}
-
-/**
- * Delete a state object
- */
-void delete_state(struct state *st)
-{
-       connection_t *const c = st->st_connection;
-       struct state *old_cur_state = cur_state == st? NULL : cur_state;
-
-       set_cur_state(st);
-
-       /* If DPD is enabled on this state object, clear any pending events */
-       if(st->st_dpd_event != NULL)
-                       delete_dpd_event(st);
-
-       /* if there is a suspended state transition, disconnect us */
-       if (st->st_suspended_md != NULL)
-       {
-               passert(st->st_suspended_md->st == st);
-               st->st_suspended_md->st = NULL;
-       }
-
-       /* tell the other side of any IPSEC SAs that are going down */
-       if (IS_IPSEC_SA_ESTABLISHED(st->st_state)
-       || IS_ISAKMP_SA_ESTABLISHED(st->st_state))
-               send_delete(st);
-
-       delete_event(st);   /* delete any pending timer event */
-
-       /* Ditch anything pending on ISAKMP SA being established.
-        * Note: this must be done before the unhash_state to prevent
-        * flush_pending_by_state inadvertently and prematurely
-        * deleting our connection.
-        */
-       flush_pending_by_state(st);
-
-       /* effectively, this deletes any ISAKMP SA that this state represents */
-       unhash_state(st);
-
-       /* tell kernel to delete any IPSEC SA
-        * ??? we ought to tell peer to delete IPSEC SAs
-        */
-       if (IS_IPSEC_SA_ESTABLISHED(st->st_state))
-               delete_ipsec_sa(st, FALSE);
-       else if (IS_ONLY_INBOUND_IPSEC_SA_ESTABLISHED(st->st_state))
-               delete_ipsec_sa(st, TRUE);
-
-       if (c->newest_ipsec_sa == st->st_serialno)
-               c->newest_ipsec_sa = SOS_NOBODY;
-
-       if (c->newest_isakmp_sa == st->st_serialno)
-               c->newest_isakmp_sa = SOS_NOBODY;
-
-       st->st_connection = NULL;   /* we might be about to free it */
-       cur_state = old_cur_state;  /* without st_connection, st isn't complete */
-       connection_discard(c);
-
-       release_whack(st);
-
-       /* from here on we are just freeing RAM */
-
-       {
-               struct msgid_list *p = st->st_used_msgids;
-
-               while (p != NULL)
-               {
-                       struct msgid_list *q = p;
-                       p = p->next;
-                       free(q);
-               }
-       }
-
-       unreference_key(&st->st_peer_pubkey);
-
-       DESTROY_IF(st->st_dh);
-
-       chunk_clear(&st->st_tpacket);
-       chunk_clear(&st->st_rpacket);
-       chunk_clear(&st->st_p1isa);
-       chunk_clear(&st->st_gi);
-       chunk_clear(&st->st_gr);
-       chunk_clear(&st->st_shared);
-       chunk_clear(&st->st_ni);
-       chunk_clear(&st->st_nr);
-       chunk_clear(&st->st_skeyid);
-       chunk_clear(&st->st_skeyid_d);
-       chunk_clear(&st->st_skeyid_a);
-       chunk_clear(&st->st_skeyid_e);
-       chunk_clear(&st->st_enc_key);
-
-       free(st->st_ah.our_keymat);
-       free(st->st_ah.peer_keymat);
-       free(st->st_esp.our_keymat);
-       free(st->st_esp.peer_keymat);
-
-       free(st);
-}
-
-/**
- * Is a connection in use by some state?
- */
-bool states_use_connection(connection_t *c)
-{
-       /* are there any states still using it? */
-       struct state *st = NULL;
-       int i;
-
-       for (i = 0; st == NULL && i < STATE_TABLE_SIZE; i++)
-               for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
-                       if (st->st_connection == c)
-                               return TRUE;
-
-       return FALSE;
-}
-
-/**
- * Delete all states that were created for a given connection.
- * if relations == TRUE, then also delete states that share
- * the same phase 1 SA.
- */
-void delete_states_by_connection(connection_t *c, bool relations)
-{
-       int pass;
-       /* this kludge avoids an n^2 algorithm */
-       enum connection_kind ck = c->kind;
-       struct spd_route *sr;
-
-       /* save this connection's isakmp SA, since it will get set to later SOS_NOBODY */
-       so_serial_t parent_sa = c->newest_isakmp_sa;
-
-       if (ck == CK_INSTANCE)
-               c->kind = CK_GOING_AWAY;
-
-       /* We take two passes so that we delete any ISAKMP SAs last.
-        * This allows Delete Notifications to be sent.
-        * ?? We could probably double the performance by caching any
-        * ISAKMP SA states found in the first pass, avoiding a second.
-        */
-       for (pass = 0; pass != 2; pass++)
-       {
-               int i;
-
-               /* For each hash chain... */
-               for (i = 0; i < STATE_TABLE_SIZE; i++)
-               {
-                       struct state *st;
-
-                       /* For each state in the hash chain... */
-                       for (st = statetable[i]; st != NULL; )
-                       {
-                               struct state *this = st;
-
-                               st = st->st_hashchain_next;     /* before this is deleted */
-
-
-                               if ((this->st_connection == c
-                                               || (relations && parent_sa != SOS_NOBODY
-                                               && this->st_clonedfrom == parent_sa))
-                                               && (pass == 1 || !IS_ISAKMP_SA_ESTABLISHED(this->st_state)))
-                               {
-                                       struct state *old_cur_state
-                                               = cur_state == this? NULL : cur_state;
-#ifdef DEBUG
-                                       lset_t old_cur_debugging = cur_debugging;
-#endif
-
-                                       set_cur_state(this);
-                                       plog("deleting state (%s)"
-                                               , enum_show(&state_names, this->st_state));
-                                       delete_state(this);
-                                       cur_state = old_cur_state;
-#ifdef DEBUG
-                                       cur_debugging = old_cur_debugging;
-#endif
-                               }
-                       }
-               }
-       }
-
-       sr = &c->spd;
-       while (sr != NULL)
-       {
-               passert(sr->eroute_owner == SOS_NOBODY);
-               passert(sr->routing != RT_ROUTED_TUNNEL);
-               sr = sr->next;
-       }
-       c->kind = ck;
-}
-
-/**
- * Walk through the state table, and delete each state whose phase 1 (IKE)
- * peer is among those given.
- */
-void delete_states_by_peer(ip_address *peer)
-{
-       char peerstr[ADDRTOT_BUF];
-       int i;
-
-       addrtot(peer, 0, peerstr, sizeof(peerstr));
-
-       /* For each hash chain... */
-       for (i = 0; i < STATE_TABLE_SIZE; i++)
-       {
-               struct state *st;
-
-               /* For each state in the hash chain... */
-               for (st = statetable[i]; st != NULL; )
-               {
-                       struct state *this = st;
-                       struct spd_route *sr;
-                       connection_t *c = this->st_connection;
-
-                       st = st->st_hashchain_next; /* before this is deleted */
-
-                       /* ??? Is it not the case that the peer is the same for all spds? */
-                       for (sr = &c->spd; sr != NULL; sr = sr->next)
-                       {
-                               if (sameaddr(&sr->that.host_addr, peer))
-                               {
-                                       plog("peer %s for connection %s deleting - claimed to have crashed"
-                                                , peerstr
-                                                , c->name);
-                                       delete_states_by_connection(c, TRUE);
-                                       if (c->kind == CK_INSTANCE)
-                                               delete_connection(c, TRUE);
-                                       break;      /* can only delete it once */
-                               }
-                       }
-               }
-       }
-}
-
-/* Duplicate a Phase 1 state object, to create a Phase 2 object.
- * Caller must schedule an event for this object so that it doesn't leak.
- * Caller must insert_state().
- */
-struct state *duplicate_state(struct state *st)
-{
-       struct state *nst;
-
-       DBG(DBG_CONTROL, DBG_log("duplicating state object #%lu",
-               st->st_serialno));
-
-       /* record use of the Phase 1 state */
-       st->st_outbound_count++;
-       st->st_outbound_time = now();
-
-       nst = new_state();
-
-       memcpy(nst->st_icookie, st->st_icookie, COOKIE_SIZE);
-       memcpy(nst->st_rcookie, st->st_rcookie, COOKIE_SIZE);
-
-       nst->st_connection = st->st_connection;
-       nst->st_doi = st->st_doi;
-       nst->st_situation = st->st_situation;
-       nst->st_clonedfrom = st->st_serialno;
-       nst->st_oakley = st->st_oakley;
-       nst->st_modecfg = st->st_modecfg;
-       nst->st_skeyid_d = chunk_clone(st->st_skeyid_d);
-       nst->st_skeyid_a = chunk_clone(st->st_skeyid_a);
-       nst->st_skeyid_e = chunk_clone(st->st_skeyid_e);
-       nst->st_enc_key = chunk_clone(st->st_enc_key);
-
-       return nst;
-}
-
-#if 1
-void for_each_state(void *(f)(struct state *, void *data), void *data)
-{
-               struct state *st, *ocs = cur_state;
-               int i;
-               for (i=0; i<STATE_TABLE_SIZE; i++) {
-                               for (st = statetable[i]; st != NULL; st = st->st_hashchain_next) {
-                                               set_cur_state(st);
-                                               f(st, data);
-                               }
-               }
-               cur_state = ocs;
-}
-#endif
-
-/**
- * Find a state object.
- */
-struct state *find_state(const u_char *icookie, const u_char *rcookie,
-                                                const ip_address *peer, msgid_t msgid)
-{
-       struct state *st = *state_hash(icookie, rcookie, peer);
-
-       while (st != (struct state *) NULL)
-       {
-               if (sameaddr(peer, &st->st_connection->spd.that.host_addr)
-               && memeq(icookie, st->st_icookie, COOKIE_SIZE)
-               && memeq(rcookie, st->st_rcookie, COOKIE_SIZE)
-               && msgid == st->st_msgid)
-               {
-                       break;
-               }
-               else
-               {
-                       st = st->st_hashchain_next;
-               }
-       }
-       DBG(DBG_CONTROL,
-               if (st == NULL)
-                       DBG_log("state object not found");
-               else
-                       DBG_log("state object #%lu found, in %s"
-                               , st->st_serialno
-                               , enum_show(&state_names, st->st_state)));
-
-       return st;
-}
-
-/**
- * Find the state that sent a packet
- * ??? this could be expensive -- it should be rate-limited to avoid DoS
- */
-struct state *find_sender(size_t packet_len, u_char *packet)
-{
-       int i;
-       struct state *st;
-
-       if (packet_len >= sizeof(struct isakmp_hdr))
-       {
-               for (i = 0; i < STATE_TABLE_SIZE; i++)
-               {
-                       for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
-                       {
-                               if (st->st_tpacket.ptr != NULL
-                               && st->st_tpacket.len == packet_len
-                               && memeq(st->st_tpacket.ptr, packet, packet_len))
-                               {
-                                       return st;
-                               }
-                       }
-               }
-       }
-       return NULL;
-}
-
-struct state *find_phase2_state_to_delete(const struct state *p1st,
-                                                                                 u_int8_t protoid, ipsec_spi_t spi,
-                                                                                 bool *bogus)
-{
-       struct state *st;
-       int i;
-
-       *bogus = FALSE;
-       for (i = 0; i < STATE_TABLE_SIZE; i++)
-       {
-               for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
-               {
-                       if (IS_IPSEC_SA_ESTABLISHED(st->st_state)
-                       && p1st->st_connection->host_pair == st->st_connection->host_pair
-                       && same_peer_ids(p1st->st_connection, st->st_connection, NULL))
-                       {
-                               struct ipsec_proto_info *pr = protoid == PROTO_IPSEC_AH
-                                       ? &st->st_ah : &st->st_esp;
-
-                               if (pr->present)
-                               {
-                                       if (pr->attrs.spi == spi)
-                                               return st;
-                                       if (pr->our_spi == spi)
-                                               *bogus = TRUE;
-                               }
-                       }
-               }
-       }
-       return NULL;
-}
-
-/**
- * Find newest Phase 1 negotiation state object for suitable for connection c
- */
-struct state *find_phase1_state(const connection_t *c, lset_t ok_states)
-{
-       struct state
-               *st,
-               *best = NULL;
-       int i;
-
-       for (i = 0; i < STATE_TABLE_SIZE; i++)
-               for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
-                       if (LHAS(ok_states, st->st_state)
-                       && c->host_pair == st->st_connection->host_pair
-                       && same_peer_ids(c, st->st_connection, NULL)
-                       && (best == NULL || best->st_serialno < st->st_serialno))
-                               best = st;
-
-       return best;
-}
-
-void state_eroute_usage(ip_subnet *ours, ip_subnet *his, unsigned long count,
-                                               time_t nw)
-{
-       struct state *st;
-       int i;
-
-       for (i = 0; i < STATE_TABLE_SIZE; i++)
-       {
-               for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
-               {
-                       connection_t *c = st->st_connection;
-
-                       /* XXX spd-enum */
-                       if (IS_IPSEC_SA_ESTABLISHED(st->st_state)
-                               && c->spd.eroute_owner == st->st_serialno
-                               && c->spd.routing == RT_ROUTED_TUNNEL
-                               && samesubnet(&c->spd.this.client, ours)
-                               && samesubnet(&c->spd.that.client, his))
-                       {
-                               if (st->st_outbound_count != count)
-                               {
-                                       st->st_outbound_count = count;
-                                       st->st_outbound_time = nw;
-                               }
-                               return;
-                       }
-               }
-       }
-       DBG(DBG_CONTROL,
-               {
-                       char ourst[SUBNETTOT_BUF];
-                       char hist[SUBNETTOT_BUF];
-
-                       subnettot(ours, 0, ourst, sizeof(ourst));
-                       subnettot(his, 0, hist, sizeof(hist));
-                       DBG_log("unknown tunnel eroute %s -> %s found in scan"
-                               , ourst, hist);
-               });
-}
-
-void fmt_state(bool all, struct state *st, time_t n, char *state_buf,
-                          size_t state_buf_len, char *state_buf2, size_t state_buf2_len)
-{
-       /* what the heck is interesting about a state? */
-       const connection_t *c = st->st_connection;
-
-       long delta = st->st_event->ev_time >= n
-               ? (long)(st->st_event->ev_time - n)
-               : -(long)(n - st->st_event->ev_time);
-
-       char inst[CONN_INST_BUF];
-       const char *np1 = c->newest_isakmp_sa == st->st_serialno
-               ? "; newest ISAKMP" : "";
-       const char *np2 = c->newest_ipsec_sa == st->st_serialno
-               ? "; newest IPSEC" : "";
-       /* XXX spd-enum */
-       const char *eo = c->spd.eroute_owner == st->st_serialno
-               ? "; eroute owner" : "";
-       const char *dpd = (all && st->st_dpd && c->dpd_action != DPD_ACTION_NONE)
-                                         ? "; DPD active" : "";
-
-       passert(st->st_event != 0);
-
-       fmt_conn_instance(c, inst);
-
-       snprintf(state_buf, state_buf_len
-               , "#%lu: \"%s\"%s %s (%s); %N in %lds%s%s%s%s"
-               , st->st_serialno
-               , c->name, inst
-               , enum_name(&state_names, st->st_state)
-               , state_story[st->st_state]
-               , timer_event_names, st->st_event->ev_type
-               , delta
-               , np1, np2, eo, dpd);
-
-       /* print out SPIs if SAs are established */
-       if (state_buf2_len != 0)
-               state_buf2[0] = '\0';   /* default to empty */
-       if (IS_IPSEC_SA_ESTABLISHED(st->st_state))
-       {
-
-               bool tunnel;
-               char buf[SATOT_BUF*6 + 2*20 + 1];
-               const char *p_end = buf + sizeof(buf);
-               char *p = buf;
-
-#       define add_said(adst, aspi, aproto) { \
-                       ip_said s; \
-                       \
-                       initsaid(adst, aspi, aproto, &s); \
-                       if (p < p_end - 1) \
-                       { \
-                               *p++ = ' '; \
-                               p += satot(&s, 0, p, p_end - p) - 1; \
-                       } \
-               }
-
-#       define add_sa_info(st, inbound) { \
-                       u_int bytes; \
-                       time_t use_time; \
-                       \
-                       if (get_sa_info(st, inbound, &bytes, &use_time)) \
-                       { \
-                               p += snprintf(p, p_end - p, " (%'u bytes", bytes); \
-                               if (bytes > 0 && use_time != UNDEFINED_TIME) \
-                                       p += snprintf(p, p_end - p, ", %ds ago", (int)(now - use_time)); \
-                               p += snprintf(p, p_end - p, ")"); \
-                       } \
-               }
-
-               *p = '\0';
-               if (st->st_ah.present)
-               {
-                       add_said(&c->spd.that.host_addr, st->st_ah.attrs.spi, SA_AH);
-                       add_said(&c->spd.this.host_addr, st->st_ah.our_spi, SA_AH);
-               }
-               if (st->st_esp.present)
-               {
-                       time_t now = time_monotonic(NULL);
-
-                       add_said(&c->spd.that.host_addr, st->st_esp.attrs.spi, SA_ESP);
-                       add_sa_info(st, FALSE);
-                       add_said(&c->spd.this.host_addr, st->st_esp.our_spi, SA_ESP);
-                       add_sa_info(st, TRUE);
-               }
-               if (st->st_ipcomp.present)
-               {
-                       add_said(&c->spd.that.host_addr, st->st_ipcomp.attrs.spi, SA_COMP);
-                       add_said(&c->spd.this.host_addr, st->st_ipcomp.our_spi, SA_COMP);
-               }
-               tunnel =  st->st_ah.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL
-                          || st->st_esp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL
-                          || st->st_ipcomp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL;
-               p += snprintf(p, p_end - p, "; %s", tunnel? "tunnel":"transport");
-
-               snprintf(state_buf2, state_buf2_len
-                       , "#%lu: \"%s\"%s%s"
-                       , st->st_serialno
-                       , c->name, inst
-                       , buf);
-
-#       undef add_said
-#       undef add_sa_info
-       }
-}
-
-/*
- * sorting logic is:
- *
- *  name
- *  type
- *  instance#
- *  isakmp_sa (XXX probably wrong)
- *
- */
-static int state_compare(const void *a, const void *b)
-{
-       const struct state *sap = *(const struct state *const *)a;
-       connection_t *ca = sap->st_connection;
-       const struct state *sbp = *(const struct state *const *)b;
-       connection_t *cb = sbp->st_connection;
-
-       /* DBG_log("comparing %s to %s", ca->name, cb->name); */
-
-       return connection_compare(ca, cb);
-}
-
-void show_states_status(bool all, const char *name)
-{
-       time_t n = now();
-       int i;
-       char state_buf[LOG_WIDTH];
-       char state_buf2[LOG_WIDTH];
-       int count;
-       struct state **array;
-
-       /* make count of states */
-       count = 0;
-       for (i = 0; i < STATE_TABLE_SIZE; i++)
-       {
-               struct state *st;
-
-               for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
-               {
-                       if (name == NULL || streq(name, st->st_connection->name))
-                               count++;
-               }
-       }
-
-       /* build the array */
-       array = malloc(sizeof(struct state *)*count);
-       count = 0;
-       for (i = 0; i < STATE_TABLE_SIZE; i++)
-       {
-               struct state *st;
-
-               for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
-               {
-                       if (name == NULL || streq(name, st->st_connection->name))
-                               array[count++]=st;
-               }
-       }
-
-       /* sort it! */
-       qsort(array, count, sizeof(struct state *), state_compare);
-
-       /* now print sorted results */
-       for (i = 0; i < count; i++)
-       {
-               struct state *st;
-
-               st = array[i];
-
-               fmt_state(all, st, n
-                                 , state_buf, sizeof(state_buf)
-                                 , state_buf2, sizeof(state_buf2));
-               whack_log(RC_COMMENT, state_buf);
-               if (state_buf2[0] != '\0')
-                       whack_log(RC_COMMENT, state_buf2);
-
-               /* show any associated pending Phase 2s */
-               if (IS_PHASE1(st->st_state))
-                       show_pending_phase2(st->st_connection->host_pair, st);
-       }
-       if (count > 0)
-               whack_log(RC_COMMENT, BLANK_FORMAT);    /* spacer */
-
-       /* free the array */
-       free(array);
-}
-
-/* Muck with high-order 16 bits of this SPI in order to make
- * the corresponding SAID unique.
- * Its low-order 16 bits hold a well-known IPCOMP CPI.
- * Oh, and remember that SPIs are stored in network order.
- * Kludge!!!  So I name it with the non-English word "uniquify".
- * If we can't find one easily, return 0 (a bad SPI,
- * no matter what order) indicating failure.
- */
-ipsec_spi_t uniquify_his_cpi(ipsec_spi_t cpi, struct state *st)
-{
-       int tries = 0;
-       int i;
-       rng_t *rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
-
-startover:
-
-       /* network order makes first two bytes our target */
-       rng->get_bytes(rng, 2, (u_char *)&cpi);
-
-       /* Make sure that the result is unique.
-        * Hard work.  If there is no unique value, we'll loop forever!
-        */
-       for (i = 0; i < STATE_TABLE_SIZE; i++)
-       {
-               struct state *s;
-
-               for (s = statetable[i]; s != NULL; s = s->st_hashchain_next)
-               {
-                       if (s->st_ipcomp.present
-                       && sameaddr(&s->st_connection->spd.that.host_addr
-                         , &st->st_connection->spd.that.host_addr)
-                       && cpi == s->st_ipcomp.attrs.spi)
-                       {
-                               if (++tries == 20)
-                               {
-                                       rng->destroy(rng);
-                                       return 0;   /* FAILURE */
-                               }
-                               goto startover;
-                       }
-               }
-       }
-       rng->destroy(rng);
-       return cpi;
-}
-
-/*
- * Local Variables:
- * c-basic-offset:4
- * End:
- */
diff --git a/src/pluto/state.h b/src/pluto/state.h
deleted file mode 100644 (file)
index a307d9f..0000000
+++ /dev/null
@@ -1,274 +0,0 @@
-/* state and event objects
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2001  D. Hugh Redelmeier.
- * Copyright (C) 2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef _STATE_H
-#define _STATE_H
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <time.h>
-
-#include <crypto/diffie_hellman.h>
-
-#include "defs.h"
-#include "connections.h"
-
-/* Message ID mechanism.
- *
- * A Message ID is contained in each IKE message header.
- * For Phase 1 exchanges (Main and Aggressive), it will be zero.
- * For other exchanges, which must be under the protection of an
- * ISAKMP SA, the Message ID must be unique within that ISAKMP SA.
- * Effectively, this labels the message as belonging to a particular
- * exchange.
- *
- * RFC2408 "ISAKMP" 3.1 "ISAKMP Header Format" (near end) states that
- * the Message ID must be unique.  We interpret this to be "unique within
- * one ISAKMP SA".
- *
- * BTW, we feel this uniqueness allows rekeying to be somewhat simpler
- * than specified by draft-jenkins-ipsec-rekeying-06.txt.
- */
-
-typedef u_int32_t msgid_t;      /* Network order! */
-#define MAINMODE_MSGID    ((msgid_t) 0)
-
-struct state;   /* forward declaration of tag */
-extern bool reserve_msgid(struct state *isakmp_sa, msgid_t msgid);
-extern msgid_t generate_msgid(struct state *isakmp_sa);
-
-
-/* Oakley (Phase 1 / Main Mode) transform and attributes
- * This is a flattened/decoded version of what is represented
- * in the Transaction Payload.
- * Names are chosen to match corresponding names in state.
- */
-struct oakley_trans_attrs {
-       u_int16_t encrypt;          /* Encryption algorithm */
-       u_int16_t enckeylen;        /* encryption key len (bits) */
-       const struct encrypt_desc *encrypter;   /* package of encryption routines */
-       u_int16_t hash;             /* Hash algorithm */
-       const struct hash_desc *hasher;         /* package of hashing routines */
-       u_int16_t auth;             /* Authentication method */
-       const struct dh_desc *group;            /* Diffie-Hellman group */
-       time_t life_seconds;        /* When this SA expires (seconds) */
-       u_int32_t life_kilobytes;   /* When this SA is exhausted (kilobytes) */
-#if 0 /* not yet */
-       u_int16_t prf;              /* Pseudo Random Function */
-#endif
-};
-
-/* IPsec (Phase 2 / Quick Mode) transform and attributes
- * This is a flattened/decoded version of what is represented
- * by a Transaction Payload.  There may be one for AH, one
- * for ESP, and a funny one for IPCOMP.
- */
-struct ipsec_trans_attrs {
-       u_int8_t transid;   /* transform id */
-       ipsec_spi_t spi;    /* his SPI */
-       time_t life_seconds;                /* When this SA expires */
-       u_int32_t life_kilobytes;   /* When this SA expires */
-       u_int16_t encapsulation;
-       u_int16_t auth;
-       u_int16_t key_len;
-       u_int16_t key_rounds;
-#if 0 /* not implemented yet */
-       u_int16_t cmprs_dict_sz;
-       u_int32_t cmprs_alg;
-#endif
-};
-
-/* IPsec per protocol state information */
-struct ipsec_proto_info {
-       bool present;       /* was this transform specified? */
-       struct ipsec_trans_attrs attrs;
-       ipsec_spi_t our_spi;
-       u_int16_t keymat_len;       /* same for both */
-       u_char *our_keymat;
-       u_char *peer_keymat;
-};
-
-/* state object: record the state of a (possibly nascent) SA
- *
- * Invariants (violated only during short transitions):
- * - each state object will be in statetable exactly once.
- * - each state object will always have a pending event.
- *   This prevents leaks.
- */
-struct state
-{
-       so_serial_t        st_serialno;            /* serial number (for seniority) */
-       so_serial_t        st_clonedfrom;          /* serial number of parent */
-
-       struct connection *st_connection;          /* connection for this SA */
-
-       int                st_whack_sock;          /* fd for our Whack TCP socket.
-                                                                                               * Single copy: close when freeing struct.
-                                                                                               */
-
-       struct msg_digest *st_suspended_md;        /* suspended state-transition */
-
-       struct oakley_trans_attrs st_oakley;
-
-       struct ipsec_proto_info st_ah;
-       struct ipsec_proto_info st_esp;
-       struct ipsec_proto_info st_ipcomp;
-       ipsec_spi_t        st_tunnel_in_spi;          /* KLUDGE */
-       ipsec_spi_t        st_tunnel_out_spi;         /* KLUDGE */
-
-       const struct dh_desc *st_pfs_group;        /* group for Phase 2 PFS */
-
-       u_int32_t          st_doi;                 /* Domain of Interpretation */
-       u_int32_t          st_situation;
-
-       lset_t             st_policy;              /* policy for IPsec SA */
-
-       msgid_t            st_msgid;               /* MSG-ID from header.  Network Order! */
-
-       /* only for a state representing an ISAKMP SA */
-       struct msgid_list  *st_used_msgids;        /* used-up msgids */
-
-/* symmetric stuff */
-
-  /* initiator stuff */
-       chunk_t            st_gi;                  /* Initiator public value */
-       u_int8_t           st_icookie[COOKIE_SIZE];/* Initiator Cookie */
-       chunk_t            st_ni;                  /* Ni nonce */
-
-  /* responder stuff */
-       chunk_t            st_gr;                  /* Responder public value */
-       u_int8_t           st_rcookie[COOKIE_SIZE];/* Responder Cookie */
-       chunk_t            st_nr;                  /* Nr nonce */
-
-
-  /* my stuff */
-
-       chunk_t            st_tpacket;             /* Transmitted packet */
-
-       /* Phase 2 ID payload info about my user */
-       u_int8_t           st_myuserprotoid;       /* IDcx.protoid */
-       u_int16_t          st_myuserport;
-
-  /* his stuff */
-
-       chunk_t            st_rpacket;             /* Received packet */
-
-       /* Phase 2 ID payload info about peer's user */
-       u_int8_t           st_peeruserprotoid;     /* IDcx.protoid */
-       u_int16_t          st_peeruserport;
-
-/* end of symmetric stuff */
-
-       diffie_hellman_t  *st_dh;                  /* Our local DH secret value */
-       chunk_t            st_shared;              /* Derived shared secret
-                                                                                               * Note: during Quick Mode,
-                                                                                               * presence indicates PFS
-                                                                                               * selected.
-                                                                                               */
-
-       /* In a Phase 1 state, preserve peer's public key after authentication */
-       struct pubkey     *st_peer_pubkey;
-
-       enum state_kind    st_state;               /* State of exchange */
-       u_int8_t           st_retransmit;          /* Number of retransmits */
-       unsigned long      st_try;                 /* number of times rekeying attempted */
-                                                                                          /* 0 means the only time */
-       time_t             st_margin;              /* life after EVENT_SA_REPLACE */
-       unsigned long      st_outbound_count;      /* traffic through eroute */
-       time_t             st_outbound_time;       /* time of last change to st_outbound_count */
-       chunk_t            st_p1isa;               /* Phase 1 initiator SA (Payload) for HASH */
-       chunk_t            st_skeyid;              /* Key material */
-       chunk_t            st_skeyid_d;            /* KM for non-ISAKMP key derivation */
-       chunk_t            st_skeyid_a;            /* KM for ISAKMP authentication */
-       chunk_t            st_skeyid_e;            /* KM for ISAKMP encryption */
-       u_char             st_iv[MAX_DIGEST_LEN];  /* IV for encryption */
-       u_char             st_new_iv[MAX_DIGEST_LEN];
-       u_char             st_ph1_iv[MAX_DIGEST_LEN]; /* IV at end if phase 1 */
-       unsigned int       st_iv_len;
-       unsigned int       st_new_iv_len;
-       unsigned int       st_ph1_iv_len;
-
-       chunk_t            st_enc_key;             /* Oakley Encryption key */
-
-       struct event      *st_event;               /* backpointer for certain events */
-       struct state      *st_hashchain_next;      /* Next in list */
-       struct state      *st_hashchain_prev;      /* Previous in list */
-
-       struct {
-               bool vars_set;
-               bool started;
-       } st_modecfg;
-
-       struct {
-               int attempt;
-               bool started;
-               bool status;
-       } st_xauth;
-
-       u_int32_t         nat_traversal;
-       ip_address        nat_oa;
-
-       /* RFC 3706 Dead Peer Detection */
-       bool                st_dpd;                 /* Peer supports DPD */
-       time_t              st_last_dpd;            /* Time of last DPD transmit */
-       u_int32_t           st_dpd_seqno;           /* Next R_U_THERE to send */
-       u_int32_t           st_dpd_expectseqno;     /* Next R_U_THERE_ACK to receive */
-       u_int32_t           st_dpd_peerseqno;       /* global variables */
-       struct event        *st_dpd_event;          /* backpointer for DPD events */
-
-       u_int32_t         st_seen_vendorid;         /* Bit field about recognized Vendor ID */
-};
-
-/* global variables */
-
-extern u_int16_t pluto_port;    /* Pluto's port */
-
-extern bool states_use_connection(struct connection *c);
-
-/* state functions */
-
-extern struct state *new_state(void);
-extern void init_states(void);
-extern void insert_state(struct state *st);
-extern void unhash_state(struct state *st);
-extern void release_whack(struct state *st);
-extern void state_eroute_usage(ip_subnet *ours, ip_subnet *his
-       , unsigned long count, time_t nw);
-extern void delete_state(struct state *st);
-extern void delete_states_by_connection(struct connection *c, bool relations);
-
-extern struct state
-       *duplicate_state(struct state *st),
-       *find_state(const u_char *icookie
-               , const u_char *rcookie
-               , const ip_address *peer
-               , msgid_t msgid),
-       *state_with_serialno(so_serial_t sn),
-       *find_phase2_state_to_delete(const struct state *p1st, u_int8_t protoid
-               , ipsec_spi_t spi, bool *bogus),
-       *find_phase1_state(const struct connection *c, lset_t ok_states),
-       *find_sender(size_t packet_len, u_char *packet);
-
-extern void show_states_status(bool all, const char *name);
-extern void for_each_state(void *(f)(struct state *, void *data), void *data);
-extern ipsec_spi_t uniquify_his_cpi(ipsec_spi_t cpi, struct state *st);
-extern void fmt_state(bool all, struct state *st, time_t n
-                                        , char *state_buf, size_t state_buf_len
-                                        , char *state_buf2, size_t state_buf_len2);
-extern void delete_states_by_peer(ip_address *peer);
-
-#endif /* _STATE_H */
diff --git a/src/pluto/timer.c b/src/pluto/timer.c
deleted file mode 100644 (file)
index 1d34d2c..0000000
+++ /dev/null
@@ -1,551 +0,0 @@
-/* timer event handling
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2001  D. Hugh Redelmeier.
- * Copyright (C) 2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <time.h>
-#include <unistd.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/queue.h>
-
-#include <freeswan.h>
-
-#include <library.h>
-#include <crypto/rngs/rng.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "connections.h"
-#include "state.h"
-#include "demux.h"
-#include "ipsec_doi.h"  /* needs demux.h and state.h */
-#include "kernel.h"
-#include "server.h"
-#include "log.h"
-#include "timer.h"
-#include "whack.h"
-#include "nat_traversal.h"
-
-/**
- * monotonic version of time(3)
- */
-time_t now(void)
-{
-       return time_monotonic(NULL);
-}
-
-/* This file has the event handling routines. Events are
- * kept as a linked list of event structures. These structures
- * have information like event type, expiration time and a pointer
- * to event specific data (for example, to a state structure).
- */
-
-static struct event *evlist = (struct event *) NULL;
-
-/**
- * This routine places an event in the event list.
- */
-void event_schedule(enum event_type type, time_t tm, struct state *st)
-{
-       struct event *ev = malloc_thing(struct event);
-
-       ev->ev_type = type;
-       ev->ev_time = tm + now();
-       ev->ev_state = st;
-
-       /* If the event is associated with a state, put a backpointer to the
-        * event in the state object, so we can find and delete the event
-        * if we need to (for example, if we receive a reply).
-        */
-       if (st != NULL)
-       {
-               if (type == EVENT_DPD || type == EVENT_DPD_TIMEOUT)
-               {
-                       passert(st->st_dpd_event == NULL);
-                       st->st_dpd_event = ev;
-               }
-               else
-               {
-                       passert(st->st_event == NULL);
-                       st->st_event = ev;
-               }
-       }
-
-       DBG(DBG_CONTROL,
-               if (st == NULL)
-                       DBG_log("inserting event %N, timeout in %lu seconds"
-                               , timer_event_names, type, (unsigned long)tm);
-               else
-                       DBG_log("inserting event %N, timeout in %lu seconds for #%lu"
-                               , timer_event_names, type, (unsigned long)tm
-                               , ev->ev_state->st_serialno));
-
-       if (evlist == (struct event *) NULL
-       || evlist->ev_time >= ev->ev_time)
-       {
-               ev->ev_next = evlist;
-               evlist = ev;
-       }
-       else
-       {
-               struct event *evt;
-
-               for (evt = evlist; evt->ev_next != NULL; evt = evt->ev_next)
-                       if (evt->ev_next->ev_time >= ev->ev_time)
-                               break;
-
-#ifdef NEVER    /* this seems to be overkill */
-               DBG(DBG_CONTROL,
-                       if (evt->ev_state == NULL)
-                               DBG_log("event added after event %N"
-                                       , timer_event_names, evt->ev_type);
-                       else
-                               DBG_log("event added after event %N for #%lu"
-                                       , timer_event_names, evt->ev_type,
-                                       , evt->ev_state->st_serialno));
-#endif /* NEVER */
-
-               ev->ev_next = evt->ev_next;
-               evt->ev_next = ev;
-       }
-}
-
-/**
- * Generate the secret value for responder cookies, and
- * schedule an event for refresh.
- */
-bool init_secret(void)
-{
-       rng_t *rng;
-
-       rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
-
-       if (rng == NULL)
-       {
-               plog("secret initialization failed, no RNG supported");
-               return FALSE;
-       }
-       rng->get_bytes(rng, sizeof(secret_of_the_day), secret_of_the_day);
-       rng->destroy(rng);
-    event_schedule(EVENT_REINIT_SECRET, EVENT_REINIT_SECRET_DELAY, NULL);
-       return true;
-}
-
-/**
- * Handle the first event on the list.
- */
-void handle_timer_event(void)
-{
-       time_t tm;
-       struct event *ev = evlist;
-       int type;
-       struct state *st;
-       connection_t *c = NULL;
-       ip_address peer;
-
-       if (ev == (struct event *) NULL)    /* Just paranoid */
-       {
-               DBG(DBG_CONTROL, DBG_log("empty event list, yet we're called"));
-               return;
-       }
-
-       type = ev->ev_type;
-       st = ev->ev_state;
-
-       tm = now();
-
-       if (tm < ev->ev_time)
-       {
-               DBG(DBG_CONTROL, DBG_log("called while no event expired (%lu/%lu, %N)"
-                       , (unsigned long)tm, (unsigned long)ev->ev_time
-                       , timer_event_names, type));
-
-               /* This will happen if the most close-to-expire event was
-                * a retransmission or cleanup, and we received a packet
-                * at the same time as the event expired. Due to the processing
-                * order in call_server(), the packet processing will happen first,
-                * and the event will be removed.
-                */
-               return;
-       }
-
-       evlist = evlist->ev_next;           /* Ok, we'll handle this event */
-
-       DBG(DBG_CONTROL,
-               if (evlist != (struct event *) NULL)
-                       DBG_log("event after this is %N in %ld seconds"
-                               , timer_event_names, evlist->ev_type
-                               , (long) (evlist->ev_time - tm)));
-
-       /* for state-associated events, pick up the state pointer
-        * and remove the backpointer from the state object.
-        * We'll eventually either schedule a new event, or delete the state.
-        */
-       passert(GLOBALS_ARE_RESET());
-       if (st != NULL)
-       {
-               c = st->st_connection;
-               if (type  == EVENT_DPD || type == EVENT_DPD_TIMEOUT)
-               {
-                       passert(st->st_dpd_event == ev);
-                       st->st_dpd_event = NULL;
-               }
-               else
-               {
-                       passert(st->st_event == ev);
-                       st->st_event = NULL;
-               }
-               peer = c->spd.that.host_addr;
-               set_cur_state(st);
-       }
-
-       switch (type)
-       {
-               case EVENT_REINIT_SECRET:
-                       passert(st == NULL);
-                       DBG(DBG_CONTROL, DBG_log("event EVENT_REINIT_SECRET handled"));
-                       init_secret();
-                       break;
-
-               case EVENT_LOG_DAILY:
-                       daily_log_event();
-                       break;
-
-               case EVENT_RETRANSMIT:
-                       /* Time to retransmit, or give up.
-                        *
-                        * Generally, we'll only try to send the message
-                        * MAXIMUM_RETRANSMISSIONS times.  Each time we double
-                        * our patience.
-                        *
-                        * As a special case, if this is the first initiating message
-                        * of a Main Mode exchange, and we have been directed to try
-                        * forever, we'll extend the number of retransmissions to
-                        * MAXIMUM_RETRANSMISSIONS_INITIAL times, with all these
-                        * extended attempts having the same patience.  The intention
-                        * is to reduce the bother when nobody is home.
-                        */
-                       {
-                               time_t delay = 0;
-
-                               DBG(DBG_CONTROL, DBG_log(
-                                       "handling event EVENT_RETRANSMIT for %s \"%s\" #%lu"
-                                       , ip_str(&peer), c->name, st->st_serialno));
-
-                               if (st->st_retransmit < MAXIMUM_RETRANSMISSIONS)
-                                       delay = EVENT_RETRANSMIT_DELAY_0 << (st->st_retransmit + 1);
-                               else if (st->st_state == STATE_MAIN_I1
-                               && c->sa_keying_tries == 0
-                               && st->st_retransmit < MAXIMUM_RETRANSMISSIONS_INITIAL)
-                                       delay = EVENT_RETRANSMIT_DELAY_0 << MAXIMUM_RETRANSMISSIONS;
-
-                               if (delay != 0)
-                               {
-                                       st->st_retransmit++;
-                                       whack_log(RC_RETRANSMISSION
-                                               , "%s: retransmission; will wait %lus for response"
-                                               , enum_name(&state_names, st->st_state)
-                                               , (unsigned long)delay);
-                                       send_packet(st, "EVENT_RETRANSMIT");
-                                       event_schedule(EVENT_RETRANSMIT, delay, st);
-                               }
-                               else
-                               {
-                                       /* check if we've tried rekeying enough times.
-                                        * st->st_try == 0 means that this should be the only try.
-                                        * c->sa_keying_tries == 0 means that there is no limit.
-                                        */
-                                       unsigned long try = st->st_try;
-                                       unsigned long try_limit = c->sa_keying_tries;
-                                       const char *details = "";
-
-                                       switch (st->st_state)
-                                       {
-                                       case STATE_MAIN_I3:
-                                               details = ".  Possible authentication failure:"
-                                                       " no acceptable response to our"
-                                                       " first encrypted message";
-                                               break;
-                                       case STATE_MAIN_I1:
-                                               details = ".  No response (or no acceptable response) to our"
-                                                       " first IKE message";
-                                               break;
-                                       case STATE_QUICK_I1:
-                                               if (c->newest_ipsec_sa == SOS_NOBODY)
-                                                       details = ".  No acceptable response to our"
-                                                               " first Quick Mode message:"
-                                                               " perhaps peer likes no proposal";
-                                               break;
-                                       default:
-                                               break;
-                                       }
-                                       loglog(RC_NORETRANSMISSION
-                                               , "max number of retransmissions (%d) reached %s%s"
-                                               , st->st_retransmit
-                                               , enum_show(&state_names, st->st_state), details);
-                                       if (try != 0 && try != try_limit)
-                                       {
-                                               /* A lot like EVENT_SA_REPLACE, but over again.
-                                                * Since we know that st cannot be in use,
-                                                * we can delete it right away.
-                                                */
-                                               char story[80]; /* arbitrary limit */
-
-                                               try++;
-                                               snprintf(story, sizeof(story), try_limit == 0
-                                                       ? "starting keying attempt %ld of an unlimited number"
-                                                       : "starting keying attempt %ld of at most %ld"
-                                                       , try, try_limit);
-
-                                               if (st->st_whack_sock != NULL_FD)
-                                               {
-                                                       /* Release whack because the observer will get bored. */
-                                                       loglog(RC_COMMENT, "%s, but releasing whack"
-                                                               , story);
-                                                       release_pending_whacks(st, story);
-                                               }
-                                               else
-                                               {
-                                                       /* no whack: just log to syslog */
-                                                       plog("%s", story);
-                                               }
-                                               ipsecdoi_replace(st, try);
-                                       }
-                                       delete_state(st);
-                               }
-                       }
-                       break;
-
-               case EVENT_SA_REPLACE:
-               case EVENT_SA_REPLACE_IF_USED:
-                       {
-                               so_serial_t newest = IS_PHASE1(st->st_state)
-                                       ? c->newest_isakmp_sa : c->newest_ipsec_sa;
-
-                               if (newest != st->st_serialno
-                               && newest != SOS_NOBODY)
-                               {
-                                       /* not very interesting: no need to replace */
-                                       DBG(DBG_LIFECYCLE
-                                               , plog("not replacing stale %s SA: #%lu will do"
-                                                       , IS_PHASE1(st->st_state)? "ISAKMP" : "IPsec"
-                                                       , newest));
-                               }
-                               else if (type == EVENT_SA_REPLACE_IF_USED
-                               && st->st_outbound_time <= tm - c->sa_rekey_margin)
-                               {
-                                       /* we observed no recent use: no need to replace
-                                        *
-                                        * The sampling effects mean that st_outbound_time
-                                        * could be up to SHUNT_SCAN_INTERVAL more recent
-                                        * than actual traffic because the sampler looks at change
-                                        * over that interval.
-                                        * st_outbound_time could also not yet reflect traffic
-                                        * in the last SHUNT_SCAN_INTERVAL.
-                                        * We expect that SHUNT_SCAN_INTERVAL is smaller than
-                                        * c->sa_rekey_margin so that the effects of this will
-                                        * be unimportant.
-                                        * This is just an optimization: correctness is not
-                                        * at stake.
-                                        *
-                                        * Note: we are abusing the DBG mechanism to control
-                                        * normal log output.
-                                        */
-                                       DBG(DBG_LIFECYCLE
-                                               , plog("not replacing stale %s SA: inactive for %lus"
-                                                       , IS_PHASE1(st->st_state)? "ISAKMP" : "IPsec"
-                                                       , (unsigned long)(tm - st->st_outbound_time)));
-                               }
-                               else
-                               {
-                                       DBG(DBG_LIFECYCLE
-                                               , plog("replacing stale %s SA"
-                                                       , IS_PHASE1(st->st_state)? "ISAKMP" : "IPsec"));
-                                       ipsecdoi_replace(st, 1);
-                               }
-                               delete_dpd_event(st);
-                               event_schedule(EVENT_SA_EXPIRE, st->st_margin, st);
-                       }
-                       break;
-
-               case EVENT_SA_EXPIRE:
-                       {
-                               const char *satype;
-                               so_serial_t latest;
-
-                               if (IS_PHASE1(st->st_state))
-                               {
-                                       satype = "ISAKMP";
-                                       latest = c->newest_isakmp_sa;
-                               }
-                               else
-                               {
-                                       satype = "IPsec";
-                                       latest = c->newest_ipsec_sa;
-                               }
-
-                               if (st->st_serialno != latest)
-                               {
-                                       /* not very interesting: already superseded */
-                                       DBG(DBG_LIFECYCLE
-                                               , plog("%s SA expired (superseded by #%lu)"
-                                                       , satype, latest));
-                               }
-                               else
-                               {
-                                       plog("%s SA expired (%s)", satype
-                                               , (c->policy & POLICY_DONT_REKEY)
-                                                       ? "--dontrekey"
-                                                       : "LATEST!"
-                                               );
-                               }
-                       }
-                       /* FALLTHROUGH */
-               case EVENT_SO_DISCARD:
-                       /* Delete this state object.  It must be in the hash table. */
-                       delete_state(st);
-                       break;
-
-               case EVENT_DPD:
-                       dpd_outI(st);
-                       break;
-               case EVENT_DPD_TIMEOUT:
-                       dpd_timeout(st);
-                       break;
-               case EVENT_NAT_T_KEEPALIVE:
-                       nat_traversal_ka_event();
-                       break;
-               default:
-                       loglog(RC_LOG_SERIOUS, "INTERNAL ERROR: ignoring unknown expiring event %N"
-                               , timer_event_names, type);
-       }
-
-       free(ev);
-       reset_cur_state();
-}
-
-/**
- * Return the time until the next event in the queue
- * expires (never negative), or -1 if no jobs in queue.
- */
-long next_event(void)
-{
-       time_t tm;
-
-       if (evlist == (struct event *) NULL)
-               return -1;
-
-       tm = now();
-
-       DBG(DBG_CONTROL,
-               if (evlist->ev_state == NULL)
-                       DBG_log("next event %N in %ld seconds"
-                               , timer_event_names, evlist->ev_type
-                               , (long)evlist->ev_time - (long)tm);
-               else
-                       DBG_log("next event %N in %ld seconds for #%lu"
-                               , timer_event_names, evlist->ev_type
-                               , (long)evlist->ev_time - (long)tm
-                               , evlist->ev_state->st_serialno));
-
-       if (evlist->ev_time - tm <= 0)
-               return 0;
-       else
-               return evlist->ev_time - tm;
-}
-
-/**
- * Delete an event.
- */
-void delete_event(struct state *st)
-{
-       if (st->st_event != (struct event *) NULL)
-       {
-               struct event **ev;
-
-               for (ev = &evlist; ; ev = &(*ev)->ev_next)
-               {
-                       if (*ev == NULL)
-                       {
-                               DBG(DBG_CONTROL, DBG_log("event %N to be deleted not found",
-                                       timer_event_names, st->st_event->ev_type));
-                               break;
-                       }
-                       if ((*ev) == st->st_event)
-                       {
-                               *ev = (*ev)->ev_next;
-
-                               if (st->st_event->ev_type == EVENT_RETRANSMIT)
-                               {
-                                       st->st_retransmit = 0;
-                               }
-                               free(st->st_event);
-                               st->st_event = (struct event *) NULL;
-
-                               break;
-                       }
-               }
-       }
-}
-
-/**
- * Delete a DPD event.
- */
-void delete_dpd_event(struct state *st)
-{
-       if (st->st_dpd_event != (struct event *) NULL)
-       {
-               struct event **ev;
-
-               for (ev = &evlist; ; ev = &(*ev)->ev_next)
-               {
-                       if (*ev == NULL)
-                       {
-                               DBG(DBG_CONTROL, DBG_log("event %N to be deleted not found",
-                                       timer_event_names, st->st_dpd_event->ev_type));
-                               break;
-                       }
-                       if ((*ev) == st->st_dpd_event)
-                       {
-                               *ev = (*ev)->ev_next;
-                               free(st->st_dpd_event);
-                               st->st_dpd_event = (struct event *) NULL;
-                               break;
-                       }
-               }
-       }
-}
-
-/**
- * Free remaining events
- */
-void free_events(void)
-{
-       struct event *ev_tmp, *ev;
-
-       ev = evlist;
-       evlist = NULL;
-
-       while (ev)
-       {
-               ev_tmp = ev;
-               ev = ev->ev_next;
-               free(ev_tmp);
-       }
-}
-
diff --git a/src/pluto/timer.h b/src/pluto/timer.h
deleted file mode 100644 (file)
index c8e9b72..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/* timing machinery
- * Copyright (C) 1998-2001  D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-extern time_t now(void);        /* careful version of time(2) */
-
-struct state;   /* forward declaration */
-
-struct event
-{
-       time_t          ev_time;
-       int             ev_type;        /* Event type */
-       struct state   *ev_state;       /* Pointer to relevant state (if any) */
-       struct event   *ev_next;        /* Pointer to next event */
-};
-
-extern void event_schedule(enum event_type type, time_t tm, struct state *st);
-extern void handle_timer_event(void);
-extern long next_event(void);
-extern void delete_event(struct state *st);
-extern void delete_dpd_event(struct state *st);
-extern void daily_log_event(void);
-extern void free_events(void);
-extern bool init_secret(void);
diff --git a/src/pluto/vendor.c b/src/pluto/vendor.c
deleted file mode 100644 (file)
index 6cc599d..0000000
+++ /dev/null
@@ -1,511 +0,0 @@
-/* ISAKMP VendorID
- * Copyright (C) 2002-2005 Mathieu Lafon - Arkoon Network Security
- * Copyright (C) 2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <sys/queue.h>
-#include <freeswan.h>
-
-#include <library.h>
-#include <crypto/hashers/hasher.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "connections.h"
-#include "packet.h"
-#include "demux.h"
-#include "whack.h"
-#include "vendor.h"
-#include "kernel.h"
-#include "nat_traversal.h"
-
-/**
- * Unknown/Special VID:
- *
- * SafeNet SoftRemote 8.0.0:
- *  47bbe7c993f1fc13b4e6d0db565c68e5010201010201010310382e302e3020284275696c6420313029000000
- *  >> 382e302e3020284275696c6420313029 = '8.0.0 (Build 10)'
- *  da8e937880010000
- *
- * SafeNet SoftRemote 9.0.1
- *  47bbe7c993f1fc13b4e6d0db565c68e5010201010201010310392e302e3120284275696c6420313229000000
- *  >> 392e302e3120284275696c6420313229 = '9.0.1 (Build 12)'
- *  da8e937880010000
- *
- * Netscreen:
- *  d6b45f82f24bacb288af59a978830ab7
- *  cf49908791073fb46439790fdeb6aeed981101ab0000000500000300
- *
- * Cisco:
- *  1f07f70eaa6514d3b0fa96542a500300 (VPN 3000 version 3.0.0)
- *  1f07f70eaa6514d3b0fa96542a500301 (VPN 3000 version 3.0.1)
- *  1f07f70eaa6514d3b0fa96542a500305 (VPN 3000 version 3.0.5)
- *  1f07f70eaa6514d3b0fa96542a500407 (VPN 3000 version 4.0.7)
- *  (Can you see the pattern?)
- *  afcad71368a1f1c96b8696fc77570100 (Non-RFC Dead Peer Detection ?)
- *  c32364b3b4f447eb17c488ab2a480a57
- *  6d761ddc26aceca1b0ed11fabbb860c4
- *  5946c258f99a1a57b03eb9d1759e0f24 (From a Cisco VPN 3k)
- *  ebbc5b00141d0c895e11bd395902d690 (From a Cisco VPN 3k)
- *
- * Microsoft L2TP (???):
- *  47bbe7c993f1fc13b4e6d0db565c68e5010201010201010310382e312e3020284275696c6420313029000000
- *  >> 382e312e3020284275696c6420313029 = '8.1.0 (Build 10)'
- *  3025dbd21062b9e53dc441c6aab5293600000000
- *  da8e937880010000
- *
- * 3COM-superstack
- *    da8e937880010000
- *    404bf439522ca3f6
- *
-
- * If someone know what they mean, mail me.
- */
-
-#define MAX_LOG_VID_LEN    32
-
-#define VID_KEEP                   0x0000
-#define VID_MD5HASH                0x0001
-#define VID_STRING                 0x0002
-#define VID_FSWAN_HASH             0x0004
-
-#define VID_SUBSTRING_DUMPHEXA     0x0100
-#define VID_SUBSTRING_DUMPASCII    0x0200
-#define VID_SUBSTRING_MATCH        0x0400
-#define VID_SUBSTRING  (VID_SUBSTRING_DUMPHEXA | VID_SUBSTRING_DUMPASCII | VID_SUBSTRING_MATCH)
-
-struct vid_struct {
-               enum known_vendorid id;
-               unsigned short flags;
-               const char *data;
-               const char *descr;
-               chunk_t vid;
-};
-
-#define DEC_MD5_VID_D(id,str,descr) \
-               { VID_##id, VID_MD5HASH, str, descr, { NULL, 0 } },
-#define DEC_MD5_VID(id,str) \
-               { VID_##id, VID_MD5HASH, str, NULL, { NULL, 0 } },
-
-static struct vid_struct _vid_tab[] = {
-
-               /* Implementation names */
-
-               { VID_OPENPGP, VID_STRING, "OpenPGP10171", "OpenPGP", { NULL, 0 } },
-
-               DEC_MD5_VID(KAME_RACOON, "KAME/racoon")
-
-               { VID_MS_NT5, VID_MD5HASH | VID_SUBSTRING_DUMPHEXA,
-                               "MS NT5 ISAKMPOAKLEY", NULL, { NULL, 0 } },
-
-               DEC_MD5_VID(SSH_SENTINEL, "SSH Sentinel")
-               DEC_MD5_VID(SSH_SENTINEL_1_1, "SSH Sentinel 1.1")
-               DEC_MD5_VID(SSH_SENTINEL_1_2, "SSH Sentinel 1.2")
-               DEC_MD5_VID(SSH_SENTINEL_1_3, "SSH Sentinel 1.3")
-               DEC_MD5_VID(SSH_SENTINEL_1_4, "SSH Sentinel 1.4")
-               DEC_MD5_VID(SSH_SENTINEL_1_4_1, "SSH Sentinel 1.4.1")
-
-               /* These ones come from SSH vendors.txt */
-               DEC_MD5_VID(SSH_IPSEC_1_1_0,
-                               "Ssh Communications Security IPSEC Express version 1.1.0")
-               DEC_MD5_VID(SSH_IPSEC_1_1_1,
-                               "Ssh Communications Security IPSEC Express version 1.1.1")
-               DEC_MD5_VID(SSH_IPSEC_1_1_2,
-                               "Ssh Communications Security IPSEC Express version 1.1.2")
-               DEC_MD5_VID(SSH_IPSEC_1_2_1,
-                               "Ssh Communications Security IPSEC Express version 1.2.1")
-               DEC_MD5_VID(SSH_IPSEC_1_2_2,
-                               "Ssh Communications Security IPSEC Express version 1.2.2")
-               DEC_MD5_VID(SSH_IPSEC_2_0_0,
-                               "SSH Communications Security IPSEC Express version 2.0.0")
-               DEC_MD5_VID(SSH_IPSEC_2_1_0,
-                               "SSH Communications Security IPSEC Express version 2.1.0")
-               DEC_MD5_VID(SSH_IPSEC_2_1_1,
-                               "SSH Communications Security IPSEC Express version 2.1.1")
-               DEC_MD5_VID(SSH_IPSEC_2_1_2,
-                               "SSH Communications Security IPSEC Express version 2.1.2")
-               DEC_MD5_VID(SSH_IPSEC_3_0_0,
-                               "SSH Communications Security IPSEC Express version 3.0.0")
-               DEC_MD5_VID(SSH_IPSEC_3_0_1,
-                               "SSH Communications Security IPSEC Express version 3.0.1")
-               DEC_MD5_VID(SSH_IPSEC_4_0_0,
-                               "SSH Communications Security IPSEC Express version 4.0.0")
-               DEC_MD5_VID(SSH_IPSEC_4_0_1,
-                               "SSH Communications Security IPSEC Express version 4.0.1")
-               DEC_MD5_VID(SSH_IPSEC_4_1_0,
-                               "SSH Communications Security IPSEC Express version 4.1.0")
-               DEC_MD5_VID(SSH_IPSEC_4_2_0,
-                               "SSH Communications Security IPSEC Express version 4.2.0")
-
-               /* note: md5('CISCO-UNITY') = 12f5f28c457168a9702d9fe274cc02d4 */
-               { VID_CISCO_UNITY, VID_KEEP, NULL, "Cisco-Unity",
-                 { "\x12\xf5\xf2\x8c\x45\x71\x68\xa9\x70\x2d\x9f\xe2\x74\xcc\x01\x00", 16 } },
-
-               { VID_CISCO3K, VID_KEEP | VID_SUBSTRING_MATCH, NULL, "Cisco VPN 3000 Series" ,
-                 { "\x1f\x07\xf7\x0e\xaa\x65\x14\xd3\xb0\xfa\x96\x54\x2a\x50", 14 } },
-
-               { VID_CISCO_IOS, VID_KEEP | VID_SUBSTRING_MATCH,
-                 NULL, "Cisco IOS Device", { "\x3e\x98\x40\x48", 4 } },
-
-               /*
-                * Timestep VID seen:
-                *   - 54494d455354455020312053475720313532302033313520322e303145303133
-                *     = 'TIMESTEP 1 SGW 1520 315 2.01E013'
-                */
-               { VID_TIMESTEP, VID_STRING | VID_SUBSTRING_DUMPASCII, "TIMESTEP",
-                               NULL, { NULL, 0 } },
-
-               /*
-                * Netscreen:
-                * 4865617274426561745f4e6f74696679386b0100  (HeartBeat_Notify + 386b0100)
-                */
-               { VID_MISC_HEARTBEAT_NOTIFY, VID_STRING | VID_SUBSTRING_DUMPHEXA,
-                               "HeartBeat_Notify", "HeartBeat Notify", { NULL, 0 } },
-               /*
-                * MacOS X
-                */
-               { VID_MACOSX, VID_STRING|VID_SUBSTRING_DUMPHEXA, "Mac OSX 10.x",
-                 "\x4d\xf3\x79\x28\xe9\xfc\x4f\xd1\xb3\x26\x21\x70\xd5\x15\xc6\x62", { NULL, 0 } },
-
-               /* NCP */
-               { VID_NCP_SERVER, VID_KEEP | VID_SUBSTRING_MATCH, NULL, "NCP Server",
-                       { "\xc6\xf5\x7a\xc3\x98\xf4\x93\x20\x81\x45\xb7\x58", 12 } },
-               { VID_NCP_CLIENT, VID_KEEP | VID_SUBSTRING_MATCH, NULL, "NCP Client",
-                       { "\xeb\x4c\x1b\x78\x8a\xfd\x4a\x9c\xb7\x73\x0a\x68", 12 } },
-
-               /*
-                * Windows Vista (and Windows Server 2008?)
-                */
-               DEC_MD5_VID(VISTA_AUTHIP, "MS-Negotiation Discovery Capable")
-               DEC_MD5_VID(VISTA_AUTHIP2, "IKE CGA version 1")
-               DEC_MD5_VID(VISTA_AUTHIP3, "MS-MamieExists")
-
-               /*
-                * strongSwan
-                */
-               DEC_MD5_VID(STRONGSWAN,       "strongSwan")
-
-               DEC_MD5_VID(STRONGSWAN_4_3_5, "strongSwan 4.3.5")
-               DEC_MD5_VID(STRONGSWAN_4_3_4, "strongSwan 4.3.4")
-               DEC_MD5_VID(STRONGSWAN_4_3_3, "strongSwan 4.3.3")
-               DEC_MD5_VID(STRONGSWAN_4_3_2, "strongSwan 4.3.2")
-               DEC_MD5_VID(STRONGSWAN_4_3_1, "strongSwan 4.3.1")
-               DEC_MD5_VID(STRONGSWAN_4_3_0, "strongSwan 4.3.0")
-               DEC_MD5_VID(STRONGSWAN_4_2_17,"strongSwan 4.2.17")
-               DEC_MD5_VID(STRONGSWAN_4_2_16,"strongSwan 4.2.16")
-               DEC_MD5_VID(STRONGSWAN_4_2_15,"strongSwan 4.2.15")
-               DEC_MD5_VID(STRONGSWAN_4_2_14,"strongSwan 4.2.14")
-               DEC_MD5_VID(STRONGSWAN_4_2_13,"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")
-               DEC_MD5_VID(STRONGSWAN_4_2_8, "strongSwan 4.2.8")
-               DEC_MD5_VID(STRONGSWAN_4_2_7, "strongSwan 4.2.7")
-               DEC_MD5_VID(STRONGSWAN_4_2_6, "strongSwan 4.2.6")
-               DEC_MD5_VID(STRONGSWAN_4_2_5, "strongSwan 4.2.5")
-               DEC_MD5_VID(STRONGSWAN_4_2_4, "strongSwan 4.2.4")
-               DEC_MD5_VID(STRONGSWAN_4_2_3, "strongSwan 4.2.3")
-               DEC_MD5_VID(STRONGSWAN_4_2_2, "strongSwan 4.2.2")
-               DEC_MD5_VID(STRONGSWAN_4_2_1, "strongSwan 4.2.1")
-               DEC_MD5_VID(STRONGSWAN_4_2_0, "strongSwan 4.2.0")
-               DEC_MD5_VID(STRONGSWAN_4_1_11,"strongSwan 4.1.11")
-               DEC_MD5_VID(STRONGSWAN_4_1_10,"strongSwan 4.1.10")
-               DEC_MD5_VID(STRONGSWAN_4_1_9, "strongSwan 4.1.9")
-               DEC_MD5_VID(STRONGSWAN_4_1_8, "strongSwan 4.1.8")
-               DEC_MD5_VID(STRONGSWAN_4_1_7, "strongSwan 4.1.7")
-               DEC_MD5_VID(STRONGSWAN_4_1_6, "strongSwan 4.1.6")
-               DEC_MD5_VID(STRONGSWAN_4_1_5, "strongSwan 4.1.5")
-               DEC_MD5_VID(STRONGSWAN_4_1_4, "strongSwan 4.1.4")
-               DEC_MD5_VID(STRONGSWAN_4_1_3, "strongSwan 4.1.3")
-               DEC_MD5_VID(STRONGSWAN_4_1_2, "strongSwan 4.1.2")
-               DEC_MD5_VID(STRONGSWAN_4_1_1, "strongSwan 4.1.1")
-               DEC_MD5_VID(STRONGSWAN_4_1_0, "strongSwan 4.1.0")
-
-               DEC_MD5_VID(STRONGSWAN_2_8_11,"strongSwan 2.8.11")
-               DEC_MD5_VID(STRONGSWAN_2_8_10,"strongSwan 2.8.10")
-               DEC_MD5_VID(STRONGSWAN_2_8_9, "strongSwan 2.8.9")
-               DEC_MD5_VID(STRONGSWAN_2_8_8, "strongSwan 2.8.8")
-               DEC_MD5_VID(STRONGSWAN_2_8_7, "strongSwan 2.8.7")
-               DEC_MD5_VID(STRONGSWAN_2_8_6, "strongSwan 2.8.6")
-               DEC_MD5_VID(STRONGSWAN_2_8_5, "strongSwan 2.8.5")
-               DEC_MD5_VID(STRONGSWAN_2_8_4, "strongSwan 2.8.4")
-               DEC_MD5_VID(STRONGSWAN_2_8_3, "strongSwan 2.8.3")
-               DEC_MD5_VID(STRONGSWAN_2_8_2, "strongSwan 2.8.2")
-               DEC_MD5_VID(STRONGSWAN_2_8_1, "strongSwan 2.8.1")
-               DEC_MD5_VID(STRONGSWAN_2_8_0, "strongSwan 2.8.0")
-
-               /* NAT-Traversal */
-
-               DEC_MD5_VID(NATT_STENBERG_01, "draft-stenberg-ipsec-nat-traversal-01")
-               DEC_MD5_VID(NATT_STENBERG_02, "draft-stenberg-ipsec-nat-traversal-02")
-               DEC_MD5_VID(NATT_HUTTUNEN, "ESPThruNAT")
-               DEC_MD5_VID(NATT_HUTTUNEN_ESPINUDP, "draft-huttunen-ipsec-esp-in-udp-00.txt")
-               DEC_MD5_VID(NATT_IETF_00, "draft-ietf-ipsec-nat-t-ike-00")
-               DEC_MD5_VID(NATT_IETF_02, "draft-ietf-ipsec-nat-t-ike-02")
-               /* hash in draft-ietf-ipsec-nat-t-ike-02 contains '\n'... Accept both */
-               DEC_MD5_VID_D(NATT_IETF_02_N, "draft-ietf-ipsec-nat-t-ike-02\n", "draft-ietf-ipsec-nat-t-ike-02_n")
-               DEC_MD5_VID(NATT_IETF_03, "draft-ietf-ipsec-nat-t-ike-03")
-               DEC_MD5_VID(NATT_RFC, "RFC 3947")
-
-               /* misc */
-
-               { VID_MISC_XAUTH, VID_KEEP, NULL, "XAUTH",
-                       { "\x09\x00\x26\x89\xdf\xd6\xb7\x12", 8 } },
-
-               { VID_MISC_DPD, VID_KEEP, NULL, "Dead Peer Detection",
-                       { "\xaf\xca\xd7\x13\x68\xa1\xf1\xc9\x6b\x86\x96\xfc\x77\x57\x01\x00", 16 } },
-
-               DEC_MD5_VID(MISC_FRAGMENTATION, "FRAGMENTATION")
-
-               DEC_MD5_VID(INITIAL_CONTACT, "Vid-Initial-Contact")
-
-               /**
-                * Cisco VPN 3000
-                */
-               { VID_MISC_FRAGMENTATION, VID_MD5HASH | VID_SUBSTRING_DUMPHEXA,
-                       "FRAGMENTATION", NULL, { NULL, 0 } },
-
-               /* -- */
-               { 0, 0, NULL, NULL, { NULL, 0 } }
-
-};
-
-static const char _hexdig[] = "0123456789abcdef";
-
-static int _vid_struct_init = 0;
-
-void init_vendorid(void)
-{
-       hasher_t *hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5);
-       struct vid_struct *vid;
-
-       for (vid = _vid_tab; vid->id; vid++)
-       {
-               if (vid->flags & VID_STRING)
-               {
-                       /** VendorID is a string **/
-                       vid->vid = chunk_create((u_char *)vid->data, strlen(vid->data));
-                       vid->vid = chunk_clone(vid->vid);
-               }
-               else if (vid->flags & VID_MD5HASH)
-               {
-                       chunk_t vid_data = { (u_char *)vid->data, strlen(vid->data) };
-
-                       /** VendorID is a string to hash with MD5 **/
-                       hasher->allocate_hash(hasher, vid_data, &vid->vid);
-               }
-
-               if (vid->descr == NULL)
-               {
-                       /** Find something to display **/
-                       vid->descr = vid->data;
-               }
-       }
-       hasher->destroy(hasher);
-       _vid_struct_init = 1;
-}
-
-void free_vendorid(void)
-{
-       struct vid_struct *vid;
-
-       for (vid = _vid_tab; vid->id; vid++)
-       {
-               if (vid->flags & (VID_STRING | VID_MD5HASH | VID_FSWAN_HASH))
-               {
-                       free(vid->vid.ptr);
-               }
-       }
-}
-
-static void handle_known_vendorid (struct msg_digest *md, const char *vidstr,
-                                                                  size_t len, struct vid_struct *vid)
-{
-       char vid_dump[128];
-       bool vid_useful = FALSE;
-       size_t i, j;
-
-       switch (vid->id)
-        {
-               /* Remote side is a strongSwan host */
-               case VID_STRONGSWAN:
-                       vid_useful = TRUE;
-                       break;
-
-               /* Remote side supports OpenPGP certificates */
-               case VID_OPENPGP:
-                       md->openpgp = TRUE;
-                       vid_useful = TRUE;
-                       break;
-
-               /* Remote side is a Windows 2000+ host */
-               case VID_MS_NT5:
-                       md->ms_nt5 = TRUE;
-                       vid_useful = TRUE;
-                       break;
-
-               /*
-                * Use most recent supported NAT-Traversal method and ignore the
-                * other ones (implementations will send all supported methods but
-                * only one will be used)
-                *
-                * Note: most recent == higher id in vendor.h
-                */
-               case VID_NATT_IETF_00:
-                       if (!nat_traversal_support_non_ike)
-                               break;
-                       if ((nat_traversal_enabled) && (!md->nat_traversal_vid))
-                       {
-                               md->nat_traversal_vid = vid->id;
-                               vid_useful = TRUE;
-                       }
-                       break;
-               case VID_NATT_IETF_02:
-               case VID_NATT_IETF_02_N:
-               case VID_NATT_IETF_03:
-               case VID_NATT_RFC:
-                       if (nat_traversal_support_port_floating
-                       && md->nat_traversal_vid < vid->id)
-                       {
-                               md->nat_traversal_vid = vid->id;
-                               vid_useful = TRUE;
-                       }
-                       break;
-
-               /* Remote side would like to do DPD with us on this connection */
-               case VID_MISC_DPD:
-                       md->dpd = TRUE;
-                       vid_useful = TRUE;
-                       break;
-               case VID_MISC_XAUTH:
-                       vid_useful = TRUE;
-                       break;
-               default:
-                       break;
-       }
-
-       if (vid->flags & VID_SUBSTRING_DUMPHEXA)
-       {
-               /* Dump description + Hexa */
-               memset(vid_dump, 0, sizeof(vid_dump));
-               snprintf(vid_dump, sizeof(vid_dump), "%s ",
-                                vid->descr ? vid->descr : "");
-               for (i = strlen(vid_dump), j = vid->vid.len;
-                        j < len && i < sizeof(vid_dump) - 2;
-                        i += 2, j++)
-               {
-                       vid_dump[i] = _hexdig[(vidstr[j] >> 4) & 0xF];
-                       vid_dump[i+1] = _hexdig[vidstr[j] & 0xF];
-               }
-       }
-       else if (vid->flags & VID_SUBSTRING_DUMPASCII)
-       {
-               /* Dump ASCII content */
-               memset(vid_dump, 0, sizeof(vid_dump));
-               for (i = 0; i < len && i < sizeof(vid_dump) - 1; i++)
-               {
-                       vid_dump[i] = (isprint(vidstr[i])) ? vidstr[i] : '.';
-               }
-       }
-       else
-       {
-               /* Dump description (descr) */
-               snprintf(vid_dump, sizeof(vid_dump), "%s",
-                                vid->descr ? vid->descr : "");
-       }
-
-       loglog(RC_LOG_SERIOUS, "%s Vendor ID payload [%s]",
-                       vid_useful ? "received" : "ignoring", vid_dump);
-}
-
-void handle_vendorid (struct msg_digest *md, const char *vid, size_t len)
-{
-       struct vid_struct *pvid;
-
-       if (!_vid_struct_init)
-               init_vendorid();
-
-       /*
-        * Find known VendorID in _vid_tab
-        */
-       for (pvid = _vid_tab; pvid->id; pvid++)
-       {
-               if (pvid->vid.ptr && vid && pvid->vid.len && len)
-               {
-                       if (pvid->vid.len == len)
-                       {
-                               if (memeq(pvid->vid.ptr, vid, len))
-                               {
-                                       handle_known_vendorid(md, vid, len, pvid);
-                                       return;
-                               }
-                       }
-                       else if ((pvid->vid.len < len) && (pvid->flags & VID_SUBSTRING))
-                       {
-                               if (memeq(pvid->vid.ptr, vid, pvid->vid.len))
-                               {
-                                       handle_known_vendorid(md, vid, len, pvid);
-                                       return;
-                               }
-                       }
-               }
-       }
-
-       /*
-        * Unknown VendorID. Log the beginning.
-        */
-       {
-               char log_vid[2*MAX_LOG_VID_LEN+1];
-               size_t i;
-
-               memset(log_vid, 0, sizeof(log_vid));
-
-               for (i = 0; i < len && i < MAX_LOG_VID_LEN; i++)
-               {
-                       log_vid[2*i] = _hexdig[(vid[i] >> 4) & 0xF];
-                       log_vid[2*i+1] = _hexdig[vid[i] & 0xF];
-               }
-               loglog(RC_LOG_SERIOUS, "ignoring Vendor ID payload [%s%s]",
-                          log_vid, (len>MAX_LOG_VID_LEN) ? "..." : "");
-       }
-}
-
-/**
- * Add a vendor id payload to the msg
- */
-bool out_vendorid (u_int8_t np, pb_stream *outs, enum known_vendorid vid)
-{
-       struct vid_struct *pvid;
-
-       if (!_vid_struct_init)
-               init_vendorid();
-
-       for (pvid = _vid_tab; pvid->id && pvid->id != vid; pvid++);
-
-       if (pvid->id != vid)
-               return STF_INTERNAL_ERROR; /* not found */
-       if (!pvid->vid.ptr)
-               return STF_INTERNAL_ERROR; /* not initialized */
-
-       DBG(DBG_EMITTING,
-               DBG_log("out_vendorid(): sending [%s]", pvid->descr)
-       )
-       return out_generic_raw(np, &isakmp_vendor_id_desc, outs,
-                               pvid->vid.ptr, pvid->vid.len, "V_ID");
-}
-
diff --git a/src/pluto/vendor.h b/src/pluto/vendor.h
deleted file mode 100644 (file)
index ac6b0d4..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-/* FreeS/WAN ISAKMP VendorID
- * Copyright (C) 2002-2003 Mathieu Lafon - Arkoon Network Security
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef _VENDOR_H_
-#define _VENDOR_H_
-
-enum known_vendorid {
-/* 1 - 100 : Implementation names */
-  VID_OPENPGP                   =  1,
-  VID_KAME_RACOON               =  2,
-  VID_MS_NT5                    =  3,
-  VID_SSH_SENTINEL              =  4,
-  VID_SSH_SENTINEL_1_1          =  5,
-  VID_SSH_SENTINEL_1_2          =  6,
-  VID_SSH_SENTINEL_1_3          =  7,
-  VID_SSH_SENTINEL_1_4          =  8,
-  VID_SSH_SENTINEL_1_4_1        =  9,
-  VID_SSH_IPSEC_1_1_0           = 10,
-  VID_SSH_IPSEC_1_1_1           = 11,
-  VID_SSH_IPSEC_1_1_2           = 12,
-  VID_SSH_IPSEC_1_2_1           = 13,
-  VID_SSH_IPSEC_1_2_2           = 14,
-  VID_SSH_IPSEC_2_0_0           = 15,
-  VID_SSH_IPSEC_2_1_0           = 16,
-  VID_SSH_IPSEC_2_1_1           = 17,
-  VID_SSH_IPSEC_2_1_2           = 18,
-  VID_SSH_IPSEC_3_0_0           = 19,
-  VID_SSH_IPSEC_3_0_1           = 20,
-  VID_SSH_IPSEC_4_0_0           = 21,
-  VID_SSH_IPSEC_4_0_1           = 22,
-  VID_SSH_IPSEC_4_1_0           = 23,
-  VID_SSH_IPSEC_4_2_0           = 24,
-  VID_CISCO_UNITY               = 25,
-  VID_CISCO3K                   = 26,
-  VID_CISCO_IOS                 = 27,
-  VID_TIMESTEP                  = 28,
-  VID_SAFENET                   = 29,
-  VID_MACOSX                    = 30,
-  VID_NCP_SERVER                = 31,
-  VID_NCP_CLIENT                = 32,
-  VID_VISTA_AUTHIP              = 33,
-  VID_VISTA_AUTHIP2             = 34,
-  VID_VISTA_AUTHIP3             = 35,
-
-  VID_STRONGSWAN                = 36,
-
-  VID_STRONGSWAN_2_8_0          = 37,
-  VID_STRONGSWAN_2_8_1          = 38,
-  VID_STRONGSWAN_2_8_2          = 39,
-  VID_STRONGSWAN_2_8_3          = 40,
-  VID_STRONGSWAN_2_8_4          = 41,
-  VID_STRONGSWAN_2_8_5          = 42,
-  VID_STRONGSWAN_2_8_6          = 43,
-  VID_STRONGSWAN_2_8_7          = 44,
-  VID_STRONGSWAN_2_8_8          = 45,
-  VID_STRONGSWAN_2_8_9          = 46,
-  VID_STRONGSWAN_2_8_10         = 47,
-  VID_STRONGSWAN_2_8_11         = 48,
-
-  VID_STRONGSWAN_4_1_0          = 88,
-  VID_STRONGSWAN_4_1_1          = 89,
-  VID_STRONGSWAN_4_1_2          = 90,
-  VID_STRONGSWAN_4_1_3          = 91,
-  VID_STRONGSWAN_4_1_4          = 92,
-  VID_STRONGSWAN_4_1_5          = 93,
-  VID_STRONGSWAN_4_1_6          = 94,
-  VID_STRONGSWAN_4_1_7          = 95,
-  VID_STRONGSWAN_4_1_8          = 96,
-  VID_STRONGSWAN_4_1_9          = 97,
-  VID_STRONGSWAN_4_1_10         = 98,
-  VID_STRONGSWAN_4_1_11         = 99,
-  VID_STRONGSWAN_4_2_0          =100,
-  VID_STRONGSWAN_4_2_1          =101,
-  VID_STRONGSWAN_4_2_2          =102,
-  VID_STRONGSWAN_4_2_3          =103,
-  VID_STRONGSWAN_4_2_4          =104,
-  VID_STRONGSWAN_4_2_5          =105,
-  VID_STRONGSWAN_4_2_6          =106,
-  VID_STRONGSWAN_4_2_7          =107,
-  VID_STRONGSWAN_4_2_8          =108,
-  VID_STRONGSWAN_4_2_9          =109,
-  VID_STRONGSWAN_4_2_10         =110,
-  VID_STRONGSWAN_4_2_11         =111,
-  VID_STRONGSWAN_4_2_12         =112,
-  VID_STRONGSWAN_4_2_13         =113,
-  VID_STRONGSWAN_4_2_14         =114,
-  VID_STRONGSWAN_4_2_15         =115,
-  VID_STRONGSWAN_4_2_16         =116,
-  VID_STRONGSWAN_4_2_17         =117,
-  VID_STRONGSWAN_4_3_0          =118,
-  VID_STRONGSWAN_4_3_1          =119,
-  VID_STRONGSWAN_4_3_2          =120,
-  VID_STRONGSWAN_4_3_3          =121,
-  VID_STRONGSWAN_4_3_4          =122,
-  VID_STRONGSWAN_4_3_5          =123,
-
-  /* 101 - 200 : NAT-Traversal */
-  VID_NATT_STENBERG_01          =151,
-  VID_NATT_STENBERG_02          =152,
-  VID_NATT_HUTTUNEN             =153,
-  VID_NATT_HUTTUNEN_ESPINUDP    =154,
-  VID_NATT_IETF_00              =155,
-  VID_NATT_IETF_02_N            =156,
-  VID_NATT_IETF_02              =157,
-  VID_NATT_IETF_03              =158,
-  VID_NATT_RFC                  =159,
-
-  /* 201 - 300 : Misc */
-  VID_MISC_XAUTH                =201,
-  VID_MISC_DPD                  =202,
-  VID_MISC_HEARTBEAT_NOTIFY     =203,
-  VID_MISC_FRAGMENTATION        =204,
-  VID_INITIAL_CONTACT           =205,
-  VID_CISCO3K_FRAGMENTATION     =206
-};
-
-void init_vendorid(void);
-void free_vendorid(void);
-
-struct msg_digest;
-void handle_vendorid (struct msg_digest *md, const char *vid, size_t len);
-
-bool out_vendorid (u_int8_t np, pb_stream *outs, enum known_vendorid vid);
-
-#endif /* _VENDOR_H_ */
-
diff --git a/src/pluto/virtual.c b/src/pluto/virtual.c
deleted file mode 100644 (file)
index 3e8d5fc..0000000
+++ /dev/null
@@ -1,325 +0,0 @@
-/* FreeS/WAN Virtual IP Management
- * Copyright (C) 2002 Mathieu Lafon - Arkoon Network Security
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <freeswan.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <sys/queue.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "connections.h"
-#include "whack.h"
-#include "virtual.h"
-
-#define F_VIRTUAL_NO          1
-#define F_VIRTUAL_DHCP        2
-#define F_VIRTUAL_IKE_CONFIG  4
-#define F_VIRTUAL_PRIVATE     8
-#define F_VIRTUAL_ALL         16
-#define F_VIRTUAL_HOST        32
-
-struct virtual_t {
-       unsigned short flags;
-       unsigned short n_net;
-       ip_subnet net[0];
-};
-
-static ip_subnet *private_net_ok=NULL, *private_net_ko=NULL;
-static unsigned short private_net_ok_len=0, private_net_ko_len=0;
-
-/**
- * read %v4:x.x.x.x/y or %v6:xxxxxxxxx/yy
- * or %v4:!x.x.x.x/y if dstko not NULL
- */
-static bool
-_read_subnet(const char *src, size_t len, ip_subnet *dst, ip_subnet *dstko,
-       bool *isok)
-{
-       bool ok;
-       int af;
-
-       if ((len > 4) && (strneq(src, "%v4:", 4)))
-       {
-               af = AF_INET;
-       }
-       else if ((len > 4) && (strneq(src, "%v6:", 4)))
-       {
-               af = AF_INET6;
-       }
-       else
-       {
-               return FALSE;
-       }
-
-       ok = (src[4] != '!');
-       src += ok ? 4 : 5;
-       len -= ok ? 4 : 5;
-
-       if (!len)
-               return FALSE;
-       if (!ok && !dstko)
-               return FALSE;
-
-       passert ( ((ok)?(dst):(dstko))!=NULL );
-
-       if (ttosubnet(src, len, af, ((ok)?(dst):(dstko))))
-       {
-               return FALSE;
-       }
-       if (isok)
-               *isok = ok;
-       return TRUE;
-}
-
-void
-init_virtual_ip(const char *private_list)
-{
-       const char *next, *str=private_list;
-       unsigned short ign = 0, i_ok, i_ko;
-       ip_subnet sub;
-       bool ok;
-
-       /** Count **/
-       private_net_ok_len=0;
-       private_net_ko_len=0;
-
-       while (str)
-       {
-               next = strchr(str,',');
-               if (!next)
-                       next = str + strlen(str);
-               if (_read_subnet(str, next-str, &sub, &sub, &ok))
-                       if (ok)
-                               private_net_ok_len++;
-                       else
-                               private_net_ko_len++;
-               else
-                       ign++;
-               str = *next ? next+1 : NULL;
-       }
-
-       if (!ign)
-       {
-               /** Allocate **/
-               if (private_net_ok_len)
-               {
-                       private_net_ok = (ip_subnet *)malloc(private_net_ok_len * sizeof(ip_subnet));
-               }
-               if (private_net_ko_len)
-               {
-                       private_net_ko = (ip_subnet *)malloc(private_net_ko_len * sizeof(ip_subnet));
-               }
-               if ((private_net_ok_len && !private_net_ok)
-               ||  (private_net_ko_len && !private_net_ko))
-               {
-                       loglog(RC_LOG_SERIOUS,
-                               "can't alloc in init_virtual_ip");
-                       free(private_net_ok);
-                       private_net_ok = NULL;
-                       free(private_net_ko);
-                       private_net_ko = NULL;
-               }
-               else
-               {
-                       /** Fill **/
-                       str = private_list;
-                       i_ok = 0;
-                       i_ko = 0;
-
-                       while (str)
-                       {
-                               next = strchr(str,',');
-                               if (!next)
-                                       next = str + strlen(str);
-                               if (_read_subnet(str, next-str,
-                                  &(private_net_ok[i_ok]), &(private_net_ko[i_ko]), &ok))
-                               {
-                                       if (ok)
-                                               i_ok++;
-                                       else
-                                               i_ko++;
-                               }
-                               str = *next ? next+1 : NULL;
-                       }
-               }
-       }
-       else
-               loglog(RC_LOG_SERIOUS,
-                       "%d bad entries in virtual_private - none loaded", ign);
-}
-
-/**
- * virtual string must be :
- * {vhost,vnet}:[%method]*
- *
- * vhost = accept only a host (/32)
- * vnet  = accept any network
- *
- * %no   = no virtual IP (accept public IP)
- * %dhcp = accept DHCP SA (0.0.0.0/0) of affected IP  [not implemented]
- * %ike  = accept affected IKE Config Mode IP         [not implemented]
- * %priv = accept system-wide private net list
- * %v4:x = accept ipv4 in list 'x'
- * %v6:x = accept ipv6 in list 'x'
- * %all  = accept all ips                             [only for testing]
- *
- * ex: vhost:%no,%dhcp,%priv,%v4:192.168.1.0/24
- */
-struct virtual_t
-*create_virtual(const connection_t *c, const char *string)
-{
-       unsigned short flags=0, n_net=0, i;
-       const char *str = string, *next, *first_net=NULL;
-       ip_subnet sub;
-       struct virtual_t *v;
-
-       if (!string || string[0] == '\0')
-               return NULL;
-
-       if (strlen(string) >= 6 && strneq(string,"vhost:",6))
-       {
-               flags |= F_VIRTUAL_HOST;
-               str += 6;
-       }
-       else if (strlen(string) >= 5 && strneq(string,"vnet:",5))
-               str += 5;
-       else
-               goto fail;
-
-       /**
-        * Parse string : fill flags & count subnets
-        */
-       while ((str) && (*str))
-       {
-               next = strchr(str,',');
-               if (!next) next = str + strlen(str);
-               if (next-str == 3 && strneq(str, "%no", 3))
-                       flags |= F_VIRTUAL_NO;
-#if 0
-               else if (next-str == 4 && strneq(str, "%ike", 4))
-                       flags |= F_VIRTUAL_IKE_CONFIG;
-               else if (next-str == 5 && strneq(str, "%dhcp", 5))
-                       flags |= F_VIRTUAL_DHCP;
-#endif
-               else if (next-str == 5 && strneq(str, "%priv", 5))
-                       flags |= F_VIRTUAL_PRIVATE;
-               else if (next-str == 4 && strneq(str, "%all", 4))
-                       flags |= F_VIRTUAL_ALL;
-               else if (_read_subnet(str, next-str, &sub, NULL, NULL))
-               {
-                       n_net++;
-                       if (!first_net)
-                               first_net = str;
-               }
-               else
-                       goto fail;
-
-               str = *next ? next+1 : NULL;
-       }
-
-       v = (struct virtual_t *)malloc(sizeof(struct virtual_t) +
-                                                                 (n_net * sizeof(ip_subnet)));
-       if (!v) goto fail;
-
-       v->flags = flags;
-       v->n_net = n_net;
-       if (n_net && first_net)
-       {
-               /**
-                * Save subnets in newly allocated struct
-                */
-               for (str = first_net, i = 0; str && *str; )
-               {
-                       next = strchr(str,',');
-                       if (!next) next = str + strlen(str);
-                       if (_read_subnet(str, next-str, &(v->net[i]), NULL, NULL))
-                               i++;
-                       str = *next ? next+1 : NULL;
-               }
-       }
-
-       return v;
-
-fail:
-       plog("invalid virtual string [%s] - "
-               "virtual selection disabled for connection '%s'", string, c->name);
-       return NULL;
-}
-
-bool
-is_virtual_end(const struct end *that)
-{
-       return ((that->virt)?TRUE:FALSE);
-}
-
-bool
-is_virtual_connection(const connection_t *c)
-{
-       return ((c->spd.that.virt)?TRUE:FALSE);
-}
-
-static bool net_in_list(const ip_subnet *peer_net, const ip_subnet *list,
-                                               unsigned short len)
-{
-       unsigned short i;
-
-       if (!list || !len)
-               return FALSE;
-
-       for (i = 0; i < len; i++)
-       {
-               if (subnetinsubnet(peer_net, &(list[i])))
-                       return TRUE;
-       }
-       return FALSE;
-}
-
-bool is_virtual_net_allowed(const connection_t *c, const ip_subnet *peer_net,
-                                                       const ip_address *his_addr)
-{
-       if (c->spd.that.virt == NULL)
-               return FALSE;
-
-       if ((c->spd.that.virt->flags & F_VIRTUAL_HOST)
-       &&  !subnetishost(peer_net))
-               return FALSE;
-
-       if ((c->spd.that.virt->flags & F_VIRTUAL_NO)
-       &&  subnetishost(peer_net) &&  addrinsubnet(his_addr, peer_net))
-               return TRUE;
-
-       if ((c->spd.that.virt->flags & F_VIRTUAL_PRIVATE)
-       &&   net_in_list(peer_net, private_net_ok, private_net_ok_len)
-       &&  !net_in_list(peer_net, private_net_ko, private_net_ko_len))
-               return TRUE;
-
-       if (c->spd.that.virt->n_net
-       &&  net_in_list(peer_net, c->spd.that.virt->net, c->spd.that.virt->n_net))
-               return TRUE;
-
-       if (c->spd.that.virt->flags & F_VIRTUAL_ALL)
-       {
-               /** %all must only be used for testing - log it **/
-               loglog(RC_LOG_SERIOUS, "Warning - "
-                       "v%s:%%all must only be used for testing",
-                       (c->spd.that.virt->flags & F_VIRTUAL_HOST) ? "host" : "net");
-               return TRUE;
-       }
-
-       return FALSE;
-}
-
diff --git a/src/pluto/virtual.h b/src/pluto/virtual.h
deleted file mode 100644 (file)
index e64407c..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* FreeS/WAN Virtual IP Management
- * Copyright (C) 2002 Mathieu Lafon - Arkoon Network Security
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef _VIRTUAL_IP_H
-#define _VIRTUAL_IP_H
-
-extern void init_virtual_ip(const char *private_list);
-
-extern struct virtual_t *create_virtual(const struct connection *c,
-       const char *string);
-
-extern bool is_virtual_end(const struct end *that);
-extern bool is_virtual_connection(const struct connection *c);
-extern bool is_virtual_net_allowed(const struct connection *c,
-       const ip_subnet *peer_net, const ip_address *his_addr);
-
-#endif /* _VIRTUAL_IP_H */
-
diff --git a/src/pluto/whack_attribute.c b/src/pluto/whack_attribute.c
deleted file mode 100644 (file)
index 6a12f0c..0000000
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * Copyright (C) 2010 Tobias Brunner
- * Copyright (C) 2008 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include "whack_attribute.h"
-
-#include "log.h"
-
-/* these are defined as constants in constant.h but redefined as enum values in
- * attributes/attributes.h */
-#undef INTERNAL_IP4_SERVER
-#undef INTERNAL_IP6_SERVER
-
-#include <hydra.h>
-#include <attributes/mem_pool.h>
-#include <utils/linked_list.h>
-#include <threading/rwlock.h>
-
-typedef struct private_whack_attribute_t private_whack_attribute_t;
-
-/**
- * private data of whack_attribute
- */
-struct private_whack_attribute_t {
-
-       /**
-        * public functions
-        */
-       whack_attribute_t public;
-
-       /**
-        * list of pools, contains mem_pool_t
-        */
-       linked_list_t *pools;
-
-       /**
-        * rwlock to lock access to pools
-        */
-       rwlock_t *lock;
-};
-
-/**
- * global object
- */
-whack_attribute_t *whack_attr;
-
-/**
- * compare pools by name
- */
-static bool pool_match(mem_pool_t *current, char *name)
-{
-       return name && streq(name, current->get_name(current));
-}
-
-/**
- * find a pool by name
- */
-static mem_pool_t *find_pool(private_whack_attribute_t *this, char *name)
-{
-       mem_pool_t *found;
-       if (this->pools->find_first(this->pools, (linked_list_match_t)pool_match,
-               (void**)&found, name) == SUCCESS)
-       {
-               return found;
-       }
-       return NULL;
-}
-
-METHOD(attribute_provider_t, acquire_address, host_t*,
-          private_whack_attribute_t *this, char *name, identification_t *id,
-          host_t *requested)
-{
-       mem_pool_t *pool;
-       host_t *addr = NULL;
-       this->lock->read_lock(this->lock);
-       pool = find_pool(this, name);
-       if (pool)
-       {
-               addr = pool->acquire_address(pool, id, requested);
-       }
-       this->lock->unlock(this->lock);
-       return addr;
-}
-
-METHOD(attribute_provider_t, release_address, bool,
-          private_whack_attribute_t *this, char *name, host_t *address,
-          identification_t *id)
-{
-       mem_pool_t *pool;
-       bool found = FALSE;
-       this->lock->read_lock(this->lock);
-       pool = find_pool(this, name);
-       if (pool)
-       {
-               found = pool->release_address(pool, address, id);
-       }
-       this->lock->unlock(this->lock);
-       return found;
-}
-
-METHOD(whack_attribute_t, add_pool, bool,
-          private_whack_attribute_t *this, const char *name,
-          const whack_end_t *right)
-{
-       mem_pool_t *pool;
-       host_t *base = NULL;
-       u_int32_t bits = 0;
-
-       /* named pool */
-       if (right->sourceip_mask <= 0)
-       {
-               return FALSE;
-       }
-
-       /* if %config, add an empty pool, otherwise */
-       if (right->sourceip)
-       {
-               DBG(DBG_CONTROL,
-                       DBG_log("adding virtual IP address pool '%s': %s/%d",
-                                       name, right->sourceip, right->sourceip_mask);
-               );
-               base = host_create_from_string(right->sourceip, 0);
-               if (!base)
-               {
-                       loglog(RC_LOG_SERIOUS, "virtual IP address invalid, discarded");
-                       return FALSE;
-               }
-               bits = right->sourceip_mask;
-       }
-       pool = mem_pool_create((char*)name, base, bits);
-       DESTROY_IF(base);
-
-       this->lock->write_lock(this->lock);
-       this->pools->insert_last(this->pools, pool);
-       this->lock->unlock(this->lock);
-       return TRUE;
-}
-
-METHOD(whack_attribute_t, del_pool, void,
-          private_whack_attribute_t *this, char *name)
-{
-       enumerator_t *enumerator;
-       mem_pool_t *pool;
-
-       this->lock->write_lock(this->lock);
-       enumerator = this->pools->create_enumerator(this->pools);
-       while (enumerator->enumerate(enumerator, &pool))
-       {
-               if (streq(name, pool->get_name(pool)))
-               {
-                       DBG(DBG_CONTROL,
-                               DBG_log("deleting virtual IP address pool '%s'", name)
-                       );
-                       this->pools->remove_at(this->pools, enumerator);
-                       pool->destroy(pool);
-                       break;
-               }
-       }
-       enumerator->destroy(enumerator);
-       this->lock->unlock(this->lock);
-}
-
-/**
- * Pool enumerator filter function, converts pool_t to name, size, ...
- */
-static bool pool_filter(void *lock, mem_pool_t **poolp, const char **name,
-                                               void *d1, u_int *size, void *d2, u_int *online,
-                                               void *d3, u_int *offline)
-{
-       mem_pool_t *pool = *poolp;
-       *name = pool->get_name(pool);
-       *size = pool->get_size(pool);
-       *online = pool->get_online(pool);
-       *offline = pool->get_offline(pool);
-       return TRUE;
-}
-
-METHOD(whack_attribute_t, create_pool_enumerator, enumerator_t*,
-          private_whack_attribute_t *this)
-{
-       this->lock->read_lock(this->lock);
-       return enumerator_create_filter(this->pools->create_enumerator(this->pools),
-                                                                       (void*)pool_filter,
-                                                                       this->lock, (void*)this->lock->unlock);
-}
-
-METHOD(whack_attribute_t, create_lease_enumerator, enumerator_t*,
-          private_whack_attribute_t *this, char *name)
-{
-       mem_pool_t *pool;
-       this->lock->read_lock(this->lock);
-       pool = find_pool(this, name);
-       if (!pool)
-       {
-               this->lock->unlock(this->lock);
-               return NULL;
-       }
-       return enumerator_create_cleaner(pool->create_lease_enumerator(pool),
-                                                                        (void*)this->lock->unlock, this->lock);
-}
-
-/**
- * see header file
- */
-void whack_attribute_finalize()
-{
-       private_whack_attribute_t *this;
-
-       if (whack_attr)
-       {
-               this = (private_whack_attribute_t*)whack_attr;
-               hydra->attributes->remove_provider(hydra->attributes,
-                                                                          &this->public.provider);
-               this->lock->destroy(this->lock);
-               this->pools->destroy_offset(this->pools, offsetof(mem_pool_t, destroy));
-               free(this);
-       }
-}
-
-/**
- * see header file
- */
-void whack_attribute_initialize()
-{
-       private_whack_attribute_t *this;
-
-       INIT(this,
-               .public = {
-                       .provider = {
-                               .acquire_address = _acquire_address,
-                               .release_address = _release_address,
-                               .create_attribute_enumerator = enumerator_create_empty,
-                       },
-                       .add_pool = _add_pool,
-                       .del_pool = _del_pool,
-                       .create_pool_enumerator = _create_pool_enumerator,
-                       .create_lease_enumerator = _create_lease_enumerator,
-               },
-               .pools = linked_list_create(),
-               .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
-       );
-
-       hydra->attributes->add_provider(hydra->attributes, &this->public.provider);
-
-       whack_attr = &this->public;
-}
-
-/**
- * list leases of a single pool
- */
-static void pool_leases(char *pool, host_t *address,
-                                               identification_t *identification,
-                                               u_int size, u_int online, u_int offline)
-{
-
-       enumerator_t *enumerator;
-       identification_t *id;
-       host_t *lease;
-       bool on, found = FALSE;
-
-       whack_log(RC_COMMENT, "Leases in pool '%s', usage: %lu/%lu, %lu online",
-                         pool, online + offline, size, online);
-       enumerator = whack_attr->create_lease_enumerator(whack_attr, pool);
-       while (enumerator && enumerator->enumerate(enumerator, &id, &lease, &on))
-       {
-               if ((!address && !identification) ||
-                       (address && address->ip_equals(address, lease)) ||
-                       (identification && identification->equals(identification, id)))
-               {
-                       whack_log(RC_COMMENT, "  %15H   %s   '%Y'",
-                                         lease, on ? "online" : "offline", id);
-                       found = TRUE;
-               }
-       }
-       enumerator->destroy(enumerator);
-       if (!found)
-       {
-               whack_log(RC_COMMENT, "  no matching leases found");
-       }
-}
-
-/**
- * see header file
- */
-void list_leases(char *name, char *addr, char *id)
-{
-       identification_t *identification = NULL;
-       host_t *address = NULL;
-       bool found = FALSE;
-       enumerator_t *enumerator;
-       u_int size, online, offline;
-       char *pool;
-
-       if (addr)
-       {
-               address = host_create_from_string(addr, 0);
-       }
-       if (id)
-       {
-               identification = identification_create_from_string(id);
-       }
-
-       enumerator = whack_attr->create_pool_enumerator(whack_attr);
-       while (enumerator->enumerate(enumerator, &pool, &size, &online, &offline))
-       {
-               if (!name || streq(name, pool))
-               {
-                       pool_leases(pool, address, identification, size, online, offline);
-                       found = TRUE;
-               }
-       }
-       enumerator->destroy(enumerator);
-       if (!found)
-       {
-               if (name)
-               {
-                       whack_log(RC_COMMENT, "pool '%s' not found", name);
-               }
-               else
-               {
-                       whack_log(RC_COMMENT, "no pools found");
-               }
-       }
-       DESTROY_IF(identification);
-       DESTROY_IF(address);
-}
-
-/**
- * see header file
- */
-void show_pools(const char *name)
-{
-       enumerator_t *enumerator;
-       u_int size, online, offline;
-       char *pool;
-       bool first = TRUE;
-
-       enumerator = whack_attr->create_pool_enumerator(whack_attr);
-       while (enumerator->enumerate(enumerator, &pool, &size, &online, &offline))
-       {
-               if (name && !streq(name, pool))
-               {
-                       continue;
-               }
-               if (first)
-               {
-                       first = FALSE;
-                       whack_log(RC_COMMENT, "Virtual IP pools (size/online/offline):");
-               }
-               whack_log(RC_COMMENT, "\"%s\": %u/%u/%u", pool, size, online, offline);
-       }
-       enumerator->destroy(enumerator);
-}
diff --git a/src/pluto/whack_attribute.h b/src/pluto/whack_attribute.h
deleted file mode 100644 (file)
index 58441b9..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2010 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup whack_attribute
- * @{ @ingroup pluto
- */
-
-#ifndef WHACK_ATTRIBUTE_H_
-#define WHACK_ATTRIBUTE_H_
-
-#include <whack.h>
-#include <attributes/attribute_provider.h>
-
-typedef struct whack_attribute_t whack_attribute_t;
-
-/**
- * Whack attribute provider (basically an in-memory IP address pool)
- */
-struct whack_attribute_t {
-
-       /**
-        * Implements attribute provider interface
-        */
-       attribute_provider_t provider;
-
-       /**
-        * Add a virtual IP address pool.
-        *
-        * @param name          name of the pool
-        * @param right         "right" end of whack message
-        * @return                      TRUE, if the pool was successfully added
-        */
-       bool (*add_pool)(whack_attribute_t *this, const char *name,
-                                        const whack_end_t *right);
-
-       /**
-        * Remove a virtual IP address pool.
-        *
-        * @param name          name of the pool
-        */
-       void (*del_pool)(whack_attribute_t *this, char *name);
-
-       /**
-        * Create an enumerator over installed pools.
-        *
-        * Enumerator enumerates over
-        * char *pool, u_int size, u_int offline, u_int online.
-        *
-        * @return                      enumerator
-        */
-       enumerator_t* (*create_pool_enumerator)(whack_attribute_t *this);
-
-       /**
-        * Create an enumerator over the leases of a pool.
-        *
-        * Enumerator enumerates over
-        * identification_t *id, host_t *address, bool online
-        *
-        * @param name          name of the pool to enumerate
-        * @return                      enumerator, NULL if pool not found
-        */
-       enumerator_t* (*create_lease_enumerator)(whack_attribute_t *this,
-                                                                                        char *name);
-};
-
-/**
- * Global object to manage pools. Set between calls to
- * whack_attribute_initialize() and whack_attribute_finalize().
- */
-extern whack_attribute_t *whack_attr;
-
-/**
- * Initialize the whack attribute provider
- */
-void whack_attribute_initialize();
-
-/**
- * Finalize the whack attribute provider
- */
-void whack_attribute_finalize();
-
-/**
- * List the leases matching the given parameters.
- *
- * @param name         name of the pool, NULL for all pools
- * @param addr         ip address of the lease to list, NULL to ignore
- * @param id           id of the lease to list, NULL to ignore
- */
-void list_leases(char *name, char *addr, char *id);
-
-/**
- * List either all pools or the pool with a given name
- *
- * @param name         name of the pool, NULL for all pools
- */
-void show_pools(const char *name);
-
-#endif /** WHACK_ATTRIBUTE_H_ @}*/
diff --git a/src/pluto/x509.c b/src/pluto/x509.c
deleted file mode 100644 (file)
index f017e57..0000000
+++ /dev/null
@@ -1,463 +0,0 @@
-/* Support of X.509 certificates
- * Copyright (C) 2000 Andreas Hess, Patric Lichtsteiner, Roger Wegmann
- * Copyright (C) 2001 Marco Bertossa, Andreas Schleiss
- * Copyright (C) 2002 Mario Strasser
- * Copyright (C) 2000-2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <time.h>
-#include <sys/types.h>
-
-#include <freeswan.h>
-
-#include <asn1/asn1.h>
-#include <crypto/hashers/hasher.h>
-#include <utils/enumerator.h>
-#include <utils/identification.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "x509.h"
-#include "crl.h"
-#include "ca.h"
-#include "certs.h"
-#include "keys.h"
-#include "whack.h"
-#include "fetch.h"
-#include "ocsp.h"
-
-/**
- * Check for equality between two key identifiers
- */
-bool same_keyid(chunk_t a, chunk_t b)
-{
-       if (a.ptr == NULL || b.ptr == NULL)
-       {
-               return FALSE;
-       }
-       return chunk_equals(a, b);
-}
-
-/**
- * Stores a chained list of end certs and CA certs
- */
-void store_x509certs(linked_list_t *certs, bool strict)
-{
-       cert_t *x509cert, *cacerts = NULL;
-       certificate_t *cert;
-       enumerator_t *enumerator;
-
-       /* first extract CA certs, ignoring self-signed root CA certs */
-
-       enumerator = certs->create_enumerator(certs);
-       while (enumerator->enumerate(enumerator, &cert))
-       {
-               x509_t *x509 = (x509_t*)cert;
-               x509_flag_t flags;
-
-               flags = x509->get_flags(x509);
-               if (flags & X509_CA)
-               {
-                       /* we don't accept self-signed CA certs */
-                       if (flags & X509_SELF_SIGNED)
-                       {
-                               plog("self-signed cacert rejected");
-                       }
-                       else
-                       {
-                               /* insertion into temporary chain of candidate CA certs */
-                               x509cert = malloc_thing(cert_t);
-                               *x509cert = cert_empty;
-                               x509cert->cert = cert->get_ref(cert);
-                               x509cert->next = cacerts;
-                               cacerts = x509cert;
-                       }
-               }
-       }
-       enumerator->destroy(enumerator);
-
-       /* now verify the candidate CA certs */
-
-       while (cacerts)
-       {
-               cert_t *cert = cacerts;
-
-               cacerts = cacerts->next;
-
-               if (trust_authcert_candidate(cert, cacerts))
-               {
-                       add_authcert(cert, X509_CA);
-               }
-               else
-               {
-                       plog("intermediate cacert rejected");
-                       cert_free(cert);
-               }
-       }
-
-       /* now verify the end certificates */
-
-       enumerator = certs->create_enumerator(certs);
-       while (enumerator->enumerate(enumerator, &cert))
-       {
-               time_t valid_until;
-               x509_t *x509 = (x509_t*)cert;
-
-               if (!(x509->get_flags(x509) & X509_CA))
-               {
-                       x509cert = malloc_thing(cert_t);
-                       *x509cert = cert_empty;
-                       x509cert->cert = cert->get_ref(cert);
-
-                       if (verify_x509cert(x509cert, strict, &valid_until))
-                       {
-                               DBG(DBG_CONTROL | DBG_PARSING,
-                                       DBG_log("public key validated")
-                               )
-                               add_public_key_from_cert(x509cert, valid_until, DAL_SIGNED);
-                       }
-                       else
-                       {
-                               plog("X.509 certificate rejected");
-                               cert_free(x509cert);
-                       }
-               }
-       }
-       enumerator->destroy(enumerator);
-}
-
-/**
- * Check if a signature over binary blob is genuine
- */
-bool x509_check_signature(chunk_t tbs, chunk_t sig, int algorithm,
-                                                 certificate_t *issuer_cert)
-{
-       bool success;
-       public_key_t *key;
-       signature_scheme_t scheme;
-
-       scheme = signature_scheme_from_oid(algorithm);
-       if (scheme == SIGN_UNKNOWN)
-       {
-               return FALSE;
-       }
-
-       key = issuer_cert->get_public_key(issuer_cert);
-       if (key == NULL)
-       {
-               return FALSE;
-       }
-       success = key->verify(key, scheme, tbs, sig);
-       key->destroy(key);
-
-       return success;
-}
-
-/**
- * Build an ASN.1 encoded PKCS#1 signature over a binary blob
- */
-chunk_t x509_build_signature(chunk_t tbs, int algorithm, private_key_t *key,
-                                                        bool bit_string)
-{
-       chunk_t signature;
-       signature_scheme_t scheme = signature_scheme_from_oid(algorithm);
-
-       if (scheme == SIGN_UNKNOWN || !key->sign(key, scheme, tbs, &signature))
-       {
-               return chunk_empty;
-       }
-       return (bit_string) ? asn1_bitstring("m", signature)
-                                               : asn1_wrap(ASN1_OCTET_STRING, "m", signature);
-}
-
-/**
- * Verifies a X.509 certificate
- */
-bool verify_x509cert(cert_t *cert, bool strict, time_t *until)
-{
-       int pathlen, pathlen_constraint;
-
-       *until = 0;
-
-       for (pathlen = -1; pathlen <= X509_MAX_PATH_LEN; pathlen++)
-       {
-               certificate_t *certificate = cert->cert;
-               identification_t *subject = certificate->get_subject(certificate);
-               identification_t *issuer  = certificate->get_issuer(certificate);
-               x509_t *x509 = (x509_t*)certificate;
-               chunk_t authKeyID = x509->get_authKeyIdentifier(x509);
-               cert_t *issuer_cert;
-               time_t notBefore, notAfter;
-               bool valid;
-
-               DBG(DBG_CONTROL,
-                       DBG_log("subject: '%Y'", subject);
-                       DBG_log("issuer:  '%Y'", issuer);
-                       if (authKeyID.ptr)
-                       {
-                               DBG_log("authkey:  %#B", &authKeyID);
-                       }
-               )
-
-               valid = certificate->get_validity(certificate, NULL,
-                                                                                 &notBefore, &notAfter);
-               if (*until == UNDEFINED_TIME || notAfter < *until)
-               {
-                       *until = notAfter;
-               }
-               if (!valid)
-               {
-                       plog("certificate is invalid (valid from %T to %T)",
-                                &notBefore, FALSE, &notAfter, FALSE);
-                       return FALSE;
-               }
-               DBG(DBG_CONTROL,
-                       DBG_log("certificate is valid")
-               )
-
-               lock_authcert_list("verify_x509cert");
-               issuer_cert = get_authcert(issuer, authKeyID, X509_CA);
-               if (issuer_cert == NULL)
-               {
-                       plog("issuer cacert not found");
-                       unlock_authcert_list("verify_x509cert");
-                       return FALSE;
-               }
-               DBG(DBG_CONTROL,
-                       DBG_log("issuer cacert found")
-               )
-
-               if (!certificate->issued_by(certificate, issuer_cert->cert))
-               {
-                       plog("certificate signature is invalid");
-                       unlock_authcert_list("verify_x509cert");
-                       return FALSE;
-               }
-               DBG(DBG_CONTROL,
-                       DBG_log("certificate signature is valid")
-               )
-               unlock_authcert_list("verify_x509cert");
-
-               /* check path length constraint */
-               pathlen_constraint = x509->get_constraint(x509, X509_PATH_LEN);
-               if (pathlen_constraint != X509_NO_CONSTRAINT &&
-                       pathlen > pathlen_constraint)
-               {
-                       plog("path length of %d violates constraint of %d",
-                                pathlen, pathlen_constraint);
-                       return FALSE;
-               }
-
-               /* check if cert is a self-signed root ca */
-               if (pathlen >= 0 && (x509->get_flags(x509) & X509_SELF_SIGNED))
-               {
-                       DBG(DBG_CONTROL,
-                               DBG_log("reached self-signed root ca with a path length of %d",
-                                                pathlen)
-                       )
-                       return TRUE;
-               }
-               else
-               {
-                       time_t nextUpdate = *until;
-                       time_t revocationDate = UNDEFINED_TIME;
-                       crl_reason_t revocationReason = CRL_REASON_UNSPECIFIED;
-
-                       /* first check certificate revocation using ocsp */
-                       cert_status_t status = verify_by_ocsp(cert, &nextUpdate
-                               , &revocationDate, &revocationReason);
-
-                       /* if ocsp service is not available then fall back to crl */
-                       if ((status == CERT_UNDEFINED)
-                       ||  (status == CERT_UNKNOWN && strict))
-                       {
-                               status = verify_by_crl(cert, &nextUpdate, &revocationDate
-                                       , &revocationReason);
-                       }
-
-                       switch (status)
-                       {
-                       case CERT_GOOD:
-                               /* if status information is stale */
-                               if (strict && nextUpdate < time(NULL))
-                               {
-                                       DBG(DBG_CONTROL,
-                                               DBG_log("certificate is good but status is stale")
-                                       )
-                                       remove_x509_public_key(cert);
-                                       return FALSE;
-                               }
-                               DBG(DBG_CONTROL,
-                                       DBG_log("certificate is good")
-                               )
-
-                               /* with strict crl policy the public key must have the same
-                                * lifetime as the validity of the ocsp status or crl lifetime
-                                */
-                               if (strict && nextUpdate < *until)
-                               {
-                                       *until = nextUpdate;
-                               }
-                               break;
-                       case CERT_REVOKED:
-                               plog("certificate was revoked on %T, reason: %N"
-                                       , &revocationDate, TRUE
-                                       , crl_reason_names, revocationReason);
-                               remove_x509_public_key(cert);
-                               return FALSE;
-                       case CERT_UNKNOWN:
-                       case CERT_UNDEFINED:
-                       default:
-                               plog("certificate status unknown");
-                               if (strict)
-                               {
-                                       remove_x509_public_key(cert);
-                                       return FALSE;
-                               }
-                               break;
-                       }
-               }
-
-               /* go up one step in the trust chain */
-               cert = issuer_cert;
-       }
-       plog("maximum path length of %d exceeded", X509_MAX_PATH_LEN);
-       return FALSE;
-}
-
-/**
- * List all X.509 certs in a chained list
- */
-void list_x509cert_chain(const char *caption, cert_t* cert,
-                                                x509_flag_t flags, bool utc)
-{
-       bool first = TRUE;
-       time_t now;
-
-       /* determine the current time */
-       time(&now);
-
-       while (cert)
-       {
-               certificate_t *certificate = cert->cert;
-               x509_t *x509 = (x509_t*)certificate;
-
-               if (certificate->get_type(certificate) == CERT_X509 &&
-                  (flags == X509_NONE || (flags & x509->get_flags(x509))))
-               {
-                       enumerator_t *enumerator;
-                       char buf[BUF_LEN];
-                       char *pos = buf;
-                       int len = BUF_LEN, pathlen;
-                       bool first_altName = TRUE;
-                       identification_t *id;
-                       time_t notBefore, notAfter;
-                       public_key_t *key;
-                       chunk_t serial, keyid, subjkey, authkey;
-
-                       if (first)
-                       {
-                               whack_log(RC_COMMENT, " ");
-                               whack_log(RC_COMMENT, "List of X.509 %s Certificates:", caption);
-                               first = FALSE;
-                       }
-                       whack_log(RC_COMMENT, " ");
-
-                       enumerator = x509->create_subjectAltName_enumerator(x509);
-                       while (enumerator->enumerate(enumerator, &id))
-                       {
-                               int written;
-
-                               if (first_altName)
-                               {
-                                       written = snprintf(pos, len, "%Y", id);
-                                       first_altName = FALSE;
-                               }
-                               else
-                               {
-                                       written = snprintf(pos, len, ", %Y", id);
-                               }
-                               if (written < 0 || written >= len)
-                               {
-                                       break;
-                               }
-                               pos += written;
-                               len -= written;
-                       }
-                       enumerator->destroy(enumerator);
-                       if (!first_altName)
-                       {
-                               whack_log(RC_COMMENT, "  altNames:  %s", buf);
-                       }
-
-                       whack_log(RC_COMMENT, "  subject:  \"%Y\"",
-                               certificate->get_subject(certificate));
-                       whack_log(RC_COMMENT, "  issuer:   \"%Y\"",
-                               certificate->get_issuer(certificate));
-                               serial = chunk_skip_zero(x509->get_serial(x509));
-                       whack_log(RC_COMMENT, "  serial:    %#B", &serial);
-
-                       /* list validity */
-                       certificate->get_validity(certificate, &now, &notBefore, &notAfter);
-                       whack_log(RC_COMMENT, "  validity:  not before %T %s",
-                               &notBefore, utc,
-                               (notBefore < now)?"ok":"fatal (not valid yet)");
-                       whack_log(RC_COMMENT, "             not after  %T %s",
-                               &notAfter, utc,
-                               check_expiry(notAfter, CA_CERT_WARNING_INTERVAL, TRUE));
-
-                       key = certificate->get_public_key(certificate);
-                       if (key)
-                       {
-                               whack_log(RC_COMMENT, "  pubkey:    %N %4d bits%s",
-                                       key_type_names, key->get_type(key),
-                                       key->get_keysize(key),
-                                       cert->smartcard ? ", on smartcard" :
-                                       (has_private_key(cert)? ", has private key" : ""));
-
-                               if (key->get_fingerprint(key, KEYID_PUBKEY_INFO_SHA1, &keyid))
-                               {
-                                       whack_log(RC_COMMENT, "  keyid:     %#B", &keyid);
-                               }
-                               if (key->get_fingerprint(key, KEYID_PUBKEY_SHA1, &subjkey))
-                               {
-                                       whack_log(RC_COMMENT, "  subjkey:   %#B", &subjkey);
-                               }
-                               key->destroy(key);
-                       }
-
-                       /* list optional authorityKeyIdentifier */
-                       authkey = x509->get_authKeyIdentifier(x509);
-                       if (authkey.ptr)
-                       {
-                               whack_log(RC_COMMENT, "  authkey:   %#B", &authkey);
-                       }
-
-                       /* list optional pathLenConstraint */
-                       pathlen = x509->get_constraint(x509, X509_PATH_LEN);
-                       if (pathlen != X509_NO_CONSTRAINT)
-                       {
-                               whack_log(RC_COMMENT, "  pathlen:   %d", pathlen);
-                       }
-
-               }
-               cert = cert->next;
-       }
-}
-
diff --git a/src/pluto/x509.h b/src/pluto/x509.h
deleted file mode 100644 (file)
index 3101724..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Support of X.509 certificates
- * Copyright (C) 2000 Andreas Hess, Patric Lichtsteiner, Roger Wegmann
- * Copyright (C) 2001 Marco Bertossa, Andreas Schleiss
- * Copyright (C) 2002 Mario Strasser
- * Copyright (C) 2000-2009 Andreas Steffen, Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef _X509_H
-#define _X509_H
-
-#include <utils/identification.h>
-#include <utils/linked_list.h>
-#include <credentials/keys/private_key.h>
-#include <credentials/certificates/x509.h>
-
-#include "constants.h"
-#include "certs.h"
-
-#define X509_MAX_PATH_LEN                               7
-
-extern bool same_keyid(chunk_t a, chunk_t b);
-extern bool x509_check_signature(chunk_t tbs, chunk_t sig, int algorithm,
-                                                                certificate_t *issuer_cert);
-extern chunk_t x509_build_signature(chunk_t tbs, int algorithm,
-                                                                       private_key_t *key, bool bit_string);
-extern bool verify_x509cert(cert_t *cert, bool strict, time_t *until);
-extern void store_x509certs(linked_list_t *certs, bool strict);
-extern void list_x509cert_chain(const char *caption, cert_t* cert,
-                                                               x509_flag_t flags, bool utc);
-extern void list_x509_end_certs(bool utc);
-
-#endif /* _X509_H */
diff --git a/src/pluto/xauth/xauth_manager.c b/src/pluto/xauth/xauth_manager.c
deleted file mode 100644 (file)
index 2e57cce..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2010 Andreas Steffen
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include "xauth_manager.h"
-
-typedef struct private_xauth_manager_t private_xauth_manager_t;
-
-/**
- * private data of xauth_manager
- */
-struct private_xauth_manager_t {
-
-       /**
-        * public functions
-        */
-       xauth_manager_t public;
-
-       /**
-        * list of registered secret providers
-        */
-       linked_list_t *providers;
-
-       /**
-        * list of registered secret verifiers
-        */
-       linked_list_t *verifiers;
-};
-
-METHOD(xauth_manager_t, get_secret, bool,
-       private_xauth_manager_t *this, connection_t *c, chunk_t *secret)
-{
-       xauth_provider_t *provider;
-       enumerator_t *enumerator;
-       bool success = FALSE;
-
-       *secret = chunk_empty;
-
-       enumerator = this->providers->create_enumerator(this->providers);
-       while (enumerator->enumerate(enumerator, &provider))
-       {
-               if (provider->get_secret(provider, c, secret))
-               {
-                       success = TRUE;
-                       break;
-               }
-       }
-       enumerator->destroy(enumerator);
-       return success;
-}
-
-METHOD(xauth_manager_t, verify_secret, bool,
-       private_xauth_manager_t *this, connection_t *c, chunk_t secret)
-{
-       xauth_verifier_t *verifier;
-       enumerator_t *enumerator;
-       bool success = FALSE;
-
-       enumerator = this->verifiers->create_enumerator(this->verifiers);
-       while (enumerator->enumerate(enumerator, &verifier))
-       {
-               if (verifier->verify_secret(verifier, c, secret))
-               {
-                       success = TRUE;
-                       break;
-               }
-       }
-       enumerator->destroy(enumerator);
-       return success;
-}
-
-METHOD(xauth_manager_t, add_provider, void,
-       private_xauth_manager_t *this,  xauth_provider_t *provider)
-{
-       this->providers->insert_last(this->providers, provider);
-}
-
-METHOD(xauth_manager_t, add_verifier, void,
-       private_xauth_manager_t *this,  xauth_verifier_t *verifier)
-{
-       this->verifiers->insert_last(this->verifiers, verifier);
-}
-
-METHOD(xauth_manager_t, destroy, void,
-       private_xauth_manager_t *this)
-{
-       this->providers->destroy_offset(this->providers,
-                                                                       offsetof(xauth_provider_t, destroy));
-       this->verifiers->destroy_offset(this->verifiers,
-                                                                       offsetof(xauth_verifier_t, destroy));
-       free(this);
-}
-
-/*
- * Described in header.
- */
-xauth_manager_t *xauth_manager_create()
-{
-       private_xauth_manager_t *this;
-
-       INIT(this,
-               .public = {
-                       .get_secret = _get_secret,
-                       .verify_secret = _verify_secret,
-                       .add_provider = _add_provider,
-                       .add_verifier = _add_verifier,
-                       .destroy = _destroy,
-                }
-       );
-
-       this->providers = linked_list_create();
-       this->verifiers = linked_list_create();
-
-       return &this->public;
-}
-
diff --git a/src/pluto/xauth/xauth_manager.h b/src/pluto/xauth/xauth_manager.h
deleted file mode 100644 (file)
index 843eb2f..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2010 Andreas Steffen
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup xauth_manager xauth_manager
- * @{ @ingroup xauth
- */
-
-#ifndef XAUTH_MANAGER_H_
-#define XAUTH_MANAGER_H_
-
-#include "xauth_provider.h"
-#include "xauth_verifier.h"
-
-typedef struct xauth_manager_t xauth_manager_t;
-
-/**
- * An xauth_manager registers xauth_providers and xauth_verifiers.
- */
-struct xauth_manager_t {
-
-       /**
-        * Register an xauth_provider
-        *
-        * @param provider              xauth_provider to be registered
-        */
-       void (*add_provider)(xauth_manager_t *this, xauth_provider_t *provider);
-
-       /**
-        * Register an xauth_verifier
-        *
-        * @param verifier              xauth_verifier to be registered
-        */
-       void (*add_verifier)(xauth_manager_t *this, xauth_verifier_t *verifier);
-
-       /**
-        * Use registered providers to retrieve an XAUTH user secret
-     * based on connection information.
-        *
-        * @param c                             connection information
-        * @param secret                secret if found, chunk_empty otherwise
-        * @return                              TRUE if a matching secret was found
-        */
-       bool (*get_secret)(xauth_manager_t *this, connection_t *c, chunk_t *secret);
-
-       /**
-        * Use registered verifiers to verify an XAUTH user secret 
-        * based on connection information
-        *
-        * @param c                             connection information
-        * @param secret                secret to be compared
-        * @return                              TRUE if secret matches
-        */
-       bool (*verify_secret)(xauth_manager_t *this, connection_t *c, chunk_t secret);
-
-       /**
-        * Destroy an xauth_verifier instance.
-        */
-       void (*destroy)(xauth_manager_t *this);
-};
-
-/**
- * Create an xauth_manager instance.
- */
-xauth_manager_t *xauth_manager_create();
-
-#endif /** XAUTH_MANAGER_H_ @}*/
-
diff --git a/src/pluto/xauth/xauth_provider.h b/src/pluto/xauth/xauth_provider.h
deleted file mode 100644 (file)
index 90adbff..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2010 Andreas Steffen
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup xauth_provider xauth_provider
- * @{ @ingroup xauth
- */
-
-#ifndef XAUTH_PROVIDER_H_
-#define XAUTH_PROVIDER_H_
-
-#include <library.h>
-
-#include <connections.h>
-
-typedef struct xauth_provider_t xauth_provider_t;
-
-/**
- * An xauth provider retrieves xauth user secrets on the client side. 
- */
-struct xauth_provider_t {
-
-       /**
-        * Retrieve an XAUTH user secret based on connection information.
-        *
-        * @param c                             connection information
-        * @param secret                secret if found, chunk_empty otherwise
-        * @return                              TRUE if a matching secret was found
-        */
-       bool (*get_secret)(xauth_provider_t *this, connection_t *c, chunk_t *secret);
-
-       /**
-        * Destroy an xauth_provider instance.
-        */
-       void (*destroy)(xauth_provider_t *this);
-};
-
-/**
- * Create an xauth_provider instance.
- */
-xauth_provider_t *xauth_provider_create();
-
-#endif /** XAUTH_PROVIDER_H_ @}*/
-
diff --git a/src/pluto/xauth/xauth_verifier.h b/src/pluto/xauth/xauth_verifier.h
deleted file mode 100644 (file)
index 7c9ff3a..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2010 Andreas Steffen
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup xauth_verifier xauth_verifier
- * @{ @ingroup xauth
- */
-
-#ifndef XAUTH_VERIFIER_H_
-#define XAUTH_VERIFIER_H_
-
-#include <library.h>
-
-#include <connections.h>
-
-typedef struct xauth_verifier_t xauth_verifier_t;
-
-/**
- * An xauth verifier verifies xauth user secrets on the server side.
- */
-struct xauth_verifier_t {
-
-       /**
-        * Verify an XAUTH user secret base on connection information
-        *
-        * @param c                             connection information
-        * @param secret                secret to be compared
-        * @return                              TRUE if secret matches
-        */
-       bool (*verify_secret)(xauth_verifier_t *this, connection_t *c, chunk_t secret);
-
-       /**
-        * Destroy an xauth_verifier instance.
-        */
-       void (*destroy)(xauth_verifier_t *this);
-};
-
-/**
- * Create an xauth_verifier instance.
- */
-xauth_verifier_t *xauth_verifier_create();
-
-#endif /** XAUTH_VERIFIER_H_ @}*/
-
index 05f28fe45a10ac14112fd75c32461776f5f67223..c7e81d284e88701287f7c09944cabe9a77b17efd 100644 (file)
@@ -20,10 +20,6 @@ LOCAL_C_INCLUDES += \
 LOCAL_CFLAGS := $(strongswan_CFLAGS) -DSTART_CHARON \
        -DPLUGINS='"$(strongswan_STARTER_PLUGINS)"'
 
-ifneq ($(strongswan_BUILD_PLUTO),)
-LOCAL_CFLAGS += -DSTART_PLUTO
-endif
-
 LOCAL_MODULE := starter
 
 LOCAL_MODULE_TAGS := optional
index 37aa7f21970a0ee4b0173f2070ecdcccf7325d72..7888b85bcb60625bb26209900141f351bd445d45 100644 (file)
@@ -29,10 +29,6 @@ EXTRA_DIST = keywords.txt ipsec.conf Android.mk
 MAINTAINERCLEANFILES = keywords.c
 BUILT_SOURCES = parser.h
 
-if USE_PLUTO
-  AM_CFLAGS += -DSTART_PLUTO
-endif
-
 if USE_CHARON
   AM_CFLAGS += -DSTART_CHARON
 endif
index 55392c207a39bdbc44dbc6ed701d6f6f5721177f..f78a06112887e50885f95e39372d096b40b9b6a6 100644 (file)
@@ -77,9 +77,6 @@ static void default_values(starter_config_t *cfg)
 #ifdef START_CHARON
        cfg->setup.charonstart = TRUE;
 #endif
-#ifdef START_PLUTO
-       cfg->setup.plutostart  = TRUE;
-#endif
 
        cfg->conn_default.seen    = SEEN_NONE;
        cfg->conn_default.startup = STARTUP_NO;
@@ -143,20 +140,13 @@ static void load_setup(starter_config_t *cfg, config_parsed_t *cfgp)
                }
        }
 
-       /* verify the executables are actually available (some distros split
-        * packages but enabled both) */
+       /* verify the executables are actually available */
 #ifdef START_CHARON
        cfg->setup.charonstart = cfg->setup.charonstart &&
                                                         daemon_exists("charon", CHARON_CMD);
 #else
        cfg->setup.charonstart = FALSE;
 #endif
-#ifdef START_PLUTO
-       cfg->setup.plutostart = cfg->setup.plutostart &&
-                                                       daemon_exists("pluto", PLUTO_CMD);
-#else
-       cfg->setup.plutostart = FALSE;
-#endif
 }
 
 static void kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token,
index 88857c0b2e1e98d5ea09cb1ff91a6053f15d3a60..96b76fdf173a4056fdc010ccc9b47d4297770839 100644 (file)
 #define CONFIG_FILE     IPSEC_CONFDIR "/ipsec.conf"
 #define SECRETS_FILE    IPSEC_CONFDIR "/ipsec.secrets"
 
-#define PLUTO_CMD       IPSEC_DIR "/pluto"
-#define PLUTO_CTL_FILE  IPSEC_PIDDIR "/pluto.ctl"
-#define PLUTO_PID_FILE  IPSEC_PIDDIR "/pluto.pid"
-
 #define CHARON_CMD      IPSEC_DIR "/charon"
 #define CHARON_CTL_FILE IPSEC_PIDDIR "/charon.ctl"
 #define CHARON_PID_FILE IPSEC_PIDDIR "/charon.pid"
diff --git a/src/whack/.gitignore b/src/whack/.gitignore
deleted file mode 100644 (file)
index b1bf2d8..0000000
+++ /dev/null
@@ -1 +0,0 @@
-whack
diff --git a/src/whack/Android.mk b/src/whack/Android.mk
deleted file mode 100644 (file)
index bf5ec0e..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-# copy-n-paste from Makefile.am
-LOCAL_SRC_FILES := \
-whack.c whack.h
-
-# build whack ------------------------------------------------------------------
-
-LOCAL_C_INCLUDES += \
-       $(libvstr_PATH) \
-       $(strongswan_PATH)/src/libstrongswan \
-       $(strongswan_PATH)/src/libfreeswan \
-       $(strongswan_PATH)/src/libhydra \
-       $(strongswan_PATH)/src/pluto
-
-LOCAL_CFLAGS := $(strongswan_CFLAGS)
-
-LOCAL_MODULE := whack
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_ARM_MODE := arm
-
-LOCAL_PRELINK_MODULE := false
-
-LOCAL_SHARED_LIBRARIES += libstrongswan libfreeswan
-
-include $(BUILD_EXECUTABLE)
-
diff --git a/src/whack/Makefile.am b/src/whack/Makefile.am
deleted file mode 100644 (file)
index 2337447..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-ipsec_PROGRAMS = whack
-
-whack_SOURCES = \
-whack.c whack.h
-
-INCLUDES = \
--I$(top_srcdir)/src/libstrongswan \
--I$(top_srcdir)/src/libfreeswan \
--I$(top_srcdir)/src/libhydra \
--I$(top_srcdir)/src/pluto
-
-whack_LDADD = \
-$(top_builddir)/src/libstrongswan/libstrongswan.la \
-$(top_builddir)/src/libfreeswan/libfreeswan.a
-
-AM_CFLAGS = -DDEBUG -DIPSEC_PIDDIR=\"${piddir}\"
-
-EXTRA_DIST = Android.mk
diff --git a/src/whack/whack.c b/src/whack/whack.c
deleted file mode 100644 (file)
index a7945d6..0000000
+++ /dev/null
@@ -1,1959 +0,0 @@
-/* command interface to Pluto
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2001  D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <getopt.h>
-#include <assert.h>
-
-#include <freeswan.h>
-
-#include <utils/optionsfrom.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "whack.h"
-
-static void help(void)
-{
-       fprintf(stderr
-               , "Usage:\n\n"
-               "all forms:"
-                       " [--optionsfrom <filename>]"
-                       " [--ctlbase <path>]"
-                       " [--label <string>]"
-                       "\n\n"
-               "help: whack"
-                       " [--help]"
-                       " [--version]"
-                       "\n\n"
-               "connection: whack"
-                       " --name <connection_name>"
-                       " \\\n   "
-                       " [--ipv4 | --ipv6]"
-                       " [--tunnelipv4 | --tunnelipv6]"
-                       " \\\n   "
-                       " (--host <ip-address> | --id <identity>)"
-                       " \\\n   "
-                       " [--cert <path>]"
-                       " [--ca <distinguished name>]"
-                       " [--sendcert <policy>]"
-                       " \\\n   "
-                       " [--groups <access control groups>]"
-                       " \\\n   "
-                       " [--ikeport <port-number>]"
-                       " [--nexthop <ip-address>]"
-                       " [--srcip <ip-address>]"
-                       " \\\n   "
-                       " [--client <subnet> | --clientwithin <address range>]"
-                       " [--clientprotoport <protocol>/<port>]"
-                       " \\\n   "
-                       " [--dnskeyondemand]"
-                       " [--updown <updown>]"
-                       " \\\n   "
-                       " --to"
-                       " (--host <ip-address> | --id <identity>)"
-                       " \\\n   "
-                       " [--cert <path>]"
-                       " [--ca <distinguished name>]"
-                       " [--sendcert <policy>]"
-                       " \\\n   "
-                       " [--ikeport <port-number>]"
-                       " [--nexthop <ip-address>]"
-                       " [--srcip <ip-address>]"
-                       " \\\n   "
-                       " [--client <subnet> | --clientwithin <address range>]"
-                       " [--clientprotoport <protocol>/<port>]"
-                       " \\\n   "
-                       " [--dnskeyondemand]"
-                       " [--updown <updown>]"
-                       " [--psk]"
-                       " [--rsasig]"
-                       " \\\n   "
-                       " [--encrypt]"
-                       " [--authenticate]"
-                       " [--compress]"
-                       " [--tunnel]"
-                       " [--pfs]"
-                       " \\\n   "
-                       " [--ikelifetime <seconds>]"
-                       " [--ipseclifetime <seconds>]"
-                       " \\\n   "
-                       " [--reykeymargin <seconds>]"
-                       " [--reykeyfuzz <percentage>]"
-                       " \\\n   "
-                       " [--keyingtries <count>]"
-                       " \\\n   "
-                       " [--esp <esp-algos>]"
-                       " \\\n   "
-                       " [--dontrekey]"
-
-                       " [--dpdaction (none|clear|hold|restart)]"
-                       " \\\n   "
-                       " [--dpddelay <seconds> --dpdtimeout <seconds>]"
-                       " \\\n   "
-                       " [--initiateontraffic|--pass|--drop|--reject]"
-                       " \\\n   "
-                       " [--failnone|--failpass|--faildrop|--failreject]"
-                       "\n\n"
-               "routing: whack"
-                       " (--route | --unroute)"
-                       " --name <connection_name>"
-                       "\n\n"
-               "initiation:"
-                       "\n "
-                       " whack"
-                       " (--initiate | --terminate)"
-                       " --name <connection_name>"
-                       " [--asynchronous]"
-                       "\n\n"
-               "opportunistic initiation: whack"
-                       " [--tunnelipv4 | --tunnelipv6]"
-                       " \\\n   "
-                       " --oppohere <ip-address>"
-                       " --oppothere <ip-address>"
-                       "\n\n"
-               "delete: whack"
-                       " --delete"
-                       " (--name <connection_name> | --caname <ca name>)"
-                       "\n\n"
-               "deletestate: whack"
-                       " --deletestate <state_object_number>"
-                       " --crash <ip-address>"
-                       "\n\n"
-               "pubkey: whack"
-                       " --keyid <id>"
-                       " [--addkey]"
-                       " [--pubkeyrsa <key>]"
-                       "\n\n"
-               "myid: whack"
-                       " --myid <id>"
-                       "\n\n"
-               "ca: whack"
-                       " --caname <name>"
-                       " --cacert <path>"
-                       " \\\n   "
-                       " [--ldaphost <hostname>]"
-                       " [--ldapbase <base>]"
-                       " \\\n   "
-                       " [--crluri <uri>]"
-                       " [--crluri2 <uri>]"
-                       " [--ocspuri <uri>]"
-                       " [--strictcrlpolicy]"
-                       "\n\n"
-#ifdef DEBUG
-               "debug: whack [--name <connection_name>]"
-                       " \\\n   "
-                       " [--debug-none]"
-                       " [--debug-all]"
-                       " \\\n   "
-                       " [--debug-raw]"
-                       " [--debug-crypt]"
-                       " [--debug-parsing]"
-                       " [--debug-emitting]"
-                       " \\\n   "
-                       " [--debug-control]"
-                       " [--debug-lifecycle]"
-                       " [--debug-kernel]"
-                       " [--debug-dns]"
-                       " \\\n   "
-                       " [--debug-natt]"
-                       " [--debug-oppo]"
-                       " [--debug-controlmore]"
-                       " [--debug-private]"
-                       "\n\n"
-#endif
-               "leases: whack --leases"
-                       " [--name <connection_name>]"
-                       " [--lease-addr <ip-address> | --lease-id <identity>]"
-                       "\n\n"
-               "listen: whack"
-                       " (--listen | --unlisten)"
-                       "\n\n"
-               "list: whack [--utc]"
-                       " [--listalgs]"
-                       " [--listpubkeys]"
-                       " [--listcerts]"
-                       " [--listcacerts]"
-                       " \\\n   "
-                       " [--listacerts]"
-                       " [--listaacerts]"
-                       " [--listocspcerts]"
-                       " [--listgroups]"
-                       " \\\n   "
-                       " [--listcainfos]"
-                       " [--listcrls]"
-                       " [--listocsp]"
-                       " [--listcards]"
-                       " [--listplugins]"
-                       " [--listall]"
-                       "\n\n"
-               "purge: whack"
-                       " [--purgeocsp]"
-                       "\n\n"
-               "reread: whack"
-                       " [--rereadsecrets]"
-                       " [--rereadcacerts]"
-                       " [--rereadaacerts]"
-                       " \\\n   "
-                       " [--rereadocspcerts]"
-                       " [--rereadacerts]"
-                       " [--rereadcrls]"
-                       " [--rereadall]"
-                       "\n\n"
-               "status: whack"
-                       " [--name <connection_name>] --status|--statusall"
-                       "\n\n"
-               "scdecrypt: whack"
-                       " --scencrypt|scdecrypt <value>"
-                       " [--inbase <base>]"
-                       " [--outbase <base>]"
-                       " [--keyid <id>]"
-                       "\n\n"
-               "shutdown: whack"
-                       " --shutdown"
-                       "\n\n"
-               "strongSwan "VERSION"\n");
-}
-
-static const char *label = NULL;        /* --label operand, saved for diagnostics */
-
-static const char *name = NULL; /* --name operand, saved for diagnostics */
-
-/* options read by optionsfrom */
-options_t *options;
-
-/**
- * exit whack after cleaning up
- */
-static void whack_exit(int status)
-{
-       options->destroy(options);
-       exit(status);
-}
-
-/**
- * print a string as a diagnostic, then exit whack unhappily
- */
-static void diag(const char *mess)
-{
-       if (mess != NULL)
-       {
-               fprintf(stderr, "whack error: ");
-               if (label != NULL)
-               {
-                       fprintf(stderr, "%s ", label);
-               }
-               if (name != NULL)
-               {
-                       fprintf(stderr, "\"%s\" ", name);
-               }
-               fprintf(stderr, "%s\n", mess);
-       }
-       whack_exit(RC_WHACK_PROBLEM);
-}
-
-/* conditially calls diag; prints second arg, if non-NULL, as quoted string */
-static void diagq(err_t ugh, const char *this)
-{
-       if (ugh != NULL)
-       {
-               if (this == NULL)
-               {
-                       diag(ugh);
-               }
-               else
-               {
-                       char buf[120];      /* arbitrary limit */
-
-                       snprintf(buf, sizeof(buf), "%s \"%s\"", ugh, this);
-                       diag(buf);
-               }
-       }
-}
-
-/* complex combined operands return one of these enumerated values
- * Note: these become flags in an lset_t.  Since there are more than
- * 32, we partition them into:
- * - OPT_* options (most random options)
- * - LST_* options (list various internal data)
- * - DBGOPT_* option (DEBUG options)
- * - END_* options (End description options)
- * - CD_* options (Connection Description options)
- * - CA_* options (CA description options)
- */
-enum {
-#   define OPT_FIRST    OPT_CTLBASE
-       OPT_CTLBASE,
-       OPT_NAME,
-
-       OPT_CD,
-
-       OPT_KEYID,
-       OPT_ADDKEY,
-       OPT_PUBKEYRSA,
-
-       OPT_MYID,
-
-       OPT_ROUTE,
-       OPT_UNROUTE,
-
-       OPT_INITIATE,
-       OPT_TERMINATE,
-       OPT_DELETE,
-       OPT_DELETESTATE,
-       OPT_LISTEN,
-       OPT_UNLISTEN,
-
-       OPT_LEASES,
-       OPT_LEASEADDR,
-       OPT_LEASEID,
-
-       OPT_PURGEOCSP,
-
-       OPT_REREADSECRETS,
-       OPT_REREADCACERTS,
-       OPT_REREADAACERTS,
-       OPT_REREADOCSPCERTS,
-       OPT_REREADACERTS,
-       OPT_REREADCRLS,
-       OPT_REREADALL,
-
-       OPT_STATUS,
-       OPT_STATUSALL,
-       OPT_SHUTDOWN,
-
-       OPT_OPPO_HERE,
-       OPT_OPPO_THERE,
-
-       OPT_ASYNC,
-       OPT_DELETECRASH,
-
-#   define OPT_LAST OPT_ASYNC   /* last "normal" option */
-
-/* Smartcard options */
-
-#   define SC_FIRST SC_ENCRYPT  /* first smartcard option */
-
-       SC_ENCRYPT,
-       SC_DECRYPT,
-       SC_INBASE,
-       SC_OUTBASE,
-
-#   define SC_LAST SC_OUTBASE   /* last "smartcard" option */
-
-/* List options */
-
-#   define LST_FIRST LST_UTC    /* first list option */
-       LST_UTC,
-       LST_ALGS,
-       LST_PUBKEYS,
-       LST_CERTS,
-       LST_CACERTS,
-       LST_ACERTS,
-       LST_AACERTS,
-       LST_OCSPCERTS,
-       LST_GROUPS,
-       LST_CAINFOS,
-       LST_CRLS,
-       LST_OCSP,
-       LST_CARDS,
-       LST_PLUGINS,
-       LST_ALL,
-
-#   define LST_LAST LST_ALL     /* last list option */
-
-/* Connection End Description options */
-
-#   define END_FIRST END_HOST   /* first end description */
-       END_HOST,
-       END_ID,
-       END_CERT,
-       END_CA,
-       END_SENDCERT,
-       END_GROUPS,
-       END_IKEPORT,
-       END_NEXTHOP,
-       END_CLIENT,
-       END_CLIENTWITHIN,
-       END_CLIENTPROTOPORT,
-       END_DNSKEYONDEMAND,
-       END_SRCIP,
-       END_HOSTACCESS,
-       END_UPDOWN,
-
-#define END_LAST  END_UPDOWN    /* last end description*/
-
-/* Connection Description options -- segregated */
-
-#   define CD_FIRST CD_TO       /* first connection description */
-       CD_TO,
-
-#   define CD_POLICY_FIRST  CD_PSK
-       CD_PSK,     /* same order as POLICY_* */
-       CD_RSASIG,  /* same order as POLICY_* */
-       CD_ENCRYPT, /* same order as POLICY_* */
-       CD_AUTHENTICATE,    /* same order as POLICY_* */
-       CD_COMPRESS,        /* same order as POLICY_* */
-       CD_TUNNEL,  /* same order as POLICY_* */
-       CD_PFS,     /* same order as POLICY_* */
-       CD_DISABLEARRIVALCHECK,     /* same order as POLICY_* */
-       CD_SHUNT0,  /* same order as POLICY_* */
-       CD_SHUNT1,  /* same order as POLICY_* */
-       CD_FAIL0,   /* same order as POLICY_* */
-       CD_FAIL1,   /* same order as POLICY_* */
-       CD_DONT_REKEY,      /* same order as POLICY_* */
-
-       CD_TUNNELIPV4,
-       CD_TUNNELIPV6,
-       CD_CONNIPV4,
-       CD_CONNIPV6,
-
-       CD_IKELIFETIME,
-       CD_IPSECLIFETIME,
-       CD_RKMARGIN,
-       CD_RKFUZZ,
-       CD_KTRIES,
-       CD_DPDACTION,
-       CD_DPDDELAY,
-       CD_DPDTIMEOUT,
-       CD_IKE,
-       CD_PFSGROUP,
-       CD_ESP,
-
-#   define CD_LAST CD_ESP       /* last connection description */
-
-/* Certificate Authority (CA) description options */
-
-#   define CA_FIRST CA_NAME     /* first ca description */
-
-       CA_NAME,
-       CA_CERT,
-       CA_LDAPHOST,
-       CA_LDAPBASE,
-       CA_CRLURI,
-       CA_CRLURI2,
-       CA_OCSPURI,
-       CA_STRICT
-
-#   define CA_LAST CA_STRICT    /* last ca description */
-
-#ifdef DEBUG    /* must be last so others are less than 32 to fit in lset_t */
-#   define DBGOPT_FIRST DBGOPT_NONE
-       ,
-       /* NOTE: these definitions must match DBG_* and IMPAIR_* in constants.h */
-       DBGOPT_NONE,
-       DBGOPT_ALL,
-
-       DBGOPT_RAW,         /* same order as DBG_* */
-       DBGOPT_CRYPT,       /* same order as DBG_* */
-       DBGOPT_PARSING,     /* same order as DBG_* */
-       DBGOPT_EMITTING,    /* same order as DBG_* */
-       DBGOPT_CONTROL,     /* same order as DBG_* */
-       DBGOPT_LIFECYCLE,   /* same order as DBG_* */
-       DBGOPT_KERNEL,      /* same order as DBG_* */
-       DBGOPT_DNS,         /* same order as DBG_* */
-       DBGOPT_NATT,        /* same order as DBG_* */
-       DBGOPT_OPPO,        /* same order as DBG_* */
-       DBGOPT_CONTROLMORE, /* same order as DBG_* */
-
-       DBGOPT_PRIVATE,     /* same order as DBG_* */
-
-       DBGOPT_IMPAIR_DELAY_ADNS_KEY_ANSWER,        /* same order as IMPAIR_* */
-       DBGOPT_IMPAIR_DELAY_ADNS_TXT_ANSWER,        /* same order as IMPAIR_* */
-       DBGOPT_IMPAIR_BUST_MI2,     /* same order as IMPAIR_* */
-       DBGOPT_IMPAIR_BUST_MR2      /* same order as IMPAIR_* */
-
-#   define DBGOPT_LAST DBGOPT_IMPAIR_BUST_MR2
-#endif
-
-};
-
-/* Carve up space for result from getop_long.
- * Stupidly, the only result is an int.
- * Numeric arg is bit immediately left of basic value.
- *
- */
-#define OPTION_OFFSET   256     /* to get out of the way of letter options */
-#define NUMERIC_ARG (1 << 9)    /* expect a numeric argument */
-#define AUX_SHIFT   10  /* amount to shift for aux information */
-
-static const struct option long_opts[] = {
-#   define OO   OPTION_OFFSET
-       /* name, has_arg, flag, val */
-
-       { "help", no_argument, NULL, 'h' },
-       { "version", no_argument, NULL, 'v' },
-       { "optionsfrom", required_argument, NULL, '+' },
-       { "label", required_argument, NULL, 'l' },
-
-       { "ctlbase", required_argument, NULL, OPT_CTLBASE + OO },
-       { "name", required_argument, NULL, OPT_NAME + OO },
-
-       { "keyid", required_argument, NULL, OPT_KEYID + OO },
-       { "addkey", no_argument, NULL, OPT_ADDKEY + OO },
-       { "pubkeyrsa", required_argument, NULL, OPT_PUBKEYRSA + OO },
-
-       { "myid", required_argument, NULL, OPT_MYID + OO },
-
-       { "route", no_argument, NULL, OPT_ROUTE + OO },
-       { "unroute", no_argument, NULL, OPT_UNROUTE + OO },
-
-       { "initiate", no_argument, NULL, OPT_INITIATE + OO },
-       { "terminate", no_argument, NULL, OPT_TERMINATE + OO },
-       { "delete", no_argument, NULL, OPT_DELETE + OO },
-       { "deletestate", required_argument, NULL, OPT_DELETESTATE + OO + NUMERIC_ARG },
-       { "crash", required_argument, NULL, OPT_DELETECRASH + OO },
-       { "listen", no_argument, NULL, OPT_LISTEN + OO },
-       { "unlisten", no_argument, NULL, OPT_UNLISTEN + OO },
-
-       { "leases", no_argument, NULL, OPT_LEASES + OO },
-       { "lease-addr", required_argument, NULL, OPT_LEASEADDR + OO },
-       { "lease-id", required_argument, NULL, OPT_LEASEID + OO },
-
-       { "purgeocsp", no_argument, NULL, OPT_PURGEOCSP + OO },
-
-       { "rereadsecrets", no_argument, NULL, OPT_REREADSECRETS + OO },
-       { "rereadcacerts", no_argument, NULL, OPT_REREADCACERTS + OO },
-       { "rereadaacerts", no_argument, NULL, OPT_REREADAACERTS + OO },
-       { "rereadocspcerts", no_argument, NULL, OPT_REREADOCSPCERTS + OO },
-       { "rereadacerts", no_argument, NULL, OPT_REREADACERTS + OO },
-       { "rereadcrls", no_argument, NULL, OPT_REREADCRLS + OO },
-       { "rereadall", no_argument, NULL, OPT_REREADALL + OO },
-       { "status", no_argument, NULL, OPT_STATUS + OO },
-       { "statusall", no_argument, NULL, OPT_STATUSALL + OO },
-       { "shutdown", no_argument, NULL, OPT_SHUTDOWN + OO },
-
-       { "oppohere", required_argument, NULL, OPT_OPPO_HERE + OO },
-       { "oppothere", required_argument, NULL, OPT_OPPO_THERE + OO },
-
-       { "asynchronous", no_argument, NULL, OPT_ASYNC + OO },
-
-       /* smartcard options */
-
-       { "scencrypt", required_argument, NULL, SC_ENCRYPT + OO },
-       { "scdecrypt", required_argument, NULL, SC_DECRYPT + OO },
-       { "inbase", required_argument, NULL, SC_INBASE + OO },
-       { "outbase", required_argument, NULL, SC_OUTBASE + OO },
-
-       /* list options */
-
-       { "utc", no_argument, NULL, LST_UTC + OO },
-       { "listalgs", no_argument, NULL, LST_ALGS + OO },
-       { "listpubkeys", no_argument, NULL, LST_PUBKEYS + OO },
-       { "listcerts", no_argument, NULL, LST_CERTS + OO },
-       { "listcacerts", no_argument, NULL, LST_CACERTS + OO },
-       { "listacerts", no_argument, NULL, LST_ACERTS + OO },
-       { "listaacerts", no_argument, NULL, LST_AACERTS + OO },
-       { "listocspcerts", no_argument, NULL, LST_OCSPCERTS + OO },
-       { "listgroups", no_argument, NULL, LST_GROUPS + OO },
-       { "listcainfos", no_argument, NULL, LST_CAINFOS + OO },
-       { "listcrls", no_argument, NULL, LST_CRLS + OO },
-       { "listocsp", no_argument, NULL, LST_OCSP + OO },
-       { "listcards", no_argument, NULL, LST_CARDS + OO },
-       { "listplugins", no_argument, NULL, LST_PLUGINS + OO },
-       { "listall", no_argument, NULL, LST_ALL + OO },
-
-       /* options for an end description */
-
-       { "host", required_argument, NULL, END_HOST + OO },
-       { "id", required_argument, NULL, END_ID + OO },
-       { "cert", required_argument, NULL, END_CERT + OO },
-       { "ca", required_argument, NULL, END_CA + OO },
-       { "sendcert", required_argument, NULL, END_SENDCERT + OO },
-       { "groups", required_argument, NULL, END_GROUPS + OO },
-       { "ikeport", required_argument, NULL, END_IKEPORT + OO + NUMERIC_ARG },
-       { "nexthop", required_argument, NULL, END_NEXTHOP + OO },
-       { "client", required_argument, NULL, END_CLIENT + OO },
-       { "clientwithin", required_argument, NULL, END_CLIENTWITHIN + OO },
-       { "clientprotoport", required_argument, NULL, END_CLIENTPROTOPORT + OO },
-       { "dnskeyondemand", no_argument, NULL, END_DNSKEYONDEMAND + OO },
-       { "srcip",  required_argument, NULL, END_SRCIP + OO },
-       { "hostaccess", no_argument, NULL, END_HOSTACCESS + OO },
-       { "updown", required_argument, NULL, END_UPDOWN + OO },
-
-       /* options for a connection description */
-
-       { "to", no_argument, NULL, CD_TO + OO },
-
-       { "psk", no_argument, NULL, CD_PSK + OO },
-       { "rsasig", no_argument, NULL, CD_RSASIG + OO },
-
-       { "encrypt", no_argument, NULL, CD_ENCRYPT + OO },
-       { "authenticate", no_argument, NULL, CD_AUTHENTICATE + OO },
-       { "compress", no_argument, NULL, CD_COMPRESS + OO },
-       { "tunnel", no_argument, NULL, CD_TUNNEL + OO },
-       { "tunnelipv4", no_argument, NULL, CD_TUNNELIPV4 + OO },
-       { "tunnelipv6", no_argument, NULL, CD_TUNNELIPV6 + OO },
-       { "pfs", no_argument, NULL, CD_PFS + OO },
-       { "disablearrivalcheck", no_argument, NULL, CD_DISABLEARRIVALCHECK + OO },
-       { "initiateontraffic", no_argument, NULL
-               , CD_SHUNT0 + (POLICY_SHUNT_TRAP >> POLICY_SHUNT_SHIFT << AUX_SHIFT) + OO },
-       { "pass", no_argument, NULL
-               , CD_SHUNT0 + (POLICY_SHUNT_PASS >> POLICY_SHUNT_SHIFT << AUX_SHIFT) + OO },
-       { "drop", no_argument, NULL
-               , CD_SHUNT0 + (POLICY_SHUNT_DROP >> POLICY_SHUNT_SHIFT << AUX_SHIFT) + OO },
-       { "reject", no_argument, NULL
-               , CD_SHUNT0 + (POLICY_SHUNT_REJECT >> POLICY_SHUNT_SHIFT << AUX_SHIFT) + OO },
-       { "failnone", no_argument, NULL
-               , CD_FAIL0 + (POLICY_FAIL_NONE >> POLICY_FAIL_SHIFT << AUX_SHIFT) + OO },
-       { "failpass", no_argument, NULL
-               , CD_FAIL0 + (POLICY_FAIL_PASS >> POLICY_FAIL_SHIFT << AUX_SHIFT) + OO },
-       { "faildrop", no_argument, NULL
-               , CD_FAIL0 + (POLICY_FAIL_DROP >> POLICY_FAIL_SHIFT << AUX_SHIFT) + OO },
-       { "failreject", no_argument, NULL
-               , CD_FAIL0 + (POLICY_FAIL_REJECT >> POLICY_FAIL_SHIFT << AUX_SHIFT) + OO },
-       { "dontrekey", no_argument, NULL, CD_DONT_REKEY + OO },
-       { "ipv4", no_argument, NULL, CD_CONNIPV4 + OO },
-       { "ipv6", no_argument, NULL, CD_CONNIPV6 + OO },
-
-       { "ikelifetime", required_argument, NULL, CD_IKELIFETIME + OO + NUMERIC_ARG },
-       { "ipseclifetime", required_argument, NULL, CD_IPSECLIFETIME + OO + NUMERIC_ARG },
-       { "rekeymargin", required_argument, NULL, CD_RKMARGIN + OO + NUMERIC_ARG },
-       { "rekeywindow", required_argument, NULL, CD_RKMARGIN + OO + NUMERIC_ARG }, /* OBSOLETE */
-       { "rekeyfuzz", required_argument, NULL, CD_RKFUZZ + OO + NUMERIC_ARG },
-       { "keyingtries", required_argument, NULL, CD_KTRIES + OO + NUMERIC_ARG },
-       { "dpdaction", required_argument, NULL, CD_DPDACTION + OO },
-       { "dpddelay", required_argument, NULL, CD_DPDDELAY + OO + NUMERIC_ARG },
-       { "dpdtimeout", required_argument, NULL, CD_DPDTIMEOUT + OO + NUMERIC_ARG },
-       { "ike", required_argument, NULL, CD_IKE + OO },
-       { "pfsgroup", required_argument, NULL, CD_PFSGROUP + OO },
-       { "esp", required_argument, NULL, CD_ESP + OO },
-
-       /* options for a ca description */
-
-       { "caname", required_argument, NULL, CA_NAME + OO },
-       { "cacert", required_argument, NULL, CA_CERT + OO },
-       { "ldaphost", required_argument, NULL, CA_LDAPHOST + OO },
-       { "ldapbase", required_argument, NULL, CA_LDAPBASE + OO },
-       { "crluri", required_argument, NULL, CA_CRLURI + OO },
-       { "crluri2", required_argument, NULL, CA_CRLURI2 + OO },
-       { "ocspuri", required_argument, NULL, CA_OCSPURI + OO },
-       { "strictcrlpolicy", no_argument, NULL, CA_STRICT + OO },
-
-#ifdef DEBUG
-       { "debug-none", no_argument, NULL, DBGOPT_NONE + OO },
-       { "debug-all]", no_argument, NULL, DBGOPT_ALL + OO },
-       { "debug-raw", no_argument, NULL, DBGOPT_RAW + OO },
-       { "debug-crypt", no_argument, NULL, DBGOPT_CRYPT + OO },
-       { "debug-parsing", no_argument, NULL, DBGOPT_PARSING + OO },
-       { "debug-emitting", no_argument, NULL, DBGOPT_EMITTING + OO },
-       { "debug-control", no_argument, NULL, DBGOPT_CONTROL + OO },
-       { "debug-lifecycle", no_argument, NULL, DBGOPT_LIFECYCLE + OO },
-       { "debug-klips", no_argument, NULL, DBGOPT_KERNEL + OO },
-       { "debug-kernel", no_argument, NULL, DBGOPT_KERNEL + OO },
-       { "debug-dns", no_argument, NULL, DBGOPT_DNS + OO },
-       { "debug-natt", no_argument, NULL, DBGOPT_NATT + OO },
-       { "debug-oppo", no_argument, NULL, DBGOPT_OPPO + OO },
-       { "debug-controlmore", no_argument, NULL, DBGOPT_CONTROLMORE + OO },
-       { "debug-private", no_argument, NULL, DBGOPT_PRIVATE + OO },
-
-       { "impair-delay-adns-key-answer", no_argument, NULL, DBGOPT_IMPAIR_DELAY_ADNS_KEY_ANSWER + OO },
-       { "impair-delay-adns-txt-answer", no_argument, NULL, DBGOPT_IMPAIR_DELAY_ADNS_TXT_ANSWER + OO },
-       { "impair-bust-mi2", no_argument, NULL, DBGOPT_IMPAIR_BUST_MI2 + OO },
-       { "impair-bust-mr2", no_argument, NULL, DBGOPT_IMPAIR_BUST_MR2 + OO },
-#endif
-#   undef OO
-       { 0,0,0,0 }
-};
-
-struct sockaddr_un ctl_addr = { AF_UNIX, DEFAULT_CTLBASE CTL_SUFFIX };
-
-/* helper variables and function to encode strings from whack message */
-
-static char    *next_str,*str_roof;
-
-static bool pack_str(char **p)
-{
-       const char *s = *p == NULL? "" : *p;        /* note: NULL becomes ""! */
-       size_t len = strlen(s) + 1;
-
-       if (str_roof - next_str < (ptrdiff_t)len)
-       {
-               return FALSE;   /* fishy: no end found */
-       }
-       else
-       {
-               strcpy(next_str, s);
-               next_str += len;
-               *p = NULL;      /* don't send pointers on the wire! */
-               return TRUE;
-       }
-}
-
-static void check_life_time(time_t life, time_t limit, const char *which,
-                                                       const whack_message_t *msg)
-{
-       time_t mint = msg->sa_rekey_margin * (100 + msg->sa_rekey_fuzz) / 100;
-
-       if (life > limit)
-       {
-               char buf[200];  /* arbitrary limit */
-
-               snprintf(buf, sizeof(buf)
-                       , "%s [%lu seconds] must be less than %lu seconds"
-                       , which, (unsigned long)life, (unsigned long)limit);
-               diag(buf);
-       }
-       if ((msg->policy & POLICY_DONT_REKEY) == LEMPTY && life <= mint)
-       {
-               char buf[200];  /* arbitrary limit */
-
-               snprintf(buf, sizeof(buf)
-                       , "%s [%lu] must be greater than"
-                       " rekeymargin*(100+rekeyfuzz)/100 [%lu*(100+%lu)/100 = %lu]"
-                       , which
-                       , (unsigned long)life
-                       , (unsigned long)msg->sa_rekey_margin
-                       , (unsigned long)msg->sa_rekey_fuzz
-                       , (unsigned long)mint);
-               diag(buf);
-       }
-}
-
-static void clear_end(whack_end_t *e)
-{
-       zero(e);
-       e->id = NULL;
-       e->cert = NULL;
-       e->ca = NULL;
-       e->updown = NULL;
-       e->host_port = IKE_UDP_PORT;
-}
-
-static void update_ports(whack_message_t *m)
-{
-       int port;
-
-       if (m->left.port != 0) {
-               port = htons(m->left.port);
-               setportof(port, &m->left.host_addr);
-               setportof(port, &m->left.client.addr);
-       }
-       if (m->right.port != 0) {
-               port = htons(m->right.port);
-               setportof(port, &m->right.host_addr);
-               setportof(port, &m->right.client.addr);
-       }
-}
-
-static void check_end(whack_end_t *this, whack_end_t *that,
-                                         bool default_nexthop, sa_family_t caf, sa_family_t taf)
-{
-       if (caf != addrtypeof(&this->host_addr))
-               diag("address family of host inconsistent");
-
-       if (default_nexthop)
-       {
-               if (isanyaddr(&that->host_addr))
-                       diag("our nexthop must be specified when other host is a %any or %opportunistic");
-               this->host_nexthop = that->host_addr;
-       }
-
-       if (caf != addrtypeof(&this->host_nexthop))
-               diag("address family of nexthop inconsistent");
-
-       if (this->has_client)
-       {
-               if (taf != subnettypeof(&this->client))
-                       diag("address family of client subnet inconsistent");
-       }
-       else
-       {
-               /* fill in anyaddr-anyaddr as (missing) client subnet */
-               ip_address cn;
-
-               diagq(anyaddr(caf, &cn), NULL);
-               diagq(rangetosubnet(&cn, &cn, &this->client), NULL);
-       }
-
-       /* fill in anyaddr if source IP is not defined */
-       if (!this->has_srcip)
-               diagq(anyaddr(caf, &this->host_srcip), optarg);
-
-   /* check protocol */
-       if (this->protocol != that->protocol)
-               diag("the protocol for leftprotoport and rightprotoport must be the same");
-}
-
-static void get_secret(int sock)
-{
-       const char *buf = NULL, *secret;
-       int len;
-
-       fflush(stdout);
-       usleep(20000); /* give fflush time for flushing */
-#ifdef HAVE_GETPASS
-       buf = getpass("Enter: ");
-#endif
-       secret = (buf == NULL)? "" : buf;
-
-       /* send the secret to pluto */
-       len = strlen(secret) + 1;
-       if (write(sock, secret, len) != len)
-       {
-               int e = errno;
-
-               fprintf(stderr, "whack: write() failed (%d %s)\n", e, strerror(e));
-               exit(RC_WHACK_PROBLEM);
-       }
-}
-
-/* This is a hack for initiating ISAKMP exchanges. */
-
-int main(int argc, char **argv)
-{
-       whack_message_t msg;
-       char esp_buf[256];  /* uses snprintf */
-       lset_t
-               opts_seen = LEMPTY,
-               sc_seen = LEMPTY,
-               lst_seen = LEMPTY,
-               cd_seen = LEMPTY,
-               ca_seen = LEMPTY,
-               end_seen = LEMPTY,
-               end_seen_before_to = LEMPTY;
-       const char
-               *af_used_by = NULL,
-               *tunnel_af_used_by = NULL;
-
-       /* check division of numbering space */
-#ifdef DEBUG
-       assert(OPTION_OFFSET + DBGOPT_LAST < NUMERIC_ARG);
-#else
-       assert(OPTION_OFFSET + CA_LAST < NUMERIC_ARG);
-#endif
-       assert(OPT_LAST - OPT_FIRST < (sizeof opts_seen * BITS_PER_BYTE));
-       assert(SC_LAST  - SC_FIRST  < (sizeof sc_seen   * BITS_PER_BYTE));
-       assert(LST_LAST - LST_FIRST < (sizeof lst_seen  * BITS_PER_BYTE));
-       assert(END_LAST - END_FIRST < (sizeof end_seen  * BITS_PER_BYTE));
-       assert(CD_LAST  - CD_FIRST  < (sizeof cd_seen   * BITS_PER_BYTE));
-       assert(CA_LAST  - CA_FIRST  < (sizeof ca_seen   * BITS_PER_BYTE));
-#ifdef DEBUG    /* must be last so others are less than (sizeof cd_seen * BITS_PER_BYTE) to fit in lset_t */
-       assert(DBGOPT_LAST - DBGOPT_FIRST < (sizeof cd_seen * BITS_PER_BYTE));
-#endif
-       /* check that POLICY bit assignment matches with CD_ */
-       assert(LELEM(CD_DONT_REKEY - CD_POLICY_FIRST) == POLICY_DONT_REKEY);
-
-       zero(&msg);
-
-       clear_end(&msg.right);      /* left set from this after --to */
-
-       msg.name = NULL;
-       msg.keyid = NULL;
-       msg.keyval.ptr = NULL;
-       msg.esp = NULL;
-       msg.ike = NULL;
-       msg.pfsgroup = NULL;
-
-   /* if a connection is added via whack then we assume IKEv1 */
-       msg.ikev1 = TRUE;
-
-       msg.sa_ike_life_seconds = OAKLEY_ISAKMP_SA_LIFETIME_DEFAULT;
-       msg.sa_ipsec_life_seconds = PLUTO_SA_LIFE_DURATION_DEFAULT;
-       msg.sa_rekey_margin = SA_REPLACEMENT_MARGIN_DEFAULT;
-       msg.sa_rekey_fuzz = SA_REPLACEMENT_FUZZ_DEFAULT;
-       msg.sa_keying_tries = SA_REPLACEMENT_RETRIES_DEFAULT;
-
-       msg.addr_family = AF_INET;
-       msg.tunnel_addr_family = AF_INET;
-
-       msg.cacert = NULL;
-       msg.ldaphost = NULL;
-       msg.ldapbase = NULL;
-       msg.crluri = NULL;
-       msg.crluri2 = NULL;
-       msg.ocspuri = NULL;
-
-       options = options_create();
-
-       for (;;)
-       {
-               int long_index;
-               unsigned long opt_whole = 0;  /* numeric argument for some flags */
-
-               /* Note: we don't like the way short options get parsed
-                * by getopt_long, so we simply pass an empty string as
-                * the list.  It could be "hp:d:c:o:eatfs" "NARXPECK".
-                */
-               int c = getopt_long(argc, argv, "", long_opts, &long_index) - OPTION_OFFSET;
-               int aux = 0;
-
-               /* decode a numeric argument, if expected */
-               if (0 <= c)
-               {
-                       if (c & NUMERIC_ARG)
-                       {
-                               char *endptr;
-
-                               c -= NUMERIC_ARG;
-                               opt_whole = strtoul(optarg, &endptr, 0);
-
-                               if (*endptr != '\0' || endptr == optarg)
-                                       diagq("badly formed numeric argument", optarg);
-                       }
-                       if (c >= (1 << AUX_SHIFT))
-                       {
-                               aux = c >> AUX_SHIFT;
-                               c -= aux << AUX_SHIFT;
-                       }
-               }
-
-               /* per-class option processing */
-               if (0 <= c && c <= OPT_LAST)
-               {
-                       /* OPT_* options get added to opts_seen.
-                        * Reject repeated options (unless later code intervenes).
-                        */
-                       lset_t f = LELEM(c);
-
-                       if (opts_seen & f)
-                               diagq("duplicated flag", long_opts[long_index].name);
-                       opts_seen |= f;
-               }
-               else if (SC_FIRST <= c && c <= SC_LAST)
-               {
-                       /* SC_* options get added to sc_seen.
-                        * Reject repeated options (unless later code intervenes).
-                        */
-                       lset_t f = LELEM(c - SC_FIRST);
-
-                       if (sc_seen & f)
-                               diagq("duplicated flag", long_opts[long_index].name);
-                       sc_seen |= f;
-               }
-               else if (LST_FIRST <= c && c <= LST_LAST)
-               {
-                       /* LST_* options get added to lst_seen.
-                        * Reject repeated options (unless later code intervenes).
-                        */
-                       lset_t f = LELEM(c - LST_FIRST);
-
-                       if (lst_seen & f)
-                               diagq("duplicated flag", long_opts[long_index].name);
-                       lst_seen |= f;
-               }
-#ifdef DEBUG
-               else if (DBGOPT_FIRST <= c && c <= DBGOPT_LAST)
-               {
-                       msg.whack_options = TRUE;
-               }
-#endif
-               else if (END_FIRST <= c && c <= END_LAST)
-               {
-                       /* END_* options are added to end_seen.
-                        * Reject repeated options (unless later code intervenes).
-                        */
-                       lset_t f = LELEM(c - END_FIRST);
-
-                       if (end_seen & f)
-                               diagq("duplicated flag", long_opts[long_index].name);
-                       end_seen |= f;
-                       opts_seen |= LELEM(OPT_CD);
-               }
-               else if (CD_FIRST <= c && c <= CD_LAST)
-               {
-                       /* CD_* options are added to cd_seen.
-                        * Reject repeated options (unless later code intervenes).
-                        */
-                       lset_t f = LELEM(c - CD_FIRST);
-
-                       if (cd_seen & f)
-                               diagq("duplicated flag", long_opts[long_index].name);
-                       cd_seen |= f;
-                       opts_seen |= LELEM(OPT_CD);
-               }
-               else if (CA_FIRST <= c && c <= CA_LAST)
-               {
-                       /* CA_* options are added to ca_seen.
-                        * Reject repeated options (unless later code intervenes).
-                        */
-                       lset_t f = LELEM(c - CA_FIRST);
-
-                       if (ca_seen & f)
-                               diagq("duplicated flag", long_opts[long_index].name);
-                       ca_seen |= f;
-               }
-
-               /* Note: "break"ing from switch terminates loop.
-                * most cases should end with "continue".
-                */
-               switch (c)
-               {
-               case EOF - OPTION_OFFSET:       /* end of flags */
-                       break;
-
-               case 0 - OPTION_OFFSET: /* long option already handled */
-                       continue;
-
-               case ':' - OPTION_OFFSET:       /* diagnostic already printed by getopt_long */
-               case '?' - OPTION_OFFSET:       /* diagnostic already printed by getopt_long */
-                       diag(NULL); /* print no additional diagnostic, but exit sadly */
-                       break;      /* not actually reached */
-
-               case 'h' - OPTION_OFFSET:       /* --help */
-                       help();
-                       whack_exit(0);              /* GNU coding standards say to stop here */
-
-               case 'v' - OPTION_OFFSET:       /* --version */
-                       {
-                               const char **sp = ipsec_copyright_notice();
-
-                               printf("strongSwan "VERSION"\n");
-                               for (; *sp != NULL; sp++)
-                                       puts(*sp);
-                       }
-                       whack_exit(0);   /* GNU coding standards say to stop here */
-
-               case 'l' - OPTION_OFFSET:       /* --label <string> */
-                       label = optarg;             /* remember for diagnostics */
-                       continue;
-
-               case '+' - OPTION_OFFSET:       /* --optionsfrom <filename> */
-                       if (!options->from(options, optarg, &argc, &argv, optind))
-                       {
-                               fprintf(stderr, "optionsfrom failed");
-                               whack_exit(RC_WHACK_PROBLEM);
-                       }
-                       continue;
-
-               /* the rest of the options combine in complex ways */
-
-               case OPT_CTLBASE:       /* --port <ctlbase> */
-                       if (snprintf(ctl_addr.sun_path, sizeof(ctl_addr.sun_path)
-                       , "%s%s", optarg, CTL_SUFFIX) == -1)
-                               diag("<ctlbase>" CTL_SUFFIX " must be fit in a sun_addr");
-                       continue;
-
-               case OPT_NAME:  /* --name <connection-name> */
-                       name = optarg;
-                       msg.name = optarg;
-                       continue;
-
-               case OPT_KEYID: /* --keyid <identity> */
-                       msg.whack_key = !msg.whack_sc_op;
-                       msg.keyid = optarg; /* decoded by Pluto */
-                       continue;
-
-               case OPT_MYID:  /* --myid <identity> */
-                       msg.whack_myid = TRUE;
-                       msg.myid = optarg;  /* decoded by Pluto */
-                       continue;
-
-               case OPT_ADDKEY:        /* --addkey */
-                       msg.whack_addkey = TRUE;
-                       continue;
-
-               case OPT_PUBKEYRSA:     /* --pubkeyrsa <key> */
-                       {
-                               static char keyspace[RSA_MAX_ENCODING_BYTES];   /* room for 8K bit key */
-                               char diag_space[TTODATAV_BUF];
-                               const char *ugh = ttodatav(optarg, 0, 0
-                                       , keyspace, sizeof(keyspace)
-                                       , &msg.keyval.len, diag_space, sizeof(diag_space)
-                                       , TTODATAV_SPACECOUNTS);
-
-                               if (ugh != NULL)
-                               {
-                                       char ugh_space[80]; /* perhaps enough space */
-
-                                       snprintf(ugh_space, sizeof(ugh_space)
-                                               , "RSA public-key data malformed (%s)", ugh);
-                                       diagq(ugh_space, optarg);
-                               }
-                               msg.pubkey_alg = PUBKEY_ALG_RSA;
-                               msg.keyval.ptr = keyspace;
-                       }
-                       continue;
-
-               case OPT_ROUTE: /* --route */
-                       msg.whack_route = TRUE;
-                       continue;
-
-               case OPT_UNROUTE:       /* --unroute */
-                       msg.whack_unroute = TRUE;
-                       continue;
-
-               case OPT_INITIATE:      /* --initiate */
-                       msg.whack_initiate = TRUE;
-                       continue;
-
-               case OPT_TERMINATE:     /* --terminate */
-                       msg.whack_terminate = TRUE;
-                       continue;
-
-               case OPT_DELETE:        /* --delete */
-                       msg.whack_delete = TRUE;
-                       continue;
-
-               case OPT_DELETESTATE:   /* --deletestate <state_object_number> */
-                       msg.whack_deletestate = TRUE;
-                       msg.whack_deletestateno = opt_whole;
-                       continue;
-
-               case OPT_DELETECRASH:   /* --crash <ip-address> */
-                       msg.whack_crash = TRUE;
-                       tunnel_af_used_by = long_opts[long_index].name;
-                       diagq(ttoaddr(optarg, 0, msg.tunnel_addr_family, &msg.whack_crash_peer), optarg);
-                       if (isanyaddr(&msg.whack_crash_peer))
-                               diagq("0.0.0.0 or 0::0 isn't a valid client address", optarg);
-                       continue;
-
-               case OPT_LEASES:        /* --leases */
-                       msg.whack_leases = TRUE;
-                       continue;
-
-               case OPT_LEASEADDR:     /* --lease-addr <ip-address> */
-                       msg.whack_lease_ip = optarg;      /* decoded by Pluto */
-                       continue;
-
-               case OPT_LEASEID:       /* --lease-id <identity> */
-                       msg.whack_lease_id = optarg;      /* decoded by Pluto */
-                       continue;
-
-               case OPT_LISTEN:        /* --listen */
-                       msg.whack_listen = TRUE;
-                       continue;
-
-               case OPT_UNLISTEN:      /* --unlisten */
-                       msg.whack_unlisten = TRUE;
-                       continue;
-
-               case OPT_PURGEOCSP:     /* --purgeocsp */
-                       msg.whack_purgeocsp = TRUE;
-                       continue;
-
-               case OPT_REREADSECRETS:   /* --rereadsecrets */
-               case OPT_REREADCACERTS:   /* --rereadcacerts */
-               case OPT_REREADAACERTS:   /* --rereadaacerts */
-               case OPT_REREADOCSPCERTS: /* --rereadocspcerts */
-               case OPT_REREADACERTS:    /* --rereadacerts */
-               case OPT_REREADCRLS:      /* --rereadcrls */
-                       msg.whack_reread |= LELEM(c-OPT_REREADSECRETS);
-                       continue;
-
-               case OPT_REREADALL:     /* --rereadall */
-                       msg.whack_reread = REREAD_ALL;
-                       continue;
-
-               case OPT_STATUSALL:     /* --statusall */
-                       msg.whack_statusall = TRUE;
-                       /* fall through */
-
-               case OPT_STATUS:        /* --status */
-                       msg.whack_status = TRUE;
-                       continue;
-
-               case OPT_SHUTDOWN:      /* --shutdown */
-                       msg.whack_shutdown = TRUE;
-                       continue;
-
-               case OPT_OPPO_HERE:     /* --oppohere <ip-address> */
-                       tunnel_af_used_by = long_opts[long_index].name;
-                       diagq(ttoaddr(optarg, 0, msg.tunnel_addr_family, &msg.oppo_my_client), optarg);
-                       if (isanyaddr(&msg.oppo_my_client))
-                               diagq("0.0.0.0 or 0::0 isn't a valid client address", optarg);
-                       continue;
-
-               case OPT_OPPO_THERE:    /* --oppohere <ip-address> */
-                       tunnel_af_used_by = long_opts[long_index].name;
-                       diagq(ttoaddr(optarg, 0, msg.tunnel_addr_family, &msg.oppo_peer_client), optarg);
-                       if (isanyaddr(&msg.oppo_peer_client))
-                               diagq("0.0.0.0 or 0::0 isn't a valid client address", optarg);
-                       continue;
-
-               case OPT_ASYNC:
-                       msg.whack_async = TRUE;
-                       continue;
-
-               /* Smartcard options */
-
-               case SC_ENCRYPT:        /* --scencrypt <plaintext data> */
-               case SC_DECRYPT:        /* --scdecrypt <encrypted data> */
-                       msg.whack_sc_op = 1 + c - SC_ENCRYPT;
-                       msg.whack_key = FALSE;
-                       msg.sc_data = optarg;
-                       continue;
-
-               case SC_INBASE:         /* --inform  <format> */
-               case SC_OUTBASE:        /* --outform <format> */
-                  {
-                               int base = 0;
-
-                               if (streq(optarg, "16") || strcaseeq(optarg, "hex"))
-                                       base = 16;
-                               else if (streq(optarg, "64") || strcaseeq(optarg, "base64"))
-                                       base = 64;
-                               else if (streq(optarg, "256") || strcaseeq(optarg, "text")
-                                         || strcaseeq(optarg, "ascii"))
-                                       base = 256;
-                               else
-                                       diagq("not a valid base", optarg);
-
-                               if (c == SC_INBASE)
-                                       msg.inbase = base;
-                               else
-                                       msg.outbase = base;
-                       }
-                       continue;
-
-               /* List options */
-
-               case LST_UTC:           /* --utc */
-                       msg.whack_utc = TRUE;
-                       continue;
-
-               case LST_ALGS:          /* --listalgs */
-               case LST_PUBKEYS:       /* --listpubkeys */
-               case LST_CERTS:         /* --listcerts */
-               case LST_CACERTS:       /* --listcacerts */
-               case LST_ACERTS:        /* --listacerts */
-               case LST_AACERTS:       /* --listaacerts */
-               case LST_OCSPCERTS:     /* --listocspcerts */
-               case LST_GROUPS:        /* --listgroups */
-               case LST_CAINFOS:       /* --listcainfos */
-               case LST_CRLS:          /* --listcrls */
-               case LST_OCSP:          /* --listocsp */
-               case LST_CARDS:         /* --listcards */
-               case LST_PLUGINS:       /* --listplugins */
-                       msg.whack_list |= LELEM(c - LST_ALGS);
-                       continue;
-
-               case LST_ALL:   /* --listall */
-                       msg.whack_list = LIST_ALL;
-                       continue;
-
-               /* Connection Description options */
-
-               case END_HOST:  /* --host <ip-address> */
-               {
-                       lset_t new_policy = LEMPTY;
-
-                       af_used_by = long_opts[long_index].name;
-                       diagq(anyaddr(msg.addr_family, &msg.right.host_addr), optarg);
-                       if (streq(optarg, "%any"))
-                       {
-                       }
-                       else if (streq(optarg, "%opportunistic"))
-                       {
-                               /* always use tunnel mode; mark as opportunistic */
-                               new_policy |= POLICY_TUNNEL | POLICY_OPPO;
-                       }
-                       else if (streq(optarg, "%group"))
-                       {
-                               /* always use tunnel mode; mark as group */
-                               new_policy |= POLICY_TUNNEL | POLICY_GROUP;
-                       }
-                       else if (streq(optarg, "%opportunisticgroup"))
-                       {
-                               /* always use tunnel mode; mark as opportunistic */
-                               new_policy |= POLICY_TUNNEL | POLICY_OPPO | POLICY_GROUP;
-                       }
-                       else
-                       {
-                               diagq(ttoaddr(optarg, 0, msg.addr_family
-                                       , &msg.right.host_addr), optarg);
-                       }
-
-                       msg.policy |= new_policy;
-
-                       if (new_policy & (POLICY_OPPO | POLICY_GROUP))
-                       {
-                               if (!LHAS(end_seen, END_CLIENT - END_FIRST))
-                               {
-                                       /* set host to 0.0.0 and --client to 0.0.0.0/0
-                                        * or IPV6 equivalent
-                                        */
-                                       ip_address any;
-
-                                       tunnel_af_used_by = optarg;
-                                       diagq(anyaddr(msg.tunnel_addr_family, &any), optarg);
-                                       diagq(initsubnet(&any, 0, '0', &msg.right.client), optarg);
-                               }
-                               msg.right.has_client = TRUE;
-                       }
-                       if (new_policy & POLICY_GROUP)
-                       {
-                               /* client subnet must not be specified by user:
-                                * it will come from the group's file.
-                                */
-                               if (LHAS(end_seen, END_CLIENT - END_FIRST))
-                                       diag("--host %group clashes with --client");
-
-                               end_seen |= LELEM(END_CLIENT - END_FIRST);
-                       }
-                       if (new_policy & POLICY_OPPO)
-                               msg.right.key_from_DNS_on_demand = TRUE;
-                       continue;
-               }
-               case END_ID:    /* --id <identity> */
-                       msg.right.id = optarg;      /* decoded by Pluto */
-                       continue;
-
-               case END_CERT:  /* --cert <path> */
-                       msg.right.cert = optarg;    /* decoded by Pluto */
-                       continue;
-
-               case END_CA:    /* --ca <distinguished name> */
-                       msg.right.ca = optarg;      /* decoded by Pluto */
-                       continue;
-
-               case END_SENDCERT:
-                       if (streq(optarg, "yes") || streq(optarg, "always"))
-                       {
-                               msg.right.sendcert = CERT_ALWAYS_SEND;
-                       }
-                       else if (streq(optarg, "no") || streq(optarg, "never"))
-                       {
-                               msg.right.sendcert = CERT_NEVER_SEND;
-                       }
-                       else if (streq(optarg, "ifasked"))
-                       {
-                               msg.right.sendcert = CERT_SEND_IF_ASKED;
-                       }
-                       else
-                       {
-                               diagq("whack sendcert value is not legal", optarg);
-                       }
-                       continue;
-
-               case END_GROUPS:/* --groups <access control groups> */
-                       msg.right.groups = optarg;  /* decoded by Pluto */
-                       continue;
-
-               case END_IKEPORT:       /* --ikeport <port-number> */
-                       if (opt_whole<=0 || opt_whole >= 0x10000)
-                               diagq("<port-number> must be a number between 1 and 65535", optarg);
-                       msg.right.host_port = opt_whole;
-                       continue;
-
-               case END_NEXTHOP:       /* --nexthop <ip-address> */
-                       af_used_by = long_opts[long_index].name;
-                       if (streq(optarg, "%direct"))
-                               diagq(anyaddr(msg.addr_family
-                                       , &msg.right.host_nexthop), optarg);
-                       else
-                               diagq(ttoaddr(optarg, 0, msg.addr_family
-                                       , &msg.right.host_nexthop), optarg);
-                       continue;
-
-               case END_SRCIP:        /* --srcip <ip-address> */
-                       af_used_by = long_opts[long_index].name;
-                       if (streq(optarg, "%modeconfig") || streq(optarg, "%modecfg"))
-                       {
-                               msg.right.modecfg = TRUE;
-                       }
-                       else
-                       {
-                               diagq(ttoaddr(optarg, 0, msg.addr_family
-                                       , &msg.right.host_srcip), optarg);
-                               msg.right.has_srcip = TRUE;
-                       }
-                       msg.policy |= POLICY_TUNNEL;        /* srcip => tunnel */
-                       continue;
-
-               case END_CLIENT:        /* --client <subnet> */
-                       if (end_seen & LELEM(END_CLIENTWITHIN - END_FIRST))
-                               diag("--client conflicts with --clientwithin");
-                       tunnel_af_used_by = long_opts[long_index].name;
-                       if ((strlen(optarg) >= 6 && strncmp(optarg,"vhost:",6) == 0)
-                       ||  (strlen(optarg) >= 5 && strncmp(optarg,"vnet:",5) == 0))
-                       {
-                               msg.right.virt = optarg;
-                       }
-                       else
-                       {
-                               diagq(ttosubnet(optarg, 0, msg.tunnel_addr_family, &msg.right.client), optarg);
-                               msg.right.has_client = TRUE;
-                       }
-                       msg.policy |= POLICY_TUNNEL;        /* client => tunnel */
-                       continue;
-
-               case END_CLIENTWITHIN:  /* --clienwithin <address range> */
-                       if (end_seen & LELEM(END_CLIENT - END_FIRST))
-                               diag("--clientwithin conflicts with --client");
-                       tunnel_af_used_by = long_opts[long_index].name;
-                       diagq(ttosubnet(optarg, 0, msg.tunnel_addr_family, &msg.right.client), optarg);
-                       msg.right.has_client = TRUE;
-                       msg.policy |= POLICY_TUNNEL;        /* client => tunnel */
-                       msg.right.has_client_wildcard = TRUE;
-                       continue;
-
-               case END_CLIENTPROTOPORT: /* --clientprotoport <protocol>/<port> */
-                       diagq(ttoprotoport(optarg, 0, &msg.right.protocol, &msg.right.port
-                               , &msg.right.has_port_wildcard), optarg);
-                       continue;
-
-               case END_DNSKEYONDEMAND:        /* --dnskeyondemand */
-                       msg.right.key_from_DNS_on_demand = TRUE;
-                       continue;
-
-               case END_HOSTACCESS:    /* --hostaccess */
-                       msg.right.hostaccess = TRUE;
-                       continue;
-
-               case END_UPDOWN:        /* --updown <updown> */
-                       msg.right.updown = optarg;
-                       continue;
-
-               case CD_TO:             /* --to */
-                       /* process right end, move it to left, reset it */
-                       if (!LHAS(end_seen, END_HOST - END_FIRST))
-                               diag("connection missing --host before --to");
-                       msg.left = msg.right;
-                       clear_end(&msg.right);
-                       end_seen_before_to = end_seen;
-                       end_seen = LEMPTY;
-                       continue;
-
-               case CD_PSK:            /* --psk */
-               case CD_RSASIG:         /* --rsasig */
-               case CD_ENCRYPT:        /* --encrypt */
-               case CD_AUTHENTICATE:   /* --authenticate */
-               case CD_COMPRESS:       /* --compress */
-               case CD_TUNNEL:         /* --tunnel */
-               case CD_PFS:            /* --pfs */
-               case CD_DISABLEARRIVALCHECK:    /* --disablearrivalcheck */
-               case CD_DONT_REKEY:     /* --donotrekey */
-                       msg.policy |= LELEM(c - CD_POLICY_FIRST);
-                       continue;
-
-               /* --initiateontraffic
-                * --pass
-                * --drop
-                * --reject
-                */
-               case CD_SHUNT0:
-                       msg.policy = (msg.policy & ~POLICY_SHUNT_MASK)
-                               | ((lset_t)aux << POLICY_SHUNT_SHIFT);
-                       continue;
-
-               /* --failnone
-                * --failpass
-                * --faildrop
-                * --failreject
-                */
-               case CD_FAIL0:
-                       msg.policy = (msg.policy & ~POLICY_FAIL_MASK)
-                               | ((lset_t)aux << POLICY_FAIL_SHIFT);
-                       continue;
-
-               case CD_IKELIFETIME:    /* --ikelifetime <seconds> */
-                       msg.sa_ike_life_seconds = opt_whole;
-                       continue;
-
-               case CD_IPSECLIFETIME:  /* --ipseclifetime <seconds> */
-                       msg.sa_ipsec_life_seconds = opt_whole;
-                       continue;
-
-               case CD_RKMARGIN:       /* --rekeymargin <seconds> */
-                       msg.sa_rekey_margin = opt_whole;
-                       continue;
-
-               case CD_RKFUZZ: /* --rekeyfuzz <percentage> */
-                       msg.sa_rekey_fuzz = opt_whole;
-                       continue;
-
-               case CD_KTRIES: /* --keyingtries <count> */
-                       msg.sa_keying_tries = opt_whole;
-                       continue;
-
-               case CD_DPDACTION:
-                       if (streq(optarg, "none"))
-                               msg.dpd_action = DPD_ACTION_NONE;
-                       else if (streq(optarg, "clear"))
-                               msg.dpd_action = DPD_ACTION_CLEAR;
-                       else if (streq(optarg, "hold"))
-                               msg.dpd_action = DPD_ACTION_HOLD;
-                       else if (streq(optarg, "restart"))
-                               msg.dpd_action = DPD_ACTION_RESTART;
-                       else
-                               msg.dpd_action = DPD_ACTION_UNKNOWN;
-                       continue;
-
-               case CD_DPDDELAY:
-                       msg.dpd_delay = opt_whole;
-                       continue;
-
-               case CD_DPDTIMEOUT:
-                       msg.dpd_timeout = opt_whole;
-                       continue;
-
-               case CD_IKE:    /* --ike <ike_alg1,ike_alg2,...> */
-                       msg.ike = optarg;
-                       continue;
-
-               case CD_PFSGROUP:       /* --pfsgroup modpXXXX */
-                       msg.pfsgroup = optarg;
-                       continue;
-
-               case CD_ESP:    /* --esp <esp_alg1,esp_alg2,...> */
-                       msg.esp = optarg;
-                       continue;
-
-               case CD_CONNIPV4:
-                       if (LHAS(cd_seen, CD_CONNIPV6 - CD_FIRST))
-                               diag("--ipv4 conflicts with --ipv6");
-
-                       /* Since this is the default, the flag is redundant.
-                        * So we don't need to set msg.addr_family
-                        * and we don't need to check af_used_by
-                        * and we don't have to consider defaulting tunnel_addr_family.
-                        */
-                       continue;
-
-               case CD_CONNIPV6:
-                       if (LHAS(cd_seen, CD_CONNIPV4 - CD_FIRST))
-                               diag("--ipv6 conflicts with --ipv4");
-
-                       if (af_used_by != NULL)
-                               diagq("--ipv6 must precede", af_used_by);
-
-                       af_used_by = long_opts[long_index].name;
-                       msg.addr_family = AF_INET6;
-
-                       /* Consider defaulting tunnel_addr_family to AF_INET6.
-                        * Do so only if it hasn't yet been specified or used.
-                        */
-                       if (LDISJOINT(cd_seen, LELEM(CD_TUNNELIPV4 - CD_FIRST) | LELEM(CD_TUNNELIPV6 - CD_FIRST))
-                       && tunnel_af_used_by == NULL)
-                               msg.tunnel_addr_family = AF_INET6;
-                       continue;
-
-               case CD_TUNNELIPV4:
-                       if (LHAS(cd_seen, CD_TUNNELIPV6 - CD_FIRST))
-                               diag("--tunnelipv4 conflicts with --tunnelipv6");
-
-                       if (tunnel_af_used_by != NULL)
-                               diagq("--tunnelipv4 must precede", af_used_by);
-
-                       msg.tunnel_addr_family = AF_INET;
-                       continue;
-
-               case CD_TUNNELIPV6:
-                       if (LHAS(cd_seen, CD_TUNNELIPV4 - CD_FIRST))
-                               diag("--tunnelipv6 conflicts with --tunnelipv4");
-
-                       if (tunnel_af_used_by != NULL)
-                               diagq("--tunnelipv6 must precede", af_used_by);
-
-                       msg.tunnel_addr_family = AF_INET6;
-                       continue;
-
-               case CA_NAME:           /* --caname <name> */
-                       msg.name = optarg;
-                       msg.whack_ca = TRUE;
-                       continue;
-               case CA_CERT:           /* --cacert <path> */
-                       msg.cacert = optarg;
-                       continue;
-               case CA_LDAPHOST:       /* --ldaphost <hostname> */
-                       msg.ldaphost = optarg;
-                       continue;
-               case CA_LDAPBASE:       /* --ldapbase <base> */
-                       msg.ldapbase = optarg;
-                       continue;
-               case CA_CRLURI:         /* --crluri <uri> */
-                       msg.crluri = optarg;
-                       continue;
-               case CA_CRLURI2:        /* --crluri2 <uri> */
-                       msg.crluri2 = optarg;
-                       continue;
-               case CA_OCSPURI:        /* --ocspuri <uri> */
-                       msg.ocspuri = optarg;
-                       continue;
-               case CA_STRICT:         /* --strictcrlpolicy */
-                       msg.whack_strict = TRUE;
-                       continue;
-
-#ifdef DEBUG
-               case DBGOPT_NONE:       /* --debug-none */
-                       msg.debugging = DBG_NONE;
-                       continue;
-
-               case DBGOPT_ALL:        /* --debug-all */
-                       msg.debugging |= DBG_ALL;   /* note: does not include PRIVATE */
-                       continue;
-
-               case DBGOPT_RAW:        /* --debug-raw */
-               case DBGOPT_CRYPT:      /* --debug-crypt */
-               case DBGOPT_PARSING:    /* --debug-parsing */
-               case DBGOPT_EMITTING:   /* --debug-emitting */
-               case DBGOPT_CONTROL:    /* --debug-control */
-               case DBGOPT_LIFECYCLE:  /* --debug-lifecycle */
-               case DBGOPT_KERNEL:     /* --debug-kernel, --debug-klips */
-               case DBGOPT_DNS:        /* --debug-dns */
-               case DBGOPT_NATT:       /* --debug-natt */
-               case DBGOPT_OPPO:       /* --debug-oppo */
-               case DBGOPT_CONTROLMORE: /* --debug-controlmore */
-               case DBGOPT_PRIVATE:    /* --debug-private */
-               case DBGOPT_IMPAIR_DELAY_ADNS_KEY_ANSWER:       /* --impair-delay-adns-key-answer */
-               case DBGOPT_IMPAIR_DELAY_ADNS_TXT_ANSWER:       /* --impair-delay-adns-txt-answer */
-               case DBGOPT_IMPAIR_BUST_MI2:    /* --impair_bust_mi2 */
-               case DBGOPT_IMPAIR_BUST_MR2:    /* --impair_bust_mr2 */
-                       msg.debugging |= LELEM(c-DBGOPT_RAW);
-                       continue;
-#endif
-               default:
-                       assert(FALSE);      /* unknown return value */
-               }
-               break;
-       }
-
-       if (optind != argc)
-       {
-               /* If you see this message unexpectedly, perhaps the
-                * case for the previous option ended with "break"
-                * instead of "continue"
-                */
-               diagq("unexpected argument", argv[optind]);
-       }
-
-       /* For each possible form of the command, figure out if an argument
-        * suggests whether that form was intended, and if so, whether all
-        * required information was supplied.
-        */
-
-       /* check opportunistic initiation simulation request */
-       switch (opts_seen & (LELEM(OPT_OPPO_HERE) | LELEM(OPT_OPPO_THERE)))
-       {
-       case LELEM(OPT_OPPO_HERE):
-       case LELEM(OPT_OPPO_THERE):
-               diag("--oppohere and --oppothere must be used together");
-               /*NOTREACHED*/
-       case LELEM(OPT_OPPO_HERE) | LELEM(OPT_OPPO_THERE):
-               msg.whack_oppo_initiate = TRUE;
-               if (LIN(cd_seen, LELEM(CD_TUNNELIPV4 - CD_FIRST) | LELEM(CD_TUNNELIPV6 - CD_FIRST)))
-                       opts_seen &= ~LELEM(OPT_CD);
-               break;
-       }
-
-       /* check leases */
-       if (LHAS(opts_seen, OPT_LEASEADDR) && LHAS(opts_seen, OPT_LEASEID))
-       {
-               diag("--lease-addr and --lease-id cannot be used together");
-       }
-
-       /* check connection description */
-       if (LHAS(opts_seen, OPT_CD))
-       {
-               if (!LHAS(cd_seen, CD_TO-CD_FIRST))
-                       diag("connection description option, but no --to");
-
-               if (!LHAS(end_seen, END_HOST-END_FIRST))
-                       diag("connection missing --host after --to");
-
-               if (isanyaddr(&msg.left.host_addr)
-               && isanyaddr(&msg.right.host_addr))
-                       diag("hosts cannot both be 0.0.0.0 or 0::0");
-
-               if (msg.policy & POLICY_OPPO)
-               {
-                       if ((msg.policy & (POLICY_PSK | POLICY_PUBKEY)) != POLICY_PUBKEY)
-                               diag("only PUBKEY is supported for opportunism");
-                       if ((msg.policy & POLICY_PFS) == 0)
-                               diag("PFS required for opportunism");
-                       if ((msg.policy & POLICY_ENCRYPT) == 0)
-                               diag("encryption required for opportunism");
-               }
-
-               check_end(&msg.left, &msg.right, !LHAS(end_seen_before_to, END_NEXTHOP-END_FIRST)
-                       , msg.addr_family, msg.tunnel_addr_family);
-
-               check_end(&msg.right, &msg.left, !LHAS(end_seen, END_NEXTHOP-END_FIRST)
-                       , msg.addr_family, msg.tunnel_addr_family);
-
-               if (subnettypeof(&msg.left.client) != subnettypeof(&msg.right.client))
-                       diag("endpoints clash: one is IPv4 and the other is IPv6");
-
-               if (NEVER_NEGOTIATE(msg.policy))
-               {
-                       /* we think this is just a shunt (because he didn't specify
-                        * a host authentication method).  If he didn't specify a
-                        * shunt type, he's probably gotten it wrong.
-                        */
-                       if ((msg.policy & POLICY_SHUNT_MASK) == POLICY_SHUNT_TRAP)
-                               diag("non-shunt connection must have --psk or --rsasig or both");
-               }
-               else
-               {
-                       /* not just a shunt: a real ipsec connection */
-                       if ((msg.policy & POLICY_ID_AUTH_MASK) == LEMPTY)
-                               diag("must specify --rsasig or --psk for a connection");
-
-                       if (!HAS_IPSEC_POLICY(msg.policy)
-                       && (msg.left.has_client || msg.right.has_client))
-                               diag("must not specify clients for ISAKMP-only connection");
-               }
-
-               msg.whack_connection = TRUE;
-       }
-
-       /* decide whether --name is mandatory or forbidden */
-       if (!LDISJOINT(opts_seen
-       , LELEM(OPT_ROUTE) | LELEM(OPT_UNROUTE)
-       | LELEM(OPT_INITIATE) | LELEM(OPT_TERMINATE)
-       | LELEM(OPT_DELETE) | LELEM(OPT_CD)))
-       {
-               if (!LHAS(opts_seen, OPT_NAME) && !msg.whack_ca)
-                       diag("missing --name <connection_name>");
-       }
-       else if (!msg.whack_options && !msg.whack_status && !msg.whack_leases)
-       {
-               if (LHAS(opts_seen, OPT_NAME))
-                       diag("no reason for --name");
-       }
-
-       if (!LDISJOINT(opts_seen, LELEM(OPT_PUBKEYRSA) | LELEM(OPT_ADDKEY)))
-       {
-               if (!LHAS(opts_seen, OPT_KEYID))
-                       diag("--addkey and --pubkeyrsa require --keyid");
-       }
-
-       if (!(msg.whack_connection || msg.whack_key || msg.whack_myid
-       || msg.whack_delete || msg.whack_deletestate
-       || msg.whack_initiate || msg.whack_oppo_initiate || msg.whack_terminate
-       || msg.whack_route || msg.whack_unroute || msg.whack_listen
-       || msg.whack_unlisten || msg.whack_list || msg.whack_purgeocsp
-       || msg.whack_reread || msg.whack_ca || msg.whack_status
-       || msg.whack_options || msg.whack_shutdown || msg.whack_sc_op
-       || msg.whack_leases))
-       {
-               diag("no action specified; try --help for hints");
-       }
-
-       update_ports(&msg);
-
-       /* tricky quick and dirty check for wild values */
-       if (msg.sa_rekey_margin != 0
-       && msg.sa_rekey_fuzz * msg.sa_rekey_margin * 4 / msg.sa_rekey_margin / 4
-        != msg.sa_rekey_fuzz)
-               diag("rekeymargin or rekeyfuzz values are so large that they cause oveflow");
-
-       check_life_time (msg.sa_ike_life_seconds, OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM
-               , "ikelifetime", &msg);
-
-       check_life_time(msg.sa_ipsec_life_seconds, SA_LIFE_DURATION_MAXIMUM
-               , "ipseclifetime", &msg);
-
-       if (msg.dpd_action == DPD_ACTION_UNKNOWN)
-               diag("dpdaction must be \"none\", \"clear\", \"hold\" or \"restart\"");
-
-       if (msg.dpd_action != DPD_ACTION_NONE)
-       {
-               if (msg.dpd_delay <= 0)
-                       diag("dpddelay must be larger than zero");
-
-               if (msg.dpd_timeout <= 0)
-                       diag("dpdtimeout must be larger than zero");
-
-               if (msg.dpd_timeout <= msg.dpd_delay)
-                       diag("dpdtimeout must be larger than dpddelay");
-       }
-
-       /* pack strings for inclusion in message */
-       next_str = msg.string;
-       str_roof = &msg.string[sizeof(msg.string)];
-
-       /* build esp message as esp="<esp>;<pfsgroup>" */
-       if (msg.pfsgroup) {
-                       snprintf(esp_buf, sizeof (esp_buf), "%s;%s",
-                                       msg.esp ? msg.esp : "",
-                                       msg.pfsgroup ? msg.pfsgroup : "");
-                       msg.esp=esp_buf;
-       }
-       if (!pack_str(&msg.name)             /* string  1 */
-       ||  !pack_str(&msg.left.id)          /* string  2 */
-       ||  !pack_str(&msg.left.cert)        /* string  3 */
-       ||  !pack_str(&msg.left.ca)          /* string  4 */
-       ||  !pack_str(&msg.left.groups)      /* string  5 */
-       ||  !pack_str(&msg.left.updown)      /* string  6 */
-       ||  !pack_str(&msg.left.sourceip)    /* string  7 */
-       ||  !pack_str(&msg.left.virt)        /* string  8 */
-       ||  !pack_str(&msg.right.id)         /* string  9 */
-       ||  !pack_str(&msg.right.cert)       /* string 10 */
-       ||  !pack_str(&msg.right.ca)         /* string 11 */
-       ||  !pack_str(&msg.right.groups)     /* string 12 */
-       ||  !pack_str(&msg.right.updown)     /* string 13 */
-       ||  !pack_str(&msg.right.sourceip)   /* string 14 */
-       ||  !pack_str(&msg.right.virt)       /* string 15 */
-       ||  !pack_str(&msg.keyid)            /* string 16 */
-       ||  !pack_str(&msg.myid)             /* string 17 */
-       ||  !pack_str(&msg.cacert)           /* string 18 */
-       ||  !pack_str(&msg.ldaphost)         /* string 19 */
-       ||  !pack_str(&msg.ldapbase)         /* string 20 */
-       ||  !pack_str(&msg.crluri)           /* string 21 */
-       ||  !pack_str(&msg.crluri2)          /* string 22 */
-       ||  !pack_str(&msg.ocspuri)          /* string 23 */
-       ||  !pack_str(&msg.ike)              /* string 24 */
-       ||  !pack_str(&msg.esp)              /* string 25 */
-       ||  !pack_str(&msg.sc_data)          /* string 26 */
-       ||  !pack_str(&msg.whack_lease_ip)   /* string 27 */
-       ||  !pack_str(&msg.whack_lease_id)   /* string 28 */
-       ||  !pack_str(&msg.xauth_identity)   /* string 29 */
-       ||  str_roof - next_str < (ptrdiff_t)msg.keyval.len)
-               diag("too many bytes of strings to fit in message to pluto");
-
-       memcpy(next_str, msg.keyval.ptr, msg.keyval.len);
-       msg.keyval.ptr = NULL;
-       next_str += msg.keyval.len;
-
-       msg.magic = ((opts_seen & ~LELEM(OPT_SHUTDOWN))
-                               | sc_seen | lst_seen | cd_seen | ca_seen) != LEMPTY
-                       || msg.whack_options
-               ? WHACK_MAGIC : WHACK_BASIC_MAGIC;
-
-       /* send message to Pluto */
-       if (access(ctl_addr.sun_path, R_OK | W_OK) < 0)
-       {
-               int e = errno;
-
-               switch (e)
-               {
-               case EACCES:
-                       fprintf(stderr, "whack: no right to communicate with pluto (access(\"%s\"))\n"
-                               , ctl_addr.sun_path);
-                       break;
-               case ENOENT:
-                       fprintf(stderr, "whack: Pluto is not running (no \"%s\")\n"
-                               , ctl_addr.sun_path);
-                       break;
-               default:
-                       fprintf(stderr, "whack: access(\"%s\") failed with %d %s\n"
-                               , ctl_addr.sun_path, errno, strerror(e));
-                       break;
-               }
-               whack_exit(RC_WHACK_PROBLEM);
-       }
-       else
-       {
-               int sock = socket(AF_UNIX, SOCK_STREAM, 0);
-               int exit_status = 0;
-               ssize_t len = next_str - (char *)&msg;
-
-               if (sock == -1)
-               {
-                       int e = errno;
-
-                       fprintf(stderr, "whack: socket() failed (%d %s)\n", e, strerror(e));
-                       whack_exit(RC_WHACK_PROBLEM);
-               }
-
-               if (connect(sock, (struct sockaddr *)&ctl_addr
-               , offsetof(struct sockaddr_un, sun_path) + strlen(ctl_addr.sun_path)) < 0)
-               {
-                       int e = errno;
-
-                       fprintf(stderr, "whack:%s connect() for \"%s\" failed (%d %s)\n"
-                               , e == ECONNREFUSED? " is Pluto running? " : ""
-                               , ctl_addr.sun_path, e, strerror(e));
-                       whack_exit(RC_WHACK_PROBLEM);
-               }
-
-               if (write(sock, &msg, len) != len)
-               {
-                       int e = errno;
-
-                       fprintf(stderr, "whack: write() failed (%d %s)\n", e, strerror(e));
-                       whack_exit(RC_WHACK_PROBLEM);
-               }
-
-               /* for now, just copy reply back to stdout */
-
-               {
-                       char buf[4097];     /* arbitrary limit on log line length */
-                       char *be = buf;
-
-                       for (;;)
-                       {
-                               char *ls = buf;
-                               ssize_t rl = read(sock, be, (buf + sizeof(buf)-1) - be);
-
-                               if (rl < 0)
-                               {
-                                       int e = errno;
-
-                                       fprintf(stderr, "whack: read() failed (%d %s)\n", e, strerror(e));
-                                       whack_exit(RC_WHACK_PROBLEM);
-                               }
-                               if (rl == 0)
-                               {
-                                       if (be != buf)
-                                               fprintf(stderr, "whack: last line from pluto too long or unterminated\n");
-                                       break;
-                               }
-
-                               be += rl;
-                               *be = '\0';
-
-                               for (;;)
-                               {
-                                       char *le = strchr(ls, '\n');
-
-                                       if (le == NULL)
-                                       {
-                                               /* move last, partial line to start of buffer */
-                                               memmove(buf, ls, be-ls);
-                                               be -= ls - buf;
-                                               break;
-                                       }
-
-                                       le++;       /* include NL in line */
-                                       ignore_result(write(1, ls, le - ls));
-
-                                       /* figure out prefix number
-                                        * and how it should affect our exit status
-                                        */
-                                       {
-                                               unsigned long s = strtoul(ls, NULL, 10);
-
-                                               switch (s)
-                                               {
-                                               case RC_COMMENT:
-                                               case RC_LOG:
-                                                       /* ignore */
-                                                       break;
-                                               case RC_SUCCESS:
-                                                       /* be happy */
-                                                       exit_status = 0;
-                                                       break;
-                                               case RC_ENTERSECRET:
-                                                       get_secret(sock);
-                                                       break;
-                                               /* case RC_LOG_SERIOUS: */
-                                               default:
-                                                       /* pass through */
-                                                       exit_status = s;
-                                                       break;
-                                               }
-                                       }
-                                       ls = le;
-                               }
-                       }
-               }
-               whack_exit(exit_status);
-       }
-       return -1; /* should never be reached */
-}
diff --git a/src/whack/whack.h b/src/whack/whack.h
deleted file mode 100644 (file)
index c92eaf3..0000000
+++ /dev/null
@@ -1,352 +0,0 @@
-/* Structure of messages from whack to Pluto proper.
- * Copyright (C) 1998-2001  D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef _WHACK_H
-#define _WHACK_H
-
-#include <freeswan.h>
-
-#include <defs.h>
-#include <constants.h>
-
-/* copy of smartcard operations, defined in smartcard.h */
-#ifndef SC_OP_T
-#define SC_OP_T
-typedef enum {
-       SC_OP_NONE =    0,
-       SC_OP_ENCRYPT = 1,
-       SC_OP_DECRYPT = 2,
-       SC_OP_SIGN =    3,
-} sc_op_t;
-#endif /* SC_OP_T */
-
-/* Since the message remains on one host, native representation is used.
- * Think of this as horizontal microcode: all selected operations are
- * to be done (in the order declared here).
- *
- * MAGIC is used to help detect version mismatches between whack and Pluto.
- * Whenever the interface (i.e. this struct) changes in form or
- * meaning, change this value (probably by changing the last number).
- *
- * If the command only requires basic actions (status or shutdown),
- * it is likely that the relevant part of the message changes less frequently.
- * Whack uses WHACK_BASIC_MAGIC in those cases.
- *
- * NOTE: no value of WHACK_BASIC_MAGIC may equal any value of WHACK_MAGIC.
- * Otherwise certain version mismatches will not be detected.
- */
-
-#define WHACK_BASIC_MAGIC (((((('w' << 8) + 'h') << 8) + 'k') << 8) + 24)
-#define WHACK_MAGIC (((((('w' << 8) + 'h') << 8) + 'k') << 8) + 30)
-
-typedef struct whack_end whack_end_t;
-
-/* struct whack_end is a lot like connection.h's struct end
- * It differs because it is going to be shipped down a socket
- * and because whack is a separate program from pluto.
- */
-struct whack_end {
-       char *id;           /* id string (if any) -- decoded by pluto */
-       char *cert;         /* path string (if any) -- loaded by pluto  */
-       char *ca;           /* distinguished name string (if any) -- parsed by pluto */
-       char *groups;       /* access control groups (if any) -- parsed by pluto */
-       char *sourceip;         /* source IP address or pool identifier -- parsed by pluto */
-       int   sourceip_mask;
-       ip_address host_addr;
-       ip_address host_nexthop;
-       ip_address host_srcip;
-       ip_subnet client;
-       bool key_from_DNS_on_demand;
-       bool has_client;
-       bool has_client_wildcard;
-       bool has_port_wildcard;
-       bool has_srcip;
-       bool has_natip;
-       bool modecfg;
-       bool hostaccess;
-       bool allow_any;
-       certpolicy_t sendcert;
-       char *updown;               /* string */
-       u_int16_t host_port;        /* host order */
-       u_int16_t port;             /* host order */
-       u_int8_t protocol;
-       char *virt;
- };
-
-typedef struct whack_message whack_message_t;
-
-struct whack_message {
-       unsigned int magic;
-
-       /* for WHACK_STATUS: */
-       bool whack_status;
-       bool whack_statusall;
-
-
-       /* for WHACK_SHUTDOWN */
-       bool whack_shutdown;
-
-       /* END OF BASIC COMMANDS
-        * If you change anything earlier in this struct, update WHACK_BASIC_MAGIC.
-        */
-
-       /* name is used in connection, ca and initiate */
-       size_t name_len;    /* string 1 */
-       char *name;
-
-       /* for WHACK_OPTIONS: */
-
-       bool whack_options;
-
-       lset_t debugging;   /* only used #ifdef DEBUG, but don't want layout to change */
-
-       /* for WHACK_CONNECTION */
-
-       bool whack_connection;
-       bool whack_async;
-       bool ikev1;
-
-       lset_t policy;
-       time_t sa_ike_life_seconds;
-       time_t sa_ipsec_life_seconds;
-       time_t sa_rekey_margin;
-       unsigned long sa_rekey_fuzz;
-       unsigned long sa_keying_tries;
-
-       /* For DPD 3706 - Dead Peer Detection */
-       time_t dpd_delay;
-       time_t dpd_timeout;
-       dpd_action_t dpd_action;
-
-
-       /* Assign optional fixed reqid and xfrm marks to IPsec SA */
-       u_int32_t reqid;
-       struct {
-               u_int32_t value;
-               u_int32_t mask;
-       } mark_in, mark_out;
-
-       /*  note that each end contains string 2/5.id, string 3/6 cert,
-        *  and string 4/7 updown
-        */
-       whack_end_t left;
-       whack_end_t right;
-
-       /* note: if the client is the gateway, the following must be equal */
-       sa_family_t addr_family;    /* between gateways */
-       sa_family_t tunnel_addr_family;     /* between clients */
-
-       char *ike;          /* ike algo string (separated by commas) */
-       char *pfsgroup;     /* pfsgroup will be "encapsulated" in esp string for pluto */
-       char *esp;          /* esp algo string (separated by commas) */
-
-       /* for WHACK_KEY: */
-       bool whack_key;
-       bool whack_addkey;
-       char *keyid;        /* string 8 */
-       enum pubkey_alg pubkey_alg;
-       chunk_t keyval;     /* chunk */
-
-       /* for WHACK_MYID: */
-       bool whack_myid;
-       char *myid; /* string 7 */
-
-       /* for WHACK_ROUTE: */
-       bool whack_route;
-
-       /* for WHACK_UNROUTE: */
-       bool whack_unroute;
-
-       /* for WHACK_INITIATE: */
-       bool whack_initiate;
-
-       /* for WHACK_OPINITIATE */
-       bool whack_oppo_initiate;
-       ip_address oppo_my_client, oppo_peer_client;
-
-       /* for WHACK_TERMINATE: */
-       bool whack_terminate;
-
-       /* for WHACK_DELETE: */
-       bool whack_delete;
-
-       /* for WHACK_DELETESTATE: */
-       bool whack_deletestate;
-       so_serial_t whack_deletestateno;
-
-       /* for WHACK_LEASES: */
-       bool whack_leases;
-       char *whack_lease_ip, *whack_lease_id;
-
-       /* for WHACK_LISTEN: */
-       bool whack_listen, whack_unlisten;
-
-       /* for WHACK_CRASH - note if a remote peer is known to have rebooted */
-       bool whack_crash;
-       ip_address whack_crash_peer;
-
-       /* for WHACK_LIST */
-       bool whack_utc;
-       lset_t whack_list;
-
-       /* for WHACK_PURGEOCSP */
-       bool whack_purgeocsp;
-
-       /* for WHACK_REREAD */
-       u_char whack_reread;
-
-       /* for WHACK_CA */
-       bool whack_ca;
-       bool whack_strict;
-
-       char *cacert;
-       char *ldaphost;
-       char *ldapbase;
-       char *crluri;
-       char *crluri2;
-       char *ocspuri;
-
-       /* for WHACK_SC_OP */
-       sc_op_t whack_sc_op;
-       int inbase, outbase;
-       char *sc_data;
-
-       /* XAUTH user identity */
-       char *xauth_identity;
-
-       /* space for strings (hope there is enough room):
-        * Note that pointers don't travel on wire.
-        *  1 connection name
-        *  2 left's id
-        *  3 left's cert
-        *  4 left's ca
-        *  5 left's groups
-        *  6 left's updown
-        *  7 left's source ip
-        *  8 left's virtual ip ranges
-        *  9 right's id
-        * 10 right's cert
-        * 11 right's ca
-        * 12 right's groups
-        * 13 right's updown
-        * 14 right's source ip
-        * 15 right's virtual ip ranges
-        * 16 keyid
-        * 17 myid
-        * 18 cacert
-        * 19 ldaphost
-        * 20 ldapbase
-        * 21 crluri
-        * 22 crluri2
-        * 23 ocspuri
-        * 24 ike
-        * 25 esp
-        * 26 smartcard data
-        * 27 whack leases ip argument
-        * 28 whack leases id argument
-        * 29 xauth identity
-        * plus keyval (limit: 8K bits + overhead), a chunk.
-        */
-       size_t str_size;
-       char string[2048];
-};
-
-/* Codes for status messages returned to whack.
- * These are 3 digit decimal numerals.  The structure
- * is inspired by section 4.2 of RFC959 (FTP).
- * Since these will end up as the exit status of whack, they
- * must be less than 256.
- * NOTE: ipsec_auto(8) knows about some of these numbers -- change carefully.
- */
-enum rc_type {
-       RC_COMMENT,         /* non-commital utterance (does not affect exit status) */
-       RC_WHACK_PROBLEM,   /* whack-detected problem */
-       RC_LOG,             /* message aimed at log (does not affect exit status) */
-       RC_LOG_SERIOUS,     /* serious message aimed at log (does not affect exit status) */
-       RC_SUCCESS,         /* success (exit status 0) */
-
-       /* failure, but not definitive */
-
-       RC_RETRANSMISSION = 10,
-
-       /* improper request */
-
-       RC_DUPNAME = 20,    /* attempt to reuse a connection name */
-       RC_UNKNOWN_NAME,    /* connection name unknown or state number */
-       RC_ORIENT,          /* cannot orient connection: neither end is us */
-       RC_CLASH,           /* clash between two Road Warrior connections OVERLOADED */
-       RC_DEAF,            /* need --listen before --initiate */
-       RC_ROUTE,           /* cannot route */
-       RC_RTBUSY,          /* cannot unroute: route busy */
-       RC_BADID,           /* malformed --id */
-       RC_NOKEY,           /* no key found through DNS */
-       RC_NOPEERIP,        /* cannot initiate when peer IP is unknown */
-       RC_INITSHUNT,       /* cannot initiate a shunt-oly connection */
-       RC_WILDCARD,        /* cannot initiate when ID has wildcards */
-       RC_NOVALIDPIN,      /* cannot initiate without valid PIN */
-
-       /* permanent failure */
-
-       RC_BADWHACKMESSAGE = 30,
-       RC_NORETRANSMISSION,
-       RC_INTERNALERR,
-       RC_OPPOFAILURE,     /* Opportunism failed */
-
-       /* entry of secrets */
-       RC_ENTERSECRET = 40,
-
-       /* progress: start of range for successful state transition.
-        * Actual value is RC_NEW_STATE plus the new state code.
-        */
-       RC_NEW_STATE = 100,
-
-       /* start of range for notification.
-        * Actual value is RC_NOTIFICATION plus code for notification
-        * that should be generated by this Pluto.
-        */
-       RC_NOTIFICATION = 200       /* as per IKE notification messages */
-};
-
-/* options of whack --list*** command */
-
-#define LIST_NONE       0x0000  /* don't list anything */
-#define LIST_ALGS       0x0001  /* list all registered IKE algorithms */
-#define LIST_PUBKEYS    0x0002  /* list all public keys */
-#define LIST_CERTS      0x0004  /* list all host/user certs */
-#define LIST_CACERTS    0x0008  /* list all ca certs */
-#define LIST_ACERTS     0x0010  /* list all attribute certs */
-#define LIST_AACERTS    0x0020  /* list all aa certs */
-#define LIST_OCSPCERTS  0x0040  /* list all ocsp certs */
-#define LIST_GROUPS     0x0080  /* list all access control groups */
-#define LIST_CAINFOS    0x0100  /* list all ca information records */
-#define LIST_CRLS       0x0200  /* list all crls */
-#define LIST_OCSP       0x0400  /* list all ocsp cache entries */
-#define LIST_CARDS      0x0800  /* list all smartcard records */
-#define LIST_PLUGINS    0x1000  /* list all plugins with dependencies */
-
-#define LIST_ALL        LRANGES(LIST_ALGS, LIST_PLUGINS) /* all list options */
-
-/* options of whack --reread*** command */
-
-#define REREAD_NONE       0x00  /* don't reread anything */
-#define REREAD_SECRETS    0x01  /* reread /etc/ipsec.secrets */
-#define REREAD_CACERTS    0x02  /* reread certs in /etc/ipsec.d/cacerts */
-#define REREAD_AACERTS    0x04  /* reread certs in /etc/ipsec.d/aacerts */
-#define REREAD_OCSPCERTS  0x08  /* reread certs in /etc/ipsec.d/ocspcerts */
-#define REREAD_ACERTS     0x10  /* reread certs in /etc/ipsec.d/acerts */
-#define REREAD_CRLS       0x20  /* reread crls in /etc/ipsec.d/crls */
-
-#define REREAD_ALL      LRANGES(REREAD_SECRETS, REREAD_CRLS)  /* all reread options */
-
-#endif /* _WHACK_H */